Wakeup Lamp with Home Assistant

home assistant
Author

Daniel Kent

Published

February 28, 2023

Dealing with the lack of light during the winter months in the Mitten is rough, and even more so when your only window faces a streetlight that floods your bedroom with light at night. The latter problem can be dealt with using some inexpensive blackout curtains, but then you lose any hope of waking up to a sunrise.

To solve this problem, I decided to convert my existing wall light into a smart light. I purchased several tunable white Philips Hue bulbs, installed them into the fixture, and paired them with my home server running Home Assistant with an inexpensive Zigbee USB interface. Pairing was remarkably easy; in fact, simply enabling ZHA pairing mode within Home Assistant (Settings > “Configure” under ZHA device > “Add Device”) and then turning on the bulb caused the bulb to flash, and Home Assistant to report the device was paired. Neat!

Next, I joined the bedroom lights into a singly-addressable group, which makes automations a bit easier (versus needing to select every bulb). The documentation for how to create groups with ZHA is poor, so here’s how to do it:

  1. Go to Settings > Integrations and press “Configure” under the ZHA Integration (NOT the device!)

  2. At the bottom, select “Groups”, then press “Create Group”

Next, I created a helper (Settings > Integrations > Helpers) of type “Date and/or time” and gave it the name 30_minutes_before_alarm (this can be whatever you want). This will be the entity that is used to trigger the start of the wakeup sequence, but still needs to be set to 30 minutes prior to the alarm time. To do this, we need to add an automation that pulls the next alarm data from our phone:

  1. Add a new automation, call it “Set Pre-Alarm Timestamp” (or whatever you want)
  2. Set the trigger to “When Next Alarm changes”
  3. Change the edit mode for the first action to YAML and paste the following, changing the 30 to the number of minutes of your choice:
service: input_datetime.set_datetime
data:
  timestamp: "{{ as_timestamp(states.sensor.pixel_6a_next_alarm.state) - 60 * 30 }}"
target:
  entity_id: input_datetime.30_minutes_before_alarm

All together, it should look something like this:

alias: Set Pre-Alarm Timestamp
description: Gets the time 30 minutes before the next alarm.
trigger:
  - platform: state
    entity_id:
      - sensor.pixel_6a_next_alarm
condition: []
action:
  - service: input_datetime.set_datetime
    data:
      timestamp: "{{ as_timestamp(states.sensor.pixel_6a_next_alarm.state) - 60 * 30 }}"
    target:
      entity_id: input_datetime.30_minutes_before_alarm
mode: single

Next, we need to create a script to slowly turn our lights on. This isn’t strictly necessary if you plan to dim the lights on in five minutes or less, but if you do then you need to create a script to do this for you. After saving the automation, go to the Scripts tab, and create a new script. The first action should be a service call to Light: Turn On, with the target being your Zigbee light group, followed by a delay for some time. I have my brightness step sequence set to 5%, 10%, 15%, 25%, 35%, 50%, and 100%, with delay set to 300 seconds (5 minutes) and an extra 5-minute delay action between service calls. My YAML for this script looks like this:

alias: wake_alarm
sequence:
  - service: light.turn_off
    data:
      transition: 0
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 1
  - service: light.turn_on
    data:
      transition: 300
      brightness_pct: 5
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: light.turn_on
    data:
      transition: 300
      brightness_pct: 10
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: light.turn_on
    data:
      transition: 300
      brightness_pct: 15
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: light.turn_on
    data:
      transition: 300
      brightness_pct: 25
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: light.turn_on
    data:
      transition: 300
      brightness_pct: 35
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: light.turn_on
    data:
      brightness_step_pct: 50
      transition: 300
    target:
      entity_id: light.bedroom_wall_light
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: light.turn_on
    data:
      transition: 10
      brightness_pct: 100
    target:
      entity_id: light.bedroom_wall_light
mode: single
icon: mdi:alarm-light

Now that the script is in place, we just need to add one more automation to trigger the script when the time is right. Going back to the Automations tab, create a new one called “Pre-Alarm Lights On” (or whatever name strikes your fancy). For the trigger, set a time trigger, select date/time helper, then on the dropdown select the date/time helper you created earlier. Then, under Actions, add a service action and select the script you created earlier. You may also want to set some conditions to skip the wakeup light sequence if, say, you are not home. You may also want to set up a widget that lets you toggle on and off the automation from the main panel.

If you did everything right, you should wake up to a bright, shining light, and either some refreshing or horrorific sounds from your phone.