Node-RED Dashboard 2.0 convierte topics MQTT en una interfaz web con indicadores, gráficos y controles, sin necesidad de un proyecto de front-end aparte. En este tutorial crearás una página que muestra la temperatura y la humedad en directo de un dispositivo simulado, representa ambas en un gráfico de líneas y controla un ventilador mediante un interruptor que publica comandos y refleja el estado confirmado por el dispositivo. Todo funciona contra un broker gratuito, así que puedes seguirlo ahora mismo.
Qué es Node-RED Dashboard 2.0
Dashboard 2.0 es el sucesor del paquete original node-red-dashboard, que ahora está obsoleto. Se publica como @flowfuse/node-red-dashboard, está construido sobre Vue y Vuetify y mantiene la misma idea: los nodos de widget de tu flujo se convierten en elementos de una página web que Node-RED sirve en /dashboard.
La estructura es una jerarquía de nodos de configuración:
| Nivel | Nodo | Propósito |
|---|---|---|
| Dashboard | ui-base |
La aplicación completa, su ruta URL y su estilo de navegación |
| Página | ui-page |
Una ruta, por ejemplo /dashboard/room1 |
| Grupo | ui-group |
Una tarjeta dentro de una página que contiene widgets |
| Tema | ui-theme |
Colores y espaciados compartidos por las páginas |
| Widget | ui-gauge, ui-chart, ui-switch... |
Los elementos visibles, conectados a tu flujo |
Rara vez los crearás a mano. Cuando colocas el primer widget y eliges "Add new ui-group", el editor se ofrece a crear la página y la base por ti. La documentación oficial de Dashboard 2.0 enumera todos los widgets y sus opciones.
Instala Dashboard 2.0
En el editor de Node-RED, abre Menu → Manage palette → Install, busca @flowfuse/node-red-dashboard e instálalo. O desde la línea de comandos, en tu directorio de usuario de Node-RED:
cd ~/.node-red
npm install @flowfuse/node-red-dashboard
# reinicia Node-RED después, p. ej.:
node-red-restart # en una instalación con el script de Raspberry Pi
Usa una versión actual de Node-RED 4.x. Tras reiniciar verás una nueva sección "dashboard 2" en la paleta. Si todavía estás instalando Node-RED, el tutorial de Node-RED MQTT recorre la instalación y tu primera conexión con un broker.
Simula un dispositivo que publica telemetría
Para tener algo que mostrar, ejecuta un pequeño script de Python que se comporta como un controlador de sala. Publica telemetría JSON cada dos segundos, escucha comandos para el ventilador y publica el estado del ventilador como mensaje retenido una vez aplicado el comando. Se conecta a broker.connectmq.com, el servidor MQTT público gratuito, que acepta clientes anónimos con cualquier client ID único y no vacío.
Sustituye a7f3k2 por tu propia cadena aleatoria. Cualquiera puede leer el broker público, así que mantén el prefijo único y los datos inofensivos.
# 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"
# Informa del estado confirmado, retenido para que los paneles nuevos lo vean al instante
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()
Déjalo en ejecución. Puedes ver su salida con mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-a7f3k2 -v -t 'connectmq/demo/a7f3k2/#'.
Crea el flujo de Node-RED Dashboard 2.0
Paso 1: suscríbete a la telemetría
Añade un nodo mqtt in. Crea un nuevo nodo de configuración mqtt-broker con el servidor broker.connectmq.com, el puerto 1883 y un client ID único como nr-dash-a7f3k2. Configura el topic connectmq/demo/a7f3k2/room1/telemetry, QoS 1 y la salida como a parsed JSON object.
Paso 2: divide el payload para cada widget
Los indicadores esperan un único número en msg.payload, mientras que un gráfico con varias series espera un mensaje por serie con el nombre de la serie en msg.topic. Un nodo function con tres salidas hace ambas cosas:
// Nodo function "split telemetry" - configura Outputs a 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 }, // salida 1 -> indicador de temperatura
{ payload: h }, // salida 2 -> indicador de humedad
[ // salida 3 -> gráfico, dos series
{ topic: "Temperature (C)", payload: t },
{ topic: "Humidity (%)", payload: h }
]
];
Devolver un array dentro de una posición de salida envía varios mensajes por ese puerto, uno tras otro.
Paso 3: añade indicadores
Coloca dos nodos ui-gauge y conéctalos a las salidas 1 y 2. En el primero, haz clic en el lápiz junto a Group para añadir un nuevo grupo llamado "Room 1", lo que también crea la página y la base. Ajustes útiles:
- Tipo: "Gauge 3/4" para la temperatura, y estilo "Tile" o "Battery" para la humedad si prefieres una vista compacta.
- Rango: de 0 a 40 para la temperatura y de 0 a 100 para la humedad.
- Segmentos: verde desde 0, ámbar desde 26 y rojo desde 30, para que el propio color cuente la historia.
- Unidades:
°Cy%.
Paso 4: añade un gráfico de líneas
Conecta la salida 3 a un nodo ui-chart en el mismo grupo. Elige el tipo "Line", deja Series como msg.topic y deja X como marca de tiempo para que cada punto se marque al llegar. En los límites de puntos, conserva los últimos 300 puntos o la última hora. Sin límite, un panel que funciona durante mucho tiempo no deja de crecer en memoria.
Los datos de los gráficos en Dashboard 2.0 viven en la memoria de Node-RED, así que un reinicio los vacía. La guía complementaria sobre el historial de gráficos en Node-RED muestra cómo persistirlos y reproducirlos.
Paso 5: añade un control que publique comandos
Añade al grupo un ui-switch con la etiqueta "Fan". Configura su payload de encendido como la cadena ON y el de apagado como OFF. Conéctalo a un nodo mqtt out con el topic connectmq/demo/a7f3k2/room1/fan/set, QoS 1 y retain desactivado. Los comandos no deben ser retenidos: un ON retenido se volvería a enviar al dispositivo cada vez que se reconecte, incluso horas después.
Paso 6: refleja el estado real del dispositivo
Un interruptor que solo muestra lo que pulsó el usuario puede mentir. Si el dispositivo está desconectado, el interruptor dice "encendido" mientras el ventilador está apagado. Soluciónalo devolviendo al interruptor el estado confirmado por el dispositivo:
- Añade un segundo nodo
mqtt inenconnectmq/demo/a7f3k2/room1/fan/state, con la salida como cadena UTF-8. - Conéctalo a la entrada del mismo
ui-switch. - En los ajustes del interruptor, asegúrate de que los mensajes de entrada no pasan a la salida. De lo contrario, cada actualización de estado se volvería a publicar como un nuevo comando y crearías un bucle.
Como el simulador publica el estado como retenido, un panel recién abierto, o un Node-RED reiniciado, muestra la posición correcta de inmediato.
Paso 7: despliega y abre la página
Haz clic en Deploy y abre http://localhost:1880/dashboard. Los indicadores se mueven cada dos segundos, el gráfico dibuja dos líneas y, al activar el ventilador, la temperatura empieza a bajar unas cuantas lecturas después.
Referencia de widgets para paneles MQTT
| Widget | Entrada que espera | Uso típico en MQTT |
|---|---|---|
ui-gauge |
Número en msg.payload |
Temperatura actual, nivel de un depósito |
ui-chart |
Número más msg.topic como serie |
Tendencias a lo largo de minutos u horas |
ui-text |
Cadena o número | Hora de la última actualización, versión de firmware |
ui-switch |
Valor de encendido o apagado | Relés, ventiladores, bombas |
ui-button |
El clic emite un payload | Comandos puntuales como "reset counter" |
ui-slider |
Número | Consignas, nivel de un regulador |
ui-notification |
Texto | Alertas por umbral como avisos emergentes |
ui-template |
Cualquier cosa, renderizada con Vue | Tablas o diseños personalizados |
Para proyectos más grandes, echa un vistazo al ejemplo de panel OEE, que calcula los KPI antes de que lleguen a los widgets, y al tutorial de worldmap para datos de ubicación.
Problemas comunes y soluciones
- Los widgets nunca se actualizan. Revisa el estado del nodo
mqtt in. Si dice "connecting", puede que otro cliente esté usando el client ID; hazlo único. - El indicador muestra NaN o se queda en cero. El payload llegó al indicador como objeto. Asegúrate de que solo le llega un número.
- El gráfico dibuja una única línea fusionada. Todos los mensajes llevan el mismo
msg.topic. Asigna un nombre de serie distinto a cada valor. - El interruptor parpadea o los comandos se repiten. El paso directo está activado mientras se devuelven los mensajes de estado. Desactívalo.
- La página es accesible desde cualquier lugar. Dashboard 2.0 no tiene login por defecto. Pon Node-RED detrás de una autenticación o de un proxy inverso antes de exponerlo.
- El panel funciona en la LAN pero no en remoto. El puerto 1880 suele estar bloqueado; publica la página a través de un proxy con HTTPS en lugar de abrir el puerto.
De la demo a la producción
El servidor MQTT público gratuito es perfecto para este tutorial, pero sus datos son visibles para cualquiera y tiene límites de frecuencia por cliente. Para una instalación real, apunta el mismo nodo de configuración mqtt-broker a un broker privado con credenciales y TLS en el puerto 8883. Un broker MQTT en la nube también permite que dispositivos de varios edificios publiquen en un único lugar que un solo panel de Node-RED puede leer. Si configuras certificados por primera vez, la guía de Node-RED MQTT TLS lo explica paso a paso.
Con ConnectMQ obtienes en el portal el usuario, la contraseña y el client ID generados, y el único cambio en el flujo es el nodo de configuración. Todos los widgets, funciones y topics de este tutorial siguen igual en cuanto eliminas el prefijo de demostración. Optar por un broker MQTT gestionado también elimina la necesidad de ejecutar y parchear Mosquitto en la misma máquina que tu panel. Si más adelante necesitas ver una planta o un edificio en contexto espacial, los mismos topics pueden alimentar un gemelo digital 3D en el navegador.
Ejecuta tu panel de Node-RED en ConnectMQ
Crea una cuenta gratuita en app.connectmq.com, elige el plan Serverless (Free), sin tarjeta de crédito, y crea un broker. Pega las credenciales en tu nodo de configuración de Node-RED, cambia al puerto 8883 con TLS y tu página de Dashboard 2.0 estará leyendo datos privados y cifrados. El cliente MQTT en el navegador del portal de ConnectMQ resulta muy útil para enviar comandos de prueba al topic del ventilador mientras diseñas la página.
Preguntas frecuentes
¿Cuál es la diferencia entre Node-RED Dashboard y Dashboard 2.0?
El node-red-dashboard original está obsoleto y se basa en AngularJS. Dashboard 2.0, @flowfuse/node-red-dashboard, es su sustituto mantenido, construido sobre Vue, con una estructura de páginas, grupos y widgets que te resultará familiar.
¿Cuál es la URL de Node-RED Dashboard 2.0?
Por defecto el panel se sirve en http://<node-red-host>:1880/dashboard. Puedes cambiar la ruta en el nodo de configuración ui-base.
¿Puede Dashboard 2.0 enviar comandos MQTT?
Sí. Conecta un ui-switch, un ui-button o un ui-slider a un nodo mqtt out. Devuelve al widget el estado confirmado por el dispositivo para que la interfaz muestre la realidad y no solo el último clic.
¿Por qué se vacía mi gráfico al reiniciar Node-RED?
Los datos del gráfico se mantienen en memoria. Persiste las lecturas en el almacenamiento de contexto o en una base de datos y reprodúcelas al arrancar para conservar el historial entre reinicios.



