Location mode else if returns false?


#1

1) Give a description of the problem
Location Mode in Else If evaluating to false but if it is in its own if block it returns true. This is quite confusing, what did i do wrong?

2) What is the expected behavior?
Else if should evaluate true - even in the logs it looks like it should be true (at 135ms in log below:

|+135ms|║║Comparison (string) :5dd4122925624ac923a872714e8c881a: changes_to (string) :5dd4122925624ac923a872714e8c881a: = false (1ms)|
|---|---|
|+136ms|║║Condition #29 evaluated false (3ms)|

3) What is happening/not happening?
I’m sure i’m not understanding something correctly with how this works. Note that condition 29 is included to illustrate that it is returning false, i originally had actions in that block but created block 23 because they were not executing.

4) Post a Green Snapshot of the piston!

5) Attach any logs (From ST IDE and by turning logging level to Full)

12/20/2017, 6:40:48 PM +222ms
+1ms	╔Received event [Home].mode = Home with a delay of 74ms
+120ms	║RunTime Analysis CS > 40ms > PS > 50ms > PE > 30ms > CE
+123ms	║Runtime (43967 bytes) successfully initialized in 50ms (v0.2.100.20171211) (121ms)
+123ms	║╔Execution stage started
+129ms	║║Comparison (string) :5dd4122925624ac923a872714e8c881a: changes_to (string) :73dfbd386a584442e820c2e0e468e6cd: = false (0ms)
+130ms	║║Cancelling condition #11's schedules...
+131ms	║║Condition #11 evaluated false (4ms)
+132ms	║║Cancelling condition #1's schedules...
+132ms	║║Condition group #1 evaluated false (state changed) (5ms)
+135ms	║║Comparison (string) :5dd4122925624ac923a872714e8c881a: changes_to (string) :5dd4122925624ac923a872714e8c881a: = false (1ms)
+136ms	║║Condition #29 evaluated false (3ms)
+137ms	║║Condition group #28 evaluated false (state did not change) (4ms)
+141ms	║║Comparison (string) :5dd4122925624ac923a872714e8c881a: changes_to (string) :5dd4122925624ac923a872714e8c881a: = true (0ms)
+142ms	║║Cancelling condition #24's schedules...
+143ms	║║Condition #24 evaluated true (3ms)
+176ms	║║Calculating (decimal) 0.0 - (decimal) 30.0 >> (decimal) -30.0
+179ms	║║Comparison (datetime) 1513824048365 is_between (datetime) 1513813740000 .. (datetime) 1513785240000 = true (2ms)
+180ms	║║Time restriction check passed
+181ms	║║Condition #27 evaluated true (38ms)
+182ms	║║Cancelling condition #23's schedules...
+183ms	║║Condition group #23 evaluated true (state changed) (43ms)
+184ms	║║Cancelling statement #25's schedules...
+215ms	║║Executed physical command [Toy chests].on() (27ms)
+216ms	║║Executed [Toy chests].on (28ms)
+224ms	║║Calculating (decimal) 0.0 - (decimal) 15.0 >> (decimal) -15.0
+226ms	║║Comparison (datetime) 1513824048442 happens_daily_at (datetime) 1513814640000 = false (0ms)
+227ms	║║Condition #19 evaluated false (8ms)
+228ms	║║Cancelling statement #19's schedules...
+233ms	║║Calculating (decimal) 0.0 - (decimal) 15.0 >> (decimal) -15.0
+235ms	║║Condition group #16 evaluated false (state did not change) (16ms)
+237ms	║╚Execution stage complete. (114ms)
+238ms	╚Event processed successfully (238ms)```

#2

I’d remove the else if - Location mode changes to Home
co-2017-12-20-21-56-47

You already have an second IF block setting up the Location changes to Home
co-2017-12-20-21-59-30

and I’d suggest changing {addMinutes{$sunset, -30}} to 30 minutes before preset sunset


#3

I’d prefer to put the actions in the else-if. I created the second If block because the else-if was returning false as a workaround for the time being to try and figure this out.

If having a second if block is the only way to do this, then i can stick with that, but it doesn’t seem like that should be the case. It seems like the else-if should be evaluating to true based on the log entries.


#4

then put it in the else not else if section. if you have more than Home and Away modes, you are out of luck.


#5

I want to add additional modes other than just away and “not away”. Maybe a switch would be better suited?

Also, you mentioned changing the addMinutes to “minutes before” - i couldn’t find an offset option when using the presets, can you point me to the correct way to implement that?


#6

use Time instead of Date and Time


#7

“Changes to” are instantaneous and only evaluate true for a short period of time. If I’m constructing a multiple layer IF statement like that, I’ll either use one trigger at the top (changes to) and conditions for the rest (location is)… or all conditions.


#8

Your expression and the offset @jkp mentioned are both viable solutions… that get you to the same place. But if you want to use them, you have to use the Virtual Device ‘Time’… then choose a preset (Sunrise, Sunset, etc.) and there will be an option for an offset there.


#9

@michicago
Ok - perhaps that’s what’s causing the failure, but it still seems like it should eval true based on the log snippet:
Comparison (string) :5dd4122925624ac923a872714e8c881a: changes_to (string) :5dd4122925624ac923a872714e8c881a: = false (1ms)

I’m not trying to be argumentative, i’m just very confused and wondering if perhaps there’s a bug here, or if i’m going to start running into a lot of issues when i start adding in the other 4 modes i want to check for and need to rethink my approach.

@jkp
Thank you - found it in Time


#10

Trust me, I’m not taking it as argumentative at all. I’ve posted in here where times (in epoch) that clearly should have evaluated true, gave a false outcome. Never figured out why - just rewrote my piston to something that was more predictable.

I think you’ll find the same with “changes to”. :slight_smile:


#11

LOL I never took it as argumentative. I took it as you are learning :slight_smile:


#12

Ok - well i’ll just accept this as an oddity. I’ll try a switch maybe, and if that doesn’t work i guess it’s just going to have to be a bunch of separate if blocks.

Thank you both for your replies!


#13

at some point, you will also get into using presence detection and perhaps setting SHM. this post might help…


#14

dont use else if use else then if or switch case as you probably already have.


#15

changes to as processed by a piston does not process the change itself but an event generated by the change so its true for that run of the piston irrespective of the duration.


#16

That’s what I thought until recently when my garage door sensor started returning a false in my piston. It was a “changes to” trigger, but it’s many lines down in the piston… and even though the triggering event was GarageDoorSensor.contact, it would evaluate false.

Sorry, not trying to pass out bad info. The more I think I’m starting to understand this stuff, the less clear it becomes…


#17

you are right after about 10 seconds of runtime it seems to revert to false instead of true in the same piston run. thats unfortunate.

thanks for correcting me. :slight_smile:

Logs
12/20/2017, 10:09:27 PM +923ms
+203ms	║yes 1
+3223ms	║yes 2
+6243ms	║yes 3
+9263ms	║yes 4
12/20/2017, 10:09:27 PM +921ms
+196ms	║yes 1
+3218ms	║yes 2
+6237ms	║yes 3
+9257ms	║yes 4

#18

Yikes, I hope my pistons aren’t running for 10 seconds to operate a garage door! (the only ones that do are waiting at a semaphore for 9000+ms, and for the life of me I can’t figure out why).

I think mine was only 250-270ms in, but evaluating false. It’s working now so I haven’t bothered to switch it back again.

Interesting litmus test - I never would have thought of that. I’ll have to remember that!


#19

if i remember correctly from checking the code lsat time, semaphore wait is used to synchronize across multiples instances of the piston run. but there may be more to it.


#20

Someone else is seeing a similar “changes to” evaluate false about 2/10ths of a second after the event registers. Any idea why this might be occurring? I’ve had it to… just seems to get pushed out of my logging before I can grab it.