Counts the lights on

I have lot off mqtt switch in my home. I want to count the lights on in order to notify when there are too many light on and reduct my carbon footprint (and money).

any ideas on how to get the number of entityes in status on?
TNK
MArco

Try this:

{{ states.switch|selectattr('state','equalto','on')|list|length }}

10 Likes

OK, Work fine…
thanks a lot

in “/home/homeassistant/.homeassistant/sensors.yaml”, line 152, column 9
expected , but found ‘’

  • platform: template
    sensors:
    licznikswiatel:
    friendly_name: ‘Licznik swiateł’
    value_template: ‘{{ states.switch|selectattr(‘state’,‘equalto’,‘on’)|list|length }}’

?

Hey, the script works fine, but the counter always stays at its initial value and doesn’t update when I turn lights on. What am I doing wrong?

How are you using it?

It won’t ever update unless you list out all entity ids in the entity_id field for a template sensor. It’s an unfortunate requirement when using template devices. They need entities to know when to update.

1 Like

okay, so that’s how it works now, thanks a lot.

do i have to list all entities individually, or is there also a possibility to specify a group?

You ‘should’ be fine with the group but it’s easier just to test it and see.
Alternatively (and less elegantly) you could just have it update on a time pattern. Though that would infer it would mostly be out of date.

I always specify them all individually.

Place this into the template editor

{%- for s in states.switch %}
- {{ s.entity_id }}
{%- endfor %}

This is how I have my sensor configured to count my lights (or switches, or doorsensors, or…):

  - platform: template
    sensors:
      current_lights_on:
        friendly_name: Lights at this moment
        unit_of_measurement: 'on'
        value_template: >
          {% set total = 0 %}
          {% if is_state('light.eetkamer', 'on') %}
            {% set total = total + 1 %}
          {% endif %}
          {% if is_state('light.slaapkamer', 'on') %}
            {% set total = total + 1 %}
          {% endif %}
          {% if is_state('light.voortuin', 'on') %}
            {% set total = total + 1 %}
          {% endif %}
          {{total}}

And ofcourse it’s simple to make a notification-automation when the value is too high… Something like:

- alias: Waytoomanylights
  trigger:
  - platform: numeric_state
    entity_id: sensor.current_lights_on
    above: 5
  action:
  - service: notify.global_notify
    data_template:
      message: 'Maybe it's time to turn off some lights.'
      title: Turn off some lights!
3 Likes

you can optimize that

  value_template: >
    {% set lights = [
      states.light.eetkamer,
      states.light.slaapkamer,
      states.light.voortuin,
      ] %}
    {{ lights | selectattr('state','eq','on') | list | count }}

Then to add a light, all you need to do is add to the list. No need for a huge if statement

17 Likes

Hi all

Jumping in here, hoping to get help.
I’ve tried to use your config, Petro. But cannot get my counter to work. I get back “0” lights on.
2020-01-28_21h02_46

Using hass.io on RPI4

My config looks like this (I’ve listed all my lights, but just show 2 here)

- platform: template
  sensors: 
    number_of_lights_on: 
      unit_of_measurement: 'on'
      value_template: >
        {% set light = [
          states.light.bad_1,
          states.light.walk_in_spot_4,
          ] %}
        {{ lights | selectattr('state','eq','on') | list | count }}

Can you help me?

Thanks in advance

PS. This is my first post, hope I did it right.

1 Like

change to

        {% set lights = [
1 Like

Thanks a lot!!
And thanks for the fast reply, well spotted :wink:

I funny how you can go blind on your own code…

The solution by @petro works great, but I would like to extend it somehow.

Apart from counting the lights on, I would like to also have an overview of all lights that are off. I currently do this by copying the same template code in a markdown lovelace card, but omitting the | count part and iterating over all lights.

However, could this be done using a single sensor (that counts the number of lights on, but also stores the actual lights in an attribute)? This way I won’t have to define the same array (lights) in two different places?

Many thanks in advance!

you can make a attribute template. But you may not be able to use it in other areas of your template sensor. It really depends on when it gets updated, i.e. do attributes resolve templates prior to value_templates? I don’t know the answer to this.

Here’s one way:

- platform: template
  sensors: 
    lights_on_off: 
      value_template: >
        {% set lights = [ states.light.first,
                          states.light.second,
                          states.light.third,
                          states.light.etc   ] %}
        {{ lights | selectattr('state','eq','on') | list | count }} {{ lights | selectattr('state','eq','off') | list | count }}

The state of this Template Sensor will be something like:

3 12

which means 3 lights are on and 12 lights are off.

If you want to extract the number of lights that are off (12) you would use a template like this:

{{ states('sensor.lights_on_off').split()[1] }}

Change the 1 to 0 to get the number of lights that are on.

If you to get fancy, you can add the total number of lights so the sensor’s state looks something like this:

3 12 17

That would mean 3 are on, 12 are off, 17 in total, and 17 - (3+12) = 2 are neither on or off (possibly unknown or unavailable).

Thanks for this answer, gives some ideas!

But what I am looking for is a way to return a list of entities in the sensor, e.g. the output of this:

{{lights | selectattr('state','eq','on') | list}}

I currently use this code in my frontend (markdown card), but the same variable lights is also used in the sensor configuration for counting the number of lights that are active. It works, but whenever I want to change this variable (e.g. adding a new light), I need to add it in 2 places (sensor and frontend).

Therefore, I was wondering if I could add the current entities (or just their names) into the sensor, or does anyone know another trick for not having to define the same variable twice? Or should I just get rid of the sensor and do everything in the markdown (frontend) card?

Yes, as I said, you’ have to use it as an attribute inside a sensor. If you want it to properly push updates you’ll need to jump through hoops, below is my initial attempt (I have not tried it, you’re welcome to). You can create a ‘helper’ entity, then a series of template sensors off it. In the helper, you’ll have to declare the list a few times but it every time outside that helper entity, you should be good.

sensor:
- platform: template
  sensors:
    light_helper:
      value_template: >
        {%- set lights = [ states.light.first,
                          states.light.second,
                          states.light.third ] %}
        {%- set ns = namespace(last_updated=[]) %}
        {%- for light in lights %}
        {%- set ns.last_updated = ns.last_updated +  [ as_timestamp(light.last_updated) ] %}
        {%- endfor %}
        {{ ns.last_updated | max | timestamp_custom('%Y-%m-%dT%H:%M:%S.%f+00:00', False) }}
      entity_id: light.first, light.second, light.third
      device_class: timestamp
      attribute_templates:
        lights: >
          {%- set lights = [ states.light.first,
                          states.light.second,
                          states.light.third ] %}
          {{ lights }}

Now create a separate template sensor and get whatever you want.

    lights_on:
      value_template: >
        {{ state_attr('sensor.light_helper', 'lights') | selectattr('state','eq','on') | list | count }}