Select sensors not being updated for some time

Hello,

I’m trying to make a list of sensors not updated for some time.

In first place I’ve tried to select all the sensors updated before now() without problem with the next code:

{%  set sensor_lu_list = states.sensor | selectattr('last_updated', 'lessthan', now()) | map(attribute='last_updated') | list  %}
{{ sensor_lu_list }}

I get something like:

[datetime.datetime(2021, 10, 14, 7, 38, 36, 891149, tzinfo=datetime.timezone.utc), datetime.datetime(2021, 10, 13, 13, 4, 58, 709781, tzinfo=datetime.timezone.utc), datetime.datetime(2021, 10, 14, 7, 57, 22, 382337, tzinfo=datetime.timezone.utc), datetime.datetime(2021, 10, 13, 13, 1, 28, 374336, tzinfo=datetime.timezone.utc),
...]

BTW, if I print one of the list elements, the format is converted to UTC:

{{ sensor_lu_list[0] }}

and the output is:

2021-10-14 07:38:36.891149+00:00

Now I have two problems:

In first place, I need to map the entity_id attribute instead of last_updated, but if I try this in the template depeveloper tools I have no output (it doesn’t work):

{%  set sensor_ids_list = states.sensor | selectattr('last_updated', 'lessthan', now()) | map(attribute='entity_id') | list  %}
{{ sensor_ids_list }}

In second place, I don’t get how to change now() to now() - x hours. I’ve tried this without success:

{%  set sensor_lu_list = states.sensor | selectattr('last_updated', 'lessthan', ((as_timestamp(now())-4*3600)|timestamp_custom ('%Y-%m-%d %H:%M:%S.%f%z')) | map(attribute='last_updated') | list  %}
{{ sensor_lu_list }}

Any help or hint will be welcome.
TIA.

I have it. The problem was that last_changed attribute has to be compared with a datetime object. For this purpose timedelta() function can be used:

{% set time = now() - timedelta(hours=23) %}
{%  set sensor_ids_list = states.sensor | selectattr('last_changed', '<', time) | map(attribute='name') | list  %}
{{ sensor_ids_list }}

Hope this helps somebody else.

3 Likes

I’ve been playing with this.

First, I have an input_datetime to define the length of time that I want to check for but then I wanted to go further and have a separate sensor for various groups of sensors.

Is it there a way to only include those sensors with a specific device_class? Or can this only be done by including the sensors in a group - which wouldn’t be as flexible.

{% set delay_seconds = state_attr('input_datetime.not_updated_for_time', 'timestamp') %}
{% set time = now() - timedelta(seconds = delay_seconds) %}
{% set sensor_ids_list = states.sensor | selectattr('device_class', 'eq', 'temperature') 
                                       | selectattr('last_changed', '<', time) 
                                       | map(attribute = 'entity_id') 
                                       | list  %}
{{ sensor_ids_list }}

You can use this:

{% set delay_seconds = state_attr('input_datetime.not_updated_for_time', 'timestamp') %}
{% set time = now() - timedelta(seconds = delay_seconds) %}
{% set sensor_ids_list = states.sensor  | selectattr('last_changed', '<', time) 
                                       | selectattr('entity_id', 'search', 'temperature')
                                       | map(attribute = 'entity_id') 
                                       | list  %}
{{ sensor_ids_list }}

You could even pipe several |selectattr('entity_id', 'search', pattern)|.

I’ve found a more elegant way to do what you want:

{% set delay_seconds = state_attr('input_datetime.not_updated_for_time', 'timestamp') %}
{% set time = now() - timedelta(seconds = delay_seconds) %}
{% set sensor_ids_list = states.sensor | selectattr('attributes.device_class', 'eq', 'temperature') 
                                       | selectattr('last_changed', '<', time) 
                                       | map(attribute = 'entity_id') 
                                       | list  %}
{{ sensor_ids_list }}
1 Like

Reinventing the wheel.

Detecting stale sensors:

1 Like

Thank you, Taras. I hadn’t found it.