How to use MQTT with MODE
Introduction
MQ Telemetry Transport, or MQTT, is a messaging protocol that is gaining popularity as a solution to connect low-powered devices. Although MQTT was originally designed for communications based on the pub/sub architecture, it can be used as a general-purpose "machine-to-machine" (M2M) communication protocol.
For device connectivity, MODE supports MQTT 3.1.1 as an alternative to its REST API. Using MQTT, devices can "publish" events to and "subscribe" to commands from the MODE cloud. If you have an existing device implementation that is based on MQTT, you can easily integrate it into a MODE project.
Known Restrictions
While MODE's MQTT implementation covers many common IoT use cases, currently the following restrictions are in place:
- Only MQTT version 3.1.1 is supported.
- For publishing, only QoS levels 0 and 1 are supported.
- For subscription, only QoS level 0 is supported.
- Persistent sessions are not allowed.
- Will topics are not supported.
- Message retain is not supported.
Making MQTT Connections
Your MQTT client (device) should connect to the host mqtt.tinkermode.com
at the standard MQTT port 1883, or for a secure connection, at port 8883. We highly recommend the use of the secure port. (Some MQTT client libraries require you to provide a root CA certificate in order to make TLS connections to the server. MODE's root CA for the MQTT service is DigiCert and you can download the certificate here.)
Once a connection is established, the client should issue the CONNECT
message with the following arguments:
clientId
should be blank.cleanSession
should be true.username
should be the device ID.password
should be the API key issued to the device.
If the message is successful, your client should proceed to set itself up to receive commands from MODE.
Receiving Commands
To receive commands targetting your device, your client needs to subscribe to the appropriate topic with the SUBSCRIBE
message. The topic name must be in the format /devices/DEVICE_ID/command
, where DEVICE_ID is the assigned device ID. The only QoS level supported is 0.
If the SUBSCRIBE
message is successful, your client will receive a PUBLISH
message whenever a command is issued to the the device. The payload of the message is a JSON string as defiend by MODE's schema for the Device Command object.
Mosquitto has some convenient command-line programs for testing MQTT. In the following example, we are using mosquitto_sub
to listen to incoming commands and output the JSON strings to the screen. (Replace DEVICE_ID
and DEVICE_API_KEY
with the actual device ID and API key.)
$ mosquitto_sub -d -V mqttv311 -h mqtt.tinkermode.com -t /devices/DEVICE_ID/command -u DEVICE_ID -P DEVICE_API_KEY
Sending Events
To send events to MODE, your client simply issues the PUBLISH
message with the following arguments:
topicName
must be in the format/devices/DEVICE_ID/event
, where DEVICE_ID is the assigned device ID.payload
is a JSON string as defined by MODE's schema for the Event object.qos
can be 0 or 1.
In the following example, we are using mosquitto_pub
to send an event to MODE with QoS1. (Replace DEVICE_ID
and DEVICE_API_KEY
with the actual device ID and API key.)
$ mosquitto_pub -d -V mqttv311 -h mqtt.tinkermode.com -t /devices/DEVICE_ID/event -m '{ "eventType": "test", "eventData": { "x": 123 } }' -u DEVICE_ID -P DEVICE_API_KEY -q 1
Sending Bulk Data
You can send arbitrary binary data as "Bulk Data".
Currently, "Bulk Data" is used as a way for some Smart Modules to receive data in an efficient manner.
"Bulk Data" transfer is done by publishing to a special topic.
topicName
must be in the format/devices/DEVICE_ID/bulkData/BULK_DATA_LABEL
, where DEVICE_ID is the assigned device ID and BULK_DATA_LABEL is the one configured in your Smart Module configuration page.payload
is an arbitrary byte sequence. Actual payload format is defined by each Smart Module.qos
can be 0 or 1.
This "Bulk Data" topic is provided for efficient data transfer to Smart Modules where the data is supposed to be high-density and high-throughput.
The following are the Smart Modules that accept bulk data. Please refer to each individual manual for more details.
Accessing Device Data Proxy
Device Data Proxy (or DDP) provides each device instance a persistent cloud storage for key-value pairs. With an MQTT connection, a device receives and makes changes to the data store by subscribing and publishing to the appropriate topic. See this document for details.
Request and Response Communication
In general, MQTT protocol itself by nature doesn't support request / response type communication. But, in some use cases, request / response type of communication is very useful.
MODE provides this functionality on MQTT communication between MODE Platform and IoT devices by providing:
- Special topics for devices to publish requests to the MODE Platform.
- Special topics for devices to subscribe to and receive responses corresponding to those requests.
To make a Bulk Data Request, publish data in the following manner:
topicName
must be in the format/devices/DEVICE_ID/bulkData/BULK_DATA_LABEL/request
.payload
is a JSON string described below.qos
can be 0 or 1.
- FieldTypeDescriptionRequired?
- bulkDataLabelstringBulk Data Label for your Smart Module.Yes
- requestIdstringAn arbitrary string. This string is ideally a unique string across your system because this is used for identifying the correspondence between request and response.Yes
- payloadobjectJSON object which is specific to the type of Smart ModulesYes
To receive Bulk Data Responses, make a subscription in the following manner:
topicName
must be in the format/devices/DEVICE_ID/bulkData/BULK_DATA_LABEL/response
.payload
is a JSON string described below.qos
can be 0 or 1.
- FieldTypeDescriptionRequired?
- requestIdstringString value that is set in the request JSONYes
- statusstringString representing the result of the request. Possible response is described below.Yes
- payloadobjectJSON object which is specific to the type of Smart ModulesYes
status
values are either of the following:
OK
: the request is processed by the corresponding Smart Module.INVALID_BULK_DATA_LABEL
: thebulkdDataLabel
specified in the request is not valid.SERVICE_UNAVAILABLE
: the corresponding Smart Module is temporarily unavailable.
Please note that even a status
of OK
in the response JSON doesn't mean the request itself was successful;
that just means the request is processed by the Smart Module. To find out the actual outcome of the request, please check the content of the paylod
field.
Both of the Request payload
field and the Response payload
fields are different from Smart Module to Smart Module.
So, when working with the Bulk Data Request / Response functionality, please reference the specific Smart Module documentation.
Disconnecting Gracefully
If your device no longer wishes to send events or receive commands, it is good practice to gracefully disconnect from the MQTT server. Make sure the client issues an UNSUBSCRIBE
message to stop any subscription, then a DISCONNECT
message to terminate the session cleanly.