New to WebCore: how to get motion active AND have button push override sensor settings?


#1

1) Give a description of the problem
Very new to webcore, thought I had it all figured out, but I must be missing something. I have THESE sensor switches and everything working great in SmartThings on the IDE. Discovered Webcore and got excited about the possibilities, but can’t get it to work right. Everything installed perfectly as per the instructions. I’m trying to enable these motion switches to work only during the day (6am-11pm), motion makes them turn on for 60 seconds, AND I want to sometimes be able to push button ‘1’ which would then OVERRIDE the sensor and make light stay on for 15 minutes.

2) What is the expected behavior?
I am hoping to have the light stay on for 15 minutes ONLY when the button is pushed AND have my motion sensor piston working during all other instances (when detecting motion)

3) What is happening/not happening?

  1. Motion triggers switch to come on – no problem.
  2. When I push the button ‘1’, the light doesn’t stay on for 15 minutes as it senses no motion, so shuts off.

4) Post a Green Snapshot of the piston![

)

5) Attach any logs (From ST IDE and by turning logging level to Full)
( 2019-04-17, 7:26:51 AM +820ms
+1ms ╔Received event [Home].test = 1555511211820 with a delay of 1ms
+52ms ║RunTime Analysis CS > 13ms > PS > 19ms > PE > 19ms > CE
+55ms ║Runtime (36612 bytes) successfully initialized in 19ms (v0.3.10a.20190223) (52ms)
+56ms ║╔Execution stage started
+74ms ║║Condition #2 evaluated false (9ms)
+75ms ║║Condition group #1 evaluated false (state did not change) (12ms)
+81ms ║╚Execution stage complete. (24ms)
+83ms ╚Event processed successfully (83ms))

REMOVE BELOW AFTER READING


#2

I have not used the GE motion-switch, so I don’t really know what its behavior is, but I will assume that you have it configured to handle the 60 second time on and that it will not turn on autonomously in response to motion. Assuming those things to be true, then the first piston work basically as you state, but I am unsure why you have the “but only” clauses. Also, if it were me, I would remove all time constraints for the ‘turn off’ portion. As it currently stands, if you walk into the room at 9:59 PM, and walk out after 10:00 PM, your light will stay on all night.

But the issue is that there is no interaction between the two pistons, so if you push the button to turn on the light using the second piston, there is nothing to tell the first piston not to turn off the light when motion changes to inactive. You can fix this by using a variable to indicate that the light has been turned on manually. If you keep these as two pistons, you would need it to be a global (boolean) variable that is set to true when you push the button and cleared to false after 15 minutes. If you move everything into a single piston (which I would probably do as things are fairly simple), you can use a local variable. Then the turn-off portion of the first piston needs to check to make sure that the variable is false before turning off the light.


#3

OK, I tried to make a piston to do what the OP wanted, but I cannot figure out how to get the light to turn off after the long timeout caused by the button press if there was motion while the light was on during the button press. It works for the button press as long as there is no motion, and works for the motion as long as there is no button press, but when interaction occurs things don’t work. The problem is that the section after the WAIT (line 52) doesn’t execute when the piston is triggered after the WAIT if there was an intermediate trigger from motion. I have tried various combinations of cancellation policies and asynch, but nothing seems to work. The log showing button followed by motion is below the piston.

4/17/2019, 12:16:40 PM +279ms
+0ms	╔Received event [Home].time = 1555521401348 with a delay of -1070ms
+341ms	║RunTime Analysis CS > 28ms > PS > 281ms > PE > 33ms > CE
+344ms	║Runtime (41443 bytes) successfully initialized in 281ms (v0.3.10a.20190223) (343ms)
+345ms	║╔Execution stage started
+347ms	║╚Execution stage complete. (1ms)
+348ms	╚Event processed successfully (348ms)
4/17/2019, 12:15:01 PM +4ms
+2ms	╔Received event [Coat Closet Motion].motion = inactive with a delay of 134ms
+276ms	║RunTime Analysis CS > 20ms > PS > 220ms > PE > 36ms > CE
+279ms	║Runtime (41447 bytes) successfully initialized in 220ms (v0.3.10a.20190223) (275ms)
+280ms	║╔Execution stage started
+289ms	║║Comparison (enum) inactive changes = true (1ms)
+291ms	║║Condition #2 evaluated true (4ms)
+292ms	║║Condition group #1 evaluated true (state did not change) (7ms)
+301ms	║║Comparison (enum) inactive is (string) active = false (2ms)
+303ms	║║Cancelling condition #5's schedules...
+304ms	║║Condition #5 evaluated false (9ms)
+305ms	║║Cancelling condition #3's schedules...
+306ms	║║Condition group #3 evaluated false (state changed) (12ms)
+313ms	║║Comparison (boolean) true is_not (boolean) true = false (2ms)
+315ms	║║Cancelling condition #6's schedules...
+316ms	║║Condition #6 evaluated false (8ms)
+318ms	║║Cancelling condition #4's schedules...
+319ms	║║Condition group #4 evaluated false (state changed) (10ms)
+330ms	║║Condition #14 evaluated false (7ms)
+331ms	║║Condition group #13 evaluated false (state did not change) (9ms)
+334ms	║╚Execution stage complete. (55ms)
+336ms	╚Event processed successfully (336ms)
4/17/2019, 12:13:55 PM +44ms
+1ms	╔Received event [Coat Closet Motion].motion = active with a delay of 135ms
+273ms	║RunTime Analysis CS > 21ms > PS > 216ms > PE > 36ms > CE
+276ms	║Runtime (41446 bytes) successfully initialized in 216ms (v0.3.10a.20190223) (273ms)
+277ms	║╔Execution stage started
+287ms	║║Comparison (enum) active changes = true (1ms)
+289ms	║║Cancelling condition #2's schedules...
+290ms	║║Condition #2 evaluated true (6ms)
+291ms	║║Cancelling condition #1's schedules...
+292ms	║║Condition group #1 evaluated true (state changed) (9ms)
+301ms	║║Comparison (enum) active is (string) active = true (2ms)
+304ms	║║Cancelling condition #5's schedules...
+305ms	║║Condition #5 evaluated true (10ms)
+306ms	║║Cancelling condition #3's schedules...
+307ms	║║Condition group #3 evaluated true (state changed) (12ms)
+326ms	║║Comparison (time) 44035355 is_between (time) 21600000 .. (time) 79200000 = true (12ms)
+328ms	║║Time restriction check passed
+330ms	║║Condition #10 evaluated true (19ms)
+332ms	║║Condition group #9 evaluated true (state did not change) (22ms)
+335ms	║║Cancelling statement #11's schedules...
+345ms	║║Skipped execution of physical command [Coat Closet].on([]) because it would make no change to the device. (4ms)
+346ms	║║Executed [Coat Closet].on (7ms)
+359ms	║║Cancelling condition #14's schedules...
+360ms	║║Condition #14 evaluated false (9ms)
+362ms	║║Cancelling condition #13's schedules...
+363ms	║║Condition group #13 evaluated false (state changed) (11ms)
+367ms	║╚Execution stage complete. (91ms)
+368ms	╚Event processed successfully (369ms)
4/17/2019, 12:13:40 PM +921ms
+1ms	╔Received event [Test Button].button = pushed with a delay of 71ms
+354ms	║RunTime Analysis CS > 19ms > PS > 296ms > PE > 38ms > CE
+357ms	║Runtime (41442 bytes) successfully initialized in 296ms (v0.3.10a.20190223) (354ms)
+358ms	║╔Execution stage started
+371ms	║║Cancelling condition #2's schedules...
+373ms	║║Condition #2 evaluated false (8ms)
+374ms	║║Cancelling condition #1's schedules...
+375ms	║║Condition group #1 evaluated false (state changed) (11ms)
+383ms	║║Comparison (enum) pushed gets (string) pushed = true (1ms)
+385ms	║║Cancelling condition #14's schedules...
+386ms	║║Condition #14 evaluated true (7ms)
+387ms	║║Cancelling condition #13's schedules...
+388ms	║║Condition group #13 evaluated true (state changed) (10ms)
+391ms	║║Cancelling statement #15's schedules...
+408ms	║║Executed physical command [Coat Closet].on() (13ms)
+409ms	║║Executed [Coat Closet].on (15ms)
+413ms	║║Cancelling statement #17's schedules...
+420ms	║║Executed virtual command setVariable (3ms)
+425ms	║║Executed virtual command wait (0ms)
+426ms	║║Requesting a wake up for Wed, Apr 17 2019 @ 12:16:41 PM CDT (in 180.0s)
+433ms	║╚Execution stage complete. (75ms)
+435ms	║Setting up scheduled job for Wed, Apr 17 2019 @ 12:16:41 PM CDT (in 179.993s)
+445ms	╚Event processed successfully (444ms)

#4

Another try - same result.
When the piston kicks off again after the wait, nothing is done. It doesn’t continue on immediately after the wait and it doesn’t execute the piston again from the top. I set statement 26 to not cancel (which as happening when motion was detected after button press) so it should be evaluated one way or another when the piston runs, correct? It is outside of any trigger conditions. The log file is just when the piston executes after the wait timer expires. Nothing is evaluated at all which is what is really confusing me.

4/17/2019, 2:08:23 PM +154ms
+0ms ╔Received event [Home].time = 1555528104893 with a delay of -1740ms
+346ms ║RunTime Analysis CS > 43ms > PS > 272ms > PE > 31ms > CE
+349ms ║Runtime (43006 bytes) successfully initialized in 272ms (v0.3.10a.20190223) (347ms)
+350ms ║╔Execution stage started
+351ms ║╚Execution stage complete. (2ms)
+353ms ╚Event processed successfully (352ms)

#5

I really appreciate you taking the time to do this. I’ll admit what you speak of is 50% Greek to me, but I’m trying my best to follow you. Let me know if you can figure this out (if you have time).

Otherwise, I see no option then to just use motion sensor working and have a wait time of 15 minutes (and manually turn off if we leave before that). If I HAVE to go that way, can you explain why the wait time is not working for me? Here is the piston I edited:

I’m finding it’s ignoring this wait time and shutting off when there’s no motion. What am I missing?


#6

You have two triggers - one for sensor going active and one for the sensor going inactive. The wait schedules a time 15 minutes in the future to run the piston again but when the motion sensor changes to inactive, it starts again anyway, and turns off the light.


#7

One more try - Still not sure why my previous attempts don’t work…
This one seems to do exactly what you said you were trying to do! Yaaa! Success!

This piston just reacts to a button press. It will turn on the light and keep it on for 3 minutes (you can change to any time you want but for testing wanted to make it short) then turn it off no matter what. If you press the button again, it will restart the timer.

This piston handles the motion sensor. It only turns the light on if motion changes to active while the light is off and uses a local variable to keep track of whether or not the light was turned on by motion. If the light was not turned on by motion, then this piston will not turn off the light. Note that it also has a trigger that responds to a button press which sets a variable to let this piston know not to turn off the light when motion goes inactive.

This was an interesting project which helped me become a better WebCore programmer. I still need to figure out why my first to attempts didn’t work. Need to better understand what happens when a piston is relaunched after a wait timer expires.


#8

It was bothering me that I didn’t understand why my piston 2abx (several posts above) didn’t work, so I kept playing with it this morning and I figured out how to make it work. I can’t say I completely understand why 2abx didn’t work, but my theory is that the ‘with’ statement at line 56 was not yet scheduled when the wait started, so when the motion sensor kicked off the piston again, it couldn’t be “not cancelled” because it hadn’t been scheduled. If made the With statement that included the Wait be never canceled, then it worked!

The piston below seems to work is a cleaned up and fixed version of 2abx. I think it is more elegant than the two piston solution above. I moved everything that I want to happen in response to the button press within a single with statement and set it to never cancel.

Thanks for posing an interesting problem!