Trying to trigger 'wait' after sensor is active, but inactivity cancels the timer


#1

1) Give a description of the problem
I am putting together a piston that I want to start a wait after a sensor goes active (detects motion) but after it goes inactive the timer stops. I’ll probably throw in some more logic as I build out to decrease false-postives, but would like to get the ‘wait’ to work properly first. :slight_smile:

2) What is the expected behaviour?
That after the conditions are met (contact closed AND motion detected) the wait timer begins

3) What is happening/not happening?
After the sensor reports inactivity, the wait timer is cancelled

4) Post a Green Snapshot of the piston!

**

5) Attach logs after turning logging level to Full
6/1/2021, 12:09:48 PM +411ms
+2ms ╔Received event [Washing Machine].acceleration = inactive with a delay of 83ms
+47ms ║RunTime Analysis CS > 22ms > PS > 6ms > PE > 18ms > CE
+49ms ║Runtime (40429 bytes) successfully initialized in 6ms (v0.3.113.20210203) (46ms)
+50ms ║╔Execution stage started
+57ms ║║Comparison (enum) inactive changes_to (string) active = false (0ms)
+59ms ║║Cancelling condition #2’s schedules…
+60ms ║║Condition #2 evaluated false (5ms)
+61ms ║║Cancelling condition #1’s schedules…
+62ms ║║Condition group #1 evaluated false (state changed) (8ms)
+64ms ║╚Execution stage complete. (14ms)
+73ms ╚Event processed successfully (73ms)
6/1/2021, 12:09:22 PM +140ms
+1ms ╔Received event [Washing Machine].acceleration = active with a delay of 60ms
+39ms ║RunTime Analysis CS > 18ms > PS > 5ms > PE > 16ms > CE
+42ms ║Runtime (40434 bytes) successfully initialized in 5ms (v0.3.113.20210203) (40ms)
+43ms ║╔Execution stage started
+50ms ║║Comparison (enum) active changes_to (string) active = true (1ms)
+52ms ║║Cancelling condition #2’s schedules…
+52ms ║║Condition #2 evaluated true (5ms)
+61ms ║║Comparison (enum) closed is (string) closed = true (2ms)
+62ms ║║Condition #3 evaluated true (9ms)
+63ms ║║Cancelling condition #1’s schedules…
+64ms ║║Condition group #1 evaluated true (state changed) (17ms)
+66ms ║║Cancelling statement #4’s schedules…
+70ms ║║Executed virtual command setVariable (1ms)
+73ms ║║Cancelling statement #6’s schedules…
+76ms ║║Executed virtual command wait (1ms)
+77ms ║║Requesting a wake up for Tue, Jun 1 2021 @ 1:09:22 PM EDT (in 3600.0s)
+81ms ║╚Execution stage complete. (39ms)
+83ms ║Setting up scheduled job for Tue, Jun 1 2021 @ 1:09:22 PM EDT (in 3599s)
+90ms ╚Event processed successfully (90ms)


#2

I suspect your acceleration sensor is going inactive after it went active, which triggers your piston again. That cancels your 60 minute wait. Try putting never cancel on the wait and see if that helps.


#3

Your piston will be executed automatically whenever an acceleration event is generated for your contact sensor. When you get the active event it will start a one hour wait which it does by setting a timer for sixty minutes time and then exiting. This is called a scheduled task in webCoRe terminology. If no other events happen during those sixty minutes a new instance of the piston will be started up and it will realise it is waking up after a wait and so fast forward to the end of it and continue with anything else in the piston.

However your piston does get an event during the wait. In fact it got the inactive one 16 seconds into it. As your piston is not running a new instance starts up and it sees the first condition is no longer true. So what does it do about the timer that started up when it was true? Is it still needed? webCoRE has something called the Task Cancellation Policy (TCP) that will, by default, cancel any scheduled tasks that were set up when the condition returned a different result (in this case it is now false not true, but it works both ways).

This may seem odd but think of something like a cellar light that is controlled by a motion sensor and turns off a minute after motion stops. If you go into the cellar, realise you forgot something and come back 55 seconds later, you don’t want that light to still be turning off in five seconds time.

If you need the timer to keep going you need to change the TCP to ‘Never Cancel Scheduled Tasks’. You do that by editing either the action containing the wait (the with statement you’ll see when in edit mode) or the wait task itself. It’ll be hidden in the settings cog. That will make sure the piston continues after the wait regardless.

That isn’t actually going to help your piston though, because there is another ‘gotcha’ here. The way the is not active condition is evaluated is by first checking what event the piston is running. In your case the piston will be running an acceleration event saying it is active (it will still be considered as doing that even after sleeping for an hour) so the piston considers the current state must be active. It does not check what it actually now is. So that condition will always be true.

That one is a little stranger but does make sense if you think about it hard enough. Unfortunately it also makes sense for it not to work like that.

So you have to reconsider the logic a bit.


#4

Thanks @Pantheon!
The TCP has tripped me up before, albeit a long time ago, and I had completely forgot about that
:man_facepalming: Adjusting that seems to be the ticket!

And thanks @orangebucket for the advice and prompting me to re-think the logic here. Sometimes the simplest things are unexpectedly more challenging to put into practice once you consider the way things work. I think leveraging TCP should do it, and it looks promising so far.

I think this has me on the right track. I’ll put those suggestions into practice, and mess around with it some more. I’ll check back tomorrow after I have some time to experiment and report my success! Thank you both!!!