Hol dir die Strompreis-Prognosen in dein Smart Home und lade dein E-Auto automatisch dann, wenn Strom günstig ist.
Konto anlegen
Kostenlos registrieren, ohne Zahlungsdaten.
API-Key erstellen
Lege dir unter API-Keys einen Token an.
Plattform wählen
Passenden Code-Block unten kopieren, einfügen, fertig.
DEIN_API_TOKEN. Sobald du eingeloggt bist und einen Key angelegt hast, setzen wir ihn beim Kopieren automatisch ein, ohne ihn auf der Seite anzuzeigen: API-Keys
Bei beiden Varianten werden Daten ab 0 Uhr des aktuellen Tages geliefert. Die Vorhersagen werden täglich zweimal aktualisiert.
Der schnellste Weg ist ein REST-Sensor in der configuration.yaml. Kein HACS, keine Zusatz-Integration.
Home Assistant bringt alles mit, was du brauchst. Die eingebaute RESTful-Integration holt die Prognose alle sechs Stunden ab, Template-Entitäten leiten daraus minutengenau die Werte ab, mit denen du automatisierst. Du musst dafür nichts zusätzlich installieren.
1. REST-Sensor anlegen
Füge den folgenden Block in deine configuration.yaml ein. Der Sensor legt die komplette Viertelstunden-Prognose im Attribut data ab. Sein Status ist der Zeitpunkt, zu dem wir die Prognose berechnet haben, nicht der Preis.
rest:
- resource: "https://www.energyforecast.de/api/v2/forecast?token=DEIN_API_TOKEN"
scan_interval: 21600
timeout: 30
sensor:
- name: "Energyforecast Forecast"
unique_id: energyforecast_forecast
value_template: "{{ value_json.generated_at }}"
device_class: timestamp
json_attributes:
- data
- valid_until
- plan
Sechs Stunden Abstand reichen, weil wir die Prognose zweimal täglich neu berechnen. Das sind vier Abrufe pro Tag, dein Tageslimit bleibt praktisch unberührt.
2. Daraus nutzbare Entitäten bauen
Diese Template-Entitäten lesen die gespeicherte Prognose und vergleichen sie mit der aktuellen Uhrzeit. Weil sie now() verwenden, berechnet Home Assistant sie jede Minute neu, obwohl die Daten nur alle sechs Stunden geholt werden.
template:
- sensor:
# Aktueller Gesamtpreis inkl. Fixkosten, Netzentgelt und Steuern
- name: "Energyforecast Price Now"
unique_id: energyforecast_price_now
unit_of_measurement: "ct/kWh"
state_class: measurement
availability: "{{ state_attr('sensor.energyforecast_forecast', 'data') is not none }}"
state: >
{% set slots = state_attr('sensor.energyforecast_forecast', 'data') or [] %}
{% set ns = namespace(price='') %}
{% for s in slots if ns.price == '' and as_timestamp(s.end) > as_timestamp(now()) %}
{% set ns.price = s.total_ct_kwh | round(2) %}
{% endfor %}
{{ ns.price }}
# Start des günstigsten zusammenhängenden 4-Stunden-Blocks (16 Viertelstunden)
- name: "Energyforecast Best Charging Start"
unique_id: energyforecast_best_charging_start
device_class: timestamp
availability: "{{ state_attr('sensor.energyforecast_forecast', 'data') is not none }}"
state: >
{% set size = 16 %}
{% set slots = state_attr('sensor.energyforecast_forecast', 'data') or [] %}
{% set ns = namespace(future=[]) %}
{% for s in slots if as_timestamp(s.end) > as_timestamp(now()) %}
{% set ns.future = ns.future + [s] %}
{% endfor %}
{% set window = ns.future[:96] %}
{% set best = namespace(price=none, start='') %}
{% for i in range(0, [(window | count) - size + 1, 0] | max) %}
{% set block = window[i:i + size] %}
{% set avg = (block | map(attribute='total_ct_kwh') | sum) / size %}
{% if best.price is none or avg < best.price %}
{% set best.price = avg %}
{% set best.start = block[0].start %}
{% endif %}
{% endfor %}
{{ best.start }}
- binary_sensor:
# An, wenn die aktuelle Viertelstunde zu den 16 günstigsten der nächsten 24 h zählt
- name: "Energyforecast Cheap Now"
unique_id: energyforecast_cheap_now
icon: mdi:ev-station
state: >
{% set size = 16 %}
{% set slots = state_attr('sensor.energyforecast_forecast', 'data') or [] %}
{% set ns = namespace(future=[]) %}
{% for s in slots if as_timestamp(s.end) > as_timestamp(now()) %}
{% set ns.future = ns.future + [s] %}
{% endfor %}
{% set window = ns.future[:96] %}
{% set cheapest = (window | sort(attribute='total_ct_kwh'))[:size] | map(attribute='start') | list %}
{{ (window | count) > 0 and window[0].start in cheapest }}
Damit hast du:
sensor.energyforecast_forecast – die komplette Viertelstunden-Prognose im Attribut data, Status ist der Zeitpunkt der Berechnungsensor.energyforecast_price_now – aktueller Gesamtpreis in ct/kWh, klein genug für die Historiesensor.energyforecast_best_charging_start – Startzeit des günstigsten zusammenhängenden 4-Stunden-Blocks in den nächsten 24 Stundenbinary_sensor.energyforecast_cheap_now – an, wenn die aktuelle Viertelstunde zu den 16 günstigsten der nächsten 24 Stunden gehört3. Datenbank schonen (empfohlen)
Der Prognose-Sensor trägt je nach Tarif einige zehn bis über hundert Kilobyte als Attribut. Nimm ihn aus dem Recorder, damit deine Datenbank nicht unnötig wächst. Die kleinen abgeleiteten Sensoren werden weiterhin aufgezeichnet.
recorder:
exclude:
entities:
- sensor.energyforecast_forecast
4. Home Assistant neu starten
Prüfe die Konfiguration unter Entwicklerwerkzeuge, YAML, Konfiguration prüfen und starte dann neu. Danach findest du die Entitäten unter Einstellungen, Geräte und Dienste, Entitäten.
Diese Automatisierung schaltet deine Wallbox ein, sobald die aktuelle Stunde zu den günstigsten gehört, und wieder aus, wenn nicht. Ersetze switch.wallbox durch deine eigene Entität.
alias: E-Auto in den günstigsten Stunden laden
description: Schaltet die Wallbox in den 4 günstigsten Stunden der nächsten 24 Stunden ein
triggers:
- trigger: state
entity_id: binary_sensor.energyforecast_cheap_now
actions:
- choose:
- conditions:
- condition: state
entity_id: binary_sensor.energyforecast_cheap_now
state: "on"
sequence:
# Strom ist gerade günstig, also laden
- action: switch.turn_on
target:
entity_id: switch.wallbox
default:
# Strom ist gerade teuer, also pausieren
- action: switch.turn_off
target:
entity_id: switch.wallbox
mode: single
Einfügen über Einstellungen, Automatisierungen und Szenen, Automatisierung erstellen, Dreipunkt-Menü, In YAML bearbeiten.
Mit der ApexCharts Card (über HACS) zeigst du die komplette Preiskurve als Balkendiagramm an.
type: custom:apexcharts-card
graph_span: 72h
span:
start: day
experimental:
color_threshold: true
header:
show: true
show_states: true
colorize_states: true
title: Strompreis-Prognose
now:
show: true
color: "#ef4444"
label: Jetzt
yaxis:
- id: price
min: ~0
decimals: 1
apex_config:
title:
text: ct/kWh
apex_config:
chart:
height: 280
legend:
show: false
xaxis:
labels:
format: "ddd HH:mm"
tooltip:
x:
format: "ddd dd.MM. HH:mm"
series:
# Preiskurve - grün bis 25 ct, gelb bis 35 ct, darüber rot
- entity: sensor.energyforecast_forecast
name: Preis
type: column
yaxis_id: price
unit: " ct/kWh"
float_precision: 2
show:
in_header: false
extremas: true
color_threshold:
- value: 0
color: "#16a34a"
- value: 25
color: "#eab308"
- value: 35
color: "#ef4444"
data_generator: |
return (entity.attributes.data || []).map(slot => {
return [new Date(slot.start).getTime(), slot.total_ct_kwh];
});
# Kopfzeile der Karte - Jetzt-Preis, Tagesschnitt und günstigste Viertelstunde der nächsten 24 Stunden
- entity: sensor.energyforecast_forecast
name: Jetzt
yaxis_id: price
unit: " ct/kWh"
float_precision: 2
show:
in_chart: false
in_header: true
data_generator: |
const now = Date.now();
const current = (entity.attributes.data || [])
.find(slot => new Date(slot.end).getTime() > now);
return current ? [[now, current.total_ct_kwh]] : [];
- entity: sensor.energyforecast_forecast
name: Ø heute
yaxis_id: price
unit: " ct/kWh"
float_precision: 1
show:
in_chart: false
in_header: true
data_generator: |
const today = new Date().toDateString();
const slots = (entity.attributes.data || [])
.filter(slot => new Date(slot.start).toDateString() === today);
if (slots.length === 0) return [];
const avg = slots.reduce((sum, slot) => sum + slot.total_ct_kwh, 0) / slots.length;
return [[Date.now(), avg]];
- entity: sensor.energyforecast_forecast
name: Min 24 h
yaxis_id: price
unit: " ct/kWh"
float_precision: 1
show:
in_chart: false
in_header: true
data_generator: |
const now = Date.now();
const slots = (entity.attributes.data || [])
.filter(slot => new Date(slot.end).getTime() > now)
.slice(0, 96);
if (slots.length === 0) return [];
return [[now, Math.min(...slots.map(slot => slot.total_ct_kwh))]];
Die Karte zeigt 3 Tage - genau den Zeitraum, den dein Zugang liefert. Die senkrechte Linie markiert die laufende Viertelstunde, die Balken sind nach Preisniveau eingefärbt, Hoch- und Tiefpunkt sind beschriftet und über dem Diagramm stehen Jetzt-Preis, Tagesdurchschnitt und das Minimum der nächsten 24 Stunden. Alle Werte kommen aus dem REST-Sensor, die Karte braucht die Template-Entitäten also nicht.
In Home Assistant kannst du die Vorhersagen über das Plugin EPEX Spot einbinden. Je nachdem ob du den Free- oder Pro-Tarif nutzt, bekommst du 2 bzw. 6 volle Tage Vorhersage.
Und so gehts:
Wenn du evcc schon nutzt, ist die Anbindung eine Handvoll Zeilen in der evcc.yaml.
Die Vorhersagen können in evcc integriert werden, um zu steuern wann dein Auto geladen wird.
Und so gehts:
Der Preis wird dann über die Formel <code class="bg-gray-50 px-2 py-1 rounded text-sm font-mono">(Preis + fixed_cost_cent) * (1 + vat / 100.0)</code> berechnet.
tariffs:
grid:
type: template
template: energyforecast
token: DEIN_API_TOKEN
charges: # Aufschlag, Zusätzlicher fester Aufschlag pro kWh (z.B. 0.05 für 5 Cent) (optional)
tax: # Steuer, Zusätzlicher prozentualer Aufschlag (z.B. 0.2 für 20%) (optional)
Vor der Integration sind nur die EPEX Spot dayahead Preise verfügbar.
Nach der Integration
Prognose per JavaScript-Adapter abrufen und als Datenpunkte bereitstellen.
ioBroker ist eine Open-Source IoT-Plattform, die besonders in Deutschland sehr beliebt ist. Über den JavaScript-Adapter holst du die Prognose ab und stellst sie als Datenpunkte bereit.
Und so gehts:
// Datenpunkte anlegen (nur beim ersten Lauf nötig)
createState("javascript.0.energyforecast.data", "[]", { type: "string" });
createState("javascript.0.energyforecast.price_now", 0, { type: "number", unit: "ct/kWh" });
createState("javascript.0.energyforecast.cheap_now", false, { type: "boolean" });
// Prognose abrufen und zwischenspeichern (alle 6 Stunden)
async function fetchForecast() {
const res = await httpGetAsync("https://www.energyforecast.de/api/v2/forecast?token=DEIN_API_TOKEN");
setState("javascript.0.energyforecast.data", JSON.stringify(JSON.parse(res.data).data), true);
}
// Aus den gespeicherten Daten die aktuelle Viertelstunde bestimmen (alle 15 Minuten)
function evaluate() {
const slots = JSON.parse(getState("javascript.0.energyforecast.data").val || "[]");
const now = Date.now();
const upcoming = slots.filter(s => new Date(s.end).getTime() > now).slice(0, 96);
if (upcoming.length === 0) return;
const cheapest = [...upcoming]
.sort((a, b) => a.total_ct_kwh - b.total_ct_kwh)
.slice(0, 16)
.map(s => s.start);
setState("javascript.0.energyforecast.price_now", upcoming[0].total_ct_kwh, true);
setState("javascript.0.energyforecast.cheap_now", cheapest.includes(upcoming[0].start), true);
}
schedule("0 */6 * * *", async () => { await fetchForecast(); evaluate(); });
schedule("*/15 * * * *", evaluate);
fetchForecast().then(evaluate);
Tipp: Nutze total_ct_kwh für den Gesamtpreis inklusive Fixkosten, Netzentgelt und Steuern. price_ct_kwh enthält den reinen Börsenpreis, falls du selbst weiterrechnen möchtest.
Flow-basiert automatisieren, eigenständig oder als Home-Assistant-Add-on.
Der Flow trennt Abruf und Auswertung: Ein Takt holt die Prognose alle sechs Stunden und legt sie im Flow-Kontext ab, ein zweiter wertet sie alle 15 Minuten aus und entscheidet, ob gerade geladen werden soll.
Und so gehts:
[
{
"id": "ef_fetch_tick",
"type": "inject",
"name": "Alle 6 Stunden",
"repeat": "21600",
"once": true,
"onceDelay": "5",
"wires": [["ef_fetch"]]
},
{
"id": "ef_fetch",
"type": "http request",
"name": "Energyforecast",
"method": "GET",
"ret": "obj",
"url": "https://www.energyforecast.de/api/v2/forecast?token=DEIN_API_TOKEN",
"wires": [["ef_store"]]
},
{
"id": "ef_store",
"type": "function",
"name": "Prognose zwischenspeichern",
"func": "flow.set('energyforecast', msg.payload.data);\nreturn null;",
"outputs": 1,
"wires": [[]]
},
{
"id": "ef_eval_tick",
"type": "inject",
"name": "Alle 15 Minuten",
"repeat": "900",
"wires": [["ef_eval"]]
},
{
"id": "ef_eval",
"type": "function",
"name": "Günstigste Viertelstunden",
"func": "const size = 16;\nconst slots = flow.get('energyforecast') || [];\nconst now = Date.now();\nconst upcoming = slots.filter(s => new Date(s.end).getTime() > now).slice(0, 96);\nif (upcoming.length === 0) { return null; }\nconst cheapest = [...upcoming].sort((a, b) => a.total_ct_kwh - b.total_ct_kwh).slice(0, size);\nconst cheapNow = cheapest.some(s => s.start === upcoming[0].start);\nmsg.payload = cheapNow ? 'on' : 'off';\nmsg.priceNow = upcoming[0].total_ct_kwh;\nreturn msg;",
"outputs": 1,
"wires": [[]]
}
]
Danach enthält msg.payload den Wert on oder off, msg.priceNow den aktuellen Gesamtpreis in ct/kWh.
Prognose per HTTP-Binding holen und den aktuellen Preis in einer Regel ableiten.
openHAB kann unsere API direkt über das HTTP-Binding abfragen, ganz ohne zusätzliches Add-on.
1. Thing anlegen
Thing http:url:energyforecast "Energyforecast" [
baseURL="https://www.energyforecast.de/api/v2/forecast?token=DEIN_API_TOKEN",
refresh=21600,
timeout=30000
] {
Channels:
Type string : forecast "Prognose" [ stateTransformation="JSONPATH:$.data" ]
}
2. Items anlegen
String Energyforecast_Forecast "Prognose"
{ channel="http:url:energyforecast:forecast" }
Number Energyforecast_Price_Now "Aktueller Preis [%.2f ct/kWh]"
Switch Energyforecast_Cheap_Now "Günstige Ladezeit"
3. Regel für den aktuellen Preis anlegen
Das HTTP-Binding kann per JSONPATH keine „aktuelle" Viertelstunde bestimmen. Diese Regel im JS-Scripting-Ordner wertet die gespeicherte Liste alle 15 Minuten aus und füllt die beiden abgeleiteten Items.
rules.JSRule({
name: "Energyforecast",
triggers: [triggers.GenericCronTrigger("0 */15 * * * ?")],
execute: () => {
const slots = JSON.parse(items.Energyforecast_Forecast.state || "[]");
const now = Date.now();
const upcoming = slots
.filter(s => new Date(s.end).getTime() > now)
.slice(0, 96);
if (upcoming.length === 0) return;
const cheapest = [...upcoming]
.sort((a, b) => a.total_ct_kwh - b.total_ct_kwh)
.slice(0, 16)
.map(s => s.start);
items.Energyforecast_Price_Now.postUpdate(upcoming[0].total_ct_kwh);
items.Energyforecast_Cheap_Now.postUpdate(cheapest.includes(upcoming[0].start) ? "ON" : "OFF");
}
});
Rohdaten per REST abrufen und in dein eigenes Projekt einbauen.
Wenn du dich auskennst kannst du über die API die Daten einfach abrufen und in deinem Projekt verwenden. Die API-Dokumentation findest du unter Swagger / Open API-Dokumentation
Endpunkte
| Endpunkt | Wofür |
|---|---|
/api/v2/forecast
Aktuell
|
Viertelstundenwerte mit Rohpreis (price_ct_kwh) und Gesamtpreis inklusive Fixkosten, Netzentgelt und Steuern (total_ct_kwh), jeweils in Cent. Alle Beispiele auf dieser Seite nutzen diesen Endpunkt. |
/api/v1/predictions/prices_for_ha
Legacy
|
Stundenwerte in Euro pro kWh plus einen fertig berechneten aktuellen Preis. Wird durch v2 abgelöst. |
/api/v1/predictions/prices
Legacy
|
Nur die Preiswerte als flache Liste, praktisch für einfache Skripte. Wird durch v2 abgelöst. |
Parameter
| Parameter | Bedeutung |
|---|---|
token |
Dein API-Key. Pflichtangabe. |
resolution |
HOURLY oder QUARTER_HOURLY. Gilt nur für die v1-Endpunkte, v2 liefert immer Viertelstundenwerte. |
fixed_cost_cent |
Fixkosten in Cent pro kWh. Überschreibt die Einstellung aus deinem Profil. |
vat |
Mehrwertsteuersatz in Prozent, zum Beispiel 19. Überschreibt die Einstellung aus deinem Profil. |
market_zone |
Marktzone, Standard ist DE-LU. |
Schnell ausprobieren
curl "https://www.energyforecast.de/api/v2/forecast?token=DEIN_API_TOKEN"
Falls du eine Integration baust, die für andere Hilfreich sein könnte, lass es uns wissen. Wir freuen uns über jede Integration und helfen gerne bei der Verbreitung.
Kontakt