Aeon Smartstrip driver update?

Will the built-in Aeon Smartstrip device handler be updated for the new parent/child device functionality? I tweaked a Zooz powerstrip driver to do parent/child and it works well, but would rather the experts tackle the Aeon one :wink: .

Care to share this driver tweak?

Yes, just can't say when at this point.

1 Like

Caveats:

I started with the ST device handlers. Even though I used the same fingerprint from another driver that worked, this one was found and set to Device, then I had to change to Zooz Power Strip.

The children didn't get created when I first changed the device handler to this one, so I removed the strip from the hub and tried to re-add, still no children. So I added the Recreate Child Devices command and that put the children out there.

And finally, there seems to be some flakiness with the digital events; sometimes they work, sometimes not. I added a new device so perhaps I need to do a z-wave repair and/or turn the hub off and on. Physical events for the outlets are captured though. I don't know what happens if the strip is physically powered off and then on.

Any improvements/fixes are greatly appreciated!! I am a software engineer but kind of clueless with the z-wave/ZigBee, so I put these things together by looking at lots of other code and making assumptions which may or may not be correct!

 /*
 *  Zooz ZEN20 Power Strip
 */
metadata {
    definition (name: "Zooz Power Strip", namespace: "hubitat", author: "hubitat") {
        capability "Switch"
        capability "Refresh"
        capability "Actuator"
        capability "Sensor"
        capability "Configuration"
        
        command "childOn"
        command "childOff"
        command "recreateChildDevices"

        fingerprint manufacturer: "015D", prod: "0651", model: "F51C", deviceJoinName: "Zooz ZEN20 Power Strip"
        fingerprint deviceId: "0x1004", inClusters: "0x5E,0x85,0x59,0x5A,0x72,0x60,0x8E,0x73,0x27,0x25,0x86"
   }
}

def installed() {
    log.debug "installed"
    createChildDevices()
    configure()
}

def updated() {
    log.debug "updated"
    
    if (!childDevices) {
        createChildDevices()
    }
    else if (device.label != state.oldLabel) {
        childDevices.each {
            def newLabel = "$device.displayName (CH${channelNumber(it.deviceNetworkId)})"
            it.setLabel(newLabel)
        }
  
        state.oldLabel = device.label
    }

    configure()
}

def configure() {
    log.debug "configure"
    def cmds = [
                   zwave.versionV1.versionGet().format(),
                   zwave.manufacturerSpecificV2.manufacturerSpecificGet().format(),
                   zwave.firmwareUpdateMdV2.firmwareMdGet().format()
               ]
    response(delayBetween(cmds, 1000))
}

def refresh() {
    log.debug "refresh"
    def cmds = []
    cmds << zwave.basicV1.basicGet().format()
    cmds << zwave.switchBinaryV1.switchBinaryGet().format()
    
    (1..5).each { endpoint ->
        cmds << encap(zwave.basicV1.basicGet(), endpoint)
        cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), endpoint)
    }
 
    delayBetween(cmds, 100)
}

def recreateChildDevices() {
    log.debug "recreateChildDevices"
    deleteChildren()
    createChildDevices()
}

def deleteChildren() {
	log.debug "deleteChildren"
	def children = getChildDevices()
    
    children.each {child->
  		deleteChildDevice(child.deviceNetworkId)
    }
}


def parse(String description) {
    log.debug "parse $description"
    def result = null
 
    if (description.startsWith("Err")) {
        result = createEvent(descriptionText:description, isStateChange:true)
    } else {
        def cmd = zwave.parse(description, [0x60: 3, 0x25: 1, 0x20: 1])
        log.debug "Command: ${cmd}"
  
        if (cmd) {
            result = zwaveEvent(cmd)
            log.debug "parsed '${description}' to ${result.inspect()}"
        } else {
            log.debug "Unparsed description $description"
        }
    }
 
    result
}

def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
    log.debug "multichannelv3.MultiChannelCmdEncap $cmd"
    def encapsulatedCommand = cmd.encapsulatedCommand([0x25: 1, 0x20: 1])
    log.debug "encapsulatedCommand: $encapsulatedCommand"
 
    if (encapsulatedCommand) {
        return zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
    } else {
        log.debug "Unable to get encapsulated command: $encapsulatedCommand"
        return []
    }
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd, endpoint = null) {
    log.debug "basicv1.BasicReport $cmd, $endpoint"
    zwaveBinaryEvent(cmd, endpoint, "digital")
}

def zwaveEvent(hubitat.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, endpoint = null) {
    log.debug "switchbinaryv1.SwitchBinaryReport $cmd, $endpoint"
    zwaveBinaryEvent(cmd, endpoint, "physical")
}

def zwaveBinaryEvent(cmd, endpoint, type) {
    log.debug "zwaveBinaryEvent cmd $cmd, endpoint $endpoint, type $type"
    def childDevice = childDevices.find{it.deviceNetworkId.endsWith("$endpoint")}
    def result = null
 
    if (childDevice) {
        log.debug "childDevice.sendEvent $cmd.value"
        childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off", type: type)
    } else {
        result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: type)
    }
 
    result
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
    log.debug "manufacturerspecificv2.ManufacturerSpecificReport cmd $cmd"
    updateDataValue("MSR", String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId))
}

def zwaveEvent(hubitat.zwave.commands.configurationv2.ConfigurationReport cmd) {
    log.debug "configurationv2.ConfigurationReport: parameter ${cmd.parameterNumber} with a byte size of ${cmd.size} is set to ${cmd.configurationValue}"
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
    log.debug "configurationv2.ConfigurationReport: parameter ${cmd.parameterNumber} with a byte size of ${cmd.size} is set to ${cmd.configurationValue}"
}

def zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport cmd, endpoint) {
   log.debug "versionv1.VersionReport, applicationVersion $cmd.applicationVersion, cmd $cmd, endpoint $endpoint"
}

def zwaveEvent(hubitat.zwave.Command cmd, endpoint) {
    log.debug "${device.displayName}: Unhandled ${cmd}" + (endpoint ? " from endpoint $endpoint" : "")
}

def zwaveEvent(hubitat.zwave.Command cmd) {
    log.debug "${device.displayName}: Unhandled ${cmd}"
}

def on() {
    log.debug "on"
    def cmds = []
    cmds << zwave.basicV1.basicSet(value: 0xFF).format()
    cmds << zwave.basicV1.basicGet().format()
    
    (1..5).each { endpoint ->
        cmds << encap(zwave.basicV1.basicSet(value: 0xFF), endpoint)
        cmds << encap(zwave.basicV1.basicGet(), endpoint)
    }

    return delayBetween(cmds, 1000)
}

def off() {
    log.debug "off"
    def cmds = []
    cmds << zwave.basicV1.basicSet(value: 0x00).format()
    cmds << zwave.basicV1.basicGet().format()
    
    (1..5).each { endpoint ->
        cmds << encap(zwave.basicV1.basicSet(value: 0x00), endpoint)
        cmds << encap(zwave.basicV1.basicGet(), endpoint)
    }
    
    return delayBetween(cmds, 1000)
}

def childOn(String dni) {
    onOffCmd(0xFF, channelNumber(dni))
}

def childOff(String dni) {
    onOffCmd(0, channelNumber(dni))
}

private onOffCmd(value, endpoint) {
    log.debug "onOffCmd, value: $value, endpoint: $endpoint"
    
    def cmds = []
    cmds << encap(zwave.basicV1.basicSet(value: value), endpoint)
    cmds << encap(zwave.basicV1.basicGet(), endpoint)
    
    return delayBetween(cmds, 1000)
}

private channelNumber(String dni) {
    def ch = dni.split("-")[-1] as Integer
    return ch
}

private void createChildDevices() {
    log.debug "createChildDevices"
    
    for (i in 1..5) {
        addChildDevice("hubitat", "Zooz Power Strip Outlet", "$device.deviceNetworkId-$i", [name: "ch$i", label: "$device.displayName $i", isComponent: true])
    }
}

private encap(cmd, endpoint) {
    if (endpoint) {
        zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint:endpoint).encapsulate(cmd).format()
    } else {
        cmd.format()
    }
}


/*
 *  Zooz Power Strip Outlet
 */
metadata {
    definition (name: "Zooz Power Strip Outlet", namespace: "hubitat", author: "hubitat") {
        capability "Switch"
        capability "Actuator"
        capability "Sensor"
    }
}

void on() { 
    log.debug "$device on"
    parent.childOn(device.deviceNetworkId)
}

void off() {
    log.debug "$device off"
    parent.childOff(device.deviceNetworkId)
}
3 Likes

Thanks for this driver! I finally moved my Zooz ZEN20 from ST to Hubitat and after a few failed, hasty attemps to create/port a driver myself (or using the Aeon but being without control of the fifth outlet, and I still couldn't get it to create child devices), I found the above.

Note to others who may be using it: the code snippet above contains two drivers, the parent and child, that you will have to split (child is the "Zooz Power Strip Outlet" bit at the end) and add separately. I actually skipped the child driver and changed the parent driver to point to the InovelliUSA "Child Switch Device" driver that I already had installed (almost the exact same code), and it works fine--I figured I wouldn't add another driver if I didn't need to. (BTW, speaking of Inovelli, my ZEN20 was detected as their 2-channel indoor scene outlet that I have. It does work as such, but it only creates child devices for, unsurprisingly, the first two channels.)

I also had a heck of a time getting the ZEN20 reset. I was usually able to exclude and include it following the directions, but despite being removed from Hubitat it wouldn't pair once, so I followed the reset directions (unplug the strip, press and hold CH5 button as you plug it in, and keep holding for at least 5 seconds). This still didn't work for me. Thinking it might still think it's paired to Hubitat despite having been removed, I put Hubitat in general Z-Wave exclusion mode, followed the exclusion steps for the strip (press CH1 three times rapidly), and then was able to include it. Still not sure how to reset it since that didn't seem to have worked.

1 Like

Hi
Are you implying in your post that you were able to use Zooz's driver for the Aeotec's SmartStrip? I'm not sure. If so, can you help figure this out? The driver posted above doesn't work for me, cmds don't go trhough. Let me know if there are tweaks to make to the Zooz's driver in order to have it work with the Aeotec Strip. Also, do you create the child by creating a virtual device? Thanks.

Hello @mike.maxwell! It'd be great to have this one work with child devices. It seems it's been forgotten since this time when, a year ago, @denise.grider asked about this. Any news?

Nice talking to you again on this platform (trying to quit ST... got exhausted of their too many service interruptions... Thanks for making Hubitat Happen! I'm currently in the middle of a very harduous, long, unfinishable migration...)

UPDATE: the modified Zooz driver seems to do the job at creating child devices with aeotec smarstrip but cmds don't go through to the physical device, even though they log perfectly.

Hi @Denise.grider! Thanks for the great work!

Did you eventually get it to work reliably? I got the install ok thanks to your tweaks but I can't get the Aeotec smartstrip (not event the whole thing) to turn on/off.

I originally in this thread, had cobbled together a Zooz strip driver, and was asking Mike when the built-in driver would be converted to parent/child.

As of now, there is a built-in driver for the Aeotec Smartstrip (is not parent/child) and a built-in driver for the Zooz strip (is parent/child), so we are still waiting for the Aeotec driver to be modified to be parent/child.

You should use the built-in driver for the Aeotec Smartstrip.

Actually I just found out that, using zooz driver, it's just a matter of replacing these values:

fingerprint mfr: "0086", prod: "0003", model: "000B"
		fingerprint deviceId: "0x1001", inClusters: "0x25,0x32,0x27,0x70,0x85,0x72,0x86,0x60", outClusters: "0x82"

by these values:

fingerprint manufacturer: "015D", prod: "0651", model: "F51C", deviceJoinName: "Zooz ZEN20 Power Strip"
        fingerprint deviceId: "0x1004", inClusters: "0x5E,0x85,0x59,0x5A,0x72,0x60,0x8E,0x73,0x27,0x25,0x86"

It's far from perfect but at least child devices respond to commands now. Let me know if, from here, you can fix the code further to update power consumption, for example. I used Eric Maycock's ST device handler to figure out the fingerprints but maybe using Cooper Lee's "Multi Switch with Virtual Tiles for Master Switch" you could help with that?

Let me know! :slight_smile:

Just following up on this thread. It would be great to see parent-child support for this, if that means I would be able to create Rule Machine rules to control the individual outlets.

What about power metering? I've tried the erocm123 version but I'm getting null values for scaledMeterValue

It really seems that Hubitat's staff is not even aware of the issue here... Dunno what their policy is but on this one, despite what we are used to, they are not reactive at all.

How do I get to where I can edit this driver. This is maddening. I have been into automation for years and I feel so lost right now.

start here:

He also has a SmartStrip 6 driver.

I installed and still no good. modified the code as stated and got error message. Is there a way to create a child device from the parent. Thanks for the patience and help.

Here is a solution that works for me:

Create the parent and child device drivers in the "Drivers code" section of your hub interface, using the codes below:

  1. Driver for the parent device
/*
*  Zooz ZEN20 Power Strip turned into a driver for Aeotec's
*/
metadata {
    definition (name: "Aeotec SmartStrip for Hubitat", namespace: "hubitat", author: "hubitat, denise.grider and elfege") {
        capability "Switch"
        capability "Energy Meter"
        capability "Power Meter"
        capability "Refresh"
        capability "Configuration"
        capability "Actuator"
        capability "Sensor"
        capability "Temperature Measurement"
        capability "Health Check"

        command "reset"


        command "childOn"
        command "childOff"
        command "recreateChildDevices"

        fingerprint manufacturer: "0086", prod: "0003", model: "000B", deviceJoinName: "Zooz ZEN20 Power Strip"
        fingerprint deviceId: "0x1001", inClusters: "0x25,0x32,0x27,0x70,0x85,0x72,0x86,0x60", outClusters: "0x82"

    }
}

	// simulator metadata
	simulator {
		status "on":  "command: 2003, payload: FF"
		status "off":  "command: 2003, payload: 00"
		status "switch1 on": "command: 600D, payload: 01 00 25 03 FF"
		status "switch1 off": "command: 600D, payload: 01 00 25 03 00"
		status "switch4 on": "command: 600D, payload: 04 00 25 03 FF"
		status "switch4 off": "command: 600D, payload: 04 00 25 03 00"
		status "power": new hubitat.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 30, precision: 3, meterType: 4, scale: 2, size: 4).incomingMessage()
		status "energy": new hubitat.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 200, precision: 3, meterType: 0, scale: 0, size: 4).incomingMessage()
		status "power1": "command: 600D, payload: 0100" + new hubitat.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 30, precision: 3, meterType: 4, scale: 2, size: 4).format()
		status "energy2": "command: 600D, payload: 0200" + new hubitat.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 200, precision: 3, meterType: 0, scale: 0, size: 4).format()

		// reply messages
		reply "2001FF,delay 100,2502": "command: 2503, payload: FF"
		reply "200100,delay 100,2502": "command: 2503, payload: 00"
	}

preferences {
    input("enableDebugging", "bool", title:"Enable Debugging")
}

def installed() {
    logging("installed")
    createChildDevices()
    configure()
}

def updated() {
    logging("updated")

    if (!childDevices) {
        createChildDevices()
    }
    else if (device.label != state.oldLabel) {
        childDevices.each {
            def newLabel = "$device.displayName (CH${channelNumber(it.deviceNetworkId)})"
            it.setLabel(newLabel)
        }

        state.oldLabel = device.label
    }

    configure()
}

def configure() {
    state.enableDebugging = settings.enableDebugging
    logging("configure()")
    sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
    def cmds = [
        // Configuration of what to include in reports and how often to send them (if the below "change" conditions are met
        // Parameter 101 & 111: Send energy reports every 60 seconds (if conditions are met)
        // Parameter 102 & 112: Send power reports every 60 seconds (if conditions are met)
        zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, configurationValue: [0,0,0,127]).format(),
        zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, configurationValue: [0,0,127,0]).format(),
        zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 60).format(),
        zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 60).format(),
    ]
    [5, 6, 7, 8, 9, 10, 11].each { p ->
        // Send power reports at the time interval if they have changed by at least 1 watt
        cmds << zwave.configurationV1.configurationSet(parameterNumber: p, size: 2, scaledConfigurationValue: 100).format()
    }
    [12, 13, 14, 15, 16, 17, 18].each { p ->
        // Send energy reports at the time interval if they have changed by at least 5%
        cmds << zwave.configurationV1.configurationSet(parameterNumber: p, size: 1, scaledConfigurationValue: 50).format()
    }
    cmds += [
        // Parameter 4: Induce automatic reports at the time interval if the above conditions are met to reduce network traffic 
        zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: 100).format(),
        // Parameter 80: Enable to send automatic reports to devices in association group 1
        zwave.configurationV1.configurationSet(parameterNumber: 80, size: 1, scaledConfigurationValue: 2).format(),
    ]

    delayBetween(cmds, 1000) + "delay 5000" + refresh()
}

def refresh() {
    logging("refresh")
    def cmds = [
        zwave.basicV1.basicGet().format(),
        zwave.meterV3.meterGet(scale: 0).format(),
        zwave.meterV3.meterGet(scale: 2).format(),
        encap(zwave.basicV1.basicGet(), 1)  // further gets are sent from the basic report handler
    ]
    cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), null)
    (1..4).each { endpoint ->
        cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), endpoint)
    }
    (1..6).each { endpoint ->
        cmds << encap(zwave.meterV2.meterGet(scale: 0), endpoint)
        cmds << encap(zwave.meterV2.meterGet(scale: 2), endpoint)
    }
    [90, 101, 102, 111, 112].each { p ->
        cmds << zwave.configurationV1.configurationGet(parameterNumber: p).format()
    }
    delayBetween(cmds, 1000)
}

def recreateChildDevices() {
    logging("recreateChildDevices")
    deleteChildren()
    createChildDevices()
}

def deleteChildren() {
    logging("deleteChildren")
    def children = getChildDevices()

    children.each {child->
        deleteChildDevice(child.deviceNetworkId)
    }
}


def parse(String description) {

    state.enableDebugging = settings.enableDebugging

    def result = []
    if (description.startsWith("Err")) {
        result = createEvent(descriptionText:description, isStateChange:true)
    } else if (description != "updated") {
        def cmd = zwave.parse(description, [0x60: 3, 0x32: 3, 0x25: 1, 0x20: 1])
        logging("Command: ${cmd}")
        if (cmd) {
            result += zwaveEvent(cmd, null)
        }
    }

    def statusTextmsg = ""
    if (device.currentState('power') && device.currentState('energy')) statusTextmsg = "${device.currentState('power').value} W ${device.currentState('energy').value} kWh"
    sendEvent(name:"statusText", value:statusTextmsg, displayed:false)

    logging("parsed '${description}' to ${result.inspect()}")

    result

}


def resetCmd(endpoint = null) {
    logging("resetCmd($endpoint)")
    delayBetween([
        encap(zwave.meterV2.meterReset(), endpoint),
        encap(zwave.meterV2.meterGet(scale: 0), endpoint)
    ])
}

def reset() {
    logging("reset()")
    delayBetween([resetCmd(null), reset1(), reset2(), reset3(), reset4(), reset5(), reset6()])
}

def reset1() { resetCmd(1) }
def reset2() { resetCmd(2) }
def reset3() { resetCmd(3) }
def reset4() { resetCmd(4) }
def reset5() { resetCmd(5) }
def reset6() { resetCmd(6) }

def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd, ep) {
    def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
    if (encapsulatedCommand) {
        if (encapsulatedCommand.commandClassId == 0x32) {
            // Metered outlets are numbered differently than switches
            Integer endpoint = cmd.sourceEndPoint
            if (endpoint > 2) {
                zwaveEvent(encapsulatedCommand, endpoint - 2)
            } else if (endpoint == 0) {
                zwaveEvent(encapsulatedCommand, 0)
            } else if (endpoint == 1 || endpoint == 2) {
                zwaveEvent(encapsulatedCommand, endpoint + 4)
            } else {
                log.debug "Ignoring metered outlet ${endpoint} msg: ${encapsulatedCommand}"
                []
            }
        } else {
            zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
        }
    }
}

def endpointEvent(endpoint, map) {
    logging("endpointEvent($endpoint, $map)")
    if (endpoint) {
        map.name = map.name + endpoint.toString()
    }
    createEvent(map)
}

def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
    logging("multichannelv3.MultiChannelCmdEncap $cmd")
    // def encapsulatedCommand = null//cmd.encapsulatedCommand([0x25: 1, 0x20: 1]) // throws "java.lang.IndexOutOfBoundsException: toIndex = 8 on line 109 (parse)"

    def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
    logging("encapsulatedCommand: $encapsulatedCommand")

    if (encapsulatedCommand) {
        return zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
    } else {
        logging("Unable to get encapsulated command: $encapsulatedCommand")
        return []
    }
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd, endpoint = null) {
    logging("basicv1.BasicReport $cmd, $endpoint")
    zwaveBinaryEvent(cmd, endpoint, "digital")
}

def zwaveEvent(hubitat.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, endpoint = null) {
    logging("switchbinaryv1.SwitchBinaryReport $cmd, $endpoint")
    zwaveBinaryEvent(cmd, endpoint, "physical")
}

def zwaveBinaryEvent(cmd, endpoint, type) {
    logging("zwaveBinaryEvent cmd $cmd, endpoint $endpoint, type $type")
    def childDevice = childDevices.find{it.deviceNetworkId.endsWith("$endpoint")}
    def result = null

    if (childDevice) {
        logging("childDevice.sendEvent $cmd.value")
        childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off", type: type)
    } else {
        result = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: type)
    }

    result
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
    logging("manufacturerspecificv2.ManufacturerSpecificReport cmd $cmd")
    updateDataValue("MSR", String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId))
}

def zwaveEvent(hubitat.zwave.commands.configurationv2.ConfigurationReport cmd, ep) {
    def temperatureEvent
    if (cmd.parameterNumber == 90) { 
        def temperature = convertTemp(cmd.configurationValue)
        if(getTemperatureScale() == "C"){
            temperatureEvent = [name:"temperature", value: Math.round(temperature * 100) / 100]
        } else {
            temperatureEvent = [name:"temperature", value: Math.round(celsiusToFahrenheit(temperature) * 100) / 100]
        }
        state.lastTempReport = now()
    } else {
        //log.debug "${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd.configurationValue}'"
    }
    if (temperatureEvent) { 
        createEvent(temperatureEvent) 
    }
}

def convertTemp(value) {
    def highbit = value[0]
    def lowbit = value[1]

    if (highbit > 127) highbit = highbit - 128 - 128
    lowbit = lowbit * 0.00390625

    return highbit+lowbit
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
    logging("configurationv1.ConfigurationReport: parameter ${cmd.parameterNumber} with a byte size of ${cmd.size} is set to ${cmd.configurationValue}")
}

def zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport cmd, endpoint) {
    logging("versionv1.VersionReport, applicationVersion $cmd.applicationVersion, cmd $cmd, endpoint $endpoint")
}

def zwaveEvent(hubitat.zwave.Command cmd, endpoint) {
    logging("${device.displayName}: Unhandled ${cmd}" + (endpoint ? " from endpoint $endpoint" : ""))
}

def zwaveEvent(hubitat.zwave.Command cmd) {
    logging("${device.displayName}: Unhandled ${cmd}")
}

def on() {
    logging("on")
    def cmds = []
    cmds << zwave.basicV1.basicSet(value: 0xFF).format()
    cmds << zwave.basicV1.basicGet().format()
    logging("cmds = $cmds")

    (1..5).each { endpoint ->
        cmds << encap(zwave.basicV1.basicSet(value: 0xFF), endpoint)
        cmds << encap(zwave.basicV1.basicGet(), endpoint)
    }

    return delayBetween(cmds, 1000)
}

def off() {
    logging("off")
    def cmds = []
    cmds << zwave.basicV1.basicSet(value: 0x00).format()
    cmds << zwave.basicV1.basicGet().format()

    (1..5).each { endpoint ->
        cmds << encap(zwave.basicV1.basicSet(value: 0x00), endpoint)
        cmds << encap(zwave.basicV1.basicGet(), endpoint)
    }

    return delayBetween(cmds, 1000)
}

def childOn(String dni) {
    onOffCmd(0xFF, channelNumber(dni))
}

def childOff(String dni) {
    onOffCmd(0, channelNumber(dni))
}

private onOffCmd(value, endpoint) {
    logging("onOffCmd, value: $value, endpoint: $endpoint")

    def cmds = []
    cmds << encap(zwave.basicV1.basicSet(value: value), endpoint)
    cmds << encap(zwave.basicV1.basicGet(), endpoint)

    return delayBetween(cmds, 1000)
}

private channelNumber(String dni) {
    def ch = dni.split("-")[-1] as Integer
    return ch
}

private void createChildDevices() {
    logging("createChildDevices")

    for (i in 1..4) {
        addChildDevice("hubitat", "Zooz Power Strip Outlet", "$device.deviceNetworkId-$i", [name: "ch$i", label: "$device.displayName $i", isComponent: true])
    }
}


private encap(cmd, endpoint) {
    if (endpoint) {
        if (cmd.commandClassId == 0x32) {
            // Metered outlets are numbered differently than switches
            if (endpoint == 5 || endpoint == 6) {
                endpoint -= 4
            }
            else if (endpoint < 0x80) {
                endpoint += 2
            } else {
                endpoint = ((endpoint & 0x7F) << 2) | 0x80
            }
        }
        zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint:endpoint).encapsulate(cmd).format()
    } else {
        cmd.format()
    }
}


private def logging(message) {
    //log.debug "state.enableDebugging = $state.enableDebugging"
    if (state.enableDebugging == true) log.debug message
}
  1. Child devices driver:
/*
 *  Zooz Power Strip Outlet
 */
metadata {
    definition (name: "Zooz Power Strip Outlet", namespace: "hubitat", author: "hubitat") {
        capability "Switch"
        capability "Actuator"
        capability "Sensor"
    }
}



void on() { 
    log.debug "$device on"    
    parent.childOn(device.deviceNetworkId)
    sendEvent(name: "switch", value: "on")
}

void off() {
    log.debug "$device off"
    sendEvent(name: "switch", value: "off")
    parent.childOff(device.deviceNetworkId)
}
1 Like

Do you get power readings using this? I tried but I get no power readings.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.