Inhaltsverzeichnis
Fast jeder Guide zum Huawei SUN2000 fängt mit demselben Satz an: „Installier die huawei-solar Custom-Integration.“ Und sie funktioniert auch — bis zum nächsten Home-Assistant-Upgrade, das eine Breaking-Change einführt, die Integration nicht mehr lädt und plötzlich das halbe Energy-Dashboard leer ist. Genau das ist mir zweimal passiert, bevor ich den dependency-freien Weg gegangen bin.
Der SUN2000 spricht nämlich von Haus aus Modbus-TCP, und Home Assistant bringt eine eingebaute modbus:-Plattform mit. Man braucht keine Custom-Komponente — man deklariert jeden Sensor selbst über seine Registeradresse. Das ist etwas mehr YAML, dafür bricht nichts beim Upgrade, und du verstehst genau, woher jeder Wert kommt. Dieser Post liefert die komplette Register-zu-YAML-Karte für PV-Ertrag, Batterie und Netz — fertig fürs Energy-Dashboard.
Warum native modbus-YAML statt Custom-Integration
Die Custom-Integration ist bequem, aber sie ist eine zusätzliche Abhängigkeit zwischen dir und deinen Daten. Bei jedem HA-Update riskierst du, dass sie nicht mehr kompatibel ist, und du sitzt im Zweifel zwei Tage ohne Energiedaten da, bis ein Maintainer nachzieht. Die eingebaute modbus:-Plattform ist Kern-Bestandteil von Home Assistant — sie wird mit dem Core gepflegt und kann nicht „verwaisen“. Der Preis ist Transparenz statt Magie: du schreibst pro Wert eine Handvoll Zeilen mit Registeradresse, data_type und scale. Genau diese Zeilen liefere ich hier.
Der Modbus-Hub: auf den Proxy zeigen, nicht direkt auf den SDongle
Der SDongle des SUN2000 erlaubt nur eine gleichzeitige Modbus-Verbindung. Wenn HA, evcc und ein AC·THOR alle direkt darauf zugreifen, blockieren sie sich gegenseitig. Deshalb zeigt mein Modbus-Hub nicht auf die SDongle-IP, sondern auf 127.0.0.1:5502 — den lokalen Caching-Proxy, der den SDongle einmal pollt und das Ergebnis an beliebig viele Clients ausliefert. Warum und wie das nötig ist, beschreibe ich im Modbus-Caching-Grundlagen-Post. Wenn du nur einen einzigen Client hast, kannst du host/port stattdessen direkt auf den SDongle setzen — die Sensoren darunter bleiben identisch.
- name: huawei_inverter
type: tcp
host: 127.0.0.1
port: 5502
delay: 2
timeout: 10
sensors:
- name: "PV Gesamt Ertrag"
unique_id: huawei_pv_cumulative_yield
slave: 1
address: 32106
input_type: holding
data_type: uint32
scale: 0.01
precision: 2
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
scan_interval: 60Die zwei Felder, auf die es fürs Energy-Dashboard ankommt, sind device_class: energy und state_class: total_increasing. Ohne sie taucht der Sensor in der Energy-Konfiguration gar nicht erst als wählbare Quelle auf. Der delay: 2 am Hub gibt dem (langsamen) SDongle nach dem Verbindungsaufbau zwei Sekunden Luft, bevor der erste Read kommt — ohne das siehst du sporadische Timeouts beim Start.
Batterie: Gesamtladung und -entladung als uint32
Die Batterie-Energieregister sind kumulative Zähler — sie laufen nur hoch und passen damit perfekt zu total_increasing. Wichtig ist hier der data_type uint32: die Werte überschreiten schnell den 16-Bit-Bereich und belegen deshalb zwei aufeinanderfolgende Register (37780 und das Folgeregister). HA liest beide zusammen, wenn du data_type uint32 setzt — keine zweite Adresse nötig.
- name: "Batterie Gesamt Ladung"
unique_id: huawei_battery_total_charge
slave: 1
address: 37780
input_type: holding
data_type: uint32
scale: 0.01
precision: 2
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
scan_interval: 60
- name: "Batterie Gesamt Entladung"
unique_id: huawei_battery_total_discharge
slave: 1
address: 37782
input_type: holding
data_type: uint32
scale: 0.01
precision: 2
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
scan_interval: 60Diese beiden Sensoren trägst du im Energy-Dashboard als „Heimspeicher“ ein — Ladung als „Energie in den Speicher“, Entladung als „Energie aus dem Speicher“. Damit zeichnet HA die Batterie-Round-Trip-Bilanz korrekt nach.
Netz: Bezug und Einspeisung als signed int32
Bei den Netzregistern ist der typische Fehler der data_type. Netzwerte können je nach Firmware als signed int32 kommen — wenn du sie versehentlich als uint32 liest, kippt ein knapp positiver oder negativer Wert in eine riesige Zahl (Zweierkomplement). Lies sie also als int32, dann stimmen Vorzeichen und Betrag.
- name: "Netzeinspeisung Gesamt"
unique_id: huawei_grid_exported_energy
slave: 1
address: 37119
input_type: holding
data_type: int32
scale: 0.01
precision: 2
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
scan_interval: 60
- name: "Netzbezug Gesamt"
unique_id: huawei_grid_imported_energy
slave: 1
address: 37121
input_type: holding
data_type: int32
scale: 0.01
precision: 2
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
scan_interval: 60Netzeinspeisung und Netzbezug sind die letzten beiden Quellen, die das Energy-Dashboard für die vollständige Bilanz braucht: Einspeisung unter „Rückspeisung ins Netz“, Bezug unter „Netzbezug“. Sobald PV-Ertrag, Batterie und Netz eingetragen sind, hast du das komplette Sankey-Diagramm ohne eine einzige Custom-Zeile.
scale, precision und data_type — die drei Stolperfallen
Drei Felder entscheiden, ob die Werte stimmen. scale: Huawei liefert Energie in Zehntel- oder Hundertstel-Einheiten — 0.01 macht aus dem Rohregister kWh. Liegt dein Wert um Faktor 10 oder 100 daneben, ist es fast immer der scale. data_type: Energie-Zähler sind 32 Bit (uint32/int32); ein versehentliches uint16 schneidet bei ~655 kWh ab und springt auf null zurück. precision: nur kosmetisch (Nachkommastellen), aber zwei Stellen halten die Historie sauber. Wenn etwas nach dem Neustart „unavailable“ bleibt, prüf zuerst slave (Geräte-ID, meist 1) und input_type (holding).
Aktivieren und prüfen
Die Sensor-Blöcke kommen unter den modbus:-Hub in deine configuration.yaml (oder eine per !include eingebundene Datei). Nach „YAML-Konfiguration neu laden“ → „Modbus“ (oder einem Neustart) erscheinen die Entities. Geh in die Entwicklerwerkzeuge → Zustände und filtere auf sensor.pv_gesamt_ertrag und die Batterie-/Netz-Sensoren: stehen dort plausible kWh-Werte, hast du eine vollständige, upgrade-feste Datenquelle — ganz ohne Custom-Integration. Wer auf diesen rohen Registern abgeleitete Kennzahlen wie den Autarkiegrad aufbauen will, findet das im Autarkie-Sensoren-Post.
Häufige Fragen
Warum 127.0.0.1:5502 statt der echten SDongle-IP?
Weil der SUN2000-SDongle nur eine gleichzeitige Modbus-Verbindung erlaubt. Sobald HA und ein zweiter Client (evcc, AC·THOR, Skript) direkt zugreifen, würgen sie sich gegenseitig ab. 127.0.0.1:5502 ist ein lokaler Caching-Proxy, der den SDongle einmal pollt und beliebig viele Clients bedient. Mit nur einem Client kannst du host/port auch direkt auf die SDongle-IP setzen.
Warum uint32 / int32 und nicht einfach uint16?
Energie-Zähler in kWh überschreiten schnell den 16-Bit-Bereich (max ~655 mit scale 0.01) und liegen deshalb in zwei aufeinanderfolgenden Registern. data_type uint32 (oder int32 bei vorzeichenbehafteten Netzwerten) liest beide zusammen. Mit uint16 schneidest du den oberen Teil ab und der Zähler springt scheinbar zurück.
Bricht das bei einem Home-Assistant-Upgrade?
Nein — genau das ist der Punkt. Die modbus-Plattform ist Teil des HA-Core und wird mit ihm gepflegt. Es gibt keine Drittanbieter-Integration, die inkompatibel werden könnte. Im schlimmsten Fall ändert sich mal die Schreibweise eines Konfig-Schlüssels, was die Release-Notes ankündigen — deine Datenquelle „verwaist“ aber nie.
Gelten die Registeradressen für jeden SUN2000?
Die hier genannten Adressen (32106 Ertrag, 37780/37782 Batterie, 37119/37121 Netz) gelten für die gängigen SUN2000-Residential-Wechselrichter mit LUNA-Speicher. Bei abweichender Firmware oder anderen Modellen prüfe das offizielle Huawei-Modbus-Interface-Dokument — Layout und scale können je nach Generation minimal abweichen, die YAML-Struktur bleibt dieselbe.



