Skip to content

Automating on device data ​

To react to what a device sends, attach a Device MQTT trigger to a workflow. Each matching message a device publishes starts one run of the workflow, with the message as the workflow input.

Device MQTT triggers are independent of metric recording. They fire on any topic a device publishes to, including s/metrics and topics of your own such as events/door.

Create the trigger ​

In the console, open the workflow, go to Triggers, choose Add Trigger and select the type Device MQTT. Or use the createWorkflowTrigger mutation:

graphql
mutation AddDeviceMqttTrigger($input: CreateWorkflowTriggerInput!) {
  createWorkflowTrigger(input: $input) {
    trigger {
      id
      name
      isEnabled
    }
    errors {
      path
      message
    }
  }
}
json
{
  "input": {
    "workflowId": "wfl_…",
    "name": "Oven too hot",
    "config": {
      "deviceMqtt": {
        "topic": "s/metrics",
        "deviceId": "dev_…",
        "filter": "{\"some\":[{\"var\":\"mqtt.payload.points\"},{\"and\":[{\"==\":[{\"var\":\"name\"},\"temperature\"]},{\">\":[{\"var\":\"value\"},80]}]}]}"
      }
    }
  }
}
FieldNotes
topicRequired. The device-relative topic, as the device publishes it. MQTT wildcards + (one level) and # (all remaining levels) are allowed, for example events/+. Do not include a device or tenant prefix; a topic starting with t/ is rejected.
deviceIdOptional dev_… ID. Leave it out to match every device in the tenant.
filterOptional JSONLogic rule, passed as a JSON string. The workflow only starts when the rule is truthy.

Triggers are enabled when created (isEnabled defaults to true). A new trigger starts listening within a few seconds. Changing the topic, device or filter of a trigger that is already listening does not take effect on its own: disable the trigger, wait a few seconds, then enable it again.

Only messages from devices connected with a valid device token ID as client ID are considered (see Connecting a device).

What the workflow receives ​

The filter is evaluated against this object:

json
{
  "mqtt": {
    "relativeTopic": "s/metrics",
    "topic": "…",
    "deviceId": "dev_…",
    "tenantId": "…",
    "fromClient": "dtk_…",
    "qos": 1,
    "retain": false,
    "receivedAt": "2026-09-24T10:15:00Z",
    "payloadRaw": "{\"points\":[…]}",
    "payload": { "points": [ … ] }
  }
}
  • relativeTopic is the topic as the device published it. topic is the broker's internal form of it and includes a namespace prefix.
  • payload is the message parsed as JSON, or null if it is not JSON. payloadRaw is the message as text.

The workflow input is the same object, plus the payload's top-level keys copied alongside mqtt. For the metrics message above, a workflow can read either mqtt.payload.points or points. A payload that is JSON but not an object (an array or a number) is available as payload instead.

In the filter, some sets var to each element of the array it walks, which is why the example reads name and value directly.

Example: a Lua script node ​

A root script node receives the workflow input as its first vararg. This one sends a notification when a temperature reading is above 80:

lua
-- A root script node receives the workflow input as its first vararg.
local input = ...
local mqtt = input.mqtt

local hot = {}
for _, point in ipairs(input.points or {}) do
  if point.name == "temperature" and point.value > 80 then
    table.insert(hot, point.value)
  end
end

if #hot == 0 then
  return { alerted = false }
end

local ok, res = ctx.notify.send({
  group = "ops-team",
  subject = "Temperature alert",
  body = "Device " .. mqtt.deviceId .. " reported " .. tostring(hot[1]) .. " on " .. mqtt.relativeTopic,
})
if not ok then error(res) end

ctx.log.info("temperature alert sent for " .. mqtt.deviceId)
return { alerted = true, readings = #hot }

Replace ops-team with the name or ID of one of your notification groups. The script's return value becomes the node's output. See the Lua API overview for what else a script can call.

Things to know ​

  • One message starts one run. A device that publishes every second starts a workflow every second, so narrow the trigger with deviceId, a specific topic and a filter, and choose a concurrencyPolicy that suits the load.
  • A device only sees its own topics: platform events (such as job changes) are not delivered to devices, and a device cannot subscribe to other devices' topics. To react to platform events, use an event trigger on the workflow instead.

Connect machines, automate workflows, and build custom apps for print production.