SMA Sunny Island Inverter modbus configuration

Hi,
relatively new to homeassistant im trying to interact with my “new” sunny island battery inverter from sma.
I know there is already a ton of threads regarding sma inverters and I think I’ve read them all. None is covering sunhy island either.
The actual problem:
I can connect to the inverter, modbus is enabled.
I can read out values wich make sense… but only with the ios app “peek & poke”.
For example connecting to the inverters IP with port 502 and ID 3 getting the holding register 30845 (count 2) gets me the SoC of the battery. Same for other values like battery voltage.
If I read the same register as input register the ios app shows me the same value.

However when I try to connect with HA I get the following error:

Pymodbus: SMA Sunny Island: Exception Response(131, 3, IllegalAddress)

My configuration.yaml looks like this:

modbus:
  - name: "SMA Sunny Island"
    type: "tcp"
    host: 172.17.172.20
    port: 502
    #close_comm_on_error: true
    sensors:
      - name: Sunny Island - SoC
        input_type: holding
        unit_of_measurement: "%"
        slave: 3
        address: 30845
        count: 2
        data_type: uint32
        precision: 1

What makes me headaches is: even with other tools like modbus examiner or QModMaster I’m not able to read out the values. I can connect to the server but dont get values. So the ios app peek & poke seems to make something different but I cant figure out what. Maybe I have to read out a special register first to get access to the values. I’m lost after hours of trying and googling.

A table of register can be found at the end of the modbus communication manual.


I got a bit further. Fiddling around with register numbers it seems (at least with qmodmaster) a matter of counting from 0 or 1. Reading Two register from adress 30846 gives me the SoC outside of ios.
Sadly going one number up in my config doenst solve it.

I got a big step further. After being very self confident that it must be a bug… after filing one on github a nice guy over there found out I had a 0 too much in my configurations adress after only a few seconds. I stared at that code for hours.

However, after the first proof of concept I startet too fiddle with GPT4 to write the configuration and this is what I come up with now. tbh I’m not sure if this was really faster this way. Without having a coarse idea of what to do and how to script the results would not work. However, the following code shows some values of the inverter and I am even able to change one register with a switch wich keeps its state. Unfortunately I have the Sunny Island SI 3.0M-11 Model wich seems to differ in many registers from the documentation and modbus integration manual from SMA. I’ll have to ask SMA for the proper documentation.

script:
  write_register_turn_on_bit:
    sequence:
      - service: homeassistant.update_entity
        data:
          entity_id: "{{ sensor_value }}"

  write_register_turn_off_bit:
    sequence:
      - service: homeassistant.update_entity
        data:
          entity_id: "{{ sensor_value }}"

modbus:
  - type: tcp
    host: 172.17.172.20
    port: 502
    name: "SMA Sunny Island"
    close_comm_on_error : false
    delay : 2
    retries: 10
    retry_on_empty: true
    sensors:
      - name: "Sunny Island - State of Charge"
        data_type: uint32 #U32
        input_type: holding
        swap: none
        slave: 3
        address: 30845
        count: 2
        unit_of_measurement: "%"
      - name: "Sunny Island - Batterietemperatur"
        data_type: uint32 #U32
        input_type: holding
        swap: none
        slave: 3
        address: 30849
        count: 2
        unit_of_measurement: "°C"
        scale: 0.1
      - name: "Sunny Island - Batteriestrom"
        data_type: int32 #S32
        input_type: holding
        swap: none
        slave: 3
        address: 30843
        count: 2
        unit_of_measurement: "A"
        #precision: 1
      - name: "Sunny Island - Eigenverbrauchserhoehung Status"
        data_type: uint32
        input_type: holding
        swap: none
        slave: 3
        address: 40075
        count: 2

template:
  - sensor:
    - name: "Sunny Island - Batteriestrom Scaled"
      unit_of_measurement: "A"
      state: "{{ ((states('sensor.sunny_island_batteriestrom')|float * -1) / 1000)|round(1) }}"

switch:
  - platform: template
    switches:
      sunny_island_eigenverbrauch:
        friendly_name: "Eigenverbrauchserhöhung Sunny Island"
        value_template: >
          {% set bit = 1 %}
          {{ states('sensor.sunny_island_eigenverbrauchserhoehung_status') | int(default=0) | bitwise_and(2 ** (bit | int - 1)) > 0 }}
        turn_on:
          - service: script.write_register_turn_on_bit
            data:
              bit: 1
              sensor_value: sensor.sunny_island_eigenverbrauchserhoehung_status
          - service: modbus.write_register
            data:
              hub: "SMA Sunny Island"
              unit: 3
              address: 40075
              value: [0, 1129]
          - delay: "00:00:05"
          - service: homeassistant.update_entity
            data:
              entity_id: sensor.sunny_island_eigenverbrauchserhoehung_status
        turn_off:
          - service: script.write_register_turn_off_bit
            data:
              bit: 1
              sensor_value: sensor.sunny_island_eigenverbrauchserhoehung_status
          - service: modbus.write_register
            data:
              hub: "SMA Sunny Island"
              unit: 3
              address: 40075
              value: [0, 1130]
          - delay: "00:00:05"
          - service: homeassistant.update_entity
            data:
              entity_id: sensor.sunny_island_eigenverbrauchserhoehung_status

Hi everyone,
I am new to this forum. I have a sunny island at home and am trying to access it through Modbus. No luck thus far. I am able to connect with an app on the iPhone to the Sunny Island but cannot receive any data. I keep getting errors.

Has anyone good experience in this subject?

Thank you,

Hey I’ve been reasonably successful connecting to my Sunny Island 8.0H to both read and write modbus registers. First make sure the Sunny Island is properly network connected and you have Modbus installed on your HAOS.

You want to setup your Modbus connection in your configuration.yaml file first. Eg:

modbus:
  - name: "Sunny Island Modbus"
    type: tcp
    host: 192.168.1.174
    port: 502
    delay: 5
    sensors:
      - name: "Generator Nominal Current"
        unit_of_measurement: "mA"
        address: 40047
        data_type: int32
        precision: 0
        input_type: holding
        scan_interval: 60
        slave: 3

Then whatever is in the sensors block will show up as an entity in HAOS. To then go and write to the same register you can create a script to use as part of your automations. Edit your scripts.yaml file with something like this:

set_sunnyisland_to_3a:
  alias: Set Grid Current to 3A
  sequence:
    - service: modbus.write_register
      data:
        hub: Sunny Island Modbus
        unit: 3
        address: 40047
        value:
          - 0
          - 3000

If you haven’t found it already the register lists are available from the SMA website. Just make sure to take note of the revision of your device and also the firmware versions.

Hope this helps!