Prior to 0.36, I had a simple template sensor that looped over a list of sensor names, added them up and divided by the length of the list – simple!
It seems that with 0.36, this is no longer working and now only uses the last item iterated, as is to be expected with Jinja’s loop scope, it seems.
For the life of me, I can no longer write a template that takes a list of temperature sensors and generates an average output. It appears the “Sum” Jinja filter is the way to go but I cannot get my head around how to pull the state value as an attribute to use in “Sum”.
If anyone has ideas, or code, to get this extremely simple template sensor working, it would be much appreciated.
Thanks – your code is pretty much same as mine. Set a variable with 0 outside the loop, add to it from within and divide by length once iterating over the last item.
Just copied and pasted your full code from this thread and swapped the sensor names. Issue persists.
If you upgrade to 0.36, I’d expect your sensor to also report issues. In my case, because it divides by the (length + 1), the output was ~7ºc. Yours might look okay as sum will end up being 1 at the end of the loop.
Just for reference, here’s mine:
indoor_temperature:
friendly_name: "Indoor Temperature"
entity_id:
- sensor.living_room_thermostat_temperature
- sensor.temperatureandhumidity_1_1
- sensor.temperatureandhumidity_2_1
unit_of_measurement: "°C"
value_template: >
{% set sensors = ["sensor.living_room_thermostat_temperature", "sensor.temperatureandhumidity_1_1", "sensor.temperatureandhumidity_2_1"] %}
{% set output = 0 %}
{% for state in sensors %}
{% set output = output + states(state)|float %}
{% if loop.last %}
{{ (((output / sensors|length) * 2)|round(0)) / 2 }}
{% endif %}
{% endfor %}
Yup. Template is how I’ve been testing it (including yours).
Definitely didn’t see this behaviour pre-0.36. Might see what happens with 0.37 and re-evaulate as necessary.
As for rpitera’s option – that works, but it’s so simple that it’s messy. I’d have to manually update the sensor count, and specifically define the sensors. Mine and Daniel’s options automate it somewhat.
Yeah, that was partially my worry as that is how the loop scoping is advertised with Jinja.
Looks like me and a few others managed to catch a glimpse of an ‘issue’ that worked in our advantage.
If anyone has any ideas on how to achieve a similar loop without this scoping problem, it’d be appreciated.
I’ve come up with a solution, it’s not entirely as tidy as I’d like it to be but it works in 0.36.
Essentially, it’s just a sum filter applied to an array of the states of various temperature sensors and cuts out the loop altogether.
The second line’s multiply by 2 and divide by 2 is just to create a decimal that is either .0 or .5 similar to the standard temperature readings from a Nest thermostat.
{%- set data = namespace(entities=[]) -%}
{%- for state in states.sensor -%}
{% if 'power' in state.entity_id %}
{%- set data.entities = data.entities + [state.state | float] -%}
{% endif %}
{%- endfor -%}
{{ data | sum(attribute='entities') }}
but I am getting an ‘Unknown error rendering template’ error, thoughts?
{%- set data = namespace(entities=[]) -%}
{%- for state in states.sensor if 'power' in state.entity_id %}
{%- set data.entities = data.entities + [state.state | float] -%}
{%- endfor -%}
{{ data.entities | sum }}
If you wanted to calculate the average:
{%- set data = namespace(entities=[], qty=0) -%}
{%- for state in states.sensor if 'power' in state.entity_id %}
{%- set data.entities = data.entities + [state.state | float] -%}
{%- set data.qty = data.qty + 1 -%}
{%- endfor -%}
{{ (data.entities | sum) / data.qty }}
EDIT
One more variation, but only if all the desired sensors have their device_class set to power and use the same units (W or kW).
{% set x = states.sensor
| selectattr('attributes.device_class', 'eq', 'power')
| map(attribute='state') | map('float') | list %}
{{ (x | sum) / (x | count) }}
{%- set data = namespace(entities=[]) -%}
{%- for state in states.sensor -%}
{% if ('power' in state.entity_id and 'W' in state.attributes.unit_of_measurement) %}
{%- set data.entities = data.entities + [state.state | float] -%}
{% endif %}
{%- endfor -%}
{{ data.entities | sum }}