I wanted to post a summary of this old thread because it helped me fix a problem, but it took a long while to figure out how. Everyone seemed to be talking at crossed purposes. Hopefully this will help someone else get to a solution quicker.
The problem
Davinci’s original problem involved sensors that were supposed to return numeric values, but actually returned strings like "unknown"
or "unavailable"
. These values then caused errors when used in template functions that expected inputs that could be converted into numeric values.
Digeridrew and Petro suggested adding default
parameters into the functions that threw the errors, but this didn’t seem to make sense to Davinci: using a default value of the correct type makes the error go away, but then means that the template that uses those functions will produce a valid but incorrect answer. Defaulting to the string "unknown"
just produces more errors when the template is expected to output a number.
Petro and Dbrunt also mentioned using availability:
templates. If these templates evaluate to a value like false
, the sensor will have the state "unavailable"
and its icon will be greyed-out in the UI. You can use these to flag a template entity as unavailable when the values it depends on are unavailable or unknown. However, this doesn’t solve the whole problem either. Even when the template sensor is flagged as unavailable, it will still throw errors if "unknown"
or "unavailable"
values are passed into numeric functions in the template.
The Solution
To fix this issue robustly, you need to use both default values and availability:
templates at the same time. In an ideal world, if the availability:
template flagged the sensor as unavailable, then Home Assistant wouldn’t try to render the state:
template, and you wouldn’t get errors. Unfortunately, it seems to still process the state:
template, even though it will discard its output. This means you need to use defaults in any numeric function in the state:
template that could potentially receive an unexpected string value like “unknown” or “unavailable”. Similarly, if you are expecting JSON inputs, the state:
template needs to handle missing data elements without throwing errors, e.g. by checking that objects exist before trying to access their attributes.
You then need to set the availability:
template to check for bad inputs to your template, so that the output of the state:
template will be discarded and replaced by "unavailable"
, rather than a plausible but wrong value based on default inputs.
For me, something like this worked:
template:
sensor:
- name: Test Sensor
unit_of_measurement: "%"
state_class: measurement
availability: |-
{{ states("sensor.unreliable_sensor") != "unavailable"
and states("sensor.unreliable_sensor") != "unknown" }}
state: |-
{{ states("sensor.unreliable_sensor") |float(default = 100) / 100 }}
Remember that even once you have set this up properly, if your template sensor was supposed to output a numeric value rather than a string, you will still have to make sure that any automations or other templates that it is used in can also handle receiving "unavailable"
as their input.