MQTT JavaScript Example
The following example describes how to develop a simple MQTT client in JavaScript with Node.js. We use the opensource library mqtt.js that implements a MQTT layer for Node.js. You can use the npm (node.js package manager) to install it:
npm install mqtt
You are free to use any MQTT library written in any programming language to connect your Production Things with the CloudPlugs MQTT server. Please refer to the MQTT API Overview page for additional details on our MQTT API.
Connecting an existing device
With a few lines of code we can connect an existing device such as a Production Thing or Controller to the CloudPlugs IoT platform:
var mqtt = require('mqtt');
var USER = 'dev-XXXXXXXXXXXXXXXXXXXXXXXX'; // enter a valid Plug-ID for a Thing or Controller.
var PASS = '********'; // enter the **Connection password** (see Enrolling a Thing below) for the Thing or Controller.
var url = 'mqtts://'+USER+':'+PASS+'@api.cloudplugs.com';
var opts = { keepalive: 299 }; // to send a PING request every 4 minutes 59 seconds
var client = mqtt.connect(url, opts); // connect to the CloudPlugs server
client.on('connect', function() {
console.log('MQTT client connected');
doMyStuff(); // now we are connected: let's publish or subscribe...
});
Publishing data
The following function is used to publish data to CloudPlugs. Note that “device Plug-ID”/data/ must precede the target topic:
// publish data (consisting of any valid JSON value) to a channel with an (optional) timestamp
function pubData(client, channel, msg) {
client.publish('dev-yyyyyyyyyyyyyyyyyyyyy/data/'+channel, JSON.stringify(msg)); // we must send the payload as JSON and include the device Plug-ID
}
If you have enough permissions to publish data in the name of another Plug-ID (as in the case of a Controller which has WRITE permissions over a given Thing), such data will be published exactly as if it was published by the Thing Plug-ID. If the permission level is READ ONLY or DENY, the PUBLISH command will be discarded by the server and the data won’t be published.
We can then invoke the function we defined previously:
function doMyStuff() {
var plugID = 'dev-YYYYYYYYYYYYYYYYYYYYYYYY'; // enter a valid Plug-ID
pubData(client, plugID+'/data/any/given/channel', { data: 'any value', at: Date.now() });
pubData(client, plugID+'/data/another/channel', 100); // publish the value 100 in the name of another device
}
Subscribing to read data
Per the previous section, any MQTT topic for subscribing or publishing data must contain a “/data/” string followed by the channel:
client.subscribe('+/data/#'); // subscribe to all channels published by any device
We need to set up a callback for getting the messages received by CloudPlugs server:
client.on('message', function(topic, payload) { // this callback is called everytime a data is received
var parts = topic.split('/');
var plugID = parts[0]; // the device has published this received data
var channel = parts.slice(2).join('/'); // channel where data has been published
var msg = JSON.parse(payload); // payload is a JSON value containing information about the published data
var id = msg.id; // unique identifier of this data (it can be used to modify this published data)
var at = new Date(msg.at); // when the data has been published
var data = msg.data; // the published data
console.log('received data of Plug-ID '+plugID+' from channel "'+channel+'": '+JSON.stringify(data));
}
Enrolling a Thing
We can enroll a new Thing and retrieve its Plug-ID and Connection password in the following way:
var idModel = 'mod-XXXXXXXXXXXXXXXXXXXXXXXX'; // enter the Plug-ID of the Thing's Production Template
var hwid = 'ZZZZZZZZZZZ'; // enter the thing hardware-id or serial number of the Thing
var pass = '********'; // enter the Enrollment password of the Thing
// we are connecting with an empty username and connection password because we want to enroll;
// note that the MQTT client ID must be the hardware ID or serial number of the device to enroll
var client = mqtt.connect('mqtts://api.cloudplugs.com', { keepalive:299, clientId:hwid });
client.on('connect', function() {
client.subscribe(idModel+'/thing/'+pass); // request to enroll the thing!
client.on('message', onEnroll);
});
function onEnroll(topic, payload) {
client.removeListener('message', onEnroll); // enroll phase finished: we don't need this listener anymore
var msg = JSON.stringify(payload); // get the response message of enrollment
if(msg.err) {
console.error('Enrollment failed!');
} else {
var plugID = msg.id;
var pass = msg.auth;
console.log('Enrollment successful: now the Plug-ID of this device is '+plugID
+' with the Connection password "'+pass+'"');
// we should now store plugID and pass in a persistent way to use them in future connections;
// we can now subscribe and publish data to the cloud
doMyStuff();
}
}
Enrolling a Controller
The enrollment of a Controller is similar to the enrollment of a Thing:
var idModel = 'mod-XXXXXXXXXXXXXXXXXXXXXXXX'; // enter the ID of the Production Template of the thing to control
var thingHwid = 'WWWWWWWWWWW'; // enter the thing hardware-id or serial number
var ctrlHwid = 'ZZZZZZZZZZZ'; // enter the controller hardware-id
var pass = '********'; // enter the control password of the controller as defined in the thing Production Template
// we are connecting with an empty username and password because we want to enroll;
// note that the MQTT client ID must be the hardware ID of the Controller device to enroll
var client = mqtt.connect('mqtts://api.cloudplugs.com', { keepalive:299, clientId:ctrlHwid });
client.on('connect', function() {
client.subscribe(idModel+'/ctrl/'+thingHwid+'/'+pass); // request to enroll the controller!
client.on('message', onEnroll);
});
function onEnroll(topic, payload) {
client.removeListener('message', onEnroll); // enroll phase finished: we don't need this listener anymore
var msg = JSON.stringify(payload); // get the response message of enrollment
if(msg.err) {
console.error('Enrolling failed!');
} else {
var plugID = msg.id;
var pass = msg.auth;
console.log('Enrollment success: now the Plug-ID of this device is '+plugID
+' with the Connection password "'+pass+'"');
// we should now store plugID and pass in a persistent way to use them in future connections;
// we can now subscribe and publish data to the cloud
doMyStuff();
}
}
A Full example
Here’s a complete example for subscribing to CloudPlugs IoT and publishing data:
var mqtt = require('mqtt');
var USER = 'dev-XXXXXXXXXXXXXXXXXXXXXXXX'; // enter a valid Plug-ID
var PASS = '********'; // enter the Connection authentication password of the device
var url = 'mqtts://'+USER+':'+PASS+'@api.cloudplugs.com';
var opts = { keepalive: 540 }; // to send a PING request every 9 minutes
var client = mqtt.connect(url, opts); // connect to CloudPlugs server
client.on('connect', function() {
console.log('MQTT client connected');
doMyStuff();
});
client.on('message', function(topic, payload) {
var msg = JSON.parse(payload);
console.log('received data from topic "'+topic+'" at '+new Date(msg.at)+' : '+JSON.stringify(msg.data));
});
client.on('close', function() {
console.log('MQTT connection closed, now exiting.');
process.exit(0);
});
function doMyStuff() {
client.subscribe('+/data/#'); // let's receive data from all channels of any allowed device
pubData(client, '/data/my/temperature', 40);
pubData(client, '/data/complex/value', { sampledData: [0,1,2,3,4,'to','test'], subObject:{ 'just': 'for example' }});
}
function pubData(client, channel, data, at) {
client.publish(USER+'/data/'+channel, JSON.stringify({ data: data, at: at||Date.now() });
}