Subscribe to Zooz ZEN71 switch not working

Logs showing problem:

Code of application "Night Light":

/*
 * Night Light switch controller
 *
 * This controls a Kasa TP-Link smart color bulb to act as a nightlight during the night
 * The switch is expected to be an on-off pushbutton that controls the on/off state of the bulb
 * Night time variable is a Hub Variable that is set true at night, and false during the day.
 *   Use a couple of rules in Rule Machine to switch it at sunrise and sunset.
 * The bulb is the light bulb to control.  As written, this works with Kasa TP-Link bulbs,
 *   connected via the Kasa Integration package.  You may well need to change controlBulb()
 *   at the bottom to work with other bulbs.  It should be obvious what goes where.
 * Nightlight colors are the HSL for the nightlight setting.  This is very Kasa specific and
 *   might well need changing for other bulbs.  In particular a white only LED bulb might only
 *   have a level setting.  You'll need to adjust as needed for your setup.
*/

import groovy.transform.Field

@Field final int ON_BUTTON = 1
@Field final int OFF_BUTTON = 2

definition(
    name: "Night Light",
    namespace: "dgnuff",
    author: "David Goodenough",
    description: "Smart LED nightlight controller",
    category: "Utility",
    iconUrl: "",
    iconX2Url: ""
)

preferences
{
    section("Switch to read:")
    {
        input "theswitch", "capability.pushableButton", required: true, title: "Select"
    }
    section("Night Time variable:")
    {
        input "nighttime", "capability.sensor", required: true, title: "Select"
    }
    section("Night light to control:")
    {
        input "theNightlight", "capability.colorControl", required: true, title: "Select"
    }
    section("On/off lights to control:")
    {
        input "theOnOfflights", "capability.colorControl", required: false, multiple: true, title: "Select"
    }
    section("Nightlight color:")
    {
        input "nightLightHue", "int", title: "Hue", required: true, range: "0..100"
        input "nightLightSaturation", "int", title: "Saturation", required: true, range: "0..100"      
        input "nightLightLevel", "int", title: "Level", required: true, range: "0..100"
    }
}

def installed()
{
    log.debug "Installed with settings: ${settings}"
    initialize()
}

def updated()
{
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    initialize()
}

def initialize()
{
    subscribe(theswitch, "pushed", pushHandler)
    subscribe(theswitch, "held", pushHandler)
    subscribe(nighttime, "variable", nightHandler)
    state.isOn = false
}

def pushHandler(evt)
{
    log.debug("pushHandler called button $evt.value")
    def isOn = state.isOn;
    state.isOn = evt.value.toInteger() == ON_BUTTON
    def newIsOn = state.isOn
    log.debug("pushHandler says isOn changed from $isOn to $newIsOn")
    controlBulbs()
}

def nightHandler(evt)
{
    log.debug "nightHandler called"
    runIn(5, "controlBulbs")
}

def controlBulbs()
{
    String isNightStr = nighttime.currentValue("variable")
    boolean isNight = isNightStr == "true"
    
    theOnOfflights.each{ bulb -> controlBulb(bulb, true, isNight) }
    controlBulb(theNightlight, false, isNight)
}

def controlBulb(bulb, isOnOff, isNight)
{
    log.debug "controlNightBulb() isOn $state.isOn isNight $isNight"
    if (state.isOn)
    {
        log.debug "controlNightBulb on"
        bulb.setColorTemperature(2700, 100, 0)
    }
    else if (isNight && !isOnOff)
    {
        log.debug "controlNightBulb night $nightLightHue, $nightLightSaturation, $nightLightLevel"
        Map color =
        [
            hue: nightLightHue.toInteger(),
            saturation: nightLightSaturation.toInteger(),
            level: nightLightLevel.toInteger()
        ]
        bulb.setColor(color)
    }
    else
    {
        log.debug "controlNightBulb off"
        bulb.off()
    }
}

That should be enough to reproduce the issue, assuming it can be reproduced. You might want to fiddle with the logic in controlBulb() to make it work with other bulbs, so far the only ones I've tried are TP-Link Kasa KL125's, mostly because that's all I have at the moment.

Also, I find that Hue 45, Saturation 100 and Level 2 are reasonable parameters for nightlight mode, your actual mileage may vary.

"Test Switch" is a Zooz ZEN71 switch, I've got the "Zooz ZEN Switch Advanced" driver by jtp10181 installed, but I'm not sure if that's picking up the switch, I may be using the generic Z-Wave driver instead. It shouldn't make any difference, all I want to do is detect when the paddles on the switch are pressed, nothing fancy at all.

The logs show the problem. As can be seen in the App code, I've subscribed to "pushed" and "held" events for "Test Switch". There are info lines in the log showing "Test Switch" being turned on and off, these correspond to presses on the two paddles. However the log.debug() call at the top of pushHandler(evt) is never invoked, meaning my handler isn't getting called.

The weird thing is that if I use a ZEN34 remote switch with Zooz's own "Zooz Remote Switch ZEN34 Advanced" driver, everything works correctly.

So what's the difference between the ZEN34 that works, and the ZEN71 that doesn't? And how can I force the ZEN71 to use jtp10181's driver?

This could actually make a difference--the Generic Z-Wave Switch driver may not generate button events on button pushes (normally CentralScene commands coming in from the Z-Wave device, how most handle taps/multi-taps). The custom driver I assume you're using does, though it's always helpful if you can provide a link to the thread driver authors normally make for their code or the code itself to be sure.

I don't see any button events for the device in question in your logs. The switch on/off events are different, though unless you're using settings on the switch that disable local control or certain kind of "smart bulb modes" (don't think the Zooz ones are affected), they'll normally coincide. Your code also looks correctly written in this regard, and you've demonstrated that it works correctly with a different device and driver. So, my guess is that this isn't really the problem. (Logs could by lying, you could have info/descriptionText logging disabled, or the driver author could have made a mistake and not followed logging convention, so it's also worth noting that you can check an authoritative source under the "Events" button at the top of the device page. If you don't see the exact event you're subscribing to, then that is your problem.)

To ensure your device is actually using this driver, make sure it's selected under the "Type" field under the "Device Information" section on your device page. It's often a good idea to hit "Configure" (after you hit "Save Device") when switching drivers, so you may also want to do that here, too. I suspect this is your issue.

On a related note, I'm not sure if you ended up using the "Generic Z-Wave..." driver by manually choosing it; it should have paired with the "Zooz 700 Series Light Switch" driver by default. (I'm not sure if this driver parses the button events, so it could still be the case even if you're using this one. No need to guess what you're using--the device page will show, as above.) The community driver you alluded to should also work and will probably give you access to more features.

Hope this helps!

5 Likes

To get the "pushed" events if using my driver enable "Scene Control Events" in the settings, which is disabled by default. With that disabled you only get switch on/off events not the button "pushed" events.

If you enable description text logging all the button events should show up in the logs.

Towards the bottom of the device page is where you set the driver. The custom drivers are all the way at the bottom of the list or you can search by typing part of the name.

3 Likes

I'm not crystal clear what's going on here, but I do have it working now. The thing that has me puzzled is that if I set the type to "Zooz ZEN Switch Advanced" i.e. the name of your driver that I installed, the Scene Control option isn't visible. However if I select "Zooz Zen71 Switch", I can see the option in the preferences, and switching that makes everything work.

What has me beat is that in the Type selection, "Zooz Zen71 Switch" is a "System" type, which I assume means built in, while "Zooz ZEN Switch Advanced" shows as a User device, which is what I'd expect from an installed driver. Why is the option not visible when I use your driver?

All that said, the main thing is that I do have a working solution: we have a fully functioning nightlight in the bathroom. Thank you so much for the help.

Look up from where your last screenshot is. Middle section of the settings page. Once you find that setting, be sure it is Enabled by clicking in the box I circled. And save if you change it.

While I've edited my post a lot since you posted this, the issue is still a bit puzzling. When I initially switched it to use jtp10181's driver, that option wasn't visible. I've found it usually takes a couple of attempts switching back and forth between jtp10181's driver, and the system "Zooz Zen71 Switch" driver to get that to show. However, it usually shows up eventually, I had just been getting puzzled by the fact that it wasn't showing up immediately.

You have to press refresh or configure so the driver can detect which switch model it is and display the proper options. I should probably make it do that more automatically somehow, or give some sort of warning.

2 Likes

Ahh - that's the magic incantation I need. I had been relying on a random collection of reapplying the correct type, and refreshing the page, which would eventually get it to show. Since I'm going to be installing a fair number of these over the coming months, that's good to know.

1 Like