My Energy Dashboard (Multi Part - How To)

So I have been playing with energy since I have gotten my Home Assistant setup. I have been playing around with setups and what works and what doesn’t work. So after about 4 months of tinkering I think I finally have something that works for me and is accurate!

Thought I would share it with others… there is a lot of work into one of these and ill add some information that shows how I did everything but I don’t have time to post right now but I will

This is using a Mark Down card and a bunch of programming…

The lightning bolt shows what is currently drawing energy and then you have the total months cost and then the current Watts that are being pulled form it…

I have a bunch of z-wave energy monitoring devices and also a whole home energy CT clamp for my panel.

I live in Ontario so i had to calculate costs based on 3 Tariffs and TOU and all that fun math!!

3 Likes

I am going to break down how I did this one post at a time when I have a few minutes for each step… First thing is first if you want to calculate the total cost of you hydro and you have different pricing based on use or time of day… You are going to need to create a helper that just changes its value to the current tariff you should be using:

For me I am in Ontario and have 3 different time of use tariffs… I have On-Peak, Mid-Peak, Off-Peak so I needed to create a helper that changes to what the current TOU is!!

I used a template sensor for this and this is the code below

{% set date = now() %}
{% set isHoliday = is_state('calendar.canada_on', 'on') %}
{% set isWeekend = date.isoweekday() in [6,7] %}
{% set isSummer  = date.month in [5,6,7,8,9,10] %}

{% if isWeekend or isHoliday %}
  {% set lookup = 'OOOOOOOOOOOOOOOOOOOOOOOO' %}
{% elif isSummer %}
  {% set lookup = 'OOOOOOOMMMMPPPPPPMMOOOOO' %}
{% else %}
  {% set lookup = 'OOOOOOOPPPPMMMMMMPPOOOOO' %}
{% endif %}
{% set map = {'O': 'Off-Peak', 'M': 'Mid-Peak', 'P': 'On-Peak'} %}
{{ map[lookup[now().hour]] }}

I am also using the Canadian holiday calendar to determine if its a holiday or not i used this HACS repo “GitHub - bruxy70/Holidays: 📅 Custom Home Assistant integration for public holidays - also used for garbage_collection integration to automatically move scheduled events that fall on a public holiday (by an automation blueprint)

If you let this helper run for a few days you will start to see in the history how it functions

You now have a helper that tells you the current TOU

1 Like

Next i need the cost of my hydro. I have been told that there is an really cool GitHub project that does all this for me (Link to repo) but I do not want my devices to rely on the internet to calculate the information and wanted to keep it all local.

I created 3 input number helpers to store the current cost… it does not change that much for Ontario so if it ever does I can manually update it. I did think about creating a template sensor so that you cannot accidently change the values, you could use the dev tools to manually change it if required. I chose to do input numbers but a sensor could work.

Create 3 different number helpers with the cost per kWh for hydro and give them a descriptive name like “Hydro Rates - On-Peak”

1 Like

The next step is to create a filter for your energy source. I spent so much time trying to clean up dirty reads from Home Assistant. USE FILTERS. go to the helpers section and create a filter. Give it a name that is descriptive like “Washer - Electric Consumption - [kWh Filtered]” and then select the electric consumption entity for your device.

Set your filter to outlier:

Window Size: 1
Radius: 0.2
Precision: 4

This will create a new filter that will remove any crazy spikes of +/- 0.2 kWh up or down. Most devices would never climb by that much between readings but look at the history of your device to see how much it changes by I only care about the previous reading and that the next one does not change by more than +/- 0.2 kWh. I don’t want to have more than 1 reading because it uses an average off all samples then does a +/- 0.2 so you have to be careful how many samples you use. I personally just care about the last reading and that the next one does not change by this amount. The precision is just decimal places so if it has to calculate it will use 4 places of precision so in this case because there is only 1 reading I want it to use 4 decimal places of that reading and check how much it has moved to compare

1 Like

Now you have a clean source of electricity used… Time to store that information somewhere so it’s useful. This place is a Utility Meter. In the helper section, create a Utility Meter. In the Utility Meter give it a descriptive name like “Washer - Utility Meter” the input sensor will be the filter that you created in the previous step. I am tracking Monthly costs so I have mine reset monthly… This means that all the electricity consumptions readings for this utility go back to 0 at the beginning of the month, I have no offset but if you want them to reset on the 4th you would sent the offset to 3.

In the Tariff section I create my 3 Tariffs for me On-Peak, Off-Peak, Mid-Peak PLEASE make sure you use the exact same names as you used in the helper you created in the second step above. The reason being the output from that helper will be used to tell this utility meter what current tariff should be set to.

Then I set Periodic Resetting to true and Sensor Always Available to Yes

1 Like

The next part is a little trickier. I wanted to create an automation that listens to for when my TOU helper changes, I want the automation to update my utility meter tariff. Because when you create a utility meter that has tariffs the main utility meter gets turned into a select. THen a child utility meter gets created for each Tariff you created. The main utility meter then acts as a redirector… all the electric consumption goes to it and whatever the select is set to it will redirect that current reading to that child utility meter. I like to think about it like sand falling into a funnel and the end of that funnel can be directed at one of 3 places. So I want the main utility meter to change where it points to when ever the TOU changes. I wrote a qick and dirty one that targeted this utility meter. This worked for the first few utility meters, but as I started to have more and more utility meters it was a pain to remember to update this automation to also change the new one I created. I figured there has to be a better way to do this so after some chatGPTing (That’s a word right?) I decided to use labels and create an automation that basically said "If the TOU changes, then update any Utility Meter that has a label of “Utility Meter - TOU” this made it so all I had to do was add this label to the Utility Meter and the automation would update it!

Pretty Cool!

Here is my code for the automation
Please update the entity_id of the TOU helper you created above… this is just what mine was called

alias: Hydro - TOU Change
description: >-
  When the helper for TOU changes to a new value, update the parent utility
  meter to the new TOU tariff
triggers:
  - trigger: state
    entity_id:
      - sensor.hydro_current_tariff
    to: null
conditions: []
actions:
  - action: select.select_option
    metadata: {}
    data:
      option: "{{ trigger.to_state.state }}"
    target:
      label_id: utility_meter_tou
    alias: Update All Utility Meters to New TOU
mode: single

This now allowed all utility meters to change their tariffs based on my TOU. After a few days you should have energy usage collecting in each one of you tariffs. the next step is to calculate the cost.

1 Like

Now we need to create a template sensor to store the calculated value of the hydro… To do this just multiply each tariff usage by its cost per kWh…

create a template sensor

{% set s = 'sensor.washer_utility_meter' %}
{% set i = 'input_number.hydro_rates' %}

{% if states(s ~ '_mid_peak') in ['unknown','unavailable'] or
      states(s ~ '_off_peak') in ['unknown','unavailable'] or
      states(s ~ '_on_peak' ) in ['unknown','unavailable'] or
      states(i ~ '_mid_peak') in ['unknown','unavailable'] or
      states(i ~ '_off_peak') in ['unknown','unavailable'] or
      states(i ~ '_on_peak' ) in ['unknown','unavailable'] %}
  {{ None }}
{% else %}
  {% set mid_usage = states(s ~ '_mid_peak') | float(0) %}
  {% set off_usage = states(s ~ '_off_peak') | float(0) %}
  {% set on_usage  = states(s ~ '_on_peak' ) | float(0) %}
  {% set mid_rate = states(i ~ '_mid_peak') | float(0) %}
  {% set off_rate = states(i ~ '_off_peak') | float(0) %}
  {% set on_rate  = states(i ~ '_on_peak' ) | float(0) %}
  
{{ 
     (mid_usage * mid_rate) +
     (off_usage * off_rate) +
     (on_usage * on_rate)
}}

{% endif %}

I also set the following settings

I give it a unit of measure as $, the state class I set to Total because I want to track the total cost over a few months using the graph integration. By giving it a class it allows long term statistics to be stored for the sensor. I also attach this cost to the device so that we can see the monthly cost on the device itself

I did some testing to make sure the sensors are there so no weird calculations happened like if a value is unavailable etc… I also just removed the “_off_peak” off the ends of the variable to make the code more updateable for each monthly cost I am going to create. This way I only have to update the first line of the code for each utility meter… Just look at one of the child utility meter and copy its entity id without the _tariffName on the end. If you notice for each tariff you created for you utility meter another helper was created with the name of the tariff added to the end of it. I could have not used variables in here but this just looked cleaner! If anyone has a cleaner way to do this I would love to hear it! We finally have the monthly cost! Also create and give this a label of “Monthly Cost” and any subsequent Monthly cost you create later add this same label to it, I’ll explain why later

Rinse and repeat for every single electricity consumption source that you want to monitor!!

I know this takes a lot of time. It also takes time to monitor them and make sure each one is working as expected!

PS if anyone has a better way to do this please feel free to share an easier way so that its a bit more dynamic and not such a pain to set up each monthly cost copying the code changing some values… not super hard but like the automation if there was a way to make it so no code has to change each time would be nice!!

1 Like

Remember before I told you to give all your monthly totals a label of “Monthly Cost”, this step explains why. I wanted to get the TOTAL monthly cost for all devices so again instead of updating the calculation every time I added a new monitor, I created a formula that just add up all the sensors with the label “Monthly Cost” on them.

{{ label_entities('monthly_cost') 
             | map('states') 
             | map('float', default=0) 
             | sum }}
1 Like

Then for the dashboard i created the following code for the markdown card

type: markdown
content: |-
  {% set devices = [
      {"name": "Washer",                "cost": "sensor.washer_monthly_cost",                "active": states('sensor.washer_plug_electric_consumption_w') | float(0) > 2.5,               "watts": "sensor.washer_plug_electric_consumption_w"},
      {"name": "Dryer",                 "cost": "sensor.dryer_monthly_cost",                 "active": states('sensor.dryer_plug_electric_consumption_w') | float(0) > 0.1,                "watts": "sensor.dryer_plug_electric_consumption_w"},
      {"name": "Freezer",               "cost": "sensor.freezer_monthly_cost",               "active": states('sensor.freezer_plug_current_consumption_w') | float(0) > 0.1,               "watts": "sensor.freezer_plug_current_consumption_w"},
      {"name": "Office Heater",         "cost": "sensor.office_heater_monthly_cost",         "active": states('sensor.office_heater_plug_current_consumption_w') | float(0) > 0.1,         "watts": "sensor.office_heater_plug_current_consumption_w"},
      {"name": "Office Desk",           "cost": "sensor.office_desk_monthly_cost",           "active": states('sensor.office_desk_electric_consumption_w') | float(0) > 0.1,               "watts": "sensor.office_desk_electric_consumption_w"},
      {"name": "Ripley's Heater",       "cost": "sensor.ripleys_heater_monthly_cost",        "active": states('sensor.ripleys_heater_current_consumption_w') | float(0) > 0.1,             "watts": "sensor.ripleys_heater_current_consumption_w"},
      {"name": "Master Bedroom Heater", "cost": "sensor.master_bedroom_heater_monthly_cost", "active": states('sensor.master_bedroom_heater_current_consumption_w') | float(0) > 0.1,      "watts": "sensor.master_bedroom_heater_current_consumption_w"},
      {"name": "Kitty Litter Fan",      "cost": "sensor.kitty_litter_fan_monthly_cost",      "active": states('sensor.kitty_litter_fan_electric_consumption_w') | float(0) > 0.1,          "watts": "sensor.kitty_litter_fan_electric_consumption_w"}      

  ] %}

  {% set lights = [
      {"name": "Couch Light",         "cost": "sensor.couch_light_monthly_cost",           "active": is_state('light.couch_lights',        'on'),   "watts": "sensor.couch_lights_electric_consumption_w"},
      {"name": "Office Light",        "cost": "sensor.office_light_monthly_cost",          "active": is_state('light.office_lights',       'on'),   "watts": "sensor.office_lights_electric_consumption_w"},
      {"name": "Driveway Light",      "cost": "sensor.driveway_light_monthly_cost",        "active": is_state('light.driveway_light',      'on'),   "watts": "sensor.driveway_light_electric_consumption_w"},
      {"name": "Theatre Room Lights", "cost": "sensor.theatre_room_lights_monthly_cost",   "active": is_state('light.theatre_room_lights', 'on'),   "watts": "sensor.theatre_room_lights_electric_consumption_w"},
      {"name": "Spa Lights",          "cost": "sensor.spa_lights_monthly_cost",            "active": is_state('light.spa_light',           'on'),   "watts": "sensor.spa_light_electric_consumption_w"},
      {"name": "Laundry Room Lights", "cost": "sensor.laundry_room_lights_monthly_cost",   "active": is_state('light.laundry_room_light',  'on'),   "watts": "sensor.laundry_room_light_electric_consumption_w"},
      {"name": "Amanda's Light",      "cost": "sensor.amanda_s_light_monthly_cost",        "active": is_state('light.amandas_light',       'on'),   "watts": "sensor.amandas_light_energy_consumption_w"},
      {"name": "Steve's Light",       "cost": "sensor.steve_s_light_monthly_cost",         "active": is_state('light.steves_light',        'on'),   "watts": "sensor.steves_light_energy_consumption_w"},
      {"name": "Patio Lanterns",      "cost": "sensor.patio_lanterns_monthly_cost",        "active": is_state('light.patio_lanterns',      'on'),   "watts": "sensor.spa_light_electric_consumption_w"}

  ] %}
  <table width='100%'>
   <thead>
      <tr>
        <td>Home Energy Meter</td>
        <td align="right">${{"%.2f"|format(states('sensor.house_energy_monthly_cost') | float(0)) }}</td>
        <td align="right">{{"%.2f"|format(states('sensor.home_energy_meter_electric_consumption_w') | float(0)) }}</td>
      </tr>
  </thead>      
   <tbody>
    <tr>
      <td colspan="3"><hr style="border: 1px solid white;"></td>
    </tr>
    <tr>
      <td align="left">Devices</td>
      <td align="right"></td>
      <td align="right"></td>
    </tr>
  {% for device in devices %}
     <tr>
       <td>{{device.name}}{% if device.get('active', False) %}<font color="Blue"><ha-icon icon="mdi:lightning-bolt"></ha-icon></font> {% endif %}</td>
       <td align="right">${{"%.2f"|format(states(device.cost) | float(0))}}</td>
       <td align="right">{{"%.2f"|format(states(device.watts) | float(0))}}</td>
     </tr>
  {% endfor %}
     <tr>
       <th align="left"><br>Lights</td>
       <th align="right"></td>
       <th align="right"></td>
     </tr>     
  {% for light in lights %}
     <tr>
       <td>{{light.name}}{% if light.get('active', False) %}<font color="Blue"><ha-icon icon="mdi:lightning-bolt"></ha-icon></font> {% endif %}</td>
       <td align="right">${{"%.2f"|format(states(light.cost) | float(0))}}</td>
       <td align="right">{{"%.2f"|format(states(light.watts) | float(0))}}</td>
     </tr>
  {% endfor %}
     <tr>
        <td colspan="3"><hr style="border: 1px solid white;"></td>
      </tr>
      <tr>
        <td>Total</td>
        <td align="right">${{"%.2f"|format(states('sensor.total_monthly_cost') | float(0)) }}</td> 
        <td align="right"></td>
      </tr>
    </tbody>
  </table>
title: Energy Usage & Cost
card_mod:
  style: |
    ha-card {
      --mdc-icon-size: 14px;
    }

This one i want to make a bit more dynamic somehow but I am not sure how I could. I am open to suggestions. For now you just update the array above with your devices and what entities that you want to use to determine if its on or off, or running or stopped… Also what entities you use to pull that Watts form and monthly costs…

1 Like

Because I have a whole house energy monitor on my electrical panel, I created a filter for it and dumped my energy use into a Utility Meter and added each TOU utility meter to the Built In Energy Dashboard and also using the hydro cost number helpers for each one to help calculate total house hold use and cost for the month.

I then used the filter I created for each device earlier to feed that usage into the individual consumption section of the built in Energy board to help give me a better understanding of my energy usage by device against each other and total energy used!

I am hoping this helps someone else get some ideas on tracking energy. This also makes me realize how much energy I am not tracking :slight_smile: Time for more energy monitors!!!

1 Like

I know I did this very quick and dirty so if I did not explain something very well please ask questions and I can update the steps above with any clarification if needed