Tutorial: Advanced iOS Notifications with Home Assistant

This is a continuation of the iOS Actionable Notifications tutorial. If you’re looking for advanced features and enhancements of your iOS Actionable notifications – keep reading. If you’re looking to start from the beginning, check out that tutorial here first!

Basic Notification Enhancements

The following examples will all be using the Developer Tools, Service calls. We will be calling the notify.mobile_app_xx service, replacing xx with the iOS mobile device name. If this is unclear, take a look at the first part of this tutorial!

App Icon Badges

Notification Sounds

Replacing Notifications

There are still a few more enhancements you can add to your notifications! This includes sending notifications to multiple devices, and controlling how a notification will display when you have the Home Assistant Companion app open. I won’t cover them in this tutorial, but they’re explained in full detail over in the companion documents. If you’re having trouble implementing, feel free to contact me on Discord and I’d be happy to help!

Actionable Notification Enhancements

The following actionable notification enhancements will require modifying your actionable notification categories, in your configuration.yaml file. If this is unclear, take a look at the first part of this tutorial!

Activation Mode

Requiring Authentication

Destructive Alerts

As with the basic notification enhancements, there are still more enhancements you can add your actionable notifications! You can also add a text field to your actionable notifications, which will let the user enter a text response that will be sent back to Home Assistant. More details are available on the companion app documents here.

Critical Notifications

As you expand the types of sensors integrated in Home Assistant, some of these sensors & systems will produce critical notifications — Security system alarm tripped? Water leak detected? Smoke alarm sounding? Home temperature below freezing?

All of these are examples that would immediately require your attention which is where critical notifications are best used. Apple introduced them in iOS 12 and as such, your iOS device must be running iOS 12 or later.

Critical notifications are given full priority on iOS. They:

  • Appear first in Notification Center regardless of Do No Disturb
  • Will play a sound even if the iOS device is muted or on Do Not Disturb
  • Wont disappear on their own, must be swiped away
  • And, if you are using CarPlay, these notifications will even appear on the CarPlay dashboard!

To make an alert a critical notification, in the service call (i.e. not in configuration.yaml), under sound, we will add these three entries:

{
  "message": "Actionable iOS Notification - Alarm System",
  "data": {
      "push": {
        "sound": {
          "name": default,
          "critical": 1,
          "volume": 1
          }
      }
  }
}

But WAIT! Before calling this service, this example will send an alert, at full volume on you iOS device. Make sure you wont be waking anyone up as you test this. To make the alert a critical notification, critical: must be set to 1. The volume can be set to any decimal between 0 and 1. For example, to set the volume to 50%, "volume": 0.5. To turn the volume off but still make it a critical notification, set the volume level to 0.

Putting it All Together

Now, an example of combining multiple enhancements is shown below. The following example will call an actionable notification we previously defined in our configuration.yaml, called, 'alarm_notification', which defines two buttons: a destructive (red) button to Sound Alarm, and a button which requires authentication to Dismiss Alarm.

ios:
  push:
    categories:
      - name: "Alarm Control" 
        identifier: 'alarm_notification' 
        actions: 
          - identifier: 'SOUND_ALARM'
            title: 'Sound Alarm'
            destructive: true
            authenticationRequired: false
          - identifier: 'SILENCE_ALARM'
            title: 'Dismiss Alarm'
            destructive: false
            authenticationRequired: true

The example service call will set the Home Assistant Companion app badge number to 1. And, it is defined as a critical notification, at full volume, with a built in notification sound.

{
  "message": "Critical alert!",
  "data": {
      "push": {
        "sound": {
          "name": US-EN-Morgan-Freeman-Back-Door-Opened.wav,
          "critical": 1,
          "volume": 1
          },
          "category": "alarm_notification",
          "badge": 1
      }
  }
}

If you called this service, you would have ‘Morgan Freeman’ yell at you that your back door is open — nice.

Advanced Actionable Notification Example

An example of an actionable notification that I frequently use is for my robot vacuum. Three times a week, I receive a push notification stating that the robot vacuum will begin cleaning in 30 minutes. The three options I am presented are, Begin cleaning now, Delay cleaning, or Cancel cleaning. This automation is relatively easily set up in Node-RED. Let me show you how:

Setting up the Notification Category

This actionable notification returns one of three options: 'CLEAN_NOW', 'DELAY_CLEAN', OR 'CLEAN_CANCEL'. Authentication is not required for any option, and the Cancel cleaning button is presented as destructive (in red).

ios:
  push:
    categories:
      - name: 'Robot Vacuum'
        identifier: 'robovac'
        actions:
          - identifier: 'CLEAN_NOW'
            title: 'Begin cleaning now'
            activationMode: 'background'
            authenticationRequired: false
            destructive: false
          - identifier: 'DELAY_CLEAN'
            title: 'Delay cleaning'
            activationMode: 'background'
            authenticationRequired: false
            destructive: false
          - identifier: 'CLEAN_CANCEL'
            title: 'Cancel cleaning'
            activationMode: 'background'
            authenticationRequired: false
            destructive: true

Creating the Service Call

This service call is relatively simple. Just a message (always required) and a call to the robovac notification category that we previous defined. Make sure to ‘Import push configuration from server’ in the Companion App in order to correctly present a newly created notification category.

{
    "message": "Vacuum: Beginning the cleanup in 30 minutes",
    "data": {
        "push": {
            "category": "robovac"
        }
    }
}

Creating the Automation

I’ve created the automation in Node-RED. I’ll link the entire flow below, and will go through and explain the various components of how it works:

  1. On Tuesday, Thursday and Sunday, at 12:00am, I send a push notification to my phone with the three vacuum options.
  2. When that notification is sent, the event node labeled ‘iOS Notification’, picks that event up, and checks to see if it was the ‘robovac’ notification sent. If it was, it sends a command to the delay node (labeled variable). This delay node is set to a variable delay, that can be set with the msg.delay payload. As such, as soon as the notification is sent (regardless if I interact with the notification), a msg.delay with 1800000 milliseconds, or 30 minutes, is sent as the payload. This way, if I don’t interact with the notification, the vacuum will default to start in 30 minutes from the time the notification is delivered.
  3. If I do interact with the notification, these events are detected by the ‘iOS Action’ node, where the responses are sorted, depending on if I click clean now, delay or cancel clean.
  4. If I select: Clean Now, then a msg.flush message with a true boolean payload is sent. This causes the delay node ignores any delay and immediately pushes the message through to start the vacuum
  5. If I select: Delay Cleaning, msg.reset is sent to clear all pending messages, and then after 1 second, msg.delay is sent with a payload of 5400000 milliseconds, or 1.5 hours, which sets the delay longer than the default 30 minutes.
  6. If I select: Cancel Cleaning, a msg.reset message with a true boolean payload is sent, which causes the delay to clear all delayed messages, and does not send any message to the vacuum node, effectively canceling the cleaning.

If you want to check out the Node-RED automation yourself, feel free to import the code below:

[{"id":"ae04dda.53498a","type":"server-events","z":"bd820e3e.db5e08","name":"iOS Action","event_type":"ios.notification_action_fired","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":100,"y":160,"wires":[["9d96d971.25fd48"]]},{"id":"9d96d971.25fd48","type":"switch","z":"bd820e3e.db5e08","name":"Clean, Delay or Cancel","property":"payload.event.actionName","propertyType":"msg","rules":[{"t":"eq","v":"CLEAN_NOW","vt":"str"},{"t":"eq","v":"DELAY_CLEAN","vt":"str"},{"t":"eq","v":"CLEAN_CANCEL","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":280,"y":160,"wires":[["791dcd0a.079364"],["3f2598a0.15c06","ef45d6f8.e9bdf8"],["3f2598a0.15c06"]]},{"id":"61d130bd.1697d8","type":"server-events","z":"bd820e3e.db5e08","name":"iOS Notification","event_type":"call_service","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":140,"y":320,"wires":[["6e25e328.b7e33c"]]},{"id":"6e25e328.b7e33c","type":"switch","z":"bd820e3e.db5e08","name":"iPhone Notified","property":"payload.event.service_data.data.push.category","propertyType":"msg","rules":[{"t":"cont","v":"robovac","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":320,"y":320,"wires":[["c16e2b4e.77cd4"]]},{"id":"6bc6e94a.c86f18","type":"api-call-service","z":"bd820e3e.db5e08","name":"Start Vaccuum","version":1,"debugenabled":false,"service_domain":"vacuum","service":"start","entityId":"vacuum.xiaomi_vacuum_cleaner","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1080,"y":160,"wires":[[]]},{"id":"ba66e5c2.c03f2","type":"delay","z":"bd820e3e.db5e08","name":"","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":920,"y":160,"wires":[["6bc6e94a.c86f18"]]},{"id":"653fbbba.d985a4","type":"change","z":"bd820e3e.db5e08","name":"Set Delay - Extended","rules":[{"t":"set","p":"delay","pt":"msg","to":"5400000","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":160,"wires":[["ba66e5c2.c03f2"]]},{"id":"c16e2b4e.77cd4","type":"change","z":"bd820e3e.db5e08","name":"Set Delay - Default","rules":[{"t":"set","p":"delay","pt":"msg","to":"1800000","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":320,"wires":[["ba66e5c2.c03f2"]]},{"id":"791dcd0a.079364","type":"change","z":"bd820e3e.db5e08","name":"Flush","rules":[{"t":"set","p":"flush","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":120,"wires":[["ba66e5c2.c03f2"]]},{"id":"3f2598a0.15c06","type":"change","z":"bd820e3e.db5e08","name":"Reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":200,"wires":[["ba66e5c2.c03f2"]]},{"id":"97626d2f.f7e388","type":"api-call-service","z":"bd820e3e.db5e08","name":"Vacuum Notify","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_xx","entityId":"","data":"{\"message\":\"Vacuum: Beginning the cleanup in 30 minutes\",\"data\":{\"push\":{\"category\":\"robovac\"}}}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":400,"y":60,"wires":[[]]},{"id":"38771646.3189fa","type":"inject","z":"bd820e3e.db5e08","name":"Run at 12:00am Tu,Th,Sun","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"00 00 * * 1,3,5","once":false,"onceDelay":0.1,"x":180,"y":60,"wires":[["97626d2f.f7e388"]]},{"id":"ef45d6f8.e9bdf8","type":"delay","z":"bd820e3e.db5e08","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":460,"y":160,"wires":[["653fbbba.d985a4"]]}]

Conclusion

Hopefully these iOS notification enhancements can help your Home Assistant automations! Let me know in the comments some of your notification examples. And, if you’re loving the actionable notifications, check out the newly released Actionable Notifications from Alexa to Home Assistant created by Keaton!

2 thoughts on “Tutorial: Advanced iOS Notifications with Home Assistant”

  1. Hi, is there a way to repeat the sound of a notification?
    The intention is to create an alarm clock. Of course, this could be achieved by either have an insane long sound file or by sending the notification over and over again but i wonder if it is possible to just repeat the sound.
    Many thanks for the tutorial anyways, it’s awesome!

    Reply

Leave a Comment