Energiemessung in Home Assistant: lokale API statt Cloud
Mein Energie-Dashboard sah monatelang gut aus — bis ich es das erste Mal ernst genommen habe. Dann fiel auf: die Kurve hatte Löcher. Ganze Stunden fehlten, einzelne Verbraucher sprangen nachts auf null und danach wieder auf einen viel zu hohen Wert. Die Ursache lag nicht an Home Assistant, sondern daran, wo die Messwerte herkamen: aus einer Hersteller-Cloud.
Die Zahlen, auf die ich mich heute verlasse, kommen aus einer lokalen Quelle: meine NEOOM-Anlage hat eine lokale REST-API im eigenen Netz. Kein Login bei einem fremden Server, keine Rate Limits, kein Internet-Zwang. Das ist der eigentliche Unterschied — nicht die Marke, sondern die Frage: Wer antwortet, wenn Home Assistant fragt?
Das eigentliche Problem: Cloud-Zähler sind keine Zähler
Ein Tuya-Gerät in Home Assistant sieht aus wie ein lokales Gerät. Ist es
aber nicht. Die Entität kommt über die tuya-Integration, und die redet
mit dem Rechenzentrum des Herstellers, nicht mit der Steckdose in deinem
Flur. Bei mir hängt zum Beispiel eine mobile Klimaanlage als
climate.portable_air_conditioner genau so drin — Plattform tuya,
Werte über die Cloud.
Für einen Schalter ist das ärgerlich, aber verkraftbar. Für Energie ist es fatal, denn das HA-Energie-Dashboard braucht einen monoton steigenden kWh-Zähler. Jeder Aussetzer erzeugt entweder eine Lücke oder — schlimmer — einen scheinbaren Zählerneustart, den HA als riesigen Verbrauchssprung interpretiert.
Wie real diese Latenz ist, hat mir genau diese Klimaanlage beigebracht.
Wenn du hvac_mode, temperature und fan_mode schnell hintereinander
schickst, zeigt HA kurz cool — und das Gerät meldet dann off zurück.
Geholfen hat nur, die Befehle zu entzerren:
action:
- service: climate.set_hvac_mode
target:
entity_id: climate.portable_air_conditioner
data:
hvac_mode: cool
- delay: "00:00:05"
- service: climate.set_temperature
target:
entity_id: climate.portable_air_conditioner
data:
temperature: 20
Fünf Sekunden Pause, weil der Cloud-Roundtrip den Rest sonst nicht sauber verarbeitet. Fünf Sekunden, um ein Gerät einzuschalten, das in meinem eigenen Haus steht. Das ist der Moment, in dem man merkt: man automatisiert nicht sein Haus, man automatisiert einen fremden Server. Und wenn schon ein simpler Schaltbefehl fünf Sekunden Puffer braucht, willst du auf demselben Weg garantiert keine Zählerstände einsammeln.
Cloud vs. lokal — ehrlich gegenübergestellt
| Kriterium | Hersteller-Cloud (z. B. Tuya) | Lokale API im LAN |
|---|---|---|
| Zuverlässigkeit | Abhängig von Internet + Anbieter | Läuft weiter, auch offline |
| Latenz | 0,5–3 s, schwankend | 50–200 ms, konstant |
| Datenschutz | Verbrauchsprofil verlässt das Haus | Daten bleiben im LAN |
| Zählerqualität | Lücken bei jedem Ausfall | Lückenlos, solange HA läuft |
| Überlebt Hersteller-Abschaltung | Nein | Ja |
| Rate Limits / API-Kontingente | Jederzeit möglich | Nicht vorhanden |
Die vorletzte Zeile ist die wichtige, und sie steht auf keiner Verpackung: Eine Cloud-Integration ist eine Leihgabe. Ändert der Hersteller die API-Bedingungen, führt er Kontingente ein oder stellt den Dienst ein, sind deine Geräte still — und deine Historie im Energie-Dashboard endet an genau diesem Tag. Ein Zähler, der für den Zählerstand erst in einem fremden Rechenzentrum nachfragen muss, ist kein Zähler. Das ist ein Abo.
NEOOM über die lokale API in Home Assistant
Meine Anlage stellt im lokalen Netz einen Endpunkt bereit, der den kompletten Energiefluss als JSON liefert:
http://<neoom-ip>/api/v1/site/state
<neoom-ip> ist die IP deiner Anlage im eigenen Netz — bei mir eine feste
Adresse im 192.168er-Bereich. Trag deine eigene ein und vergib sie im
Router am besten fix, sonst zeigt die Integration nach dem nächsten
DHCP-Lease ins Leere.
Die Antwort enthält unter energyFlow.states[] eine Liste von
Zustandsobjekten mit sprechenden Schlüsseln — unter anderem
POWER_GRID, POWER_PRODUCTION, POWER_CONSUMPTION_CALC und
STATE_OF_CHARGE, dazu die kumulierten Energiesummen.
Der Trick, der die Sache sauber und schonend macht: ein REST-Sensor holt den ganzen Block und legt ihn als JSON-Attribut ab. Alles Weitere sind Template-Sensoren, die nur noch aus diesem Attribut lesen. Ein HTTP-Request pro Intervall, beliebig viele Entitäten.
Ich halte die gesamte Integration in einer Package-Datei,
/config/packages/neoom.yaml. Das hält die configuration.yaml sauber
und man kann die Datei am Stück versionieren:
# /config/packages/neoom.yaml
rest:
- resource: "http://<neoom-ip>/api/v1/site/state"
scan_interval: 30
sensor:
- name: "neoom_raw_state"
value_template: "{{ value_json.energyFlow.states | length }}"
json_attributes_path: "$.energyFlow"
json_attributes:
- states
template:
- sensor:
- name: "neoom Power Production"
unique_id: neoom_power_production
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >
{{ state_attr('sensor.neoom_raw_state', 'states')
| selectattr('key', 'eq', 'POWER_PRODUCTION')
| map(attribute='value') | first | float(0) }}
- name: "neoom Power Grid"
unique_id: neoom_power_grid
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >
{{ state_attr('sensor.neoom_raw_state', 'states')
| selectattr('key', 'eq', 'POWER_GRID')
| map(attribute='value') | first | float(0) }}
- name: "neoom Power Consumption"
unique_id: neoom_power_consumption
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >
{{ state_attr('sensor.neoom_raw_state', 'states')
| selectattr('key', 'eq', 'POWER_CONSUMPTION_CALC')
| map(attribute='value') | first | float(0) }}
- name: "neoom Battery SOC"
unique_id: neoom_battery_soc
unit_of_measurement: "%"
device_class: battery
state_class: measurement
state: >
{{ state_attr('sensor.neoom_raw_state', 'states')
| selectattr('key', 'eq', 'STATE_OF_CHARGE')
| map(attribute='value') | first | float(0) }}
Die kumulierten Zähler laufen nach demselben Muster, brauchen aber die
beiden Zeilen, an denen es fast immer scheitert — device_class: energy
und state_class: total_increasing:
template:
- sensor:
- name: "neoom Energy Imported"
unique_id: neoom_energy_imported
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
state: >
{{ state_attr('sensor.neoom_raw_state', 'states')
| selectattr('key', 'eq', 'ENERGY_IMPORTED')
| map(attribute='value') | first | float(0) }}
Denselben Block gibt es bei mir für neoom_energy_exported,
neoom_energy_produced, neoom_energy_charged und
neoom_energy_discharged. Wichtig: schau dir die JSON-Antwort einmal
selbst an, bevor du die Schlüssel abtippst. Ruf die URL im Browser auf
und vergleiche, welche Keys deine Anlage tatsächlich liefert und in
welcher Einheit — Watt oder Kilowatt macht im Dashboard einen Faktor 1000
Unterschied. Danach in Entwicklerwerkzeuge → Template gegenprüfen.
Zuordnung im Energie-Dashboard
Unter Einstellungen → Dashboards → Energie sieht die Zuordnung bei mir so aus:
| Feld im Energie-Dashboard | Entität |
|---|---|
| Netzbezug | sensor.neoom_energy_imported |
| Einspeisung ins Netz | sensor.neoom_energy_exported |
| Solarerzeugung | sensor.neoom_energy_produced |
| Batterie geladen | sensor.neoom_energy_charged |
| Batterie entladen | sensor.neoom_energy_discharged |
Mehr braucht es nicht. Erscheint eine Entität nicht in der Auswahlliste,
fehlt fast immer state_class: total_increasing oder die Einheit ist
nicht kWh.
So sieht das Ergebnis bei mir aus — ein ganz normaler Sommertag, alle Werte aus der lokalen API:

neoom Energy Produced, Imported, Exported, Charged und Discharged.Interessant ist nicht die Zahl oben rechts, sondern der Verlauf: Die
Balken sind lückenlos. Genau das war mit den Cloud-Werten nicht der
Fall — dort fehlten einzelne Stunden komplett. Gut sichtbar ist auch das
Muster, das die Batterie erzeugt: mittags lädt sie (rosa, unter der
Nulllinie), abends speist sie zurück (türkis). Ohne saubere
total_increasing-Zähler kippt genau diese Darstellung.
Ehrlich bleiben: lokal heißt nicht herstellerunabhängig
Eine lokale API ist deutlich robuster als eine Cloud — aber sie bleibt eine herstellerspezifische Schnittstelle. Feldnamen, Struktur oder Einheiten können sich mit einem Firmware-Update ändern, und niemand schickt dir dazu eine Mail. Mein Umgang damit: nach jedem Update einmal die Roh-URL aufrufen und prüfen, ob die Keys noch stimmen. Der Vorteil gegenüber der Cloud bleibt trotzdem: Wenn sich hier etwas ändert, passiert es zu einem Zeitpunkt, den du auslöst — nicht der Hersteller.
Wenn du einzelne Verbraucher messen willst
NEOOM misst am Hausanschluss, nicht an der Waschmaschine. Wer einzelne Stromkreise oder Steckdosen erfassen will und kein Energiemanagement-System hat, greift üblicherweise zu Messsteckdosen oder kleinen Messrelais; Shelly-Geräte sind hier die verbreitetste Antwort, weil sie eine offene lokale API mitbringen und die Cloud abschaltbar ist. Das ist eine allgemeine Empfehlung, keine Beschreibung meines Aufbaus.
Wichtig, falls du diesen Weg gehst:
Achtung: Messrelais für die Unterputzdose werden fest an 230 V angeschlossen. Arbeiten an der festen Elektroinstallation sind lebensgefährlich. In Deutschland, Österreich und der Schweiz dürfen solche Eingriffe grundsätzlich nur von einer Elektrofachkraft ausgeführt werden — bei Eigenarbeit riskierst du zusätzlich deinen Versicherungsschutz. Wenn du kein Elektriker bist: lass es machen oder nimm die Steckdosenvariante.
Ein Zwischenstecker mit Messfunktion ist die sichere Alternative: einstecken, fertig, keine Elektroarbeit. Liefert das Gerät nur Watt und keine kWh, baust du den Zähler in HA selbst:
sensor:
- platform: integration
source: sensor.waschmaschine_power
name: waschmaschine_kwh
unit_prefix: k
unit_time: h
method: left
utility_meter:
waschmaschine_taeglich:
source: sensor.waschmaschine_kwh
cycle: daily
Tuya-Geräte lokal betreiben (LocalTuya)
Wirfst du deine Tuya-Steckdosen weg? Musst du nicht. LocalTuya ist eine Custom-Integration, die du über HACS installierst und die direkt mit dem Gerät im LAN spricht — vorbei an der Cloud.
- HACS installieren, falls noch nicht vorhanden.
- In HACS nach LocalTuya suchen, installieren, HA neu starten.
- Einmalig Device ID und Local Key aus der Tuya-IoT-Plattform holen — das ist der unangenehme Teil (ein Entwicklerkonto, damit du mit deiner eigenen Steckdose reden darfst), aber du machst ihn genau einmal.
- Geräte in LocalTuya anlegen, die Datenpunkte (DPs) für Power und Energy zuordnen.
Zwei Erfahrungswerte dazu: Der Local Key ändert sich, wenn du das Gerät neu mit der Hersteller-App koppelst — also nach der Einrichtung die App in Ruhe lassen. Und: HACS-Integrationen können nach HA-Updates Warnungen werfen. Eine Deprecation-Meldung im Log ist kein Fehler, sondern ein Hinweis an den Entwickler; das Gerät funktioniert weiter.
Was NICHT hilft
- Scan-Intervall der Cloud-Integration verkürzen. Du bekommst keine besseren Daten, nur schneller ein Rate Limit.
- Mehr Steckdosen der gleichen Cloud-Marke kaufen. Skaliert das Problem, nicht die Lösung.
state_class: measurementfür kWh-Zähler. Falsch. Das ist ein Momentanwert, kein Zähler — das Dashboard nimmt ihn nicht an.- Watt-Sensoren direkt ins Energie-Dashboard hängen. Geht nicht, dafür
brauchst du die
integration-Plattform oben. - Pro Messwert einen eigenen REST-Sensor anlegen. Vervielfacht die Requests auf dieselbe Anlage. Ein Raw-Sensor plus Templates reicht.
- Lücken mit
availability_templateüberkleben. Das versteckt den Ausfall, es repariert ihn nicht. - Alles über einen Bridge-Dienst in der Cloud zusammenführen. Du tauschst eine Abhängigkeit gegen zwei.
Wo ich gelandet bin
Alles, was ich langfristig auswerten will — Netzbezug, Einspeisung, PV-Erzeugung, Batterie — kommt heute aus der lokalen NEOOM-API. Was noch an der Cloud hängt, ist die Klimaanlage: ein Gerät, bei dem mir fünf Sekunden Verzögerung egal sind und dessen Historie ich nicht brauche. Das ist die Trennlinie, die ich empfehle:
Wenn du den Wert in einem Jahr noch im Diagramm sehen willst, muss er lokal erfasst werden. Alles andere ist geliehen.