Easier notifications in iOS 2021.5

Notifications are a popular feature of the Companion apps, but the differences between Android and iOS made it painful to use them to their full potential. Starting with today’s release of iOS 2021.5, the vast majority of functionality is now shared across both platforms. As part of this, the notifications documentation has been extensively updated as well.

Actionable notifications

Building actionable notifications for iOS and watchOS no longer requires defining categories in advance of using them; instead, you can include the actions right in the notification. Support for macOS will be included in a future release. Categories were one of the hurdles around multi-server support, so removing them entirely solves that part!

Included in the documentation is how to migrate from categories to dynamic actions. Both are still supported in the app at this time, but categories will be removed in the future.

Below is an example script which sends an actionable notification and uses script variables, wait for trigger, and choose to decide what to run.

# In a script's `sequence` or an automation's `actions`
- alias: "Set up action variables"
  variables:
    # Including 'id' in 'action' allows us to identify this script run
    # and not accidentally trigger for other notification actions
    action_very: "{{ 'VERY_' ~ context.id }}"
    action_mod: "{{ 'MOD_' ~ context.id }}"
- alias: "Send the notification"
  service: notify.mobile_app_zac_iphone
  data:
    message: "Are you hungry?"
    data:
      actions:
        - action: "{{ action_very }}"
          title: "Very Hungry"
        - action: "{{ action_mod }}"
          title: "Moderately Hungry"
- alias: "Wait for a response"
  wait_for_trigger:
    # We wait for specific actions because we don't want to run for 
    # any action, only for a response to the one we just sent
    - platform: event
      event_type: mobile_app_notification_action
      event_data:
        action: "{{ action_very }}"
    - platform: event
      event_type: mobile_app_notification_action
      event_data:
        action: "{{ action_mod }}"
- alias: "Handle the response"
  choose:
    - conditions: "{{ wait.trigger.event.data.action == action_very }}"
      sequence:
        - service: notify.notify
          data:
            message: "⚠️ Soylent Launch Incoming"
        - service: homeassistant.turn_on
          target:
            entity_id: switch.soylent_dispenser
    - conditions: "{{ wait.trigger.event.data.action == action_mod }}"
      sequence:
        - service: notify.notify
          data:
            message: "Anyone want to grab a croissant? -Zac"

This works for both platforms without including any platform-specific logic! Other features around actionable notifications are also shared, including adding a URL to open when picking an action:

actions:
  - action: "URI"
    title: "View More"
    uri: "/lovelace/some-dashboard"

Replacing, grouping, clearing

Replacing existing notifications or threading certain notifications was another difference between platforms, and the iOS-specific versions were a bit less ergonomic, so the Android versions now work for both. You can now use the simpler tag and group keys:

- service: notify.mobile_app_<your_device>
  data:
    message: "The front door is unlocked!"
    data:
      # replace any existing front_door_lock notifications
      tag: front_door_lock
      # thread with other doors notifications
      group: doors

You can also remove an existing notification by its tag:

- service: notify.mobile_app_<your_device>
  data:
    message: clear_notification
    data:
      tag: front_door_lock

Attachments

Attachments no longer require certain categories for dynamic attachment, so you can include streaming playback of a camera for any notification:

- service: notify.mobile_app_<your_device>
  data:
    message: "Motion detected"
    data:
      entity_id: camera.outside

Specifying a non-dynamic attachment is a little easier now, allowing you to short-hand the attachment part:

- service: notify.mobile_app_<your_device>
  data:
    message: "3D Print Complete"
    data:
      image: /media/local/3dprinter/latest.jpg

You can use video, image and audio. Only image is supported on Android.

You may have noticed that iOS notifications have file limits; this release adds on-demand downloading of attachments that exceed the size limit or when requested using the lazy attachment option.

Future areas of improvement

We’re still on the lookout for places of confusion or redundancy in notifications across the iOS and Android apps. What would you like to see improved?


This is a companion discussion topic for the original entry at https://www.home-assistant.io/blog/2021/05/10/ios-20215/
11 Likes

As someone who has a house with both android and ios, thank you.

I fully understand how we ended up with two different methods for notification but it drove me mad. Thank you for spending the time to sort it out.

Have a gold star, you legends :star:

2 Likes

This is a stellar improvement!

Wow this makes me unbelievably happy, 100% less hair pulling is extremely accurate. For reference, here’s the 150 lines of javascript I was using today in Node RED to do exactly this - normalize the schema of notifications between Android and iOS. Very glad to drop all that :+1:

For feedback on what else is frustrating:

  1. Can critical and priority: high be normalized? I know that some of the sound settings are ios/android specific so nothing can be done to normalize it entirely. But it would be nice there was a common way to mark a notification as critical on both platforms.
  2. Can action_data be added to android? It’s useful to be able to include additional data with your notification that then gets passed back to the automation when an action is taken. This is super easy in iOS since you can put whatever data you want parrotted back in action_data. It’s not really possible on android, you essentially just get back which action was clicked and the tag. It would be great if action_data was universal.
  3. If only icon_url is set it would be nice if that was normalized. The way I do this today is by making that into an image attachment and not hiding the thumbnail on iOS/Mac. It would be great if this was just done natively. Or even better if iOS/Mac had icon support like android, is that possible? Probably one of the features I miss the most on iOS/Mac.
  4. I personally normalize subtitle and subject in my usage of the two. I know they aren’t quite the same so I understand if others don’t agree though.

Other then that you really nailed this. I’m going through my code and you covered nearly all of it. The only other thing I’d personally request has nothing to do with iOS and Android but rather with persistent_notifications. What I have in my setup is a notify group called notify.home. This sends the notification to each person in my house as well as creating it as a persistent notification in HA.

Currently Node RED listens for calls to this group and actually sends the notifications so it can do all the normalization. After these changes I will almost be able to remove Node RED and make it a normal group except one last thing. In order to replicate the notification to HA you have to do the following:

  1. Move the value in data.tag to notification_id
  2. Remove data entirely
  3. Call persistent_notification.create. Can’t use notify.persistent_notification since it doesn’t accept an ID for the notification.

It would be great if notify.persistent_notification also used data.tag as its notification_id so you could easily send the same notifications to HA, android and iOS.

It would also be great if those had actions, images and all the other features as well but that’s a whole separate discussion

Would be nice one day to get actionable notifications without being forced to make a contract with Google or Apple. This includes not being obligated using their infrastructure for notifications. :bulb:

Like it is written on this site for almost 3 years now:

image

2 Likes

I’d love to see a better/easier/automated way to handle the notification counter (badge).

Right now it’s kinda complicated to implement those. You have to keep track of them with an input_number that increases with every notification (but not if it’s the same message that simply gets “updated”) and resets to 0 as soon as you open the app - the situation where one of the notifications becomes redundant (and removed with the new option) is even way harder. I imagine something like this would be the best from a user’s perspective:

data:
  push:
    badge: +1
data:
  push:
    badge: -1

Personally I just wish the badge was automatically set to the number of persistent notifications. I have an automation which listens for the persistent_notifications_updated event and keeps them in sync but it seems like this would be nice default behavior. Also the number is off a lot if the notification to update the badge number failed to deliver, like if my mac is asleep for a while or something.

1 Like

It would be great, if notification clearing would also work with notifications created by the alerts integration. It seems to be supported on the android companion app, but on ios I could not make it work.

I tried it with the following “done_message” parameter:

  message: "Alert message"
  done_message: clear_notification

Check here:

And use data: from the alert integration

Thanks for posting this link. This is exactly what I did, with “data” as well as “tag” and even “group” tags. It still doesn’t clear the notification.

  message: "Window is open"
  done_message: clear_notification
  data:
    tag: window_open_notification
    group: alert_group

The first alert notification goes through. The done_message never gets sent somehow. Could it be that clearing notifications is not supported from alerts on ios yet?

There’s a useful conversation happening now over at this Nextcloud Talk issue. They needed an option for instant notifications across Android and iOS devices without involving Google or Apple. While there’s currently a lot of bickering and fighting on the thread about which system is best to do it, the people arguing actually all came up with very similar solutions.

There is working, open source code available linked there right now.

Maybe the Home Assistant could use something similar. Alternatively, OpenPush (by Bubu, also mentioned in that thread) is designed to basically set up a self hosted notification server that any app can register with, so maybe the HA app could just register with that or even better, have an add-on that hosts the notification server itself.

I know it’s not easy, but the time has come for privacy, self hosted focused projects like HA / Nextcloud to work together and stop sending users private metadata through Google and Apple’s surveillance machines. The Code is Out There.:woman_technologist::alien:

2 Likes

What do you mean alerts?

Critical notifications can be cleared in iOS but only mist recent one. currently I worked around that by sending clear notification every time prior to actual notification. This way I ensure that only one critical notification (for particular tag) is active.

Hi @maxym,
my problem with clearing notifications on ios is with the alert integreation:

It’s a special kind of automation which is very handy to create notifications for binary sensors like door (open/close) or smoke alarms. Easier to reason about for me than regular automations.

Thanks for the answer. Don’t even know such thing does exists. I create such logic on my own (in NR), which in most cases remains working regardless changes in core HA (or I can fix it on my in a minute)

This alert works for me:

input_boolean:
  alert_test:
    name: Alert Test

alert:
  test:
    name: 'Test'
    entity_id: input_boolean.alert_test
    state: 'on'
    message: 'Alert Test'
    done_message: 'clear_notification'
    repeat: 5
    notifiers: mobile_app_zac_iphone
    data:
      tag: test_alert

Toggling on/off the input_boolean causes it to clear the previously-sent one.

This is extremely odd. It works now. But first I tried removing and readding a lot of tags, changing quotation style, and lots of restarting. One of the many changes finally worked. Unfortunately I can’t tell which one made the difference.

One suspicion I have is that my data: tag: tag was to loong. Possibly launching the Home Assistant app using the notification also helped.

Anyways, it works now. Thanks for your help.

Have a look here: Notify to persistent notification
It predates the new notify.persistent_notification, but it can handle notification_id.

Yea I’ve seen that one. And just to be clear, I have a working workaround. The article was just asking for info on what other places of confusion or redundancy we’ve found to get a list for future improvements. The differences between HA notifications and HA Companion app notifications is one for me