Sure, that would work.
Ok, thanks. I also read about the difference between offset and delay_on/delay_off. Offset fires the trigger later and for delay the event has still to be going at the point of the delay, otherwise it won’t work. I still don’t understand, why my solution didn’t work. Is there something wrong in the code?
The addition of an offset to a trigger fires it at a different time, but the Calendar event details are part of the trigger. Whether or not that event is active in the calendar would make no difference.
I don’t think there’s anything “wrong” with it on its face. But, I don’t know if using a delay like that has an effect on the update of subsequent sensors configured in the same block…
You could try an experiment like:
Splitting the two sensors
- triggers:
- trigger: calendar
entity_id: 'calendar.my_calendar'
event: start
- trigger: calendar
entity_id: 'calendar.my_calendar'
event: end
actions:
- variables:
message: "{{ trigger.calendar_event.summary }}"
binary_sensor:
- name: Event 1
state: |
{% if message != "Event 1" %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
delay_on:
hours: 8
delay_off:
hours: 8
- triggers:
- trigger: calendar
entity_id: 'calendar.my_calendar'
event: start
- trigger: calendar
entity_id: 'calendar.my_calendar'
event: end
actions:
- variables:
message: "{{ trigger.calendar_event.summary }}"
binary_sensor:
- name: Event 2
state: |
{% if message != "Event 2" %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
delay_on:
hours: 8
delay_off:
hours: 8
But, I would really try to stay away from such extended delay_on and delay_off values.
It could also just be a quirk of all-day events… there have been weird issues with them in the past, but I thought those had been resolved.
For some reason all the approaches above don’t work in my setup. All my events are repeating, multi-day events, that sometimes overlap, sometimes Event 1 starts when Event 2 ends and sometimes there is time in between. The sensors never turn on when a specific event starts. What works, is turning them off.
In my test scenarios I did not have all- or multi-day-events. These worked as expected. So it seems, that your suspicion is right. There seem to be some quirks with all day events.
My idea was to use the calendar entries that are already there for some automations in home assistant. But I guess I have to think of another approach.
Thanks anyway for all your help.
Hi,
this issue still haunts me, so I’ve given it some thought recently.
First of all, here is a summary for everyone who is new:
I would like some binary sensors, that represent if certain events in a calendar are currently ongoing.
- Every event has its own sensor.
- The events are usually all- or multiple day events (but not necessarily).
- Some of them are serial events.
- They can be overlapping, touching each other (Event 1 ends in the same moment as Event 2 starts) or have some time in between.
With much help of @Didgeridrew, I came to this piece of code:
Trigger based binary sensor
template:
- triggers:
- trigger: calendar
entity_id: 'calendar.my_calendar'
event: start
- trigger: calendar
entity_id: 'calendar.my_calendar'
event: end
actions:
- variables:
message: "{{ trigger.calendar_event.summary }}"
binary_sensor:
- name: "Event 1"
state: |
{% if message != "Event 1" %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
- name: "Event 2"
state: |
{% if message != "Event 2" %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
binary_sensor:
- name: "Event 3"
state: |
{% if message is not search("event 3", ignorecase=True) %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
I created some test events in a local calendar and the sensors worked as expected. For my productive calendar they never really worked. They would turn off a sensor if the corresponding event ended, but would never turn on if the event started.
@Didgeridrew suspected that there may be some unresolved issues with all day events.
I came to another question: If the events are “touching” each other then event: start and event: end occur at the same time. Can this be the reason for the behavior?
Also I thought about a different approach to achieve my goal: Check every minute which events are currently active and set the sensors accordingly. The code, I’d use for this would probably look like this:
Time based trigger for calendar events
template:
- triggers:
- platform: time_pattern
minutes: "/1"
actions:
- variables:
message: "{{ calendar.my_calendar_event.summary }}"
binary_sensor:
- name: "Event 1"
state: |
{% if message != "Event 1" %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
- name: "Event 2"
state: |
{% if message != "Event 2" %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
binary_sensor:
- name: "Event 3"
state: |
{% if message is not search("event 3", ignorecase=True) %}
{{ this.state | default('off', true) }}
{% else %}
{{ 'on' if trigger.event == 'start' else 'off' }}
{% endif %}
- Does this idea make sense?
- Is the code correct?
Thanks again for any help on this.
I think, that the combination off all-day-events and back-to-back-events caused the problem. With the help of my preferred ai agent I found this solution to be working:
Solution
template:
- trigger:
- trigger: time_pattern
minutes: "*"
- trigger: homeassistant
event: start
action:
- action: calendar.get_events
target:
entity_id: calendar.my_calendar
data:
duration:
hours: 0
minutes: 1
response_variable: agenda
binary_sensor:
- name: "Event 1"
unique_id: event_1_check
state: >
{% set events = agenda['calendar.my_calendar'].events %}
{{ events | selectattr('summary', 'eq', 'Event 1') | list | count > 0 }}
- name: "Event 2"
unique_id: event_2_check
state: >
{% set events = agenda['calendar.my_calendar'].events %}
{{ events | selectattr('summary', 'eq', 'Event 2') | list | count > 0 }}
- name: "Event 3"
unique_id: event_3_check
state: >
{% set events = agenda['calendar.my_calendar'].events %}
{{ events | selectattr('summary', 'search', 'event 3', ignorecase=True) | list | count > 0 }}
This works for standard events as well as for one- and multi-day-events, no matter if they are overlapping, or touch each other or neither of both.