How to get a list filtering another list in a template?

I am trying to build an automation that sends me a notification if any of the entities inside a group of temperature sensors is above a given value.

First I am trying to build the template for it but I just can find how to create a new list from my filtered values.

Given this

{% set temp_sensors =  expand('sensor.home_inside_temperature_sensors') | map(attribute='entity_id') | list %}
{% set max_temp = 1 %}
{{ temp_sensors |   list }}

{% set filtered_list = [] %}
{% for item in temp_sensors %}
  {% if (states(item) | float) > 16 %}
    "{{states(item)}}"
  
    {% set filtered_list = filtered_list + [item] %}
  {% endif %}
{% endfor %}

{{filtered_list}}

I get this output

['sensor.2_hobbyraum_keller_temperature',
'sensor.1_abstellraum_keller_temperature',
'sensor.3_technikraum_keller_temperature',
'sensor.room_temperature',
'sensor.switchbot_temp_sala']

    "19.6"

    "20.5"
 
    "19.2"
    
    "21.6"
  
    "22.0"
  

[]

As you see the filtering is working correctly but {% set filtered_list = filtered_list + [item] %} is not working.

I also tried with {% set _ = filtered_list.append(item) %} but it is rejected.

I can not wrap y head around how to do this.

I would be grateful for any tip!

Thanks!

{% set entities = state_attr('sensor.home_inside_temperature_sensors', 'entity_id') %}
{% set values = entities | map('states') | map('float',0) | list %}
{% set z = zip(entities, values) | selectattr(1, 'gt', 16) | list %}
{{ z | map(attribute=0) | list }}

The result is a list containing the entity_id of all sensors (who are members of sensor.home_inside_temperature_sensors) whose state value is greater than 16.

Let me know if you need help to modify it to meet any other requirements you have.


NOTE

The reason why filtered_list fails to report anything is because of Jinja2’s scope rules. When you change a variable’s value inside a Jinja2 for-loop, that value remains local to the for-loop. In other words, that value doesn’t exist outside of the for-loop.

You would need to use namespace to ensure the variable’s value is preserved outside the for-loop.

{% set ns = namespace(filtered_list = []) %}
{% for item in temp_sensors %}
  {% if (states(item) | float) > 16 %}
    {% set ns.filtered = ns.filtered_list + [item] %}
  {% endif %}
{% endfor %}
{{ ns.filtered_list }}

Or like this:

{% set ns = namespace(filtered_list = []) %}
{% for item in temp_sensors if (states(item) | float) > 16 %}
    {% set ns.filtered = ns.filtered_list + [item] %}
{% endfor %}
{{ ns.filtered_list }}

Or you can forego the use of a for-loop and use zip as shown in my example.

Wouldn’t you want the select('has_value') on entities… otherwise you might get deletion errors when zipping.

1 Like

Thanks for bringing it to my attention.

For simplicity, I removed it and will let float(0) take care of non-nominal values.

WOW! thanks I am pretty sure I would not arrive to that solution without expending some weeks on the process.

Thanks a lot!

1 Like