Skip to main content

MQTT topics & ACL

Console ACLs use a flat topic prefix. The SDK builds topics to match.

Prefix

{workspace_slug}/{device_key}/…
SegmentSource
workspace_slugProvision JSON → NVS. Kconfig override optional.
device_keyProvision JSON → NVS. Usually equals mqtt_username.

Publish (device → cloud)

TopicQoSRetainPurpose
…/telemetry0NoSensor readings
…/state1YesActuator state
…/event1NoLive alarms / discrete events (not history; see Event logging)
…/presence1YesOnline/offline JSON
…/config/get1NoConfig pull request
…/config/status1NoConfig apply ack
…/cmd/ack/{ch}1NoCommand ack (e.g. OTA queued / starting)

Subscribe (cloud → device)

TopicQoSPurpose
…/cmd1Commands (iotmer_subscribe_commands)
…/cmd/#1Optional: cmd/device and nested command topics
…/config/#1Config protocol

OTA command ("cmd":"ota") and history ("cmd":"event.get") are application handlers on cmd / cmd/device. See OTA and Event logging.

Device → cloud command acks (products that implement them): {prefix}/cmd/ack/{ch} (e.g. cmd/ack/device), QoS 1, retain 0.

Payload routing

Route by JSON fields type and ch, not by topic depth:

{"type":"cmd","ch":"relay_1","cmd":"set","state":true}
{"type":"telemetry","ch":"ch_1","voltage":22050,"ts":1748000000}

Same schema over MQTT and BLE. See operational protocol.

Presence (LWT)

Topic: {workspace_slug}/{device_key}/presence

On connect (retained):

{"status":"online","ts":1748000000}

On unexpected disconnect (broker LWT, retained):

{"status":"offline","ts":0}

Enable with presence_lwt_enable in iotmer_config_t.

Config protocol

Subscription …/config/# covers:

TopicDirection
…/config/metaCloud → device (retained)
…/config/getDevice → cloud
…/config/respCloud → device (chunked)
…/config/statusDevice → cloud

Details: MQTT Config Protocol.

Platform MQTT rules: docs.iotmer.com