MODBUS data from SMA Inverter

OK,

So at the top of page 10 in both the inverter manuals they mention that we need to query the inverter for the correct Slave ID.
It says to do this we need to read register 42019 with a slave ID as 1. Then once we have the slave ID we can use that to poll the rest of the registers.

We can use the TCP view software.

Open the software and go to configure in the menu at the top.
Select “master”
And the mode as TCP, then put in the IP address of the inverter.

then back on the main page set the following

Variable Type: Holding Registers
Start Register: 2019 (you dont need the 4 because the software already knows you are trying to read a holding register so the 4 is implied)
Length: 4 (going by the manual, it seems to imply we want 4 registers returned)
Display as: unsigned ints

and finally make sure they address on the right is set to 1!

You should then be able to hit read and hopefully the poll will succeed and in register +3 we will have the slave ID of the unit.

Once you have the correct slave ID you can use this software to poll any available registers and its very quick to use and test. Once you know you can successfully read registers then you can set up your home assistant config to match.

Thanks very much for the extra effort you put in for me Techs. Sorry I took so long to come back. Had some other problems to deal with. Anyway, it did get me to a point where I managed to Read OK, but have issues with the results now. All values returned 65535. Does that mean anything to you?

Omg I just realised I misread the register number. The address we need to poll is 42109 not 42019. Lol sorry about that. Try the correct address and hopefully the data should make sense!

Bah! still getting the same.

Hmm I don’t understand why all data is like that. We are successfully polling the registers of the inverter and I can’t see anything we have missed in the manual. Are you getting those same results on both inverters?

Just in case you might not need modbus - there are other ways to get the data: see SMA Energy Meter in Home Assistant for additional details.

The other inverter just doesn’t respond. I get an error “Poll 0 Time Out occurred”. Not sure if the modbus is exposed on that one as I noticed the other day my other monitoring service also doesn’t read from it.

Mine would work with this. but since the last update it’s stopped working:

configuration.yaml:
modbus:
type: tcp
host: 16.1.1.144
port: 502

sensors.yaml:

  • platform: modbus
    scan_interval: 10
    registers:

    • name: SMA Power AC
      unit_of_measurement: W
      slave: 3
      register: 30775
      count: 2
      data_type: int
    • name: SMA Daily Yield
      unit_of_measurement: Wh
      slave: 3
      register: 30517
      count: 4
      data_type: int
    • name: SMA Total
      unit_of_measurement: MWh
      slave: 3
      register: 30513
      count: 4
      data_type: int
    • name: SMA Volt
      unit_of_measurement: V
      slave: 3
      register: 30783
      count: 2
      data_type: int
  • platform: template
    sensors:
    sma_current_solar:
    value_template: “{% if states(‘sensor.sma_power_ac’)|float < 0 or states(‘sensor.sma_power_ac’)|float > 6000 %}0{% else %}{{ states(‘sensor.sma_power_ac’)}}{% endif %}”
    friendly_name: ‘Current Solar’
    unit_of_measurement: ‘Watt’
    icon_template: mdi:flash-circle
    sma_power:
    value_template: “{% if states(‘sensor.sma_power_ac’)|float < 0 or states(‘sensor.sma_power_ac’)|float > 6000 %}0{% else %}{{ states(‘sensor.sma_power_ac’)}}{% endif %}”
    friendly_name: ‘Power’
    unit_of_measurement: ‘Watt’
    icon_template: mdi:flash-circle
    sma_day_production:
    value_template: “{{ states(‘sensor.sma_daily_yield’) }}”
    friendly_name: ‘Daily Yield’
    unit_of_measurement: ‘Wh’
    icon_template: mdi:flash-circle
    sma_total_production:
    value_template: “{{ (states(‘sensor.sma_total’) | float / 1000) | round(2) }}”
    friendly_name: ‘Total Yield’
    unit_of_measurement: ‘MWh’
    icon_template: mdi:flash-circle
    sma_voltage:
    value_template: “{% if states(‘sensor.sma_volt’)|float < 0 %}0{% else %}{{ states(‘sensor.sma_volt’) | float / 100 | round(2)}}{% endif %}”
    friendly_name: ‘Voltage’
    unit_of_measurement: ‘V’
    icon_template: mdi:flash-circle

Hi Cheesewine
there are few different modbus function if you would like to read 40037 that means you are working with holding register type. In the sensor declaration, no need to write the entire number but only 37 because the “group” 40000 is already defined by the argument: register_type
for more information related modbus have a look on this site: Data Communication Solutions | Simply Modbus Software

Anyway try the following code:

sensor:
  - platform: modbus
    scan_interval: 10 #scan every 10 secs
    registers:
    - name: SI6ModelID
      hub: SI6
      slave: 1 #with TCP should be optional
      register: 37 # if not working try 36 some modbus map starting from 0 instead of 1
      register_type: holding
      count: 1

    - name: SB5ModelID
      hub: SB5000
      slave: 1
      register: 37
      register_type: holding
      count: 1

let me know
Ciao
Matteo

Thanks All. I tried all the various variations but still have no success. Although I do have a different error message now. Considering the errors and the tips @techs gave then I’m getting the feeling the problem is in properly connecting to modbus in the first place rather than reading the registers. Does this error mean anything to anyone?

Error while setting up platform modbus
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 126, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/modbus/sensor.py", line 92, in setup_platform
    hub = hass.data[MODBUS_DOMAIN][hub_name]
KeyError: 'default'

I think I have the solution. I just tried this out with my Sunny Tripower STB 6000TL-20

With slave ID 3 I get the right results with one addition to the sensor definition: register_type: input
Without it I get no data.

here my two snippets:

modbus:
  name: sma
  type: tcp
  host: 192.168.178.101
  port: 502


sensors:
  - platform: modbus
    scan_interval: 30
    registers:
      - name: Gesamtertrag
        hub: sma
        unit_of_measurement: kWh
        slave: 3
        register: 30531
        register_type: input
        count: 2

have u done any changes exept enable modbus udp and tcp at the inverter via sunny explorer ?
I try to connect to my stp 10000tl-20 with no luck so far .The Ip Adresses are choosen automaticaly so i try to get to the modbus via my sunny homemanager 2.0.

Hi morpheus,

To enable this I only activated modbus tcp on the inverter. You must use the IP address from the inverter however.
I also have a home manager 2.0 setup. and I was not able to get any modbus communication with home Manager via tcp going so far. But I realized that the HomeManager 2.0 sends udp multicast messages every second with data from the built in energy meter.

So my approach is twofold.

  • I use a Node Red Flow to intercept the udp muticast messages from Home Manager 2.0 to get Energy in and out (current values and meters). see here: SMA Energy Meter in Home Assistant
  • I use the HA modbus integration to read the inverter.

So to get this to work you need to use the IP address from your inverter in the host section.

@chris_ka thankyou. I just tried slave 3 and it finally started returning some sort of data. Although the data ins’t totally meaningful. I’m getting -1 as the result. For some other registers I’m getting some sort of number other than -1 but none are correct. Is it the “count” or something else I should be looking at?

OK let’s do this step by step.

Prerequisites:

  1. Get the IP address of the inverter in your local Network. At daytime when the Inverter is sending data you can check your router to find the ip address. (note it down)

  2. Start Sunny Explorer and connect to your Inverter. Go to Settings and open External Communication: You should find something similar to this

  3. Note down the UnitID and TCP-Server port. Ensure that TCP-Server is active. If not change it!

  4. Now get this document: http://files.sma.de/dl/2585/WEBBOX-MODBUS-TB-en-19.pdf
    and have a look on page 28 Section 5.4.1 common Addresses of all SMA Devices. here you find the values for all relevant registers (ADR), the count (CNT) and their description.

  5. configure modbus integration in Home Manager configuration

modbus:
  name: sma
  type: tcp
  host: 192.168.178.101    # use the ip address for your inverter as mentioned in the text
  port: 502                # use the port you saw in sunny explorer
  1. configure modbus sensors in HA
sensors:
  - platform: modbus
    scan_interval: 30
    registers:
      - name: Gesamtertrag
        hub: sma
        unit_of_measurement: kWh   # see register description in section 5.4.1 of the document
        slave: 3                   # use the UnitID you found in Sunny Explorer
        register: 30531            # use a register from section 5.4.1 of the document
        register_type: input       # all registers starting with 3 need to have the type input
        count: 2                   # use the correct count for the register see section 5.4.1 of the document
  1. Have fun
6 Likes

Ah turns out getting the slave number, register and count right as per the SMA specs right can lead to point 7.

All seems to be working well except for a couple of registers such as model ID. Maybe my model is actually -1. in any case, it’ unimportant as the other values are working as expected.

Just noting that I fount there are 2 different sets of Sunny Island (SI) register specifications. The Excel one that is found on the SMA website seems to be only partially correct which this one http://files.sma.de/dl/2585/WEBBOX-MODBUS-TB-en-19.pdf has registers that mostly work.

I use the following. This gets data out of the SMA Tripower 8.0. Not all registers seem to have the right variables I think. And if the power generated by the solar panels is to low or none, the most of the registers will go to the maximum value in the variable or so. Few still make sense like SMA total.

Does anyone else has the same experience?

configuration.yaml:

modbus:
  type: tcp
  host: 192.168.15.35
  port: 502

sensor.yaml

  - platform: modbus
    scan_interval: 10
    registers:
    - name: SMA Power L1
      unit_of_measurement: kW
      slave: 3
      register: 30777
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Power L2
      unit_of_measurement: kW
      slave: 3
      register: 30779
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Power L3
      unit_of_measurement: kW
      slave: 3
      register: 30781
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Stroom L1
      unit_of_measurement: A
      slave: 3
      register: 30977
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Stroom L2
      unit_of_measurement: A
      slave: 3
      register: 30979
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Stroom L3
      unit_of_measurement: A
      slave: 3
      register: 30981
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Spanning L1
      unit_of_measurement: V
      slave: 3
      register: 30783
      count: 2
      data_type: uint
      scale: 0.01
      precision: 1
    - name: SMA Spanning L2
      unit_of_measurement: V
      slave: 3
      register: 30785
      count: 2
      data_type: uint
      scale: 0.01
      precision: 1
    - name: SMA Spanning L3
      unit_of_measurement: V
      slave: 3
      register: 30787
      count: 2
      data_type: uint
      scale: 0.01
      precision: 1
    - name: SMA Netfrequentie
      unit_of_measurement: Hz
      slave: 3
      register: 30803
      count: 2
      data_type: uint
      scale: 0.01
      precision: 2
    - name: SMA power
      unit_of_measurement: k
      slave: 3
      register: 30775
      count: 2
      data_type: int
      scale: 0.001
      precision: 2
    - name: SMA Total
      unit_of_measurement: kW
      slave: 3
      register: 30529
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA Today
      unit_of_measurement: kWh
      slave: 3
      register: 30535
      count: 2
      data_type: uint
      scale: 0.001
      precision: 2
    - name: SMA device type 9347 = 8.0
      slave: 3
      register: 30053
      count: 2
      data_type: int 
    - name: SMA grid relay 51=Closed 311= Open
      slave: 3
      register: 30217
      count: 2
      data_type: int

And would colde like the code in the bottom of this message be a good catch to go to ‘0’ in stead of high values?

  - platform: SMA
    sensors:
      sma_power_power:
        value_template: “{% if states(‘sensor.sma_power_l1’)|float < 0 %}0{% else %}{{ states(‘sensor.sma_power_l1’) | float / 100 | round(2)}}{% endif %}”
        friendly_name: ‘Power’
        unit_of_measurement: ‘W’
        icon_template: mdi:flash-circle

Hi MBolt,

I solved this by using an additional template sensor using the modbus sensor as input like this:

      power_sma_filtered:
        friendly_name: "Erzeugung aktuell"
        unit_of_measurement: W
        value_template: >-
          {% if (states('sensor.power_sma')|int >= 10000 or states('sensor.power_smal')|int < 0) %}
            0
          {% else %}
            {{(states('sensor.power_sma')|int)}}
          {% endif %}  

1 Like

I use this in config

# SMA over modbus
modbus:
  type: tcp
  host: 192.168.178.171
  port: 502

and this in sensors

- platform: modbus
  scan_interval: 30
  registers:
    - name: Gesamtertrag
      hub: sma
      unit_of_measurement: kWh   # see register description in section 5.4.1 of the document
      slave: 3                   # use the UnitID you found in Sunny Explorer
      register: 30531            # use a register from section 5.4.1 of the document
      register_type: input       # all registers starting with 3 need to have the type input
      count: 2                   # use the correct count for the register see section 5.4.1 of the document

and get this error in my log

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 179, in _async_setup_platform
    await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 442, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/modbus/sensor.py", line 129, in setup_platform
    hub = hass.data[MODBUS_DOMAIN][hub_name]
KeyError: 'sma'

I can login to the webinterface just fine. I came here bc the standard SMA integration was not working, but am having issues with this as well. Anyone care to shed some light on this?