Availability template ignored?

I have again something I scratch my head about.
Maybe one of you can enlighten me what I am doing wrong.

I have this pretty simple Template Sensor:

# ---- Total Power Consumption ---- #
- sensor:
    - name: "Total Power Consumption"
      unit_of_measurement: W
      device_class: power
      state_class: measurement
      state: >
        {{ float(states('sensor.netz_total_power_consumed')) + float(states('sensor.pv_anlage_power'),0) - float(states('sensor.netz_total_power_returned'),0) }}
      availability: >
        {{ is_number(states('sensor.netz_total_power_consumed')) }}
# ---- Total Power Consumption ---- #

However I get the following Error in the Logs:

Logger: homeassistant.components.template.template_entity
Source: components/template/template_entity.py:424
Integration: Template (documentation, issues)
First occurred: 02:01:37 (1 occurrences)
Last logged: 02:01:37

TemplateError('ValueError: Template error: float got invalid input 'unavailable' when rendering template '{{ float(states('sensor.netz_total_power_consumed')) + float(states('sensor.pv_anlage_power'),0) - float(states('sensor.netz_total_power_returned'),0) }}' but no default was specified') while processing template 'Template<template=({{ float(states('sensor.netz_total_power_consumed')) + float(states('sensor.pv_anlage_power'),0) - float(states('sensor.netz_total_power_returned'),0) }}) renders=25004>' for attribute '_attr_native_value' in entity 'sensor.total_power_consumption'

How can that be?
For 2 Values there is a default defined, the third value is checked via the availability template, that it actually contains a number.
So I would expect the Sensor to become unavailabel if sensor.netz_total_power_consumed got invalid input ā€˜unavailableā€™, but I would not expect this Error message.

Am I thinking wrong?

Not all of your float functions have defaults, the first does not, and you are not checking the availability of all sensors used in the template. Try this:

      state: >
        {{ states('sensor.netz_total_power_consumed')|float(0) + 
           states('sensor.pv_anlage_power')|float(0) - 
           states('sensor.netz_total_power_returned')|float(0) 
        }}
      availability: >
        {{ has_value('sensor.netz_total_power_consumed') and 
           has_value('sensor.pv_anlage_power') and 
           has_value('sensor.netz_total_power_returned')
        }}

Your observation is correct and its intentional.

When sensor.netz_total_power_consumed has a non-numeric Value (i.e. because Connection to the Sensor is lost) the Sensor should become unavailable. If any of the other two Sensors become unavailable it should instead just assume the value to be 0, hence the default in the float() function.

So the question remains:
Why am I getting this Error Message then?

Are you sure youā€™ve reloaded the template entities (or restarted) since you last made changes? Iā€™m unable to replicate your issue. I can only replicate the error if the availability template renders true. There are no errors when the the availability template renders false.

When I add not(ā€¦) around the availability template then I get the error to show up. You might try that and see if there is any change. Make sure to clear the log so you are not seeing old errors.

ā€¦but itā€™s also probably good practice to make sure the state template renders correctly in all scenarios anywayā€¦

Thereā€™s a bug in has_value, where it doesnā€™t properly cause availability to update, a fix is coming whenever the PR is pushed through. has_value as a function (by some fluke) works correctly. However, when used as a filter, it does not work correctly.

If this is a trigger based template, the availability is not resolved prior to the state template.

If this is a non-trigger based template entity, then availability is always resolved first and you will not get this error. If you are getting this error, that means the template isnā€™t loaded into the system properly.

As a sidebar, the absence of a unique_id will cause YAML reloading to add an additional sensor instead of overwriting your original. Meaning you will fix your template but your old template will still error.

Make sure you restart to avoid that when making changes. And I advise you to add a unique_id so that you can reload properly without creating a new entity.

The Sensor above is pretty old and works reliably.
But as I am in the process of wheeding out Errors and Warnings and making my logic more robust and streamlined the Error message posted above sparked my interest for two reasons:

a) I dont understand why it is getting thrown in the first place.
b) the Setup of the Sensor in question is fairly common in my config, so this could affect others as well.

So yes, reloading changes / restarting Home Assistantā€¦ I am accutely aware of that :grin:

@petro
Thanks! That is indeed shining more light on this.
It is a Template Sensor, so afaik it should get evaluated whenever one of its Values schanges and indeed the availability should be evaluated before the actual value template.

Now here it comesā€¦ the time this Error was dropped does not allign to a restart of HA. So imho it SHOULD have been loaded properly into the system all the time.
But it might be (likely even) that the availability template {{ is_number(states('sensor.netz_total_power_consumed')) }} briefly became false at this point in time.
But to my understanding this should result in the state of this template sensor to transition to unavailable and NOT to the Error complaining about input 'unavailable'.
Am I right?

Or could it be, that there is a time gap between evaluating the availability template (input value still a number) and evaluating the state template (value has turned to ā€˜unavailableā€™ in the meantime)?

EDIT: and thanks for the hint with the UniqueIDsā€¦ I will look into this, but this likely turns into a major project giving all my Sensors unique IDs.

To be honest, I think youā€™re chasing nothing here and the error is a result of you reloading template entities.

:thinking:

I cannot completely exclude that I reloaded the Config at that point in timeā€¦

But can you confirm, that my expectation is correct:

Speaking about a Template Sensor, if the availability template evaluates to false, the state template will NOT be evaluated and instead the sensor will return ā€˜unavailableā€™?

If you reload template entities in yaml, entities without unique_id (Yours), will be duplicated. Youā€™ll have the OLD template entity and the NEW template entity in your system at the same time. The old one would error, where the new one wouldnā€™t.

Correct.

FWIW, expand misbehaves the same way; works as a function but fails as a filter (despite the documentationā€™s claim that it can be used either way).

I reported it ages ago but nobody has been interested in fixing it. Works correctly as function or filter in the Template Editor but not when used in, for example, a Template Sensor.

To be clear, I havenā€™t installed 2023.9 so I havenā€™t confirmed if the bug still exists in the latest release.

IIRC, this was fixed.

I thought it was fixed awhile ago. @rccoleman put in a fix that didnā€™t make it through, when talking with him he alluded that someone else fixed it a different way.

Thx!
@petro

Great! Iā€™ll test it today (in 2023.8).

Might have been nice if the corrective PR had been used to close my long-standing Issue ā€¦ but thatā€™s just paperwork.

Well, I tagged rob. Iā€™m going off second hand info on this, Iā€™m not sure itā€™s actually fixed.

Thanks for the tip about has_value. Just as well Iā€™ve only been using it as a function.

I just ran a quick test and it does appear to be fixed. Iā€™m pretty sure that this would have failed the config check earlier and it works now:

template:
- sensor:
  - name: expand_test
    state: "{{ ['switch.fr_table_lamp']|expand|map(attribute='state')|list|first }}"
1 Like