UPDATE 2024-09-24
This appears to get getting some attention so I’ve made it easier to install using a script blueprint as well
Installation
- Create datetime helper for the time this is to be triggered (Target finish time - time for all steps)
- Import the script blueprint
- Create a script from the script blueprint (Only needs to be done once. Can be reused in many automations)
- Import the automation blueprint
- Create the automation from the automation blueprint and use the script and datetime helper created above in the automation
UPDATE 2024-09-13
New version in the post below
Original Post Below
[Removed Rant]
Basically it contains 2 components. The first component is a script that can be executed many times in series to change the rates of the 2 main settings, mireds and brightness. By running it many times in series you get get a more parabolic effect. I added this feature because I could visually detect changes in brightness more at lower values. Below is an example of this. You can see the points of which the values change.
The second component is an automation that executes the script one or more times in series with different values for each execution. It is here that you can add your own pre and post execution steps if desired.
Detailed Explaination of Script
The script expects to be kicked off with parameters defined. If the target light or light group is off, all values of the parameters will be used. If the target is already on, its current brightness and mired values will be used as the starting values. It has been designed this way so the script can create the more parabolic like curve you can see above.
If you turn off the light at any point while the script is running, the script will end. However, you have the script chained in the automation to achieve the parabolic curve, you will need to check that the light is off before executing the script again or it will just start up again with the values defined in the script instantiation.
The script also allows for defining how long to take to get from start to finish values and how many steps per minute to take to get there. The script will also turn off the light after the ‘Light Timeout’ period. Setting this value to 0 will disable the timeout, and this is how you can chain executions of the script together to get the desired parabolic curve effect.
alias: Lamp Wake Up
sequence:
- service: light.turn_on
data:
brightness: "{{ min_brightness }}"
color_temp: "{{ max_mireds }}"
target:
entity_id: "{{ target_light }}"
- repeat:
until:
- condition: or
conditions:
- condition: template
value_template: "{{ is_state(target_light, 'off') }}"
- condition: template
value_template: "{{ state_attr(target_light, 'brightness') >= max_brightness }}"
- condition: template
value_template: "{{ state_attr(target_light, 'color_temp') <= min_mireds }}"
- condition: template
value_template: >-
{{ (((as_timestamp(now()) - start_time) / individual_step) |
round(0, "ceil")) > steps }}
sequence:
- variables:
steps_to_now: |-
{{ ((as_timestamp(now()) - start_time) / individual_step) |
round(0, "ceil") }}
brightness: >-
{{ min_brightness + (bright_step * steps_to_now) | round(0,
'ceil') }}
mireds: "{{ max_mireds - (mireds_step * steps_to_now) }}"
- delay:
seconds: "{{ individual_step }}"
- if:
- condition: template
value_template: "{{ is_state(target_light, 'on') }}"
then:
- service: light.turn_on
data:
brightness: "{{ brightness }}"
color_temp: "{{ mireds }}"
transition: "{{ individual_step - 1 }}"
target:
entity_id: "{{ target_light }}"
- if:
- condition: and
conditions:
- condition: template
value_template: "{{ light_timeout != 0 }}"
- condition: template
value_template: "{{ is_state(target_light, 'on') }}"
then:
- delay:
minutes: "{{ light_timeout }}"
- service: light.turn_off
data: {}
target:
entity_id: "{{ target_light }}"
description: Turn on lamps brighter based on wake time
fields:
min_mireds:
description: Minimum mireds value. This is the end value - most white
selector:
color_temp: null
required: true
default: 200
name: Min Mireds
example: 200
max_mireds_selector:
description: >-
Maximum mireds value. This is the start value. If the light is on the
current value from the state of the light will be used and this will be
ignored.
example: 400
selector:
color_temp: null
default: 400
required: true
name: Max Mireds
max_brightness_pct:
description: Maximum brightness in percent.
example: 80
selector:
number:
min: 1
max: 100
default: 80
required: true
name: Max brightness
alarm_length:
description: >-
This is the start to finish time. Take this into account when setting up
the automation this script is called by.
example: 10
selector:
number:
min: 1
max: 60
default: 10
required: true
name: Alarm Length
steps_per_minute:
description: How many steps per minute
example: 4
selector:
number:
min: 1
max: 12
default: 12
name: Steps Per minute
required: true
target_light:
description: A single light or group
example: light.master_lamp
selector:
entity:
filter:
domain: light
name: Target Light
required: true
light_timeout:
description: >-
Minutes to delay after Max Brightness has been reached to turn the light
back off. Value of 0 disables the timeout
example: 5
selector:
number:
min: 0
max: 60
default: 5
name: Light Timeout
required: true
variables:
steps: "{{ alarm_length * steps_per_minute }}"
min_brightness: |-
{% if state_attr(target_light, 'brightness') == None %}
1
{% else %}
{{ state_attr(target_light, 'brightness') }}
{% endif %}
max_brightness: "{{ max_brightness_pct * 2.55 }}"
max_mireds: |-
{% if state_attr(target_light, 'color_temp') == None %}
{{ max_mireds_selector }}
{% else %}
{{ state_attr(target_light, 'color_temp') }}
{% endif %}
mireds_step: "{{ (max_mireds - min_mireds) / steps }}"
bright_step: "{{ (max_brightness - min_brightness) / steps }}"
start_time: "{{ as_timestamp(now()) }}"
individual_step: "{{ 60 / steps_per_minute }}"
mode: parallel
Detailed Explaination of Automation
This CAN be replaced with the Blueprint created below
The automation is much simpler. Execute the script as many times in series as you’d like to get the desired parabolic curve. All executions of the script (except for the last one) will need to have the ‘Light Timeout’ set to 0 so that the script will continue from current values. You will also need to check to see if the light is off (for all executions but the first one) so that if you turn the light off, the subsequent executions of the script in the currently running automation will not turn it back on.
When setting up start time for the trigger you will need to take into account when you want it to finish. In my example below I want it to finish by 7:00 am, so I do the math backwards and start it at 6:35. The total time is solved by adding up all the ‘Alarm Length’ fields of all executions of the script.
In my automation I’m using the Workday Integration and its binary sensor to only execute on days I have configured in that integration.
alias: Light Alarm
description: ""
trigger:
- platform: time
at: "06:35:00"
condition:
- condition: state
entity_id: binary_sensor.workday_sensor
state: "on"
action:
- service: script.1702692125821
data:
min_mireds: 375
max_mireds_selector: 400
max_brightness_pct: 10
alarm_length: 10
steps_per_minute: 12
light_timeout: 0
target_light: light.light_alarm_lights
- if:
- condition: state
entity_id: light.light_alarm_lights
state: "on"
then:
- service: script.1702692125821
data:
min_mireds: 325
max_mireds_selector: 400
max_brightness_pct: 50
alarm_length: 10
steps_per_minute: 12
light_timeout: 0
target_light: light.light_alarm_lights
- if:
- condition: state
entity_id: light.light_alarm_lights
state: "on"
then:
- service: script.1702692125821
data:
min_mireds: 250
max_mireds_selector: 400
max_brightness_pct: 100
alarm_length: 5
steps_per_minute: 12
light_timeout: 25
target_light: light.light_alarm_lights
mode: parallel
max: 10
Installation
- Copy and paste the script as is into a new script on your system when editing in YAML mode.
- Copy and paste the automation into a new automation when editing in YAML mode. You will need to update the ‘service’ value to your script which you will be able to more easily find after you save and edit in GUI mode. You can also add remove executions of the script to change the curve and customize the parameters.