Skip to main content
Version: 3.0 (next)

Azure IoT Edge Trigger Nodes

Overview​

When MaestroHub runs as an Azure IoT Edge module, two triggers start pipelines from the local edge hub:

  • Azure IoT Edge Input Trigger — one run per message an edge hub route delivers to one of MaestroHub's module inputs: results from an analytics or AI module, or data from a device behind the edge gateway.
  • Azure IoT Edge Twin Trigger — one run per change to the desired properties of MaestroHub's module twin, for example configuration pushed to many devices through an IoT Hub deployment.
  • Azure IoT Edge Method Trigger — one run per direct-method call a cloud application makes on MaestroHub's module; the pipeline answers with a Respond to Direct Method node.

All three keep working while the device is offline from Azure: the messages come from the edge hub on the device.


Core Functionality​

Routes decide what arrives. An input receives a message only when a route delivers to it, for example FROM /messages/modules/anomaly-detector/outputs/alerts INTO BrokeredEndpoint("/modules/maestrohub/inputs/alerts"). Without a route the trigger never fires.

At-least-once delivery. MaestroHub acknowledges an input message only after the run's trigger event is stored, so the edge hub keeps a message until then and a message can arrive twice after a reconnect. Deduplicate on $trigger._metadata.sys_mid where that matters.

No missed configuration. With Sync Full Twin (the default), the twin trigger delivers the full desired properties when the pipeline is enabled, and again after a reconnect if they changed while MaestroHub was away. Each desired version is delivered once: a patch and a resync of the same version never both run.

Refused subscriptions are reported. If the edge hub refuses a subscription, it fails with an error naming the filter instead of silently never firing.


Configuration Options​

Parameters​

ParameterTypeDefaultRequiredConstraintsDescription
Connection IDstring""Yes--Azure IoT Edge connection profile to use.
Function IDstring""Yes--A Receive on Input function (input trigger), a Module Twin Desired Changes function (twin trigger) or a Receive Direct Method function (method trigger) of the connection.
Trigger Modeselect"always"Noalways / onChangeonChange: the input trigger suppresses a body identical to the last one on the same input; the twin trigger suppresses a repeated version. The method trigger has no Trigger Mode: every call runs.
EnabledbooleantrueNo--Enable or disable the trigger.

The function carries the rest: the Input Name (or * for every input), or the twin Property Filter and Sync Full Twin switch.


Output​

Input trigger​

The message body is under result; everything else is under _metadata, as strings.

{
"_metadata": {
"type": "azureiotedge_input_trigger",
"connectionId": "7b2a0cf0-c9f5-444c-835e-fc2cb957be07",
"functionId": "85bab7a5-70da-4bb3-9639-9a59a414c01f",
"protocol": "azureiotedge",
"inputName": "alerts",
"sys_mid": "m-8121",
"sys_cmid": "anomaly-detector",
"sys_cdid": "factory-edge-01",
"attr_line": "3",
"timestamp": "2026-09-28T10:30:00.123456789Z"
},
"result": { "anomaly": true, "line": 3 }
}
FieldExpressionDescription
Message Body$trigger.resultThe message body (parsed JSON object, or the raw value)
Input Name$trigger._metadata.inputNameThe input the route delivered to
System properties$trigger._metadata.sys_<name>One per system property: sys_mid (message id), sys_cid (correlation id), sys_cdid (sending device), sys_cmid (sending module), sys_ct (content type), sys_ce (content encoding)
Application properties$trigger._metadata.attr_<name>One per application property, for example $trigger._metadata.attr_line
Protocol$trigger._metadata.protocolAlways azureiotedge
Connection ID$trigger._metadata.connectionIdThe connection profile used
Function ID$trigger._metadata.functionIdThe function that received the message
Trigger Type$trigger._metadata.typeAlways azureiotedge_input_trigger
Timestamp$trigger._metadata.timestampWhen MaestroHub received the message

Twin trigger​

result is the desired-properties patch, or the full desired properties on a resync, including $version.

{
"_metadata": {
"type": "azureiotedge_twin_trigger",
"connectionId": "7b2a0cf0-c9f5-444c-835e-fc2cb957be07",
"functionId": "85bab7a5-70da-4bb3-9639-9a59a414c01f",
"protocol": "azureiotedge",
"version": "4",
"isFullTwin": "false",
"timestamp": "2026-09-28T10:30:00.123456789Z"
},
"result": { "sampling": { "line3": "5s" }, "$version": 4 }
}
FieldExpressionDescription
Desired properties$trigger.resultThe patch, or the full desired properties when isFullTwin is "true"
Version$trigger._metadata.versionThe desired-properties version
Full twin$trigger._metadata.isFullTwin"true" for the full desired properties delivered on enable or after a reconnect, "false" for a patch
Protocol$trigger._metadata.protocolAlways azureiotedge
Connection ID$trigger._metadata.connectionIdThe connection profile used
Function ID$trigger._metadata.functionIdThe function that received the change
Trigger Type$trigger._metadata.typeAlways azureiotedge_twin_trigger
Timestamp$trigger._metadata.timestampWhen MaestroHub received the change

Method trigger​

result is the call's JSON payload.

{
"_metadata": {
"type": "azureiotedge_method_trigger",
"connectionId": "7b2a0cf0-c9f5-444c-835e-fc2cb957be07",
"functionId": "85bab7a5-70da-4bb3-9639-9a59a414c01f",
"protocol": "azureiotedge",
"methodName": "setRecipe",
"requestId": "17",
"deadline": "2026-09-28T10:30:25Z",
"timestamp": "2026-09-28T10:30:00.123456789Z"
},
"result": { "recipe": "B7" }
}
FieldExpressionDescription
Call payload$trigger.resultThe JSON the caller sent
Method$trigger._metadata.methodNameThe method called
Request ID$trigger._metadata.requestIdThe call to answer — map it into the Respond to Direct Method node
Deadline$trigger._metadata.deadlineWhen the response budget runs out
Protocol$trigger._metadata.protocolAlways azureiotedge
Connection ID$trigger._metadata.connectionIdThe connection profile used
Function ID$trigger._metadata.functionIdThe function that received the call
Trigger Type$trigger._metadata.typeAlways azureiotedge_method_trigger
Timestamp$trigger._metadata.timestampWhen MaestroHub received the call

Answering in time. IoT Hub does not tell the module how long the caller waits, so the Receive Direct Method function has a Response Budget (25 s by default, below IoT Hub's default 30 s call timeout). If the pipeline has not answered within it, the caller gets 504 with the reason, unless Answer 504 When Late is off. A call for a method no pipeline handles is answered 501 at once. A call still waiting when MaestroHub's connection to the edge hub ends — including the reconnect that renews its token, at 80% of the token lifetime — is answered 503; retry it.

Every call runs its pipeline: the method trigger never suppresses a repeated call, whatever the Trigger Mode.

Strings, not booleans

$trigger._metadata.isFullTwin is the string "false", which is truthy in an expression. Compare it explicitly: {{ $trigger._metadata.isFullTwin == "true" }}.


Usage Examples​

Act on an AI module's results​

Scenario: an anomaly-detection module sends {"anomaly":true,"line":3} on its output alerts.

Configuration: route FROM /messages/modules/anomaly-detector/outputs/alerts INTO BrokeredEndpoint("/modules/maestrohub/inputs/alerts"); a Receive on Input function with Input Name alerts. The pipeline writes a stop bit to the PLC when $trigger.result.anomaly is true.

Configuration from IoT Hub​

Scenario: operations sets {"sampling":{"line3":"5s"}} in the module twin's desired properties on 200 devices.

Configuration: a Module Twin Desired Changes function with Sync Full Twin on. The pipeline applies $trigger.result.sampling and reports the applied value back with the Twin Report node.