Skip to content

Commit

Permalink
Merge branch 'master' into eslint-check-labels
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Oct 11, 2023
2 parents a4302d1 + f54a9ac commit 986963a
Show file tree
Hide file tree
Showing 47 changed files with 920 additions and 160 deletions.
26 changes: 25 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@
<!--
Add placeholder for next release with `wip` snippet
-->
## 12.0.4 (2023-10-09)
### Bugfixes
* Normalize result of `Controller.getAvailableFirmwareUpdates` to always include `channel` field (#6359)
* Fixed a crash that could happen while logging dropped sensor readings (#6379)
* Increased the range and default of the `response` timeout to accomodate slower 500 series controllers (#6378)

### Config file changes
* Treat Basic Set as events for TKB TZ35S/D and TZ55S/D (#6381)
* Add Zooz ZAC38 Range Extender (#6136)
* Corrected the label of the notification event `0x0a` to be `Emergency Alarm` (#6368)

## 12.0.3 (2023-10-05)
The `v12` release was supposed to increase reliability of Z-Wave JS, primarily by detecting situations where the controller was unable to transmit due to excessive RF noise or being unresponsive and automatically taking the necessary steps to recover.

Instead, it uncovered bugs and erratical behavior in the 500 series firmwares, which triggered the automatic recovery in situations where it was not necessary. In the worst case, this would cause Z-Wave JS to end up in an infinite loop or restart over and over.

This patch should fix and/or work around most (if not all) of these issues. Really sorry for the inconvenience!

### Bugfixes
* Fixed an infinite loop caused by assuming the controller was temporarily unable to transmit when when sending a command results in the transmit status `Fail` (#6361)
* Added a workaround to avoid a restart loop caused by 500 series controllers replying with invalid commands when assigning routes back to the controller (SUC) failed (#6370, #6372)
* Automatically recovering an unresponsive controller by restarting it or Z-Wave JS in case of a missing callback is now only done for `SendData` commands. Previously some commands which were expecting a specific command to be received from a node could also trigger this, even if that command was not technically a command callback. (#6373)
* Fixed an issue where rebuilding routes would throw an error because of calling the wrong method internally (#6362)

## 12.0.2 (2023-09-29)
### Bugfixes
* The workaround from `v12.0.0` for the `7.19.x` SDK bug was not working correctly when the command that caused the controller to get stuck could be retried. This has now been fixed. (#6343)
Expand All @@ -27,6 +51,7 @@ Home Assistant users who manage `zwave-js-server` themselves, **must** install t
* `zwave-js-server` **1.32.0**

### Breaking changes · [Migration guide](https://zwave-js.github.io/node-zwave-js/#/getting-started/migrating-to-v12)
* Removed auto-disabling of soft-reset capability. If Z-Wave JS is no longer able to communicate with the controller after updating, please read [this issue](https://github.com/zwave-js/node-zwave-js/issues/6341) (#6256)
* Remove support for Node.js 14 and 16 (#6245)
* Subpath exports are now exposed using the `exports` field in `package.json` instead of `typesVersions` (#5839)
* The `"notification"` event now includes a reference to the endpoint that sent the notification (#6083)
Expand All @@ -43,7 +68,6 @@ Home Assistant users who manage `zwave-js-server` themselves, **must** install t

### Bugfixes
* A bug in the `7.19.x` SDK has surfaced where the controller gets stuck in the middle of a transmission. Previously this would go unnoticed because the failed commands would cause the nodes to be marked dead until the controller finally recovered. Since `v11.12.0` however, Z-Wave JS would consider the controller jammed and retry the last command indefinitely. This situation is now detected and Z-Wave JS attempts to recover by soft-resetting the controller when this happens. (#6296)
* Removed auto-disabling of soft-reset capability (#6256)
* Default to RF protection state `Unprotected` if not given for `Protection CC` V2+ (#6257)

### Config file changes
Expand Down
6 changes: 6 additions & 0 deletions docs/api/driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,9 @@ interface ZWaveOptions extends ZWaveHostOptions {
/** How long generated nonces are valid */
nonce: number; // [3000...20000], default: 5000 ms
/** How long to wait before retrying a command when the controller is jammed */
retryJammed: number; // [10...5000], default: 1000 ms
/**
* How long to wait without pending commands before sending a node back to sleep.
* Should be as short as possible to save battery, but long enough to give applications time to react.
Expand Down Expand Up @@ -736,6 +739,9 @@ interface ZWaveOptions extends ZWaveHostOptions {
/** How often the driver should try sending SendData commands before giving up */
sendData: number; // [1...5], default: 3
/** How often the driver should retry SendData commands while the controller is jammed */
sendDataJammed: number; // [1...10], default: 5
/**
* How many attempts should be made for each node interview before giving up
*/
Expand Down
6 changes: 6 additions & 0 deletions docs/config-files/file-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,12 @@ Several command classes are refreshed regularly (every couple of hours) if they

By default, received `Basic CC::Report` commands are mapped to a more appropriate CC. Setting `disableBasicMapping` to `true` disables this feature.

### `disableCallbackFunctionTypeCheck`

By default, responses or callbacks for Serial API commands must have the same function type (command identifier) in order to be recognized. However, in some situations, certain controllers send a callback with an invalid function type. In this case, the faulty commands may be listed in the `disableCallbackFunctionTypeCheck` array to disable the check for a matching function type.

> [!NOTE] This compat flag requires command-specific support and is not a generic escape hatch.
### `disableStrictEntryControlDataValidation`

The specifications mandate strict rules for the data and sequence numbers in `Entry Control CC Notifications`, which some devices do not follow, causing the notifications to get dropped. Setting `disableStrictEntryControlDataValidation` to `true` disables these strict checks.
Expand Down
8 changes: 8 additions & 0 deletions maintenance/schemas/device-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,14 @@
"disableBasicMapping": {
"const": true
},
"disableCallbackFunctionTypeCheck": {
"type": "array",
"items": {
"type": "integer",
"minimum": 1
},
"minItems": 1
},
"disableStrictEntryControlDataValidation": {
"const": true
},
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zwave-js/repo",
"version": "12.0.2",
"version": "12.0.4",
"private": true,
"description": "Z-Wave driver written entirely in JavaScript/TypeScript",
"keywords": [],
Expand Down Expand Up @@ -40,7 +40,7 @@
"@dprint/json": "^0.17.4",
"@dprint/markdown": "^0.16.0",
"@dprint/typescript": "^0.87.1",
"@microsoft/api-extractor": "^7.36.4",
"@microsoft/api-extractor": "^7.37.3",
"@monorepo-utils/workspaces-to-typescript-project-references": "^2.10.2",
"@tsconfig/node18": "^18.2.1",
"@types/fs-extra": "^11.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/cc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zwave-js/cc",
"version": "12.0.2",
"version": "12.0.4",
"description": "zwave-js: Command Classes",
"keywords": [],
"publishConfig": {
Expand Down Expand Up @@ -71,7 +71,7 @@
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.36.4",
"@microsoft/api-extractor": "^7.37.3",
"@types/fs-extra": "^11.0.1",
"@types/node": "^18.17.14",
"@zwave-js/maintenance": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/cc/src/cc/MultilevelSensorCC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ export class MultilevelSensorCCReport extends MultilevelSensorCC {
if (supportedSensorTypes?.length) {
validatePayload.withReason(
`Unsupported sensor type ${
sensorType!.label
applHost.configManager.getSensorTypeName(this.type)
} or corrupted data`,
)(supportedSensorTypes.includes(this.type));
}
Expand Down
2 changes: 2 additions & 0 deletions packages/config/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ export class ConditionalCompatConfig implements ConditionalItem<CompatConfig> {
// (undocumented)
readonly disableBasicMapping?: boolean;
// (undocumented)
readonly disableCallbackFunctionTypeCheck?: number[];
// (undocumented)
readonly disableStrictEntryControlDataValidation?: boolean;
// (undocumented)
readonly disableStrictMeasurementValidation?: boolean;
Expand Down
4 changes: 4 additions & 0 deletions packages/config/config/devices/0x0000/husbzb-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@
"firmwareVersion": {
"min": "0.0",
"max": "255.255"
},
"compat": {
// Workaround for a firmware bug in 500 series controllers
"$import": "~/templates/master_template.json#500_series_controller_compat_flags"
}
}
4 changes: 4 additions & 0 deletions packages/config/config/devices/0x0086/zw090.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,9 @@
"metadata": {
"reset": "Use this procedure only in the event that the primary controller is missing or otherwise inoperable.\n\nPress and hold the Action Button on Z-Stick for 20 seconds and then release",
"manual": "https://products.z-wavealliance.org/ProductManual/File?folder=&filename=MarketCertificationFiles/1345/Z%20Stick%20Gen5%20manual%201.pdf"
},
"compat": {
// Workaround for a firmware bug in 500 series controllers
"$import": "~/templates/master_template.json#500_series_controller_compat_flags"
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"manufacturer": "TKB Home",
"manufacturerId": "0x0118",
"label": "TZ55S",
"description": "Single Paddle Wall Dimmer",
"label": "TZ35S / TZ35D / TZ55S / TZ55D",
"description": "Single/Dual Paddle Wall Dimmer",
"devices": [
{
"productType": "0x0808",
Expand Down Expand Up @@ -97,5 +97,9 @@
}
]
}
]
],
"compat": {
// The right paddle sends its status via Basic Set commands
"treatBasicSetAsEvent": true
}
}
61 changes: 61 additions & 0 deletions packages/config/config/devices/0x027a/zac38.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"manufacturer": "Zooz",
"manufacturerId": "0x027a",
"label": "ZAC38",
"description": "Range Extender",
"devices": [
{
"productType": "0x0004",
"productId": "0x0510"
}
],
"firmwareVersion": {
"min": "0.0",
"max": "255.255"
},
"paramInformation": [
{
"#": "1",
"$import": "templates/zooz_template.json#low_battery_alarm_threshold",
"defaultValue": 10
},
{
"#": "2",
"$import": "~/templates/master_template.json#base_enable_disable",
"label": "Enable Battery Threshold Reports",
"defaultValue": 1
},
{
"#": "3",
"$import": "templates/zooz_template.json#battery_report_threshold",
"minValue": 5
},
{
"#": "4",
"label": "Battery Check Interval",
"description": "How often the device checks the battery level.",
"valueSize": 2,
"unit": "seconds",
"minValue": 1,
"maxValue": 65535,
"defaultValue": 600,
"unsigned": true
},
{
"#": "5",
"$import": "~/templates/master_template.json#base_enable_disable",
"label": "Enable Timed Battery Reports",
"defaultValue": 1
},
{
"#": "6",
"label": "Battery Report Interval",
"valueSize": 2,
"unit": "seconds",
"minValue": 30,
"maxValue": 65535,
"defaultValue": 3600,
"unsigned": true
}
]
}
4 changes: 4 additions & 0 deletions packages/config/config/devices/0x027a/zst10.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@
"firmwareVersion": {
"min": "0.0",
"max": "255.255"
},
"compat": {
// Workaround for a firmware bug in 500 series controllers
"$import": "~/templates/master_template.json#500_series_controller_compat_flags"
}
}
10 changes: 10 additions & 0 deletions packages/config/config/devices/templates/master_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -675,5 +675,15 @@
"text": "Firmware version 7.19.3 has a bug that causes the controller to randomly hang during transmission until it is restarted. It is currently unclear if this bug is fixed in a later firmware version."
}
]
},
"500_series_controller_compat_flags": {
// It seems that all 500 series controllers have a firmware bug:

// When failing, AssignSUCReturnRoute and DeleteSUCReturnRoute get answered with a wrong callback function type,
// triggering Z-Wave JS's unresponsive controller check.
"disableCallbackFunctionTypeCheck": [
81, // AssignSUCReturnRoute
85 // DeleteSUCReturnRoute
]
}
}
2 changes: 1 addition & 1 deletion packages/config/config/notifications.json
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@
}
},
"0x0a": {
"name": "System",
"name": "Emergency Alarm",
"events": {
"0x01": {
"label": "Contact police"
Expand Down
6 changes: 3 additions & 3 deletions packages/config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zwave-js/config",
"version": "12.0.2",
"version": "12.0.4",
"description": "zwave-js: configuration files",
"publishConfig": {
"access": "public"
Expand Down Expand Up @@ -66,7 +66,7 @@
"winston": "^3.10.0"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.36.4",
"@microsoft/api-extractor": "^7.37.3",
"@types/fs-extra": "^11.0.1",
"@types/js-levenshtein": "^1.1.1",
"@types/json-logic-js": "^2.0.2",
Expand All @@ -88,7 +88,7 @@
"sinon": "^15.2.0",
"ts-pegjs": "^0.3.1",
"typescript": "5.2.2",
"xml2js": "^0.5.0",
"xml2js": "^0.6.2",
"yargs": "^17.7.2"
}
}
19 changes: 19 additions & 0 deletions packages/config/src/devices/CompatConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ compat option disableBasicMapping must be true or omitted`,
this.disableBasicMapping = definition.disableBasicMapping;
}

if (definition.disableCallbackFunctionTypeCheck != undefined) {
if (
!isArray(definition.disableCallbackFunctionTypeCheck)
|| !definition.disableCallbackFunctionTypeCheck.every(
(d: any) => typeof d === "number" && d % 1 === 0 && d > 0,
)
) {
throwInvalidConfig(
"devices",
`config/devices/${filename}:
when present, compat option disableCallbackFunctionTypeCheck msut be an array of positive integers`,
);
}
this.disableCallbackFunctionTypeCheck =
definition.disableCallbackFunctionTypeCheck;
}

if (definition.disableStrictEntryControlDataValidation != undefined) {
if (definition.disableStrictEntryControlDataValidation !== true) {
throwInvalidConfig(
Expand Down Expand Up @@ -568,6 +585,7 @@ compat option overrideQueries must be an object!`,
public readonly disableBasicMapping?: boolean;
public readonly disableStrictEntryControlDataValidation?: boolean;
public readonly disableStrictMeasurementValidation?: boolean;
public readonly disableCallbackFunctionTypeCheck?: number[];
public readonly enableBasicSetMapping?: boolean;
public readonly forceNotificationIdleReset?: boolean;
public readonly forceSceneControllerGroupCount?: number;
Expand Down Expand Up @@ -608,6 +626,7 @@ compat option overrideQueries must be an object!`,
"removeCCs",
"disableAutoRefresh",
"disableBasicMapping",
"disableCallbackFunctionTypeCheck",
"disableStrictEntryControlDataValidation",
"disableStrictMeasurementValidation",
"enableBasicSetMapping",
Expand Down
22 changes: 19 additions & 3 deletions packages/core/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1218,17 +1218,25 @@ export function isMessagePriority(val: unknown): val is MessagePriority;
// Warning: (ae-missing-release-tag) "isMissingControllerACK" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function isMissingControllerACK(e: unknown): e is ZWaveError;
export function isMissingControllerACK(e: unknown): e is ZWaveError & {
code: ZWaveErrorCodes.Controller_Timeout;
context: "ACK";
};

// Warning: (ae-missing-release-tag) "isMissingControllerCallback" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function isMissingControllerCallback(e: unknown): e is ZWaveError;
export function isMissingControllerCallback(e: unknown): e is ZWaveError & {
code: ZWaveErrorCodes.Controller_Timeout;
context: "callback";
};

// Warning: (ae-missing-release-tag) "isRecoverableZWaveError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function isRecoverableZWaveError(e: unknown): e is ZWaveError;
export function isRecoverableZWaveError(e: unknown): e is ZWaveError & {
code: ZWaveErrorCodes.Controller_InterviewRestarted | ZWaveErrorCodes.Controller_NodeRemoved;
};

// Warning: (ae-missing-release-tag) "isRssiError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down Expand Up @@ -2627,6 +2635,14 @@ export enum TransmitStatus {
// @public
export function tryParseDSKFromQRCodeString(qr: string): string | undefined;

// Warning: (ae-missing-release-tag) "tryParseParamNumber" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function tryParseParamNumber(str: string): {
parameter: number;
valueBitMask?: number;
} | undefined;

// Warning: (ae-missing-release-tag) "TXReport" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
Expand Down
Loading

0 comments on commit 986963a

Please sign in to comment.