Last active
July 10, 2022 14:02
-
-
Save simonwh/36f2a82ff6a8cf581274610b24d81aa0 to your computer and use it in GitHub Desktop.
Wake-up alarm automation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
blueprint: | |
name: Wake-up light and music alarm with sunrise effect and increasing volume | |
description: 'A wake-up light and music alarm with a brightness and color temperature sunrise effect and increasing volume. | |
Note: Requires date_time_iso sensor in configuration, not manually executable!' | |
domain: automation | |
input: | |
light_entity: | |
name: Wake-up light entity | |
description: The light to control. Turning it off during the sunrise will keep | |
it off. Color temperature range is auto-detected. | |
selector: | |
entity: | |
domain: light | |
speaker_entity: | |
name: Wake-up speaker entity | |
description: The speaker to control. Turning it off during the wake-up will keep | |
it off. | |
selector: | |
entity: | |
domain: media_player | |
music_source: | |
name: Sound source | |
description: What the speaker should play | |
selector: | |
text: | |
timestamp_sensor: | |
name: Alarm timestamp sensor | |
description: 'Sensor with timestamp of next alarm with device_class: timestamp | |
(set to ''none'' for manual alarm time)' | |
default: none | |
selector: | |
entity: | |
device_class: timestamp | |
manual_time: | |
name: Manual alarm time | |
description: Time to trigger alarm every day if timestamp sensor is not set. | |
Settings at or shortly after midnight will not work as expected! | |
default: '7:00:00' | |
selector: | |
time: {} | |
check_entity: | |
name: Additional entity to check before wake-up is triggered | |
description: If set, checks if entity is 'on' or 'home' before triggering. Use | |
e.g. a (workday) sensor, device_tracker or person entity. | |
default: none | |
selector: | |
entity: {} | |
wakeup_duration: | |
name: Wake-up duration | |
description: The wake-up will start the configured number of minutes before | |
the timestamp. | |
default: 25 | |
selector: | |
number: | |
min: 5.0 | |
max: 60.0 | |
step: 5.0 | |
unit_of_measurement: min | |
mode: slider | |
start_brightness: | |
name: Minimum brightness in percentage | |
description: The brightness to start with. Some lights ignore very low values | |
and may turn on with full brightness instead! | |
default: 1 | |
selector | |
number: | |
min: 1.0 | |
max: 100.0 | |
step: 1.0 | |
mode: slider | |
end_brightness: | |
name: Maximum brightness in percentage | |
description: The brightness will be transitioned from the minimum to the configured | |
value. | |
default: 100 | |
selector: | |
number: | |
min: 5.0 | |
max: 100.0 | |
step: 1.0 | |
mode: slider | |
min_mired: | |
name: Minimum color temperature | |
description: 'The minimum color temperature to use. (0: lowest supported)' | |
default: 0 | |
selector: | |
number: | |
min: 0.0 | |
max: 500.0 | |
step: 5.0 | |
mode: slider | |
unit_of_measurement: mired | |
lock_mired: | |
name: Lock color temperature | |
description: Lock the color temperature to the selected minimum temperature | |
default: false | |
selector: | |
boolean: | |
start_volume: | |
name: Minimum volume | |
description: The volume to start with | |
default: 1 | |
selector: | |
number: | |
min: 1.0 | |
max: 100.0 | |
step: 1.0 | |
mode: slider | |
end_volume: | |
name: Maximum volume | |
description: The volume will be transitioned from the minimum to the configured | |
value. | |
default: 20 | |
selector: | |
number: | |
min: 5.0 | |
max: 100.0 | |
step: 1.0 | |
mode: slider | |
pre_wakeup_actions: | |
name: Pre-wakeup actions | |
description: Optional actions to run before wake-up starts. | |
default: [] | |
selector: | |
action: {} | |
post_wakeup_actions: | |
name: Post-wakeup actions | |
description: Optional actions to run after wake-up ends (around the alarm time). | |
default: [] | |
selector: | |
action: {} | |
variables: | |
light_entity: !input 'light_entity' | |
speaker_entity: !input 'speaker_entity' | |
music_source: !input 'music_source' | |
sensor: !input 'timestamp_sensor' | |
wakeup_duration: !input 'wakeup_duration' | |
start_brightness: !input 'start_brightness' | |
end_brightness: !input 'end_brightness' | |
range_brightness: '{{float(end_brightness) - float(start_brightness)}}' | |
min_mired: !input 'min_mired' | |
lock_mired: !input 'lock_mired' | |
start_mired: '{{state_attr(light_entity, ''max_mireds'') | float(0)}}' | |
end_mired: '{{[state_attr(light_entity, ''min_mireds'') | int(0), min_mired | int(0)] | max}}' | |
range_mired: '{{float(start_mired) - float(end_mired) | float(0)}}' | |
start_volume: !input 'start_volume' | |
end_volume: !input 'end_volume' | |
range_volume: '{{float(end_volume) - float(start_volume)}}' | |
manual_time: !input 'manual_time' | |
seconds: '{{float(wakeup_duration) * 60}}' | |
tick_time: '{{float(seconds) / float(range_brightness)}}' | |
check_entity: !input 'check_entity' | |
trigger: | |
- platform: time_pattern | |
minutes: '*' | |
action: | |
- wait_template: '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}' | |
- wait_template: '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now()) <= float(seconds) and states(check_entity) in [''unknown'', ''on'', ''home'']}}' | |
- choose: [] | |
default: !input 'pre_wakeup_actions' | |
- condition: template | |
value_template: '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}' | |
- condition: template | |
value_template: '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now()) <= float(seconds) and states(check_entity) in [''unknown'', ''on'', ''home'']}}' | |
- choose: | |
- conditions: | |
- '{{state_attr(light_entity, ''min_mireds'') != None}}' | |
sequence: | |
- service: light.turn_on | |
data: | |
brightness_pct: '{{start_brightness}}' | |
color_temp: '{{end_mired + 1 if lock_mired else start_mired}}' | |
entity_id: !input 'light_entity' | |
default: | |
- service: light.turn_on | |
data: | |
brightness_pct: '{{start_brightness}}' | |
entity_id: !input 'light_entity' | |
- service: media_player.volume_set | |
data: | |
volume_level: '{{float(start_volume / 100)}}' | |
entity_id: !input 'speaker_entity' | |
- service: media_player.select_source | |
data: | |
source: !input 'music_source' | |
entity_id: !input 'speaker_entity' | |
- repeat: | |
while: | |
- '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}' | |
- '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now()) <= float(seconds)}}' | |
sequence: | |
- delay: '{{tick_time}}' | |
- choose: | |
- conditions: | |
- '{{0 < state_attr(light_entity, ''brightness'') | int(0) < float(end_brightness) / 100 * 255 | int(0)}}' | |
sequence: | |
- choose: | |
- conditions: | |
- '{{state_attr(light_entity, ''min_mireds'') != None}}' | |
sequence: | |
- service: light.turn_on | |
data: | |
brightness_pct: '{{float(end_brightness) - ([0, float(range_brightness) * (as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now())) / seconds, float(end_brightness)]|sort)[1] | round(0)}}' | |
color_temp: '{{end_mired if lock_mired else | |
float(end_mired) + ([0, float(range_mired) * (as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now())) / seconds, float(start_mired)]|sort)[1] | round(0)}}' | |
entity_id: !input 'light_entity' | |
default: | |
- service: light.turn_on | |
data: | |
brightness_pct: '{{float(end_brightness) - ([0, float(range_brightness) * (as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now())) / seconds, float(end_brightness)]|sort)[1] | round(0)}}' | |
entity_id: !input 'light_entity' | |
- choose: | |
- conditions: | |
- '{{0 < state_attr(speaker_entity, ''volume_level'') * 100 | round(0) < float(end_volume) - ([0, float(range_volume) * (as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now())) / seconds, float(end_volume)]|sort)[1] | round(0) <= float(end_volume)}}' | |
sequence: | |
- service: media_player.volume_set | |
data: | |
volume_level: '{{(float(end_volume) - ([0, float(range_volume) * (as_timestamp(states(sensor) if sensor != ''none'' else (states(''sensor.date'') ~ '' '' ~ manual_time) | as_datetime() | as_local()) | |
- as_timestamp(now())) / seconds, float(end_volume)]|sort)[1]) / 100 | round(2)}}' | |
entity_id: !input 'speaker_entity' | |
- choose: [] | |
default: !input 'post_wakeup_actions' | |
mode: single | |
max_exceeded: silent |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment