Dashboard Widgets — The SETI Stack
The SETI Stack is SETI AI's visual analytics surface: a freeform canvas where you compose your own operations dashboard from 40+ drag-and-drop widgets. Every widget is live — there is zero mock data in the data path. A widget either shows a real reading from your hardware and services, or it tells you plainly that it is waiting for data. Nothing is invented to make a screenshot look busy.
This page explains the widget catalog, how live data reaches each widget through the AnalyticsBus, and how an operator builds and saves a dashboard.
Related: Power Analytics · Inverter Drivers · Energy Nodes
What you get
- A blank canvas, your layout. You start with an empty board and drag in only the widgets you care about. Pan and zoom across an infinite canvas, drag each widget by its header, and your arrangement is saved automatically.
- Live by default. Widgets poll or stream from real endpoints (
/api/victron,/api/system,/api/analytics/*,/api/notifications/*). Refresh cadences are tuned per widget — fast-moving solar telemetry refreshes every 5–10 seconds, cost analytics every few minutes. - One consistent design language. Gold-accented, dark, dense, Font Awesome icons throughout — the same look across the Command Center, Node Editor, and Setup surfaces.
How a user composes a dashboard
- Open the Analytics Palette. The left sidebar lists every widget, grouped into collapsible sections, with a search box ("Search widgets...") to filter by name.
- Add a widget. Either drag a palette item onto the canvas (drop where you want it) or click it to spawn it at a default position. Widgets are transform-pan and zoom aware, so a dropped widget lands exactly under the cursor regardless of how far you have panned.
- Arrange. Drag any widget by its header to reposition. Mouse deltas are scaled by the current zoom level so dragging always tracks the cursor.
- Bind data-bound widgets (see below) by typing a cluster ID and choosing a metric in the small picker row at the top of the widget body.
- It saves itself. Every change — add, move, remove, or re-bind — calls
saveCanvasState(), which persists the layout both to the browser (localStorage) and to the server (POST /api/canvas/save). Reload the page and your board, including each widget's binding choices, comes back exactly as you left it. - Export / import / clear. The Quick Actions widget and sidebar footer let you export the layout as JSON, reload a saved layout, refresh every widget on the board at once, or clear the canvas.
Because layouts are saved server-side as named canvases, the same dashboard can be recalled across sessions and devices.
AnalyticsBus — the live data backbone (zero mock data)
Data-bound widgets never fetch on their own schedule and never fabricate a number. They subscribe to a shared, single-source-of-truth event bus called the AnalyticsBus:
widget → AnalyticsBus.subscribe(cluster, metric, callback)
The bus delivers updates from three coordinated sources so a widget is both instant and always current:
- Live push (SSE). A Server-Sent Events stream at
/api/analytics/streampushes atelemetryevent every time a workflow writes a new value (/api/pipeline/output). Bound widgets update the moment new data lands. - Poll fallback (30s). A background 30-second poll against
/api/analytics/datakeeps widgets fresh even if the SSE connection drops (the bus auto-reconnects after a 5-second backoff). - Immediate first value. On the very first subscribe, the bus does a one-shot fetch
(
?hours=24) so the widget shows a real reading right away instead of an empty box.
The bus caches the last payload per cluster|metric key and fans it out to every
subscribed widget, so ten widgets watching the same metric cost one data feed, not ten.
Binding controls — point a widget at a data source
Every data-bound widget renders a binding row at the top of its body: a free-text
cluster ID field plus a metric dropdown (Voltage, Current, Temp °C, SOC %,
SOH %, Power). When you change either, the widget transparently unsubscribes and
re-subscribes to the new (cluster, metric) tuple, and the choice is written into the
widget's saved options (node.opts) so it persists across reloads.
This is the bridge between the Node Editor and the dashboard: any workflow that
POSTs to /api/pipeline/output for a given cluster + metric will light up every widget
bound to that pair — live over SSE, or within 30 seconds via poll.
The "no fake data" guarantee in practice. If a widget has nothing real to show, it says so — "awaiting data", "No data yet — collecting…", "No temperature sensor data available", or a
driver_pendingnotice — rather than rendering a random curve. The backend enforces the same rule: energy nodes return{driver_pending: true}when a real reading is not available.
Widget categories
Widgets are organized by category, each with its own accent color. The four DATA families (KPI, Gauge, Chart, Status) are the composable, bind-anything widgets that ride the AnalyticsBus. The rest are purpose-built panels for solar, battery, sites, system health, and operations.
| Category | Color | Purpose |
|---|---|---|
| DATA · KPI | Gold | Single-value / delta / stats readouts |
| DATA · GAUGE | Gold | Dials, bars, donuts, radial indicators |
| DATA · CHART | Gold | Time-series, area, histogram, pie, wave, compare |
| DATA · STATUS | Gold | Lights, alarms, leaderboards, value lists, calendar |
| SOLAR / ENERGY | Gold | Live Victron + multi-brand power surfaces |
| BATTERY | Blue | Fleet SOH, pack breakdown, degradation, cells |
| PIPELINES | Green | Cluster-bound charts, cell grids |
| OPERATIONS | Cyan | Power output, workflow/exec views |
| SITES | Gold | Multi-site overview |
| MONITORING | Red | Alerts, temperature monitor |
| SYSTEM | Blue | Host + Docker health, agent activity, error log |
The catalog
DATA · KPI — single-value readouts (bindable)
| Widget | What it shows |
|---|---|
| Big Number | One large metric value with its label, gold-glow styling |
| Stat Card | Compact value + cluster · metric caption |
| LED Display | Seven-segment style numeric readout |
| Delta Card | Current value plus the change versus the first sample (up/down arrow, color-coded) |
| Trend Arrow | Direction-of-travel indicator for a metric |
| Min / Max / Avg | Three-up summary statistics for the bound series |
DATA · GAUGE — dials and bars (bindable)
| Widget | What it shows |
|---|---|
| Live Gauge | Gold arc gauge with auto-ranged scale per metric (V, A, °C, %, W) and animated center value |
| Tachometer | Sweep-dial style gauge |
| Bar Gauge (H) / Bar Gauge (V) | Horizontal / vertical fill bars |
| Donut % | Percentage ring |
| Range Indicator | Value placed within a low/high band |
| Radial Bars | Concentric radial bar display |
DATA · CHART — time-series (bindable)
| Widget | What it shows |
|---|---|
| Custom Metric Chart | Full ECharts line chart with source picker, metric picker, and 1h/6h/24h/7d range — auto-refreshes every 30s |
| Area Chart | Filled time-series with gradient |
| Sparkline | Minimal inline trend line |
| Wave Display | Oscilloscope-style waveform |
| Histogram | Value distribution bars |
| Pie Chart | Proportional breakdown |
| Compare A vs B | Two clusters, one metric, side by side |
DATA · STATUS — state and history (bindable)
| Widget | What it shows |
|---|---|
| Status Light | Color-coded state lamp |
| Threshold Alarm | Trips on configurable low/high bounds |
| Top-N Leaderboard | Ranked values |
| Recent Values | Rolling list of the latest samples |
| Calendar Heatmap | Year-grid of daily values (ECharts calendar) |
SOLAR / ENERGY — live power surfaces
| Widget | Source | What it shows |
|---|---|---|
| Energy Flow | /api/victron |
Animated Solar → Battery (SETI Power Pack) → Load diagram. Particle density and pipe width scale with real wattage; the battery ring fills to live SoC and turns red below 20%. Footer shows live voltage, current, and "VRM Cloud". Refreshes every 5s. |
| Victron Solar | /api/victron |
SoC ring gauge (color-stepped by charge level) plus voltage, current, power, PV, load, capacity (Ah), consumed Ah, and time-to-go. Shows charging vs discharging state. Refreshes every 5s; cleanly shows "Victron offline" if the feed drops. |
| Power Overview | /api/victron + /api/analytics/history |
Dense, GPU-monitor-style card: four live metric tiles, a metric-selectable sparkline, and a monthly calendar heatmap of daily energy (kWh). See Power Analytics. |
| Inverter Hub | multi-brand | The flagship power console — 6 inverter brands, 10 swappable mini-widgets, drag-to-zoom chart, clickable calendar, 12 time ranges, live badge. See Power Analytics and Inverter Drivers. |
| Energy Cost | /api/analytics/cost |
$/kWh × kWh savings analysis with daily solar-vs-load bars, rate pills, and a monthly savings heatmap. See Power Analytics. |
The three solar widgets — Energy Flow, Victron Solar, and Power Overview — are also packaged as reusable modules in the widget registry (
web/widgets/) so they can be embedded across both the dashboard and the analytics canvas from a single source of truth.
BATTERY — pack health
| Widget | What it shows |
|---|---|
| Fleet SOH | Live battery SoC gauge from Victron VRM (multi-pack SOH trend builds as fleet data accrues) |
| Pack Breakdown | Per-pack SoC bars (SETI Power Pack today; expands with the pack table) |
| Degradation Tracker | SOH-over-time trend, populated automatically from VRM telemetry |
| Cell Voltage Grid | 14S × 5P color-coded per-cell voltage map with hover detail |
PIPELINES / OPERATIONS / SITES / MONITORING
| Widget | What it shows |
|---|---|
| Power Output | Live solar and load summary (links to Power Overview for history) |
| Sites Overview | Per-site status, SoC, and solar table |
| Active Alerts | Live notification history with severity, channel, and delivery status |
| Temperature Monitor | Live battery temperature bar, color-stepped by °C |
SYSTEM — infrastructure health (real Docker/host data)
| Widget | Source | What it shows |
|---|---|---|
| System Health | /api/system |
CPU, RAM, Disk gauges plus uptime, load average, and healthy/total container count |
| Active Nodes | /api/system |
Healthy-vs-down container donut |
| Execution Timeline | /api/system |
Per-container up/down timeline bars |
| Node Usage | /api/system |
Container heatmap |
| Error Log | /api/system |
Unhealthy-first service table with image and status |
| Agent Activity | /api/system |
Live status of Bob, Bill, MQTT, SSE clients, loaded tools, and containers |
| Workflow Runs | /api/canvas/list |
Saved-canvas count with a live sparkline |
| Quick Actions | — | Export layout, refresh all, clear canvas, jump to Command Center |
Why it matters
- Build the view your role needs. A site operator can put Energy Flow, Inverter Hub, and Active Alerts front and center; an analyst can fill a board with bound charts and KPIs tied to specific battery clusters. The layout is yours and it persists.
- Trust every pixel. Because the AnalyticsBus is the single source of truth and the backend refuses to fake readings, a number on the SETI Stack is a real number from real hardware or a real service — never a placeholder.
- One canvas, live end to end. Workflows in the Node Editor publish to clusters; widgets on the dashboard subscribe to them. Data flows from your inverters and batteries through the pipeline and onto the screen with no manual refresh.