Home Assistant - Notifications - An Alarm for an Alarm

Home Assistant - Notifications - An Alarm for an Alarm

Greetings all and welcome back to a long overdue post on MAKES.swakes!

It happened again like with most of the elements I design or build within Home Assistant, I ended up down a rabbit hole. This time it was delving into the realm of notifications. Two types of notifications to be precise -  'Actionable Notifications' and 'Notification Commands' which are both via the Home Assistant Companion App.

Firstly, let me provide some context and explain the method behind the madness. An alarm for an alarm. Yes, you read it correctly. As I start work at 6AM each day (Mon-Fri), I'm dependant on an alarm to wake me up in the morning as I'd happily sleep in until mid-morning/day. Armed with the recent discovery of 'Actionable' and 'Command' notifications, I began to knock up a handy automation to help combat the possible risk of oversleeping and missing the start of my shift (and ultimately not getting fired).

So how does it work exactly? Well, the automation runs at 11PM the night before each shift and checks that either an alarm has been set and/or phone alarm volume is above a certain level. From there it'll push an Actionable Notification to my phone and give the options of 'Ignore' (ignore alert), 'Volume Up' (increase alarm volume) or 'Set Alarm' (create and set an alarm for next morning).

Before we dive into the 'how' it's worth stating that this automation and the 'Notification Commands' have been created for an Android phone setup and may be different/not feasible for an iOS phone/device.

Be sure to checkout the documentation here to determine what can/can't be done on your device.

Here is how the automation works, broken down into its 6 stages ...

Triggers

First we sort out the trigger which in this case is 'time' (at 11PM).

Conditions

Next are the conditions which would ultimately decide on whether to go ahead with the rest of the magic. Here it's checking for two things, if my phones alarm volume is below a set value (minimum is 0, maximum is 6) and if an alarm has been set (something other than 'unavailable').

Actions

If the conditions above have been met, we can then crack on and put some stuff into motion. Firstly, we need to declare some variables which will be the 'Actionable' options for the push notification.

Next is the actual content which will be shown within the push notification.

Normally this would be a simple text content/message (under 'message: ...') however in this instance I've gone down the route of displaying an image instead. For an alert such as this, using a static image containing no specific variables/data (timings, sensor name etc) would suffice.

After that a 'wait_for_trigger' (event) needs to be defined ...

And the final part of the automation are the actions using the 'Notification Commands' in order to perform the 'needful' on the phone as desired.

This is what the entire automation YAML code looks like ...

alias: "Morning Phone Alarm"
description: ""
trigger:
  - platform: time
    at: "23:00:00"
    enabled: true
condition:
  - condition: or
    conditions:
      - condition: numeric_state
        entity_id: sensor.pixel_6_pro_volume_level_alarm
        below: 5
      - condition: state
        entity_id: sensor.pixel_6_pro_next_alarm
        state: unavailable
action:
  - alias: Set up variables for the actions
    variables:
      action_ack: "{{ 'Ack_' ~ context.id }}"
      action_setvol: "{{ 'SetVol_' ~ context.id }}"
      action_setal: "{{ 'SetAl_' ~ context.id }}"
  - alias: Work Alarm Warning Message and Responses
    service: notify.mobile_app_pixel_6_pro
    data:
      message: ""
      title: Home Assistant
      data:
        image: https://i.imgur.com/DZRSkYB.png
        actions:
          - action: "{{ action_ack }}"
            title: ‎ ‎‎ ‎ ‎  Ignore
          - action: "{{ action_setvol }}"
            title: ‎ ‎ ‎ ‎ Volume Up
          - action: "{{ action_setal }}"
            title: ‎ ‎‎  ‎ Alarm Set
  - alias: Wait for a response
    wait_for_trigger:
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: "{{ action_ack }}"
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: "{{ action_setvol }}"
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: "{{ action_setal }}"
  - alias: Perform the action
    choose:
      - conditions: "{{ wait.trigger.event.data.action == action_ack }}"
        sequence:
          - service: notify.mobile_app_pixel_6_pro
            data:
              message: clear_notification
              data:
                tag: phone-alarm-reminder
      - conditions: "{{ wait.trigger.event.data.action == action_setal }}"
        sequence:
          - service: notify.mobile_app_pixel_6_pro
            data:
              message: command_activity
              data:
                intent_package_name: com.google.android.deskclock
                intent_action: android.intent.action.SET_ALARM
                intent_extras: >-
                  android.intent.extra.alarm.HOUR:{{ 5
                  }},android.intent.extra.alarm.MINUTES:{{ 45
                  }},android.intent.extra.alarm.SKIP_UI:true,android.intent.extra.alarm.RINGTONE:VALUE_RINGTONE_SILENT
      - conditions: "{{ wait.trigger.event.data.action == action_setvol }}"
        sequence:
          - service: notify.mobile_app_pixel_6_pro
            data:
              message: command_volume_level
              data:
                media_stream: alarm_stream
                command: 6
mode: single

Pretty handy though eh? With all that said and done, the automation in its current state it works as intended however there are still a bunch of tweaks/improvements to be made. Some of these include ...

Setup Google Calendar (work schedule/rota)
Checks against entries on Google Calendar and only runs on workdays to avoid firing on days off and/or weekends.

Include 'timed out'/ignored/no response element
If not acknowledged within 'X' minutes > Repeat, cast audio notification, flash LEDs etc

ImageMagick to amend/edit image alerts
Additional element needed to potentially make image alerts dynamic (include sensor details, values etc) using ImageMagick 'convert'.

So we've finally come to the end of todays ramblings.

If you've got any suggestions or queries about where/what to do next, please drop me a message on Reddit!

Buy Me A Coffee