refactor for kelvin

This commit is contained in:
Stephen Kuntz 2024-09-13 15:41:48 -04:00
parent ddb845e7ec
commit 409d5c3763
3 changed files with 216 additions and 40 deletions

28
README.md Normal file
View File

@ -0,0 +1,28 @@
I wanted to try the sunrise effect for waking up in the morning and found the [blueprint](https://community.home-assistant.io/t/wake-up-light-alarm-with-sunrise-effect/255193/145) that would do this for me. However, this didn't work and was overly difficult to troubleshoot. It triggers every minute, and as I used to be a Systems Adminitrator, this unnecessary use of resources also bugged me. If you didn't catch the errors in the automation with in the number of available traces, it was gone. If you did manage to catch the trace, it was so convoluted that it was nearly impossible to troubleshoot unless you are intimately aware of the execution steps. Not to mention the issues trying to trigger it with a date/time helper other then the the one integrated with the HA phone app.
I created my own script and automation to bypass the frustations above. It is not nearly as full featured as the blueprint but it is highly configureable. 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, color temperature in kelvin 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.
![image|690x196](upload://MHf7C5rNaVUQZPrWWkcCHY68Um.png)
The second component is an blueprint that executes the script 3 times in series with different values for each execution.
## Detailed Explaination of Script
The script expects to be kicked off with parameters defined. For the script to work, the target light needs to be and set to starting Kelvin values. The starting brightnes is always 1%. The blueprint handles the inital turning on of the light. The kelvin value of the light will be used as the starting value.
![image|690x456](upload://7bOOnbkscen4a6DBca9HNMoflN3.png)
If you turn off the light at any point while the script is running, the script and blueprint will end.
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.
## Detailed Explaination of Bluebrint
The bluebrint is much simpler. Execute the script 3 to get the desired parabolic curve. All executions of the script (except for the last one) have the 'Light Timeout' set to 0 so that the script will continue from current values. It also checks 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.
## Installation
1. Copy and paste the script as is into a new script on your system when editing in YAML mode.
1. Import the blueprint

View File

@ -12,21 +12,21 @@ blueprint:
- domain: input_datetime
workday_sensor:
name: Workday Sensor
description: Binary Sensor for determining it it should run. Typically from Workday Integratoin
description: Binary Sensor for determining whether it should run. Typically from Workday Integration
selector:
entity:
filter:
- domain: binary_sensor
alarm_script:
name: Script to trigger
description: Script to trigger
description: Light Alarm Script
selector:
entity:
filter:
- domain: script
target_light:
name: Lights
description: The light(s) with Mireds
description: The light(s) with kelvin
selector:
entity:
filter:
@ -48,21 +48,24 @@ blueprint:
min: 1
max: 60
min_mireds_1:
description: Minimum mireds value (coldest) for 1st run
start_kelvin_temp:
description: Start Kelvin value (warm) for 1st run
selector:
color_temp:
default: 375
name: Min Mireds 1
max_mireds_1:
unit: kelvin
default: 2500
name: Starting Kelvin
target_kelvin_1:
description: >-
Maximum mireds value (warmest) for 1st run
Target Kelvin value (cold) for the end of the first run
selector:
color_temp:
default: 400
name: Max Mireds 1
unit: kelvin
default: 3000
name: Target Kelvin 1
max_brightness_1:
name: Maximum Brightness 1
description: Finish value for first run
selector:
number:
min: 1
@ -78,21 +81,17 @@ blueprint:
max: 60
default: 10
min_mireds_2:
description: Minimum mireds value (coldest) for 1st run
selector:
color_temp:
default: 300
name: Min Mireds 1
max_mireds_2:
target_kelvin_2:
description: >-
Maximum mireds value (warmest) for 1st run
Target Kelvin value (cold) for second run
selector:
color_temp:
default: 400
name: Max Mireds 1
unit: kelvin
default: 4000
name: Target Kelvin 2
max_brightness_2:
name: Maximum Brightness 1
description: Finish value for second run
selector:
number:
min: 1
@ -108,21 +107,17 @@ blueprint:
max: 60
default: 10
min_mireds_3:
description: Minimum mireds value (coldest) for 1st run
selector:
color_temp:
default: 160
name: Min Mireds 1
max_mireds_3:
target_kelvin_3:
description: >-
Maximum mireds value (warmest) for 1st run
Target Kelvin value (cold) for third run
selector:
color_temp:
default: 400
name: Max Mireds 1
unit: kelvin
default: 6500
name: Target Kelvin 3
max_brightness_3:
name: Maximum Brightness 1
description: Finish value for third and final run
selector:
number:
min: 1
@ -148,24 +143,32 @@ condition:
state: "on"
action:
- service: !input alarm_script
- action: light.turn_on
data:
min_mireds: !input min_mireds_1
max_mireds_selector: !input max_mireds_1
color_temp_kelvin: !input start_kelvin_temp
brightness_pct: 1
entity_id: !input target_light
- delay:
seconds: 5
- action: !input alarm_script
data:
target_kelvin: !input target_kelvin_1
start_kelvin: !input start_kelvin_temp
max_brightness_pct: !input max_brightness_1
alarm_length: !input alarm_length_1
steps_per_minute: !input steps_per_minute
light_timeout: 0
target_light: !input target_light
- if:
- condition: state
state: "on"
entity_id: !input target_light
then:
- service: !input alarm_script
- action: !input alarm_script
data:
min_mireds: !input min_mireds_2
max_mireds_selector: !input max_mireds_2
target_kelvin: !input target_kelvin_2
start_kelvin: !input target_kelvin_1
max_brightness_pct: !input max_brightness_2
alarm_length: !input alarm_length_2
steps_per_minute: !input steps_per_minute
@ -176,10 +179,10 @@ action:
state: "on"
entity_id: !input target_light
then:
- service: !input alarm_script
- action: !input alarm_script
data:
min_mireds: !input min_mireds_3
max_mireds_selector: !input max_mireds_3
target_kelvin: !input target_kelvin_3
start_kelvin: !input target_kelvin_2
max_brightness_pct: !input max_brightness_3
alarm_length: !input alarm_length_3
steps_per_minute: !input steps_per_minute

145
parabolic_alarm_script.yaml Normal file
View File

@ -0,0 +1,145 @@
alias: Lamp Wake Up
sequence:
- 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_kelvin') >=
target_kelvin }}
- 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') }}
kelvin: "{{ start_kelvin + (kelvin_step * steps_to_now) }}"
- delay:
seconds: "{{ individual_step }}"
- if:
- condition: template
value_template: "{{ is_state(target_light, 'on') }}"
then:
- data:
brightness: "{{ brightness }}"
color_temp_kelvin: "{{ kelvin }}"
transition: "{{ individual_step - 1 }}"
target:
entity_id: "{{ target_light }}"
action: light.turn_on
- 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 }}"
- data: {}
target:
entity_id: "{{ target_light }}"
action: light.turn_off
description: Turn on lamps brighter based on wake time
fields:
target_kelvin:
description: Coldest Kelvin value. This is the end value - most white
selector:
color_temp:
unit: kelvin
required: true
default: 6500
name: Coldest Kelvin
example: 6500
start_kelvin:
description: >-
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: 2500
selector:
color_temp:
unit: kelvin
min: 2500
max: 6500
default: 6500
required: true
name: Warmest Kelvin
max_brightness_pct:
description: Maximum brightness in percent to reach by the end of the script
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 states(target_light) == 'off' %}
3
{% else %}
{{ state_attr(target_light, 'brightness') }}
{% endif %}
max_brightness: "{{ max_brightness_pct * 2.55 }}"
kelvin_step: "{{ (target_kelvin - start_kelvin) / steps }}"
bright_step: "{{ (max_brightness - min_brightness) / steps }}"
start_time: "{{ as_timestamp(now()) }}"
individual_step: "{{ 60 / steps_per_minute }}"
mode: parallel