Using Home Assistant to calculate my energy bill using data from my Solar Inverter

Absolutely. I’m sure there’s a tidier or more efficient way but I think this will work. I’ll watch the tariff history over the next week to confirm.

I updated the code block above as I realised I could use the template to avoid having multiple automations for tariffs with multiple windows.

This would be quite simple to include logic for months, I’m just not sure if having an automation trigger every 30 seconds should be avoided for any reason.

I would exclude the history of that automation in the recorder so it doesnt fill up the database

1 Like

Good thought - have done and also from logbook.

I came up with a much simpler tariff automation that doesn’t have an ‘at’ or ‘delay’ time trigger that I think is working well. It triggers on state change as well as on boot so should pick up any missed triggers for whatever reason.

Template sensor: (this could easily have seasonal/monthly logic written in to it)

- sensor:
    - name: Tariff Logic
      state: >
        {% if (22 <= now().hour or now().hour < 7 or now().isoweekday() > 5) %}
          offpeak
        {% elif 17 <= now().hour < 20 %}
          peak
        {% else%}
          shoulder
        {% endif %}

Automation:

alias: Switch tariffs
description: ''
trigger:
  - platform: state
    entity_id:
      - sensor.tariff_logic
  - platform: homeassistant
    event: start
action:
  - service: utility_meter.select_tariff
    data_template:
      tariff: '{{states(''sensor.tariff_logic'')}}'
    target:
      entity_id: utility_meter.daily_energy
mode: single
1 Like

Looking good.

Thanks but there is no need to manually enter holiday dates that you will have to update ad finitum. Use the Workday integration instead. i.e.

binary_sensor:
  # Whether it is a workday or not - binary_sensor.workday_sensor
  - platform: workday
    country: AU
    province: NSW

template:
  # Australian Ausgrid NSW Peak-shoulder-offpeak sensor defined
  # https://www.ausgrid.com.au/Your-energy-use/Meters/Time-of-use-pricing
  # Peak: 2pm - 8pm on working weekdays 1 November - 31 March;
  # Peak: 5pm - 9pm on working weekdays 1 June - 31 August
  # Off-peak: 10pm - 7am
  # Shoulder: all other times
  - sensor:
      name: TOU Period
      icon: mdi:clock-time-three-outline
      state: >
        {% set tou_period = 'shoulder' %}
        {% set n_month = now().month %}
        {% set n_hour = now().hour %}
        {% set is_summer = (n_month <= 3 or n_month >= 11) %}
        {% set is_winter = (6 <= n_month <= 8 ) %}
        {% if n_hour >= 22 or n_hour < 7 %}
          {% set tou_period = 'offpeak' %}
        {% elif ((is_summer and (14 <= n_hour <= 19))
           or (is_winter and (17 <= n_hour <= 20)))
           and (is_state("binary_sensor.workday_sensor", "on")) %}
          {% set tou_period = 'peak' %}
        {% endif %}
        {{tou_period}}

  - sensor:
      name: Electricity Cost
      icon: mdi:currency-usd
      unit_of_measurement: AUD/kWh
      state: >
        {% if is_state('sensor.tou_period', 'peak') %}
          {{ 0.3465 }}
        {% elif is_state('sensor.tou_period', 'offpeak') %}
          {{ 0.1397 }}
        {% else %}
          {{ 0.1727 }}
        {% endif %}
3 Likes

Thanks for sharing @Muppetteer, I did not know about this Workday integration.

FYI - just noticed this in my logs:

The 'utility_meter.select_tariff' service has been deprecated and will be removed in HA Core 2022.7. Please use 'select.select_option' instead

I haven’t updated anything at my end yet due to time but will likely affect us all unless you’ve already changed it.

1 Like

@del13r this is amazing!

Have you or anyone else applied this data to calculating the payback of your solar system?

I had mine installed in Feb, so I’m just now getting data to build out my payback model. Thinking this could be a cool next step on top of this to see when it will pay for itself. And then a counter for how much it’s earned after that time.

Thanks.
I haven’t thought that far ahead.
I got solar installed last year and a few months later I started using Home Assistant.
Due to this, I am comparing current bills with bills from before I got solar installed.
The problem with my historical bills are that they are quarterly which doesn’t allow me to get an accurate daily cost over a 90 day period as the months and seasons aren’t clear cut.

Yeah, it’s unnecessarily complicated.

I’ve got TOU rates as well, but I changed to that when I got solar. So I’m thinking of doing something like this if I can figure out how to set it up:

Total monthly calculated total cost for grid power already done by HA + monthly solar payment (I’m doing a loan, so this is static) = how much I have paid out in cash that month.

Then calculate the WHAT IF I had no solar. Total monthly consumption in kWh times the going rate per kWh regardless of Time of Use (since I wouldn’t be using it if I didn’t have solar).

The difference between these two numbers would represent whatever I’m contributing to my payback. Then I just have to figure out how to build out how to project that out for a payback date that changes each month. New to this part, so this is what you have inspired me to figure out!

Hello all

Very good topic!
I’m using Shelly EM and i`m not exporting energy, so in my case this should be simpler to implement!
My Shelly gives me negative values in the consumption when I’m not consuming all the solar production energy so I would like to know if del13r Envoy works the same way?

Thanks
Pedro Fonseca

I’m not sure how that works.
You cannot throttle the output of solar panels. If you are not exporting energy, then where does the excess solar production go?

If you are seeing negative values on your consumption, that would indicate the excess production is being detected via the Shelly EM and you can still use the 0,MAX logic to only record positive values.

Hi @apnafonseca

In your isolated case, I would try this.
I made up the sensor name as I don’t know anything about Shelly em

  - sensor:
        name: Grid Import Power
        state_class: measurement
        icon: mdi:transmission-tower
        unit_of_measurement: W
        device_class: power
        state: >
            {{ [0, states('sensor.shelly_em_current_power_consumption') | int ] | max }}

This code has 1 job, and that is to ignore negative values so that the integration sensor can count only positive values for the consumption energy odometer needed by energy dashboard.

I’m just going back to add in my monthly billing cycles to my own set up and noticed that you can use cron in the documentation here under Advanced Configuration:
if you replace cycle: with cron: "0 0 13 * *" then it should reset for you on the 13th of each month.

Edit cron: "0 0 13 */3 *" for quarterly on the 13th

1 Like

It would be complicated to do true payback in HA using utility meter. Not impossible, but complicated.
I have done it in excel using exported data from my enphase. It accounted for energy sold, self consumption and time of use of that consumption. It was (is) a beast of a spreadsheet and when enphase changed the format of their export data I didn’t go back and maintain it… I really should.

There would be a great opportunity (for someone cleverer than me) for a solar payback integration that is built specifically with this in mind, I think.

Sorry for triple post, have been working on my energy views
This is a great idea - I’ve taken this approach and applied it to my monthly billing. As you’ll see, I’ve done this in a similar way to you but laid it out in a way that I found easier to work with.

Have also after scratching my head for a while, worked out how to get the last billing period calculating too:

  - name: Monthly Energy Total Cost #calculating energy cost for this billing period.
    device_class: monetary
    state_class: measurement
    unit_of_measurement: AUD
    state: >
      {% set peak = states('sensor.monthly_energy_peak') | float %}
      {% set p_tariff = states('input_text.peak') | float %}
      {% set shoulder = states('sensor.monthly_energy_shoulder') | float %}
      {% set s_tariff = states('input_text.shoulder') | float %}
      {% set offpeak = states('sensor.monthly_energy_offpeak') | float %}
      {% set o_tariff = states('input_text.offpeak') | float %}
      {% set buyback = states('sensor.monthly_energy_export_buyback') | float %}
      {% set b_tariff = states('input_text.feedin') | float %}
      {% set daily = states('input_text.daily') | float %}
      {% set reset = state_attr('sensor.monthly_energy_offpeak','last_reset') |as_datetime %}
      {% set days_in = ((now() - reset)).days %}
      {{ (peak * p_tariff + shoulder * s_tariff + offpeak * o_tariff + buyback * b_tariff + daily * days_in) | round(2) }}

  - name: Last Month Energy Total Cost #calculating energy cost for previous billing period
    device_class: monetary
    unit_of_measurement: AUD
    state: >
      {% set peak_last = state_attr('sensor.monthly_energy_peak','last_period') | float %}
      {% set p_tariff = states('input_text.peak') | float %}
      {% set shoulder_last = state_attr('sensor.monthly_energy_shoulder','last_period') | float %}
      {% set s_tariff = states('input_text.shoulder') | float %}
      {% set offpeak_last = state_attr('sensor.monthly_energy_offpeak','last_period') | float %}
      {% set o_tariff = states('input_text.offpeak') | float %}
      {% set buyback_last = state_attr('sensor.monthly_energy_export_buyback','last_period') | float %}
      {% set b_tariff = states('input_text.feedin') | float %}
      {% set daily = states('input_text.daily') | float %}
      {% set last_month = now().month - 1 if now().month - 1 >= 1 else 12 %}
      {% set last_year = now().year - 1 if now().month == 1 else now().year %}
      {% set reset = state_attr('sensor.monthly_energy_offpeak','last_reset') |as_datetime %}
      {% set last_reset = reset.replace(year=last_year, month=last_month) %}
      {% set last_days = (reset - last_reset).days %}
      {{ (peak_last * p_tariff + shoulder_last * s_tariff + offpeak_last * o_tariff + buyback_last * b_tariff + daily * last_days) | round(2) }}

In terms of payback I have been calculating the savings from solar, my case is complicated as my buy/ sell prices change every 30 minutes.

Solar Savings =
energy self consumption * buy price +
energy export * sell price

Thanks @Muppetteer
This code is really great.
I will soon be replacing my automations with your code.
Currently running them both in parallel for a few days to check the code works.

For those interested in specifically what holidays apply to what country/province, go to
https://github.com/dr-prodigy/python-holidays/tree/master/holidays/countries

Hi @del13r

I see there is a breaking change from HA 2022.08 with the metering tariff command/service. I tried to change from the previous “service utility_meter.select_tariff” but couldn’t get it to work properly.

My code from your earlier posts is like this j

utility_meter:
  daily_energy:
    source: sensor.grid_import_energy
    name: Daily Import Meter
    cycle: daily
    tariffs:
      - peak
      - go

  daily_energy_export:
    source: sensor.grid_export_energy
    name: Daily Export Meter
    cycle: daily
    tariffs:
      - export

  daily_energy_gas:
#    source: sensor.gas_consumption_today
    source: sensor.grid_gas_power
    name: Daily Gas Meter
    cycle: daily
    tariffs:
      - standard

  daily_garage_solar:
    source: sensor.garage_solar_production
    name: Garage Solar Meter
    cycle: daily

and for one of the automatons the automation like this:

alias: Switch to the STD Tariff for metering functionality
description: >-
  This automation only changes the metering tariffs that I set up in the Octopus
  folder
trigger:
  - platform: time
    at: "04:30:00"
condition:
  - condition: state
    entity_id: input_boolean.go_tariff
    state: "on"
action:
  - service: utility_meter.select_tariff
    data:
      tariff: peak
    target:
      entity_id: utility_meter.daily_energy
mode: single

Now I’m seeing this in HA notifications:

Any guidance on how to change that service line and the utility meter code to work again?

As always thanx very much