Using MQTT to publish data and send commands for IoT

MQTT is a publish-subscribe messaging pattern with a light-weight footprint, ideal for IoT devices. This tutorial will create a basic workflow via an MQTT Broker from device client to application server and back. To avoid any hardware dependencies in this tutorial I will simulate the device client and implement it as a Node.js server. The application server will also be a Node.js server.

  1. Requirements
  2. Setup an MQTT Broker
  3. Register a Device on the MQTT Broker
  4. Create an API Key on the MQTT Broker
  5. Create the IoT Device Client
  6. Create the IoT Application Server
  7. Publish Data from Client to Application via Broker
  8. Send Commands from Application to Client via Broker

Requirements

Setup an MQTT Broker

The publish-subscribe messaging pattern of MQTT requires a message broker. One easy way to create one is to create an MQTT broker from a boilerplate application ‘Internet of Things Platform Starter‘ in Bluemix.

1. Go to the Bluemix catalog and click the ‘Internet of Things Platform Starter‘ boilerplate,
2. In the menu options of the boilerplate, select a space, for name enter ‘<username>-mqtt-broker’, which will also populate the host name, and leave the ‘mybluemix.net’ for domain, and click ‘CREATE’,
3. This created a Node.js runtime with an ‘Internet of Things Platform‘ service and a ‘Cloudant NoSQL DB’ service, an implementation of Apache CouchDB.

Bmx-IOTF-Service

Register a Device on the MQTT Broker

In the application Overview page of the ‘Internet of Things Platform Starter’ application, which is our MQTT Broker, click on the ‘Internet of Things Platform’ service icon or in the left menu under ‘SERVICES’, click the ‘Internet of Things Platform’ service. Then click the ‘Launch dashboard’ button.
Bmx-IOTF-Service-LaunchDashboard

This takes you to the IBM Watson IoT Platform site.
IBM-Watson-IoTPlatform-AllBoards1

Click on the ‘devices’ icon to go to the devices overview, and click the ‘Add Device’ button to add a new IoT device:

  • First, click the ‘Create device type’ button,
  • Click the ‘Create device type’ button again,
  • As name enter: ‘my-nodejs-device’ and click ‘Next’,
  • Skip the ‘Define Template’ page and click ‘Next’,
  • Click ‘Next’ to ‘Submit Information’,
  • Skip the ‘Metadata (optional)’ page, click ‘Create’ to create the new device type,
  • In the ‘Choose device type’ dropdown select the ‘my-nodejs-device’, and click ‘Next’,
  • For ‘Device ID’ type ‘my-nodejs-device-1’, unfold the ‘Additional fields’ to see what other properties you can define for a device.
    ibm-iotp-deviceid
    Collapse the additional properties again and click ‘Next’,
  • Skip the ‘Metadata (optional)’ page and click ‘Next’,
  • Skip the ‘Security’ page, a token will be generated when leaving empty, and click ‘Next’, and
  • In the ‘Summary’ page click the ‘Add’ link to create the new device,
  • Make sure to save ‘Your Device Credentials’ with among other the ‘Authentication Token’, you will need it later.
    ibm-iotp-your-device-credentials

You now should see your new device listed in the devices overview. You also see an alert icon with an exclamation mark inside to indicate that the device is currently not connected.
ibm-iotp-device

Create an API Key on the MQTT Broker

The device client is authenticated by the MQTT broker via the token, but the application is authenticated via an API key. To create the API key, in the IBM Watson IOT Platform click the ‘Access’ icon, click the ‘API Keys’ tab, and click the ‘Generate API Key’ button in the top right. Save your ‘API key information’, the ‘API Key’ and the ‘Authentication Token’ that were generated, you will need this later, and press ‘Finish’. You should now see an API key listed in the ‘API Keys’ overview.
ibmiotf-generateAPIKey

Create the IoT Device Client

I will use a Node.js server to simulate the IoT device client, which communicates to the application server via the MQTT broker. To create the Node.js server to simulate the MQTT device client:

  • Go to the Bluemix catalog, browse to ‘Runtimes’ and select the ‘SDK for Node.js‘ runtime,
  • Select the space, and for ‘Name’ enter ‘<username>-mqtt-device’, which autopopullates the ‘Host’ name, and leave the ‘Domain’ default to ‘mybluemix.net’, and click the ‘CREATE’ button,
  • In the left menu, go to the application ‘Overview’ page, and click ‘ADD GIT’,
  • Leave the ‘Populate the repo…’ checkbox checked, and click ‘CONTINUE’, and click ‘CLOSE’,

Configure the IoT Device Client

Now, the IoT device client is created, let’s add the configuration to the device client that connects it to the MQTT broker service.

  • In the left menu, go to the application ‘Overview’ page,
  • Click the ‘EDIT CODE’ button in the top right, which will open the DevOps environment with the online editor among other, open the ‘app.js’ file,
  • We will use the Node.js ‘ibmiotf‘ package, so let’s add this to the ‘app.js’ file under the ‘cfenv’ require,
    var iotf = require('ibmiotf');
  • Open the ‘package.json’ file and add the dependency for ‘ibmiotf’,
    "ibmiotf": "*"
  • Open ‘app.js’ again, and add the device credentials as generated when we setup the device in the IBM Watson IoT Platform to the configuration as follows,
  • In the above code, you also see that I created an ‘IotfDevice’ object with ‘var Client = iotf.IotfDevice;’ and created a configured instance of the client with the MQTT broker configuration in ‘var deviceClient = new Client(config);’,

Add User Defined Variables for Configuration

To add user defined variables in Bluemix, instead of hardcoding the MQTT broker credentials into the application code, browse to your application’s ‘Environment Variables’ page.

  • Go to the Bluemix console, click the Dashboard menu, in the left menu select your application space, select ‘CF APPS’, select ‘<username>-mqtt-device’ and click the ‘Environment Variables’ link.
  • Click the ‘USER-DEFINED’ tab, and click the ‘ADD’ button,
  • Add the following variables:
    • deviceOrgId : <your-orgId>
    • deviceType : <your-deviceType>
    • deviceId : <your-deviceId>
    • deviceAuthMethod: "token"
    • deviceAuthToken : <your-authToken>

In your code, retrieve the user defined variables as follows:
var myVar1 = process.env.myVar1;
for each of the device credentials.

Create the Application Server

Next, I will setup the application server, before we connect the pieces together and send data via the MQTT Broker. To create the Node.js server for our MQTT application server:

  • Go to the Bluemix catalog, browse to ‘Runtimes’ and select the ‘SDK for Node.js‘ runtime,
  • Select the space, and for ‘Name’ enter ‘<username>-mqtt-application’, which autopopullates the ‘Host’ name, and leave the ‘Domain’ default to ‘mybluemix.net’, and click the ‘CREATE’ button,
  • In the left menu, go to the application ‘Overview’ page, and click ‘ADD GIT’,
  • Leave the ‘Populate the repo…’ checkbox checked, and click ‘CONTINUE’, and click ‘CLOSE’.

Configure the Application Server

Now, the application server is created, let’s add the configuration to the application server that connects it to the MQTT broker service.

  • In the left menu, go to the application ‘Overview’ page,
  • Click the ‘EDIT CODE’ button in the top right, which will open the DevOps environment with the online editor among other, open the ‘app.js’ file,
  • We will use the Node.js ‘ibmiotf‘ package, so let’s add this to the ‘app.js’ file under the ‘cfenv’ require,
    var iotf = require('ibmiotf');
  • Open the ‘package.json’ file and add the dependency for ‘ibmiotf’,
    "ibmiotf": "*"
  • Open ‘app.js’ again, and add the access credentials as generated when we created the API Key in the IBM Watson IoT Platform to the configuration as follows,
  • In the above code, you also see that I created a configured instance of the IotfApplication object with the MQTT broker configuration in ‘var application = new iotf.IotfApplication(config);’,
  • Optionally, you can set log levels as follows:
    application.log.setLevel('trace');.

Publish Data from Client to Application via Broker

Connect Device to MQTT Broker

deviceClient.connect();
deviceClient.on("connect", function () {
// do your thing
});

Publish Data

var msg = {"d" : { "cpu" : 60, "mem" : 50 }};
msg = JSON.stringify(msg);
deviceClient.publish("status","json",msg);

Command Handling

deviceClient.on("command", function (commandName, format, payload, topic) {
if(commandName === "blink") {
// handle command
} else {
// command not supported
}
});

Error Handling

deviceClient.on("error", function (err) {
// handle error
});

Disconnect

deviceClient.disconnect();

Send Commands from Application to Client via Broker

Connect Application to MQTT Broker

To connect the application to the MQTT broker, you call the connect method.
var deviceType = "";
var deviceId = "";
application.connect();
application.on("connect", function () {
// do something
});

Subscribe to Device Events

Before you subscribe to device events or a device status, the application must be connected to the MQTT broker.
application.subscribeToDeviceEvents(deviceType);
You can subscribe to events from specific devices by adding one of the following properties:

  • deviceType
  • deviceId
  • eventType
  • format
  • payload
  • topic

For more examples and details, look at the Node.js ibmiotf package page.

Subscribe to Device Status

application.subscribeToDeviceStatus(deviceType, deviceId);

Handling Device Events

Once, the application is connected and subscribed to device events, you can handle events from devices as follows.
application.on("deviceEvent", function (deviceType, deviceId, eventType, format, payload) {
// handle event
});

Handling Device Status

application.on("deviceStatus", function (deviceType, deviceId, payload, topic) {
// handle status
});

Publishing Commands to Device

To publish commands to a connected device, you must provide:

  • deviceType,
  • deviceId,
  • commandType,
  • format, and
  • data.

var myData={'DelaySeconds' : 10};
myData = JSON.stringify(myData);
var myFormat = "json";
var myCommand = "blink";
application.publishDeviceCommand(deviceType, deviceId, myCommand, myFormat, myData);

Publishing Device Events

You can also publish events from the application as if they were sent from a device. You must provide:

  • deviceType,
  • deviceId,
  • eventType,
  • format, and
  • data.

application.publishDeviceEvent(deviceType, deviceId, eventType, eventFormat, eventData);

Disconnect

application.disconnect();

4 thoughts on “Using MQTT to publish data and send commands for IoT

  1. Ramcharan

    Hi,

    i was getting error at Configure the IoT Device Client topic

    when i was copying the below code in bluemix git application

    var iotf = require(“ibmiotf”);

    the library could not be found error is showing

    please help me to move further

  2. Ramcharan

    Hi am able post data to bluemix by following your document.

    but am not able to subscribe the published data from bluemix

    please provide sample code how to get published data from bluemix and display in table using apikey and auth-key etc in node.js

  3. imran ghazali

    will you please help me to send individual device information through gateway to ibm watson cloud.
    gatewayClient.publishDeviceEvent(“Raspi”,”pi03″,”status”,”json”,'{“d” : { “cpu” : 30, “mem” : 10 }}’);

    i am using this. But not able to see event. but data is comming fine

Leave a Reply

Your email address will not be published. Required fields are marked *