Template Sensor - what happens if the template doesn't resolve to anything?

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

image
Can I change the

          {% if ns.count == 0 %}
            {{ states('sensor.average_downstairs_temperature') }}
          {% else %}
            {{ (ns.value / ns.count) | round (1) }}
          {% endif %}

to

          {% if ns.count != 0 %}
            {{ states('sensor.average_downstairs_temperature') }}
          {% endif %}

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.

No, you’re not I’m just VERY guilty of multitasking when I didn’t even have enough time for one task and copying the wrong piece of code.

It should have been this to ‘fix’ my problem.

          {% if ns.count != 0 %}
            {{ (ns.value / ns.count) | round (1) }}
          {% endif %}

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.

image

Lovelace:

          - type: custom:mini-graph-card
            entities:
              - entity: sensor.dark_sky_current_temperature
                name: Outside
              - entity: sensor.average_downstairs_temperature
                name: Average Downstairs
              - entity: sensor.hall_temperature
                name: Hall
              - entity: sensor.kitchen_temperature
                name: Kitchen
              - entity: sensor.sitting_room_temperature
                name: Sitting Room
              - entity: sensor.back_bedroom_temperature
                name: Back Bedroom
              - entity: sensor.upstairs_hall_temperature
                name: Upstairs Hall
              - entity: sensor.loft_temperature
                name: Loft
              - entity: binary_sensor.above_horizon
                name: Night
                y_axis: secondary
                color: black
                show_line: false
                show_points: false
                show_legend: false
            line_width: 1
            points_per_hour: 4
            aggregate_func: min
            show:
              labels: true
              # labels_secondary: true
              # average: true
              extrema: true
            state_map:
              - value: 'on'
                label: 'Day'
              - value: 'off'
                label: 'Night'

Why are your sensors so unreliable?

What are you using?

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).

I’m open to other suggestions.

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.

So:

input_number:
  avg_indoor_humidity:
    min: 0
    max: 100
    unit_of_measurement: '%'
automation:
  - alias: Average Indoor avg_indoor_humidity
    trigger:
      platform: state
      entity_id: sensor.avg_indoor_humidity
    action:
      service: input_number.set_value
      entity_id: input_number.avg_indoor_humidity
      data_template:
        value: "{{ trigger.to_state.state }}"
sensor:
  - platform: template
    sensors:
      avg_indoor_humidity:
        unit_of_measurement: '%'
        entity_id:
          - sensor.kitchen_thermostat_humidity
          - sensor.foyer_relative_humidity
        value_template: >
          {% set h1 = states('sensor.kitchen_thermostat_humidity')|float(-1) %}
          {% set h2 = states('sensor.foyer_relative_humidity')|float(-1) %}
          {% if h1 >= 0 and h2 >= 0 %}
            {{ (h1 + h2) / 2 }}
          {% elif h1 >= 0 %}
            {{ h1 }}
          {% elif h2 >= 0 %}
            {{ h2 }}
          {% else %}
            {{ states('input_number.avg_indoor_humidity') }}
          {% endif %}

Of course, now I just realized I can use the Min/max Sensor instead, which is much simpler. :laughing:

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.

1 Like

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.

Just keep in mind that Min/Max sensor never changes to unknown even if all its entities become unknown. It just holds a valid numeric value.