Skip to content

About this article

  • Audience: Integrators and operators who need fleet MQTT contracts without reading firmware source
  • Goal: After reading, you can name publish topics, validate JSON shapes, and read cached state through the proxy
  • Type: Reference

Summary

Shadows publish JSON on devices/{device_id}/… at roughly 10 Hz for telemetry and detections. The phantom proxy subscribes to fleet wildcards, caches the latest payloads, and serves them over HTTP. Use this page for topic names and schema shapes; use API quick reference for proxy ingest commands.

Prerequisites

  • Phantom host stack (MQTT 1883, proxy 8788)
  • PHANTOM_PROXY=https://<phantom-proxy>:8788
  • Device IDs as role labels (site-role-a, site-role-b)

Base namespace: devices/{device_id}/… (primary), shadow/{device_id}/… (telemetry mirror), devices/{device_id}/cmd/… (ingress). See glossary for device_id and precomp.

Publish topics

Topic suffixQoSRatePurpose
status1, retainOn change + LWTOnline/offline and thermal governor
health1~30 sFleet health: serial, role, storage summary
telemetry1~10 HzDie temp, fps, embedded detection list
telemetry/wifi1PeriodicRSSI, SSID, failover state
telemetry/can1PeriodicJ1939 / CAN decoded frames
dets1~10 HzRF-DETR precomp detection batches
data_manifest1On boot + on requestRecording index responses
responses1On commandUpload, plugin, and error replies
events/{type}0–1Event-drivenIncidents, automation logs, plugin events
hello1On connectFleet registration handshake

Notable events: incident (proxy video-understanding pull), automation_log.

Detection schema (dets / telemetry.detections)

Contract-required keys per detection:

KeyTypeRequiredDescription
cintegerYesClass id (0 = person in RF-DETR precomp)
pnumberYesConfidence score
bnumber[4+]YesBounding box coordinates
track_idintegerNoStable id when object tracker layer is enabled
x, y, znumberNoSpatial fusion depth (layer 3)

Example shape (placeholders only):

json
{
  "timestamp": "2026-06-10T12:00:00Z",
  "camera_id": "site-role-a",
  "dets": [
    { "c": 0, "p": 0.92, "b": [0.1, 0.2, 0.3, 0.4], "track_id": "<integer>" }
  ],
  "person_count": 1,
  "rf_detr_precomputed": true
}

rf_detr_precomputed: true marks on-device RF-DETR authority (not cloud inference).

Telemetry schema (telemetry)

json
{
  "timestamp": "2026-06-10T12:00:00Z",
  "camera_id": "site-role-a",
  "detections": [{ "c": 0, "p": 0.88, "b": [0.0, 0.0, 0.5, 0.5] }],
  "telemetry": { "die_temp": "<celsius>", "fps": 10 }
}

Required keys for contract verify: timestamp, camera_id, detections, telemetry.die_temp, telemetry.fps.

Health, status, manifest

TopicKey fields
healthstatus, storage_health (OK/WARNING/CRITICAL), cert_fingerprint_present
statusthermal_state (NORMAL/THERMAL_WARN/THERMAL_CRITICAL), die_temp_c, LWT retain
data_manifestChunk index; sidecar: duration_s, keyframe_count, justified, rfdetr_stride_fps

Rates and contract

SignalExpected rateStaleness threshold
telemetry / dets3–15 Hz (nominal ~10 Hz)stale_sec > 120 in proxy cache
health~30 sSame broker path
Schema validity≥ 80% of samplesverify_fleet_contract.py

Run contract verify after deploy or broker changes:

bash
python3 [repo-root]/oak-vms-firmware/scripts/verify_fleet_contract.py \
  --mqtt-host <phantom-proxy> --device-id site-role-a --duration-s 20

Proxy ingest (HTTP)

Preferred read path: proxy subscribes to devices/+/… wildcards (status, telemetry, dets, health, manifest, events) and caches for HTTP.

EndpointReturns
GET /fleet/mqtt/latestPer-device cached telemetry, dets, health, recent_chunks, anomaly_alerts, stale_sec
GET /fleet/mqtt/configBroker host, subscribed wildcards, ingest status

Commands and response shapes: API quick reference. Full route catalog: API reference.

Quick probe:

bash
export PHANTOM_PROXY=https://<phantom-proxy>:8788
curl -s "$PHANTOM_PROXY/fleet/mqtt/latest" | jq '.devices | keys'
curl -s "$PHANTOM_PROXY/fleet/mqtt/config" | jq '.topics_subscribed'

Next steps

Operator depth

Live fleet state and harness evidence live in private operator handoff (not published) (private).