I would like to select all lights in a certain ‘room’ (‘ruimte’ in Dutch) so that I can inform with a mushroom card the user how many lights are (still) on on that floor, or in that room.
Now I have it hardcoded with a manual filled array of all lights on that floor like this:
- type: vertical-stack
cards:
- type: custom:mushroom-title-card
title: 1e Verdieping
subtitle: >-
Er zijn {{ [
'light.badkamer_bad',
'light.badkamer_douche',
'light.badkamer_toilet' ,
'light.badkamer_wastafel' ,
'light.slaapkamer_kleurenlamp',
'light.overloop_lamp',
'light.kantoor_burolamp',
'light.kantoor_plafond_kast',
'light.kantoor_plafond_lamp_printer',
'light.kantoor_plafond_schilderij'
] | select('is_state', 'on') | list | count }} op de eerste verdieping aan, {{user}}!
But that isn’t very flexible; as soon as I add a light, I need to code again.
On my first floor I have the following Rooms/Ruimtes (which I consider as a pretty stable list):
You can sum the counts from different areas as follows:
- type: vertical-stack
cards:
- type: custom:mushroom-title-card
title: 1e Verdieping
subtitle: >-
{% set ns = namespace(lights_on=[]) %}
{% set region = ['Slaapkamer', 'Logeerkamer', 'Badkamer',
'Kantoor', 'Overloop'] %}
{% for room in region %}
{% set ns.lights_on = ns.lights_on + [area_entities(room)
| select('match', 'light.*') | select('is_state', 'on') | list | count ] %}
{% endfor %}
Er zijn {{ ns.lights_on | sum }} op de eerste verdieping aan, {{user}}!
However, using an Area-based approach may end up needing just as much maintenance as your original method. There can be numerous integrations that create light entities that you don’t want to include in your count which you will have to reject from the results of the template or disable. Light groups pose a similar issue that you will need to decide how to handle and possibly update every time you add or change a light group.
Jinja Docs: These docs are not geared toward new/casual users, but they contain a lot of important information.
Jinja for Ninjas: @skalavala has put together a well organized tutorial and group of examples. It’s been a while since this was updated, so there are better/easier ways to do some of the things shown, but it’s still a good source.
Many Python methods also to work in templates. I’ve never seen a complete list of which methods work and which don’t… But the Official Python docs have come in handy for me multiple times to figure out what’s going on in templates posted by some of the more advanced users on this forum.
{% set ns = namespace(lights_on=[]) %}
{% set region = ['Slaapkamer', 'Logeerkamer', 'Badkamer',
'Kantoor', 'Overloop'] %}
Setup variables:
A namespace is needed so that we can access the information outside of the loop.
{% for room in region %}
{% set ns.lights_on = ns.lights_on + [area_entities(room)
| select('match', 'light.*') | select('is_state', 'on') | list | count ] %}
{% endfor %}
Loop through rooms. area_entities(room): Instantiate a list of the entitie IDs assigned to a given Area. | select('match', 'light.*'): Keep all entity IDs that contain “light.” | select('is_state', 'on'): Keep only entity IDs for entities whose state is “on” | list | count : Generate a list of the entity IDs and return the count of items in the list
Er zijn {{ ns.lights_on | sum }} op de eerste verdieping aan, {{user}}!
Return results: ns.lights_on | sum: Return the sum of all the counts in the list.
Came across this looking for a solution.
Didgeridew’s answer helped a lot, but I managed to improve upon it thanks to the recent addition of some functions
So I thought I’d share here for anyone else looking for a better answer
- type: vertical-stack
cards:
- type: custom:mushroom-title-card
title: 1e Verdieping
subtitle: >-
{% set ns = namespace(lights_on=[]) %}
{% set region = floor_areas('floor_1') %}
{% for room in region %}
{% set ns.lights_on = ns.lights_on + [area_entities(room)
| select('match', 'light.*') | select('is_state', 'on') | list | count ] %}
{% endfor %}
Er zijn {{ ns.lights_on | sum }} op de eerste verdieping aan, {{user}}!
- type: vertical-stack
cards:
- type: custom:mushroom-title-card
title: 1e Verdieping
subtitle: >-
{% set x = floor_areas('floor_1') | map('area_entities') | sum(start=[])
| select('match', 'light') | select('is_state', 'on') | list | count %}
Er zijn {{ x }} op de eerste verdieping aan, {{ user }}!
I slightly improved the code you provided to adapt it for my use. Sharing in case it helps someone, just as the code @123 helped me. I used Mushroom Template Card and two basics Home Assistant script.
This script toggles the lights on and off for the ground floor using the Mushroom Template Card.
Button mushroom-template-card :
type: custom:mushroom-template-card
primary: Ground Floor # Title of the card
icon: >
# Initialize a namespace to keep track of lights on
{% set ns = namespace(lights_on=[]) %}
# Get all areas for the ground floor
{% set region = floor_areas('ground_floor') %}
# Loop through each room in the region
{% for room in region %}
# Add count of 'on' lights to the namespace list
{% set ns.lights_on = ns.lights_on +
[area_entities(room) | select('match', 'light.*') | select('is_state', 'on') | list | count ] %}
{% endfor %}
# Set the icon based on whether any lights are on
{{ 'mdi:lightbulb-on' if ns.lights_on | sum > 0 else 'mdi:lightbulb-off' }}
icon_color: >-
# Same logic to determine the icon color
{% set ns = namespace(lights_on=[]) %}
{% set region = floor_areas('ground_floor') %}
{% for room in region %}
{% set ns.lights_on = ns.lights_on +
[area_entities(room) | select('match', 'light.*') | select('is_state', 'on') | list | count ] %}
{% endfor %}
# Set the icon color to yellow if any lights are on, otherwise gray
{{ 'yellow' if ns.lights_on | sum > 0 else 'gray' }}
secondary: >
# Calculate and display the number of lights on in the secondary text
{% set ns = namespace(lights_on=[]) %}
{% set region = floor_areas('ground_floor') %}
{% for room in region %}
{% set ns.lights_on = ns.lights_on +
[area_entities(room) | select('match', 'light.*') | select('is_state', 'on') | list | count ] %}
{% endfor %}
# Display the message with the count of lights on
There are {{ ns.lights_on | sum }} lights on the ground floor, {{user}}!
tap_action:
action: call-service
service: script.light_ground_floor_off
target: {}
badge_color: ''
multiline_secondary: false
hold_action:
action: call-service
service: script.light_ground_floor_on
target: {}
Your comments will break those templates. Comments in Jinja need to be enclosed in comment delimiters {# #}.
As Taras showed in the previous post, there is no need to use all those loops since the area_entities function can be applied across the list of areas using map, and the list can be flattened with sum:
type: custom:mushroom-template-card
primary: Ground Floor
icon: >
{% set x = floor_areas('ground_floor') | map('area_entities') | sum(start=[])
| select('match', 'light') | select('is_state', 'on') | list | count %}
{{ 'mdi:lightbulb-on' if x > 0 else 'mdi:lightbulb-off' }}
icon_color: >-
{% set x = floor_areas('ground_floor') | map('area_entities') | sum(start=[])
| select('match', 'light') | select('is_state', 'on') | list | count %}
{{ 'yellow' if x > 0 else 'gray' }}
secondary: >
{% set x = floor_areas('ground_floor') | map('area_entities') | sum(start=[])
| select('match', 'light') | select('is_state', 'on') | list | count %}
There are {{ x }} lights on the ground floor, {{user}}!
tap_action:
action: call-service
service: script.light_ground_floor_off
target: {}
multiline_secondary: false
hold_action:
action: call-service
service: script.light_ground_floor_on
target: {}
It’s much easier to read and understand like this, thank you!
I wanted to add comments to provide a bit more explanation in case someone needed it, but I hadn’t included any in my code. I’ll remember to close my comments in the future! (I’m just getting started.)
Could you explain your solution a bit more? I haven’t used template sensors before and I’m curious how they could simplify things. How would this help in avoiding multiple recalculations? Thanks!
See the UI configuration section — very easy. Just use the counting template from above as the state template, then you have a sensor showing the lights on on that floor.