Presence sensor fires when I arrive and when I leave?


#1

1) Give a description of the problem
I have a piston that I am building to slective lights on (if they are not on already) when I arrive. My trigger is when my presence device (through life 360) changes to present.

2) What is the expected behaviour?
I expect the triggers to execute when I arrive home. But it also executes when I leave! The trigger appears to execute when any action occurs with my presence. I attempt to have my presence set a Boolean variable (home=true) but the same behavior resulted when I leave and {not present=false) the piston would still fire when I departed.

3) What is happening/not happening?
a. Turns lights on when I arrive home, which is the desired and expect result of the presence changes to present trigger.
b. But also fires and executes the piston when I leave home, which is not desired or expected. I need to find a way or a trigger that only fires when I arrive.

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


5) Attach logs after turning logging level to Full
5/1/2019, 5:07:49 PM +161ms
+0ms ╔Received event [Home].time = 1556744870023 with a delay of -863ms
+156ms ║RunTime Analysis CS > 22ms > PS > 81ms > PE > 53ms > CE
+159ms ║Runtime (40483 bytes) successfully initialized in 81ms (v0.3.10a.20190223) (156ms)
+161ms ║╔Execution stage started
+1569ms ║║Executed physical command [Light_circle].off() (1377ms)
+1571ms ║║Executed [Light_circle].off (1380ms)
+2557ms ║║Executed physical command [Light_foyer].off() (983ms)
+2559ms ║║Executed [Light_foyer].off (985ms)
+2573ms ║║Executed virtual command [Light_circle, Light_foyer].sendSMSNotification (6ms)
+2576ms ║╚Execution stage complete. (2416ms)
+2577ms ╚Event processed successfully (2578ms)
5/1/2019, 5:07:20 PM +403ms
+2ms ╔Received event [Jack].presence = not present with a delay of 98ms
+119ms ║RunTime Analysis CS > 20ms > PS > 61ms > PE > 37ms > CE
+121ms ║Runtime (40475 bytes) successfully initialized in 61ms (v0.3.10a.20190223) (118ms)
+123ms ║╔Execution stage started
+133ms ║║Comparison (enum) not present changes_to (string) present = false (1ms)
+135ms ║║Cancelling condition #20’s schedules…
+136ms ║║Condition #20 evaluated false (7ms)
+138ms ║║Cancelling condition #19’s schedules…
+139ms ║║Condition group #19 evaluated false (state changed) (10ms)
+142ms ║║Condition group #1 evaluated true (state did not change) (0ms)
+160ms ║║Comparison (enum) off is (string) on = false (2ms)
+163ms ║║Comparison (enum) off is (string) on = false (2ms)
+171ms ║║Condition #7 evaluated false (25ms)
+172ms ║║Condition group #3 evaluated false (state did not change) (27ms)
+214ms ║║Comparison (time) 61640579 is_after (datetime) 1556707440000 = true (7ms)
+216ms ║║Time restriction check passed
+217ms ║║Condition #2 evaluated true (41ms)
+219ms ║║Condition group #8 evaluated true (state did not change) (43ms)
+222ms ║║Cancelling statement #15’s schedules…
+479ms ║║Executed physical command [Light_circle].on() (254ms)
+480ms ║║Executed [Light_circle].on (256ms)
+598ms ║║Executed physical command [Light_foyer].on() (115ms)
+599ms ║║Executed [Light_foyer].on (118ms)
+612ms ║║Executed virtual command [Light_circle, Light_foyer].sendSMSNotification (5ms)
+617ms ║║Executed virtual command [Light_circle, Light_foyer].wait (1ms)
+619ms ║║Requesting a wake up for Wed, May 1 2019 @ 5:07:50 PM EDT (in 29.0s)
+625ms ║╚Execution stage complete. (503ms)
+627ms ║Setting up scheduled job for Wed, May 1 2019 @ 5:07:50 PM EDT (in 28.994s)
+638ms ╚Event processed successfully (638ms)

REMOVE BELOW AFTER READING
If a solution is found for your question then please mark the post as the solution.


#2

Not sure why what your asking for. Dont know if #3 is expected or not expected behavior.


#3

On my phone so I can’t completely check your piston but what I see immediately is line 24 needs to be moved to line 26 and erase the first IF. Your first THEN is blank and your second IF is blank. Then take line 29,30,31 out of the IF and put them in your FIRST THEN. Others may have more to offer.


#4

When you have a trigger like this looking for change in presence, it will trigger on a change to present or not present. That is the only way to check if your presence is true. I believe you are trying to get the following statements to always execute. You could do something like this:

If 
  presence sensor 2 changes to not present
then
    exit ' not present'
endif

This would only allow the ‘present’ to make it to the rest of the piston/logic


#5

Pantheon, Thanks for your suggestions. It appears to work properly now, but I will do some more testing. Guxdude,I will try your suggestion also, and may the logic may help where I have issue with a door sensor that the trigger is “changes to open” but also fires again when door is closed.

Jack


#6

Guxdude. Your suggestion has helped my two problematic pistons. Can you help me understand how it works. The exit cancels the trigger from executing during this piston until all steps are completed. I believe ‘not Present’ is just a comment, and doesn’t do anything, is that correct?


#7

That is correct. The exit statement requires a status value for the piston which can be any text. I just chose ‘not present’ as descriptive of the last state of the piston but you could make it anything.

As far as how it works, the exit just makes sure the piston stops executing when the trigger you don’t want fires. So when it is the trigger you want, it will continue on.


#8

Just in case anyone is needing a more thorough description of what’s happening in the original design of the piston:
An “if” statement with a trigger in it’s condition will fire whenever the trigger fires and then check the condition. Since the “then” in that block is blank, it only acts to run the piston whenever there is a change to Presence Sensor 2.
If there were a “then” inside the “if” block, then that code would execute only if the condition were true. However, regardless of whether the condition is true or not, execution continues after the “endif” of the block. All the code following the “endif” executes on any change.
One solution is to take all the code following the first “endif” and place it inside the “then” of the first “if” block.
guxdude’s solution also works because it bypasses the following code if the condition is not true.


#9

I am not sure that I understand this at all. Is there additional documentation somewhere that I can reference?


#10

I don’t know of any specific documentation. This is based on experience with webCoRE (and a lot of other programming languages).
I’ll try to be more clear. The thing is that there is an aspect of program code and there is a specific aspect of webCoRE event handling:

  1. (webCoRE event handing) When you put a trigger into the code (using an ON or IF) that code block will execute, as will any code following the “EndIf”, any time the status of the trigger item (switch, contact, presence, etc) changes. What happens when it executes is a function of…
  2. (program code) In an “If” block, the condition is evaluated. If it is true, then then code in the “Then” block is executed. If it is false, then the code in the “Else” block is executed. After the “Then” or “Else” block is executed, execution continues for any code following the “EndIf” because code executes sequentially.
    There is a special case in webCoRE when you want several things to trigger activity regardless of any of the others. In that case, you put each trigger into a separate “If” block and set each for “asynchronous execution”. In those cases each “asynchronous” block only executes when it gets a trigger event.
    However, within those blocks, #2 still holds and any code following the “EndIf” of each of those asynchronous blocks will execute whenever the trigger fires regardless of the conditions within the block.

To put it another way, any trigger within your code will cause the block that has that trigger to begin execution. After executing that block (including any conditional blocks within it) execution will continue to any code following the block with the trigger.
So,

execute
  /* whenever device's status changes execution starts below */
  if {device}'s condition
  then
    /* this code will execute only if condition is true */
  else
    /* this code will execute only if condition is false */
  endif;
  /* this code will execute whenever device's status changes regardless */
end execute;

#11

I think I actually understand, qoheleth and your education if very helpful. I did not add the then in the 2nd if (any of white bulb2 or outlet switch is on) that set the variables which device is on and which one is off, with the assumption?? that if no devices were on the if would be considered false and subsequent actions that are currently in the 2nd then statement (turn on, wait and then off) would never execute. I was not sure if the conditional statement that save matching and not matching devices would stop the flow. If any of the above makes sense.


#12

[quote=“qoheleth, post:10, topic:12428”]
After executing that block (including any conditional blocks within it) execution will continue to any code following the block with the trigger./quote]
I think I know this, but what happens to the code ABOVE the block?


#13

As far as I know, because code is executed sequentially, code above the block would not execute on a change of condition. It would execute if you ran a test, however.


#14

Wouldn’t the piston start over from the very beginning upon a condition change?


#15

You are correct, sir. I just tested it and it does start at the beginning.
I also stated the “asynchronous” thing wrong. An If statement with a trigger can be set to “Always execute”, “Execute on condition state changes only”, “Execute on Piston state changes only”,“Execute on both”. It can also be set to “Synchronous (default)” or “Asynchronous” execution. The former means that the condition in the If will either be checked every time the piston triggers, only when a specific event would change the condition, only when the state of the piston (which is set by an Action) changes, or either of those two things happen. Asynchronous execution simply allows code to proceed even if prior code has done a wait or other operations that might pause execution.

To correct my statements above, then,
If any change in any triggers occur, the code executes from the beginning of the piston. Each conditional in the piston will execute only the “then” code if the condition is true or the “else” code if the condition is false.

execute
  /* this code executes when ever any change to a trigger occurs or when test is run */
  if condition1  /* this condition will be checked on any change to condition 1 or 2 */
    then
      /* this code executes only when condition1 is true */
    else
      /* this code executes only when condition1 is true */
  endif;
  /* this code will also execute when ever any change to a trigger occurs or when test is run */
  if condition2 /* this condition will be checked on any change to condition 1 or 2 */
  then
      /* this code executes only when condition2 is true */
    else
      /* this code executes only when condition2 is true */
  endif;
  /* this code will also execute when ever any change to a trigger occurs or when test is run */
  if (condition state change only) condition3  /* this condition will be checked only on a change of condition3 */
  then
      /* this code executes only when condition3 is true */
    else
      /* this code executes only when condition3 is true */
  endif;
  /* here's some more code that will execute when ever any change to a trigger occurs or when test is run */
end execute;

There’s one additional thing to note: The if statements also have “when true” and “when false” blocks. Code in the “when true” block executes when the condition is true and code in the “when false” block executes when the condition is false, which essentially duplicates the functionality of the “then” and “else” blocks. I’m not sure why this exists, but it’s part of the webCoRE language.