Open HubertusH opened 1 month ago
No, Sungather is designed for Sungrow inverters. Not for wallboxes
Ok, I have found the registers that the inverter has to read the information from the wallbox.
"_address name description unit type len factor offset formula role room poll wp cw isScale"
"21200 Total_Energy Bisher geladene Gesamtleistung wh uint32be 2 1 state true true false false"
"21202 SetOutI Ausgangsstrom | 0,1A | 6A-63A A uint16be 1 1 state true true false false"
"21203 PhaseSwitch PhaseSwitch | 0=3ph 1=1ph uint16be 1 1 state true true false false"
"21210 Charger_Enable Charger Enable | 0=disable 1=enable uint16be 1 1 state true true false false"
"21211 START_STOP_CHARGING Ladung Starten | Stoppen 0=Start 1=Stop uint16be 1 1 state true true false false"
"21212 Total_Energy Total_Energy Wh uint32be 2 1 state true true false false"
"21224 Year Year uint16be 1 1 state true true false false"
"21225 Month Month uint16be 1 1 state true true false false"
"21226 Day Day uint16be 1 1 state true true false false"
"21227 Hour Hour uint16be 1 1 state true true false false"
"21228 Minute Minute uint16be 1 1 state true true false false"
"21229 Second Second uint16be 1 1 state true true false false"
"21230 Dev_Address Bus Adresse | deafult 248 uint16be 1 1 state true true false false"
"21231 Enery_per_Km Energie pro Km uint16be 1 1 state true true false false"
This also works via modbus client if you enter the correct Clint ID (in my case "2").
modbus 192.168.179.9:502 -s 2 21203
Parsed 0 registers definitions from 1 files
21203: 0 0x0
I then created a register.yaml:
version: 0.2.3
vendor: Sungrow
registers:
- read:
- name: "Total_Energy"
level: 2
address: 21200
datatype: "U32"
- name: "SetOutI"
level: 2
address: 21202
datatype: "U32"
- name: "PhaseSwitch"
level: 2
address: 21203
datatype: "U16"
datarange:
- response: 0x00
value: "3ph"
- response: 0x01
value: "1ph"
scan: # these have to be 1 less than the first register
- read:
- start: 21200
range: 4
- start: 21210
range: 3
- start: 21224
range: 12
- hold:
- start: 21200
range: 4
- start: 21210
range: 3
- start: 21224
range: 12
but always get an IndexError at startup:
python3 sungather.py -c /home/pi/SunGather/Wallbox/config.yaml -r /home/pi/SunGather/Wallbox/registers-wallbox.yaml --runonce -v 10
2024-05-28 17:29:17 INFO Starting SunGather 0.5.2
2024-05-28 17:29:17 INFO Need Help? https://github.com/bohdan-s/SunGather
2024-05-28 17:29:17 INFO NEW HomeAssistant Add-on: https://github.com/bohdan-s/hassio-repository
2024-05-28 17:29:18 INFO Loaded config: /home/pi/SunGather/Wallbox/config.yaml
2024-05-28 17:29:19 INFO Loaded registers: /home/pi/SunGather/Wallbox/registers-wallbox.yaml
2024-05-28 17:29:19 INFO Registers file version: 0.2.3
2024-05-28 17:29:19 INFO Logging to console set to: DEBUG
2024-05-28 17:29:19 DEBUG Inverter Config Loaded: {'host': '192.168.179.9', 'port': 502, 'timeout': 10, 'retries': 3, 'slave': 2, 'scan_interval': 30, 'connection': 'modbus', 'model': 'AC011E-01', 'smart_meter': False, 'use_local_time': False, 'log_console': 'WARNING', 'log_file': 'OFF', 'level': 2}
2024-05-28 17:29:19 INFO Loading SungrowClient 0.1.0
2024-05-28 17:29:19 DEBUG Checking Modbus Connection
2024-05-28 17:29:19 INFO Modbus client is not connected, attempting to reconnect
2024-05-28 17:29:19 INFO Connection: ModbusTcpClient(192.168.179.9:502)
2024-05-28 17:29:19 DEBUG Connection to Modbus server established. Socket ('192.168.179.77', 41381)
2024-05-28 17:29:22 INFO Bypassing Model Detection, Using config: AC011E-01
Traceback (most recent call last):
File "/home/pi/SunGather/Wallbox/sungather.py", line 195, in <module>
main()
File "/home/pi/SunGather/Wallbox/sungather.py", line 129, in main
inverter.configure_registers(registersfile)
File "/home/pi/.local/lib/python3.9/site-packages/SungrowClient/SungrowClient.py", line 159, in configure_registers
for register in registersfile['registers'][1]['hold']:
IndexError: list index out of range
Did you notice this comment:
scan: # these have to be 1 less than the first register
oh dear ;-) ok i have changed that to:
scan: # these have to be 1 less than the first register
- read:
- start: 21199
range: 10
- hold:
- start: 21199
range: 10
but the error remains - I may not have understood the "hold" parameter.
Thanks & greetings Hubertus
Edited (sigh) ...
Change this:
- response: 0x01
value: "1ph"
scan: # these have to be 1 less than the first register
into this:
- response: 0x01
value: "1ph"
- hold:
scan: # these have to be 1 less than the first register
Thank you - one step further! Because the error message with the "year" came up, I set use_local_time to true. But it still doesn't run smoothly. The key "year" is not set in my config.
python3 sungather.py -c /home/pi/SunGather/Wallbox/config.yaml -r /home/pi/SunGather/Wallbox/registers-wallbox.yaml -v 30 --runonce
2024-05-29 10:19:43 INFO Starting SunGather 0.5.2
2024-05-29 10:19:43 INFO Need Help? https://github.com/bohdan-s/SunGather
2024-05-29 10:19:43 INFO NEW HomeAssistant Add-on: https://github.com/bohdan-s/hassio-repository
2024-05-29 10:19:44 INFO Loaded config: /home/pi/SunGather/Wallbox/config.yaml
2024-05-29 10:19:44 INFO Loaded registers: /home/pi/SunGather/Wallbox/registers-wallbox.yaml
2024-05-29 10:19:44 INFO Registers file version: 0.2.3
+----------------------------------------------+
| Inverter Configuration Settings |
+----------------------------------------------+
| Config | Value |
+--------------------+-------------------------+
| host | 192.168.179.9 |
| port | 502 |
| timeout | 10 |
| retries | 3 |
| RetryOnEmpty | False |
| model | AC011E-01 |
| serial_number | None |
| level | 2 |
| scan_interval | 30 |
| use_local_time | True |
| smart_meter | False |
| connection | modbus |
| slave | 2 |
| start_time | |
+----------------------------------------------+
2024-05-29 10:19:47 ERROR Failed to scrape: 'year'
Traceback (most recent call last):
File "/home/pi/SunGather/Wallbox/sungather.py", line 156, in main
success = inverter.scrape()
File "/home/pi/.local/lib/python3.9/site-packages/SungrowClient/SungrowClient.py", line 379, in scrape
del self.latest_scrape["year"]
KeyError: 'year'
Failed to scrape: 'year'
Traceback (most recent call last):
File "/home/pi/SunGather/Wallbox/sungather.py", line 156, in main
success = inverter.scrape()
File "/home/pi/.local/lib/python3.9/site-packages/SungrowClient/SungrowClient.py", line 379, in scrape
del self.latest_scrape["year"]
KeyError: 'year'
2024-05-29 10:19:47 WARNING Data collection failed, skipped exporting data. Retying in 30 secs
Data collection failed, skipped exporting data. Retying in 30 secs
Thanks & greetings Hubertus
It really only scrapes what you defined in registers:
. If the yaml you posted earlier is complete there are only 3 registers defined, not including year.
Background information: The scan:
section is used to first read all data in the defined address areas. In a second step Sungather extracts all defined registers from these areas. After this it has some logic to convert date information into a date field and delete the single year, month, day, etc. fields. Thus the del self.latest_scrape["year"]
code snippet. This cannot be changed by configuration. So you must pull all those date fields.
Thank you !
i defined "Year":
- name: "Year"
level: 2
address: 21224
datatype: "U16"
unit: "YYYY"
but "year" is case sensitiv and now with "year" lowercase it works. So - for you: a query of the wallbox connected to the inverter (in this case the AC011E-01) also works.
MANY THANKS for the support. Great.
Sunny greetings Hubertus
Well, thanks to you for researching this wallbox stuff!
Super only a few formatting problems remain ;-) The documentary writes:
"_address name description unit type len factor offset formula role room poll wp cw isScale"
"21200 Total_Energy Bisher geladene Gesamtleistung wh uint32be 2 1 state true true false false"
"21202 SetOutI Ausgangsstrom | 0,1A | 6A-63A A uint16be 1 1 state true true false false"
"21203 PhaseSwitch PhaseSwitch | 0=3ph 1=1ph uint16be 1 1 state true true false false"
"21210 Charger_Enable Charger Enable | 0=disable 1=enable uint16be 1 1 state true true false false"
"21211 START_STOP_CHARGING Ladung Starten | Stoppen 0=Start 1=Stop uint16be 1 1 state true true false false"
"21212 Total_Energy Total_Energy Wh uint32be 2 1 state true true false false"
"21224 Year Year uint16be 1 1 state true true false false"
"21225 Month Month uint16be 1 1 state true true false false"
"21226 Day Day uint16be 1 1 state true true false false"
"21227 Hour Hour uint16be 1 1 state true true false false"
"21228 Minute Minute uint16be 1 1 state true true false false"
"21229 Second Second uint16be 1 1 state true true false false"
"21230 Dev_Address Bus Adresse | deafult 248 uint16be 1 1 state true true false false"
"21231 Enery_per_Km Energie pro Km uint16be 1 1 state true true false false"
the results from modbus tool fit so far:
modbus 192.168.179.9 -s 2 21200 = 38174 // according to APP "38.2" would be correct
modbus 192.168.179.9 -s 2 21202 = 60
modbus 192.168.179.9 -s 2 21203 = 0 // only "0" or "1"
modbus 192.168.179.9 -s 2 21210 = 1 // only "0" or "1"
modbus 192.168.179.9 -s 2 21211 = 0 // only "0" or "1"
modbus 192.168.179.9 -s 2 21230 = 248 // default is 248 !
modbus 192.168.179.9 -s 2 21231 = 50
but the output from Sungather doesn't really fit:
+----------------------------------------------------------------------+
| Address | Register | Value |
+---------+-------------------------------------+----------------------+
| ---- | device_type_code | AC011E-01 |
| 21200 | Total_Energy | 1093795840 wh |
| 21202 | SetOutI | 842543673 A |
| 21203 | PhaseSwitch | 12856 |
| 21210 | ChargerEnable | 0 |
| 21211 | StartStopCharging | 0 |
| 21212 | TotalEnergy2 | 0 wh |
| 21230 | Dev_Adress | 17709 |
| 21231 | Energy_per_Km | 12853 |
| vr002 | timestamp | 2024-05-29 13:36:02 |
+----------------------------------------------------------------------+
the matching register configuration:
version: 0.2.3
vendor: Sungrow
registers:
- read:
- name: "Total_Energy"
level: 2
address: 21200
datatype: "U32"
unit: "wh"
- name: "SetOutI"
level: 2
address: 21202
datatype: "U32"
unit: "A"
- name: "PhaseSwitch"
level: 2
address: 21203
datatype: "U16"
# datarange:
# - response: 0x00
## value: "3ph"
# - response: 0x01
# value: "1ph"
- name: "ChargerEnable"
level: 2
address: 21210
datatype: "U16"
- name: "StartStopCharging"
level: 2
address: 21211
datatype: "U16"
- name: "TotalEnergy2"
level: 2
address: 21212
datatype: "U32"
unit: "wh"
- name: "year"
level: 2
address: 21224
datatype: "U16"
unit: "YYYY"
- name: "month"
level: 2
address: 21225
datatype: "U16"
unit: "MM"
- name: "day"
level: 2
address: 21226
datatype: "U16"
- name: "hour"
level: 2
address: 21227
datatype: "U16"
- name: "minute"
level: 2
address: 21228
datatype: "U16"
- name: "second"
level: 2
address: 21229
datatype: "U16"
- name: "Dev_Adress"
level: 2
address: 21230
datatype: "U16"
- name: "Energy_per_Km"
level: 2
address: 21231
datatype: "U16"
maybe you have an idea how to get the values displayed correctly
Otherwise, YES, it was great to work this out together.
Greetings Hubertus
Another important note for other users: querying the registers of the wallbox only works on the WInetS connection - these registers are not available on the LAN connection!
Try accuracy:
- name: "Total_Energy"
level: 2
address: 21200
datatype: "U32"
unit: "wh"
accuracy: 0.001
And I suggest you put this register into the hold
section. At least the settings parametert MUST be hold
parameters as you cannot write to read
parameters. Possibly this whole section belongs in the hold
section.
Another important note for other users: querying the registers of the wallbox only works on the WInetS connection - these registers are not available on the LAN connection!
This is a pity - but good to know. However check reading the registers from the hold section (see my other post) before this is final.
Now the chaos is complete ;-)
I have looked in your "registers-sungrow". There the registers for "year" etc. are in the hold section. If I do the same I get the error message:
2024-05-31 10:38:49 ERROR Failed to scrape: 'year'
Traceback (most recent call last):
File "/home/pi/SunGather/Wallbox/sungather.py", line 156, in main
success = inverter.scrape()
File "/home/pi/.local/lib/python3.9/site-packages/SungrowClient/SungrowClient.py", line 379, in scrape
del self.latest_scrape["year"]
KeyError: 'year'
Failed to scrape: 'year'
Traceback (most recent call last):
File "/home/pi/SunGather/Wallbox/sungather.py", line 156, in main
success = inverter.scrape()
File "/home/pi/.local/lib/python3.9/site-packages/SungrowClient/SungrowClient.py", line 379, in scrape
del self.latest_scrape["year"]
KeyError: 'year'
I then put these registers back in the read section - at least that part works.
An additional question: my serial number of the wallbox is "A2292803764" but with the query data type "UTF-8" I only get "A2292803".
I will now test the registers one by one and get back to you with the next problem :-))
Greetings Hubertus
Translated with www.DeepL.com/Translator (free version)
The registers for year etc. are not the same as those from the inverter, because it is another unit / slave.
Testing register by register is a good idea. (However year and month etc. will probably not be in different sections.) But those registers that deliver strange values are good candidates. The data you reported is not only off by an accuracy factor ...
The problem with serial number and UTF8 is a bug in Sungather. (There has been an issue about this here before: The person reporting this had the problem of two identical serial numbers because they were different in only the last digit.) Sungather simply assumes too few bytes of data. And this is hardcoded way in the original version of Sungather and cannot be configured.
Btw. are you sure you get "A2292803" and not "A229280376" (only omitting the "4")?
wow - the biggest mistake on my part was that an offset of "1" must be observed for the INet connection. But not for all registers. :-)
Now, after a lot of testing, it works:
+----------------------------------------------------------------------+
| Address | Register | Value |
+---------+-------------------------------------+----------------------+
| ---- | device_type_code | AC011E-01 |
| vr001 | run_state | OFF |
| vr003 | last_reset | 2024-06-21 10:10:25 |
| vr006 | daily_export_to_grid | 0.0 kWh |
| vr007 | daily_import_from_grid | 0.0 kWh |
| 21201 | serial_number | A229280376 |
| 21207 | PhaseSwitch | 0 |
| 21262 | Rated_Voltage | 230 V |
| 21263 | WorkMode | Netzwerk |
| 21268 | Charger_Status | Enable |
| 21300 | Total_Energy | 172.7 kWh |
| 21302 | Charging_Voltage_R | 0.0 V |
| 21303 | Charging_Current_R | 0.0 A |
| 21304 | Charging_Voltage_S | 0.0 V |
| 21305 | Charging_Current_S | 0.0 A |
| 21306 | Charging_Voltage_T | 0.0 V |
| 21307 | Charging_Current_T | 0.0 A |
| 21308 | Charging_Power | 0.0 kW |
| 21310 | Charging_Engery | 12.67 kWh |
| 21314 | Start_Mode | None |
| 21316 | Power_Regulation | forbidden |
| 21317 | Charging_Status | Idle |
| 21318 | Charge_Start_Time | 1718883655 |
| 21320 | Charge_End__Time | 1718894336 |
| 21316 | Hold-Status | 0 |
| vr002 | timestamp | 2024-06-21 10:10:25 |
| vr004 | export_to_grid | 0 W |
| vr005 | import_from_grid | 0 W |
+----------------------------------------------------------------------+
Logged 28 registers to Console
I have also attached my register file registers-wallbox.yaml.txt
The "PhaseSwitch" register has not yet been confirmed. But you can also see the function, whether single-phase or multi-phase, from the Charging_xxx_y registers. If only one phase is charging, the power is Charging_Voltage_R Charging_Current_R for all three phases (simplified formula) Charging_Voltage_R Charging_Current_R * 1.732 (square root of 3).
Small problems remain:
Sungrow has confirmed that the registers of the wallbox are only available via the WINetS connection. If you could use two instances of sungather this would not be a problem.
Greetings Hubertus
Hello everyone, would it also be possible to query a wallbox such as the AC011E-01? Then you could also read out this data. This would be practical as it would also allow you to calculate the charging power. Currently, the inverter only displays the total power consumed.
Thank you and best regards Hubertus