Reading a bit more into the calendar entity…
“Calendar triggers are the best way to automate based on calendar events. A calendar entity can also be used to automate based on its state, but these are limited and attributes only represent the next event.”
(Calendar - Home Assistant)
Whilst that is a limitation… it’s fine for my purposes - I only ever need the next event for a given calendar for heating purposes.
A quick play in the template editor gives me the start time, so I can just subtract the current time to see how far away the next entry is (EDIT: added some handling for “no next event”):
{% set cal = state_attr('calendar.webcal_...','start_time') %}
{% if cal is none %}{% set cal=now() + timedelta(days=1) %}{% endif %}
{{ as_timestamp(cal) - as_timestamp(now()) }}
Technically this doesn’t always give the next entry - it gives the current one if the calendar is active - so I get negative “time to next event” if the calendar is active.
So we have a few distinct scenarios:
A - If an event (-1hr) triggers and there isn’t an event active, then we’re all good - set the temp.
B - If an event (-1hr) triggers whilst there is already an event active (i.e. the calendar is active) then wait until much later (say, a 45 minute wait) before adjusting the target temperature.
I might do 59 minutes, rather than an hour, to avoid edge cases where the time taken to run the template means the logic catches one event, but not the other.
C - If an event stops (+1 min) and there isn’t an event for more than 3600 seconds, then we’re all good - set back.
D - If an event stops (+1 min) and there is an event within 3600 seconds (or has been running for just 60)… then we’re probably already waiting, or recently had the temp set, (both from scenario B). We can set the new temperature right away, it’s probably going to end up being set twice, but that’s not a problem, it’s redundancy .
At this point the automation needs to allow parallel running to deal with the potential waits etc…
I think that’s the “main” spaces logic in a relatively short list (and therefore simple automation)
Calling a script for the shared spaces then makes sense. I’m thinking that the shared spaces probably always want to have the “default” temperature - it’s not like the dancers will be dancing in the loos…
That script would loop through each calendar and check whether there is an event running, or one starting in the next hour - and add the relevant tags/labels/spaces to a list of areas to heat.
After all the calendars are checked the areas on the list are set to heat, and the rest of the area are set_back (again, it’s ok to set a temperature on a thermostat that’s already at that temperature). That would be a script which can be run when an event starts or stops, or indeed at any random time.