Shelly 3EM 3-phase Net Metering templates for Import, export and consumption

Hi,

Please see my templates below to calculate Net Metering correctly for the Shelly 3EM with 3-phase and solar(single or 3-phase), as used in Australia and many other countries.

This uses the shelly instantaneous power sensors to achieve the best possible accuracy, as the counters are updated approx. every second.
The energy import and export daily sensors can then be used in the HA new Energy Dashboard.

Setup your Shelly 3EM using the core integration.
Tested and working on HA 2022.2.3 Shelly FW 20211109-131251/v1.11.7-g682a0db
Copy and paste the templates into your configuration.yaml, restart homeassistant
Configure the energy dashboard as per the photo in post 9 Energy dashboard config

Let me know if this helps you out!
If you find this useful please Buy Me A Beer, thanks!

# Shelly 3EM templates for 3-phase Net Import, Export and Consumption(if you have solar generation details)
# This uses the shelly instantaneous power sensors to achieve the best possible accuracy. 
# Shelly Sensors are  sensor.l1_power, sensor.l2_power, sensor.l3_power for the three phases
# Solar generation in W is used to calculate consumption via sensor.power_solargen
# V1.0 Initial release by Uksa007
# V1.1 add float(0) to Consumption template to stop log warnings.
# V1.2 add Friendly names to Utility Meter sensors
# V1.3 remove negative spikes from power consumption due to different update timing of solar sensor
# V1.4 change round: 2 for small value users.

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.l1_power')|float + states('sensor.l2_power')|float + states('sensor.l3_power')|float) > 0 %}
            {{ states('sensor.l1_power')|float + states('sensor.l2_power')|float + states('sensor.l3_power')|float }}
          {% else %}
            {{ 0 }}
          {% endif %}
        availability_template: "{{
            [ states('sensor.l1_power'),
              states('sensor.l2_power'),
              states('sensor.l3_power')
            ] | map('is_number') | min
          }}"

      # Template sensor for values of power export (active_power < 0)
      power_export:
        friendly_name: "Power Export"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.l1_power')|float + states('sensor.l2_power')|float + states('sensor.l3_power')|float) < 0 %}
            {{ (states('sensor.l1_power')|float + states('sensor.l2_power')|float + states('sensor.l3_power')|float) * -1 }}
          {% else %}
            {{ 0 }}
          {% endif %}
        availability_template: "{{
            [ states('sensor.l1_power'),
              states('sensor.l2_power'),
              states('sensor.l3_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.power_solargen')|float(0) - states('sensor.power_export')|float(0)) < 0 %}
          {% elif (states('sensor.power_export')|float(0)) > 0 and (states('sensor.power_solargen')|float(0) - states('sensor.power_export')|float(0)) > 0 %}
            {{ (states('sensor.power_solargen')|float(0)) - states('sensor.power_export')|float(0) }}    
          {% else %}
            {{ states('sensor.power_import')|float(0) + states('sensor.power_solargen')|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

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
23 Likes

Nice work!

I use a NodeRed-flow with MQTT-Injection with 1minute Wh-Values. But your code might more exact and doesnā€™t need those extra integrations!

I might try it out, thanks for your input!

Great work, this is an ongoing issue, so Iā€™ll implement your templates.

I have resisted the Riemann sum integration of instant power (W) to calculate energy (Wh), as the shelly also measures energy directly (Wh) without calculation, but as you say it doesnā€™t handle the net metering correctly.

So I wonder which will be more ā€˜accurateā€™ and reflect the actual electricity provider measurement using their meter?

I have compared with my Electricity provider smart meter data daily totals for usage and solar feedin, using the templates energy_import_daily and energy_export_daily.

Itā€™s better than I expected, itā€™s about 1% different so thatā€™s pretty good!, given there would also be Shelly measurement accuracy in play.

For your consideration I do the same with the min/ max function instead of the if statement, and the same for export using min/ abs.

      # Template sensor for values of power import (active_power > 0)
      power_import:
        friendly_name: "Power Import"
        unit_of_measurement: 'W'
        value_template: >-
           {{ max(0,states('sensor.shelly_channel_a_power')|float + states('sensor.shelly_channel_b_power')|float + states('sensor.shelly_channel_c_power')|float )}}

        availability_template: "{{
            [ states('sensor.shelly_channel_a_power'),
              states('sensor.shelly_channel_b_power'),
              states('sensor.shelly_channel_c_power')
            ] | map('is_number') | min
          }}"

      # Template sensor for values of power export (active_power < 0)
      power_export:
        friendly_name: "Power Export"
        unit_of_measurement: 'W'
        value_template: >-
           {{ min(0,states('sensor.shelly_channel_a_power')|float + states('sensor.shelly_channel_b_power')|float + states('sensor.shelly_channel_c_power')|float)|abs}}
        availability_template: "{{
            [ states('sensor.shelly_channel_a_power'),
              states('sensor.shelly_channel_b_power'),
              states('sensor.shelly_channel_c_power')
            ] | map('is_number') | min
          }}"
3 Likes

Hi,

My brain just works better with if statements and it can add flexibility if you need further conditions eg elif.

Is there any advantage of max and min over if?

Thanks.

I presume it is faster as it doesnā€™t have to lookup the same sensors multiple times. Also reduces errors when entering yaml as it is simpler/ shorter as you donā€™t need to duplicate sensors entries.

But as with most things there are many ways to achieve the same outcome.

1 Like

@Uksa007

Can you please share a screenshot of your the dashboard and sensor used?

Use Energy Import Daily for Grid Consumption and Energy Export Daily for Returned to grid.
You need to supply your own daily solar generation data from your inverter for Solar Production.

3 Likes

I also find Solcast works well to estimate solar production in Australia.

135556872-ff5b51ac-699e-4ea5-869c-f9b0d0c5b815

1 Like

Thanks, this was the missing info for me.

Hello everyone,

iā€™m having trouble with getting the integrations up and running.
I copied the above sensor: section into my sensors.yaml (which is referenced in configuration.yaml) and the utility_meter: section directly into my configuration.yaml. I also changed the shelly 3em entities according to my config, of course.

Now while iā€™m seeing all the new entities successfully created, the energy_*_sum integrations are not updated - even though the ā€œPower *ā€ templates are showing the correct values.

Is there something i did wrong/miss?

If they are showing up they should be updating, it can take an hour or so for them to start populating.

you were right (at least in part?)

As you can see in the screenshots, the import sensors work good (consumption doest too).
But the export ones is not moving.

Or am i still impatient and just have to wait longer? :slight_smile:
(Iā€™m new to this)

Ok, so i waited for almost two days now :slight_smile:
It managed do update exactly 3 times

What can cause such delays? Anyone has a suggestion?

your production power is low and there is a rounding setting round: 1 to 1 digit ( == 0.1 kWh) you see steps when 0.1kWh was produced.

If you change to round: 2 you will see more updates.

My god - I feel so stupid now, that was it.
THANK YOU!

no worries, I also had to learn it the hard way :wink:

@uksa007 Thanks for your work!

IĀ“ve implented this but i have 2 Solar Sensors. It seems that is will not work? could you please check my code? (iĀ“m not good with codingā€¦) :frowning:

    # 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.shelly1pm_8caab574ce25_power')|float(0) + states('sensor.shellysolarhaus_power')|float(0) - states('sensor.power_export')|float(0)) < 0 %}
          {% elif (states('sensor.power_export')|float(0)) > 0 and (states('sensor.shelly1pm_8caab574ce25_power')|float(0) + states('sensor.shellysolarhaus_power')|float(0) - states('sensor.power_export')|float(0)) > 0 %}
            {{ (states('sensor.shelly1pm_8caab574ce25_power'))|float(0) + states('sensor.shellysolarhaus_power')|float(0) - states('sensor.power_export')|float(0) }}    
          {% else %}
            {{ states('sensor.power_import')|float(0) + states('sensor.shelly1pm_8caab574ce25_power')|float(0) + states('sensor.shellysolarhaus_power')|float(0) }}
          {% endif %}

Thanks for your help!

Looks ok, does it work as expected?
I also have two solar inverters and I have a template that adds the two together so I can see my total solar generation.

      # Template sensor for values of energy Solar generation (solar_power > 0)
      power_solargen:
        friendly_name: "Power Solar Generation"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.pv_power')|float(0) + states('sensor.pv_power_2')|float(0)) > 0 %}
            {{ (states('sensor.pv_power')|float(0) + states('sensor.pv_power_2')|float(0)) }}
          {% else %}
            {{ 0 }}
          {% endif %}
1 Like