Azure IoT Edge Integration Guide
Azure IoT Edge runs containerised modules on a factory edge device. A local edge hub routes messages between the modules and to Azure IoT Hub, and buffers them while the device is offline.
The Azure IoT Edge connector makes MaestroHub a module on that device. MaestroHub talks only to the local edge hub, never directly to the cloud; edge routes decide where its messages go.
Overview
The connector provides:
- Send to Output — publish a message on a named module output. Routes deliver it to IoT Hub (
$upstream) or to another module's input. - Report Module Twin Properties — patch the module twin's reported properties, so the cloud can query edge status.
- Read Module Twin — read the desired configuration and reported properties with their versions.
- Receive on Input — start a pipeline for each message routed to one of MaestroHub's module inputs.
- Module Twin Desired Changes — start a pipeline when the cloud changes MaestroHub's desired properties.
- Direct methods — let a cloud application call a method on MaestroHub and get the pipeline's answer.
- Two authentication methods — through the IoT Edge runtime with nothing secret stored, or with a module key.
- Edge CA trust only — the edge hub's certificate is verified against the edge device's own CA. Public roots are never trusted and verification is never skipped.
- Store & Forward for Send to Output and Report Module Twin Properties while the edge hub is unreachable.
The edge hub buffers messages while the device is offline from Azure (for the route's time to live, 2 hours by default). MaestroHub's Store & Forward buffers them while the edge hub itself is unreachable from MaestroHub — for example while it restarts.
Connection Configuration
Navigate to Connections → New Connection → Azure IoT Edge.
Authentication
| Method | When to use | What you enter |
|---|---|---|
| IoT Edge runtime (default) | MaestroHub is deployed as an IoT Edge module | Nothing. The identity comes from the module's IOTEDGE_* environment, and the IoT Edge runtime signs its tokens and supplies the edge CA. |
| Module key | MaestroHub runs next to the IoT Edge runtime, not as a module | The module identity, its key, the edge hub host and the edge CA certificate |
When MaestroHub is not running as an IoT Edge module, IoT Edge runtime is shown disabled with the reason.
Module key fields
| Field | Required | Description |
|---|---|---|
| IoT Hub Hostname | Yes | The IoT Hub the edge device belongs to, e.g. myhub.azure-devices.net |
| Edge Device ID | Yes | The IoT Edge device identity |
| Module ID | Yes | The module identity MaestroHub connects as |
| Module Key | Yes | The module identity's primary or secondary key (Base64). Stored encrypted. |
| Edge Hub Host | Yes | Host name of the edge device. MaestroHub dials it and checks the edge hub certificate against it. |
| Edge Hub Port | No | Default 8883, where the edge hub listens inside the edge network. Also applies under IoT Edge runtime authentication, if the edge hub is published on another port. |
| Edge CA Certificate (PEM) | Yes | The edge device's root CA certificate |
Advanced fields
| Field | Default | Description |
|---|---|---|
| TLS Server Name | Edge Hub Host | The name the edge hub certificate is issued for, when it differs from the host you dial |
| Workload API Socket | IOTEDGE_WORKLOADURI | Override for the IoT Edge workload API socket (unix:///…). IoT Edge runtime authentication only. |
| SAS Token Lifetime | 1h | Between 5m and 24h. The connection renews its token by reconnecting at 80% of the lifetime. |
| Keep Alive | 60s | Between 10s and 29m, and less than half the token lifetime |
| Connection Timeout | 30s | Between 5s and 300s |
One connection per module identity
The edge hub keeps one session per module identity: when a second client connects as the same identity, the edge hub closes the first. MaestroHub therefore refuses to create a second connection — in any organization on the same instance — that uses a module identity another connection already uses. Cloning an Azure IoT Edge connection is refused for the same reason.
Test Connection on a connection that is running opens a second session with the same identity, so it briefly interrupts the running connection, which then reconnects.
Test Connection also reads the module twin, which needs IoT Hub. When IoT Hub does not answer (for example, the hub's daily message quota is used up, or the hub is throttling), the test still succeeds, because the local link works, and it shows a warning that twin functions fail until the hub answers. Sending to outputs and receiving inputs keep working meanwhile.
Functions
Send to Output
| Parameter | Required | Description |
|---|---|---|
| Output Name | Yes | The module output. Routes select messages by it: FROM /messages/modules/<module>/outputs/<name>. Must not contain /, # or +. |
| Data | Yes | The message body. Text is sent as-is; a JSON value is sent as JSON. |
| Message Properties | No | Application properties that route queries can filter on. Names starting with $ or iothub- are reserved and rejected. |
| Content Type | No | Default application/json |
| Content Encoding | No | Default utf-8. Route queries on the body need application/json and utf-8. |
| Message ID | No | Leave empty to generate a unique ID for each message. A message resent by Store & Forward also gets a new ID, so consumers cannot use it to spot duplicates. |
| Correlation ID | No | Carried with the message |
| QoS | No | 1 (default) waits for the edge hub to acknowledge; 0 does not. |
Success means the edge hub accepted and stored the message — not that it was delivered. A message whose output no route matches is dropped by the edge hub, and MaestroHub cannot see routes. The result names the output so you can check it against your routes.
Result:
{ "outputName": "telemetry", "topic": "devices/edge-01/modules/maestrohub/messages/events/%24.on=telemetry&…", "bytesWritten": 156, "qos": 1, "messageId": "…" }
Report Module Twin Properties
| Parameter | Required | Description |
|---|---|---|
| Reported Properties | Yes | JSON object merged into the reported properties. A null value deletes that property. |
Result: { "statusCode": 204, "version": "12", "bytesWritten": 89 }
Read Module Twin
| Parameter | Default | Description |
|---|---|---|
| Section | all | all, desired or reported |
Result: { "section": "all", "desired": { …, "$version": 4 }, "reported": { …, "$version": 12 } }
Receive on Input
Starts a pipeline for each message an edge hub route delivers to one of MaestroHub's module inputs. See the Azure IoT Edge Triggers.
| Parameter | Required | Description |
|---|---|---|
| Input Name | Yes | The input, as named in the route's BrokeredEndpoint("/modules/<module>/inputs/<name>"), or * for every input |
Module Twin Desired Changes
Starts a pipeline when the desired properties of MaestroHub's module twin change.
| Parameter | Default | Description |
|---|---|---|
| Property Filter | every change | Top-level desired property names to react to |
| Sync Full Twin | on | Deliver the full desired properties when the pipeline is enabled, and after a reconnect if they changed while MaestroHub was away |
Receive Direct Method
Starts a pipeline for each direct-method call a cloud application makes on MaestroHub's module, for example az iot hub invoke-module-method --method-name setRecipe.
| Parameter | Default | Description |
|---|---|---|
| Method Name | — (required) | The method to handle, or * for every method |
| Response Budget | 25s | How long the pipeline has to answer. Keep it below the caller's timeout (30 s by default); IoT Hub does not tell the module the caller's timeout. |
| Answer 504 When Late | on | Answer the caller with 504 and the reason when the pipeline has not answered within the budget |
A call for a method no pipeline handles is answered 501 at once.
Respond to Direct Method
Answers a call received by Receive Direct Method.
| Parameter | Required | Description |
|---|---|---|
| Request ID | Yes | {{ $trigger._metadata.requestId }} from the trigger |
| Status | No | Default 200; 100–599 |
| Payload | Yes | JSON returned to the caller, up to 128 KB. Text that is not JSON is sent as a JSON string. |
A call is answered once, and only while its caller waits: not after the response budget ran out, and not after MaestroHub's connection to the edge hub restarted since the call arrived (the caller got 503). This function is never buffered by Store & Forward.
Running MaestroHub as a module
To deploy MaestroHub as an IoT Edge module — the module definition, routes and the edge hub's offline time to live — follow Run MaestroHub as an Azure IoT Edge Module.
Delivery guarantees
Delivery is at least once. The edge hub does not deduplicate, and a message can be sent twice when the connection drops before the edge hub's acknowledgement arrives. Deduplicate downstream on the message ID.
Limits
| Limit | Value | What happens above it |
|---|---|---|
| Message size (body and properties) | 256 KB | Refused permanently, never retried. With Store & Forward enabled on the connection, the message goes straight to the dead-letter queue; without it, the node fails. |
| Reported-properties patch | 32 KB | Same |
| Direct-method answer | 128 KB | The Respond to Direct Method node fails at once |
What the connector cannot see
- Routes. A module cannot read the edge hub's routes. An output with no matching route is dropped silently by the edge hub.
- Upstream time to live. While the device is offline from Azure, the edge hub keeps messages for the route's time to live (2 hours by default) and then drops them. Raise
timeToLiveSecsin the edge hub's deployment if outages can last longer.
Starting without internet
When the device starts with no connection to Azure, the IoT Edge runtime tries to reach IoT Hub before it uses its cached identities. With IoT Edge runtime authentication, it can then take a few minutes to sign MaestroHub's token. Until it does, the connection keeps retrying and its error says it is still waiting for the runtime. It connects on its own as soon as the runtime answers, while the device is still offline, and local routes and pipelines work from then on.