How to create multiple persistent notifications in 1 automation on multiple triggers

HI,

using this automation:

  - alias: Feest
    id: 'Feest'
    trigger:
      platform: state
      entity_id:
        - sensor.birthday_f
        - sensor.birthday_h
        - sensor.birthday_louise
        - sensor.birthday_marijn
        - sensor.birthday_m
        - sensor.birthday_w
        - sensor.wedding_lovebirds
        - sensor.met_lovebirds
    condition:
      condition: template
      value_template: >
        {{trigger.to_state.state|int in [0,1]}}
    action:
      - service: notify.notify
        data_template:
          title: >
            {% set dag = trigger.to_state.state|int %}
            {{'Morgen' if dag == 1 else 'Vandaag'}} is het Feest!
          message: >
           {% set dag = trigger.to_state.state|int %}
           {{trigger.to_state.attributes.persoon}} {{'wordt morgen' if dag == 1 else 'is vandaag '}} {{trigger.to_state.attributes.years}} !
      - condition: template
        value_template: >
          {{trigger.to_state.state|int == 0}}
      - service: persistent_notification.create
        data_template:
          notification_id: celebration-notification
          title: 'Vandaag is het Feest!'
          message: >
           {{trigger.to_state.attributes.persoon}} is vandaag {{trigger.to_state.attributes.years}} !

works perfectly fine, except for the 1 time more than 1 of the triggers trigger simultaneously. As it happens, there are 2 celebrations on the same day (today )ā€¦ In that case it only creates a single persistent notification, while the regular notifications are effectively created for both events.

Why would this be, and, how can I change that for the persistent notification.

Could it be something to do with the notification_id?

Instead of

notification_id: celebration-notification

How about trying

notification_id: {{trigger.to_state.attributes.persoon}}

ah yes, that might be a good suggestion. But, as a counter thought, I wouldnā€™t even need the notification-id for the notifications to be createdā€¦ I only use that to dismiss them on tap_actionā€¦

still, Ill experiment with that. thanks

edit

bingo!

Schermafbeelding 2020-02-20 om 11.59.35

now need to change the dismiss logic, but that will probably be a simple templateā€¦
thanks @klogg

dismissing seems rather easy,

    service: persistent_notification.dismiss
    service_data:
      notification_id: >
        [[[ return entity.attributes.persoon ]]]

and it doesnā€™t work just yet, and I see an error popup:

Secondly, the animation has been complicatedā€¦

I now need this:

      - animation: >
          [[[ var id = entity.attributes.persoon;
              if (states['persistent_notification.' + id].state === 'notifying') return 'blink 2s ease infinite';
              return 'none'; ]]]

but it errors out:

and the complete button isnā€™t displayed
same for:

      - animation: >
          [[[ if (states['persistent_notification.' + entity.attributes.persoon].state === 'notifying') return 'blink 2s ease infinite';
              return 'none'; ]]]

if I try

      - animation: >
          [[[ var id = 'persistent_notification.' + entity.attributes.persoon;
              if (states[id].state === 'notifying') return 'blink 2s ease infinite';
              return 'none'; ]]]

the button is displayed, but it isnā€™t blinkingā€¦

@petro might I nudge you please and ask if you can have a look?

edit

I was being an idiot, and referencing the wrong entityā€¦ persoon is an attributes of the sensor. and used in the automation, while my buttons use the binary_sensor. and donā€™t have an attributes persoon. I can use the attribute name though, albeit lowered:

  hold_action:
    action: call-service
    service: persistent_notification.dismiss
    service_data:
      notification_id: >
        [[[ return entity.attributes.name.toLowerCase() ]]]

works correctly now.

Still struggling with the animation though:

      - animation: >
          [[[ var id = entity.attributes.name.toLowerCase();
              if (states['persistent_notification.' + id].state === 'notifying') return 'blink 2s ease infinite';
              return 'none'; ]]]

wont show, and errors with:

Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'states['persistent_notification.' + id].state')

above error gave me the idea I needed different quotes, and yes using

      - animation: >
          [[[ var id = entity.attributes.name.toLowerCase();
              if (states["persistent_notification." + id].state && states["persistent_notification." + id].state === 'notifying') return 'blink 2s ease infinite';
              return 'none'; ]]]

makes the button appear again, but when dismissed, takes out the persistent_notification, so it becomes an undefined objectā€¦ and, the test on its existence above doesnā€™t work. SO, still stuckā€¦
please helpā€¦!

does your name have spaces? if so replace them with underscores.

no, no spaces.

Ive just tested this:

      - animation: >
          [[[ var id = entity.attributes.name.toLowerCase();
              if (id === 'louise') return 'blink 2s ease infinite';
              return 'none'; ]]]

which works for the Louise button,and obviously not for the other. It makes them appear both correctly, so I know 100% the id is correct. Now how to test for the existence of the persistent_notificationā€¦ using the id?

check to see if the property exists on the object.

var id = entity.attributes.name.toLowerCase();
state = states["persistent_notification." + id]
if (state.hasOwnProperty('state')  && state.state == 'notifying') return 'blink 2s ease infinite';
return 'none';

ok testing right now, also did most of these: function - JavaScript check if variable exists (is defined/initialized) - Stack Overflow

first result seems promising, both buttons appear fixed, which is what they need to do when no Pers Not is existing. Will restart to see what happens.

btw, made me think, if the persistent_notification exists, it is always notifyingā€¦ so maybe I can simply test on existence and dont need the test for ā€˜notifyingā€™?

_tested
Nope, the buttons arenā€™t blinking when notifying is on.

tested this:

  name: >
    [[[ var id = entity.attributes.name.toLowerCase();
        return 'persistent_notification.' + id ]]]

and it returns the names perfectly. Why then wouldnā€™t

    [[[ var id = entity.attributes.name.toLowerCase();
        var notification =  'persistent_notification.' + id;
        if (states[notification].state) return 'blink 2s ease infinite';
        return 'none'; ]]]

work? But it didnā€™t. Hazzarded a wild throw at

    [[[ var id = entity.attributes.name.toLowerCase();
        var notification =  'persistent_notification.' + id;
        if (states[notification]) return 'blink 2s ease infinite';
        return 'none'; ]]]

And bingo! this worksā€¦! I am completely lost as to the why the other options didnā€™t work (note I am again able to use single quotesā€¦) or why leaving the .state out of the template is even a valid state to evaluate.

If anyone can explain that to me, I would be most appreciative because I dont like coding I dont understandā€¦:wink:

just as an experiment, this works fine too:

  state:

    - operator: template
      value: >
         [[[ var id = entity.attributes.name.toLowerCase();
             var notification = 'persistent_notification.' + id;
             return states[notification] ]]]
      spin: true

for reference the complete button template using the new persistent notification settings:

button_celebration_alert:
  template: button_body
#  entity: 'binary_sensor.birthday_louise'
  aspect_ratio: 1/1
#  name: >
#    [[[ var id = entity.attributes.name.toLowerCase();
#        return 'persistent_notification.' + id ]]]
  name: >
    [[[ return entity.attributes.name + ' ' + entity.attributes.event ]]]
  icon: mdi:party-popper
  spin: true
  show_state: false
  #show_entity_picture: true
  #entity_picture: >
  #  [[[ return entity.attributes.entity_picture ]]]
  size: 20px
  tap_action:
    action: navigate
    navigation_path: tijd_agenda
  hold_action:
    action: call-service
    service: persistent_notification.dismiss
    service_data:
      notification_id: >
        [[[ return entity.attributes.name.toLowerCase() ]]]
  state:
    - operator: template
      value: >
         [[[ var id = entity.attributes.name.toLowerCase();
             var notification = 'persistent_notification.' + id;
             return states[notification] ]]]
      spin: true
  styles:
    icon:
      - color: blue
      - align-self: start
      - justify-self: start
#      - padding: 5px
    card:
      - background-image: >
          [[[ return `url("/local/family/${entity.attributes.name.toLowerCase()}.jpg")`; ]]]
      - background-repeat: no-repeat
      - background-size: 100%
      - background-position: center
      - padding: 5px
      - font-size: 10px
      - color: white
  #    - background: orange
#      - animation: >
#          [[[ var id = entity.attributes.name.toLowerCase();
#              var notification = 'persistent_notification.' + id;
#              if (states[notification]) return 'blink 2s ease infinite';
#              return 'none'; ]]]
#      - animation: >
#          [[[ if (entity.state === 'on') return 'blink 2s ease infinite';
#              return 'none'; ]]]
    grid:
      - grid-template-areas: '"i years" "n n" "original_date original_date" "type type"'
      - grid-template-columns: 1fr 1fr
      - grid-template-rows: 1fr min-content min-content min-content min-content
    name:
      - align-self: start
      - justify-self: start
      - padding-bottom: 4px
      - color: pink
    img_cell:
      - margin: none
    custom_fields:
      years:
        - font-size: 20px
        - align-self: start
        - justify-self: end
        - --text-color-sensor: red
        - animation: >
            [[[ var id = entity.attributes.name.toLowerCase();
                var notification = 'persistent_notification.' + id;
                if (states[notification]) return 'blink 2s ease infinite';
                return 'none'; ]]]
      original_date:
        - padding-bottom: 2px
        - align-self: middle
        - justify-self: start
        - --text-color-sensor: red
      type:
        - padding-bottom: 2px
        - align-self: middle
        - justify-self: start
        - --text-color-sensor: yellow
  custom_fields:
    years: >
      [[[
        return `<span style='color: var(--text-color-sensor);'>${entity.attributes.years} </span></span>`
      ]]]
    original_date: >
      [[[
        return `<span>Date: <span style='color: var(--text-color-sensor);'>${entity.attributes.original_date}</span></span>`
      ]]]
    type: >
      [[[
        return `<span>Type: <span style='color: var(--text-color-sensor);'>${entity.attributes.type}</span></span>`
      ]]]
1 Like

It depends on what states[entity_id] returns. If it returns undefined, then you canā€™t get the state from it and you canā€™t use .hasOwnProperty either because itā€™s not an object. So simply checking for itā€™s existence is all you can do.

ok thanks Petro, will keep that in mind, it has been quite a puzzleā€¦

only thing left really is the silly icon on the left that keeps sliding down, while I would love to keep it mirrored in position to the years number on the right.

I can add a negative margin, but it is different on the individual buttons because of the different names. Would you know the correct css for that?

try align-text: start on the icon

your other option is to make the lovebirds not word rwrap. Possibly by shrinking up the date and type. Remove the labels and display the year, then type:

1999 - Birthday
1995 - Wedding

People will already know the month and the day is in the upper corner. Hell you could add the month there as well.

just letting you know I tried, but canā€™t make the icon stay put.

Probably because of lack of full understanding how these grids exactly work, but I would think the top icon wouldnā€™t have to be bothered by whatā€™s happening below, since you can see the word wrapped name still offers enough space for the icon. Even more, it puts it on the correct spot, while the 1 line name makes the icon dropā€¦

will need some more reading and experimenting.
hope I can find something here: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ or https://css-tricks.com/snippets/css/complete-guide-grid/

maybe I need to adjust the grid-template-row setting after all