From 01de18a568587d9faa0c0aa9dd0d165d9d100ed5 Mon Sep 17 00:00:00 2001 From: Justin Paul Date: Tue, 30 Jun 2026 14:06:49 -0400 Subject: [PATCH] Document cross-platform support (Windows/macOS/Linux) The stack is portable by construction: PySide6/pyqtgraph/numpy/pyserial all ship wheels for all three OSes (incl. Apple Silicon); obdcore has no OS-specific code; the terminal dashboard's only platform code is guarded (os.name=='nt' vs termios for POSIX = macOS+Linux). - ARCHITECTURE.md: Cross-platform section -- portability rules (list_ports only, pathlib, no shelling out, platformdirs for config), the three per-OS seams (CH340 driver, PyInstaller per-OS packaging, Gatekeeper/SmartScreen). - README: Setup now covers Windows (CH341SER), macOS (CH34xVCPDriver), Linux (in-kernel ch341 + dialout group) instead of Windows-only. No code changes; obdcore tests still pass. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_016yT89n4zR4qbrySoSiEyZs --- ARCHITECTURE.md | 42 +++++++++++++++++++++++++++++++++++++++++- README.md | 19 +++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 6aa34b2..41ec6ec 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -113,6 +113,43 @@ sensors (e.g. a serial/analog EGT/oil-PSI module) can feed extra channels later. - **PID discovery scan** in GUI (the brute-scan, auto-add hits). - Units toggle, night theme, big-touch cab mode. +## Cross-platform support + +Target: **Windows, macOS, Linux** from one codebase. The whole stack is +portable — `PySide6`, `pyqtgraph`, `numpy`, `pyserial` all ship wheels for +all three (incl. Apple Silicon). `obdcore` is pure Python/IO with no +OS-specific calls; the only platform code is the terminal dashboard's +ANSI/key handling, guarded `os.name == "nt"` (Windows) vs `termios` (POSIX = +macOS + Linux). Rules to keep it that way: + +- **Serial enumeration** goes through `serial.tools.list_ports` only — never + assume `COMx`. Port names differ per OS (`COM5` / `/dev/cu.usbserial-*` / + `/dev/ttyUSB0`); the GUI shows a dropdown from `find_ports()`, no typing. +- **Paths**: `pathlib`/caller-supplied only; no hardcoded separators or drives. +- **No shelling out** to OS tools in core; no `os.system`. (The Windows VT + enable via `ctypes.windll` is the one exception, fully guarded.) +- **Config/recordings** live under a per-OS app-data dir + (`platformdirs`) rather than next to the script. + +Three seams that are inherently per-OS (not code we can unify): + +1. **CH340 USB driver** (the adapter, not our app): + - **Windows** — install WCH `CH341SER`. + - **macOS** — install the WCH `CH34xVCPDriver` (Mac App Store / WCH); + recent macOS bundles a CH34x driver but clones often need WCH's. + Port shows as `/dev/cu.wchusbserial*` or `/dev/cu.usbserial*`. + - **Linux** — `ch341` is in the kernel; zero install. Just add the user to + the `dialout` group for `/dev/ttyUSB0` access. +2. **Packaging** — PyInstaller is per-OS (no cross-compile): build the `.exe` + on Windows, the `.app`/`.dmg` on macOS, an ELF/AppImage on Linux. We have + all three hosts available, or do it in CI. (Briefcase is the alternative if + we want macOS notarization/signing handled.) +3. **macOS Gatekeeper / Windows SmartScreen** — unsigned builds warn on first + run; optional code-signing/notarization later (P5). + +Primary dev/use target is the Windows laptop; macOS/Linux are first-class for +development (build the GUI against `MockLink` on any box) and supported targets. + ## Roadmap - **P0 — core (this commit):** `obdcore` package + tests + this doc. *Next:* @@ -130,5 +167,8 @@ sensors (e.g. a serial/analog EGT/oil-PSI module) can feed extra channels later. ## Dependencies - Runtime (core): `pyserial`. -- GUI: `PySide6`, `pyqtgraph`, `numpy`. +- GUI: `PySide6`, `pyqtgraph`, `numpy`, `platformdirs` (per-OS config/recording dirs). - Dev: `pytest`, `pyinstaller`. + +All are cross-platform with wheels for Windows / macOS (incl. Apple Silicon) / +Linux, so `pip install` is the same everywhere. diff --git a/README.md b/README.md index ea2351a..95119f3 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,22 @@ reading/clearing codes and the basics, not Ford-enhanced diesel PIDs (see Scope - Key **live values** (coolant, IAT, MAP, module voltage, RPM, load, throttle) + battery voltage - 6.0 Power Stroke **no-start triage** checklist (FICM, ICP, cam/crank, batteries, fuel) -## Setup (Windows) +## Setup -1. Install the CH340 driver (WCH `CH341SER`) so the adapter appears as - `USB-SERIAL CH340 (COMx)` in Device Manager → Ports. -2. Install Python from — tick **Add Python to PATH**. +Runs on **Windows, macOS, and Linux** (Python + pyserial). The only per-OS +difference is the CH340 USB driver: + +- **Windows** — install WCH `CH341SER`; adapter shows as `USB-SERIAL CH340 (COMx)` + in Device Manager → Ports. Install Python from + (tick **Add Python to PATH**), or just double-click `RUN_OBD.bat`. +- **macOS** — install WCH `CH34xVCPDriver` (Mac App Store or wch.cn). Port appears + as `/dev/cu.wchusbserial*`. `pip install pyserial`. +- **Linux** — `ch341` driver is built into the kernel (no install). Port is + `/dev/ttyUSB0`; add yourself to the `dialout` group for access + (`sudo usermod -aG dialout $USER`, then re-login). `pip install pyserial`. + +The tool auto-detects the port on all three; pass it explicitly if needed +(`COM5`, `/dev/cu.usbserial-1420`, `/dev/ttyUSB0`). ## Usage