How to add unique id to persistent notification and binary sensor

using this small setup creates pers notifications for my feedreader urls:

feedreader:
  urls:
    - https://www.home-assistant.io/atom.xml
    - https://hasspodcast.io/feed/podcast
    - https://www.gdacs.org/xml/rss.xml
  scan_interval:
    minutes: 30
  max_entries: 5

automation:
  - alias: Notify RSS feed updated
    trigger:
      platform: event
      event_type: feedreader
    action:
      service: persistent_notification.create
      data_template:
        title: >
          {{ trigger.event.data.title }}
        message: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          New Rss feed for {{source[url] if url in source else 'Unknown'}}, see
          {{trigger.event.data.link}}

        notification_id: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          rss-feed-{{source[url] if url in source else 'Unknown'}}

and the pers not id is in the form of persistent_notification.rss_feed_gdacs which I thought was fine enough, but I hadn’t realized more than 1 notification could be created…

so I tried to add a few characters of the title to the template above, but though working fine, looks a bit hacky:

        notification_id: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          {% set suffix = trigger.event.data.title[0:5] %}
          rss-feed-{{source[url] + '-' + suffix if url in source else 'Unknown'}}

Made me wonder if I couldn’t just add a unique id to each notification. Maybe a random number, but, being random, that doesn’t exclude an identical id…

Probably just need some extra logic to add a suffix _2, _3, _4, in case a second/third etc notification should arise.

And for that I would need some assistance… please have a look if and how you can help me out here, thanks!


secondly, Id need a dynamic binary sensor for any persistent_notification.rss_feed_xxxx goin on.

I’d start with the hardcoded entity_id’s, but since they will be hopefully changed into dynamic ones, that wouldn’t suffice. So I should need some very simple (…) logic to test if a persistent_notification exists, starting with the string ‘rss_feed’ in the object_id

       {%set feed = states.persistent_notification
                   |map(attribute='object_id')
                   |list %}
                   {{feed}}
                   {{'rss_feed' in feed }}

but this renders False:

this however:

         {%set feed = states.persistent_notification
                   |map(attribute='object_id')
                   |join %}
                   {{feed}}
                   {{'rss_feed' in feed }}

seems to work, but it feels utmost hacky:

binary_sensor:
  platform: template
  sensors:
    rss_feeds:
      entity_id:
        - automation.notify_rss_feed_updated
      friendly_name: Rss feeds
      icon_template: >
        {{'mdi:rss' if is_state('binary_sensor.rss_feeds','on') else 'mdi:rss-off'}}
      value_template: >
        {% set feed = states.persistent_notification
                    |map(attribute='object_id')
                   |join %}
        {{'rss_feed' in feed }}
      attribute_templates:
        count: >
          {% for state in states.persistent_notification  %}
            {% if 'rss_feed' in state.entity_id %}
              {% if loop.first %}{{loop.length}}
              {% endif %}
            {% endif %}
          {% endfor %}
        feeds: >
          {% set feed = states.persistent_notification
                   |map(attribute='attributes.message')
                   |list|join(',\n ') %}
          {{feed if feed and 'New Rss feed' in feed else 'No Rss feeds'}}

Hope you can check for better syntax/logic … again, please have a look

If you go the list route, you’d need to iterate through the list of object_id’s and test if the object_id startswith() rss_feed. Your method of turning it into a string is less code and will always work. It won’t work if you have rss_feed in any persistent notification that isn’t an rss_feed. e.g. ‘my_rando_notification_rss_feed’. That would return a false positive because rss_feed is in the string instead of checking against the start of the string being rss_feed.

Hi,
Yes I think I tried that, but it returned an error, or nothing, not sure. Was this already availble? (thought you were contemplating adding that and contains to the jinja engine…)

that is not the case, so for now this works altright, glad to hear it is a valid method.
do you have any thoughts on the suffix to add to the notification-id?
Again, it’s working now, but doesn’t feel elegant.

It’ll be a pain in the ass.

{% set url = trigger.event.data.feed_url.split('https://')[1] %}
{% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}
{% set suffix = trigger.event.data.title[0:5] %}
{% set object_id = 'rss-feed-' ~ source[url] ~ '-' ~ suffix if url in source else 'Unknown' %}
{% set object_id = object_id.replace('-','_').lower() %}
{% set object_ids = tates.persistent_notification  |map(attribute='object_id') |list %}
{% set found = namespace(values=[]) %}
{% for o_id in object_ids %}
{% if o_id.startswith(object_id) %}
{% set found.values = found.values + [ o_id.replace(object_id,'').replace('_','') | int ] %}
{% endif %}
{% endfor %}
{% if found.values %}
{% set next = found.values | max + 1 %}
{{ object_id ~ '_' ~ next }}
{% else %}
{{ object_id }}
{% endif %}

o dear.

before I start trying to understand this, I think the suffix as I posted/use it now, should be taken out? Otherwise we have no need for a _2, _3 etc .
iow, I am looking for persistent_notification.gdacs, persistent_notification.gdacs_2, persistent_notification.gdacs_3 etc, and that, of course… for each of the sources

this just adds a number at the end of each new persistent_notification

I’ve tested it with this (and took out the original suffix)
Not quite grasping why it ads the suffix 107, unless that is from the 106 (the new HA version) and adds +1 to that :wink: Yep that must be it, the original [0:5] suffix is still in my own config of course.

{% set url = 'https://www.home-assistant.io/atom.xml'.split('https://')[1] %}
{% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}

{% set object_id = 'rss-feed-' ~ source[url] if url in source else 'Unknown' %}
{% set object_id = object_id.replace('-','_').lower() %}
{% set object_ids = states.persistent_notification|map(attribute='object_id')|list %}
{% set found = namespace(values=[]) %}
{% for o_id in object_ids %}
{% if o_id.startswith(object_id) %}
{% set found.values = found.values + [ o_id.replace(object_id,'').replace('_','') | int ] %}
{% endif %}
{% endfor %}
{% if found.values %}
{% set next = found.values | max + 1 %}
{{ object_id ~ '_' ~ next }}
{% else %}
{{ object_id }}
{% endif %}

which renders:

that’s what it does, it finds the highest _# and adds 1 to it if your object_id starts with whatever the rss_feed_{{ source }} {{ suffix}} is

1 Like

ok so I report back with an observation.

using the Petro solution for adding a counter for notifications of the same source, has some strange side effects, in that it does actually show these for 1 source (GDACS in this case) but does not show the other sources at all.

as you can see, it even shows the identical notification more than once.

using my first notification -id template with the [0:5] suffix does show the other notifications.

Apparently the former overwrites these, or interferes somehow in the notification system. Don’t quite understand yet how, but it does.

to show you it keeps updating, this is a screen from just now (and I’ve added the time in the notifications for clarity to be sure):

building on the above I’ve made this template to use in a dismiss all script:

  dismiss_all:
    alias: 'Dismiss all Notifications'
    icon: mdi:message-bulleted-off
    sequence:
      service: persistent_notification.dismiss
      data_template:
        notification_id: >
          {%- set ns = namespace(notifications = '') %}
          {%- for item in states.persistent_notification %}
            {%- set id =  item.object_id %} #previously used entity_id....
            {%- set d = ', ' if ns.notifications | length > 0 else '' %}
            {%- set ns.notifications = ns.notifications ~ d ~ id %}
          {%- endfor %}
          {%- if ns.notifications|length|int == 0 %} None
          {% else %}
          {{- ns.notifications }}
          {%- endif %}

which shows the notifications as I would have thought they needed to be in a comma separated list, to use that in the notification-id field for the service:

however, clicking the script, (or using the developers-tools/service), nothing happens, not even a log entry to say what’s wrong :wink:

@petro would you know how to handle/solve this?

update
found this python_script by @pnbruckner which works perfectly, thanks! (isn’t object_id available in python for the notification_id ? )
Would still like to understand why the above jinja template doesn’t work in the script setting.

It most likely doesn’t work with a comma separated string. Not all fields accept that. Only entity_id does in specific service calls. Also, that is extremely verbose…

  dismiss_all:
    alias: 'Dismiss all Notifications'
    icon: mdi:message-bulleted-off
    sequence:
      service: persistent_notification.dismiss
      data_template:
        notification_id: >
          {{ states.persistent_notification | map(attribute='object_id') | list | join(', ') }}

thanks Petro, I had been playing with various variations on that theme, starting at:

        {%- for item in states.persistent_notification %}
        {{ item.object_id }}
        {% endfor %}

though your template seems clean as a whistle, it doesn’t do what its supposed to. As a matter of fact, nothing happens at all.

the more I try, to more I start to suspect this service only accepts 1 entity_id at a time…which would empower the FR for a default core dismiss-all service al the more.

Oh I know it won’t work, I was just showing you a shorter template than the large template you had before.

Ah ok, didn’t understand that’s what you meant, was pulling my hairs here to try and figure out before I reposted… thanks anyways!

Hi Mariusthvdb.

Thanks for posting this as I looked at this a while ago and the default code did not work and all I got was unknown in the title when a new RSS feed was available. Ive followed both your posts and got mine working now.

I never knew what GDACS was as living in the UK but loving it but do you know of a way to select what comes through as all I am getting is about the US Drought but Im interested in the Earthquakes and also the Hurricanes etc ?

One more thing. I have tried but is there a way to get the name after the : in the Title ?

ie GDACS - Drought etc or Home Assistant - Migrating the OS

Thanks Martyn

yes, you can set that using the configuration variables: Global Disaster Alert and Coordination System (GDACS) - Home Assistant

well, anything possible, it depends on what you pass along to the template and then the filter you create.

why dont you give us what you have, and we can see how to proceed?

Hi

Yeah. No problems. Its pretty much all your code. I added some podcasts to the rss feed as below in the configuration.yaml but I havent set anything up as you linked above…so would that work if I just added earthquakes an hurricanes?

Below is my automation. Ive tried adding the author into the title but not everything has a author. So my thinking was to have the name at the end of the link but I just cant seem to get it into the title ie Forty 20 : Weekly Show or Home Assistant : 0.114 is now available

image

- id: '87654456789098765'
  alias: Notify Rss feed updated
  trigger:
    - platform: event
      event_type: feedreader
  action:
    - service: persistent_notification.create
      data_template:
        message: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-Assistant',
                          'hasspodcast.io/feed/podcast':'Haome Assistant Podcast',
                          'feed.podbean.com/forty20rl/feed.xml':'Forty 20',
                          'rss.whooshkaa.com/rss/podcast/id/1687':'Talking with TK',
                          'selfhosted.show/rss':'Self Hosted Show',
                          'www.spreaker.com/show/4381953/episodes/feed':'Dogcast with Brad Dwyer',
                          'www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/yh':'Met Office Weather Warning',
                          'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          {{as_timestamp(now())|timestamp_custom('%X %d-%b-%Y', true)}}: New Rss feed for {{source[url] if url in source else 'Unknown'}}, see
          {{trigger.event.data.link}}
        title: >
          {{ trigger.event.data.title }}
        notification_id: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-Assistant',
                          'hasspodcast.io/feed/podcast':'Home Assistant Podcast',
                          'feed.podbean.com/forty20rl/feed.xml':'Forty 20',
                          'rss.whooshkaa.com/rss/podcast/id/1687':'Talking with TK',
                          'selfhosted.show/rss':'Self Hosted Show',
                          'www.spreaker.com/show/4381953/episodes/feed':'Dogcast with Brad Dwyer',
                          'www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/yh':'Met Office Weather Warning',
                          'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          {% set object_id = 'rss-feed-' ~ source[url] if url in source else 'Unknown' %}
          {% set object_id = object_id.replace('-','_').lower() %}
          {% set object_ids = states.persistent_notification|map(attribute='object_id')|list %}
          {% set found = namespace(values=[]) %}
          {% for o_id in object_ids %}
          {% if o_id.startswith(object_id) %}
          {% set found.values = found.values + [ o_id.replace(object_id,'').replace('_','') | int ] %}
          {% endif %}
          {% endfor %}
          {% if found.values %}
          {% set next = found.values | max + 1 %}
          {{ object_id ~ '_' ~ next }}
          {% else %}
          {{ object_id }}
          {% endif %}

Thanks. This is more cosmetic and is working great.

Martyn

you know that each template is a world of its own? that means that if you would like a phrase of the link into your title, you’d have to repeat that bit of the template under the title template. Check the bit under the notification_id or persistent_notification: a lot of double code, but necessary.
You only display the full title of the event now in the title template, so add the parts that create the {{source[url]}} mapper for the title and add that in front of the title you now have.

Wouldn’t that do what you want?

btw Ive changed my automation to this:

  - alias: Notify Rss feed updated
    trigger:
      platform: event
      event_type: feedreader
    mode: queued
    action:
      service: persistent_notification.create
      data_template:
        title: >
          {{trigger.event.data.title}}
#({{trigger.event.data.link}})
        message: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          ![image](/local/various/rss_icon.png) {{as_timestamp(now())|timestamp_custom('%X %d-%b-%Y', true)}}: New Rss feed for [{{source[url]}}]({{trigger.event.data.link}})


        notification_id: >
          {% set url = trigger.event.data.feed_url.split('https://')[1] %}
          {% set source = {'www.home-assistant.io/atom.xml':'Home-assistant',
                           'hasspodcast.io/feed/podcast':'Hass podcast',
                           'www.gdacs.org/xml/rss.xml':'GDACS'} %}
          {% set suffix = trigger.event.data.title[0:5] %}
          rss-feed-{{source[url] + '-' + suffix}}

adding a string of the title to make it unique