My Z-Wave is borked

To those who can reproduce the issue: Can you please show the Code representation of the thing before and after saving it? Can you also go to the “API Explorer”, and show the result of “things” / “GET things/{thingUID}” for the thing before and after saving it?

Value -1 is “normal” for quite a long time. I have this issue on 3.2.0 stable, and it was there on 3.1.0 (I’m new to OH, I didn’t see older versions).

255 is 1111 1111 in unsigned int8… but 1111 1111 is -1 in signed int8.
Looks like minor mistake in binding code - not an issue for me.

Sadly it’s more complicated than this. As you may be aware, the ZWave protocol defines that all config parameters are signed numbers - so for 8 bits, as you point out that is -127 to +128. However many devices define their configuration as unsigned values - so 0 to 255. The database was written to the standard and it doesn’t have a way to configure signed or unsigned data, so this is why the data is showing as -1, since this is how the ZWave protocol documents define a value of 0xFF.

1 Like

code before, when HANDLER_CONFIGURATION_PENDING:

UID: zwave:device:512:node49
label: Freezer Leak Sensor
thingTypeUID: zwave:homeseer_hsls100_00_000
configuration:
  config_20_2: 1040
  config_32_1: 20
  wakeup_interval: 3600
  group_1:
    - controller
  group_2: []
  wakeup_node: 1
  config_17_1: 5
  config_18_1: 1
  config_19_1: -112
  config_22_2: 320
  config_24_1: 1
  config_14_1: 0
  config_15_1: 0
  node_id: 49
bridgeUID: zwave:serial_zstick:512

… and, I can’t save it. But a validation error pops up when I try: Dropbox Capture

if I change that to 60, I can save, and it comes online. The new code is

label: Freezer Leak Sensor
thingTypeUID: zwave:homeseer_hsls100_00_000
configuration:
  config_20_2: 1040
  config_32_1: 20
  wakeup_interval: 3600
  group_1:
    - controller
  group_2: []
  wakeup_node: 1
  config_17_1: 5
  config_18_1: 1
  config_19_1: 60
  config_22_2: 320
  config_24_1: 1
  config_14_1: 0
  config_15_1: 0
  node_id: 49
bridgeUID: zwave:serial_zstick:512

Disabling and re-enabling it reverts back to -112.

Another one:

label: Water Closet Lights
thingTypeUID: zwave:ge_26933_00_000
configuration:
  config_10_2: 2
  config_11_1: 1
  group_1:
    - controller
  group_3: []
  group_2: []
  switchall_mode: 255
  config_1_1: 1
  config_2_1: -1
  config_15_2: 2
  config_16_1: 0
  config_7_1: 1
  config_17_1: 0
  config_12_2: 1
  config_18_1: 0
  config_8_2: 1
  config_9_1: 1
  config_19_1: 0
  config_3_1: 3
  config_13_1: 1
  config_4_1: 0
  config_14_1: 0
  config_5_1: 0
  config_6_1: 1
  node_id: 147
bridgeUID: zwave:serial_zstick:512

I can correct config2_1 by setting it to 255, but it reverts back to -1 again. It’s Level to restore the dimmer to when turning on, with -1 meaning the prior level.

Another is

label: Dining Room Deck Door Lock
thingTypeUID: zwave:kwikset_914c_00_000
configuration:
  config_31_1: 0
  config_40_1: 0
  group_1: "[controller]"
  config_33_4: 538976288
  config_35_2: 0
  config_34_4: 538976288
  group_2:
    - controller
  node_id: 193
bridgeUID: zwave:serial_zstick:512

Config 33 and 34 it’s complaining that Value must be less than or equal to 126.

Another:

UID: zwave:device:512:node52
label: Great Room Left Lamp
thingTypeUID: zwave:qubino_zmnhdd_00_000
configuration:
  config_30_1: 0
  config_10_2: 255
  group_9: []
  group_8: []
  group_5: []
  group_4:
    - controller
  group_7: []
  group_6: []
  group_1:
    - controller
  group_11: []
  group_3:
    - controller
  group_2:
    - controller
  config_110_2: 32536
  config_12_2: 0
  config_11_2: 0
  config_250_1: 0
  config_20_1: 0
  config_65_2: 50
  config_21_1: 0
  config_42_2: 0
  config_61_1: 99
  config_40_1: 10
  config_60_1: 1
  group_10: []
  config_1_1: 1
  config_2_1: 0
  config_101_1: 0
  config_120_1: 5
  config_100_1: 0
  config_3_1: 0
  config_4_1: 0
  config_66_2: 1
  config_67_1: 0
  config_68_1: 0
  node_id: 52
bridgeUID: zwave:serial_zstick:512

This one doesn’t have any configuration errors when I save it. The post-save code:

UID: zwave:device:512:node52
label: Great Room Left Lamp
thingTypeUID: zwave:qubino_zmnhdd_00_000
configuration:
  config_30_1: 0
  config_10_2: 255
  group_9: []
  group_8: []
  group_5: []
  group_4:
    - controller
  group_7: []
  group_6: []
  group_1:
    - controller
  group_11: []
  group_3:
    - controller
  group_2:
    - controller
  config_110_2: 32536
  config_12_2: 0
  config_11_2: 0
  config_250_1: 0
  config_20_1: 0
  config_65_2: 50
  config_21_1: 0
  config_42_2: 0
  config_61_1: 99
  config_40_1: 10
  config_60_1: 1
  group_10: []
  config_1_1: 1
  config_2_1: 0
  config_101_1: 0
  config_120_1: 5
  config_100_1: 0
  config_3_1: 0
  config_4_1: 0
  config_66_2: 1
  config_67_1: 0
  config_68_1: 0
  node_id: 52
bridgeUID: zwave:serial_zstick:512

If there is a simple error in the database, then this will need to be resolved - this seems to be the case for the first example, but the second example looks the same both pre and post save as far as I can see.

Looking at the first example (zwave:homeseer_hsls100_00_000) this looks like a signed/unsigned issue. -112 signed is 240 unsigned which looks reasonable, if you set it to 60 (seems to be a time in s). The second one (zwave:ge_26933_00_000) is the same.

I‘ll check the code if it has issues with negative numbers.

I have no idea about the third one (zwave:kwikset_914c_00_000), is that the one you said has a database error, @chris?

What is the validation complaining about for the last one (zwave:qubino_zmnhdd_00_000)?

No - by the database error I meant if the min/max is not set appropriately given that the binding treats values as signed (as per the standards) but device manuals sometimes don’t.

The database looks fine - all the defaults are within the min/max values set and there doesn’t appear to be any issue with signed / unsigned in this device (as far as I can see, but I don’t have the device so I can’t confirm this)…

I guess it might be useful to add some logging to log what the error is?

1 Like

Just to make sure: the min/max defined is -127/128 so!-1 is a valid value and the checker tries to validate against 0-255?

Then it would be very useful to see the configdescription for that device. This can be retrieved from the REST API, can you show that, @ccutrer?

Apart from that I‘ll add the logging. It‘s easy because the validation code already gives a reason, it‘s only converted to valid/invalid.

No - what I meant when I said there doesn’t appear to be a signed/unsigned issue is that for this device, the values are (for example) 0 to 32, or 15 to 126 - nothing that should end up being a problem for signed/unsigned.

The signed / unsigned issue is not so easy to resolve automatically since it comes down to the standard saying one thing, and manufacturers doing something different. the only way I can see to resolve this is to add a signed/unsigned option in the database and changing the way the data is managed.

I checked the first case and found

<parameter name="config_19_1" type="integer" groupName="configuration"
                 min="0" max="255">
        <label>19: Temperature report time (minute)</label>
        <description><![CDATA[
Temperature report time (minute)<br /> <h1>Overview</h1><p>The higher the value ,the long the report time</p> <p>0 - Disable report</p>
        ]]></description>
        <default>0</default>
      </parameter>

So, clearly it’s correct that the validation fails on -1. I don’t fully understand why it reverts back to -1. I had a quick look at 'ZWaveThingHandler`. Am I right that this requests the config from the device and updates the configuration with the received value? And since that is a byte (which is signed), the value is re-set to -1. If so I don’t see an issue with the validation code, either the restrictions on the values need to be adjusted (which feels wrong, you already said that these reflect the bounds defined by the manufacturer) or the handler should decide on the defined range if he needs to chose signed or unsigned.

here’s an excerpt of /rest/thing-types/zwave:homeseer_hsls100_00_000

"configParameters": [
        {
            "default": "0",
            "description": "Enabe/Disable BASIC SET command",
            "label": "14: Enabe/Disable BASIC SET command",
            "name": "config_14_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Disable",
                    "value": "0"
                },
                {
                    "label": "Enable",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Value of the BASIC SET",
            "label": "15: Value of the BASIC SET",
            "name": "config_15_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "BASIC SET 255",
                    "value": "0"
                },
                {
                    "label": "BASIC SET 0",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "5",
            "description": "Set flooding alarm interval (Minute)<br /> <h1>Overview</h1><p>The higher the value, the long the report periodically - in hexadecimal values from 0x01 to 0xFF, or 1 to 255 if your controller allows unsigned decimal values.</p> <p>0 - Disable flooding alarm</p>",
            "label": "17: Set flooding alarm interval (Minute)",
            "name": "config_17_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 255,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Enabe/Disable shock alarm",
            "label": "18: Enabe/Disable shock alarm",
            "name": "config_18_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Disable",
                    "value": "0"
                },
                {
                    "label": "Enable",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Temperature report time (minute)<br /> <h1>Overview</h1><p>The higher the value ,the long the report time</p> <p>0 - Disable report</p>",
            "label": "19: Temperature report time (minute)",
            "name": "config_19_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 255,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "1040",
            "description": "Set the high temperature alarm trigger value<br /> <h1>Overview</h1><p>The larger the value , the higher the high temperature in Fahrenheits (US)</p>",
            "label": "20: Set the high temperature alarm trigger value",
            "name": "config_20_2",
            "required": false,
            "type": "INTEGER",
            "min": -670,
            "max": 2570,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "320",
            "description": "Set the low temperature alarm trigger value<br /> <h1>Overview</h1><p>The smaller the value , the lower the low temperature in Fahrenheits (US)</p>",
            "label": "22: Set the low temperature alarm trigger value",
            "name": "config_22_2",
            "required": false,
            "type": "INTEGER",
            "min": -670,
            "max": 2570,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "1",
            "description": "Enable/Disable blinking alarm LED",
            "label": "24: Enable/Disable blinking alarm LED",
            "name": "config_24_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Disable",
                    "value": "0"
                },
                {
                    "label": "Enable",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "20",
            "description": "Level of low battery<br /> <h1>Overview</h1><p>Set the trigger value for the low battery alarm</p>",
            "label": "32: Level of low battery",
            "name": "config_32_1",
            "required": false,
            "type": "INTEGER",
            "min": 10,
            "max": 50,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "<br /> <h1>Overview</h1><p>1. Notification Report. Sensor will send Notification Report to the associated nodes</p> <p>2. Battery Report. Sensor will send Battery Report when the battery level is low and the battery report’s value is 0xFF.</p> <p>3. Device Reset Locally Notification. Sensor will send Device Reset Locally Notification when reset</p> <p>4.Sensor multilevel report When associated to Group 1, you can adjust the temperature reporting cycle according to the configuration settings.</p>",
            "label": "1: Lifeline",
            "name": "group_1",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 5,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "<br /> <h1>Overview</h1><p>1. Basic Set. Flood Sensor will send Basic Set to associated nodes when Water leak detected.</p>",
            "label": "2: Control",
            "name": "group_2",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 5,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "label": "Node ID",
            "name": "node_id",
            "required": true,
            "type": "INTEGER",
            "min": 1,
            "max": 232,
            "readOnly": true,
            "multiple": false,
            "advanced": true,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Sets the node ID<BR/>The node ID is assigned by the controller and can not be changed.",
            "label": "Node ID",
            "name": "node_id",
            "required": true,
            "type": "INTEGER",
            "min": 1,
            "max": 232,
            "readOnly": true,
            "multiple": false,
            "groupName": "thingcfg",
            "advanced": true,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        }
    ],

for /rest/thing-types/zwave:kwikset_914c_00_000, the config parameters:

"configParameters": [
        {
            "default": "5",
            "description": "Dipswitch Settings<br /> <h1>Overview</h1><p>Configuration parameter is a one byte read only bit mask that returns the state of the user accessible dipswitches on the rear panel of the door lock. This is a read only parameter and cannot be used to set dipswitch settings.</p> <p>The following table shows the definition for the bits being used in the returned value: </p> <table><tr><td>Bit</td> <td>Description</td> </tr><tr><td>0 (0x01)</td> <td>Lock status LED (1:enabled)</td> </tr><tr><td>1 (0x02)</td> <td>Autolock setting (1:enabled)</td> </tr><tr><td>2 (0x04)</td> <td>Buzzer (1:enabled)</td> </tr><tr><td>3 (0x08)</td> <td>Handing Invert (1:enabled)</td> </tr></table><p><strong>Possible Values:</strong></p> <table><tr><td>0</td> <td>All features disabled</td> </tr><tr><td>1</td> <td>Lock status LED enabled</td> </tr><tr><td>2</td> <td>Autolock Enabled</td> </tr><tr><td>4</td> <td>Internal buzzer enabled</td> </tr><tr><td>8</td> <td>Handling invert enabled</td> </tr><tr><td>3</td> <td>Autolock &amp; Lock status LED enabled</td> </tr><tr><td>5</td> <td>Internal buzzer and lock status LED enabled</td> </tr><tr><td>7</td> <td>Autolock, Internal buzzer, and lock status LED enabled</td> </tr><tr><td>15</td> <td>All Features enabled</td> </tr></table>",
            "label": "31: Dipswitch Settings",
            "name": "config_31_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 15,
            "readOnly": true,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "32",
            "description": "SKU (length = 8 bytes)<br /> <h1>Overview</h1><p>The configuration parameters 33 and 34 are used to set and get the SKU part numbers. The SKU is made up of 8 bytes. Each parameter consists of four bytes of data. Parameter 33 contains the first four most significant bytes of the SKU, while parameter 34 contains the four least significant bytes of the SKU.</p> <p>When setting the SKU, it must be done in two set commands, one for each parameter. The order of programming the SKU does not matter.</p> <p>Setting parameter 33 will program the first four bytes of the SKU. Setting parameter 34 will program the last 4 bytes of the SKU. Most printable values are accepted for the set command.</p> <p>When getting the SKU, it must be done in two get commands, one for each parameter. The order of getting the SKU does not matter.</p> <p>Getting parameter 33 will retrieve the first four bytes of the SKU. Getting parameter 34 will retrieve the last 4 bytes of the SKU. </p>",
            "label": "33: First 4 bytes of SKU",
            "name": "config_33_4",
            "required": false,
            "type": "INTEGER",
            "min": 32,
            "max": 126,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": true,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "32",
            "description": "SKU (length = 8 bytes)<br /> <h1>Overview</h1><p>The configuration parameters 33 and 34 are used to set and get the SKU part numbers. The SKU is made up of 8 bytes. Each parameter consists of four bytes of data. Parameter 33 contains the first four most significant bytes of the SKU, while parameter 34 contains the four least significant bytes of the SKU.</p> <p>When setting the SKU, it must be done in two set commands, one for each parameter. The order of programming the SKU does not matter.</p> <p>Setting parameter 33 will program the first four bytes of the SKU. Setting parameter 34 will program the last 4 bytes of the SKU. Most printable values are accepted for the set command.</p> <p>When getting the SKU, it must be done in two get commands, one for each parameter. The order of getting the SKU does not matter.</p> <p>Getting parameter 33 will retrieve the first four bytes of the SKU. Getting parameter 34 will retrieve the last 4 bytes of the SKU. </p>",
            "label": "34: Last 4 bytes of SKU",
            "name": "config_34_4",
            "required": false,
            "type": "INTEGER",
            "min": 32,
            "max": 126,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": true,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Report the Unique ID of the lock type<br /> <h1>Overview</h1><p>The configuration Parameter 35 is used as read-only to report the Unique ID of the lock type.</p> <table><tr><td><strong>Released Board ID</strong></td> <td><strong>Unique ID</strong></td> </tr><tr><td>910 Z-wave (Legacy, FW 3.4)</td> <td>0x00 0x00</td> </tr><tr><td>912 Z-wave (Legacy, FW 3.2)</td> <td>0x00 0x00</td> </tr><tr><td>910 Z-wave</td> <td>0x02 0x36</td> </tr><tr><td>912 Z-wave</td> <td>0x03 0x36</td> </tr><tr><td>914 Z-wave</td> <td>0x04 0x36</td> </tr><tr><td>916 Z-wave</td> <td>0x06 0x42</td> </tr></table>",
            "label": "35: Lock Type",
            "name": "config_35_2",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 65535,
            "readOnly": true,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Reset Lock to Factory Default<br /> <h1>Overview</h1><p>The configuration parameter 40 is a one byte field, used to set the lock to its default setting, known as a factory reset command.</p> <p>Reading this parameter will always return a value of 0.</p> <p>Writing a value of 1 to this parameter will cause both the lock and Z-Wave card to reset back to their default settings and will remove itself from the network. All network information, including associations will be cleared. </p>",
            "label": "40: Factory Reset",
            "name": "config_40_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 1,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Lifeline<br /> <h1>Overview</h1><p>Z-Wave Plus Lifeline Supports the following types of unsolicited messages:</p> <table> <tr> <td><strong>Command Class</strong></td> <td><strong>Command</strong></td> <td><strong>Info</strong></td> </tr> <tr> <td>Command Class Battery</td> <td>Battery Report</td> <td>Sends periodic battery reports containing the battery percentage.</td> </tr> <tr> <td>Command Class Door Lock</td> <td>Door Lock Operation Report</td> <td>Upon power up, this message will be sent to allow the controller to sync up with the current lock status.</td> </tr> <tr> <td>Command Class Notification</td> <td>Notification Report</td> <td>Many notification types will be sent for status and alarms. The following notification types are supported: Access Control (V2) and Power Management (V2).</td> </tr> <tr> <td>Command Class Device Reset Locally</td> <td>Device Reset Locally Notification</td> <td>This message will be sent to notify the smart home controller that the lock is resetting back to factory defaults and will be leaving the network.</td> </tr> </table>",
            "label": "1: Group 1",
            "name": "group_1",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": false,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Doorlock notify group<br /> <h1>Overview</h1><p>This group will provide all Notification reports as described for the Lifeline. This group allows other controllers, other than the lifeline, to receive these types of unsolicited messages as well.</p> <p>It allows at most 5 other nodes to be associated with the lock and will provide all Notification Reports, via the Command Class Notification, generated by the lock. </p>",
            "label": "2: Group 2",
            "name": "group_2",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 5,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "label": "Node ID",
            "name": "node_id",
            "required": true,
            "type": "INTEGER",
            "min": 1,
            "max": 232,
            "readOnly": true,
            "multiple": false,
            "advanced": true,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Sets the node ID<BR/>The node ID is assigned by the controller and can not be changed.",
            "label": "Node ID",
            "name": "node_id",
            "required": true,
            "type": "INTEGER",
            "min": 1,
            "max": 232,
            "readOnly": true,
            "multiple": false,
            "groupName": "thingcfg",
            "advanced": true,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        }
    ]

In particular, config_33_4 and config_34_4, it’s showing min is 32, max is 126, but the current code for it:

UID: zwave:device:512:node148
label: Mud Room Door Lock
thingTypeUID: zwave:kwikset_914c_00_000
configuration:
  config_31_1: 5
  config_40_1: 0
  group_1:
    - controller
  config_33_4: 538976288
  config_35_2: 0
  node_id: 148
  config_34_4: 538976288
  group_2:
    - controller
bridgeUID: zwave:serial_zstick:512

That one definitely looks like the database is wrong. The description is clear that parameters 33 and 34 are supposed to be 4 bytes each.

Just a guess: one of the groups on the qubino device is not defined with multiple=true, correct? That was reported for another device on GitHUB.

oh golly don’t I know it! :woozy_face:

/rest/thing-types/zwave:qubino_zmnhdd_00_000

Yes, I see a "multiple": true in there.

"configParameters": [
        {
            "default": "0",
            "label": "1: Input 1 switch type",
            "name": "config_1_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Mono-stable switch type (push button)",
                    "value": "0"
                },
                {
                    "label": "Bi-stable switch type",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "label": "2: Input 2 switch type",
            "name": "config_2_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Mono-stable switch type (push button)",
                    "value": "0"
                },
                {
                    "label": "Bi-stable switch type",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "label": "3: Input 2 contact type",
            "name": "config_3_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "NO (normally open) input type",
                    "value": "0"
                },
                {
                    "label": "NC (normally closed) input type",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "label": "4: Input 3 contact type",
            "name": "config_4_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "NO (normally open) input type",
                    "value": "0"
                },
                {
                    "label": "NC (normally closed) input type",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "255",
            "description": "Flush dimmer module responds to commands ALL ON / ALL OFF<br /> <h1>Overview</h1><p>Flush dimmer module responds to commands ALL ON / ALL OFF that may be sent by the main controller or by other controller belonging to the system.</p>",
            "label": "10: Activate / deactivate functions ALL ON / ALL OFF",
            "name": "config_10_2",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "ALL ON is not active, ALL OFF is not active",
                    "value": "0"
                },
                {
                    "label": "ALL ON is not active, ALL OFF active",
                    "value": "1"
                },
                {
                    "label": "ALL ON active, ALL OFF is not active",
                    "value": "2"
                },
                {
                    "label": "ALL ON active, ALL OFF active",
                    "value": "255"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Auto OFF enabled with defined time, step is 1 second.<br /> <h1>Overview</h1><ul><li>0 - Auto OFF disabled</li> <li>1 – 32536 = 1 second – 32536 seconds</li> </ul>",
            "label": "11: Automatic turning off output after set time",
            "name": "config_11_2",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 32536,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Auto ON enabled with defined time, step is 1 second.<br /> <h1>Overview</h1><ul><li>0 - Auto ON disabled</li> <li>1 – 32536 = 1 second – 32536 seconds</li> </ul>",
            "label": "12: Automatic turning on output after set time",
            "name": "config_12_2",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 32536,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Dimming is done by push button or switch connected to I1.<br /> <h1>Overview</h1><p>Dimming is done by push button or switch connected to I1 (by default).</p> <p>Enabling 3way switch, dimming can be controlled by push button or switch connected to I1 and I2.</p>",
            "label": "20: Enable / Disable 3-way switch",
            "name": "config_20_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "single push button (connected to I1)",
                    "value": "0"
                },
                {
                    "label": "3-way switch (connected to I1 and I2)",
                    "value": "1"
                },
                {
                    "label": "Additional switch connected to I2",
                    "value": "2"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "A fast double click on the push button will set dimming power at maximum.<br /> <h1>Overview</h1><p>If Double click function is enabled, a fast double click on the push button will set dimming power at maximum dimming value.</p>",
            "label": "21: Enable / Disable Double click function",
            "name": "config_21_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "double click disabled",
                    "value": "0"
                },
                {
                    "label": "double click enabled",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Saving the state after a power failure<br /> <h1>Overview</h1><p>If state saving is enabled, flush dimmer module saves its state before power failure (it returns to the last position saved before a power failure).</p> <p>If state saving is disabled, flush dimmer module does not save the state after a power failure.</p>",
            "label": "30: Saving the state after a power failure",
            "name": "config_30_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Save state enabled",
                    "value": "0"
                },
                {
                    "label": "Save state disabled",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "5",
            "description": "Set value is percentage, set value from 0 - 100 = 0% - 100%.<br /> <h1>Overview</h1><p>Set value means percentage, set value from 0 - 100 = 0% - 100%. Default value is 5.</p> <ul><li>0 – Reporting Disabled</li> <li>1 – 100 = 1% - 100% Reporting enabled.</li> </ul><p>Power report is send (push) only when actual power in Watts in real time changes for more than set percentage comparing to previous actual power in Watts, step is 1%.</p> <p>NOTE: if power changed is less than 1W, the report is not send (pushed), independent of percentage set.</p>",
            "label": "40: Power reporting in watts on power change",
            "name": "config_40_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 100,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "300",
            "description": "Set value means time interval (0 – 32767) in seconds.<br /> <h1>Overview</h1><p>Set value means time interval (0 – 32767) in seconds, when power report is sent.</p> <ul><li>0 – reporting disabled</li> <li>1 – 32767 = 1 second – 32767 seconds. Reporting enabled.</li> </ul><p>Power report is send with time interval set by entered value.</p>",
            "label": "42: Power reporting in Watts by time interval",
            "name": "config_42_2",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 32767,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "1",
            "description": "Minimum dimming value is set by entered value.<br /> <h1>Overview</h1><ul><li>1-98 = 1% – 98%, step is 1%. Minimum dimming value is set by entered value.</li> </ul><p>NOTE: The minimum level may not be higher than the maximum level! 1% min. dimming value is defined by Z- Wave multilevel device class.</p>",
            "label": "60: Minimum dimming value",
            "name": "config_60_1",
            "required": false,
            "type": "INTEGER",
            "min": 1,
            "max": 98,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "99",
            "description": "Maximum dimming value is set by entered value.<br /> <h1>Overview</h1><ul><li>2-99 = 2% – 99%, step is 1%. Maximum dimming value is set by entered value.</li> </ul><p>NOTE: The maximum level may not be lower than the minimum level! 99% max. dimming value is defined by Z- Wave multilevel device class.</p>",
            "label": "61: Maximum dimming value",
            "name": "config_61_1",
            "required": false,
            "type": "INTEGER",
            "min": 2,
            "max": 99,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "100",
            "description": "Set value means time of moving the Dimmer between min. and max. dimming values<br /> <h1>Overview</h1><p>Set value means time of moving the Dimmer between min. and max. dimming values by short press of push button I1 or controlled through UI (BasicSet).</p> <ul><li>default value 100 = 1s</li> <li>1 - 255 = 100 mseconds – 25500 mseconds, step is 10 mseconds</li> </ul>",
            "label": "65: Dimming time (soft on/off)",
            "name": "config_65_2",
            "required": false,
            "type": "INTEGER",
            "min": 1,
            "max": 255,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "3",
            "description": "Time of moving the Dimmer between min. and max dimming values<br /> <h1>Overview</h1><p>Time of moving the Dimmer between min. and max dimming values by continuous hold of push button I1 or associated device.</p> <ul><li>default value 3 = 3s</li> <li>1- 255 = 1 second – 255 seconds.</li> </ul>",
            "label": "66: Dimming time when key pressed",
            "name": "config_66_2",
            "required": false,
            "type": "INTEGER",
            "min": 1,
            "max": 255,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "This parameter is used with association group 3<br /> <h1>Overview</h1><p>This parameter is used with association group 3. A receiving device SHOULD respect the start level if the Ignore Start Level bit is 0. A receiving device MUST ignore the start level if the Ignore Start Level bit is 1.</p>",
            "label": "67: Ignore start level",
            "name": "config_67_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "respect start level",
                    "value": "0"
                },
                {
                    "label": "ignore start level",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "This parameter is used with association group 3<br /> <h1>Overview</h1><p>This parameter is used with association group 3. The Duration field MUST specify the time that the transition should take from the current value to the new target value. A supporting device SHOULD respect the specified Duration value.</p>",
            "label": "68: Dimming duration",
            "name": "config_68_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 127,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Enabling I2 means that Endpoint (I2) will be present on UI.<br /> <h1>Overview</h1><p>Enabling I2 means that Endpoint (I2) will be present on UI. Disabling it will result in hiding the endpoint according to the parameter set value. Additionally, a Notification Type and Event can be selected for the endpoint.</p> <p>NOTE1: After parameter change, first exclude module (without setting parameters to default value) then wait at least 30s and then re include the module!</p> <p>NOTE 2: When the parameter is set to value 9 the notifications are send for Home Security.</p>",
            "label": "100: Enable / Disable Endpoints I2",
            "name": "config_100_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Disabled",
                    "value": "0"
                },
                {
                    "label": "Home Security",
                    "value": "1"
                },
                {
                    "label": "Carbon Monoxide",
                    "value": "2"
                },
                {
                    "label": "Carbon Dioxide",
                    "value": "3"
                },
                {
                    "label": "Water Alarm",
                    "value": "4"
                },
                {
                    "label": "Heat Alarm",
                    "value": "5"
                },
                {
                    "label": "Smoke Alarm",
                    "value": "6"
                },
                {
                    "label": "Sensor binary",
                    "value": "9"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Enabling I3 means that Endpoint (I3) will be present on UI.<br /> <h1>Overview</h1><p>Enabling I3 means that Endpoint (I3) will be present on UI. Disabling it will result in hiding the endpoint according to the parameter set value. Additionally, a Notification Type and Event can be selected for the endpoint.</p> <p>NOTE1: After parameter change, first exclude module (without setting parameters to default value) then wait at least 30s and then re include the module!</p> <p>NOTE 2: When the parameter is set to value 9 the notifications are send for Home Security.</p>",
            "label": "101: Enable / Disable Endpoints I3",
            "name": "config_101_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Disabled",
                    "value": "0"
                },
                {
                    "label": "Home Security",
                    "value": "1"
                },
                {
                    "label": "Carbon Monoxide",
                    "value": "2"
                },
                {
                    "label": "Carbon Dioxide",
                    "value": "3"
                },
                {
                    "label": "Water Alarm",
                    "value": "4"
                },
                {
                    "label": "Heat Alarm",
                    "value": "5"
                },
                {
                    "label": "Smoke Alarm",
                    "value": "6"
                },
                {
                    "label": "Sensor binary",
                    "value": "9"
                }
            ],
            "filterCriteria": []
        },
        {
            "default": "32536",
            "description": "Offset to actual measured value<br /> <h1>Overview</h1><p>Set value is added or subtracted to actual measured value by sensor. Available configuration parameters:</p> <ul><li>default value 32536</li> <li>32536 – offset is 0.0C</li> <li>From 1 to 100 – value from 0.1 °C to 10.0 °C is added to actual measured temperature.</li> <li>From 1001 to 1100 -value from -0.1 °C to -10.0 °C is subtracted to actual measured temperature.</li> </ul>",
            "label": "110: Temperature sensor offset settings",
            "name": "config_110_2",
            "required": false,
            "type": "INTEGER",
            "min": 1,
            "max": 32536,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "5",
            "description": "Module reports measured temperature on defined temperature change<br /> <h1>Overview</h1><p>If digital temperature sensor is connected, module reports measured temperature on temperature change defined by this parameter. Available configuration parameters:</p> <ul><li>default value 5 = 0.5°C</li> <li>0 – Reporting disabled</li> </ul>",
            "label": "120: Digital temperature sensor reporting",
            "name": "config_120_1",
            "required": false,
            "type": "INTEGER",
            "min": 0,
            "max": 127,
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": false,
            "verify": false,
            "limitToOptions": false,
            "options": [],
            "filterCriteria": []
        },
        {
            "default": "0",
            "description": "Unsecure / Secure Inclusion<br /> <h1>Overview</h1><p>The Flush dimmer supports both, the secure and unsecure inclusion. Even if the controller does not support security command classes, a dimmer could be included as unsecure and keep all the functionality</p>",
            "label": "250: Unsecure / Secure Inclusion",
            "name": "config_250_1",
            "required": false,
            "type": "INTEGER",
            "readOnly": false,
            "multiple": false,
            "groupName": "configuration",
            "advanced": true,
            "verify": false,
            "limitToOptions": false,
            "options": [
                {
                    "label": "Unsecure Inclusion",
                    "value": "0"
                },
                {
                    "label": "Secure Inclusion",
                    "value": "1"
                }
            ],
            "filterCriteria": []
        },
        {
            "description": "Lifeline group",
            "label": "1: Controller Updates",
            "name": "group_1",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": false,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I1 state and reflecting its state",
            "label": "2: I1 basic on/off",
            "name": "group_2",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I1 state and reflecting its state",
            "label": "3: I1 start/stop level change",
            "name": "group_3",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at changes of state/value of the Flush Dimmer",
            "label": "4: Multilevel",
            "name": "group_4",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I2 state and reflecting its state",
            "label": "5: I2 basic on/off",
            "name": "group_5",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I2 state and reflecting its state",
            "label": "6: I2 notification report",
            "name": "group_6",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I2 state and reflecting its state",
            "label": "7: I2 binary sensor",
            "name": "group_7",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I3 state and reflecting its state",
            "label": "8: I3 basic on/off",
            "name": "group_8",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I3 state and reflecting its state",
            "label": "9: I3 notification report",
            "name": "group_9",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of the input I3 state and reflecting its state",
            "label": "10: I3 binary sensor",
            "name": "group_10",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Triggered at change of temperature sensor",
            "label": "11: Multilevel sensor",
            "name": "group_11",
            "required": false,
            "type": "TEXT",
            "readOnly": false,
            "multiple": true,
            "multipleLimit": 16,
            "groupName": "association",
            "advanced": false,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "label": "Node ID",
            "name": "node_id",
            "required": true,
            "type": "INTEGER",
            "min": 1,
            "max": 232,
            "readOnly": true,
            "multiple": false,
            "advanced": true,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        },
        {
            "description": "Sets the node ID<BR/>The node ID is assigned by the controller and can not be changed.",
            "label": "Node ID",
            "name": "node_id",
            "required": true,
            "type": "INTEGER",
            "min": 1,
            "max": 232,
            "readOnly": true,
            "multiple": false,
            "groupName": "thingcfg",
            "advanced": true,
            "verify": false,
            "limitToOptions": true,
            "options": [],
            "filterCriteria": []
        }
    ]

But group_1 has multiple=false, so only a plain string is allowed, but an array is provided.

The device documentation clearly states that only 1 node is allowed in group 1. Sounds like a problem with the database export, that it should be setting "multiple": true for all groups, but then set the "multipleLimit": 1? Either that or the Z-Wave node picker UI for association groups needs to output a non-array if "multiple": false.

What I am confused by are the devices I have that fail no validations but do not initialise until saved. The fibaro switch FGS223 has no out of bound parameters but does not initialise under this version but does under milestone with same parameters, It has a lot of parameters so not ideal for testing but is interesting as all parameters in my setup are valid. It is also interesting that the only device that does initialise on start is one with no parameters.

Is this a timing thing? Could the validation be running before the parameters are initialised and therefore failing as values are not set therefore stopping the devices from initialising?

I’ve commented out the code that checks all this in the exporter so ALL groups will now be multiple, and the multipleLimit will be set. Previously the limit was only set if it allowed more than 1.

The big problem the binding has is it can’t (easily) access the config descriptions so it doesn’t have this information available so it’s not possible for the binding to check any of this, and we therefore probably can’t eliminate this sort of issue in the binding.