Embedded Edge Agent MQTT Specification

The Losant Embedded Agent (EEA), while technically protocol agnostic, is designed with the intention that your edge applications will be communicating with Losant through its MQTT broker. This document outlines the MQTT subscriptions, topics, and payloads that are specific to EEA implementations.

MQTT Connection

Embedded Devices, which are the Losant device class to which Embedded Workflows can be deployed, connect to the MQTT broker just like Standalone, Gateway, and Edge Compute devices. Refer to the MQTT documentation for details.

MQTT Topic Subscriptions for EEA

This section lists the topics that are required for most EEA implementations. The Losant MQTT broker supports communication over any arbitrary topics, and the EEA supports receiving messages from any topic, so your edge application may optionally subscribe to additional topics beyond what’s listed here.

The <device_id> should be replaced with the ID of the Embedded Device on which the EEA is deployed.

losant/<device_id>/toAgent/flows

The flows topic receives compiled WebAssembly (WASM) modules whenever a workflow is deployed to a device. Messages received over this topic should be intercepted by your application code and not sent to the EEA.

The payload is the raw bytes that make up the WASM module, which can be directly loaded into your specific WASM runtime. When a WASM module is received on this topic, your application should destroy any existing WASM runtime and instantiate a new one using the new module.

losant/<device_id>/toAgent/virtualButton

The virtualButton topic receives a message whenever a user clicks a Virtual Button in a workflow version deployed to the device. Received messages should be directly forwarded to the EEA using eea_message_received, which will result in the execution of any matching Virtual Button Triggers.

losant/<device_id>/command

The command topic receives a message whenever a Device Command is sent to this device. If your solution does not utilize device commands, you are not required to subscribe to this topic. Received messages should be directly forwarded to the EEA using eea_message_received, which will result in the execution of any matching Device: Command Triggers.

Custom Topics

If your Embedded Workflows make use of any MQTT Triggers, it is necessary to also subscribe to the custom topics configured within those triggers, or else they will never fire. Received messages should be directly forwarded to the EEA using eea_message_received, which will result in the execution of any matching MQTT Triggers.

Publishing Messages Generated by Embedded Workflows

Device: State Nodes, MQTT Nodes, and Debug Nodes all require publishing messages to Losant’s MQTT broker. When the EEA invokes one of these nodes, it results in a call to the imported function eea_send_message. The topic, payload, and QoS are all included as arguments to the function; your native code simply needs to publish a message through your MQTT client using the values from this invocation.

Publishing The Hello Message

Your edge application is required to report information back to the Losant platform in the form of a Hello Message, which contains information about the bundle (WASM module containing EEA and workflows) that the device is currently running. This message is important for a number of reasons:

  • The message allows the platform to keep track of what workflow versions are deployed to specific devices. With this information, Losant can automatically compile and publish a new bundle to a device’s flows topic whenever updates are made.
  • The message also provides configuration to the platform to change WASM compiler options based on your system’s capabilities.

Topic and Payload

The Hello Message is published on the topic:

losant/<device_id>/fromAgent/hello

Its payload is a JSON object of the following shape (with defaults in place):

{
  "service": "embeddedWorkflowAgent",
  "version": "1.0.0", 
  "bundle": "<bundleId>",
  "compilerOptions": {
    "exportMemory": false,
    "disableDebugMessage": false,
    "traceLevel": 1,
    "debugSymbols": false,
    "stackSize": 32768,
    "gzip": false
  }
}
  • version: The version of the EEA API that your native code expects to wrap.
  • bundle: The unique ID for this compiled bundle. This is the most important field to report, since this is what the platform uses to know what is actively running on your device and whether a new deployment should be published. If your device has no bundle loaded, report “nullVersion” as the bundle identifier. The bundle ID can be read from the WASM module.
  • exportMemory: Whether the compiled WASM bundle should export its memory, instead of the default, which is to import memory from the native code. Not all WASM runtimes support importing memory, so this setting depends on the runtime you’re using. Defaults to false.
  • disableDebugMessages: Setting this to true prevents Debug Nodes from invoking eea_send_message. (See eea_config_set_debug_enabled). This is useful to reduce network traffic and reduce the compiled bundle size. Defaults to false.
  • traceLevel: The maximum trace level supported by EEA. (See eea_config_set_trace_level.) Lowering this value will reduce bundle size since the trace messages will not be compiled into the bundle. Options:

    • 0: Disabled
    • 1: Errors Only (default)
    • 2: All/Verbose
  • debugSymbols: Setting this to true adds symbols (like function names) to the compiled bundle. This is useful for debugging, but will greatly increase the bundle size. Defaults to false.
  • stackSize: The amount of stack memory, in bytes, that is available to the EEA for execution. Defaults to 32768.
  • gzip: Setting this to true causes the platform to gzip the bundle before publishing to the flows topic. This is useful for reducing network traffic and supporting bundles that might be larger than the maximum MQTT payload limit (256KB). Defaults to false.

When to Publish the Hello Message

The Hello Message should be sent to the platform under the following scenarios:

  • Whenever your application establishes an MQTT connection.

    • If no bundle is loaded, publish “nullVersion” as the bundle identifier.
    • If a bundle is loaded, publish that bundle’s identifier.
  • Whenever the device receives and loads a new bundle.

The following example demonstrates when Hello Messages are sent for a device powering on for the first time:

  1. Device powers on and connects to the MQTT broker.
  2. Your application code publishes a Hello Message with “nullVersion” as the bundle identifier.
  3. Since this a new device and no workflows have been deployed to it, the platform takes no action.
  4. You deploy an Embedded Workflow to this device.
  5. The platform publishes the compiled bundle to this device’s flows topic.
  6. Your application code loads the bundle and begins executing workflows.
  7. Your application code reads the bundle ID from the newly received module and publishes a new Hello Message with the updated bundle identifier.

Was this page helpful?


Still looking for help? You can also search the Losant Forums or submit your question there.