How to list multiple calendar event in a template

It’s 8 days and dozens of posts later and I have run out of free time for this topic. Hopefully someone else can assist you. Good luck.

1 Like

No problem, thank you for all your help

image

something is wrong here

Invalid config for [sensor.template]: [sensor] is an invalid option for [sensor.template]. Check: sensor.template->sensor. (See ?, line ?).

Yes it’s because you tried to configure a Trigger-based Template Sensor using a mixture of the formats for both a legacy and modern Template Sensor.

  • There are two ways to configure a Template Sensor, using either modern or legacy format.

  • There’s only one way to configure a Trigger-based Template Sensor and that’s using modern format.

Modern format Template entities are configured under the template: key and use different option names from legacy format. For example, modern format doesn’t use platform: template.

works now…
is it
a) possible to add more as one calendar
b) possible to split the entities in e.g.
event01name
event01daystart
event01dayend
event01timestart
event01timeend
event01location
event02name

background is, i want show this entities on a display (esphome + epaper)

Just going to add this here since someone asked in Discord and linked back to this thread…

To get events from multiple calendar entities into a single sensor, send them to unique response variables then concatenate the lists:

2023.8 version using Automation
alias: Multiple Cal to Event
trigger:
  - platform: calendar
    event: end
    entity_id: calendar.a
  - platform: calendar
    event: end
    entity_id: calendar.b
sequence:
  - service: calendar.list_events
    data:
      duration:
        hours: 72
        minutes: 0
        seconds: 0
    target:
      entity_id:
        - calendar.a
    response_variable: agenda1
  - service: calendar.list_events
    data:
      duration:
        hours: 72
        minutes: 0
        seconds: 0
    target:
      entity_id:
        - calendar.b
    response_variable: agenda2
  - event: custom_multical_event
    event_data:
      scheduled_events: "{{ agenda1.events + agenda2.events}}"
mode: single
template:
  - trigger:
      - platform: event
        event_type: custom_multical_event
    sensor:
      - name: Multi Cal Events
        unique_id: multical_events_0001
        state: "{{ trigger.event.data.scheduled_events | count() }}"
        attributes:
          events: "{{ trigger.event.data.scheduled_events }}"
        icon: mdi:calendar

UPDATE: 2023.9

Introduction of actions into trigger-based template sensors make the intermediary automation unnecessary.

  - trigger:
      - platform: calendar
        event: end
        entity_id: calendar.a
      - platform: calendar
        event: end
        entity_id: calendar.b
      - platform: calendar
        event: end
        entity_id: calendar.c
      - platform: event
        event_type: event_template_reloaded
    action:
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.a
        response_variable: agenda1
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.b
        response_variable: agenda2
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.c
        response_variable: agenda3
    sensor:
      - name: Next 24hr Events
        unique_id: custom_multical_todays_events
        state: |
          {% set ns = namespace(alt_events=[]) %}
          {% for e in agenda1.events %}
          {% set ns.alt_events = ns.alt_events + [e]  %}
          {% endfor%}
          {% for e in agenda2.events %}
          {% set ns.alt_events = ns.alt_events + [e]  %}
          {% endfor%}
          {% for e in agenda3.events %}
          {% set ns.alt_events = ns.alt_events + [e]  %}
          {% endfor%}
          {{ns.alt_events|selectattr('start', 'search', now().date()|string)
          | list | count}}
        attributes:
          scheduled_events: |
            {% set ns = namespace(alt_events=[]) %}
            {% for e in agenda1.events %}
              {% set ns.alt_events = ns.alt_events + [dict(e, **{"calendar":"A"})]  %}
            {% endfor%}
            {% for e in agenda2.events %}
              {% set ns.alt_events = ns.alt_events + [dict(e, **{"calendar":"B"})]  %}
            {% endfor%}
            {% for e in agenda3.events %}
              {% set ns.alt_events = ns.alt_events + [dict(e, **{"calendar":"C"})]  %}
            {% endfor%}
            {{ns.alt_events | sort(attribute='start') | list }}

EDIT: The template above is more complicated than it needs to be for normal use. However, using this method allows you to add data to every event. I have updated the template to show how to do that.

If you do not want/need to add calendar origin data to your events you can use the list concatenation shown in petro’s post below.

1 Like

Hello,

I have carefully read your exchanges.
Unfortunately, I’m a newby with Home Assistant and I’m lost. I have a lot to learn …
I’m having trouble understanding and reproducing what you’ve done.

I have the same need than you.
I have a calendar with events under HA.
I need to access all events thru ESPhome.
The goal is to show all events for the further 3 days on an epaper screen.

Can you help me how to proceed ?

I am lost, I don’t undestand what I have to add in the diffrent .yaml file.

There are some things to add in

  • the sensor.yaml
  • the script.yaml
    There are some
  • automations
  • services

I am completly lost …

Service

I’m certainly not an expert but I have this setup based on input in this thread.

In automations.yaml I have this:

alias: Get events
description: ""
trigger:
  - platform: time_pattern
    minutes: "45"
condition: []
action:
  - service: calendar.list_events
    data:
      duration:
        hours: 168
        minutes: 0
        seconds: 0
    target:
      entity_id: calendar.family
    response_variable: fam_scheduled_events
  - service: calendar.list_events
    data:
      duration:
        hours: 168
        minutes: 0
        seconds: 0
    target:
      entity_id: calendar.garbage
    response_variable: gar_scheduled_events
  - service: calendar.list_events
    data:
      duration:
        hours: 168
        minutes: 0
        seconds: 0
    target:
      entity_id: calendar.ical_holidays
    response_variable: hol_scheduled_events
  - event: cal_scheduled_events
    event_data:
      scheduled_events: >-
        {{ fam_scheduled_events.events + gar_scheduled_events.events +
        hol_scheduled_events.events }}
mode: single

That will fetch all events from 3 separate calendars occurring in the next 7 days, runs every hour at min 45.

Then in configuration.yaml I have:

  - trigger:
      - platform: event
        event_type: cal_scheduled_events
    sensor:
      - name: Calendar Scheduled Events
        unique_id: calendar_scheduled_events
        state: "{{ trigger.event.data.scheduled_events | count() }}"
        attributes:
          scheduled_events: "{{ trigger.event.data.scheduled_events }}"
        icon: mdi:calendar

That will create a template sensor which triggers based on the automation above and creates a sensor with all the events.

In configuration.yaml I also have another template sensor to format the events (and combine with other data I send to my e-paper)

  - trigger:
      - platform: time_pattern
        # This will update every hour
        minutes: 0
    
    sensor:
      - name: Weatherman Data
        state: "OK"
        attributes:
          cal_family: >-
            {% set items = state_attr('sensor.calendar_scheduled_events', 'scheduled_events') | sort(attribute='start') %}
            {%- for item in items -%}
            {% set delta = (item.start) | as_datetime | as_local - today_at() %}
            {%- if delta.days == 0 -%}
            {% set start = "I dag " %}
            {%- elif delta.days == 1 -%}
            {% set start = "I morgon " %}
            {%- elif delta.days == 2 -%}
            {% set start = "I övermorgon " %}
            {%- else -%}
            {% set start = as_timestamp(item.start) | timestamp_custom('%A %d %b ', default=0) %}
            {%- endif -%}
            {{ start + as_timestamp(item.start) | timestamp_custom('%H:%M', default=0) + " - " + as_timestamp(item.end) | timestamp_custom('%H:%M', default=0) + '~' }}
            {{item.summary + '~'}}
            {% endfor %}

That will update every hour and sort the events, also uses timedelta to format as “Today”, Tomorrow" and “Day after tomorrow” (but in swedish). It will output each start and end time and summary of the event separated with ~

Lastly, in my esphome folder I have display.yaml where I have this:

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: cal_family
    id: cal_family

Takes the attribute from the previous template sensor and creates a text sensor in esphome.

And in the lambda section:

      char *strFam = strdup( id(cal_family).state.c_str() );
      char delim[] = "~";

      char *nxtStrFam = strtok(strFam, delim);

      if (nxtStrFam != NULL && strlen(nxtStrFam) > 0) {
          it.printf(30, 515, id(font2), TextAlign::TOP_LEFT, "%s", nxtStrFam);
      }

      nxtStrFam = strtok(NULL, delim);

      if (nxtStrFam != NULL && strlen(nxtStrFam) > 0) {
          it.printf(15, 540, id(font2), TextAlign::TOP_LEFT, "%s", nxtStrFam);
      }

Repeated for as many events I would like to display (fit) on my e-paper

Hi,

Thank you.
I had created all up to the the configuration file.

But I don’t see/find any sensor with my data !

I have this in the configuration.yaml file

template:
  - trigger:
      - platform: event
        event_type: calendar_events
    sensor:
      - name: Calendar Scheduled Events
        unique_id: calendar_scheduled_events
        state: "{{ trigger.event.data.scheduled_events.events | count() }}"
        attributes:
          scheduled_events: "{{ trigger.event.data.scheduled_events.events }}"
        icon: mdi:calendar'

I have this in my automations.yaml file

alias: Get events
description: ''
trigger:
   - platform: time_pattern
     minutes: /1
condition: []
action:
  - service: calendar.list_events
    data:
      duration:
        hours: 192
        minutes: 0
        seconds: 0
      start_date_time: '2023-09-06 00:00:00'
    target:
      entity_id: calendar.travail
    response_variable: scheduled_events
  - event: birthday_events
    event_data:
      scheduled_events: '{{ scheduled_events }}'
mode: single

Where should I find the results ?

You probably need to reboot, then you should have a sensor named sensor.calendar_scheduled_events
You can check in developer tools > states to find it.

Your sensor is listening for a different event than your automation is creating…

However, with today’s release of 2023.9, the intermediary automation is no longer necessary. Once you update, you can get rid of the automation and just use the following for your sensor.

template:
  - trigger:
      - platform: time_pattern
        minutes: /1
    action:
      - service: calendar.list_events
        data:
          duration:
            hours: 192
            minutes: 0
            seconds: 0
          start_date_time: "{{ today_at() }}"
        target:
          entity_id: calendar.travail
        response_variable: scheduled_events
    sensor:
      - name: Calendar Scheduled Events
        unique_id: calendar_scheduled_events
        state: "{{ scheduled_events.events | count() }}"
        attributes:
          scheduled_events: "{{ scheduled_events.events }}"
        icon: mdi:calendar'
1 Like

Hello,

Thank you Zinken fr your guide and explanation.
Now it’s working very fine !

Drew, so nice. I have installed the 2023.9 release and test the simplied implementation.
IT’s working very fine too !

Thank you guys for your help.

impressive, looks good.

can you help, need the next 5 events as “state” for esphome…

  • here i see only 3
  • can i add location?
  • how can i get a clear time and date?
Friseur
11.09.2023
16:30 - 17:30

i think i need a format for esphome like this (sample)

  - platform: homeassistant
    id: event01_summary
    entity_id: sensor.xxxx

  - platform: homeassistant
    id: event01_startdate
    entity_id: sensor.xxxx

  - platform: homeassistant
    id: event01_starttime
    entity_id: sensor.xxxx

  - platform: homeassistant
    id: event01_enddate
    entity_id: sensor.xxxx

  - platform: homeassistant
    id: event01_endtime
    entity_id: sensor.xxxx

is it possible, to observe more as one calendar? this here works not:

#-------------------------------------------------------------
# Display Kalender Events
#-------------------------------------------------------------
  - trigger:
      - platform: time_pattern
        minutes: /1
    action:
      - service: calendar.list_events
        data:
          duration:
            hours: 192
            minutes: 0
            seconds: 0
          start_date_time: "{{ today_at() }}"
        target:
          entity_id:
            - calendar.one
            - calendar.two
            - calendar.three
        response_variable: scheduled_events
    sensor:
      - name: Calendar Scheduled Events
        unique_id: calendar_scheduled_events
        state: "{{ scheduled_events.events | count() }}"
        attributes:
          scheduled_events: "{{ scheduled_events.events }}"
        icon: mdi:calendar'

10 comments up

You shouldn’t need to use namespace here for any of those. Just add the lists together, and you can use variables.

  - trigger:
      - platform: calendar
        event: end
        entity_id: calendar.a
      - platform: calendar
        event: end
        entity_id: calendar.b
      - platform: calendar
        event: end
        entity_id: calendar.c
      - platform: event
        event_type: event_template_reloaded
    action:
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.a
        response_variable: agenda1
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.b
        response_variable: agenda2
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.c
        response_variable: agenda3
      - variables:
          all_events: >
            {{ agenda1.events + agenda2.events + agenda2.events }}
          events: >
            {{ all_events | selectattr('start', 'search', now().date() | string) | list }}
    sensor:
      - name: Next 24hr Events
        unique_id: custom_multical_todays_events
        state: "{{ events | count }}"
        attributes:
          scheduled_events: "{{ events }}"

and if you want to shorten the yaml, you can use anchors.

  - trigger:
      - <<: &cal_trigger
          platform: calendar
          event: end
        <<: &cal_a
          entity_id: calendar.a
      - <<: *cal_trigger
        <<: &cal_b
          entity_id: calendar.b
      - <<: *cal_trigger
        <<: &cal_c
          entity_id: calendar.c
      - platform: event
        event_type: event_template_reloaded
    action:
      - <<: &cal_action
          service: calendar.list_events
          data:
            duration:
              hours: 24
        target: *cal_a
        response_variable: agenda1
      - <<: *cal_action
        target: *cal_b
        response_variable: agenda2
      - <<: *cal_action
        target: *cal_c
        response_variable: agenda3
      - variables:
          all_events: >
            {{ agenda1.events + agenda2.events + agenda2.events }}
          events: >
            {{ all_events | selectattr('start', 'search', now().date() | string) | list }}
    sensor:
      - name: Next 24hr Events
        unique_id: custom_multical_todays_events
        state: "{{ events | count }}"
        attributes:
          scheduled_events: "{{ events }}"
2 Likes

thx for this code snipped. not easy for me to understand… i tried it with my calendar, but my entity is empty.

You’d have to post what you tried.

my code: (same as yours, only with my calendars)

#-------------------------------------------------------------
# Display Kalender Events
#-------------------------------------------------------------
  - trigger:
      - platform: calendar
        event: end
        entity_id: calendar.mil
      - platform: calendar
        event: end
        entity_id: calendar.ab
      - platform: calendar
        event: end
        entity_id: calendar.geburtstage
      - platform: event
        event_type: event_template_reloaded
    action:
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.mil
        response_variable: agenda1
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.ab
        response_variable: agenda2
      - service: calendar.list_events
        data:
          duration:
            hours: 24
        target:
          entity_id:
            - calendar.geburtstage
        response_variable: agenda3
      - variables:
          all_events: >
            {{ agenda1.events + agenda2.events + agenda2.events }}
          events: >
            {{ all_events | selectattr('start', 'search', now().date() | string) | list }}
    sensor:
      - name: Next 24hr Events
        unique_id: custom_multical_todays_events
        state: "{{ events | count }}"
        attributes:
          scheduled_events: "{{ events }}