Energy measurement for any light (that don't report energy)

Here are some scripts to generate energy measurements for any bulb (or device) that home assistant can turn on or off. This is helpful if you have smart bulbs that don’t report power or dumb bulbs on a switch, or anything, really, where home assistant knows if it is on or off and you know the power.

It consists of two parts:

  1. A template sensor where you put in a list of lights (any device, really) and their power when on.
  2. An integration sensor that integrates the power into energy.

Compute the power based on whether devices are on in a template sensor:
File: templates/light_energy.yaml:

- sensor:
  - name: "living_room_bulb_power_w"
    unique_id: living_room_bulb_power_w
    unit_of_measurement: "W"
    device_class: power
    state_class: measurement
    attributes:
      last_reset: '1970-01-01T00:00:00+00:00'
    state: >-
        {%- set check = 
          {
          'switch.living_room_lamp_1_plug':6.6*6,
          'switch.living_room_lamp_2_plug':6.6*6,
          'light.living_room_white_led_strip_no_ct':19.2*5*0.5,
          'light.living_room_reading_lamp':11
          }
        -%}
        {%- set found = expand(check) | selectattr('state', 'eq', 'on') | map(attribute='entity_id') | list -%}
        {{check.items() | selectattr(0, 'in', found) | map(attribute=1) | sum }}

A few things to note about this code:

  1. The “set check =” sets up a dictionary that has ‘entity’:Watts_when_on. You can simply put as many items in this list as you want with their wattage. For example, my ‘switch.living_room_lamp_1_plug’ controls a lamp with six 6.6W bulbs, so the power when on is 6*6.6. Don’t forget that you need a comma after each line and no comma at the end.
  2. You need to include device_class, state_class, and last_reset for this to work with the energy integration.

(The code works by expanding the dictionary into entity objects, selecting only the ones that are ‘on’, then extracting only their entity_id into a list. Then it takes all of the power values from the dictionary for each of the on items in the previous list and adds them up.)

Note that this code provides a sensor “sensor. living_room_bulb_power_w” that reports the current power (W) used by these devices. To get energy (power over time) you need to integrate it:

Integrate the power to get energy:
File: sensors.yaml

- platform: integration
  name: living_room_bulb_energy_kwh
  source: sensor.living_room_bulb_power_w
  unit_prefix: k
  method: left

This code will produce a new sensor ‘sensor. living_room_bulb_energy_kwh’ that will produce the energy. Note that it may not update until after some of the elements in the power sensor change.

Now, how do you put these together?
Well, in my configuration.yaml I have the following to load them.

sensor: !include sensors.yaml
template: !include_dir_merge_list templates/ 

How to debug:
Under Configuration->Server Controls
Use “Check Configuration” to find obvious mistakes.
Reload Template entities will reload the power sensor.
Then go to “Logs” and press refresh. The top entry will tell you if there are any non-obvious mistakes.
However, there is no way to reload the energy (integration) sensor, so you have to Restart home assistant to reload that.

Enjoy!
-David

An alternative approach suggested by @123 (sorry, can’t find the post at the moment) is to assign a custom attribute to each switch, representing the power consumed when on. (Configuration > Customizations > “Pick an attribute to override” > Other)

This makes the .yaml a little easier to follow:

  - platform: template
    sensors:
      lrlights_power:
        friendly_name: Living room lights
        unit_of_measurement: Watt
        value_template: >
          {{ expand('switch.living_room_socket_1', 'switch.living_room_socket_4', 'switch.living_room_spotlights') | selectattr('state', 'eq', 'on') | map(attribute='attributes.power') | map('int') | sum }}
          
  - platform: integration
    source: sensor.lrlights_power
    name: lrlights_kWh
    unit_prefix: k
    round: 5
    method: left

Also, when you get a new light you can simply change the switch power value, rather than editing the .yaml

1 Like

That’s a neat approach! Wouldn’t you still have to add any new lights to sensor as well?

I think a good combination could be to create a group of lights, add the power to each light as an attribute, and then make a sensor that computes power for the group. Then you can use the existing group interface to manage the list. (I haven’t tried that.)

Yes, sorry. I was thinking of lights etc. plugged into sockets.

Did you check out this awesome custom component?

3 Likes

Looks great!

I’m sorry to revive this, but i’m looking for a solution like this now and I tried this. However, my resulting sensor always reports a state of ‘unknown’

I coped your code verbatim, only replacing the keys and values on the dictionary with my entity names and power consumption for each.

Any ideas what else I may be missing?

Did you try the yaml on top or Powercalc (the link posted 2 posts above) ?

Tried the Yaml method described on the initial post.

Try Powercalc, it’s much easier and more powerful to use

2 Likes

I’ll give that a world.
That worked great! Thanks!