Sungrow SH10.RT Modbus integration

Hallo Artur,

einfach einen neuen Kommentar erstellen, STRG + E und dann den kopierten code einfügen.

# Home Assistant Sungrow inverter integration
# https://github.com/mkaiser/Sungrow-SHx-Inverter-Modbus-Home-Assistant
# by Martin Kaiser
# last update: 2023-09-28

modbus:
  - name: WR2_Sungrow_SG5.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

      - 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

Hallo Zusammen,
ich kämpfe gerade mit einer Sache.
Ich würde gerne über HA die Backup-Funktion aktivieren bzw. deaktivieren können.
Dazu gibt es aber keine entität bei M.Kaiser
Und welches Register das ist, finde ich auch nirgends.
Hat das jemand schon mal gebastelt?

Hello everyone,
I’m currently struggling with something.
I would like to be able to activate or deactivate the backup function via HA.
But there is no entity for this in M.Kaiser
And I can’t find anywhere which register this is.
Has anyone ever tinkered with this?

Has somebody two SH10RT-V112 running as master/slave?
I only seem to be able to read out the master.

Hi Mkai

I am totally fresh here and know near to nothing… trying to install the modbusTCP2MQTT to connect mysungrow inverter… but getting fail notification:

The command ‘/bin/ash -o pipefail -c pip install --upgrade pycryptodomex==3.11.0 --no-cache-dir -r requirements.txt’ returned a non-zero code: 1

what am I doing wrong?

Hi, I am wondering if you managed to get the SH10RS working.

I connected it to the single LAN port (WiNet-S2) port, as per the comments in this thread. I can access the WiNet-S2 portal page (shows live data for the device, via the same IP address in the below error - can add a screenshot of the page).

Note, I did try the two other COM ports, but they never produced a network connection of any sort - tried a few different ways to get a connection via them

I’ve followed the configuartion directions for this integration and am receiving an error:

Pymodbus: SungrowSHx: Error: device: 1 address: 4999 -> Modbus Error: [Connection] Not connected[AsyncModbusTcpClient 192.168.86.140:502]

Did you have to make additional adjustments to get the Modbus to feed the data into Hass?

Hallo Achim,
bei mir hat der Installateur die Backup-Funktion aktiviert.
Allerdings meine ich, dass es über die icloudsolar-App auch gehen müsste, wenn du alle Berechtigungen erhalten hast.
Nach einmaliger Aktivierung habe ich die Funktion nicht wieder deaktiviert und passe nur die Backup-Reserve über HA der Wetterlage entsprechend an. Daher war die Aktivierung / Deaktivierung über HA bislang nicht notwendig.
VG Ralph

Hi,

I am working on a Sungrow Sh10RT inverter and I am finding that even when Self-consume mode is triggered the inverter is not supplying current to the house. I am not sure if it is a problem with the integration or the inverter? To keep things simple I have created a script that sends these modbus commands directly to the inverter, it matches this integration. Is there anything else I should be doing to trigger the inverter to go into Self-Consume mode?

alias: "SMART MOTION: Self-consumption mode battery"
sequence:
  - service: modbus.write_register
    data:
      hub: SungrowSHx
      slave: 1
      address: 13050
      value: 204
    alias: Set Stop (default)
  - service: modbus.write_register
    data:
      hub: SungrowSHx
      slave: 1
      address: 13049
      value: 0
    alias: Set EMS Mode Self-consumption mode (default)

Does anyone know how to get the scan_interval in practice down below 5 seconds?

Did you get readings to work with RS485?

I am doing the same thing, same inverter, seems to work fine for me:

    sequence:
      - service: modbus.write_register
        metadata: {}
        data:
          hub: SungrowSHx
          address: 13049
          slave: 1
          value: 0
      - service: modbus.write_register
        metadata: {}
        data:
          hub: SungrowSHx
          address: 13050
          slave: 1
          value: 204

Hallo,
kann es sein das der SH10RT nur von einem Gerät Modbus Abfragen annimmt?
Ich habe schon ein anderes Projekt laufen das den Sungrow abfragt über Modbus.
Jetzt wollte ich über Home Assistent zusätzlich die Werte abgreifen, da kommt aber
2024-06-21 08:55:11.582 ERROR (MainThread) [homeassistant.components.modbus.modbus] Pymodbus: SungrowSHx: Error: device: 1 address: 4999 → Modbus Error: [Connection] Not connected[AsyncModbusTcpClient 192.168.2.211:502]

Hi, new to the forum, please go easy on me.

I am after the method to change parameters on the SH10RT to govern export management, via HA.

I have seen posts here from @mvandersteen, and from what I can read - it looks like you have cracked it, or have a line on it.

FYI - I have the SH10RT, with 38kw of storage, have just gone wholesale on the grid provider, so having tight, automated control on when we should and should not export is now a big deal. The modbus/TCP integration is on sing, I can see all of the data from the inverter, but I have not sussed out how to change it. Specifically the parameters that govern the export management.

Appreciate people’s patience with this specific query, and will be grateful for any assistance.

Cheers !

Still struggling to find out the IP address of my inverter. Tried different IP scanners but don’t seem to find the correct one.
I have found the IP address of the WiFi dongle but not the LAN.
Both are connected.

Any tips on how to get a hold of it?

I have a SH10RT-v112.

BR,
Håkan

Log into your router! Then plug and unplug until you know!

There is no difference in the connected clients in the router when I unplug the cable.
Does anyone now if I somehow can login to the inverter to see the IP-address?

I asked the company that installed the inverter and the battery if they could provide me with the admin login credentials.
I said I needed them for an integration.

They told me I had to sign a non-disclosure agreement with Sungrow to get an access key. But is that correct? Isn’t that for developers using the API, as for the creator of this integration, not me as end user of the integration right?

I mean, when you get the password you can change all the important settings, so it is reasonable, that they want to be safe.
I’m not sure if you can see the ip by connecting to the inverter hotspot, but you can try.
But if you unplug the inverter, be sure to wait some time, before looking for changed devices. The name could be Espressif. Also if you want to go really far the MAC address issuer (the first 6 letters) is either Espressif or Sungrow Power Supply (for modbus).

Another thing to look for is if they are using a router of their own to be able to remote login. That way you would never be able to see the IP in your router.

and specific error noted in this post:
Pymodbus: SungrowSHx: Error: device: 1 address: 4999 → Modbus Error: [Connection] Not connected[AsyncModbusTcpClient 192.168.86.140:502]

I’m getting the same error as this. My installation was running fine for months maybe over a year without issue and then suddenly on 28th August 4:05pm it stops working. As far as I am aware no updates were undertaken at that time or even in the couple of months before that.
I’ve updated supervisor and core and this has not helped. I’ve relooked at the Github code and made a few changes to bring what I have inline with that, but short of re-copying the whole lot into my installation I’m not sure what has gone wrong.

I don’t see any record on my inverter of an update, but I guess it is possible.

did anyone happen to see similar and find a route to a fix?

I’ve had no luck unfortunately- hoping your update sparks some new ideas

1 Like

OK I got it going.
I worked my way though the FAQ for the integration one by one.
I don’t know what has changed, but I now have to use a modbus proxy.
After a full reboot it was working again. Yay!

FAQ: My Modbus connection always cuts out · mkaiser/Sungrow-SHx-Inverter-Modbus-Home-Assistant Wiki (github.com)