# For loop in template? Calculating a mean using a certain threshold

I want to create a template to get the mean temperature of certain sensors, but only include sensors that are above a certain reference threshold.
Here’s what i’ve come up with, but it always returns ‘0’.

``````          {% set total_temp = 0 %}
{% set num_sensors = 0 %}
{% set reference_sensor = states('sensor.house_actual_setpoint') %}
{% for sensor_id in ['sensor.28_42faa80d0000_temperature', 'sensor.28_d124a80d0000_temperature', 'sensor.28_2c3949f6293c_temperature', 'sensor.28_f98b49f6b23c_temperature', 'sensor.28_477649f63e3c_temperature', 'sensor.28_1d2449f6d33c_temperature'] %}
{% if states(sensor_id) | float > reference_sensor | float %}
{% set total_temp = total_temp + states(sensor_id) | float %}
{% set num_sensors = num_sensors + 1 %}
{% endif %}
{% endfor %}
{% if num_sensors < 1 %}
{% set num_sensors = 1 %}
{% endif %}
{{ (total_temp / num_sensors)  | round(1) }}
``````

Lots of problems with that.

1. Doing for sensor_id creates a variable, not an entity, so there is no states(sensor_id).
2. You cannot pull out variables in a for loop like that, you need to create a namespace. The inner loop is a different scope than the outer loop so all the outer loop sees is 0, which is why the answer is always 0.

For testing use integers instead of entities in the developer - templates tab to get your logic right.
You should be able to do this without the loop completely using a filter statement against your list. and the sum() and count() filters.
Give me an hour I could do it, but someone here will probably whip that up on the fly.

Copy-paste the following into the Template Editor and confirm it produces the correct result.

``````{% set reference_sensor = states('sensor.house_actual_setpoint') | float(0) %}
{% set sensors = ['sensor.28_42faa80d0000_temperature', 'sensor.28_d124a80d0000_temperature', 'sensor.28_2c3949f6293c_temperature', 'sensor.28_f98b49f6b23c_temperature', 'sensor.28_477649f63e3c_temperature', 'sensor.28_1d2449f6d33c_temperature'] %}

{% set s = sensors
| map('states')
| reject('in', ['unavailable', 'unknown'])
| map('float', 0)
| select('gt', reference_sensor)
| list %}

{% set total_temp = s | sum %}
{% set num_sensors = s | count%}
{% set num_sensors = iif(num_sensors < 1, 1, num_sensors) %}

{{ (total_temp / num_sensors)  | round(1) }}
``````

Be advised that you can reduce it to this:

``````{{ ['sensor.x', 'sensor.z', 'sensor.y', 'sensor.28_f98b49f6b23c_temperature', 'sensor.28_477649f63e3c_temperature', 'sensor.28_1d2449f6d33c_temperature']
| map('states')
| reject('in', ['unavailable', 'unknown'])
| map('float', 0)
| select('gt', states('sensor.house_actual_setpoint') | float(0))
| average(0)
| round(1) }}
``````

It appears it does, yes. Thanks a lot!

1 Like