Sunrise Alarm with Home Assistant 2020-09-26
Up in the PNW it's starting to get darker, which particularly means it's a pain-in-the-butt to wake up in the morning. During the summer months the sun makes that easy. But I've gotten tired of... uh, being tired in the winter months.
Fancy Pants
So I bought one of those fancy Philips sunrise alarm clocks. It's the HF3520, which is one of the most popular ones on Amazon at the moment.
And for $120, it is a real turd. It has no concept of a date, something that even the cheapest alarm clocks have had for decades. Let alone any automatic DST time changes, "atomic clock" radio time auto-set, or any battery backup. The manual isn't even honest about things:
You can set two different wake-up times, for example if you want to wake up at a different time in the weekend than on weekdays.
That implies that the alarm clock knows what a weekday/weekend is, in any modern society. Nope -- it's telling you that you get to manually turn your alarms on and off each day.
Quickest back-into-the-box-and-returned-to-Amazon ever, for me.
DIY I guess
A friend reminded me that I have smart lights and Home Assistant (HA). I had tinkered with this before but didn't get anything really nice set up for an alarm, but I've had some renewed motivation.
The goal: A smooth light transition that starts with a dim red "sun", ending 30 minutes later with a bright yellow light. All automatically set to go off before my phone alarm.
Caveat: The rest of this write-up assumes you have used HA a little bit already, and have a passing knowledge of smart home Stuff.
Shopping List
I already had all this stuff, but you'll need at least this for anything useful:
- An RGB (or at least a color temp capable) smart bulb. Sengled makes some fantastic Z-Wave A19 bulbs that are easy to find; pictured.
- Home Assistant and a device to run it on; I use a Raspberry Pi 4.
- A smart hub, dongle for Home Assistant, or any other way to connect your bulb. I use a SmartThings hub as HA can use that.
- The Home Assistant Android app -- not the website! There's a specific feature of the app needed here to detect when your next alarm is set.* (Unfortunately, it sounds like the iOS app doesn't have this feature yet, but I haven't tried myself.)
*If your phone doesn't support this or you just don't care, then skip the sections that set up and automate a "helper". Use a fixed time for running your sunrise script.
Set-up
I'm not going over how to configure HA because that's a series of articles in itself. This is focused on actually making a pseudo-sunrise light effect before your alarm goes off.
These are the main components to configure:
- A helper to store your next alarm time with an offset
- An automation to update said helper
- A script to slowly transition light brightness and color temperature over time.
- An automation to run the script at the stored helper time
There are other ways of accomplishing this, but this is the easiest way to manage and understand.
Create an alarm helper
In HA, open Configuration and then go to Helpers. Create a date/time helper and call it something like "next pre-alarm" (I know, I'm very creative). Make sure the type is "Date and time".
Then, on the Home Assistant app go to App Configuration, Manage Sensors, and Next Alarm. Enable that sensor and ensure it looks right: it should have a timestamp of the next alarm you have set on your phone.
Automate the helper value
Still with me? Create an automation in Home Assistant (Configuration area, again). Call it... "fill alarm helper".
Add a trigger of type State, entity sensor.yourphone_next_alarm
(the name will vary based on your phone's actual device name, but it'll end in _next_alarm
). This field has a drop-down + auto-complete, but you can browse entities in the Configuration area too if you're having trouble finding it.
Skip Conditions. Add an Action of type Call service, with a service of input_datetime.set_datetime
.
The Entity ID will be input_datetime.next_pre_alarm
(again, the name can vary based on what you called your helper above).
Fill in service data with this:
timestamp: '{{ as_timestamp(states.sensor.skiboard_next_alarm.state) - 60 * 30 }}'
This instructs HA to fill that helper with your next alarm time (which triggers the automation when changed), minus 30 minutes.
Save it. You can run it manually (Execute button at the top) or change the alarm on your phone and watch it magically update on its own. It should read a time that is indeed 30 minutes before your next scheduled alarm.
Script a smooth sunrise effect
Next, create a script. You could put this directly into an automation, but keeping this separate is a lot less messy and lets you re-use it elsewhere. Also, this can be done via the UI, but it's a bit tedious. It's best to open up /config/scripts.yaml
directly, which you can do with the File Editor HA add-on.
Add this in, taking care to not destroy anything that might already be in that file:
sunrise_wake_up:
alias: Sunrise wake-up
sequence:
- variables:
start_temp: 500
end_temp: 380
duration_mins: 30
- service: light.turn_on
data:
color_temp: '{{ start_temp }}'
brightness: 1
entity_id: light.nightstand_light
- delay: '1'
- repeat:
count: '{{ duration_mins }}'
sequence:
- service: light.turn_on
data:
brightness: '{{ (repeat.index / duration_mins * 255) | int }}'
color_temp: '{{ (start_temp + repeat.index / duration_mins * (end_temp -
start_temp)) | int }}'
entity_id: light.nightstand_light
- delay: '60'
mode: single
It starts by setting some variables. Play around with these if you want; the start/end temperatures are in "mireds" and I find these to be acceptable sunrise-ish colors. duration_mins
is set to 30 minutes, but if you want more or less feel free to tweak this. But, be sure to update your helper automation to change the "pre-alarm" time to match. Also, my light is called light.nightstand_light
, but you'll want to replace the two locations there.
Then, we turn the light on to some minimum values. Afterwards, we wait a second (some lights are fickle if you try to do stuff fast right after turning them on), and begin a loop.
This loop sets the brightness and color temperature, linearly scaling up using the loop index. Then it waits a minute, and repeats until 30 minutes have passed. In other words, each minute the brightness and color temperature change by tiny amounts until complete.
If you're an HA expert, you might know that light.turn_on
supports a transition
key, which would remove the need for the loop and delay. But my bulbs don't support that (although I have some switches that do), and bulbs that do don't tend to support long transitions of color temperature. So we're doing it ourselves.
Tie it all together
We have a script, we have an auto-updating helper. Let's make things actually work. Easy:
Create another automation. Call this... "Alarm sunrise wake-up".
Trigger of type Time, using "Value of a date/time helper", and pick that helper we've been using (input_datetime.next_pre_alarm
). Skip conditions again.
Add an action of type Call service, service script.sunrise_wake_up
(match the entity ID of the script as before). Leave Service data blank. Save it. Done! The next time your alarm goes off, you'll have a nice sunlight-ish transition happen 30 minutes before.
$120 saved and a fun adventure into home automation guts.