Files
yaris-obd/readme.md
T

221 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
**Open source** — released under the [MIT License](LICENSE). Contributions welcome.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
<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
[![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)
</td>
</tr>
</table>
## 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 and
can be cleared straight from the DTC page.
- **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** — fast 5GHz in-car AP on a T3U (wlan1), internet uplink (home WiFi +
phone hotspot) on a second T3U (wlan2); the onboard radio is a fallback. SSID/password configurable from the Settings page.
- **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. Captures OBD speed before the
first GPS fix so rolling starts aren't lost.
- **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.
- **Manual odometer** — Pi Settings page accepts a baseline reading; dashboard computes
`odometer = baseline + trip distance`. Synced to the remote server; portal shows read-only value.
- **Device config sync** — server-side owner name, car model, display name, avatar path, and sync
toggle hot-reload on the Pi without restart. Multi-device management on the portal with
create/rotate/delete keys and one-time API-key reveal.
- **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.
- **Android companion app** — native Kotlin app in `android/` (Phase 28, in progress). Dual-network
on the phone: browse + download dashcam clips over the car's WiFi, relay uploads over cellular.
Networking gate + dashcam browser/download verified on a Pixel; cellular upload in progress.
- **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) |
| 2× TP-Link Archer T3U (RTL8812BU) | USB WiFi dongles — AC1300 dual-band. wlan1 hosts the 5GHz in-car AP; wlan2 carries the internet uplink since 2026-08-14 |
| Onboard BCM43438 (wlan0) | Fallback only — was the internet uplink until 2026-08-14 |
| 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). For a **full hardware → software build walkthrough** on a fresh Pi —
including the one-shot `deploy/auto_install.sh` installer — 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/<owner_name>_<car_model>.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, device sync, and the Android companion app are all implemented and
verified on real hardware:
- **Phase 25** — real-car road test ✅
- **Phase 26** — road-test bug fixes (14 bugs) ✅
- **Phase 27** — feature additions: DTC history sync, manual odometer, hotspot settings +
5GHz WiFi swap, trip-history odometer ✅
- **Phase 28** — Android companion app ✅ — networking gate, dashcam browser/download,
cellular upload, live dashboard, trip history, remote portal, UI redesign, and signed APK
distribution. End-to-end cellular upload on the owner's Pixel is the last item pending final
verification.
- **Phase 29** — round-2 road-test bug fixes 🚧 in progress.
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)
## License
This project is open source and released under the [MIT License](LICENSE).