Growatt SPH 4000-10000 TL3 BH UP MQTT über ESP

Begonnen von Teamdrachen, 18 März 2023, 18:24:08

Vorheriges Thema - Nächstes Thema

Teamdrachen

Den Ansatz dazu habe ich im Growatt Wechselrichter / ShineWiFi einbinden Thread #88 gefunden.
Link: https://forum.fhem.de/index.php/topic,98637.msg1260611.html#msg1260611

Um den Thread nicht zu kapern, könnte es ja hier weitergehen.

GROWATT SPH 10000 TL3 BH UP hab ich heute installiert und das von Tobias beschriebene Interface in Betrieb genommen.
https://github.com/tobiasfaust/SolaxModbusGateway

Daten bekomme ich rein, aber es ist ein reines Datenkauderwelsch.
Dabei ist es ganz egal welchen WR ich wähle.

Laut Growatt wäre folgendes für die SPH Reihe interessant
03 register range: 0-124, 1000-1124
04 register range: 0-124, 1000-1124

Zusätzlich laut PV Forum noch Register 608 für den STOP SOC.

Jetzt ist mein Modubus Wissen leider sehr gering.
Ich hab versucht über die RAW Data Funktion mal ein bestimmtes Register abzufragen, die Werte passen dann allerdings nicht zu den Erwartungen.

Wie unterscheide ich bei der Abfrage zwischen Register 4.1 Holding Reg und 4.2 Input Reg?






Aurel_B

Mit dem Gateway selbst kenne ich mich nicht aus, mit Modbus allerdings ein wenig :-) Ich würde zuerst einmal QModMaster https://sourceforge.net/projects/qmodmaster/ verwenden. Ist eine GUI um Modbus Anfragen tätigen zu können. Der Vorteil ist, du kannst sehr rasch Register, Datentypen etc. ändern und bekommst so in der Regel rasch ein Verständnis dafür, wie das Gateway funktioniert.

Wenn ich das richtig verstehe, so sollte z.B. die Abfrage vom Holding Register 5 die aktuelle Leistung in Watt ausgeben. In QModMaster würde das gemäss Screenshot eingestellt werden. ACHTUNG: FHEM zählt die Register ab 0, in der Anleitung (https://github.com/tobiasfaust/SolaxModbusGateway/blob/master/docs/growatt-inverter-modbus-rtu-protocolii-v120-english.pdf) die ich gefunden habe beginnt die Zählweise anscheinend auch bei 0. QModMaster beginnt allerdings bei 1, dort musst du also Register #6 einstellen. Probier das doch mal aus und berichte, ob es funktioniert.


Tobias

wie ich schon sagte,
stell mal bitte von RAW-Data ein Screenshot und als Codetext hier rein.
Dann kann man es relativ schnell sehen.
Im Wiki ist auch genau beschrieben wie man eigene Register findet. Das geht über die raw-data Seite sehr einfach. Die gefunden Registergruppen muss man dann einfach nur in der register.h einstellen, über gitpod neu kompilieren und fertig

Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

O.K. ich hab mich mal am Beispiel Grid Frequenz aus Github versucht.

Modbus Version sollte 1.20 sein.
Grid frequency = 37
Example
Growatt Inverter, you are looking for the item "GridFrequency" in live-data, GridFrequency is at position 37 in Growatt modbus documentation, datatype is uint16

uint16 means 2 Bytes
(position) 37 x 2 (byte) = (position) 74
(position) 74 + 3 (byte header)) = (position) 77
look in Rawdata at position 77 and 78

ich bekomme aber nur "undefined"
Ab Pos 54 kommen keine Werte mehr.


Tobias

Dein RAW datastring sieht komisch aus. Der ist nicht korrekt. Welche Modbus ClientID hat dein Growatt eingestellt? Passt die Baudrate überein?

Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Client ID ist 01 und Baudrate bei Growatt ist Standard 9600.
Ich hab so langsam den SP3485 in Verdacht.
Es dauert manchmal bis überhaupt Daten kommen und manchmal blockiert er den ESP komplett.
Hab mal paar HW-0519 geordert, die sollten morgen da sein und dann teste ich weiter.

Tobias

Wenn die clientid 01 ist muss als erstes Byte in der Antwort ein 0x01 zurückkommen, danach ein 0x04 da die Anfrage für LiveDaten das InputRegister 04 ist

Blinkt der SP3484 immer ordentlich wenn eine Anfrage geschickt bzw. eine Antwort erhalten wird? Der Direction Pin ist auch korrekt konfiguriert?

Im Zweifelsfall bitte mal mit dem example Programm testen
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Direction Pin ist richtig definiert, ich hatte D5 genutzt.
Die Blinkintervalle waren nicht so richtig sauber erkennbar.
Wie erwähnt hatte ich gerade das Phänomen: Der ESP war "blockiert" und über Wifi nicht erreichbar, nach dem trennen des SP3484 war das Problem weg.
ESP ist nicht schuld, ein zweiter zeigte ein ähnliches verhalten.

War schon vorher "seltsam" es sollten ja alle paar Sekunden Werte aus dem WR kommen und ich musste manchmal 10 Minuten warten eh nach dem anstecken was passierte.

Möglicherweise ärgere ich mich wirklich gerade mit einem faulen Stück Hardware rum, daher wird der Wandler morgen getauscht.
Dann kann ich das zumindest ausschließen.

Teamdrachen

Zurück aus dem Keller.....
Mit dem neuen Adapter kommen endlich plausible Daten rein  :)

Jetzt geht es ans Wertesammeln.
4.2 Input Reg .... damit dürften die Live Daten gemeint sein.

Pos 46  VAC3  3Phase Grid Voltage  0.1V

46x2 (byte) = 92
92 + 3 (byte header) = 95

Da wir beide brauchen 95,96
Raw Data spuckt 4016 aus..... x0.1 = 401,6V

Klingt plausibel.

Pos 47  VAC3  3Phase Output curr.  0.1VA
47x2+3 =97

97,98 = 0X00, 0X06 = 6 .... kann ich wohl nur bei Sonne testen.

Zumindest läuft das System schon mal.



Tobias

Super!
Kompiliert mal bitte neu aus dem git. Hab heute 2 Änderungen eingecheckt. Incl Anpassungen an den Growatt Items
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

#10
Super, noch mehr Daten.

Was mir auffällt:  Wenn der Inverter im Standby ist und man den ESP rebootet.... darf man in Keller laufen und den Cat Stecker kurz ziehen.
Sonst kommt der ESP nicht richtig in Gang. Ist zu 85% einfach nicht erreichbar, zu 15% bauen die Seiten zumindest teilweise auf, eh er dann wieder nicht erreichbar ist.


Frage: Wie sieht es mit den Registern >250 aus?
Ab Position 485 ist ja wieder alles "undefined"
input Register 1021:1022 -> AC power to user total, da erhoffe ich mir die durchgeschliffenen Daten vom EMeter zu finden.

Tobias

Zitat von: Teamdrachen am 20 März 2023, 20:11:37Super, noch mehr Daten.

Was mir auffällt:  Wenn der Inverter im Standby ist und man den ESP rebootet.... darf man in Keller laufen und den Cat Stecker kurz ziehen.
Sonst kommt der ESP nicht richtig in Gang. Ist zu 85% einfach nicht erreichbar, zu 15% bauen die Seiten zumindest teilweise auf, eh er dann wieder nicht erreichbar ist.
hab ich gestern abend gecheckt und kein Problem festgestellt. Alles super.
Im Zweifelsfall bitte mal über die Arduino IDO oder PlatformIO an den Rechner hängen und den Seriellen Monitor beobachten wo er hängt.

ZitatFrage: Wie sieht es mit den Registern >250 aus?
Ab Position 485 ist ja wieder alles "undefined"
input Register 1021:1022 -> AC power to user total, da erhoffe ich mir die durchgeschliffenen Daten vom EMeter zu finden.
Kannst du alles selbst einstellen WAS er abfragt. registers.h -> config -> RequestLiveData

In der aktuellen Growatt Registereinstellung sieht es so aus:
["#ClientID", "0x04", "0x00", "0x00", "0x00", "0x77"],
["#ClientID", "0x04", "0x03", "0xE8", "0x00", "0x77"]

Der erste fragt die ersten 119 Register ab, der zweite die Register 1000 - 1119

Wenn du also zusätzlich noch die Register 3000 - 3119 abfregen willst musst du dieses hinzufügen:
["#ClientID", "0x04", "0x0B", "0xB8", "0x0C", "0x2F"]
In der RawData sind alle Ergebnisse hintereinander dargestellt, du musst die Positionen also korrekt ausrechnen.

Bedenke aber bitte, jeder zusätzliche Eintrag dort (aktuell sind es ja 2) bedeutet eine Verarbeitungszeit von 1sek. Das ist vom Inverter festgelegt. Dementsprechend kannst du das permanente Abfrageintervall nicht zu weit herunterdrücken.

Also 3 Anfragen an den Inverter bedeutet ein Daten Updateintervall > 3sek
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Registerabfragen muss ich später noch mal genauer schauen.
Momentan ist da noch ein Knoten warum 3001-3119 und wieso ich da mit
["#ClientID", "0x04", "0x0B", "0xB8", "0x0C", "0x2F"]drauf Abfrage.

Generelles Problem ist momentan die Stabilität des ESP
Der schmiert immer wieder ab.
Trenne ich die 485 Verbindung startet er sauber, irgendwann ist er dann aber wieder weg.

Tobias

War nur ein Beispiel, je nachdem was du abfragen willst. I.d.R. Passt die aktuelle Anfrage so ;)
Ich übernehme gerne neue Items die du anhand der Modbus Protokoll Doku herausgefunden hast, allerdings erstmal keinen 3. Request da viele ein sehr kleines Invervall wollen.
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Mit der aktuellen Anfrage komme ich aber nicht über Position 485 hinaus, bzw bekomme nur noch "undefined"

Aber da geh ich die Tage noch mal mit nem USB Stick ran um die Register zu ermitteln.
Das Reset Problem ist erst mal das größere.

Nach ziemlich genau einer Stunde geht der ESP in eine Reset Schleife.
Meldet sich im 3-5 Sekunden Takt beim Router an/ab
Wenn man mal Glück hat ist er lange genug da um rudimentär das Webinterface zu zeigen und da steht dann UPTIME: 0:0:0
Ist also kein reiner Wifi Verlust, sondern er ist in einer Bootschleife gefangen.


Abhilfe schafft nur das RS485 Kabel zu entfernen, dann bootet er durch und eine Stunde später fängt es wieder an.
Manueller Reboot innerhalb der Stunde führt auch zur Schleife.



Tobias

Das ist alles nur noch Glaskugel lesen.
Stell Debuglevel auf 3 und monitore den Seriellen Monitor. Ggf auf Debuglevel 4 oder 5 erhöhen. Nur damit kann dir geholfen werden.

Bei meinen Testanordnungen hänge ich in einer Bootschleife nur bei "Brownout detection", sprich, Stromversorgung (oder Kabel) zu schwach
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Brownout wäre zu einfach

WebServer started...

abort() was called at PC 0x4015b45f on core 1


Backtrace: 0x40083665:0x3ffb1a20 0x4008b9c9:0x3ffb1a40 0x40091331:0x3ffb1a60 0x4015b45f:0x3ffb1ae0 0

ELF file SHA256: 172f1d46cb9098f1


Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13192
load:0x40080400,len:3028
entry 0x400805e4
Start of Solar Inverter MQTT Gateway
Starting BaseConfig
reading config file
opened config file
{
  "mqttroot": "Growatt",
  "mqttserver": "test.mosquitto.org",
  "mqttport": "1883",
  "mqttbasepath": "home",
  "UseRandomClientID": "none",
  "debuglevel": 0,
  "count": 1
}Starting Wifi and MQTT
WiFi Start
WiFi connected with local IP: 192.168.1.168
Starting MQTT (test.mosquitto.org:1883)




Tobias

#17
kann ich leider nicht nachvollziehen.
Ich habe meinen ESP32 einmal komplett formatiert (-> Button Reset -> Werkszustand herstellen) und danach ist er mit der defaultkonfiguration sofort gestartet....
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4
Start of Solar Inverter MQTT Gateway
Starting BaseConfig
Starting Wifi and MQTT
WiFi Start
WiFi connected with local IP: 10.0.2.93
Starting MQTT (test.mosquitto.org:1883)


MQTT aktiviert
Starting WebServer
WebServer started...
Attempting MQTT connection as Solax-52426
connected...
MQTT Subscribed to: home/Solax/set/TargetBatSOC/#
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

So langsam bin ich kurz vorm anzünden.

Wroom32 + Board HW-0519

Daten kommen sauber rein, aber nach 60 Minuten fällt er in den Bootloop, wo er nur wieder raus kommt wenn man das HW-0519 trennt.

Wroom32 + SP3485 (welches ich für defekt hielt)

Nach dem Booten dauert es etwas (ca. 10-30sek) bis Daten kommen.
Serial Monitor spuckt Fehler ohne Ende
Request queue data to inverter: 0x01 0x04 0x03 0xE8 0x00 0x77 0x30 0x5C
Read Data from Queue:
Dataframe invalid
Parse 503 Bytes of data
Failed to parse JSON Register Data: EmptyInput
Error: for Name 'undefined' no position array found
Request queue data to inverter: 0x01 0x04 0x00 0x00 0x00 0x77 0xB0 0x2C

                                  Publish home/Solax/rssi: -67
                                                              Query Live Data into Queue:
0x01 0x04 0x00 0x00 0x00 0x77
0x01 0x04 0x03 0xE8 0x00 0x77
Ajax Json Empfangen: {
  "action": "RefreshLiveData"
}
Ajax Json Antwort:
Request queue data to inverter: 0x01 0x04 0x00 0x00 0x00 0x77 0xB0 0x2C
Read Data from Queue:
0x00 0xFF 0x96 0x01 0x04 0xEE 0x00 0x05 0x00 0x00 0x54 0xC4 0x16 0xE0 0x00 0x25 0x00 0x00 0x50 0x11
Dataframe invalid
Request queue data to inverter: 0x01 0x04 0x03 0xE8 0x00 0x77 0x30 0x5C
Read Data from Queue:
0xFF 0x00 0x7F 0xC0 0x30 0x1F 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x00 0x00
Dataframe invalid

Im Webinterface kommen dennoch Daten rein, die alle 20-30 Sekunden wechseln.

Anhang 1
Erzeugungsleistung PV1
Grid frequency
stimmen
Entladene Energy Speicher entspricht der Einspeisung

Anhang2
Erzeugungsleistung PV1

Alles kommt aus dem selben Stream, zwischen 1 & 2 wurde nicht restartet und der serial Monitor zeigt immer den selben Code


Tobias

Also auf jeden Fall ist die empfangende Antwort falsch. Wenn dein Inverter die Modbus Adresse 0x01, also 1 hat, muss die Antwort auch immer mit 0x01 beginnen. In deinem Fall muss die Antwort also IMMER mit "0x01 0x04" beginnnen. Wenn nicht, ist was schief bei dir.

Am besten du testest erstmal nur mit dem example_esp32 testsketch
https://github.com/tobiasfaust/SolaxModbusGateway/tree/master/examples/test_RS485_Solax_ESP32

Anpassungen dann im Sketch machen, wie zb. den Anfragestring auf dein obiges Beispiel "0x01 0x04 0x00 0x00 0x00 0x77" setzen.

Wichtig, du hast den ModbusAdapter an einem Hardwareserialport?
Solch nicht erklärbaren Fehler hatte ich nur wenn ich Softwareserial benutzt hatte
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Mein Problem: Ich versteh Deinen Code nicht wirklich.  :'(
Ich kann das nachvollziehen, Du hast den Code im Kopf da ist vieles selbsterklärend, aber von außen muss man sich erst mal reinfitzen.
Deswegen auch die Frage wie unterscheide ich z.b. zwischen Register 4.1 und 4.2 ?
Vermutlich meint Growatt damit Register 3 und 4, aber auch dann kann ich bis auf die 119 mit
["#ClientID", "0x04", "0x00", "0x00", "0x00", "0x77"],
["#ClientID", "0x04", "0x03", "0xE8", "0x00", "0x77"]
nicht viel anfangen.

Ich bin kein Programmierer, aber ich verstehe zumindest gewisse Logiken und wenn ich mit dem selben Code, dem selben ESP aber 2 unterschiedlichen 485 Modulen unterschiedliche Ergebnisse bekomme, dann passt irgendwas in der Ansteuerung nicht.
Ein 485 Modul interpretiert die Daten richtig, schmiert aber nach einer Stunde ab.
Ein 485 Modul läuft stabil, produziert aber Datenkauderwelsch.

Da passt irgendwas im Code nicht, was den Datenaustausch mit Growatt SPH angeht, aber ich kann an der Stelle nicht weiterhelfen... siehe 1. Satz.
Und Dir fehlt der Growatt SPH was es auch nicht gerade einfacher macht.

Wie gesagt, ich verstehe zumindest gewisse Logiken und hatte gestern Abend noch ESPHOME gefunden.
Damit konnte ich mir in einer Stunde einen Code zusammenklöppeln der den Growatt schon mal ausliest und in einem Webinterface darstellt.

Im Gegensatz zum Solax-ESP ist auf dem 485 Board auch richtig was los, bei jeder Abfrage blinken beide LED abwechselnd schnell, während mit dem Solax Code nur ein eher müdes vereinzeltes kurzes aufleuchten zu verzeichnen ist.
Ich nutze die selbe Hardware, die selbe Verkabelung, die selben Pins.

MQTT fehlt noch, aber das sollte schaffbar sein jedem Wert noch ein Topic zu spendieren.

Zumindest kann ich so aber die interessanten Register wie Eigenverbrauch, Netzbezug, momentane Einspeiseleistung und noch einiges mehr beisteuern.


Tobias

Wie die Register zu interpretieren sind und wie man die Input und Holding Register anspricht und ausließt steht alles sehr detailliert in der Modbus Doku drin.

Wenn du das beispielprogramm welches ich dir empfohlen hatte zum Testen von oben nicht benutzt, kann ich dir auch nicht weiterhelfen. Das ist minimalistisch mit dem man die grundsätzliche Kommunikation testen kann.

Bei anderen hat's mit Growatt ja auch funktioniert.
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Growatt, oder Growatt SPH UP ?

Es ging doch auch nicht allein um die Holdings, das System war instabil und reagierte unterschiedlich auf verschiedene 485 Module.
Wie auch immer, der Gedankenanstoß "es ist möglich" reichte.

Mein ESP sendet jetzt brav alle benötigten Daten über MQTT und FHEM kann wieder Verbraucher steuern und den EV der WP berechnen.

Tobias

Super,
Kannst du uns allen dann noch verraten woran es gelegen hat? Für die Nachfolger mit ähnlichen Problemen... und ich kann meine FAQ's füllen ;)
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

Teamdrachen

Zitat von: Tobias am 25 März 2023, 09:48:20Super,
Kannst du uns allen dann noch verraten woran es gelegen hat? Für die Nachfolger mit ähnlichen Problemen... und ich kann meine FAQ's füllen ;)

Leider nicht, ich habe das ganze über ESPHome realisiert.
yaml versteh ich irgendwie einfacher als c und ESPHome hat eine Modbus und sogar eine Growatt api, damit zieht es sich die benötigten Daten selbst, baut den Arduio Code, kompiliert und flasht.

Hatte es auch mit dem Growatt Template gestestet, allerdings müsste man da für jede Änderung die generierte growatt_solar.cpp und growatt_solar.h anpassen und über IDE/Visual Studio kompilieren.
Mit der Modbus api kann man das ganze in der yaml anpassen. Da wird nur der Registertyp 0x04 festgelegt.
Client ID, Register-ID, valuetype, Intervall etc. in der yaml bestimmen und den Rest macht ESPHome.

Das unterscheidet sich von Deiner Herangehensweise, da Du die kompletten Register abfragst und dann den Output zuordnest, während so nur bestimmte Register abgefragt werden.




Tobias

#25
Noch ein Nachtrag,
Ja ich frage alle Register auf einmal ab anstatt jedes einzeln. Das hat auch seinen Grund da jede Abfrage immer 1sek benötigt. Das ist vom Inverter so festgelegt.
Damit könnte man also jede Sekunde frische Werte ins MQTT pushen. Frage ich alle Register einzeln ab so könnte ich bei 20 werten nur maximal alle 20sek frische Werte pushen ;)

Bei mir ist die Konfiguration über ein JSON file , also auch nicht schwer ;)

Aber Hauptsache es funktioniert nun irgendwie ;)
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter