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

was a c&p.
I’ve edited above

can I leave out the else, and still have the sensor count correctly? figured Id need that empty list to count 0

if I condense those 2 triggers (love that) I can not use the trigger.id. have to change that inside the template then, let me see.

I’m reworking the template now. There’s a bunch of things that aren’t correct anymore in that template. Like all notifications via that trigger will have a notification_id

there’s 1 oddity I noticed after taking out the else:

upon reloading and no notifications active, all seems fine. But then, firing a notification reveals [] in the markdown (might be the default I set in the sensor)

I didnt see that with the else in the trigger template

how to discern the 2 update_types? can we do tri…

nevermind, you beat me

this is all you really need

  - trigger:
      - platform: persistent_notification
        update_type:
        - added
        - removed
    sensor:
      - unique_id: persistent_notifications_overview
        name: Persistent notifications
        device_class: timestamp
        state: >
          {{ now() }}
        attributes:
          notifications: >
            {% set msgs = this.attributes.get('notifications', []) %}
            {% if trigger.update_type == 'added' %}
              {{ msgs + [{
                  "id": trigger.notification.notification_id,
                  "title": trigger.notification.title | default(''),
                  "message": trigger.notification.message | default(''),
                  "time": trigger.notification.created_at.isoformat() }] }}
            {% else %}
              {{ msgs | rejectattr('id', 'eq', trigger.notification.notification_id) | list }}
            {% endif %}
3 Likes

I’m not sure about template reloading. If restore state brings back the attribute, then it should still work.

taking some time here, as many errors on the other entities now, and the main sensor is not available…

main issue:

Logger: homeassistant.helpers.sensor
Source: helpers/template_entity.py:609 
First occurred: 13:45:24 (2 occurrences) 
Last logged: 13:45:28

Error rendering state template for sensor.persistent_notifications: TypeError: can only concatenate str (not "list") to str

got it back to this working:

        attributes:
          notifications: >
            {% set msgs = this.attributes.get('notifications', []) %}
            {% if trigger.update_type == 'added' %}
              {% set new = [{
                  "id": trigger.notification.notification_id | default('TS' ~ now().timestamp()),
                  "title": trigger.notification.title | default(''),
                  "message": trigger.notification.message | default(''),
                  "time": now().isoformat() }] %}
              {{ (msgs + new) }}
            {% else %}
              {{msgs | rejectattr('id', 'eq', trigger.notification.notification_id) | list }}
            {% endif %}

and we’re back live…

do see this:

TemplateError('TypeError: object of type 'NoneType' has no len()') while processing template 'Template<template=({% set msgs = state_attr('sensor.persistent_notifications','notifications')|default([]) %} {{msgs|count}}) renders=4>' for attribute '_attr_native_value' in entity 'sensor.persistent_notifications_count'

but thats a default error on the counter not being correct probably.
fixed using:

# | default([], true) to apply the default when the input is none
      - unique_id: persistent_notifications_count
        state: >
          {% set msgs = state_attr('sensor.persistent_notifications','notifications') or [] %}
          {{msgs|count}}

Ive edited the post above with that.
Ive noticed there’s an oddity with the markdown card not updating upon reload and keeping the [] is view

reloading the view then fixes that, a bit ugly , but not a real life issue

just for completeness sake, the above does not really help when testing for individually created notifying notifications.
What I still need to do for those requirements is set a boolean with hat exact naming, and test for that to be on/off

      - service: persistent_notification.create
        data:
          notification_id: trash_tomorrow_notificatie
          title: >
            {{now().strftime('%d %B')}}: Afvalmelding morgen
          message: >
            {{states('sensor.afvalwijzer_tomorrow')|title}} wordt morgen opgehaald!
      - service: input_boolean.turn_on
        entity_id: input_boolean.trash_tomorrow_notificatie

and same for dismiss/turn_off.

doing that for all programmed notifications allows me to show Frontend stuff based on the state of what we had before {{is_state('persistent_notification.xxx','notifying')}}

markdown card in general has update issues i’ve noticed. I added my first one the other day and I have to force state changes and reload for it to “start working” after a restart of HA.

that must be a newish ‘feature’. I’ve have quite a few of them, and never saw any issue at all in that regard.
Ill keep an eye on these, and see if anything can be done

talking about that Dashboard yaml:

type: entities
title: Notification dashboard
show_header_toggle: false
state_color: true
card_mod:
  class: class-header-margin
entities:

  - entity: binary_sensor.persistent_notifications
    secondary_info: last-changed
  - entity: sensor.persistent_notifications_count
    secondary_info: last-changed
    format: relative
  - entity: sensor.persistent_notifications
    secondary_info: last-changed
  - type: custom:hui-element
    card_type: conditional
    conditions:
      - entity: binary_sensor.persistent_notifications
        state: 'on'
    card:
      type: custom:hui-element
      card_type: markdown
      card_mod:
        style: |
          ha-card {
            box-shadow: none;
            margin: 0px -16px;
          }
      content: >
        {% set count = states('sensor.persistent_notifications_count') %}
        ### {{count}} Notification{{'' if count == '1' else 's'}}:

        {% for m in state_attr('sensor.persistent_notifications','notifications') if m %}

        **{{m.title}}**{{'\n'}}
        *{{m.message}}*{{'\n'}}
        {{m.id}}{{'\n'}}
        {% endfor %}

  - type: conditional
    conditions:
      - entity: binary_sensor.persistent_notifications
        state: 'on'
    row:
      entity: script.dismiss_all_persistent_notifications #script.dismiss_all #former python
      secondary_info: last-triggered
      action_name: Wis

I could drop the bottom 2 conditional in 1 and use an entities card + plus a nice divider, but then I’d have to mod that again to not show borders/shadows etc. this was the lazy solution.

here’s the other:

  - type: custom:hui-element
    card_type: conditional
    conditions:
      - entity: binary_sensor.persistent_notifications
        state: 'on'
    card:
      type: entities
      card_mod:
        style: |
          ha-card {
            box-shadow: none;
            margin: 0px -16px;
          }
      entities:
        - type: divider
        - type: custom:hui-element
          card_type: markdown
          card_mod:
            style: |
              ha-card {
                box-shadow: none;
                margin: 0px -16px;
              }
          content: >
            {% set count = states('sensor.persistent_notifications_count') %}
            ### {{count}} Notification{{'' if count == '1' else 's'}}:

            {% for m in state_attr('sensor.persistent_notifications','notifications') if m %}

            **{{m.title}}**{{'\n'}}
            *{{m.message}}*{{'\n'}}
            {{m.id}}{{'\n'}}
            {% endfor %}

        - entity: script.dismiss_all_persistent_notifications #script.dismiss_all #former python
          secondary_info: last-triggered
          action_name: Wis

couldn’t resist and it seems less condition checking for the Frontend, so maybe just a bit more efficient

ive tested this once more, but it has unexpected result really:

 {'id': '75fa4c6be5fdc4155449eca69ac04eb4', 'title': 'Notification created at', 'message': 'Test notification containing a lot of info on noteworthy things', 'time': datetime.datetime(2023, 6, 30, 14, 51, 37, 172775, tzinfo=datetime.timezone.utc)}

compare to the now().isoformat() I used:

{'id': '62cb50577c591123c1c2c8448247203e', 'title': 'Notification title', 'message': 'Test notification containing a lot of info on noteworthy things', 'time': '2023-06-30T16:50:14.601893+02:00'}

and that throws off the template, and also the counter


.
because of:

not really unexpected, if that’s a datetime just change this

                  "time": trigger.notification.created_at.isoformat() }] }}

Can someone help me get a push if there is a failed login?

alias: Failed Login I Push Nachricht
trigger:
  - platform: state
    entity_id: persistent_notification.http_login
condition:
  - condition: template
    value_template: "{{ trigger.to_state.state != 'None' }}"
action:
  - service: notify.mobile_app_iphone_c_fischer
    data_template:
      title: "{{ states.persistent_notification.http_login.attributes.message }}"
      message: >-
        url:
        https://whatismyipaddress.com/ip/{{states.persistent_notification.http_login.attributes.message.split("from
        ")[1]}}
  - service: persistent_notification.dismiss
    data:
      notification_id: http_login
initial_state: true
mode: single

you mean smth like this:

  - alias: Notify of login persistent notifications
    id: notify_of_login_persistent_notifications
    trigger:
      platform: persistent_notification
      update_type: added
    condition:
      >
        {% set message = trigger.notification.message %}
        {{'Too many login attempts' in message or
          'invalid authentication' in message or 'login attempt' in message}}
    action:
      service: notify.system
      data:
        title: >
          {% set title = trigger.notification.title %}
            Ha Main: {{title}}
        message: >
          {% set message = trigger.notification.message %}
          {% set now = now().strftime('%d %b: %X') %}
          {% if 'Too many login attempts' in message %}
           Login notification: {{now}}: {{message}}
          {% elif 'invalid authentication' in message or 'login attempt' in message %}
            Login notification: {{now}}: {{message}}
            Track offending ip on http://www.ip-tracker.org/locator/ip-lookup.php?ip={{message.split('from ')[1]}}
          {% else %}
            Login notification other: {{now}}: {{message}}
          {% endif %}

its yet untested, only a quick rewrite for what was used before

1 Like

right, does your code work with the new beta?

but why would that make the template list individual characters, instead of the dict

1 Like

because the datetime object isn’t a basic object, so when the resolver checks the output type of the template it turns it into a string. Later on, when it runs again, you turn it into a list, which makes it look the way it does.

right, I see now the same thing happens when using only now() in the time field…
thanks

displaying in the markdown with:

created at: *{{as_timestamp(m.created_at)|timestamp_custom('%d %b: %X')}}*

to make it readable

don’t we have some crafty way of rewriting this:

              {% set new = [{
                  "id": trigger.notification.notification_id | default('TS' ~ now().timestamp()),
                  "title": trigger.notification.title | default(''),
                  "message": trigger.notification.message | default(''),
                  "created_at": trigger.notification.created_at.isoformat() }] %}

and have that built automatically based on those 4 variables?
especially since we can probably safely use:

              {% set new = [{
                  "id": trigger.notification.notification_id,
                  "title": trigger.notification.title,
                  "message": trigger.notification.message,
                  "created_at": trigger.notification.created_at.isoformat() }] %}

thats a system service, check your service tools page for available notify services in your system, and use which ever you want

1 Like

thx , it works …I found my mistake … THX!!!