Why an availability template is important for energy template sensors

When defining a template sensor for use in the energy dashboard it is important to also use the availability template option. Without this you may see incorrect values in your energy dashboard.

For example, consider this template sensor that sums two energy sensors to obtain a total:

template:
  - sensor:
      - name: "Energy Total"
        unique_id: 094412db-6903-dead-beef-b40e0e41ea28
        device_class: energy
        state_class: total_increasing
        unit_of_measurement: kWh
        state: "{{ states('sensor.one') | float(0) + states('sensor.two') | float(0) }}"

If one of the source sensors becomes unavailable or unknown for some reason the total will drop in value. When the sensor becomes available again the total will increase. This increase will be incorrectly logged to the energy dashboard as actual energy used.

To prevent this we add an availability template:

template:
  - sensor:
      - name: "Energy Total"
        unique_id: 094412db-6903-dead-beef-b40e0e41ea28
        device_class: energy
        state_class: total_increasing
        unit_of_measurement: kWh
        state: "{{ states('sensor.one') | float(0) + states('sensor.two') | float(0) }}"
        availability: "{{ has_value('sensor.one') and has_value('sensor.two') }}"

Now if one (or both) of the source sensors become unavailable the total sensor value will also be set to unavailable.

Changing from unavailable to a value is not logged by the energy dashboard.

If using attributes you can use is_number instead of has_value, e.g.

availability: "{{ state_attr('sensor.one','energy')|is_number and has_value('sensor.two') }}"

There are other ways to construct the availability template, the important thing is that it must only evaluate to true when all your source sensors are reporting valid numeric state values.

NOTE: I used the simplest possible example here. If you only want to add two sensors you can do this in the UI using the Min / Max Helper from the Settings menu (set the State Characteristic option to ā€œSumā€) and it will take care of the availability for you.

The Home Assistant Cookbook - Index.

11 Likes

Here is an alternative Availability Sensor method for your consideration.

thanks for this, we should point to this wherever the question/issue arisesā€¦ and it does a lot.

btw, hereā€™s my example for calculating the unaccounted energy daily:

      - unique_id: ongemeten_energie_per_dag
        state: >
          {{states('sensor.energy_consumed_daily')|float(0) -
            states('sensor.gemeten_energie_per_dag')|float(0)}}
        <<: &energy_total
          unit_of_measurement: kWh
          device_class: energy
          state_class: total
        availability: >
          {{has_value('sensor.energy_consumed_daily') and
            has_value('sensor.gemeten_energie_per_dag')}}

ofc, you need to set up the 2 main entities, and everyone can do that as detailed as they would like, I have a lot setup via Powercalc integration for fixed and un smart-plugged devices.

Powercalc does all the work for you, only need to feed it with a device or a fixed value.

btw, having these availability templates make the ā€˜defaultā€™ requirement superfluous (when uses as a regular template, not when used as a trigger based template.

Iā€™ve never liked to set a default because it obfuscates the truth in case of issuesā€¦ this is better

      - unique_id: ongemeten_energie_per_dag
        state: >
          {{states('sensor.energy_consumed_daily')|float -
            states('sensor.gemeten_energie_per_dag')|float}}
        <<: &energy_total
          unit_of_measurement: kWh
          device_class: energy
          state_class: total
        availability: >
          {{has_value('sensor.energy_consumed_daily') and
            has_value('sensor.gemeten_energie_per_dag')}}

Iā€™ve also found the is_number() test to be useful for availability templates

      - unique_id: saldo_totaal_dag_energie_afname_of_levering
        state: >
           {{states('sensor.grid_energy_total')|float|abs }}
        attributes:
          phrase: >
            {{'levering' if states('sensor.grid_energy_total')|float < 0 else 'afname'}}
          saldo: >
            {{states('sensor.grid_energy_total')}}
        <<: *energy_total
        availability: >
          {{is_number(states('sensor.grid_energy_total'))}}
1 Like
  1. What is the learning of has_value filter not consistent in its output Ā· Issue #91607 Ā· home-assistant/core Ā· GitHub regarding the ā€œhas_valueā€ usage?

  2. According to 2023.4: Custom template macros, and many more new entity dialogs! - Home Assistant has_value ā€œonlyā€ filters unavailable and unknown - right? Is that really sufficient for an availability template? So far I always checked with several other states like:

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

I did not use the filter |has_value I used the function has_value() this does not have the same problem. And actually there is no problem. Marius is not using the filter correctly.

It should be:

{{ states('binary_sensor.boiler_on')|has_value }}

or:

{{has_value('binary_sensor.boiler_on')}}

Not:

{{ ('binary_sensor.boiler_on')|has_value }}

Yes it is sufficient I use it everywhere and have never had an issue.

Got it. Unless @Sir_Goodenough has good arguments to check for other states :slight_smile: Iā€™ll likely migrate all my availability templates to the way more simple has_value function.

If you use it in other places that for instance may not be available at startup, or that might be from a zigbee sensor that might go offline, etc.
I am actually testing ATM has_value to replace the ā€˜unknown or unavailableā€™ part of what I had, leaving the other 3 possibles.

is_number would not work in mine as it tests booleans and about every other kind of entity.

this might be outdated by edits, but sorry I missed it, somehow I didnt get a tag.

where in my examples do I use the incorrect syntax you paste there?

In multiple places you are using:

{{ ('binary_sensor.boiler_on')|has_value }}

That is incorrect. You need to use the states() function with the has_value filter, like this:

{{ states('binary_sensor.boiler_on')|has_value }}

Ornly if you use the has_value() function can you do:

{{ has_value('binary_sensor.boiler_on') }}

Hmm. I canā€™t find the templates you say I am using .
Do seem to recall I had made that mistake before, but not in this thread ? Odd.
just checked my complete config, but dont even use a has_value in either syntax at all on the binary_sensor.boiler_on

(I just like to know, because I can then correct a fluke)

rightā€¦

that is oldā€¦

I was looking in this topic, and checking my contributions hereā€¦

and yes, that was what I tried to remember, but couldnt find.

not sure why you would link to that though, as it wasnt part of this discussion at all?
anyways, glad weā€™ve got that out of the way.

Yes it was, in the post I was directly replying to:

1 Like