Changes to "|default(0)" in latest version?

I just updated to 2023.11 and having so many issues with broken automations and blueprints.

Among them is this:
states.light.bedroom_light.attributes.brightness|default(0) => This now returns “None”

I’m pretty confident that this code used to return a 0 value in the previous version.

It seems I can change |default(0) to |int(0) to fix the problem, but it’s annoying that this would suddenly break, and I have to fix a number of places. It literally broke every light automation in my house.

Is no one else seeing this?

default filter is used to handle undefined variables. In 2023.11 light attributes were changed so they always exist even if the light is off. https://github.com/home-assistant/core/pull/101946 When the light is off, instead of becoming undefined, the attribute values are set to None.

You can see in the PR comments it was flagged as a breaking change, but it looks like it never made it into any release notes or blog.

2 Likes

This is a change for the better. A whole lot of people get tripped up by the brightness value not existing when the light is off. It is unfortunate that you have to change your config because of this change but using the “find and replace” function of any text editor should make short work of it.

2 Likes

Thank you both for the replies and for the context.
The change does make sense, though it really should be in the patch notes (which I did read).
Ideally, with a warning to people using |default(0) that it won’t work any more for lights.

For anyone else coming across this topic, working with brightness values in a list was a bit less intuitive to solve.
I needed to add the bold line to make this work again:

{% set lights = ( states.light.light1, states.light.light2, states.light.light3 ) %}

{{
lights
| map(attribute='attributes.brightness', default=0)
| map('replace', 'None', 0)
| map('multiply', 1/255*100)
| map('int') | list | join('%, ')
}}%

The HA docs also recommend against using states directly. To access an attribute you would usually use state_attr('light.bedroom_light', 'brightness'), which would have returned None from the start.

1 Like

Thank you for the advice.

This was some older code before I had learnt about the recommendation to use state_attr, but actually the outcome is the same regardless of which approach is used, so unfortunately it doesn’t solve the problem here.

Before 2023.11:
{{ states.light.lightname.attributes.brightness|default(0) }} => 0
{{ state_attr('light.lightname', 'brightness')|default(0) }} => 0

After 2023.11:
{{ states.light.lightname.attributes.brightness|default(0) }} => None
{{ state_attr('light.lightname', 'brightness')|default(0) }} => None

You’re right, it did report 0 when the light was off.

Here’s how it behaves in version 2023.10.5.

Example 1

The light entity exists and is off (in other words brightness attribute doesn’t exist).

Example 2

The light entity exists and is on.

Example 3

The attribute doesn’t exist (same result as when the light is off).

Example 4

The entity doesn’t exist.


Now that the brightness attribute is defined even when the light if off, the default filter is skipped and the brightness attribute’s value is reported (even though that value is null).

2 Likes

Correct. My comment wasn’t to say that using state_attr would solve your problem, but that if you were using it to start with you would not be experiencing a breaking change, since it would have always returned None. Those users using state_attr in their templates won’t see any difference due to this release.

1 Like

Not quite true:
https://www.home-assistant.io/docs/configuration/templating/#states

Suggestion:

{% set lights = [ 'light.light1', 'light.light2', 'light.light3' ] %}
{{ expand(lights)
    | map(attribute='attributes.brightness', default=0)
    | map('replace', none, 0)
    | map('multiply', 1/255*100)
    | map('int')
    | map('regex_replace', '$', '%')
    | join(', ')
}}

This is an incredibly frustrating breaking change. It broke a 1000 line pyscript file I wrote in many places.

Moreover, the idea that you could fix this with a “find and replace” is just silly. There are myriad ways people could have been relying on the old behavior in templates.

I’m so tired of my setup breaking once every couple months.

1 Like