Quick TLDR on how to create multi-tariff energy meters

I get asked this a lot, so thought I’d create a quick HOWTO on how to create a multi-tariff energy measurement system, for the dashboard etc. YMMV.

How to do multi-tariff power monitoring on Home Assistant. Assumes that you have some existing sensor that provides power consumption (W), or energy consumption (Wh).

  1. if your input sensor is only power (W) you convert it to energy (Wh) using an “Integration - Riemann sum integral” Helper from http://homeassistant.local:8123/config/helpers
  • name = daily energy
  • input sensor = sensor.import (or wherever you get your consumption W)
  • integration method = left
  • others as defaults
  • use the new sensor that this creates (in Wh) for all the future steps
  1. Create Number helpers for each tariff/rate at http://homeassistant.local:8123/config/helpers and set them to real values

    • input_number.electricity_peak_rate
    • input_number.electricity_offpeak_rate
  2. create a template sensor that picks the right tariff (as a string) based on the logic that your location uses. Make sure it only outputs the tariffs you defined above.

    eg (I have two separate tariff - one for import, one for export)

    template:
    - sensor:
        # peak time is 3pm-9pm every day
        - name: "Electricity Tariff"
            unique_id: 230e307a-6150-4c2e-8571-7634dec8fcd9
            state: "{{ 'peak' if today_at('15:00') < now() < today_at('21:00') else 'offpeak' }}"
    
        # Time Of Use (TOU) – Local time Feed-In rates
        # Peak (4pm – 9pm)
        # Sholder (9pm – 10am) & (2pm-4pm)
        # Off-Peak (10am-2pm)
        - name: "Electricity Export Tariff"
            unique_id: 541d7af3-7518-42b4-ad78-7fba858c7770
            state: "{{ 'peak' if today_at('16:00') < now() < today_at('21:00') else ('offpeak' if today_at('10:00') < now() < today_at('14:00') else 'shoulder') }}"
    
  3. in order to create the multiple sensors that apply your tariffs, use utility meter helper

    • create a utility_meter at http://homeassistant.local:8123/config/helpers
    • call it something like “daily energy”
    • input sensor = your Wh sensor
    • meter reset cycle = daily
    • supported tariffs = add each of the tariffs you created in step 3 (as labels)
    • this will create a “base” sensor (which controls which tariff is currently in use), and one sensor for each tariff (which counts the amount of energy used on each tariff)
  4. now, you need a bit of automation to change the utility meter selection (from step 3) whenever the current tariff changes (from step 2)

    1. create an new/empty automation at http://homeassistant.local:8123/config/automation/dashboard
    2. the trigger is “When Electricity Tariff changes state or any attributes”
      1. type=state
      2. entity=the sensor you created in step 3
    3. the action is to set the current tariff into the (first) sensor created by the utility meter
      1. type = call service
      2. service = select: select
      3. target = (entity) the first sensor you created in step 5
      4. option = “{{ trigger.to_state.state if ‘to_state’ in trigger else ‘offpeak’ }}”

    you can also create this in YAML mode:

alias: Set Electricity Tariff
trigger:
  - platform: state
    entity_id: sensor.electricity_tariff
    not_to:
      - unavailable
      - unknown
action:
  - service: select.select_option
    target:
      entity_id: select.daily_energy
    data:
      option: "{{ trigger.to_state.state if 'to_state' in trigger else 'offpeak' }}"
mode: single

  1. Now you have two energy sensors, which accumulate during the day, depending on which tariff you are currently in. You can add them into your energy dashboard individually (so you can get accurate pricing, and different colours)

When you add the utility_meter (say peak) to the energy dashboard, you pick the usage sensor (A) and you also configure a pricing sensor (B). Make sure you align peak-usage with peak-price, offpeak-usage with offpeak-price, etc

Afterwards, your energy dashboard should look something like this.

And the graphs on the Energy Dashboard should show multiple shades of the blue (import) or purple (export) as configured

14 Likes

To debug your tariff selector, you can use the template editor. Change the now() to a local variable (nowish) then you can loop across the whole day and check the results. For example

{% for offset in range(24) %}
{% set nowish = today_at('00:05') + timedelta(hours=offset) -%}
{{ nowish }} "{{ 'peak' if today_at('16:00') < nowish < today_at('21:00')
else ('offpeak' if today_at('10:00') < nowish < today_at('14:00') else 'shoulder') }}"
{%- endfor %}

emits

2023-06-28 00:05:00+10:00 "shoulder"
2023-06-28 01:05:00+10:00 "shoulder"
2023-06-28 02:05:00+10:00 "shoulder"
2023-06-28 03:05:00+10:00 "shoulder"
2023-06-28 04:05:00+10:00 "shoulder"
2023-06-28 05:05:00+10:00 "shoulder"
2023-06-28 06:05:00+10:00 "shoulder"
2023-06-28 07:05:00+10:00 "shoulder"
2023-06-28 08:05:00+10:00 "shoulder"
2023-06-28 09:05:00+10:00 "shoulder"
2023-06-28 10:05:00+10:00 "offpeak"
2023-06-28 11:05:00+10:00 "offpeak"
2023-06-28 12:05:00+10:00 "offpeak"
2023-06-28 13:05:00+10:00 "offpeak"
2023-06-28 14:05:00+10:00 "shoulder"
2023-06-28 15:05:00+10:00 "shoulder"
2023-06-28 16:05:00+10:00 "peak"
2023-06-28 17:05:00+10:00 "peak"
2023-06-28 18:05:00+10:00 "peak"
2023-06-28 19:05:00+10:00 "peak"
2023-06-28 20:05:00+10:00 "peak"
2023-06-28 21:05:00+10:00 "shoulder"
2023-06-28 22:05:00+10:00 "shoulder"
2023-06-28 23:05:00+10:00 "shoulder"
2 Likes

Thanks for this. Im getting my head around it. My question is what would the code for the template look like for 2 lots of peak rates during the day? For example, my peak rates are 7am-9am and 5pm-8pm, my shoulder times (2 lots 9am-5pm, 8pm-10pm) and off peak time (10pm-7am) would be covered by the above example. Thanks in advance.
edit: also my energy is provided in kWh, how do I change this using the reimann sensor to Wh?

1 Like

Thanks for the tutorial. I noticed this did not quite work in 2023.10.3 where I added the automation through the UI.

The automation kept failing because trigger.to_state.state kept returning state: "offpeak" instead of just off-peak

I used the code below to strip out that extra text and now it worked perfectly.

service: select.select_option
target:
  entity_id: select.daily_energy
data:
  option: >-
    {{ trigger.to_state.state.strip('state: "').strip('"') if 'to_state' in
    trigger else 'offpeak' }}

I have been pullin my hair out to get this to work. I have a emporia vue 2 sensor on my main feed and its measured in watts. I have created a Integration - Riemann sum integral sensor to convert it to kWh. but i cant figure out how to get the tier to work properly. I have a 2 tier set up where the first 1350kwH are priced at $0.0975 and anything above is $0.1405. my utility company is set up on a bi-monthly billing cycle so i have added a cron to my utility yaml but i’m not sure i added it correctly.

cron: "0 0 6 2,4,6,8,10,12 * " so it resets on the 6th day of every even month

I am on a tarrif that changes it’s rates every 30 minutes (Agile Octopus in the UK). I use an HA integration that reports the current tarrif at any time.

I’d like to track the cost of charging my car. I’ve got the energy rate in kWh as a Reimann integration sensor.

I think I should be able to create a Utility Meter helper that has the Reimann integration as input, but giving the tariff sensor as the Supported Tariff is just returning the name of the tariff entity. I don’t understand how the tariff input works - it isn’t documented in enough detail. Any pointers?

Did you get anywhere with this?
I have the exact same question (Agile + EV charging)

I found the Dynamic Energy Cost integration. It is still a little rough round the edges but does a good job of calculating costs for EV charging.

1 Like

Thank you. I’ll give it a go

  1. Create Number helpers for each tariff/rate at http://homeassistant.local:8123/config/helpers and set them to real values
  • input_number.electricity_peak_rate
  • input_number.electricity_offpeak_rate

How do you create a single value number helper? In the menu, you specify a minimum and maximum value, and they can’t be the same.

in step 2 you write “create a template sensor …” - I am struggling to do this as i think the YAML code and files have changed since you wrote this - do you have an update? This is what I am looking for (for our tariffs), thanks, John

I was having trouble following the instructions kindly shown here, after a certain level of complexity with computers a monkey in my head starts banging a big cymbal and I lose track…
I eventually found the following YT vid which showed a similar process well:

and another one which helped me work out my situation which was peak, shoulder and offpeak during the week and offpeak all weekend.

Between the two I got it working quite easily.

It’s a little more straightforward, mostly UI based with a bit of cut and paste yaml which you just need to modify to suit your needs.

1 Like

I am looking into this now to try and create a comparison.
Essentially…I want to compare a fixed rate tariff (easy), my current Tibber price (already set up), Octopus Go (2 different prices a day) and Octopus Go + Variable grid cost (3 Prices a day in different windows). This is turning out to be rather difficult for me…

I managed to solve it (I hope) by first creating a Utility Meter with an hourly reset (reading from my Solar Inverter Power Meter), using that to calculate the current cost via a Template and then using that as the source for a Utility Meter with Monthly Reset.

Fingers crossed that it won’t go haywire again…:crossed_fingers: