What to put in the else clause? No else clause? None? Something else?
In YAML, the availability template can be used. However I must repeat the state logic in availability, so it not great to have to repeat logic (not DRY).
It would be great that a template sensor’s state is unavailable if the state returned is None.
Perhaps this is just a documentation issue then - I spent at least two hours searching for answers in the docs, forums, and Reddit. I did not see a definitive answer. This thread was the closest I could find: How to handle unknown or unavailable states in template entities or automations - but it danced around a lot of aspects of this problem.
But that said, on restart of HA I was seeing exceptions when using none or leaving out the else clause. One example from my logs:
s6-rc: info: service legacy-services: stopping
2024-12-06 17:43:11.439 ERROR (MainThread) [homeassistant.helpers.event] Error while dispatching event for climate.ecobee to <Job track state_changed event {'climate.ecobee', 'sensor.ecobee_temperature_t6xz'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template<template=({% if has_value('sensor.ecobee_temperature_t6xz')
and has_value('climate.ecobee') %}
{% set upstairs =
states('sensor.ecobee_temperature_t6xz') | float %}
{% set current = state_attr('climate.ecobee',
'current_temperature') | float %}
{{ '%0.1f' | format(current*2 - upstairs) }}
{% else %}
none
{% endif %}) renders=8>: <RenderInfo Template<template=({% if has_value('sensor.ecobee_temperature_t6xz')
and has_value('climate.ecobee') %}
{% set upstairs =
states('sensor.ecobee_temperature_t6xz') | float %}
{% set current = state_attr('climate.ecobee',
'current_temperature') | float %}
{{ '%0.1f' | format(current*2 - upstairs) }}
{% else %}
none
{% endif %}) renders=8> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({'sensor.ecobee_temperature_t6xz'}) rate_limit=None has_time=False exception=None is_static=False>}>>>
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 677, in state
numerical_value = float(value) # type:ignore[arg-type]
ValueError: could not convert string to float: 'none'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 356, in _async_dispatch_entity_id_event
hass.async_run_hass_job(job, event)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 949, in async_run_hass_job
hassjob.target(*args)
~~~~~~~~~~~~~~^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1314, in _refresh
self.hass.async_run_hass_job(self._job, event, updates)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 949, in async_run_hass_job
hassjob.target(*args)
~~~~~~~~~~~~~~^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/template/template_entity.py", line 463, in _handle_results
self.async_write_ha_state()
~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1023, in async_write_ha_state
self._async_write_ha_state()
~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1148, in _async_write_ha_state
self.__async_calculate_state()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1085, in __async_calculate_state
state = self._stringify_state(available)
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1029, in _stringify_state
if (state := self.state) is None:
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 679, in state
raise ValueError(
...<5 lines>...
) from err
ValueError: Sensor sensor.ecobee_main_floor_temperature has device class 'temperature', state class 'measurement' unit '°C' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: 'none' (<class 'str'>)
I have tried both none and None. Does not seem to be a difference. I prefer using None. The errors have stopped at the moment. I’m not sure why as I did not change anything.
However, back to the WTH… It seems a template returning None for the state is the correct way and seems to work best. If it is the HA sanctioned way to do this, then a note in the template docs would be the solution to this WTH.
There may also be some undocumented behaviour or a bug around whether setting state class of the sensor causes this. As I play with this some more I will amend this WTH or create a bug if warranted.
None is the correct one. none is the test, and it should only be used in a test, i.e. x is not none
Well, you can’t set the value to None if it’s a numeric sensor state_class entity. That’s likely a feature request. I can look into adding it. IMO it should behave the way you describe, however I could see getting pushback from the dev team if I change the behavior.
If the sensor is numeric, i.e. it has a state_class or a unit_of_measurement , the state template must render to a number or to none .
It’s just that None will result in unknown only for state-based template sensors. Something is broken with trigger-based template sensors and None results in an error.