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.
- Requirements
- Setup an MQTT Broker
- Register a Device on the MQTT Broker
- Create an API Key on the MQTT Broker
- Create the IoT Device Client
- Create the IoT Application Server
- Publish Data from Client to Application via Broker
- Send Commands from Application to Client via Broker
Requirements
- Signup and login to Bluemix,
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.
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.
This takes you to the IBM Watson IoT Platform site.
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.
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.
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.
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.
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();
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
Hi Ramcharan, i will send you a direct email and help you debug.
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
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