How to call the calendar service for events of "today"?

The problem is that this is an automation that runs on a regular basis so “today’s date” will be obsolete tomorrow+.

Only if you hard-code the date.

Template the date.

Ah, I did not know that was possible in the first place. I will try that then - thanks!

{{ today_at().strftime('%Y-%m-%d %H:%M') }}
1 Like

This is what I use for my Google Assistant to tell me my calendar events for the day.
Notice the duration:
Is this what you are looking for?

    - condition: template
      value_template: >-
            {% set next_calendar_event_date = (as_timestamp(state_attr('calendar.joint', 'start_time'))) | timestamp_custom('%Y-%m-%d', True) %}
            {% set today = as_timestamp(now()) | timestamp_custom('%Y-%m-%d', True) %}
            {% set tomorrow = (as_timestamp(now())+ (43200)) | timestamp_custom('%Y-%m-%d', True) %}
            {{ next_calendar_event_date == today}}    
    - service: calendar.list_events
        entity_id: calendar.joint
          hours: 24
      response_variable: agenda  

    - service: tts.cloud_say
        cache: false
          - media_player.kitchen_assistant
          - media_player.main_bedroom_assistant
        message: >-
          Calendar Events for Today:
          {% for event in %}
            {{ event.summary }}: at {{  as_timestamp(event.start) | timestamp_custom('%-I:%M %p') }}:
          {% endfor %}

Do you run the automation at 00:00?

The reason why I ask is because if you don’t specify a value for start_date_time it will default to using the current time (now). Therefore a duration of 24 hours means 24 hours into the future starting from the current time (now).

1 Like

This is part of my house morning “wake up” automation.
First morning movement in our kitchen area triggers presence sensor and sets thermostats, security cameras, Google assistant announces day weather, rain chance, package deliveries expected, and calendar events for the day taking place AFTER the automation triggers

The service call you created will include all events occurring in the next 24 hours after the automation triggers. If it triggers at 09:00 then it includes all events for the current day as well as the next day’s events up to 09:00.

According to WoJWoJ’s first post, the goal is to report all events occurring in the current calendar day, regardless of time when the automation triggers during the day.

Quick question on the merged calendar, how can you tell which persons calendar has the events, my TTS states Good Morning Gary your agenda for today is ???, then Bob your agenda is ??? and so on?

The other approach in which I have been trying to complete which is more elegant is to wright a number of macros :“Weather”, “Greetings” and hopefully “Calendar 1 agenda”, "Calendar 2 agenda"and so on. Then stringing them all together to make 1 x TTS announcement. I am 3/4 of the way through however cant seem to workout how to write a macro for the “Calendar: list events”?
This way I just have a number of automations that call some or all of these macros.
Looking for guidance for this approach if possible?

After trying all kind of code (with the help of @Zoriontsu post), I still cannot make it work. The automation is now (the relevant part) (NOTE: this is after the EDIT below)

alias: datacenter ⬤ reload calendars
description: ""
  - platform: time_pattern
    minutes: /1
  - condition: template
    value_template:"{% set today = today_at().strftime('%Y-%m-%d %H:%M') %}"
  - service: homeassistant.reload_config_entry
    data: {}
  - delay:
      hours: 0
      minutes: 0
      seconds: 20
      milliseconds: 0
  - service: calendar.list_events
        hours: 48
        minutes: 0
        seconds: 0
    start_date_time: "{{ today }}"
    response_variable: calendar_response
  - event: calendarResponseDadEvent
      response: "{{ calendar_response }}"

This fails with the error

</s> <s>Message malformed: invalid template (TemplateSyntaxError: expected token ':', got '}') for dictionary value @ data['condition'][0]['value_template']</s> <s>

EDIT: thanks to the template checker in HA I found out that the template that works is

"{% set today = today_at().strftime('%Y-%m-%d %H:%M') %}"

Side notes:

  • - I expected the pattern to be '%Y-%m-%d 00:00' rather than ‘%Y-%m-%d %H:%M’ but it does not matter for the error After carefully reading the doc for today_at(), it gives the date (and not date and time of today, so the time is automatically 00:00
  • {{ today }} to refer to the variable in start_date_time is not accepted → this is my current issue, the error is now
domotique-hass-1  | 2023-08-18 12:29:47.653 ERROR (MainThread) [homeassistant.components.automation.datacenter_reload_calendars] datacenter ⬤ reload calendars: Error executing script. Invalid data for call_service at pos 3: Invalid datetime specified:  for dictionary value @ data['start_date_time']
domotique-hass-1  | 2023-08-18 12:29:47.666 ERROR (MainThread) [homeassistant.components.automation.datacenter_reload_calendars] Error while executing automation automation.datacenter_reload_calendars: Invalid datetime specified:  for dictionary value @ data['start_date_time']

Thank you for your follow-up (also @Zoriontsu) - I have a surprisingly hard time understanding the structure of the configuration files (where templating config lands, how to piece together the configurations, …) despite developing for 30 years and working in IT. At the very end, I realize that everything is in the documentation at some point, but I seem to never find a “high level introduction” to the entries.

Yes - this is to allow me to display current events (i.e. events that started before “now” but did not end yet). These are discarded when listing calendars from “now”. (I will filter out events from today that have truly ended)

That’s my point; Zoriontsu’s example doesn’t do that (it lists events occurring after the time it’s triggered, in other words, after “now”) because it doesn’t employ start_date_time.

Your example contains the following mistake:

This Template Condition serves no purpose.

  - condition: template
    value_template: "{% set today = today_at().strftime('%Y-%m-%d %H:%M') %}"

If you think it creates a script variable named today, it doesn’t. It creates a Jinja2 variable that is only defined inside of value_template and undefined elsewhere. That’s why you get this error message:

Invalid datetime specified: for dictionary value @ data[‘start_date_time’]

Simply use the template I suggested directly in the start_date_time option.

start_date_time: "{{ today_at().strftime('%Y-%m-%d %H:%M') }}"

Questions for you:

  • If you want a list of today’s events (24 hours), why is calendar.list_events retrieving events for 48 hours?

  • The automation employs a Time Pattern Trigger to reload the calendar and list its events every minute. Why? It seems excessive unless you regularly schedule numerous new events each day.

  • The automation doesn’t process the list of Calendar events but posts it as a custom Home Assistant event (calendarResponseDadEvent). What’s the reason for using a separate automation to processes the custom event? Is it designed to process multiple kinds of custom events?

1 Like

Ah la la, by looking too much at solutions I missed the obvious one. Thank you!

Because this is used by two components in a home dashboard (written independently of HA, from scratch in Vue.js) - one for “today’s” and the other for “tomorrow’s” events. I do the filtering client-side to just keep the events that fit the day.
You are of course right to be surprised because I did not mention that in my question. I see that I could very well set specific dates in the automation (now that I know how it works) to have a clear-cut “from the start of today to the end of tomorrow” but I am filtering each event anyway in the app.

They can be scheduled on a regular basis, yes. It really depends on how the day at home is busy. It obviously does not require checking every minute but neither my server, the network, nor the Google quotas are problematic so far.

The main reason is that I access HA via the Websockets API, where I can either read the states, or start services.
I initially thought that I would simply access the calendars, but discovered that they hold only one event (the next one, timewise)
I then thought that I would call the calendar list service via the API, and process the response. And discovered that the response is not implemented in the API :no_mouth::frowning:
So the next idea was to populate a state from within an automation (there are several family calendars) and get more or less the something I expected in the first place. And here we are :slight_smile:

In any case: thank you very much for your help. I will probably document my journey through templating as I use it more (see, I was not aware that the {{ ... }} you initially suggested could be directly used. I am sure it is somewhere in the docs but then you have “template conditions”, template_thisand that in various places where I do not expect them). And share with the world somewhere.

Your help was fantastic - thank you very much.

1 Like

You’re welcome!

Please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. This helps users find answers to similar questions.

For more information about the Solution tag, refer to guideline 21 in the FAQ.

Yes, it’s done. I always mark solutions but, believe it or not, even on Friday of the week of the 15th of August, in France, someone called and interrupted me while I was about to do so :slight_smile:

I’m looking into this now, I’m just going to use:

service: calendar.get_events
  start_date_time: "{{ states ('') }} {{ states ('sensor.time') }}"
  end_date_time: "{{ states ('') }} 23:59:59"
  entity_id: calendar.richard

Then I’ll have it fire every time the calendar changes, that way I have a live list that can update when / if I add new things

Google Calendar only updates once per 15 minutes. So if you do not use the current time but only the date as the start, you’ll get the same result every minute for 14 minutes straight. The only benefit is you’ll see new events within 15+1=16 minutes.

I think I like this solution the best – where do you “store” the information? Or do you just call calendar.get_events every time you access the info?

Was looking to have a card on my dashboard that lists all the events per day per person, so I’m trying to figure out a way to save these to a helper or something maybe?

Yeah it autocalls every time then stores the information in the entity it creates.