Can I get list of area_names from a list of entities?

Not sure if this is possible but, I have a template that gives me a list of all my occupancy sensors (HLK-LD2410) that are currently detecting a STILL presence

{{ states | selectattr('attributes.device_class', 'eq', 'occupancy') | selectattr( 'state', 'equalto', 'on' ) | selectattr('name', 'search', 'Still') | map(attribute='name')  | list | count }}

and this works to give me a count of rooms occupied.

My next step is to get a list of the occupied rooms, if I remove the count pipe then I get a list of entities. Is it possible to get the corresponding list of rooms/areas for that entity list? Simply changing the map(attribute='name') “name” to “area_name” returns [Undefined]. So not as simple as I thought it was going to be!

In the template editor if is try this for each entity then I get the corresponding room/area name returned as I’d expect,

{{ area_name('binary_sensor.lounge_presence_still') }}

Do I need a different attribute or maybe another attribute to pipe? For every option I’ve tried so far I get Undefined, None, Unknown returned in the template editor.

Chris

area_name is a function, not an attribute, so you need to map to the function:

{{ states.binary_sensor | selectattr('attributes.device_class', 'defined')
| selectattr('attributes.device_class', 'eq', 'occupancy') 
| selectattr( 'state', 'eq', 'on' ) | selectattr('name', 'search', 'Still') 
| map(attribute='entity_id') | map('area_name') | list }}

FYI, you may want to add | reject('eq', none) | unique before the list filter to get a more concise list.

3 Likes

@Didgeridrew Exactly the information that was needed. Learn a little (or sometimes a lot!) each day!

Does exactly what I was trying to do. Thank you!

Where is this described/documented, just to understand a bit more? Nothing that I read in Templates explained that so that I understood?

Specifically, I’d like to understand the difference between filter function and attibute in this context.

An entity’s state object contains a group of pieces of information, usually referred to as properties. Attributes are one of the common properties for entities and contain a list of paired data points.

Functions are ways of modifying or interacting with data. Examples of functions used in HA templates include states(), expand(), and map(). Filters are just functions that are written in a different way. Some functions, like expand() and area_name() can be written both ways; while others, like is_state() and map() can’t.

Function syntax:
{{ area_name('switch.kitchen') }}
{{ expand('light.example') }}
{{ is_state('light.example', 'on') }}

Filter syntax:
{{ 'switch.kitchen' | area_name }}
{{ ('light.example', 'switch.kitchen') | expand }}

The map() filter/function can be used to perform two kinds of operations on a sequence of objects. When you use the attribute= argument, it will look up and return the value of that attribute for all the members of the sequence. When you supply the name of another filter, that filter’s function will be applied to all the members of the sequence.

TLDR: Attributes are pieces of data, filters/functions are ways of interacting with data, and map() can be used either to retrieve data or modify data using other functions.

2 Likes

Assume this may be used to get a list of areas from “states” object:

{{ states
   | sort(reverse=false,attribute='entity_id')
   | map(attribute='entity_id')
   | map('area_id')
   | unique
   | reject('==',none)
   | list }}

i.e. areas associated with entities.
But let’s assume that some entity (“garden”) is not assoc. with any entity.
Then this area will not be acquired by that template.

So, how can I get a list of ALL areas?

Update: completely forgot about “areas()”.
My bad.