Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save triplepoint/1b9006ddec208a07fc0100a2a30110eb to your computer and use it in GitHub Desktop.
Save triplepoint/1b9006ddec208a07fc0100a2a30110eb to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Wake-up light alarm with sunrise effect
blueprint:
name: Wake-up light alarm with sunrise effect
description:
"A wake-up light alarm with a brightness and color temperature sunrise
effect. Note: 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
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 sunrise 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: {}
sunrise_duration:
name: Sunrise duration
description:
The sunrise 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
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: 255.0
step: 1.0
mode: slider
end_brightness:
name: Maximum brightness
description:
The brightness will be transitioned from the minimum to the configured
value.
default: 254
selector:
number:
min: 5.0
max: 255.0
step: 1.0
mode: slider
min_mired:
name: Minimum color temperature
description: "The minimum color temperature to use. (1 : lowest supported)"
default: 1
selector:
number:
min: 1.0
max: 500.0
step: 5.0
mode: slider
unit_of_measurement: mired
pre_sunrise_actions:
name: Pre-sunrise actions
description: Optional actions to run before sunrise starts.
default: []
selector:
action: {}
post_sunrise_actions:
name: Post-sunrise actions
description: Optional actions to run after sunrise ends (around the alarm time).
default: []
selector:
action: {}
source_url: https://gist.github.com/triplepoint/1b9006ddec208a07fc0100a2a30110eb
variables:
light_entity: !input "light_entity"
sensor: !input "timestamp_sensor"
sunrise_duration: !input "sunrise_duration"
start_brightness: !input "start_brightness"
end_brightness: !input "end_brightness"
range_brightness: "{{ float(end_brightness)-float(start_brightness) }}"
manual_time: !input "manual_time"
seconds: "{{ float(sunrise_duration) * 60 }}"
min_mired: !input "min_mired"
start_mired: "{{ state_attr(light_entity, 'max_mireds') }}"
end_mired: "{{ [state_attr(light_entity, 'min_mireds')|int(0), min_mired|int(0)]|max }}"
tick_time: "{{ float(seconds) / float(range_brightness) }}"
check_entity: !input "check_entity"
trigger:
- platform: time_pattern
minutes: "*"
condition: []
action:
- wait_template: "{{ sensor == 'none' or as_timestamp(states(sensor), None) != None }}"
- wait_template: "{{ 0 <
as_timestamp(states(sensor) if sensor != 'none' else today_at(manual_time)) - as_timestamp(now())
<= float(seconds)
and states(check_entity) in ['unknown', 'on', 'home'] }}"
- choose: []
default: !input "pre_sunrise_actions"
- condition: template
value_template: "{{ sensor == 'none' or as_timestamp(states(sensor), None) != None }}"
- condition: template
value_template: "{{ 0 <
as_timestamp(states(sensor) if sensor != 'none' else today_at(manual_time)) - 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: "{{ start_brightness }}"
color_temp_kelvin: "{{ 1000000 / start_mired }}"
entity_id: !input "light_entity"
default:
- service: light.turn_on
data:
brightness: "{{ start_brightness }}"
entity_id: !input "light_entity"
- repeat:
while:
- "{{ sensor == 'none' or as_timestamp(states(sensor), None) != None }}"
- "{{ 0 <
as_timestamp(states(sensor) if sensor != 'none' else today_at(manual_time)) - as_timestamp(now())
<= float(seconds) }}"
sequence:
- delay: "{{ tick_time }}"
- choose:
- conditions:
- "{{ 0 < state_attr(light_entity, 'brightness') | int(0) < end_brightness | int }}"
- "{{ sensor == 'none' or as_timestamp(states(sensor), None) != None }}"
- "{{ 0 <
as_timestamp(states(sensor) if sensor != 'none' else today_at(manual_time)) - as_timestamp(now())
<= float(seconds) }}"
sequence:
- choose:
- conditions:
- "{{ state_attr(light_entity, 'min_mireds') != None }}"
sequence:
- service: light.turn_on
data:
brightness:
"{{ (float(end_brightness) - (float(range_brightness) *
(as_timestamp(states(sensor) if sensor != 'none' else today_at(manual_time)) - as_timestamp(now())) / float(seconds)))
| int(0) }}"
color_temp_kelvin:
"{{ 1000000 / ((float(end_mired) + (float(start_mired) - float(end_mired))
* ((as_timestamp(states(sensor) if sensor != 'none' else today_at(manual_time)) - as_timestamp(now())) / float(seconds)))
| int(0)) }}"
entity_id: !input "light_entity"
default:
- service: light.turn_on
data:
brightness:
"{{ (float(end_brightness) - (float(range_brightness) * (as_timestamp(states(sensor)
if sensor != 'none' else today_at(manual_time))
- as_timestamp(now())) / float(seconds))) | int(0) }}"
entity_id: !input "light_entity"
- choose: []
default: !input "post_sunrise_actions"
mode: single
max_exceeded: silent
@WhatMeansGithub
Copy link

Mate, you fixed my issue with the original blueprint. Well done!

@Maaajaaa
Copy link

thanks, this also solved an issue I had with time zones/summer winter time

@lnlyssg
Copy link

lnlyssg commented Feb 11, 2025

Thanks for this. I have one minor issue in that it fills the logs with messages like the below, obviously not an immediate issue:

2025-02-11 07:29:57.023 WARNING (MainThread) [homeassistant.components.light] Got `color_temp` argument in `turn_on` service, which is deprecated and will break in Home Assistant 2026.1, please use `color_temp_kelvin` argument

@triplepoint
Copy link
Author

Hi @lnlyssg, I modified the two spots in the blueprint that were using color_temp, and replaced them with color_temp_kelvin. I haven't tested it out, so if you have a chance, please kick the tires and let me know if it worked.

@lnlyssg
Copy link

lnlyssg commented Feb 11, 2025

Working perfectly thanks!

@muesli79
Copy link

Hi @lnlyssg, I modified the two spots in the blueprint that were using color_temp, and replaced them with color_temp_kelvin. I haven't tested it out, so if you have a chance, please kick the tires and let me know if it worked.

Thank you!

@Edocsyl
Copy link

Edocsyl commented Apr 2, 2025

Hi @triplepoint, is there an Option to Implement an other Time Class? Something like:

      selector:
        entity:
          domain:
          - input_datetime

I would like to use a helper to set an time value instead of an device_class: - timestamp

@lnlyssg
Copy link

lnlyssg commented Apr 2, 2025

Yeah that's what I've done, I updated the input like this:

    timestamp_sensor:
      name: Alarm timestamp sensor
      description:
        "Datetime helper with timestamp of next alarm or set to 'none' for manual alarm time"
      default: none
      selector:
        entity:
          filter:
          - domain:
            - input_datetime

@Edocsyl
Copy link

Edocsyl commented Apr 2, 2025

I replaced the "timestamp_sensor" with your code and restarted home assistant. Sadly it's not starting the automation. Did you change something else in the code? Ad additional check, i use an input_boolean helper.

@lnlyssg
Copy link

lnlyssg commented Apr 2, 2025

@Edocsyl Probably... I made quite a few changes to it so just stuck everything in my own gist at https://gist.github.com/lnlyssg/65e47876a767385e331300d440404a31 if you want to take a look and compare

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment