# OBDash **Open-source, vehicle-agnostic OBD-II scanner — Python/Qt, cross-platform.** A desktop app that turns a cheap ELM327 adapter into a real diagnostic tool: live multi-axis graphs, automotive-style gauges, a sortable data table, and DTC read/clear — for **any OBD-II vehicle**. What it can read for each car is defined by a **JSON vehicle profile** (PIDs, scaling, codes, gauges), so adding a new vehicle is data, not code. Runs on **Windows, macOS, and Linux**. ![Multi-axis graph](docs/gui-p2-multiaxis.png) ![Gauge view](docs/gui-p2-gauges.png) > Validated on real vehicles (1997 Jeep Wrangler 4.0 I6, 1996 Mustang Cobra 4.6 > DOHC, Ford 6.0L Power Stroke, …) using a QinHeng CH340 ELM327 clone. ## Features - **Live graphs** with **true multi-axis** overlay — each metric gets its own Y axis, colored to match its line; click a line to move its axis to the left. Optional Normalize (% of range) mode. - **Gauge view** — round, tach-style gauges with tick scales, needles, **redline zones** (configurable per metric), and peak-hold. - **Table view** — value, min/max, and confidence per signal. - **Diagnostics** — read/clear trouble codes (guarded), with descriptions from a built-in **1,400+ generic SAE DTC database** (profiles override) and no-start codes flagged; plus **freeze-frame** (the snapshot when a code set). - **Emissions readiness** — I/M monitor status + MIL → a "will it pass inspection?" report. **Vehicle info** — VIN, calibration IDs, ECU name (Mode 09). - **Trip / Performance** — live MPG, trip distance/fuel, and **0-60 mph & 1/4-mile** timers (auto-detected from a standing start). - **Bi-directional / service functions** — actuator tests, service resets, etc., defined per-vehicle in the profile and run behind risk-based confirmations (ships with safe standard actions; OBDash never synthesizes command bytes). - **Vehicle profiles** — switch/import/edit vehicles from the Profile menu. - **Units** — °C/°F toggle (US/metric). - **Captures** — record a session to CSV and replay it. - **Mock mode** — explore the whole app with simulated data, no adapter needed. ## Download Grab a prebuilt binary from the [**latest release**](https://git.jpaul.io/justin/obdash/releases/latest): | Platform | File | |---|---| | Windows | `OBDash-windows.exe` | | macOS | `OBDash-macos.zip` (unzip → `OBDash.app`) | | Linux x86_64 | `OBDash-linux-x86_64` | | Linux ARM64 (Raspberry Pi) | `OBDash-linux-aarch64` | Each binary ships with a `.sha256` so you can verify the download: ```bash # macOS / Linux shasum -a 256 -c OBDash-macos.zip.sha256 # macOS sha256sum -c OBDash-linux-x86_64.sha256 # Linux ``` ```powershell # Windows (Get-FileHash OBDash-windows.exe -Algorithm SHA256).Hash.ToLower() Get-Content OBDash-windows.exe.sha256 # compare the two ``` ### Unsigned-binary warnings (expected for open source) The binaries aren't code-signed, so the OS will warn on first launch. They're safe — verify the checksum above, then: - **Windows (SmartScreen):** "Windows protected your PC" → **More info** → **Run anyway**. - **macOS (Gatekeeper):** right-click the app → **Open** (then **Open** again), or clear the quarantine flag: `xattr -dr com.apple.quarantine OBDash.app`. - **Linux:** `chmod +x OBDash-linux-x86_64 && ./OBDash-linux-x86_64`. (Code signing removes these warnings but costs money / a hardware token; see the project notes. Checksums give you the same integrity guarantee for free.) ## Run from source ```bash pip install -r requirements-gui.txt python run_gui.py # tick "Mock" + Connect to explore with no adapter ``` Needs Python 3.10+. The GUI deps (`PySide6`, `pyqtgraph`, `numpy`, `pyserial`) all ship wheels for Windows / macOS (incl. Apple Silicon) / Linux. ## Connecting to a vehicle Pick the adapter type in the toolbar, then **Connect** (key to RUN). OBDash speaks to any ELM327 over three transports: - **Serial / USB / classic-Bluetooth** — the port dropdown. USB CH340 adapters need a one-time driver: - **Windows** — WCH `CH341SER`; shows as `USB-SERIAL CH340 (COMx)`. - **macOS** — WCH `CH34xVCPDriver`; port `/dev/cu.wchusbserial*`. - **Linux** — kernel `ch341` (no install); `/dev/ttyUSB0` (add yourself to `dialout`). - **Classic-Bluetooth** ELM327 pair as a serial port (COMx / `/dev/cu.*` / `rfcomm`) — pair in your OS, then pick that port here. - **WiFi** — for WiFi ELM327 dongles: enter the host/port (default `192.168.0.10:35000`). Connect to the dongle's WiFi network first. No driver needed. - **Bluetooth LE** — Scan and pick the device. BLE support needs `pip install bleak` (optional; not bundled in the prebuilt binaries). BLE dongle GATT layouts vary, so this is experimental. Default serial baud is 38400; the ELM327 auto-negotiates the vehicle's protocol. ## Vehicle profiles Each `profiles/*.json` teaches OBDash how to read one vehicle. Bundled profiles: | Profile | Vehicle | |---|---| | `generic-obd2.json` | Any OBD-II vehicle (standard SAE PIDs) — a base to fork | | `ford-6.0-powerstroke.json` | Ford 6.0L Power Stroke (2003–2007) — incl. enhanced ICP/FICM/EBP PIDs | | `jeep-wrangler-4.0-1997.json` | 1997 Jeep Wrangler TJ 4.0 I6 | | `ford-mustang-cobra-4.6-1996.json` | 1996 Mustang SVT Cobra 4.6 DOHC | | `ford-mustang-gt-4.6-1996.json` | 1996 Mustang GT 4.6 SOHC | | `mercury-mountaineer-4.6-2006.json` | 2006 Mercury Mountaineer 4.6 V8 | **Add your vehicle:** the format is documented in [`profiles/PROFILE_SPEC.md`](profiles/PROFILE_SPEC.md) — it's written to be handed straight to an AI agent (*"research <year make model> and produce an OBDash profile per this spec"*). Drop the `.json` in `profiles/`, load it from the **Profile** menu, and open a PR. Profiles are pure data — they can't run code (formulas go through a sandboxed evaluator). ## Terminal tool (Ford 6.0 no-start) The repo also includes `obd_reader.py`, a self-contained **CLI** focused on diagnosing a **6.0 Power Stroke that won't start** — a big live **ICP-during-crank** monitor (`--crank`), code read/clear, and CSV logging. It needs only `pyserial`. See `handoff.md` and `diagnostics/` for the worked no-start investigation that seeded this project. (The GUI above is the general-purpose, multi-vehicle tool; the CLI is the diesel-specific workflow it grew out of.) ```bash python obd_reader.py COM5 --crank # big ICP cranking monitor python obd_reader.py COM5 --clear # read, then clear codes (guarded) ``` ## Project - [`ARCHITECTURE.md`](ARCHITECTURE.md) — design, the acquisition engine, roadmap. - Built on a headless `obdcore` package (link / registry / scheduler / store) shared by the GUI and the CLI; tested without hardware via a mock adapter. - CI builds the cross-platform binaries on tag (`.gitea/workflows/release.yml`). ## License MIT — see [`LICENSE`](LICENSE).