Der Node-RED Context ist der eingebaute Schlüssel-Wert-Speicher, mit dem sich ein Flow Werte zwischen Nachrichten merkt, etwa die letzte Temperatur, die ein Sensor gemeldet hat, oder einen Zähler der heutigen Alarme. Diese Erklärung behandelt die drei Context-Gültigkeitsbereiche, wie Context Neustarts übersteht, wie Sie mehrere Speicher gleichzeitig nutzen und ein sauberes Muster, um den letzten MQTT-Wert jedes Geräts zu behalten.
Warum Flows einen Zustand brauchen
Nachrichten in Node-RED sind unabhängig voneinander. Wenn ein mqtt in-Node einen Messwert ausgibt, kennt der nächste Node nur, was in dieser Nachricht steht. Viele reale Aufgaben brauchen mehr:
- Einen Wert mit dem vorherigen vergleichen, um eine Änderung oder einen Trend zu erkennen.
- Eine HTTP-Anfrage mit dem jüngsten Messwert beantworten, obwohl gerade keine MQTT-Nachricht eintrifft.
- Ereignisse pro Schicht zählen oder sich merken, wann ein Alarm begann.
- Werte aus zwei Topics kombinieren, die zu unterschiedlichen Zeiten eintreffen.
MQTT selbst bietet eine Form von Gedächtnis über retained messages: Der Broker speichert die letzte Nachricht eines Topics und übergibt sie neuen Abonnenten. Das ist ideal für Zustände, die mehrere Clients teilen, und Sie sollten es nutzen. Context ist das ergänzende Werkzeug für Zustände, die innerhalb von Node-RED leben. Wenn Sie unsicher sind, auf welche Seite eine Aufgabe gehört, zieht unsere Erklärung Was ein MQTT-Broker macht die Grenze.
Die drei Gültigkeitsbereiche des Node-RED Context
| Gültigkeitsbereich | Sichtbar für | Typische Verwendung | Zugriff in einer Function |
|---|---|---|---|
| Node | Nur den Node, der ihn gesetzt hat | Totbandfilter, Zähler innerhalb einer Function | context.get() / context.set() |
| Flow | Alle Nodes im selben Tab (oder in derselben Subflow-Instanz) | Letzte Werte, die mehrere Nodes eines Tabs nutzen | flow.get() / flow.set() |
| Global | Jeden Node der Node-RED-Instanz | Gemeinsame Konfiguration, Nachschlagetabellen | global.get() / global.set() |
Wählen Sie den engsten Gültigkeitsbereich, der funktioniert. Ein Wert im Global Context kann von jedem Node in jedem Tab geändert werden, was Fehler schwer nachvollziehbar macht. Node Context ist privat, nichts anderes kann ihn beschädigen.
Sie müssen keinen Code schreiben, um Context zu nutzen. Der Change-Node kann flow.- und global.-Eigenschaften setzen, lesen, verschieben und löschen, und Inject-, Switch- und Template-Nodes können sie lesen. Der Tab Context Data in der Seitenleiste des Editors zeigt die aktuellen Werte jedes Gültigkeitsbereichs und erlaubt es, Einträge beim Debuggen zu aktualisieren oder zu löschen.
Subflows haben eine Besonderheit: Der Flow Context innerhalb eines Subflows gehört zu dieser Instanz. Ein Subflow erreicht den Context seines übergeordneten Flows mit dem Präfix $parent., etwa flow.get("$parent.lastTemp").
Arbeitsspeicher vs. persistenter Context
Standardmäßig wird aller Context im Arbeitsspeicher gehalten. Das ist schnell, verschwindet aber, wenn Node-RED neu startet, der Container neu erstellt wird oder der Host neu bootet. Für alles, was Sie nicht leicht wiederherstellen können, schalten Sie dateibasierten Speicher ein.
Öffnen Sie settings.js (bei einer Standardinstallation in ~/.node-red/, im Docker-Image in /data/) und suchen Sie den Abschnitt contextStorage:
// settings.js
module.exports = {
// ...
contextStorage: {
default: { module: "memory" },
file: { module: "localfilesystem" }
},
// ...
};
Starten Sie Node-RED neu. Sie haben nun zwei Speicher: default, der im Arbeitsspeicher bleibt, und file, der JSON-Dateien im Ordner context/ Ihres Benutzerverzeichnisses schreibt. Nodes wählen einen Speicher explizit:
flow.set("lastReading", msg.payload, "file"); // persistent
flow.set("scratch", 42); // Arbeitsspeicher (Standardspeicher)
const last = flow.get("lastReading", "file");
Im Change-Node und in anderen Editoren erscheint neben flow.- und global.-Feldern eine kleine Speicherauswahl, sobald Sie mehr als einen Speicher haben.
Soll alles persistent sein, setzen Sie stattdessen default: { module: "localfilesystem" }. Beachten Sie, wie der Dateispeicher arbeitet: Werte werden im Arbeitsspeicher zwischengespeichert und in einem Intervall auf die Festplatte geschrieben, standardmäßig alle 30 Sekunden, gesteuert über die Option flushInterval. Ein harter Absturz kann die Änderungen der letzten Sekunden verlieren. Für letzte Werte und Zähler ist das in Ordnung, aber Context ist keine Datenbank. Für historische Daten schreiben Sie in einen Zeitreihenspeicher wie InfluxDB, wie in unserem Node-RED-InfluxDB-Leitfaden gezeigt.
Beachten Sie auch, dass nur JSON-serialisierbare Werte zuverlässig persistiert werden. Funktionen, Timer und Klasseninstanzen kommen nach einem Neustart nicht intakt zurück; speichern Sie daher einfache Objekte, Zahlen und Zeichenketten.
Synchroner und asynchroner Zugriff
Mit den Speichern memory und localfilesystem arbeiten get und set wie oben gezeigt synchron. Manche Drittanbieter-Speicher, etwa Redis-basierte Module, sind asynchron und erfordern Callbacks:
flow.get("count", "redis", (err, count) => {
if (err) { node.error(err, msg); return; }
count = (count || 0) + 1;
flow.set("count", count, "redis", (err) => {
if (err) { node.error(err, msg); return; }
msg.payload = count;
node.send(msg);
node.done();
});
});
Code von Anfang an mit Callbacks zu schreiben kostet wenig und bedeutet, dass Sie den Speicher später wechseln können, ohne jede Function neu zu schreiben. Beachten Sie, dass ein get gefolgt von einem set nicht atomar ist. Bei sehr hohen Nachrichtenraten auf einem asynchronen Speicher können zwei Nachrichten denselben alten Zählerstand lesen. Halten Sie Zähler im Node Context, wo nur ein Node sie schreibt, oder bündeln Sie Aktualisierungen.
Sie können auch mehrere Schlüssel auf einmal lesen und schreiben, indem Sie Arrays übergeben: flow.get(["a", "b"]) liefert ein Array von Werten.
Muster: Den letzten MQTT-Wert pro Gerät behalten
Eine häufige Aufgabe für den Node-RED Context ist eine Live-Tabelle der zuletzt bekannten Werte: ein Eintrag pro Gerät, bei jeder Nachricht aktualisiert, von überall im Flow lesbar. Publizieren Sie einige Testdaten an den Öffentlichen MQTT-Broker von ConnectMQ und ersetzen Sie c8d1 durch Ihre eigene Zufallszeichenfolge (er ist nur für Tests gedacht, alle Daten sind öffentlich lesbar):
mosquitto_pub -h broker.connectmq.com -p 1883 -i demo-ctx-c8d1 \
-t "connectmq/demo/c8d1/boiler/tank1/telemetry" -m '{"level": 71.5, "temp": 63.2}'
mosquitto_pub -h broker.connectmq.com -p 1883 -i demo-ctx-c8d1 \
-t "connectmq/demo/c8d1/boiler/pump2/telemetry" -m '{"rpm": 1450, "temp": 41.0}'
Abonnieren Sie in Node-RED mit einem mqtt in-Node auf connectmq/demo/c8d1/+/+/telemetry, Ausgabe auf geparstes JSON gesetzt, und verbinden Sie ihn mit dieser Function:
// Function "store latest"
const parts = msg.topic.split("/");
const deviceId = parts[3] + "/" + parts[4]; // z. B. "boiler/tank1"
const latest = flow.get("latest", "file") || {};
latest[deviceId] = {
values: msg.payload,
ts: Date.now()
};
flow.set("latest", latest, "file");
node.status({ text: Object.keys(latest).length + " devices" });
return null;
Nun kann jeder Node im Tab die Tabelle lesen. Ein http in-Node auf GET /latest, gefolgt von dieser Function und einem http response-Node, ergibt eine kleine API:
// Function "serve latest"
const latest = flow.get("latest", "file") || {};
const staleMs = 5 * 60 * 1000;
const now = Date.now();
msg.payload = Object.entries(latest).map(([id, v]) => ({
device: id,
values: v.values,
ageSeconds: Math.round((now - v.ts) / 1000),
stale: now - v.ts > staleMs
}));
return msg;
Das Flag stale ist das entscheidende Detail. Eine Tabelle letzter Werte, die nie abläuft, zeigt munter den Messwert eines Geräts, das gestern ausgefallen ist. Speichern Sie immer einen Zeitstempel zusammen mit dem Wert.
In industriellen Anwendungen lohnt es sich, die Geräteschlüssel an der ISA-95-Hierarchie auszurichten, etwa werk-muenchen/montage/linie-1/zelle-2. Dann spiegelt die Context-Tabelle dieselbe Struktur wider wie der Unified Namespace (UNS) auf dem Broker, und Werte lassen sich eindeutig einer Anlage zuordnen.
Checkliste: Best Practices für den Node-RED Context
- Verwenden Sie den engsten Gültigkeitsbereich: Node, dann Flow, dann Global.
- Aktivieren Sie einen Dateispeicher und wählen Sie ihn explizit für Werte, die Sie nicht wiederherstellen können.
- Speichern Sie Zeitstempel zusammen mit den Werten, damit Sie veraltete Daten erkennen.
- Vermeiden Sie riesige Objekte; große Context-Einträge verlangsamen jeden Flush und jede Aktualisierung der Seitenleiste.
- Versehen Sie globale Schlüssel mit einem Präfix nach Zweck, etwa
cfg_für Konfiguration undcache_für Nachschlagedaten. - Speichern Sie keine Geheimnisse im Context. Zugangsdaten gehören in Config-Nodes und Umgebungsvariablen.
- Nutzen Sie retained MQTT-Nachrichten für Zustände, die andere Clients brauchen, und Context für Zustände, die nur Node-RED braucht.
- Sichern Sie den Ordner
context/zusammen mit Ihren Flows. Betreiben Sie Node-RED in Containern? Unser Node-RED-Docker-Leitfaden zeigt, wie Sie/dataauf einem persistenten Volume halten.
Die offizielle Context-Dokumentation behandelt die Speicher-API und die Konfigurationsoptionen vollständig. Für die Code-Seite dieser Muster siehe unseren Leitfaden zum Node-RED Function-Node, und für das größere Bild der Anbindung von Flows an Broker das Node-RED-MQTT-Tutorial.
Node-RED Context mit ConnectMQ kombinieren
Context bewahrt das Gedächtnis von Node-RED; der Broker das aller anderen. ConnectMQ ist ein vollständig verwalteter MQTT-Broker mit retained messages, MQTT-5-Session-Ablauf und TLS, sodass Geräte, Dashboards und Node-RED konsistente zuletzt bekannte Werte sehen. Das Portal ergänzt einen Live-Topic-Explorer und Schwellwert-Alarmregeln für schnelle Prüfungen, ohne einen Flow zu bauen. Starten Sie mit dem kostenlosen Serverless-Plan unter app.connectmq.com, ohne Kreditkarte, und verbinden Sie Node-RED mit dem generierten Benutzernamen, Passwort und der Client-ID.
Häufig gestellte Fragen
Was ist der Unterschied zwischen Flow und Global Context in Node-RED?
Flow Context teilen nur die Nodes im selben Tab, Global Context dagegen alle Nodes der Node-RED-Instanz. Verwenden Sie Flow Context, sofern nicht wirklich mehrere Tabs denselben Wert brauchen.
Wie übersteht der Node-RED Context einen Neustart?
Fügen Sie in settings.js unter contextStorage einen localfilesystem-Speicher hinzu, starten Sie Node-RED neu und schreiben Sie in diesen Speicher, zum Beispiel flow.set("key", value, "file").
Wo speichert Node-RED persistente Context-Dateien?
In einem Ordner context im Node-RED-Benutzerverzeichnis, meist ~/.node-red/context oder in Docker /data/context, gegliedert nach Gültigkeitsbereich.
Sollte ich für letzte Werte Context oder retained MQTT-Nachrichten verwenden?
Verwenden Sie retained messages, wenn andere MQTT-Clients den letzten Wert brauchen, und Context, wenn nur Node-RED ihn braucht, etwa um eine API zu bedienen oder Messwerte zu vergleichen. Viele Flows nutzen beides.



