I have a template binary sensor based on a weather forecast attribute:
template:
- binary_sensor:
- name: Regenradar
unique_id: '202210291555'
icon: |-
{% set x = this.state %}
mdi:weather-{{ 'pouring' if x is not none and x == 'on' else 'sunny' }}
state: "{{ this.attributes.mm > 0 or this.attributes.vorhersage == 'rainy' }}"
availability: |-
{{ blah }}
attributes:
vorhersage: "{{ state_attr('weather.forecast_home_hourly','forecast')[1]['condition'] |default('N/A') }}"
mm: "{{ state_attr('weather.forecast_home_hourly','forecast')[1]['precipitation'] |float(0) |default(0) }}"
The above state definition throws an error:
TemplateError('UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'mm'') while processing template 'Template("{{ this.attributes.mm|float(0) > 0 or this.attributes.vorhersage == 'rainy' }}")' for attribute '_state' in entity 'binary_sensor.regenradar'
Whereas, the following definitions don’t throw an error:
Because in one case you’re looking for an object. It throws an error on that object not existing or being ‘unavailable’ whereas your other two are templates that test in the first… Doesthis thing equal another thing and in the second is it greater than this other thing.
In both cases the absence of an object (effectively, null) does not equal ‘rainy’ it doesn’t exist. So it should return true. Also mm does not exist so it cannot be greater than 0 so I suspect that one returns false.
Could this mean that the given defaults in the attribute itself aren’t respected? I can’t see any difference between the attributes. Both are nested attributes of weather.forecast_home_hourly, both have fallback values and both are true.
The problem is that, during the start-up (when Home Assistant is starting after a boot), all those values are undefined for certain time and you might be trying to check for an attribute which is not available yet (not even with the default value).
This is a temporary condition. Probably after the start-up process your attributes will be all right, providing the default value and then no error anymore, but during the start-up it’s a special moment.
My guess is it’s due to a timing issue (mere microseconds that make the difference). In other words, even if state and attributes are processed in parallel, there’s no guarantee which one will be ready first (arguably the more complex template will take more time to complete so the simplest template finishes first).
You believe the attribute is calculated when it is requested, right? But I don’t think this is the case.
So, when the attribute is calculated, the default value will be used if the value is not available, however, if you try to use that attribute before it was calculated it won’t force the calculation, it will just be unavailable.
It is not the case.
While the attribute doesn’t exists it simply doesn’t exists. Something that doesn’t exists doesn’t have anything, not even a default value.