ThingSet to MQTT mapping
WARNING
The MQTT mapping is still work-in-progress and may change in the future.
This chapter specifies a topic layout that supports the publish/subscribe as well as the request/response feature of ThingSet.
A gateway has to be used to translate the messages between the device (connected via CAN or serial) and the MQTT broker.
General thoughts
MQTT topics used for ThingSet are namespaced with a ts/
at the very beginning. This allows to use the same broker for multiple purposes and data formats. As topics are sent with every single MQTT message, no additional versioning prefix is added in order to keep them short.
The ThingSet-specific part of the topic starts with rx
or tx
to indicate the direction of the message. tx
means that a message is transmitted from the device to the broker (uplink), rx
means that the device receives a message from the broker (downlink).
The direction identifier is followed by a user or tenant name, the device ID and the path relative to the device root.
In environments without different users or during bootstrapping of devices, null
shall be used instead of an actual user name.
A Gateway that translates MQTT to multiple devices connected e.g. via CAN subscribes to the following topic for downlink messages
ts/rx/{user}/#
and publishes uplink messages to the topic
ts/tx/{user}/{device-id}/{path}
Remark: For MQTT v3.1.1 it is not possible to use the same topic for uplink and downlink messages, as a device would receive its own published message if it subscribed to the topic aswell. Only MQTT v5 has a "No Local" bit to prevent getting messages from same clientID.
This topic layout allows to easily grant access rights on user or device basis, e.g. with following wild card:
ts/+/{user}/{device-id}/#
Statements
Device to broker
Messages in text mode are published to the tx
path and the payload format must be the valid JSON data extracted from a ThingSet statement.
JSON name:value map, QoS 0/1
ts/tx/{user}/{device-id}/{group}
Messages can also be published directly in the binary format to the txb
topic if the device does not support the text mode.
Binary messages can either be published as a map or with IDs and values in a separate topic.
CBOR id:value map, QoS 0/1
ts/txb/m/{user}/{device-id}/{group-id}
CBOR ids, retained flag, QoS 1
ts/txb/i/{user}/{device-id}/{group-id}
CBOR values, QoS 0
ts/txb/v/{user}/{device-id}/{group-id}
The text mode is the preferred way for MQTT communication if supported by the device or gateway.
A cloud service might subscribe to the CBOR topics and convert them into the JSON topic automatically so that they can be further processed by other services.
The link to extended device data information will be published to a special topic:
ts/tx/{user}/{device-id}/MetadataURL
If the binary mode is used with separated IDs and values, the IDs should be published with QoS 1 and the retained flag in order to make sure they are always available and matching the values that are sent to the /v/
topic.
In general, static data like firmware version from the info
group should only be published once after startup and may use the retained flag aswell.
Broker to device
JSON name:value map
ts/rx/{user}/{device-id}/{group-name}
CBOR id:value map
tsb/rx/m/{user}/{device-id}/{group-id}
CBOR ids
tsb/rx/i/{user}/{device-id}/{group-id}
CBOR values
tsb/rx/v/{user}/{device-id}/{group-id}
Request / response
For the request / response messaging mode the response has to be matched with the request. For this reason, the request is stored in a topic with an appended request ID chosen by the requesting device. The response will be stored in a topic containing the same ID.
Requests (JSON or CBOR)
ts/req/{user}/{device-id}/{req-id}
Response (JSON or CBOR, same as request)
ts/res/{user}/{device-id}/{req-id}
The above topics contain the entire ThingSet request or response. Hence, both binary or text mode can be used with the same topic.
Data Processing
The following diagrams explain the data flow between a device and an MQTT broker.
In case of LoRaWAN or CAN where the binary mode with IDs is used, an agent may be installed which subscribes to the binary messages and translates them to the JSON messages which are later on consumed by a higher-level application.
This translation can also be done on a local gateway.
The mapping of IDs and names can either be retrieved from the device (e.g. via request/response for a device connected via CAN) or it can be stored in a .json
file on a server which contains extended information. The detailed specification of this file is still work in progress.
Device to Broker
MQTT direct (low bandwidth, with agent)
- e.g. 2G with global SIM card and very low data rate
- ID mapping by data agent
Dev MQTT:bin Agent MQTT:txt Broker
| | |
| | |
| ids (QoS 1) | |
| --------------------> | |
| values (QoS 0) | |
| --------------------> | objects (QoS 0) |
| | ---------------------> |
| | |
| ... | |
| | |
| values (QoS 0) | |
| --------------------> | objects (QoS 0) |
| | ---------------------> |
MQTT direct (sufficient bandwidth)
- e.g. LTE with local SIM card
Dev MQTT:txt Broker
| |
| objects (QoS 0) |
| ---------------------> |
Serial
Dev UART:txt GW HTTP:txt Web App
| | |
| objects | |
| --------------> | objects |
| | ---------------> |
CAN (smart gateway)
- ID mapping and translation between binary and text mode on gateway
- Preferred way
Dev CAN:bin GW MQTT:txt Broker
| | |
| values | |
| -----------------> | |
| req/resp names | |
| <----------------> | objects (QoS 0) |
| | ----------------------> |
| ... | |
| | |
| values | |
| -----------------> | objects (QoS 0) |
| | ----------------------> |
CAN (with data agent)
- ID mapping by data agent
Dev CAN:bin GW MQTT:bin Agent MQTT:txt Broker
| | | |
| values | | |
| ----------------> | | |
| req/resp ids | | |
| <---------------> | ids (QoS 1) | |
| | ----------------------> | |
| | values (QoS 0) | |
| | ----------------------> | objects (QoS 0) |
| | | ---------------------> |
| ... | | |
| | | |
| values | | |
| ----------------> | values (QoS 0) | |
| | ----------------------> | objects (QoS 0) |
| | | ---------------------> |
LoRaWAN (smart gateway)
- ID mapping on gateway
Dev LoRaWAN:bin GW MQTT:txt Broker
| | |
| ids (ACK-ed) | |
| ------------------> | |
| values | |
| ------------------> | objects (QoS 0) |
| | ---------------------> |
| ... | |
| | |
| values | |
| ------------------> | objects (QoS 0) |
| | ---------------------> |
LoRaWAN (with data agent)
- Simple forwarding of messages by gateway
- ID mapping by data agent or statically via TTN payload formatter
- Probably preferred way in order to be able to use standard TTN gateways
Dev LoRaWAN:bin GW MQTT:bin Agent MQTT:txt Broker
| | | |
| ids (ACK-ed) | | |
| ------------------> | ids (QoS 1) | |
| values | --------------------> | |
| ------------------> | values (QoS 0) | |
| | --------------------> | objects (QoS 0) |
| | | ---------------------> |
| ... | | |
| | | |
| values | | |
| ------------------> | values (QoS 0) | |
| | --------------------> | objects (QoS 0) |
| | | ---------------------> |
Broker to Device
Serial
Dev UART:txt GW MQTT:txt Broker
| | |
| | objects |
| objects | <--------------- |
| <--------------- | |
CAN (direct)
- No mapping of IDs needed, as incoming statements are sent via ISO-TP and can have almost arbitrary length.
Dev CAN:txt GW MQTT:txt Broker
| | |
| | objects (QoS 0) |
| objects | <---------------------- |
| <---------------- | |
LoRaWAN (direct)
- ID mapping on gateway
Dev LoRaWAN:bin GW MQTT:txt Broker
| | |
| ids (ACK-ed) | |
| ------------------> | |
| | |
| ... | |
| | |
| | objects (QoS 0) |
| values | <--------------------- |
| <------------------ | |
LoRaWAN (with data agent)
- Simple forwarding of messages by gateway
- ID mapping by data agent or statically via TTN payload formatter
- Probably preferred way in order to be able to use standard TTN gateways
Dev LoRaWAN:bin GW MQTT:bin Agent MQTT:txt Broker
| | | |
| ids (ACK-ed) | | |
| ------------------> | ids (QoS 1) | |
| values | --------------------> | |
| ------------------> | values (QoS 0) | |
| | --------------------> | objects (QoS 0) |
| | | ---------------------> |
| ... | | |
| | | |
| values | | |
| ------------------> | values (QoS 0) | |
| | --------------------> | objects (QoS 0) |
| | | ---------------------> |
Broker to Device (requests)
ToDo
References
[1] Designing MQTT Topics for AWS IoT Coreopen in new window
[2] https://pi3g.com/2019/05/29/mqtt-topic-tree-design-best-practices-tips-examples/