feat: add MQTT subscriber for ESP32 camera status ingestion

Implements MQTT subscriber (internal/mqtt/subscriber.go) that:
- Connects to Mosquitto broker with auto-reconnect
- Subscribes to remoterig/cameras/+/status, +/heartbeat, +/announce
- Parses and validates incoming messages per MQTT contract
- Inserts status_logs with duplicate prevention
- Auto-detects recording state changes and manages recording_events
- Broadcasts camera status changes via SSE hub
- Camera auto-registration via announce (MAC-based, sequential cam-NNN)
- Heartbeat watchdog marks cameras offline after 120s silence
- Wired into main.go with graceful degradation (warns if broker unreachable)

Dependency: github.com/eclipse/paho.mqtt.golang v1.5.0

Closes CUB-232.
This commit is contained in:
2026-05-21 21:16:08 +00:00
parent ce188086cb
commit f200cd9782
3 changed files with 443 additions and 0 deletions
+8
View File
@@ -15,6 +15,7 @@ import (
"github.com/cubecraft/remoterig/internal/auth"
"github.com/cubecraft/remoterig/internal/db"
"github.com/cubecraft/remoterig/internal/events"
"github.com/cubecraft/remoterig/internal/mqtt"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
@@ -59,6 +60,13 @@ func main() {
// Create SSE hub for real-time updates
sseHub := events.NewHub()
// Start MQTT subscriber for ESP32 camera status ingestion
mqttSub := mqtt.NewSubscriber(cfg.MQTT.Broker, cfg.MQTT.ClientID, sqlDB, sseHub)
if err := mqttSub.Connect(); err != nil {
log.Printf("WARNING: MQTT subscriber failed to connect: %v (running without MQTT)", err)
}
defer mqttSub.Close()
// Set up router
r := chi.NewRouter()
r.Use(middleware.RequestID)