Calendar - Get Events Help

Having trouble figuring out how to list the events in a calendar - the time below is just relative as I was trying to get it to fire so I could see results.

At the end of the day, I just want to see the listed events, and the start and end time… the below is just event and start… but, I can’t get even that to work. The sensor is ripped right off the documentation page for the calendar integration - still no dice on that either. Appreciate the assist in advance!

  - trigger:
      - platform: time
        at: "15:35:00"
    action:
      - service: calendar.get_events
        data:
          duration:
            hours: 24
        target:
          entity_id: calendar.my_calendar
        response_variable: agenda
    sensor:
      - name: Katie Calendar Test
        state: >
            " {% for event in agenda["calendar.my_calendar"]["events"] %}
              {{ event.start}}: {{ event.summary }}<br>
              {% endfor %} "

You’ve got some extraneous quotes. And you may run into a length issue… states are limited to 255 characters. When it goes over length the state will be returned as “unknown”.

- trigger:
      - platform: time
        at: "15:35:00"
    action:
      - service: calendar.get_events
        data:
          duration:
            hours: 24
        target:
          entity_id: calendar.my_calendar
        response_variable: agenda
    sensor:
      - name: Katie Calendar Test
        state: >
          {% for event in agenda["calendar.my_calendar"]["events"] %}
            {{ event.start}}: {{ event.summary }}<br>
          {% endfor %}

I didn’t know that limitation, and the “unknown” is exactly what I’m returning - to break it down into chunks - say 3 or 4 at a time - how would I achieve that? Any guidance including converting to local time?

Ultimately what I’m looking for is a more customizable calendar list than the standard calendar card (use card mod on basically everything in my dashboard) and nothing of what I’ve seen in HACS really does it for me - figured this would be the best way to achieve that “true” customization

Really appreciate your response

Getting the start into local time can be accomplished as follows

{% for event in agenda["calendar.my_calendar"]["events"] %}
  {{- (event.start|as_datetime|as_local).strftime("%H:%M") }}: {{ event.summary }}<br>
{% endfor %}

You can get around the length limitation by storing the value in an attribute instead of the state. I’m not well-versed in card mod and frontend stuff, but in case it’s helpful… Keep in mind that attributes aren’t limited to strings like states are; so you can store you data as a list or dictionary if that’s more useful.

That sounds like a great place to start - nit intimate with the storing of the attribute variable, do you have an example you could share… or, even better, where some of the documentation is? Ive gone through the template docs several times i believe and i havent seen that

You just need to add an attributes key and a name for the attribute to your earlier configuration, and change the state value to something else (I usually use now() to get a timestamp of when the trigger fired).

- trigger:
      - platform: time
        at: "15:35:00"
    action:
      - service: calendar.get_events
        data:
          duration:
            hours: 24
        target:
          entity_id: calendar.my_calendar
        response_variable: agenda
    sensor:
      - name: Katie Calendar Test
        state: "{{ now() }}"
        attributes:
          events: |
            {% for event in agenda["calendar.my_calendar"]["events"] %}
              {{- (event.start|as_datetime|as_local).strftime("%H:%M") }}: {{ event.summary }}<br>
            {% endfor %}
2 Likes

Thanks, you’ve been a huge help!!! I was receiving a “missed comma flow” for the “events” portion of the attributes - adding the > helped solve for that.

How do you “search” or exclude results? Example - I have an event that is at time “00:00” and “Home” - I want to exclude this from the population returned.

Also - i’ve scoped the templating documentation, as well as the jinja documentation and I see the syntax, but, there aren’t examples for “search” “first” “map” etc. that are in the HA documentation. Do you have any documentation source that has examples of the above that you could point me too?

Again, I really appreciate all the help you’ve given here!!!

  - trigger:
      - platform: time
        at: "19:12:00"
    action:
      - service: calendar.get_events
        data:
          duration:
            hours: 24
        target:
          entity_id: calendar.me_calendar
        response_variable: agenda
    sensor:
      - name: Calendar Test
        state: "now()"
        attributes:
          events: >
             {% for event in agenda["calendar.my_calendar"]["events"] %}
              {{- (event.start|as_datetime|as_local).strftime("%H:%M") }}-{{- (event.end|as_datetime|as_local).strftime("%H:%M") }}: {{ event.summary }}
             {% endfor %}

There are filter functions like selectattr and rejectattr that can be used to “edit” the list of events based on the values they contain.

...
attributes:
  events: >
    {% for event in agenda["calendar.my_calendar"]["events"] | rejectattr('summary', 'eq', 'Home') | list %}
      {{- (event.start | as_datetime | as_local).strftime("%H:%M") }}: {{ event.summary }}<br>
    {% endfor %}

One useful trick for calendar events is to select for : in the start time, since all-day events don’t have : in their start and end variable values.

...
attributes:
  events: >
    {% for event in agenda["calendar.my_calendar"]['events'] | selectattr('start', 'search', ':') | list %}
      {{- (event.start | as_datetime | as_local).strftime("%H:%M") }}: {{ event.summary }}<br>
    {% endfor %}

It could also be done as an inline if:

...
attributes:
  events: >
    {% for event in agenda["calendar.my_calendar"]["events"] if event.start is search(':') %}
      {{- (event.start | as_datetime | as_local).strftime("%H:%M") }}: {{ event.summary }}<br>
    {% endfor %}

The closest thing to an organized tutorial is Jinja code for Ninjas . Unfortunately, it hasn’t been updated in a while and it’s showing its age. The HA devs and community regularly add template functions, so there are often better/easier ways to do some of the examples you’ll find there, but it covers the basics well.

This year, the forum community has been working on creating and indexing useful examples and explanations which can be found in the Cookbook Index, but there’s still a lot of work to be done on it.

1 Like

Once again - I really appreciate it. Trying to take to take it one step beyond -trying to template “event.start” “event.end” from the state_attr of the sensor, but coming to the conclusion it won’t work? I can create multiple sensors and print the start/end times and work with that - but, it seems like it’d be more efficient coming from the state_attr of the original sensor

What I’m trying to do is format the display of the event if it’s in current time - as an example, if there’s a meeting at 1200 - 1300 and the time (now) is between those hours, make it red. I’m comfortable with the templating of the format, but it seems like i’d 1) need to make the times a state and 2) somehow map them back to the state_attr of the sensor

You may have an easier time if you maintain the list of dictionaries instead of just printing the values. But, like I posted before, frontend/card mod stuff is not my forte, so I’m not really sure how you are using the results on that side of things:

...
    sensor:
      - name: Calendar Test
        state: "now()"
        attributes:
          events_list: >
            {% set ns = namespace( sched = [] ) %}
            {% for event in agenda["calendar.my_calendar"]["events"] 
            if event.start is search(':') %}
              {%- set ns.sched = ns.sched + [{"start":(event.start | as_datetime | as_local).strftime("%H:%M"), "summary": event.summary }] %}
            {% endfor %}
            {{ ns.sched }}