MQTT in Nodered | Building MQTT Dashboard

Welcome to our blog on MQTT in NodeRED, where we will explore the powerful combination of MQTT and Node-RED to create an interactive MQTT dashboard. With MQTT being a popular messaging protocol for IoT applications, and Node-RED providing a visual programming interface, we will uncover the seamless integration of ESP32 and Node-RED to build a robust and user-friendly MQTT dashboard.

In this blog, we will guide you through the process of setting up an MQTT infrastructure using Node-RED, and demonstrate how to connect and control ESP32 devices from the dashboard. By leveraging the flexibility of Node-RED’s visual interface, you can effortlessly design an MQTT dashboard tailored to your specific needs.

By following this blog on MQTT in Node-RED and creating an MQTT dashboard, readers will gain valuable insights into integrating MQTT with their IoT projects. You will learn the fundamentals of Node-RED and its components for MQTT, enabling you to efficiently gather data and control devices connected to ESP32.

The step-by-step instructions and practical examples provided will equip you with the skills to design a dynamic and interactive MQTT dashboard. This newfound knowledge will not only enhance your understanding of MQTT and Node-RED but also empower you to apply these concepts to your own IoT projects, enabling you to build efficient, scalable, and user-friendly solutions. Whether you are a hobbyist or a professional developer, this blog will provide you with the necessary tools and knowledge to unlock the potential of MQTT in Node-RED and take your IoT projects to new heights.

What is NodeRed ?

Node-RED is an open-source visual programming tool that simplifies the development of IoT (Internet of Things) applications. It provides a browser-based interface that allows users to create flows by connecting nodes, representing different functionalities, together. Each node performs a specific task, such as data input, manipulation, or output, making it easy to create complex workflows without the need for traditional programming.

Node-RED’s intuitive drag-and-drop interface, coupled with its vast library of pre-built nodes, enables users to rapidly prototype and deploy IoT applications. It supports a wide range of devices, protocols, and APIs, making it highly versatile for integrating different components of an IoT ecosystem. With Node-RED, developers can easily connect sensors, actuators, databases, cloud services, and other devices or services, facilitating seamless communication and data processing.

Furthermore, Node-RED’s extensibility through custom nodes and the availability of a vibrant community contribute to its popularity. It offers a user-friendly environment for both beginners and experienced developers to harness the power of IoT and build innovative applications. Whether you are creating a smart home automation system, industrial monitoring solution, or IoT data visualization dashboard, Node-RED provides a flexible and efficient platform to bring your ideas to life.

How to Install NodeRed ?

To install Node-RED, you can follow the instructions provided in the official Node-RED documentation. The documentation provides detailed step-by-step guidance on installing Node-RED on various operating systems, including Windows, macOS, Linux, and even running it on Raspberry Pi devices.

To access the installation instructions, you can visit the Node-RED website at https://nodered.org/docs/getting-started/. This page provides comprehensive guidance on setting up Node-RED on different platforms, including prerequisites, installation methods, and troubleshooting tips. Simply select the appropriate operating system or device you wish to install Node-RED on, and follow the instructions provided in the documentation.

By visiting the above link, you will have access to the official Node-RED documentation, which covers all the necessary information and steps to successfully install Node-RED on your desired device or operating system.

Introduction to NodeRed User interface and Hello world

The Node-RED user interface is a web-based graphical interface that allows users to visually create, edit, and manage their Node-RED flows. It provides an intuitive and user-friendly environment for building IoT applications without the need for traditional programming. Let’s dive into the basics of the Node-RED user interface and get started with a “Hello World” example.

introduction to nodered userinterface and hello world using node red
Introduction to nodered userinterface and hello world using node red

Upon launching Node-RED in a web browser, you are greeted with a workspace called the flow editor. Here, you can design your flows by dragging and dropping nodes from the palette onto the canvas and connecting them together. Nodes represent various functions or devices, such as input nodes for receiving data, processing nodes for manipulating data, and output nodes for sending data to external systems.

To get started with a “Hello World” example, we can begin by adding an inject node from the input nodes category. This node allows us to manually trigger a message in our flow. Next, we can connect the inject node to a debug node from the output nodes category. The debug node enables us to display the payload of the message on the debug sidebar in the Node-RED user interface.

Once the nodes are connected, we can deploy the flow, which makes it active and ready to respond to events. Clicking the “Deploy” button at the top-right corner of the Node-RED interface applies any changes made to the flow and activates it.

Now, if we click the button on the inject node, it will trigger a message, and the payload of that message will be displayed on the debug sidebar. In this case, we would see “Hello World” as the output.

This simple “Hello World” example showcases the basic workflow in Node-RED, where nodes are connected to create a flow of data. Let’s explore further, and we will discover the vast range of nodes available in the palette, allowing us to integrate various devices, services, and protocols into your IoT applications.

MQTT Dashboard using Nodered

To make the MQTT dashboard using nodered, we will first have to download the Userinterface palette in the nodered. So first let’s see what is a palette?

Palettes in Nodered and how to install it ?

A palette refers to the collection of nodes (blocks) available in the Node-RED editor for building flows. It acts as a toolbox containing various pre-built nodes that perform specific functions. The palette is located on the left side of the Node-RED editor and provides an easy way to access and add nodes to your flow.

Now we will install the palette, to do so we will follow the following steps,

  1. Access Manage Palette: Once you are in the Node-RED editor, click on the three horizontal lines in the top-right corner (also known as the “hamburger” icon) to open the menu. From the menu, select “Manage palette.”
  2. Install New Palette: In the Manage Palette dialog, you’ll see two tabs: “Node,” and “Install.” Click on the “Install” tab.
  3. Search for the Palette: In the “Install” tab, you can search for the palette you want to install. You can enter the name of the palette or specific keywords related to the functionality you need. In our case we will install “node-red-contrib-open” and “node-red-dashboard”.
  4. Install the Palette: Once you find the palette you want, click the “Install” button next to it. Node-RED will download and install the selected palette.
  5. Confirm Installation: A confirmation dialog will appear, asking you to confirm the installation. Click “Install” to proceed.
How to install palettes in nodered
How to install palettes in nodered

Once the required palettes are installed, you will be able to see them in the Nodes tab.

Installed palettes in nodered
Installed palettes in nodered

After installing the “Node-red-dashboard” palette, you will be able to see its node in the left hand side menu.

Nodered-dashboard elements
Nodered-dashboard elements

Making MQTT Dashboard layout in Nodered

Now, we will create the layout of our MQTT dashboard in Nodered. We have the following data,

  1. Temperature and Humidity from DHT22 sensor
  2. LED
  3. Neopixel LED Strips
  4. Servo Motor

For the Temperature and Humidity values, we will get two gauges, two charts and two buttons to open the Excel file for the data logged. After importing them into your flow window double click on them and change the labels. The nodes will look as follows,

Gauges and charts in nodered
Gauges and charts in nodered

Click on the deploy button on the top right to deploy it and a basic user interface without any data will be created which could be accessed by going to http://localhost:1880/ui .

Similarly, we will drag a switch for LED and change the label to “LED”, a slider for servo motor and rename it to “Servo Motor” and a color picker for neopixel LEDs and we will change the label to “Neopixel color picker”. We will also drag two label nodes, one for the LED status and one for the servo motor angle. The elements are shown in the following figure,

Switch for LED, Slider for Servo and Color pixker for neopixel
Switch for LED, Slider for Servo and Color pixker for neopixel

and our dashboard will look as follows,

MQTT dashboard layout
MQTT dashboard layout

Looks like our basic layout is ready, now we will change few settings. For example setting the servo motor slider value from 0-180 degree, LED switch values to ON and OFF. You could change the settings by double clicking on the elements and a menu will appear to change settings. Following are the settings for the temperature gauge in which we have changed the unit to °C and range to -20 to 60 .

Editing temperature gauge
Editing temperature gauge

Similarly we will change the settings of all other nodes as follows,

  • Temperature Gauge: Label set to “Temperature Gauge”, Unit set to “°C” and range set to -20 to 60.
  • Humidity Gauge: Label set to “Humidity Gauge”, Unit set to “%” and range set to 0 to 100.
  • For the LED switch, we will first change label and then, ON payload to string and then set the text to “ON” and similarly for OFF payload we will set it to string and then set the string to “OFF”.
  • For the servo motor slider, we will change the label and we will set the Range from 0 to 180.
  • For the Neopixel color picker, we will first change the label and then change the format to RGB.
  • For the buttons and the charts, we only changed the labels.

Now we will add the MQTT components in the layout to give life to this dashboard.

MQTT in Nodered | MQTT nodes

The MQTT nodes could be found under the network category and there are two MQTT nodes presented here “MQTT in” (responsible for subscribing to message and when a message is received on that topic, it returns that message) and “MQTT out” (responsible for publishing MQTT message on a certain topic).

MQTT in nodered | MQTT nodes
MQTT in nodered | MQTT nodes

Sending data from Nodered to ESP32 using MQTT

In this part, we will learn how we could make use of the “MQTT out” node to send data from nodered to ESP32 or another MQTT clients using MQTT.

For the LED, Servo motor and Neopixel color picker, we will use the “MQTT out” node, since the ESP32 will be expecting an output from the nodered. Firstly, we will drag the “MQTT out” node and connect it with the output of the LED.

publishing mqtt data using nodered
publishing mqtt data using nodered

And now we will double click on the mqtt node to open a configuration dialog. In the dialog, you need to provide the details of the MQTT broker you want to connect to, as you can see in the following figure we have added broker.hivemq.com, you could add it by clicking on the “edit” button on the right side of server option. Furthermore, we will change the topic to “lights” and QoS to “1”.

MQTT in Nodered | Building MQTT Dashboard

Similarly, we will add another mqtt out node for servo motor and change the topic to “servo” and for the neopixel color picker we will add mqtt node as well and change the topic to “lights/neopixel”. But the neopixel color picker returns the data in “rgb(R, G, B)” form and ESP32 expects the data in “R ,G, B” form without the “rgb(” and “)”. So, we will add an function between the the color picker and mqtt out to strip out the unrequired part.

We will drag a function block from the nodes block, and double click on the function to open the configuration and then rename the function to “convert Colorpicker data to string” and paste the following code,

msg.payload = msg.payload.replace("rgb(", "").replace(")", "");
return msg;

This function will strip out the unrequired part and then we will connect the output of the color picker to input of function node and the output of the function node with the input of mqtt out node. Our flow and the function configuration looks as following,

MQTT in Nodered | Building MQTT Dashboard

Now, we are done sending data from the nodered to MQTT clients which in our case is ESP32 using MQTT, now we will see how could we receive data using MQTT and using the “MQTT in” node of nodered.

Receivng data from ESP32 to Nodered using MQTT

To receive data, we will use the “MQTT in” Node. “MQTT in” node subscribes to the desired topic, and wait for message and once the message is received, it returns the message. ESP32 will be sending data sensor data on “Temptopic” in the “temperature,humidity” format. The data is being sent by ESP32 in comma seperated values. Lets drag the MQTT out nodes to receive the data and show it on gauges, save it to the file and plot it in chart.

We will drag the “MQTT out” node and configure it to subscribe to “Tempdata” topic, also you will have to select the broker and QoS. Then the gauge and the chart is expecting a single value in integer format, where as the data coming from ESP32 throught MQTT is string data and is comma seperated. So first lets write a function to extract a temperature value in float format.

We will change the function name to “Extract temperature” and will paste the following code,

var input = msg.payload; // Assuming the input is in msg.payload

// Remove any leading or trailing whitespace
input = input.trim();

// Split the input string using commas as the delimiter
var values = input.split(',');

// Remove leading and trailing whitespace from each value and convert to float
values = values.map(function (value) {
    return parseFloat(value.trim());
});

msg.payload = values[0]; // Set the output payload to the array of float values
return msg;

The above code splits the data using the “,” as a delimiter and converts the data into float and returns the first value i.e. temperature.

Similarly we will create another function and rename it to the “Extract humidity” and paste the following code,

var input = msg.payload; // Assuming the input is in msg.payload

// Remove any leading or trailing whitespace
input = input.trim();

// Split the input string using commas as the delimiter
var values = input.split(',');

// Remove leading and trailing whitespace from each value and convert to float
values = values.map(function (value) {
    return parseFloat(value.trim());
});

msg.payload = values[1]; // Set the output payload to the array of float values
return msg;

The above function splits the data and converts the data into float and returns the second element which is humidity.

we will connect both functions to the output of the mqtt out node and our flow will look like this,

MQTT in Nodered | Building MQTT Dashboard

after that, we will connect the outputs of the functions to the desired gauges and charts. It will look as follows.

MQTT in Nodered | Building MQTT Dashboard

Now you will be able to see MQTT data in nodered dashboard as shown n following figure,

MQTT in Nodered | Building MQTT Dashboard

Now lets see how we could log data to excel file in the nodered.

Logging MQTT data to csv file using Nodered

To log data, we will drag the “write file” node in the flow.

MQTT in Nodered | Building MQTT Dashboard

In the “write file” node configuration, we will define the path of the file. I have set it to “[yourpath]/datalog.csv” and if we will connect it to extract temperature or extract humidty function, it will only log humidity and temperature data and there will be no timestamps. So, we will write a function to crate “timestamp, temperature, humidity” format.

So we will drag a function node and rename it to “add timestamp” and paste the following code to our function,

var timestamp = new Date().toISOString(); // Get the current timestamp in ISO 8601 format
var value = msg.payload; // Get the input value

// Create the output message
msg.payload = timestamp + ", " + value;

return msg;

and now we will connect the timestamp function with the mqtt out node and write file node as follows,

MQTT in Nodered | Building MQTT Dashboard

And after deploying the flow, the data will be start logging to the excel file.

MQTT in Nodered | Building MQTT Dashboard

ESP32 MQTT

We have already covered a lot of tutorials , in which we have learned how MQTT works in ESP32. But for this tutorial, I will share the circuit diagram and the ESP32 code used.

MQTT in Nodered | Building MQTT Dashboard
#include <Adafruit_Sensor.h>
#include <DHT_U.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Servo.h> // Include the Servo library
#include <FastLED.h> // Include the FastLED library

// Defining Pins
#define DHTPIN 12
#define LED 26
#define SERVO_PIN 2 // Servo motor pin
#define LED_PIN 4 // WS2812 LED strip pin
#define NUM_LEDS 16 // Number of LEDs in the strip

// DHT parameters
#define DHTTYPE    DHT22     // DHT 11
DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t delayMS;

// Servo motor
Servo servo;

// WS2812 LED strip
CRGB leds[NUM_LEDS];

// MQTT Credentials
const char* ssid = "Wokwi-GUEST"; // Setting your AP SSID
const char* password = ""; // Setting your AP PSK
const char* mqttServer = "broker.hivemq.com";
// const char* mqttUserName = "bqzbdodo";
// const char* mqttPwd = "5oU2W_QN2WD8";
const char* clientID = "ujaisldaalkjlasdfgh;laslksdja1"; // Client ID username+0001
const char* topic = "Tempdata"; // Publish topic

// Parameters for using non-blocking delay
unsigned long previousMillis = 0;
const long interval = 1000;
String msgStr = "";      // MQTT message buffer
float temp, hum;

// Setting up WiFi and MQTT client
WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect(clientID)) {
      Serial.println("MQTT connected");
      client.subscribe("lights");
      client.subscribe("servo"); // Subscribe to servo topic
      client.subscribe("lights/neopixel"); // Subscribe to neopixel topic
      Serial.println("Topic Subscribed");
    }
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);  // wait 5sec and retry
    }
  }
}

// Subscribe callback
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  Serial.print("Message: ");
  String data = "";
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    data += (char)payload[i];
  }
  Serial.println();
  Serial.print("Message size: ");
  Serial.println(length);
  Serial.println();
  Serial.println("-----------------------");
  Serial.println(data);

  if (String(topic) == "lights") {
    if (data == "ON") {
      Serial.println("LED");
      digitalWrite(LED, HIGH);
    }
    else {
      digitalWrite(LED, LOW);
    }
  }
  else if (String(topic) == "servo") {
    int degree = data.toInt(); // Convert the received data to an integer
    Serial.print("Moving servo to degree: ");
    Serial.println(degree);
    servo.write(degree); // Move the servo to the specified degree
  }
  else if (String(topic) == "lights/neopixel") {
    int red, green, blue;
    sscanf(data.c_str(), "%d,%d,%d", &red, &green, &blue); // Parse the received data into RGB values
    Serial.print("Setting NeoPixel color to (R,G,B): ");
    Serial.print(red);
    Serial.print(",");
    Serial.print(green);
    Serial.print(",");
    Serial.println(blue);
    fill_solid(leds, NUM_LEDS, CRGB(red, green, blue)); // Set all LEDs in the strip to the specified color
    FastLED.show(); // Update the LED strip with the new color
     fill_solid(leds, NUM_LEDS, CRGB(red, green, blue));
     FastLED.show();
  }
}

void setup() {
  Serial.begin(115200);
  // Initialize device.
  dht.begin();
  // Get temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  dht.humidity().getSensor(&sensor);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

  // Setup servo
  servo.attach(SERVO_PIN);
  servo.write(0);

  // Setup WS2812 LED strip
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);

  setup_wifi();
  client.setServer(mqttServer, 1883); // Setting MQTT server
  client.setCallback(callback); // Define function which will be called when a message is received.
}

void loop() {
  if (!client.connected()) { // If client is not connected
    reconnect(); // Try to reconnect
  }
  client.loop();
  unsigned long currentMillis = millis(); // Read current time
  if (currentMillis - previousMillis >= interval) { // If current time - last time > 5 sec
    previousMillis = currentMillis;
    // Read temperature and humidity
    sensors_event_t event;
    dht.temperature().getEvent(&event);
    if (isnan(event.temperature)) {
      Serial.println(F("Error reading temperature!"));
    }
    else {
      Serial.print(F("Temperature: "));
      temp = event.temperature;
      Serial.print(temp);
      Serial.println(F("°C"));
    }
    // Get humidity event and print its value
    dht.humidity().getEvent(&event);
    if (isnan(event.relative_humidity)) {
      Serial.println(F("Error reading humidity!"));
    }
    else {
      Serial.print(F("Humidity: "));
      hum = event.relative_humidity;
      Serial.print(hum);
      Serial.println(F("%"));
    }
    msgStr = String(temp) + "," + String(hum) + ",";
    byte arrSize = msgStr.length() + 1;
    char msg[arrSize];
    Serial.print("PUBLISH DATA: ");
    Serial.println(msgStr);
    msgStr.toCharArray(msg, arrSize);
    client.publish(topic, msg);
    msgStr = "";
    delay(1);
  }
}

Leave a Comment

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