Using an event in the wait_template of a script?

Does anyone know what the syntax is to use an event in a wait_template in a script?

For context…

  1. I start a script with an automation.

  2. In the sequence step 1 of the script I start a 4 hour timer

  3. at a later point in the script I have a wait template to do some other thing but it will always happen within the 4 hour window of the running timer.

  4. at the end of the 4 hour timer I want another thing to happen and then the script exits.

What I don’t know is how to write the template for the wait_template to check the timer.finished event of the 4 hour timer to complete the final step of the script.

I thought about using the timer state going to “idle” but in my past experiences with timers I’m not sure that the timer displayed state actually represents the true timer status. But the timer.finished event should always fire at the correct time.

Did I misread your post or are you creating a script that will pause its own execution for up to four hours?

I know scripts run in blocking mode (can’t run a script that’s already running) but, damn, four hours is next-level blocking!

Instead of waiting within the script for the timer to finish, why not transfer execution flow to an automation triggered by the timer’s completion?

So if I understand this correctly, you want something like this:

-4 hour timer starts
-do something
-do something, etc
-wait_template(for something to be true)
-do something
-do something, etc
-wait_template(timer.finished)
-do something

?

exactly!!!

Dang 10 character minimum…

ok, that sounds pretty easy… maybe

The wait_template in the middle will be easy, just write it as you would normally.

At the end of the script you can have something like…(not sure if this will work as I’ve never played with timers)

wait_template: "{{ is_state('timer.your_4hr_timer', 'on') }}"

EDIT: sorry, I posted too soon. I meant to include the timer.finished event in there, just not 100% sure how since that is an event, not a state :thinking:

EDIT 2: maybe you could just use this at the end:

wait_template: "{{ is_state('timer.your_4hr_timer', 'off') }}"

It does seem strange but my use case is that I just started using a CPAP machine. And for the insurance to pay up I have to use it for four hours in a 24 hour period.

And to complicate things my work schedule is a rotating 12 hour shift (4 days on days. 4 days off, 4 days on nights, 4 days off) so I can’t just use a regular time slot because I never really go to bed at a regular time.

So I figured I would setup an automation to turn on an indicator to tell me it’s been at least four hours that I have been wearing the mask. At night I turn on a Sonoff Basic that I have connected to an unused extension cord and I use the green glow of the LED to tell me I haven’t reached the 4 hour mark yet. It’s bright enough to see it on but not so bright it bugs my sleep.

When I work nights and sleep during the day I can’t see the green glow so I use a bedside lamp with a Z Wave bulb in it that I set to a minimum brightness and when it goes off I know I can remove the mask.

So I set up two automations for that triggered by two input booleans. One to turn on the nights indicator & one to turn on the days indicator. And I use a simple delay in the action to wait four hours to turn the indicators and booleans off. So far so good. Until today when I told Alexa to turn on the wrong boolean and my system failed me.

So I figured I could write it all into one automation and use one boolean to control everything. The problem is my services and entity_ids are different depending on which time of day I turn it on.

So I figured I could use the automation and call a script based on the time I turned on the boolean to either run the days script or the night script. easy right. Again, so far so good. But then I thought about the fact that what happens when I turn on either the days indicator when it’s light out and then it gets dark and then light being on will bug me? Or when I turn on the night indicator and it gets light and I can no longer see the green LED glow? So I set up a couple of transitional scripts that takes sunrise/sunset into account to turn off the days//nights indicator and turn on the nights/days indicator.

So I use a wait template to do the transition during the four hour window based oin the sun rising or setting. But then I can’t use another wait template to turn it off at four hours from the time it originally got turned on. So I figured I’d start a timer at the beginning of the script then take the last actions (turn off both the correct indicator and the boolean trigger) when the timer was finished.

So that leads to the question. How do I use the timer.finshed event in a wait_template.

Here is an example of my transitional script:

  cpap_morning_transition:
    sequence:
      - service: switch.turn_on
        entity_id: switch.extension_cord_3
      - service: timer.start
        entity_id: timer.cpap_transition
      - wait_template: "{{ is_state('sun.sun','above_horizon') }}"
      - service: light.turn_on    
        entity_id: light.zw_light_2_level
        data:
          brightness: 15
      - service: switch.turn_off
        entity_id: switch.extension_cord_3
      - wait_template: "{{ what_do_I_put_here_? }}" <---
      - service: light.turn_off
        entity_id: light.zw_light_2_level
      - service: input_boolean.turn_off
        entity_id: input_boolean.cpap_indicator

I don’t think the timer states are on or off. I believe they are active & idle.

But I think I’ve had issues with the correct state showing (idle) when the timer should be done.

Can you not then use ‘idle’ in the wait_template? While the timer is running it should then be ‘active’, allowing you to use the transition to ‘idle’ as the trigger for that last wait_template?

Yeah, I guess I could try it because I don’t have any hard evidence that the timer state is unreliable. just kind of a vague “I think I remember something about that”.

It would still be interesting to know the answer to the original question tho in case it comes up in another scenario.

I did a search and didn’t find anything with an answer.

A workaround would be to use an automation to set an input_boolean with the event, and then switch the boolean back off a second later. Then use the input_boolean turning on in the wait_template.

I thought about doing something like that as well. It would add another automation tho.

But it’s only one more automation so it’s not really a big deal.

Or instead of a timer I could set an input_datetime to four hours later and use that to reset everything. Which, TBH, would probably be more bullet proof since I think timers don’t survive restarts. But, OTOH, I doubt that’s a concern because I’m the only one who ever restarts HA and hopefully I’d be sleeping. :wink:

1 Like

Have you considered using the History Statistics Sensor?

  • It would monitor the the state of cpap_indicator.
  • An automation would monitor the HS Sensor for when it reaches 4 hours.
  • The HS Sensor resets itself every day at midnight.

The only thing I’m not sure is how this approach may be affected by your 12 hour shifts.

I think I would have to figure out how crossing the midnight boundary would affect it. If I go to bed at 10 then I could remove it at 2 but since the sensor gets reset at midnight then it would reach 4 hours until 4 am.

Also, the reset boundary for the cpap machine is noon. So there might be some strangeness trying to get those two things to work in tandem.

I’ll definitely look into it tho. Thanks for the suggestion.

I’ll admit that I didn’t grok the implications of the 12-hour shift cycle. FWIW, you can specify when the HS sensor resets itself. I said ‘midnight’ out of habit but the start option supports a template so it can be set to whatever hour you require. The example in the docs sets the time to 00:00:00.

# Example configuration.yaml entry
sensor:
  - platform: history_stats
    name: Lamp ON today
    entity_id: light.my_lamp
    state: 'on'
    type: time
    start: '{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}'
    end: '{{ now() }}'

I would seriously at least try my suggestion for the final wait_template to see if it works before writing it off and trying other more complicated solutions…

wait_template: "{{ is_state('timer.cpap_transition', 'idle') }}"

1 Like

It’s not a bug, it’s a feature! I got the same advice as you, to use an input_boolean.

1 Like

Actually I didn’t write it off because that is what I currently decided to go with right now and it seems to be working OK in the very limited testing I’ve done in the last couple of hours or so.

So, thanks for the suggestion. :wink:

I might change and go with the input_datetime option tho just to make it a bit more bullet-proof due to timer state retention issues as noted above.

Unfortunately that’s kind of the same conclusion I’ve come to myself.

But the timer going to idle seems to be working for now and I may switch to another solution.

But I guess for now the “solution” to the original question in this thread is there isn’t one. :frowning:

Well, after doing some more testing I realized that using an input_datetime in the script instead of a timer finished won’t make the script any more reliable. I didn’t think about the fact that scripts using a wait_template don’t survive HA restarts either just like timers. So the script would never get to the timer to “idle” or the input_datetime comparison either.

To really make this bullet-proof i will end up having to use an automation to cancel all of the actions that the script turns on (light or switch) at the pre-set input_datetime.

Since I realized I had to also take into account varying sunset/sunrise times and DST changes throughout the year this simple little exercise in writing two easy automations has bloomed into a mildly complex little project. :laughing:

I’m sure I can pare it down some, tho, if i eliminate some redundancy.

sounds like an appdaemon solution to me. I can help you with that if you need to get there. Or even node red. Either way, it’ll take alot with HA’s automation.