Switch Event Handler: Discerning One Press or Two

I am trying to create a SmartApp that is essentially a combination of ‘The Big Switch’ and ‘Double Tap’. The behavior I am looking for is:

On single press do X
On double press do Y; but NOT X

Obviously the first press always falls through initially, so a double press does X and Y. I have tried putting a ‘pause’ in the event handler to wait for the second press (if present), but that seems to block any additional events.

How can I look for a double press first? and if not present, then execute X.

Have you tried this: schedule X using runIn() after first press, then if second press, unschedule X and execute Y?

That’s a thought. I wonder what the average latency on schedule and unschedule is. Guess I’ll find out. (c;

@geko Well it works… sort of.

It seems ‘runIn’ won’t actually set a schedule unless it is set for 60 seconds or more. Really don’t want to have to wait a whole minute for X to be executed via a single press.

Any other thoughts?

So, what you want is a delay after first press to wait xx seconds before firing first press command but if 2nd press occurs within xx seconds then first only double press?

What I would do is something like this:

On first press, log the datetime of first press
start a timer for xx seconds

On second press, check if datetime of this press is within xx time of first press datetime
if yes, fire double press event, set var for double press = true

On end of timer, check for double press == true
if not, then fire single press event.

Or, just get last two events from button press, compare times and do one or the other based on time difference :smile:

1 Like

Well… that’s what I am struggling with; how to set a timer, that when it times out I send the single press event.

Will runOnce() do it? Just set the timeToday() + 30 seconds…

Looking at the canned DoubleTap app, it looks like when it sees an “on” tap, it looks in the log for the device to see if there’s been recent activity and if there’s two “on” taps within the recently time allowed then it acts on the double tap instructions.

It might be possible to do the same thing but look for NO additional press within the time allotted.

That throws an error. But this seems to be working reliably:

import groovy.time.TimeCategory
def switchHandler(evt) {
    log.debug "in event handler"
    if (state.gotON) {
        unschedule()
    	fireDouble()
    } else {
    	state.gotON = true
        def timer = new Date()
		use(TimeCategory) {
    	timer = timer + 3.second
		}
    	runOnce(timer, "fireSingle")
    }
}

def fireSingle() {
    log.debug "firing single"
    state.gotON = null
}

def fireDouble() {
    log.debug "firing double"
    state.gotON = null
}

UPDATE: Yup… working like a charm. See this post for more info and the final app.

I get an error whenever I try to use any interation of unschedule(). It seems like this is a job for the java.util.timer, but for some reason creating an instance of that is not allowed.

This worked… albeit I haven’t used it in quite some time. Seems SmartThings broke a lot of things in the recent platform update. What you’re seeing may be due to one of them.

Thanks…any idea how you pass a parameter on to the function you are running in runonce? like runOnce(timer, doThis(val))

?

Dunno. There is no example of that in the docs. Have you tried ‘doThis(value)’?

If it doesn’t work you’ll need to use a variable or state prior to calling it to change what happens in ‘doThis’

My problem was trying to use those functions in a device type. Device types are even more limited than apps, and there do not seem to be any delay or timer functions whatsoever.