The problem is that the switchOnHandler and switchOffHandler events are being called when the switch is toggled automatically and when it’s toggled manually. How do I distinguish between the two cases?
That is exactly what I’m looking for but unfortunately evt.source keeps showing up as “DEVICE” in my event handler. I’ve tried 3 ways to turn the switch on: 1) using the Android app 2) calling sw.on(), and 3) manually pressing the switch. Unfortunately, evt.source always returns “DEVICE”.
Has anyone got this to work or any ideas what I’m doing wrong?
George, thank you for that idea. I tested with evt.isPhysical() and it always returned false, so that didn’t work.
For now, I’ve found an ugly workaround/hack by recording the time just before the app calls “switch.on()” and checking again in the switch.on event handler. If the two times are within a few seconds, I assume the event handler was called by the app. It’s not perfect, but it’s close enough for my purposes.
BTW, I have a SmartApp that’s now checked into github that I’d like to share. What’s the best way to announce or share this?
This would be useful. I want to automatically turn on a light when there is motion unless it has recently been turned off manually. Otherwise you end up fighting ST when you want the light off. I put in a delay in a CoRE Piston so that it won’t be turned on if it has recently been changed, but that isn’t ideal. If a Piston turned off the light due to lack of motion, it won’t come on until the delay is up. If I could distinguish between a manual flip and the Piston I could avoid this issue. . . .
I never could identify a physical press of the button based on the suggestions above but I’ve finally got my app to work using the workaround I mentioned above.
If you’re interested, my source code is at
and you can see the workaround I used in the switchHandler() event handler.
As for the SmartApp, it allows turning on/off a fan based on motion, manual button presses, and temperature offset between two rooms. Even though there seem to be a lot of fan related SmartApps, I couldn’t find any that did exactly what I needed which is why I wrote this.
There’s an anther workaround that I use.
Each time my app calls for on/off on any device it declares some variables which can be compared in the handler to figure out what happened:
def SwitchesOn(){
// declare 2 variables
state.TurnedOnByTheApp = 1
state.TurnedOffByTheApp = 0
switches?.on()
}
def SwitchesOff(){
// declare 2 variable
state.TurnedOnByTheApp = 0
state.TurnedOffByTheApp = 1
switches?.off()
}
/// handler will now know whether the command came from within the app or
def SwitchHandler(){
if(evt.value == "on" && state.TurnedOnByTheApp = 0){
log.debug "This command did not come from within the app"
//
else {
log.debug "This command came from within the app"
}
if(evt.value == "off" && state.TurnedOffByTheApp = 0){
log.debug "This command did not come from within the app"
else {
log.debug "This command came from within the app"
}
}
for the rest, you need to figure out under which conditions you want each variable to be reset. For instance, I use this principle in a multi thermostat manager that I wrote so I can override its settings and undo the override just by either turning on/off one of my thermostats, or by changing its temperature set points, which leads to a laborious and complex set of comparative loops, using sets of arrays. If anyone is interested I can share this code, it would actually greatly help to learn a bit more on how to simplify it… I’ve been working on this for a while now and it starts to be quite stable… but I went through hell, especially when my wife ended up sweating or freezing while I was working on it at night…
anyone had any luck with this? I’ve been trying to see if there’s anything I could use to differentiate a command from the physical switch or my phone (either smartthings app, iphone integration, etc.). as discussed here, the source is always DEVICE, physical is always false, etc.
most of my commands come from the json API (integrated with my iphone home kit)… I was wondering If I could inject something there when it triggers the device, so I could parse on the CoRE rule code and set this as “not physical”…