Help - zigbee momentary switch


#1

To begin with a confession - I know nothing of programming. But if pointed in the right direction, can copy & paste like its going out of style.

I used to use a Mimolite as a momentary switch to control my garage door. I had it disconnected from the GDO yesterday, and in a flash my cat Diesel ran off with it and dropped it in his water bowl. It's drying out in some rice, but I'm not hopeful.

So I pulled out a relay with a 120V coil, and decided to re-purpose a Securifi Peanut plug as a momentary switch to power the relay. There is a driver for this plug on GitHub that I modified to include momentary capability (Push) using Groovy examples I found.

It works well enough and I used it as a momentary switch in RM.

However, I also want to be able to make the physical button on the Peanut plug act like a momentary switch. I can do that using Rule Machine. Is there anyway to do that by modifying the device driver?

Thank you!


#2

This is actually a lot easier than you have made it. All you need to do is add the off command to the bottom of the on function and have it run in say, 1 second. Like this:

runIn(1,off)

That will turn the switch off 1 second after it turn on.


#3

That works when I tried it using the device page. Will it also work when I turn the switch on physically? (I'm at work - so I can't try that right now).


#4

Just find the section of code in the driver (i.e. the parse() routine) that recieves status updates from the Peanut when a change occurs, and add the runIn(1, off) command there. This way it should occur whether the device is operated manually (via physical button) or digitally via a Hubitat App. Both methods should result in the status of the device being reported back to Hubitat via the parse() function in the driver.


#5

Thank you. I'll do that (or something very similar).


#6

I just looked at the driver you linked above... Looks like you'll want to add some logic at about line 217/218. I added a /*** comment ***/ below in the area that I believe you should focus on.

def parse(String description) {

//	zigbee.ELECTRICAL_MEASUREMENT_CLUSTER is 2820
	log "description is: $description"
	def event = zigbee.getEvent(description)
	if (event) {
	    log "event name is $event.name"
		if (event.name == "power") {
			def powerValue
			powerValue = (event.value as Integer) * getPowerMultiplier()
			sendEvent(name: "power", value: powerValue)
			def time = (now() - state.time) / 3600000 / 1000
			state.time = now()
			log "powerValues is $state.powerValue"
			state.energyValue = state.energyValue + (time * state.powerValue)
			state.powerValue = powerValue
			// log "energyValue is $state.energyValue"
			sendEvent(name: "energy", value: state.energyValue)
		} else {
			sendEvent(event)

/***  Add your logic here to check if the 'event' was an 'on' event, and if so, call 'runIn(1, off)' ***/

		}
	} else if (description?.startsWith("read attr -")) {

#7

@ogiewon

That's exactly what I'll do. Thank you again!


#8

I did something like that (insertion right after line 187). Works great. Thank you and @Ryan780 very much!

I don't need most of what is in that driver. So, maybe this weekend, I'll simplify it down to the bare minimum that I need.

For now, I pleased as punch that there's enough code samples, and helpful folk like both of you, so even a total novice can achieve what's needed.

	if (event) {
	    log "event name is $event.name & event value is $event.value"
        if (event.name == "switch" && event.value == "on") {
            runInMillis(pulseLength * 1000, off)
            sendEvent(event)
        }
        else if (event.name == "power") {
			def powerValue
			powerValue = (event.value as Integer) * getPowerMultiplier()
			sendEvent(name: "power", value: powerValue)
			def time = (now() - state.time) / 3600000 / 1000

#9

Does your driver’s parse routine still handle the “off” event? Since you put the sendEvent() call inside your new if() block, I don’t see how it would still handle receiving an “off” Zigbee event.


#10

It does. I am parsing (event.name == "switch" && event.value == "on"). Therefore, I'm guessing that ("event.name == "switch" && event.value == "off") is picked up further down where there is another sendEvent(event).

In any event, it correctly displays on and off status.


#11

Got it. Yes, as long as you left the rest of the code the same, it should work as desired.

Glad to hear it’s working! Hopefully the rice does the trick on your Mimolite.


#12

I don't have much hope. I didn't realize he dropped in there until at least 10 minutes later. I spent most of time checking under the beds, which are Diesel's favorite spots for his loot.