generated from CubeCraft-Creations/Tracehound
Dev #26
@@ -26,12 +26,12 @@ func ListCameras(database *db.DB) http.HandlerFunc {
|
|||||||
c.friendly_name,
|
c.friendly_name,
|
||||||
s.battery_pct,
|
s.battery_pct,
|
||||||
s.video_remaining_sec,
|
s.video_remaining_sec,
|
||||||
s.recording_state,
|
COALESCE(s.recording_state, 0),
|
||||||
s.mode,
|
s.mode,
|
||||||
s.resolution,
|
s.resolution,
|
||||||
s.fps,
|
s.fps,
|
||||||
s.online,
|
COALESCE(s.online, 0),
|
||||||
s.recorded_at
|
COALESCE(s.recorded_at, c.created_at)
|
||||||
FROM cameras c
|
FROM cameras c
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT camera_id, battery_pct, video_remaining_sec, recording_state,
|
SELECT camera_id, battery_pct, video_remaining_sec, recording_state,
|
||||||
|
|||||||
@@ -283,7 +283,9 @@ func (s *Subscriber) handleStatus(cameraID string, payload []byte) {
|
|||||||
|
|
||||||
type heartbeatPayload struct {
|
type heartbeatPayload struct {
|
||||||
CameraID string `json:"camera_id"`
|
CameraID string `json:"camera_id"`
|
||||||
Timestamp string `json:"timestamp"`
|
// No Timestamp field: the node sends a numeric millis() value and the
|
||||||
|
// handler doesn't use it; omitting the field lets it be ignored instead
|
||||||
|
// of failing JSON unmarshal (number into string).
|
||||||
UptimeSec *int `json:"uptime_sec"`
|
UptimeSec *int `json:"uptime_sec"`
|
||||||
FreeHeap *int `json:"free_heap"`
|
FreeHeap *int `json:"free_heap"`
|
||||||
}
|
}
|
||||||
@@ -360,8 +362,8 @@ func (s *Subscriber) handleAnnounce(cameraID string, payload []byte) {
|
|||||||
"SELECT camera_id FROM cameras WHERE mac_address = ?", ap.MacAddress,
|
"SELECT camera_id FROM cameras WHERE mac_address = ?", ap.MacAddress,
|
||||||
).Scan(&existingID)
|
).Scan(&existingID)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil && existingID == cameraID {
|
||||||
// Already registered — just update friendly_name
|
// Same self-id re-connecting — just refresh friendly_name.
|
||||||
_, err = s.db.Exec(
|
_, err = s.db.Exec(
|
||||||
"UPDATE cameras SET friendly_name = ?, updated_at = datetime('now') WHERE camera_id = ?",
|
"UPDATE cameras SET friendly_name = ?, updated_at = datetime('now') WHERE camera_id = ?",
|
||||||
ap.FriendlyName, existingID,
|
ap.FriendlyName, existingID,
|
||||||
@@ -372,6 +374,12 @@ func (s *Subscriber) handleAnnounce(cameraID string, payload []byte) {
|
|||||||
}
|
}
|
||||||
log.Printf("MQTT announce: camera %s (%s) re-connected", existingID, ap.FriendlyName)
|
log.Printf("MQTT announce: camera %s (%s) re-connected", existingID, ap.FriendlyName)
|
||||||
} else {
|
} else {
|
||||||
|
// MAC known under a different id (legacy cam-NNN from before self-IDs)
|
||||||
|
// → drop the old row so we re-register under the node's self-id.
|
||||||
|
if err == nil && existingID != cameraID {
|
||||||
|
s.db.Exec("DELETE FROM cameras WHERE camera_id = ?", existingID)
|
||||||
|
log.Printf("MQTT announce: migrating %s -> %s (%s)", existingID, cameraID, ap.FriendlyName)
|
||||||
|
}
|
||||||
// Option B: the node self-assigns its camera_id (the announce topic id).
|
// Option B: the node self-assigns its camera_id (the announce topic id).
|
||||||
_, err = s.db.Exec(`
|
_, err = s.db.Exec(`
|
||||||
INSERT INTO cameras (camera_id, friendly_name, mac_address, created_at, updated_at)
|
INSERT INTO cameras (camera_id, friendly_name, mac_address, created_at, updated_at)
|
||||||
|
|||||||
Reference in New Issue
Block a user