webCoRE Location Calculation works - but with semaphores


#1

1) Give a description of the problem
The piston works but with semaphores. This piston calculates the appropriate Location Mode (Home, Away or Vacation) based on our iPhones’ distance from home with the webCoRE presence capabilities and the @AwayCircle and @VacCircle global variables. It then ‘presses’ the appropriate simulated ‘Location Mode’ switch - which causes the ‘Location Modes Actuator’ Piston to run. The ‘Location Modes Actuator’ Piston changes both the Location Mode and the associated Thermostat Heat/Cool Set Points. Further, since the ‘T-Stat Schedule’ Piston can only make thermostat setpoint changes when the Location Mode is ‘Home’, changing the Location Mode to ‘Away’ or ‘Vacation’ effectively places thermostat setpoint changes on hold until the Location Mode is set back to ‘Home’ again.

2) What is the expected behaviour?
No/Less semaphores if possible. I think the semiphores are happening due to the frequent feedback from the phones regarding their location. I had originally had written this to only trigger when both phones crossed a linie (Away or Vacation). However, since the two phones never cross the lines at the same time, it never worked that way. So, I changed it to check for the phones being in a particular range . This requires BOTH phones to be in a range when when moving away from home and ANY phone when getting closer to home. This is so that the closest range to home is calculated.

3) What is happening/not happening?
See above

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

5) Attach logs after turning logging level to Full
2/25/2020, 9:39:16 AM +845ms
+1ms ╔Received event [Lee].distance = 0.01958875750529802 with a delay of 101ms
+10183ms ║RunTime Analysis CS > 23ms > PS > 10110ms > PE > 51ms > CE
+10184ms ║Piston waited at a semaphore for 10079ms
+10187ms ║Runtime (53163 bytes) successfully initialized in 10110ms (v0.3.110.20191009) (10185ms)
+10188ms ║╔Execution stage started
+10206ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+10208ms ║║Condition #6 evaluated false (14ms)
+10218ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (1ms)
+10221ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (1ms)
+10222ms ║║Condition #26 evaluated false (13ms)
+10224ms ║║Condition group #25 evaluated false (state did not change) (14ms)
+10225ms ║║Condition group #24 evaluated false (state did not change) (31ms)
+10226ms ║║Condition group #1 evaluated false (state did not change) (33ms)
+10237ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (1ms)
+10239ms ║║Condition #12 evaluated false (11ms)
+10240ms ║║Condition group #7 evaluated false (state did not change) (12ms)
+10253ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+10255ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+10257ms ║║Condition #22 evaluated false (14ms)
+10258ms ║║Condition group #19 evaluated false (state did not change) (16ms)
+10270ms ║║Comparison (decimal) 0.01958875750529802 is_less_than (integer) 5 = true (1ms)
+10271ms ║║Condition #18 evaluated true (10ms)
+10276ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (2ms)
+10277ms ║║Condition #17 evaluated false (5ms)
+10278ms ║║Condition group #13 evaluated false (state did not change) (17ms)
+10280ms ║╚Execution stage complete. (92ms)
+10281ms ╚Event processed successfully (10281ms)
2/25/2020, 9:39:16 AM +800ms
+1ms ╔Received event [Lee].distance = 0.01958875750529802 with a delay of 104ms
+10153ms ║RunTime Analysis CS > 20ms > PS > 10069ms > PE > 65ms > CE
+10154ms ║Piston waited at a semaphore for 10040ms
+10157ms ║Runtime (53163 bytes) successfully initialized in 10069ms (v0.3.110.20191009) (10155ms)
+10158ms ║╔Execution stage started
+10176ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+10178ms ║║Condition #6 evaluated false (15ms)
+10188ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (1ms)
+10191ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (2ms)
+10193ms ║║Condition #26 evaluated false (12ms)
+10194ms ║║Condition group #25 evaluated false (state did not change) (13ms)
+10195ms ║║Condition group #24 evaluated false (state did not change) (31ms)
+10196ms ║║Condition group #1 evaluated false (state did not change) (33ms)
+10206ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (1ms)
+10207ms ║║Condition #12 evaluated false (9ms)
+10208ms ║║Condition group #7 evaluated false (state did not change) (10ms)
+10220ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+10223ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+10224ms ║║Condition #22 evaluated false (13ms)
+10225ms ║║Condition group #19 evaluated false (state did not change) (15ms)
+10237ms ║║Comparison (decimal) 0.01958875750529802 is_less_than (integer) 5 = true (1ms)
+10239ms ║║Condition #18 evaluated true (10ms)
+10243ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (2ms)
+10244ms ║║Condition #17 evaluated false (5ms)
+10245ms ║║Condition group #13 evaluated false (state did not change) (17ms)
+10247ms ║╚Execution stage complete. (89ms)
+10248ms ╚Event processed successfully (10248ms)
2/25/2020, 9:39:24 AM +345ms
+2ms ╔Received event [Lee].distance = 0.010905761747191153 with a delay of 105ms
+121ms ║RunTime Analysis CS > 26ms > PS > 30ms > PE > 64ms > CE
+124ms ║Runtime (53085 bytes) successfully initialized in 30ms (v0.3.110.20191009) (121ms)
+125ms ║╔Execution stage started
+143ms ║║Comparison (decimal) 0.010905761747191153 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+145ms ║║Condition #6 evaluated false (14ms)
+155ms ║║Comparison (decimal) 0.010905761747191153 is_greater_than (integer) 50 = false (1ms)
+158ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (1ms)
+159ms ║║Condition #26 evaluated false (13ms)
+160ms ║║Condition group #25 evaluated false (state did not change) (14ms)
+161ms ║║Condition group #24 evaluated false (state did not change) (30ms)
+162ms ║║Condition group #1 evaluated false (state did not change) (32ms)
+173ms ║║Comparison (decimal) 0.010905761747191153 is_greater_than (integer) 50 = false (2ms)
+174ms ║║Condition #12 evaluated false (9ms)
+175ms ║║Condition group #7 evaluated false (state did not change) (10ms)
+186ms ║║Comparison (decimal) 0.010905761747191153 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+189ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+191ms ║║Condition #22 evaluated false (12ms)
+192ms ║║Condition group #19 evaluated false (state did not change) (14ms)
+202ms ║║Comparison (decimal) 0.010905761747191153 is_less_than (integer) 5 = true (1ms)
+204ms ║║Condition #18 evaluated true (9ms)
+208ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (2ms)
+209ms ║║Condition #17 evaluated false (5ms)
+210ms ║║Condition group #13 evaluated false (state did not change) (16ms)
+212ms ║╚Execution stage complete. (87ms)
+213ms ╚Event processed successfully (213ms)
2/25/2020, 9:39:23 AM +309ms
+2ms ╔Received event [Lee].distance = 0.0057985429684405225 with a delay of 111ms
+109ms ║RunTime Analysis CS > 27ms > PS > 32ms > PE > 50ms > CE
+112ms ║Runtime (53083 bytes) successfully initialized in 32ms (v0.3.110.20191009) (110ms)
+113ms ║╔Execution stage started
+130ms ║║Comparison (decimal) 0.0057985429684405225 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+132ms ║║Condition #6 evaluated false (14ms)
+141ms ║║Comparison (decimal) 0.0057985429684405225 is_greater_than (integer) 50 = false (1ms)
+144ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (1ms)
+145ms ║║Condition #26 evaluated false (12ms)
+146ms ║║Condition group #25 evaluated false (state did not change) (13ms)
+147ms ║║Condition group #24 evaluated false (state did not change) (30ms)
+148ms ║║Condition group #1 evaluated false (state did not change) (31ms)
+158ms ║║Comparison (decimal) 0.0057985429684405225 is_greater_than (integer) 50 = false (1ms)
+159ms ║║Condition #12 evaluated false (9ms)
+160ms ║║Condition group #7 evaluated false (state did not change) (10ms)
+171ms ║║Comparison (decimal) 0.0057985429684405225 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+173ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+175ms ║║Condition #22 evaluated false (13ms)
+176ms ║║Condition group #19 evaluated false (state did not change) (13ms)
+185ms ║║Comparison (decimal) 0.0057985429684405225 is_less_than (integer) 5 = true (1ms)
+187ms ║║Condition #18 evaluated true (9ms)
+191ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (1ms)
+192ms ║║Condition #17 evaluated false (5ms)
+193ms ║║Condition group #13 evaluated false (state did not change) (15ms)
+195ms ║╚Execution stage complete. (81ms)
+196ms ╚Event processed successfully (195ms)
2/25/2020, 9:39:22 AM +389ms
+1ms ╔Received event [Lee].distance = 0.00516319961353673 with a delay of 113ms
+234ms ║RunTime Analysis CS > 29ms > PS > 152ms > PE > 54ms > CE
+237ms ║Runtime (53085 bytes) successfully initialized in 152ms (v0.3.110.20191009) (235ms)
+238ms ║╔Execution stage started
+255ms ║║Comparison (decimal) 0.00516319961353673 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+257ms ║║Condition #6 evaluated false (14ms)
+268ms ║║Comparison (decimal) 0.00516319961353673 is_greater_than (integer) 50 = false (1ms)
+270ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (1ms)
+272ms ║║Condition #26 evaluated false (14ms)
+273ms ║║Condition group #25 evaluated false (state did not change) (15ms)
+274ms ║║Condition group #24 evaluated false (state did not change) (31ms)
+275ms ║║Condition group #1 evaluated false (state did not change) (33ms)
+286ms ║║Comparison (decimal) 0.00516319961353673 is_greater_than (integer) 50 = false (1ms)
+288ms ║║Condition #12 evaluated false (10ms)
+289ms ║║Condition group #7 evaluated false (state did not change) (11ms)
+301ms ║║Comparison (decimal) 0.00516319961353673 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+304ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+306ms ║║Condition #22 evaluated false (15ms)
+307ms ║║Condition group #19 evaluated false (state did not change) (16ms)
+318ms ║║Comparison (decimal) 0.00516319961353673 is_less_than (integer) 5 = true (2ms)
+320ms ║║Condition #18 evaluated true (9ms)
+324ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (2ms)
+325ms ║║Condition #17 evaluated false (5ms)
+326ms ║║Condition group #13 evaluated false (state did not change) (17ms)
+328ms ║╚Execution stage complete. (90ms)
+329ms ╚Event processed successfully (330ms)
2/25/2020, 9:39:20 AM +522ms
+1ms ╔Received event [Lee].distance = 0.017139259181741306 with a delay of 104ms
+103ms ║RunTime Analysis CS > 27ms > PS > 29ms > PE > 47ms > CE
+106ms ║Runtime (53083 bytes) successfully initialized in 29ms (v0.3.110.20191009) (104ms)
+107ms ║╔Execution stage started
+123ms ║║Comparison (decimal) 0.017139259181741306 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+125ms ║║Condition #6 evaluated false (13ms)
+134ms ║║Comparison (decimal) 0.017139259181741306 is_greater_than (integer) 50 = false (1ms)
+136ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (2ms)
+137ms ║║Condition #26 evaluated false (11ms)
+138ms ║║Condition group #25 evaluated false (state did not change) (12ms)
+139ms ║║Condition group #24 evaluated false (state did not change) (28ms)
+140ms ║║Condition group #1 evaluated false (state did not change) (29ms)
+150ms ║║Comparison (decimal) 0.017139259181741306 is_greater_than (integer) 50 = false (1ms)
+152ms ║║Condition #12 evaluated false (9ms)
+153ms ║║Condition group #7 evaluated false (state did not change) (11ms)
+164ms ║║Comparison (decimal) 0.017139259181741306 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+166ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+168ms ║║Condition #22 evaluated false (13ms)
+169ms ║║Condition group #19 evaluated false (state did not change) (14ms)
+179ms ║║Comparison (decimal) 0.017139259181741306 is_less_than (integer) 5 = true (1ms)
+180ms ║║Condition #18 evaluated true (9ms)
+184ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (1ms)
+185ms ║║Condition #17 evaluated false (4ms)
+186ms ║║Condition group #13 evaluated false (state did not change) (15ms)
+188ms ║╚Execution stage complete. (81ms)
+189ms ╚Event processed successfully (189ms)
2/25/2020, 9:39:16 AM +781ms
+1ms ╔Received event [Lee].distance = 0.01958875750529802 with a delay of 114ms
+121ms ║RunTime Analysis CS > 33ms > PS > 37ms > PE > 51ms > CE
+124ms ║Runtime (53082 bytes) successfully initialized in 37ms (v0.3.110.20191009) (122ms)
+125ms ║╔Execution stage started
+142ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+144ms ║║Condition #6 evaluated false (13ms)
+155ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (1ms)
+157ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (1ms)
+159ms ║║Condition #26 evaluated false (14ms)
+160ms ║║Condition group #25 evaluated false (state did not change) (15ms)
+161ms ║║Condition group #24 evaluated false (state did not change) (31ms)
+162ms ║║Condition group #1 evaluated false (state did not change) (33ms)
+173ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (2ms)
+174ms ║║Condition #12 evaluated false (10ms)
+175ms ║║Condition group #7 evaluated false (state did not change) (11ms)
+187ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+189ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+191ms ║║Condition #22 evaluated false (13ms)
+192ms ║║Condition group #19 evaluated false (state did not change) (14ms)
+203ms ║║Comparison (decimal) 0.01958875750529802 is_less_than (integer) 5 = true (1ms)
+204ms ║║Condition #18 evaluated true (9ms)
+208ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (1ms)
+210ms ║║Condition #17 evaluated false (4ms)
+211ms ║║Condition group #13 evaluated false (state did not change) (16ms)
+212ms ║╚Execution stage complete. (87ms)
+213ms ╚Event processed successfully (213ms)
2/25/2020, 9:39:16 AM +308ms
+1ms ╔Received event [Lee].distance = 0.01958875750529802 with a delay of 110ms
+114ms ║RunTime Analysis CS > 32ms > PS > 34ms > PE > 49ms > CE
+117ms ║Runtime (53083 bytes) successfully initialized in 34ms (v0.3.110.20191009) (115ms)
+118ms ║╔Execution stage started
+136ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+139ms ║║Condition #6 evaluated false (15ms)
+151ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (2ms)
+154ms ║║Comparison (decimal) 0.013600698207647786 is_greater_than (integer) 50 = false (2ms)
+156ms ║║Condition #26 evaluated false (16ms)
+157ms ║║Condition group #25 evaluated false (state did not change) (17ms)
+159ms ║║Condition group #24 evaluated false (state did not change) (35ms)
+160ms ║║Condition group #1 evaluated false (state did not change) (38ms)
+173ms ║║Comparison (decimal) 0.01958875750529802 is_greater_than (integer) 50 = false (1ms)
+175ms ║║Condition #12 evaluated false (12ms)
+176ms ║║Condition group #7 evaluated false (state did not change) (13ms)
+189ms ║║Comparison (decimal) 0.01958875750529802 is_inside_of_range (integer) 5 … (integer) 50 = false (1ms)
+192ms ║║Comparison (decimal) 0.013600698207647786 is_inside_of_range (integer) 5 … (integer) 50 = false (2ms)
+194ms ║║Condition #22 evaluated false (15ms)
+195ms ║║Condition group #19 evaluated false (state did not change) (16ms)
+206ms ║║Comparison (decimal) 0.01958875750529802 is_less_than (integer) 5 = true (1ms)
+208ms ║║Condition #18 evaluated true (10ms)
+212ms ║║Comparison (string) :cf8423e7dfeccd9432227c2ce2fa3008: is (string) :5f1ef659f5fd1e1805884f942e292500: = false (2ms)
+213ms ║║Condition #17 evaluated false (4ms)
+214ms ║║Condition group #13 evaluated false (state did not change) (16ms)
+216ms ║╚Execution stage complete. (98ms)
+217ms ╚Event processed successfully (217ms)


#2

I would probably reduce to a single trigger, with conditions indented beneath it… Something like this:

IF any of {PresenceSensor}'s distance changes  <-- Trigger (Lv 1)
Then
    IF {Calculating} is false                  <-- Condition (Lv 2)
       and
       {OverrideSwitch} is off                 <-- Condition (Lv 2)
    Then
        IF condition is X                      <-- Condition (Lv 3)
            Then do something
        END IF
        IF condition is Y                      <-- Condition (Lv 3)
            Then do something else
        END IF
        IF condition is Z                      <-- Condition (Lv 3)
            Then do something completely different
        END IF
        etc.
    END IF
END IF

#3

Thanks! That sounds very promising. Fewer triggers may just eliminate the semaphores. I’ll give it a shot and let you know!


#4

Pro Tip:

If either Presence Sensor updates it’s distance during the 4 second WAIT, I don’t think you can avoid the semaphore delay (unless you allow multiple copies of the piston to run concurrently). The shorter you can make this WAIT (without breaking your other piston) the better… Ideally, you want this piston to complete before either sensor reports a new distance.

All that being said, I still think you will find better results with my structure above. It will run to completion much faster due to no condition being checked more than once. (and double hits will likely cancel out at one of the first two conditions)


#5

Thanks again. I had originally used both a longer and then shorter waits and then with and without TCP set to never - in an effort to find the right mix. So that I didn’t have to guess in each instance how long the wait should be, I even tried setting ‘do until loops’ for each different change with the ‘UNTIL’ parameter being the appropriate changed Mode Switch. That idea still has some merit I think but it added one more trigger per loop that I didn’t want - because the ‘UNTIL’ has to be a trigger.

Anyway, that’s how I got here. I think your idea has a lot of merit and will try it tonight or tomorrow.


#6

Based on your feedback and advice, here’s what I now have. In addition to the different structuring of the IF blocks that allowed the piston to be reduced to just one trigger, I’ve at least temporarily reduced the waitTime variable to (0) seconds. Seems OK that way. I’m also not sure if the boolean variable {Calculating} is really needed anymore, but I think it’s probably a good idea in case both of our phones report almost simultaneous movement. So, at this point, I’ve left it in.

So far, in the short time it’s been running, I haven’t seen any semaphores, Previously, I was getting them with any phone movement - even when we were at home. Now that the semaphores have been at least reduced, I now need to test how it works when we’re actually moving around and crossing Away/Vacation Circle thresholds. The ‘Away’ Circle is currently set at 5 miles as the crow flies, so we’ll need to travel at least that far. I’ll let you know. Thanks again.


#7

Lookin’ good, @lflorack!!

Just to clarify, this piston will not change the frequency of your phone reporting any location changes.
(IE: This piston will trigger just as often as your original)

This piston was specifically designed to abort promptly, OR, run to completion as quickly as possible. This is so the next location change will (hopefully) always encounter a “clean-slate”, and not cause a semaphore delay.


#8

Understood, and thanks for the clarification. I’ve now received a couple of semaphores, but that’s a lot less than I was getting previously. AND the piston looks - and likely runs , much cleaner and faster.

FYI, I’ve made another change to the piston by moving the {Calculating} = True and a False statements to the ends of the main IF block and eliminating all of the others.


#9

Looking at your logs, your specific problem seems to be that shortly after 09:39:16 AM you received FOUR identical distance ‘change’ events in quick succession, all delayed by about a tenth of a second. The sequence was:

+308 ms First instance fires.
+515 ms First instance completes.
+781 ms Second instance fires.
+800 ms Third instance fires. Held at semaphore for about 10 seconds.
+845 ms Fourth instance fires. Held at semaphore for about 10 seconds.
+994 ms Second instance completes.

Your piston could perhaps test that the distance has actually changed, but it’ll still take about 100ms for the execution to hit the piston itself and that might still not be quick enough to knock out the semaphore waits.


#10

Interesting. It’s also notable that during that time, the phone was sitting in my pocket as I sat in front of my PC. I guess the most I can hope for is to make the piston as streamlined as possible to reduce the semaphores to the least number possible and leave it at that. As I said earlier, the piston worked fine before I started and it will work even better now.

Thanks for the analysis and feedback.


#11

Update:
As per the discussion above - thanks again to @WCmore and @orangebucket for their insights -regarding the need for piston execution speed to reduce semaphores, I have further tweaked the most recent piston by eliminating the multiple waits that I thought I needed, slightly restructuring the code and removing the {Calculating} boolean. All the same basic logic remains, so I think this piston should function properly just as the original did - except with more speed and fewer semaphores. Here’s the result:


#12

Update Again:

When initially setting this piston up, it made sense to use our iPhone’s locations within the Home, Away and Vacation ranges as the trigger to change the thermostat’s setpoints - only measuring when there’s iPhone movement. However, after watching even the above improved piston run for a few days, I’ve seen that GPS drift results in multiple movement notifications and semaphores - even when there isn’t any real movement. Although using the iPhone’s locations as the trigger was intended to limit piston executions, in reality, it ended up running almost constantly.

So, using the iPhone’s location as the piston’s trigger may not be the best choice - especially because I don’t really need to know immediately that we’ve moved between the Home, Away or Vacation areas. It’s not like when we arrive at home and we need to trigger something immediately. Knowing that we’re in a different range within a few minutes to make thermostat setpoint changes is very likely more than good enough.

Therefore, I’ve removed the ‘presence distance change’ trigger and put all the remaining logic inside a 5-minute Loop. With the loop now acting as the trigger, the piston only checks on the locations of both iPhones during each loop - which should also eliminate all semaphores. Although it will now run every 5 minutes, based on what I’ve observed, the old piston was essentially running all the time anyway. So, the loop should greatly reduce piston executions. I may even change the loop time to every 10 minutes.

Thanks for listening. Feedback is welcome!

Here’s the new piston:


#13

I agree… Those presence triggers can be a real chatterbox…

I have not analyzed every line above, but one trick to reduce executions is to prevent it from running at specific times, (such as when you are asleep).

IE:

Every 5 minutes
Do
    IF SleepSwitch is off (meaning you are awake)
        Then continue on with the rest of the piston...

This should reduce triggers by 33% (8 hours a day)


Pro Tip:

My “Good Night” and “Good Morning” pistons sets my SimulatedSleepSwitch either on or off, but as always, there are other ways to achieve this. (@globals are another good way to achieve this)


#14

Excellent tip regarding further reduction of Piston executions. In my case - this Piston is calculating Home, Away and Vacation modes only for thermostat set point changes.

With that in mind, Home is different than ‘present’ for me. Using your idea to limit unneeded portion executions I’ll add one line to the Piston to check to see if either of us is present. If so, I’ll skip Piston execution. Otherwise, I’ll run the 5-minute loop.

Thanks for the idea!


#15

Brilliant!

For fastest response times, I would recommend using an “IF” instead of “ONLY WHEN”…