meltaxa / solariot

Leverage your IoT enabled Solar PV Inverter to stream your solar energy usage data to a real time dashboard.
https://solariot.live
MIT License
199 stars 69 forks source link

Sungrow SG10RT - "unable to decode request" #58

Open gservat opened 2 years ago

gservat commented 2 years ago

Just got a Sungrow SG10RT installed and my config.py looks like this:

inverter_ip = "192.168.1.120"
inverter_port = 502
slave = 0x01
model = "sungrow-sg10rt"
timeout = 3
scan_interval = 10
json_file = "telemetry.json"

Confirmed that port 502 is open on the inverter_ip. Log:

INFO:root:Loaded config sungrow-sg10rt
INFO:root:Creating SungrowModbusTcpClient
INFO:root:Connecting
INFO:root:Connected
INFO:root:No MQTT configuration detected
INFO:root:No InfluxDB configuration detected
INFO:root:No PVOutput configuration detected
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x4 0x13 0x88 0x0 0x64
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Transaction failed. ([Errno 54] Connection reset by peer)
DEBUG:pymodbus.framer.socket_framer:Processing:
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
WARNING:root:Modbus connection failed
WARNING:root:Failed to scrape inverter, sleeping until next scan

I saw another issue that mentioned using pymodbus version 2.4.0. I'm already on that version as per requirements.txt

Any ideas?

rark-ha commented 2 years ago

See issue [https://github.com/meltaxa/solariot/issues/53]

It will pull the holding registers (time/date etc) but not the input registers. I had this inverter working, but unsure if a firmware update or the wifi/lan change killed it for me.

bohdan-s commented 2 years ago

Hi, please see https://github.com/meltaxa/solariot/pull/66, I have created a new library SungrowModbusWebClient to pull the modbus via HTTP requests. It's dirty but I have been running it now for a week.

gservat commented 2 years ago

@bohdan-s thanks for your efforts! I just gave it a shot with my SG10RT and getting this error:

INFO:root:Loaded config sungrow-sg10rt
INFO:root:Creating SungrowModbusWebClient
INFO:root:Connecting
DEBUG:root:Connection to websocket server established: ws://192.168.0.102:8082/ws/home/overview
DEBUG:root:{'result_code': 1, 'result_msg': 'success', 'result_data': {'service': 'connect', 'token': '<token>, 'uid': 1, 'tips_disable': 0}}
INFO:root:Token Retrieved: <token>
INFO:root:Requesting Device Information
DEBUG:root:{'result_code': 1, 'result_msg': 'success', 'result_data': {'service': 'runtime', 'count': 1, 'list': [{'dev_name': 'SG10RT(COM1-001)', 'dev_model': 'SG10RT', 'dev_type': 21, 'dev_procotol': 2, 'today_energy': '20.10', 'today_energy_unit': 'kWh', 'total_energy': '2670.70', 'total_energy_unit': 'kWh', 'dev_state': '0', 'dev_state_unit': '', 'curr_power': '8.48', 'curr_power_unit': 'kW', 'reactive_power': '1.51', 'reactive_power_unit': 'kvar'}], 'connect_count': 1, 'off_count': 0}}
Traceback (most recent call last):
  File "./solariot.py", line 115, in <module>
    client.connect()
  File "/Users/gservat/.pyenv/versions/3.7.9/lib/python3.7/site-packages/SungrowModbusWebClient/SungrowModbusWebClient.py", line 91, in connect
    self.dev_code = next(s for s in self.model_codes if self.model_codes[s] == payload_dict['result_data']['list'][0]['dev_model'])
StopIteration
gservat commented 2 years ago

Maybe because the SungrowModbusWebClient doesn't support sg10rt?

     # See: Appendix 6、Device Information
     model_codes = {
         "9264": "SG5.0RT",
         "9276": "SG7.0RT"
     }
gservat commented 2 years ago

Sorry didn't realise you wrote the SungrowModbusWebClient library :)

gservat commented 2 years ago

Happy to file a PR to add the model for the SG10RT, however no idea where to get the model_code from?

bohdan-s commented 2 years ago

@gservat that was quick,

Added SG10RT to model list, pip install SungrowModbusWebClient==0.2.3

Let me know how it goes.

gservat commented 2 years ago

Thanks @bohdan-s you mean 0.2.4 yeah?

Excited to see it works!!

One thing though. I noticed that in the telemetry.json it doesn't have any info around power exported. This is the output:

{
  "daily_power_yield": 40600,
  "total_power_yield": 26.91,
  "total_ongrid_running_time": 762,
  "internal_temp": 61.1,
  "apparent_power": 2993000,
  "pv1_voltage": 367.8,
  "pv1_current": 4.1,
  "pv2_voltage": 398.2,
  "pv2_current": 4.1,
  "total_pv_power": 3139,
  "grid_voltage_a": 238.4,
  "grid_voltage_b": 240.8,
  "grid_voltage_c": 241.6,
  "inverter_current_a": 4,
  "inverter_current_b": 4.1,
  "inverter_current_c": 4.1,
  "total_active_power": 2976,
  "grid_frequency": 500.3,
  "array_insulation_resistance": 317.2,
  "daily_operation_time": 540,
  "monthly_power_yield": 263400,
  "export_power": 0,
  "export_power_indicator": 65535,
  "power_meter": 65535,
  "year": 2021,
  "month": 12,
  "day": 6,
  "hour": 13,
  "minute": 48,
  "second": 45,
  "timestamp": "6/12/2021 13:48:45"
}

I'd like to look at the output provided by my SG10RT as I'm not sure if it's a register mapping problem or if the inverter is simply not providing that info. Any ideas?

I tried the following:

curl http://192.168.0.102/device/getParam\?dev_id\=1\&dev_type\=21\&dev_code\=9267\&type\=3\&param_addr\=5000\&param_num\=10\&param_type\=1\&token\=<token>\&lang\=en_us\&time123456\=1638762788
{
        "result_code":  1,
        "result_msg":   "success",
        "result_data":  {
                "param_value":  "07 E5 00 0C 00 06 00 0D 00 35 00 20 00 CF 00 AA 04 4C FF FF "
        }
}

... but not sure what each of those hex pairs mean.

bohdan-s commented 2 years ago

curl http://192.168.0.102/device/getParam\?dev_id\=1\&dev_type\=21\&dev_code\=9267\&type\=3\&param_addr\=5000\&param_num\=10\&param_type\=0\&token\=\&lang\=en_us\&time123456\=1638762788

That query is reading Holding Registers, 07 E5 = 2021 which is register 5000 of the holding register. you want the Read-only so param_type=0 (not 1 as above).

Have a look at the SG7.0RT config, I have mapped out almost all the registers, you can comment/uncomment and test and see if you get the right data. The 7.0/10 are almost the same for registers.

The below code will loop through 5000-5200 and output the register and the Decimal value. Swap the [xxx] values.

import json
import requests
import time

address = 5000
print(time.localtime())
while address < 5200:
    r = requests.get(f'http://192.168.1.[xxx]/device/getParam?dev_id=1&dev_type=21&dev_code=9267&type=3&param_addr={address}&param_num=1&param_type=0&token=[xxx]&lang=en_us&time123456={str(int(time.time()))}')
    if str(r.status_code) == '200':
        payload_dict = json.loads(str(r.text))
        if payload_dict['result_code'] == 1:
            print("Address: " + str(address) + ", " + str(payload_dict['result_data']['param_value']) + ": " + str(int(payload_dict['result_data']['param_value'].replace(" ",""), 16)))
    address += 1
bohdan-s commented 2 years ago

@gservat, Also do you see power export on the iSolarCloud app? With the SG7.0RT I had to get a DTSU666 smart meter installed to see that extra data.

gservat commented 2 years ago

@bohdan-s yep I definitely see how much power we sell back to the grid via iSolarCloud. We got a smart meter installed with the system.

Thanks heaps for your feedback btw. I'll try what you suggested and see how I go.

gservat commented 2 years ago

With that code you provided, I've got lots of interesting values for each register but I just don't know what each register means :-) Any ideas how to figure that out?

gservat commented 2 years ago

Oh.. you suggested looking at the SG7RT config 👍

bohdan-s commented 2 years ago

Sorry, took a while to upload, here is the official document i based the SG7.0RT file on: https://github.com/bohdan-s/Sungrow-Inverter/blob/main/Modbus%20Information/Communication%20Protocol%20of%20PV%20Grid-Connected%20String%20Inverters_V1.1.37_EN.pdf

gservat commented 2 years ago

Super userful. Thanks @bohdan-s!

Just wondering: in pvoutput.org, live data looks like this for me:

image

I think most fields look OK except for "power used". Is this field displaying whatever solariot sends as "power consumption"? That would be power_meter for me (register 5218), but it's always 65535.

gservat commented 2 years ago

Come to think of it I don't think that "energy used" column is very accurate either.

bohdan-s commented 2 years ago

I thought I would just update, I have forked (and rewritten) Solariot here: https://github.com/bohdan-s/SunGather The main difference is there is no more model files, it uses a shared registers file and detects your model to return the correct registers. It also resolves the PVOutput data issues above.