docs: sign off Phase 25 road test, add BUGS.md, renumber Android to Phase 27
This commit is contained in:
@@ -0,0 +1,190 @@
|
|||||||
|
# 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.)
|
||||||
@@ -1400,7 +1400,7 @@ including two UX polish passes and multiple bug-fix rounds.
|
|||||||
|
|
||||||
**Roadmap ordering note (2026-08-10):** the late phases are intentionally sequenced as
|
**Roadmap ordering note (2026-08-10):** the late phases are intentionally sequenced as
|
||||||
Phase 25.5a–25.5d (configuration/sync/status work) -> Phase 25 (real-car acceptance gate) ->
|
Phase 25.5a–25.5d (configuration/sync/status work) -> Phase 25 (real-car acceptance gate) ->
|
||||||
Phase 26 (Android, always last).
|
Phase 26 (road-test bug fixes) -> Phase 27 (Android, always last).
|
||||||
|
|
||||||
### Phase 25.5a: Device configuration sync backend — ✅ COMPLETE (connection-driven server sync)
|
### Phase 25.5a: Device configuration sync backend — ✅ COMPLETE (connection-driven server sync)
|
||||||
**Server API and Pi sync thread implemented.** Server stores device config; Pi fetches when internet available and applies changes without restart.
|
**Server API and Pi sync thread implemented.** Server stores device config; Pi fetches when internet available and applies changes without restart.
|
||||||
@@ -1714,7 +1714,14 @@ architecture.
|
|||||||
`/` HTML places `Overview` before `Live GPS`.
|
`/` HTML places `Overview` before `Live GPS`.
|
||||||
|
|
||||||
---
|
---
|
||||||
### Phase 25: Pre-install Yaris 2013 compatibility test — 🚧 PLANNED (core-system gate)
|
### Phase 25: Pre-install Yaris 2013 compatibility test — ✅ DONE (owner road test; full checklist not followed)
|
||||||
|
**Owner conducted the in-car road test and checked for bugs. Per explicit owner instruction this
|
||||||
|
phase is marked complete — however, the full Phase 25 acceptance checklist was NOT rigorously
|
||||||
|
worked through item-by-item (an engineer was not present; several checklist items were skipped or
|
||||||
|
only informally observed). Treat the system's compatibility with the 2013 Yaris as validated by
|
||||||
|
the owner's practical drive, not as a documented item-by-item pass.** Bugs surfaced by the road
|
||||||
|
test are cataloged in `BUGS.md` and tracked for fixing in Phase 26. The former Phase 26 Android
|
||||||
|
slot was renumbered to **Phase 27 (always last)** to make room — see the roadmap note below.
|
||||||
**Added 2026-08-09; intentionally immediately before the Android app.** Bench tests, synthetic
|
**Added 2026-08-09; intentionally immediately before the Android app.** Bench tests, synthetic
|
||||||
routes, attached-hardware tests, and stationary Pi runs cannot prove the complete system works
|
routes, attached-hardware tests, and stationary Pi runs cannot prove the complete system works
|
||||||
when temporarily connected to and powered by the actual 2013 Toyota Yaris. This phase is the
|
when temporarily connected to and powered by the actual 2013 Toyota Yaris. This phase is the
|
||||||
@@ -1725,20 +1732,38 @@ cable routing, trim work, and final installation are explicitly outside the road
|
|||||||
handled by the owner after this phase passes.
|
handled by the owner after this phase passes.
|
||||||
|
|
||||||
Prepare a temporary, removable test setup before driving:
|
Prepare a temporary, removable test setup before driving:
|
||||||
- Connect the Pi, SIM868 HAT/antennas, USB OBD adapter, dashcam, and representative intended power
|
- ~~Connect the Pi, SIM868 HAT/antennas, USB OBD adapter, dashcam, and representative intended power
|
||||||
source without permanently mounting or routing anything. Secure every temporary component and
|
source without permanently mounting or routing anything. Secure every temporary component and
|
||||||
cable so it cannot interfere with pedals, steering, airbags, visibility, occupants, or loose-item
|
cable so it cannot interfere with pedals, steering, airbags, visibility, occupants, or loose-item
|
||||||
safety during the controlled drive; remove the setup after testing.
|
safety during the controlled drive; remove the setup after testing.~~ — ✅ **DONE** (owner set up
|
||||||
- Resolve the Phase 19/20 undervoltage/throttling warning before the test; confirm
|
the temporary test rig).
|
||||||
|
- ~~Resolve the Phase 19/20 undervoltage/throttling warning before the test; confirm
|
||||||
`vcgencmd get_throttled` shows no current power fault at idle and under load with the temporary
|
`vcgencmd get_throttled` shows no current power fault at idle and under load with the temporary
|
||||||
representative power setup. This validates electrical compatibility, not final cable routing.
|
representative power setup. This validates electrical compatibility, not final cable routing.~~ —
|
||||||
- Back up the Pi SQLite database and record baseline row/trip/video/upload counts on the Pi and
|
⚠️ **OPEN — NOT DONE.** The Phase 19/20 undervoltage/throttling warning was **not** resolved
|
||||||
|
before the test. The intended power source is the **cigarette-lighter USB charger**, with the
|
||||||
|
5V/GND to be **hard-wired onto the Pi's GPIO header** (bypassing the worn micro-USB port — see
|
||||||
|
BUG-02). Whether the cigarette-lighter USB supplies clean, non-undervolting 5V under the Pi's
|
||||||
|
load still needs to be verified. **Action**: hard-wire 5V/GND to the GPIO header, then run
|
||||||
|
`vcgencmd get_throttled` at idle and under load and confirm **no current** fault before
|
||||||
|
declaring the power source adequate. If the lighter charger undervolts, it is **not** a
|
||||||
|
sufficient power source and a higher-rated/supported PSU must be chosen. (Cigarette-lighter
|
||||||
|
USB alone, on a worn/loose connector, is the most likely culprit for residual throttling.)
|
||||||
|
- ~~Back up the Pi SQLite database and record baseline row/trip/video/upload counts on the Pi and
|
||||||
remote server. Use a uniquely timestamped test window so generated records can be reconciled
|
remote server. Use a uniquely timestamped test window so generated records can be reconciled
|
||||||
without deleting unrelated history.
|
without deleting unrelated history.~~ — ⚠️ **SKIPPED** (owner: "didn't do it but don't very
|
||||||
- Verify the service, watchdog, storage mounts, hotspot, `http://yaris.local/`, alert engine, GPS
|
care"). Acceptable to skip the pre-test backup/baseline, but be aware there is now **no
|
||||||
antenna view, dashcam recording mode, free space, and remote server health before moving.
|
pre-test record** to reconcile test drive rows against, and no pre-drive SQLite backup exists.
|
||||||
- Use a second person for UI/log observations while the vehicle is moving, or record diagnostics
|
- ~~Verify the service, watchdog, storage mounts, hotspot, `http://yaris.local/`, alert engine, GPS
|
||||||
for review afterward. The driver must not operate or troubleshoot the UI while driving.
|
antenna view, dashcam recording mode, free space, and remote server health before moving.~~ —
|
||||||
|
🟡 **PARTIAL.** Pre-move verification was done and the hot-spot is connectable, but
|
||||||
|
**`yaris.local` does not resolve** on the phone → tracked as **BUG-01**. Everything else on this
|
||||||
|
line checked out (service/watchdog/mounts/free space/remote health) per the owner.
|
||||||
|
- ~~Use a second person for UI/log observations while the vehicle is moving, or record diagnostics
|
||||||
|
for review afterward. The driver must not operate or troubleshoot the UI while driving.~~ —
|
||||||
|
⛔ **SCRATCHED** (owner: "will do it solo"). **Safety note kept**: the driver must NOT operate or
|
||||||
|
troubleshoot the UI while driving; solo testing relies on recording diagnostics for later
|
||||||
|
review.
|
||||||
|
|
||||||
Run a controlled route containing ignition-off/on, stationary idle, low-speed streets, normal road
|
Run a controlled route containing ignition-off/on, stationary idle, low-speed streets, normal road
|
||||||
speed, several complete stops, turns, a short GPS-obstructed segment if safely available, and a
|
speed, several complete stops, turns, a short GPS-obstructed segment if safely available, and a
|
||||||
@@ -1747,22 +1772,34 @@ clean trip end:
|
|||||||
adapter firmware, and verify real speed/RPM/coolant/fuel/throttle/MIL/DTC values. Compare wheel
|
adapter firmware, and verify real speed/RPM/coolant/fuel/throttle/MIL/DTC values. Compare wheel
|
||||||
speed against the instrument cluster at several safe speeds. Record unsupported PIDs (especially
|
speed against the instrument cluster at several safe speeds. Record unsupported PIDs (especially
|
||||||
odometer PID A6) as capabilities, not failures, and verify reconnect after ignition cycling and a
|
odometer PID A6) as capabilities, not failures, and verify reconnect after ignition cycling and a
|
||||||
deliberate USB disconnect/reconnect.
|
deliberate USB disconnect/reconnect. — ✅ **DONE** (owner: "seems to work — OBD connects, DTC
|
||||||
|
codes working, throttle working, speed, etc."). Negotiabd protocol/firmware values not explicitly
|
||||||
|
logged, and odometer PID A6 support remains unconfirmed (expected unsupported on the 2013 Yaris —
|
||||||
|
see Phase 24.6).
|
||||||
- **GPS and motion logging:** confirm fixes while stationary and moving, route coordinates on the
|
- **GPS and motion logging:** confirm fixes while stationary and moving, route coordinates on the
|
||||||
offline map, OBD-speed-first motion detection, GPS displacement fallback when OBD is deliberately
|
offline map, OBD-speed-first motion detection, GPS displacement fallback when OBD is deliberately
|
||||||
unavailable, one-minute idle heartbeat behavior, and no false trip from stationary GPS drift.
|
unavailable, one-minute idle heartbeat behavior, and no false trip from stationary GPS drift. —
|
||||||
|
✅ **DONE** (owner: "seems to work for the trip"). **Cross-ref:** the *server-side* trip-boundary
|
||||||
|
mismatch (BUG-04) is the known follow-up.
|
||||||
- **Trip boundary/replay:** after the inactivity timeout, verify exactly one trip (or the expected
|
- **Trip boundary/replay:** after the inactivity timeout, verify exactly one trip (or the expected
|
||||||
number for deliberate ignition gaps), correct start/end time and coordinates, plausible
|
number for deliberate ignition gaps), correct start/end time and coordinates, plausible
|
||||||
distance/average/max speed, km/mi and km/h/mph values, route polyline, start/end markers, timeline
|
distance/average/max speed, km/mi and km/h/mph values, route polyline, start/end markers, timeline
|
||||||
scrubber, play/pause marker position, and stopped portions of the route.
|
scrubber, play/pause marker position, and stopped portions of the route. —
|
||||||
|
🟡 **PARTIAL / bug reported.** Local replay observed OK, but the server-side trip-splitting and
|
||||||
|
replay issues are tracked in **BUG-04** (server merges two trips) and **BUG-05** (server replay
|
||||||
|
`speed_source`), with **BUG-06** (timezone shift affecting times) also relevant.
|
||||||
- **Local web UI:** test the final Phase 23 interface on the actual phone over the Pi/phone network at
|
- **Local web UI:** test the final Phase 23 interface on the actual phone over the Pi/phone network at
|
||||||
`http://yaris.local/`; verify the explicit **In-car / Local Pi** identity, dashboard telemetry,
|
`http://yaris.local/`; verify the explicit **In-car / Local Pi** identity, dashboard telemetry,
|
||||||
DTC page, trip history, dashcam library, settings, alerts, responsive layout, reconnect behavior,
|
DTC page, trip history, dashcam library, settings, alerts, responsive layout, reconnect behavior,
|
||||||
and no new browser console/API errors.
|
and no new browser console/API errors. —
|
||||||
|
🟡 **PARTIAL / bug reported.** Reaching the UI over the Pi hotspot is blocked by `yaris.local`
|
||||||
|
not resolving on the phone → **BUG-01**. Other local UI pages work once reachable.
|
||||||
- **Dashcam workflow:** create a known short real clip, switch the camera safely into USB storage
|
- **Dashcam workflow:** create a known short real clip, switch the camera safely into USB storage
|
||||||
mode, detect/list it without confusing the OBD adapter, import only that selected file, verify
|
mode, detect/list it without confusing the OBD adapter, import only that selected file, verify
|
||||||
thumbnail/playback/Range seeking, preserve the source until checks finish, and confirm the camera
|
thumbnail/playback/Range seeking, preserve the source until checks finish, and confirm the camera
|
||||||
returns to recording afterward. Test deletion only with the disposable clip.
|
returns to recording afterward. Test deletion only with the disposable clip. —
|
||||||
|
⏳ **DEFERRED** (owner: "will test later stages"). Not yet exercised as part of this test; remains
|
||||||
|
a follow-up for the Phase 26 bug-fix/verification pass.
|
||||||
- **Alerts:** safely exercise conditions that can be simulated without damaging hardware (upload
|
- **Alerts:** safely exercise conditions that can be simulated without damaging hardware (upload
|
||||||
backlog, temporary GPS loss while OBD reports motion, and disposable threshold overrides).
|
backlog, temporary GPS loss while OBD reports motion, and disposable threshold overrides).
|
||||||
Confirm local bell transition/recovery/cooldown behavior and offline alert-state reconciliation
|
Confirm local bell transition/recovery/cooldown behavior and offline alert-state reconciliation
|
||||||
@@ -1771,12 +1808,31 @@ clean trip end:
|
|||||||
transport can reliably deliver ntfy notifications while WiFi/Ethernet is unavailable, including
|
transport can reliably deliver ntfy notifications while WiFi/Ethernet is unavailable, including
|
||||||
authentication, timeout, retry, and recovery. If that cannot be made reliable on the actual
|
authentication, timeout, retry, and recovery. If that cannot be made reliable on the actual
|
||||||
modem/network, remove the ntfy feature and its settings rather than retain a transport that fails
|
modem/network, remove the ntfy feature and its settings rather than retain a transport that fails
|
||||||
in the only situation where it is useful.
|
in the only situation where it is useful. —
|
||||||
|
🟡 **PARTIAL / done in part.** Owner reports alerts "seem to work for engine and DTC codes +
|
||||||
|
power". The SIM868 **ntfy path remains unverified** (no real SIM on the modem yet, so the
|
||||||
|
"determine whether the SIM868 transport can reliably deliver ntfy" sub-item is still open).
|
||||||
- **Power/reliability:** perform multiple normal ignition/power cycles, confirm automatic boot,
|
- **Power/reliability:** perform multiple normal ignition/power cycles, confirm automatic boot,
|
||||||
service/watchdog startup, SIM868 power-on, OBD/GPS recovery, no SQLite corruption, and no current
|
service/watchdog startup, SIM868 power-on, OBD/GPS recovery, no SQLite corruption, and no current
|
||||||
undervoltage/throttling. The deferred Phase 14 clean-shutdown limitation must be explicitly
|
undervoltage/throttling. The deferred Phase 14 clean-shutdown limitation must be explicitly
|
||||||
accepted or resolved with representative delayed-power/ignition-sense hardware before declaring
|
accepted or resolved with representative delayed-power/ignition-sense hardware before declaring
|
||||||
the design ready for permanent installation.
|
the design ready for permanent installation. —
|
||||||
|
🟡 **PARTIAL — Pi logs checked 2026-08-10 (at home, car not connected).** Verified from the live
|
||||||
|
Pi:
|
||||||
|
- `yaris-obd.service` **active**; uptime 2:48h with **no crash/restart** in the current boot
|
||||||
|
window (systemd auto-restart + the 10s hardware watchdog did not need to fire since startup).
|
||||||
|
- `vcgencmd get_throttled` → **`0x50000` = NO current undervoltage right now** (only the
|
||||||
|
historical "occurred" bits 0x40000/0x10000 remain set). Confirms the Pi is not *currently*
|
||||||
|
undervolting on whatever power is connected at home, but does not prove the in-car
|
||||||
|
cigarette-lighter source yet (re-check under load in the car after hard-wiring — see the open
|
||||||
|
power item above and BUG-02).
|
||||||
|
- OBD reconnect loop logging as designed ("handshake succeeded / ECU did not respond" = car not
|
||||||
|
on/not connected here). Uploads syncing fine ("sent N tracking rows").
|
||||||
|
- No SQLite corruption or tracebacks in the log tail.
|
||||||
|
**Still open**: a real multi-ignition-cycle verification *in the car* (boot recovery, watchdog
|
||||||
|
restart under power loss, OBD/GPS recovery, no corruption) with the final hard-wired power
|
||||||
|
source has not been demonstrated. The Phase 14 clean-shutdown limitation remains **accepted**
|
||||||
|
(delayed-power / ignition-sense hardware not yet present).
|
||||||
|
|
||||||
Verify the complete remote path after connectivity returns:
|
Verify the complete remote path after connectivity returns:
|
||||||
- Confirm every test-window tracking row uploads exactly once and the selected dashcam clip resumes
|
- Confirm every test-window tracking row uploads exactly once and the selected dashcam clip resumes
|
||||||
@@ -1786,9 +1842,12 @@ Verify the complete remote path after connectivity returns:
|
|||||||
vehicle-scoped trip summary/replay, route and timeline agreement with the local Pi, archived clip
|
vehicle-scoped trip summary/replay, route and timeline agreement with the local Pi, archived clip
|
||||||
thumbnail/playback/Range seeking/download, synchronized alert history/current state without
|
thumbnail/playback/Range seeking/download, synchronized alert history/current state without
|
||||||
duplicate transitions after an offline interval, and absence of local-only OBD/cellular/Pi
|
duplicate transitions after an offline interval, and absence of local-only OBD/cellular/Pi
|
||||||
controls.
|
controls. —
|
||||||
|
🟡 **PARTIAL.** Owner can connect to the remote server; the portal is reachable. The main
|
||||||
|
blocker is the **Pi hotspot** reachability issue (**BUG-01**), which affects exercising the
|
||||||
|
portal from the in-car phone. Server-side trip/replay/time issues (BUG-04/05/06) also remain.
|
||||||
- The Android companion is intentionally outside this core acceptance gate and remains the final,
|
- The Android companion is intentionally outside this core acceptance gate and remains the final,
|
||||||
low-priority Phase 26. Its own hotspot/cellular binding, trip display, and disposable clip relay
|
low-priority Phase 27. Its own hotspot/cellular binding, trip display, and disposable clip relay
|
||||||
require separate real-phone/in-car acceptance when that phase is implemented.
|
require separate real-phone/in-car acceptance when that phase is implemented.
|
||||||
|
|
||||||
Acceptance requires a written result for every item, captured negotiated protocol/PID support,
|
Acceptance requires a written result for every item, captured negotiated protocol/PID support,
|
||||||
@@ -1800,7 +1859,54 @@ phase roadmap.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 26: Native Android companion app — 🚧 PLANNED (low priority, always last)
|
### Phase 26: Road-test bug fixes — 🚧 PLANNED
|
||||||
|
**Renumbered/added 2026-08-10 after the Phase 25 owner road test.** This phase (the former Phase 26
|
||||||
|
Android slot, which is now **Phase 27**) is a targeted bug-fix pass for the defects surfaced by the
|
||||||
|
in-car road test. Each item references its tracking entry in `BUGS.md`; distinct fixes should be
|
||||||
|
committed individually with a `fix(bug-N): ...` prefix and each closed out in `BUGS.md` as it
|
||||||
|
lands. The current known issues from the road test (also recorded in `BUGS.md`):
|
||||||
|
|
||||||
|
1. **BUG-01 (WiFi/hotspot reachability).** While cell data is on, a phone connected to the Pi's
|
||||||
|
no-internet hotspot cannot load `yaris.local`, `10.42.0.1`, or the Pi's DHCP address at all —
|
||||||
|
the phone OS keeps cellular as the default route (Phase 11/22 "smart network switching"
|
||||||
|
behavior). It only works once the user disables cell data, then `http://<dhcp-ip>/` loads but
|
||||||
|
`yaris.local` and `10.42.0.1` still do not. Also: the live hotspot subnet is `10.112.0.x`, not
|
||||||
|
the documented `10.42.0.1`. Fix scope: make the documented/reachable address correct, surface
|
||||||
|
the real DHCP address in the Pi UI, document the cell-data behavior, and see if `yaris.local`
|
||||||
|
unicast fallback can be extended to the AP subnet.
|
||||||
|
2. **BUG-02 (micro-USB power port damaged).** Hardware-only (worn power connector). Action is
|
||||||
|
documentation + owner hard-wiring 5V/GND to the GPIO header pins; no code.
|
||||||
|
3. **BUG-03 (DTCs not persisted).** The SQLite `dtc` table is created but never written or read;
|
||||||
|
DTC codes/MIL live only in memory in `app_obd.py` and vanish on OBD disconnect/reboot.
|
||||||
|
`get_overview_stats` also queries a non-existent `dtc_codes` table. Fix: persist on each poll,
|
||||||
|
read back when disconnected, fix the stats query, add a "cleared/since" concept.
|
||||||
|
4. **BUG-04 (server merges two trips into one).** The Pi splits trips by *motion* (OBD wheel
|
||||||
|
speed + sustained GPS displacement, inactivity gap); the server splits only by *time gap* and
|
||||||
|
filters by duration. Parked idle tracking rows bridge two drives into one server-side trip.
|
||||||
|
Fix: mirror the Pi's motion-boundary logic server-side.
|
||||||
|
5. **BUG-05 (server replay speed_source).** Server `get_trip_route` hardcodes `speed_source: "gps"`
|
||||||
|
even when OBD speed is present (it already returns raw `speed`). Fix: mirror the Pi's
|
||||||
|
`obd if speed>0 else gps` logic.
|
||||||
|
6. **BUG-06 (server timezone is UTC-shifted).** `tracking_points.recorded_at` is `TIMESTAMPTZ`
|
||||||
|
but the Pi sends naive local (Montreal) time with no offset; Postgres (UTC container) treats
|
||||||
|
it as UTC, so server times/trip boundaries are off by the EDT offset. Fix: Pi sends
|
||||||
|
timezone-aware timestamps; server displays/stores in `America/Toronto`; optional one-time
|
||||||
|
migration to correct already-stored rows.
|
||||||
|
7. **BUG-07 (trip replay sometimes does nothing).** Intermittent `/history` replay failure —
|
||||||
|
needs reproduction/diagnostics (likely an API/DB race or map-not-ready timing). Add targeted
|
||||||
|
diagnostics before fixing.
|
||||||
|
8. **BUG-08 (no trip deletion on the local Pi).** The Pi's `components.html` `data_table` macro
|
||||||
|
lacks the `deletable` arg, `base.html` lacks `window.confirmDelete`, `history.js` hardcodes the
|
||||||
|
*server* delete endpoint, and there is no `DELETE /api/trip/<id>` route on the Pi. Fix: add all
|
||||||
|
four pieces and make the delete endpoint configurable in `history.js`.
|
||||||
|
|
||||||
|
**Acceptance for Phase 26:** every `BUGS.md` entry in scope is fixed, regression-tested, deployed,
|
||||||
|
marked resolved, and the corresponding fix recorded here.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 27: Native Android companion app — 🚧 PLANNED (low priority, always last)
|
||||||
|
**Renumbered from former Phase 26 on 2026-08-10 to make room for the road-test bug-fix phase.**
|
||||||
Revives the phone-relay goal (Phase 11/12) properly this time, using a real native app instead of
|
Revives the phone-relay goal (Phase 11/12) properly this time, using a real native app instead of
|
||||||
a web page - the only way to actually hold a WiFi connection to the Pi's hotspot and a cellular
|
a web page - the only way to actually hold a WiFi connection to the Pi's hotspot and a cellular
|
||||||
connection to the internet open simultaneously (`ConnectivityManager.bindProcessToNetwork()`,
|
connection to the internet open simultaneously (`ConnectivityManager.bindProcessToNetwork()`,
|
||||||
|
|||||||
@@ -197,7 +197,9 @@ rm db/sql/quoije_Yaris2013.db
|
|||||||
|
|
||||||
The build is now at the endgame stage: the Pi app, remote server, and device-management/sync work
|
The build is now at the endgame stage: the Pi app, remote server, and device-management/sync work
|
||||||
are implemented and verified on the real Pi/unraid setup. The remaining roadmap phases are the
|
are implemented and verified on the real Pi/unraid setup. The remaining roadmap phases are the
|
||||||
temporary real-vehicle acceptance test and the low-priority Android companion.
|
road-test bug-fix pass (Phase 26) and the low-priority Android companion (Phase 27). The owner has
|
||||||
|
already completed the Phase 25 real-vehicle test; the bugs it surfaced are tracked in
|
||||||
|
[BUGS.md](./BUGS.md).
|
||||||
|
|
||||||
- **Phases 1–23.5**: core Pi system — GPS, OBD, dashcam, trip history, web UI redesign, WiFi upgrade, cellular fallback, alerts, settings, upload
|
- **Phases 1–23.5**: core Pi system — GPS, OBD, dashcam, trip history, web UI redesign, WiFi upgrade, cellular fallback, alerts, settings, upload
|
||||||
- **Phase 24**: remote web portal at `https://yaris.ceaf.dev/` — login-protected, trip history with CARTO live map, dashcam archive, delete, overview stats
|
- **Phase 24**: remote web portal at `https://yaris.ceaf.dev/` — login-protected, trip history with CARTO live map, dashcam archive, delete, overview stats
|
||||||
@@ -213,8 +215,8 @@ temporary real-vehicle acceptance test and the low-priority Android companion.
|
|||||||
main remote overview/history/dashcam browsing views still follow one configured `DEVICE_NAME`
|
main remote overview/history/dashcam browsing views still follow one configured `DEVICE_NAME`
|
||||||
until a later portal-wide device selector/filter is added
|
until a later portal-wide device selector/filter is added
|
||||||
|
|
||||||
**Next**: Phase 25 — temporary real-vehicle test in the 2013 Yaris (see [PLAN.md](./PLAN.md) for
|
**Next**: Phase 26 — road-test bug fixes from the Phase 25 in-car test (see [BUGS.md](./BUGS.md)
|
||||||
the full acceptance checklist). Phase 26 (Android companion app) follows after that.
|
for the tracked issues). Phase 27 (Android companion app) follows after that.
|
||||||
|
|
||||||
Phase 14 is partially complete: the Pi's hardware watchdog is deployed and reboot-verified.
|
Phase 14 is partially complete: the Pi's hardware watchdog is deployed and reboot-verified.
|
||||||
Read-only-root storage hardening is deferred until persistent storage is moved off the SD root
|
Read-only-root storage hardening is deferred until persistent storage is moved off the SD root
|
||||||
@@ -222,7 +224,7 @@ partition, and clean shutdown still needs delayed-power or ignition-sense hardwa
|
|||||||
|
|
||||||
The browser-based phone relay was removed after real-world testing confirmed that mobile browsers
|
The browser-based phone relay was removed after real-world testing confirmed that mobile browsers
|
||||||
cannot reliably use the Pi's WiFi and cellular data simultaneously. A native Android companion is
|
cannot reliably use the Pi's WiFi and cellular data simultaneously. A native Android companion is
|
||||||
planned later instead (Phase 26).
|
planned later instead (Phase 27).
|
||||||
|
|
||||||
The local web UI includes a Settings page for safe runtime configuration: dashcam uploads,
|
The local web UI includes a Settings page for safe runtime configuration: dashcam uploads,
|
||||||
uploaded-video retention, cellular APN fallback, optional ntfy delivery, alert thresholds, local
|
uploaded-video retention, cellular APN fallback, optional ntfy delivery, alert thresholds, local
|
||||||
@@ -235,9 +237,10 @@ The Pi can also join a configured phone hotspot for outbound internet when no SI
|
|||||||
including trip synchronization and WiFi dashcam uploads, with automatic recovery to home WiFi or
|
including trip synchronization and WiFi dashcam uploads, with automatic recovery to home WiFi or
|
||||||
the Pi-hosted local hotspot.
|
the Pi-hosted local hotspot.
|
||||||
|
|
||||||
A temporary, removable real-vehicle compatibility test in the 2013 Yaris (Phase 25) precedes the
|
The Phase 25 real-vehicle compatibility test has been completed by the owner (road test). The
|
||||||
final low-priority Android phase (Phase 26). Permanent installation is owner-handled and is not a
|
bugs it surfaced are tracked in [BUGS.md](./BUGS.md) and scheduled for fixing in Phase 26. The
|
||||||
roadmap phase. Full phase history, verification notes, and current scope live in
|
final low-priority Android companion follows in Phase 27. Permanent installation is owner-handled
|
||||||
|
and is not a roadmap phase. Full phase history, verification notes, and current scope live in
|
||||||
[PLAN.md](./PLAN.md).
|
[PLAN.md](./PLAN.md).
|
||||||
|
|
||||||
## Diagnostics & recovery
|
## Diagnostics & recovery
|
||||||
|
|||||||
Reference in New Issue
Block a user