Skip to content

Commit

Permalink
feat: add compat flag to treat Set commands as Report, enable for…
Browse files Browse the repository at this point in the history
… SRT321 HRT4-ZW (#6423)

Co-authored-by: Dominic Griesel <[email protected]>
  • Loading branch information
XLDom and AlCalzone authored Oct 23, 2023
1 parent 37b4b25 commit 79a62cc
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .vscode/deviceSnippets.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"body": [
"\"compat\": {",
"\t$LINE_COMMENT This device incorrectly ${1:[problem]}",
"\t\"${2|disableBasicMapping,disableStrictEntryControlDataValidation,disableStrictMeasurementValidation,enableBasicSetMapping,forceNotificationIdleReset,mapRootReportsToEndpoint,preserveRootApplicationCCValueIDs,skipConfigurationNameQuery,skipConfigurationInfoQuery,treatBasicSetAsEvent,treatMultilevelSwitchSetAsEvent,treatDestinationEndpointAsSource|}\": true",
"\t\"${2|disableBasicMapping,disableStrictEntryControlDataValidation,disableStrictMeasurementValidation,enableBasicSetMapping,forceNotificationIdleReset,mapRootReportsToEndpoint,preserveRootApplicationCCValueIDs,skipConfigurationNameQuery,skipConfigurationInfoQuery,treatBasicSetAsEvent,treatMultilevelSwitchSetAsEvent,treatSetAsReport,treatDestinationEndpointAsSource|}\": true",
"},"
],
"description": "Insert parameter condition"
Expand Down
7 changes: 7 additions & 0 deletions docs/config-files/file-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,13 @@ By default, `Basic CC::Set` commands are interpreted as status updates. This fla

By default, `Multilevel Switch CC::Set` commands are ignored, because they are meant to control end devices. This flag causes the driver to emit a `value event` for the `"event"` property instead, so applications can react to these commands, e.g. for remotes.

### `treatSetAsReport`

By default, many `Set` CC commands are ignored, because they are meant to control end devices. For some devices, those commands are the only way to receive updates about some values though.
This flag causes the driver treat the listed commands as a report instead and issue a `value report`, so applications can react to them.

> [!NOTE] This mapping is CC specific and must be implemented for every CC that needs it. Currently, only `BinarySwitchCCSet` and `ThermostatModeCCSet` are supported.
### `treatDestinationEndpointAsSource`

Some devices incorrectly use the multi channel **destination** endpoint in reports to indicate the **source** endpoint the report originated from. When this flag is `true`, the destination endpoint is instead interpreted to be the source and the original source endpoint gets ignored.
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 @@ -702,6 +702,14 @@
"treatMultilevelSwitchSetAsEvent": {
"const": true
},
"treatSetAsReport": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
}
},
"treatDestinationEndpointAsSource": {
"const": true
},
Expand Down
6 changes: 5 additions & 1 deletion packages/config/config/devices/0x0059/hrt4-zw.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,9 @@
"defaultValue": 10,
"unsigned": true
}
]
],
"compat": {
// The device "reports" some of its state with Set commands
"treatSetAsReport": ["BinarySwitchCCSet", "ThermostatModeCCSet"]
}
}
19 changes: 19 additions & 0 deletions packages/config/src/devices/CompatConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,23 @@ error in compat option treatMultilevelSwitchSetAsEvent`,
definition.treatMultilevelSwitchSetAsEvent;
}

if (definition.treatSetAsReport != undefined) {
if (
!(isArray(definition.treatSetAsReport)
&& definition.treatSetAsReport.every(
(d: any) => typeof d === "string",
))
) {
throwInvalidConfig(
"devices",
`config/devices/${filename}:
compat option treatSetAsReport must be an array of strings`,
);
}

this.treatSetAsReport = new Set(definition.treatSetAsReport);
}

if (definition.treatDestinationEndpointAsSource != undefined) {
if (definition.treatDestinationEndpointAsSource !== true) {
throwInvalidConfig(
Expand Down Expand Up @@ -616,6 +633,7 @@ compat option overrideQueries must be an object!`,
public readonly skipConfigurationInfoQuery?: boolean;
public readonly treatBasicSetAsEvent?: boolean;
public readonly treatMultilevelSwitchSetAsEvent?: boolean;
public readonly treatSetAsReport?: ReadonlySet<string>;
public readonly treatDestinationEndpointAsSource?: boolean;
public readonly useUTCInTimeParametersCC?: boolean;
public readonly queryOnWakeup?: readonly [
Expand Down Expand Up @@ -657,6 +675,7 @@ compat option overrideQueries must be an object!`,
"skipConfigurationInfoQuery",
"treatBasicSetAsEvent",
"treatMultilevelSwitchSetAsEvent",
"treatSetAsReport",
"treatDestinationEndpointAsSource",
"useUTCInTimeParametersCC",
"queryOnWakeup",
Expand Down
3 changes: 3 additions & 0 deletions packages/config/src/devices/DeviceConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,9 @@ export class DeviceConfig {
if (this.compat.removeCCs) {
c.removeCCs = Object.fromEntries(this.compat.removeCCs);
}
if (this.compat.treatSetAsReport) {
c.treatSetAsReport = [...this.compat.treatSetAsReport].sort();
}

c = sortObject(c);
if (Object.keys(c).length > 0) {
Expand Down
56 changes: 56 additions & 0 deletions packages/zwave-js/src/lib/node/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ import {
BasicCCSet,
BasicCCValues,
} from "@zwave-js/cc/BasicCC";
import {
type BinarySwitchCC,
BinarySwitchCCSet,
BinarySwitchCCValues,
} from "@zwave-js/cc/BinarySwitchCC";
import {
CentralSceneCCNotification,
CentralSceneCCValues,
Expand Down Expand Up @@ -106,6 +111,11 @@ import {
SecurityCCNonceGet,
SecurityCCNonceReport,
} from "@zwave-js/cc/SecurityCC";
import {
type ThermostatModeCC,
ThermostatModeCCSet,
ThermostatModeCCValues,
} from "@zwave-js/cc/ThermostatModeCC";
import {
VersionCCCommandClassGet,
VersionCCGet,
Expand Down Expand Up @@ -3009,6 +3019,10 @@ protocol version: ${this.protocolVersion}`;
return this.handleBasicCommand(command);
} else if (command instanceof MultilevelSwitchCC) {
return this.handleMultilevelSwitchCommand(command);
} else if (command instanceof BinarySwitchCCSet) {
return this.handleBinarySwitchCommand(command);
} else if (command instanceof ThermostatModeCCSet) {
return this.handleThermostatModeCommand(command);
} else if (command instanceof CentralSceneCCNotification) {
return this.handleCentralSceneNotification(command);
} else if (command instanceof WakeUpCCWakeUpNotification) {
Expand Down Expand Up @@ -3731,6 +3745,48 @@ protocol version: ${this.protocolVersion}`;
}
}

private handleBinarySwitchCommand(command: BinarySwitchCC): void {
// Treat BinarySwitchCCSet as a report if desired
if (
command instanceof BinarySwitchCCSet
&& this._deviceConfig?.compat?.treatSetAsReport?.has(
command.constructor.name,
)
) {
this.driver.controllerLog.logNode(this.id, {
endpoint: command.endpointIndex,
message: "treating BinarySwitchCC::Set as a report",
});
this._valueDB.setValue(
BinarySwitchCCValues.currentValue.endpoint(
command.endpointIndex,
),
command.targetValue,
);
}
}

private handleThermostatModeCommand(command: ThermostatModeCC): void {
// Treat ThermostatModeCCSet as a report if desired
if (
command instanceof ThermostatModeCCSet
&& this._deviceConfig?.compat?.treatSetAsReport?.has(
command.constructor.name,
)
) {
this.driver.controllerLog.logNode(this.id, {
endpoint: command.endpointIndex,
message: "treating ThermostatModeCC::Set as a report",
});
this._valueDB.setValue(
ThermostatModeCCValues.thermostatMode.endpoint(
command.endpointIndex,
),
command.mode,
);
}
}

private async handleZWavePlusGet(command: ZWavePlusCCGet): Promise<void> {
const endpoint = this.getEndpoint(command.endpointIndex) ?? this;

Expand Down

0 comments on commit 79a62cc

Please sign in to comment.