Waschmaschinen-Status in Node-RED visualisieren

So baust du eine intelligente Statusanzeige mit Homematic, Node-RED und Dashboard

In diesem Beitrag zeige ich dir, wie du mit Node-RED und einer Homematic-Messsteckdose den Status deiner Waschmaschine automatisch ausliest, zuverlässig zwischen „Aus“,„Pause“ und „Fertig“ unterscheidest und den aktuellen Zustand übersichtlich im Dashboard anzeigst. Das Projekt ist ideal, wenn du wissen möchtest, wann deine Wäsche wirklich fertig ist – und nicht nur, ob die Maschine gerade Strom verbraucht.

1. Ausgangslage und Ziel

Viele Waschmaschinen machen am Ende des Programms eine längere Pause oder verbrauchen im Leerlauf noch etwas Strom. Einfache Auswertungen (z.B. „unter 4 Watt = fertig“) führen daher oft zu Fehlalarmen.

Das Ziel:

  • Status „Wäscht“, „Pause“, „Fertig“ und „Aus“ unterscheiden
  • Status im Node-RED Dashboard farbig anzeigen
  • Status automatisch erkennen – auch nach längeren Pausen

2. Hardware und Voraussetzungen

  • Messsteckdose. Bei mir Homematic-Messsteckdose und Homematic-CCU
  • Node-RED

3. Funktionsweise im Überblick

  • Die Messsteckdose liefert regelmäßig den aktuellen Stromverbrauch der Waschmaschine.
  • Ein Node-RED Flow wertet die Werte aus:
    • > 4 Watt: Die Maschine läuft („Wäscht“)
    • 1–4 Watt: Entweder Pause oder fertig – das entscheidet die Zeitdauer
    • < 1 Watt:Aus
    • Bleibt der Wert länger als 2 Minuten im Bereich 1–4 Watt, gilt die Maschine als „Fertig“.
    • Das Ergebnis wird im Dashboard farbig und mit Symbolen angezeigt.

4. Schritt-für-Schritt-Anleitung zum Nachbauen

4.1 Stromverbrauch einlesen

Nutze den `ccu-value` Node, um die Messwerte deiner Homematic-Steckdose abzurufen. Stelle sicher, dass der richtige Kanal und Datenpunkt (`POWER`) ausgewählt ist.

4.2 Logik zur Statusbestimmung

Eine Function-Node übernimmt die Auswertung und speichert Pausenbeginn und -dauer im Kontext. Hier das zentrale Script:

//aus = 0
//wäscht = 1
//Pause = 2
//Fertig = 3    

//Konfiguration:
const fertigWartezeit = 2 * 60 * 1000; //Zeit größer als maximale Waschpause
const geraetePrefix= "WM";


let pauseStart = context.get(geraetePrefix+'pauseStart') || null;
let isPause = context.get(geraetePrefix+'isPause') || false;


if (msg.payload > 4) {
    context.set(geraetePrefix+'pauseStart', null);
    context.set(geraetePrefix+'isPause', false);
    msg.payload = 1; //WÄSCHT
    return msg;
}

if (msg.payload >= 1 && msg.payload <= 4) {
    if (!isPause) {
        context.set(geraetePrefix+'pauseStart', Date.now());
        context.set(geraetePrefix+'isPause', true);
    } else {
        let pauseDuration = Date.now() - context.get(geraetePrefix+'pauseStart');
        if (pauseDuration > fertigWartezeit) { // 2 Minuten
            msg.payload = 3; //FERTIG
            return msg;
        } else {
            msg.payload = 2; //PAUSE
            return msg;
        }
    }
}

if (msg.payload < 1) {
    context.set(geraetePrefix+'pauseStart', null);
    context.set(geraetePrefix+'isPause', false);
    msg.payload = 0; // AUS
    return msg;
}
return null;

Das Script erkennt, ob die Pause länger als 2 Minuten dauert und setzt dann den Status auf „Fertig“.

4.3 Status farbig und mit Symbolen anzeigen

Eine zweite Function-Node setzt die passende Farbe für das Dashboard je nach Status. – Mit dem `ui_led` Node wird der Status als farbiger Kreis angezeigt (z.B. Grün = „Fertig“, Rot = „Wäscht“ usw.). Zusätzlich zeigt ein `ui_text` Node den Status als Text mit Symbol an (z.B. ✅ Fertig, 🚿 Wäscht, 💤 Pause, Aus).

4.4 Sichtbarkeit im Dashboard steuern

Mit einem `switch` Node und `ui_control` kannst du z.B. die Statusanzeige im Dashboard ein- oder ausblenden, je nachdem, ob die Maschine gerade läuft.

5. Flow-Übersicht

So ist der Flow aufgebaut:

1. Datenquelle: `ccu-value` Node liest den Stromverbrauch der Waschmaschine ein.

2. Status-Logik: Function-Node wertet den Verbrauch aus und bestimmt den Status (Aus, Wäscht, Pause, Fertig).

3. Visualisierung: `ui_led` zeigt den Status farbig an. – `ui_text` gibt den Status als Text mit Symbol aus.

4. Dashboard-Steuerung: Mit `switch` und `ui_control` wird die Statusanzeige im Dashboard dynamisch ein- oder ausgeblendet.

6. Tipps zum Nachbauen

– Passe die Schwellenwerte (1 Watt, 4 Watt, 2 Minuten) ggf. an deine Waschmaschine an.

– Die Context-Variablen (`context.get`, `context.set`) funktionieren direkt in der Function-Node – für dauerhafte Speicherung kannst du in den Node-RED Einstellungen die Persistenz aktivieren.

– Das Dashboard kannst du nach Belieben gestalten und z.B. Benachrichtigungen ergänzen.

NodeRed ExportFile

Screenshot aus Nodered mit dem Ablauf.

Hier des komplette NodeRed Export File:

[
    {
        "id": "7468c89c.1ade48",
        "type": "ui_led",
        "z": "bad75d9.4aa3d2",
        "order": 1,
        "group": "804512e2.d68c78",
        "width": 0,
        "height": 0,
        "label": "Waschmaschine Status",
        "labelPlacement": "left",
        "labelAlignment": "left",
        "colorForValue": [
            {
                "color": "#000000",
                "value": "0",
                "valueType": "num"
            },
            {
                "color": "#ff0000",
                "value": "1",
                "valueType": "num"
            },
            {
                "color": "#008000",
                "value": "4",
                "valueType": "num"
            },
            {
                "color": "#ffff00",
                "value": "3",
                "valueType": "num"
            }
        ],
        "allowColorForValueInMessage": false,
        "shape": "circle",
        "showGlow": true,
        "name": "",
        "x": 770,
        "y": 720,
        "wires": []
    },
    {
        "id": "30d60409.e9cbf4",
        "type": "ccu-value",
        "z": "bad75d9.4aa3d2",
        "name": "",
        "iface": "HmIP-RF",
        "channel": "0001DD89973D01:6 Waschmaschine Messwerte",
        "datapoint": "POWER",
        "mode": "",
        "start": true,
        "change": true,
        "cache": true,
        "queue": true,
        "on": 0,
        "onType": "undefined",
        "ramp": 0,
        "rampType": "undefined",
        "working": false,
        "ccuConfig": "38263145.35ea0e",
        "topic": "${CCU}/${Interface}/${channel}/${datapoint}",
        "x": 170,
        "y": 800,
        "wires": [
            [
                "2f8e95d3.efcc12",
                "38b915d0.e2e612",
                "1af2f084.d28617",
                "93e9e08c.743e3"
            ]
        ]
    },
    {
        "id": "aff7bd59.1cc148",
        "type": "ccu-sysvar",
        "z": "bad75d9.4aa3d2",
        "name": "Waschmaschinen",
        "ccuConfig": "38263145.35ea0e",
        "topic": "ReGaHSS/${Name}",
        "change": true,
        "cache": true,
        "x": 810,
        "y": 840,
        "wires": [
            []
        ]
    },
    {
        "id": "5ecf759a.3b5cec",
        "type": "switch",
        "z": "bad75d9.4aa3d2",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "0",
                "vt": "num"
            },
            {
                "t": "neq",
                "v": "0",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 770,
        "y": 800,
        "wires": [
            [
                "6ce3799b.fcee4"
            ],
            [
                "e7f5082f.5b766"
            ]
        ]
    },
    {
        "id": "9a6b6dc2.f90e9",
        "type": "ui_ui_control",
        "z": "bad75d9.4aa3d2",
        "name": "",
        "events": "all",
        "x": 1400,
        "y": 820,
        "wires": [
            []
        ]
    },
    {
        "id": "e7f5082f.5b766",
        "type": "change",
        "z": "bad75d9.4aa3d2",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"group\":{\"show\":[\"Übersicht_Waschmaschine\"]}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1200,
        "y": 840,
        "wires": [
            [
                "9a6b6dc2.f90e9"
            ]
        ]
    },
    {
        "id": "6ce3799b.fcee4",
        "type": "change",
        "z": "bad75d9.4aa3d2",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"group\":{\"hide\":[\"Übersicht_Waschmaschine\"]}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1200,
        "y": 800,
        "wires": [
            [
                "9a6b6dc2.f90e9"
            ]
        ]
    },
    {
        "id": "5779e7d7.bdc",
        "type": "function",
        "z": "bad75d9.4aa3d2",
        "name": "Color",
        "func": "//aus = 0\n//wäscht = 1\n//Pause = 2\n//Fertig = 3  \n\nif (msg.payload == 0) {\n        msg.color = \"black\";\n    } else if (msg.payload == 1) {\n        msg.color = \"red\";\n    } else if (msg.payload == 2) {\n        msg.color = \"yellow\";\n    } else if (msg.payload == 3) {\n        msg.color = \"green\";\n    } else {\n        \n    }\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 770,
        "y": 760,
        "wires": [
            [
                "30bbff38.105e28"
            ]
        ]
    },
    {
        "id": "30bbff38.105e28",
        "type": "change",
        "z": "bad75d9.4aa3d2",
        "name": "Auf/Zu",
        "rules": [
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "1",
                "fromt": "num",
                "to": "🚿 Wäscht",
                "tot": "str"
            },
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "0",
                "fromt": "num",
                "to": "Aus",
                "tot": "str"
            },
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "3",
                "fromt": "num",
                "to": "✅ Fertig",
                "tot": "str"
            },
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "2",
                "fromt": "num",
                "to": "💤 Pause",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 980,
        "y": 760,
        "wires": [
            [
                "cb85db23.4db7f"
            ]
        ]
    },
    {
        "id": "cb85db23.4db7f",
        "type": "ui_text",
        "z": "bad75d9.4aa3d2",
        "group": "c9559968.740fd8",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "Waschmaschine - Übersicht",
        "label": "🧼 Waschmaschine",
        "format": "<font color=\"{{msg.color}}\"> {{msg.payload}}</font>",
        "layout": "row-spread",
        "x": 1236.5500030517578,
        "y": 758.5499877929688,
        "wires": []
    },
    {
        "id": "2f8e95d3.efcc12",
        "type": "function",
        "z": "bad75d9.4aa3d2",
        "name": "",
        "func": "//aus = 0\n//wäscht = 1\n//Pause = 2\n//Fertig = 3    \n\n//Konfiguration:\nconst fertigWartezeit = 2 * 60 * 1000; //Zeit größer als maximale Waschpause\nconst geraetePrefix= \"WM\";\n\n\nlet pauseStart = context.get(geraetePrefix+'pauseStart') || null;\nlet isPause = context.get(geraetePrefix+'isPause') || false;\n\n\nif (msg.payload > 4) {\n    context.set(geraetePrefix+'pauseStart', null);\n    context.set(geraetePrefix+'isPause', false);\n    msg.payload = 1; //WÄSCHT\n    return msg;\n}\n\nif (msg.payload >= 1 && msg.payload <= 4) {\n    if (!isPause) {\n        context.set(geraetePrefix+'pauseStart', Date.now());\n        context.set(geraetePrefix+'isPause', true);\n    } else {\n        let pauseDuration = Date.now() - context.get(geraetePrefix+'pauseStart');\n        if (pauseDuration > fertigWartezeit) { // 2 Minuten\n            msg.payload = 3; //FERTIG\n            return msg;\n        } else {\n            msg.payload = 2; //PAUSE\n            return msg;\n        }\n    }\n}\n\nif (msg.payload < 1) {\n    context.set(geraetePrefix+'pauseStart', null);\n    context.set(geraetePrefix+'isPause', false);\n    msg.payload = 0; // AUS\n    return msg;\n}\nreturn null;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 460,
        "y": 800,
        "wires": [
            [
                "5ecf759a.3b5cec",
                "5779e7d7.bdc",
                "7468c89c.1ade48",
                "aff7bd59.1cc148"
            ]
        ]
    },
    {
        "id": "804512e2.d68c78",
        "type": "ui_group",
        "name": "Waschmaschine",
        "tab": "f2ef0293.ecfaa",
        "order": 3,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "38263145.35ea0e",
        "type": "ccu-connection",
        "name": "localhost",
        "host": "localhost",
        "regaEnabled": true,
        "bcrfEnabled": true,
        "iprfEnabled": true,
        "virtEnabled": true,
        "bcwiEnabled": false,
        "cuxdEnabled": false,
        "regaPoll": true,
        "regaInterval": "30",
        "rpcPingTimeout": "60",
        "rpcInitAddress": "127.0.0.1",
        "rpcServerHost": "127.0.0.1",
        "rpcBinPort": "2047",
        "rpcXmlPort": "2048"
    },
    {
        "id": "c9559968.740fd8",
        "type": "ui_group",
        "name": "Waschmaschine",
        "tab": "b6d53ae.0a35fc8",
        "order": 5,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "f2ef0293.ecfaa",
        "type": "ui_tab",
        "name": "Hausgeräte",
        "icon": "filter_vintage",
        "order": 9,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "b6d53ae.0a35fc8",
        "type": "ui_tab",
        "name": "Übersicht",
        "icon": "home",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

7. Fazit

Mit diesem Node-RED Flow weißt du immer genau, wann deine Waschmaschine wirklich fertig ist – auch wenn sie am Ende noch eine Weile „herumtrödelt“. Das System ist flexibel, einfach nachzubauen und lässt sich auch für andere Geräte anpassen.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert