RemoteRig is a **multi-camera remote monitoring system**. It provides a camera grid dashboard for monitoring multiple GoPro cameras remotely. Cameras push status via MQTT/HTTP, the UI shows a live grid with SSE updates, and the system supports start/stop recording control.
**Target hardware:** Raspberry Pi Zero 2 W as the central hub, with ESP32 nodes attached to each GoPro camera for status collection and MQTT communication.
## Tech Stack
| Layer | Technology | Notes |
|-------|-----------|-------|
| Backend | Go 1.25+ | Chi v5 router, SQLite (modernc.org/sqlite), go-yaml v3 |
**Network is fully self-contained — no internet dependency.** The travel router creates the LAN. All devices connect to it. The Pi runs all services (Mosquitto, Go API, React UI, SQLite). ESP8266 boards talk to the GoPro AP over HTTP, then relay camera status/commands over UART to ESP32 boards. ESP32 boards stay on the travel-router LAN and bridge UART messages to MQTT.
- **Two-board camera node** — ESP8266 handles GoPro AP/HTTP; ESP32 stays on the travel-router LAN for MQTT. This avoids ESP32 dual-STA/channel switching complexity.
- **ESP8266 → GoPro over Wi-Fi** — Bacpac I²C route rejected (30-pin Herobus connector too complex). HTTP to GoPro AP is proven and reliable.
- **UART bridge between boards** — ESP8266 reports GoPro status and receives commands over UART; ESP32 relays those messages to/from MQTT.
- **MQTT for ESP32 → Hub** — Lightweight, designed for IoT. Mosquitto on Pi. QoS 1 for status, QoS 2 for commands. Full contract: [docs/MQTT_CONTRACT.md](./docs/MQTT_CONTRACT.md)
- **SQLite over PostgreSQL** — Single-node Pi Zero 2 W deployment. WAL mode for concurrent read/write.
- **SSE over WebSocket** — Unidirectional hub → browser updates. Simpler, sufficient for status dashboard.
- **Chi router** — Lightweight Go HTTP router with middleware support.
- **Zustand over Redux** — Minimal boilerplate for camera status store.
1.`lint-and-typecheck`: npm ci → eslint → tsc --noEmit
2.`test` (needs lint): npm test (vitest)
3.`build` (needs test): npm run build → upload dist artifact
### build-dev.yaml
Triggered by `repository_dispatch: dev-build-success`:
- Checks out, downloads artifact, builds Go binary
### deploy-dev.yaml
Triggered by `workflow_dispatch`:
- SCP binary + deploy script to dev host
- Deploy with backup/rollback, systemctl restart
- Failure notification
## Key Design Decisions
1.**SQLite chosen over PostgreSQL** — Single-node Pi Zero 2 W deployment; no need for a separate DB server. WAL mode for concurrent read/write.
2.**SSE chosen over WebSocket** — Unidirectional updates (hub → browser) are sufficient for status dashboard; SSE is simpler to implement and maintain.
3.**Chi router** — Lightweight, idiomatic Go HTTP router with middleware support.
4.**Zustand over Redux** — Minimal boilerplate for the camera status store.
5.**API key auth** — Simple bearer token; hub is on a local network, not internet-facing.
6.**MQTT** — Standard IoT protocol for ESP32 communication; Mosquitto broker runs locally on the Pi.
7.**Recording state tracking** — Status push handler detects recording state changes and automatically opens/closes recording_events rows.
- **MQTT subscriber not yet implemented** (CUB-232) — ESP32→hub communication backbone is designed (see [MQTT_CONTRACT.md](./docs/MQTT_CONTRACT.md)) but not built. Currently only HTTP status push is wired up.
- **No camera auto-discovery** (CUB-229) — Cameras must be manually registered. ESP32 announce protocol designed in MQTT contract but not implemented.
- **No battery calibration** (CUB-228) — GoPro Hero 3 reports raw byte; per-camera calibration offset column not yet added to schema.
- **No offline buffering on ESP32** (CUB-230) — If travel router Wi-Fi drops, status data is lost. SPIFFS buffer designed but not implemented.
- **CameraCard wireframe pending** (CUB-197) — Dashboard UI has live code but needs UX review/wireframe sign-off.
- **remoterig.db committed to repo** — Should be in `.gitignore` for production. Low priority (convenient for dev).
- **Time sync TBD** — ESP32s need accurate timestamps without internet. Options: Pi as NTP server, GPS module, or HTTP time endpoint. See MQTT contract open questions.