I hate my iPhone alarm clock. I wonder why this is one of the most neglected applications on every phone out there, even if it is one of the most used.
I don’t like to be woken up abruptly. I need to wake up gently with a slow process. That makes my day better. I also don’t need to listen to any voice in the early morning. I need some soft music to drive me to the awake state.
This is the reason why I designed my alarm clock on Home Assistant.
Here are the features I implemented:
- The alarm clock will trigger ten minutes before I set for wake up.
- The alarm clock will have to simulate sunrise in ten minutes.
- The alarm clock will have to play a playlist of gentle and instrumental songs.
- The alarm clock will have a Snooze functionality.
- The alarm clock must be controlled with Alex (still to be implemented, actually.)
I found out that implementing those features with native Home Assistant was a little bit of a mess, at least for me. I decide to take the Node-RED path instead. I have always loved Node-RED, and it is responsive on my system.
I copied the idea I found on the DIY Futurism blog a couple of years ago. It was a great blog, but the author does not post anymore. I started from his Node-RED flow and modified it to suit my needs.
Ok, let’s dive into it.
The first thing you will have to do is to implement some helpers to expose on the Lovelace user interface.
You need to have two input_boolean:
alarm_clock_on_off:
name: Alarm Clock
icon: mdi:alarm
alarm_clock_snooze:
name: Alarm Snooze
icon: mdi:alarm-snooze
alarm_clock_on_off: this will control the alarm clock. If true, the clock is armed and ready to be activated at the right time.
alarm_clock_snooze: if this is true, we are snoozing.
You will need a Date and/or Time helper. This is where you will set the time for your alarm clock.
alarm_clock_time:
name: Alarm Clock Time
icon: mdi:timer-edit-outline
has_date: false
has_time: true
I set those up in my YAML files, but you can easily do the same thing from the UI (Settings → Devices & Services → Helpers → Create Helper)
You will also need a variable to control the status of the alarm clock. I have used the home-assistant-variables custom integration. (GitHub - snarky-snark/home-assistant-variables at v0.15.0)
Here’s my definition:
house_state:
friendly_name: House State
initial_value: "Sleeping"
The house_state variable will be “Sleeping” when the alarm is not active and will turn to “Waking Up” when the alarm Node-RED flow is running to wake me up.
You will now need to create a Lovelace card to control the alarm clock. This is mine:
type: vertical-stack
cards:
- type: custom:mushroom-title-card
title: Alarm Clock
- type: entities
entities:
- entity: input_boolean.alarm_clock_on_off
- entity: input_datetime.alarm_clock_time
- entity: var.house_state
name: Alarm Status
- type: horizontal-stack
cards:
- type: custom:button-card
name: Snooze
icon: mdi:alarm-snooze
show_state: false
tap_action:
action: call-service
service: script.turn_on_alarm_clock_snooze
data: {}
target: {}
styles:
card:
- width: 100px
- height: 100px
img_cell:
- align-self: start
- text-align: start
name:
- justify-self: center
- padding-left: 0px
- font-weight: bold
state:
- justify-self: center
- padding-left: 0px
- type: custom:button-card
name: Stop
icon: mdi:stop-circle-outline
show_state: false
tap_action:
action: call-service
service: script.stop_alarm_2
data: {}
target: {}
styles:
card:
- width: 100px
- height: 100px
img_cell:
- align-self: start
- text-align: start
name:
- justify-self: center
- padding-left: 0px
- font-weight: bold
state:
- justify-self: center
- padding-left: 0px
There are a couple of Custom Cards in there: mushroom-title-card and button-card. You can work out what is best for you.
The buttons “Snooze” and “Stop” have two scripts associated with them. We will talk about these later.
Ok, that’s all you need to do on your Home Assistant instance. Now let’s move to Node-RED. You will have to have the Node-RED add-on installed on your system.
Please create a new flow and give it the name you prefer.
This is a picture of my node as it is today:
The flow code above is available on PasteBin: Alarm Clock Node-RED Flow
The flow code has been “scrubbed” and you should be able to import to your instance without any issue with Servers and so on.
The flow is not one of the most simple, but it is readable in terms of functionality.
The flow will wait for the alarm time by checking the value of input_datetime.alarm_clock_time each minute. When the alarm triggers, it will start the media player with the media content you have defined and start the light procedure.
Here is what you may want to change to adapt the flow to your needs:
- You have a node called “Set Flow Variables.” In this node, you can define which media player and light will be used for your alarm clock. I have Sonos speakers and Philips Hue lights all around my house, and this is what I use.
- A node called “Play Spotify Playlist” will let you define what media the selected media player will play on wakeup. I am a Spotify user, and I use a Spotify playlist.
- The “Increment Volume” will increase the media player volume one step at a time since you will have reached the value defined in the if condition of this node. Adjust the value to your needs.
- Same thing for the “Increment Brightness” node.
- I can snooze the alarm from the Companion App on my iPhone or by long pressing a button on the Philips Hue Switch that controls the light I have associated with the alarm. Any smart switch you have will do the trick. Important to note that I have used a Philips Hue palette to get notified of the press event. You can use whatever event you want to control the snooze.
- When the alarm loop is done, some actions will be taken. You can see them on the right side of the node called “Is Loop Done?”. You can change these actions to whatever suits your needs. The only thing you must not remove is the “House State - Sleeping” node. This is used to control the alarm clock.
As I said before, two scripts on Home Assistant are used by the Lovelace card.
Here is the code for those scripts.
Turn on alarm clock snooze:
alias: Turn on Alarm Clock Snooze
sequence:
- service: input_boolean.turn_on
data: {}
target:
entity_id: input_boolean.alarm_clock_snooze
mode: single
Stop Alarm:
alias: Stop Alarm
sequence:
- condition: state
entity_id: input_boolean.alarm_clock_on_off
state: "on"
- service: media_player.media_pause
data: {}
target:
entity_id: media_player.sonos_camera
- service: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.alarm_clock_on_off
- service: var.set
data:
entity_id: var.house_state
value: Sleeping
- service: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.alarm_clock_snooze
mode: single
icon: mdi:stop-circle-outline
This last script mimics the behavior of the Node_RED nodes after the “Is Loop Done?” node. Modify it to reflect the same thing you added there—no big deal.
This is it.
I don’t actually need to implement a Weekday/Weekend functionality in my alarm. My agenda is quite hectic and I prefer to set the alarm clock manually every single day. You may want to add this functionality if you want to. The Node-RED flow area where you need to add this check is the “TRIGGER ALARM CLOCK” area. To accomplish this you will also need to add some more helpers to do the trick.
One last thing. The behavior of the Philips Hue Light when turning them on and then changing the brightness value is silly. Before the new brightness has an effect, the light will turn on at the same brightness it was on the last time. This means that you may find yourself with full brightness when the alarm clock triggers. The light will dim to the value set in the Node-RED flow a few moments later. This is not good at all. I am still investigating this, but the only thing I found was to remember to dim the light before going to sleep. Not very good.