I have several binary sensors that I want to be able to use for templates. For example I want to start with 3 binary_sensors A,B,C and add them to some sort of list/group/other structure so I can easily add/remove sensors.
Then using this structure, I want to be able to create templates that accomplish the following:
get a list of strings of these sensor names. e.g. A, B, C
create a template that gives me the count of sensors that are on. e.g. 2
get a list of the sensors that are on e.g. A,C
sensors that are off e.g. B
Now I want to be able to add binary_sensor D to the “list” without having to change the templates.
I can manage to create templates that accomplish these bullet points, but I have to hard code the binary sensor names. There’s gotta be a cleaner OO way of doing this.
I think I have it, but there’s always something else, as I’m trying to parse the results. I can easily find the “on” sensors using selectattr, but I’m having a b*** parsing the returned values.
{{
expand(['binary_sensor.mygroup']) | selectattr("state",'eq','on')
| list
}}
The attribute entity_id of the group helper contains a list of the entity IDs of all the entities in the group.
Master the map() filter and don’t use expand() where it isn’t necessary. The functionality of map() has been expanded over the last year or so to greatly reduce the places where you need to use expand().
get a list of strings of these sensor names. e.g. A, B, C
{{ state_attr('binary_sensor.example_group', 'entity_id')
| map('state_attr', 'friendly_name') | list }}
create a template that gives me the count of sensors that are on. e.g. 2
{{ state_attr('binary_sensor.example_group', 'entity_id')
| select('is_state','on') | list | count }}
get a list of the sensors that are on e.g. A,C
{# Returns a list of the entity IDs #}
{{ state_attr('binary_sensor.example_group', 'entity_id')
| select('is_state','on') | list }}
{# Returns a list of the friendly names #}
{{ state_attr('binary_sensor.example_group', 'entity_id')
| select('is_state','on') | map('state_attr', 'friendly_name') | list }}
I’d say, the expand versions is shorter to write and more user friendly (explicit in what its doing). Let’s take your first example:
{{
state_attr('binary_sensor.outer_doors_and_windows', 'entity_id')
| map('state_attr', 'friendly_name')
| list
}}
# vs
{{
expand('binary_sensor.outer_doors_and_windows')
| map(attribute='attributes.friendly_name')
| list
}}
When I say that the expand version is more explicit, I mean that I’d never guess that state_attr('binary_sensor.outer_doors_and_windows', 'entity_id') would give me a LIST of entity_ids of the group members → I’d assume it gives just the group’s entity_id. It looks like a hack / bad naming.
But your argument of “explicitness” requires a number of seemingly incongruous things. First it needs knowledge of how expand() works with a specific subset of entities (groups and group helpers) compared to other all other entities. At the same time, it requires a lack of understanding the differences between properties of the state object and attributes. And still, it uses attributes.friendly_name in the map() filter, demonstrating an understanding that attributes is a property of the state object containing a dictionary of other values.
The bottom line, as I understand it, is that using expand() is more process hungry than the other option. According to current published analytics, relatively low-spec systems represent a large proportion of Home Assistant’s user base. So, wherever possible, we should share and promote efficient practices to the best of our abilities and knowledge.