Zigbee Switch DH not triggering zigbee.on/off methods() inside eventhandler?

Hi all, I have a spare zigbee on-off switch lying around, which I thought I’d use for opening my garage door, yet I’m looking to make it behave as a momentary switch, rather than the on-off toggle switch it behaves like per default. The switch runs on the standard “Zigbee Switch” device handler. I’m attempting to mod a copy of that DH to implement a “flick” function, basically doing this:

  1. turn switch on
  2. wait a couple of seconds
  3. turn switch off

Browsing the community I see some folks have worked on this already. Taking a couple of clues, I’ve implemented a push() method to support a momentary close>open of the switch. Not 100% sure if this is the right way to go about it, yet the method seems to trigger just fine, according to the debug log. Here’s what’s weird. The regular zigbee.on() and off() methods work just fine on their own, but when I use them inside my own event-scheduled method, they seem to have no effect?

I would be most grateful if someone would lend a pair of eyeballs to my DH and explain what I’m doing wrong and give me a nudge in the right direction. Thanks a bunch in advance. Code below:

metadata {
definition (name: “ZigBee Switch PLUS”, namespace: “MySpaceHaha”, author: “MeSomeWhat”, ocfDeviceType: “oic.d.switch”, runLocally: false, minHubCoreVersion: ‘000.019.00012’, executeCommandsLocally: true) {
capability “Actuator”
capability “Configuration”
capability “Refresh”
capability “Switch”
capability “Health Check”
capability “Momentary”

    fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006"
    fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "0003, 0006, 0019, 0406", manufacturer: "Leviton", model: "ZSS-10", deviceJoinName: "Leviton Switch"
    fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "000A", manufacturer: "HAI", model: "65A21-1", deviceJoinName: "Leviton Wireless Load Control Module-30amp"
    fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006", outClusters: "0003, 0006, 0008, 0019, 0406", manufacturer: "Leviton", model: "DL15A", deviceJoinName: "Leviton Lumina RF Plug-In Appliance Module"
    fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006", outClusters: "0003, 0006, 0008, 0019, 0406", manufacturer: "Leviton", model: "DL15S", deviceJoinName: "Leviton Lumina RF Switch"
    fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Plug 01", deviceJoinName: "OSRAM SMART+ Plug"
    fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0B05, FC01, FC08", outClusters: "0003, 0019", manufacturer: "LEDVANCE", model: "PLUG", deviceJoinName: "SYLVANIA SMART+ Smart Plug"
}

// simulator metadata
simulator {
    // status messages
    status "on": "on/off: 1"
    status "off": "on/off: 0"

    // reply messages
    reply "zcl on-off on": "on/off: 1"
    reply "zcl on-off off": "on/off: 0"
}

tiles(scale: 2) {
    multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
        tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
            attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
            attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
            attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
            attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
        }
    }
    standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
    }
    standardTile("push", "device.push", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", label:"Flick", action:"momentary.push", icon:"st.secondary.activity"
    }
    main "switch"
    details(["switch", "refresh","push"])
}

}

// Parse incoming device messages to generate events
def parse(String description) {
log.debug “description is $description”
def event = zigbee.getEvent(description)
if (event) {
sendEvent(event)
}
else {
log.warn “DID NOT PARSE MESSAGE for description : $description”
log.debug zigbee.parseDescriptionAsMap(description)
}
}

def off() {
log.debug “*** OFF!!”
zigbee.off()
}

def on() {
log.debug “*** ON!!”
zigbee.on()
}

// —here are the bit’s I’ve glommed on ---------------------------------------------------------------------

def startTimer(ms) {
log.debug “*** DelayTimer: start”
def now = new Date()
def runTime = new Date(now.getTime() + ms)
runOnce(runTime, offEventHandler)
}

def offEventHandler() {
off()
log.debug “*** DelayTimer: time to turn off”
}

def push() {
on() // turn the thingymagoo on for a bit
log.debug “*** Flick begin”
startTimer(2000) // schedule 2 sec into the future to turn off
}

/**

  • PING is used by Device-Watch in attempt to reach the Device
  • */
    def ping() {
    return refresh()
    }

def refresh() {
zigbee.onOffRefresh() + zigbee.onOffConfig()
}

def configure() {
// Device-Watch allows 2 check-in misses from device + ping (plus 2 min lag time)
sendEvent(name: “checkInterval”, value: 2 * 10 * 60 + 2 * 60, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])
log.debug “Configuring Reporting and Bindings.”
zigbee.onOffRefresh() + zigbee.onOffConfig()
}

Have you checked the debug output when you execute the push?

Hi Tony, yes - I added a bunch of debug messages just to test that my code indeed is begin triggered. Here is what happens in the log:

nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:21 PM: debug *** DelayTimer: time to turn off
nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:21 PM: debug *** OFF!!
nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:18 PM: debug *** DelayTimer: start
nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:18 PM: debug *** Flick begin
nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:18 PM: debug *** ON!!
nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:18 PM: debug *** Flick begin
nnnnnnnn-c95d-4cc8-nnnn-nnnnnnnnnnnn 10:48:18 PM: debug *** ON!!

As you can see the timer schedule works fine, albeit with a slightly longer delay. The on() and off() functions never seems to be called though. I also tried to call zigbee.on() and zigbee.off() directly, however that doesn’t make any difference unfortunately.

If anyone can tell me what I’m doing wrong, I’d be very happy.
Thanks,
Max

did you ever work this out? I am having a similar problem. I want to put another button in the dth that can turn the switch on and off but although the log shows that the method has been fired the switch does not turn on.
I am using zigbee.on() to try and get it to work but it doesn’t.
Weird thing is though that it works in another method in the same dth.

Hi Mike, as a matter of fact, I did manage to slap something together which did the trick. I abandoned the eventhandler approach as it never seemed to invoke the second zigbee.off and I never figured out why. I found a better way, using the delayBetween() function.

Have a look at my github for the DHT I’m using now.

Note: to begin with, all I wanted was just something that could trigger a switch mounted in parallel with the garage door button for a second. Now with the ability to configure the pulse-length per thing it’s much more versatile: I have now have switches controlling power to various solenoid valves, which run sprinklers, patio misters and a pool shower. As mentioned in the source, it’s not perfect as you must configure the pulse length before using it.

Hope it works for you. Happy New Year
/Max

Hi Max,
That’s pretty sweet. I like it (might have to steal bits of it!).
Just before I read you reply I actually managed to get it to work. Really don’t understand why though.
It appears that if you put a log.debug event immediately after a zigbee.on() then the zigbee.on() will not work. I swapped the commands over (really out of being lazy when typing and couldn’t be arsed to cut and paste) so the log.debug was before the zigbee.on() and it just works. Very strange but it seem ST is full of these little quirks.

Huh, how about that! I spent the better part of a day moaning over why the F the thing didn’t work as advertised . Never occurred to me the debug calls were the culprit. Indeed another samsung lovebite, I suppose, lol.

Steal away good sir, yet give a shout if you make something cool (i.e. re-stealable :wink:

SmartThings automatically calls sendHubCommand if a HubAction is returned from a command method, otherwise you have to call it yourself. Similarly it calls sendEvent() if the result of a createEvent() is returned from parse(), otherwise you have to do it yourself.

Maybe this is the same concept and the zigbee commands are actually providing a return value rather than actually sending the commands. I don’t know but it seems plausible.

I’ll tell you what I am making, I actually wish I had written more about it from the start but it has been a very slow process and just me trying to learn some stuff.

I wanted to create an indicator led to light up when the dog needs feeding. That way he doesn’t get fed twice. I know there are several easier ways of doing it but that’s what I wanted.

So, I have taken apart an Ikea Tradfri GU10 bulb and stole the zigbee chip from it. Got the idea from someone on here who did it with a cree bulb but you can’t get cree in the UK. So I can power the chip and a standard 5mm green led with as low as 1.9v so I intended it to be run from 2 AA batteries but that turned out not feasible as it would only last 4 days before dying and normally when it died the waining power would cause it to factory reset and not connect again after fresh batteries.
So with a new 3v power supply I have been tinkering. I also managed to find a duo-led (3 pins, common ground and one pin for green and one pin for red) so then by adding an NPN transistor I created a NOT gate so if the green led was not on then the red was. in doing this I found that I could actually create an orange/yellow colour by lowering the dimming level on the green as the red would also fade up.

Hence why I found your post as I was trying to modify the standard Zigbee dimming bulb to set the level when I pressed a button on the tile.
I have managed to finish it this evening although I am still not completely satisfied and will still tinker with it for a while.

I started to write about it a while ago here but gave up for a while. Might go update it now.

The device handler code is not working as momentary switch. I tried.

Well, full disclosure I kinda abandoned the idea anyway as I’ve migrated the functionality to Webcore. Instead of a tweaked DTH, I’m just having a piston running a statement like this

if garagedoor’s switch stays on for more than 1 second
then
with garagedoor do
turn off
endwith
endif

I guess you can say this is a Webcore implementation of the most useless machine in the world :slight_smile: which converts a regular switch to a pushbutton

Can you share me the handler for Zigbee switch relay which should act as a momentary switch to open the garage door.