Verify Zwave parameter settings (2016)

I am trying to verify the zwave parameter settings and I have used the following command to set them in the configure() function for a Fibaro Motion Sensor ( parameter 42 is the lux report interval)

cmds << zwave.configurationV1.configurationSet(configurationValue: [0,220], parameterNumber: 42, size: 2).format()

My problem is trying to read the value to verify it was set correctly. I have tried using the following, but I get the same value reported regardless of the value set.

log.debug "Value: ${zwave.configurationV1.configurationGet(parameterNumber: 42).format()}

I know there are reported problem with lux reporting, but I have just used parameter 42 as an example.

The Get command doesn’t return the value, it’s used the same way as the Set command. After you call the Get command it will send the requested parameter as a Report command.

I believe you would need to put something like the following below your Set line.

cmds << zwave.configurationV1.configurationGet(parameterNumber: 42).format()

And add the method below to retrieve the value.

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {	 
	log.debug "${cmd.configurationValue}"	
}
2 Likes

Kevin - Thank you for the reply.
I forgot to mention is the original post I had tried what you had suggested and was not getting any debug output so I assume I was not calling the method correctly so I went down another track.
I am not familiar with the groovy syntax.
Any suggestions?

The cmds object needs to be the last line of the method so if you put a log statement below it, nothing would have shown in the log. Without seeing the rest of your code, I can’t really help identify a syntax problem, but the code should have looked something like this:

def someMethod() {
	def cmds = []

	cmds << zwave.configurationV1.configurationSet(configurationValue: [0,220], parameterNumber: 42, size: 2).format()
	
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 42).format()
	
	cmds
}

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {	 
	log.debug "${cmd.configurationValue}"	
}

Appreciate the help. Thank you.

having a similar problem. in my configure method trying to get the configuration settings after they are set. but none of the configurationGet seem to actually generate an event at least none that gets received by the parse method.

any help would be much appreciated.

thank you.

delayBetween([
	zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: settings.ReportTime).format(),	//send meter report every x minutes.
	zwave.configurationV1.configurationSet(parameterNumber: 10, size: 1, scaledConfigurationValue: settings.ReportTime).format(),	//accumulated energy report meter interval
	zwave.configurationV1.configurationSet(parameterNumber: 11, size: 1, scaledConfigurationValue: 1).format(),	//send only meter report when wattage change 1=meter, 2=multilevel , 3=both, 0=none 
	zwave.configurationV1.configurationSet(parameterNumber: 12, size: 1, scaledConfigurationValue: wattageadjust).format(),//Minimum change in wattage 0-255
	zwave.configurationV1.configurationSet(parameterNumber: 9, size: 1, scaledConfigurationValue: 0).format(),// dont send multilevel report
	zwave.configurationV1.configurationGet(parameterNumber: 8).format(),
	zwave.configurationV1.configurationGet(parameterNumber: 9).format(),
	zwave.configurationV1.configurationGet(parameterNumber: 10).format(),
	zwave.configurationV1.configurationGet(parameterNumber: 11).format(),
	zwave.configurationV1.configurationGet(parameterNumber: 12).format(),
])

EDIT: here is the method i was hoping that would recieve the value and log it.

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
log.debug "in config report cmd = $cmd "

[name: "indicatorStatus", value: state.currentIndicatorStatus, display: true]

}

How are you executing the configure command?

If you’re doing it from the updated method or a zwave event you need to wrap delayBetween with response().

I’ve run into some devices that only execute the first few zwave commands if they’re sent to the device too quickly so changing delayBetween([…]) to delayBetween([…], 250) might solve the problem.

By having all the gets at the end, you have no way of knowing if any of the commands made it to the device so I usually put each get command below the set command.

that delaybetween is the last thing in the configure method which is called from the updated method.

ok. let me try the delay and alternating the sets and gets and see if that works.

thank you.

EDIT: i think you meant this:

   cmds += configure()
		
	if (cmds) {
		cmds << "delay 1200"
	}
	
	cmds << wakeUpNoMoreInfoCmd()
	return response(cmds)

you mean like this?

def updated() {		
	if (!isDuplicateCommand(state.lastUpdated, 5000)) {
		state.lastUpdated = new Date().time

		logTrace "Executing updated()"
		
		def cmds = configure()
		return cmds ? sendResponse(cmds) : []
	}
}

private sendResponse(cmds) {
	def actions = []
	cmds?.each { cmd ->
		actions << new physicalgraph.device.HubAction(cmd)
	}	
	sendHubCommand(actions)
	return []
}

this is the DH. none of the zwave commands seem to be going thru, like the configuration set and get. if you dont mind giving it a quick review and share your feedback that would be much appreciated.

thank you.

/**
 *  Copyright 2015 SmartThings
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 * modified by lgkahn v1 for control of the on/off light
 * the lite when on/off is not the normal parameter settings of the config class and there also
 * is no never lite option.. So custom code for this device only.
 *
 */
metadata {
	definition (name: "Enerwave ZW15SM Metering Switch", namespace: "smartthings", author: "LGKahn") {
		capability "Energy Meter"
		capability "Actuator"
		capability "Switch"
		capability "Power Meter"
		capability "Polling"
		capability "Refresh"
		capability "Configuration"
		capability "Sensor"
        capability "Indicator"
        

// bangali - added the next 3 line
//		attribute "power", "string"
//		attribute "energy", "string"
//		attribute "indicatorStatus", "string"
       
		fingerprint inClusters: "0x25,0x32"
	}


preferences {
   input("ReportTime", "number", title: "Report Timeout Interval?", description: "The time in minutes after which an update is sent?", defaultValue: 3, required: false)
   input("WattageChange", "number", title: "Wattage change before reporting: 1-25?", description: "The minimum wattage change before reporting?",defaultValue: 15, required: false)
   }

	// simulator metadata
	simulator {
		status "on":  "command: 2003, payload: FF"
		status "off": "command: 2003, payload: 00"

		for (int i = 0; i <= 10000; i += 1000) {
			status "power  ${i} W": new physicalgraph.zwave.Zwave().meterV1.meterReport(
				scaledMeterValue: i, precision: 3, meterType: 4, scale: 2, size: 4).incomingMessage()
		}
		for (int i = 0; i <= 100; i += 10) {
			status "energy  ${i} kWh": new physicalgraph.zwave.Zwave().meterV1.meterReport(
				scaledMeterValue: i, precision: 3, meterType: 0, scale: 0, size: 4).incomingMessage()
		}

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

	}

	// tile definitions
	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
			state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
			state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
		}
		valueTile("power", "device.power", inactiveLabel: false, decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy", "device.energy") {
			state "default", label:'${currentValue} kWh'
		}
		standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat") {
			state "default", label:'reset kWh', action:"reset"
		}
		standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}

		standardTile("indicatorStatus", "device.indicatorStatus", width: 1, height: 1, inactiveLabel: false, decoration: "flat") {
			state "when off", action:"indicator.indicatorWhenOn", icon:"st.indicators.lit-when-off"
			state "when on", action:"indicator.indicatorWhenOff", icon:"st.indicators.lit-when-on"
		
		}
		main(["switch","power","energy"])
		details(["switch","power","energy","indicatorStatus","refresh","reset"])
	}
}


def parse(String description) {
	def result = null
log.debug "in parse desc = $description"

	if(description == "updated") return 
	def cmd = zwave.parse(description, [0x20: 1, 0x32: 1, 0x70: 1, 0x72: 2])
	if (cmd) {
		result = zwaveEvent(cmd)
	}
	return result
}



def zwaveEvent(physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
log.debug "in meter report cmd = $cmd "

// bangali - commented the following block and changed them to sendEvent from createEvent
	if (cmd.scale == 0) {
		createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kWh")
	} 
    else if (cmd.scale == 1) {
		createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kVAh")
	} 
    else if (cmd.scale == 2) {
		createEvent(name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W")
	}
}


def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
// bangali
log.debug "in basic report cmd = $cmd "

	def evt = createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "physical")
	if (evt.isStateChange) {
		[evt, response(["delay 3000", zwave.meterV2.meterGet(scale: 2).format()])]
	}
    else {
		evt
	}
}


def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
// bangali
log.debug "in switch report cmd = $cmd "

	createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
}


def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
// log.debug "in config report  got indicatorstatus = $state.currentIndicatorStatus"	
// bangali
log.debug "in config report cmd = $cmd "

	[name: "indicatorStatus", value: state.currentIndicatorStatus, display: true]
}


def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
log.debug "in manuf specific report cmd = $cmd "

	def result = []
	
	result << response(delayBetween([
		zwave.meterV2.meterGet(scale: 0).format(),
		zwave.meterV2.meterGet(scale: 2).format(),
	]))

	result
}


def zwaveEvent(physicalgraph.zwave.Command cmd) {
// bangali
log.debug "in unhandled report cmd = $cmd"

log.debug "$device.displayName: Unhandled: $cmd"
	[:]
}


def on() {
log.debug "in on"

// bangali - everything originally worked fine except there was no reporting of 
// energy usage unless the refresh button is clicked in the ST app.
// to fix that, this schedules the poll() method to be executed on a recurring 
// schedule when switch is turned on. after this device handler is installed,
// turn on and off the switch for this polling to get scheduled.
// this one is every n minutes where n = reporting interval in settings.
//	schedule("0 */$settings.ReportTime * * * ?", refresh)

// bangali - to change reporting of energy usage to every 30 seconds,
// uncomment the following line and comment the schedule line before this.
//	schedule("0/30 0/1 0 ? * * *", poll)

	[
		zwave.basicV1.basicSet(value: 0xFF).format(),
		zwave.switchBinaryV1.switchBinaryGet().format(),
		"delay 3000",
		zwave.meterV2.meterGet(scale: 2).format()
	]
}


def off() {
log.debug "in off"

// bangali - this unschedules the poll() method when switch is turned off.
//	unschedule(refresh)

	[
    	zwave.basicV1.basicSet(value: 0x00).format(),
		zwave.switchBinaryV1.switchBinaryGet().format(),
		"delay 3000",
		zwave.meterV2.meterGet(scale: 2).format()
	]
}


def poll() {
// bangali - added next 2 lines and commented the remaining lines
log.debug "in poll"
    refresh()
    
//	delayBetween([
//		zwave.switchBinaryV1.switchBinaryGet().format(),
//		zwave.meterV2.meterGet(scale: 0).format(),
//        zwave.meterV2.meterGet(scale: 2).format()
//	])
}


// bangali - added PING is used by Device-Watch in attempt to reach the Device
def ping() {
// bangali
log.debug "in ping"
	refresh()
}


def refresh() {
log.debug "in refresh"

	def value = "when off"
//  log.debug "in refresh for when on got indicatorstatus = $state.currentIndicatorStatus"
	sendEvent(name: "indicatorStatus", value: state.currentIndicatorStatus, display: true)
	
	delayBetween([
		zwave.switchBinaryV1.switchBinaryGet().format(),
		zwave.meterV2.meterGet(scale: 0).format(),
        zwave.meterV2.meterGet(scale: 2).format(),
	], 1000)
}


def updated() {
log.debug "in updated"

	def cmds = []
//bangali - added next 3 lights
    // Device-Watch simply pings if no device events received for 32min(checkInterval)
	sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
    
	cmds = configure()
    unschedule(refresh)
	schedule("0 */$settings.ReportTime * * * ?", refresh)
	return response(cmds)
}


def configure() {
// bangali
log.debug "in configure"

	if (settings.WattageChange < 1 || settings.WattageChange > 25) {
		settings.WattageChange = 5;
	}
 
log.debug "In configure timeout value = $settings.ReportTime"
log.debug "Wattage change = $settings.WattageChange"
def wattageadjust = settings.WattageChange * 10;
log.debug "Wattage change = $settings.WattageChange adjusted: $wattageadjust "

	delayBetween([
		zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: settings.ReportTime).format(),	//send meter report every x minutes.
		zwave.configurationV1.configurationSet(parameterNumber: 10, size: 1, scaledConfigurationValue: settings.ReportTime).format(),	//accumulated energy report meter interval
		zwave.configurationV1.configurationSet(parameterNumber: 11, size: 1, scaledConfigurationValue: 1).format(),	//send only meter report when wattage change 1=meter, 2=multilevel , 3=both, 0=none 
		zwave.configurationV1.configurationSet(parameterNumber: 12, size: 1, scaledConfigurationValue: wattageadjust).format(),//Minimum change in wattage 0-255
		zwave.configurationV1.configurationSet(parameterNumber: 9, size: 1, scaledConfigurationValue: 0).format(),// dont send multilevel report
// bangali - added the following
		zwave.configurationV1.configurationGet(parameterNumber: 8).format(),
		zwave.configurationV1.configurationGet(parameterNumber: 9).format(),
		zwave.configurationV1.configurationGet(parameterNumber: 10).format(),
		zwave.configurationV1.configurationGet(parameterNumber: 11).format(),
		zwave.configurationV1.configurationGet(parameterNumber: 12).format(),
    ], 1000)
}


def reset() {
log.debug "in reset"
	state.currentIndicatorStatus = "when on"
	return [
		zwave.meterV2.meterReset().format(),
		zwave.meterV2.meterGet(scale: 0).format()
	]
}


def indicatorWhenOn() {
log.debug "in when on"
	state.currentIndicatorStatus = "when on"
	sendEvent(name: "indicatorStatus", value: "when on", display: true)
	zwave.configurationV1.configurationSet(parameterNumber: 0x01, size: 1, scaledConfigurationValue: 1).format()
}


def indicatorWhenOff() {
log.debug "in when off"
	state.currentIndicatorStatus = "when off"
	sendEvent(name: "indicatorStatus", value: "when off", display: true)	  
	zwave.configurationV1.configurationSet(parameterNumber: 0x01, size: 1, scaledConfigurationValue: 0).format()
}

Yes, that code segment was taken from the wakeupnotification zwave event so cmds had to be wrapped with response.

Nope. That code segment appears to be taken from one of my DTHs which has a workaround I had to put in when a ST Update broke the response command, but they fixed the bug shortly after.

There are a lot of issues unrelated to the configuration commands not making it to the device, but the most poorly written DTHs I’ve seen were written by SmartThings so some of them may have already been there…

You have a comment stating you added 3 attributes, but the attributes are already commeted out so I’m assuming you’re aware that those lines shouldn’t be there because their already declared by the corresponding capabilities.

You also have a comment stating you changed the createEvents into sendEVents in the PowerMeterReport event handler, but that wasn’t necessary.

I’m not sure if the Health Check related code was left over from the original DTH or if you implemented it, but it has several issues. The main one being that it’s not included in the capability list.

The ConfigurationReport event handler is returning a map instead of creatEvent so the indicatorStatus attribute won’t get updated.

The best way to troubleshoot the configuration problem is to add config get after config set in the indicatorWhenOn/off commands because the delay won’t matter since only 2 commands are being sent. I also recommend removing sendEvent from those commands and letting the ConfigurationReport method create it instead.

If that works, then change the configure method so that each config get is under the corresponding config set which will allow you to see if any of the commands are making it to the device.

If adding config get to the indicatorWhenon/off commands didn’t work, check the device’s fingerprint. If you see “sec:” and 70 is in the list then the device most likely only supports configuration commands that have been encapsulated.

If you don’t see “sec:” in the fingerprint then the only other thing I can think of is to try switching to configuration V2. Device’s are supposed to be backwards compatible, but at least one of the devices I’ve worked with wasn’t. To use v2 you have to change the number in your version get/set commands, configurationreport event, and change “0x70: 1” to “0x70: 2” in your parse method.

If I misunderstood the configuration problem and the configuration reports were coming back, but the values weren’t changing then switching to configuration v2 will most likely fix that.

@krlaframboise thank you much. i am going to parse through each line of your response and go back to work on this one. yes, i did take the examples i posted from your DHs.

thank you again.

still working through this, this device seems almost flaky. parts will work, then stop working and rework only if i unplug and replug-in the device.

one mystery i am trying to find a clue to is these 2 methods. the poll method seems to get called by ST every ~10 mins and returns the right meter data. the updateWatts method which is scheduled to run every 1 minute, gets called because i see the log output, but the meter data is never returned. given those methods are exactly the same that doesnt seem to make any sense.

any hints? :slight_smile:

def poll()	{
log.debug "in poll()"
	return	[
    	zwave.meterV2.meterGet(scale: 2).format()
    ]
}

def updateWatts()	{
log.debug "in updateWatts()"
	return [
		zwave.meterV2.meterGet(scale: 2).format()
	]
}

thanks!

Commands returned from a method executed by a schedule won’t get sent to the device so you have to use sendHubAction.

If you use that “sendResponse” method of mine, that you previously posted, in your updateWatts method it should solve your problem.

1 Like

that fixed it. :slight_smile: thank you.

1 Like

I know this is quite an old thread but I was looking into how to configure parameters without knowing them in advance and it seemed appropriate to add a comment since I have not found this information anywhere else. The Z-Wave PC controller seems like it already does this (probably) as it queries the device and it is possible to get up all the parameters of new devices without knowing them in advance.

I have found out that it should be possible with support for COMMAND_CLASS_CONFIGURATION
v3. There should be a CONFIGURATION_REPORT, a CONFIGURATION_INFO_REPORT, a CONFIGURATION_NAME_REPORT and CONFIGURATION_PROPERTIES_REPORT which provide the configuration parameter numbers, names, and range info. I have played around and used parts of the code from zwaveTweaker in my own DH, and I have seen payloads for the INFO report showing the names of parameters in my device (which supports V3) so I know it is almost working. Unfortunately ST does not parse these into the payload of the command handlers, and it doesn’t allow the properties report at all (groovy error).

If one day ST properly supports CONFIGURATION v3, and the parsing of that then it would be possible to query the device itself for the configuration parameters that it supports. Ideally helper functions for that should be available in the z-wave API for ST as its quite a bit of additional code to cycle through the BULK configuration report and query all of the parameters with a V3 CONFIGURATION_NAME_GET etc.

As you noted, this thread is four years old, and quite a bit has changed in that time.

In particular, a community member built a DTH to do exactly this and it works very well. You just temporarily switch your device to the “Z wave tweaker“, scan for the current settings, make any changes you want, and then switch back to your every day DTH.

It’s been very popular since it was first introduced a few years ago, and just recently another community member has updated it to work with the current version of the smartthings app. :sunglasses:

See the first post in the thread for an explanation of what it does (the topic title is a clickable link), then skip down to post number 209 for the updated version.

What you cant do at the moment with ST is a full introspection of the device even though the device may support it. If this was supported properly then you would be able to write a more generic DH without needing the devices documentation. The tweaker (and the new one) only gives you a list of the parameters and their values, but the device may also have the list of parameter names and their valid options/ranges which can be queried. It is this level of query that is not supported by ST.
A little more info here:

In future I hope ST can fully support CONFIGURE v3 so that you can make a full in depth query and not have to program in all of the configuration options.

1 Like

I checked with friends who are current field techs. They said configure V3 had a lot of problems with it, including the recommendation of using English text, an inability to handle bulk requests, and a major problem with configurations getting reset by accident. And the V3 fields don’t respond support multi endpoints anyway. So they said very few manufacturers have adopted it for their devices.

A new version, V4, has been approved, And is intended to go along with the new Smart Start paradigm where professional installers receive network kits with all of the devices already set up on the network, and they just have to be physically installed and verified.

The configuration parameters in those cases are mostly used for devices which have to be calibrated, so the configure parameters are intended to work with the pro installer tools. There is also a big emphasis in V4 on bulk response, again intended for this use case. And some fields will be read only, to prevent accidental changes.

Nobody seems to be expecting this to be an update to existing devices, their expectation is that it will roll out with the series 700 “zwave plus V2” Devices once the long range upgrade is available (LR). But probably not before.

One of them pointed out that V3 is very specific that anything that you can get from the report in regard to the description fields also Has to be in the user manual for the device , And that should be available with the conformance statement. He said this has the advantage of being able to be in different languages in the printed materials. He said the installer tools that he uses do not use the V3 fields but they have been told that in the future they will use the V4 fields.

It should be emphasized that, just like versions 1 and 2, the Configuration Command Class, version 3 is intended only for access to product specific configuration parameters. The access to parameter information is only meant to facilitate access via Z-Wave to information which can also be found in the printed documentation.

So since right now most of the devices don’t have anything to report for V3 anyway, I’m not sure it will ever be supported in that sense. But my guess would be that Aeotec will push for V4 support at least in the cloud platform once they have a “works as a smartthings hub“ series 700 version with Z wave plus V2 LR. But maybe not before.

Here’s the specification for the configure command which includes the V4 updates.

https://www.silabs.com/documents/login/miscellaneous/SDS13781-Z-Wave-Application-Command-Class-Specification.pdf#page174