Files
yaris-obd/BUGS.md
T

11 KiB

yaris-obd Bug Tracker

Standalone bug/issue tracker for the yaris-obd project, kept separate from PLAN.md. Use this file to record, track status, and hand off bugs to another agent/session. PLAN.md still summarizes bug-fix progress in its phase sections (and Phase 26 is the dedicated road-test bug-fix phase), but the authoritative, issue-by-issue record lives here.

How to use this tracker

  • File format: one ## BUG-XX section per issue. Keep the numbering sequential.
  • Status field: OPEN → IN PROGRESS → FIXED (commit ref) → CLOSED (deployed + verified) or WONTFIX/DUP as appropriate.
  • Relate to phases: each entry's Phase field links a bug to the relevant PLAN.md phase so an agent can find the surrounding context and acceptance criteria.
  • When fixed: keep the original symptom/impact recorded (don't delete history), set status to FIXED, add the commit SHA in the Fix field, then move to CLOSED after deploy/verify. Also drop a one-line mention in the corresponding PLAN.md phase.
  • For future bugs: add new ## BUG-XX entries here rather than only burying them in chat history. Keep them SMALL and one-issue-per-entry so they are easy to pick up and verify.

Open bugs

BUG-01 — WiFi/hotspot unreachable from phone while cell data is on (and wrong documented gateway)

  • Status: OPEN
  • Severity: Medium (usability of the in-car hotspot from a phone)
  • Area: Networking / Pi hotspot (yaris-uplink, NetworkManager shared AP, docs)
  • Phase: Phase 26
  • Symptom: While a phone is connected to the Pi's no-internet hotspot and cell data is on, the phone cannot load yaris.local, 10.42.0.1, or the Pi's DHCP address at all. With cell data disabled, http://<dhcp-ip>/ loads, but yaris.local and 10.42.0.1 still do not. The working address seen was 10.112.<...>.
  • Root cause (confirmed): Phone-OS "smart network switching" — with a no-internet WiFi network associated and cellular available, the OS keeps cellular as the whole-device default route, so no traffic (even a plain page navigation or fetch()) reaches the Pi hotspot. Disabling cell data forces the hotspot WiFi to become the default network. This is the same OS-level ceiling documented in Phase 11/22. Separately, the actual NetworkManager shared-AP subnet is 10.112.0.x, not the documented 10.42.0.1, and yaris.local mDNS isn't resolved from the phone on the Pi AP.
  • Fix scope / actions:
    • Make the documented/reachable address correct (surface the Pi's real DHCP-assigned address in the UI / status page rather than hardcoding 10.42.0.1).
    • Extend the yaris.local unicast (shared-dnsmasq) fallback to the AP subnet so it resolves from a phone on the Pi hotspot.
    • Clearly document the cell-data limitation and the workaround (disable cell data / "smart network switching").
  • Acceptance: phone on the Pi hotspot can load the web UI via a documented, correct address (optionally yaris.local), and the cell-data caveat is documented.

BUG-02 — Micro-USB power port on the Pi is physically damaged

  • Status: OPEN
  • Severity: Hardware (reliability/power)
  • Area: Hardware / power
  • Phase: Phase 26
  • Symptom: The Pi's micro-USB 5V power connector is worn/damaged and no longer makes a reliable connection. Power is likely to drop under vibration in the car.
  • Root cause: Physical wear on the connector.
  • Fix scope / actions: No code. Owner hard-wires 5V and GND directly to the Pi's GPIO header (pins 2/4 for 5V, 6/9/14/20/25/30/34/39 for GND) with a suitable PSU, bypassing the micro-USB port. Confirm vcgencmd get_throttled shows no current undervoltage after rewiring (the Phase 19/20 alerts monitor this).
  • Acceptance: Stable power with no undervoltage/throttling under load.

BUG-03 — DTC/MIL codes are never persisted; lost on OBD disconnect or reboot

  • Status: OPEN
  • Severity: Medium (lost diagnostic data; also a stats bug)
  • Area: modules/app_obd.py, modules/app_sql.py, get_overview_stats
  • Phase: Phase 26
  • Symptom: Stored DTC trouble codes and MIL state live only in the in-memory dtc_codes global in app_obd.py. They vanish as soon as OBD disconnects or the Pi reboots. Separately, get_overview_stats queries a table named dtc_codes that does not exist (the created table is dtc), so the post-road-test state may be wrong/broken.
  • Root cause: The SQLite dtc table is created in schema but is never written to or read from by any code path. No DTC persistence exists at all.
  • Fix scope / actions:
    • Persist MIL + DTC codes to the dtc SQLite table on each successful poll.
    • Read back from SQLite when OBD is disconnected so last-known codes stay visible.
    • Fix get_overview_stats to query the real dtc table (and use current MIL/DTC state).
    • Add a "cleared/since" concept so a code that was cleared is distinguishable from one still set.
  • Acceptance: Codes set during a drive survive a power cycle / OBD disconnect and appear on the DTC page and overview stats.

BUG-04 — Server merges two separate trips into one (motion boundary mismatch)

  • Status: OPEN
  • Severity: Medium (incorrect server trip history vs the Pi)
  • Area: server/modules/db.py compute_trips_for_device
  • Phase: Phase 26
  • Symptom: Two distinct drives (parked in between) appear as a single merged trip on the remote portal, while the Pi correctly reports them as separate trips.
  • Root cause: The Pi splits trips by motion (OBD wheel speed + sustained GPS displacement, with a 5-min motion gap). The server splits only by a pure time gap (>5 min) and filters by duration/50 m, so parked idle tracking rows bridging two drives get combined into one trip.
  • Fix scope / actions: Mirror the Pi's motion-aware trip-boundary logic on the server so the two systems agree. Note this may re-split/recompute existing server trips — get owner sign-off before recomputing, and re-run scripts/recompute_trips.py after the fix.
  • Acceptance: A real drive with a parked gap produces the same number of trips on the server as on the Pi.

BUG-05 — Server route replay reports speed_source: "gps" even when OBD speed is present

  • Status: OPEN
  • Severity: Low (display/metadata)
  • Area: server/modules/db.py get_trip_route
  • Phase: Phase 26
  • Symptom: Server route replay always labels points with speed_source: "gps", even though the points carry real OBD speed. The Pi's route_points correctly uses "obd" when speed > 0.
  • Root cause: get_trip_route hardcodes speed_source: "gps" rather than deriving it from the per-point speed value.
  • Fix scope / actions: Mirror the Pi's logic ("obd" when speed > 0, otherwise "gps") in the server route response.
  • Acceptance: Server route points report obd speed source where wheel speed was recorded.

BUG-06 — Server timestamps are shifted (Postgres stores naive local time as UTC)

  • Status: OPEN
  • Severity: High-ish (all server trip times / boundaries off by the EDT offset)
  • Area: Pi upload (modules/app_upload.py / SQL), server/sql, server/modules/db.py, portal display
  • Phase: Phase 26
  • Symptom: Server shows trip times (and effectively trip boundaries/comparisons against the Pi) shifted by the Montreal-timezone-to-UTC offset (~4-5 hours depending on DST).
  • Root cause: tracking_points.recorded_at is TIMESTAMPTZ, but the Pi sends naive local (Montreal) time (datetime.now()) with no offset. Postgres (UTC container timezone) interprets that naive string as UTC.
  • Fix scope / actions (delicate — touches sending, storage, and display):
    • Pi should send timezone-aware timestamps in local Eastern time (or explicit UTC).
    • Server should store/read as America/Toronto (or consistent UTC) and display in Eastern.
    • Optional one-time migration to correct already-stored rows (depends on offset at insert time — needs a decision: re-map by DST window or accept a best-effort correction). Rebuilding the server trips table may be needed. Get owner sign-off on migrating existing data.
  • Acceptance: New data displays at the correct local time on the portal; existing shifted rows are corrected (or explicitly accepted as-is if the owner opts out of migration).

BUG-07 — Trip replay on the portal sometimes does nothing

  • Status: OPEN (needs reproduction/diagnostics)
  • Severity: Low/Medium (intermittent UI)
  • Area: static/js/history.js (shared Pi+server), server /api/v1/portal/trip/<id>
  • Phase: Phase 26
  • Symptom: Clicking a trip to replay on the /history page intermittently does nothing — no route renders, no error shown.
  • Root cause: Not yet isolated. Plausible contributors: an API/DB race (recompute_trips running concurrently with a route read), DB lock, or clicking before the map is ready. Note history.js uses shared parsing that expects space-separated Pi timestamps and "T"-separated server ones — verify both.
  • Fix scope / actions: Add targeted diagnostics (log/reproduce) before fixing. Check map readiness, error handling on the trip-fetch, and the shared timestamp parsing. Add an explicit "failed to load route" state instead of silent inaction.
  • Acceptance: Replay is reliable; any failure surfaces a visible error rather than doing nothing.

BUG-08 — No trip deletion on the local Pi (only on the remote portal)

  • Status: OPEN
  • Severity: Medium (feature parity: delete trips locally)
  • Area: Pi templates/components.html, templates/base.html, templates/history.html, static/js/history.js, app.py
  • Phase: Phase 26
  • Symptom: The Pi /history page has no way to delete a trip. The remote portal does.
  • Root cause: Several Pi pieces are missing compared to the server:
    1. Pi components.html data_table macro lacks the deletable arg that emits data-deletable="1" (the server's macro has it).
    2. Pi base.html does not define window.confirmDelete (the server's does).
    3. Pi history.js hardcodes the server delete endpoint /api/v1/portal/trip/<id> — which does not exist on the Pi.
    4. There is no DELETE /api/trip/<id> route on the Pi at all.
  • Fix scope / actions: Add all four pieces on the Pi — the deletable macro arg, the window.confirmDelete helper, a DELETE /api/trip/<id> route that removes only the derived trip record (keeping the raw tracking data), and make the delete endpoint configurable in history.js (e.g. via a data attribute like the tile URL) so the same JS works on Pi and server.
  • Acceptance: The Pi /history page can delete a trip with confirmation; raw GPS data is preserved; the server portal is unaffected.

Resolved bugs

(No entries yet — resolved-and-fixed bugs land here, oldest→newest. Keep the bug's original symptom text intact and add the fix/closure details.)