Subtract time from a helper

Hi,

I am trying to fix my morning alarm automation to make it cleaner. Right now, I use a helper that I input my desired wake-up time in & the automation triggers at that time. However, I like to have some things started before I wake up, such as my lights beginning to turn on. So, if I want to wake up at 7:30, I input 7:25 to get things going by the time 7:30 comes.

I have seen some other topics similar to mine, but I could not make sense of them, to be honest. How can I subtract 5 minutes from my wake-up time? I would like to input 7:30 & have things begin at 7:25.

Right now my automation triggers include a template with a Value template of
{{ states('sensor.time') ==(states.input_datetime.sunrise_time.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}

& my other trigger is Time at input_datetime.sunrise_time which is my current helper ID.

To make things worse, this automation has not been triggering every day as it used to do. I was also hoping someone could point out if I have an error in my triggers. Thank you ahead of time for your help.

Use


value_template: "{{ states('sensor.time') == (state_attr('input_datetime. sunrise_time', 'timestamp') - 300) | timestamp_custom('%H:%M', false) }}"

or


value_template: "{{ now().timestamp() | timestamp_custom('%H:%M') == (state_attr('input_datetime.sunrise_time', 'timestamp') - 300) | timestamp_custom('%H:%M', false) }}"

→ 300 = seconds

(stolen from User 123)

I use this trigger, too, and never had a problem. What does the automation debug trace say?

2 Likes

A different way, possibly better, is to use timedelta.

{{ strptime(today_at(states('input_datetime.sunrise_time')), '%Y-%m-%d %H:%M:%S') - timedelta(minutes=5)  }}

You could make a template sensor of the above with timedelta minutes a input_number.
And in automation use the trigger time on sensor.
That way you can have a variable time and variable timedelta and a easily readable automation.
The downside is that you add more entities

That gives me TypeError: unsupported operand type(s) for -: 'str' and 'datetime.timedelta'

{{ (as_timestamp(now() + timedelta( days = 14 )) - as_timestamp(strptime(states('sensor.mydatetimesensor'), '%Y-%m-%dT%H:%M:%S+00:00')))|int > 0 }}

I use this one, check 14 days before set time.
Works pretty well, except it throws one error during startup (system not ready??)

2022-01-17 08:18:23 ERROR (MainThread) [homeassistant.helpers.event] Error while processing template: Template("{{ (as_timestamp(now() + timedelta( days = 14 )) - as_timestamp(strptime(states('sensor. mydatetimesensor'), '%Y-%m-%dT%H:%M:%S+00:00')))|int > 0 }}")

but once system is running, it works fine :wink:

1 Like

Did you really use the exact template as I posted above?

Sure. Only changed the input_datetime entity.

I remember vaguely i had to format my sensor value to get rid of that error (i also wanted it to only check at midnight (0:00), so i only use the date part :wink:)

The state of an entity is string.
The output of strptime is an object.

Python strptime() - string to datetime object (programiz.com)

So if the error is about string then I can only assume that strptime has not been used.

EDIT:

I see now that if the helper is only time then you get that error since it doesn’t have Y-M-D.

If it’s a helper with only time then today_at can be used.

{{ strptime(today_at(states('input_datetime.sunrise_time')), '%Y-%m-%d %H:%M:%S') - timedelta(minutes=5)  }}

Now strftime is working. What is the advantage compared to the other method?

You could make it a sensor that follows your wake up time.
So wake up time is 7:30, then the sensor shows 7:25.
If you add the input_number in the minutes part then the 7:25 could be variable depending on other factors.

And the automation will only be:

But that is not an advantage because the same effect can be reached by using the timestamp method.

sure…
But I find it easier to read with timedelta.
You might have a different opinion. But I rather keep automations clean to read.

I generally find it harder the more conversions there are, especially when it’s in seconds.
If you then add the minutes as input number, I don’t find that makes it easier to read.
But that is my opinion.

I would rather have the automation look like the above image and if I need to look at the sensor then it’s at least as readable as possible.

Ah, ok! I struggled a lot to create an automation with several time triggers and conditions, before it fitted, so any discussion on this topic is educational.

Hi Everyone. Thank you all for all of your help. I went with Pedolsky’s second suggestion & it looks like it is working for me. Hellis81 I do appreciate your tips, I definitely learned a lot here. I prefer having fewer, but more complicated automations over having many simple ones. Just a personal preference. Again, thank you all for your help!

Just a clarification.
I was suggesting one simple automation that was easier to read. Not multiple automations.

today_at returns a datetime object. Your strptime is doing nothing.

{{ today_at(states('input_datetime.sunrise_time')) - timedelta(minutes=5)  }}

EDIT: To be clear: I added today_at to make datetime calculations simple. If you find yourself using strptime… you’re not doing it right anymore. The only time strptime should be used is when you have an oddly formated string timestamp. E.g. Mon Jan 17th @ 9:29 AM.

5 Likes

today_at is a great addition to the templating toolbox. :+1:

It makes setting a datetime object to a specific time less verbose than the traditional way (even shorter if you want midnight because you just omit the time).

1 Like

I did not know that.
Thanks!