- 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]>
154 lines
8.8 KiB
Markdown
154 lines
8.8 KiB
Markdown
# yaris-obd 🚗📡
|
||
|
||
A Raspberry Pi 3-based OBD-II, GPS, and dashcam system for my 2013 Toyota Yaris. It reads live
|
||
vehicle data over USB, tracks position with a SIM868 GNSS/GSM HAT, logs everything locally, and
|
||
serves a web UI over the car's own WiFi hotspot. The dashboard and pre-cached map work fully
|
||
offline, while trip data and dashcam footage sync to a self-hosted remote server whenever an
|
||
internet uplink is available.
|
||
|
||
<table>
|
||
<tr>
|
||
<td width="120">
|
||
<a href="https://open.spotify.com/playlist/5u9vSw39FrIz7KghBkmgH4">
|
||
<img src="https://image-cdn-fa.spotifycdn.com/image/ab67706c0000d72c979ac180a23a70139d1ebd81" width="100" />
|
||
</a>
|
||
</td>
|
||
<td>
|
||
|
||
**rené lévesque bangers**
|
||
i have a dream
|
||
|
||
[](https://open.spotify.com/playlist/5u9vSw39FrIz7KghBkmgH4)
|
||
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
## Screenshots
|
||
|
||
Dashboard — mobile (390 px) and desktop (1280 px):
|
||
|
||

|
||
|
||
## Features
|
||
|
||
- 📊 **Live OBD-II data** over a cheap USB ELM327-compatible adapter: speed, RPM, coolant
|
||
temperature, fuel level, throttle position, MIL status, stored DTCs, and odometer when the ECU
|
||
supports it. Includes automatic background reconnects, serialized queries, and clear
|
||
adapter/ELM327/ECU diagnostics
|
||
- 🛰️ **Real GPS tracking** via a Waveshare SIM868 GNSS/GSM/Bluetooth HAT, plotted live on an
|
||
offline Leaflet map (pre-cached map tiles — no internet needed in the car). The module powers
|
||
itself on through the HAT's GPIO PWRKEY wiring after a Pi power cycle
|
||
- 📶 **Self-hosted WiFi hotspot** so you can load the web UI on your phone from inside the car,
|
||
with automatic switching back to home WiFi when it is available (`http://yaris.local` — no
|
||
port number)
|
||
- 🎥 **Dashcam file retrieval** — detects a USB dashcam automatically (any brand/folder layout,
|
||
no hardcoded device path), mounts it read-only, and safely copies footage locally. Verified
|
||
against a real 28GB/87-file import. The web UI can also browse, sort, and delete individual or
|
||
all videos directly from the connected dashcam with confirmed, temporary read-write operations,
|
||
plus import one file or any checkbox selection instead of always importing the whole card
|
||
- ▶️ **Local video library** — browse imported clips with cached thumbnails and upload status,
|
||
play H.264 footage inline with seeking, and delete only the local Pi copy. Optional retention
|
||
can automatically remove older local copies after their exact content is confirmed uploaded
|
||
- ☁️ **Remote upload** — a self-hosted server (Flask + Postgres, `server/`) receives trip/GPS
|
||
logs and dashcam footage over the internet (via Cloudflare Tunnel or a plain port-forward).
|
||
Dashcam videos upload in resumable 40MB chunks (works around tunnel body-size limits and keeps
|
||
the Pi's memory footprint flat regardless of file size); a UI toggle can pause dashcam uploads
|
||
independently while trip logs keep syncing
|
||
- 📡 **Optional cellular fallback** through the SIM868 for small trip-log uploads when normal
|
||
WiFi/Ethernet is unavailable (dashcam video stays off cellular)
|
||
- 🗄️ **Motion-aware local-first SQLite logging** — five-second motion checks without five-second
|
||
parked writes, plus retry-safe remote sync and automatic backoff
|
||
- 🌡️ **Pi health monitoring** — dashboard temperature, RAM, disk space, uptime, and explicit
|
||
undervoltage/throttling warnings from the Raspberry Pi firmware
|
||
- 🔔 **Offline-first alerts** — a notification bell on every page reports check-engine state,
|
||
storage pressure, upload backlog, temperature/power faults, and GPS loss while moving. Optional
|
||
ntfy delivery is available but remains disabled until configured
|
||
- 🛣️ **Trip history and route replay** — detects motion from OBD wheel speed with sustained GPS
|
||
displacement as a fallback, summarizes distance and speed in metric units (km / km/h), and replays
|
||
each route as a line on the offline map with a timestamped play/pause timeline, moving marker, and
|
||
live reverse-geocoded location name during scrubbing. Tap any trip row on mobile to load the route
|
||
- 🗺️ **Offline reverse geocoding** — a `/api/geocode` route on the Pi uses the `reverse_geocoder`
|
||
library (20 MB world dataset, no internet needed) for city/region, and upgrades to Nominatim
|
||
street-level when an internet uplink is available. Results are LRU-cached in-process. The browser
|
||
never calls any external geocoding service
|
||
- 🖥️ **Offline web UI** built with Flask, Jinja, Bootstrap 5, Socket.IO, Chart.js, and Leaflet,
|
||
all served locally with a shared responsive page shell
|
||
- 🔌 **Headless Pi deployment** as a self-restarting `systemd` service with a 10-second BCM2835
|
||
hardware watchdog, verified across a real reboot
|
||
|
||
## Hardware
|
||
|
||
| Part | Notes |
|
||
| --- | --- |
|
||
| Raspberry Pi 3 Model B Rev 1.2 | Web UI host, logger, uploader, and WiFi hotspot |
|
||
| Waveshare SIM868 HAT | GNSS (GPS) + optional GSM/GPRS uplink, unused Bluetooth |
|
||
| USB OBD-II adapter | PL2303-based, ELM327-compatible (originally Bluetooth, switched to USB) |
|
||
| TP-Link Archer T3U (RTL8812BU) | USB WiFi dongle — AC1300 dual-band, replaces onboard wlan0 for hotspot + uplink |
|
||
| USB dashcam | Any brand — detected as generic USB mass storage |
|
||
| 2013 Toyota Yaris | The patient |
|
||
|
||
See [PLAN.md](./PLAN.md) for full hardware bring-up notes (SIM868 jumper/UART setup, antenna
|
||
gotchas, etc.) and the detailed project history.
|
||
|
||
## Getting started
|
||
|
||
```bash
|
||
python3 -m venv venv
|
||
source venv/bin/activate
|
||
pip install -r requirements.txt
|
||
python3 app.py
|
||
```
|
||
|
||
The app serves on `http://<host>:5000`. On the Pi it runs as a `systemd` service and is reachable
|
||
with no port number at `http://yaris.local` after installing the mDNS and port-redirect setup.
|
||
Deployment helpers for the app service, hotspot watcher, port redirect, and hardware watchdog are
|
||
in [deploy/](./deploy); see [PLAN.md](./PLAN.md) for the complete Pi setup and hardware notes.
|
||
|
||
For the remote server (receives trip logs + dashcam uploads), see [server/README.md](./server/README.md).
|
||
|
||
## Project status
|
||
|
||
Phases 1–13, 15–23, and 23.5 are complete. The full responsive web UI redesign (Phase 23) is done,
|
||
followed by a major polish and hardware upgrade pass (Phase 23.5):
|
||
|
||
- **Async dashcam import** with progress polling — no more mobile timeouts
|
||
- **Per-file Convert button** with real ffmpeg progress (reads `out_time_ms` via `-progress pipe:1`)
|
||
- **Odometer tracking** from OBD in every trip row and the overview dashboard
|
||
- **Separate upload toggles** for trips/logs vs dashcam videos
|
||
- **Download button** on Pi video files
|
||
- **Offline reverse geocoding** — `/api/geocode` route on the Pi uses `reverse_geocoder` (20 MB,
|
||
no internet needed); falls back to Nominatim for street-level accuracy when online. Browser never
|
||
calls any external service
|
||
- **Live location name** on dashboard GPS card (updates every ~50 m) and trip scrubber timeline
|
||
- **Recenter button** on dashboard and history maps
|
||
- **Imperial units removed** — metric only (km / km/h)
|
||
- **Mobile trip replay** — tap any trip row to load the route; Replay button kept on desktop only
|
||
- **TP-Link Archer T3U WiFi dongle** — RTL8812BU DKMS driver installed; all WiFi traffic moved to
|
||
`wlan1` (AC1300, dual-band). `wlan0` onboard stays silent as automatic fallback if dongle is
|
||
absent. Consistent phone-hotspot IP via `dhcp-client-id`
|
||
|
||
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
|
||
partition, and clean shutdown still needs delayed-power or ignition-sense hardware.
|
||
|
||
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
|
||
planned later instead.
|
||
|
||
The local Web UI includes a Settings page for safe runtime configuration: dashcam uploads,
|
||
uploaded-video retention, cellular APN fallback, optional ntfy delivery, and alert thresholds.
|
||
Notification secrets are write-only in the browser API, and network credentials that could lock
|
||
the Pi out remain SSH/file-managed. When cellular is configured, small ntfy notifications use the
|
||
SIM868 first and WiFi/Ethernet only as fallback; that modem path is implemented and mock-tested but
|
||
still needs real-SIM/carrier verification.
|
||
|
||
The Pi can also join a configured phone hotspot for outbound internet when no SIM is available,
|
||
including trip synchronization and WiFi dashcam uploads, with automatic recovery to home WiFi or
|
||
the Pi-hosted local hotspot.
|
||
|
||
A temporary, removable real-vehicle compatibility test in the 2013 Yaris (Phase 25) precedes the
|
||
final low-priority Android phase (Phase 26). 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).
|