From 7c07338707ef157a05b4e84a502e6ea99d71d913 Mon Sep 17 00:00:00 2001 From: Joshua King Date: Fri, 5 Jun 2026 21:57:07 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20update=20CONTEXT.md=20=E2=80=94=20contr?= =?UTF-8?q?ol-path=20wiring,=20dashboard,=20decisions=2018-21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §11: dashboard now renders live (SSE/seed/kiosk); GoPro monitoring works; flag that camera CONTROL is blocked by the faulty XIAO->ESP command wire (status RX works, command TX doesn't). Dedupe the token/default-branch lines. - §9: add decisions for the MQTT control path, SSE longevity + REST seed, nullable status JSON (NaN% fix), and UART being two independent wires. Co-Authored-By: Claude Opus 4.8 --- CONTEXT.md | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 47a9115..5e227c8 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -193,6 +193,19 @@ reach; the Pi pulls instead. Arduino String), recording = byte 29, battery = byte 19; record start/stop = `/bacpac/SH?t=&p=%01/%00`. ESP-01S flashing needs RST tied HIGH (RST→GND holds it in reset) and a known-good UART adapter (verify with a TX↔RX loopback). +18. **Control path:** `/cameras/{id}/start|stop` publish `{"command":...}` to + `remoterig/cameras//command` via `Subscriber.PublishCommand`; the XIAO forwards + it over UART to the ESP-01S. (The handlers used to only write a DB row — no command + was ever sent.) +19. **SSE longevity:** no global `middleware.Timeout` and `WriteTimeout: 0` — a write + deadline terminates the long-lived `/events/stream` (it was dying at 10s). The SPA + also **seeds** the list via `GET /api/v1/cameras` on mount (SSE only pushes on change). +20. **Nullable status JSON:** `battery_pct`/`video_remaining_sec` serialized as `null` + (not `omitempty`) — omitting them became `undefined` in the SPA → "NaN%". +21. **UART is two independent wires:** status (ESP `TX/GPIO1` → XIAO `D7`) and commands + (XIAO `D6` → ESP `RX/GPIO3`) are separate paths — receiving status does NOT prove + the command direction works. Verify the command path with the `set_config` + poll-interval test (status rate should change). ## 10. Conventions @@ -205,17 +218,29 @@ reach; the Pi pulls instead. ## 11. Current status & open items (2026-06-05) **Working / proven on hardware:** -- Hub up on the Pi (Mosquitto + `remoterig` + SQLite), dashboard on `:8080`. +- Hub up on the Pi (Mosquitto + `remoterig` + SQLite); **dashboard renders live** + (kiosk mode `api_key:""`, SSE kept alive, list seeded via REST on mount). - Full CI/CD loop proven: commit → CI build → `dev-latest` → Pi self-update (checksum, atomic replace, health-check) → service active. -- C6 (fw `0.4.0`) joins RemoteRig, connects to the broker, announces as `rig-86d978`, - and is **registered + listed** in `GET /api/v1/cameras` and the dashboard, with - status/heartbeat ingested cleanly. Shows `online:false` / zeros until a GoPro is - attached (expected on the bench). ESP-01S UART link alive. **End-to-end verified.** +- C6 (fw `0.4.0`) self-IDs as `rig-86d978`, registered + listed. +- **GoPro monitoring works (Hero 3 Silver):** ESP-01S joins `goprosilver-1`, reads + `/camera/se`, and `online:true` + `battery_raw` + `video_remaining_sec` flow + GoPro → ESP-01S → XIAO → MQTT → hub → SQLite → API/SSE → dashboard. +- Hub publishes start/stop commands to `…//command` (verified on the bus). **In progress / unresolved:** -- **GoPro Hero 3 protocol fix** (ESP-01S `fetchStatus` shutter bug) — required before - real battery/recording data; needs a real Hero 3. +- **Camera CONTROL not working — XIAO→ESP command wire is faulty.** Status (ESP→XIAO, + `GPIO1→D7`) works, but the command direction (XIAO `D6` → ESP `RX/GPIO3`) does not, + so `start_recording`/`set_config` never reach the ESP. Confirmed via the `set_config` + poll-interval test (status rate didn't change). Fix/re-seat that one jumper; then + Record + live config will work. (See decision #21.) +- **Battery calibration:** `battery_raw` (~56–59) flows; set `set_battery_cal` + (`raw_min/raw_max`, provisionally 0/100) for `battery_pct` — but this is a *command*, + so it's blocked by the same XIAO→ESP wire above. `video_remaining` offset (25-26) + provisional. SPA now shows "N/A" (not "NaN%") when `battery_pct` is null. +- **Pi SD-card health:** a transient `Input/output error` on core binaries cleared on + reboot — watch for recurrence (failing card); re-image via `setup-pi.sh` if it + returns (everything is reproducible from git). - **Rotate the Gitea runner registration token** (was exposed in a setup paste). - Gitea repo **default-branch HEAD** points at a nonexistent ref — set default branch. - Optional: clear the stale **retained** MQTT message at