Skip to content

Node.js example with MQTT

Overview

This guide provides an example to process MQTT data via Node.js in a docker container.

Prerequisites

  • CMTK device with Docker already setup and a working Portainer instance.

Setup a Node.js project

Intialize a new project with the npm init command first. You may adjust the prompted information or leave the default values.

For this example you have to install the mqtt and async-mqtt packages.

npm install --save mqtt async-mqtt

Create an index.js file in the folder. The functionality of the code is documented in the comments.

index.js:

// MQTT package used as MQTT client
const mqtt = require('async-mqtt');

// Constants
const mqttBrokerUrl = `172.16.0.2:1883`;

// Dynamic variables
let units = [];

// Main function
main = async () => {
    // Connect to the MQTT broker.
    console.log(`Connecting to MQTT broker...`);
    const client = await mqtt.connect(`mqtt://${mqttBrokerUrl}`,
        {
            clientId:"demo",
        }
    );

    // Handle new MQTT messages
    client.on('message',function(topic, message, packet){
        // Extract information of the MQTT message.
        topic_type = topic.split('/')[6];
        topic_port = Number(topic.split('/')[5][4]);
        messageJson = JSON.parse(message.toString())

        // Save units of the data
        if(topic_type == `unit`)
        {
            delete messageJson['ts'];
            units[topic_port] = messageJson;
        }
        // Handle new data
        else if(topic_type == `pd`)
        {
            console.clear();
            for(field in messageJson)
            {
                // Look for an available unit for the data field.
                var unit;
                if(units[topic_port])
                {
                    unit = units[topic_port][field];
                }

                // Print data with or without unit.
                if(unit)
                {
                    console.log(`${field}: ${messageJson[field]} ${unit}`);
                }
                else
                {
                    console.log(`${field}: ${messageJson[field]}`);
                }

            }
        }
    });
    console.log(`Connected to MQTT broker!`);

    // Subscribe to every port.
    await client.subscribe(`balluff/cmtk/master1/iolink/devices/#`);
    console.log(`Subscribed to MQTT topic.`);
}


main();

Dockerfile:

FROM node:17-alpine

WORKDIR /usr/src/app
COPY index.js package.json package-lock.json ./
RUN npm ci

CMD [ "node", "index.js" ]

When developing on the device you can run the example with node index.js: Documentation. The alternative is to create a Dockerfile and upload the project to Portainer: Documentation.