It’s checking if light’s current brightness value is equal to the previous value that it had set. If it isn’t then (someone/something external to the automation had changed it) the Template Condition reports false and the while stops looping.
- repeat:
while:
- condition: template
value_template: >-
{% set b = state_attr(light, 'brightness') %}
{% set b = (b/255*100)|round(0, default=0) if b != none else b %}
{{ repeat.index <= n and
( (sign == 1 and (b == none or b < end_pct)) or
(sign == -1 and (b != none or b|int(0) > end_pct)) ) and
(b | round(0, default=0) == start_pct + ((repeat.index - 1) * sign)) }}
The light only turns on and it halts/stops. So far I can confirm these two lines by themselves don’t cause any issues:
{% set b = state_attr(light, 'brightness') %}
{% set b = (b/255*100)|round(0, default=0) if b != none else b %}
So I think it’s down to this bit:
{{ repeat.index <= n and
( (sign == 1 and (b == none or b < end_pct)) or
(sign == -1 and (b != none or b|int(0) > end_pct)) ) and
(b | round(0, default=0) == start_pct + ((repeat.index - 1) * sign)) }}
This together with a slightly longer time-frames worked. I was testing it with 60 seconds, setting this to 180 seconds at least made everything work flawlessly. Works for me as I don’t intend to use this sort of a timeframe for transitions.
When manually switched off, the script will halt.
Final version:
fade_light_v2:
description: "Fades lights to a desired level over a specified transition period."
fields:
light:
name: Light
description: Entity_id of light.
selector:
entity:
domain: light
example: light.kitchen
end_pct:
name: End brightness Level
description: Integer value from 0 to 100 representing the desired final brightness level.
selector:
number:
min: 0
max: 100
step: 1
mode: slider
default: 50
example: "50"
transition:
name: Transition Time
description: Transition time for fading in seconds.
selector:
number:
min: 0
max: 1800
step: 1
mode: slider
default: 10
example: "10"
mode: parallel
sequence:
- variables:
start_pct: "{{ ((state_attr(light, 'brightness') | int(0))/255*100) | round(0, default=0) }}"
end_pct: "{{ end_pct | int(0) | round(0, default=0) }}"
delay_msec: >-
{{ ([100, (((transition / (end_pct - start_pct)) | abs) | round(3, default=0) * 1000) | int(0)]|sort)[1] }}
sign: "{{ 1 if start_pct < end_pct else -1 }}"
n: "{{ 1000 * transition / delay_msec | int(0) }}"
- repeat:
while:
- condition: template
value_template: >-
{% set b = state_attr(light, 'brightness') %}
{% set b = (b/255*100)|round(0, default=0) if b != none else b %}
{{ repeat.index <= n and
( (sign == 1 and (b == none or b < end_pct)) or
(sign == -1 and (b != none or b|int(0) > end_pct)) ) and
(b | round(0, default=0) - (start_pct + ((repeat.index - 1) * sign))) | abs < 3 }}
sequence:
- delay:
milliseconds: "{{ delay_msec }}"
- service: light.turn_on
target:
entity_id: "{{ light }}"
data:
brightness_pct: "{{ ([0, (start_pct + (repeat.index * sign)), 100]|sort)[1] }}"
What kind of lighting do you have that its brightness doesn’t match what it was set to?
My guess is whatever lighting integration you’re using experiences communication problems (‘flooding’) when the interval between successive commands is very short.
I’m trying to do the same thing as everyone else here but over long transition times (15m). I’m using the transition as a morning “sunrise” alarm. After running cleanly for 30 seconds or so, the script fails with:
Stopped because an error was encountered at 5 January 2023 at 07:00:37 (runtime: 36.88 seconds)
string indices must be integers
The script is called from an automation that is currently set to trigger at 7am weekdays. I’m passing in target brightness of 100% and a transition time of 900s, along with my light entity.
Where do I put this code? In my script.yaml with your inintal code or do I add this somewhere else. It is just I do not know where to put the fade out light code. I do not see where you say to put it.
We don’t know how your config is structured and whether you do everything in YAML or also via the UI. If you look at the script documentation, it’s telling you it must go under a singular script: key in your configuration.yaml, but if your config is split it could be different (packages can repeat keys). Do you have a script.yaml? Then it would be a yes (most likely).
Hey all, I modified ReanuKeeves01 script to fade lights slightly differently.
I found the script ReanuKeeves01 posted worked great except it only ever faded the light in ticks of 1%. This meant to go from 100% to 10%, you needed 90 ticks. Ticks are limited to a minimum of 100ms. Assuming this limit is a common smart light hardware limitation; mine didn’t change faster when I went below 100ms.
This all meant to go from 100% to 10%, the minimum transition time you need to put is 9 seconds. The fastest rate is 10% every 1 second.
I’ve updated the script to now always fade in the time you set on the transition. It does this by calculating the perfect brightness % tick and delay MS.
For example if you want to go from 100% to 10% in 4 seconds, it calculates that it needs to tick 3% every 133ms, and it fades at that rate without issue.
tl;dr This script works very well when you want to fade large % amounts quickly.
The updated script:
alias: Light Fader
description: Fades lights to a desired level over a specified transition period.
fields:
light:
name: Light
description: Entity_id of light.
selector:
entity:
domain: light
example: light.kitchen
end_pct:
name: End brightness Level
description: >-
Integer value from 0 to 100 representing the desired final brightness
level.
selector:
number:
min: 0
max: 100
step: 1
mode: slider
default: 50
example: "50"
transition:
name: Transition Time
description: >-
Transition time for fading in seconds. Tick rate of brightness % is
dependant on this and total brightness % traversed.
selector:
number:
min: 0
max: 1800
step: 1
mode: slider
default: 10
example: "10"
mode: parallel
sequence:
- variables:
start_pct: >-
{{ ((state_attr(light, 'brightness') | int(0))/255*100) | round(0,
default=0) }}
end_pct: "{{ end_pct | int(0) | round(0, default=0) }}"
delay_msec: >-
{% set min = (((transition / (end_pct - start_pct)) | abs) |
round(3,default=0) * 1000) %} {{ (min * ((100 / min) | round(0,
"ceil"))) | int(0) }}
tick_pct: >-
{{ ([1, (((start_pct - end_pct)|abs) / (transition * (1000 /
delay_msec)))|round]|sort)[1] }}
sign: "{{ tick_pct if start_pct < end_pct else tick_pct * -1 }}"
"n": "{{ transition * (1000 / delay_msec) | int(0) }}"
- repeat:
while:
- condition: template
value_template: >-
{% set b = state_attr(light, 'brightness') %} {% set b =
(b/255*100)|round(0, default=0) if b != none else b %} {{
repeat.index <= n and ( (sign >= 1 and (b == none or b < end_pct))
or (sign <= -1 and (b != none or b|int(0) > end_pct)) ) and (b |
round(0, default=0) - (start_pct + ((repeat.index - 1) * sign))) |
abs < 3 }}
sequence:
- delay:
milliseconds: "{{ delay_msec }}"
- service: light.turn_on
target:
entity_id: "{{ light }}"
data:
brightness_pct: "{{ ([0, (start_pct + (repeat.index * sign)), 100]|sort)[1] }}"
max: 10
@TimeBomb First off, I just want to say that I so appreciate all the effort that you put into this script!
And while I don’t at all want to take away from that, I think that I may have come across a potential bug that—just based on my Spidey-sense alone—miiiight potentially stem from a rounding issue somewhere?
Known-good scenario:
If I have a light that starts at 0% (off), and I set it to fade to 20% over a span of 10 seconds, that works as expected.
On the other hand, if I have a light that starts at 0% (off), and I set it to fade to 20% over a span of 11 seconds, then that doesn’t quite seem to work?
In this scenario, the lamp fades from 0% to 11%—and then it stops.
@TimeBomb continuing my post above about these scripts not working any longer in the latest HA, I switched to your script on HA 2023.6.2 and it also has all these errors which used to not occur in prior HA releases. Curious if you have any insight.
Example error:
Logger: homeassistant.components.automation.kitchen_lights_on_with_no_cloud_cover_already_on_adjustment
Source: components/automation/init.py:580
Integration: Automation (documentation, issues)
First occurred: 9:06:54 AM (1 occurrences)
Last logged: 9:06:54 AM
Error while executing automation automation.kitchen_lights_on_with_no_cloud_cover_already_on_adjustment: ZeroDivisionError: division by zero
Morning. On the road but didn’t want to not reply. My setup worked fine previously, but apparently something over updates stopped working. I use a new script recommended by @123 and it has been flawlessly and is more versatile than these previous ones.
Hello @123, first off thank you very much for all your work on this, and of course, thank you to mrsnyds for starting all this. I really hope I can start fading in and out some of the lights in my house.
I’m slowly figuring out how to implement this script into my HASS. I got as far as adding the script you provided to my scripts.yaml. I see it under services, but for some reason, the transition time differs from your screenshot and shows actual 24 hours time with AM/PM rather than a range of determined time.
I don’t know enough about scripts in HASS to make any changes without potentially breaking it, but is there a way to fix this?
I suggest you consider using something created more recently, for example this script has more functionality and currently gets updates from its author (handcoding) and technical support: