MODBUS data from SMA Inverter

here the complete modbus and template






Is it working again for you? I still got some problems.

regards,
Chris

Which problems ?
Please define exactly. At everything works again.

Hi Bimbo009!

Looks great! :slight_smile: :+1:
Would it be possible that you share the modbus.yaml and template.yaml as code?
I’m about to integrate my SMA inverter and you have some good metrics.
That would save me a lot of manual retyping.

Thx and regards

Webrat

 sensors:
      - name: "PV_Status"
        unique_id: "PV_Status"
        state_class: "measurement"
        data_type: "int32"
        unit_of_measurement: "status"
        slave: 3
        address: 30201
        count: 2
      - name: "PV_Gesamtertrag"
        unique_id: "PV_Gesamtertrag"
        device_class: "energy"
        state_class: "total_increasing"
        data_type: "int32"
        unit_of_measurement: "kWh"
        slave: 3
        address: 30531
        count: 2
      - name: "PV_Leistung"
        unique_id: "PV_Leistung"
        state_class: measurement
        device_class: power
        data_type: "int32"
        unit_of_measurement: "W"
        slave: 3
        address: 30775
        count: 2
      - name: "PV_Tagesertrag"
        unique_id: "PV_Tagesertrag"
        state_class: "total_increasing"
        device_class: "energy"
        data_type: "int64"
        unit_of_measurement: "Wh"
        slave: 3
        address: 30517
        count: 4
      - name: "PV_Frequenz"
        unique_id: "PV_Frequenz"
        state_class: "measurement"
        device_class: "frequency"
        data_type: "uint32"
        unit_of_measurement: "Hz"
        slave: 3 
        address: 30803
        count: 2
        scale: 0.01
        precision: 2
      - name: "Power_L1"
        unique_id: "Powe_L1"
        state_class: "measurement"
        device_class: "power"
        unit_of_measurement: "W"
        slave: 3
        address: 30777
        count: 2
        data_type: "int32"
      - name: "Power_L2"
        unique_id: "Powe_L2"
        state_class: "measurement"
        device_class: "power"
        unit_of_measurement: "W"
        slave: 3
        address: 30779
        count: 2
        data_type: "int32"
      - name: "Power_L3"
        unique_id: "Powe_L3"
        state_class: "measurement"
        device_class: "power"
        unit_of_measurement: "W"
        slave: 3
        address: 30781
        count: 2
        data_type: "int32"
      - name: "AMP_L1"
        unique_id: "AMP_L1"
        state_class: "measurement"
        device_class: "current"
        unit_of_measurement: "A"
        slave: 3
        address: 30797
        count: 2
        scale: 0.001
        precision: 2
        data_type: "int32"
      - name: "AMP_L2"
        unique_id: "AMP_L2"
        state_class: "measurement"
        device_class: "current"
        unit_of_measurement: "A"
        slave: 3
        address: 30799
        count: 2
        data_type: "int32"
        scale: 0.001
        precision: 2
      - name: "AMP_L3"
        unique_id: "AMP_L3"
        state_class: "measurement"
        device_class: "current"
        unit_of_measurement: "A"
        slave: 3
        address: 30801
        count: 2
        data_type: "int32"
        scale: 0.001
        precision: 2
      - name: "Volt_L1"
        unique_id: "Volt_L1"
        state_class: "measurement"
        device_class: "voltage"
        unit_of_measurement: "V"
        slave: 3
        address: 30783
        count: 2
        data_type: "int32"
        scale: 0.01
        precision: 1
      - name: "Volt_L2"
        unique_id: "Volt_L2"
        device_class: "voltage"
        state_class: "measurement"
        unit_of_measurement: "V"
        slave: 3
        address: 30785
        count: 2
        data_type: "int32"
        scale: 0.01
        precision: 1
      - name: "Volt_L3"
        unique_id: "Volt_L3"
        device_class: "voltage"
        state_class: "measurement"
        unit_of_measurement: "V"
        slave: 3
        address: 30787
        count: 2
        data_type: "int32"
        scale: 0.01
        precision: 1
1 Like
  - sensor:
    - name: "PV_Leistung_template"
      unique_id: "PV_Leistung_template"
      device_class: "power"
      state_class: "measurement"
      unit_of_measurement: "W"
      state: >
        {% if states('sensor.PV_Leistung') is not none %}
        {% if states('sensor.PV_Leistung') | int < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.PV_Leistung') | int }}
        {% endif %}
        {% else %}
        {% endif %}
    - name: "pv_status_template"
      unique_id: "pv_status_template"
      state: >
        {% if is_state('sensor.PV_Status', '35') %} Fault
        {% elif is_state('sensor.PV_Status', '303') %} Off
        {% elif is_state('sensor.PV_Status', '455') %} Warning
        {% elif is_state('sensor.PV_Status', '307') %} OK
        {% else %} Unknown Code
        {% endif %}
    - name: "pv_frequenz_template"
      unique_id: "pv_frequenz_template"
      device_class: "frequency"
      state_class: "measurement"
      unit_of_measurement: "Hz"
      state: >
        {% if states('sensor.pv_frequenz') is not none %}
        {% if states('sensor.pv_frequenz') | float(default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.pv_frequenz') | float(default=0) }}
        {% endif %}
        {% endif %}
    - name: "Power_L1_template"
      unique_id: "Power_L1_template"
      device_class: "power"
      state_class: "measurement"
      unit_of_measurement: "W"
      state: > 
        {% if states('sensor.power_l1') is not none %}
        {% if states('sensor.power_l1') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.power_l1') | float(default=0.0) }}
        {% endif %}
        {% else %}
        {% endif %}
    - name: "Power_L2_template"
      unique_id: "Power_L2_template"
      device_class: "power"
      state_class: "measurement"
      unit_of_measurement: "W"
      state: >
        {% if states('sensor.power_l2') is not none %}
        {% if states('sensor.power_l2') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.power_l2') | float(default=0.0) }}
        {% endif %}
        {% else %}
        {% endif %}
    - name: "Power_L3_template"
      unique_id: "Power_L3_template"
      device_class: "power"
      state_class: "measurement"
      unit_of_measurement: "W"
      state: >
        {% if states('sensor.power_l3') is not none %}
        {% if states('sensor.power_l3') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.power_l3') | float(default=0.0) }}
        {% endif %}
        {% else %}
        {% endif %}
    - name: "Volt_L1_template"
      unique_id: "Volt_L1_template"
      device_class: "voltage"
      state_class: "measurement"
      unit_of_measurement: "V"
      state: >
        {% if states('sensor.volt_l1') is not none %}
        {% if states('sensor.volt_l1') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.volt_l1') | float(default=0.0) }}
        {% endif %}
        {% else %}
        {% endif %}
    - name: "Volt_L2_template"
      unique_id: "Volt_L2_template"
      device_class: "voltage"
      state_class: "measurement"
      unit_of_measurement: "V"
      state: >
        {% if states('sensor.volt_l2') is not none %}
        {% if states('sensor.volt_l2') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.volt_l2') | float(default=0.0) }}
        {% endif %}
        {% endif %}
    - name: "Volt_L3_template"
      unique_id: "Volt_L3_template"
      device_class: "voltage"
      state_class: "measurement"
      unit_of_measurement: "V"
      state: >
        {% if states('sensor.volt_l3') is not none %}
        {% if states('sensor.volt_l3') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.volt_l3') | float(default=0.0) }}
        {% endif %}
        {% endif %}
    - name: "AMP_L1_template"
      unique_id: "AMP_L1_template"
      device_class: "current"
      state_class: "measurement"
      unit_of_measurement: "A"
      state: >
        {% if states('sensor.amp_l1') is not none %}
        {% if states('sensor.amp_l1') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.amp_l1') | float(default=0.0) }}
        {% endif %}
        {% endif %}
    - name: "AMP_L2_template"
      unique_id: "AMP_L2_template"
      device_class: "current"
      state_class: "measurement"
      unit_of_measurement: "A"
      state: >
        {% if states('sensor.amp_l2') is not none %}
        {% if states('sensor.amp_l2') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.amp_l2') | float(default=0.0) }}
        {% endif %}
        {% endif %}
    - name: "AMP_L3_template"
      unique_id: "AMP_L3_template"
      device_class: "current"
      state_class: "measurement"
      unit_of_measurement: "A"
      state: >
        {% if states('sensor.amp_l3') is not none %}
        {% if states('sensor.amp_l3') | round(2,default=0) < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.amp_l3') | float(default=0.0) }}
        {% endif %}
        {% endif %}
    - name: "PV_Tagesertrag01_template"
      unique_id: "PV_Tagesertrag01_template"
      state: >
        {% if states('sensor.PV_Tagesertrag') is not none %}
        {% if states('sensor.PV_Tagesertrag') | int < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.PV_Tagesertrag') | int }}
        {% endif %}
        {% endif %}
      unit_of_measurement: "Wh"
      device_class: "energy"
      state_class: "total"
    - name: "PV_Leistung01_template"
      unique_id: "PV_Leistung01_template"
      state: >
        {% if states('sensor.PV_Leistung') is not none %}
        {% if states('sensor.PV_Leistung') | int < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.PV_Leistung') | int }}
        {% endif %}
        {% endif %}
      unit_of_measurement: "W"
      device_class: "power"
    - name: "Gesamtertrag_template"
      unique_id: "Gesamtertrag_template"
      unit_of_measurement: "kWh"
      state: >
        {% if states('sensor.PV_Gesamtertrag') is not none %}
        {% if states('sensor.PV_Gesamtertrag') | int < 0 %}
        {{ 0 }}
        {% else %}
        {{ states('sensor.PV_Gesamtertrag') | int }}
        {% endif %}
        {% endif %}
      device_class: "energy"
      state_class: "total"
1 Like

@ Bimbo009Stefan Boy

I was actually responding to @Crash123Crash123, because he has the same unit as I have (SMA Sunnyboy 3600TL-21 , but I tried it with your config now, tomorrow I will check the result.

@Crash123Crash123, Is yours fully working again? (and if so, can you post the config files :slight_smile: )

thanks !

1 Like

Yes, everything works as usual.
The config is already online, see above, except for the beginning with the IP and whatever else is included, but all sensors and template sensors that I use. I wrote the normal sensors so that I can use the conversion that has been available in ha since the last update so that I no longer need them with the Riemann helper and the correct symbols are also displayed immediately.

1 Like

Yes it is working fine. It is a little bit mixed and not fine tuned, but working :wink:

sensor.yaml:

 - platform: template
   sensors:
     modbus_sma_pv_power:
       friendly_name: 'SMA_Power Output'
       value_template: >-
           {% if states('sensor.sma_power_ac')|float < 0 or states('sensor.sma_power_ac')|float > 10000 %}
             0
           {% else %}
             {{ states('sensor.sma_power_ac') }}
           {% endif %}
       unit_of_measurement: "W"
       icon_template: mdi:flash-circle
     modbus_sma_pv_power_kw:
       friendly_name: 'SMA_Power Output kW'
       value_template: >-
           {% if states('sensor.sma_power_ac')|float < 0 or states('sensor.sma_power_ac')|float > 10000 %}
             0
           {% else %}
             {{ states('sensor.sma_power_ac')|float / 1000 }}
           {% endif %}
       unit_of_measurement: "kW"
       icon_template: mdi:flash-circle
     modbus_sma_pv_apparent_power:
       friendly_name: 'SMA_Apparent Power'
       value_template: >-
           {% if states('sensor.sma_apparent_power')|float < 0 or states('sensor.sma_apparent_power')|float > 10000 %}
             0
           {% else %}
             {{ states('sensor.sma_apparent_power') }}
           {% endif %}
       unit_of_measurement: "VA"
       icon_template: mdi:flash-circle
     modbus_sma_pv_reactive_power:
        
       friendly_name: 'SMA_Reactive Power'
       value_template: >-
           {% if states('sensor.sma_reactive_power')|float < 0 or states('sensor.sma_reactive_power')|float > 10000 %}
             0
           {% else %}
             {{ states('sensor.sma_reactive_power') }}
           {% endif %}
       unit_of_measurement: "VAr"
       icon_template: mdi:flash-circle
     modbus_sma_pv_residual:
        
       friendly_name: 'SMA_Residual Current'
       value_template: >-
           {% if states('sensor.sma_residual_current')|float < 0 or states('sensor.sma_residual_current')|float > 10000 %}
             0
           {% else %}
             {{ states('sensor.sma_residual_current') }}
           {% endif %}
       unit_of_measurement: "mA"
       icon_template: mdi:flash-circle
     modbus_sma_temperature:
        
       friendly_name: 'SMA_Inverter Temp'
       value_template: >-
           {% if states('sensor.sma_temp')|float < 0 or states('sensor.sma_temp')|float > 100 %}
             0
           {% else %}
             {{ states('sensor.sma_temp') }}
           {% endif %}
       unit_of_measurement: "°C"
     modbus_grid_frequency:
        
       friendly_name: 'SMA_Grid Frequency'
       value_template: >-
           {% if states('sensor.sma_grid_frequency')|float < 30 or states('sensor.sma_grid_frequency')|float > 100 %}
             Not Measured
           {% else %}
             {{ states('sensor.sma_grid_frequency') }}
           {% endif %}
       unit_of_measurement: "Hz"
     modbus_grid_voltage:
       
       friendly_name: 'SMA_Grid Voltage'
       value_template: >-
           {% if states('sensor.sma_grid_voltage')|float < 180 or states('sensor.sma_grid_voltage')|float > 300 %}
             Not Measured
           {% else %}
             {{ states('sensor.sma_grid_voltage') }}
           {% endif %}
       unit_of_measurement: "V"
     modbus_inverter_status:
       
       friendly_name: 'SMA_Inverter Status'
       value_template: >-
           {% if is_state('sensor.sma_status', '307' ) %}
             OK
           {% elif is_state('sensor.sma_status', '303' ) %}
             Off
           {% elif is_state('sensor.sma_status', '455' ) %}
             Warning
           {% elif is_state('sensor.sma_status', '35' ) %}
             Fault
           {% endif %}
     modbus_grid_contactor:
        
       friendly_name: 'SMA_Grid contactor'
       value_template: >-
           {% if is_state('sensor.sma_grid', '51' ) %}
             Closed
           {% else %}
             Open
           {% endif %} 

configuration.yaml

modbus:
  - name: SMA
    type: tcp
    host: 192.168.188.59
    port: 502
    sensors:
      - name: SMA_Power_AC
        state_class: measurement
        unit_of_measurement: W
        slave: 3
        address: 30775
        count: 2
        data_type: uint32
        scan_interval: 10
      - name: SMA1_PV_Daily_Yield
        unit_of_measurement: kWh
        state_class: measurement
        slave: 3
        address: 30517
        scan_interval: 60
        scale: 0.001
        precision: 3
        count: 4
        data_type: int64    
      - name: SMA1_PV_Total_Production
        unit_of_measurement: MWh
        state_class: measurement
        slave: 3
        address: 30513
        scan_interval: 3600
        scale: 0.000001
        precision: 3
        count: 4
        data_type: int64
      - name: SMA_Grid Voltage
        unit_of_measurement: V
        slave: 3 
        address: 30783
        scan_interval: 120
        count: 2
        scale: 0.01
        precision: 2
        data_type: int32
      - name: SMA_Grid frequency
        unit_of_measurement: Hz
        slave: 3 
        address: 30803
        scan_interval: 120
        count: 2
        scale: 0.01
        precision: 2
        data_type: uint32
      - name: SMA_temp
        unit_of_measurement: °C
        slave: 3
        address: 30953
        scan_interval: 60
        count: 2
        scale: 0.1
        precision: 1
        data_type: int32
      - name: SMA_status
        slave: 3
        address: 30201
        scan_interval: 10
        count: 2
        data_type: int32
      - name: SMA_grid
        slave: 3
        address: 30217
        scan_interval: 60
        count: 2
        data_type: uint32
      - name: SMA1_Insulation
        slave: 3
        address: 30225
        scan_interval: 120
        count: 2
1 Like

Then congratulations, it’s not that difficult if you follow the instructions.
However, if you use the right sensor right away, you don’t need to do so many conversions.

      - name: "PV_Gesamtertrag"
        unique_id: "PV_Gesamtertrag"
        device_class: "energy"
        state_class: "total_increasing"
        data_type: "int32"
        unit_of_measurement: "kWh"
        slave: 3
        address: 30531
        count: 2

Got yours and Crash123 config working, but went for the SunSpec intergration, because is was less work. (the modbus solutions still have errors in the log). thanks for sharing the configs

You can also try SBFSpot, works with Lan too.

I have been tweaking a lot to get this right for my SB4000. Just figured out there is also a min_value: 0 option to get rid of the negative numbers without needing the template.

modbus: 
  - type: tcp
    host: 192.168.2.7 # SMA SB4000-TL21
    port: 502
    name: "sma"
    close_comm_on_error: true
    delay: 5
    timeout: 5
    sensors:
      - name: PV_Total
        unique_id: fa400021001
        unit_of_measurement: kWh
        slave: 3
        address: 30531
        input_type: input
        count: 2
        data_type: int32
        min_value: 0
        device_class: energy
        state_class: total_increasing
      - name: PV_DC_Voltage_1
        unique_id: fa400021002
        unit_of_measurement: V
        slave: 3
        address: 30771
        input_type: input
        count: 2
        scale: 0.01
        precision: 2
        data_type: int32
        min_value: 0
        device_class: voltage
        state_class: measurement
      - name: PV_DC_Current_1
        unique_id: fa400021003
        unit_of_measurement: A
        slave: 3
        address: 30769
        input_type: input
        count: 2
        scale: 0.001
        precision: 3
        data_type: int32
        min_value: 0
        device_class: current
        state_class: measurement
      - name: PV_DC_Voltage_2
        unique_id: fa400021004
        unit_of_measurement: V
        slave: 3
        address: 30959
        input_type: input
        count: 2
        scale: 0.01
        precision: 2
        data_type: int32
        min_value: 0
        device_class: voltage
        state_class: measurement
      - name: PV_DC_Current_2
        unique_id: fa400021005
        unit_of_measurement: A
        slave: 3
        address: 30957
        input_type: input
        count: 2
        scale: 0.001
        precision: 3
        data_type: int32
        min_value: 0
        device_class: current
        state_class: measurement
      - name: PV_Actual
        unique_id: fa400021006
        unit_of_measurement: W
        slave: 3
        address: 30775
        input_type: input
        count: 2
        data_type: int32
        min_value: 0
        device_class: power
        state_class: measurement
      - name: PV_Today
        unique_id: fa400021007
        unit_of_measurement: Wh
        slave: 3
        address: 30517
        count: 4
        data_type: int64
        min_value: 0
        device_class: energy
        state_class: total_increasing

Hello,

I used the config @Bimbo009 provided, thank you.
I guess everything is working fine.
Now I wondered if I can get the current power consumption or power send to the grid values from the inverter as well.
I tried register 30865 and 30867 but I only recieve super high and wrong values.

I am using a Sunny Tripower 20000TL-30 and a Sunny Homemanager 2.0

The Sunny Home Manager 2.0 unfortunately doesn’t support modbus properly.

You can still get values (grid export, grid import) from it by decoding its multicast messages in Node-RED. More on this can be found here: Home Manager 2: "Direct Meter communication" (Version 2.4.14.R) - SMA - Anlagenüberwachung - Photovoltaikforum

My old SMA from 2013 did never work with modbus or any other integration then scrape, alas that did stop with the new multi scrape too, i would love to see it running again but I lack the skills, could anyone please?

My code used to be:

 Webscrapping for SMA Inverter values
- name: pv_einheit
  platform: scrape
  resource: "https://www.sunnyportal.com/Templates/PublicPage.aspx?page=my page"
  select: "#ctl00_ContentPlaceHolder1_PublicPagePlaceholder1_PageUserControl_ctl00_PublicPageLoadFixPage_energyYieldWidget_energyYieldUnit"

- name: pv_periode
  platform: scrape
  resource: "https://www.sunnyportal.com/Templates/PublicPage.aspx?page=my page"
  select: "#ctl00_ContentPlaceHolder1_PublicPagePlaceholder1_PageUserControl_ctl00_PublicPageLoadFixPage_energyYieldWidget_energyYieldPeriodTitle"

- name: pv_wert
  platform: scrape
  resource: "https://www.sunnyportal.com/Templates/PublicPage.aspx?page=my page"
  select: "#ctl00_ContentPlaceHolder1_PublicPagePlaceholder1_PageUserControl_ctl00_PublicPageLoadFixPage_energyYieldWidget_energyYieldValue"
  value_template: '{% if is_state("sensor.pv_einheit", "Wh") %}{{ value | float / 1000 }}{% else %}{{ value | float }}{% endif %}'
unit_of_measurement: 'kW/h'

With our dynamic energy contract and negative energy prices in recent sunny weekends I figured out how to shut down my sunnyboy. Similar automation with writing 4000 to the same register to turn it back on. :+1:

Power off:

Power on: (4000W)

2 Likes

Hi Roumen

Did you need to setup the modbus in your configuration.yaml to set the registers as an installer profile? In the modbus list this is write level installer.

If so, how did you do this?

thanks

Hi Mathieu,

I installed the panels and inverter myself so I do have installer code but I don’t think I did some special setup for Modbus (apart from enable it) my modus.yaml is a few posts above but nothing special there:

  • type: tcp
    host: 192.168.2.7 # SMA SB4000-TL21
    port: 502
    name: “sma”
    close_comm_on_error: true
    delay: 5
    timeout: 5
    sensors:
    • name: PV_Total
      unique_id: fa400021001
      unit_of_measurement: kWh
      slave: 3
      address: 30531
      input_type: input
      count: 2
      data_type: int32
      min_value: 0
      device_class: energy
      state_class: total_increasing
      etc.

Regards, Roger.

Can someone help me with the correct modbus commands to STOP and start the production of an SMA inverter? I’m doing this through the web interface now by setting the parameters to “stop” or when desired to start producing energy again set it back to “MPP”. I can’t find anyone doing this so there are no examples and I don’t really seem to understand the basics of Modbus.

I’ve tried this (but failed) in Home Assistant:

  - name: sma_solar
    type: tcp
    host: 192.168.1.176
    port: 502
    
    sensors:
      - name: sma_status
        data_type: int32
        unit_of_measurement: status
        slave: 3
        address: 30201
        count: 2
      - name: sma_production
        data_type: int32
        slave: 3
        address: 30227
        count: 2
        
    switches:
    - name: sma_start_stop_production
      address: 40009
      command_on: 295
      command_off: 381
      write_type: holding
      slave: 3
      scan_interval: 5

As I had no idea how to make it work I then moved on to Node Red and tried this command to STOP, (which also failed):

msg.payload = { 
    'value': 381,
    'unitid': 3,
    'fc': 16,
    'address': 40009,
    'quantity': 1 
} 
return msg