a4refillpad / Xiaomi

my Xiaomi Device Handlers for Smartthings
Apache License 2.0
248 stars 1.85k forks source link

Enhancement: Zigbee Buttons - Double Tap #9

Open mpartoglou opened 6 years ago

mpartoglou commented 6 years ago

Hi @a4refillpad , Thanks so much for creating such robust device handlers for the Xiaomi products. I am loving it and have found them to be extremely reliable.

I use and love the buttons capability to control so much via single / hold options, plus even more utilising CoRe to add the time dimension.

I had a feature enhancement request: double tap for the Zigbee Buttons.

I've never written Groovy - I have had a thought as to logically how it could be added (no clue if what I wrote would even compile), but it seems the code could support a "double tap" type feature. I am not sure how to update the rest of the code to enable it be used across CoRe etc.

attribute "previousPress" "string" //I am unsure if this is possible / how to get it (given I can see this in SmartThings history, I am assuming this could be obtained through some mechanism)

private createButtonEvent(button) {
    def currentTime = now()
    def startOfPress = device.latestState('lastPress').date.getTime()
    def timeDif = currentTime - startOfPress
    def holdTimeMillisec = (settings.holdTime?:3).toInteger() * 1000

// my additional various
    def previousPress = device.latestState('previousPress').date.getTime() 
    def timeDifPreviousPress = currentTime - previousPress

    if (timeDif < 0) 
        return []   //likely a message sequence issue. Drop this press and wait for another. Probably won't happen...

//my simple logic to check if the last two presses occurred in the hold time
    else if (timeDif <holdTimeMillisec & timeDifPreviousPress < holdTimeMillisec)
        return createEvent(name: "button", value: "double tap", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was double tapped", isStateChange: true)

    else if (timeDif < holdTimeMillisec) 
        if (
            return createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
    else 
        return createEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true)
}

I would test it myself, but I have no idea how to get the Previous Press time.