I have an automation that I want to use with a wait_for_trigger for a specific (random) time. The automation is triggered by a state change, which usually occurs around midnight. The automation should trigger a notification at random in the morning between 6:00 and 9:00. I want to use a template for the time, just like I would do with a delay.
automation:
- alias: Notify in the morning
trigger:
platform: state
entity_id: sensor.holiday
action:
# this delay template works
# - delay: '0{{ (range(6, 8)|random|int) }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}'
- wait_for_trigger:
platform: time
# at: '06:59:59' # this works just fine
# random time between 06:00:00 and 08:59:59 -- Err
at: '0{{ (range(6, 8)|random|int) }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}'
- service: notify.notify
data:
message: "Today is: {{ states('sensor.holiday') }}"
What Burningstone said, you can’t template the at option.
In addition, if you want a random value between 6 and 8 (inclusively) then the second argument in the range() function should be 9 (not 8). The second argument is the “stop” argument and should be greater, by one, than the desired range.
You can try this Template Trigger. However, the now() function only updates every minute so you can’t schedule a time containing seconds.EDIT: Potential flaw in this approach. See post by charlyr below
Thanks for the suggestions. Too bad the at: can’t be templated. My next attempt will be to wait until 6:00:00 and then add a delay for 0-2 hours. Something like this:
automation:
- alias: Notify in the morning
trigger:
platform: state
entity_id: sensor.holiday # triggers around midnight
action:
- wait_for_trigger:
platform: time
at: '06:00:00' # 'at' can't be templated yet
- delay: '0{{ (range(0, 1)|random|int) }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}'
- service: notify.notify
data:
message: "Today is {{ states('sensor.holiday') }}"
Both Time Trigger and now() employ the internal clock to determine when the appointed time occurs.
Primary difference is that now() in a Template Trigger has a resolution of one-minute whereas Time Trigger’s is one-second. If your application requires a one-second resolution then a Template Trigger with now() isn’t suitable.
EDIT
My suggestion has a potential flaw because the computed random time will change each minute thereby making it a moving target.
@123 just a quick question about this template that you posted above.
The presence of now() causes the template to be evaluated every minute, does this not mean that the random filters are also recalculated every minute, so it is possible that this could never fire or fire multiple times within the time window, as the time that you are comparing to is different every minute?
possible that this could never fire or fire multiple times within the time window
Yes; no.
Good catch that it may never trigger because it computes a new time each minute. Each computed time could be in the past or future to the extent that the current time never succeeds to match it.
However, it won’t trigger multiple times because it’s not the automation’s primary trigger but is used in the action’s wait_for_trigger. After triggering, the execution move on to the next action (delay).
Thanks for identifying the potential bug and Happy Cake Day!
@metbril
I retract the suggestion to use a Template Trigger in this situation because there’s a possibility it will never trigger during the desired time range. The flaw is that the inclusion of now() means the template is re-evaluated every minute which causes a new random time to be computed (i.e. the computed time become a moving target).