Piston Trigger by one sensor, Wait and then check Another Sensor


#1

1) Give a description of the problem
Hi all. This is my first piston and I read discussions about the Wait and TCP. So I have been trying to understand why my piston does not execute as I expect it to. I have modified the TCP for the if statement. If that is not the right approach, where and why the TCP needs to change? Per logs, the wake up command seems to be scheduled but then when the piston resumes, I do not see the command to turn off the switch. The bathroom sensor goes from active to inactive within 30 seconds. Is this related to my issue?

Here is what I am trying to achieve:

When the laundry sensor is active and there is no motion in the bathroom (different sensor) 30 seconds later, I want to turn off ceiling lights.

Any insights would be appreciated.
Thank you.

2) What is the expected behaviour?
Ceiling lights turn off
3) What is happening/not happening?
Ceiling lights do not turn off
4) Post a Green Snapshot of the pistonimage


(UPLOAD YOUR IMAGE HERE)

5) Attach logs after turning logging level to Full
12/28/2020, 1:27:06 PM +45ms
+0ms ╔Received event [Home].time = 1609180027385 with a delay of -1341ms
+51ms ║RunTime Analysis CS > 16ms > PS > 4ms > PE > 31ms > CE
+53ms ║Runtime (37206 bytes) successfully initialized in 4ms (v0.3.110.20191009) (52ms)
+54ms ║╔Execution stage started
+55ms ║╚Execution stage complete. (0ms)
+56ms ╚Event processed successfully (56ms)
12/28/2020, 1:26:48 PM +697ms
+1ms ╔Received event [Motion Sensor Laundry].motion = inactive with a delay of 35ms
+42ms ║RunTime Analysis CS > 13ms > PS > 5ms > PE > 24ms > CE
+44ms ║Runtime (37210 bytes) successfully initialized in 5ms (v0.3.110.20191009) (42ms)
+45ms ║╔Execution stage started
+52ms ║║Comparison (enum) inactive changes_to (string) active = false (0ms)
+53ms ║║Cancelling condition #2’s schedules…
+54ms ║║Condition #2 evaluated false (5ms)
+55ms ║║Cancelling condition #1’s schedules…
+56ms ║║Condition group #1 evaluated false (state changed) (7ms)
+58ms ║╚Execution stage complete. (13ms)
+59ms ╚Event processed successfully (59ms)
12/28/2020, 1:26:37 PM +318ms
+1ms ╔Received event [Motion Sensor Laundry].motion = active with a delay of 42ms
+46ms ║RunTime Analysis CS > 18ms > PS > 4ms > PE > 24ms > CE
+48ms ║Runtime (37215 bytes) successfully initialized in 4ms (v0.3.110.20191009) (47ms)
+49ms ║╔Execution stage started
+56ms ║║Comparison (enum) active changes_to (string) active = true (1ms)
+57ms ║║Cancelling condition #2’s schedules…
+58ms ║║Condition #2 evaluated true (5ms)
+59ms ║║Cancelling condition #1’s schedules…
+60ms ║║Condition group #1 evaluated true (state changed) (7ms)
+62ms ║║Cancelling statement #3’s schedules…
+65ms ║║Executed virtual command wait (1ms)
+66ms ║║Requesting a wake up for Mon, Dec 28 2020 @ 1:27:07 PM EST (in 30.0s)
+70ms ║╚Execution stage complete. (21ms)
+71ms ║Setting up scheduled job for Mon, Dec 28 2020 @ 1:27:07 PM EST (in 29.996s)
+81ms ╚Event processed successfully (81ms)
12/28/2020, 1:26:23 PM +853ms
+0ms ╔Received event [Motion Sensor Laundry].motion = inactive with a delay of 38ms
+41ms ║RunTime Analysis CS > 14ms > PS > 3ms > PE > 25ms > CE
+43ms ║Runtime (37210 bytes) successfully initialized in 3ms (v0.3.110.20191009) (42ms)
+44ms ║╔Execution stage started
+50ms ║║Comparison (enum) inactive changes_to (string) active = false (0ms)
+52ms ║║Cancelling condition #2’s schedules…
+53ms ║║Condition #2 evaluated false (4ms)
+54ms ║║Cancelling condition #1’s schedules…
+54ms ║║Condition group #1 evaluated false (state changed) (7ms)
+56ms ║╚Execution stage complete. (12ms)
+57ms ╚Event processed successfully (58ms)
12/28/2020, 1:26:10 PM +762ms
+1ms ╔Received event [Motion Sensor Laundry].motion = active with a delay of 42ms
+48ms ║RunTime Analysis CS > 15ms > PS > 4ms > PE > 29ms > CE
+50ms ║Runtime (37215 bytes) successfully initialized in 4ms (v0.3.110.20191009) (48ms)
+51ms ║╔Execution stage started
+58ms ║║Comparison (enum) active changes_to (string) active = true (1ms)
+59ms ║║Cancelling condition #2’s schedules…
+60ms ║║Condition #2 evaluated true (5ms)
+61ms ║║Cancelling condition #1’s schedules…
+62ms ║║Condition group #1 evaluated true (state changed) (7ms)
+64ms ║║Cancelling statement #3’s schedules…
+66ms ║║Executed virtual command wait (0ms)
+67ms ║║Requesting a wake up for Mon, Dec 28 2020 @ 1:26:40 PM EST (in 30.0s)
+71ms ║╚Execution stage complete. (20ms)
+72ms ║Setting up scheduled job for Mon, Dec 28 2020 @ 1:26:40 PM EST (in 29.996s)
+79ms ╚Event processed successfully (79ms)

REMOVE BELOW AFTER READING
If a solution is found for your question then please mark the post as the solution.


#2

Although it is possible to set the TCP on the ‘if’, it really isn’t clear what on earth it does in that position. The place it needs to go, if required, is on the ‘wait’ task (or tasks), or the action (the ‘with’) that contains that task (or tasks). So do you need it?

Consider your ‘wait 30 seconds’ task. Any ‘wait’ that lasts more than five seconds, or that would otherwise leave less than ten seconds of execute time available at the end of it (there is a twenty second limit), is executed by scheduling a new timed execution of the piston and exiting the current run. When the end of the wait arrives the piston is sent a timer event, wakes up, and then fast forwards to the end of the wait and continues. This is a ‘scheduled task’.

Now what if another event fires the piston during the ‘wait’? It doesn’t matter what event, but an obvious thing that might happen in your case is the laundry room motion sensor going inactive. As there isn’t a running instance of the piston, a new one will execute immediately (as opposed by hitting a semaphore wait). So a new piston will start running immediately.

If the event is NOT the laundry motion sensor changing to active your trigger condition on line 18 will return false. However you already have a scheduled task waiting that was created only because the condition previously returned true (the laundry room motion changed to active). So should that task still be allowed to run. The Task Cancellation Policy says, by default, that any scheduled task should be cancelled if the condition that caused it to be create changes state. So that is what happens. The timer event still wakes up the piston at the end of the wait but it finds nothing to do and so exits again.

If you want that 30 seconds to happen regardless of what happens with the laundry room sensor then you need to change the TCP to ‘Never Cancel Scheduled Tasks’ on the tasks that you don’t want to be cancelled (either on each ‘wait’ task itself, or the ‘with’ action for the tasks).


#3

Thanks Graham for taking time to explain. I changed the TCP for line 20 and 24 and that worked.