Just an FYI you don’t actually need the expand
. states.binary_sensor
is a list of all the binary sensors you have already expanded. That’s why you can use selectattr
and rejectattr
on it. Also the last | list
is redundant, | sort
already makes things into a list. I think you can simplify this first bit to just this:
{% set x = states.binary_sensor
| selectattr("attributes.device_class", "eq", "motion")
| rejectattr("state", "in", ["unknown", "unavailable"])
| sort(reverse=true, attribute='last_changed')
%}
Note: I also added an ignore unavailable
as I assume you want to ignore binary_sensors in that state as well.
One other thought, this sensor is going to track changes for every single binary sensor in your system. It’s only going to change state when a binary sensor with device_class: motion
changes but its going to run the template every time any binary sensor changes because you’re accessing the state object of every binary sensor to find out its device class. In addition to updating once a minute since you’re accessing now()
.
I point this out because I actually just tried something like this and ran into issues. I tried to use a sensor to tell me the entity ID of the last light which updated so I could trigger an automation which changed something about the room that light was in like so:
state: >-
{{ (states.light
| rejectattr('state', 'in', ['unknown', 'unavailable'])
| sort(reverse=true, attribute='last_updated')
| first).entity_id
}}
I found it didn’t work very well. If changes to lights happened too close together then my sensor would just never have its state set to the entity ID of some of the lights. Like I knew the light changed and the sensor should’ve tried to run but the automation never ran and the sensor never showed that entity ID in its state history.
Now you’re doing area name rather then entity ID which is good since it means the template will have the same result more then mine did. But still something to keep an eye on if you’re planning to trigger an automation from this. The simpler the template the better since its gotta be lightning fast for how much its going to run.
Like maybe consider dropping the timestamp check? Why does it matter if it changed literally in the same second? Seems like a recipe for very weird bugs. Like if the motion actually occurred at .99 after the last whole second but this template didn’t get to that point until .02 of the next second.