When is False equal to True?


#1

Ok I am stumped. Is my code bugged or something weird happening at the server end. Here is a block of code that includes several SendPush() messages:

if (devicesAway == atomicState.arrayCount) { // All presences sensors defined in Preferences have left home
atomicState.atHome=false
atomicState.hasLeft=true
sendPush(“All Devices are currently away”)
}
else {
if (devicesAway==0) {
atomicState.atHome=true
sendPush(“All of the Devices are at home”)
}
}

if (atomicState.atHome==true && atomicState.hasLeft==true) { // All sensors have once left home but now have returned.
atomicState.hasLeft=false
atomicState.setToAway=false
if (lock) {
sendPush(“Door Unlocking”)
lock.unlock()
}
}

Yesterday afternoon I left home and the App sent me the message “All Devices are currently away”. Milliseconds later I get the message “Door Unlocking”. I simply cannot figure out how the statement if (atomicState.atHome==true && atomicState.hasLeft==true) returned true and the code that sent the “Unlocking” message could have executed. :hushed:

There is only one place (see the above code snippet) where the var atomicState.hasLeft is set to True. There are two places where the Var atomicState.atHome is set to True. One place within the above code snippet (which also would send me the message “All of the Devices are at home” and the second location is within the Initialize function (called from installed() and updated()) is shown below

def initialize() {
atomicState.atHome=true as boolean
atomicState.hasLeft=false as boolean
.
.
.
.
.
.
}

In summary, I first get the message “All Devices are currently away” immediately followed by “Door Unlocking”. I cannot see how this could have happened. What am I missing here??


#2

No means no. :scorpion:+characters


#3

Is that supposed to point me to the solution for my problem??? :unamused:


(Mike Maxwell) #4

Not quite following the need to have two state variables tracking presence, wouldn’t one do the job?
Seems this could be done with just the atHome. Also if the variables are Boolean, when evaluating the state in the if, the following can be used:
If (boolVar) { blablabla…
}
If you’re using hasLeft to prevent multiple messages, it may be clearer to name it so and I would use that as a separate if within the isHome one to a new send message/unlock. This also gives you a place to add some log debug to see what’s going on.


(John S) #5

It’s possible the push messages arrived out of order (ie, the code sent Door Unlocking first, then, in response to another event, sent All Devices are Currently away… but Google Cloud Messaging delivered them in the opposite order. Add a timestamp to the message text, that will show you if they’re arriving out of order.


(Kristopher Kubicki) #6

Somewhat unrelated but maybe not - ST is having trouble tracking modes consistently. A fix is coming soon I believe


(Jim Anderson) #7

Is this consistently reproducible?

If the code block you posted is all within one method, you really don’t need to read from atomicState repeatedly. You could create a local variable that has the information you need and use that for your logic. Of course still write to atomicState before the method exits so that future executions have the correct info, but not necessary to continually read from it.

Also, I’d suggest putting a bunch of log statements in that show the values you are getting from atomicState every time. This should show if the values are not as you’d expect, and thus causing conditional branching that is not expected.

Let us know what you find, will be interested to know.


(Jim Anderson) #8

Also, while I don’t think it’s directly related to this issue, be aware that Groovy does have some special definitions of “truth”. They are pretty convenient and make sense (i.e., an empty collection is considered false), but can cause some confusion if not understood. http://www.groovy-lang.org/semantics.html#Groovy-Truth


(Alex) #9

If you have any boolean Smart App preferences involved in calculating any of the state variable values, make sure you understand the difference between input bool and input boolean as described here:
http://docs.smartthings.com/en/latest/smartapp-developers-guide/preferences-and-settings.html?highlight=preferences#input

One returns boolean true/false the other returns strings "true"/"false".

Also, it’s possible that your presence device jumped in and out of the geo-fence briefly.


(Alex) #10

Also, if the state variable value is calculated based on an input from a preference on a dynamic page, under certain conditions it may evaluate to something like this:

input "myInput", "bool"

log.debug "value of myInput = $myInput" // prints "value of myInput = myInput

#11

When one sensor (falsely) “leaves home” and then “returns” the state “All of the Devices are at home” is true and things can go bad for me (i.e unlock a door when it shouldnt). For safety reasons I planned to utilize multiple sensors and only when all sensors had actually left then returned unlock doors, turn on lights etc…

That said… A closer look at my code seems to suggest that with a few changes I can probably do with just the .atHome boolean.


#12

That should only occur if I had left AND actually returned. I was still away when the door unlocked. Funny thing is that the log showed my presences were still away when the darn door unlocked. Makes no sense


#13

No it isn’t. That is what is so frustrating. This morning all was well.

Another thing I checked was the event log for the app to see what happened before this problem (which occurred around 4:30PM) . I noticed I had left earlier that morning and the order of all messages (i.e left home, returned home) and the unlocking of the door occurred exactly as it should. In other words, at the time of this problem there did not appear to be any “unfinished business” from previous execution of the app.

Actually I had recently removed all the log statements to reduce clutter. Used to have all kinds of sendPush messages as well but the code appeared to be working so well over the past few weeks I felt I didnt need all these messages anymore :blush: Go figure


#14

Considered that but the sendPush(“All of the Devices are at home”) message should have fired. Also, in this case the sensor is Life360. Checking the log for this device during the problem period and it correctly shows when I left and when I returned. The door unlocked when Life360 showed as “not present”. :rage:


#15

Here is the app log showing the last 3 times the app executed. The first entry is from this morning (worked as it should), the second set of entries show the problem I described above and lastly the third set of entries show the times earlier that day. (worked as it should)

2015-09-24 10:38:51.863 AM EDT 3 hours ago APP NOTIFICATION message Door Unlocking
2015-09-24 10:38:51.600 AM EDT 3 hours ago APP NOTIFICATION message All of the Devices are at home
2015-09-24 10:29:09.588 AM EDT 3 hours ago APP NOTIFICATION message All Devices are currently away

2015-09-23 7:32:30.644 PM EDT 13 hours ago APP NOTIFICATION message null All of the Devices are at home
2015-09-23 4:56:18.629 PM EDT 16 hours ago APP NOTIFICATION message null Door Unlocking
2015-09-23 4:56:18.293 PM EDT 16 hours ago APP NOTIFICATION message null All Devices are currently away

2015-09-23 10:15:10.025 AM EDT 22 hours ago APP NOTIFICATION message null Door Unlocking
2015-09-23 10:15:09.689 AM EDT 22 hours ago APP NOTIFICATION message null All of the Devices are at home
2015-09-23 9:41:13.042 AM EDT 23 hours ago APP NOTIFICATION message All Devices are currently away