From c1744074af4a51623531ee381b446ed075e18077 Mon Sep 17 00:00:00 2001 From: Robin Bolscher Date: Fri, 13 Mar 2026 16:24:00 +0100 Subject: [PATCH 1/4] Unify iasZone zoneType enum to match ZCL spec - Extract shared ZONE_TYPE_VALUES constant used by both the zoneType attribute and zoneEnrollRequest command - Fix typo: cabonMonoxideSensor -> carbonMonoxideSensor - Fix casing: keyfob -> keyFob (spec says "Key fob") - Unify names: standard -> standardCIE, invalid -> invalidZoneType - Add missing doorWindowHandle (0x0016) zone type from spec --- README.md | 9 +++++++ lib/clusters/iasZone.js | 57 +++++++++++++++-------------------------- test/iasZone.js | 2 +- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 4f7cf69..7896b66 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,15 @@ Make sure to take a look at the API documentation: [https://athombv.github.io/no ## Breaking changes +v3.0.0 + +- **iasZone**: Unified `zoneType` enum keys between attribute and `zoneEnrollRequest` command to match ZCL spec (Table 8-5): + - `cabonMonoxideSensor` -> `carbonMonoxideSensor` (typo fix) + - `keyfob` -> `keyFob` (spec says "Key fob" - two words) + - `standard` -> `standardCIE` (in `zoneEnrollRequest`) + - `invalid` -> `invalidZoneType` (in `zoneEnrollRequest`) + - Added missing `doorWindowHandle` (0x0016) zone type from spec + v2.0.0 - Changed `Cluster.readAttributes` signature, attributes must now be specified as an array of strings. diff --git a/lib/clusters/iasZone.js b/lib/clusters/iasZone.js index e0dd129..fbb1328 100644 --- a/lib/clusters/iasZone.js +++ b/lib/clusters/iasZone.js @@ -5,6 +5,25 @@ const { ZCLDataTypes } = require('../zclTypes'); const ZONE_STATUS_DATA_TYPE = ZCLDataTypes.map16('alarm1', 'alarm2', 'tamper', 'battery', 'supervisionReports', 'restoreReports', 'trouble', 'acMains', 'test', 'batteryDefect'); +const ZONE_TYPE_VALUES = { + standardCIE: 0x0000, + motionSensor: 0x000d, + contactSwitch: 0x0015, + doorWindowHandle: 0x0016, + fireSensor: 0x0028, + waterSensor: 0x002a, + carbonMonoxideSensor: 0x002b, + personalEmergencyDevice: 0x002c, + vibrationMovementSensor: 0x002d, + remoteControl: 0x010f, + keyFob: 0x0115, + keypad: 0x021d, + standardWarningDevice: 0x0225, + glassBreakSensor: 0x0226, + securityRepeater: 0x0229, + invalidZoneType: 0xffff, +}; + const ATTRIBUTES = { zoneState: { id: 0, @@ -15,24 +34,7 @@ const ATTRIBUTES = { }, zoneType: { id: 1, - // Note: enum keys differ from zoneEnrollRequest.zoneType but can't be changed without breaking - type: ZCLDataTypes.enum16({ - standardCIE: 0, - motionSensor: 13, - contactSwitch: 21, - fireSensor: 40, - waterSensor: 42, - cabonMonoxideSensor: 43, - personalEmergencyDevice: 44, - vibrationMovementSensor: 45, - remoteControl: 271, - keyfob: 277, - keypad: 541, - standardWarningDevice: 549, - glassBreakSensor: 550, - securityRepeater: 553, - invalidZoneType: 65535, - }), + type: ZCLDataTypes.enum16(ZONE_TYPE_VALUES), }, zoneStatus: { id: 2, @@ -79,24 +81,7 @@ const COMMANDS = { // Add direction property as "initiateNormalOperationMode" has same command id. direction: Cluster.DIRECTION_SERVER_TO_CLIENT, args: { - // Note: enum keys differ from the zoneType attribute but can't be changed without breaking - zoneType: ZCLDataTypes.enum16({ - standard: 0x0000, - motionSensor: 0x000d, - contactSwitch: 0x0015, - fireSensor: 0x0028, - waterSensor: 0x002a, - carbonMonoxideSensor: 0x002b, - personalEmergencyDevice: 0x002c, - vibrationMovementSensor: 0x002d, - remoteControl: 0x010f, - keyFob: 0x0115, - keyPad: 0x021d, - standardWarningDevice: 0x0225, - glassBreakSensor: 0x0226, - securityRepeater: 0x0229, - invalid: 0xffff, - }), + zoneType: ZCLDataTypes.enum16(ZONE_TYPE_VALUES), manufacturerCode: ZCLDataTypes.uint16, }, }, diff --git a/test/iasZone.js b/test/iasZone.js index b797e6b..c78d1f1 100644 --- a/test/iasZone.js +++ b/test/iasZone.js @@ -19,7 +19,7 @@ describe('IAS Zone', function() { }); node.endpoints[1].clusters.iasZone.onZoneEnrollRequest = data => { - assert.strictEqual(data.zoneType, 'keyPad'); + assert.strictEqual(data.zoneType, 'keypad'); assert.strictEqual(data.manufacturerCode, 4117); done(); }; From 7f4fcf6ca92057cf3fb6762b5d601a32b690153a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Mar 2026 15:24:34 +0000 Subject: [PATCH 2/4] chore(types): auto-generate TypeScript definitions Updated by GitHub Actions after cluster changes. [skip ci] --- index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 6474e31..9e3b77a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -467,7 +467,7 @@ export interface IASWDCluster extends ZCLNodeCluster { export interface IASZoneClusterAttributes { zoneState?: 'notEnrolled' | 'enrolled'; - zoneType?: 'standardCIE' | 'motionSensor' | 'contactSwitch' | 'fireSensor' | 'waterSensor' | 'cabonMonoxideSensor' | 'personalEmergencyDevice' | 'vibrationMovementSensor' | 'remoteControl' | 'keyfob' | 'keypad' | 'standardWarningDevice' | 'glassBreakSensor' | 'securityRepeater' | 'invalidZoneType'; + zoneType?: 'standardCIE' | 'motionSensor' | 'contactSwitch' | 'doorWindowHandle' | 'fireSensor' | 'waterSensor' | 'carbonMonoxideSensor' | 'personalEmergencyDevice' | 'vibrationMovementSensor' | 'remoteControl' | 'keyFob' | 'keypad' | 'standardWarningDevice' | 'glassBreakSensor' | 'securityRepeater' | 'invalidZoneType'; zoneStatus?: Partial<{ alarm1: boolean; alarm2: boolean; tamper: boolean; battery: boolean; supervisionReports: boolean; restoreReports: boolean; trouble: boolean; acMains: boolean; test: boolean; batteryDefect: boolean }>; iasCIEAddress?: string; zoneId?: number; @@ -481,7 +481,7 @@ export interface IASZoneCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: IASZoneClusterAttributes[K]) => void): this; zoneStatusChangeNotification(args: { zoneStatus: Partial<{ alarm1: boolean; alarm2: boolean; tamper: boolean; battery: boolean; supervisionReports: boolean; restoreReports: boolean; trouble: boolean; acMains: boolean; test: boolean; batteryDefect: boolean }>; extendedStatus: number; zoneId: number; delay: number }, opts?: ClusterCommandOptions): Promise; zoneEnrollResponse(args: { enrollResponseCode: 'success' | 'notSupported' | 'noEnrollPermit' | 'tooManyZones'; zoneId: number }, opts?: ClusterCommandOptions): Promise; - zoneEnrollRequest(args: { zoneType: 'standard' | 'motionSensor' | 'contactSwitch' | 'fireSensor' | 'waterSensor' | 'carbonMonoxideSensor' | 'personalEmergencyDevice' | 'vibrationMovementSensor' | 'remoteControl' | 'keyFob' | 'keyPad' | 'standardWarningDevice' | 'glassBreakSensor' | 'securityRepeater' | 'invalid'; manufacturerCode: number }, opts?: ClusterCommandOptions): Promise; + zoneEnrollRequest(args: { zoneType: 'standardCIE' | 'motionSensor' | 'contactSwitch' | 'doorWindowHandle' | 'fireSensor' | 'waterSensor' | 'carbonMonoxideSensor' | 'personalEmergencyDevice' | 'vibrationMovementSensor' | 'remoteControl' | 'keyFob' | 'keypad' | 'standardWarningDevice' | 'glassBreakSensor' | 'securityRepeater' | 'invalidZoneType'; manufacturerCode: number }, opts?: ClusterCommandOptions): Promise; initiateNormalOperationMode(opts?: ClusterCommandOptions): Promise; } From d18cd49ebb01fd2e5a8a18da44431a3226dac803 Mon Sep 17 00:00:00 2001 From: Robin Bolscher Date: Fri, 13 Mar 2026 16:28:24 +0100 Subject: [PATCH 3/4] Add link to PR #176 impact analysis in breaking changes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7896b66..fd0fa91 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Make sure to take a look at the API documentation: [https://athombv.github.io/no v3.0.0 -- **iasZone**: Unified `zoneType` enum keys between attribute and `zoneEnrollRequest` command to match ZCL spec (Table 8-5): +- **iasZone**: Unified `zoneType` enum keys between attribute and `zoneEnrollRequest` command to match ZCL spec (Table 8-5). See [#176](https://github.com/athombv/node-zigbee-clusters/pull/176) for full impact analysis. - `cabonMonoxideSensor` -> `carbonMonoxideSensor` (typo fix) - `keyfob` -> `keyFob` (spec says "Key fob" - two words) - `standard` -> `standardCIE` (in `zoneEnrollRequest`) From 276a85d8242f3cca269730d9c97c10c3aa27f852 Mon Sep 17 00:00:00 2001 From: Robin Bolscher Date: Fri, 13 Mar 2026 16:29:11 +0100 Subject: [PATCH 4/4] Add missing keyPad -> keypad rename to breaking changes --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fd0fa91..c9284e8 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ v3.0.0 - `keyfob` -> `keyFob` (spec says "Key fob" - two words) - `standard` -> `standardCIE` (in `zoneEnrollRequest`) - `invalid` -> `invalidZoneType` (in `zoneEnrollRequest`) + - `keyPad` -> `keypad` (in `zoneEnrollRequest`, spec says "Keypad" - one word) - Added missing `doorWindowHandle` (0x0016) zone type from spec v2.0.0