Node-RED: Bosch Smart Home Raumnamen im globalen Kontext speichern
In diesem Beitrag erfährst du, wie du die Raumnamen deines Bosch Smart Home Systems mithilfe von Node-RED auslesen und im globalen Kontext speichern kannst. Dies ermöglicht dir, in deinen Flows verständliche Raumnamen statt kryptischer IDs zu verwenden, was deine Automatisierungen übersichtlicher und einfacher zu warten macht.
Kernpunkte
- Verständlichkeit: Ersetze technische Raum-IDs durch klare Namen in deinen Node-RED Flows.
- Globaler Kontext: Lerne, wie du Daten zentral speicherst, damit sie in verschiedenen Flows verfügbar sind.
- Bosch Smart Home API: Nutze die lokale API deines Bosch Smart Home Controllers, um Raumdaten abzufragen.
- JavaScript in Node-RED: Verstehe den einfachen Code, der die Raumnamen extrahiert und speichert.
- Effizienz: Frage die Raumnamen einmalig ab (z.B. täglich) und nutze sie dann jederzeit aus dem Speicher.
Inhaltsverzeichnis
- Was ist Node-RED?
- Was ist der globale Kontext in Node-RED?
- Warum Raumnamen speichern?
- Voraussetzungen
- Der Node-RED Flow im Detail
- Wie greife ich auf die gespeicherten Raumnamen zu?
- Anwendungsbeispiele
- Wichtige Hinweise
- Der komplette Flow zum Importieren
Was ist Node-RED?
Node-RED ist eine visuelle Programmierumgebung, die ursprünglich von IBM entwickelt wurde und jetzt ein Open-Source-Projekt ist. Es ermöglicht dir, Hardwaregeräte, APIs und Online-Dienste auf neue und interessante Weise miteinander zu verbinden. Stell es dir wie einen digitalen Baukasten vor: Du ziehst vorgefertigte Bausteine (genannt “Nodes”) auf eine Arbeitsfläche und verbindest sie, um “Flows” zu erstellen. Diese Flows definieren dann, wie Daten verarbeitet und Aktionen ausgelöst werden. Du kannst damit komplexe Automatisierungen für dein Smart Home oder andere IoT-Projekte erstellen, oft ganz ohne selbst Code schreiben zu müssen. Es ist besonders beliebt, um Geräte verschiedener Hersteller miteinander kommunizieren zu lassen.
Was ist der globale Kontext in Node-RED?
In Node-RED gibt es eine Möglichkeit, Informationen zu speichern, die von verschiedenen Nodes oder sogar verschiedenen Flows genutzt werden können, ohne dass diese Informationen direkt über die Nachrichten (“msg”-Objekte) weitergegeben werden müssen. Das nennt man Kontextspeicher. Es gibt drei Ebenen (Scopes) des Kontexts:
- Node-Kontext: Daten sind nur innerhalb des einen Nodes verfügbar, der sie gespeichert hat. Nützlich für interne Zustände eines Function-Nodes.
- Flow-Kontext: Daten sind für alle Nodes innerhalb desselben Flows (also auf demselben Tab im Editor) verfügbar.
- Globaler Kontext: Daten sind für alle Nodes in deiner gesamten Node-RED-Instanz verfügbar, über alle Flows hinweg.
Für unser Ziel, die Raumnamen des Bosch Smart Home Systems systemweit verfügbar zu machen, ist der globale Kontext die richtige Wahl. So können wir die Namen einmal abrufen und speichern und dann in beliebigen anderen Flows darauf zugreifen, zum Beispiel in einem Flow für Benachrichtigungen oder einem für die Anzeige auf einem Dashboard. Wir verwenden die Funktionen global.set("variablenname", wert)
zum Speichern und global.get("variablenname")
zum Abrufen von Werten aus dem globalen Kontext.
Der globale Kontext ist ideal, um systemweite Informationen wie Konfigurationen oder selten ändernde Zustandsdaten zentral zu verwalten.
Warum Raumnamen speichern?
Wenn du mit dem Bosch Smart Home Controller (SHC) über dessen API oder spezielle Node-RED Nodes interagierst, liefern viele Abfragen technische IDs für Räume zurück (z.B. “hz_123…”). Diese IDs sind eindeutig, aber nicht besonders lesbar oder intuitiv. Wenn du eine Benachrichtigung senden möchtest wie “Fenster im Raum X geöffnet”, möchtest du wahrscheinlich “Fenster im Wohnzimmer geöffnet” sehen und nicht “Fenster im hz_123 geöffnet”.
Indem du die Liste aller Räume einmalig abrufst und die Zuordnung von ID zu Name (z.B. {"hz_10": "Wohnzimmer", "hz_24": "Küche"}
) im globalen Kontext speicherst, schaffst du eine Art zentrales “Nachschlagewerk”. Jeder andere Flow kann dann bei Bedarf einfach die ID nehmen, im globalen Kontext den passenden Namen nachschlagen und diesen für menschenlesbare Ausgaben verwenden. Das macht deine Flows verständlicher, einfacher zu debuggen und zu warten.
Voraussetzungen
Bevor du loslegen kannst, stelle sicher, dass du Folgendes eingerichtet hast:
- Eine laufende Node-RED Instanz.
- Ein Bosch Smart Home Controller (SHC), der im selben Netzwerk wie deine Node-RED Instanz erreichbar ist.
- Die IP-Adresse deines SHC.
- Zugangsdaten bzw. Zertifikate für die lokale API des SHC. Für die Interaktion ist oft das Node-RED Modul node-red-contrib-bosch-shc hilfreich, das auch bei der Einrichtung der Verbindung und dem Pairing unterstützt. Alternativ kannst du, wie im gezeigten Flow, direkt die API per HTTP-Request ansprechen, benötigst dann aber gültige Zertifikate.
Hinweis: Die Kommunikation mit der lokalen API des SHC erfolgt über HTTPS (Port 8444) und erfordert eine korrekte Zertifikatkonfiguration in Node-RED.
Der Node-RED Flow im Detail
Der Kern dieses Projekts ist ein einfacher Node-RED Flow, der die Rauminformationen vom SHC abruft und verarbeitet.
Schritt 1: Räume abrufen (HTTP Request Node)
Der erste aktive Node im Flow ist ein HTTP Request Node. Dieser Node ist dafür verantwortlich, die Daten vom Bosch Smart Home Controller abzufragen. Er sendet eine GET-Anfrage an die lokale API des SHC.
- Methode: GET
- URL:
https://<IP-Adresse-Deines-SHC>:8444/smarthome/rooms/
(Ersetze<IP-Adresse-Deines-SHC>
mit der tatsächlichen IP-Adresse deines Controllers). - Rückgabe: Wähle “ein analysiertes JSON Objekt”, da die API die Daten im JSON-Format liefert.
- TLS-Konfiguration: Hier musst du eine TLS-Konfiguration auswählen oder erstellen, die die notwendigen Zertifikate für die sichere Verbindung zum SHC enthält. Dies ist entscheidend, da die Verbindung über HTTPS läuft. Das Modul
node-red-contrib-bosch-shc
kann bei der Erstellung dieser Zertifikate helfen, oder du musst sie manuell beschaffen und in Node-RED hinterlegen.
Wenn die Anfrage erfolgreich ist, enthält msg.payload
ein Array von Objekten, wobei jedes Objekt einen Raum mit seiner ID, seinem Namen und anderen Details repräsentiert.
Schritt 2: Daten verarbeiten (Function Node)
Der nächste Node ist ein Function Node. Hier findet die eigentliche Logik statt, um die empfangenen Daten aufzubereiten und im globalen Kontext zu speichern. Der Node nimmt das Array aus msg.payload
entgegen und führt den folgenden JavaScript-Code aus:
// Initialize an empty object to store room names by their IDs
let roomNames_BSH = {};
// Check if msg.payload is an array
if (Array.isArray(msg.payload)) {
// Loop through each element (room) in the array
msg.payload.forEach(room => {
// Check if the room object has both 'id' and 'name' properties
if (room.id && room.name) {
// Assign the room name to the object using the room ID as key
roomNames_BSH[room.id] = room.name;
}
});
// Save the roomNames_BSH object into the global context
// so it can be accessed from other parts of the flow
global.set("roomNames_BSH", roomNames_BSH);
// Optional: Output a warning message to indicate the data was saved
node.warn("Rooms saved in global context under 'roomNames_BSH'");
} else {
// If msg.payload is not an array, log an error
node.error("msg.payload is not an array");
}
Was passiert hier im Detail?
let roomNames_BSH = {};
: Es wird ein leeres JavaScript-Objekt namensroomNames_BSH
erstellt. Dieses Objekt wird später unsere Zuordnung von Raum-ID zu Raum-Namen enthalten.if (Array.isArray(msg.payload)) { ... }
: Es wird geprüft, ob die ankommendemsg.payload
tatsächlich ein Array ist, wie wir es vom HTTP Request Node erwarten. Dies ist eine wichtige Fehlerprüfung.msg.payload.forEach(room => { ... });
: Wenn es ein Array ist, wird jede Zeile (jeder Raum) im Array durchlaufen.if (room.id && room.name) { ... }
: Für jeden Raum wird geprüft, ob er sowohl eineid
als auch einenname
besitzt.roomNames_BSH[room.id] = room.name;
: Wenn beides vorhanden ist, wird dem ObjektroomNames_BSH
ein neuer Eintrag hinzugefügt. Die Raum-ID (z.B. “hz_123”) wird zum Schlüssel (Key) und der Raumname (z.B. “Wohnzimmer”) wird zum Wert (Value).global.set("roomNames_BSH", roomNames_BSH);
: Nachdem alle Räume verarbeitet wurden, wird das kompletteroomNames_BSH
-Objekt im globalen Kontext unter dem Schlüssel “roomNames_BSH” gespeichert. Ab jetzt ist es global verfügbar.node.warn(...)
: Eine optionale Warnung wird im Debug-Fenster ausgegeben, um zu bestätigen, dass die Speicherung erfolgreich war.else { node.error(...) }
: Fallsmsg.payload
kein Array war, wird eine Fehlermeldung ausgegeben.return msg;
: Die ursprüngliche Nachricht wird weitergeleitet, falls nachfolgende Nodes sie benötigen.
Schritt 3: Trigger (Inject Node)
Der Flow beginnt mit einem Inject Node. Dieser Node löst den gesamten Flow aus. Im Beispiel-Flow ist er so konfiguriert, dass er einmal täglich um 12:00 Uhr mittags auslöst (“Cronjob”). Du kannst dies natürlich anpassen:
- Manuell: Klicke auf den Button am Node, um den Flow bei Bedarf zu starten.
- Beim Start: Konfiguriere den Node so, dass er einmalig auslöst, wenn Node-RED startet oder der Flow deployed wird.
- Zeitgesteuert: Wähle ein Intervall (z.B. alle 24 Stunden) oder einen festen Zeitpunkt (wie im Beispiel), um die Raumnamen regelmäßig zu aktualisieren. Da sich Raumnamen selten ändern, ist ein tägliches Update meist ausreichend.
Schritt 4: Debugging (Debug Node)
Am Ende des Flows befindet sich ein Debug Node. Dieser ist optional, aber sehr nützlich während der Entwicklung. Er zeigt die Nachrichten an, die ihn erreichen. Du kannst ihn hinter den HTTP Request Node schalten, um die Rohdaten vom SHC zu sehen, oder hinter den Function Node (wie im Beispiel, aber deaktiviert), um zu überprüfen, ob die Verarbeitung korrekt funktioniert hat und was der Function Node weitergibt. Die eigentliche Überprüfung, ob die Daten im globalen Kontext gelandet sind, erfolgt jedoch über den Kontext-Daten-Tab in der rechten Seitenleiste von Node-RED oder durch einen anderen Node, der global.get()
verwendet.
Gespeicherten Raumnamen im Kontext
Nachdem der Flow einmal erfolgreich durchgelaufen ist, sind die Raumnamen im globalen Kontext gespeichert. Du kannst nun in jedem beliebigen Function Node in deiner Node-RED Instanz darauf zugreifen.

Anwendungsbeispiele
Mit den gespeicherten Raumnamen kannst du deine Smart-Home-Automatisierung erheblich verbessern:
- Benachrichtigungen: Sende klare Nachrichten an dein Handy oder per Sprache: “Heizung im Badezimmer auf 22°C gestellt.” statt “… im hz_123..”.
- Dashboards: Zeige in deinem Node-RED Dashboard (oder externen Systemen wie Grafana) den Status von Geräten mit verständlichen Raumnamen an.
- Dynamische Steuerung: Erstelle Flows, die basierend auf dem Raumnamen unterschiedliche Aktionen ausführen (z.B. andere Lichtszenen im “Schlafzimmer” als im “Wohnzimmer”).
- Logging: Schreibe Log-Dateien oder Einträge in Datenbanken (z.B. InfluxDB) mit den Raumnamen, um spätere Analysen zu erleichtern.
Wichtige Hinweise
- Persistenz des globalen Kontexts: Standardmäßig wird der Inhalt des globalen Kontexts im Speicher (RAM) gehalten und geht bei einem Neustart von Node-RED verloren. Du musst den Flow also mindestens einmal nach jedem Neustart auslösen (z.B. über den Inject Node mit der Option “Beim Start auslösen”). Alternativ kannst du den Kontextspeicher so konfigurieren, dass er Daten auf der Festplatte ablegt und bei Neustarts automatisch lädt. Suche in der Node-RED Dokumentation nach “Context Storage” für Details. Es gibt auch Flows, die helfen, globale Variablen zu sichern und wiederherzustellen.
- Fehlerbehandlung: Der Beispielcode enthält grundlegende Prüfungen (ist es ein Array? haben Räume ID und Name?). Erweitere die Fehlerbehandlung bei Bedarf, z.B. was passieren soll, wenn der SHC nicht erreichbar ist oder die API-Anfrage fehlschlägt.
- Sicherheit: Der Zugriff auf die SHC API erfordert Zertifikate. Stelle sicher, dass diese sicher gespeichert und gehandhabt werden. Beschränke den Zugriff auf deine Node-RED Instanz.
- Aktualisierung: Wenn du in der Bosch Smart Home App einen Raum umbenennst oder hinzufügst, musst du den Flow manuell oder durch den nächsten geplanten Lauf erneut ausführen, damit die Änderungen im globalen Kontext ankommen.
Der komplette Flow zum Importieren
Hier ist der vollständige Node-RED Flow im JSON-Format. Du kannst diesen Code kopieren und in Node-RED über “Menü -> Importieren” einfügen. Denke daran, die IP-Adresse in der URL des HTTP Request Nodes und die TLS-Konfiguration anzupassen!
[{"id":"e2b8a95a24281245","type":"inject","z":"f48cf010.9333b","g":"84c0a94210ead469","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"00 12 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":3530,"y":800,"wires":[["b0b095d7ce2039f2","b368747f48ea99ae"]]},{"id":"b368747f48ea99ae","type":"http request","z":"f48cf010.9333b","g":"84c0a94210ead469","name":"Room Names","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://192.168.178.186:8444/smarthome/rooms/","tls":"9b926ab94fdcfb8e","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":3740,"y":800,"wires":[["7bd61fb2fc7c89b7"]]},{"id":"7bd61fb2fc7c89b7","type":"function","z":"f48cf010.9333b","g":"84c0a94210ead469","name":"roomNames","func":"// Initialisiere ein Objekt zur Speicherung der Raum-ID und Namen\nlet roomNames_BSH = {};\n\n// Überprüfe, ob msg.payload ein Array ist\nif (Array.isArray(msg.payload)) {\n msg.payload.forEach(room => {\n if (room.id && room.name) {\n roomNames_BSH[room.id] = room.name;\n }\n });\n\n // Speichere das Objekt im globalen Kontext mit dem Namen \"roomNames_BSH\"\n global.set(\"roomNames_BSH\", roomNames_BSH);\n\n // Optional: Ausgabe zur Überprüfung\n node.warn(\"Räume gespeichert im globalen Kontext unter 'roomNames_BSH'\");\n} else {\n node.error(\"msg.payload ist kein Array\");\n}\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":3950,"y":800,"wires":[["71089ef5c87d35aa"]]},{"id":"71089ef5c87d35aa","type":"debug","z":"f48cf010.9333b","g":"84c0a94210ead469","name":"debug 1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":4140,"y":800,"wires":[]},{"id":"9b926ab94fdcfb8e","type":"tls-config","name":"Controller","cert":"","key":"","ca":"","certname":"client-cert.pem","keyname":"client-key.pem","caname":"","servername":"","verifyservercert":false,"alpnprotocol":""}]
Das Speichern von Raumnamen im globalen Kontext ist eine einfache, aber effektive Methode, um deine Node-RED-Flows im Zusammenhang mit dem Bosch Smart Home System übersichtlicher und benutzerfreundlicher zu gestalten. Viel Spaß beim Ausprobieren und Erweitern deiner Smart-Home-Automatisierung!
Add comment