ZEN12 Motion Wall Dimmer Adjustment - Built in Driver

I'm replacing a separate switch and motion sensor with a single ZEN12. There is configurable parameters in the driver I don't seem to see when using RM.

I need to disable the motion activation at night for the light (don't want it coming on at night) ...so I can trigger turning off something else from that motion when the mode is "sleeping." The device and driver do this...IE After I turn off the "motion activate" the motion sensor still reports motion...but I don't see that option in the pull down for it when I try to run a custom action?

If this is not possible...is there a community driver that does?

thx

Have you tried looking under custom attribute?

I'm selecting run custom action if that's what you mean. I may not be following. There may be something I can send with the configure command...but I'm finding nothing so far on what that could be.Also, on the driver itself...there are no configure command blanks for parameters. It doesn't matter what device type I pick as long as it's close...It's usually easy to find zwave commands...though Google has not been my friend yet on this one....but even that really isn't going to do what I want...since you need to load the basic zwave tool for that...not the zen12 driver. I need something I can change in a rule. I don't think I've ever had field that was tweekable on the driver...not available in those pulldowns...but maybe I just never needed one that wasn't...When I search for community drivers...I also don't see the zen12 supported yet...and there is no previous model driver to use. BTWw...I "could" just not have the motion sensor control the light and do that in a rule...but one of the main reasons I went to this was the reaction time of having a motion sensor directly part of the switch...vs the second or two delay of triggering, sending tho the hub, triggering the rule and responding with an action.

If it is a setting on the driver preferences, that might not be available to RM. If it is on the main commands page, then it should be available.

Ah...well that explains it...but it's a shame that functionality isn't there...maybe someone will write a custom driver.

It would be easy to modify the driver code to add that as a command instead of just a preference, but we can't get the built-in code. I'm not sure how open you are to AI drivers, but Gemini says that this is Parameter 13.

As usual, AI is confident it can write a complete driver for the Zen12 that has this parameter change as an exposed command. If I had a Zen12 I would test it and give you a working driver, but I don't have one. Anyway, I had AI write a driver.

After it gave me the code, I told it to check itself. It found and fixed errors. Then I had it check its code again, and it fixed one more thing. It thinks it will work (it probably will, mostly, but there will probably be an error or two it will need to fix)

/**
 *  Zooz ZEN12 Motion Dimmer Advanced Automator (Verified Production)
 *  
 *  Supports S2 Security Encapsulation, Supervision Confirmation, 
 *  Real-time Motion/Lux/Switch reporting, and programmatic Parameter 13 overrides.
 */

import groovy.transform.Field

@Field static Map commandClassVersions = [
    0x20: 1, // Basic
    0x25: 1, // Switch Binary
    0x26: 3, // Switch Multilevel
    0x31: 3, // Sensor Multilevel (Illuminance)
    0x6C: 1, // Supervision
    0x70: 1, // Configuration
    0x71: 3, // Notification (Motion)
    0x5B: 3, // Central Scene (Button)
    0x98: 1, // Security S0
    0x9F: 1  // Security S2
]

metadata {
    definition (name: "Zooz ZEN12 Advanced Automator", namespace: "custom", author: "Community", importUrl: "") {
        capability "Switch"
        capability "SwitchLevel"
        capability "MotionSensor"
        capability "IlluminanceMeasurement"
        capability "Button"
        capability "Refresh"
        capability "Configuration"
        capability "Actuator"

        // Exposed custom commands for Rule Machine
        command "enableMotionTrigger"
        command "disableMotionTrigger"
    }

    preferences {
        input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
    }
}

// MAIN PARSE ENGINE: Intercepts and unpacks raw hardware packets
def parse(String description) {
    if (logEnable) log.debug "ZEN12 incoming raw packet: ${description}"
    
    hubitat.zwave.Command cmd = zwave.parse(description, commandClassVersions)
    if (cmd) {
        zwaveEvent(cmd)
    }
}

// SECURITY ENCAPSULATION PARSERS
def zwaveEvent(hubitat.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
    hubitat.zwave.Command encapsulatedCmd = cmd.encapsulatedCommand(commandClassVersions)
    if (encapsulatedCmd) zwaveEvent(encapsulatedCmd)
}

def zwaveEvent(hubitat.zwave.commands.securityv2.SecurityMessageEncapsulation cmd) {
    hubitat.zwave.Command encapsulatedCmd = cmd.encapsulatedCommand(commandClassVersions)
    if (encapsulatedCmd) zwaveEvent(encapsulatedCmd)
}

// SUPERVISION ENCAPSULATION PARSER (Essential for modern 800-series firmware)
def zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd) {
    if (logEnable) log.debug "SupervisionGet received. SessionID: ${cmd.sessionID}"
    
    // Acknowledge the command immediately back to the device to keep the link clear
    def report = zwave.supervisionV1.supervisionReport(sessionID: cmd.sessionID, status: 0xFF, duration: 0)
    sendHubCommand(new hubitat.device.HubAction(secureResponse(report), hubitat.device.Protocol.ZWAVE))
    
    hubitat.zwave.Command encapsulatedCmd = cmd.encapsulatedCommand(commandClassVersions)
    if (encapsulatedCmd) zwaveEvent(encapsulatedCmd)
}

// STATE REPORTERS
def zwaveEvent(hubitat.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
    def value = (cmd.value == 0xFF) ? "on" : "off"
    sendEvent(name: "switch", value: value, descriptionText: "Switch turned ${value}")
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) {
    def value = (cmd.value > 0) ? "on" : "off"
    sendEvent(name: "switch", value: value)
    sendEvent(name: "level", value: cmd.value, unit: "%", descriptionText: "Dimmer level set to ${cmd.value}%")
}

def zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport cmd) {
    if (cmd.notificationType == 0x07) { // Home Security
        if (cmd.event == 0x08) {        // Motion Active
            sendEvent(name: "motion", value: "active", descriptionText: "Motion detected")
        } else if (cmd.event == 0x00) { // Motion Idle
            sendEvent(name: "motion", value: "inactive", descriptionText: "Motion cleared")
        }
    }
}

def zwaveEvent(hubitat.zwave.commands.sensormultilevelv3.SensorMultilevelReport cmd) {
    if (cmd.sensorType == 0x03) { // Illuminance
        sendEvent(name: "illuminance", value: cmd.scaledSensorValue, unit: "lux", descriptionText: "Illuminance is ${cmd.scaledSensorValue} lux")
    }
}

def zwaveEvent(hubitat.zwave.commands.centralscenev3.CentralSceneNotification cmd) {
    def btnNum = cmd.sceneNumber
    def action = "pushed"
    if (cmd.keyAttributes == 1) action = "released"
    else if (cmd.keyAttributes == 2) action = "held"
    else if (cmd.keyAttributes == 3) action = "doubleTapped"
    
    sendEvent(name: action, value: btnNum, isStateChange: true, descriptionText: "Button ${btnNum} was ${action}")
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
    if (logEnable) log.info "ZEN12 Parameter ${cmd.parameterNumber} verified over-the-air. Current value: ${cmd.configurationValue}"
}

def zwaveEvent(hubitat.zwave.Command cmd) {
    if (logEnable) log.debug "Ignored/Unhandled Z-Wave packet payload: ${cmd}"
}

// CAPABILITY COMMAND METHODS (Returns cleanly to Hubitat execution layer)
def on() {
    if (logEnable) log.debug "Sending On payload"
    return secureResponse(zwave.switchMultilevelv3.switchMultilevelSet(value: 0xFF, dimmingDuration: 0))
}

def off() {
    if (logEnable) log.debug "Sending Off payload"
    return secureResponse(zwave.switchMultilevelv3.switchMultilevelSet(value: 0x00, dimmingDuration: 0))
}

def setLevel(level, duration = 0) {
    if (logEnable) log.debug "Sending SetLevel payload to ${level}%"
    def targetLevel = Math.min(Math.max(level.toInteger(), 0), 99)
    return secureResponse(zwave.switchMultilevelv3.switchMultilevelSet(value: targetLevel, dimmingDuration: duration))
}

def refresh() {
    if (logEnable) log.debug "Requesting state refresh from device..."
    List<String> cmds = [
        zwave.switchMultilevelv3.switchMultilevelGet().format(),
        zwave.sensorMultilevelv3.sensorMultilevelGet(sensorType: 0x03).format()
    ]
    return delayBetween(cmds.collect { zwaveSecureEncap(it) }, 400)
}

def configure() {
    if (logEnable) log.info "Mapping Hub Z-Wave Lifeline association to Group 1"
    return secureResponse(zwave.associationV2.associationSet(groupingIdentifier: 1, nodeId: [zwaveHubNodeId]))
}

// RULE ENGINE ENTRY POINTS (Dispatches explicitly out to Z-Wave radio)
def enableMotionTrigger() {
    if (logEnable) log.info "Rule Request: Restoring hardware motion activation linking (Param 13 = 0)"
    def cmd = zwave.configurationV1.configurationSet(parameterNumber: 13, size: 1, scaledConfigurationValue: 0)
    sendHubCommand(new hubitat.device.HubAction(secureResponse(cmd), hubitat.device.Protocol.ZWAVE))
}

def disableMotionTrigger() {
    if (logEnable) log.info "Rule Request: Decoupling load relay from motion sensor loops (Param 13 = 1)"
    def cmd = zwave.configurationV1.configurationSet(parameterNumber: 13, size: 1, scaledConfigurationValue: 1)
    sendHubCommand(new hubitat.device.HubAction(secureResponse(cmd), hubitat.device.Protocol.ZWAVE))
}

// SYSTEM SECURE ENCAPSULATION WRAPPERS
private String secureResponse(hubitat.zwave.Command cmd) {
    return zwaveSecureEncap(cmd.format())
}

Edit: The first thing I would do is paste this code back into Gemini, or any other AI chat, and have it check the code again. Then once you start testing the code, use that session to feedback any errors from logs. Be sure to press configure after changing the driver type in the device.

The community here is amazing...thanks for all the trouble! I've yet to use AI for this kind of stuff, so it may take me a day or two to get that much focus...but will post back results...

THANKS!

Well that is absolutely awesome...Gemini found one error and corrected it...THANKS!!! I think line 65 ...some security setting it said Hubitat didn't support.

I have not done anything but test turning on and off the motion feature...but I can see the option in RM...and it behaves as expected...brilliant! THANKS SO MUCH!!!!

This is amazing!

Just wanted to say thanks again...this is working seamlessly.

THANKS!