Hello all,
I do consults at various properties throughout the day, and I’m trying to make a card that shows when I have to leave for my next appointment, like this:
(context for card - that’s an appointment that starts at 20:00, and finishes at 21:00 and it’s 20:59 when I made the screenshot)
Mostly this all works, but I have a couple bugs still and I was hoping someone might point me in the right direction.
My templates/project works great if there is not a current appointment. i.e. nothing on schedule “now”, but looking forward at the next appointment.
My problem is that once an appointment starts my templates still focuses on the current appointment, and I need them to look at the next appointment as soon as the “start time” has passed.
Here is my foundational template. I have others, but all they do is manipulate the event that this one grabs from the schedule.
YAML
- trigger:
- platform: homeassistant
event: start
- platform: time_pattern
hours: "/6"
- trigger: state
entity_id:
- input_button.update_next_event
action:
- action: calendar.get_events
target:
entity_id: calendar.personal_calender
data:
duration:
hours: 168
minutes: 0
seconds: 0
response_variable: agenda
- alias: Find upcoming events with locations
variables:
upcoming: "{{ agenda['calendar.personal_calender']['events'] | rejectattr('location', 'undefined') | list }}"
sensor:
- name: "Next Location"
state: >
{% if upcoming|length > 0 %}
{{ upcoming[0].location }}
{% endif %}
- name: "Next Location Summary"
state: >
{% if upcoming|length > 0 %}
{{ upcoming[0].summary }}
{% endif %}
- name: "Next Location Start"
state: >
{% if upcoming|length > 0 %}
{{ upcoming[0].start }}
{% endif %}
device_class: timestamp
Reading the docs for calendar.get_events
, I thought it is supposed to only grab events that start after now by default, however it seems to include events that are currently occurring. I may misunderstand that one.
I think I need to add something to the if
of each sensor to compare the start time to “now”, but I’m not sure how to approach that and haven’t found a relatable example.
I have a related template question if I may…
- In the above template, what does the [0] after upcoming do?
Thank you!
A follow up question…
Here is a response for:
action: calendar.get_events
data:
duration:
hours: 72
minutes: 0
seconds: 0
start_date_time: "2024-11-25 19:00:00"
target:
entity_id: calendar.personal_calender
calendar.personal_calender:
events:
- start: "2024-11-25T20:00:00-08:00"
end: "2024-11-25T21:00:00-08:00"
summary: work source everett
location: WorkSource Everett, 3201 Smith Ave, Everett, WA 98201, USA
- start: "2024-11-25T21:00:00-08:00"
end: "2024-11-25T22:00:00-08:00"
summary: bellingham highscchool
location: Bellingham High School, 2020 Cornwall Ave, Bellingham, WA 98225, USA
How can I format that response so that I can play with it in the Template Tool so that it’s similar to how it’s formatted with the trigger above:? Or do I have to use an automation to test it?
response_variable: agenda
- alias: Find upcoming events with locations
variables:
upcoming: "{{ agenda['calendar.personal_calender']['events'] | rejectattr('location', 'undefined') | list }}"
Part of why I’ve found this especially hard is that the foundation template is a trigger that requires restarting to tweak vs being live in the Template Tool.
You were mistaken, any currently active events will be selected as well. If you want to remove all currently active events, you can add a rejectattr
filter to your template like:
- alias: Find upcoming events with locations
variables:
upcoming: |
{{ agenda['calendar.personal_calender']['events']
| rejectattr('location', 'undefined')
| rejectattr('start', 'le', (now().replace(microsecond=0)).isoformat())
| list }}"
It selects the first calendar event in the list of events being stored in the variable upcoming
.
After running the action in the Actions tab, scroll to the bottom and click “Copy to Clipboard (Template)”. This will save a Jinja set
statement to the clipboard which you can paste directly into the Template Editor tool. By default it uses the variable ID action_response
, but you can change that to whatever you want in the Template Editor.
2 Likes
Thank you so much @Didgeridrew! This is very helpful not just for this project, but for my learning in general. The python link is great too.
For someone like myself with a rudimentary knowledge of programming, but an interest in learning Python at least to read and tweak scripts, is there a resource that you would suggest? (that link may be the answer I’m looking for too.)
Is there a way to check more than 1 calendar? I’ve added it to the calendar.get_events
action which now outputs:
calendar.some_dude_s_jobber_schedule:
events:
- start: "2024-12-19"
end: "2025-01-05"
summary: Christmas break
- start: "2025-01-01"
end: "2025-01-02"
summary: New Years Day - Paid Holiday!
- start: "2025-01-06"
end: "2025-01-07"
summary: some_dude-Site Assessments
- start: "2025-01-06T15:00:00+00:00"
end: "2025-01-06T15:30:00+00:00"
summary: Jetta Mileage
description: "in: out: Total:"
calendar.some_dude_s_personal_calender:
events:
- start: "2025-01-02"
end: "2025-01-03"
summary: an important day