Help with calendar and all day events

Hi all,

I share a dance studio with a group of people, and I’ve set up an automation in Home Assistant to send a message to a private Discord channel one minute before an event in our shared studio calendar. The message includes the event’s name, start time, and end time. This part works great—YAY!

However, I’ve encountered a new problem. We have some all-day events, like recycling and rent, which start at 00:00:00. For these events, we would prefer to receive the notification at 9 AM instead of one minute before midnight.

Here’s my current automation in YAML:

alias: New calendar
description: ""
trigger:
  - platform: calendar
    event: start
    offset: "-0:1:0"
    entity_id: calendar.eco_collective_chicago
condition: []
action:
  - service: notify.eco_bot
    data:
      message: >-
        session starting 

        {{ state_attr('calendar.eco_collective_chicago', 'message') }} 
         
        start time {{
        as_timestamp(strptime(state_attr('calendar.eco_collective_chicago',
        'start_time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom("%A %b %d @
        %-I:%M %p") }} 

        end time {{
        as_timestamp(strptime(state_attr('calendar.eco_collective_chicago',
        'end_time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom("%A %b %d @ %-I:%M
        %p") }}
      target:
        - "234234"
        - "234234234"
mode: single

How can I modify this automation to send notifications for all-day events at 9 AM while keeping the one-minute-before notifications for all other events?

Thanks for your help!

By using trigger ID’s and the available trigger variable properties, the following will allow the automation to continue when either:

  • The event type is all-day and calendar event start was 9 hours ago.
  • It is a normal event triggering the normal trigger.

Make sure to change the mode to queued or parallel, in case there are coincident trigger events.

alias: New calendar
description: ""
trigger:
  - platform: calendar
    event: start
    offset: "-0:1:0"
    entity_id: calendar.eco_collective_chicago
    id: normal
  - platform: calendar
    event: start
    offset: "9:0:0"
    entity_id: calendar.eco_collective_chicago
    id: all-day
condition:
  - condition: template
    value_template: "{{ (trigger.calendar_event.all_day) == (trigger.id == 'all-day') }}"  
action:
  - service: notify.eco_bot
    data:
      message: >-
        session starting 

        {{ state_attr('calendar.eco_collective_chicago', 'message') }} 
         
        start time {{
        as_timestamp(strptime(state_attr('calendar.eco_collective_chicago',
        'start_time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom("%A %b %d @
        %-I:%M %p") }} 

        end time {{
        as_timestamp(strptime(state_attr('calendar.eco_collective_chicago',
        'end_time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom("%A %b %d @ %-I:%M
        %p") }}
      target:
        - "1240529094131843082"
        - "1230543576174166108"
mode: queued
1 Like

thank you for the response. but I want it to trigger the notification 9 hours after an event that starts at midnight (all day) and any event that starts not at midnight to send the notification one minute before an event starts.

That is exact what it should do.

The option above seemed simplest to me since it requires minimal templating and doesn’t alter the source calendar. But, if you don’t like the method employed, there are other ways…

A second option would be to used a Choose action with an Option for the normal events and one for the all-day events. The first Option would proceed as your original actions do. The second would call the calendar.create_event service to create a new event at 9am that mirrors the details of the all-day event. When 8:59am rolls around, you’ll get the all-day message because it will be considered a non-all-day event. You will still want to change the mode to queued or parallel so coinciding events don’t get lost.

A third option would be to trigger at “09:00” every morning, then use the calendar.get_events service to create a list of all the events that were active at “00:00”, use templates to reject any that were from the previous day’s all-day events, and if there are any results left, send them as notifications.

1 Like

Thank you so much for your help. I really love this community. And you’re a regular here.

I just wanted to say that an all day event happened and your logic worked perfectly. Thank you so much.

1 Like

just found something :cry:
if there are two events happening in the calendar, HA ignores the title of the event.
we have a recycling event that is all day, but if someone rents the studio I get a notification for recycling instead of the actual event.
please halp

this is my YAML

alias: calDiscord-forumhelp
description: ""
trigger:
  - platform: calendar
    event: start
    offset: "-0:1:0"
    entity_id: calendar.eco_collective_chicago
    id: normal
  - platform: calendar
    event: start
    offset: "9:0:0"
    entity_id: calendar.eco_collective_chicago
    id: all-day
condition:
  - condition: template
    value_template: "{{ (trigger.calendar_event.all_day) == (trigger.id == 'all-day') }}"
action:
  - service: notify.eco_bot
    data:
      message: >-
        session starting 

        {{ state_attr('calendar.eco_collective_chicago', 'message') }} 
         
        start time {{
        as_timestamp(strptime(state_attr('calendar.eco_collective_chicago',
        'start_time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom("%A %b %d @
        %-I:%M %p") }} 

        end time {{
        as_timestamp(strptime(state_attr('calendar.eco_collective_chicago',
        'end_time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom("%A %b %d @ %-I:%M
        %p") }}
      target:
        - "numbers"
        - "#numbers"
mode: parallel

Yeah, we should have changed the message info to be based on the trigger, something like:

alias: calDiscord-forumhelp
description: ""
trigger:
  - platform: calendar
    event: start
    offset: "-0:1:0"
    entity_id: calendar.eco_collective_chicago
    id: normal
  - platform: calendar
    event: start
    offset: "9:0:0"
    entity_id: calendar.eco_collective_chicago
    id: all-day
condition:
  - condition: template
    value_template: "{{ (trigger.calendar_event.all_day) == (trigger.id == 'all-day') }}"
action:
  - service: notify.eco_bot
    data:
      message: >-
        session starting 

        {{ trigger.calendar_event.summary }} 
         
        start time {{ (trigger.calendar_event.start | as_datetime | as_local).strftime("%A %b %d @%-I:%M %p") }}

        end time {{ (trigger.calendar_event.end | as_datetime | as_local).strftime("%A %b %d @%-I:%M %p") }}
      target:
        - "numbers"
        - "#numbers"
mode: parallel

If you want a specific value for start and end for the all day events you can alter them like:

  end time {{ 'EXAMPLE EXAMPLE' if (trigger.id == all-day) else (trigger.calendar_event.end | as_datetime | as_local).strftime("%A %b %d @%-I:%M %p") }}
1 Like

Thank you so much. i created the animation but it didn’t trigger, i did traces and got this message
"

Error: Error rendering data template: UndefinedError: ‘dict object’ has no attribute ‘calendar_event’
"
I am still struggling with understanding the concepts (and configuration) of Templates and configuration.yaml. so I appreciate all your help

How did you test the automation?

1 Like


i went through the automation’s three dotted menu

When you use the “Run” function it completely skips the Trigger and Condition blocks and runs the Action block. That means the trigger variable isn’t populated with any values. Unfortunately, when using Calendar events, we need the information that comes from the trigger variable.

So to test the automation you need a real Calendar event. However, the calendar event trigger listener only updates on the quarter-hour or when an automation with a calendar event trigger is reloaded. When testing by creating a new calendar event make sure to either:

  • Create the test calendar event so that it will trigger the automation after the next quarter hour. This means you need to wait a while for your test to run.
  • Create the calendar event then edit the automation so that it requires a new save. One easy option for this is to add a short delay at the end of the automation.

Unfortunately, it’s pretty much impossible to test the all-day event part of the automation until 9AM. You could set up a third, temporary trigger with a different offset to get the all-day message sent sooner.

1 Like

you are a genius. Thank you!

1 Like