Heads up: 2023.6 longer has persistent notifications in states: what to do?

Thats ok. I understand that if there is a bug than it has to be corrected, but why not correct in a way that the integration remain usable with entities? Or offer some alternative for it without loss of functionality. Basicaly I’m lost because 80% of my automations used this which are somehow connected to the dashboard.

1 Like

I have a different use case compared to most of you above, and this is how I worked around this issue and it is working perfectly now.

To track the state of a clothes dryer for instance… I have a plug that monitors power and an input_boolean to monitor the reminder state.

When dryer goes from on to off, set reminder state to true for the dryer and send an initial notification. After that, every 30 minutes as long as the dryer reminder is on, keep sending notifications (unless it is after bedtime, then halt until we wake up and resume again).

This also helps resolve the issue of persistent notifications not actually being… well, persistent. I have another automation that restores persistent notifications after a restart by looking to see if any of the *_reminder booleans are turned on, and recreates the notifications if they are.

Where I was using the persistent notification state was in a trigger to dismiss and turn off the notification reminders. Basically…

alias: Helper - Dryer Reminder Acknowledged
description: "Stop reminding once notification is dismissed."
trigger:
  - platform: state
    entity_id:
      - persistent_notification.dryer_reminder
    from: notifying
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.dryer_notification
mode: single

I am now using a trigger combined with a condition…

alias: Helper - Dryer Reminder Acknowledged
description: "Stop reminding once notification is dismissed."
trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: persistent_notification
      service: dismiss
condition:
  - condition: template
    value_template: "{{ 'dryer_reminder' in trigger.event.data.service_data.notification_id }}"
action:
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.dryer_notification
mode: single

I am working to make notification names and helpers have the same naming scheme so I can template and have one reminder acknowledged for every single reminder I use. So this has a lot of room for improvement.

As a note, I use automation helpers to dismiss the notifications when tags are scanned, buttons are pressed, other actions are performed etc but they ALL hinge around persistent notifications existing or not.

It seems to me that a Trigger-based Template Sensor could be designed to replicate the functionality of persistent_notifications.

It would use Event Triggers to support custom create and delete (a.k.a. dismiss) events for creating/deleting a notification. All notifications would be stored in an attribute as a list of dictionary items. Each dictionary item would have an id, title, message, and (automatically generated) datetime property.

Would this concept be of any use to you?

1 Like

The numbering being tied to order of notifications was better for automations when doing a mass read of them. Otherwise your automation needs to be an if then automation for every single possible notification ID which could be and in my case is over 20 of notification automations and if they don’t exist then there’s going to be a lot of warnings in the logs about them not existing along with the reduced speed of the TTS, that’s a mess.

It’s far cleaner just to able to connect it to a 1 2 3 4 system where you only have to check a persistent notification count easily achieved via a counter helper and then read the respective persistent notification IDs.

Whilst custom IDs should definitely exist for those who wish to use them. They could only achieve the same result if there was a way to have them do a numbering system ie custom_notification, custom_notification_2 etc instead of just replacing each other.

yes, very much so!
trigger templates were mentioned during beta, but I didnt get around to configure, let alone with the functionality you describe.

my boolean system works ok-ish, but does not have the list of title and message obviously. I still need both (notification an boolean).

I would most certainly appreciate your suggestions!

Here’s the first version of what I had proposed. I chose to use the term “message” instead of “notification” to avoid confusion with Home Assistant’s native persistent_notification.

template:
  - trigger:
      - platform: event
        event_type:
          - message_create
          - message_delete
          - message_delete_all
    sensor:
      - name: Messages
        state: "{{ now().timestamp() | timestamp_custom() }}"
        attributes:
          messages: >
            {% set msgs = this.attributes.get('messages', []) %}
            {% if trigger.event.event_type == 'message_create' %}
              {% set new = [{
                  "id": trigger.event.data.id | default('TS' ~ now().timestamp()),
                  "title": trigger.event.data.title | default(''),
                  "message": trigger.event.data.message | default(''),
                  "time": now().isoformat() }] %}
              {{ (msgs + new) }}
            {% elif trigger.event.event_type == 'message_delete' %}
              {% if trigger.event.data.id is defined %}
                {% set msgs = msgs | rejectattr('id', 'eq', trigger.event.data.id) | list %}
              {% elif trigger.event.data.index is defined and trigger.event.data.index | is_number %}
                {% set t = trigger.event.data.index | int(0) - 1 %}
                {% if 0 <= t < msgs|count %}
                  {% set msgs = msgs | rejectattr('id', 'eq', msgs[t].id) | list %}
                {% endif %}
              {% endif %}
              {{ msgs }}
            {% else %}
              {{ [] }}
            {% endif %}

Here are the three custom events for managing messages:

1. message_create

Create a new message.

Example

  - event: message_create
    event_data:
      id: abc123
      title: Hello world
      message: The quick brown fox jumped over etc
  • If you do not supply a value for id then a unique value is automatically generated.
  • If you do not supply a value for title or message then an empty string is automatically supplied.

2. message_delete

Delete a message by either its id or index value (i.e. its index position in the list of all messages). Index values start with 1 (not 0).

Example by id

  - event: message_delete
    event_data:
      id: abc123

Example by index

  - event: message_delete
    event_data:
      index: 1

3. message_delete_all

Deletes all messages in the list.

Example

  - event: message_delete_all

To make it easier to test this Trigger-based Template Sensor, I suggest using Developer Tools > Events.

image

Here’s a simple template to list all messages:

{% for m in state_attr('sensor.messages', 'messages') %}
ID: {{ m.id }}
Title: {{ m.title }}
Message: {{ m.message }}
Time: {{ m.time | as_timestamp | timestamp_custom() }}
{% endfor %}

EDIT

Replaced use of trigger.id in favor of trigger.event.event_type.

6 Likes

wow, that’s mightily impressive indeed.

let me test that over the weekend for my messages and Ill report back :wink:

thanks Taras!

FWIW, I tried to make it fault tolerant but feel free to test it by supplying wrong options and values. For example, it won’t do anything if you fire message_delete without specifying an id or index. It will ignore a non-numeric or out-of-range index value. Similarly, nothing happens if you specify a non-existent id value. If you fire message_create with no options, it will simply create an empty message (with a unique id value).

Skimming this thread I don’t see many users running the issue that I have with this change. I don’t create persistent notifications myself as there are far better solutions for that usecase out there using e.g. the companion apps.

My main gripe with this change is that we’d no longer be able to intercept critical persistent_notifications as indicated by @110hs. I push persistent notifications to my phone, and can dismiss them from the notification drawer when I want to. Especially for something like an IP-ban notification, I’d like to be able to intercept and forward the notification. But also for something like the invalid config notification!

It’s already been quite odd to me that the call stack used internally to create persistent notifications persistent_notification.async_create does not raise the call_service event that is fired when the registered service persistent_notification.create is called. Because of this I had to rely on the underlying state machine entities created by the persistent_notification.async_create call. The changes in 20223.6 make this completely impossible without workaround.

Very unhappy with this change!

3 Likes

since this is a user community, and nt the place dev’s hangout, you might be better joining in on the Draft Pr in the making, and see if you can help out that development.

btw, you can forward pers notifications. I had an automation doing that, but have long disabled it. Unless O dont undertand what you said above?

something like:

  - alias: Notify of persistent notifications
    id: notify_of_persistent_notifications
    trigger:
      platform: event
      event_type: call_service
      event_data:
        domain: persistent_notification
        service: create
    action:
      service: notify.system
      data:
        message: >
          {% set message = trigger.event.data.service_data.message %}
          {% if 'Too many login attempts' in message %}
           Notify of Pers Not: {{now().strftime('%d %b: %X')}}: {{message}}
          {% elif 'invalid authentication' in message or 'login attempt' in message %}
            Notify of Pers Not: {{now().strftime('%d %b: %X')}}: {{message}}
            Track offending ip on http://www.ip-tracker.org/locator/ip-lookup.php?ip={{message.split('from ')[1]}}
          {% else %}
            Notify of Pers Not: {{now().strftime('%d %b: %X')}}: {{message}}
          {% endif %}
        title: >
          {% set title = trigger.event.data.service_data.title %}
            Ha Main: {{title}}

I copied this from my archived yaml, so forgive me if not all is up to the latest scripting/templating options

@Mariusthvdb, This only works for externally created persistent notifications. Internal one’s such as new device discoveries, IP-bans, Invalid Config notifications etc. will not cause this to trigger.

1 Like

well, you have to be a little creative:

  - alias: New device registered config
    id: new_device_registered_config
    mode: queued
    trigger:
      platform: event
      event_type: entity_registry_updated
      event_data:
        action: create
    condition: >
      {{trigger.event.data.entity_id.startswith('device_tracker')}}

anyways, focus on the possibilities, and accept what is the current status quo…

1 Like

I’d have to strongly disagree with you on that.
It’s not about accepting just anything. It’s about managing use-cases.
Which, the example that you gave does not take into account is the inability to capture all the other events where persistent notifications are fired internally.

I’ve opened up a small pr that would fire events when notifications are created or dismissed such that we can once again trigger automations based on these events.

1 Like

cool, I added a small suggestion, seems like its done like that in other places aswell.

No idea if this would be accepted by the dev team though, but might be just as well worth the effort of trying.
thanks for that.

Your use-cases are the same as mine, and all centre around internally-fired events that I wish to publish externally eg via companion app/telegram etc.

Any idea how we show support for draft PRs? @Mariusthvdb do you have suggestions on how that might best be achieved? Even if braco’s PR is merged, RoboMagus’ one seems complimentary rather than an overlap, and more useful for simple amplification of the notification out to other channels (I don’t see how bdraco’s PR could be used to trigger an automation, only to render what is already notified). It also appears to be a minimal code change to implement.

Commenting or ':+1:'ing on PR’s shows interest and is hopefully used as an indicator by Devs to get things merged, but there’s no guarantee ofcourse.

Thanks for mentioning Bdraco’s draft too. Though indeed the ability to use the proposed template function to trigger automations would be a bummer for those of us that want to act upon these notifications when they occur. But it’s for sure an improvement to not being able to tap into this information at all.

With some assistance we’ve managed to come to a solution creating a new persistent_notification trigger to be used in automations. The PR just got merged.

So at some point in the (near) future we can once again trigger automations based on any persistent notification (that includes the internal ones!).

3 Likes

Nice! thanks go to @bdraco in particular too! we even expect to get a nice Frontend for it. really appreciated.

my only worry still is whether we will to be able to check system persistent notification for its id… I have several scenarios where I want to trigger on the dismissal of a persistent notification, or the existence of it.

Ive checked both the backend and frontend Pr, and am still not sure we will be able to do so

Maybe I’m miss understanding you, but an automation would handle that based on the trigger information. If you look at the documentation that’s paired with that PR, there’s a whole section about the data that is supplied with the trigger. Meaning you can get the notification ID from the trigger and then do what you want with it.

The only thing missing is a blanket “Remove all notifications” function.

In theory, you could create an automation that stores all your notifications, and then at a specific time of the day, remove them all. (Using an input_select to store said notification_ids)

yes and that is awesome indeed. But we can not 'go and have a look ’ in some system registry (I think) and check whether our automation templates would be correct.
on self made pers noti’s that is easy, as we just need to make sure we use the same in creating and dismissing.

the systems ones remain mysterious (on their id)

besides that, there s scenario where I have an animated frontend element on the condition the pers notify is ‘notifying’. clicking the notification away stops the animation (but does not change the triggering state for the notification). think garbage day, and garbage has been move out. no more animation, but it is still garbage day… etc etc

Ive added booleans for all of those scenarios, and that works ok, until now with the exception of not benig able to turn off the bollena when the pers notify is dismissed. The new Pr will fix that, so almost there!

just discovering the systems id’s (and hope some day an active state) left

and yes, the clear all. Isnt some nifty for loop possible in a script somehow, with the new trigger options?

script:

  dismiss_all_persistent_notifications:
    alias: Clear All Persistent Notifications
    sequence:
      repeat:
        for_each: |
          {{states.persistent_notification|map(attribute='object_id')|list}}
        sequence:
          service: persistent_notification.dismiss
          data:
            notification_id: >
              {{repeat.item}}
    mode: single

or the even nicer equivalent as python script:

for notif in hass.states.entity_ids('persistent_notification'):
    hass.services.call(
        'persistent_notification', 'dismiss',
        {'notification_id': notif.split('.', 1)[-1]})

and then adapt to the new situation?

1 Like