# yaris-obd A Raspberry Pi 3-based OBD-II, GPS, and dashcam system for a 2013 Toyota Yaris. 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.
**rené lévesque bangers** i have a dream [![Listen on Spotify](https://img.shields.io/badge/Listen_on-Spotify-1DB954?style=for-the-badge&logo=spotify&logoColor=white)](https://open.spotify.com/playlist/5u9vSw39FrIz7KghBkmgH4)
## Screenshots Dashboard — mobile (390 px) and desktop (1280 px): ![Mobile and desktop dashboard](pics/ui.png) ## Features - **Live OBD-II data** — speed, RPM, coolant temp, fuel level, throttle, MIL/DTC via USB ELM327. Automatic reconnects with clear adapter/ECU diagnostics. DTC codes persist across reboots. - **Real GPS tracking** — Waveshare SIM868 GNSS HAT with GPIO PWRKEY auto-power-on. Live position plotted on an offline Leaflet map (pre-cached tiles, no internet needed). - **WiFi hotspot** — auto-switches between home WiFi and a self-hosted AP for in-car phone access at `http://yaris.local` (no port number). Phone hotspot uplink supported for on-the-road sync. - **Dashcam workflow** — auto-detects any USB dashcam, mounts read-only, browses files before importing. Import one, selected, or all files. Delete individual or all files directly from the dashcam. Verified against real 28GB/87-file hardware. - **Local video library** — browse imported clips with cached thumbnails and upload status. Inline H.264 playback with seeking. Local-only delete. Optional auto-retention after confirmed upload. - **Remote sync** — trip logs and dashcam footage upload to a self-hosted Flask + Postgres server. Dashcam videos stream in resumable 40MB chunks. Independent toggles for trip and dashcam uploads. - **Remote web portal** — login-protected at the server URL. Trip history with CARTO live map and route replay, dashcam archive with inline player, overview stats, device management (create/delete/rotate keys), and server-side device identity sync that hot-reloads on the Pi. - **Trip history and replay** — motion-aware detection (OBD wheel speed primary, GPS displacement fallback). Metric summaries, offline route polyline, play/pause timeline with moving marker and live reverse-geocoded location names. Tap-to-replay on mobile. - **Status page** — Pi health (temp, RAM, disk, uptime, throttling), service states, uplink/server/ GPS/OBD diagnostics, and quick actions (test server, sync now, reconnect uplink, restart app). - **Offline-first alerts** — notification bell on every page for check-engine, storage pressure, upload backlog, temperature/power faults, and GPS loss while moving. Optional ntfy push. - **Reverse geocoding** — `/api/geocode` uses `reverse_geocoder` offline (no internet needed), upgrades to Nominatim street-level when online. LRU-cached. Results pre-loaded for trip scrubbing. - **Offline web UI** — Flask, Bootstrap 5, Socket.IO, Chart.js, Leaflet. All assets served locally. Responsive with collapsible sidebar and mobile bottom nav. - **Headless deployment** — systemd service with auto-restart, 10-second hardware watchdog, and nftables port-80 redirect. Deploy scripts in `deploy/`. ## 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://: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). For a clean-install walkthrough on a fresh Pi, use [deploy/readme.md](./deploy/readme.md). See [PLAN.md](./PLAN.md) for the full hardware/project history. For the remote server (receives trip logs + dashcam uploads), see [server/README.md](./server/README.md). ## Customizing device identity The Pi displays an owner name, car model, device name, and avatar. You can manage those values in two ways: - **Locally on the Pi** through the Settings page - **From the server portal** when **Sync with server** is enabled on the Pi The local fallback/default source remains [config/device.json](./config/device.json), so the car still boots with sensible identity values even when fully offline. ### Edit device configuration Edit [config/device.json](./config/device.json): ```json { "owner_name": "quoije", "car_model": "Yaris 2013", "device_name": "Yaris OBD", "avatar_path": "img/yaris.png" } ``` | Field | Location | Purpose | |-------|----------|---------| | `owner_name` | Top-right of app topbar | Your name/username | | `car_model` | Left sidebar (next to car icon) | Vehicle model/year | | `device_name` | Local settings / remote portal | Device identity used by server sync/provisioning | | `avatar_path` | Top-right avatar circle | Profile picture (relative to `static/`) | If you edit the JSON file directly, restart the app: ```bash # If running as a systemd service: sudo systemctl restart yaris-obd.service # If running manually: # Ctrl+C and python3 app.py ``` ### Changing the profile picture Option 1: Replace the default image file: ```bash cp /path/to/your/image.png static/img/yaris.png ``` Option 2: Add your image to `static/img/` and update `avatar_path`: ```json { "avatar_path": "img/my-avatar.png" } ``` ### Important: Username and database filename The local SQLite database filename is based on `owner_name`: `db/sql/_.db` (via [modules/app_sql.py](./modules/app_sql.py)). If you **change `owner_name`** and already have trip data: - The app will create a **new database** with the new name - Your old database remains at `db/sql/quoije_Yaris2013.db` (orphaned) To preserve your data: ```bash # Option 1: Rename the database file mv db/sql/quoije_Yaris2013.db "db/sql/YourName_YourCar.db" # Option 2: Start fresh rm db/sql/quoije_Yaris2013.db ``` ## Project status The Pi app, remote server, and device sync are all implemented and verified on real hardware. Phase 25 (road test) is complete; Phase 26 (12 bug fixes) is complete. Phase 27 (feature additions) is up next with 7 candidates. Full phase history and verification notes live in [PLAN.md](./PLAN.md). Open issues in [BUGS.md](./BUGS.md). Feature requests in [FEATURES.md](./FEATURES.md). ## Diagnostics & recovery If something goes wrong in the car, SSH in and run: ```bash bash ~/app/yaris-obd/scripts/diagnose.sh # read-only health check bash ~/app/yaris-obd/scripts/diagnose.sh --fix # attempt auto-fix ``` Checks service state, OBD/UART hardware, disk/DB health, upload backlog, Pi throttling, and prints a cheatsheet of recovery commands. Exit code = number of critical issues found. ## Hardware photo ![Yaris OBD hardware build](./pics/yaris-obd-hardware.jpg)