Skip to content

Dashboard

A built-in, read-only status page at port 8080. Stdlib Python + one self-contained HTML page per view: no framework, no CDN, no external assets, because the whole point is working where there is no Internet.

Live view (/)

  • 24h strip chart: one row per node, events as color-coded ticks (vehicle amber, vibration ember, contact teal, wireless slate). Correlated events line up vertically across rows: the chart shows the fusion logic structurally.
  • Nodes: per-node last-seen and totals; nodes silent past 30 minutes flag in red.
  • Notification log: the last 40 delivery attempts with ✓/✗ and errors.
  • Recent events: live feed, refreshing every 5 s, with an "unknown & strong signals only" filter that hides whitelisted gear and weak sightings.

History search (/history)

Searches all recorded activity (pre-v0.2 detections are backfilled in):

  • free text: matches node names, event names, and meta content including MACs
  • type / node / event dropdowns, populated from the actual data
  • date/time range with native pickers, converted to UTC for the query
  • 100 rows per page with "load older"

Night mode

The NIGHT toggle switches both pages to red-flashlight mode: every color becomes a brightness-ranked red so checking the dashboard at 2 AM doesn't destroy your night vision. Event types rank by brightness (hue carries no meaning under red light). Persisted per browser; ?theme=night deep-links it.

Mobile

Both pages are built for one-handed phone use: the event feed leads the live view, feed rows break MACs onto their own full-width line, history results render as card rows with collapsed-by-default filters, and nothing ever scrolls horizontally.

API

The dashboard's endpoints are plain JSON over GET, usable by scripts and automations directly:

Endpoint Returns
/api/events?limit= recent canonical events, newest first
/api/nodes per-node last-seen and event count
/api/notifications?limit= alert delivery attempts per channel
/api/search?q=&type=&node=&event=&from=&to=&limit=&offset= filtered event search
/api/facets distinct types/nodes/events for filter UIs

Security posture

Read-only by design: no arm/disarm buttons, no configuration endpoints; control stays on the secret-gated MQTT topic. All MQTT-sourced strings are HTML-escaped before rendering (sensor names arrive from a broker that may allow anonymous LAN publishes; see Arming & Security).