Basic Z-Wave Tool

I may just be getting old, but although I can find lots of references to this app/driver in the forum, I can't seem to find the actual source thread for it where I would presume there would be instructions etc.

Is this it:

It's the closest thing I can find. I still don't really see the basic "how to use" stuff though.

Appreciate he help unfogging my brain! Thanks!

1 Like

The driver you’ve linked to is the Basic ZWave Tool. It comes with these instructions on its use:

and this warning:

2 Likes

It works like a champ though... I finally got around to programming in the auto-off timer for my Zen 17 relay (an otherwise hidden parameter), and it worked great.

For this tool, you'll need 3 things - Parameter #, Size, and desired Value - you cannot leave any of those fields blank. Prior to my tweak, I checked the Parameter Report (available thru this tool) for my parameter and noticed the Size field was as expected, so I thought I could leave it blank when I updated the desired Value. Nope, gotta fill out all 3 fields for the change to stick.

3 Likes

OK, thanks. Perhaps I misunderstand what the purpose of this app is. I know that It can let you tweak parameters. What I’m trying to use it for is to get reliable information on firmware levels of devices.

For example I have a zooz power strip that I got the latest version of firmware for from zooz. With or without this driver being loaded to read the device, it seems to be showing a newer version of firmware than what they even sent me so I don’t know how that could be possible. I guess I was expecting the perimeter fields and all that stuff to populate when I switch to the driver but everything is just blank. The information down at the bottom of the page when you load it is the same whether you use the correct driver for the device or this utility driver.

FTR, i’m not trying to change any parameters whatsoever. I’m just trying to get a baseline on my devices so I can update the firmware on them if appropriate.

This is probably not what mostly people use the Tool for, but the "Get Version Report" command should spit out a few things in "Logs," one of which should be the firmware version for most devices that report it. I think something like "firmware version" and "firmware subversion" are the pieces you could put together to do this (e.g., "1" and "5" would be 1.5 or, as it is often displayed, 1.05--but keep in mind that these are equivalent).

Many drivers also display this in the "Device Data" section at the bottom of the device page. However, some drivers don't update this after a firmware update, and there's no standard for how to force it to re-check (a refresh or configure might). So, I suppose the Tool is one way to always see for sure. If you're using a C-7 hub, the built-in Device Firmware Updater app can also tell you--just go to the page in it where you choose deivces, and pick the one you're interested it. The "firmware targets" dropdown will then show you the version(s), and you can just back out or close it before you update (you don't even need to upload any firmware files to get this far).

4 Likes

Does anyone know if I should type hex or decimal in the parameter input field when setting parameters?

Normally, I guess commands should use hex, but since the log messages from this driver displays the parameter values in decimal I don't feel sure, and I really don't know how much I might mess up my devices if I put the wrong numbers...

Decimal

i.e, for a parameter of length 1, use 0 .. 255

2 Likes

i used all ones on mine and it worked. You have to dry contact the the middle terminal and the one on the side of the tamper switch to make it register. These guys in this topic have the solution.

TLDR process to get dry contact working (at least for me)
#1 get the thing paired with the series 7 aeotec driver (hit include button then tamper button on device x3)
#2 get the driver for the zwave tool at (https://raw.githubusercontent.com/hubitat/HubitatPublic/master/examples/drivers/basicZWaveTool.groovy)
#3 copy the driver into drivers code and save it
#4 Change the device to use that basic zwave tool (in the device area)
#5 open the device and enter 1 in all three slots under set parameter and then click set parameter
#6 Then tap the tamper switch to wake the dumb thing up and take parameter change
#7 Change driver back to the aeotec series 7 one in devices section
#7 open the device back up and short the two terminals closest to the tamper switch and then feel joy in your heart as you watch the status change.

Useful link because the included instructions sucked.

Updated this driver to include set and delete associations

/*
	Basic Z-Wave tool updated by Anitesh Kumar (added set and delete associations)

	Copyright 2016 -> 2020 Hubitat Inc.  All Rights Reserved
	2020-08-14 maxwell
		-refactor
		-update VersionReport
	2020-08-12 maxwell
		-update with S2 support
	2018-11-28 maxwell
		-add command hints
	2018-11-09 maxwell
		-add association and version reports

	usage:
		-replace existing driver with this driver
		-set your paremeters
		-replace this driver with previous driver
	
	WARNING!
		--Setting device parameters is an advanced feature, randomly poking values to a device
		can lead to unexpected results which may result in needing to perform a factory reset 
		or possibly bricking the device
		--Refer to the device documentation for the correct parameters and values for your specific device
		--Hubitat cannot be held responsible for misuse of this tool or any unexpected results generated by its use
*/

import groovy.transform.Field

metadata {
    definition (name: "Basic Z-Wave tool",namespace: "hubitat", author: "Mike Maxwell") {
        
    	command "getAssociationReport"
	command "setAssociationGroup", [[name: "groupingIdentifier", type: "NUMBER", description: "Association Group Number", constraints: ["NUMBER"]],
                                         [name: "nodeId", type: "STRING", description: "Comma-separated list of node IDs"]]
        command "deleteAssociationGroup", [[name: "group", type: "NUMBER", description: "Association Group Number", constraints: ["NUMBER"]],
                                   [name: "node", type: "NUMBER", description: "Node ID", constraints: ["NUMBER"]]]
        command "getVersionReport"
	command "getCommandClassReport"
	command "getParameterReport", [[name:"parameterNumber",type:"NUMBER", description:"Parameter Number (omit for a complete listing of parameters that have been set)", constraints:["NUMBER"]]]
	command "setParameter",[[name:"parameterNumber",type:"NUMBER", description:"Parameter Number", constraints:["NUMBER"]],[name:"size",type:"NUMBER", description:"Parameter Size", constraints:["NUMBER"]],[name:"value",type:"NUMBER", description:"Parameter Value", constraints:["NUMBER"]]]
		
    }
}

@Field Map zwLibType = [
	0:"N/A",1:"Static Controller",2:"Controller",3:"Enhanced Slave",4:"Slave",5:"Installer",
	6:"Routing Slave",7:"Bridge Controller",8:"Device Under Test (DUT)",9:"N/A",10:"AV Remote",11:"AV Device"
]

void parse(String description) {
    hubitat.zwave.Command cmd = zwave.parse(description,[0x85:1,0x86:2])
    if (cmd) {
        zwaveEvent(cmd)
    }
}

//Z-Wave responses
void zwaveEvent(hubitat.zwave.commands.versionv2.VersionReport cmd) {
    Double firmware0Version = cmd.firmware0Version + (cmd.firmware0SubVersion / 100)
    Double protocolVersion = cmd.zWaveProtocolVersion + (cmd.zWaveProtocolSubVersion / 100)
    log.info "Version Report - FirmwareVersion: ${firmware0Version}, ProtocolVersion: ${protocolVersion}, HardwareVersion: ${cmd.hardwareVersion}"
    device.updateDataValue("firmwareVersion", "${firmware0Version}")
    device.updateDataValue("protocolVersion", "${protocolVersion}")
    device.updateDataValue("hardwareVersion", "${cmd.hardwareVersion}")
    if (cmd.firmwareTargets > 0) {
        cmd.targetVersions.each { target ->
            Double targetVersion = target.version + (target.subVersion / 100)
            device.updateDataValue("firmware${target.target}Version", "${targetVersion}")
        }
    }
}

void zwaveEvent(hubitat.zwave.commands.associationv1.AssociationReport cmd) {
    log.info "AssociationReport- groupingIdentifier:${cmd.groupingIdentifier}, maxNodesSupported:${cmd.maxNodesSupported}, nodes:${cmd.nodeId}"
}

void zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
    log.info "ConfigurationReport- parameterNumber:${cmd.parameterNumber}, size:${cmd.size}, value:${cmd.scaledConfigurationValue}"
}

void zwaveEvent(hubitat.zwave.commands.versionv1.VersionCommandClassReport cmd) {
    log.info "CommandClassReport- class:${ "0x${intToHexStr(cmd.requestedCommandClass)}" }, version:${cmd.commandClassVersion}"		
}	

String zwaveEvent(hubitat.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
    hubitat.zwave.Command encapCmd = cmd.encapsulatedCommand()
    if (encapCmd) {
		return zwaveEvent(encapCmd)
    } else {
        log.warn "Unable to extract encapsulated cmd from ${cmd}"
    }
}

void zwaveEvent(hubitat.zwave.Command cmd) {
    log.debug "skip: ${cmd}"
}

//cmds
def getVersionReport(){
	return secureCmd(zwave.versionV1.versionGet())		
}

List<String> setParameter(parameterNumber = null, size = null, value = null){
    if (parameterNumber == null || size == null || value == null) {
		log.warn "incomplete parameter list supplied..."
		log.info "syntax: setParameter(parameterNumber,size,value)"
    } else {
		return delayBetween([
	    	secureCmd(zwave.configurationV1.configurationSet(scaledConfigurationValue: value, parameterNumber: parameterNumber, size: size)),
	    	secureCmd(zwave.configurationV1.configurationGet(parameterNumber: parameterNumber))
		],500)
    }
}

List<String> getAssociationReport(){
	List<String> cmds = []
	1.upto(5, {
		cmds.add(secureCmd(zwave.associationV1.associationGet(groupingIdentifier: it)))
    })
    return delayBetween(cmds,500)	
}

List<String> setAssociationGroup(group, node) {
    Integer groupNum = group as Integer
    Integer nodeNum = node as Integer
    
    if (groupNum == null || nodeNum == null) {
        log.warn "Incomplete association group parameters supplied..."
        log.info "Syntax: setAssociationGroup(group, node)"
    } else {
        return delayBetween([
            secureCmd(zwave.associationV1.associationSet(groupingIdentifier: groupNum, nodeId: [nodeNum])),
            secureCmd(zwave.associationV1.associationGet(groupingIdentifier: groupNum))
        ], 500)
    }
}



List<String> deleteAssociationGroup(group, node) {
    Integer groupNum = group as Integer
    Integer nodeNum = node as Integer

    if (groupNum == null || nodeNum == null) {
        log.warn "Incomplete association group parameters supplied..."
        log.info "Syntax: deleteAssociationGroup(group, node)"
    } else {
        return delayBetween([
            secureCmd(zwave.associationV1.associationRemove(groupingIdentifier: groupNum, nodeId: [nodeNum])),
            secureCmd(zwave.associationV1.associationGet(groupingIdentifier: groupNum))
        ], 500)
    }
}




List<String> getParameterReport(param = null){
    List<String> cmds = []
    if (param != null) {
		cmds = [secureCmd(zwave.configurationV1.configurationGet(parameterNumber: param))]
    } else {
		0.upto(255, {
	    	cmds.add(secureCmd(zwave.configurationV1.configurationGet(parameterNumber: it)))	
		})
    }
    log.trace "configurationGet command(s) sent..."
    return delayBetween(cmds,500)
}	

List<String> getCommandClassReport(){
    List<String> cmds = []
    List<Integer> ic = getDataValue("inClusters").split(",").collect{ hexStrToUnsignedInt(it) }
    ic.each {
		if (it) cmds.add(secureCmd(zwave.versionV1.versionCommandClassGet(requestedCommandClass:it)))
    }
    return delayBetween(cmds,500)
}

String secure(String cmd){
    return zwaveSecureEncap(cmd)
}

String secure(hubitat.zwave.Command cmd){
    return zwaveSecureEncap(cmd)
}

void installed(){}

void configure() {}

void updated() {}

String secureCmd(cmd) {
    if (getDataValue("zwaveSecurePairingComplete") == "true" && getDataValue("S2") == null) {
		return zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
    } else {
		return secure(cmd)
    }	
}





image

image

i had a issue with my aeotec switch not reporting its status back. The group 1 identifier was empty. I set that to 1 and its done, works fine now. Hope the driver can help someone that has issues with devices reporting its status back.

1 Like