Node-RED

Node-RED Dashboard 2.0 with MQTT: Gauges, Charts and Controls

A hands-on Node-RED Dashboard 2.0 tutorial: subscribe to live MQTT telemetry, show it on gauges and a line chart, and control a device with a switch that publishes commands and reflects real state.

Node-RED Dashboard 2.0 page with temperature gauges, a live line chart and a fan switch fed by MQTT topics
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

Node-RED Dashboard 2.0 turns MQTT topics into a browser UI with gauges, charts and controls, without a separate front-end project. In this tutorial you will build a page that shows live temperature and humidity from a simulated device, plots both on a line chart, and drives a fan through a switch that publishes commands and reflects the device's confirmed state. Everything runs against a free broker, so you can follow along right now.

What Node-RED Dashboard 2.0 Is

Dashboard 2.0 is the successor to the original node-red-dashboard package, which is now deprecated. It is published as @flowfuse/node-red-dashboard, is built on Vue and Vuetify, and keeps the same idea: widget nodes in your flow become elements on a web page served by Node-RED at /dashboard.

The structure is a hierarchy of configuration nodes:

Level Node Purpose
Dashboard ui-base The whole app, its URL path and navigation style
Page ui-page One route, for example /dashboard/room1
Group ui-group A card on a page that holds widgets
Theme ui-theme Colours and spacing shared by pages
Widget ui-gauge, ui-chart, ui-switch... The visible elements, wired into your flow

You rarely create these by hand. When you drop the first widget and pick "Add new ui-group", the editor offers to create the page and base for you. The official Dashboard 2.0 documentation lists every widget and its options.

Install Dashboard 2.0

In the Node-RED editor, open Menu → Manage palette → Install, search for @flowfuse/node-red-dashboard and install it. Or from the command line in your Node-RED user directory:

cd ~/.node-red
npm install @flowfuse/node-red-dashboard
# restart Node-RED afterwards, e.g.:
node-red-restart   # on a Raspberry Pi install script setup

Use a current Node-RED 4.x release. After a restart you will see a new "dashboard 2" section in the palette. If you are still setting up Node-RED itself, the Node-RED MQTT tutorial walks through installation and your first broker connection.

Simulate a Device That Publishes Telemetry

To have something to display, run a small Python script that behaves like a room controller. It publishes JSON telemetry every two seconds, listens for fan commands, and publishes the fan state as a retained message once it has applied a command. It connects to broker.connectmq.com, the free public MQTT broker, which accepts anonymous clients with any unique, non-empty client ID.

Replace a7f3k2 with your own random string. The public broker is readable by anyone, so keep the prefix unique and the data harmless.

# pip install "paho-mqtt>=2.0"
import json
import random
import time
import uuid

import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/a7f3k2/room1"
fan_on = False


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe(f"{PREFIX}/fan/set", qos=1)


def on_message(client, userdata, msg):
    global fan_on
    command = msg.payload.decode().strip().upper()
    if command in ("ON", "OFF"):
        fan_on = command == "ON"
        # Report the confirmed state, retained so new dashboards see it at once
        client.publish(f"{PREFIX}/fan/state", command, qos=1, retain=True)
        print("Fan is now", command)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"room-sim-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()

temperature = 24.0
try:
    while True:
        drift = random.uniform(-0.3, 0.35) - (0.25 if fan_on else 0.0)
        temperature = max(15.0, min(35.0, temperature + drift))
        payload = {
            "temperature": round(temperature, 2),
            "humidity": round(random.uniform(40, 55), 1),
        }
        client.publish(f"{PREFIX}/telemetry", json.dumps(payload), qos=0)
        time.sleep(2)
except KeyboardInterrupt:
    pass
finally:
    client.loop_stop()
    client.disconnect()

Leave it running. You can watch its output with mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-a7f3k2 -v -t 'connectmq/demo/a7f3k2/#'.

Build the Node-RED Dashboard 2.0 Flow

Step 1: Subscribe to telemetry

Add an mqtt in node. Create a new mqtt-broker config node with server broker.connectmq.com, port 1883 and a unique client ID such as nr-dash-a7f3k2. Set the topic to connectmq/demo/a7f3k2/room1/telemetry, QoS 1, and output to a parsed JSON object.

Step 2: Split the payload for each widget

Gauges expect a single number in msg.payload, while a multi-series chart expects one message per series with the series name in msg.topic. A function node with three outputs does both:

// Function node "split telemetry" - set Outputs to 3
const t = Number(msg.payload.temperature);
const h = Number(msg.payload.humidity);

if (Number.isNaN(t) || Number.isNaN(h)) {
    node.warn("Unexpected payload: " + JSON.stringify(msg.payload));
    return null;
}

return [
    { payload: t },                       // output 1 -> temperature gauge
    { payload: h },                       // output 2 -> humidity gauge
    [                                      // output 3 -> chart, two series
        { topic: "Temperature (C)", payload: t },
        { topic: "Humidity (%)", payload: h }
    ]
];

Returning an array inside an output slot sends several messages from that port, one after another.

Step 3: Add gauges

Drop two ui-gauge nodes and wire them to outputs 1 and 2. In the first, click the pencil next to Group to add a new group called "Room 1", which also creates the page and base. Useful settings:

  • Type: "Gauge 3/4" for temperature, "Tile" or "Battery" style for humidity if you prefer a compact view.
  • Range: 0 to 40 for temperature, 0 to 100 for humidity.
  • Segments: green from 0, amber from 26, red from 30, so the colour itself tells the story.
  • Units: °C and %.

Step 4: Add a line chart

Wire output 3 to a ui-chart node in the same group. Choose type "Line", leave Series as msg.topic and leave X as a timestamp so each point is stamped when it arrives. Under the point limits, keep the last 300 points or the last hour. Without a limit, a long-running dashboard keeps growing in memory.

Chart data in Dashboard 2.0 lives in Node-RED's memory, so a restart empties it. The follow-up guide on Node-RED chart history shows how to persist and replay it.

Step 5: Add a control that publishes commands

Add a ui-switch labelled "Fan" to the group. Set its on payload to the string ON and off payload to OFF. Wire it to an mqtt out node with topic connectmq/demo/a7f3k2/room1/fan/set, QoS 1, retain off. Commands should not be retained: a retained ON would be replayed to the device every time it reconnects, even hours later.

Step 6: Reflect the real device state

A switch that only shows what the user clicked can lie. If the device is offline, the switch says "on" while the fan is off. Fix this by feeding the device's confirmed state back into the switch:

  1. Add a second mqtt in node on connectmq/demo/a7f3k2/room1/fan/state, output as a UTF-8 string.
  2. Wire it into the input of the same ui-switch.
  3. In the switch settings, make sure input messages are not passed through to the output. Otherwise every state update would be re-published as a new command and you create a loop.

Because the simulator publishes the state as retained, a freshly opened dashboard, or a restarted Node-RED, shows the correct position immediately.

Step 7: Deploy and open the page

Click Deploy and open http://localhost:1880/dashboard. The gauges move every two seconds, the chart draws two lines, and toggling the fan makes the temperature trend downward a few readings later.

Widget Reference for MQTT Dashboards

Widget Input it expects Typical MQTT use
ui-gauge Number in msg.payload Current temperature, tank level
ui-chart Number plus msg.topic as series Trends over minutes or hours
ui-text String or number Last update time, firmware version
ui-switch On or off value Relays, fans, pumps
ui-button Click emits a payload One-shot commands such as "reset counter"
ui-slider Number Set points, dimmer level
ui-notification Text Threshold alerts as toasts
ui-template Anything, rendered with Vue Custom tables or layouts

For larger projects, look at the OEE dashboard example, which computes KPIs before they reach the widgets, and the worldmap tutorial for location data.

Common Problems and Fixes

  1. Widgets never update. Check the mqtt in node status. If it says "connecting", the client ID may be in use by another client; make it unique.
  2. Gauge shows NaN or stays at zero. The payload reached the gauge as an object. Make sure only a number goes to the gauge.
  3. Chart draws a single merged line. Every message carries the same msg.topic. Set a distinct series name per value.
  4. Switch flickers or commands repeat. Pass-through is enabled while state messages are fed back. Disable it.
  5. The page is reachable from anywhere. Dashboard 2.0 has no login by default. Put Node-RED behind authentication or a reverse proxy before exposing it.
  6. Dashboard works on the LAN but not remotely. Port 1880 is usually blocked; publish the page through a proxy with HTTPS rather than opening the port.

From Demo to Production

The public test broker is great for this tutorial, but its data is visible to anyone and it has per-client rate limits. For a real installation, point the same mqtt-broker config node at a private broker with credentials and TLS on port 8883. A cloud MQTT broker also lets devices in several buildings publish to one place that a single Node-RED dashboard can read. If you are configuring certificates for the first time, the Node-RED MQTT TLS guide covers it step by step.

With ConnectMQ you get the generated username, password and client ID from the portal, and the only flow change is the config node. Every widget, function and topic in this tutorial stays the same once you drop the demo prefix. Opting for a managed MQTT broker also removes the need to run and patch Mosquitto on the same box as your dashboard.

Run Your Node-RED Dashboard on ConnectMQ

Create a free account at app.connectmq.com, pick the Serverless (Free) plan, no credit card required, and create a broker. Paste the credentials into your Node-RED config node, switch to port 8883 with TLS, and your Dashboard 2.0 page is reading private, encrypted data. The ConnectMQ portal's in-browser MQTT client is handy for sending test commands to the fan topic while you design the page.

Frequently Asked Questions

What is the difference between Node-RED Dashboard and Dashboard 2.0?

The original node-red-dashboard is deprecated and built on AngularJS. Dashboard 2.0, @flowfuse/node-red-dashboard, is its maintained replacement built on Vue, with a page, group and widget structure that will feel familiar.

Where is the Node-RED Dashboard 2.0 URL?

By default the dashboard is served at http://<node-red-host>:1880/dashboard. You can change the path in the ui-base configuration node.

Can Dashboard 2.0 send MQTT commands?

Yes. Wire a ui-switch, ui-button or ui-slider to an mqtt out node. Feed the device's confirmed state back into the widget so the UI shows reality, not just the last click.

Why does my chart empty after restarting Node-RED?

Chart data is held in memory. Persist readings to context storage or a database and replay them on startup to keep history across restarts.

Related articles

Node-RED OPC UA Client to MQTT with ISA-95 Topics

Use node-red-contrib-opcua to subscribe to OPC UA variables on a PLC or simulation server, map node IDs to ISA-95 style MQTT topics, and publish values with quality and timestamps.

9 min read

Node-RED Chart History: Keep MQTT Chart Data Across Restarts

Dashboard charts forget everything when Node-RED restarts. This guide shows two reliable ways to keep Node-RED chart history for MQTT data: file-backed context storage and a small SQLite table, both replayed into Dashboard 2.0 on startup.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.