Look at the very first post pinned at the top of the forum telling you how to ask a good questionā¦ Start with a title that actually says what you need help with and go from thereā¦
Thatās exactly what I needed. Someone to explain the given outputs. If it had to be more specific then the title would have contained the entire post.
I donāt have insight into how the is_state_attr function performs its comparisons but itās clear it doesnāt like comparing to a null value. In contrast, the equivalence operator == handles a null value properly.
Your second example, involving true and false, works as one would expect. A boolean value (true/false) is never a null value so is_state_attr handles it correctly.
EDIT
The function is_state_attr is located in Home Assistantās template.py file. I believe this line of code is responsible for how it handles a comparison with None (null value).
return attr is not None and attr == value
It returns a result but only if its notNone (except in this case, it isNone so it returns nothing).
The title should capture the essence of your question: Why does None appear to be handled inconsistently?
I may have worded it that way had I realized that (None handled inconsistently unlike True) before submitting the question. As you would notice, I only observed that after results of further investigation (my second post).
Edit: Nevertheless, I will try to use better titles next time.
Null value is no value which isnāt quite the same as unknown value. It may sound like quibbling about semantics but there is a difference. If I havenāt been able to acquire a value then itās reported to be unknown (a string). If I acquired it and itās null then itās reported to be None (a constant).
FWIW, when Home Assistant reports unknown thatās a string value. Hereās an example of an entity with an unknown state. When compared to the string 'unknown' it evaluates to True. Itās False when compared to unknown (thereās no constant called unknown) or to None (because itās not null; its value is ā¦ unknown).
The answer is in the code. Basically, is_state_attr checks attr is not None, which guarantees that it will always return False if the value is None. Your check using == bypasses that extra condition.
I donāt see this mentioned in the documentation, so it probably needs to be updated to mention that behavior.
I think the is_state_attr function is dealing with a ācorner-case situationā. Hereās what I mean:
is_state_attr calls the state_attr function with this line:
attr = state_attr(hass, entity_id, name)
The state_attr function gets the entity with this:
state_obj = _get_state(hass, entity_id)
Then, if state_obj is not None, it proceeds to get the attributeās value and returns it to is_state_attr.
if state_obj is not None:
return state_obj.attributes.get(name) # if attribute value is None, it returns None
However, and hereās the interesting part, is state_obj is None then it immediately returns None to is_state_attr (which, in turn, reports False). Effectively, None is used like a flag to indicate the entity_id it received doesnāt exist.
The ācorner-case situationā is if the entity does exist but has a value thatās None. The following two lines get executed and the attributeās true value, None, is returned to is_state_attr.
if state_obj is not None:
return state_obj.attributes.get(name)
In other words, the attributeās legitimate value, None, is misinterpreted to be the flag thatās used when indicating the entity_id is non-existent.
Not to say that I agree or disagree with the code, but I interpret the logic more like a shortcut - if entity_id does not exist, then attributes (and values) also do not exist.
The resolution for is_state_attr() is handled by this line of code:
return attr is not None and attr == value
attr contains the value inside the attribute. So when attr is None, that section of the if statement resolves to false. Even if attr == value, the first section of the return statement resolves false, so no matter what, youāll get false if the attribute is null/None.