Waking Up to a Sunrise, Five Minutes Before My Alarm
Table of Contents
In the last post I promised a proper look at the automation people always ask about: my bedroom lights fade up to full brightness over the five minutes before my phone alarm, so I wake up to light instead of noise. It’s my favourite thing in the setup, and also the most over-engineered.
Your phone won’t tell your house anything #
Home Assistant (the open-source hub I run my whole smart home through) has no idea what time the alarm on your iPhone is set for. Apple doesn’t expose that to third parties, and there is no integration, no API, no polling trick that gets it out of iOS. As far as Home Assistant is concerned, the alarm on your phone does not exist.
There’s one exception, though. The Shortcuts app (Apple’s built-in automation tool) can read your alarms, through its “Find Alarms” action. So the plan is to build a Shortcut that reads the alarm time out of iOS and pushes it into Home Assistant, where the rest of the automation can get at it.
What you’d need to build it #
Nothing here is exotic, but it does assume a few things are already in place:
- A running Home Assistant instance. Any box will do: a Raspberry Pi, a mini PC, one of the official Home Assistant Green or Yellow units, or a VM. It’ll run as a dedicated appliance, inside a VM, or in Docker like mine. The last post covers how mine came to exist.
- The Home Assistant companion app on your phone, signed in to that instance. It’s what puts the Call Service action inside Shortcuts, and it handles the notifications and phone sensors too.
- Smart lights that honour transitions. The whole effect rides on the
transitionparameter, and not every bulb respects it. Cheaper wifi bulbs often jump straight to full brightness instead of fading; most Zigbee bulbs and Hue handle it properly. - Three helpers and a template sensor, created once through the Home Assistant interface. Steps 2 and 3 walk through them.
- The Shortcut and its trigger: the iCloud link in Step 1, plus the Personal Automation that runs it whenever the Clock app opens or closes.
One note if you’re on Android: you can skip Step 1 and the helpers in Step 2 altogether. The Home Assistant companion app there exposes your next alarm as a sensor already, so there’s no Shortcut to build and nothing to feed it into. Point the Step 3 trigger at that sensor in place of sensor.first_alarm, and Step 4 is identical.
Step 1: getting the alarm time out of iOS #
The Shortcut does three things. It finds every alarm on the phone, throws away the ones that are switched off, and pushes what’s left into Home Assistant: the earliest alarm time into one helper, the latest into another, and a simple on/off flag into a third so the rest of the system knows whether any alarm is set at all.
Cleaned up, the logic looks like this:
Find All Alarms
Repeat with each alarm
If the alarm Is Enabled
Add it to a List
End Repeat
If the List has any value (at least one alarm is on)
take the first item → set input_datetime.first_alarm
take the last item → set input_datetime.last_alarm
turn on input_boolean.alarm_boolean
Otherwise (no alarms set)
turn off input_boolean.alarm_boolean
The awkward part is when this runs. iOS has no “an alarm changed” trigger, so there is nothing to hang the Shortcut on directly. My workaround is a Personal Automation in the Shortcuts app that fires whenever the Clock app is opened or closed, set to run immediately without the confirmation prompt. The logic being: the one time I reliably touch my alarms is when I’m in the Clock app, so leaving the Clock app is a decent proxy for “I might have just changed something.” Every time I close it, the current alarm state gets synced across.
Rather than have you rebuild all that by hand, I’ve shared the whole Shortcut as an iCloud link: grab it here. Add it, then point the four Call Service actions at your own Home Assistant server and helper names. It leans on the Home Assistant companion app’s Call Service action, which is what lets a Shortcut poke a helper on your HA box directly.
Step 2: where the alarm lands in Home Assistant #
On the Home Assistant side, the Shortcut is writing into three helpers I set up by hand, all sitting in the Bedroom area:
input_datetime.first_alarm, a Time helper, holding the earliest enabled alarm.input_datetime.last_alarm, the same, for the latest.input_boolean.alarm_boolean, a simple on/off that’s on when any alarm is set.
There’s one more small layer. Instead of having my automation read the input_datetime attribute directly, I convert each helper into a plainly formatted template sensor, because HH:MM is much easier to work with downstream than a raw timestamp:
template:
- sensor:
- name: "First alarm"
state: >-
{{ state_attr('input_datetime.first_alarm', 'timestamp')
| timestamp_custom('%H:%M', None) }}
That gives me sensor.first_alarm, reading something like 07:00. Everything after this point works off that sensor.
Step 3: the trigger that fires five minutes early #
The automation uses a template trigger rather than a fixed time, because the fire time has to move whenever my alarm does:
trigger:
- platform: template
value_template: >-
{{ as_timestamp(today_at(states('sensor.first_alarm'))) - 300
< as_timestamp(now()) }}
Reading it inside out: today_at('07:00') gives today’s date at the alarm time, - 300 knocks off five minutes, and the whole thing becomes true the moment now() passes that point. Home Assistant re-checks any template containing now() roughly once a minute, so at 06:55 the expression flips from false to true and the automation fires. Move the alarm to 06:30 and the trigger point slides to 06:25 on its own.
Two conditions guard it so it only runs when it should:
condition:
- condition: state
entity_id: person.joshua_knipe
state: home
- condition: state
entity_id: input_boolean.alarm_boolean
state: "on"
The first stops my bedroom lighting up at dawn while I’m away for the weekend. Home Assistant works out whether I’m home from a luci device tracker pointed at my OpenWRT router, which watches whether my phone is on the home network. The second condition means no enabled alarm, no sunrise, which is what makes weekend lie-ins possible.
Step 4: the actual sunrise #
The trigger did the hard part. What it fires is just two light.turn_on calls:
action:
- service: light.turn_on
target:
entity_id: light.desk_lamp
data:
transition: 300
brightness_pct: 100
rgb_color: [255, 251, 185]
- service: light.turn_on
target:
device_id: 5c3ac8a2fcc5ff4c2e98fec9e41ffa3a
data:
transition: 300
brightness_pct: 100
rgb_color: [254, 252, 221]
transition: 300 is the entire trick. It tells the bulbs to take 300 seconds to reach the target, so instead of snapping on they ramp from dark to full over exactly five minutes, landing at 100% brightness in a warm off-white right as the alarm would have gone off. By then I’m usually already awake, before the alarm sound has to do anything.
One last action, less obvious than the two light calls:
- service: automation.turn_off
data:
stop_actions: true
target:
entity_id:
- automation.bedroom_lights_auto_off
- automation.bedroom_lights_auto_on
My bedroom lights are normally driven by motion, switching on when I move and off when the room’s been still for a while. Left alone, those automations will happily fight the sunrise, snapping the lights to full the instant I stir or killing them mid-fade because I’ve been lying still. So the sunrise disables both of them as it starts. (It also means they have to be switched back on again later, which is a trap I fell into the very first morning.)
The rest of the house, briefly #
The sunrise is the showpiece, but it sits on top of a pile of smaller automations built on exactly the same parts: a trigger, a condition or two, a service call. A few of the ones I use daily:
- Front door notifications. A Zigbee contact sensor on the door fires a push to my phone every time it opens. There are two conditions in there for “only notify when I’m away,” both currently switched off, because I decided I actually wanted to know every time regardless.
- Morning kettle. A smart plug switches the kettle on when my alarm goes off, so the water’s boiled by the time I get to the kitchen. It hangs off the same alarm time as the sunrise, just fired at the alarm itself rather than five minutes before.
- HomeKit bridge. Home Assistant exposes a handful of lights and automations back into Apple Home, so I can still say “Hey Siri, turn off the desk lamp” and have it route through HA. Half the entities in there are
wled_*, the addressable-LED strips dotted around the flat.
Those door notifications come from the Home Assistant companion app on my phone, which also feeds a pile of phone sensors back to HA: battery level, location, and the like.
Any problems? #
Plenty, and most of them live in that first step.
The trigger is a proxy, not the real thing. The Shortcut only syncs when I open or close the Clock app. If I ever changed an alarm some other way, or the Personal Automation silently failed to run, Home Assistant would be working off a stale time and either fire at the wrong moment or not at all. In practice I open the Clock app to set an alarm anyway, so it mostly self-corrects, but it’s really a proxy for “I changed an alarm”, not proof that I did.
The template trigger is a little fragile. Because it re-evaluates about once a minute, the fire time can be up to a minute out, which is fine for a five-minute run-up. Less fine is that if sensor.first_alarm is ever blank, the today_at() call throws errors into the log until the next sync fixes it.
I forgot to turn the motion automations back on. The very first morning this worked, I woke up delighted, got up, and then spent the rest of the day baffled that my bedroom lights had gone completely dumb. The sunrise had disabled the motion automations exactly as designed, and I hadn’t built anything to switch them back on.
What’s next #
More of the series to come:
- Ambient lighting with Hyperion and LedFX, and all those
wled_entities that snuck into the HomeKit bridge above. - Home networking: Tailscale, OpenWRT and Pi-hole, including the router-based presence detection that decides whether my sunrise runs.
- Linux, and why I chose EndeavourOS for the mini PC.
If you’ve got a phone, a Home Assistant box and a smart bulb, the sunrise is worth the afternoon it takes to wire up. Just remember to switch your other automations back on afterwards.