Yeah, thanks Taras. Tried and working fine.
For future reference, if you want the Template Sensor to include an entity that is not in the group (and for whatever reason you donât want it within the group), you can simply add it to expand
like this:
value_template: "{{ expand('group.luces', 'light.whatever') | selectattr('state','eq','on') | list | count }}"
EDIT
Correction. Removed errant closing parenthesis.
Just to share how I did it.
To explain a bit:
- My second floor is organized in 4 areas.
- I have renamed all lights that are part of another light to something like â2nd Floor xyzâ. These are for instance IKEA bulbs in a lamp with 3 bulbs. I have organized this using light groups into one light.
- I use custom button cards for the buttons. Check out https://github.com/custom-cards/button-card.
- platform: template
sensors:
lights_number_on_in_2nd_floor:
friendly_name: 'Lights on in 2nd floor'
unique_id: lights_number_on_in_2nd_floor
value_template: >
{%- set search_state = 'on' %}
{%- set search_areas = ['Office', 'Loft', 'Bedroom', 'Master bedroom'] %}
{%- set ns = namespace(lights=[]) %}
{%- for light in states.light | selectattr('state','eq', search_state) %}
{%- for area in search_areas %}
{% if area_name(light.entity_id) == area and "2nd Floor" not in state_attr(light.entity_id, "friendly_name") %}
{%- set ns.lights = ns.lights + [ light.entity_id ] %}
{% endif%}
{%- endfor %}
{%- endfor %}
{{ ns.lights| list | length }}
Edit: Thanks to @petro and everyone else for the help in the thread.
If you wish, you can reduce the template to this (no for-loops required):
value_template: >
{{ states.light | selectattr('state', 'eq', 'on')
| rejectattr('name', 'search', '2nd Floor')
| map(attribute='entity_id') | map('area_name')
| select('in', ['Office', 'Loft', 'Bedroom', 'Master bedroom'])
| list | count }}
EDIT
Explanation of how the template works:
- Start by selecting all lights.
- Select only the lights that are
on
. - Reject lights whose
friendly_name
contains the string2nd Floor'
. - Reduce the information to just each lightâs
entity_id
. - Find the area in which each light is located.
- Select only the areas matching one of these four: Officeâ, âLoftâ, âBedroomâ, âMaster bedroomâ.
- Convert the resulting information into a list.
- Count the number of items in the list.
EDIT
Correction. Replaced attributes.name
with name
.
Thanks. Will look at it later. More compact code is nice.
Edit: Thanks @123 ! It is working perfectly and the code is more compact. I just had to change attributes.name
to attributes.friendly_name
. Thanks again man!
Yes, that will work but the mistake I made was including the word attributes.
in attributes.name
. It only needs to be name
because thatâs synonymous with the friendly_name
attribute (if it exists).
Hereâs what I mean:
I have corrected the example in my previous message.
itâs possible to use an event trigger to automatically update the count without having to specify every light in your template.
template sensors that show a count of lights on for a light group:
template:
- trigger:
- platform: event
event_type: state_changed
sensor:
- name: Lights On Downstairs
state: >
{% set entities = state_attr('light.lights_downstairs',"entity_id") %}
{% set result = namespace(turned_on=[]) %}
{% for entity in entities if is_state(entity,'on') %}
{% set result.turned_on = result.turned_on + [entity] %}
{% endfor %}
{{ result.turned_on | count }}
- name: Lights On Upstairs
state: >
{% set entities = state_attr('light.lights_upstairs',"entity_id") %}
{% set result = namespace(turned_on=[]) %}
{% for entity in entities if is_state(entity,'on') %}
{% set result.turned_on = result.turned_on + [entity] %}
{% endfor %}
{{ result.turned_on | count }}
- name: Lights On Outside
state: >
{% set entities = state_attr('light.lights_outside',"entity_id") %}
{% set result = namespace(turned_on=[]) %}
{% for entity in entities if is_state(entity,'on') %}
{% set result.turned_on = result.turned_on + [entity] %}
{% endfor %}
{{ result.turned_on | count }}
light group:
light:
- platform: group
name: Lights Downstairs
entities:
- light.breakfast_room_light
- light.family_room_light
- light.dining_room_light
- light.kitchen_light
- light.living_room_light
- light.living_room_reading_light
- light.office_light
- light.tv_light
- light.foyer_light
- light.closet_light
- light.stairs_light
- light.desk_light
this type of template sensor would perform better if the event trigger data filter accepted wildcards, e.g.
- trigger:
- platform: event
event_type: state_changed
event_data:
entity_id: light.* # not supported in 2021.11.1 ...
*edit: complete sensor, light group, and failed event_data wildcard filter test result
Itâs possible, but not recommended.
You are suggesting to use an Event Trigger to monitor state_changed
events. That means it will be triggered by every state-change that occurs in Home Assistantâs state machine (locks, binary_sensors, sensors, fans, timers, switches, etc). The three Trigger-based Template Sensors will be evaluated far more often than simply when a light changes state.
Just use the expand()
function; the templates will be evaluated only when one of the Light Groupâs members undergoes a state-change. Counting them can also be done without using a for-loop.
template:
- sensor:
- name: Lights On Downstairs
state: "{{ expand('light.lights_downstairs') | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lights On Upstairs
state: "{{ expand('light.lights_upstairs') | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lights On Outside
state: "{{ expand('light.lights_outside') | selectattr('state', 'eq', 'on') | list | count }}"
true, and I believe the catch-all state changes code I posted may have been causing a stabilization issue in my instance âŚand, Iâve removed itâŚ
since Iâm using âlightâ groups and not a âgroupâ of lights, I had to make a small modification to your code, but it appears to be working muuuch better:
template:
- sensor:
- name: Lights On Downstairs
state: "{% set entities = state_attr('light.lights_downstairs','entity_id') %} {{ expand(entities) | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lights On Upstairs
state: "{% set entities = state_attr('light.lights_upstairs','entity_id') %} {{ expand(entities) | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lights On Outside
state: "{% set entities = state_attr('light.lights_outside','entity_id') %} {{ expand(entities) | selectattr('state', 'eq', 'on') | list | count }}"
âlightâ groups support additional features and play well with other integrations such as homekit and alexa out of the box, which is why I prefer them. however every non-dimmer zwave toggle switch requires a âlightâ switch before it can be added to a âlightâ group⌠a regular group will take both lights and switches, but the âgroupâ entity doesnât expose a turn_on/off service right? there is a smoothness still missing here
scenes are my favorite light groups, and I have created a working âlightâ scene custom component that allows scenes to be treated as a âlightâ, so that scenes can be toggled on and off, and the scene light maintains an âonâ state until a child light is changed and allow for useful/stateful scene button ui
Ah, my mistake. The expand
function is capable of automatically expanding the entity_id
attribute of a Group but not a Light Group. A compact way of handling a Light Group would be like this:
template:
- sensor:
- name: Lights On Downstairs
state: "{{ state_attr('light.lights_downstairs','entity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lights On Upstairs
state: "{{ state_attr('light.lights_upstairs','entity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lights On Outside
state: "{{ state_attr('light.lights_outside','entity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
You would use the generic homeassistant.turn_on
service (and turn_off
).
Hi, this works.
but how can I find number of lights âonâ in a specified âareaâ? ( in a room only, not in the whole house?)
thanks.
{{ expand(area_entities('Living Room')) | selectattr('domain','eq','light') | selectattr('state','eq','on') | list | count }}
make sure your area is actually named âBedroom 1â and that the âBedroom 1â contains those bedroom lights.
EDIT Also found a typo, review my original post again with the updates
area name : Bedroom 1
Area ID: bedroom_1
see my edit
YES! that works.
I am also trying to get light brightness and when it was last on? could you please help me.
thanks.
I also want to mention what the status of my garage door is (cover_garagedoor).
Any idea how i show the state (open or closed) in the markdown card?
Edit: found a solution to use the position sensor:
De garagepoort is {% if is_state(âsensor.garagepoort_positieâ, â0â) %} gesloten {% else %} open {% endif %}
This is really an interesting thread!
Iâm trying to count the lights on my different floors (Gelijkvloers, Verdieping, Zolder, Buiten).
I have following light groups:
# Light groups
light:
- platform: group
name: Lichten Gelijkvloers
entities:
- light.hue_go_1
- xxx
- platform: group
name: Lichten Verdieping
entities:
- light.hue_lightstrip_plus_bad
- xxx
- platform: group
name: Lichten Zolder
entities:
- light.bureau_tim
- xxx
- platform: group
name: Lichten Buiten
entities:
- light.buitenverlichting_keuken
- xxx
I have following template as mentioned somewhere here::
template:
- sensor:
- name: Lichten Aan Gelijkvloers
state: "{{ state_attr('light.lichten_gelijkvloersâ,âentity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lichten Aan Verdieping
state: "{{ state_attr('light.lichten_verdiepingâ,âentity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lichten Aan Zolder
state: "{{ state_attr('light.lichten_zolderâ,âentity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
- name: Lichten Aan Buiten
state: "{{ state_attr('light.lichten_buitenâ,âentity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}"
However I get the following error in the log:
Invalid config for [template]: invalid template (TemplateAssertionError: No filter named 'expand'.) for dictionary value @ data['sensor'][0]['state']. Got "{{ state_attr('light.lichten_gelijkvloersâ,âentity_id') | expand | selectattr('state', 'eq', 'on') | list | count }}". (See /config/configuration.yaml, line 267).
Anyone has an idea whatâs wrong?