Skip to content

Instantly share code, notes, and snippets.

@fensoft
Last active October 24, 2025 08:02
Show Gist options
  • Select an option

  • Save fensoft/c50e01febaf43ea703b0fe149306834a to your computer and use it in GitHub Desktop.

Select an option

Save fensoft/c50e01febaf43ea703b0fe149306834a to your computer and use it in GitHub Desktop.
Gentle Wake-up on Alexa Alarm
blueprint:
name: Gentle Wake-up on Alexa Alarm
description: >
Starts a sunrise X minutes before the next Alexa alarm (Alexa Media Player).
Event-driven: re-arms when the alarm sensor changes or HA restarts.
Fade via long transition or 1% steps paced to match fade_minutes.
domain: automation
input:
alexa_next_alarm_sensor:
name: Alexa "Next Alarm" sensor
description: sensor.<echo>_next_alarm from Alexa Media Player (e.g., sensor.echo_next_alarm)
selector:
entity:
domain: sensor
light_target:
name: Light or group to fade in
selector:
target:
entity:
domain: light
fade_minutes:
name: Fade duration (minutes)
default: 30
selector:
number:
min: 5
max: 90
step: 5
unit_of_measurement: min
mode: slider
fade_method:
name: Fade method
default: "transition"
selector:
select:
options:
- label: Smooth transition (if supported)
value: "transition"
- label: 1% steps (paced to fill fade_minutes)
value: "steps"
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: !input alexa_next_alarm_sensor
- platform: homeassistant
event: start
variables:
fade_mins: !input fade_minutes
i_fade_method: !input fade_method
alexa_sensor: !input alexa_next_alarm_sensor
# Alarm time from sensor STATE (ISO) -> timestamp (seconds)
alarm_ts: >
{{ states(alexa_sensor) | as_timestamp(none) }}
# Start = alarm - fade
start_ts: >
{{ alarm_ts - (fade_mins * 60) if alarm_ts is number else none }}
# Datetimes for precise scheduling
start_dt: >
{{ as_local(start_ts | as_datetime) if start_ts is number else none }}
wait_seconds: >
{{ ([ (start_ts - now().timestamp()) | int, 0 ] | max) if start_ts is number else 0 }}
# For 1% step mode: 100 total steps -> per-step delay (seconds)
step_delay: >
{{ ((fade_mins * 60) / 100) | round(0, 'ceil') | int }}
condition: []
action:
# Validate we have a proper alarm time
- choose:
- conditions:
- condition: template
value_template: "{{ alarm_ts is number and start_ts is number }}"
sequence: []
default:
- stop: "No valid next Alexa alarm set."
- choose:
- conditions:
- condition: template
value_template: "{{ wait_seconds > 0 }}"
sequence:
- delay:
seconds: "{{ wait_seconds }}"
default: []
- choose:
- conditions:
- condition: template
value_template: "{{ now().timestamp() >= alarm_ts }}"
sequence:
- stop: "Alarm time already passed. Nothing to do."
default: []
# Perform the fade
- choose:
# Smooth transition mode
- conditions:
- condition: template
value_template: "{{ i_fade_method == 'transition' }}"
sequence:
- service: light.turn_on
target: !input light_target
data:
brightness_pct: 100
transition: "{{ fade_mins * 60 }}"
default:
# 1% steps paced to fill fade_minutes
- service: light.turn_on
target: !input light_target
data:
brightness_pct: 1
- repeat:
count: 99
sequence:
- service: light.turn_on
target: !input light_target
data:
brightness_step_pct: 1
# Use string-form time to avoid schema complaints
- delay: "00:00:{{ step_delay }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment