What is MQTT?

MQTT is specially useful to push data to your devices. Imagine a cloud-controlled device to open/close a door remotely. In the case of HTTP, the device would have to continously make GET requests to the Ubidots server to see if there’s a change in a variable, say “Door Control Variable”, and then take an action depending on the last reading. This takes a lot of requests and it’s not entirely a real-time interaction since it depends of the polling frequency. With MQTT, the device can “listen” to the cloud and only get notified when there’s a change in the variable. This way, the connection between the device and the cloud is left open but data only travels when necessary, saving battery, network bandwith and improving the real-time experience.

To interact with an MQTT broker you’ll need an MQTT client. Here’s a quick list of MQTT clients and resources:

  • Paho: The Eclipse Paho project provides open-source MQTT clients for C/C++, Python, Java, Javascript, Go and C#.

 Embedded engineers should take a look of Paho since it already provides clients for well-known microprocessor families.

  • MQTT.fx: A JavaFX based MQTT Client.
  • MQTT Lens: A Google Chrome extension that connects to an MQTT broker and is able to publish and subscribe to MQTT topics. If you’re using this tool to test Ubidots MQTT API, then enter any random text in its password field of the connectoin, since it appears not to allow blank passwords.
  • MQTT Inspector: A general MQTT testing app for iOS (iPhone and iPad).

Authentication

Our MQTT broker is available at the following URL:

things.ubidots.com

 port: 1883

To interact with it, you will need a TOKEN. The easiest way to get yours is clicking on “API Credentials” under your profile tab:

To connect to our MQTT broker, use your Ubidots TOKEN as the MQTT username, and leave the password field empty.

  • username –> TOKEN
  • password –> Leave blank 

If the connection is successful you should be able to publish and subscribe to MQTT topics, otherwise the broker will return an error and disconnect the client.

Node.js MQTT authentication example

var mqtt = require("mqtt");
var client  = mqtt.connect('mqtt://things.ubidots.com', {username:'c74qFmzI7ikTmZ3dFvF3e2hPEmCfu5', password:""});

Publish

To send values to several variables to the broker you have to send a PUBLISH message with the topic:

/v1.6/devices/{LABEL_DEVICE}

to the url:

mqtt://things.ubidots.com

The payload should be a JSON dictionary where every key corresponds to the unique label of each variable, and every value can be any of the following:

  • A float or integer number. For example:
{"temperature": 10, "humidity": 50}
  • A JSON object containing the “value”, “timestamp” and “context” of the data point. For example:
{"temperature": {"value":10, "timestamp": 1464661369000, "context":{"lat":-6.2, "lng":75.4, "my-key":"hello there"}}, "humidity": 50}
  • A list of JSON objects, each one containing the “value” key, and optionally the “timestamp” and “context” of the data point. For example:
{"temperature":[{"value": 10, "timestamp":1464661369000}, {"value": 12, "timestamp":1464661369999}], "humidity": 50}

Node.js Example: Publish data to a Device

var mqtt = require("mqtt");
var client  = mqtt.connect('mqtt://things.ubidots.com', {username:'c74qFmzI7ikTmZ3dFvF3e2hPEmCfu5', password:""});
var variablesPublish = {"temperature": 10, "luminosity": {"value":10}, "wind_speed": [{"value": 11, "timestamp":10000}, {"value": 12, "timestamp":13000}]};
var json = JSON.stringify(variablesPublish);
client.publish("/v1.6/devices/label_ds", json, {'qos': 1, 'retain': false},
    function (error, response) {
        console.log(response);
    });

Publish values to one variable

Once the MQTT client is successfully authenticated you should be able to publish values to the broker. To send a value to the broker you have to send a PUBLISH message with the topic:

/v1.6/devices/{LABEL_OF_DEVICE}/{LABEL_OF_VARIABLE}

to the url:

mqtt://things.ubidots.com

The body of the POST request can be either:

  • A JSON object containing the “value” key, and optionally the “timestamp” and “context” of the data point. For example:
{"value":10}

or

{"value":10, "timestamp": 1464661369000, "context":{"lat":-6.2, "lng":75.4}}
  • A list of JSON objects, each one containing the “value” key, and optionally the “timestamp” and “context” of the data point:
[{"value": 10, "timestamp":1464661369000}, {"value": 12, "timestamp":1464661369999}]

Node.js Example: publish data to a single variable:

var mqtt = require("mqtt");
var client  = mqtt.connect('mqtt://things.ubidots.com', {username:'c74qFmzI7ikTmZ3dFvF3e2hPEmCfu5', password:""});
client.publish("/v1.6/devices/label_ds/label_var",
'{"value": 10.3}', {'qos':1, 'retain':false},
function(err, response){
  console.log(response);
});

Subscribe

Subscribe to a variable

Once the MQTT client is successfully authenticated you should be able to subscribe to a variable so you can get notified when the variables receives data.

To subscribe to a variable, send a SUBSCRIBE message to the url:

mqtt://things.ubidots.com

with the topic:

/v1.6/devices/{LABEL_DEVICE}/{LABEL_VARIABLE}/lv

This will return the last value of the variable as a single float value. This makes it easier to parse in microcontrollers.

Alternatively, you can use this topic:

/v1.6/devices/{LABEL_DEVICE}/{LABEL_VARIABLE}

Which will return a JSON document with the following structure:

{
    "value": value,
    "timestamp": timestamp,
    "context": context,
    "id": id_value
}

Node.js Example: Subscription to a variable


var mqtt = require("mqtt");
var client  = mqtt.connect('mqtt://things.ubidots.com', {username:'c74qFmzI7ikTmZ3dFvF3e2hPEmCfu5', password:""});
client.subscribe({"/v1.6/devices/label_ds/variable_label": 1}, function(err, granted) {
  console.log(granted);
});
client.on('message', function(topic, message, packet) {
    //here you can process updates from the broker
});

Node.js Example: Subscription to the last value of a variable


var mqtt = require("mqtt");
var client  = mqtt.connect('mqtt://things.ubidots.com', {username:'c74qFmzI7ikTmZ3dFvF3e2hPEmCfu5', password:""});
client.subscribe({"/v1.6/devices/label_ds/variable_label/lv": 1}, function(err, granted) {
  console.log(granted);
});
client.on('message', function(topic, message, packet) {
    //here you can process updates from the broker
});

Did this answer your question?