generated from CubeCraft-Creations/Tracehound
Dev #26
+6
-6
@@ -36,7 +36,7 @@ RemoteRig is a **multi-camera remote monitoring system**. It provides a camera g
|
|||||||
```
|
```
|
||||||
┌──────────────────────────────────────────┐
|
┌──────────────────────────────────────────┐
|
||||||
│ Travel Router (self-contained LAN) │
|
│ Travel Router (self-contained LAN) │
|
||||||
│ Subnet: 10.60.1.0/24 │
|
│ Subnet: 192.168.8.0/24 │
|
||||||
│ DHCP pool: .100-.200 │
|
│ DHCP pool: .100-.200 │
|
||||||
└──────┬──────────┬──────────┬──────────────┘
|
└──────┬──────────┬──────────┬──────────────┘
|
||||||
│ │ │
|
│ │ │
|
||||||
@@ -44,7 +44,7 @@ RemoteRig is a **multi-camera remote monitoring system**. It provides a camera g
|
|||||||
▼ ▼ ▼
|
▼ ▼ ▼
|
||||||
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
|
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
|
||||||
│ ESP32 #1 │ │ ESP32 #N │ │ Pi Zero 2 W │
|
│ ESP32 #1 │ │ ESP32 #N │ │ Pi Zero 2 W │
|
||||||
│ DHCP addr │ │ DHCP addr │ │ 10.60.1.56 │
|
│ DHCP addr │ │ DHCP addr │ │ 192.168.8.56 │
|
||||||
│ STA→Router │ │ STA→Router │ │ (static IP) │
|
│ STA→Router │ │ STA→Router │ │ (static IP) │
|
||||||
│ MQTT→:1883 │ │ MQTT→:1883 │ │ Mosquitto :1883 │
|
│ MQTT→:1883 │ │ MQTT→:1883 │ │ Mosquitto :1883 │
|
||||||
│ UART relay │ │ UART relay │ │ Go API :8080 │
|
│ UART relay │ │ UART relay │ │ Go API :8080 │
|
||||||
@@ -59,14 +59,14 @@ RemoteRig is a **multi-camera remote monitoring system**. It provides a camera g
|
|||||||
└──────┬───────┘ └──────┬───────┘ ┌──────────────────┐
|
└──────┬───────┘ └──────┬───────┘ ┌──────────────────┐
|
||||||
▼ ▼ │ User Device │
|
▼ ▼ │ User Device │
|
||||||
┌──────────────┐ ┌──────────────┐ │ (laptop/kiosk) │
|
┌──────────────┐ ┌──────────────┐ │ (laptop/kiosk) │
|
||||||
│ GoPro Hero 3 │ │ GoPro Hero 3 │ │ 10.60.1.56:8080 │
|
│ GoPro Hero 3 │ │ GoPro Hero 3 │ │ 192.168.8.56:8080 │
|
||||||
└──────────────┘ └──────────────┘ └──────────────────┘
|
└──────────────┘ └──────────────┘ └──────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
**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.
|
**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.
|
||||||
|
|
||||||
### Key Architecture Decisions (revised)
|
### Key Architecture Decisions (revised)
|
||||||
- **Closed travel router network** — No venue Wi-Fi dependency. User brings their own router. All devices on `10.60.1.0/24`.
|
- **Closed travel router network** — No venue Wi-Fi dependency. User brings their own router. All devices on `192.168.8.0/24`.
|
||||||
- **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.
|
- **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.
|
- **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.
|
- **UART bridge between boards** — ESP8266 reports GoPro status and receives commands over UART; ESP32 relays those messages to/from MQTT.
|
||||||
@@ -215,8 +215,8 @@ platform:
|
|||||||
type: "pi-zero-2w"
|
type: "pi-zero-2w"
|
||||||
max_cameras: 16
|
max_cameras: 16
|
||||||
network:
|
network:
|
||||||
subnet: "10.60.1.0/24" # Travel router subnet
|
subnet: "192.168.8.0/24" # Travel router subnet
|
||||||
hub_ip: "10.60.1.56" # Pi Zero 2 W static IP
|
hub_ip: "192.168.8.56" # Pi Zero 2 W static IP
|
||||||
```
|
```
|
||||||
|
|
||||||
## Frontend Component Tree
|
## Frontend Component Tree
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
┌──────────────────────────────────┐
|
┌──────────────────────────────────┐
|
||||||
│ Travel Router (10.60.1.1) │
|
│ Travel Router (192.168.8.1) │
|
||||||
│ DHCP: .100-.200 │
|
│ DHCP: .100-.200 │
|
||||||
└──────┬──────────┬──────────┬──────┘
|
└──────┬──────────┬──────────┬──────┘
|
||||||
│ │ │
|
│ │ │
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
▼ ▼ ▼
|
▼ ▼ ▼
|
||||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||||
│ ESP32 #1 │ │ ESP32 #2 │ │ Pi Zero 2 W │
|
│ ESP32 #1 │ │ ESP32 #2 │ │ Pi Zero 2 W │
|
||||||
│ 10.60.1.101 │ │ 10.60.1.102 │ │ 10.60.1.56 │
|
│ 192.168.8.101 │ │ 192.168.8.102 │ │ 192.168.8.56 │
|
||||||
│ STA→Router │ │ STA→Router │ │ Mosquitto │
|
│ STA→Router │ │ STA→Router │ │ Mosquitto │
|
||||||
│ MQTT relay │ │ MQTT relay │ │ Go backend │
|
│ MQTT relay │ │ MQTT relay │ │ Go backend │
|
||||||
└──────┬───────┘ └──────┬───────┘ │ React UI │
|
└──────┬───────┘ └──────┬───────┘ │ React UI │
|
||||||
@@ -32,14 +32,14 @@
|
|||||||
└──────────────┘ └──────────────┘
|
└──────────────┘ └──────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Travel router:** Self-contained, no internet. Gateway `10.60.1.1`. DHCP pool: `10.60.1.100-200`
|
- **Travel router:** Self-contained, no internet. Gateway `192.168.8.1`. DHCP pool: `192.168.8.100-200`
|
||||||
- **Pi Zero 2 W:** Static IP `10.60.1.56`. Runs Mosquitto (port 1883), Go backend (port 8080), serves React UI
|
- **Pi Zero 2 W:** Static IP `192.168.8.56`. Runs Mosquitto (port 1883), Go backend (port 8080), serves React UI
|
||||||
- **ESP32s:** DHCP from router. Each stays on the travel-router LAN, relays MQTT to/from its paired ESP8266 over UART
|
- **ESP32s:** DHCP from router. Each stays on the travel-router LAN, relays MQTT to/from its paired ESP8266 over UART
|
||||||
- **User device:** Connects to router, opens `http://10.60.1.56:8080` for dashboard
|
- **User device:** Connects to router, opens `http://192.168.8.56:8080` for dashboard
|
||||||
|
|
||||||
## MQTT Broker
|
## MQTT Broker
|
||||||
|
|
||||||
- **Host:** `10.60.1.56` (Pi Zero 2 W)
|
- **Host:** `192.168.8.56` (Pi Zero 2 W)
|
||||||
- **Port:** `1883` (default MQTT, no TLS — closed network)
|
- **Port:** `1883` (default MQTT, no TLS — closed network)
|
||||||
- **Auth:** None (closed network, no external access)
|
- **Auth:** None (closed network, no external access)
|
||||||
- **Client ID format:** `remoterig-<esp32_mac_last6>` (e.g., `remoterig-a1b2c3`)
|
- **Client ID format:** `remoterig-<esp32_mac_last6>` (e.g., `remoterig-a1b2c3`)
|
||||||
@@ -222,7 +222,7 @@ Hub health status broadcast.
|
|||||||
ESP32 boots
|
ESP32 boots
|
||||||
│
|
│
|
||||||
├── Connects to travel router Wi-Fi
|
├── Connects to travel router Wi-Fi
|
||||||
├── Connects to MQTT broker (10.60.1.56:1883)
|
├── Connects to MQTT broker (192.168.8.56:1883)
|
||||||
├── Publishes announce (retained) on cameras/<id>/announce
|
├── Publishes announce (retained) on cameras/<id>/announce
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
@@ -275,6 +275,6 @@ When ESP32 loses connection to travel router:
|
|||||||
|
|
||||||
## Open Questions
|
## Open Questions
|
||||||
|
|
||||||
1. **NTP/time sync:** How do ESP32s get accurate time without internet? Options: (a) Pi runs NTP server, (b) ESP32 queries Pi's HTTP /api/v1/time endpoint, (c) GPS module. **Recommendation:** Pi runs NTPd, ESP32s use SNTP from `10.60.1.56`.
|
1. **NTP/time sync:** How do ESP32s get accurate time without internet? Options: (a) Pi runs NTP server, (b) ESP32 queries Pi's HTTP /api/v1/time endpoint, (c) GPS module. **Recommendation:** Pi runs NTPd, ESP32s use SNTP from `192.168.8.56`.
|
||||||
2. **Camera naming:** Should `friendly_name` be configurable from dashboard after auto-registration? **Recommendation:** Yes — allow rename via UI, stored in cameras table.
|
2. **Camera naming:** Should `friendly_name` be configurable from dashboard after auto-registration? **Recommendation:** Yes — allow rename via UI, stored in cameras table.
|
||||||
3. **Firmware OTA:** Should ESP32 firmware updates be possible over this network? **Recommendation:** Yes but out of scope for MVP.
|
3. **Firmware OTA:** Should ESP32 firmware updates be possible over this network? **Recommendation:** Yes but out of scope for MVP.
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ The system uses a semantic 3-tier color system to indicate device health.
|
|||||||
│ │ Battery: 82% [Green] │ │
|
│ │ Battery: 82% [Green] │ │
|
||||||
│ │ Storage: 45% [Green] │ │
|
│ │ Storage: 45% [Green] │ │
|
||||||
│ │ Status: RECORDING │ │
|
│ │ Status: RECORDING │ │
|
||||||
│ │ IP: 10.60.1.12 │ │
|
│ │ IP: 192.168.8.12 │ │
|
||||||
│ │ MAC: AA:BB:CC:DD:EE:FF │ │
|
│ │ MAC: AA:BB:CC:DD:EE:FF │ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ │ [ EDIT CAMERA SETTINGS ] │ │
|
│ │ [ EDIT CAMERA SETTINGS ] │ │
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@ Each camera node uses **two boards** connected via UART — zero network switchi
|
|||||||
│ (Camera Bridge) │ RX←──────TX │ (MQTT Bridge) │
|
│ (Camera Bridge) │ RX←──────TX │ (MQTT Bridge) │
|
||||||
│ │ 115200 │ │
|
│ │ 115200 │ │
|
||||||
│ STA → GoPro AP │ 8N1 │ STA → Travel Router │
|
│ STA → GoPro AP │ 8N1 │ STA → Travel Router │
|
||||||
│ HTTP → 10.5.5.1 │ │ MQTT → 10.60.1.56│
|
│ HTTP → 10.5.5.1 │ │ MQTT → 192.168.8.56│
|
||||||
│ Start/stop/status │ │ Hub registration │
|
│ Start/stop/status │ │ Hub registration │
|
||||||
└─────────────────────┘ └──────────────────────┘
|
└─────────────────────┘ └──────────────────────┘
|
||||||
```
|
```
|
||||||
@@ -22,7 +22,7 @@ Each camera node uses **two boards** connected via UART — zero network switchi
|
|||||||
| Board | Job | Network | Protocol |
|
| Board | Job | Network | Protocol |
|
||||||
|-------|-----|---------|----------|
|
|-------|-----|---------|----------|
|
||||||
| ESP8266 | Camera control | GoPro AP only (10.5.5.1) | HTTP → UART JSON |
|
| ESP8266 | Camera control | GoPro AP only (10.5.5.1) | HTTP → UART JSON |
|
||||||
| ESP32 | Hub relay | Travel router only (10.60.1.x) | UART JSON → MQTT |
|
| ESP32 | Hub relay | Travel router only (192.168.8.x) | UART JSON → MQTT |
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ JSON-per-line at 115200 8N1. GPIO16 on both boards.
|
|||||||
|-----|---------|-------------|
|
|-----|---------|-------------|
|
||||||
| `wifi_ssid` | `"RemoteRig"` | Travel router SSID |
|
| `wifi_ssid` | `"RemoteRig"` | Travel router SSID |
|
||||||
| `wifi_password` | `""` | Travel router password |
|
| `wifi_password` | `""` | Travel router password |
|
||||||
| `mqtt_broker` | `"10.60.1.56"` | Pi Zero 2 W IP |
|
| `mqtt_broker` | `"192.168.8.56"` | Pi Zero 2 W IP |
|
||||||
| `mqtt_port` | `1883` | Mosquitto port |
|
| `mqtt_port` | `1883` | Mosquitto port |
|
||||||
| `camera_id` | `""` | Assigned by hub on first announce (leave empty) |
|
| `camera_id` | `""` | Assigned by hub on first announce (leave empty) |
|
||||||
| `heartbeat_interval_sec` | `60` | MQTT heartbeat frequency |
|
| `heartbeat_interval_sec` | `60` | MQTT heartbeat frequency |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"wifi_ssid": "RemoteRig",
|
"wifi_ssid": "RemoteRig",
|
||||||
"wifi_password": "",
|
"wifi_password": "",
|
||||||
"mqtt_broker": "10.60.1.56",
|
"mqtt_broker": "192.168.8.56",
|
||||||
"mqtt_port": 1883,
|
"mqtt_port": 1883,
|
||||||
"camera_id": "",
|
"camera_id": "",
|
||||||
"heartbeat_interval_sec": 60,
|
"heartbeat_interval_sec": 60,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
struct Config {
|
struct Config {
|
||||||
String wifi_ssid = "RemoteRig";
|
String wifi_ssid = "RemoteRig";
|
||||||
String wifi_password = "";
|
String wifi_password = "";
|
||||||
String mqtt_broker = "10.60.1.56";
|
String mqtt_broker = "192.168.8.56";
|
||||||
int mqtt_port = 1883;
|
int mqtt_port = 1883;
|
||||||
String camera_id = ""; // assigned by hub
|
String camera_id = ""; // assigned by hub
|
||||||
int heartbeat_sec = 60;
|
int heartbeat_sec = 60;
|
||||||
|
|||||||
+3
-3
@@ -158,11 +158,11 @@ GoPro Hero 3 ──(AP @ 10.5.5.1)──→ ESP-01S / ESP8266 camera bridge
|
|||||||
UART │ (inside case)
|
UART │ (inside case)
|
||||||
│
|
│
|
||||||
Travel Router ──(AP)────────────────────→ ESP32-C3 MQTT bridge
|
Travel Router ──(AP)────────────────────→ ESP32-C3 MQTT bridge
|
||||||
(10.60.1.1) │
|
(192.168.8.1) │
|
||||||
│
|
│
|
||||||
MQTT │
|
MQTT │
|
||||||
▼
|
▼
|
||||||
Pi Hub (10.60.1.56)
|
Pi Hub (192.168.8.56)
|
||||||
```
|
```
|
||||||
|
|
||||||
The ESP8266/ESP-01S and GoPro talk over Wi-Fi. The only cable to the GoPro is USB power from the case side USB-A passthrough port.
|
The ESP8266/ESP-01S and GoPro talk over Wi-Fi. The only cable to the GoPro is USB power from the case side USB-A passthrough port.
|
||||||
@@ -175,7 +175,7 @@ The ESP8266/ESP-01S and GoPro talk over Wi-Fi. The only cable to the GoPro is US
|
|||||||
4. Connect the power bank to the case bottom USB-C input; connect the GoPro USB power cable to the case side USB-A passthrough output.
|
4. Connect the power bank to the case bottom USB-C input; connect the GoPro USB power cable to the case side USB-A passthrough output.
|
||||||
5. Toggle rocker switch on.
|
5. Toggle rocker switch on.
|
||||||
6. Verify PWR LED, RGB status LED, and OLED status: camera ID, REC state, battery, link, timer.
|
6. Verify PWR LED, RGB status LED, and OLED status: camera ID, REC state, battery, link, timer.
|
||||||
7. Monitor from `http://10.60.1.56:8080`.
|
7. Monitor from `http://192.168.8.56:8080`.
|
||||||
|
|
||||||
## Case Dimensions
|
## Case Dimensions
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -9,8 +9,8 @@
|
|||||||
# Options:
|
# Options:
|
||||||
# --config PATH Path to config.yaml template to copy to /opt/remoterig/
|
# --config PATH Path to config.yaml template to copy to /opt/remoterig/
|
||||||
# --service-user USER Systemd service user (default: pi)
|
# --service-user USER Systemd service user (default: pi)
|
||||||
# --static-ip IP Static IP for wlan0 (default: 10.60.1.56/24)
|
# --static-ip IP Static IP for wlan0 (default: 192.168.8.56/24)
|
||||||
# --gateway IP Gateway for wlan0 (default: 10.60.1.1)
|
# --gateway IP Gateway for wlan0 (default: 192.168.8.1)
|
||||||
# --help Show this help
|
# --help Show this help
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -20,8 +20,8 @@ set -euo pipefail
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
CONFIG_TEMPLATE=""
|
CONFIG_TEMPLATE=""
|
||||||
SERVICE_USER="pi"
|
SERVICE_USER="pi"
|
||||||
STATIC_IP="10.60.1.56/24"
|
STATIC_IP="192.168.8.56/24"
|
||||||
GATEWAY="10.60.1.1"
|
GATEWAY="192.168.8.1"
|
||||||
MOSQUITTO_PKG="mosquitto mosquitto-clients"
|
MOSQUITTO_PKG="mosquitto mosquitto-clients"
|
||||||
DEPLOY_DIR="/opt/remoterig"
|
DEPLOY_DIR="/opt/remoterig"
|
||||||
SERVICE_NAME="remoterig"
|
SERVICE_NAME="remoterig"
|
||||||
@@ -324,13 +324,13 @@ echo " Next steps:"
|
|||||||
echo " 1. Build the remoterig binary for ARM64:"
|
echo " 1. Build the remoterig binary for ARM64:"
|
||||||
echo " GOOS=linux GOARCH=arm64 go build -o remoterig ./cmd/server"
|
echo " GOOS=linux GOARCH=arm64 go build -o remoterig ./cmd/server"
|
||||||
echo " 2. Copy binary to Pi:"
|
echo " 2. Copy binary to Pi:"
|
||||||
echo " scp remoterig pi@10.60.1.56:/opt/remoterig/"
|
echo " scp remoterig pi@192.168.8.56:/opt/remoterig/"
|
||||||
echo " 3. Copy config if needed:"
|
echo " 3. Copy config if needed:"
|
||||||
echo " scp config.yaml pi@10.60.1.56:/opt/remoterig/"
|
echo " scp config.yaml pi@192.168.8.56:/opt/remoterig/"
|
||||||
echo " 4. Start the service:"
|
echo " 4. Start the service:"
|
||||||
echo " sudo systemctl start remoterig"
|
echo " sudo systemctl start remoterig"
|
||||||
echo " 5. Check health:"
|
echo " 5. Check health:"
|
||||||
echo " curl http://10.60.1.56:8080/health"
|
echo " curl http://192.168.8.56:8080/health"
|
||||||
echo ""
|
echo ""
|
||||||
echo " To deploy updates, use: scripts/deploy.sh"
|
echo " To deploy updates, use: scripts/deploy.sh"
|
||||||
echo "=============================================="
|
echo "=============================================="
|
||||||
|
|||||||
Reference in New Issue
Block a user