Skip to main content
The Triggers tab is where a widget does something — when the user interacts with it, it sends a command to a device. If you’ve struggled with Triggers, it’s almost always because the four-step model wasn’t clear. Here it is in full.

The mental model

Hold three ideas in your head and Triggers stop being confusing:

1 · A widget is a remote

Interacting with it fires an event (a press, a toggle, a slide). That’s the signal.

2 · A trigger is the wiring

You decide what that signal sends and where: a command, to a device. That’s the whole job of the Triggers tab.

3 · Firmware is the receiver

Your device matches the command/action and acts on it — reading any values that rode along.
In one line:
The dashboard is the sender; your firmware is the receiver. A trigger is the wire between them. Everything on this page is just filling in that wire.
And the key thing people miss: value widgets carry a payload. A slider, color picker, or form automatically sends its current value along the wire (under a known key) — you don’t route it by hand. More on that below.

The model: WHEN → SEND TO → EXECUTE → Action

Every trigger reads as one sentence:
WHEN this event fires → SEND TO a device → EXECUTE a command → run an Action (with parameters).
Those four pills are exactly what you see in the editor. You build a trigger by filling them in, top to bottom.

Step by step

1

Add Event — the WHEN

Click Add Event and pick when this trigger fires — e.g. click for a Button, toggle for a Switch, threshold for a Gauge. Each widget offers only the events it can actually fire (see the table below).
2

Add Target — the SEND TO

Click Add Target and choose which device receives the command:
  • Current Device — the device this dashboard is bound to (the common case)
  • Manual Device ID — type a specific device/target ID to send elsewhere
You can add multiple targets to send the same action to several devices.
3

Add Command — the EXECUTE

Click Add Command and pick one of your product’s commands (Select command…), or type a command name. These are the commands you defined when you created the product.
4

Add Action — with parameters

Under the command, Add Action and pick the action (e.g. ON, OFF, setSpeed). Give it parameters as JSON if the action needs input:
{ "speed": 80, "unit": "rpm" }
Leave params empty ({}) for actions that take none.
That’s one complete trigger. A widget can have several — e.g. a Switch with a on trigger and an off trigger.

What actually gets sent

Under the hood, a trigger builds this message to each target and sends it when the event fires:
{
  "targetId": "<device>",
  "payload": {
    "commands": [
      { "command": "Operate", "actions": [ { "action": "ON", "params": {} } ] }
    ]
  }
}
Your firmware receives it and acts on it via setUserCommandHandler — that’s the “down” half of the core loop.

Which events each widget fires

Every widget supports the common lifecycle eventsload, ready, destroy, update, visible, hidden — plus its own interaction events:
WidgetEvents (beyond the common ones)
Buttonclick, doubleclick, longpress, push, release, hover
Switchtoggle, on, off, change, click
SliderslideStart, slide, slideEnd, change, min, max
Gaugethreshold, min, max, change
Form / Database Formsubmit, input, change, focus, blur
Text Inputinput, change, submit, clear, focus, blur, keydown, keyup, keypress
Color Pickerchange, select
Chart / Tabledataload, datafail, refresh, select
Joystickchange, touchstart, touchend
Image / SVGclick, hover, loaded, error
Labelclick, hover
Payment WidgetpaymentSuccess, paymentFailed
Countdown Timercomplete, start, pause, reset
Voice to TextspeechStart, speechEnd, speechResult
Text to SpeechspeechStart, speechEnd, complete
Navigate / URL Buttonclick
WebRTC (viewer/camera)loaded, error
Map / Mission Planning Mapclick, change, select

Widgets that emit a value (auto-injected params)

Some widgets don’t just fire an event — they emit a value (a slider’s position, a picked color, a form’s fields). For these, the platform automatically injects that value into every action’s params when the event fires. You do not type the live value by hand.
WidgetOn these eventsInjected into params as
Sliderslide, slideEnd, change{ "value": <number> }
Color Pickerchange, select{ "color", "hex", "rgb", "r", "g", "b", "hsl", "h", "s", "l", "hsv", "cmyk" }
Form / Database Formsubmitthe field values, keyed by field ID — { "<fieldId>": <value>, … }

How the merge works

The injected value is merged into the static params you configured, and wins on a key clash:
your static params   +   injected value   =   what the device receives
{ "unit": "rpm" }        { "value": 80 }       { "unit": "rpm", "value": 80 }
So for a slider, leave the action’s params as {} (or add extra static keys) — the value key arrives automatically. In firmware, read it as params["value"].
This means your firmware just reads a stable key: params["value"] for a slider, params["color"] (or params["hex"]) for a color picker, and params["<fieldId>"] for each form field. You never wire the live value through the editor by hand.

Reading emitted values in firmware (Arduino)

In your command handler, use findParams(msg, command, action) to get the action’s params, then read the injected key. These match the dashboard triggers above. Slider → params["value"]
device.setUserCommandHandler([](JsonObject &msg) {
  // Trigger: WHEN change → Motor → setSpeed
  JsonObject p = device.findParams(msg, "Motor", "setSpeed");
  if (!p.isNull()) {
    int speed = p["value"];              // the slider's live position
    analogWrite(MOTOR_PIN, speed);
  }
});
Color Picker → params["color"] / r g b
JsonObject p = device.findParams(msg, "Light", "setColor");
if (!p.isNull()) {
  const char* hex = p["color"];          // e.g. "#ff8800"
  int r = p["r"] | 0;                    // per-channel components
  int g = p["g"] | 0;
  int b = p["b"] | 0;
  setRGB(r, g, b);
}
Form → params["<fieldId>"]
JsonObject p = device.findParams(msg, "Config", "save");
if (!p.isNull()) {
  const char* name  = p["deviceName"];   // form field IDs
  int         limit = p["maxTemp"];
  // apply the submitted settings
}
p["r"] | 0 uses ArduinoJson’s default-value operator — it yields 0 if the key is missing, so a partial payload won’t crash. The command and action names in findParams(...) must match the trigger’s EXECUTE command and Action.

Conditional events (the “when a value crosses…” case)

For value widgets, some events are the condition:
  • Gauge → threshold / min / max — fires when the bound value crosses that point. Example: a Gauge with a threshold trigger that sends Operate → OFF when temperature exceeds the limit.
  • Slider → min / max — fires at the ends of the range.
For richer conditional logic (“if X and Y, then…”), use the user-facing Rules engine instead — Triggers are the direct event-to-command wiring on a single widget.

Worked examples

A button that starts a device

WHEN     click
SEND TO  Current Device
EXECUTE  Operate
Action   START   params: {}

A switch that toggles a relay

Trigger 1:  WHEN on  → Current Device → Operate → ON   { "relay": 1 }
Trigger 2:  WHEN off → Current Device → Operate → OFF  { "relay": 1 }

A slider that sets speed live

The slider’s position is injected automatically as value — leave params empty.
WHEN     change
SEND TO  Current Device
EXECUTE  Motor
Action   setSpeed   params: {}      ← the device receives { "value": <position> }
Firmware reads it with params["value"]. Add extra static keys if you want them alongside — e.g. { "unit": "rpm" } → device gets { "unit": "rpm", "value": 80 }.

A gauge that shuts things off past a threshold

WHEN     threshold
SEND TO  Current Device
EXECUTE  Operate
Action   OFF   params: {}

Tips & gotchas

The command and action names in a trigger must match the commands you defined on the product. If a dropdown is empty, define the command first in API Commands or the product wizard.
  • Params must be valid JSON — the editor flags Invalid JSON. Use {} for no parameters.
  • “Current Device” vs. “Manual Device ID” — use Current Device unless you’re intentionally commanding a different device from this widget.
  • Multiple triggers per widget — a Switch typically needs two (one for on, one for off).
  • No hardware to test? Fire the trigger and watch it arrive in the LiveLink Simulator’s Device side.

Define commands first

The commands your triggers execute.

The core loop

How commands reach the device.