221 lines
9.6 KiB
Markdown
221 lines
9.6 KiB
Markdown
# 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)
|
||
|
||
<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** — 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
|
||
|
||

|
||
|
||
## License
|
||
|
||
This project is open source and released under the [MIT License](LICENSE).
|