Gold standard: avoid template sensors falling to zero

For many template sensors (used for statistics or the energy dashboard) it is important to avoid their values falling to zero, especially/e. g. if this is not possible in reality (e. g. because it’s a total_increase sensor or whatever).

While I managed to set up percentage sensors correctly (they do basic calculations - basically transferring absolute sensor values to percentage values), I struggle with others and I’m wondering what’s the “one size fits all” solution, the gold standard of achieving this.

E. g. this one is based on a group. On every reload of groups this sensor falls to zero…

grafik

…even I meanwhile have double and triple checks to avoid this aaaaand an availability template:

template:
  - sensor:
      - name: Problematische Entitäten (ignorierte) Anzahl
        # entity_id: problems_any_ignored_count
        unique_id: xxxxxx-something-xxxxxx
        state_class: total
        icon: mdi:numeric
        #state: "{{ expand(states.group.problems_any_ignored) | length }}"
        state: >-
          {% if (expand(states.group.problems_any_ignored) | length) | int(0) == 0 %}
          {% else %}
            {% if (expand(states.group.problems_any_ignored) | length) | int(0) > 0 %}
              {{ expand(states.group.problems_any_ignored) | length }}
            {% endif %}
          {% endif %}
        availability: "{{ (expand(states.group.problems_any_ignored) | length) | int(0) > 0) }}"

…but still, every group reload (which is just ONE but a nice trigger cause I can provocate it nicely) gives this in the database (states table) and of course renders graphs unusable:

state_id 	domain 	entity_id 							state 	attributes 	event_id 	last_changed 				last_updated 				created 	old_state_id 	attributes_id
65885671 	NULL 	sensor.problems_any_ignored_count 	31 		NULL 		67523426 	2022-06-01 00:09:12.928600 	2022-06-01 00:09:12.928600 	NULL 		65885652 		478
65885652 	NULL 	sensor.problems_any_ignored_count 	0 		NULL 		67523407 	2022-06-01 00:09:12.409461 	2022-06-01 00:09:12.409461 	NULL 		65885219 		478 

What’s wrong here? Maybe the default of the int (int(0))?

But I’m not into a solution for this specific issue. I’m interested in general:
how do you template your sensors when it’s important to avoid them switching to zero?

Well I’m not sure but to start your availability template is going to have an error every time you reload groups. When you do states.group.problems_any_ignored like that then if group.problems_any_ignored doesnt exist you get an exception (and it won’t exist while groups are reloading) since you’re trying to access a non-existent key of an object.

Its much safer to replace your expands with this

expand('group.problems_any_ignored')

It does the same thing but won’t have an exception if the group doesn’t exist.

I dont know for certain if that will fix your issue since I honestly don’t know what happens if your availability template has an exception. I use those to prevent exceptions and go to great lengths to avoid causing them there.

Thanks, I adjusted all group expand syntax. Unfortunately, that makes no difference. So I’m still lost (but at least learned a bit already).

Had a similar problem and fixed it by applying the outlier filter:

I had a scrape sensor that would return zero every once in a while, because it could not get the data from the website.
With the filter i let the algo look at the last 3 values and if the new value is more than xxx away from that value it is ignored and the sensor does no longer return zero.

That’s an interesting filter.

Just wanted to follow-up:

  • The original issue has been resolved with a HA Core update meanwhile (it switches to unavailable or unknown now during reload/initialization), so the sensor doesn’t “fall to zero” anymore, even when reloading:

And in general I learned it’s good practise to use availability templates to filter undesired states (in case they are static and 100 % unwanted/impossible, like in my original use-case the value 0 (zero)):

availability: "{{ ((expand('group.problems_any_ignored') | length) | int(0) > 0) }}"

Checking unavailable etc.:

availability: "{{ states('sensor.abc') not in ['NULL', 'null', 'none', 'undefined', 'unavailable', 'unknown', ''] }}"

There’s also an integration providing this as a custom template integration using HACS: