Node-RED · Preis und CO2
Strompreis und CO2 in Node-RED nutzen, ohne lange zu klicken
Wenn du Node-RED nutzt, ist der einfachste Einstieg ein importierbarer Flow. Du fügst ihn ein, klickst auf Deploy und siehst sofort Preis, CO2, Zeitfenster und die wichtigsten Meta-Felder im Debug.
- eigener Node-RED-Endpunkt für sauberes Nutzungs-Tracking
- Import-Flow statt langer Hand-Konfiguration
- optional mit Bearer-Token und klarer Fehlerausgabe
Node-RED kann JSON-APIs direkt verarbeiten. Du brauchst deshalb keine Spezialintegration, sondern nur einen kleinen Flow mit Inject, Function, HTTP Request und Debug.
Im Beispiel ist der HTTP-Request so konfiguriert, dass er die Antwort direkt als geparstes Objekt zurückgibt. Dann musst du später keine JSON-Strings manuell auseinandernehmen.
Empfohlener Endpunkt
Für Node-RED gibt es einen eigenen Summary-Pfad mit den wichtigsten Feldern für erste Automationen und mit Meta-Feldern für Limits und API-Key-Status.
https://api.energypriceforecast.eu/api/v1/node-red/summary?country=de&hours=48&window_hours=4msg.*.msg.api_key_state, msg.allowed_horizon_hours und mehr kommen direkt mit.Was die API genau liefert
Der Endpunkt liefert eine kompakte Automation-Summary. Für Node-RED ist das praktisch, weil du die Antwort einerseits direkt für einfache Flows nutzen kannst, andererseits aber genug Struktur für spätere Erweiterungen bekommst.
| Teil | Inhalt | Nutzen |
|---|---|---|
flat | Die einfachsten Felder wie aktueller Preis, aktuelles CO2, aktive beste Fenster und Restlaufzeiten. | Sofort für msg.* nutzbar. |
price | Aktueller Preis-Slot sowie best_window und next_full_window als Objekte. | Mehr Kontext für eigene Flows. |
co2 | Aktueller CO2-Slot sowie best_window und next_full_window. | Für CO2-orientierte Entscheidungen. |
source | Metadaten zu Day-Ahead und Forecast. | Wichtig für Einordnung und Debug. |
meta | Zugriffs- und Vertragsinfos wie API-Key-Status, erlaubter Horizont und Tageszähler. | Sauberes Monitoring pro Nutzer oder Flow. |
Zeitraum und Auflösung
Das Beispiel nutzt hours=48 und window_hours=4. Das ist ein Startpunkt, nicht die komplette Produktgrenze.
hours legst du den angefragten Horizont fest. Öffentlich belastbar kommunizieren wir für die Preisprognose aktuell maximal 120 Stunden.meta.allowed_horizon_hours.source.price.day_ahead_entries und source.price.forecast_entries zählen Slots, nicht Stunden. Deshalb können Zahlen wie 97 Day-Ahead und 0 Forecast plausibel sein, wenn der angefragte Zeitraum gerade schon fast vollständig mit veröffentlichten Day-Ahead-Werten abgedeckt ist.
Schnellstart für Copy-Paste
- In Node-RED oben rechts auf
Importklicken. - Den kompletten JSON-Block unten einfügen.
- Importieren und danach auf
Deployklicken. - Die Debug-Seitenleiste öffnen und den Inject-Knopf einmal manuell auslösen.
country=de in der URL und optional den API-Key im Function-Node.msg.current_price, msg.current_co2_g_kwh, aktive beste Fenster, nächste vollständige Zukunftsfenster und die wichtigsten Meta-Felder.Import-Flow für Node-RED
Den gesamten Block kopieren und in Node-RED importieren. Wenn du keinen API-Key hast, bleibt der String im Function-Node einfach leer.
[
{
"id": "epf_tab",
"type": "tab",
"label": "StrompreisVorhersage",
"disabled": false,
"info": ""
},
{
"id": "epf_inject",
"type": "inject",
"z": "epf_tab",
"name": "Jetzt laden",
"props": [],
"repeat": "900",
"once": true,
"onceDelay": "1",
"topic": "",
"x": 120,
"y": 120,
"wires": [["epf_auth"]]
},
{
"id": "epf_auth",
"type": "function",
"z": "epf_tab",
"name": "API-Key optional",
"func": "const API_KEY = \"\";\\nmsg.headers = {};\\nif (API_KEY.trim()) {\\n msg.headers.Authorization = \"Bearer \" + API_KEY.trim();\\n}\\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 340,
"y": 120,
"wires": [["epf_http"]]
},
{
"id": "epf_http",
"type": "http request",
"z": "epf_tab",
"name": "Summary abrufen",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.energypriceforecast.eu/api/v1/node-red/summary?country=de&hours=48&window_hours=4",
"persist": false,
"x": 570,
"y": 120,
"wires": [["epf_extract"]]
},
{
"id": "epf_extract",
"type": "function",
"z": "epf_tab",
"name": "Wichtige Felder setzen",
"func": "const data = msg.payload || {};\\nconst flat = data.flat || {};\\nconst meta = data.meta || {};\\nconst price = data.price || {};\\nconst co2 = data.co2 || {};\\n\\nmsg.current_price = flat.current_price;\\nmsg.current_co2_g_kwh = flat.current_co2_g_kwh;\\nmsg.cheapest_window_start = flat.cheapest_window_start || null;\\nmsg.greenest_window_start = flat.greenest_window_start || null;\\nmsg.is_cheapest_window_now = flat.is_cheapest_window_now === true;\\nmsg.cheapest_window_remaining_minutes = flat.cheapest_window_remaining_minutes ?? null;\\nmsg.next_full_cheapest_window_start = price.next_full_window ? price.next_full_window.start : null;\\nmsg.is_greenest_window_now = flat.is_greenest_window_now === true;\\nmsg.next_full_greenest_window_start = co2.next_full_window ? co2.next_full_window.start : null;\\nmsg.api_key_state = meta.api_key_state || 'missing';\\nmsg.allowed_horizon_hours = meta.allowed_horizon_hours;\\nmsg.used_horizon_hours = meta.used_horizon_hours;\\nmsg.rate_limit_daily = meta.rate_limit_daily;\\nmsg.used_calls_today = meta.used_calls_today;\\n\\nif (msg.statusCode === 401) {\\n msg.error = '401: API-Key fehlt, ist ungültig oder wurde deaktiviert.';\\n} else if (msg.statusCode === 403) {\\n msg.error = '403: Zugriff für Route, Markt oder Vertragszustand nicht erlaubt.';\\n} else if (msg.statusCode === 429) {\\n msg.error = '429: Tageslimit erreicht.';\\n} else {\\n msg.error = null;\\n}\\n\\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 830,
"y": 120,
"wires": [["epf_debug"]]
},
{
"id": "epf_debug",
"type": "debug",
"z": "epf_tab",
"name": "Werte anzeigen",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 1070,
"y": 120,
"wires": []
}
]
Danach kannst du anstelle des Debug-Knotens später eigene Logik anschließen, zum Beispiel Dashboard, Benachrichtigungen oder Scheduler-Regeln.
Für Automationen: Anzeige und Laufentscheidung trennen
Für Dashboards reicht oft msg.cheapest_window_start. Für echte Steuerung ist aber meist wichtiger, ob das beste Fenster bereits läuft. Genau dafür setzt der Flow zusätzlich msg.is_cheapest_window_now und msg.cheapest_window_remaining_minutes.
if (msg.is_cheapest_window_now) {
// Verbraucher jetzt freigeben
} else if (msg.next_full_cheapest_window_start) {
// nächstes vollständiges Fenster für Planung verwenden
}
return msg;
Pragmatisch: Ein Boolean für "jetzt" ist für Automationen meist wertvoller als nur ein Zeitstempel in der Zukunft.
Welche Message-Felder du danach hast
| Feld | Bedeutung | Typischer Einsatz |
|---|---|---|
msg.current_price | Aktueller Preis in EUR/kWh. | Einfache Preislogik oder Debug-Ausgabe. |
msg.current_co2_g_kwh | Aktuelle CO2-Intensität. | CO2-orientierte Steuerung. |
msg.cheapest_window_start | Startzeit des günstigsten zukünftigen Fensters. | Spätere Timer- oder Scheduler-Logik. |
msg.greenest_window_start | Startzeit des CO2-ärmsten zukünftigen Fensters. | Ökologische Lastverschiebung. |
msg.is_cheapest_window_now | true, wenn das beste Preisfenster bereits läuft. | Direkte Laufentscheidung für Verbraucher. |
msg.cheapest_window_remaining_minutes | Restlaufzeit des aktuell besten Preisfensters. | Gerät nur so lange laufen lassen, wie das Fenster aktiv ist. |
msg.next_full_cheapest_window_start | Startzeit des nächsten vollständigen Preisfensters in der Zukunft. | Planung statt Sofort-Trigger. |
msg.api_key_state | Status des verwendeten API-Keys. | Sauberes Monitoring pro Nutzer oder Flow. |
msg.allowed_horizon_hours | Serverseitig erlaubter Maximalhorizont. | Prüfen, ob ein Key mehr freischaltet. |
msg.used_calls_today | Heute bereits verbrauchte Requests. | Limits im Blick behalten. |
msg.error | Lesbarer Fehlertext bei 401, 403 oder 429. | Direkte Fehlersuche im Debug. |
Wichtige Hinweise
Ist das ein offizieller Node-RED-Node?
Nein. Es ist bewusst ein normaler Flow mit Standardknoten. Das ist für den Einstieg leichter nachvollziehbar und besser an eigene Automationen anpassbar.
Wie oft sollte ich abrufen?
Alle 15 Minuten sind ein sinnvoller Start. Die Summary ist kein Sekunden-Feed. Häufigeres Polling erhöht nur Last und Tagesverbrauch.
Was tun bei 401, 403 oder 429?
Der Flow schreibt dafür einen lesbaren Text in msg.error. 401 steht für Key-Probleme, 403 für einen nicht erlaubten Zugriff und 429 für ein erreichtes Tageslimit.
Was tun, wenn im Debug nichts Brauchbares ankommt?
Prüfe zuerst, ob der HTTP-Request wirklich als geparstes Objekt zurückkommt. Wenn statt JSON HTML ankommt, zeigt die URL wahrscheinlich auf den falschen Pfad oder eine fehlerhafte Zwischenadresse.
Kleine Testphase
Für die neue Node-RED-Anbindung läuft aktuell eine kleine Testphase. Gesucht sind vor allem echte Flows, bei denen schnell sichtbar wird, ob die importierbaren Beispiele verständlich sind und ob die Daten in realen Automationen sauber weiterverarbeitet werden können.
Wenn du Node-RED aktiv nutzt und das testen möchtest, schreib kurz mit deinem Setup und Markt an StrompreisVorhersage@proton.me. Die ersten Testeinbindungen werden bewusst noch manuell begleitet.
Verwandt: ioBroker, openHAB und Home Assistant.