Shelly-Energiezähler per Modbus TCP in Home Assistant – und warum die Saldierung fehlte
Wer einen Shelly-Zähler in Home Assistant einbindet, nimmt meist die offizielle Shelly-Integration, und das ist auch in Ordnung. Anders sieht es aus, wenn dasselbe Messgerät schon von einem Wechselrichter, einer SPS oder einer Loxone-Anlage per Modbus gelesen wird und Home Assistant dieselben Zahlen aus derselben Quelle sehen soll. Dafür gibt es shelly-modbus-home-assistant: eine HACS-Integration, die den Modbus-TCP-Server der Shelly-Firmware direkt abfragt – ohne Cloud-Konto, ohne MQTT-Broker und ohne RPC-Polling.
Was unterstützt wird
Gelesen werden Shelly-Geräte der Generationen 2 bis 4, deren Firmware einen Modbus-Server mitbringt. Bei den Energiezählern sind das die Pro-3EM-Varianten, das Pro EM 50, das 3EM-63 Gen3, das EM Gen3 sowie EM Mini und EM 63 Gen4. Dazu kommen Relais wie Shelly 1, 1L, 1PM und 2PM Gen4 samt Mini-Varianten; die Ausgänge lassen sich über Modbus-Coils schalten.
Nachgemessen habe ich zwei Geräte: einen Shelly Pro 3EM und ein 3EM-63 Gen3, beide mit Firmware 2.0.0. Für beide wurde jeder dekodierte Wert mit dem verglichen, was dasselbe Gerät über seine eigene RPC-Schnittstelle meldet. Alle anderen Modelle folgen Shellys veröffentlichten Registerkarten und sind nicht an echter Hardware bestätigt.
Das Modell wird beim Einrichten aus den Registern des Geräts erkannt und lässt sich überschreiben. Dasselbe gilt für das Messprofil: Dreiphasenzähler laufen als ein Dreiphasenzähler (triphase) oder als drei einzelne Einphasenzähler (monophase). Welches Profil aktiv ist, prüft die Integration durch Abfragen der Komponenten. Geräte im Netz werden per Zeroconf gefunden.
Drei Details, die Shellys Doku offenlässt
Drei Dinge in Shellys Modbus-Umsetzung sind in der Dokumentation nicht ausbuchstabiert. Alle drei sind an echter Hardware bestätigt:
- Die dokumentierten Adressen sind nicht die Adressen auf dem Draht. Shelly nennt sie in der klassischen Schreibweise
3xxxx; gesendet wird die Zahl minus 30000. Aus dem dokumentierten Register 31020 (Spannung Phase A) wird also Input-Register 1020. Gelesen wird durchgehend mit Funktionscode 0x04, Holding-Register gibt es nicht. - 32-Bit-Werte (
float32,uint32) liegen mit dem niederwertigen Wort zuerst in den Registern (CDAB). Im üblichen Big-Endian gelesen, ergibt das Registerpaar für 240,4 V den Wert 1,65e16. - Zeichenketten sind innerhalb jedes Registers byteweise vertauscht. Aus der MAC
A0DD6CA0E0CCwird sonst0ADDC60A0ECC.
Die Registerbeschreibungen liegen als YAML-Dateien im Repository. Ein weiteres Gerät aufzunehmen ist dadurch eine Datenänderung, keine Codeänderung.

Blockweise lesen
Die Register werden zu zusammenhängenden Blöcken gebündelt und mit je einer Anfrage gelesen. Ein Pro 3EM mit den Standardentitäten braucht pro Zyklus drei Modbus-Anfragen statt 69. Blöcke überschreiten keine Komponentengrenzen und nie 80 Register, das Limit der Firmware pro Anfrage. Deaktivierte Entitäten werden gar nicht erst gelesen; wer Entitäten abschaltet, senkt also tatsächlich den Modbus-Verkehr.
Die Abfrageintervalle sind in zwei Kategorien geteilt: schnelle Werte (Leistung, Spannung, Strom, Leistungsfaktor, Relaiszustand) und langsame Werte (Energiezähler, Frequenz, Fehler- und Diagnosemeldungen). Die Geräteidentität wird einmal beim Start gelesen.
Saldierte Netzwerte ab 1.1.0
Shelly zählt Energie pro Phase und addiert die Zähler nur auf. Ein saldierender Zweirichtungszähler, wie er in Deutschland üblich ist, rechnet dagegen über alle Phasen zusammen. Der Unterschied zeigt sich bei Photovoltaik: Speist die Anlage auf Phase A mit 600 W ein, während Phase B 50 W und Phase C 550 W beziehen, ist die Summe 0 W. Ein saldierender Zähler registriert nichts. Shellys Zähler verbuchen 600 Wh Einspeisung und gleichzeitig 600 Wh Bezug. Geprüft am Pro 3EM: total_act_power (Register 31013) ist korrekt saldiert, total_act_energy (31162) ist nur die Summe der Phasenzähler.
Dreiphasige Zähler bekommen deshalb vier zusätzliche Sensoren, die standardmäßig aktiv sind: Netzbezug und Netzeinspeisung jeweils als Leistung (W) und als Energie (kWh), jeweils mit dem Zusatz „(saldiert)“. Die Leistungswerte entstehen aus der bereits saldierten vorzeichenbehafteten Gesamtleistung. Die Energiezähler integrieren sie nach der Trapezregel, wie es auch der Riemann-Summen-Helfer von Home Assistant tut. Es muss also kein Helfer angelegt werden; die beiden kWh-Sensoren lassen sich direkt im Energie-Dashboard unter „Netzbezug“ und „Netzeinspeisung“ eintragen.
Die Zähler überstehen Neustarts. Eine fehlgeschlagene Messung oder eine Lücke von mehr als 15 Minuten unterbricht die Kette, statt über die Lücke zu integrieren – ein Ausfall kann so keine Energie erfinden. Die saldierten Zähler beginnen bei null; vergangene saldierte Werte lassen sich aus den Gerätezählern nicht rekonstruieren. Die rohen Phasenzähler laufen unverändert daneben weiter. Bei Geräten, die mehrere unabhängige Stromkreise messen, etwa dem Pro EM 50, gibt es die Sensoren nicht, weil eine Summe dort sinnlos wäre.
Schnelleres Standardintervall
Mit 1.1.0 sank das Standardintervall für schnelle Werte von 10 auf 5 Sekunden. Ein schneller Zyklus am Pro 3EM dauert 70 bis 100 ms; das Gerät ist damit zu etwa 2 % ausgelastet, bei 3 s zu etwa 3 %, bei 1 s zu etwa 10 %. Wer einen Einspeisebegrenzer oder einen Speicher aus diesen Werten steuert, kann also auf 1–2 s gehen. Bestehende Installationen behalten ihr gespeichertes Intervall und müssen unter „Konfigurieren“ von Hand umgestellt werden.
Nachbesserungen in 1.1.1 und 1.1.2
Beim Einrichten auf einer echten Home-Assistant-Instanz zeigte sich in 1.1.1 ein Fehler, den Tests ohne Hardware nicht erreichten: Meldete Zeroconf ein Gerät mit IPv6-Adresse, bekam die configuration_url die Adresse ohne eckige Klammern. Home Assistant las die Doppelpunkte als Portangabe und lehnte die URL ab; die Geräteregistrierung schlug fehl, und mit ihr alle Entitäten, obwohl die Integration als geladen galt. IPv6-Adressen werden jetzt eingeklammert, und Zeroconf bevorzugt IPv4, wenn die Ankündigung eine enthält. Außerdem wird die YAML-Registerdatei nicht mehr blockierend im Event-Loop gelesen, und der Options-Listener lädt den Config-Eintrag neu, wie es Home Assistant ab 2026.12 verlangt.
Die Version 1.1.2 begrenzt, wie lange die Integration auf ein hängendes Gerät wartet. Ein Gerät, das die TCP-Verbindung annimmt, aber nie antwortet, kostete bisher retries × (Verbindung + Lesen) pro Anfrage. Jetzt teilen sich alle Versuche einer Anfrage ein Zeitbudget vom Dreifachen des Client-Timeouts, bei der Voreinstellung 15 s. Ein Zyklus endet, sobald ein Block fehlschlägt und die Verbindung weg ist. Wenn die Einrichtung scheitert, gibt sie außerdem den geöffneten Socket wieder frei; vorher blieb pro Wiederholung einer liegen.
Installation
- In HACS unter „Benutzerdefinierte Repositories“ die Adresse
https://github.com/sphings79/shelly-modbus-home-assistantmit der Kategorie „Integration“ hinzufügen. - Nach „Shelly Modbus“ suchen, installieren und Home Assistant neu starten.
- Am Shelly unter Einstellungen → Modbus den Server aktivieren (ab Werk ist er aus), danach in Home Assistant die Integration hinzufügen.
Voraussetzung ist Home Assistant 2025.9 oder neuer. Nicht unterstützt sind Shelly-Geräte ohne Modbus-Server wie Plus 1PM, Plus Plug S oder Pro 4PM sowie alle Gen1-Geräte; dafür bleibt die offizielle Integration. Die Integration steht unter MIT-Lizenz, Oberfläche und Dokumentation gibt es auf Deutsch und Englisch.
Zum Projekt
-
Shelly Modbus für Home Assistant
HACS-Integration, die Shelly-Energiezähler und -Relais der Generationen 2 bis 4 über deren eingebauten Modbus-TCP-Server ausliest – lokal, ohne Cloud, mit saldierten Netzwerten.
Unterstützen
Diese Tools entstehen in meiner Freizeit und bleiben kostenlos, offen und cloud-frei. Wenn dir eins davon einen Nachmittag gespart hat, freue ich mich über einen Kaffee oder ein Stück Pizza.
Kaffee oder PizzaWeitere Beiträge
- Rollladen-Steuerung pro Raum: Taster, Fenster, Kälte und Regen Eine Automation pro Raum, die Taster, Fensterkontakt, Kälte, Regen und die Zeit vor Sonnenaufgang zusammenführt. Zwei Merker-Helfer verhindern, dass sich die Auslöser gegenseitig überfahren.
- Stromausfall erkennen und Geräte wiederherstellen in Home Assistant Nach einem Stromausfall booten Lampen und Steckdosen in zufälligen Zuständen. Drei Erkennungswege, ein gemeinsames Script und ein Wiederherstellungsfenster bringen alles wieder in den gewünschten Zustand.
- Rauchmelder löst aus: Alle Rollläden fahren hoch (Home Assistant) Bei Rauchalarm sollen die Rollläden im ganzen Haus hochfahren, damit Fenster als Fluchtweg frei sind. Die Automation ist kurz – aber ein fehlendes „from“ im Trigger entscheidet darüber, ob sie im Ernstfall überhaupt feuert.