Commit Graph
298 Commits
Author SHA1 Message Date
Mathieu Moran 3916f9879e feat: FEAT-05 — DTC history sync to remote server
- 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
2026-08-12 01:23:23 -04:00
Mathieu Moran 13cb8b4361 docs: Phase 27 DONE (3 shipped) — odometer sync, trip ID, hotspot docs; FEAT-08 shipped, FEAT-09 wontfix 2026-08-12 01:16:53 -04:00
Mathieu Moran 22bbee3b30 feat: Phase 28.2 — dashcam video browser + WiFi download
- 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
2026-08-12 01:14:20 -04:00
Mathieu Moran 348bfdc48c feat: Phase 28.1 gate passed — dual-network test works
- 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
2026-08-12 01:09:13 -04:00
Mathieu Moran f1606ad1f6 fix: remove runBlocking(Dispatchers.Main) deadlock — app now starts
- 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
2026-08-12 00:54:27 -04:00
Mathieu Moran 40f92d8703 feat: Phase 28.1 — gradle wrapper + debug APK builds successfully
- gradlew + gradle-wrapper.jar (Gradle 8.11.1)
- Fixed manifest icon to @android:mipmap/sym_def_app_icon (no custom asset needed yet)
- Added adaptive icon XML + colors for future custom icon
- Removed deprecated buildfeatures.buildconfig from gradle.properties
- 17MB debug APK builds: ./gradlew assembleDebug
- local.properties auto-ignored (contains SDK path)
2026-08-12 00:48:05 -04:00
Mathieu Moran 8d64b1e8b0 feat: Phase 28.1.2 — dual-network binding + OkHttp clients
- NetworkBinder: discovers Pi hotspot WiFi (no-internet) and cellular networks
  via ConnectivityManager, creates per-network socket-bound OkHttpClients
- DualNetworkTestScreen: real OkHttp calls to 10.42.0.1/api/gps/status and
  yaris.ceaf.dev/health, simultaneous "Test Both" gate button
- MainActivity: discovers networks at startup, passes bound clients to screen
- Retrofit interfaces (PiApi, ServerApi) + DTOs (GpsStatus, HealthResponse)
- Uncommented OkHttp/Retrofit/kotlinx-serialization deps in build.gradle.kts
2026-08-12 00:34:41 -04:00
Mathieu Moran f1c83a2ee7 init: android project scaffold (Phase 28.1)
- Kotlin DSL build with version catalog (AGP 8.7, Kotlin 2.1, Compose BOM 2025.01)
- app module: Compose + Material 3, dark theme, network security config
- DualNetworkTestScreen — Phase 28.1 gate screen (buttons wired in 28.1.2)
- YarisApp, MainActivity, YarisOBDTheme
- ProGuard rules for Retrofit/OkHttp/Kotlinx Serialization/Coil/MapLibre/Room
- cleartext allowed for 10.42.0.1 + yaris.local
- gradle wrapper properties (needs Android Studio to generate wrapper jar)
2026-08-12 00:26:54 -04:00
Mathieu Moran 69109762a8 fix: always send device config on save — sync toggle now works both ways 2026-08-12 00:16:57 -04:00
Mathieu Moran 79222c8bb5 fix: disabling sync via settings page no longer returns spurious error 400 2026-08-12 00:02:54 -04:00
Mathieu Moran 0fea9718bc fix: prevent sync from overwriting Pi odometer — odometer is Pi→Server only 2026-08-11 23:53:42 -04:00
Mathieu Moran 0b2162a595 style: odometer field uses plaintext display — no stepper arrows, grey background 2026-08-11 23:44:05 -04:00
Mathieu Moran d35cea367f fix: odometer sync is Pi→Server only — portal displays read-only value from DB 2026-08-11 22:14:46 -04:00
Mathieu Moran 7de8948e08 docs: update Hardware and Architecture sections — dual-radio, GPIO power, 4G modem, phone hotspot uplink 2026-08-11 22:06:05 -04:00
Mathieu Moran 44cd8bd192 feat: odometer_baseline field on server portal device settings page 2026-08-11 19:52:51 -04:00
Mathieu Moran 32de77131c feat: odometer baseline syncs to server — push on save, pull on sync, +/api/device-config/push endpoint 2026-08-11 19:31:52 -04:00
Mathieu Moran 878ba4a958 fix: skip device config save when sync is enabled — prevents 'Invalid device config' blocking settings save 2026-08-11 18:57:40 -04:00
Mathieu Moran 34253b3ffb feat: manual odometer baseline — Settings field computes baseline + trip distance, Dashboard shows (manual) label 2026-08-11 18:51:11 -04:00
Mathieu Moran 887a001723 docs: Phase 27 started — 7 feature candidates ready 2026-08-11 18:40:35 -04:00
Mathieu Moran 19c538389b docs: Phase 26 rewritten — all 12 bugs documented consistently. Phase 27/28 cleaned up. 2026-08-11 18:29:03 -04:00
Mathieu Moran 9ebfea8be3 docs: readme updated, BUGS.md cleaned — all 12 bugs in Resolved, Open section empty 2026-08-11 18:25:07 -04:00
Mathieu Moran f017a301f3 docs: Phase 26 complete, Phase 27 ready — 7 feature candidates 2026-08-11 18:20:07 -04:00
Mathieu Moran 341437c2d4 docs: Phase 26 COMPLETE — BUG-02 closed, all 12 bugs resolved. GPS has 7 sats, needs clear sky for fix. 2026-08-11 18:17:31 -04:00
Mathieu Moran 0f6d9b20a2 docs: Phase 26 DONE — BUG-01 closed, all 11 bugs resolved. BUG-06/12 moved to Resolved. 2026-08-11 17:19:42 -04:00
Mathieu Moran e54391b5c9 docs: FEAT-06/07/08/09 — trip ID column, hotspot auto-connect, predictable IP, mDNS 2026-08-11 17:17:12 -04:00
Mathieu Moran 4704bb79f1 docs: BUG-01 test steps documented, FEAT-07 phone-hotspot auto-connect shipped 2026-08-11 17:11:34 -04:00
Mathieu Moran b4d622827a docs: revert BUG-01 — AP tested but phone-hotspot uplink not yet verified 2026-08-11 17:06:39 -04:00
Mathieu Moran ea47cff489 docs: BUG-01 closed — tested on iOS + Android, yaris.local resolves, Phase 26 DONE 2026-08-11 17:04:20 -04:00
Mathieu Moran 675ee67260 docs: revert BUG-01 to IN PROGRESS — needs owner test before closing 2026-08-11 16:47:58 -04:00
Mathieu Moran dc1c1e5f06 docs: BUG-01 closed — dual-radio bench-verified, Phase 26 DONE (11 closed, 1 hardware) 2026-08-11 16:46:57 -04:00
Mathieu Moran 0f76ae3f84 docs: Phase 26 updated — 10 closed, BUG-11/12 and GPS lat/lon fix documented 2026-08-11 16:43:06 -04:00
Mathieu Moran a4a92cc69b fix: Socket gps_location now passes lat/lon to renderGpsStatus, preventing overwrite with blanks 2026-08-11 16:37:01 -04:00
Mathieu Moran e8156bc39a docs: BUG-12 closed — OBD API fallback fixes dashboard blank state, GPS toFixed crash fixed 2026-08-11 16:32:15 -04:00
Mathieu Moran 91281b1e55 fix: add /api/obd/status endpoint, dashboard OBD fallback on page load, fix GPS string-to-number crash 2026-08-11 16:26:30 -04:00
Mathieu Moran e223a43170 docs: BUG-11 closed — GPS lat/lon from API, 30s staleness aligned across pages 2026-08-11 16:18:59 -04:00
Mathieu Moran 3202045654 fix: restore separate checkbox+ID cells, add matching headers (8 columns server) 2026-08-11 15:25:29 -04:00
Mathieu Moran e8c5bfec9a fix: put checkbox inside date cell — both Pi and server now share same 6-column layout 2026-08-11 15:22:05 -04:00
Mathieu Moran 22f4ae2e69 fix: merge ID into date cell, add empty checkbox header — columns now align 2026-08-11 15:17:51 -04:00
Mathieu Moran 5713417f4f Server: restore checkbox + batch-delete. Conditional ID (server only) and checkbox via data-show-id/data-batch-delete-url. 2026-08-11 15:11:12 -04:00
Mathieu Moran 2ee4862edd Remove checkbox column and batch-delete from trip history 2026-08-11 15:05:40 -04:00
Mathieu Moran 23ac6c218b feat: add trip ID column (#18517) to history table on Pi and server 2026-08-11 14:58:25 -04:00
Mathieu Moran f6a50b6bc1 docs: BUG-06 closed — migration shifted 3593 rows +4h EDT, recomputed 43 trips, times now correct 2026-08-11 14:53:18 -04:00
Mathieu Moran 7ce2a1e5f5 fix: BUG-06 — convert naive Pi timestamps to TZ-aware before upload so Postgres TIMESTAMPTZ stores correct instant 2026-08-11 14:47:37 -04:00
Mathieu Moran 9733036510 fix: BUG-11 — Dashboard GPS now shows lat/lon from API when stale, Status page uses same 30s staleness threshold 2026-08-11 14:36:58 -04:00
Mathieu Moran 7a6de8b589 docs: BUG-07 closed — history.js rewrite verified on Pi and server 2026-08-11 14:33:38 -04:00
Mathieu Moran fa93384a8e Rewrite history.js: loading spinner, active-row highlight, unified state, 300ms debounce, signal guards throughout trip loader 2026-08-11 05:37:15 -04:00
Mathieu Moran 3d6955f20f fix(phase26): fix broken click handler, remove replay button, row click only 2026-08-11 05:11:09 -04:00
Mathieu Moran 90edc73735 fix(phase26): debounce trip clicks, guard against stale renders 2026-08-11 05:07:35 -04:00
Mathieu Moran cdb3fc19c7 fix(phase26): abort preload fetches when switching trips to prevent server freeze 2026-08-11 05:01:18 -04:00
Mathieu Moran ad56380e23 fix(phase26): revert batch geocode, use rate-limited concurrent requests to avoid server freeze 2026-08-11 04:57:44 -04:00