Taras - Awesome - Just like magic, yep macro now works, learning a lot, reading a lot thank you.
I have spent many hours trying to get the day and date formatted from events using your code above, in what way do you implement it? The german makes it a little harder to understand for me
But what I can gather is your redefining the output then will use another template to call the info? is that correct or am I off base?
are you responding to me or a different post?
Sorry Carlos your post came in as I was typing to Taras, looking at yours now.
In case you missed it, it’s now possible to get events from a calendar natively; there’s no need to install any third-party applications.
If that’s what you want to do then it can be done without the use of calendar.list_events
. What you described can be achieved with a Calendar Trigger.
If you mean the example in this post, then read the post prior to it. You’ll see I took someone else’s example (containing German text) and simplified its templates.
You’ll need to explain what you want exactly.
I would like to format the event times, when the TTS reads it out so that Tuesday @ 4pm etc at the moment I have
For determining if a date is today, tomorrow, in X days, etc then you may want to consider using these custom macros:
Okay thanks, I will have a read
Thanks for the tip!
I used a different approach, because I would like to send multiple notifications. I’m now using this automation at a given time:
automation:
- alias: "Notify Events for Today"
trigger:
platform: time
at: "08:00:00"
action:
service: notify.your_notification_service
data:
title: "Today's Events"
message: >-
{% set today = now().strftime('%Y-%m-%d') %}
{% set events_today = state_attr('sensor.gary_scheduled_events', 'scheduled_events') | selectattr('start', 'eq', today) | list %}
{% for e in events_today %}
{{ e.summary }}
{% endfor %}
This works like a charm!
Next step is cleaning up code (using correct names for this service) and I’ll put a ‘how to’ on this topic.
automation:
- alias: "Notify Events for Today"
trigger:
platform: time
at: "08:00:00"
action:
service: notify.your_notification_service
data:
title: "Today's Events"
message: >-
{% for e in state_attr('sensor.robin_scheduled_events', 'scheduled_events')
| selectattr('start', 'eq', now().strftime('%Y-%m-%d')) %}
{{ e.summary }}
{% endfor %}
Thanks guys for the inspiration, I could not figure out the easy time approach, I resolved it by just inserting a timestamp similar to Robin.
Garys Agenda for today: {% for e in
state_attr('sensor.garys_agenda','scheduled_events') %}
{{ as_timestamp(e.start) | timestamp_custom ('%A %H:%M %p') }}: {{ e.summary }} {% endfor %}
Christines Aganda for today: {% for e in
state_attr('sensor.christines_agenda', 'scheduled_events') %}
{{ as_timestamp(e.start) | timestamp_custom ('%A %H:%M %p') }}: {{ e.summary }} {% endfor %}
Just one thing left for me to polish it a little, just have to work out the code to do the following:
if day = now then “Today” not the day of the week.
I finally got day changed to today and tomorrow, I am not sure if there is a better way to do it? I would be interested if there was a better way, however this seems to work okay. The only issue I cant resolve is the line spaces in between each event. See Garys agenda below as apposed to Christines agenda
Gary you have {{states('sensor.garys_agenda')}} items in your Agenda: {% for
e in state_attr('sensor.garys_agenda','scheduled_events') %}
{% set start = e.start | as_datetime | as_local %}
{% if start.strftime('%A') == now().strftime('%A') %}Today at {{ as_timestamp(e.start) | timestamp_custom ('%H:%M %p')}} {{ e.summary }}{%else%}{% if start.strftime('%A') > now().strftime('%A')%}Tomorrow at {{ as_timestamp(e.start) | timestamp_custom ('%H:%M %p')}} {{ e.summary }}{% endif %}{% endif %}{% endfor %}
The blank lines seen in the output are due to this line in your template.
{% set start = e.start | as_datetime | as_local %}
It’s represented by a blank line for each iteration of the for-loop.
You can suppress it by adding hypens to the braces, like this:
{%- set start = e.start | as_datetime | as_local -%}
Reference:
Jinja2 - Whitespace control
Assuming your sensor is constrained to containing events exclusively for today and tomorrow, you can use this streamlined version:
Gary you have {{ states('sensor.garys_agenda') }} items in your Agenda:
{% for e in state_attr('sensor.garys_agenda','scheduled_events') %}
{%- set start = e.start | as_datetime | as_local -%}
{{ ['Today', 'Tomorrow'][(start.date() - now().date()).days] }} at {{ start.strftime('%H:%M %p') }} {{ e.summary }}
{% endfor %}
Thanks Taras, I did notice the {%- in a few posts, but didn’t understand the significance? Will give it a go.
Will also give the new code a go and try to understand it.
On a side note: I see you helping a number of individuals throughout the community - you must know this stuff inside out, you not only give instruction but provide insight as well, thank you and good work from the whole community.
This is a list containing two items:
['Today', 'Tomorrow']
List items are indexed starting with zero. Therefore this will display the first item in the list (Today
).
['Today', 'Tomorrow'][0]
This displays the second item in the list (Tomorrow
).
['Today', 'Tomorrow'][1]
Subtracting two datetime objects produces a timedelta object. One of the properties of a timedelta object is days
. In other words, the timedelta object’s value is reported as the number of days.
(start.date() - now().date()).days
If the difference between start.date()
and now().date()
is 0
then it means the event starts today. If the difference is 1
then it starts tomorrow. We use this difference value to get the associated item from the list.
{{ ['Today', 'Tomorrow'][(start.date() - now().date()).days] }}
Thank you for the explanation, helps a lot especially in the future,
By adding the streamline ver, I realise now why my original ver wasn’t pulling in the next day, I only defend 2 in the list, however your solution brings in the whole list and defines 2 names. Yours is streamlined but also a better solution as if I have items in the third day I can see them as below:
I have been playing around with if statements trying to get the items after tomorrow to default back to the day “Monday” etc? No success so far. Also I have been looking into “carriage returns” something so obvious seems difficult, say I want a “carriage return” after the first line, how do you do that?
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.
No problem, thank you for all your help