Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sungrow SG10RT - "unable to decode request" #58

Open
gservat opened this issue Oct 8, 2021 · 17 comments
Open

Sungrow SG10RT - "unable to decode request" #58

gservat opened this issue Oct 8, 2021 · 17 comments

Comments

@gservat
Copy link

gservat commented Oct 8, 2021

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
Copy link
Contributor

rark-ha commented Oct 21, 2021

See issue [https://github.com//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
Copy link
Contributor

bohdan-s commented Dec 6, 2021

Hi, please see #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
Copy link
Author

gservat commented Dec 6, 2021

@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
Copy link
Author

gservat commented Dec 6, 2021

Maybe because the SungrowModbusWebClient doesn't support sg10rt?

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

@gservat
Copy link
Author

gservat commented Dec 6, 2021

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

@gservat
Copy link
Author

gservat commented Dec 6, 2021

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

@bohdan-s
Copy link
Contributor

bohdan-s commented Dec 6, 2021

@gservat that was quick,

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

Let me know how it goes.

@gservat
Copy link
Author

gservat commented Dec 6, 2021

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
Copy link
Contributor

bohdan-s commented Dec 6, 2021

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
Copy link
Contributor

bohdan-s commented Dec 6, 2021

@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
Copy link
Author

gservat commented Dec 6, 2021

@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
Copy link
Author

gservat commented Dec 6, 2021

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
Copy link
Author

gservat commented Dec 6, 2021

Oh.. you suggested looking at the SG7RT config 👍

@bohdan-s
Copy link
Contributor

bohdan-s commented Dec 6, 2021

@gservat
Copy link
Author

gservat commented Dec 7, 2021

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
Copy link
Author

gservat commented Dec 7, 2021

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

@bohdan-s
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants