Files
yaris-obd/deploy/readme.md
T

432 lines
16 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 — full build & install guide
This is the complete **hardware → software** walkthrough for building a `yaris-obd`
unit from fresh parts and getting it running on a freshly flashed Raspberry Pi OS.
It assumes you are comfortable with basic Linux (flashing an SD card, SSH, running
commands), basic soldering, and basic 12V/5V electronics — but have never touched
this particular project before. The end result is a Pi that auto-starts the
`yaris-obd` web app on boot and serves it at `http://yaris.local` over the car's
own WiFi hotspot, with GPS tracking, live OBD-II data, dashcam import, and
background uploads to a self-hosted server.
For the project's full phase-by-phase history and hardware bring-up notes, see
[`PLAN.md`](../PLAN.md).
---
## 1) Parts list
| Part | Purpose | Notes |
| --- | --- | --- |
| Raspberry Pi 3 Model B | Runs the app, logs data, hosts the hotspot | Pi 3 B is the reference build; a Pi 3B+/4 works too |
| Waveshare SIM868 HAT | GNSS (GPS) + optional GSM/GPRS | GSM needs a SIM and 2G coverage (often none in NA); GPS is the part in use |
| SIM868 antennas | GSM + GPS reception | Two **separate** antennas — GSM and GNSS each plug into their own u.FL port on the HAT |
| USB OBD-II adapter | Reads live vehicle data | PL2303-chip ELM327-compatible (USB). Appears as `/dev/ttyUSB*` |
| 2× TP-Link Archer T3U | WiFi — `wlan1` = in-car 5GHz AP, `wlan2` = internet uplink | RTL8812BU chipset, needs a DKMS driver (the installer builds it) |
| DS3231 RTC module | Keeps the clock correct with no internet | Optional but strongly recommended; on the I²C bus `i2c-1` |
| CR2032 cell | Backup battery for the RTC | Must be **non-rechargeable** type for the ZS-042 board (see below) |
| 5V power source | Powers the Pi | Either a quality USB PSU **or** a hard-wired 5V/GND feed to the GPIO header |
| USB dashcam | Records video; files are imported over USB | Any brand that enumerates as USB mass storage |
| SD card (≥16GB) | Pi boot + app storage | A2/U3 card recommended |
| Car | The patient | Reference car: 2013 Toyota Yaris |
---
## 2) Hardware assembly
> **Safety first.** Anything mounted in a car must not interfere with pedals,
> steering, airbags, visibility, or occupants. Route and secure every cable.
> Never do this work while driving. If you are tapping vehicle 12V, fuse the
> feed as close to the source as possible.
### 2.1 Raspberry Pi
- Fit the SD card after flashing (Section 3).
- If you plan to run the Pi without a keyboard/monitor, set up SSH during
flashing so you can work on it headlessly.
### 2.2 SIM868 HAT (GPS)
The SIM868 HAT stacks on the Pi's 40-pin GPIO header.
1. **Set the UART jumper to `B` (Pi ↔ SIM868).** This is the 3-position jumper on
the HAT: `A` = USB↔SIM868, `B` = Pi GPIO↔SIM868, `C` = USB↔Pi console. It must
be on **B** or the Pi cannot talk to the module.
2. **Connect both antennas.** The **GPS/GNSS antenna** and the **GSM antenna** go
into their **own separate u.FL sockets** on the HAT. A GPS fix is impossible
with only the GSM antenna connected — this was the single most common bring-up
mistake in the reference build.
3. **PWRKEY.** This HAT revision ships with the "P4" GPIO power-on mod wire
already installed (header pin 7 = BCM GPIO4). The app pulses it automatically
at boot to power the module chip on. If your board does not have that wire,
you must press the HAT's PWRKEY button for ~1–2s after every Pi power-up, or
add the mod wire yourself.
4. Run the installer with `--with-sim868` (Section 4) so the Pi frees the full
UART for the HAT (`enable_uart=1`, `dtoverlay=disable-bt`, no serial login
shell, `hciuart` disabled). Baud rate is **115200**.
### 2.3 DS3231 RTC (recommended)
Without an RTC the Pi boots with a wrong clock every time the car has no internet,
which corrupts trip timestamps.
| DS3231 (ZS-042) pin | Pi GPIO header pin |
| --- | --- |
| VCC | **Pin 1 — 3.3V** (not 5V) |
| GND | Pin 6 |
| SDA | Pin 3 (I²C SDA) |
| SCL | Pin 5 (I²C SCL) |
- **Remove the charge diode** on the ZS-042 board if you fit a non-rechargeable
CR2032 — the board's trickle-charge circuit is unsafe for non-rechargeable
cells.
- If `i2cdetect -y 1` shows nothing at `0x68`, your SDA/SCL are crossed or a
joint is cold. A lit LED only means power is present.
- Run the installer with `--with-rtc` (Section 4) to add the overlay, disable
`fake-hwclock`, and load the `i2c-dev` module.
### 2.4 USB OBD-II adapter
- Any PL2303/CH340-based ELM327 USB adapter works. It enumerates as
`/dev/ttyUSB0` (or the first available `/dev/ttyUSB*`).
- The app auto-detects the port; you can override it later with the `OBD_PORT`
env var in the systemd unit if needed.
### 2.5 WiFi dongles (2× T3U)
- Plug one T3U into each USB port. The **interface names follow USB enumeration
order**, so on a given Pi `wlan1` and `wlan2` are stable only as long as the
dongles stay in the same ports. If you ever swap ports, the AP and uplink roles
will swap too.
- The installer builds the RTL8812BU DKMS driver. On a Pi 3 the two identical
dongles are distinguished only by their position, not by MAC — a MAC-based
udev rule is a possible future improvement (not required for normal use).
- Expected roles:
- `wlan1` — hosts the in-car **AP** (5GHz, `10.42.0.1`)
- `wlan2` — carries the **internet uplink** (home WiFi + optional phone hotspot)
- `wlan0` — onboard radio, kept as a weak fallback only
### 2.6 Power
Two valid approaches:
- **Simplest:** a good 5V/2.5A+ USB PSU (the official Pi 3 PSU is ideal). Avoid
thin cables — voltage drop is the #1 cause of `vcgencmd get_throttled`
undervoltage flags.
- **Robust for permanent install (reference build):** hard-wire regulated 5V/GND
directly to the GPIO header — **red to Pin 2 (5V), black to Pin 6 (GND)** —
fed from a fused 12V→5V buck converter (≥3A) or a quality cigarette-lighter
USB supply. This bypasses the fragile micro-USB connector.
Whichever you choose, verify after install:
```bash
vcgencmd get_throttled
# 0x0 = no undervoltage, no throttling (what you want)
```
A non-zero current undervoltage/throttling bit means the power feed is
inadequate and must be fixed before the unit lives in the car.
### 2.7 Dashcam
- Any dashcam that mounts as generic USB mass storage works — the app detects USB
storage via `lsblk` and walks it for video files.
- **Known manual step:** many dashcams boot into a "select mode" menu (dashcam /
mass-storage / webcam) when they sense live USB data lines. To record, the USB
data lines must be absent; to import, they must be present. The project does
**not** switch this automatically — unplug/replug (or use a data-blocking
cable) when switching between recording and importing.
### 2.8 Final in-car placement
- Keep the GPS antenna with a skyward view (dash top is usually fine).
- Keep the Pi and dongles clear of direct sunlight and away from heater vents.
- Strap everything down; a loose Pi near the pedals is a hazard.
---
## 3) Flash Raspberry Pi OS
1. Download **Raspberry Pi Imager** and write **Raspberry Pi OS Bookworm** (Lite
is fine) to the SD card.
2. In Imager's advanced options (gear icon) set:
- hostname: `yaris`
- enable SSH (password or key)
- your primary username + password (the installer creates a separate `yaris`
service user; this is just for you to log in)
- optional: your home WiFi credentials so the Pi is reachable for the install
3. Boot the Pi, find it on your network, and SSH in:
```bash
ssh <your-user>@yaris.local
# or fall back to the IP if mDNS isn't working yet
```
---
## 4) Run the one-shot installer
The installer (`deploy/auto_install.sh`) takes a fresh OS from zero to running.
It installs packages, creates the `yaris` user, clones the repo, builds the T3U
driver, creates the NetworkManager WiFi profiles, and runs every
`deploy/install_*.sh` in the right order.
### 4.1 Get the script onto the Pi
**Option A — download it directly (recommended):**
```bash
curl -fsSL -o auto_install.sh \
https://raw.githubusercontent.com/quoije/yaris-obd/shameless-aislop/deploy/auto_install.sh
```
> Replace `shameless-aislop` with the repo's current default branch if it has
> changed since this was written.
**Option B — clone the repo and run from inside it:**
```bash
git clone https://github.com/quoije/yaris-obd.git
cd yaris-obd
# the script clones again into /home/yaris/app/yaris-obd; that is expected
```
### 4.2 Run it
The only required inputs are your **home WiFi** and **in-car hotspot**
credentials. Pass them through the environment (or let the script prompt you):
```bash
sudo -E bash auto_install.sh \
--with-rtc \
--with-sim868
```
with these environment variables set:
```bash
export HOME_WIFI_SSID="MyHomeWiFi"
export HOME_WIFI_PSK="home-wifi-password"
export HOTSPOT_SSID="yaris-obd" # in-car AP; default is "yaris-obd"
export HOTSPOT_PSK="in-car-password"
# optional phone hotspot uplink:
export PHONE_HOTSPOT_SSID="MyPhoneHotspot"
export PHONE_HOTSPOT_PSK="phone-hotspot-password"
```
Fully non-interactive (no prompts) — fails if a required value is missing:
```bash
sudo -E bash auto_install.sh --non-interactive --with-rtc --with-sim868
```
### 4.3 Flags
| Flag | Effect |
| --- | --- |
| `--with-rtc` | Enable the DS3231 RTC (I²C overlay, disable `fake-hwclock`) |
| `--with-sim868` | Enable the SIM868 UART (`enable_uart=1`, `disable-bt`, no serial console, `hciuart` off) |
| `--skip-t3u-driver` | Skip the RTL8812BU build (if you're not using T3U dongles) |
| `--no-watchdog` | Skip the 10s hardware watchdog |
| `--no-app-updater` | Skip the Android APK mirror timer |
| `--non-interactive` | Never prompt; error out on missing credentials |
| `-h` / `--help` | Print help |
Optional env vars also honoured: `GIT_URL`, `GIT_BRANCH`, `YARIS_PASSWORD`,
`OWNER_NAME`, `CAR_MODEL`, `DEVICE_NAME`, `YARIS_SERVER_URL`,
`YARIS_DEVICE_NAME`, `YARIS_API_KEY`.
### 4.4 What the installer does
1. Installs base packages (`git`, Python tooling, NetworkManager, nftables,
avahi, dnsmasq-base, `iw`) and enables NetworkManager.
2. Creates the `yaris` service user (groups: `sudo`, `dialout`, `gpio`, `i2c`).
3. Clones the repo to `/home/yaris/app/yaris-obd`.
4. Applies `--with-rtc` / `--with-sim868` boot-config changes if requested.
5. Builds the RTL8812BU driver (unless skipped).
6. Creates/updates the `home-wifi`, `Hotspot-local`, and optional `phone-hotspot`
NetworkManager profiles.
7. Runs, in order: `install_service.sh`, `install_port_redirect.sh`,
`install_netwatch.sh`, `install_video_tools.sh`, and (unless disabled)
`install_watchdog.sh` + `install_app_updater.sh`.
8. Optionally prefills `config/device.json` and `db/upload_creds.env` from env
vars, fixes repo ownership, and creates the writable data directories.
### 4.5 Reboot
If you used `--with-rtc` or `--with-sim868`, reboot so the boot-config changes
apply:
```bash
sudo reboot
```
---
## 5) Verify
After reboot, on the Pi:
```bash
sudo systemctl status yaris-obd.service --no-pager
sudo systemctl status yaris-netwatch.timer --no-pager
sudo nft list ruleset | grep -n "dport 80"
curl -I http://127.0.0.1/
curl -s http://127.0.0.1/api/gps/status
```
Expected:
- `yaris-obd.service` is `active (running)`
- `yaris-netwatch.timer` is active
- nftables redirects port `80` → `5000`
- local HTTP on port 80 returns 200/302
- `/api/gps/status` returns JSON (GPS thread alive)
From another device on your home WiFi:
- `http://yaris.local`
From a phone connected to the **in-car hotspot** (`HOTSPOT_SSID`):
- `http://yaris.local` — or `http://10.42.0.1` if the phone doesn't resolve mDNS
If the T3U dongles don't appear after the driver build:
```bash
ip link show wlan1
ip link show wlan2
```
If `wlan1` is missing, fix the driver first (see Section 9), then re-run
`sudo bash deploy/install_netwatch.sh`.
---
## 6) Configure device identity
The Pi shows an owner name, car model, device name, and avatar. Either edit the
file directly:
```bash
sudo nano /home/yaris/app/yaris-obd/config/device.json
```
```json
{
"owner_name": "Your Name",
"car_model": "Toyota Yaris 2013",
"device_name": "My Yaris OBD",
"avatar_path": "img/yaris.png"
}
```
or open the web UI → **Settings** and manage it there.
- **`owner_name`** — top-right of the topbar
- **`car_model`** — left sidebar, next to the car icon
- **`device_name`** — device identity used for remote-server sync
- **`avatar_path`** — avatar image, relative to `static/` (drop your image in
`static/img/` and update the path, or replace `static/img/yaris.png`)
Restart after editing the file:
```bash
sudo systemctl restart yaris-obd.service
```
> **Heads-up:** the local SQLite database filename is derived from `owner_name`
> (`db/sql/<owner_name>_<car_model>.db`). Changing `owner_name` later creates a
> new empty database and orphans the old one — rename the old file to match if
> you want to keep the data.
---
## 7) Connect to the remote server (optional but recommended)
Trip logs and dashcam footage upload to a self-hosted Flask + Postgres server
(`server/` in this repo). See [`server/README.md`](../server/README.md) for
deploying it.
Once the server is up and a device is registered, put the credentials on the Pi
either via the web UI (**Settings → Remote server credentials → Test connection →
Sync now**) or by prefilling `db/upload_creds.env`:
```bash
sudo nano /home/yaris/app/yaris-obd/db/upload_creds.env
```
```ini
YARIS_SERVER_URL = "https://your-server.example"
YARIS_DEVICE_NAME = "yaris-2013"
YARIS_API_KEY = "your-one-time-key"
```
Then enable **Sync with server** in Settings if you want the server to own the
device identity.
---
## 8) Daily use & updates
Update the Pi to the latest code:
```bash
cd /home/yaris/app/yaris-obd
git pull --ff-only
sudo bash deploy/install_service.sh # re-deploy the unit + sudoers
sudo systemctl restart yaris-obd.service
```
If any `deploy/` files changed, re-run the matching installer(s)
(`install_netwatch.sh`, `install_port_redirect.sh`, `install_app_updater.sh`, …).
In-car, connect your phone to the hotspot and browse `http://yaris.local`.
Dashcam files are imported from the **Dashcam** page; live telemetry is on the
**Dashboard**; past drives are under **History**.
---
## 9) Troubleshooting
```bash
bash /home/yaris/app/yaris-obd/scripts/diagnose.sh # read-only check
bash /home/yaris/app/yaris-obd/scripts/diagnose.sh --fix # attempt auto-fix
```
Common issues:
| Symptom | Likely cause | Fix |
| --- | --- | --- |
| `wlan1`/`wlan2` missing | RTL8812BU driver didn't build | Re-run the driver build from Section 4; check `dkms status` |
| GPS never gets a fix | GPS antenna on wrong u.FL / not seated; HAT jumper not on `B`; SIM868 chip not powered | Re-check antennas + jumper; confirm the app pulses PWRKEY (or press the button 1–2s) |
| Wrong time after a cold boot | No RTC or RTC not configured | `i2cdetect -y 1` should show `UU` at `0x68`; check wiring (3.3V!) |
| `vcgencmd get_throttled` ≠ `0x0` | Weak power feed | Use a better PSU/cable, or hard-wire 5V to GPIO pins 2 & 6 |
| Dashcam import hangs | `yaris` lacks passwordless sudo for mount/rm | Re-run `sudo bash deploy/install_service.sh` (installs `yaris-dashcam.sudoers`) |
| Hotspot SSID/password changes don't save | `yaris-hotspot.sudoers` missing | Re-run `sudo bash deploy/install_netwatch.sh` |
| `yaris.local` not resolving on a phone | mDNS blocked / phone doesn't relay mDNS on the hotspot | Use `http://10.42.0.1` directly |
| `pip install -r requirements.txt` fails | Outdated checkout with the concatenated `requests-toolbeltreverse_geocoder` line | `git pull --ff-only` (fixed in current repo) |
| SSH drops when NetworkManager is enabled (Bookworm Lite) | NM takes over the interface and has no profile for your current WiFi yet | Run the installer over **Ethernet**, or pre-create the profile before enabling NM; after the run, re-connect to your WiFi |
---
### Manual reference: the installers
`auto_install.sh` is just a wrapper around these individual scripts, which you can
also run by hand from `/home/yaris/app/yaris-obd`:
```bash
sudo bash deploy/install_service.sh # systemd unit + venv + sudoers
sudo bash deploy/install_port_redirect.sh # nftables port 80 -> 5000
sudo bash deploy/install_netwatch.sh # uplink watcher + hotspot profiles
sudo bash deploy/install_video_tools.sh # ffmpeg for dashcam thumbnails
sudo bash deploy/install_watchdog.sh # 10s hardware watchdog
sudo bash deploy/install_app_updater.sh # Android APK mirror timer
```
The manual order matters: `install_netwatch.sh` expects the `home-wifi` and
`Hotspot-local` profiles to already exist (create them with `nmcli`, or just let
`auto_install.sh` do it).