Task cancellation confusion

canceling

#1

Newbie in training! :sunglasses: - Looking for best practices and advice on whether the attached is OK (aside from the issue below)

1) Give a description of the problem
I’m trying to brighten the lights on the barn when either my wife or I come home (it gets really dark at night where we live). The problem is, if we come home just after one another then the barn lights are at 100% and never go back down to 10% again. I’m not confident I fully understand the cancellation policy and wonder if this is causing me some issues.

2) What is the expected behavior?
If I come home brighten the lights for 10 minutes, if my wife comes home 5 minutes after me cancel the current 10 minute period and start a new 10 minute wait. My code may be OK as testing this scenario is quite difficult but I’ve seen the lights never dim again.

3) What is happening/not happening?
The lights brighten but I’ve seen instances where they don’t dim again. I’ve also got logic in the piston to dim the lights should we pop home for something and then all leave.

**4) Post a Green Snapshot of the piston![image|45x37]

Thanks for helping, really enjoying this stuff so thank you.

Ian


#2

Do you have anything else (like a motion sensor) also controlling the brightness? If so, you might want to combine the pistons to eliminate conflict. This seems like it should work as you have it.


#3

Thanks for taking a look.

I don’t have any other sensors outside, I’m worried that the deer population will keep triggering the lights so I’ve avoided them for now! I’ll keep an eye on the behavior and report back if I see issues. I guess the other behavior I’d like to explore/experiment with is once we have the 10 minute wait running that somebody else coming hope doesn’t trigger the piston, is that possible?


#4

You can’t stop it from triggering but you can modify how the piston reacts. You could set a boolean variable true/false and look for that or just look if the light is already 100%.


#5

I like the ‘if light at 100%’ idea. I’m not familiar yet with how to use a boolean from one invocation of the piston to the next, is it a global variable that sits outside the piston itself? Like I said - read Newbie!

I wonder, does this code end up as groovy script and if so is it visible anywhere?

Thanks, Ian


#6

I would try to sperate the two presence sensors… (to test it - maybe signal issues etc and get rid of the ELSE)

IF presence sensor 1 changes to PRESENT
AND
Time is between X and Y
with (Never Cancel Task)
Dimmer 1
Set level to 100
Wait 10 minutes
Set level to 10

IF presence sensor 2 changes to PRESENT
AND
Time is between X and Y
with (Never Cancel Task)
Dimmer 1
Set level to 100
Wait 10 minutes
Set level to 10

#7

Any local variable that you define but don’t give a value to will remember its value from one invocation to the next. So if you set it to true, it will still be true the next time the piston runs. You will notice when you review your code, it will indicate what value it currently holds.


#8

Thank you, I’ll give this some thought (for fringe cases) and then give it a go; I’d not thought about doing it this way to be honest. Still lots of learning to do!


#9

Thanks guxdude for clarifying the variable.


#10

Turning on full logging and posting them when it works vs doesn’t work would be helpful. It will tell you what’s happening. I suspect youre correct about the task cancelation though. The event triggers when the condition of one of the presence sensors change, the wait happens. Then when the wait ends, it checks the state of the trigger and sees that one of the sensors are now in a different state and cancels the Set level to 10% task. If this is the case, the simple solution is to change the task cancellation policy to never cancel tasks.

Also, I don’t see how its possible your “else if” will ever trigger. The piston will only fire when one of your presence sensors changes to active… so if it were to ever make it into that else if block, your two presence sensors will never both be inactive. You should pull this out of an else if and make it its own if statement.


#11

Thanks for chiming in.

If I set the task cancellation policy to never cancel what happens if I come home, followed by my wife 5 minutes later. Do the lights:

  1. stay at 100% for 10 minutes and then dim to 10%
  2. stay at 100% for 15 minutes and then dim to 10%
  3. Something else?

Understanding this will be ‘huge’; right now I don’t understand it… (Thanks for the support here).

I suspect you’re right but I need to give this some more thought tonight.


#12

So I finally caught the issue again. I’m uploading the current code for the piston and a trace. Why is the second presence sensor (at 8:44:21) breaking the setting of the scheduled job (which should turn the dimmer back down again)?

I came home at the same time as my wife (same car), her presence sensor was picked up 8:44:11 and mine was picked up at 8:44:21.

3/31/2019, 8:49:10 PM +163ms
+1ms ╔Received event [Barn].time = 1554079751769 with a delay of -1607ms
+122ms ║RunTime Analysis CS > 32ms > PS > 49ms > PE > 42ms > CE
+126ms ║Runtime (39535 bytes) successfully initialized in 49ms (v0.3.10a.20190223) (123ms)
+127ms ║╔Execution stage started
+129ms ║╚Execution stage complete. (2ms)
+131ms ╚Event processed successfully (131ms)
3/31/2019, 8:44:21 PM +925ms
+2ms ╔Received event [His iPhone].presence = present with a delay of 84ms
+89ms ║RunTime Analysis CS > 21ms > PS > 26ms > PE > 41ms > CE
+91ms ║Runtime (39529 bytes) successfully initialized in 26ms (v0.3.10a.20190223) (88ms)
+92ms ║╔Execution stage started
+108ms ║║Comparison (enum) present changes_to (string) present = true (1ms)
+110ms ║║Condition #3 evaluated true (11ms)
+244ms ║║Comparison (time) 74662037 is_between (time) 1554076800000 … (time) 1554031200000 = true (14ms)
+245ms ║║Time restriction check passed
+247ms ║║Condition #13 evaluated true (136ms)
+253ms ║║Comparison (boolean) true is (boolean) false = false (2ms)
+255ms ║║Cancelling condition #14’s schedules…
+257ms ║║Condition #14 evaluated false (8ms)
+258ms ║║Cancelling condition #1’s schedules…
+259ms ║║Condition group #1 evaluated false (state changed) (161ms)
+262ms ║╚Execution stage complete. (170ms)
+264ms ╚Event processed successfully (263ms)
3/31/2019, 8:44:11 PM +459ms
+2ms ╔Received event [Her iPhone].presence = present with a delay of 82ms
+97ms ║RunTime Analysis CS > 20ms > PS > 34ms > PE > 43ms > CE
+100ms ║Runtime (39551 bytes) successfully initialized in 34ms (v0.3.10a.20190223) (97ms)
+101ms ║╔Execution stage started
+117ms ║║Comparison (enum) present changes_to (string) present = true (1ms)
+119ms ║║Cancelling condition #3’s schedules…
+120ms ║║Condition #3 evaluated true (13ms)
+166ms ║║Comparison (time) 74651580 is_between (time) 1554076800000 … (time) 1554031200000 = true (14ms)
+168ms ║║Time restriction check passed
+170ms ║║Cancelling condition #13’s schedules…
+171ms ║║Condition #13 evaluated true (50ms)
+177ms ║║Comparison (boolean) false is (boolean) false = true (2ms)
+179ms ║║Condition #14 evaluated true (6ms)
+180ms ║║Cancelling condition #1’s schedules…
+181ms ║║Condition group #1 evaluated true (state changed) (74ms)
+184ms ║║Cancelling statement #4’s schedules…
+294ms ║║Executed physical command [Outside].setLevel([100]) (102ms)
+295ms ║║Executed [Outside].setLevel (105ms)
+303ms ║║Executed virtual command [Outside].setVariable (4ms)
+308ms ║║Executed virtual command [Outside].wait (0ms)
+309ms ║║Requesting a wake up for Sun, Mar 31 2019 @ 8:49:11 PM EDT (in 300.0s)
+315ms ║╚Execution stage complete. (214ms)
+317ms ║Setting up scheduled job for Sun, Mar 31 2019 @ 8:49:11 PM EDT (in 299.994s)
+326ms ╚Event processed successfully (326ms)

When this works properly I see the dimmer go down like this:

+1ms ╔Received event [Barn].time = 1553684192618 with a delay of -1418ms
+166ms ║RunTime Analysis CS > 70ms > PS > 54ms > PE > 42ms > CE
+169ms ║Runtime (39877 bytes) successfully initialized in 54ms (v0.3.10a.20190223) (167ms)
+170ms ║╔Execution stage started
+237ms ║║Executed physical command [Outside].setLevel([10]) (48ms)
+238ms ║║Executed [Outside].setLevel (51ms)
+241ms ║╚Execution stage complete. (71ms)
+243ms ╚Event processed successfully (242ms)

#13

Any thoughts anyone?


#14

The “WITH” at line 30 should have Task Cancellation Policy set to “Never”.
This means that once that block begins, the conditions above will not break it.

In your case, the possible negative side effects would be if your Wife ever came home 4 minutes after you… She would only see the last minute before the light turned back to 10%.


#15

Thank you, I really appreciate your help. I now have an ‘N’ next to the ‘with’ so hopefully that’s correct. Is there another way to program this so we avoid the last minute scenario?


#16

I often “cheat” a bit, and let a different device be in charge of the “Turn off”.

For example:

IF Motion on porch stays inactive for 5 minutes
    Then set lights to 10%
END IF

#17

In addition to what @WCmore recommended (using TCP), you might also want to set the Task Execution Policy (TEP) on that WITH block also. That prevents the tasks from executing again if the conditions do not change — in your case, the conditions are true when the first person arrives, and are still true whent the second person arrives … so with TEP enabled, the tasks do not execute again.


#18

I thought of that @elf, but won’t {lightsAt100} = true mean that the second evaluation would be false?


#19

True … I was just throwing this out as general info on preventing a re-execute of tasks when conditions do not change … guess I should be more clearer, LOL.


#20

Soooo may ways to skin a cat here, LOL