Skip to main content
Every widget on a dashboard is remotely drivable. When a message arrives at the dashboard containing a widget ID, the dashboard applies it to that widget immediately — no refresh, no polling. This page documents the exact payload keys the dashboard listens for.

Mental model

Think of each widget as having a radio receiver tuned to its widget ID. Any message addressed to the dashboard whose payload names that ID is picked up by that widget — and depending on which keys the payload carries, the widget changes its value, its visibility, or even its position, size, and rotation on the canvas, live. The firmware helpers (updateWidget, updateWidgetPosition, …) are just conveniences that build these payloads for you — a device can also send them raw.

The envelope

A device sends the standard message envelope; the dashboard reads the payload:
{
  "targetId": "<dashboard / user id>",
  "payload": { "widgetId": "tempGauge", "value": 27.4 }
}
Everything below describes what goes inside payload.

Payload reference

Value update — value

{ "widgetId": "tempGauge", "value": 27.4 }
Sets the widget’s value: a number for a Gauge/Slider, text for a Label, an array for a Chart/Heatmap, text to speak for Text-to-Speech, a URL for an Image.
{ "widgetId": "statusLabel", "value": "Pump running" }
No value key? The whole payload becomes the value. If the payload has other keys (besides widgetId and the transform keys), they’re passed to the widget as an object — this is how structured widgets receive rich data:
{ "widgetId": "adi", "roll": 12.5, "pitch": -3.2 }
The Attitude Indicator receives { roll: 12.5, pitch: -3.2 }. The 3D Viewer accepts { roll, pitch, yaw, modelUrl, modelColor, autoRotate, zoom, … } the same way.

Visibility — v

{ "widgetId": "alertPanel", "v": 1 }
1 shows the widget, 0 hides it — reveal an alert panel or hide controls from the device side.

Position, size, rotation — x y w h r

{ "widgetId": "marker", "x": 120, "y": 80 }          // move
{ "widgetId": "panel",  "w": 400, "h": 250 }          // resize
{ "widgetId": "needle", "r": 45 }                     // rotate (degrees)
{ "widgetId": "hud",    "x": 10, "y": 10, "w": 200, "h": 120, "r": 0 }
Any combination works, numbers or numeric strings. The widget moves/resizes/ rotates on the canvas in real time — a device can literally animate the layout.

Countdown control — hr min sec

{ "widgetId": "runTimer", "hr": 0, "min": 5, "sec": 30 }
Starts the Countdown Timer with that duration (5m30s here).

Toast notification — no widget ID

{ "type": "toast", "text": "Watering complete", "visibility_time": 4000 }
Shows a toast on the dashboard for visibility_time ms (min 2s, default 5s). For richer dialogs, use the firmware dialog helpers.

How the firmware helpers map to these messages

Firmware call (Arduino)Payload it sends
updateWidget(target, "id", 27.4){ "widgetId": "id", "value": 27.4 }
updateWidget(target, "id", "text"){ "widgetId": "id", "value": "text" }
updateWidgetPosition(target, "id", x, y, w, h, r){ "widgetId": "id", "x", "y", "w", "h", "r" }
updateCountdown(target, "id", "0", "5", "30"){ "widgetId": "id", "hr", "min", "sec" }
updateFlightAttitude(target, "id", roll, pitch){ "widgetId": "id", "roll", "pitch" }
sendTo(target, builder)Any raw payload you build — full control
The ESP-IDF hyperwisor_update_widget_* functions produce the same shapes.

Worked examples

Change a label’s text from the device

// Arduino — the label with ID "statusLabel" updates instantly
device.updateWidget(targetId, "statusLabel", String("Cycle complete"));

Move and rotate a widget from the device

device.sendTo(targetId, [](JsonObject &p) {
  p["widgetId"] = "windArrow";
  p["r"] = heading;          // rotate to the live heading
});

device.updateWidgetPosition(targetId, "marker", 120, 80, 40, 40);

Reveal an alert panel when something goes wrong

device.sendTo(targetId, [](JsonObject &p) {
  p["widgetId"] = "alertPanel";
  p["v"] = 1;                // show it
});

Test it with no hardware

Open the LiveLink Simulator, connect the Device side, and send any of the JSON payloads above from the Send from Device panel — watch the widget react on the dashboard.

Typed message variants

Devices can also send typed messages ("type" + widget-specific key); the dashboard processes these too:
typeKey it reads
widget_updatevalue (any)
widget_statusstatus (string)
widget_gauge / widget_slidervalue (number)
widget_switchchecked (boolean)
widget_buttonaction (+ optional value)
widget_heatmapvalue (array of points)
widget_text_to_speechvalue (text to speak)
The direct payload format above is the recommended one — it’s what the firmware helpers emit.

Binding data

The widget-ID contract these messages ride on.

LiveLink Simulator

Fire these payloads with no hardware.