GoodWe GW5048D-ES mit evcc: RS485, AA55-Protokoll und PV-Überschussladen ohne zusätzlichen Smart Meter
GoodWe GW5048D-ES über RS485 mit evcc verbinden: AA55-Protokoll auslesen, Grid Power, PV, Batterie und SOC per MQTT übertragen und für PV-Überschussladen nutzen.
GoodWe GW5048D-ES mit evcc: RS485, AA55-Protokoll und PV-Überschussladen ohne zusätzlichen Smart Meter
Ein GoodWe GW5048D-ES lässt sich nicht immer so einfach mit evcc verbinden, wie es zunächst aussieht. Das Problem: Das verbreitete goodwe-hybrid-Template arbeitet mit Modbus-Registern, die zu anderen GoodWe-Plattformen passen. Beim GW5048D-ES führen diese Abfragen teilweise zu Modbus exception 2 (illegal data address).
In diesem Beitrag zeige ich, wie ich den GoodWe GW5048D-ES über RS485 direkt ausgelesen, das AA55-Laufdatenprotokoll identifiziert, wichtige Messwerte verifiziert und diese anschließend über MQTT als Custom Meter an evcc übergeben habe.
Das Ergebnis ist eine funktionierende Datenkette:
GoodWe GW5048D-ES
│
│ RS485
▼
GoodWe ES AA55 Bridge
│
│ MQTT
▼
evcc
│
▼
PV-Überschussladen
Hinweis: Dieser Beitrag dokumentiert einen reproduzierten Test mit einem GoodWe GW5048D-ES. Andere Modelle und Firmware-Versionen können sich unterscheiden. Die hier beschriebene Lösung sollte deshalb als Community-Lösung und nicht als offizielle GoodWe- oder evcc-Dokumentation verstanden werden.
1. Ausgangssituation
Ziel war es, einen GoodWe GW5048D-ES Hybridwechselrichter mit evcc zu verbinden und die Informationen zu verwenden, die für späteres PV-Überschussladen einer Wallbox erforderlich sind.
Der zusätzliche Kauf bzw. Einbau eines separaten Smart Meters sollte möglichst vermieden werden.
Das Setup für den ersten Test:
- GoodWe GW5048D-ES
- USB-RS485-Adapter
- Windows
- COM3
- 9600 Baud
- 8N1
- evcc 0.315.0
- MQTT-Broker im lokalen Netzwerk
Der erste Ansatz war das in evcc vorhandene GoodWe-Hybrid-Template.
2. Das Problem mit goodwe-hybrid
Die Verbindung über RS485 funktionierte grundsätzlich.
Der GoodWe antwortete auf Modbus-Abfragen. Allerdings schlugen bestimmte Register mit:
modbus: exception '2' (illegal data address)
fehl.
Beispielsweise lieferte die Abfrage:
f7 03 b9 95 00 01 a5 ec
eine Modbus-Ausnahme.
0xB995 entspricht dabei Register 47509.
Auch weitere Bereiche wie 37000, 36000 und 47900 waren beim getesteten ES-Gerät nicht brauchbar.
Das war ein wichtiger Hinweis:
RS485 funktioniert, aber das verwendete Registermodell passt nicht zu diesem GoodWe.
Das ist nachvollziehbar, wenn man sich die unterschiedlichen GoodWe-Plattformen ansieht. Die aktuelle Python-Bibliothek goodwe unterscheidet unter anderem die ES-Familie von anderen Modellplattformen. In der aktuellen Implementierung gehören unter anderem ESU/EMU/ESA/BPS/BPU/EMJ/IJL zur Plattform 105.
3. Erste erfolgreiche Modbus-Register
Bevor das AA55-Protokoll gefunden wurde, konnten einige klassische Modbus-Register erfolgreich gelesen werden.
Unter anderem:
35105–35118
35191–35192
Das bewies endgültig, dass die Kommunikation mit:
Slave ID: 247
Baudrate: 9600
Format: 8N1
funktioniert.
Eine interessante Beobachtung war außerdem ein Wert im Bereich um Register 35172, der sich bei einer Laständerung deutlich veränderte.
Mit einem Heizgerät/Fön mit ungefähr 2 kW Leistung konnte die Last beispielsweise von ungefähr:
~800 W
auf ungefähr:
~2700–3000 W
steigen.
Damit ließ sich zumindest empirisch bestätigen, dass Daten aus dem Gerät die tatsächliche Laständerung abbilden.
Für die endgültige Lösung war dieser Ansatz aber nicht der richtige.
4. Der entscheidende Hinweis: GoodWe AA55
Der Durchbruch kam durch die Analyse der GoodWe-ES-Unterstützung der Open-Source-Python-Bibliothek goodwe.
Die aktuelle goodwe-Implementierung verwendet für die ES/EM/BP-Familie ein anderes Protokoll als die ET-Familie.
Für die Laufdaten wird dort das AA55-Protokoll verwendet:
Request: 010600
Response: 0186
Die entsprechende Implementierung befindet sich in goodwe/es.py. Dort sind auch die Datenfelder des Running-Data-Frames definiert.
Damit ergab sich ein komplett anderer Ansatz:
Nicht mehr versuchen, die falschen GoodWe-Modbus-Register zu erraten, sondern direkt das AA55-Running-Data-Telegramm des ES auslesen.
5. Das funktionierende AA55-Telegramm
Mit dem RS485-Adapter an COM3 konnte folgende Anfrage erfolgreich gesendet werden:
AA 55 C0 7F 01 06 00 02 45
Der Wechselrichter antwortete mit einem 149 Byte langen Telegramm.
Ein Beispiel:
aa 55 7f c0 01 86 8c 00 00 00 00 00 00 00 00 00 00
01 ff 00 02 00 50 00 f0 00 00 00 50 00 64 00 00 0e
00 0e 5f 01 00 00 01 09 37 00 05 01 8f 13 83 01 09 37
00 03 01 6e 13 83 01 02 01 08 00 00 00 00 00 04 04 68
00 00 8e 04 00 9c 00 b9 00 02 e6 ef ff e1 01 00 30 02
00 00 00 01 00 00 fc 89 11 08 00 06 00 00 1a 09 03 16
20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 01 04 6e 00 00 fe 8f 02 00 00 00
00 00 00 13 e8
Länge:
149 Bytes
Damit war die komplette Kommunikationskette zum GoodWe bewiesen.
6. Die Struktur des AA55-Frames
Das Telegramm beginnt mit einem Header:
AA 55 7F C0 01 86 8C
Danach beginnt der eigentliche Datenbereich.
Die Offsets der aktuellen goodwe/es.py-Implementierung beziehen sich auf diesen Datenbereich.
Einige der wichtigsten Felder:
| Offset | Feld | Bedeutung |
|---|---|---|
| 0 | vpv1 | PV1-Spannung |
| 2 | ipv1 | PV1-Strom |
| 5 | vpv2 | PV2-Spannung |
| 7 | ipv2 | PV2-Strom |
| 10 | vbattery1 | Batteriespannung |
| 18 | ibattery1 | Batteriestrom |
| 26 | battery_soc | Batterie-SOC |
| 29 | battery_soh | Batterie-SOH |
| 30 | battery_mode | Batteriemodus |
| 34 | vgrid | Netzspannung |
| 36 | igrid | Netzstrom |
| 38–39 | pgrid | Netzleistung |
| 40 | fgrid | Netzfrequenz |
| 43 | vload | Backup-/Load-Spannung |
| 45 | iload | Backup-/Load-Strom |
| 47 | pload | Backup-/Load-Leistung |
| 49 | fload | Backup-/Load-Frequenz |
| 53 | temperature | Wechselrichtertemperatur |
| 67 | e_day | PV-Energie heute |
| 69 | e_load_day | Load-Energie heute |
| 80 | grid_in_out | Netzrichtung |
Die Felddefinitionen entsprechen der aktuellen Open-Source-Implementierung für die GoodWe-ES-Plattform.
7. Der wichtigste Treffer: Battery SOC
Ein sehr guter Test für die korrekte Dekodierung war der Batterie-SOC.
Im getesteten Telegramm liegt am entsprechenden Offset:
0E
also:
14
Der Wechselrichter meldete gleichzeitig in SolarGo:
Batterie: 14 %
Damit war die SOC-Dekodierung eindeutig bestätigt.
8. Der entscheidende Treffer: Netzleistung
Noch wichtiger war die Netzleistung.
Im AA55-Datenbereich liegt pgrid bei Offset 38–39.
Das Telegramm enthielt:
01 8F
Das entspricht:
399 W
Zusätzlich enthält Offset 80 die Richtung des Netzflusses.
Im Test:
Grid direction code = 2
Die GoodWe-Implementierung interpretiert diesen Zustand als Netzbezug und gibt entsprechend eine negative Leistung aus.
Damit wurde:
Grid power = -399 W
ermittelt.
Gleichzeitig zeigte SolarGo:
Strom importieren ≈ 0,40 kW
Damit konnte die Netzleistung unabhängig verifiziert werden.
Das war der entscheidende Beweis, dass die AA55-Laufdaten nicht nur syntaktisch korrekt gelesen werden, sondern tatsächlich die relevanten realen Messwerte des Wechselrichters enthalten.
9. Eigener Python-Decoder
Für die weitere Entwicklung wurde zunächst ein eigener Decoder geschrieben.
Die Grundidee:
REQUEST = bytes.fromhex(
"AA 55 C0 7F 01 06 00 02 45"
)
Danach wird die Antwort ab Byte 7 als Datenbereich interpretiert.
Beispielhafte Dekodierung:
data = frame[7:]
battery_soc = data[26]
grid_power = int.from_bytes(
data[38:40],
"big",
signed=True
)
grid_direction = data[80]
if grid_direction == 2:
grid_power = -abs(grid_power)
else:
grid_power = abs(grid_power)
Die eigentliche GoodWe-Implementierung berücksichtigt zusätzlich die jeweiligen Skalierungen und Vorzeichen der einzelnen Werte.
10. Ergebnis des Decoders
Ein realer Test lieferte:
=== GOODWE ES ===
PV1 voltage : 0.0
PV1 current : 0.0
PV1 power : 0
PV2 voltage : 0.0
PV2 current : 0.0
PV2 power : 0
Battery voltage : 51.1
Battery current : 0.0
Battery power : 0
Battery SOC : 14
Battery SOH : 95
Battery mode : 1
Grid voltage : 235.9
Grid current : 0.5
Grid power : -399
Grid frequency : 49.95
Grid mode : 1
Backup voltage : 235.9
Backup current : 0.3
Backup power : 366
Backup frequency : 49.95
Inverter temperature : 26.4
Today's PV energy : 15.6
Today's load energy : 18.5
Grid direction code : 2
House consumption : 399
Besonders relevant:
Battery SOC: 14 %
Grid power: -399 W
Grid voltage: 235,9 V
Grid frequency: 49,95 Hz
Battery voltage: 51,1 V
11. Belastungstest mit einem ca. 2-kW-Fön
Um die Netzleistungsmessung nicht nur im Leerlauf zu testen, wurde eine größere elektrische Last zugeschaltet.
Die Bridge meldete zunächst:
Grid -374 W
Load 374 W
Danach:
Grid -1556 W
Load 1556 W
und anschließend:
Grid -2151 W
Load 2151 W
Grid -2166 W
Load 2166 W
Grid -2171 W
Load 2171 W
Die Änderung liegt damit sehr nahe an der erwarteten Leistung des Heizgeräts.
Dieser Test ist wichtig, weil er zeigt:
Die Messung reagiert nicht nur auf einen einzelnen festen Wert, sondern folgt der tatsächlichen elektrischen Last.
12. Von GoodWe zu MQTT
Nachdem die direkte AA55-Kommunikation funktionierte, wurde daraus eine kleine Bridge.
Aufbau:
GoodWe GW5048D-ES
│
│ RS485
▼
goodwe_es_bridge.py
│
│ MQTT
▼
MQTT Broker
Die Bridge läuft zunächst unter Windows mit:
COM3
9600 Baud
8N1
und verbindet sich anschließend mit dem MQTT-Broker.
Beispiel:
MQTT Broker:
192.168.178.21:1883
Die Bridge liest die GoodWe-Daten zyklisch aus und veröffentlicht die Werte per MQTT.
13. Vorzeichenkonvention für evcc
Ein wichtiger Punkt war die Anpassung der Vorzeichen.
Der GoodWe-Decoder liefert Netzbezug in diesem Test zunächst als:
-399 W
evcc verwendet für einen Netzzähler dagegen:
positiv = Netzbezug
negativ = Einspeisung
Diese Konvention ist in der aktuellen evcc-Dokumentation für Zähler explizit beschrieben. Für einen grid-Zähler bedeutet ein positiver power-Wert Netzbezug; beim Batterie-Zähler bedeutet positiv Entladen und negativ Laden.
Deshalb konvertiert die Bridge den GoodWe-Netzwert für evcc.
Aus:
GoodWe:
-211 W
wird:
evcc:
+211 W
Das war später im evcc-Webinterface direkt sichtbar.
14. MQTT-Datenpunkte
Die Bridge stellt unter anderem folgende Daten bereit:
goodwe/grid_power
goodwe/pv_power
goodwe/battery_power
goodwe/battery_soc
goodwe/house_consumption
Zusätzlich können weitere Messwerte veröffentlicht werden, zum Beispiel:
goodwe/grid_voltage
goodwe/grid_current
goodwe/grid_frequency
goodwe/pv1/power
goodwe/pv2/power
goodwe/battery_voltage
goodwe/battery_current
goodwe/load_power
Damit ist die Bridge nicht nur für evcc interessant, sondern grundsätzlich auch für andere Systeme, die MQTT lesen können.
15. Integration in evcc
evcc unterstützt benutzerdefinierte Geräte und Zähler über type: custom. Als Datenquelle kann unter anderem MQTT verwendet werden. Ein Custom-Meter kann beispielsweise seine aktuelle Leistung über ein MQTT-Topic beziehen. Auch ein Batterie-Zähler kann zusätzlich soc aus MQTT lesen.
Die erste Konfiguration war bewusst klein:
mqtt:
broker: 192.168.178.21:1883
topic: evcc
meters:
- name: goodwe_grid
type: custom
power:
source: mqtt
topic: goodwe/grid_power
timeout: 30s
site:
title: Home
meters:
grid: goodwe_grid
Anschließend meldete evcc:
meters: grid ✓
und im Webinterface erschien der tatsächliche Netzbezug.
16. PV und Batterie ergänzen
Nachdem der Grid-Meter funktionierte, wurden PV und Batterie ebenfalls als Custom-Meter eingebunden.
Die Konfiguration:
mqtt:
broker: 192.168.178.21:1883
topic: evcc
meters:
- name: goodwe_grid
type: custom
power:
source: mqtt
topic: goodwe/grid_power
timeout: 30s
- name: goodwe_pv
type: custom
power:
source: mqtt
topic: goodwe/pv_power
timeout: 30s
- name: goodwe_battery
type: custom
power:
source: mqtt
topic: goodwe/battery_power
timeout: 30s
soc:
source: mqtt
topic: goodwe/battery_soc
timeout: 30s
site:
title: Home
meters:
grid: goodwe_grid
pv: goodwe_pv
battery: goodwe_battery
evcc bestätigte daraufhin:
site config:
meters: grid ✓ pv ✓ battery ✓
grid: power ✓
pv 1: power ✓
battery 1: power ✓ soc ✓
Damit waren alle für das grundlegende Energieflussmodell benötigten Messwerte vorhanden.
17. Was evcc aktuell tatsächlich sieht
Der aktuelle Testzustand sieht beispielsweise so aus:
Grid +177 W
PV 0 W
Battery 0 W
Battery SOC 14 %
Load 177 W
Im evcc-Webinterface:
Erzeugung 0 W
Netzbezug 177 W
Verbrauch 177 W
Ladepunkt 0 W
Einspeisung 0 W
Damit funktioniert die komplette Strecke:
GoodWe
↓
RS485
↓
AA55
↓
Python Bridge
↓
MQTT
↓
evcc
↓
Webinterface
18. Welche Werte brauchen wir für PV-Überschussladen?
Für das eigentliche PV-Überschussladen ist der Netzleistungswert der zentrale Messwert.
evcc muss wissen, ob gerade:
Netzbezug
oder
Einspeisung
stattfindet.
Die zusätzlichen Messwerte machen das Energieflussmodell vollständiger:
Grid Power ✅
PV Power ✅
Battery Power ✅
Battery SOC ✅
House Load ✅
Damit kann evcc erkennen, wie die Energie gerade im Haus verteilt wird.
Die aktuellen evcc-Custom-Meter unterstützen power als erforderliches Messattribut sowie optional energy und beim Batteriezähler soc.
19. Was noch nicht getestet wurde
Zum Zeitpunkt dieses Tests war noch keine Wallbox angeschlossen.
Deshalb ist das eigentliche Laden noch nicht praktisch getestet.
Die GoodWe-Seite ist jedoch bereits soweit vorbereitet, dass die später benötigten Energieinformationen über MQTT zur Verfügung stehen.
Der nächste Schritt ist daher die Integration der eigentlichen Wallbox in evcc.
Dabei kommen zusätzlich Wallbox-spezifische Werte und Steuerbefehle ins Spiel, insbesondere:
Ladeleistung
Ladestrom
Status
1-/3-Phasen-Betrieb
Ein/Aus
maximaler Ladestrom
Diese Informationen stammen von der Wallbox selbst und sind unabhängig vom GoodWe-Teil.
20. Ein wichtiger Punkt: Phasenmessung
Der bisherige GoodWe-Test arbeitet mit einer Gesamtleistung.
Für eine spätere Wallbox mit 1-/3-Phasen-Umschaltung können Phasenwerte interessant werden.
Die aktuelle evcc-Dokumentation unterstützt für Netzzähler und Wallboxen auch:
currents
voltages
powers
als dreiphasige Werte.
Für den ersten Überschusslade-Test ist das aber nicht zwingend erforderlich.
21. Warum MQTT statt eines evcc-Forks?
Die Lösung wurde bewusst als eigenständige Bridge aufgebaut.
Damit bleibt die Architektur:
GoodWe-spezifische Kommunikation
↓
Bridge
↓
MQTT
↓
evcc
Der Vorteil:
- evcc muss nicht gepatcht werden
- evcc-Updates bleiben einfach
- die GoodWe-Kommunikation ist unabhängig
- dieselben Daten können später auch von Home Assistant oder anderen Systemen verwendet werden
- die Bridge kann unter Windows und Linux betrieben werden
- Docker ist problemlos möglich
evcc stellt für benutzerdefinierte Geräte und Zähler ausdrücklich MQTT als Plugin-Quelle bereit.
22. Linux und Docker
Die Bridge wurde deshalb nicht als reines Windows-Provisorium aufgebaut.
Unter Windows ist der serielle Port:
COM3
Unter Linux wird der USB-RS485-Adapter typischerweise als Gerät wie:
/dev/ttyUSB0
oder
/dev/ttyACM0
sichtbar.
Die spätere Docker-Architektur kann daher ungefähr so aussehen:
Linux Host
│
├── USB-RS485
│ │
│ ▼
│ /dev/ttyUSB0
│ │
│ ▼
│ ┌────────────────┐
│ │ GoodWe ES │
│ │ Bridge │
│ └───────┬────────┘
│ │
│ │ MQTT
│ ▼
│ ┌────────────────┐
│ │ MQTT Broker │
│ └───────┬────────┘
│ │
│ ▼
│ ┌────────────────┐
│ │ evcc │
│ └────────────────┘
│
└────────────────────
Der Vorteil ist, dass sich am eigentlichen GoodWe-Protokoll nichts ändern muss. Nur der serielle Gerätepfad wird von COM3 auf /dev/ttyUSB0 angepasst.
23. Aktueller Stand
Der bisherige Entwicklungsstand lässt sich so zusammenfassen:
| Funktion | Status |
|---|---|
| RS485 Kommunikation | ✅ |
| GoodWe ID 247 | ✅ |
| 9600 / 8N1 | ✅ |
| AA55 Running Data | ✅ |
| PV-Daten | ✅ |
| Batterie-Spannung | ✅ |
| Batterie-Leistung | ✅ |
| Batterie-SOC | ✅ |
| Batterie-SOH | ✅ |
| Netzspannung | ✅ |
| Netzstrom | ✅ |
| Netzleistung | ✅ |
| Netzrichtung | ✅ |
| Netzfrequenz | ✅ |
| Load/Backup | ✅ |
| Wechselrichtertemperatur | ✅ |
| PV-Energie heute | ✅ |
| Load-Energie heute | ✅ |
| MQTT-Ausgabe | ✅ |
| evcc Grid Meter | ✅ |
| evcc PV Meter | ✅ |
| evcc Batterie Meter | ✅ |
| evcc Battery SOC | ✅ |
| Wallbox | ⏳ |
| echtes PV-Überschussladen | ⏳ |
| Docker unter Linux | ⏳ |
24. Was wir gelernt haben
Die wichtigste Erkenntnis aus dem gesamten Test war:
Beim GoodWe GW5048D-ES sollte man nicht automatisch davon ausgehen, dass die Modbus-Register anderer GoodWe-Hybridmodelle verwendet werden können.
Beim hier getesteten Gerät waren viele der zunächst getesteten Register nicht erreichbar.
Der funktionierende Weg war dagegen:
GoodWe GW5048D-ES
↓
RS485
↓
AA55 Running Data
↓
Python Decoder
↓
MQTT
↓
evcc
Besonders hilfreich war, dass sich die Daten mit SolarGo gegenprüfen ließen.
Der SOC von:
14 %
und ein Netzbezug von ungefähr:
400 W
stimmten mit den aus dem AA55-Telegramm dekodierten Daten überein.
Der Lasttest mit einem ungefähr 2-kW-Verbraucher bestätigte zusätzlich, dass die Messwerte dynamisch auf die reale Last reagieren.
25. Quellen und weiterführende Informationen
Die GoodWe-Python-Bibliothek enthält aktuell eine eigene Implementierung für die ES/EM/BP-Familie und beschreibt die entsprechenden Datenfelder des ES-Running-Data-Protokolls:
- GoodWe Python Library:
goodwe/es.py
https://github.com/marcelblijleven/goodwe/blob/master/goodwe/es.py - GoodWe Python Library – Modellplattformen
https://github.com/marcelblijleven/goodwe/blob/master/goodwe/model.py - evcc – Benutzerdefinierte Geräte / Custom Meter
https://docs.evcc.io/de/user-defined-devices/ - evcc – PV-Überschussladen
https://docs.evcc.io/de/features/solar-charging/
Die GoodWe-Bibliothek ist ein Open-Source-Projekt und unterstützt verschiedene GoodWe-Geräte und Protokollvarianten. Eine entsprechende ES/AA55-Kommunikation wurde auch bereits von anderen Nutzern in der Entwicklung bzw. in Issues thematisiert.