I have a template sensor to take the average temperature across rooms. Sometimes it seems there are occasions when none of my temperature sensors are available* in which case the divisor in the average calculation is zero. HA handles this gracefully by making the average zero but clearly this is not what I want so I was wondering what would happen if my if...then...else never resolved?
i.e. Can I have in a sensor template with no else?
Here is my sensor which currently doesn’t work as I would like,
average_downstairs_temperature:
friendly_name: Average Downstairs Temperature
entity_id:
- sensor.hall_temperature
- sensor.kitchen_temperature
- sensor.sitting_room_temperature
- sensor.back_bedroom_temperature
value_template: >
{% set entities = ['sensor.hall_temperature',
'sensor.kitchen_temperature',
'sensor.sitting_room_temperature',
'sensor.back_bedroom_temperature'] %}
{% set time = as_timestamp(now()) %}
{% set ignore_recent = 120 %}
{% set ignore_old = 600 %}
{% set ns = namespace(count=0, value=0) %}
{% for e in entities %}
{% set domain, object_id = e.split('.') %}
{% set s = states[domain][object_id] %}
{% if s.state is defined and
s.state is not none and
s != 'unknown' and
s != 'unavailable' and
s != '' and
((time - as_timestamp(s.last_updated)) < ignore_recent or
(time - as_timestamp(s.last_updated)) > ignore_old) %}
{% set ns.count = ns.count + 1 %}
{% set ns.value = ns.value + s.state | float %}
{% endif %}
{% endfor %}
{% if ns.count == 0 %}
{{ states('sensor.average_downstairs_temperature') }}
{% else %}
{{ (ns.value / ns.count) | round (1) }}
{% endif %}
unit_of_measurement: °C
and have the sensor simply remain unchanged when ns.count==0?
*For those interested, the problem seems to occur sometimes at or just after a restart (I guess that is a random/unlucky timing thing) and strangely it always happens when my automated snapshot takes place at 3am. It seems like during a snapshot sensors behaviour changes.
To specifically answer that question the answer is yes you can leave out the ‘else’. But if the ‘if’ portion doesn’t return a value it will generate an error in the log. It’s not the end of the world and won’t cause any other issues except for the error.
But what doesn’t make sense is that what you have should return the current value of the sensor if the count is zero. And that should result in…
and I don’t think this will fix your issue…
since that will cause the sensor to remain unchanged if the count is > 0.
Unless I’m misunderstanding what you want or what the problem is.
And in light of what you have told me this should ‘fix’ it albeit with errors.
But I am in agreement. I don’t know why my original code didn’t work.
For the record here is part of my graph card showing that none of the sensors look out of place when the average freaks out.
They aren’t unreliable. That’s the point. (They are Xaomi Bluetooth reporting to ESP32). But my average temperature sensors behaves weirdly sometimes (it looks like) at HA start and always during an automated snapshot.
The only thing I could think of was that for some reason it was dividing by zero (i.e. HA had no value for any sensor).
Interestingly, I just ran into a similar situation. I wanted to have the average of two humidity sensors. I tried, at first, the simple solution of using the previous value of the template sensor if the others weren’t valid yet. But I got the same results as you saw – “spikes” of zero at restart.
My solution was to save updates of the sensor to an input_number. This entity will be saved/restored over restarts. Then I use that value when the inputs aren’t valid.
Of course, now I just realized I can use the Min/max Sensor instead, which is much simpler.
But, since you’re not just taking the average (you’re also weeding out too new or too old values, too???), you probably can’t use the min_max sensor. But maybe you can use an input_number like I did to solve the “zero at startup” problem.
Yes, I considered that too. Seems like a real fudge though…
And yes, thanks to @tom_l (EDIT: I think it was tom_I, but I just realised it wasn’t in this thread!) I know that the max/min sensor also does average so I might just go with that. Weeding out the old values were just for if and when the battery dies and I don’t notice, and weeding out the too new ones was just to reduce the load as my sensors, it seems, can sometimes update several times a minute.