Syncing Web App Persistent Notification Count to Mobile Device Badge Count

This doesn’t feel horribly innovative, but after several hours slogging through documentation and forum posts, I thought it would be worth sharing how I managed to get the notification count in the web app (i.e. persistent notifications) synced up with notifications and badge count on mobile apps. I saw someone had a feature request for HA to do this as part of core, and I really wish the team would do that. Anyway, on to the show.

First, I created a counter helper called counter.notification_count with an initial value of zero and a step count of 1. I also created a notify group in configuration.yaml:

notify:
  - platform: group
    name: all
    services:
      - service: mobile_app_my_ipad
      - service: mobile_app_my_iphone

Then I created an automation that triggers on the persistent_notification.create event that increments the counter and then sends the message via notify.all:

alias: Notify Forward
description: ""
trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: create
condition: []
action:
  - service: counter.increment
    data: {}
    target:
      entity_id: counter.notification_count
  - service: notify.all
    data:
      message: "{{trigger.event.data.service_data.message}}"
      title: "{{trigger.event.data.service_data.title}}"
      data:
        push:
          badge: "{{states('counter.notification_count')}}"
mode: queued

and one that triggers on the persistent_notification.dismiss event that decrements the counter and then sends a message to notify.all that will change the badge count on the mobile devices:

alias: Notify Delete
description: ""
trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: dismiss
condition: []
action:
  - service: counter.decrement
    data: {}
    target:
      entity_id: counter.notification_count
  - service: notify.all
    data:
      message: delete_alert
      data:
        push:
          badge: "{{states('counter.notification_count')}}"
mode: queued

The mode for the Notify Delete automation is SUPER IMPORTANT. If you leave it in single mode the dismiss all button in the web app notification panel will only decrement the counter by one. In queued mode dismiss all will properly decrement the counter based on the number of notifications you are dismissing. Yup, that was an hour of my life I’ll never get back.

And to bring it all together, here’s an automation that sends me a notification if any of my batteries get low. The binary sensors are templated so that they turn on when the battery gets low (and have friendly names that make it easy to just use them as the basis of the message) and aren’t really in scope for this project share.

alias: Notify on Low Batteries
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.bedroom_left_alert
      - binary_sensor.bedroom_center_alert
      - binary_sensor.bedroom_right_alert
      - binary_sensor.lanai_door_alert
      - binary_sensor.lanai_left_alert
      - binary_sensor.lanai_left_back_alert
      - binary_sensor.lanai_right_alert
      - binary_sensor.lanai_right_back_alert
      - binary_sensor.dining_left_alert
      - binary_sensor.dining_center_alert
      - binary_sensor.dining_right_alert
      - binary_sensor.study_left_alert
      - binary_sensor.study_right_alert
      - binary_sensor.batt_ecowitt_bedroom
      - binary_sensor.batt_ecowitt_study
      - binary_sensor.batt_ecowitt_outdoor
    to: "on"
condition: []
action:
  - service: persistent_notification.create
    data:
      title: Low Battery
      message: "{{ trigger.to_state.name }} is low"
mode: queued

I hope someone else finds this useful.

5 Likes

Very cool stuff.
Tried the counter as described. Works well with single dismisses. „Dismiss all“ does not work. Any ideas?


alias: Notifications Persistant Counter
description: ""
trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: create
    id: Create
  - platform: event
    event_type: call_service
    event_data:
      domain: notify
      service: persistent_notification
    id: Notify
  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: dismiss
    id: Dismiss
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Create
              - Notify
        sequence:
          - service: counter.increment
            data: {}
            target:
              entity_id: counter.general_persistant_notification_count
      - conditions:
          - condition: trigger
            id:
              - Dismiss
        sequence:
          - service: counter.decrement
            data: {}
            target:
              entity_id: counter.general_persistant_notification_count
mode: queued

solved the problem by treating „dismiss all“ separately

Trigger added:

  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: dismiss_all
    id: DismissAll

Action added:

      - conditions:
          - condition: trigger
            id:
              - DismissAll
        sequence:
          - service: counter.set_value
            data:
              value: 0
            target:
              entity_id: counter.general_persistant_notification_count
2 Likes

@pkscout I am trying to set this up and all works except the ‘Call a service ‘Notifications: Send a notification with all’ on’ of the forward automation. So persistent notification don’t change the badge. I can try to run the ‘Call a service ‘Notifications: Send a notification with all’ on’ manually and get an error:

Error rendering data template: UndefinedError: ‘trigger’ is undefined

This is the yaml for that part:

service: notify.all
data:
  message: "{{trigger.event.data.service_data.message}}"
  title: "{{trigger.event.data.service_data.title}}"
  data:
    push:
      badge: "{{states('counter.notification_count')}}"

I ended up getting it working with these two automation tweaks:

alias: Notify Badge - Delete
description: ""
trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: dismiss
condition: []
action:
  - service: counter.decrement
    data: {}
    target:
      entity_id: counter.notification_count
  - service: notify.all
    data:
      message: delete_alert
      data:
        push:
          badge: "{{states('counter.notification_count')}}"
mode: queued
alias: Notify Badge - Forward
description: ""
trigger:
  - platform: persistent_notification
    update_type:
      - added
    notification_id: ""
condition: []
action:
  - service: counter.increment
    data: {}
    target:
      entity_id: counter.notification_count
  - service: notify.all
    data:
      message: ""
      data:
        push:
          badge: "{{states('counter.notification_count')}}"
mode: queued
max: 10

Has anyone found a similar way to Increment the count for updates or repairs found, like the number displayed in the web GUI side bar, Settings (number) shown to display the number updates or repairs?

For updates I ended up using this Blueprint:

to leverage the automations in this thread for added notification about updates. Works quite well together.

I also combined the two Automations in to 1

alias: Badge - Count
description: ""
trigger:
  - platform: persistent_notification
    update_type:
      - removed
    notification_id: ""
    id: DECREMENT
  - platform: persistent_notification
    update_type:
      - added
    notification_id: ""
    id: INCREMENT
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - DECREMENT
        sequence:
          - service: counter.decrement
            target:
              entity_id: counter.badge_notification_count
            data: {}
          - service: notify.all
            data:
              message: delete_alert
              data:
                push:
                  badge: "{{states('counter.badge_notification_count')}}"
      - conditions:
          - condition: trigger
            id:
              - INCREMENT
        sequence:
          - service: counter.increment
            target:
              entity_id:
                - counter.badge_notification_count
            data: {}
          - service: notify.all
            data:
              message: ""
              data:
                push:
                  badge: "{{states('counter.badge_notification_count')}}"
mode: queued
max: 10

Hi, Not Like this, but better für Updates - because it is reliable:

A template sensor with the following as state:
state: “{{ (expand(states.update) | selectattr( ‘state’, ‘eq’, ‘on’) |list | count) }}”