SolarEdge Modbus full setup guide with Energy Dashboard integration

I shared my project a while ago where I setup the modbus integration for SolarEdge inverters combined with a battery here:

I did find it not working correctly all of the time and after @parkkralle messaged me with some questions and his idea of using a different integration, I decided to also follow that route. We worked together on it a bit and I think we now have a full working integration which shows everything correctly.

One of the things which bugged me is that the charging of the battery does not count for production, but discharging does. This means that I would not get the actual solar produced energy on a daily basis, but the battery is factored in here, which also causes the energy dashboard to show incorrect values. After a bit of work I think now everything is covered properly with following integration and configration.

We used the integration from here:

Note: this is a fork from the integration via HACS because this also supports the battery system.

We also setup the Tesla Style Power card from here:

This is the result:
image

Following configuration, sensors and templates:

configuration.yaml:

utility_meter:
  solar_production_daily:
    source: sensor.solar_production_kwh
    name: Solar Production Daily
    cycle: daily 
  solar_production_yearly:
    source: sensor.solar_production_kwh
    name: Solar Production Yearly
    cycle: yearly 
    
  solar_imported_power_daily:
    source: sensor.solaredge_m1_imported_kwh
    name: Solar Imported Power Daily
    cycle: daily 

  solar_exported_power_daily:
    source: sensor.solaredge_m1_exported_kwh
    name: Solar Exported Power Daily
    cycle: daily    

  solar_battery_power_in_yearly:
    source: sensor.battery_power_in_kwh
    name: Battery Power In kWh Yearly
    cycle: yearly 
  solar_battery_power_out_yearly:
    source: sensor.battery_power_out_kwh
    name: Battery Power Out kWh Yearly
    cycle: yearly   

templates.yaml

- sensor:
  - name: Solar Production W
    unique_id: solar_production_w
    state_class: measurement
    device_class: energy
    unit_of_measurement: 'W'
    state: >
      {% if ((states('sensor.solaredge_i1_ac_power') | float) + (states('sensor.solaredge_storage_ac_power') | float) <= 0) %}
        0
      {% else %}
        {{((states('sensor.solaredge_i1_ac_power') | float + states('sensor.solaredge_storage_ac_power') | float) )}}
      {% endif %}

  - name: Solar Production To House W
    unique_id: solar_production_to_house_w
    state_class: measurement
    device_class: energy
    unit_of_measurement: 'W'
    state: "{{((states('sensor.solar_production_w') | float) - (states('sensor.solar_exported_power_w') | float) - (states('sensor.solar_charge_power_w') | float))}}"

  - name: Solar Imported Power W
    unique_id: solar_imported_power_w
    state_class: measurement
    device_class: energy
    unit_of_measurement: 'W'
    state: >
      {% if ((states('sensor.solaredge_m1_ac_power') | float) <= 0) %}
        {{(states('sensor.solaredge_m1_ac_power') | float*-1)}}
      {% else %}
        0
      {% endif %}

  - name: Solar Exported Power W
    unique_id: solar_exported_power_w
    state_class: measurement
    device_class: energy
    unit_of_measurement: 'W'
    state: >
      {% if ((states('sensor.solaredge_m1_ac_power') | float) > 0) %}
        {{(states('sensor.solaredge_m1_ac_power') | float)}}
      {% else %}
        0
      {% endif %}

  - name: Solar Charge Power W
    unique_id: solar_charge_power_w
    state_class: measurement
    device_class: energy
    unit_of_measurement: 'W'
    state: >
      {% if ((states('sensor.solaredge_storage_ac_power') | float) > 0) %}
        {{(states('sensor.solaredge_storage_ac_power') | float)}}
      {% else %}
        0
      {% endif %}

  - name: Solar Discharge Power W
    unique_id: solar_discharge_power_w
    state_class: measurement
    device_class: energy
    unit_of_measurement: 'W'
    state: >
      {% if ((states('sensor.solaredge_storage_ac_power') | float) < 0) %}
        {{(states('sensor.solaredge_storage_ac_power') | float*-1)}}
      {% else %}
        0
      {% endif %}

  - name: Solar Lifetime Production
    unique_id: solar_production_lifetime_mwh
    state_class: measurement
    device_class: energy  
    icon: mdi:solar-power
    unit_of_measurement: 'MWh'
    state: "{{ ((states('sensor.solaredge_i1_ac_energy_kwh') | float) / 1000) | round (2) }}"

sensors.yaml:

  - platform: integration
    source: sensor.solar_charge_power_w
    method: left
    unit_prefix: k
    name: battery_power_in_kwh
  - platform: integration
    source: sensor.solar_discharge_power_w
    method: left
    unit_prefix: k
    name: battery_power_out_kwh  
  - platform: integration
    source: sensor.solar_production_w
    method: left
    unit_prefix: k
    name: solar_production_kwh  

Configuration for the Tesla Style Card:

type: custom:tesla-style-solar-power-card
name: Home Energy Flow
grid_to_house_entity: sensor.solar_imported_power_w
generation_to_grid_entity: sensor.solar_exported_power_w
generation_to_battery_entity: sensor.solar_charge_power_w
generation_to_house_entity: sensor.solar_production_to_house_w
battery_to_house_entity: sensor.solar_discharge_power_w
battery_extra_entity: sensor.solaredge_storage_state_of_charge

Configuration of the Energy Dashboard:

I hope some others can use this information.

4 Likes

I have been having one issuue with this setup: the modbus integration cannot connect about once a day, causing the sensor to have a value of “0” for a moment. The problem with that is that the energy dashboard picks that up, meaning my “M1 Imported KWH” and “M1 Exported KWH” change the value to 0 and then back to 1 couple of thousand kWh.
The energy dashboard picks that up as if I have exported/imported the total amount of power, which of course is not correct.
I got around that issue with defining 2 more template sensors which I now use in the Energy Dashboard:

template.yaml:

  - name: Solar Exported Power Total kWh
    unique_id: solar_exported_power_total_kwh
    state_class: total_increasing
    device_class: energy
    unit_of_measurement: 'kWh'
    state: >
      {% if ((states('sensor.solaredge_m1_exported_kwh') | float) < 100) %}
      {% else %}
        {{(states('sensor.solaredge_m1_exported_kwh') | float)}}
      {% endif %}

  - name: Solar Imported Power Total kWh
    unique_id: solar_imported_power_total_kwh
    state_class: total_increasing
    device_class: energy
    unit_of_measurement: 'kWh'
    state: >
      {% if ((states('sensor.solaredge_m1_imported_kwh') | float) < 100) %}
      {% else %}
        {{(states('sensor.solaredge_m1_imported_kwh') | float)}}
      {% endif %}      

With this it now seems to work ok.

1 Like

Hi
Trying to install the integration but it doesn’t get detected even by copying the folder into custom components.

Does it work with non set app inverters too ?
(Like the SE6000H)

I have almost the same setup as you and got both the energy dashboard as the Tesly style card working.
I think 1 thing is missing, you can also charge / discharge the battery to the grid, but I have no idea how to calculate this value. Because in that case, you have 2 variables: battery to grid and the house itself…
Any suggestions ?

I do not charge or discharge the battery to grid, because I have different rates: selling power gives me 0,09€/kWh and buying costs me 0,29€/kWh…

With the template framework it must be possible to calculate the required flows. It is a bit of a puzzle and figuring out in which state you get which value, but with similar things as I did in the template.yaml it must be possible…

I am trying to get this working - but cannot get the modbus integration working. Could anyone confirm if modbus tcp can work over Wifi? Or is it really only exposed on the ethernet port?

I use it over wifi and it works well.

Couple of test points.

Can you ping the IP address of your inverter? Checks network connectivity eth or wifi.

Can you telnet into port 1502 on your inverter?
Checks MODBUS interface is setup.

If both of those tests pass this integration should work for you.

We discussed this point last week here:

Perhaps, it can help you.

I promised I would update this post with my latest config. I did now use the Modbus integration available through HACS, with options “meter1 and battery1” selected. I did not get rid of my entire setup because of 2 reasons:

  • If I only use the modbus sensors, I do not see the Solar Production the way I would like to see it: by default Solaredge does not count charging of the battery as production at that moment. When you use the battery it actually adds to the production. I would like to see this differently; I want to see what my panels produced during the day and have a separate view of my battery usage. Therefore I had to use the templates.
  • The modbus every now and then cannot connect. This is no problem, it connects after that, but what does happen is that some of the sensors jump to 0 at that moment. This can give strange effects in the energy dashboard, so my config takes care of that too.

I also have some more UI elements like the Tesla Style power card (amd others, see first post), which I use to get almost instantaneous readings for which I also had to create some template sensors.

So, here we go:

configuration.yaml

utility_meter:
  solar_production_daily:
    source: sensor.solar_production_kwh
    name: Solar Production Daily
    cycle: daily 
  solar_battery_power_in_kwh_yearly:
    source: sensor.battery_power_in_kwh
    name: Battery Power In kWh Yearly
    cycle: yearly 
  solar_battery_power_out_kwh_yearly:
    source: sensor.battery_power_out_kwh
    name: Battery Power Out kWh Yearly
    cycle: yearly	
  solar_imported_power_daily:
    source: sensor.solaredge_m1_imported_kwh
    name: Solar Imported Power Daily
    cycle: daily 
  solar_exported_power_daily:
    source: sensor.solaredge_m1_exported_kwh
    name: Solar Exported Power Daily
    cycle: daily    

sensor.yaml

  - platform: integration
    source: sensor.solar_charge_power_w
    method: left
    unit_prefix: k
    name: battery_power_in_kwh
  - platform: integration
    source: sensor.solar_discharge_power_w
    method: left
    unit_prefix: k
    name: battery_power_out_kwh
  - platform: integration
    source: sensor.solar_production_w
    method: left
    unit_prefix: k
    name: solar_production_kwh  

template.yaml

sensor:
  - name: Solar Exported Power Total kWh
    unique_id: solar_exported_power_total_kwh
    state_class: total_increasing
    device_class: energy
    unit_of_measurement: 'kWh'
    state: >
      {% if ((states('sensor.solaredge_m1_exported_kwh') | float(0)) < 100) %}
      {% else %}
        {{(states('sensor.solaredge_m1_exported_kwh') | float(0))}}
      {% endif %}

  - name: Solar Imported Power Total kWh
    unique_id: solar_imported_power_total_kwh
    state_class: total_increasing
    device_class: energy
    unit_of_measurement: 'kWh'
    state: >
      {% if ((states('sensor.solaredge_m1_imported_kwh') | float(0)) < 100) %}
      {% else %}
        {{(states('sensor.solaredge_m1_imported_kwh') | float(0))}}
      {% endif %} 
	  
sensors:
  solar_selfconsumption_ratio:
    friendly_name: Solar Selfconsumption Ratio
    value_template: "{{(((((states('sensor.solar_house_consumption_daily') | float(0)) - (states('sensor.solar_imported_power_daily') | float(0))) / ((states('sensor.solar_production_daily') | float(0)) + (states('sensor.battery_power_out_kwh_daily') | float(0)))) * 100 ) )| round (0)}}"
  solar_autarkie_ratio:
    friendly_name: Solar Autarkie Ratio
    value_template: "{{((1 - (states('sensor.solar_imported_power_daily') | float(0) / states('sensor.solar_house_consumption_daily') | float(0))) * 100 ) | round (0)}}"        

  solar_production_w:
    friendly_name: Solar Production W
    device_class: power
    unit_of_measurement: 'W'
    value_template: >
      {% if ((states('sensor.solaredge_ac_power') | float(0)) + (states('sensor.solaredge_battery1_power') | float(0)) <= 0) %}
        0
      {% else %}
        {{((states('sensor.solaredge_ac_power') | float(0) + states('sensor.solaredge_battery1_power') | float(0)) )}}
      {% endif %}

  solar_production_to_house_w:
    friendly_name: Solar Production To House W
    device_class: power
    unit_of_measurement: 'W'
    value_template: "{{((states('sensor.solar_production_w') | float(0)) - (states('sensor.solar_exported_power_w') | float(0)) - (states('sensor.solar_charge_power_w') | float(0)))}}"  
      
  solar_house_consumption_w:
    friendly_name: Solar House Consumption W
    device_class: power
    unit_of_measurement: 'W'
    value_template: "{{(((states('sensor.solar_production_w') | float(0)) - (states('sensor.solar_exported_power_w') | float(0))) + (states('sensor.solar_discharge_power_w') | float(0)) - (states('sensor.solar_charge_power_w') | float(0)) + (states('sensor.solar_imported_power_w') | float(0)))}}"
      
  solar_imported_power_w:
    friendly_name: Solar Imported Power W
    device_class: power
    unit_of_measurement: 'W'
    value_template: >
      {% if ((states('sensor.solaredge_m1_ac_power') | float) <= 0) %}
        {{(states('sensor.solaredge_m1_ac_power') | float*-1)}}
      {% else %}
        0
      {% endif %}
      
  solar_exported_power_w:
    friendly_name: Solar Exported Power W
    device_class: power
    unit_of_measurement: 'W'
    value_template: >
      {% if ((states('sensor.solaredge_m1_ac_power') | float(0)) > 0) %}
        {{(states('sensor.solaredge_m1_ac_power') | float(0))}}
      {% else %}
        0
      {% endif %}

  solar_charge_power_w:
    friendly_name: Solar Charge Power W
    device_class: power
    unit_of_measurement: 'W'
    value_template: >
      {% if ((states('sensor.solaredge_battery1_power') | float(0)) > 0) %}
        {{(states('sensor.solaredge_battery1_power') | float(0))}}
      {% else %}
        0
      {% endif %}
      
  solar_discharge_power_w:
    friendly_name: Solar Discharge Power W
    device_class: power
    unit_of_measurement: 'W'
    value_template: >
      {% if ((states('sensor.solaredge_battery1_power') | float(0)) < 0) %}
        {{(states('sensor.solaredge_battery1_power') | float(0)*-1)}}
      {% else %}
        0
      {% endif %}
    
  solar_production_lifetime_mwh:
    friendly_name: Solar Lifetime Production
    device_class: energy  
    unit_of_measurement: 'MWh'
    icon_template: mdi:solar-power
    value_template: "{{ ((states('sensor.solaredge_ac_energy_kwh') | float(0)) / 1000) | round (2) }}"

Energy Dashboard config:

This now seems to work perfectly for me…

@Heimel: Maybe, this is what you are searching for?

Frist: Thank you @Remko!

I’m trying to adapt your latest config, but getting Errors and Warning. Am i doing something wrong? Had modified the configuration.yaml and added/importet the sensor.yaml and template.yaml… is there something missing? Do you have any Hints?

thx, sash

Logger: homeassistant.helpers.template
Source: helpers/template.py:1254
First occurred: 23:40:21 (4 occurrences)
Last logged: 23:40:21

Template warning: 'float' got invalid input 'unknown' when rendering template '{% if ((states('sensor.solaredge_m1_ac_power') | float) <= 0) %} {{(states('sensor.solaredge_m1_ac_power') | float*-1)}} {% else %} 0 {% endif %}' but no default was specified. Currently 'float' will return '0', however this template will fail to render in Home Assistant core 2022.1
Logger: homeassistant.components.template.template_entity
Source: components/template/template_entity.py:73
Integration: Template (documentation, issues)
First occurred: 23:40:21 (2 occurrences)
Last logged: 23:40:21

TemplateError('ZeroDivisionError: float division by zero') while processing template 'Template("{{(((((states('sensor.solar_house_consumption_daily') | float(0)) - (states('sensor.solar_imported_power_daily') | float(0))) / ((states('sensor.solar_production_daily') | float(0)) + (states('sensor.battery_power_out_kwh_daily') | float(0)))) * 100 ) )| round (0)}}")' for attribute '_attr_native_value' in entity 'sensor.solar_selfconsumption_ratio'
TemplateError('ZeroDivisionError: float division by zero') while processing template 'Template("{{((1 - (states('sensor.solar_imported_power_daily') | float(0) / states('sensor.solar_house_consumption_daily') | float(0))) * 100 ) | round (0)}}")' for attribute '_attr_native_value' in entity 'sensor.solar_autarkie_ratio'
Logger: homeassistant.components.utility_meter.sensor
Source: components/utility_meter/sensor.py:295
Integration: Utility Meter (documentation, issues)
First occurred: 23:40:11 (3 occurrences)
Last logged: 23:40:11

Could not restore state <unknown>. Resetting utility_meter.Solar Production Daily
Could not restore state <unknown>. Resetting utility_meter.Battery Power In kWh Yearly
Could not restore state <unknown>. Resetting utility_meter.Battery Power Out kWh Yearly
Logger: homeassistant.components.integration.sensor
Source: components/integration/sensor.py:132
Integration: integration (documentation, issues)
First occurred: 23:40:11 (3 occurrences)
Last logged: 23:40:11

Could not restore last state: [<class 'decimal.ConversionSyntax'>]
Logger: homeassistant.components.template.config
Source: components/template/config.py:89
Integration: Template (documentation, issues)
First occurred: 23:40:11 (1 occurrences)
Last logged: 23:40:11

The entity definition format under template: differs from the platform configuration format. See https://www.home-assistant.io/integrations/template#configuration-for-trigger-based-template-sensors

Sorry for the late reply. Could you please post the relevant contents of the configuration files? I guess there are some things missing…
Some of the warnings are ok, but the ones about the utility meters are not