Files
beacon-server/internal/api/observers.go
T
2026-07-23 09:58:43 -07:00

70 lines
3.8 KiB
Go

// Copyright 2026 Beacon Contributors
// SPDX-License-Identifier: AGPL-3.0-or-later
package api
import "github.com/google/uuid"
// ObserverSummary is the minimal observer representation used in list responses.
type ObserverSummary struct {
ID uuid.UUID `json:"id"`
DisplayName *string `json:"displayName,omitempty"` // friendly name from /status messages
ObserverType *string `json:"observerType,omitempty"` // e.g. "meshcoretomqtt", "meshcoreha"
IATA string `json:"iata"` // most recently heard IATA
Status string `json:"status"` // "online" or "offline" derived from last_status_at
Radio *string `json:"radio,omitempty"` // friendly radio param string: freqMhz,BwKhz,SF e.g. "910.525,62.5,7"
Scopes []string `json:"scopes,omitempty"` // list of observer forwarded scopes matched to config
}
// ObserverBroker represents a single MQTT broker an observer has been seen on,
// including timestamps for diagnosing partial outages — e.g. distinguishing
// "observer is down" from "one broker stopped delivering for this observer".
type ObserverBroker struct {
Name string `json:"name"` // broker name e.g. "mqtt1"
LastSeenAt int64 `json:"lastSeenAt"` // epoch ms, last time observer was seen on this broker
LastPacketAt int64 `json:"lastPacketAt"` // epoch ms, last packet received via this broker; 0 if none
}
// Observer is the full observer representation including radio config,
// telemetry, broker memberships and raw status metadata.
type Observer struct {
ObserverSummary
PublicKey string `json:"publicKey"` // hex-encoded public key
SoftwareVersion *string `json:"softwareVersion,omitempty"`
HardwareModel *string `json:"hardwareModel,omitempty"`
FirmwareVersion *string `json:"firmwareVersion,omitempty"`
FirmwareBuild *string `json:"firmwareBuild,omitempty"`
RadioFreqMHz *float32 `json:"radioFreqMhz,omitempty"` // MHz e.g. 910.525
RadioSF *int16 `json:"radioSf,omitempty"` // LoRa spreading factor
RadioBWKHz *float32 `json:"radioBwKhz,omitempty"` // bandwidth in kHz
RadioCR *int16 `json:"radioCr,omitempty"` // coding rate denominator
BatteryLevel *float32 `json:"batteryLevel,omitempty"` // volts, nil if mains powered
UptimeSeconds *int64 `json:"uptimeSeconds,omitempty"`
StatusMetadata any `json:"statusMetadata,omitempty"` // raw /status JSON payload
LastStatusAt *int64 `json:"lastStatusAt,omitempty"` // epoch ms
FirstSeen int64 `json:"firstSeen"` // epoch ms
LastSeen int64 `json:"lastSeen"` // epoch ms
ObservationCount int64 `json:"observationCount"`
Brokers []ObserverBroker `json:"brokers"` // broker names this observer has been seen on
}
// ObserverTelemetryPoint is a single telemetry snapshot for an observer.
type ObserverTelemetryPoint struct {
T int64 `json:"t"` // epoch ms
BatteryMV *int32 `json:"batteryMv,omitempty"`
AirtimeTxPct *float32 `json:"airtimeTxPct,omitempty"`
AirtimeRxPct *float32 `json:"airtimeRxPct,omitempty"`
NoiseFloorDB *float32 `json:"noiseFloorDb,omitempty"`
UptimeSeconds *int64 `json:"uptimeSeconds,omitempty"`
QueueLength *int32 `json:"queueLength,omitempty"`
ReceiveErrors *int32 `json:"receiveErrors,omitempty"`
}
// ObserverTelemetry is the full telemetry response for an observer.
// Range and interval reflect the query parameters used.
type ObserverTelemetry struct {
Range string `json:"range"`
Interval string `json:"interval"`
Points []ObserverTelemetryPoint `json:"points"`
}