← MQTT Status LEDs on a Node-RED Touchscreen Dashboard
Industrial mixing (touch HMI)TouchBerry PiMQTTHTTPHMI / Dashboard
MQTT Status LEDs on a Node-RED Touchscreen Dashboard — full example
Build a touchscreen HMI with Node-RED Dashboard 2.0: MQTT-driven status LEDs, machine state text and a guarded force-start button on a TouchBerry Pi.
Complete, runnable program for the TouchBerry Pi (dashboard-mqtt-status-leds.js): wiring header, requirements and integration notes included.
Download the full project pack — freeThis example + the related ones + bill of materials
Read-only preview.
/*
* COMPLETE EXAMPLE — Node-RED touch dashboard with MQTT status LEDs
*
* Hardware: TouchBerry Pi (Raspberry Pi + Industrial Shields PLC, touch screen)
* Based on: industrial mixing project (Node-RED touch HMI)
*
* Requirements:
* - Node-RED with @flowfuse/node-red-dashboard (UI v2) and the ui-led node
* - Reachable MQTT broker (e.g. local Mosquitto on the TouchBerry itself)
*
* Architecture:
* The line publishes over MQTT the material-readiness status of each
* machine; the HMI shows it on green/red LEDs and allows forcing the
* mixing cycle by publishing a command back to the same broker.
*
* Flow wiring:
*
* [mqtt in topic=planta/Gk190-1/ready] ──> [function 1: payloadToLed] ──> [ui-led "MATERIALS OK?"]
* [mqtt in topic=planta/Gk190-1/estado] ─> [function 2: statusToText] ─> [ui-text "Machine status"]
* [ui-button "Force mixing"] ──> [function 3: forceCommand] ──> [mqtt out topic=planta/Gk190-1/forzar]
* [mqtt status node] ──> [function 4: brokerStatus] ──> [ui-led "MQTT"]
*
* Node configuration:
* - mqtt in/out: same broker (mqtt://localhost:1883), QoS 1.
* - ui-led: colorForValue true=green, false=red.
* - The dashboard has two pages: /control (LEDs + button) and /history (table).
*/
// ============================================================
// function 1: payloadToLed
// ------------------------------------------------------------
// The line PLC publishes "1"/"0" as a string on the topic
// planta/Gk190-1/ready. The ui-led node expects a boolean.
// ============================================================
msg.payload = msg.payload == "1"; // "1" -> true (green), anything else -> false (red)
msg.topic = "Basic"; // grouping inside the dashboard
return msg;
// ============================================================
// function 2: statusToText
// ------------------------------------------------------------
// Translates the machine's numeric status code into text the
// operator can read on the ui-text node.
// ============================================================
const STATUSES = {
"0": "STOPPED",
"1": "WAITING FOR MATERIALS",
"2": "MIXING",
"3": "UNLOADING",
"9": "ALARM"
};
msg.payload = STATUSES[String(msg.payload)] || "UNKNOWN";
return msg;
// ============================================================
// function 3: forceCommand
// ------------------------------------------------------------
// The "Force mixing" button must only act if there is an active
// administrator session (see the authentication sheet) and it
// leaves a trace of who forced the cycle.
// ============================================================
const last = global.get("lastAdminLoginDate");
const timeout = global.get("adminLoginTimeout") || 600000;
const isAdmin = last && (new Date() - new Date(last)) < timeout;
if (!isAdmin) {
node.warn("Force command rejected: administrator session required");
return null; // publish nothing
}
msg.topic = "planta/Gk190-1/forzar";
msg.payload = JSON.stringify({
orden: "forzar_mezclado",
usuario: "admin",
fecha: new Date().toISOString()
});
return msg;
// ============================================================
// function 4: brokerStatus
// ------------------------------------------------------------
// Connected to a 'status' node watching the mqtt nodes:
// lights an auxiliary LED if the broker connection is lost,
// so the operator knows the LEDs may be frozen.
// ============================================================
const connected = msg.status && msg.status.text &&
msg.status.text.indexOf("connected") !== -1;
msg.payload = connected; // true = green, false = red
msg.topic = "Basic";
return msg;
Download the full project pack — freeThis example + the related ones + bill of materials