additional info, just have a look to the sensor parameter… the “Battery discharging power” has a value of 0, the “Battery power raw” shows the right value
I have this issue too — on/off indicators are all off and some of the sensors are displaying 0. I also have the problem with running_state
being 0 and Sungrow inverter state
being “Unknown - should not see me!”
Did anyone have any luck figuring out how to get these working? I’ve tried a couple of things in this thread but nothing has fixed it yet. SH6.0RS inverter and SBR096 battery
Oh my god … have found the inconsistency
I have configured the wrong Lan port, it seems that the one on WinNetS can also do a little bit ModBus, but does not deliver everything. After the changeover, I now receive correct values.
The data for the energy display is also correct if you understand that the daily values are displayed there. I was of the (stupid) opinion that the flow is displayed there
Just learning how homeassitant is working
most of the “some sensors are not correct”-issues are related to not using the internal LAN port.
The Ethernet by WiNetS only provides a subset of the functions (same with the WLAN).
So use the internal Ethernet port of the Inverter (NOT the WinetS).
btw. there are currently some issues with the new HA version 2023.9 and pymodbus (which this integration relys on). In some cases this leads to a stopped communication after some minutes.
If you are affected, downgrade to 2023.8.
If you are still on <= 2023.8: Stay, until the github message says “cleared”
I just updated the description in the github to clarify more
As I also couldn’t find any entity for the total energy used by the complete load / all devices / my home (whatever you wanna call it).
Do you calculate it on your own now (how exactly)?
For the current value (W instead of kWh) we have the power consumption as entity “Load power”.
Before I installed the solar panels, the used energy of the house was simply the value on the smart meter of my grid provider, and it was always a good indicator to see if I use more or less energy over time and if there’s room for improvement or savings.
So I want to implement this again, even if the smart meter can’t provide it anymore because of the savings of the solar installation.
I think I need new template sensors like this, maybe someone with more experience in solar stuff can tell me if I understand the values correctly:
sensor.total_exported_energy_from_battery = sensor.total_exported_energy - sensor.total_exported_energy_from_pv
sensor.total_direct_battery_consumption = sensor.total_battery_discharge - sensor.total_exported_energy_from_battery
sensor.total_load_energy = sensor.total_imported_energy + sensor.total_direct_energy_consumption + sensor.total_direct_battery_consumption
@mkai if this makes sense, do you think this would be useful for others too and you might add it to your repo?
Otherwise I add it to my local config …
Thanks, everyone
Does this integration also work with SGx.0RT inverters?
Partly.
Some things do not work. The SG inverter uses partly other registers and you don’t need the battery section.
Here is the code for my SG. The code is based on the code from @mkai.
modbus:
- name: WR2_Sungrow_SG6.0RT
type: tcp
host: !secret sungrow_wr2_modbus_host_ip
port: !secret sungrow_wr2_modbus_port
retries: 10
sensors:
- name: WR2_Sungrow device type code
unique_id: wr2_dev_code
slave: !secret sungrow_wr2_modbus_slave
address: 4999 # reg 5000
input_type: input
data_type: uint16
scan_interval: 600
- name: WR2_Inverter temperature
unique_id: wr2_inverter_temperature
slave: !secret sungrow_wr2_modbus_slave
address: 5007 # reg 5008
input_type: input
data_type: int16
precision: 1
unit_of_measurement: °C
device_class: Temperature
scale: 0.1
scan_interval: 10
- name: WR2_MPPT1 voltage
unique_id: wr2_mppt1_voltage
slave: !secret sungrow_wr2_modbus_slave
address: 5010 # reg 5011
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
scale: 0.1
scan_interval: 10
- name: WR2_MPPT1 current
unique_id: wr2_mppt1_current
slave: !secret sungrow_wr2_modbus_slave
address: 5011 # reg 5012
input_type: input
data_type: uint16
precision: 2
unit_of_measurement: A
device_class: Current
scale: 0.1
scan_interval: 10
- name: WR2_MPPT2 voltage
unique_id: wr2_mppt2_voltage
slave: !secret sungrow_wr2_modbus_slave
address: 5012 # reg 5013
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: V
device_class: Voltage
scale: 0.1
scan_interval: 10
- name: WR2_MPPT2 current
unique_id: wr2_mppt2_current
slave: !secret sungrow_wr2_modbus_slave
address: 5013 # reg 5014
input_type: input
data_type: uint16
precision: 2
unit_of_measurement: A
device_class: Current
scale: 0.1
scan_interval: 10
- name: WR2_Total DC power
unique_id: wr2_total_dc_power
slave: !secret sungrow_wr2_modbus_slave
address: 5016 # reg 5017
input_type: input
data_type: uint32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: WR2_Grid frequency
unique_id: wr2_grid_frequency
slave: !secret sungrow_wr2_modbus_slave
address: 5035 # reg 5036
input_type: input
data_type: uint16
precision: 2
unit_of_measurement: "Hz"
device_class: frequency
state_class: measurement
scale: 0.1
scan_interval: 10
- name: WR2_Reactive power
unique_id: wr2_reactive_power
slave: !secret sungrow_wr2_modbus_slave
address: 5032 # reg 5033
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: WR2_Power factor
unique_id: wr2_power_factor
slave: !secret sungrow_wr2_modbus_slave
address: 5034 # reg 5035
input_type: input
data_type: int16
precision: 3
unit_of_measurement: "%"
device_class: power_factor
state_class: measurement
scale: 0.001
scan_interval: 10
- name: WR2_Meter active power raw
unique_id: wr2_meter_active_power_raw
slave: !secret sungrow_wr2_modbus_slave
address: 5600 # reg 5601
input_type: input
data_type: int32
swap: word
precision: 0
unit_of_measurement: W
device_class: power
state_class: measurement
scale: 1
scan_interval: 10
- name: WR2_BDC rated power
unique_id: wr2_bdc_rated_power
slave: !secret sungrow_wr2_modbus_slave
address: 5627 # reg 5628
input_type: input
data_type: uint16
unit_of_measurement: "W"
device_class: power
state_class: measurement
scale: 100
scan_interval: 600
- name: WR2_System state
unique_id: wr2_system_state
slave: !secret sungrow_wr2_modbus_slave
address: 5037 # reg 5038
input_type: input
data_type: uint16
precision: 0
scale: 1
scan_interval: 10
# register running state is not available for certain SH*RS inverters
# template sensors are used to determine the states based on other sensors
- name: WR2_Running state
unique_id: wr2_running_state
slave: !secret sungrow_wr2_modbus_slave
address: 5038 # reg 5039
input_type: input
data_type: uint16
precision: 0
scale: 1
scan_interval: 10
- name: WR2_Daily PV generation
unique_id: wr2_daily_pv_generation
slave: !secret sungrow_wr2_modbus_slave
address: 5002 # reg 5003
input_type: input
data_type: uint16
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
scale: 0.1
scan_interval: 600
- name: WR2_Total PV generation
unique_id: wr2_total_pv_generation
slave: !secret sungrow_wr2_modbus_slave
address: 5003 # reg 5004
input_type: input
data_type: uint32
swap: word
precision: 1
unit_of_measurement: kWh
device_class: energy
state_class: total
scan_interval: 600
# 'virtual' template sensors for better readability
template:
- binary_sensor:
- name: WR2_PV generating
unique_id: wr2_pv_generating
availability: >-
{{states('sensor.wr2_running_state')|is_number or
states('sensor.wr2_total_dc_power')|is_number
}}
delay_on:
seconds: 60
state: >-
{% if states('sensor.wr2_running_state')|is_number %}
{# use available sensor running_state #}
{{ states('sensor.wr2_running_state')|int(default=0)|bitwise_and(0x1) > 0 }}
{% else %}
{# workaround for SH*RS inverters without working running_state #}
{% if states('sensor.wr2_total_dc_power')|int > 0 %}
1
{% else %}
0
{% endif %}
{% endif %}
- sensor:
- name: WR2_MPPT1 power
unique_id: wr2_mppt1_power
unit_of_measurement: W
device_class: power
availability: "{{states('sensor.wr2_mppt1_voltage')|is_number and states('sensor.wr2_mppt1_current')|is_number }}"
state: "{{ (states('sensor.wr2_mppt1_voltage') | float * states('sensor.wr2_mppt1_current') | float) |int }}"
- name: WR2_MPPT2 power
unique_id: wr2_mppt2_power
unit_of_measurement: W
device_class: power
availability: "{{states('sensor.wr2_mppt2_voltage')|is_number and states('sensor.wr2_mppt2_current')|is_number }}"
state: "{{ (states('sensor.wr2_mppt2_voltage') | float * states('sensor.wr2_mppt2_current') | float) |int }}"
- name: WR2_Sungrow inverter state
unique_id: wr2_inverter_state
state: >-
{% if ((states('sensor.wr2_system_state') | int(default=0)) == 0x8000) %}
Stop
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x1400) %}
Standby
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x1200) %}
Initial Standby
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x1600) %}
Startup
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x0) %}
Running
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x5500) %}
Fault
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x1500) %}
Emergency Stop
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x1200) %}
Initial standby
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x9100) %}
Alarm run
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x8100) %}
Derating run
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x8200) %}
Dispatch run
{% elif ((states('sensor.wr2_system_state') | int(default=0)) == 0x1300) %}
Key stop
{% else %}
Unknown - should not see me!
{% endif %}
- name: WR2_Sungrow device type
unique_id: wr2_device_type
state: >-
{% if ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x243D) %}
SG3.0RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x243E) %}
SG4.0RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2430) %}
SG5.0RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2431) %}
SG6.0RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x243C) %}
SG7.0RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2432) %}
SG8.0RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2433) %}
SG10RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2434) %}
SG12RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2435) %}
SG15RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2436) %}
SG17RT
{% elif ((states('sensor.wr2_sungrow_device_type_code') | int(default=0)) == 0x2437) %}
SG20RT
{% else %}
Unknown device code!
{% endif %}
input_select:
wr2_set_inverter_run_mode:
name: WR2_Inverter mode
options:
- "Enabled"
- "Shutdown"
# Automations: Write modbus registers on input changes via GUI
# note: If you change a value by the sliders, it will take up to 60 seconds until the state variables are updated
# Unfortunately, I could not find a way to "force update" modbus registers, yet...
automation:
- id: "automation_wr2_sungrow_inverter_state"
alias: "sungrow wr2 inverter state"
description: "Enables/ stops the inverter"
trigger:
- platform: state
entity_id:
- input_select.wr2_set_inverter_run_mode
condition: []
variables:
sg_start: 0xCF
sg_stop: 0xCE
action:
- service: modbus.write_register
data_template:
hub: WR2_Sungrow_SG6.0RT
slave: !secret sungrow_wr2_modbus_slave
address: 12999 # reg 13000
value: >
{% if is_state('input_select.wr2_set_inverter_run_mode', 'Enabled') %}
{{sg_start}}
{% else %}
{{sg_stop}}
{% endif %}
mode: single
- id: "automation_wr2_sungrow_inverter_state_input_selector_update"
alias: "sungrow wr2 inverter enable/ stop input selector update"
description: "Updates enable/ stops input selector"
trigger:
- platform: state
entity_id:
- sensor.wr2_system_state
condition: []
action:
- service: input_select.select_option
target:
entity_id: input_select.wr2_set_inverter_run_mode
data:
option: >
{% if is_state('sensor.wr2_sungrow_inverter_state', 'Stop') %}
"Shutdown"
{% else %}
"Enabled"
{% endif %}
mode: single
I am planning to provide some auto-generated yaml-files with different config settings in the future (using github actions for automated copy/pasting). I guess that will take 1-2 month, depending on my schedule…
Just try to add the integration. Most Registers for SG* work also for SH* inverters.
@basti242 : do you have a list of differences at hand? I don’t have the time at the moment to manually diff the modbus register description from sungrow
will check it, soon. Sorry, not much time at the moment
but it totally makes sense to integrate a template sensor for this!
I use the Home Assistant Energy Dashboard to get the house load in energy/kWh
The Energy Dashboard uses these sensors as input:
Total imported energy
Total exported energy
Total PV generation
Total battery discharge
Total battery charge
I assume:
total_load_energy = Total PV generation - Total exported energy + Total imported energy - Total battery charge + Total battery discharge
Hi,
am I the only one having issues with modbus and 2023.10.0?
After updating the sensors are “unavailable” again…
Invalid config for [modbus]: BDC rated power:
count: 1
cannot be combined withdata_type: uint16
@ data[‘modbus’][0][‘sensors’][19]. Got {‘name’: ‘BDC rated power’, ‘unique_id’: ‘sg_bdc_rated_power’, ‘slave’: 1, ‘address’: 5627, ‘input_type’: ‘input’, ‘count’: 1, ‘data_type’: ‘uint16’, ‘swap’: ‘none’, ‘unit_of_measurement’: ‘W’, ‘device_class’: ‘power’, ‘state_class’: ‘measurement’, ‘scale’: 100, ‘scan_interval’: 600} BMS max. charging current:count: 1
cannot be combined withdata_type: uint16
@ data[‘modbus’] …
I found this issue maybe related to my problem:
Any ideas? Shall I downgrade?
Please update your modbus script to the latest version
Have a look at the corresponding github page…
I fixed it one week ago:
Yes, I know it is annoying that the HA modbus protocol changed very much over the last weeks, but all changes were good and justified and resulted in a clearer code of this sungrow integration.
Sorry for that. Thank you very much for your great work and support!
Here you will find a small list. It is not so much.
The codes for Inverter state are also different. I will add this later the day.
thank you,
I will integrate that into version 2 (experimental branch), in a couple of weeks
Hi all,
Thanks for all your work on this @mkai!
I’m preparing to do this integration for a friend, can you help me understand what the difference is between this integration and @mvandersteen’s one here: GitHub - mvandersteen/SungrowInverter: Allows to pull data from a Sungrow residential inverter via Modbus TCP
The documentation here is a lot better… I’m new to Home Assistant and I’m not sure how to install his.
Hey all
I’ll be having a SH10RS installed shortly (within the month), and I want to make sure the installers use the right comms cables for HA monitoring. In this model, COM1 is for the WiNet-S module, while COM2 has 2 RJ45 ports (see attached images)
Which port should the installers run to my switch for home assistant to read from?
Side note - they will also be using a Sungrow energy monitor, and there will be Sungrow batteries too - so not 100% if those other devices will utilise those COM2 ports.
that depends
mvandersteens integration requires some more setup to do and is based on python / HA addon
I wrote the integration in a way that it is self-contained in one .yaml file (and some configurations in the secrets.yaml) and does not require any additional stuff…
What inverter / battery will be installed?
make sure to have an Ethernet / LAN cable attached to the inverter (NOT! the WiNet-S stick). Then you will have the most stable modbus connection possible.