On/Off Event Handlers not working consistently

I can not seem to get on switch.on, swithch.off handlers to fire EVERY time when a change occurs. At the start I can turn on the virtual switch and the onHadler is called. Follow this by turning off the switch and the offHandler is called. After that anything is possible. Most of the time the handlers are not called immediately thereafter. Only way to get everything working again is to turn on then off then on again. Switching to off may cause the offHandler to be called but for certain the subsequent on will fail.

Here is the code

    subscribe(theLight, "switch.on", onHandler)
    subscribe(theLight, "switch.off", offHandler)


def onHandler(evt) {
    log.info "Modem will be monitored every $theSeconds Seconds"
    sendPush("Modem will be monitored every $theSeconds Seconds")
    atomicState.doMonitor=true
    runNotifyAt(now() + (theSeconds * 1000))
}

def offHandler(evt) {
    log.info "Modem will be not be monitored"
    sendPush("Modem will be not be monitored")
    atomicState.doMonitor=false
}

def runNotifyAt(timeMs) {
    def date = new Date(timeMs)
    runOnce(date, checkEastlinkModem)
}


def checkEastlinkModem() {
	if (atomicState.doMonitor == true) {
        def url="http://xxxx.xxxx.xxx/xxx/xxx.html"
        def theStatus=-1
        try {
        httpGet(url) {response ->
            def cnt = 0
            theStatus=response.status
            }
        }
        catch(e) {
        }
       log.info "Current Modem Status Test Result = $theStatus"
       runNotifyAt(now() + timeMS)
	}
}

Does anyone see anything obviously wrong?

1 Like

So it appears last call to runOnce() is the issue. I added the following line to the offHandler() function which removes the last runOnce(). All seems good after that. So my offHandler() now looks like

def offHandler(evt) {
    log.info "Modem will be not be monitored"
    sendPush("Modem will be not be monitored")
    atomicState.doMonitor=false
   runNotifyAt(now() + 100)
}

Is there a better way to remove the last runOnce() from queue???

Are you basing that off of the application not doing what you’re expecting to happen or the info messages shown in live logging?

SmartThings doesn’t support using runIn/runOnce commands from within methods executed by runIn/runOnce commands. It will execute the method the first time, and it will sometimes execute for a little while, but it always stops working eventually.

You need to use either runEveryX or schedule (i think that’s the command for cron jobs, but check the docs) and you can stop the schedule by using “unschedule()”

I changed all scheduling to runEveryXMinutes() but I still had issues. I then stripped the code only retain the subscribe and on/offHandler functions. Same problem. Sometimes the handlers will be called other times nothing.

I eventually rewrote the app without the on/off handlers and location.mode. i.e. If the location.mode contains “Away” then dosomething() else doNothing().

not sure when you want to check after an event or regualy?

i would have this as runIn (settings.theSeconds, checkEastlinkModem)
im assuming you only want to run an this based of a subscribe to event

© 2019 SmartThings, Inc. All Rights Reserved. Terms of Use | Privacy Policy

SmartThings; SmartApps®; Physical Graph; Hello, Home; and Hello, Smart Home are all trademarks of the SmartThings, Inc.