Page 177 of the Z-Wave Application Command Class Specification, under section 4.32.1 - Compatability considerations.
Thans for the reply
I understand what you mean, I have to trick the default libraries so that they send the value FFFF (65535), sending the value -1 to the default library function.
I would have to make a code change before sending the value to the defualt function for these specific manufacturers.
I do not want to doubt what you say, since I am not an expert in this and I am sure I am wrong and I do not want you to misunderstand me either, I just want to collaborate
As seen in the link @orangebucket sent, zwave-alliance says that you can use values with signed and unsigned format
There is even an example with size = 2 bytes and the value range from 0 to 65535.
On the other hand, also in the edge libraries it is clear that these formats can be used in the configuration, not only the signed one.
--- @class st.zwave.CommandClass.Configuration.format
--- @alias format st.zwave.CommandClass.Configuration.format
--- @field public SIGNED_INTEGER number 0x00
--- @field public UNSIGNED_INTEGER number 0x01
--- @field public ENUMERATED number 0x02
--- @field public BIT_FIELD number 0x03
local format = {
SIGNED_INTEGER = 0x00,
UNSIGNED_INTEGER = 0x01,
ENUMERATED = 0x02,
BIT_FIELD = 0x03
}
Configuration.format = format
Configuration._reflect_format = zw._reflection_builder(Configuration.format)
Also If this is going to stay like this, you will have to correct the code to send the AEON_NANO_SHUTTER configuration parameter 35, “openCloseTiming”, profile “stateless-curtain-power-button” to be able to send the values 128 to 255, with size = 1 Byte. with default libraries.
It will give oveflow integer error.
Apart from this, the profile needs in the preference the - name: "openCloseTiming"
before the title field to make it work.
name: stateless-curtain-power-button
components:
- id: main
capabilities:
- id: statelessCurtainPowerButton
version: 1
- id: refresh
version: 1
categories:
- name: Blind
preference:
- preferenceId: reverse
explicit: true
- title: "Open close timing"
description: "Set the motor's open/close time"
required: false
preferenceType: interger
definition:
minimum: 5
maximum: 255
default: 10
AEON_NANO_SHUTTER = {
MATCHING_MATRIX = {
mfrs = {0x0086, 0x0371},
product_types = {0x0003, 0x0103},
product_ids = 0x008D
},
PARAMETERS = {
openCloseTiming = {parameter_number = 35, size = 1}
}
}
Thanks agains
Actually I may be causing the confusion because I missed this in the spec relating to Configuration V3 and V4:
A device supporting the Configuration Command Class v3 MUST respond to a Configuration Properties Get command. If a Configuration Properties Report command is not returned in response to a Configuration Properties Get command, a controlling device MUST treat the parameter value as a signed integer.
This indicates to me that v3 and v4 do support other types besides signed integers. However, it does appear that we are always serializing a signed value for the configuration parameters regardless of the format (the Configuration format in the ST Lua libs is only used in the Configuration Properties commands)
The workaround provided seems necessary for these situations for the time being, but I will work internally to get the configuration format to be respected when we are sending v3 and v4 Configuration Set commands.
Thanks for bringing this to our attention.
Enlarging the size of the parameter value prevents the sending from generating an overflow error in the driver, but it does not work well since the value is interpreted in the device in an erroneous way.
Sending the value with 2’s complement and the correct size does work well to send the value and to configure the device correctly.
For now I will leave it like this in my driver for specific fibaro devices subdrivers.
--- Handle preference changes
---
--- @param driver st.zwave.Driver
--- @param device st.zwave.Device
--- @param event table
--- @param args
local function info_changed(driver, device, event, args)
local preferences = preferencesMap.get_device_parameters(device)
for id, value in pairs(device.preferences) do
if args.old_st_store.preferences[id] ~= value and preferences and preferences[id] then
local new_parameter_value = preferencesMap.to_numeric_value(device.preferences[id])
--2's complement value if needed
if preferences[id].size == 2 and new_parameter_value > 32767 then
new_parameter_value = new_parameter_value - 65536
elseif preferences[id].size == 1 and new_parameter_value > 127 then
new_parameter_value = new_parameter_value - 256
end
device:send(Configuration:Set({parameter_number = preferences[id].parameter_number, size = preferences[id].size, configuration_value = new_parameter_value}))
end
end
end
Maybe if it is implemented in the main init.lua (info_changed function), sending the value with complement 2 for all values that exceed the corresponding positive range of size 1, 2, 4 would be valid for all cases
Thanks
Doing the driver of the Z-Wave parameter configurator I have seen that smartthings default libraries to allow the sending of negative values.
This means that if the parameter is:
- 1 Byte (0xFF): positive from 0 to 127 and negative from -1 to 128
- 2 Byte (0xFFFF): positive from 0 to 32767 and negative from -1 to 32768
So far everything perfect, but still disallow sending unsigned values
Some devices like old fibaro, fibaro relay, I do not know if there will be more cases in more manufacturers or models, need send these values:
- Parameter: 4
- value : 0 to 65535
- Size: 2 Bytes
Others like Aeotec Nano Shuter in their driver zwave-window-treatment:
- parameter: 35
- value : 5 to 255
- Size: 1 Byte
As I mentioned in above post, I solved it in my modified drivers by sending the complement to 2 for values > 127 (with 1 Byte) 0 > 32767 (with 2 Byte)
The fibaro devices continues to work fine althoughthe value shown in the CLI when reading is -32768 instead of 65535, because it sends the value in hexadecimal and the device interprets it well, but the CLI and libraries default does not decode fine these values to shown It when received with configuration parameter Get function. Always interprets it as signed values.
In the drivers that do not have this modification like some yours stock, when they send values > 127 (1Byte) or > 32767 (2 Byte) it will give this fatal error and the device will not be configured:
2022-08-13T09:41:26.362964862+00:00 ERROR Z-Wave Device Config Mc Fibaro Single Relay thread encountered error: [string "st/dispatcher.lua"]:233: Error encountered while processing event for <ZwaveDevice: e062ff99 -4cfc-47c2-be7f-91881fdc3a8c [1F] (Fibaro Single Relay)>:
arg1: table: 0xa56778
[string "st/utils.lua"]:188: bad argument #2 to 'pack' (integer overflow)
The most modern devices I have seen that for values 0 to 255, they have a size of 2 bytes and for values 0 to 65535 they have a size of 4 bytes
@Mariano_Colmenarejo, thank you for your persistence. I appreciate you helping identify issues with the stock drivers. This is still on my radar, but due to some bandwidth issues it has yet to be fixed.

thank you for your persistence. I appreciate you helping identify issues with the stock drivers. This is still on my radar, but due to some bandwidth issues it has yet to be fixed.
Thanks for your response.
If the final solution is to change something in the default libraries instead of in the affected drivers, please, if you remember, let us know in case the custom drivers are affected with the solution.
Hello
I didn’t want to go back on the subject, but I found another error that I don’t know if it’s my mistake or it’s from the default libraries.
When trying to obtain the value of a configuration parameter with the default function:
device:send(Configuration:Get({ parameter_number = parameter_number }))
and I introduce a parameter number greater than 255, I get an error: bad argument #2 to 'pack ’ (unsigned overflow)
2022-08-17T15:11:42.036826361+00:00 INFO Z-Wave Device Config Multi <ZwaveDevice: e062ff99-4cfc-47c2-be7f-91881fdc3a8c [1F] (Fibaro Single Relay)> emitting event: {"attribute_id":"deviceParameter","capability_id":"legendabsolute60149.deviceParameter","component_id":"main","state":{"value":256}}
2022-08-17T15:11:42.063903027+00:00 DEBUG Z-Wave Device Config Multi Fibaro Single Relay device thread event handled
2022-08-17T15:11:43.050611028+00:00 TRACE Z-Wave Device Config Multi Received event with handler capability
2022-08-17T15:11:43.068225361+00:00 INFO Z-Wave Device Config Multi <ZwaveDevice: e062ff99-4cfc-47c2-be7f-91881fdc3a8c [1F] (Fibaro Single Relay)> received command: {"args":{},"capability":"legendabsolute60149.actionbutton2","command":"push","component":"main","positional_args":{}}
2022-08-17T15:11:43.074040028+00:00 TRACE Z-Wave Device Config Multi Found CapabilityCommandDispatcher handler in zwave_thing
2022-08-17T15:11:43.079101361+00:00 PRINT Z-Wave Device Config Multi <<< Action_button:
2022-08-17T15:11:43.084908028+00:00 ERROR Z-Wave Device Config Multi Fibaro Single Relay thread encountered error: [string "st/dispatcher.lua"]:233: Error encountered while processing event for <ZwaveDevice: e062ff99-4cfc-47c2-be7f-91881fdc3a8c [1F] (Fibaro Single Relay)>:
arg1: table: 0xc962c8
[string "st/utils.lua"]:188: bad argument #2 to 'pack' (unsigned overflow)
The Configuration statement in the driver is v4
local Configuration = (requires "st.zwave.CommandClass.Configuration")({ version=4 })
I think the range of the parameter values for v4 is from 0 to 65535
For v1 if it is from 0 to 255 or does it apply to all versions?
Thanks

I think the range of the parameter values for v4 is from 0 to 65535
The z-wave spec continues to restrict the range for Configuration:Get and Configuration:Set to 1 to 255. You’ll need to use Configuration:BulkGet and Configuration:BulkSet to access the full range of 1 to 65535.
I hit the unsigned-with-Configuration:Set issue today. Its easy to trigger.
- Try and send parameter to device with
device:send(Configuration:Set({parameter_number = 10, size = 1, configuration_value = 255}))
-
[string "st/utils.lua"]:188: bad argument #2 to 'pack' (integer overflow)
is logged.
I added the workaround for converting to signed but hoping the correct conversion is added soon.
I am seeing this as well while we are developing a new 800 series switch. We are using configuration cc v4 with unsinged integers, but ST is throwing an error when the value is in the higher range (as mentioned multiple times above). I guess I will be converting my values in the time being as a workaround.

I am seeing this as well while we are developing a new 800 series switch
Hi @erocm1231
If you are starting device development, one solution is to double the size in bytes of the parameter in the firmware, for example:
If you want to cover a value with a range from 1 to 255, which could be done with 1 Byte unsigned, you assign 2 Bytes to it, so the value 255 is into the first byte of the positive sign.
This is what I have seen that other manufacturers like fibaro are doing in their new devices.
in fibaro dimmer2:
parameter 50, range 0 to 32767 and parameter size=2 ( 2 byte range = 0 to 65535)
parameter 52, range 0 to 32767 and parameter size=2 ( 2 byte range = 0 to 65535)
parameter 53, range 0 to 255 and parameter size=2 ( 2 byte range = 0 to 65535)
- name: "periodicPowerReports"
title: "periodic power reports - 52"
description: "This parameter 52 defines in what time interval in sec the periodic power and energy reports are sent. 0 periodic reports disabled"
required: false
preferenceType: number
definition:
minimum: 0
maximum: 32767
default: 3600
- name: "energyReports"
title: "energy reports - 53"
description: "This parameter 53 Energy level change which will result in sending a new energy report. 0-energy reports disabled. 1-255 (0.01-2.55 kWh)-report triggering threshold"
required: false
preferenceType: number
definition:
minimum: 0
maximum: 255
default: 10
only use size = 1 when range is max 127
- name: "maximumLevel"
title: "Maximum brightness level - 2"
description: "This parameter 2 allows set Maximum brightness level % (2 to 99)"
required: false
preferenceType: number
definition:
minimum: 2
maximum: 99
default: 99
PARAMETERS = {
minimumLevel = {parameter_number = 1, size = 1},
maximumLevel = {parameter_number = 2, size = 1},
restoreState = {parameter_number = 9, size = 1},
autoOffTimer = {parameter_number = 10, size = 2},
autoCalibration = {parameter_number = 13, size = 1},
forcedOnLevel = {parameter_number = 19, size = 1},
switchType = {parameter_number = 20, size = 1},
toggleSwitchStatus = {parameter_number = 22, size = 1},
doubleClickOption = {parameter_number = 23, size = 1},
threeWaySwitch = {parameter_number = 26, size = 1},
sceneActivation = {parameter_number = 28, size = 1},
onOffMode = {parameter_number = 32, size = 1},
activePowerReports = {parameter_number = 50, size = 2},
periodicPowerReports = {parameter_number = 52, size = 2},
energyReports = {parameter_number = 53, size = 2}
}
The size has to be defined like this in the firmware of the device for it to work well
If you send the double size as it is now, the error does not appear in the log, but the device does not accept it

I guess I will be converting my values in the time being as a workaround.
It’s marked as fixed in beta firmware, not yet in production:
Hub Firmware 0.46.X Beta Hey everyone! We’re excited to announce the start of a new SmartThings Hub Firmware Beta. Version 0.46.4 will begin rolling out in batches starting on Dec 5, 2022. This will be a phased rollout so that we can keep a close eye on any issues that arise so your hub may not be updated immediately. The hub will be offline for about a minute during the update. See below for more specific details about the update. Known Issues Our team has identified a few known issues that will be fixed after the rollout: The use of driver:register_channel_handler for Lua LAN driver channel handler registration may cause the driver to hang. It is recommended to not use this handler until a fix is in place. The use of cosock.spawn without handler registration can work around this is…
- Fixed two Z-Wave Configuration Command Class bugs to allow for unsigned, bit mask, and enum parameter type serialization, and 0-sized parameter deserialization in the PropertiesReport Command
So i would guess its coming soon!

So i would guess its coming soon!
Only on hubs that will get the 46.x firmware though. Not going to help the ‘wifi’ hubs which lag behind, and what do the other hubs run?

So i would guess its coming soon!
I have the latest version of the beta 46.07 firmware and I have tried to send the unsigned parameters and it keeps giving the same error.
[string "st/utils.lua"]:188: bad argument #2 to 'pack' (integer overflow).
Possibly I am doing something wrong, it could be.
Using the command
device:send(Configuration:Set({parameter_number = parameter_number, size = parameter_size_set, configuration_value = parameter_value_send}))
The 2’s complement of the value that exceeds the positive range of the parameter size must continue to be needed to not error and can write the parameter value.
In fact, the stock drivers continue to use this command to send the parameters and always execute it as a signed integer.
I don’t know how to pass arguments to firmware libraries when I want to send an unsigned integer parameter.
The stock Aeotec Nano Shuter driver in their driver zwave-window-treatment:
Preferences:
- parameter: 35
- value : 5 to 255
- Size: 1 Byte
still sending values greater than 127 with a size of 1 Byte which gives the error:
[string “st/utils.lua”]:188: bad argument #2 to ‘pack’ (integer overflow).
On the other hand, I have read parameter 4 of a fibaro relay that has a value of 65535 with a size of 2 Bytes and what it reads is a value = -1, which is the 2’s complement for that value.
2023-01-17T14:57:11.544249993+00:00 TRACE Z-Wave Device Config Mc Received event with handler unnamed
2023-01-17T14:57:11.545296993+00:00 INFO Z-Wave Device Config Mc <ZwaveDevice: 664da0a9-eecb-4f9b-8062-e73135110abf [26] (Fibaro Single Relay)> received Z-Wave command: {args={configuration_value=-1, parameter_number=4, size=2}, cmd_class=“CONFIGURATION”, cmd_id=“REPORT”, dst_channels={}, encap=“NONE”, payload=“\x04\x02\xFF\xFF”, src_channel=0, version=1}
can see the payload, the value in device is 0xFF & 0xFF = 65535
I don’t know what they fixed but this seems not
As I was commenting all the newer devices from different manufacturers I’ve reviewed that have configuration parameters choose parameter sizes as if they were going to use signed integers values even though they only use positive values without sign
To avoid possible bugs with older devices, in all my drivers I use this 2’s complement conversion before sending configuration or preference parameters.
--2's complement value if needed
local parameter_value_send = parameter_value_set
if parameter_size_set == 4 and parameter_value_set > 2147483647 then
parameter_value_send = parameter_value_set - 4294967296
elseif parameter_size_set == 2 and parameter_value_set > 32767 then
parameter_value_send = parameter_value_set - 65536
elseif parameter_size_set == 1 and parameter_value_set > 127 then
parameter_value_send = parameter_value_set - 256
end
print("new_parameter_value Sent >>>>",parameter_value_send)
-- Sent configuration parameter to device
device:send(Configuration:Set({parameter_number = parameter_number, size = parameter_size_set, configuration_value = parameter_value_send}))
Thank you. I have done something similar, but was only converting for 1 byte values (since that is the only “problem” parameters that we currently have). I like your version as it covers multiple byte scenarios.
@carter.swedal while I understand that you’re trying to follow the z-wave specs to the letter, it does create a problem while porting DTH’s as well as trying to map manufacturers values. The signed value only represents the interpretation of the values, not how the values are transmitted over z-wave.
For example a value of 255 (size 1 byte) will be transmitted as 11111111 over the air. Now the z-wave libraries may treat this as -128 to 127 and the manufacturer’s z-wave device may process this as 0-255, but the underlying value itself hasn’t changed. Keeping mind that DTH’s and Manufacturers are using 0-255 I would like to request that the API’s be extended to allow the driver to send unsigned integers to the command value
as ALSO receive unsigned configuration_value
back from the received commands so the mapping them to manufacturer specs and porting DTH’s becomes manageable. It seems unreasonable for users to enter a value from -128 to 127 for something like number of seconds where as the manufacturer would be treating them as 0 to 255. Yes it can potentially be handled in the driver by converting them from unsigned to signed and vice versa but it can lead to many mistakes as Mario has pointed out above in the stock drivers as well as overly complicated code which in turn can lead to more errors in production (esp when one driver is supporting 50+ devices with 100+ configuration parameters from different manufacturers all of which seem to be publishing their specs in unsigned numbers). Unsigned numbers worked beautifully with DTH’s and I hope there’s a way to do the same with drivers.
Also, I would request some helper API’s to convert unsigned to signed numbers and vice versa, while we can write it for each driver, it would be very helpful for most devs to use a standard library api for this.
I see your point that despite the spec being clear, manufacturers have done what they want and our need to follow the spec is still causing some pain here.
I would like to request that the API’s be extended to allow the driver to send unsigned integers to the command
value
This is possible using ConfigurationSet V3 and V4 commands per the spec, support was added in 0.46.x lua libraries. This is done using format
argument.
local Configuration = (require "st.zwave.CommandClass.Configuration")({version=4})
Configuration:Set({
parameter_number = 13,
size = 1,
configuration_value = 255,
format = Configuration.format.UNSIGNED_INTEGER
})
ALSO receive unsigned
configuration_value
back from the received commands so the mapping them to manufacturer specs and porting DTH’s becomes manageable.
There is nothing in the ConfigurationReport command that indicates the format of the configuration value, so any solution we implement will still require prior knowledge of this format in the driver. I’ll get something on our backlog to add utility functions for doing 2s-complement to unsigned conversions and visa versa for various sized values, as well as integrate those utilities into functions on the configuration values that are returned from ConfigurationReport commands so the driver can easily convert to whatever type they want for any configuration value.