Skip to Content

← All functionalities

Industrial mixing (touch HMI)TouchBerry PiMQTTHTTPHMI / Dashboard

MQTT-driven status LEDs for a touchscreen machine HMI

The fastest HMI an operator can read is a LED: green means go, red means stop. This example builds a Node-RED touchscreen dashboard on a TouchBerry Pi where a "materials ready" LED follows an MQTT topic published by the line, a text widget translates numeric machine states, and a force-start button publishes orders back to the broker. It is taken from a real deployment on an industrial mixing line, where the panel replaced a rack of physical pilot lights.

From MQTT payload to LED in one line

PLCs rarely publish clean booleans — this line publishes the strings "1" and "0". A tiny function node (msg.payload = msg.payload == "1") converts them for the ui-led widget, which shows green for true and red for false. A second subscriber maps numeric state codes to readable text such as MIXING or ALARM, so the operator never sees raw numbers.

The force button publishes back

The dashboard is not read-only: a "Force mixing" button publishes a small JSON order (action, user, timestamp) to the broker, where the line controller picks it up and starts the cycle. The function node gating the button reuses the admin-session check from the authentication flow, so only a logged-in supervisor can force a cycle — and the published order itself documents who did it and when.

Show the broker state too

A frozen LED is worse than no LED at all, because it lies with confidence. A status node watches the MQTT nodes and drives an extra "MQTT" indicator on the same page: if the broker connection drops, the operator immediately knows the green lights may be stale. With QoS 1 and retained messages on every state topic, the panel repopulates correct values the moment the connection comes back.

A snippet from the implementation

Straight from the example as deployed on the TouchBerry Pi — copy it freely:

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");

The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.

Frequently asked questions

Which dashboard should I use for a touchscreen HMI in Node-RED?

Dashboard 2.0 (@flowfuse/node-red-dashboard) is the maintained option, with ui-led, ui-button and multi-page support that maps well to HMI screens.

Can the TouchBerry Pi run the MQTT broker itself?

Yes. Mosquitto runs comfortably alongside Node-RED on the same device, which keeps the panel working even if the plant network goes down.

How do I avoid stale LED states after a reboot?

Publish the state topics with the retained flag, so every new subscriber — including the dashboard after a restart — immediately receives the last known value.

Related functionalities