- Server: dtc_events table (migrate_phase27_dtc.sql), db.py helpers
(upsert_dtc_snapshot, list_dtc_events, delete_dtc_event)
- Server API: POST /api/v1/dtc/batch (device auth), GET/DELETE /api/v1/portal/dtc
- Server portal: /dtc page with code, description, MIL, status, timestamps, delete
- Server nav: DTC history in sidebar + mobile bottom nav
- Pi: _upload_dtc_snapshot() in app_upload.py — uploads when snapshot changes,
skips when OBD disconnected or unchanged
- DashcamScreen: LazyColumn of imported Pi videos with thumbnails (Coil),
file size, date, upload status, converting progress
- DashcamViewModel: Retrofit-backed video list + download to phone storage
+ delete local copy
- PiApi extended: listVideos, getVideoFile (streaming), getThumbnail, deleteVideo
- DTOs: VideoListResponse, VideoFile, ConvertProgress
- Bottom nav: Dashcam tab + Test tab
- Verified: video list loads from real Pi over yaris 911 hotspot
- Simplified to single OkHttpClient — Android OS routes correctly:
10.42.0.1 → WiFi (Pi hotspot subnet)
yaris.ceaf.dev → cellular (WiFi has no internet)
- Removed NetworkBinder-based per-socket binding (EPERM on Pixel,
OS-routed approach works better for this use case)
- Verified on real Pixel: Pi GPS + server health both return 200
simultaneously while connected to "yaris 911" hotspot
- NetworkBinder functions were suspend but never actually suspended
(ConnectivityManager calls are synchronous) — made them plain fun
- MainActivity.discoverNetworks() now calls them directly, no coroutine
- Wrapped in try/catch so network discovery failure doesn't crash Activity
- Removed unused awaitNetwork() extension + coroutine imports
Amend the Phase 26 progress note: BUG-03 was deployed to the Pi (pulled to
4f975ad, service active, /api/health ok) and real in-car behavior verification
is still pending; BUG-05 is code-ready but the unraid/server side is not yet
deployed (needs docker compose build api && docker compose up -d api).
BUG-03: DTC/MIL codes were never persisted; lost on OBD disconnect or reboot.
- Add new dtc table schema (code, description, MIL, first/last seen, IS_SET)
and a migration that rebuilds the original unused NAME/STATUS/DTC_ID table.
- Persist MIL + codes to SQLite on each successful OBD poll (_persist_dtc_state).
- /api/dtc falls back to the last-persisted snapshot when OBD is offline/stale.
- Fix get_overview_stats to count the real dtc table (was querying non-existent
dtc_codes table).
- Add cleared/since tracking via IS_SET + FIRST_SEEN_AT/LAST_SEEN_AT.
BUG-05: server trip replay hardcoded speed_source:'gps'; mirror Pi's
'obd if speed>0 else gps' logic in server get_trip_route.
Adds tests/test_dtc_persistence.py (7 tests).
- note that GPS thread is alive on the Pi but has no current fix
- clarify that missing live updates are currently due to absent GNSS fix data
Co-authored-by: Copilot <[email protected]>
- add /api/gps/status for thread/fix-age visibility
- surface GPS status in Pi health and live GPS cards
- add tests for app_gps status snapshots
Co-authored-by: Copilot <[email protected]>
- add portal API and UI action to delete non-default devices
- protect the configured portal default device from deletion
- document that trip/history pages still scope to the single DEVICE_NAME
Co-authored-by: Copilot <[email protected]>
- mark Phase 25.5c complete in PLAN
- record unraid migration/deploy and Pi API smoke tests
- note sync-ack metadata and temp provisioning helper validation
Co-authored-by: Copilot <[email protected]>
- add multi-device portal device management, key rotation, and sync request APIs
- add Pi settings UI for remote server URL, device name, and API key
- add local test-connection and sync-now actions
- make upload and config sync reuse dynamic shared credentials
- add Phase 25.5c migration and docs updates
Co-authored-by: Copilot <[email protected]>
- update plan with live portal route deployment status
- document fixed Pi sync blockers and successful round-trip test
- refresh passing test count after runtime sync coverage additions
Co-authored-by: Copilot <[email protected]>
- load server sync creds from db/upload_creds.env like uploads do
- fall back from YARIS_DEVICE_KEY to existing YARIS_API_KEY
- document shared credential flow for server-synced identity
- add test coverage for sync credential fallback
Co-authored-by: Copilot <[email protected]>
- use app_network status for device sync connectivity checks
- mount migrate_phase25_5a.sql in server docker compose
- document manual server upgrade migration steps
- record verified Pi and unraid SSH access details in PLAN
Co-authored-by: Copilot <[email protected]>
- Created app_device_sync.py: background sync thread with connectivity-driven scheduling (5min online, 60sec backoff when offline)
- Server /api/device-config endpoints: GET for Pi device auth, POST for admin user auth
- Database migration adds config_version, owner_name, car_model, device_name, avatar_path to devices table
- Pi syncs config from server on network availability; offline-first design (loads from local JSON at startup)
- Settings UI fields read-only when server sync enabled
All 63 tests passing. Ready for testing with actual server connection.
Co-authored-by: Copilot <[email protected]>