- Create config/device.json with owner_name, car_model, device_name, avatar_path
- Update app_account.py to load owner_name and avatar_path from config
- Update app_car.py to load car_model and device_name from config
- Update base.html template to use avatar_path from config instead of hardcoded
- Add graceful fallback to hardcoded defaults if config file missing
- Document in deploy/readme.md and readme.md how to customize device identity
- Update PLAN.md Phase 25.5 to reflect current implementation and future server sync
Benefits:
- No code edits needed to customize Pi (edit JSON file only)
- Offline-first: all values loaded from local file at startup
- Connection-driven sync planned for Phase 25.5a (sync when internet available, not on timer)
- Server becomes source of truth after Phase 25.5a implementation
All 63 tests passing. Database filename still based on owner_name, with migration warning in docs.
Co-authored-by: Copilot <[email protected]>
- PLAN.md: Phase 23.5 documents all work from this session
- README: hardware table adds T3U, features add geocoding/offline maps/T3U, status updated
- pics/ui.png: desktop + mobile side-by-side screenshot (updated)
Co-authored-by: Copilot <[email protected]>
Phase 23 section updated with full list of changes from all polish passes:
Overview stats card, speed chart rework, mobile dashcam table fixes,
trip history mobile layout, notification badge fix, footer text.
README project status updated to reflect Phases 1-23 complete.
Co-authored-by: Copilot <[email protected]>
Prefer a configured phone hotspot for outbound synchronization, preserve secure write-only credentials, and recover through home WiFi or the local Pi hotspot.
Co-authored-by: Copilot <[email protected]>
Removes the phone-relay feature entirely per the Phase 11 finding
that it hit a fundamental phone-OS limitation (a browser page can't
route WiFi and cellular traffic simultaneously, no code fix possible)
- see PLAN.md for the full test writeup.
- app.py: dropped /api/dash/pending, /api/dash/file/<path>,
/api/dash/relay/config, /api/dash/relay/heartbeat,
/api/dash/relay/stop, /api/dash/relay/mark_uploaded routes and
their now-unused imports (os, send_file, abort, safe_join).
- modules/app_upload.py: dropped list_pending_dashcam_files(),
relay_heartbeat()/relay_stop()/is_relay_active(),
RELAY_LEASE_SECONDS/_relay_lease_until, and the relay-lease check
inside _upload_dashcam_files()/get_status(). Kept the chunked
upload protocol, dashcam_hash_cache/_hash_dashcam_file() (still
used by the Pi's own background uploader), and DASHCAM_CHUNK_SIZE -
none of that was relay-specific.
- templates/dash.html: removed the 'Relay via phone' card.
- static/js/dash.js: removed all relay JS (relayOneFile,
fetchChunkWithRetry, uploadChunkWithRetry, heartbeat timers,
pending-file list rendering).
- server/app.py: removed the CORS after_request hook, added solely
for the phone's cross-origin browser calls (the Pi's own Python
requests-based client was never subject to CORS).
- readme.md: dropped the phone-relay feature bullet, updated the
project-status blurb to explain the removal + point at the planned
native Android app as the real fix for that use case.
- PLAN.md: marked Phase 12 done with a verification writeup.
Verified: py_compile on all touched Python files, node --check on
dash.js, grepped all touched files for any leftover relay/RELAY
reference (none), and smoke-tested by importing app.py + hitting it
with Flask's test client - app starts cleanly, every relay route is
gone from url_map, and both / and /dash still render HTTP 200 with
zero 'relay' occurrences in /dash's HTML.
Co-authored-by: Copilot <[email protected]>
Retook pics/ui.png to show the current dashboard, including the
Dashcam nav item added in later phases. Also switched the readme's
image link from a hardcoded old-commit GitHub URL to a relative path
so it won't go stale again.
Co-authored-by: Copilot <[email protected]>
Root-caused the slow-upload complaint to the Pi's own congested 2.4GHz
WiFi radio (confirmed via iperf3 - same degraded throughput even on
pure local LAN traffic, ruling out Cloudflare/ISP). Since the Pi 3 B
has no 5GHz radio, add a way to bypass it for the internet-bound leg:
a phone opens /dash and manually relays pending dashcam files straight
to the remote server over its own network, reusing the exact same
chunked upload protocol the Pi's client already uses.
- server/app.py: add CORS headers (after_request) so the phone's
browser can call the remote server cross-origin from a page served
by the Pi.
- app.py: new endpoints - GET /api/dash/pending (list not-yet-uploaded
files), GET /api/dash/file/<path> (Range-request-capable download,
path-traversal safe), GET /api/dash/relay/config (hands the phone
the device credentials), POST /api/dash/relay/heartbeat|stop (lease-
based pause of the Pi's own background uploader, self-heals if the
phone's tab closes uncleanly), POST /api/dash/relay/mark_uploaded.
- modules/app_upload.py: list_pending_dashcam_files(), relay lease
helpers, _upload_dashcam_files() now pauses while a relay lease is
active.
- modules/app_sql.py: new dashcam_hash_cache table so a file's sha256
is only computed once (keyed by path+size+mtime) instead of being
recomputed on every loop iteration/pending-list call - benefits the
existing background uploader too.
- templates/dash.html / static/js/dash.js: new "Relay via phone" card
- per-file and "relay all" buttons (manual trigger only, per user
preference), downloads+uploads one 40MB slice at a time so the
phone never holds a whole file in memory, retries chunks up to 3x.
- PLAN.md/readme.md/server/README.md updated (Phase 11).
Tested via a full local end-to-end simulation driving the real Pi and
server Flask apps side by side (Postgres mocked only at the db module
boundary - all HTTP/chunking/auth/CORS logic is real): verified Range
downloads (206), byte-for-byte reassembly via SHA256, path-traversal
rejection, and the relay lease correctly pausing/resuming the
background uploader. Not yet tested against a real phone/live network.
- PLAN.md: mark Phase 8 (dashcam retrieval) verified on real hardware, add
Phase 10 documenting the OOM/multipart and Cloudflare body-size fixes plus
the chunked/resumable upload redesign, both verified end-to-end against
real dashcam footage. Update architecture decision #3 (Mongo -> Postgres
supersession), add unraid/Pi deploy notes and memory-budget gotcha.
- readme.md: refresh feature list (remote upload, chunked dashcam uploads,
toggle) and project status (all 10 phases done, only cellular fallback
untested).
- server/README.md: document the new chunked upload endpoints and the
Cloudflare body-size-limit rationale behind them.
Squashed rewrite of the project revival work (replaces prior history on this
branch to remove personal data that had been accidentally committed - real
LAN IP, GPS coordinates, home WiFi SSID, and phone model). See PLAN.md for
full phase-by-phase details. Summary:
- Phase 2: adapt app_obd.py for a USB OBD-II adapter (was Bluetooth-only),
auto-detect /dev/ttyUSB*, fix several pre-existing crash bugs.
- Phase 3/4: make the web UI work fully offline (vendored Socket.IO/Leaflet/
Chart.js/FontAwesome, offline map tile downloader script, live GPS marker
tracking fix).
- Phase 5: systemd deployment/autostart on the Pi.
- Phase 6: WiFi hotspot mode via NetworkManager (auto-switch between home
WiFi and a local AP for in-car web UI access), mDNS hostname + port 80
redirect so the UI is reachable at a plain hostname with no port number.
- Phase 7: fix app_db.py/app_sql.py bugs, wire up local SQLite trip logging.
- Phase 8: brand-agnostic USB dashcam file retrieval (lsblk transport-based
detection, works with any dashcam brand/folder layout).
- Rewritten readme.md with a proper project overview.
Co-authored-by: Copilot <[email protected]>