Change driver in child device

I have a Zen17 relay which creates two child device drivers of type "Generic Component Switch".

I was hoping to change the child device drivers to a custom one which includes the lock/unlock capability. I use the Zen17 to turn off/on two magnetic locks so would prefer them shown as locks in automation rules.

Do I have to create my own device handler for the parent and child devices?

Yes.

You could possibly write a dummy parent driver with its only purpose is to delete the child and re-create it with your desired driver (or create it with isComponent:false so the driver can be changed). Your child driver would need to have all the proper functions and calls to interact with the parent. I have found the example drivers follow the Hubitat "standard" function names for parent childs and was able to make a simple one myself for something else. Make sure you use the same "DNI" as the stock driver so it will recognize it. Once that is done switch back to the stock parent driver. Worth a shot.

Thanks for the idea, I haven't dived yet into writing my own z-wave driver or 'companion'.

Most likely I'll find inspiration from your driver :slight_smile:

The way I understand the Zen17 is it will change zwave packets it sends depending on the zwave parameters. I wonder if it woudn't be simpler to just create a Child Device that implements all zwave capabilities. In a way, a relay can act as Lock, Switch, Contact Sensor, etc... it can be all those things, whatever you can power on/off.

Hang on... Let's try to keep this as simple as possible. All you want is to add the Lock capability to the existing child switch driver, as that will allow it to appear as a Lock device (as well as still a switch device) in various apps/dashboards/etc...

Thus, simply add the necessary code to support the Lock Capability.

Here is the original Hubitat example code.

And here is a modified version that should support the Lock capability. It is 100% UNtested, and thus you'll need to debug it a little. But this is way easier than starting from scratch or dealing with Z-Wave driver development.

/*
	Generic Component Switch
	Copyright 2016 -> 2020 Hubitat Inc. All Rights Reserved
    2020-04-16 2.2.0 maxwell
        -refactor
	2018-12-15 maxwell
	    -initial pub

*/

metadata {
    definition(name: "Generic Component Switch", namespace: "hubitat", author: "mike maxwell", component: true) {
        capability "Switch"
        capability "Refresh"
        capability "Actuator"
        capability "Lock"
    }
    preferences {
        input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true
    }
}

void updated() {
    log.info "Updated..."
    log.warn "description logging is: ${txtEnable == true}"
}

void installed() {
    log.info "Installed..."
    device.updateSetting("txtEnable",[type:"bool",value:true])
    refresh()
}

void parse(String description) { log.warn "parse(String description) not implemented" }

void parse(List description) {
    description.each {
        if (it.name in ["switch"]) {
            if (txtEnable) log.info it.descriptionText
            sendEvent(it)
            if (it.value == "on") sendEvent(name: "lock", value: "locked")
            if (it.value == "off") sendEvent(name: "lock", value: "unlocked")
        }
    }
}

void lock() {
    on()
}

void on() {
    parent?.componentOn(this.device)
}

void unlock() {
    off()
}

void off() {
    parent?.componentOff(this.device)
}

void refresh() {
    parent?.componentRefresh(this.device)
}

That would be great but how do I get the Zen17 to load this driver a child device?

I still have to write some sort of companion driver to create the custom Child devices (Make sure you use the same "DNI" as the stock driver so it will recognize it. Once that is done switch back to the stock parent driver. ) @ jtp10181

I don't mind hackery but in this case I'd rather just write my own driver when I find the time.

Also a lot work has been by done @jtp10181

  1. Start with:
    Hubitat/zooz-zen51-relay.groovy at main · jtp10181/Hubitat · GitHub

  2. Add in parameters from:
    Hubitat/zooz-zen17-companion-driver.groovy at main · jtp10181/Hubitat · GitHub

  3. Create a ZenRelayComponent device which implements on/off/lock etc.. all capabilities

  4. Create a ZenInputComponent device which implements on/off/sensor.. capabilities

  5. Add code to manage the two child devices ZenRelayComponent and the two input components ZenInputComponent

  6. I may be oversimplifying all of this :slight_smile: but my gut tells me this management of component child devices to match parameters is way too complicated and limiting. I understand why it exists for compatibility with many z-wave hubs but the simpler and more manageable solution in Hubitat seems to be 'Relay' component and 'Input' components which have many capabilities.

The easiest thing to do in this case is actually leave the driver for the ZEN17 alone, and the child device. Create a virtual driver that has what you want on it, which is I think Switch and Lock. Have the Lock status sync with the switch status in that driver.
Make a rule that when the ZEN17 child or virtual device changes states, it syncs them both up on the switch on/off status.

I have done this with a Fan Controller because the Bond integration uses terrible child devices. Works great.

1 Like

Just change each child device's default child driver to the custom one I provided above. That's it. Done! (Well, once you debug it in case I made any mistakes.)

1 Like

You cant, the childs are created as Components which locks the driver in place.
A feature could be added to the companion driver I made to create the child devices as NOT components, with the correct DNI, then the driver could be changed. But if you change the settings on the main device it might delete and re-create them again.

This is why I like the idea to just sync it to a virtual device, and why I did that with my fan. So now if I have to delete the integration or the child devices for any reason I only have to fix the one rule that keeps them in sync and not all my other integrations.

Ahhh, understood. My Parent/Child devices are configured where it is easy to change a child driver type. I specify IsComponent as FALSE to avoid this issue. It also allows one to delete a child device.

Your solution is definitely a very good option based on the restrictions imposed by the existing parent driver.

Thank you for clarifying this!

Yeah I started doing that in my drivers as well. If people want to change the driver or DNI and break it that's their own problem. Not all driver changes would break it, so gives it flexibility.

2 Likes

I'll use this for now :+1:

1 Like