From 0058bc3dbda0735121f826dc452dde94bc9bbcc7 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Thu, 27 Aug 2026 12:22:26 +0200 Subject: [PATCH 1/4] Add Time cluster attributes --- lib/clusters/time.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/clusters/time.js b/lib/clusters/time.js index 4f98b59..fc502ce 100644 --- a/lib/clusters/time.js +++ b/lib/clusters/time.js @@ -1,8 +1,22 @@ 'use strict'; const Cluster = require('../Cluster'); +const { ZCLDataTypes } = require('../zclTypes'); const ATTRIBUTES = { + time: { id: 0, type: ZCLDataTypes.UTC }, + timeStatus: { + id: 1, + type: ZCLDataTypes.map8('master', 'synchronized', 'masterZoneDst', 'superseding'), + }, + timeZone: { id: 2, type: ZCLDataTypes.int32 }, + dstStart: { id: 3, type: ZCLDataTypes.uint32 }, + dstEnd: { id: 4, type: ZCLDataTypes.uint32 }, + dstShift: { id: 5, type: ZCLDataTypes.int32 }, + standardTime: { id: 6, type: ZCLDataTypes.uint32 }, + localTime: { id: 7, type: ZCLDataTypes.uint32 }, + lastSetTime: { id: 8, type: ZCLDataTypes.UTC }, + validUntilTime: { id: 8, type: ZCLDataTypes.UTC }, }; const COMMANDS = {}; From a257021b69efcb0d34b98c58fe4ced5b860dd292 Mon Sep 17 00:00:00 2001 From: Robin Bolscher Date: Fri, 28 Aug 2026 15:42:44 +0200 Subject: [PATCH 2/4] build(deps): Bump @athombv/data-types to ^1.3.0 The Time cluster uses ZCLDataTypes.UTC, which was only added in 1.3.0. With the lockfile still pinned to 1.2.1, npm ci resolved a version where that type is undefined. Refs #216 --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4996a87..dd912dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "3.6.0", "license": "ISC", "dependencies": { - "@athombv/data-types": "^1.2.1", + "@athombv/data-types": "^1.3.0", "debug": "^4.1.1" }, "devDependencies": { @@ -29,13 +29,13 @@ "watch": "^1.0.2" }, "engines": { - "node": ">=12" + "node": ">=22" } }, "node_modules/@athombv/data-types": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@athombv/data-types/-/data-types-1.2.1.tgz", - "integrity": "sha512-b6gAW70H12ua6q9TuVbfA0xz4cz5HLx09tpM0hh4sTZbjZmpeQKuqJ680WFA9HPWbkh8IC41Eny2rXcr5oA6Sg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@athombv/data-types/-/data-types-1.3.0.tgz", + "integrity": "sha512-XJ7oMzKFcZdw2LpiBcr8QVmtQXkCpnOpDGpQ2iM2vuKjzosXQjAB0XUgKl+yubDNTFkTNa8mcFS5QdFP51O7pg==", "license": "GPL-3.0", "engines": { "node": ">=12.0.0" @@ -6509,9 +6509,9 @@ }, "dependencies": { "@athombv/data-types": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@athombv/data-types/-/data-types-1.2.1.tgz", - "integrity": "sha512-b6gAW70H12ua6q9TuVbfA0xz4cz5HLx09tpM0hh4sTZbjZmpeQKuqJ680WFA9HPWbkh8IC41Eny2rXcr5oA6Sg==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@athombv/data-types/-/data-types-1.3.0.tgz", + "integrity": "sha512-XJ7oMzKFcZdw2LpiBcr8QVmtQXkCpnOpDGpQ2iM2vuKjzosXQjAB0XUgKl+yubDNTFkTNa8mcFS5QdFP51O7pg==" }, "@athombv/jsdoc-template": { "version": "1.7.0", diff --git a/package.json b/package.json index 68b7e54..5ee5dd5 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "watch": "^1.0.2" }, "dependencies": { - "@athombv/data-types": "^1.2.1", + "@athombv/data-types": "^1.3.0", "debug": "^4.1.1" } } From 1652325079f41c4aef7b636c2596026c0803af77 Mon Sep 17 00:00:00 2001 From: Robin Bolscher Date: Fri, 28 Aug 2026 15:42:44 +0200 Subject: [PATCH 3/4] fix(time): Give validUntilTime its own attribute id ValidUntilTime is 0x0009 in the ZCL spec, not 0x0008. Because attributesById is keyed by id, the duplicate dropped lastSetTime from the lookup: reads and reports for 0x0008 decoded as validUntilTime, and 0x0009 was unknown. Refs #216 --- lib/clusters/time.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/clusters/time.js b/lib/clusters/time.js index fc502ce..bf2d824 100644 --- a/lib/clusters/time.js +++ b/lib/clusters/time.js @@ -5,10 +5,7 @@ const { ZCLDataTypes } = require('../zclTypes'); const ATTRIBUTES = { time: { id: 0, type: ZCLDataTypes.UTC }, - timeStatus: { - id: 1, - type: ZCLDataTypes.map8('master', 'synchronized', 'masterZoneDst', 'superseding'), - }, + timeStatus: { id: 1, type: ZCLDataTypes.map8('master', 'synchronized', 'masterZoneDst', 'superseding') }, timeZone: { id: 2, type: ZCLDataTypes.int32 }, dstStart: { id: 3, type: ZCLDataTypes.uint32 }, dstEnd: { id: 4, type: ZCLDataTypes.uint32 }, @@ -16,7 +13,7 @@ const ATTRIBUTES = { standardTime: { id: 6, type: ZCLDataTypes.uint32 }, localTime: { id: 7, type: ZCLDataTypes.uint32 }, lastSetTime: { id: 8, type: ZCLDataTypes.UTC }, - validUntilTime: { id: 8, type: ZCLDataTypes.UTC }, + validUntilTime: { id: 9, type: ZCLDataTypes.UTC }, }; const COMMANDS = {}; From dbb458b3fffa68b479a2e2a78fd82c3e63cbed89 Mon Sep 17 00:00:00 2001 From: Robin Bolscher Date: Fri, 28 Aug 2026 15:42:44 +0200 Subject: [PATCH 4/4] fix(types): Map the UTC ZCL data type to number zclDataTypeToValueType had no case for UTC, so generate-types threw "Unknown ZCL type UTC" as soon as a cluster used it. The type generation workflow has been failing on master since the Time cluster attributes landed, leaving index.d.ts without them. Refs #216 --- index.d.ts | 13 ++++++++++++- scripts/generate-types.mts | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index b619f79..3c3a66f 100644 --- a/index.d.ts +++ b/index.d.ts @@ -499,7 +499,18 @@ declare module "zigbee-clusters" { }, ): Promise; } - type TimeClusterAttributes = Record; + type TimeClusterAttributes = { + time: { id: 0x00, type: ZCLDataType }, + timeStatus: { id: 0x01, type: ZCLDataType> }, + timeZone: { id: 0x02, type: ZCLDataType }, + dstStart: { id: 0x03, type: ZCLDataType }, + dstEnd: { id: 0x04, type: ZCLDataType }, + dstShift: { id: 0x05, type: ZCLDataType }, + standardTime: { id: 0x06, type: ZCLDataType }, + localTime: { id: 0x07, type: ZCLDataType }, + lastSetTime: { id: 0x08, type: ZCLDataType }, + validUntilTime: { id: 0x09, type: ZCLDataType }, + }; type TimeClusterCommands = Record; class TimeCluster extends Cluster { } diff --git a/scripts/generate-types.mts b/scripts/generate-types.mts index 0c74820..b480d34 100644 --- a/scripts/generate-types.mts +++ b/scripts/generate-types.mts @@ -474,6 +474,7 @@ function zclDataTypeToValueType(type: keyof typeof DataTypes): string { case "int32": case "int40": case "int48": + case "UTC": return "number"; case "enum8": case "enum16":