Can't figure out why this piston is announcing twice


#1

1) Give a description of the problem

My Door Check piston is announcing twice.

2) What is the expected behaviour?

When I tell Alexa “Door Check” (or if I hit TEST), this piston should run, check all door contacts, set the LEDs on my Homeseer 200+, and announce if any doors are open.

3) What is happening/not happening?

If I press Test, it works perfectly. If I say “Alexa, Door Check”, she makes the announcement twice. It’s almost as if the piston is activated by the switch turning on AND off.

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

5) Attach logs after turning logging level to Full

Logging set to Minimum

This shows that the switch turning On and Off is executing the piston!

5/17/2021, 11:46:44 PM +120ms
+1ms ╔Received event [Door Check].switch = off with a delay of 628ms, canQueue: false, calledMyself: true
+5ms ║╔Execution stage started
+125ms ║║ All Doors are CLOSED at 11:46 P.M. on Mon, 5/17/2021
+168ms ║╚Execution stage complete. (164ms)
+171ms ╚Event processed successfully (169ms)

5/17/2021, 11:46:43 PM +420ms
+4ms ╔Received event [Door Check].switch = on with a delay of 84ms, canQueue: true, calledMyself: false
+28ms ║╔Execution stage started
+620ms ║║ All Doors are CLOSED at 11:46 P.M. on Mon, 5/17/2021
+644ms ║╚Execution stage complete. (616ms)
+647ms ╚Event processed successfully (644ms)

Logging set to Full

5/17/2021, 11:39:14 PM +522ms
+1ms ╔Received event [Door Check].switch = off with a delay of 651ms, canQueue: false, calledMyself: true
+8ms ║RunTime initialize > 7 LockT > 0ms > rtDT > 5ms > pistonT > 2ms (first state access 2 2 5)
+13ms ║Runtime (20552 bytes) successfully initialized in 5ms (v0.3.113.20210510_HE)
+14ms ║╔Execution stage started
+20ms ║║Comparison (enum) off changes_to (string) on = false (0ms)
+22ms ║║Cancelling condition #2’s schedules…
+23ms ║║Condition #2 evaluated false (5ms)
+24ms ║║Cancelling condition #1’s schedules…
+25ms ║║Condition group #1 evaluated false (state changed) (7ms)
+33ms ║║Comparison (enum) closed is (string) open = false (1ms)
+34ms ║║Comparison (enum) closed is (string) open = false (1ms)
+36ms ║║Comparison (enum) closed is (string) open = false (0ms)
+37ms ║║Comparison (enum) closed is (string) open = false (1ms)
+39ms ║║Comparison (enum) closed is (string) open = false (0ms)
+41ms ║║Comparison (enum) closed is (string) open = false (1ms)
+42ms ║║Comparison (enum) closed is (string) open = false (0ms)
+45ms ║║Condition #8 evaluated false (18ms)
+46ms ║║Condition group #7 evaluated false (state did not change) (20ms)
+48ms ║║Cancelling statement #52’s schedules…
+58ms ║║Calculating (dynamic)null == (integer)1 >> (boolean)false
+68ms ║║Calculating (string) All Doors are CLOSED at + (string)11:39 P.M. >> (string) All Doors are CLOSED at 11:39 P.M.
+69ms ║║Calculating (string) All Doors are CLOSED at 11:39 P.M. + (string) on >> (string) All Doors are CLOSED at 11:39 P.M. on
+70ms ║║Calculating (string) All Doors are CLOSED at 11:39 P.M. on + (string)Mon, 5/17/2021 >> (string) All Doors are CLOSED at 11:39 P.M. on Mon, 5/17/2021
+72ms ║║Calculating (string) All Doors are CLOSED at 11:39 P.M. on Mon, 5/17/2021 + (string) >> (string) All Doors are CLOSED at 11:39 P.M. on Mon, 5/17/2021
+74ms ║║Calculating (string) The + (string) >> (string) The
+76ms ║║Calculating (string) The + (string) >> (string) The
+77ms ║║Calculating (string) The + (string) >> (string) The
+78ms ║║Calculating (string) The + (string) >> (string) The
+80ms ║║Calculating (string) The + (string)are >> (string) The are
+81ms ║║Calculating (string) The are + (string) >> (string) The are
+82ms ║║Calculating (string) The are + (string) OPEN >> (string) The are OPEN
+83ms ║║Calculating (string) The are OPEN + (string) at >> (string) The are OPEN at
+85ms ║║Calculating (string) The are OPEN at + (string)11:39 P.M. >> (string) The are OPEN at 11:39 P.M.
+86ms ║║Calculating (string) The are OPEN at 11:39 P.M. + (string) on >> (string) The are OPEN at 11:39 P.M. on
+88ms ║║Calculating (string) The are OPEN at 11:39 P.M. on + (string)Mon, 5/17/2021 >> (string) The are OPEN at 11:39 P.M. on Mon, 5/17/2021
+89ms ║║Calculating (string) The are OPEN at 11:39 P.M. on Mon, 5/17/2021 + (string) >> (string) The are OPEN at 11:39 P.M. on Mon, 5/17/2021
+90ms ║║Calculating (integer)0 == (integer)0 >> (boolean)true
+94ms ║║Executed virtual command setVariable (2ms)
+109ms ║║Executed virtual command setState (0ms)
+112ms ║║ All Doors are CLOSED at 11:39 P.M. on Mon, 5/17/2021
+114ms ║║Executed virtual command log (2ms)
+229ms ║║Calculating (dynamic)null == (integer)1 >> (boolean)false
+232ms ║║Calculating (string)The + (string) >> (string)The
+233ms ║║Calculating (string)The + (string) >> (string)The
+234ms ║║Calculating (string)The + (string)are >> (string)The are
+235ms ║║Calculating (string)The are + (string) open. >> (string)The are open.
+236ms ║║Calculating (integer)0 == (integer)0 >> (boolean)true
+289ms ║║Executed virtual command setVariable (50ms)
+295ms ║║Executed virtual command setVariable (2ms)
+301ms ║║Executed virtual command setVariable (1ms)


#2

I did not got through your entire log. Any time the state of a trigger changes, “On” to “Off” or “Off” to “On”, it will fire the piston. So when your Switch 17 (your trigger) changes to “on”, the piston will run top to bottom. When your Switch 17 (trigger) changes to “off”, your piston will run top to bottom. That is normal.

At line 41, when you set Switch 17 to “Off”, that triggers your piston to run top to bottom again. This may cause your code on lines 43-47 to never be executed. This logic can also sometimes create endless loops and semaphore delays. Generally, I try to avoid resetting my triggers within the same piston. But if I do, I generally reset my trigger(s) with the very last instruction in the piston.


#3

That doesn’t make sense, because the trigger specifically states “Changes to On”. You’re telling me that, despite this, it will trigger simply as “Changes” regardless? Not only that, but I have plenty of other pistons that turn off the virtual switch early. In fact, this piston (which was going to be replaced by the piston I’m currently having problems with) is virtually identical, and doesn’t announce twice.

(And I don’t know if this is related, but I just upgraded WC as well.)


#5

The If structure is different on the first piston image and the second one. The second one looks like everything is enclosed in one big IF.


#6

It was one big If to begin with, and still repeated. I just tested it again.

5/18/2021, 8:06:30 AM +738ms
+1ms ╔Received event [Door Check].switch = off with a delay of 1096ms, canQueue: false, calledMyself: true
+4ms ║╔Execution stage started
+62ms ║║ The Back Door is OPEN at 8:06 A.M. on Tue, 5/18/2021
+99ms ║╚Execution stage complete. (95ms)
+102ms ╚Event processed successfully (101ms)

5/18/2021, 8:06:29 AM +427ms
+4ms ╔Received event [Door Check].switch = on with a delay of 150ms, canQueue: true, calledMyself: false
+179ms ║╔Execution stage started
+1229ms ║║ The Back Door is OPEN at 8:06 A.M. on Tue, 5/18/2021
+1258ms ║╚Execution stage complete. (1079ms)
+1260ms ╚Event processed successfully (1257ms)

Getting rid of the When True doesn’t help, either.

5/18/2021, 8:12:41 AM +817ms
+1ms ╔Received event [Door Check].switch = off with a delay of 485ms, canQueue: false, calledMyself: true
+5ms ║╔Execution stage started
+428ms ║║ The Back Door is OPEN at 8:12 A.M. on Tue, 5/18/2021
+490ms ║╚Execution stage complete. (485ms)
+492ms ╚Event processed successfully (492ms)

5/18/2021, 8:12:40 AM +501ms
+3ms ╔Received event [Door Check].switch = on with a delay of 142ms, canQueue: true, calledMyself: false
+348ms ║╔Execution stage started
+1244ms ║║ The Back Door is OPEN at 8:12 A.M. on Tue, 5/18/2021
+1267ms ║╚Execution stage complete. (920ms)
+1269ms ╚Event processed successfully (1267ms)


#7

I’d suggest creating a bare bones piston for testing so anyone interested in debugging can look at something small and simple.


#8

Your log above indicates exactly what I was suggesting above. At 8:12:40 it received an on event and executed. At 8:12:41 the off event was received and it executed.


#9

Yes, but the Off event isn’t a trigger, yet it’s being treated as . I’ve reduced it to the two main parts, and it’s still triggering twice. Where do I find the earlier version of Webcore to downgrade to? I want to see if that makes a difference.

Okay…I removed the Turn Door Check Switch Off command. When I manually turn the Door Check switch Off and On in my Alexa app, it runs the app both times. The “Changes to On” command is literally being triggered as an “Changes” command.

5/18/2021, 8:26:07 AM +654ms
+4ms ╔Received event [Door Check].switch = off with a delay of 101ms, canQueue: true, calledMyself: false
+11ms ║╔Execution stage started
+47ms ║║ The Back Door is OPEN at 8:26 A.M. on Tue, 5/18/2021
+68ms ║╚Execution stage complete. (56ms)
+69ms ╚Event processed successfully (67ms)

5/18/2021, 8:25:57 AM +802ms
+3ms ╔Received event [Door Check].switch = on with a delay of 109ms, canQueue: true, calledMyself: false
+11ms ║╔Execution stage started
+375ms ║║ The Back Door is OPEN at 8:25 A.M. on Tue, 5/18/2021
+397ms ║╚Execution stage complete. (386ms)
+398ms ╚Event processed successfully (396ms)


#10

So to know if something changes, you have to get all event values for that trigger, so you can compare if it changed or not. So using changes as a trigger says you subsribe to all values of that trigger (otherwise you would never know if it changes).

If you want to try to only subscribe to event.value (say on), you would want to use (on HE) receives or gets as your trigger. If you only attempt a single attribute value, HE will attempt to only subscribe to

event.value (such as event.on).


#11

I didn’t know there was such a thing on the HE version, very interesting and definitely going to try it out sometime when the need arises!


#12

Me either! That will be useful.


#13

I’ve been using virtual switches as triggers for a LONG time, in ST and HE…I’ve NEVER had this problem. This is the first time I’ve had a “Changes to On” command be treated as a “Changes” command.

This piston does the same thing with lights. It runs perfectly.

5/18/2021, 8:49:43 AM +361ms
+671ms ║ 2 Lights are on: Fan Computer Light and Lamp at 8:49 A.M. on Tue, 5/18/2021

5/18/2021, 8:37:45 AM +311ms
+675ms ║ 1 Light is on: Lamp at 8:37 A.M. on Tue, 5/18/2021

But when I separate everything, the “Changes to On” command is suddenly treated as a “Changes” command.


#14

Yes, because the rest of the statements are outside of the ‘changes to on’. They’ll get evaluated every time the switch changes :slight_smile:

Edit, you can even call that piston from another piston and it will still execute the statements that are outside of the first IF.


#15

Closing and reopening the browser appears to have solved the problem…for now.

5/18/2021, 10:23:49 AM +764ms
+1ms ╔Received event [Door Check].switch = off with a delay of 421ms, canQueue: false, calledMyself: true
+4ms ║╔Execution stage started
+12ms ║╚Execution stage complete. (7ms)
+14ms ╚Event processed successfully (14ms)

5/18/2021, 10:23:48 AM +781ms
+3ms ╔Received event [Door Check].switch = on with a delay of 112ms, canQueue: true, calledMyself: false
+95ms ║╔Execution stage started
+911ms ║║ The Back Door is OPEN at 10:23 A.M. on Tue, 5/18/2021
+931ms ║╚Execution stage complete. (836ms)
+934ms ╚Event processed successfully (931ms)

Yes, I’ve been rewriting some of my pistons if If/Then Boolean statements so they’ll do exactly that. I was in the process of doing that with this piston when I encountered this error.


#16

That isn’t what is happening though. Pistons are simply event handlers. Something happens, they run from the top, and it is down to you to write the code work out why the piston has run and whether you want it to do anything. webCoRE helps you out by looking through the code to see what events are worth subscribing to, to add to all the other events that might happen like the Test button being pressed, execution by other pistons, execution by URL, recovery events and so on. If it comes across any conditions classed as ‘triggers’ it decides those must be particularly important to you so it defaults to just using the device attributes (or times) mentioned in those. That’s the beginning and end of what the special significance of a trigger is. As soon as the piston runs, triggers and conditions are comparisons to be evaluated.

A Door Check switch changes to on trigger condition is something that is evaluated by the piston at run time. It is asking ‘am I running because the Door Check switch attribute has just changed to on, or is it for some other reason’. Roughly speaking it does the following:

  • Looks at the event being processed by the piston. If it isn’t for the switch attribute of the Door Check device then it returns false.
  • Looks to see what the value in the event is. If it isn’t on then it returns false.
  • Checks to see what the value was last time the trigger condition was evaluated. If it wasn’t off then then it returns false.
  • If all the above is true then it returns true.

If you only want something to happen when the switch has changed to on, then you have to code that explicitly.


#17

Look at it this way: How does a piston know if it changed to on or off unless every time it changes, it checks which direction it went. It is a logical test so when the value changes, it has to run the piston to look at the logic statement to determine what to do. That is what is happening and has always been the behavior. The piston will ‘wake up’ for every change. Then, the logic in the piston will determine what will happen if it change to on vs off vs anything else. You have to consider what will happen in your piston if you just execute it as that is what will happen when your ‘changes to on’ is ‘false’.

Hope this helps.


#18