I have my apocryphal coffee machine turn on/off at particular times set by input_datetime helpers that I can tweak from the UI. I am just using a standard time trigger in the automation to turn it on/off.
I also have a workday sensor which tells me if today is a holiday.
I would like to turn on/off my coffee machine one hour later if today is a holiday. I currently achieve this by doubling all my datetime helpers and having conditions to test if the workday sensor is on. But this gets out of hand when I start adjusting them, since I have to remember to do it twice.
Is it possible to modify an input_datetime by “adding” some time offset to it? I would then be able to do something like. I could then have an automation which either sets this offset to zero for normal days and e.g. 1 hour for holidays, to be used across all my automations.
There’s a PR in the works to allow offsetting a Time Trigger.
If and when it gets implemented, your goal will be easier to achieve (sort of; based on my interpretation of the PR’s description, the offset will have to be a fixed value as opposed to an entity’s value).
Until that happens, you have to use a Template Trigger or, because you need to refer to it in triggers and conditions, create a Template Sensor and reference it in triggers and conditions.
Let me know if you need help creating the template for the Template Sensor.
It would be great if you could help me how to create a template which would test if the time now is equal to the time of some (time-only) input_datetime offset stored in another (time-only) input_datetime. I get completely lost with the fact that time-only input-datetimes are not easily interpretable as timestamps.
The second method converts the calculated time to a datetime object and then compares it to the current time.
{% set t = now().fromtimestamp(state_attr('input_datetime.your_time', 'timestamp')
- state_attr('input_datetime.your_offset', 'timestamp'), utcnow().tzinfo) %}
{{ (now().hour, now().minute) == (t.hour, t.minute) }}
Both work equally well but the first one has the advantage of brevity. The second one is longer because it has extra work converting the subtracted input_datetimes into a datetime object.
A few words on how it performs the datetime conversion:
now() returns a datetime object.
now().fromtimestamp() will convert the supplied Unix timestamp into a datetime object.
The timestamp we are providing represents a local time but it’s actually expressed as a UTC time with no timezone offset. We need to inform fromtimestamp() of this missing timezone offset so that’s why we supply it with the utcnow().tzinfo adjustment.
As seen from the two examples above, they’re a bit more challenging to work with if you want to handle them as datetime objects.
NOTE
If you want to create a Template Sensor, just use a variation of the first method:
One thing to add here, is that with 2021.11 a new template filter is landing, which will allow you to do the simple thing of creating a datetime object from a time
today_as(states(`input_datetime.trigger_time`))
which will return a datetime with today’s date and the time specified in the helper.