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
right, does your code work with the new beta?
but why would that make the template list individual characters, instead of the dict
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
thx , it works …I found my mistake … THX!!!
Now that most functionality is correct, there is one more thing ( there always is…):
Upon restart, the notification tray is empty, and in the former implementation of Pers. notifications, the system would no longer have ‘notifying’ notifications. However, the trigger template still shows the state that it was in before restart, as it is restoring per design.
That is ok in itself, maybe even better than the core Pers. Notifications, but it is no longer in sync.
Also clearing the notifications now does Not work, and the last state remains. Apparently the ids are no longer in the system, so the clear does not know what to clear?
That could be an issue.
Wonder what to do. Maybe add homeassistant start to the triggers for the template?
That would probably make it sync . I do like the ‘memory’ it now displays though , but don’t like we can not clear …
No, adding the homeassistant start trigger is not perfect either, it now errors on:
Template variable error: 'dict object' has no attribute 'notification' when rendering '{% set msgs = this.attributes.get('notifications', []) %} {% if trigger.update_type == 'added' %} {% set new = [{ "id": trigger.notification.notification_id, "title": trigger.notification.title, "message": trigger.notification.message, "created_at": trigger.notification.created_at.isoformat() }] %} {{ msgs + new }} {% else %} {{msgs | rejectattr('id', 'eq', trigger.notification.notification_id) | list }} {% endif %}'
so apparently even the [] in the getter does not help here
- trigger:
- platform: homeassistant
event: start
- platform: persistent_notification
update_type:
- added
- removed
sensor:
- unique_id: persistent_notifications_overview
device_class: timestamp
state: >
{{now()}}
attributes:
notifications: >
{% set msgs = this.attributes.get('notifications', []) %}
{% if trigger.update_type == 'added' %}
{% set new = [{
"id": trigger.notification.notification_id,
"title": trigger.notification.title,
"message": trigger.notification.message,
"created_at": trigger.notification.created_at.isoformat() }] %}
{{ msgs + new }}
{% else %}
{{msgs | rejectattr('id', 'eq', trigger.notification.notification_id) | list }}
{% endif %}
Never restarted my test box this many times before testing this!!
Tried to get the template trigger method working for this scenario but also failed (was favoring this approach), so returned to the automation approach and have got it working.
alias: Persistent Notification Mirror
description: ""
trigger:
- platform: homeassistant
event: start
id: start
- platform: persistent_notification
update_type:
- added
- current
- updated
id: added
- platform: persistent_notification
update_type:
- removed
id: removed
condition: []
action:
- choose:
- conditions:
- condition: trigger
id:
- added
sequence:
- event: message_create
event_data:
id: "{{ trigger.notification.notification_id }}"
title: "{{ trigger.notification.title }}"
message: "{{ trigger.notification.message }}"
- conditions:
- condition: trigger
id:
- removed
sequence:
- event: message_delete
event_data:
id: |
{{ trigger.notification.notification_id }}
- conditions:
- condition: trigger
id:
- start
sequence:
- event: message_delete_all
event_data: {}
mode: queued
max: 30
On restart all previous mirrored notifications are cleared and then as they come in again are recreated. Supports the Dismiss All button on the slide out Persistent Notification panel.
This works well for me, as on a restart any Persistent Notifications I’ve raised via automation are recreated anyway (e.g. device offline).
Note: perhaps its just me and my config @Mariusthvdb; but I re-raise persistent notifications with the same ID multiple times e.g.
id: ntf_device
title: One device offline
message: light.office
then again when a second device goes off line
id: ntf_device
title: Two devices offline
message: light.office and switch.playroom
In this scenario the second message replaces the first (same ID) in the Persistent Notifications and also in my mirror - I think in your current configuration you may get two occurrences of ID ntf_devices
in your sensor? (which could be fine for the way your config is set up)
As a side note, has anyone noticed that the notification bell icon counter is not nicely refreshing and often needs a whole page refresh?
template config
- 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 msgs = msgs | rejectattr('id', 'eq', trigger.event.data.id) | list %}
{% 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' %}
{% set msgs = msgs | rejectattr('id', 'eq', trigger.event.data.id) | list %}
{{ msgs }}
{% else %}
{{ [] }}
{% endif %}
For interest I have logged a bug for this. It appears if you restart the count is is being persisted unless you refresh the page - a small issue but a differing in behavior and potentially misleading following restart.
I think that is a frontend issue more than a core issue though, and yes that is new behavior. With more than the notification tray I fear, but there it is very obvious.
on the restart restore:
maybe I should add a clear notifications on Ha restart/stop.
it would be my first usage of
automation:
trigger:
- platform: homeassistant
# Event can also be 'shutdown'
event: start
so I have to ask if shutdown would also trigger on restart, which would be what Id need.
Btw, on the subject of that tray: ive always found it silly we can open that without having a single notification, only to have it show an empty half screen
You’ll have to test for your needs, but I couldn’t get the shutdown event to trigger on restart. The homeassistant.start event seems run before any notifications were getting generated so works for my needs.
thanks for the heads up, moved that issue to frontend now
This is what i have now, and it works for me.
template:
- trigger:
- platform: persistent_notification
update_type:
- added
- removed
id: pn
- platform: homeassistant
event: shutdown
id: shutdown
sensor:
- name: pn_messages
state: "{{ now().timestamp() | timestamp_custom() }}"
# state: "{{ state_attr('sensor.pn_messages', 'pn_ids') | length }}" # not possible, also with 'this.attributes'
unique_id: 20230630060219
attributes:
pn_ids: >
{% if trigger.id == 'pn' %}
{% if trigger.notification.notification_id is defined %}
{% set id = trigger.notification.notification_id %}
{% set pn_ids = this.attributes.get('pn_ids', []) %}
{% if trigger.update_type == 'added' %}
{% set new = [id] %}
{{ (pn_ids + new) | unique | list }}
{% else %}
{{ pn_ids | reject('equalto', id) | list }}
{% endif %}
{% endif %}
{% elif trigger.id == 'shutdown' %}
{{ [] }}
{% endif %}
- trigger:
- platform: state
entity_id: sensor.pn_messages
sensor:
- name: pn_count
state: "{{ state_attr('sensor.pn_messages', 'pn_ids') | length }}"
unique_id: 20230615210019
I need only a list for counting and testing of notifications, so a list with id’s is enough for me.
Creating/updating multiple notifications with the same id falsified the counter, so the unique
filter.
Restarting HA deletes the notifications, but the attributes are restored, so the restart trigger to set an empty list.
What i can’t get to work ist the count as state or attribute, it seems it’s not possible to set this with values from the same sensor.
It’s also not possible to test for a notification that is created for the first time.
The trigger in a template is always faster than the same trigger in an automation, it always is false.
automation:
- alias: persistent_notification_log
id: '20230630190625'
variables:
pn_ids: "{{ state_attr('sensor.pn_messages', 'pn_ids') }}"
initial_state: true
mode: parallel
trigger:
- platform: persistent_notification
update_type:
- added
# condition:
# - "{{ trigger.notification.notification_id not in pn_ids }}" # always false
action:
- service: notify.pn_log
data_template:
message: >
{{ now().strftime('%Y%m%d %H%M%S') }}
{{ trigger.notification.title }} /
{{ trigger.notification.message }}
I’m open for improvements.
Need to test that a bit but I feel the count sensor works best a regular template and not at trigger .
Does here anyway.
Experimenting with the restart didn’t yet bring a solution as the trigger shutdown doesnt fire on restart….
update
I was so fixated on the restart event, I completely overlooked the fact I should not try to trigger off the restart/shutdown event, but simply use the start event…
- trigger:
- platform: homeassistant
event: start
id: start
- platform: persistent_notification
update_type:
- added
- removed
sensor:
- unique_id: persistent_notifications_overview
device_class: timestamp
state: >
{{now()}}
attributes:
notifications: >
{% set msgs = this.attributes.get('notifications', []) %}
{% if trigger.update_type == 'added' %}
{% set new = [{
"id": trigger.notification.notification_id,
"title": trigger.notification.title,
"message": trigger.notification.message,
"created_at": trigger.notification.created_at.isoformat() }] %}
{{ msgs + new }}
{% elif trigger.id == 'start' %}
{{[]}}
{% else %}
{{msgs | rejectattr('id', 'eq', trigger.notification.notification_id) | list }}
{% endif %}
makes it happen.
its a bit weird to see it go from a number, then restart, change to unavailable, then unknown, and then back to the number it had before (apparently from restore. Finally it is reset by the start event trigger ti an empty list, and causing the number And the binary to get the correct state. All perfect now.
excpet for the Frontend, which is still left from where it was before the restart
and requires a reload But thats a bug, and not to do with this template trigger
I linked your issue in the #beta channel on Discord, hoping it might be fixed before release
I’m not testing the July beta so I can’t test your latest example posted above (and answer my own question). What happens to this line when your Trigger-based Template Sensor is triggered by its first trigger (homeassistant start)?
{% if trigger.update_type == 'added' %}
Isn’t update_type
exclusively a property of the second trigger (persistent_notification) and not the first trigger (homeassistant start)?
I would imagine it would cause an error message indicating the trigger
object doesn’t have an update_type
property.