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