10 KiB
yaris-obd Feature Requests
Ideas and requests for new features (distinct from bugs, which belong in BUGS.md, and the
phase-by-phase implementation history in PLAN.md). Use this file to record anything that should
be built eventually but isn't an active roadmap phase yet. When a feature gets picked up, create a
dedicated PLAN.md phase (or fold it into the relevant existing work) and mark it here.
How to use this file
- One
## FEAT-XXsection per idea. Keep numbering sequential. - Status field:
IDEA(brainstormed, not planned) →PLANNED(has an assigned phase) →IN PROGRESS→SHIPPED(deployed + verified) orWONTFIX/SUPERSEDEDas appropriate. - Relate to roadmap: when a feature lands in a phase, note the phase here and drop a link back here from PLAN.md so the two stay in sync.
- Keep each entry small and one-idea-per-entry so it's easy to pick up and scope.
Feature ideas
FEAT-01 — Parallel/concurrent chunked dashcam uploads
- Status:
IDEA - Area:
modules/app_upload.py(Pi upload client) - Phase: Phase 27
- Requested: noted in Phase 10 of PLAN.md as a possible future optimization; not yet requested explicitly by the owner.
- Idea: upload multiple dashcam chunks (and/or multiple files) concurrently instead of the current strictly sequential one-chunk-then-one-file at a time. Would speed up the multi-hour full-backlog drain of a large local dashcam archive, at the cost of more complexity (bounded concurrency, per-file state, failure handling for the individual concurrent workers).
- Outstanding considerations: memory budget on the Pi (~900MB, no swap — must stay streaming), and whether the sequential pace is actually annoying enough in practice to justify the added complexity.
FEAT-02 — QR / claim-code device pairing flow
- Status:
IDEA - Area: server device provisioning + Pi credential setup (Phase 25.5c)
- Phase: Phase 27
- Requested: discussed in Phase 25.5c as a possible follow-up to the manual copy/paste API-key provisioning.
- Idea: zero-manual-copy provisioning of
YARIS_SERVER_URL/YARIS_DEVICE_NAME/YARIS_API_KEYonto the Pi — e.g. the portal shows a short-lived claim code / QR that the Pi app (or owner) enters/scans once to adopt the device, instead of typing credentials by hand. - Outstanding considerations: bigger scope than the current copy/paste flow; ship copy/paste first, add pairing only if provisioning still feels annoying.
FEAT-03 — Manual start odometer fallback when OBD odometer is unavailable
- Status:
IDEA - Area: Settings page / odometer display (Pi
app_settings,/api/stats, trip odometer) - Phase: Phase 27
- Requested: owner — the 2013 Yaris's ECU is (as expected) NOT exposing OBD PID 0xA6 odometer (see Phase 24.6), so the odometer reads nothing.
- Idea: allow the owner to enter the vehicle's current odometer reading once in the Settings
page; the app then computes a rolling odometer by adding subsequent trip distances
(from
tripstable cumulative distance) to that entered baseline, instead of relying on the unavailable OBD odometer PID. - Outstanding considerations: what happens when the user's entered value comes from the car's instrument cluster vs the OBD one being absent — this would be the only odometer source in that case; needs a clear "this is a manual baseline" indicator in the UI so it's not mistaken for a live OBD reading; decide whether it should also sync to the remote device config (Phase 25.5) or stay local.
FEAT-04 — Replace SIM868 2G GSM hat with 4G LTE modem (Huawei E3372h-153)
- Status:
IDEA - Area: modems / uplink (Pi
modules/app_cellular.py,modules/app_gps.py, uplink switching) — replaces the current SIM868 GSM/GNSS HAT + cellular fallback path - Phase: Phase 27
- Requested: owner — just purchased a Huawei E3372h-153 4G LTE Modem. The 2G/3G-only SIM868 hat will not work in Canada (2G networks are decommissioned), so the plan is to make the 4G modem the working cellular uplink instead.
- Idea: integrate the Huawei E3372h-153 as the primary cellular data uplink, replacing reliance on the SIM868's GSM (AT+HTTP) path. The E3372h-153 is a USB "stick" modem — likely supported via Realtek / cdc_ether / usb-storage based drivers and exposes a dial-up or LTE dongle interface the Pi can use for connectivity (e.g. via NetworkManager / ModemManager, or a static APN config).
- Outstanding considerations:
- Determine the E3372h-153's local mode vs stick/dial mode and the correct Linux driver/interface (hierarchical USB mode switching may be needed; it's the "153" variant which may use the RNDIS / ECM / CDC-NCM profile).
- Whether to run it as the primary uplink or just another option in the existing phone-hotspot / home-wifi / local-AP priority chain.
- What happens to the SIM868 — keep it purely for its GPS/GNSS role (it's the PWRKEY-toggled
GNSS receiver on
/dev/serial0) while dropping its 2G GSM cellular path, vs removing it entirely. - The SIM868's
app_gps.pyGNSS positioning must keep working (it's the car's GPS source) even if the 2G-modem half is retired — separate the two concerns. - Keep this feature as-is (2G/GSM fallback) for countries where 2G/3G still works — don't remove the existing cellular fallback code; gate it so the 2G path remains available there.
- LTE SIM plan/APN specifics for Canadian carriers (Rogers/Bell/Telus) and whether the modem can
run the Pi's hotspot/SSID the same way
app_network.pycurrently does.
FEAT-05 — DTC history synced to remote server with code descriptions
-
Status:
IDEA -
Area:
modules/app_upload.py,modules/app_sql.py,server/sql/,server/modules/db.py,server/app.py, server portal templates -
Phase: Phase 27
-
Requested: 2026-08-11 — owner wants DTC codes persisted to the server (not just local SQLite) with code + description, surviving until user deletes them or OBD reports the code cleared.
-
Current state (2026-08-11):
- Pi:
app_obd.pypolls DTCs from ECU →app_sql.save_dtc_state()persists MIL + codes (code, description, IS_SET, FIRST_SEEN_AT, LAST_SEEN_AT) to local SQLitedtctable. - Pi:
app_upload.pyuploads tracking rows and dashcam files — NO DTC upload path exists. - Server: NO
dtc_eventstable, NO DTC API, NO portal DTC page.
- Pi:
-
Design:
Server schema (
server/sql/migrate_phase26_dtc.sql):CREATE TABLE IF NOT EXISTS dtc_events ( id SERIAL PRIMARY KEY, device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE, code VARCHAR(10) NOT NULL, description TEXT NOT NULL DEFAULT '', mil_on BOOLEAN NOT NULL DEFAULT FALSE, is_active BOOLEAN NOT NULL DEFAULT TRUE, first_seen_at TIMESTAMPTZ NOT NULL DEFAULT now(), last_seen_at TIMESTAMPTZ NOT NULL DEFAULT now(), cleared_at TIMESTAMPTZ, UNIQUE (device_id, code) );Server API (
server/app.py):POST /api/v1/dtc/batch(device auth): receives current DTC snapshot from Pi. Body:{"mil_on": true/false, "codes": [{"code": "P0301", "description": "Cylinder 1 Misfire"}, ...]}- Insert new codes, update
last_seen_atfor existing active codes. - Mark any previously-active codes NOT in this batch as
is_active=false, cleared_at=now(). - Return
{received: N, cleared: M, unchanged: K}.
- Insert new codes, update
GET /api/v1/portal/dtc(user auth): list all DTC events for configured device.DELETE /api/v1/portal/dtc/<id>(user auth): manual deletion.
Server portal: new DTC page or section showing code, description, MIL state, first/last seen, active/cleared status, cleared timestamp.
Pi upload (
modules/app_upload.py):- New
_upload_dtc_snapshot()— called after tracking batch in_upload_loop(). - Only uploads when the local DTC snapshot differs from last-uploaded (hash or version compare).
- Reuses same
_credentials()/_headers()as tracking uploads. - Same WiFi-first, cellular-fallback (if configured) path as tracking batches.
-
Deduplication logic: server-side per
(device_id, code)unique key. Pi sends the full current snapshot each time. Server diffs: new codes = insert, existing = touch last_seen_at, missing from snapshot = mark cleared. This means if a code disappears from the ECU, it auto-clears on the server on the next upload — no manual "clear" step needed. -
Manual deletion: only via the server portal delete button. Cleared codes stay visible as history. The Pi never deletes from the server automatically.
-
Outstanding considerations:
- The Pi's local
save_dtc_state()already handles IS_SET/cleared tracking — the upload path just needs to read the current active snapshot from SQLite (reuseget_persisted_dtc_state()). - DTC descriptions come directly from the ECU (python-obd's
GET_DTCresponse) — they're the standard SAE J2012 descriptions, no external lookup needed. - Should we upload on every poll (every ~2s OBD cycle) or batch? Answer: batch. Upload alongside tracking batches (every 30s idle, 1s catchup). DTCs don't change mid-drive that often.
- First upload after Pi reboot with no OBD connected: snapshot is empty → server marks all
previously-active codes as cleared. Is that desired? Probably not — should skip upload when
OBD is disconnected/unavailable (the Pi already knows this from
connectionstate).
- The Pi's local
Ideas that landed
(No entries yet — shipped features land here. Keep the original idea text intact and add the shipped phase/date.)
FEAT-07 — Phone-hotspot auto-connect documentation
- Status:
SHIPPED2026-08-11 (already implemented in Phase 22, documented here) - Area:
deploy/yaris_uplink.py, Settings page, netwatch timer - What: The Pi auto-connects to a saved phone hotspot on wlan1 within ~60s of it appearing in range, and falls back to home-wifi when it disappears. The wlan0 AP stays up regardless. Test flow: Settings → save hotspot name + password → "Wait for hotspot" → enable phone hotspot → verify mode changes to "Phone hotspot".