Zwave configurationv2 ConfigurationReport dev question

Just looking a some specific answer (without large architecture debate, etc)…

When parsing physicalgraph.zwave.commands.configurationv2.ConfigurationReport commands (assumed to be assigned to “cmd”), the parameter being sent can be found in cmd.parameterNumber. Assuming the parameter size of 1, the parameter’s value is found in “cmd.configurationValue[0]”.

No problem. However, I’m trying to deal with a parameter with a size of 4. (32bit value.) How do I get that configuration value? Do I have to manually do the math to convert the 4 elements of the configurationValue list (in C, I’d use bitshifts, but not sure if groovy supports that), or is there some language construct to convert a list of 4 “short” values into a single 32 bit value?

If I have to “do the math”, what format is the list in? big endian or little endian? (in other words, is the least significant byte stored in [0] or [3]?)

Thanks
Gary

Nevermind - I found the answer via a bit of experimenting. In case someone finds this topic in a search, here’s the answer:

fullValue = cmd.configurationValue[3] + (cmd.configurationValue[2] * 0x100) + (cmd.configurationValue[1] * 0x10000) + (cmd.configurationValue[0] * 0x1000000)

1 Like

There is a property on the ConfigurationReport class called “scaledConfigurationValue” that does exactly what you are doing through multiplication and addition.


def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd)
{
    def value = cmd.scaledConfigurationValue
    log.debug "value: ${value}"
}
1 Like

No, that doesn’t work. Just tried it and got this result:

The “scaledConfigurationValue” propery does exist for ConfigurationSet, however.

Sorry for the bad advice.
I really wish these classes had better documentation.

stupid question perhaps… I’m dealing with the same issue where I need to convert the configurationget output from a 4 byte value… ST returns [0, 0, 2, 88] which I had set using scaledConfigurationValue to 72000… I’m at a loss how to convert from [0, 0, 2, 88] to a readable decimal value.

Yeah sorry we still haven’t added scaledConfigurationValue to the reports. No one is really working on the z-wave parsing library right now so things are only getting fixed when we really need them.

Gary’s code above looks good:

Or this should work too, and handles negative values as well if the device uses those:

int value = java.nio.ByteBuffer.wrap(cmd.configurationValue as byte[]).getInt()
1 Like

So I’m writing my own ConfigurationReport parser and I tried Duncan’s code:

int value = java.nio.ByteBuffer.wrap(cmd.configurationValue as byte).getInt()

but I just get the error:

java.lang.SecurityException: Invoking methods on class java.lang.Class is not allowed: wrap

I tried adding the import statement, but it didn’t help.

import java.nio.ByteBuffer

Any ideas?

Thanks
David

Yeah, I’d love to know why ByteBuffer is not usable in ST, nor is DataOutputStream which make writing/parsing binary data really inconvenient :frowning:

Sounds like it got taken out of the sandbox. It’s probably easier for me to just add scaledConfigurationValue than to track down why that happened. Until then, use Gary’s version

1 Like

Actually, this might work too:

def value = new BigInteger(cmd.configurationValue as byte[])

Thanks @duncan, but with this code I get the error java.lang.ArrayStoreException: java.lang.Long

Revisiting this issue with another device handler I’m writing and hoped it would be fixed by now. I’ve looked to see if scaledConfigurationValue has been added to the configuration reports yet, but it hasn’t, so still stuck with a rather nasty bit of workaround code… :frowning:

I’ve noticed there’s a bug in configurationSet(). It doesn’t work if you use a scaledConfigurationValue >= 32768 (i.e. 15bits). I would hazard a guess that it’s converting to a signed byte array instead of an unsigned one(?).

cmds << zwave.configurationV1.configurationSet(parameterNumber: 10, size: 2, scaledConfigurationValue: 32767).format() // This works.

cmds << zwave.configurationV1.configurationSet(parameterNumber: 10, size: 2, scaledConfigurationValue: 32768).format() // This doesn’t work.

Instead you have to break the integer down into bytes and use configurationValue instead :
cmds << zwave.configurationV1.configurationSet(parameterNumber: 10, size: 2, configurationValue: [128, 0]).format() // This works.

I have a fix for this and the addition of scaledConfigurationValue to ConfigurationReport going in to an upcoming release.

However, note that configurationSet(parameterNumber: 10, size: 2, scaledConfigurationValue: 32768) is not technically valid, as the field is defined as a signed integer to accommodate negative numbers. A properly implemented device will interpret [128, 0] as -32768

1 Like

Thanks for this Duncan, please let us know when the scaledConfigurationValue update is live.

Indeed you are correct that the scaledConfigurationValue is signed. I’ve re-read the documentation for the Fibaro RGBW Controller again and they are careful to describe the values for parameter #14 in binary only, so it was it is my fault for incorrectly interpreting them as unsigned integers for manipulation, before the conversion back to binary. :smile_cat: This would also explain why the parameters that range from ‘0-255’ are 2-bytes in size instead of one. Interesting that I’ve yet to see any device actually use negative numbers for parameter values though.

There have been some delays with platform updates, so I’m not sure how soon it will be live.

To be clear, my change will allow unsigned values like zwave.configurationV1.configurationSet(parameterNumber: 10, size: 2, scaledConfigurationValue: 32768).format() because of cases like the one you described.

How will this work exactly? Will this match the scaledConfigurationValue that is obtained from a corresponding configurationReport cmd (which I assume is signed)? I was happy to accept that scaledConfigurationValue is signed, as per the z-wave spec you posted above.

No, if you get a ConfigurationReport with 0x8000, then scaledConfigurationValue will return -32768