Solar Power, Shelly and Homeassistant

1. The Story

A while ago, a friend installed a small solar system on his roof, because he had a north balcony only (like me). I became interested and installed one as well. In doing so, I became interested in the Return-on-invest, in other words I wanted to measure the real net energy savings. Sounds legitimate. I fully underestimated the efforts and complexity, but finally I mastered it. Below is how.

 

Preliminary remarks

Solar panels are currently being hawked at discount retailers with the promise of significant cost savings. Can this really be true? No, because:

  1. Most solar energy is generated when it is least needed – at noon in summer. When this solar energy is returned to the grid it can help to throttle conventional power plants thereby helping to protect the environment.
    The downside: grid operation gets more complex.
  2. Simple (balcony) systems only feed power into one phase, so only the consumers in the house that are connected to that phase benefit from solar power at all.

Therefore, it is advised to first determine which phase of the household consumes the most electricity (over the midday period) and then ask your Electrician to feed your solar power in that phase.

 

2. The solution

The below picture shows my setup and the components used. After a lot of reading and talking to experts, I decided to use meters from Shelly to measure solar power generation and overall house grid consumption (or return, if there is any solar power surplus) and Home assistant as integration platform running on a Raspberry PI4.

 

My setup

Step-by-Step instruction

  1. Getting a Shelly-device up and running on the WiFi can be tricky sometimes. Here is a >>> guide from Shelly.
  2. Installing a 3EM meter to measure the overall energy consumption/return requires quite some Electrician knowledge. If you need to involve an Electrician, it might be helpful to send him the 3EM installation manual, which can be found on the Shelly support forum (after registration) >>> here
    A nice DIY instruction can be found on >>> iamklaus.org
  3. Using the Shelly-App to see your solar power generation and energy consumption/return is now possible, but if you want to see the net effect of your solar installation, there is more to do:
  4. You need to run Homeassitant on a suitable device (I recommend a Raspberry PI4). Installation is easy. Follow this >>> guide .
  5. Once you have included your meters in Homeassistant, you need to follow another instruction from >>> iamklaus.org.

While I did this setup-procedure a couple of times, until I was satisfied and understood everything, it turned out to best name the Shelly devices neither according to their type or room but purpose. Once you do, the YAML script, that allows you to see your real energy flow nicely reads like shown below.

I did name the Shelly Plug S, that meters the solar generation ‘solar’ and the 3EM that meters overall consumption/return ‘grid’.

Resulting YAML script with some comments

				
					# 2023-06-15: Sensor entity IDs according to purpose rather than to type or room

sensor:
  - platform: template
    sensors:

      # Template sensor for values of power import (active_power > 0)
      power_import:
        friendly_name: "Power Import"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.grid_channel_a_power')|float + states('sensor.grid_channel_b_power')|float + states('sensor.grid_channel_c_power')|float) > 0 %}
            {{ states('sensor.grid_channel_a_power')|float + states('sensor.grid_channel_b_power')|float + states('sensor.grid_channel_c_power')|float }}
          {% else %}
            {{ 0 }}
          {% endif %}
        availability_template: "{{
            [ states('sensor.grid_channel_a_power'),
              states('sensor.grid_channel_b_power'),
              states('sensor.grid_channel_c_power')
            ] | map('is_number') | min
          }}"

      # Template sensor for values of power export (active_power < 0)
      # if there is no physical return to grid yet, artificially create a random return to have the Rieman sum work, otherwithe return 0
      # {{ 0 }}
      power_export:
        friendly_name: "Power Export"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.grid_channel_a_power')|float + states('sensor.grid_channel_b_power')|float + states('sensor.grid_channel_c_power')|float) < 0 %}
            {{ (states('sensor.grid_channel_a_power')|float + states('sensor.grid_channel_b_power')|float + states('sensor.grid_channel_c_power')|float) * -1 }}
          {% else %}
              {{ range(1, 99) | random }} 
      
          {% endif %}
        availability_template: "{{
            [ states('sensor.grid_channel_a_power'),
              states('sensor.grid_channel_b_power'),
              states('sensor.grid_channel_c_power')
            ] | map('is_number') | min
          }}"


      # Template sensor for values of power consumption
      power_consumption:
        friendly_name: "Power Consumption"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.power_export')|float(0)) > 0 and (states('sensor.solar_power')|float(0) - states('sensor.power_export')|float(0)) < 0 %}
          {% elif (states('sensor.power_export')|float(0)) > 0 and (states('sensor.solar_power')|float(0) - states('sensor.power_export')|float(0)) > 0 %}
            {{ (states('sensor.solar_power')|float(0)) - states('sensor.power_export')|float(0) }}    
          {% else %}
            {{ states('sensor.power_import')|float(0) + states('sensor.solar_power')|float(0) }}
          {% endif %}


  # Sensor for Riemann sum of energy import (W -> Wh)
  - platform: integration
    source: sensor.power_import
    name: energy_import_sum
    unit_prefix: k
    round: 2
    method: left

  # Sensor for Riemann sum of energy export (W -> Wh)
  - platform: integration
    source: sensor.power_export
    name: energy_export_sum
    unit_prefix: k
    round: 2
    method: left

  # Sensor for Riemann sum of energy consumption (W -> Wh)
  - platform: integration
    source: sensor.power_consumption
    name: energy_consumption_sum
    unit_prefix: k
    round: 2
    method: left
    
 # Meter
utility_meter:
  energy_import_daily:
    source: sensor.energy_import_sum
    name: Energy Import Daily
    cycle: daily
  energy_import_monthly:
    source: sensor.energy_import_sum
    name: Energy Import Monthly
    cycle: monthly
    
  energy_export_daily:
    source: sensor.energy_export_sum
    name: Energy Export Daily
    cycle: daily
  energy_export_monthly:
    source: sensor.energy_export_sum
    name: Energy Export Monthly
    cycle: monthly
    
  energy_consumption_daily:
    source: sensor.energy_consumption_sum
    name: Energy Consumption Daily
    cycle: daily
  energy_consumption_monthly:
    source: sensor.energy_consumption_sum
    name: Energy Consumption Monthly
    cycle: monthly
    
    
        
    # this automation is only required, if you want to create a random grid return
automation:
  - alias: "Update Random Number Sensor"
    trigger:
      platform: time_pattern
      minutes: "/1"
    action:
      service: homeassistant.update_entity
      entity_id: sensor.power_export
      
				
			
Cookie Consent with Real Cookie Banner