Don’t allow automation to run if has already been run within last X minutes

I have an automation that will set my heating to come on boost for 60minutes when motions detected. So every time motion is detected it goes back up to 60minutes.

How can I set the automation to not re run a 2nd time and instead wait until those 60minutes are up before running. I tried a 60minutes delay but that doesn’t help if there is only 1 minute left on the boost as the heating won’t come on for 61minutes minimum. I want it that it won’t come on but a minute later for instance any motion would start a new 60mins or if there was 30minutes left then an motion will not start a new counter for another 30minutes assuming there motion after those 30 minutes still.

Can you show me your automation? I’m trying to get to something similar.

The best approach is to use set a input_datetime with date and time one hour ahead and use that as a condition in the automation.
So if current time is more than this input_datetime then it’s allowed to run.

Using a condition on last_run time can be problematic when HA restarts, but if you are fine with that then that is probably a simpler solution since it doesn’t need a input_datetime.

Set the Automation to single and it wont trigger again when its busy. So if you have the 60min delay in the automation any new trigger wont activate it again. Only after the automation is done will it be able to trigger again.

single (Default) Do not start a new run. Issue a warning.

script_modes

3 Likes

This does only work for automation instances still running. So, as already mentioned:

  • create an input_datetime “helper”
  • in your automation’s action part, call service to set the value of that helper to “now” + 1hour
  • in the automation’s condition part, add a time condition that prevents actions before current time is after the helper’s time.
condition:
- condition: time
  after: input_datetime.next_run
action:
 - service: input_datetime.set_datetime
  target:
    entity_id: input_datetime.next_run
  data:
    time: "{{ now() + timedelta(hours = 1) }} "
2 Likes

confused now, didnt the OP say he wanted a 60min boost? and at the end of the boost i can be triggered again. So if u use a Wait in the automation its still running and wont run again.

alias: Test
description: ''
trigger:
  - platform: state
    entity_id: switch_test
    to: '1'
condition: []
action:
  - service: knx.send
    data:
      address: 0/2/2
      payload: 1
  - delay:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
mode: single

In this case using switch_test will trigger the Automation and its delay of 30 seconds, after that i can spam the switch_test but nothing will happpen. Until the 30 seconds is up and then it will be able to run again.

Both solutions are valid examples, best match must be identified by the OP.

Cheers guys. I’ll give both examples a go and see which ones I get on better with.

But delaying automations more than a few seconds is always a risk that it will fail due to automation reload or restart of HA.
That is why the recommended way is to use a datetime.

Can you use a date/time for 1hour in the future as opposed to a specific time

Yes, look at what Christoph wrote.

Hi, before I did this:

{{ ( as_timestamp(now()) - as_timestamp(state_attr(‘automation.name’, ‘last_triggered’)) |int(0) ) > 300 }}

Now templates have changed and doesn’t work anymore, anyone knows how to fix?

{{ as_timestamp(now()) - as_timestamp(state_attr(this.entity_id,'last_triggered'))| int(0) > 300 }}

Yours looks just fine except for the type of quotes you’re using. Plus you can use ‘this’ so you don’t need to hardcode the name of the automation.

2 Likes

Yet another way to do the same thing:

{{ now() - state_attr('automation.name', 'last_triggered') > timedelta(minutes=5) }}

The values of now() and last_triggered are datetime objects.

When you subtract datetime objects, the result is a timedelta object. The template simply subtracts the two datetime objects and compares the result to a timedelta object of 5 minutes.

If the template is within the automation it is testing then you can use calisro’s tip and replace automation.name with this.entity_id.

{{ now() - state_attr(this.entity_id, 'last_triggered') > timedelta(minutes=5) }}

EDIT

Correction. Removed quotes wrapping this.entity_id which mistakenly changed its meaning from a variable to a string.

7 Likes

Your template above was creating an error for me!
@calisro’s tip references this.entity_id not 'this.entity_id'

{{ now() - state_attr(this.entity_id, 'last_triggered') > timedelta(minutes=5) }}

which works for me.

2 Likes

Yes it shouldn’t have quotes.

Thank you! I have corrected the mistake.

1 Like

Hi! I’ve encountered a similar issue and was wondering if this would work with automation IDs? I have some pressure mats I’ve connected to HA via ESP that when detected, open op a doggy door (there are mats on either side of the door, grouped together in HA). However I want to avoid a double activation when the dog steps on both when he goes in or out, so I figured just setting a condition of “don’t activate if the automation was ran within 15 seconds prior.” I figured setting up a custom sensor would do the job.

Using the above provided code I’m getting an error, which I assume is only due to the automation ID. Any help would be appreciated!

{{ now() - state_attr(automation.open_doggy_door_with_mat, 'last_triggered') > timedelta(seconds=15) }}

The quotes are missing around the automation entity:


{{ now() - state_attr('automation.open_doggy_door_with_mat', 'last_triggered') > timedelta(seconds=15) }}

or:


{{ now() - state_attr(this.entity_id, 'last_triggered') > timedelta(seconds=15) }}

1 Like

Thank you! Unfortunately I’m still getting an error for the date.time.

TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'NoneType'