So, I recently needed to migrate from my existing notification infrastructure (and groups) to the new notification system (that based on notify entities). So far, so… well, it’s been a little awkward, because there are more than a few things that the new system doesn’t support yet, or which various integrations don’t support yet.
The result? For me, a very large pull request to the chat server integration I use, which solved the latter problem, and this little integration, which solves the former in that there currently isn’t a way to have regular notifications delivered as persistent notifications as part of a group under the new model, and I have quite a few things that need to be persisted as well as announced.
It’s tiny. It’s simple. It creates a notify entity which turns notifications sent to it into persistent notifications, and which can be added to any notify groups you like. No muss, no fuss, no config.
But if you want to be able to send some subset of notifications smaller than “all of them” to appear as persistent notifications, then you probably want a notify entity that can participate in notify groups.
That’s what this integration does.
(And why I wrote it - because you can’t filter those events by properties of the notify, ‘cause if you look at notify.send_message, there aren’t any.)
True. Your integration creates new notify entity to explicitly target (at the source) when you want something to become a persistent notification. That’s cool and works fine, though the user must modify each existing, and new, automation. Its decentralized. I’ve been meaning to finish my method for a centralized way to determine (rule based) which to send to Persistent. If you so desire to do so, this is what I have been using for a year, I keep meaning to convert to an integration and add Rules based on the notification text and what device/service the notification was sent to. This logs to an entity, then I display it on a dashboard… you can of course also add code to send to a Persistent Notification.
alias: Log Notifications to Text Helper (Deduplicated)
description: >-
Writes qualifying notify service calls to input_text.log_all_notifications.
Skips clear_notification payloads. Merges multi-device blasts of the same
notification (fired within a short debounce window) into a single log entry
listing all target devices, and skips re-writing an identical complete entry
within 300 seconds.
triggers:
- trigger: event
event_type: call_service
event_data:
domain: notify
actions:
- variables:
notif_data: '{{ trigger.event.data.service_data }}'
notif_service: '{{ trigger.event.data.service }}'
notif_message: >-
{{ (notif_data.message | default(notif_data.title | default('No
content')))
| regex_replace(' at \d{1,2}:\d{2}(:\d{2})? (AM|PM):?\s*$', '')
| regex_replace(':\s*$', '') }}
notif_title: '{{ notif_data.title | default(''Notification'') }}'
notif_target: >-
{% set target = notif_data.target | default([]) %} {% if target is
string %}
{{ target }}
{% elif target | length > 0 %}
{{ target | join(', ') }}
{% elif 'mobile_app_' in notif_service %}
{{ notif_service.replace('mobile_app_', '') | replace('_', ' ') | title }}
{% elif notif_service == 'notify' %}
All devices
{% else %}
{{ notif_service | replace('_', ' ') | title }}
{% endif %}
notif_key: '{{ notif_title ~ '': '' ~ notif_message }}'
current_value: '{{ states(''input_text.log_all_notifications'') }}'
current_key: '{{ current_value.split('' → '')[0] if '' → '' in current_value else '''' }}'
current_targets: '{{ current_value.split('' → '')[1] if '' → '' in current_value else '''' }}'
within_debounce: >-
{{ (now() -
states.input_text.log_all_notifications.last_changed).total_seconds() <
3 }}
is_same_blast: '{{ within_debounce and current_key == notif_key }}'
merged_target_list: >-
{% set existing = current_targets.split(', ') if is_same_blast and
current_targets else [] %} {% set merged = existing + [notif_target] if
notif_target not in existing else existing %} {{ merged }}
full_msg: '{{ (notif_key ~ '' → '' ~ (merged_target_list | join('', '')))[:254] }}'
is_duplicate: |-
{{ states('input_text.log_all_notifications') == full_msg and
(now() - states.input_text.log_all_notifications.last_changed).total_seconds() < 300 }}
- condition: template
value_template: '{{ notif_message != ''clear_notification'' }}'
- condition: template
value_template: '{{ not is_duplicate }}'
- action: input_text.set_value
target:
entity_id: input_text.log_all_notifications
data:
value: '{{ full_msg }}'
mode: queued
max_exceeded: silent
Yeah, it was just a minimal design to solve the problem of the moment. In the old notification system, I had four notification services set up, dating back years to when I first started using HA: quiet, standard, quiet_persistent and standard_persistent; all of them sent notifications to a particular MQTT topic (for logging) and to a Mattermost channel, the two “standard” ones also announced the notification over Alexa, and the two “persistent” ones also sent it to the dashboard as a persistent notification. It was centralized through those groups - every script, automation, or other notify user just picked the appropriate one depending on the issue, and when I needed to change out what was behind them, I could just change the group and let everything pick it up.
So this was my quick-enough-to-be-done-in-one morning fix to replace those four old-style notification services with four new-style notify groups, which made fixing up my automations and scripts simple enough for a quick script to do it.
(I like your dedup/logging setup. Mine does something similar after it gets posted to the MQTT topic, but I reused an old logging flow I had in Node-RED to do the job.)
I do also like the idea of a nice, centralized rules engine integration to determine which notifications go where. It could integrate pretty well with the new notify system, too, where the engine defines a notify entity for everything else to use, and then farms it out to the notify entities front-ending the actual notification systems according to the rules’ determination.
(It’d still be nice if we could push some auxiliary data when using notify.send_message for the rules engine to work with rather than having to gather everything from the message text, but I suppose that’s up to the HA core folks to figure out.)