From e55dae340ba3893f38581fe67c51db9bf10bdd35 Mon Sep 17 00:00:00 2001 From: Joshua Date: Mon, 18 May 2026 17:45:10 -0400 Subject: [PATCH] CUB-185: Camera/StatusLog/RecordingEvent/Setting Go models --- pkg/models/camera.go | 91 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 pkg/models/camera.go diff --git a/pkg/models/camera.go b/pkg/models/camera.go new file mode 100644 index 0000000..e87f109 --- /dev/null +++ b/pkg/models/camera.go @@ -0,0 +1,91 @@ +// Package models contains the data structures for RemoteRig. +package models + +import ( + "time" +) + +// Camera represents a registered GoPro camera in the system. +type Camera struct { + CameraID string `json:"camera_id"` + FriendlyName string `json:"friendly_name"` + MacAddress string `json:"mac_address,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// StatusLog records a single status poll from an ESP8266 node. +type StatusLog struct { + ID int64 `json:"id"` + CameraID string `json:"camera_id"` + RecordedAt time.Time `json:"recorded_at"` + BatteryPct *int `json:"battery_pct,omitempty"` + VideoRemainingSec *int `json:"video_remaining_sec,omitempty"` + RecordingState int `json:"recording_state"` // 0=idle, 1=recording + Mode *string `json:"mode,omitempty"` + Resolution *string `json:"resolution,omitempty"` + FPS *int `json:"fps,omitempty"` + Online int `json:"online"` // 0=offline, 1=online + RawBatteryPct *float64 `json:"raw_battery_pct,omitempty"` +} + +// CameraStatus is a combined view: latest status log joined with camera info. +type CameraStatus struct { + CameraID string `json:"camera_id"` + FriendlyName string `json:"friendly_name"` + BatteryPct *int `json:"battery_pct,omitempty"` + VideoRemainingSec *int `json:"video_remaining_sec,omitempty"` + Recording bool `json:"recording"` + Mode string `json:"mode"` + Resolution string `json:"resolution"` + FPS int `json:"fps"` + Online bool `json:"online"` + LastSeen time.Time `json:"last_seen"` +} + +// RecordingEvent represents a start/stop recording event. +type RecordingEvent struct { + ID int64 `json:"id"` + CameraID string `json:"camera_id"` + StartedAt time.Time `json:"started_at"` + StoppedAt *time.Time `json:"stopped_at,omitempty"` + Reason *string `json:"reason,omitempty"` + Duration *int `json:"duration,omitempty"` // seconds +} + +// Settings stores system-wide configuration. +type Setting struct { + Key string `json:"key"` + Value string `json:"value"` + UpdatedAt time.Time `json:"updated_at"` +} + +// NewCameraStatus creates a CameraStatus from a Camera and StatusLog. +func NewCameraStatus(c Camera, sl StatusLog) CameraStatus { + return CameraStatus{ + CameraID: c.CameraID, + FriendlyName: c.FriendlyName, + BatteryPct: sl.BatteryPct, + VideoRemainingSec: sl.VideoRemainingSec, + Recording: sl.RecordingState == 1, + Mode: takeString(sl.Mode), + Resolution: takeString(sl.Resolution), + FPS: takeInt(sl.FPS), + Online: sl.Online == 1, + LastSeen: sl.RecordedAt, + } +} + +func takeString(s *string) string { + if s == nil { + return "" + } + return *s +} + +func takeInt(i *int) int { + if i == nil { + return 0 + } + return *i +}