MQTT API Overview

Any MQTT enabled device can directly connect and interact with the CloudPlugs IoT platform infrastructure. CloudPlugs IoT provides MQTT enabled devices with full login and device enrollment features, as well as publish and subscribe capabilities for storing and retrieving data.  The CloudPlugs MQTT server supports QOS level 0** (“level zero”)** only.  However, because the platform stores all published data based on the data retention period set up by the user, the traditional transient nature of Q0S 0 data is transformed into persistent data by the CloudPlugs platform.

More information about the protocol can be found at mqtt.org.

Every Production Thing or Controller device connected to the CloudPlugs MQTT server with the appropriate permissions level is able to communicate with any other connected device and exchange published data, even when using different protocols.  For instance, a MQTT connected device is able to exchange data with a HTTP connected device.  These capabilities are possible because the CloudPlugs IoT infrastructure has a polyglot message broker which are able to receive, transcode and relay real-time messages of multiple protocols in a transparent way.

MQTT topics are equivalent to the CloudPlugs IoT channels.  In this section we will refer to channels as topics.  MQTT topics have the same structure as CloudPlugs IoT channels.

Connecting

The CloudPlugs MQTT server is reachable at the host api.cloudplugs.com and it accepts the following incoming connections:

  • Plain MQTT on port 1883.
  • SSL MQTT on port 8883.

When using port 8883, SSL is required. The certificate used is the same as the rest of CloudPlugs.

MQTT’s “Last Will and Testament” feature is supported. This feature is useful if you wish to publish a message when your device is accidentally disconnected (for example, to send a notification when the client has been disconnected).

To maintain a persistent MQTT connection alive, the MQTT client should send PING requests to the CloudPlugs server at least every 5 minutes. As best practice, we suggest a period greater than 3 minutes but less than 5 minutes. Otherwise, the socket connection could be lost.

Authentication

Just after establishing the socket connection, the MQTT client sends a CONNECT message to the server with username, password and client ID.

  • The username can be the Plug-ID of the device.
  • The password is the authorization code related to the specific username.
  • The MQTT client ID must be of the form HWID/NAME where HWID is a string containing the unique Hardware ID or serial number of the device. NAME is optional and it is a mnemonic string to assign to the device.

You can manually enroll and retrieve a device’s Plug-ID and connection authentication password manually if desired. They can also be retrieved programmatically. Please refer to the Java and JavaScript examples.

After a successful authentication, the MQTT client is able to publish and subscribe. The permissions to perform any given action are not checked at the time of connection. Please note that the MQTT protocol has no way to inform the client when a PUBLISH or SUBSCRIBE request has been denied.  Therefore, you will not be informed if your request lacks permissions to complete the given action.

Enrolling

Things or MQTT devices must enroll to the platform to be able to publish and read data and to connect to other Things or controllers.  To enroll a new device (thing or controller), you must send to the server a CONNECT request with an empty username and an empty password, while the MQTT client ID should be of the form:

HWID/NAME

where HWID is a string containing the unique hardware ID or serial number of the device to enroll, while NAME is optional and it is a mnemonic string to assign to the device.   Therefore, a client ID can contain just the HWID.

To complete the enrollment phase, a client must receive a successful CONNACK response from the server and then it must send a SUBSCRIBE command to a specific topic or channel, depending on whether a thing or a controller is being enrolled:

  • topic or channel for enrolling a thing:              MODEL/thing/PASS
  • topic or channel for enrolling a controller:    MODEL/ctrl/THING_HWID/PASS

where MODEL is the Plug-ID of the Production Template of the Thing to enroll or to control and PASS is the authentication code for enrolling.  THING_HWID (used only for enrolling a controller) is the hardware ID or serial number of the Thing to control.

The server will then reply with a SUBACK command and it will send a PUBLISH request in the subscribed topic/channel with a payload structured as a UTF-8 encoded JSON which for a successful enrollment will have the form:

1.  {
2.      "id"   :  PLUG_ID,   // the Plug-ID of the just enrolled device
3.      "auth" :  String     // the authorization code required for future logins
4.  }

otherwise, on failure, the response will look like:

1.  {
2.      "err" : Number,      // numeric error code to identify the type of failure
3.      "msg" : String       // an optional mnemonic message describing what happened
4.  }

If an enrollment request fails, the server will automatically close the socket connection after publishing the failure response.

Retrieving Published Data

To retrieve published data using MQTT, the client must send an appropriate SUBSCRIBE command to the CloudPlugs MQTT server, such that the MQTT topic/channel string complies with the format:


PLUG_ID/data/CHANNEL

where PLUG_ID is optional and it is the Plug-ID of the device from which messages will be received, while CHANNEL is the CloudPlugs channel mask where the data has been stored.

Note that you can subscribe to receive different levels of published data from any authorized device by subscribing to a topic using single + and multi level # wildcards. For example, the example below, will retrieve the data published on channel “CHANNEL” by all devices.

+/data/CHANNEL

Another example:

dev-123456789012345678901234/data/#  // subscribes to all data published by that specified device
+/data/My/Sensor                     		   // subscribes to data published by any device in the channel My/Sensor

After receiving  a SUBACK command from the server, the client will receive real-time published data from other devices in the form of PUBLISH commands sent by the server. Please refer to the next section to understand how the PUBLISH payload (of the published data) is composed.

Publishing Data

To publish data, PLUG_ID/data/ must be part of the target topic. To publish data, the topic cannot have a wildcard.

The payload format is simply a UTF-8 encoded JSON object with the following structure:

{
      "id"    : String,    // the unique identifier of this published message
      "data"  : JSON,      // a JSON value (null, number, boolean, string, array or object) representing the published data
      "at"    : Number     // UTC timestamp in milliseconds indicates when this data has been published
  }

Set Additional Properties

To set additional properties for a device, the client should publish a message in the PLUG_ID/ag/prop/set channel.

The payload format is a JSON object with the following structure:

 {
   "SampleProp1" : "StaticValue",               // example of static Metadata (boolean, number, JSON or Array)
   "SampleProp2" : {"channel": "ChannelName" } // example of how to reference the last value published into
 }

The server will notify the client on the same channel above about the completition and eventually report the error (if any).

Retrieving Additional Properties

To retrieve the additional properties of a Thing or a Controller, the client should publish a message in the PLUG_ID/ag/prop/get channel.

If the message has no payload all the Additional Properties will be retrieved.

To retrieve individual properties the payload format is a JSON array as follows:

 [ "SampleProp1", "SampleProp2" ]

The server will send the response on the same channel above.

Still need help? Get in touch!
Last updated on 6th May 2021