Global variable not being set properly in Set Vacation Mode piston


#1

**1) The Global variable that tracks the current mode (@locationMode) is not correctly being reset to “Home” when a house occupant together with their presence sensor (iPhone) returns Home.

**2) The Set Vacation Mode piston incrementally transitions home thermostats to Away Mode and then to Extended Away modes based on the non-presence of all home occupants for a specified amount of time. When all presence sensors show No presence, the piston starts a 4-hour timer and then switches mode to “Away” and adjusts thermostats to save energy. Two global variables are set: one that shows the previous mode (Home), and one that shows the current mode: Away. Another timer is set for 20 hours. At the end of 20 hours, the mode is switched to “Away-Extended Absence” and thermostats are adjusted further to save even more energy. The global variables are updated. If at any time during these waiting periods, a presence sensor is detected to be present, all pending tasks are canceled, the mode is switched back to Home, the thermostats are adjusted for comfort, and the global variables are updated.

**3) The log below shows that at 6:51 am, the piston correctly determines that no one is home; it schedules an execution to run in four hours and then exits (I would have thought it would just pause for four hours, but apparently it sets a time to begin executing the piston, presumably at the very next statement after the Wait statement, and then terminates its current execution). We see at 10:51 that morning, with no one having returned home, the piston indeed picks up execution at the next step by executing a set LocationMode command, setting the two global variables, and then running the routines to adjust all three house thermostats to an energy savings mode. So far so good. At 1:45 in the afternoon, one person returns home, and the piston runs to restore the thermostats to a comfort setting, but we see that in the comparison of @locationMode to “Away” or “Away-Extended Absence” it reveals that @locationMode is still set to Home. Then for some reason, about 1 second later, the piston executes again, initiated by some unknown event (but not another presence sensor). At 3:34 pm, a second person comes home and when the piston runs in response to a second presence sensor change, we see that @locationMode is now set to “Away”, even though the first person has been home for an hour and 35 minutes. Why is @locationMode not correctly reflecting the updated mode?

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

5) Attach logs after turning logging level to Full
11/22/2019, 3:34:39 PM +228ms
+2ms ╔Received event [Matt’s iPhone].presence = present with a delay of 75ms
+318ms ║RunTime Analysis CS > 28ms > PS > 243ms > PE > 46ms > CE
+320ms ║Runtime (49900 bytes) successfully initialized in 243ms (v0.3.10e.20190628) (318ms)
+321ms ║╔Execution stage started
+331ms ║║Comparison (enum) present is (string) not present = false (2ms)
+332ms ║║Cancelling condition #6’s schedules…
+333ms ║║Condition #6 evaluated false (6ms)
+334ms ║║Condition group #5 evaluated false (state did not change) (7ms)
+341ms ║║Comparison (dynamic) Away is (string) Away = true (1ms)
+342ms ║║Cancelling condition #11’s schedules…
+343ms ║║Condition #11 evaluated true (6ms)
+344ms ║║Cancelling condition #10’s schedules…
+345ms ║║Condition group #10 evaluated true (state changed) (8ms)
+346ms ║║Cancelling condition #9’s schedules…
+347ms ║║Condition group #9 evaluated true (state changed) (11ms)
+350ms ║║Cancelling statement #25’s schedules…
+2305ms ║║Executed virtual command executeRoutine (1952ms)
+2542ms ║║Executed virtual command executeRoutine (234ms)
+3102ms ║║Executed virtual command executeRoutine (558ms)
+3112ms ║║Comparison (enum) off is (string) off = true (2ms)
+3113ms ║║Condition #40 evaluated true (8ms)
+3114ms ║║Condition group #29 evaluated true (state did not change) (9ms)
+3116ms ║║Evaluating switch with values [[i:29:null:0, v:[t:datetime, v:1574454882344, d:1, vt:string]]]
+3121ms ║║Invalid ternary operator. Ternary operator’s syntax is ( condition ? trueValue : falseValue ). Please check your syntax and try again.
+3122ms ║║Calculating (error) Variable ‘00’ not found : (error) Variable ‘00’ not found >> (error)
+3127ms ║║Invalid ternary operator. Ternary operator’s syntax is ( condition ? trueValue : falseValue ). Please check your syntax and try again.
+3128ms ║║Calculating (error) Variable ‘05’ not found : (integer) 14 >> (error)
+3132ms ║║Comparison (datetime) 1574454882344 is_inside_of_range (string) … (string) = false (2ms)
+3136ms ║║Invalid ternary operator. Ternary operator’s syntax is ( condition ? trueValue : falseValue ). Please check your syntax and try again.
+3137ms ║║Calculating (integer) 21 : (error) Variable ‘00’ not found >> (integer)
+3141ms ║║Invalid ternary operator. Ternary operator’s syntax is ( condition ? trueValue : falseValue ). Please check your syntax and try again.
+3142ms ║║Calculating (integer) 23 : (integer) 59 >> (integer)
+3146ms ║║Comparison (datetime) 1574454882344 is_inside_of_range (integer) 0 … (integer) 0 = false (2ms)
+3149ms ║╚Execution stage complete. (2828ms)
+3150ms ╚Event processed successfully (3150ms)
11/22/2019, 1:45:38 PM +298ms
+1ms ╔Received event [Home].:6ef6def0f2e8b366d3dc83a1ef0d3eca: = @locationMode with a delay of 72ms
+224ms ║RunTime Analysis CS > 22ms > PS > 148ms > PE > 54ms > CE
+227ms ║Runtime (49923 bytes) successfully initialized in 148ms (v0.3.10e.20190628) (226ms)
+228ms ║╔Execution stage started
+233ms ║╚Execution stage complete. (6ms)
+234ms ╚Event processed successfully (234ms)
11/22/2019, 1:45:37 PM +818ms
+1ms ╔Received event [Barbara’s iPhone].presence = present with a delay of 75ms
+226ms ║RunTime Analysis CS > 25ms > PS > 154ms > PE > 47ms > CE
+229ms ║Runtime (49905 bytes) successfully initialized in 154ms (v0.3.10e.20190628) (226ms)
+230ms ║╔Execution stage started
+242ms ║║Comparison (enum) not present is (string) not present = true (2ms)
+244ms ║║Condition #6 evaluated true (8ms)
+248ms ║║Comparison (enum) present is (string) not present = false (1ms)
+250ms ║║Cancelling condition #7’s schedules…
+250ms ║║Condition #7 evaluated false (6ms)
+251ms ║║Cancelling condition #5’s schedules…
+252ms ║║Condition group #5 evaluated false (state changed) (17ms)
+259ms ║║Comparison (dynamic) Home is (string) Away = false (1ms)
+260ms ║║Condition #11 evaluated false (5ms)
+264ms ║║Comparison (dynamic) Home is (string) Away-Extended Absence = false (1ms)
+266ms ║║Condition #12 evaluated false (5ms)
+267ms ║║Condition group #10 evaluated false (state did not change) (12ms)
+268ms ║║Condition group #9 evaluated false (state did not change) (14ms)
+277ms ║║Comparison (enum) off is (string) off = true (1ms)
+279ms ║║Condition #14 evaluated true (9ms)
+280ms ║║Condition group #13 evaluated true (state did not change) (10ms)
+282ms ║║Cancelling statement #20’s schedules…
+284ms ║║Executed virtual command cancelTasks (0ms)
+354ms ║║Executed virtual command setLocationMode (66ms)
+357ms ║║Executed virtual command setVariable (1ms)
+361ms ║║Executed virtual command setVariable (1ms)
+369ms ║╚Execution stage complete. (140ms)
+371ms ╚Event processed successfully (370ms)
11/22/2019, 10:51:13 AM +89ms
+0ms ╔Received event [Home].time = 1574437874631 with a delay of -1543ms
+252ms ║RunTime Analysis CS > 38ms > PS > 172ms > PE > 42ms > CE
+254ms ║Runtime (49898 bytes) successfully initialized in 172ms (v0.3.10e.20190628) (253ms)
+255ms ║╔Execution stage started
+593ms ║║Executed virtual command setLocationMode (323ms)
+598ms ║║Executed virtual command setVariable (2ms)
+604ms ║║Executed virtual command setVariable (1ms)
+2979ms ║║Executed virtual command executeRoutine (2372ms)
+3678ms ║║Executed virtual command executeRoutine (696ms)
+3957ms ║║Executed virtual command executeRoutine (276ms)
+3960ms ║║Executed virtual command wait (0ms)
+3961ms ║║Requesting a wake up for Sat, Nov 23 2019 @ 6:51:17 AM EST (in 72000.0s)
+3966ms ║╚Execution stage complete. (3711ms)
+3968ms ║Setting up scheduled job for Sat, Nov 23 2019 @ 6:51:17 AM EST (in 71999.995s)
+3978ms ╚Event processed successfully (3978ms)
11/22/2019, 6:51:14 AM +355ms
+1ms ╔Received event [Andrew’s iPhone].presence = not present with a delay of 76ms
+233ms ║RunTime Analysis CS > 34ms > PS > 154ms > PE > 45ms > CE
+236ms ║Runtime (49906 bytes) successfully initialized in 154ms (v0.3.10e.20190628) (233ms)
+237ms ║╔Execution stage started
+249ms ║║Comparison (enum) not present is (string) not present = true (1ms)
+251ms ║║Condition #6 evaluated true (8ms)
+258ms ║║Comparison (enum) not present is (string) not present = true (1ms)
+260ms ║║Condition #7 evaluated true (7ms)
+264ms ║║Comparison (enum) not present is (string) not present = true (1ms)
+266ms ║║Cancelling condition #8’s schedules…
+266ms ║║Condition #8 evaluated true (6ms)
+268ms ║║Cancelling condition #5’s schedules…
+268ms ║║Condition group #5 evaluated true (state changed) (25ms)
+271ms ║║Cancelling statement #41’s schedules…
+274ms ║║Executed virtual command wait (1ms)
+275ms ║║Requesting a wake up for Fri, Nov 22 2019 @ 10:51:14 AM EST (in 14400.0s)
+280ms ║╚Execution stage complete. (43ms)
+281ms ║Setting up scheduled job for Fri, Nov 22 2019 @ 10:51:14 AM EST (in 14399.996s)
+290ms ╚Event processed successfully (289ms)


#2

This is because when someone arrives home, the THEN section (line 31+) is ignored, and the logic jumps right to the ELSE section (line 48+)… In the ELSE section, there is no commands to change @locationMode.


You have five triggers here, and each of them has more than one possibility.

  • Switch 1 (turning on or off)
  • Presence Sensor 1’s presence (changing to anything)
  • Presence Sensor 2’s presence (changing to anything)
  • Presence Sensor 3’s presence (changing to anything)
  • @locationMode (changing to anything)

This means when any of the 15+ events happens, the entire pistons runs top to bottom, and executes anything not blocked by conditions. (I try to avoid more than one lightning bolt per piston)

In this particular case:
IF X happens, then change @locationMode
… causes a double trigger because you have a lightning bolt next to that global (lines 51 & 53). This means, whenever the global changes changes, the piston starts all over from the top.


#3

That’s true, but at 10:51, when the piston wakes up after waiting 4 hours, it should have resumed processing from line 30 (the line right after the Wait 4 hours command). It is there where location mode is set to Away and in line 32 @locationMode is set to $locationMode (which is now Away). Then when 1:45 rolls around and the Then in line 28 is ignored and execution passes to the else in line 45, @locationMode should be Away, not Home.


#4

I’m not sure what you’re talking about here. Does Switch 1 refer to the Bitter Cold Flag switch, or to the switch case construct right underneath? I don’t see how the Bitter Cold Flag switching will cause the piston to executed from the beginning, the beginning of the piston is executing only on events from the three iphones presence sensors. And assigning a new value to the global variable @locationMode is not a trigger for this piston either.


#5

Yes, you are right… It successfully resumed at line 33:

as seen here:

11/22/2019, 10:51:13 AM +89ms
╔Received event [Home].time = 1574437874631 
║║Executed virtual command setLocationMode
║║Executed virtual command setVariable
║║Executed virtual command setVariable 

The logs shows that the piston did what you asked… Not sure why your 1:45PM logic failed. Do you have any other programming that touches location mode, $locationMode or @locationMode??


Other than that, I would add a:
Log to console = 'LocMode = '$locationMode
right before you execute your first Routine. (after line 35)

This will give you real data as to what is being written to the global.


Also, for what it’s worth, global variables are not actually written until the piston has completed the very last line of code. Not sure how a 4 hour WAIT plays into this…


#6

Switch 1 is whatever device you have on lines 44 & 73 in your original piston above…


Any line that has a lightning bolt in the left margin, means that webCoRE has subscribed to that device, and will execute the entire piston each time it changes at all, in any direction.

One of the reasons you are having peculiar results is because you have absolutely zero triggers in this piston… So each and every condition is treated like a trigger. (hence, all the lightning bolts!)