Harden OBD connection and telemetry

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-09 17:47:52 -04:00
co-authored by Copilot
parent 33ea6958f4
commit cdbe8c89b1
4 changed files with 420 additions and 162 deletions
+24 -18
View File
@@ -676,23 +676,10 @@ returns HTTP 200 with no "relay" text over the real network) and the remote serv
CORS-hook removal is baked into the image at build time - confirmed `/health` still returns
`{"status":"ok"}` and the response no longer carries any `Access-Control-*` header).
**Handoff note for next session (2026-08-09, end of session)**: Phase 12 is fully done/deployed/
verified as described above - nothing left to do there. Work had just started on **Phase 17 (OBD
hardening)** next - picked because it's pure Python with zero risk to the Pi's live filesystem,
in contrast to Phase 13's overlay-FS work which is riskier and deserves its own careful pass.
**No code was written for Phase 17 yet** - only read `modules/app_events.py` (confirms
`app_obd.obd_connection()` is only called from the Socket.IO `connect` handler, exactly as
previously noted) and `modules/app_gps.py` (to use its `_poll_loop()`/`start_gps()` background-
thread pattern as the template for OBD's new reconnect loop - lock+while-True+`time.sleep`,
daemon thread, idempotent `start_*()` guard against double-starting). A `pip install obd` on the
dev machine to inspect `python-obd`'s actual API (for DTC codes, ELM327 version/protocol
attributes, exception types) was attempted but interrupted by a tool permission prompt before
producing any output - **this still needs to be done** (or just read the `python-obd` source
directly, e.g. via `pip download`/GitHub) before writing the DTC/diagnostics/protocol-override
parts of Phase 17, to get exact attribute/method names right (e.g. `connection.protocol_name()`,
`obd.commands.GET_DTC`, whatever `python-obd`'s actual exception class is called) rather than
guessing. Phases 13 and 14 (UI foundation) are also fully ready to start (no blocking deps) if
picking a different phase first makes more sense than continuing Phase 17.
**Update 2026-08-09**: Phase 17 (OBD hardening) was completed next; see its section below.
Phase 14 is the recommended next software phase because Phases 15/16 and the later list-based
features depend on its shared UI foundation. Phase 13 remains independent but requires a careful
hardware/filesystem deployment pass rather than ordinary application deployment.
### Phase 13: Power-loss resilience & watchdog — 🚧 PLANNED
**New phase, not code-dependent on anything else — OS/hardware-level, can be done anytime,
@@ -772,7 +759,7 @@ Same file-browser treatment for videos already imported to the Pi's own disk
Settings page - e.g. "delete local copies older than N days once uploaded", off by default)
so the Pi's limited storage doesn't need to be babysat manually as the dashcam backlog grows.
### Phase 17: OBD real-hardware readiness (code hardening) — 🚧 PLANNED
### Phase 17: OBD real-hardware readiness (code hardening) — ✅ DONE
**Independent of everything else in this plan — only touches `app_obd.py`/`app_events.py`, no UI
dependency for the backend part, so this can be done anytime/in parallel with the phases above.**
Nothing has been installed or tested in the actual 2013 Yaris yet - `modules/app_obd.py` has
@@ -814,6 +801,25 @@ all in `modules/app_obd.py` / `modules/app_events.py`:
confirmed once tested against the real car (falls under "code hardening only" for now - add
the query with graceful "unsupported" handling rather than assuming it will work).
**Implemented 2026-08-09**:
- Added an idempotent, browser-independent reconnect daemon started from `app.py`; it retries
every 10 seconds and restarts any dead polling workers after reconnect.
- Serialized all python-obd queries so speed, RPM, and the expanded sensor worker cannot issue
overlapping serial exchanges. Query exceptions and silent connection-state changes now close
and discard the stale handle, emit disconnected state, and hand recovery back to the reconnect
loop instead of permanently killing a worker.
- Added `OBD_PROTOCOL` support and distinct logs for no serial adapter, failed ELM327 handshake,
and ELM327 connected but no ECU response. Successful connections log port, ELM327 firmware,
negotiated protocol ID, and protocol name once.
- Added backend polling/emits for coolant temperature, fuel level, throttle position, MIL/DTC
status, stored DTCs, and SAE PID `0xA6` odometer. Odometer uses a custom python-obd command with
a null/unsupported result left as `None`; support is not assumed for the 2013 Yaris.
- Verified against the Pi's installed python-obd 0.7.3 API, plus focused mocked checks covering
successful connection, forced protocol, ECU-off status, silent disconnect cleanup, query
exceptions, and odometer decoding. The Pi currently has `/dev/ttyUSB0` present but is not
connected to the car, so actual PID availability and negotiated Toyota protocol still require
the user-planned first in-car test.
### Phase 18: Trip history & replay — 🚧 PLANNED
**New phase.** Right now the `tracking` table (Phase 7) is just a raw stream of GPS/speed points
with no concept of a discrete "trip" - there's no way to look back and see "trip #47, left home