MODBUS data from SMA Inverter

Hi all, I’m trying to configure my SMA Sunny Boy solar and Sunny Island Battery inverters into HassIO. But having trouble understanding the MODBUS Master-Slave concept. There are some settings which I just can’t understand. Hence I’m not really sure if I have the settings right. Am I doing something wrong? Any troubleshooting tips?

I followed the documentation here:

I know the inverters are listening and functioning as there’s another separate monitoring service using the MODBUS interface. but here are some errors I’m getting:

  • No response from hub SB5000, slave 1, register 40037
  • No response from hub SI6, slave 1, register 40037

Here’s the configuration settings:
Set up the modbus connections:

modbus:
  - type: tcp
    host: 192.168.1.18
    port: 502
    name: SI6

  - type: tcp
    host: 192.168.1.19
    port: 502
    name: SB5000

Setup the sensors using the connections just to return the inverter model number as a test value:

sensor:
  - platform: modbus
    scan_interval: 10
    registers:
    - name: SI6ModelID
      hub: SI6
      slave: 1
      register: 40037
      count: 1
      
  - platform: modbus
    scan_interval: 10
    registers:
    - name: SB5ModelID
      hub: SB5000
      slave: 1
      register: 40037
      count: 1

thanks.

1 Like

bump anyone?

@Cheesenwine try reworking your modbus hub config.

This format works with my four hubs…worth a try?
One other thing is to possibly stop whatever else is reading your modbus devices.
I find modbus does not seem to like multiple devices reading/writing to it simultaneously.

I moved from a Scada product to Home Assistant for PLC monitoring and control. I also had PLC programming software running and at various times all three running. That was during the development period and I would find a great many errors would develop on All platforms.

modbus:
  - name: SI6  
    type: tcp
    host: 192.168.1.18
    port: 502
    

  - name: SB5000
    type: tcp
    host: 192.168.1.19
    port: 502
    
    

Regards Steve Wells

Thanks mate. But no joy. Same issue remains.

1 Like

@Cheesenwine
Hmmm…is the other device reading/writing as expected?

I ask because in my installation where there are Master/slave relationships my initial setup involved giving each device a unique IP ADDRESS and a unique SLAVE ADDRESS. I note both your devices are slave 1?

My devices may differ in their network requirements to yours however?

Hi guys. Just thought I would put my 2 cents in as I am pretty familiar with Modbus as it’s part of my job. You should not need a unique slave address
for each device when using modbus TCP. Are you sure that the slave ID is 1? I have connected to an SMA inverter in the past over modbus TCP and the slave address was not 1. For most devices the slave address is usually 1 but I know with the SMA inverters depending on which registers you are trying to read the slave address could be different ( I believe they do this for engineers to get access to extra registers by using a certain slave address). Can you post a link to the manual for your inverter? Happy to take a look at it and see if there is anything interesting in there.

Also here is an easy piece of software to use to try for testing comms with Modbus devices.
Set it as a master and try and read one or two registers to prove your settings are correct.

https://oceancontrols.com.au/OCS-011.html

Free version limited to 15 mins per session which is heaps of time.

2 Likes

Thanks for the note. I did happen to try slave 2, 3, 4 and none (as it’s optional) to no avail. I have different monitoring product running on it which proves the modbus service is running and accessible through the network, but when I try to use the ModbusView tool I get “Poll 5 EC11 Target Device Failed to Respond”. But then again, I’m likely choosing the wrong configuration. There are so many words on that screen that mean nothing to me :stuck_out_tongue:

Here’s a link to the SMA modbus specifications:

This is my battery inverter (SI6.0) registers (definitely functioning):

Any my solar inverter (SB5.0) (potentially not communicating):

1 Like

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.