Creating a bedtime button in Home Assistant

A photo of a Zigbee scene button that I am using to trigger a bedtime automation.

To help our ten-year-old get to sleep, we play some sleepy music in their bedroom each night. I’ve now automated this, using Home Assistant and a Zigbee scene button, so a single button press starts the automation and plays the correct Spotify playlist. Here’s how I went about it.

The button

I bought the button from AliExpress for a mere £2.60. I can’t find the exact same button on Amazon, but this is a close match at £8.99 (sponsored link). It has a single CR2032 button battery, and is easily paired with Zigbee2MQTT and then Home Assistant. There’s also a double-sided sticky tab to attach it to a wall.

The button I bought offers two modes: single press, and double press. You can therefore trigger different automations in response to whether the button is pressed once or twice. The more expensive button from Amazon also supports a third mode, which is a five second long press.

Installing Music Assistant

Whilst Home Assistant has a Spotify integration, in my testing I couldn’t get it to play the correct playlist on the Google Nest Mini smart speaker that is in our ten-year-old’s room. So, a workaround is to install Music Assistant, which is a related project that is also run by the Open Home Foundation. This can be installed as an App in Home Assistant; once installed, you’ll need to add Spotify as a source. Music Assistant quickly found all of my Google Cast devices.

Next, you’ll need to install the Music Assistant integration in Home Assistant – it may be automatically discovered for you. If you already have your Google Cast devices added in Home Assistant, then you will end up with separate Music Assistant entries for them too.

Creating a timer helper

So that the music doesn’t keep playing all night, we can create a timer that can stop the music after a given time period has elapsed. I did this by creating a Helper, using the type timer and the default time of 1 hour 30 minutes.

You can also simply put a time delay in your automation, but using a helper allows you to cancel the timer before it completes – handy if our ten-year-old falls asleep quickly.

Creating the automation

I set this up using the Home Assistant UI, but here’s the YAML code:

alias: Bedtime
description: ""
triggers:
  - domain: mqtt
    device_id: [device]
    type: action
    subtype: single
    trigger: device
conditions: []
actions:
  - action: music_assistant.play_media
    metadata: {}
    target:
      entity_id: [media_player.device]
    data:
      media_id: >-
        [playlist URL]
    continue_on_error: true
  - action: timer.start
    metadata: {}
    target:
      entity_id: [timer.bedtime_timer]
    data: {}
mode: single

The automation listens for the button press, and when it’s pressed once, it starts the music playing and starts the timer. The playlist URL is from Spotify – if you find the playlist you want, go to Share and then Copy URL, this is what you need.

I then have a second automation to trigger when the timer stops:

alias: Stop bedtime music when timer finishes
description: ""
triggers:
  - trigger: timer.finished
    target:
      entity_id: [timer.bedtime_timer]
    options:
      for: "00:00:00"
conditions: []
actions:
  - action: media_player.media_stop
    metadata: {}
    target:
      area_id: [bedroom]
    data: {}
mode: single

This actually works slightly differently, and tells Home Assistant to stop playback on all media players in a room, rather than the specific media player specified in the first automation.

Finally, I made use of the double-press mode of the button to cancel the timer early:

alias: Cancel bedtime
description: ""
triggers:
  - domain: mqtt
    device_id: [device]
    type: action
    subtype: double
    trigger: device
conditions: []
actions:
  - action: timer.cancel
    metadata: {}
    target:
      entity_id: [timer.bedtime_timer]
    data: {}
  - action: media_player.media_stop
    metadata: {}
    target:
      device_id: [media_player.device]
    data: {}
mode: single

Flourishes

As a little flourish, in my first automation I have an initial first step which uses Chime TTS to announce, via the speaker, that it’s time for bed. It then starts playing the music afterwards.

My version of the automation also turns on a nightlight, as well as starting the music.

Rationale

We’ve been playing bedtime music for our ten-year-old for many years, but what prompted me was the Gemini upgrade for our Google Home smart speakers. On the whole, post-upgrade, our speakers have been more capable and offer better answers, but where they’ve fallen down is asking it to play a specific Spotify playlist. We have one playlist that we have used for years, but when we ask Google Gemini to play it, it ends up playing something else (often a different one each time) which is similar but not the same. I’m sure any parent of a neurodivergent child has experienced what can happen when you try to pass off something that isn’t quite what the child is used to as being the same.

By building an automation, I can specify the exact URL of the desired playlist, so the correct playlist is played every time. And, having a button in their room means our ten-year-old can simply press it themselves when they’re ready for bed.

A basic Home Assistant automation

A screenshot of Home Assistant showing an automation to turn off a smart plug after 18 hours

One of the biggest benefits of running Home Assistant in your home is its powerful automation tools for controlling your smart devices. In this example, I have a smart plug socket which I want to run for 18 hours, and then automatically switch off. This is the smart plug that we use for our heated drying rack, and it ensures that the rack doesn’t continue heating for longer than necessary, to save energy. As I run Home Assistant on a Raspberry Pi 4, it only uses 15 watts of power, compared to the few hundred watts that the drying rack requires.

Automations in Home Assistant have become much easier in recent releases. In times gone by, you’d have to write YAML scripts to automate your devices, but now there’s a relatively straightforward interface. Generally, automations work on the principal of ‘if this, then that’ – a bit like IFTTT, but it runs in your own home.

Tuya me, to you

For my automation, I use the trigger of the smart socket being turned on. In my case, this is a Tuya wifi-enabled smart plug, which I’ve called ‘Cuthbert’. We have four Tuya plugs, all with silly names like Cuthbert, just because. Tuya are a white label manufacturer, and so the brand names on the plugs vary despite them being exactly the same. I wouldn’t necessarily recommend them, as presumably every time you turn them on and off, your request goes via Chinese-controlled servers. I would probably buy Matter-enabled plugs instead now but they work fine. Plus, the recent 2024.02 release of Home Assistant massively improves Tuya support and no longer requires you to create a developer account, which is nice.

Automation actions

Anyway, having selected the ‘When’ event, we now need to specify the ‘Then do’ actions to take. First of all, we need a time delay, otherwise as soon as the socket is turned on, Home Assistant will turn it off again. The ordering of actions is important, as I found out the hard way; I originally had the delay after the command which meant that the socket just turned off straight-away. So, we specify a delay and then the action to turn the socket off.

The third action is optional, but it just sends a notification to my phone to tell me that the automation has completed. I’m using the Home Assistant Companion app but you could use an app like Pushover, or trigger an email.

This is a really simple automation, but you can create more complex ones. I’m hoping that, at some point in the future, we’ll have some smart blinds in our kitchen, and I’ll be able to use Home Assistant’s sun integration to open and close them at sunrise and sunset.

Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.