From 578ce1eeadd7508b00d5d978eefc7976d6094952 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Tue, 24 Mar 2026 13:23:30 +0100 Subject: [PATCH 1/9] Simplify readAttributes type definitions --- index.d.ts | 66 +++++++++++++++++++-------------------- scripts/generate-types.js | 3 +- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/index.d.ts b/index.d.ts index 0900b62..818e193 100644 --- a/index.d.ts +++ b/index.d.ts @@ -96,7 +96,7 @@ export interface AnalogInputClusterAttributes { } export interface AnalogInputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: AnalogInputClusterAttributes[K]) => void): this; @@ -117,7 +117,7 @@ export interface AnalogOutputClusterAttributes { } export interface AnalogOutputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: AnalogOutputClusterAttributes[K]) => void): this; @@ -135,7 +135,7 @@ export interface AnalogValueClusterAttributes { } export interface AnalogValueCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: AnalogValueClusterAttributes[K]) => void): this; @@ -162,7 +162,7 @@ export interface BallastConfigurationClusterAttributes { } export interface BallastConfigurationCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: BallastConfigurationClusterAttributes[K]) => void): this; @@ -188,7 +188,7 @@ export interface BasicClusterAttributes { } export interface BasicCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: BasicClusterAttributes[K]) => void): this; @@ -209,7 +209,7 @@ export interface BinaryInputClusterAttributes { } export interface BinaryInputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: BinaryInputClusterAttributes[K]) => void): this; @@ -232,7 +232,7 @@ export interface BinaryOutputClusterAttributes { } export interface BinaryOutputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: BinaryOutputClusterAttributes[K]) => void): this; @@ -255,7 +255,7 @@ export interface BinaryValueClusterAttributes { } export interface BinaryValueCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: BinaryValueClusterAttributes[K]) => void): this; @@ -275,7 +275,7 @@ export interface ColorControlClusterAttributes { } export interface ColorControlCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: ColorControlClusterAttributes[K]) => void): this; @@ -303,7 +303,7 @@ export interface DeviceTemperatureClusterAttributes { } export interface DeviceTemperatureCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: DeviceTemperatureClusterAttributes[K]) => void): this; @@ -360,7 +360,7 @@ export interface DoorLockClusterAttributes { } export interface DoorLockCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: DoorLockClusterAttributes[K]) => void): this; @@ -419,7 +419,7 @@ export interface ElectricalMeasurementClusterAttributes { } export interface ElectricalMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: ElectricalMeasurementClusterAttributes[K]) => void): this; @@ -437,7 +437,7 @@ export interface FlowMeasurementClusterAttributes { } export interface FlowMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: FlowMeasurementClusterAttributes[K]) => void): this; @@ -449,7 +449,7 @@ export interface GroupsClusterAttributes { } export interface GroupsCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: GroupsClusterAttributes[K]) => void): this; @@ -477,7 +477,7 @@ export interface IASZoneClusterAttributes { } export interface IASZoneCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: IASZoneClusterAttributes[K]) => void): this; @@ -493,7 +493,7 @@ export interface IdentifyClusterAttributes { } export interface IdentifyCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: IdentifyClusterAttributes[K]) => void): this; @@ -510,7 +510,7 @@ export interface IlluminanceLevelSensingClusterAttributes { } export interface IlluminanceLevelSensingCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: IlluminanceLevelSensingClusterAttributes[K]) => void): this; @@ -526,7 +526,7 @@ export interface IlluminanceMeasurementClusterAttributes { } export interface IlluminanceMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: IlluminanceMeasurementClusterAttributes[K]) => void): this; @@ -544,7 +544,7 @@ export interface LevelControlClusterAttributes { } export interface LevelControlCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: LevelControlClusterAttributes[K]) => void): this; @@ -744,7 +744,7 @@ export interface MeteringClusterAttributes { } export interface MeteringCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: MeteringClusterAttributes[K]) => void): this; @@ -762,7 +762,7 @@ export interface MultistateInputClusterAttributes { } export interface MultistateInputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: MultistateInputClusterAttributes[K]) => void): this; @@ -781,7 +781,7 @@ export interface MultistateOutputClusterAttributes { } export interface MultistateOutputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: MultistateOutputClusterAttributes[K]) => void): this; @@ -800,7 +800,7 @@ export interface MultistateValueClusterAttributes { } export interface MultistateValueCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: MultistateValueClusterAttributes[K]) => void): this; @@ -823,7 +823,7 @@ export interface OccupancySensingClusterAttributes { } export interface OccupancySensingCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: OccupancySensingClusterAttributes[K]) => void): this; @@ -837,7 +837,7 @@ export interface OnOffClusterAttributes { } export interface OnOffCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: OnOffClusterAttributes[K]) => void): this; @@ -870,7 +870,7 @@ export interface OTAClusterAttributes { } export interface OTACluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: OTAClusterAttributes[K]) => void): this; @@ -896,7 +896,7 @@ export interface PollControlClusterAttributes { } export interface PollControlCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: PollControlClusterAttributes[K]) => void): this; @@ -917,7 +917,7 @@ export interface PowerConfigurationClusterAttributes { } export interface PowerConfigurationCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: PowerConfigurationClusterAttributes[K]) => void): this; @@ -940,7 +940,7 @@ export interface PressureMeasurementClusterAttributes { } export interface PressureMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: PressureMeasurementClusterAttributes[K]) => void): this; @@ -958,7 +958,7 @@ export interface RelativeHumidityClusterAttributes { } export interface RelativeHumidityCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: RelativeHumidityClusterAttributes[K]) => void): this; @@ -978,7 +978,7 @@ export interface TemperatureMeasurementClusterAttributes { } export interface TemperatureMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: TemperatureMeasurementClusterAttributes[K]) => void): this; @@ -1012,7 +1012,7 @@ export interface ThermostatClusterAttributes { } export interface ThermostatCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: ThermostatClusterAttributes[K]) => void): this; @@ -1051,7 +1051,7 @@ export interface WindowCoveringClusterAttributes { } export interface WindowCoveringCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; + readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; on(eventName: `attr.${K}`, listener: (value: WindowCoveringClusterAttributes[K]) => void): this; diff --git a/scripts/generate-types.js b/scripts/generate-types.js index 1f5097f..f96aaa7 100644 --- a/scripts/generate-types.js +++ b/scripts/generate-types.js @@ -184,8 +184,7 @@ function generateClusterInterface(cluster) { // Add typed readAttributes if we have attributes if (cluster.attributes.length > 0) { - const attrNames = cluster.attributes.map(a => `'${a.name}'`).join(' | '); - lines.push(` readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>;`); + lines.push(` readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>;`); lines.push(` readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>;`); lines.push(` writeAttributes(attributes: Partial<${interfaceName}Attributes>, opts?: { timeout?: number }): Promise;`); lines.push(` on(eventName: \`attr.\${K}\`, listener: (value: ${interfaceName}Attributes[K]) => void): this;`); From b9b88ed3f24c50ee54612ba60a95f3a8f8bd6b26 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Tue, 24 Mar 2026 13:23:43 +0100 Subject: [PATCH 2/9] Export ZCLEnum8Status --- index.d.ts | 2 +- scripts/generate-types.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 818e193..13fa943 100644 --- a/index.d.ts +++ b/index.d.ts @@ -31,7 +31,7 @@ type ZCLNodeConstructorInput = { ) => Promise; }; -type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; +export type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; export interface ZCLNodeCluster extends EventEmitter { /** Dynamic command handler methods (e.g. `onZoneStatusChangeNotification`). */ diff --git a/scripts/generate-types.js b/scripts/generate-types.js index f96aaa7..2150153 100644 --- a/scripts/generate-types.js +++ b/scripts/generate-types.js @@ -280,7 +280,7 @@ type ZCLNodeConstructorInput = { ) => Promise; }; -type ZCLEnum8Status = ${zclTypeToTS(ZCLDataTypes.enum8Status, false)}; +export type ZCLEnum8Status = ${zclTypeToTS(ZCLDataTypes.enum8Status, false)}; `); // Base ZCLNodeCluster interface From 7912e709cbb6ab863d5663d6375e6dc4f9a723e0 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Tue, 24 Mar 2026 18:08:25 +0100 Subject: [PATCH 3/9] Add global attributes to cluster attribute type definitions --- index.d.ts | 71 +++++++++++++++++++++------------------ scripts/generate-types.js | 7 +++- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/index.d.ts b/index.d.ts index 13fa943..fb5ae9a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -33,6 +33,11 @@ type ZCLNodeConstructorInput = { export type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; +export type GlobalClusterAttributes = { + clusterRevision: number; + attributeReportingStatus: 0 | 1; +}; + export interface ZCLNodeCluster extends EventEmitter { /** Dynamic command handler methods (e.g. `onZoneStatusChangeNotification`). */ [key: `on${string}`]: unknown; @@ -83,7 +88,7 @@ export interface AlarmsCluster extends ZCLNodeCluster { resetAlarmLog(opts?: ClusterCommandOptions): Promise; } -export interface AnalogInputClusterAttributes { +export interface AnalogInputClusterAttributes extends GlobalClusterAttributes { description?: string; maxPresentValue?: number; minPresentValue?: number; @@ -103,7 +108,7 @@ export interface AnalogInputCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: AnalogInputClusterAttributes[K]) => void): this; } -export interface AnalogOutputClusterAttributes { +export interface AnalogOutputClusterAttributes extends GlobalClusterAttributes { description?: string; maxPresentValue?: number; minPresentValue?: number; @@ -124,7 +129,7 @@ export interface AnalogOutputCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: AnalogOutputClusterAttributes[K]) => void): this; } -export interface AnalogValueClusterAttributes { +export interface AnalogValueClusterAttributes extends GlobalClusterAttributes { description?: string; outOfService?: boolean; presentValue?: number; @@ -142,7 +147,7 @@ export interface AnalogValueCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: AnalogValueClusterAttributes[K]) => void): this; } -export interface BallastConfigurationClusterAttributes { +export interface BallastConfigurationClusterAttributes extends GlobalClusterAttributes { physicalMinLevel?: number; physicalMaxLevel?: number; ballastStatus?: Partial<{ nonOperational: boolean; lampNotInSocket: boolean }>; @@ -169,7 +174,7 @@ export interface BallastConfigurationCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: BallastConfigurationClusterAttributes[K]) => void): this; } -export interface BasicClusterAttributes { +export interface BasicClusterAttributes extends GlobalClusterAttributes { zclVersion?: number; appVersion?: number; stackVersion?: number; @@ -196,7 +201,7 @@ export interface BasicCluster extends ZCLNodeCluster { factoryReset(opts?: ClusterCommandOptions): Promise; } -export interface BinaryInputClusterAttributes { +export interface BinaryInputClusterAttributes extends GlobalClusterAttributes { activeText?: string; description?: string; inactiveText?: string; @@ -216,7 +221,7 @@ export interface BinaryInputCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: BinaryInputClusterAttributes[K]) => void): this; } -export interface BinaryOutputClusterAttributes { +export interface BinaryOutputClusterAttributes extends GlobalClusterAttributes { activeText?: string; description?: string; inactiveText?: string; @@ -239,7 +244,7 @@ export interface BinaryOutputCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: BinaryOutputClusterAttributes[K]) => void): this; } -export interface BinaryValueClusterAttributes { +export interface BinaryValueClusterAttributes extends GlobalClusterAttributes { activeText?: string; description?: string; inactiveText?: string; @@ -262,7 +267,7 @@ export interface BinaryValueCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: BinaryValueClusterAttributes[K]) => void): this; } -export interface ColorControlClusterAttributes { +export interface ColorControlClusterAttributes extends GlobalClusterAttributes { currentHue?: number; currentSaturation?: number; currentX?: number; @@ -290,7 +295,7 @@ export interface ColorControlCluster extends ZCLNodeCluster { export interface DehumidificationControlCluster extends ZCLNodeCluster { } -export interface DeviceTemperatureClusterAttributes { +export interface DeviceTemperatureClusterAttributes extends GlobalClusterAttributes { currentTemperature?: number; minTempExperienced?: number; maxTempExperienced?: number; @@ -313,7 +318,7 @@ export interface DeviceTemperatureCluster extends ZCLNodeCluster { export interface DiagnosticsCluster extends ZCLNodeCluster { } -export interface DoorLockClusterAttributes { +export interface DoorLockClusterAttributes extends GlobalClusterAttributes { lockState?: 'notFullyLocked' | 'locked' | 'unlocked' | 'undefined'; lockType?: 'deadBolt' | 'magnetic' | 'other' | 'mortise' | 'rim' | 'latchBolt' | 'cylindricalLock' | 'tubularLock' | 'interconnectedLock' | 'deadLatch' | 'doorFurniture'; actuatorEnabled?: boolean; @@ -395,7 +400,7 @@ export interface DoorLockCluster extends ZCLNodeCluster { programmingEventNotification(args: { programEventSource: number; programEventCode: number; userId: number; pin?: Buffer; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported'; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported'; zigBeeLocalTime: number; data?: Buffer }, opts?: ClusterCommandOptions): Promise; } -export interface ElectricalMeasurementClusterAttributes { +export interface ElectricalMeasurementClusterAttributes extends GlobalClusterAttributes { measurementType?: Partial<{ activeMeasurementAC: boolean; reactiveMeasurementAC: boolean; apparentMeasurementAC: boolean; phaseAMeasurement: boolean; phaseBMeasurement: boolean; phaseCMeasurement: boolean; dcMeasurement: boolean; harmonicsMeasurement: boolean; powerQualityMeasurement: boolean }>; acFrequency?: number; measuredPhase1stHarmonicCurrent?: number; @@ -429,7 +434,7 @@ export interface ElectricalMeasurementCluster extends ZCLNodeCluster { export interface FanControlCluster extends ZCLNodeCluster { } -export interface FlowMeasurementClusterAttributes { +export interface FlowMeasurementClusterAttributes extends GlobalClusterAttributes { measuredValue?: number; minMeasuredValue?: number; maxMeasuredValue?: number; @@ -444,7 +449,7 @@ export interface FlowMeasurementCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: FlowMeasurementClusterAttributes[K]) => void): this; } -export interface GroupsClusterAttributes { +export interface GroupsClusterAttributes extends GlobalClusterAttributes { nameSupport?: Partial<{ groupNames: boolean }>; } @@ -468,7 +473,7 @@ export interface IASACECluster extends ZCLNodeCluster { export interface IASWDCluster extends ZCLNodeCluster { } -export interface IASZoneClusterAttributes { +export interface IASZoneClusterAttributes extends GlobalClusterAttributes { zoneState?: 'notEnrolled' | 'enrolled'; 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 }>; @@ -488,7 +493,7 @@ export interface IASZoneCluster extends ZCLNodeCluster { initiateNormalOperationMode(opts?: ClusterCommandOptions): Promise; } -export interface IdentifyClusterAttributes { +export interface IdentifyClusterAttributes extends GlobalClusterAttributes { identifyTime?: number; } @@ -503,7 +508,7 @@ export interface IdentifyCluster extends ZCLNodeCluster { triggerEffect(args: { effectIdentifier: 'blink' | 'breathe' | 'okay' | 'channelChange' | 'finish' | 'stop'; effectVariant: number }, opts?: ClusterCommandOptions): Promise; } -export interface IlluminanceLevelSensingClusterAttributes { +export interface IlluminanceLevelSensingClusterAttributes extends GlobalClusterAttributes { levelStatus?: 'illuminanceOnTarget' | 'illuminanceBelowTarget' | 'illuminanceAboveTarget'; lightSensorType?: 'photodiode' | 'cmos' | 'unknown'; illuminanceTargetLevel?: number; @@ -517,7 +522,7 @@ export interface IlluminanceLevelSensingCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: IlluminanceLevelSensingClusterAttributes[K]) => void): this; } -export interface IlluminanceMeasurementClusterAttributes { +export interface IlluminanceMeasurementClusterAttributes extends GlobalClusterAttributes { measuredValue?: number; minMeasuredValue?: number; maxMeasuredValue?: number; @@ -533,7 +538,7 @@ export interface IlluminanceMeasurementCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: IlluminanceMeasurementClusterAttributes[K]) => void): this; } -export interface LevelControlClusterAttributes { +export interface LevelControlClusterAttributes extends GlobalClusterAttributes { currentLevel?: number; remainingTime?: number; onOffTransitionTime?: number; @@ -559,7 +564,7 @@ export interface LevelControlCluster extends ZCLNodeCluster { stopWithOnOff(opts?: ClusterCommandOptions): Promise; } -export interface MeteringClusterAttributes { +export interface MeteringClusterAttributes extends GlobalClusterAttributes { currentSummationDelivered?: number; currentSummationReceived?: number; currentMaxDemandDelivered?: number; @@ -751,7 +756,7 @@ export interface MeteringCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: MeteringClusterAttributes[K]) => void): this; } -export interface MultistateInputClusterAttributes { +export interface MultistateInputClusterAttributes extends GlobalClusterAttributes { description?: string; numberOfStates?: number; outOfService?: boolean; @@ -769,7 +774,7 @@ export interface MultistateInputCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: MultistateInputClusterAttributes[K]) => void): this; } -export interface MultistateOutputClusterAttributes { +export interface MultistateOutputClusterAttributes extends GlobalClusterAttributes { description?: string; numberOfStates?: number; outOfService?: boolean; @@ -788,7 +793,7 @@ export interface MultistateOutputCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: MultistateOutputClusterAttributes[K]) => void): this; } -export interface MultistateValueClusterAttributes { +export interface MultistateValueClusterAttributes extends GlobalClusterAttributes { description?: string; numberOfStates?: number; outOfService?: boolean; @@ -807,7 +812,7 @@ export interface MultistateValueCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: MultistateValueClusterAttributes[K]) => void): this; } -export interface OccupancySensingClusterAttributes { +export interface OccupancySensingClusterAttributes extends GlobalClusterAttributes { occupancy?: Partial<{ occupied: boolean }>; occupancySensorType?: 'pir' | 'ultrasonic' | 'pirAndUltrasonic' | 'physicalContact'; occupancySensorTypeBitmap?: Partial<{ pir: boolean; ultrasonic: boolean; physicalContact: boolean }>; @@ -830,7 +835,7 @@ export interface OccupancySensingCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: OccupancySensingClusterAttributes[K]) => void): this; } -export interface OnOffClusterAttributes { +export interface OnOffClusterAttributes extends GlobalClusterAttributes { onOff?: boolean; onTime?: number; offWaitTime?: number; @@ -853,7 +858,7 @@ export interface OnOffCluster extends ZCLNodeCluster { export interface OnOffSwitchCluster extends ZCLNodeCluster { } -export interface OTAClusterAttributes { +export interface OTAClusterAttributes extends GlobalClusterAttributes { upgradeServerID?: string; fileOffset?: number; currentFileVersion?: number; @@ -885,7 +890,7 @@ export interface OTACluster extends ZCLNodeCluster { queryDeviceSpecificFileRequest(args: { requestNodeAddress: string; manufacturerCode: number; imageType: number; fileVersion: number; zigBeeStackVersion: number }, opts?: ClusterCommandOptions): Promise<{ status?: ZCLEnum8Status; manufacturerCode?: number; imageType?: number; fileVersion?: number; imageSize?: number }>; } -export interface PollControlClusterAttributes { +export interface PollControlClusterAttributes extends GlobalClusterAttributes { checkInInterval?: number; longPollInterval?: number; shortPollInterval?: number; @@ -906,7 +911,7 @@ export interface PollControlCluster extends ZCLNodeCluster { setShortPollInterval(args: { newShortPollInterval: number }, opts?: ClusterCommandOptions): Promise; } -export interface PowerConfigurationClusterAttributes { +export interface PowerConfigurationClusterAttributes extends GlobalClusterAttributes { batteryVoltage?: number; batteryPercentageRemaining?: number; batterySize?: 'noBattery' | 'builtIn' | 'other' | 'AA' | 'AAA' | 'C' | 'D' | 'CR2' | 'CR123A' | 'unknown'; @@ -927,7 +932,7 @@ export interface PowerConfigurationCluster extends ZCLNodeCluster { export interface PowerProfileCluster extends ZCLNodeCluster { } -export interface PressureMeasurementClusterAttributes { +export interface PressureMeasurementClusterAttributes extends GlobalClusterAttributes { measuredValue?: number; minMeasuredValue?: number; maxMeasuredValue?: number; @@ -950,7 +955,7 @@ export interface PressureMeasurementCluster extends ZCLNodeCluster { export interface PumpConfigurationAndControlCluster extends ZCLNodeCluster { } -export interface RelativeHumidityClusterAttributes { +export interface RelativeHumidityClusterAttributes extends GlobalClusterAttributes { measuredValue?: number; minMeasuredValue?: number; maxMeasuredValue?: number; @@ -971,7 +976,7 @@ export interface ScenesCluster extends ZCLNodeCluster { export interface ShadeConfigurationCluster extends ZCLNodeCluster { } -export interface TemperatureMeasurementClusterAttributes { +export interface TemperatureMeasurementClusterAttributes extends GlobalClusterAttributes { measuredValue?: number; minMeasuredValue?: number; maxMeasuredValue?: number; @@ -985,7 +990,7 @@ export interface TemperatureMeasurementCluster extends ZCLNodeCluster { once(eventName: `attr.${K}`, listener: (value: TemperatureMeasurementClusterAttributes[K]) => void): this; } -export interface ThermostatClusterAttributes { +export interface ThermostatClusterAttributes extends GlobalClusterAttributes { localTemperature?: number; outdoorTemperature?: number; occupancy?: Partial<{ occupied: boolean }>; @@ -1027,7 +1032,7 @@ export interface TouchLinkCluster extends ZCLNodeCluster { getGroups(args: { startIdx: number }, opts?: ClusterCommandOptions): Promise<{ total: number; startIndex: number; groups: unknown[] }>; } -export interface WindowCoveringClusterAttributes { +export interface WindowCoveringClusterAttributes extends GlobalClusterAttributes { windowCoveringType?: 'rollershade' | 'rollershade2Motor' | 'rollershadeExterior' | 'rollershadeExterior2Motor' | 'drapery' | 'awning' | 'shutter' | 'tiltBlindTiltOnly' | 'tiltBlindLiftAndTilt' | 'projectorScreen'; physicalClosedLimitLift?: number; physicalClosedLimitTilt?: number; diff --git a/scripts/generate-types.js b/scripts/generate-types.js index 2150153..77e6063 100644 --- a/scripts/generate-types.js +++ b/scripts/generate-types.js @@ -171,7 +171,7 @@ function generateClusterInterface(cluster) { // Generate attributes interface if (cluster.attributes.length > 0) { - lines.push(`export interface ${interfaceName}Attributes {`); + lines.push(`export interface ${interfaceName}Attributes extends GlobalClusterAttributes {`); for (const attr of cluster.attributes) { lines.push(` ${attr.name}?: ${attr.tsType};`); } @@ -281,6 +281,11 @@ type ZCLNodeConstructorInput = { }; export type ZCLEnum8Status = ${zclTypeToTS(ZCLDataTypes.enum8Status, false)}; + +export type GlobalClusterAttributes = { + clusterRevision: number; + attributeReportingStatus: 0 | 1; +}; `); // Base ZCLNodeCluster interface From 530df5b25b065edda35222babc206480e6d1241d Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Thu, 26 Mar 2026 16:55:51 +0100 Subject: [PATCH 4/9] Fix invalid enum8 definitions --- lib/clusters/metering.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/clusters/metering.js b/lib/clusters/metering.js index 0b9fbb4..d0a24a7 100644 --- a/lib/clusters/metering.js +++ b/lib/clusters/metering.js @@ -19,8 +19,8 @@ const ATTRIBUTES = { fastPollUpdatePeriod: { id: 0x000B, type: ZCLDataTypes.uint8 }, // 11, Optional currentBlockPeriodConsumptionDelivered: { id: 0x000C, type: ZCLDataTypes.uint48 }, // 12, Optional dailyConsumptionTarget: { id: 0x000D, type: ZCLDataTypes.uint24 }, // 13, Optional - currentBlock: { id: 0x000E, type: ZCLDataTypes.enum8 }, // 14, Optional - profileIntervalPeriod: { id: 0x000F, type: ZCLDataTypes.enum8 }, // 15, Optional + currentBlock: { id: 0x000E, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 14, Optional + profileIntervalPeriod: { id: 0x000F, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 15, Optional // Summation TOU Information Set (0x0100 - 0x01FF) currentTier1SummationDelivered: { id: 0x0100, type: ZCLDataTypes.uint48 }, // 256, Optional @@ -52,7 +52,7 @@ const ATTRIBUTES = { // extendedStatus: { id: 0x0204, type: ZCLDataTypes.map64() }, // 516, Optional // Formatting Set (0x0300 - 0x03FF) - unitOfMeasure: { id: 0x0300, type: ZCLDataTypes.enum8 }, // 768, Mandatory + unitOfMeasure: { id: 0x0300, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 768, Mandatory multiplier: { id: 0x0301, type: ZCLDataTypes.uint24 }, // 769, Optional divisor: { id: 0x0302, type: ZCLDataTypes.uint24 }, // 770, Optional // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros @@ -63,18 +63,18 @@ const ATTRIBUTES = { // meteringDeviceType: { id: 0x0306, type: ZCLDataTypes.map8() }, // 774, Mandatory siteId: { id: 0x0307, type: ZCLDataTypes.octstr }, // 775, Optional meterSerialNumber: { id: 0x0308, type: ZCLDataTypes.octstr }, // 776, Optional - energyCarrierUnitOfMeasure: { id: 0x0309, type: ZCLDataTypes.enum8 }, // 777, Optional + energyCarrierUnitOfMeasure: { id: 0x0309, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 777, Optional // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros // energyCarrierSummationFormatting: { id: 0x030A, type: ZCLDataTypes.map8() }, // 778, Optional // energyCarrierDemandFormatting: { id: 0x030B, type: ZCLDataTypes.map8() }, // 779, Optional - temperatureUnitOfMeasure: { id: 0x030C, type: ZCLDataTypes.enum8 }, // 780, Optional + temperatureUnitOfMeasure: { id: 0x030C, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 780, Optional // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros // temperatureFormatting: { id: 0x030D, type: ZCLDataTypes.map8() }, // 781, Optional moduleSerialNumber: { id: 0x030E, type: ZCLDataTypes.octstr }, // 782, Optional operatingTariffLabelDelivered: { id: 0x030F, type: ZCLDataTypes.octstr }, // 783, Optional operatingTariffLabelReceived: { id: 0x0310, type: ZCLDataTypes.octstr }, // 784, Optional customerIdNumber: { id: 0x0311, type: ZCLDataTypes.octstr }, // 785, Optional - alternativeUnitOfMeasure: { id: 0x0312, type: ZCLDataTypes.enum8 }, // 786, Optional + alternativeUnitOfMeasure: { id: 0x0312, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 786, Optional // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros // alternativeDemandFormatting: { id: 0x0313, type: ZCLDataTypes.map8() }, // 787, Optional // alternativeConsumptionFormatting: { id: 0x0314, type: ZCLDataTypes.map8() }, // 788, Optional @@ -258,11 +258,11 @@ const ATTRIBUTES = { id: 0x0B00, // 2816 type: ZCLDataTypes.uint32, }, - proposedChangeSupplyStatus: { id: 0x0B01, type: ZCLDataTypes.enum8 }, // 2817, Optional + proposedChangeSupplyStatus: { id: 0x0B01, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 2817, Optional uncontrolledFlowThreshold: { id: 0x0B10, type: ZCLDataTypes.uint16 }, // 2832, Optional uncontrolledFlowThresholdUnitOfMeasure: { // Optional id: 0x0B11, // 2833 - type: ZCLDataTypes.enum8, + type: ZCLDataTypes.enum8({/* TODO fix */}), }, uncontrolledFlowMultiplier: { id: 0x0B12, type: ZCLDataTypes.uint16 }, // 2834, Optional uncontrolledFlowDivisor: { id: 0x0B13, type: ZCLDataTypes.uint16 }, // 2835, Optional From d782b218d24a2b9a9deb7d7f3803ca80dcf63c16 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Thu, 9 Apr 2026 15:47:31 +0200 Subject: [PATCH 5/9] Rewrite type generation --- .eslintrc.json | 2 +- package-lock.json | 819 ++++++++++++++++++++++++++++++++++++- package.json | 4 +- scripts/generate-types.js | 521 ----------------------- scripts/generate-types.mts | 413 +++++++++++++++++++ scripts/template.d.ts.txt | 281 +++++++++++++ tsconfig.json | 27 +- 7 files changed, 1521 insertions(+), 546 deletions(-) delete mode 100644 scripts/generate-types.js create mode 100644 scripts/generate-types.mts create mode 100644 scripts/template.d.ts.txt diff --git a/.eslintrc.json b/.eslintrc.json index 8893149..ec026c5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { "extends": "athom" -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 28ef2e9..fa5ad1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@athombv/jsdoc-template": "^1.6.3", + "@types/homey": "npm:homey-apps-sdk-v3-types@^0.3.12", "@types/node": "^25.0.10", "@types/sinon": "^17.0.3", "concurrently": "^5.2.0", @@ -24,6 +25,7 @@ "mocha": "^10.1.0", "serve": "^14.0.1", "sinon": "^19.0.2", + "tsx": "^4.21.0", "typescript": "^5.9.3", "watch": "^1.0.2" }, @@ -267,6 +269,448 @@ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -393,6 +837,24 @@ "dev": true, "peer": true }, + "node_modules/@types/homey": { + "name": "homey-apps-sdk-v3-types", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/homey-apps-sdk-v3-types/-/homey-apps-sdk-v3-types-0.3.12.tgz", + "integrity": "sha512-xr275VoF7FAiTi6PzElqHWpuGgSBY9hZFZsKeCTA4rluopf8sVk6zUPa+giSRSTiTrN3N3QjmHD5lUoNVwYd4g==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/node": "^14.14.20" + } + }, + "node_modules/@types/homey/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -1841,6 +2303,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -2553,11 +3057,12 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2599,6 +3104,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-tsconfig": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -4852,6 +5370,16 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -5501,6 +6029,26 @@ "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "dev": true }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -6197,6 +6745,188 @@ } } }, + "@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "dev": true, + "optional": true + }, + "@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "dev": true, + "optional": true + }, "@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -6308,6 +7038,23 @@ "dev": true, "peer": true }, + "@types/homey": { + "version": "npm:homey-apps-sdk-v3-types@0.3.12", + "resolved": "https://registry.npmjs.org/homey-apps-sdk-v3-types/-/homey-apps-sdk-v3-types-0.3.12.tgz", + "integrity": "sha512-xr275VoF7FAiTi6PzElqHWpuGgSBY9hZFZsKeCTA4rluopf8sVk6zUPa+giSRSTiTrN3N3QjmHD5lUoNVwYd4g==", + "dev": true, + "requires": { + "@types/node": "^14.14.20" + }, + "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "dev": true + } + } + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -7412,6 +8159,40 @@ "is-symbol": "^1.0.2" } }, + "esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, "escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -7964,9 +8745,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -7994,6 +8775,15 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "get-tsconfig": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -9676,6 +10466,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -10180,6 +10976,17 @@ "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "dev": true }, + "tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "requires": { + "esbuild": "~0.27.0", + "fsevents": "~2.3.3", + "get-tsconfig": "^4.7.5" + } + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", diff --git a/package.json b/package.json index 66595cf..2b346b1 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "test": "mocha --reporter list", "lint": "eslint .", - "generate-types": "node scripts/generate-types.js", + "generate-types": "tsx scripts/generate-types.mts", "serve": "concurrently \"serve build/\" \"npm run build:watch\"", "build": "jsdoc --configure ./docs/jsdoc.json", "build:clean": "rm -rf ./build", @@ -33,6 +33,7 @@ "homepage": "https://github.com/athombv/node-zigbee-clusters#readme", "devDependencies": { "@athombv/jsdoc-template": "^1.6.3", + "@types/homey": "npm:homey-apps-sdk-v3-types@^0.3.12", "@types/node": "^25.0.10", "@types/sinon": "^17.0.3", "concurrently": "^5.2.0", @@ -43,6 +44,7 @@ "mocha": "^10.1.0", "serve": "^14.0.1", "sinon": "^19.0.2", + "tsx": "^4.21.0", "typescript": "^5.9.3", "watch": "^1.0.2" }, diff --git a/scripts/generate-types.js b/scripts/generate-types.js deleted file mode 100644 index 77e6063..0000000 --- a/scripts/generate-types.js +++ /dev/null @@ -1,521 +0,0 @@ -'use strict'; - -/* eslint-disable no-console, global-require */ - -/** - * Type generation script for zigbee-clusters - * Loads cluster modules directly and generates TypeScript interfaces - */ - -const fs = require('fs'); -const path = require('path'); -const { ZCLDataTypes } = require('../lib/zclTypes'); - -const OUTPUT_FILE = path.join(__dirname, '../index.d.ts'); - -/** - * Convert a ZCLDataType object to TypeScript type string - * @param {object} dataType - ZCLDataType object with shortName and args - * @returns {string} TypeScript type string - */ -function zclTypeToTS(dataType, useEnum8StatusType = true) { - if (!dataType || !dataType.shortName) return 'unknown'; - - const { shortName, args } = dataType; - - // No data - if (shortName === 'noData') return 'null'; - - // Boolean - if (shortName === 'bool') return 'boolean'; - - // Numeric types - if (/^u?int\d+$/.test(shortName)) return 'number'; - // data8-32 use readUIntBE, return number - if (/^data(8|16|24|32)$/.test(shortName)) return 'number'; - // data40-64 use buf.slice, return Buffer - if (/^data(40|48|56|64)$/.test(shortName)) return 'Buffer'; - // Float types - if (shortName === 'single' || shortName === 'double') return 'number'; - - // String types - if (shortName === 'string' || shortName === '_FixedString') return 'string'; - // EUI addresses return colon-separated hex strings - if (shortName === 'EUI64' || shortName === 'EUI48') return 'string'; - // key128 returns colon-separated hex string - if (shortName === 'key128') return 'string'; - - // Buffer types - if (shortName === 'octstr' || shortName === '_buffer' || shortName === '_buffer8' || shortName === '_buffer16') { - return 'Buffer'; - } - - if (dataType === ZCLDataTypes.enum8Status && useEnum8StatusType) { - return 'ZCLEnum8Status'; - } - - // Enum types - extract keys from args[0] - if (/^enum(4|8|16|32)$/.test(shortName)) { - if (args && args[0] && typeof args[0] === 'object') { - const keys = Object.keys(args[0]); - if (keys.length > 0) { - return keys.map(k => `'${k}'`).join(' | '); - } - } - return 'number'; - } - - // Map/bitmap types - extract flag names from args - if (/^map(4|\d+)$/.test(shortName)) { - if (args && args.length > 0) { - const flags = args.filter(a => typeof a === 'string'); - if (flags.length > 0) { - return `Partial<{ ${flags.map(f => `${f}: boolean`).join('; ')} }>`; - } - } - return 'Partial>'; - } - - // Array types (note: shortName has underscore prefix: _Array0, _Array8) - // Recursively determine element type from args[0] - if (/^_?Array(0|8|16)$/.test(shortName)) { - if (args && args[0]) { - const elementType = zclTypeToTS(args[0]); - return `${elementType}[]`; - } - return 'unknown[]'; - } - - return 'unknown'; -} - -/** - * Parse a cluster and extract its type information - * @param {Function} ClusterClass - Cluster class with static ATTRIBUTES/COMMANDS - * @returns {object} Cluster definition - */ -function parseCluster(ClusterClass, exportName) { - const clusterName = ClusterClass.NAME; - const clusterId = ClusterClass.ID; - const attributes = []; - const commands = []; - - // Parse attributes - const attrs = ClusterClass.ATTRIBUTES || {}; - for (const [name, def] of Object.entries(attrs)) { - if (def && def.type) { - attributes.push({ - name, - tsType: zclTypeToTS(def.type), - }); - } - } - - // Parse commands - const cmds = ClusterClass.COMMANDS || {}; - for (const [name, def] of Object.entries(cmds)) { - const cmdArgs = []; - const responseArgs = []; - const cmdArgsOptional = def && def.encodeMissingFieldsBehavior === 'skip'; - const responseArgsOptional = def && def.response && def.response.encodeMissingFieldsBehavior === 'skip'; - if (def && def.args) { - for (const [argName, argType] of Object.entries(def.args)) { - cmdArgs.push({ - name: argName, - tsType: zclTypeToTS(argType), - }); - } - } - // Parse response type if present - if (def && def.response && def.response.args) { - for (const [argName, argType] of Object.entries(def.response.args)) { - responseArgs.push({ - name: argName, - tsType: zclTypeToTS(argType), - }); - } - } - commands.push({ - name, args: cmdArgs, responseArgs, cmdArgsOptional, responseArgsOptional, - }); - } - - return { - exportName, - clusterName, - clusterId, - attributes, - commands, - }; -} - -/** - * Convert cluster name to PascalCase interface name - * @param {string} clusterName - * @returns {string} - */ -function toInterfaceName(cluster) { - if (cluster.exportName) return cluster.exportName; - const name = cluster.clusterName.charAt(0).toUpperCase() + cluster.clusterName.slice(1); - return `${name}Cluster`; -} - -/** - * Generate TypeScript interface for a cluster - * @param {object} cluster - Parsed cluster definition - * @returns {string} TypeScript interface code - */ -function generateClusterInterface(cluster) { - const interfaceName = toInterfaceName(cluster); - const lines = []; - - // Generate attributes interface - if (cluster.attributes.length > 0) { - lines.push(`export interface ${interfaceName}Attributes extends GlobalClusterAttributes {`); - for (const attr of cluster.attributes) { - lines.push(` ${attr.name}?: ${attr.tsType};`); - } - lines.push('}'); - lines.push(''); - } - - // Generate cluster interface - lines.push(`export interface ${interfaceName} extends ZCLNodeCluster {`); - - // Add typed readAttributes if we have attributes - if (cluster.attributes.length > 0) { - lines.push(` readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>;`); - lines.push(` readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>;`); - lines.push(` writeAttributes(attributes: Partial<${interfaceName}Attributes>, opts?: { timeout?: number }): Promise;`); - lines.push(` on(eventName: \`attr.\${K}\`, listener: (value: ${interfaceName}Attributes[K]) => void): this;`); - lines.push(` once(eventName: \`attr.\${K}\`, listener: (value: ${interfaceName}Attributes[K]) => void): this;`); - } - - // Add command methods - for (const cmd of cluster.commands) { - // Determine return type based on response args - let returnType = 'void'; - if (cmd.responseArgs && cmd.responseArgs.length > 0) { - const sep = cmd.responseArgsOptional ? '?: ' : ': '; - returnType = `{ ${cmd.responseArgs.map(a => `${a.name}${sep}${a.tsType}`).join('; ')} }`; - } - - if (cmd.args.length > 0) { - // Args are optional when encodeMissingFieldsBehavior is 'skip', or when all args are Buffers - const allArgsOptional = cmd.cmdArgsOptional || cmd.args.every(a => a.tsType === 'Buffer'); - const argsType = `{ ${cmd.args.map(a => `${a.name}${(cmd.cmdArgsOptional || a.tsType === 'Buffer') ? '?' : ''}: ${a.tsType}`).join('; ')} }`; - // If all args are optional, make the entire args object optional - lines.push(` ${cmd.name}(args${allArgsOptional ? '?' : ''}: ${argsType}, opts?: ClusterCommandOptions): Promise<${returnType}>;`); - } else { - lines.push(` ${cmd.name}(opts?: ClusterCommandOptions): Promise<${returnType}>;`); - } - } - - lines.push('}'); - - return lines.join('\n'); -} - -/** - * Generate the full index.d.ts file - * @param {object[]} clusters - Array of parsed cluster definitions - * @param {Array<{ - * constantName: string; - * clusterId: number; - * clusterName: string; - * }>} clusterDefinitions - Array of CLUSTER definitions used to generate typed CLUSTER exports - * @returns {string} Complete TypeScript definitions file - */ -function generateConstantObject(obj, indent = 2) { - const lines = []; - const pad = ' '.repeat(indent); - for (const [key, value] of Object.entries(obj)) { - if (typeof value === 'object' && value !== null) { - lines.push(`${pad}${key}: {`); - lines.push(generateConstantObject(value, indent + 2)); - lines.push(`${pad}};`); - } else { - lines.push(`${pad}${key}: ${typeof value === 'number' ? value : JSON.stringify(value)};`); - } - } - return lines.join('\n'); -} - -function generateTypesFile(clusters, clusterDefinitions, constants) { - const lines = []; - - // Header - lines.push('// Auto-generated TypeScript definitions for zigbee-clusters'); - lines.push('// Generated by scripts/generate-types.js'); - lines.push(''); - lines.push('import * as EventEmitter from "events";'); - lines.push(''); - - // Base types - lines.push(`type EndpointDescriptor = { - endpointId: number; - inputClusters: number[]; - outputClusters: number[]; -}; - -type ConstructorOptions = { - endpointDescriptors: EndpointDescriptor[]; - sendFrame: (endpointId: number, clusterId: number, frame: Buffer) => Promise; -}; - -type ClusterCommandOptions = { - timeout?: number; - waitForResponse?: boolean; - disableDefaultResponse?: boolean; -}; - -type ZCLNodeConstructorInput = { - endpointDescriptors?: EndpointDescriptor[]; - sendFrame: (endpointId: number, clusterId: number, frame: Buffer) => Promise; - handleFrame?: ( - endpointId: number, - clusterId: number, - frame: Buffer, - meta?: unknown - ) => Promise; -}; - -export type ZCLEnum8Status = ${zclTypeToTS(ZCLDataTypes.enum8Status, false)}; - -export type GlobalClusterAttributes = { - clusterRevision: number; - attributeReportingStatus: 0 | 1; -}; -`); - - // Base ZCLNodeCluster interface - lines.push(`export interface ZCLNodeCluster extends EventEmitter { - /** Dynamic command handler methods (e.g. \`onZoneStatusChangeNotification\`). */ - [key: \`on\${string}\`]: unknown; - - discoverCommandsGenerated(params?: { - startValue?: number; - maxResults?: number; - }, opts?: { timeout?: number }): Promise<(string | number)[]>; - - discoverCommandsReceived(params?: { - startValue?: number; - maxResults?: number; - }, opts?: { timeout?: number }): Promise<(string | number)[]>; - - readAttributes( - attributes: Array, - opts?: { timeout?: number } - ): Promise<{ [x: string]: unknown }>; - - writeAttributes(attributes?: object, opts?: { timeout?: number }): Promise; - - configureReporting(attributes?: object, opts?: { timeout?: number }): Promise; - - readReportingConfiguration(attributes?: (string | number)[], opts?: { timeout?: number }): Promise<{ - status: string; - direction: 'reported' | 'received'; - attributeId: number; - attributeDataType?: number; - minInterval?: number; - maxInterval?: number; - minChange?: number; - timeoutPeriod?: number; - }[]>; - - discoverAttributes(opts?: { timeout?: number }): Promise<(string | number)[]>; - - discoverAttributesExtended(opts?: { timeout?: number }): Promise<{ - name?: string; - id: number; - dataTypeId: number; - acl: { readable: boolean; writable: boolean; reportable: boolean }; - }[]>; -} -`); - - // Generate individual cluster interfaces - for (const cluster of clusters) { - lines.push(generateClusterInterface(cluster)); - lines.push(''); - } - - // Generate cluster registry type - lines.push('/** Type-safe cluster registry */'); - lines.push('export interface ClusterRegistry {'); - for (const cluster of clusters) { - const interfaceName = toInterfaceName(cluster); - lines.push(` ${cluster.clusterName}?: ${interfaceName};`); - } - lines.push('}'); - lines.push(''); - - // Generate cluster type lookup maps for inference helpers - lines.push('/** Cluster type lookup by cluster NAME */'); - lines.push('export interface ClusterTypeByName {'); - for (const cluster of clusters) { - const interfaceName = toInterfaceName(cluster); - lines.push(` ${cluster.clusterName}: ${interfaceName};`); - } - lines.push('}'); - lines.push(''); - - // Generate cluster attribute lookup maps for inference helpers - lines.push('/** Cluster attributes lookup by cluster NAME */'); - lines.push('export interface ClusterAttributesByName {'); - for (const cluster of clusters) { - const interfaceName = toInterfaceName(cluster); - const attributesInterfaceName = `${interfaceName}Attributes`; - const attributesType = cluster.attributes.length > 0 ? attributesInterfaceName : 'Record'; - lines.push(` ${cluster.clusterName}: ${attributesType};`); - } - lines.push('}'); - lines.push(''); - - lines.push('/** Infer a typed cluster interface from a CLUSTER definition object. */'); - lines.push('export type ClusterTypeFromDefinition ='); - lines.push(" TDef['NAME'] extends keyof ClusterTypeByName"); - lines.push(" ? ClusterTypeByName[TDef['NAME']]"); - lines.push(' : ZCLNodeCluster;'); - lines.push(''); - - lines.push('/** Infer typed cluster attribute map from a CLUSTER definition object. */'); - lines.push('export type ClusterAttributesFromDefinition ='); - lines.push(" TDef['NAME'] extends keyof ClusterAttributesByName"); - lines.push(" ? ClusterAttributesByName[TDef['NAME']]"); - lines.push(' : Record;'); - lines.push(''); - - // Generate endpoint type - lines.push(`export type ZCLNodeEndpoint = { - clusters: ClusterRegistry & { - [clusterName: string]: ZCLNodeCluster | undefined; - }; - bind(clusterName: string, impl: BoundCluster): void; -}; - -export interface ZCLNode { - endpoints: { [endpointId: number | string]: ZCLNodeEndpoint }; - handleFrame: ( - endpointId: number, - clusterId: number, - frame: Buffer, - meta?: unknown - ) => Promise; -} -`); - - // Runtime value exports - lines.push(`export const ZCLNode: { - new (node: ZCLNodeConstructorInput): ZCLNode; -}; - -export const CLUSTER: { -`); - for (const def of clusterDefinitions) { - lines.push(` ${def.constantName}: {`); - lines.push(' ID: number;'); - lines.push(` NAME: '${def.clusterName}';`); - lines.push(' ATTRIBUTES: unknown;'); - lines.push(' COMMANDS: unknown;'); - lines.push(' };'); - } - lines.push('};'); - - lines.push(`export class BoundCluster { - -} - -export class ZCLError extends Error { - zclStatus: ZCLEnum8Status; - constructor(zclStatus?: ZCLEnum8Status); -}`); - - // Export all cluster classes - for (const cluster of clusters) { - const interfaceName = toInterfaceName(cluster); - const exportName = cluster.exportName || interfaceName; - lines.push(`export const ${exportName}: {`); - lines.push(` new (...args: any[]): ${interfaceName};`); - lines.push(` ID: ${cluster.clusterId};`); - lines.push(` NAME: '${cluster.clusterName}';`); - lines.push(' ATTRIBUTES: unknown;'); - lines.push(' COMMANDS: unknown;'); - lines.push('};'); - } - - // Export constants - if (constants) { - for (const [name, value] of Object.entries(constants)) { - lines.push(''); - lines.push(`export const ${name}: {`); - lines.push(generateConstantObject(value)); - lines.push('};'); - } - } - - lines.push(''); - lines.push('declare const _default: {'); - lines.push(' ZCLNode: typeof ZCLNode;'); - lines.push(' CLUSTER: typeof CLUSTER;'); - for (const cluster of clusters) { - const exportName = cluster.exportName || toInterfaceName(cluster); - lines.push(` ${exportName}: typeof ${exportName};`); - } - if (constants) { - for (const name of Object.keys(constants)) { - lines.push(` ${name}: typeof ${name};`); - } - } - lines.push('};'); - lines.push('export default _default;'); - - return lines.join('\n'); -} - -/** - * Main entry point - */ -function main() { - console.log('Loading cluster modules...'); - - // Load all clusters via the index - const clustersModule = require('../lib/clusters'); - const clusters = []; - - // Get all exported cluster classes (end with 'Cluster') - for (const [name, value] of Object.entries(clustersModule)) { - if (name.endsWith('Cluster') && typeof value === 'function' && value.NAME) { - try { - const cluster = parseCluster(value, name); - clusters.push(cluster); - console.log(` ✓ ${cluster.clusterName} (${cluster.attributes.length} attrs, ${cluster.commands.length} cmds)`); - } catch (err) { - console.warn(` ✗ Failed to parse ${name}: ${err.message}`); - } - } - } - - // Sort clusters alphabetically - clusters.sort((a, b) => a.clusterName.localeCompare(b.clusterName)); - - const clusterDefinitions = Object.entries(clustersModule.CLUSTER) - .map(([constantName, value]) => ({ - constantName, - clusterId: value.ID, - clusterName: value.NAME, - })) - .sort((a, b) => a.constantName.localeCompare(b.constantName)); - - // Load constants - const { ZIGBEE_PROFILE_ID, ZIGBEE_DEVICE_ID, IAS_ZONE_TYPE } = require('../lib/constants'); - const constants = { ZIGBEE_PROFILE_ID, ZIGBEE_DEVICE_ID, IAS_ZONE_TYPE }; - - console.log(`\nGenerating ${OUTPUT_FILE}...`); - const output = generateTypesFile(clusters, clusterDefinitions, constants); - fs.writeFileSync(OUTPUT_FILE, output); - - console.log(`Done! Generated types for ${clusters.length} clusters.`); -} - -main(); diff --git a/scripts/generate-types.mts b/scripts/generate-types.mts new file mode 100644 index 0000000..8faca6f --- /dev/null +++ b/scripts/generate-types.mts @@ -0,0 +1,413 @@ +import {Cluster} from "zigbee-clusters"; +import path from "node:path"; +import * as fs from "node:fs/promises"; +import {DataType, DataTypes} from "@athombv/data-types"; + +const INDENTATION_SPACES = 2; + +class StringBuilder { + private strings: string[]; + private indentation: number; + + constructor() { + this.strings = []; + this.indentation = 0; + } + + public startLine(): void { + this.strings.push(" ".repeat(this.indentation)); + } + public print(...line: string[]): void { + this.strings.push(...line); + } + public endLine(): void { + this.strings.push("\n"); + } + + public printLine(...line: string[]): void { + this.startLine(); + this.strings.push(...line); + this.endLine(); + } + + + public increaseIndent(levels = 1): void { + this.indentation += INDENTATION_SPACES * levels; + } + public setIndent(level: number): void { + this.indentation = INDENTATION_SPACES * level; + } + public decreaseIndent(levels = 1): void { + this.indentation -= INDENTATION_SPACES * levels; + if (this.indentation < 0) { + this.indentation = 0; + } + } + + public toString(): string { + return this.strings.join(""); + } +} + +const filePath = path.resolve('index.d.ts'); +const templatePath = path.resolve('scripts/template.d.ts.txt'); +await main(); + +async function main(): Promise { + console.log('Writing clusters to', filePath); + + // Write preamble and open module declaration + await fs.writeFile(filePath, '/* eslint-disable @typescript-eslint/no-explicit-any */\ndeclare module "zigbee-clusters" {\n import {BitMap} from "@athombv/data-types";\n'); + + // @ts-expect-error No type declarations + const clustersModule = await import("../lib/clusters/index.js"); + for (const [name, value] of Object.entries(clustersModule.default)) { + if (name !== 'Cluster' && name !== 'CLUSTER') { + await formatCluster(name, value as typeof Cluster); + } + } + + const stringBuilder = new StringBuilder(); + stringBuilder.setIndent(1); + + // Open CLUSTER + stringBuilder.printLine("const CLUSTER: {"); + stringBuilder.increaseIndent(); + + for (const [key, value] of Object.entries(clustersModule.default.CLUSTER)) { + const definition = value as {ID: number, NAME: string}; + const clusterClass = clustersModule.default.Cluster.clusters[definition.ID]; + let clusterName = clusterClass.name; + // Class names are inconsistent + if (clusterName === 'TouchlinkCluster') { + clusterName = 'TouchLinkCluster'; + } + if (!clusterName.endsWith("Cluster")) { + clusterName = `${clusterName}Cluster`; + } + stringBuilder.printLine(`${key}: {`); + stringBuilder.increaseIndent(); + stringBuilder.printLine(`ID: 0x${definition.ID.toString(16).padStart(4, "0")},`); + stringBuilder.printLine(`NAME: ${JSON.stringify(definition.NAME)},`); + stringBuilder.printLine(`ATTRIBUTES: Readonly<${clusterName}Attributes>,`); + stringBuilder.printLine(`COMMANDS: Readonly<${clusterName}Commands>,`); + stringBuilder.decreaseIndent(); + stringBuilder.printLine('},'); + } + + // Close CLUSTER + stringBuilder.decreaseIndent(); + stringBuilder.printLine("};"); + + await fs.appendFile(filePath, stringBuilder.toString()); + + const template = await fs.readFile(templatePath, 'utf8'); + const templateHeader = "declare module 'zigbee-clusters' {"; + const templateBody = template.slice(template.indexOf(templateHeader) + templateHeader.length); + // Close module declaration + await fs.appendFile(filePath, templateBody); + + console.log("Done!"); + // await stall(); +} + + +async function formatCluster(className: string, classDefinition: typeof Cluster): Promise { + const stringBuilder = new StringBuilder(); + stringBuilder.setIndent(1); + + + stringBuilder.startLine(); + stringBuilder.print(`type ${className}Attributes = `); + if (Object.keys(classDefinition.ATTRIBUTES).length === 0) { + stringBuilder.print("Record;"); + stringBuilder.endLine(); + } else { + // Open attributes + stringBuilder.print("{"); + stringBuilder.endLine(); + stringBuilder.increaseIndent(); + for (const attribute in classDefinition.ATTRIBUTES) { + const attributeDefinition = classDefinition.ATTRIBUTES[attribute]; + formatAttribute(stringBuilder, className, attribute, attributeDefinition); + } + // Close attributes + stringBuilder.decreaseIndent(); + stringBuilder.printLine('};'); + } + + stringBuilder.startLine(); + stringBuilder.print(`type ${className}Commands = `); + if (Object.keys(classDefinition.COMMANDS).length === 0) { + stringBuilder.print("Record;"); + stringBuilder.endLine(); + } else { + // Open commands + stringBuilder.print("{"); + stringBuilder.endLine(); + stringBuilder.increaseIndent(); + for (const command in classDefinition.COMMANDS) { + const commandDefinition = classDefinition.COMMANDS[command]; + formatCommand(stringBuilder, className, command, commandDefinition); + } + // Close commands + stringBuilder.decreaseIndent(); + stringBuilder.printLine('};'); + } + + // Open class + stringBuilder.printLine(`class ${className} extends Cluster {`); + + stringBuilder.increaseIndent(); + for (const command in classDefinition.COMMANDS) { + const commandDefinition = classDefinition.COMMANDS[command]; + formatCommandMethod(stringBuilder, className, command, commandDefinition); + } + + // Close class + stringBuilder.decreaseIndent(); + stringBuilder.printLine('}'); + + await fs.appendFile(filePath, stringBuilder.toString()); +} + + +function formatAttribute(stringBuilder: StringBuilder, className: string, name: string, definition: AttributeDefinition): void { + stringBuilder.startLine(); + stringBuilder.print(`${name}: { id: 0x${definition.id.toString(16).padStart(2, "0")}`); + stringBuilder.print(', type: ZCLDataType<'); + formatZCLDataTypeGeneric(stringBuilder, className, name, definition.type); + stringBuilder.print("> },"); + stringBuilder.endLine(); +} + + +function formatCommand(stringBuilder: StringBuilder, className: string, name: string, definition: CommandDefinition): void { + stringBuilder.startLine(); + stringBuilder.print(`${name}: { id: 0x${definition.id.toString(16).padStart(2, "0")}`); + stringBuilder.print(`, direction: ${JSON.stringify(definition.direction ?? "DIRECTION_SERVER_TO_CLIENT")}`); + + if (definition.frameControl !== undefined) { + stringBuilder.print(`, frameControl: ${JSON.stringify(definition.frameControl)}`); + } + if (definition.encodeMissingFieldsBehavior !== undefined) { + stringBuilder.print(`, encodeMissingFieldsBehavior: ${JSON.stringify(definition.encodeMissingFieldsBehavior)}`); + } + if (definition.global !== undefined) { + stringBuilder.print(`, global: ${definition.global}`); + } + + if (definition.args !== undefined) { + stringBuilder.print(", args: "); + if (Object.keys(definition.args).length === 0) { + stringBuilder.print("Record /* TODO fix */ "); + } else { + // Open args + stringBuilder.print("{"); + stringBuilder.endLine(); + stringBuilder.increaseIndent(2); + for (const [key, arg] of Object.entries(definition.args)) { + stringBuilder.startLine(); + stringBuilder.print(`${key}: ZCLDataType<`); + formatZCLDataTypeGeneric(stringBuilder, className, name, arg); + stringBuilder.print(">,"); + stringBuilder.endLine(); + } + // Close args + stringBuilder.decreaseIndent(); + stringBuilder.printLine('},'); + // Spaces before closing bracket of attribute + stringBuilder.decreaseIndent(); + stringBuilder.startLine(); + } + } else { + // Space before closing bracket of attribute + stringBuilder.print(" "); + } + + // TODO response - use reference based on id if possible + + stringBuilder.print('},'); + stringBuilder.endLine(); +} + + +function formatCommandMethod(stringBuilder: StringBuilder, className: string, name: string, definition: CommandDefinition): void { + // Method name + stringBuilder.startLine(); + if (definition.direction === 'DIRECTION_SERVER_TO_CLIENT') { + // Bound cluster + stringBuilder.print("on", name.charAt(0).toUpperCase(), name.slice(1)); + } else { + stringBuilder.print(name); + } + + // Open method + stringBuilder.print("("); + stringBuilder.endLine(); + + // Open args + stringBuilder.increaseIndent(); + stringBuilder.printLine("args: {"); + stringBuilder.increaseIndent(); + stringBuilder.printLine("manufacturerId?: number,"); + + for (const arg in definition.args) { + stringBuilder.startLine(); + stringBuilder.print(`${arg}: `); + formatZCLDataTypeGeneric(stringBuilder, className, name, definition.args[arg]); + stringBuilder.print(","); + stringBuilder.endLine(); + } + + // Close args + stringBuilder.decreaseIndent(); + stringBuilder.printLine("},"); + + + // Opts + stringBuilder.printLine("opts?: {"); + stringBuilder.increaseIndent(); + stringBuilder.printLine("waitForResponse?: boolean,"); + stringBuilder.printLine("timeout?: number,"); + stringBuilder.printLine("disableDefaultResponse?: boolean,"); + stringBuilder.decreaseIndent(); + stringBuilder.printLine("},"); + + // Close method + stringBuilder.decreaseIndent(); + stringBuilder.printLine("): Promise;"); +} + + +/** + * @returns whether indentation was increased + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function formatZCLDataTypeGeneric(stringBuilder: StringBuilder, className: string, command: string, definition: DataType): void { + const typeName = definition.shortName as keyof typeof DataTypes; + const typeArgs: Array = definition.args; + + if (typeName.startsWith('enum')) { + formatEnumDataType(stringBuilder, className, command, typeName, typeArgs); + } else if (typeName.startsWith('map')) { + formatMapDataType(stringBuilder, className, command, typeName, typeArgs); + } else if (typeName.startsWith("_Array")) { + stringBuilder.print("Array"); + } else { + stringBuilder.print(zclDataTypeToValueType(typeName)); + } +} + + +function formatEnumDataType(stringBuilder: StringBuilder, className: string, field: string, typeName: string, typeArgs: Array): void { + const typeArg = typeArgs[0]; + if (typeof typeArg !== 'object' || Array.isArray(typeArg) || typeArg === null) { + throw new Error(`Invalid ${typeName} arg for ${className} ${field}`); + } + + const entries = Object.keys(typeArg); + if (entries.length === 0) { + stringBuilder.print('unknown'); + } else { + stringBuilder.print(entries.map(arg => JSON.stringify(arg)).join(" | ")); + } +} + + +function formatMapDataType(stringBuilder: StringBuilder, className: string, field: string, typeName: string, typeArgs: Array): void { + if (typeof typeArgs !== 'object' || !Array.isArray(typeArgs)) { + throw new Error(`Invalid ${typeName} arg for ${className} ${field}`); + } + for (const typeArg of typeArgs) { + if (!(typeArg === null || typeof typeArg === 'string')) { + throw new Error(`Invalid ${typeName} arg for ${className} ${field}`); + } + } + if (typeArgs.length === 0) { + stringBuilder.print('BitMap'); + } else { + stringBuilder.print('BitMap<'); + stringBuilder.print(typeArgs.map(arg => JSON.stringify(arg)).join(" | ")); + stringBuilder.print(">"); + } +} + + +function zclDataTypeToValueType(type: keyof typeof DataTypes): string { + switch (type) { + case "noData": + return "null"; + case "data8": + case "data16": + case "data24": + case "data32": + case "data40": + case "data48": + case "data56": + return "number"; + case "bool": + return "boolean"; + case "map8": + case "map16": + case "map24": + case "map32": + case "map40": + case "map48": + case "map56": + case "map64": + throw new Error("Complex type"); + case "uint8": + case "uint16": + case "uint24": + case "uint32": + case "uint40": + case "uint48": + case "int8": + case "int16": + case "int24": + case "int32": + case "int40": + case "int48": + return "number"; + case "enum8": + case "enum16": + case "enum32": + throw new Error("Complex type"); + case "single": + case "double": + return "number"; + case "octstr": + case "string": + case "EUI48": + case "EUI64": + case "key128": + return "string"; + } + // Internal types + switch (type as string) { + case "_map4": + throw new Error("Complex type"); + case "_uint4": + return "number"; + case "_enum4": + throw new Error("Complex type"); + case "_buffer": + case "_buffer8": + case "_buffer16": + return "Buffer"; + case "_Array0": + case "_Array8": + throw new Error("Complex type"); + case "_FixedString": + return "string"; + } + throw new Error(`Unknown ZCL type ${type}`); +} + + +async function stall(): Promise { + await new Promise(resolve => { + setTimeout(resolve, 1_000_000_000); + }); +} diff --git a/scripts/template.d.ts.txt b/scripts/template.d.ts.txt new file mode 100644 index 0000000..7cc9604 --- /dev/null +++ b/scripts/template.d.ts.txt @@ -0,0 +1,281 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +declare module 'zigbee-clusters' { + import {EventEmitter} from "events"; + import {ZigBeeNode} from "homey"; + type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; + type ZCLDataTypes = typeof import('@athombv/data-types').DataTypes & { + enum8Status: ZCLDataType + }; + + function debug(flag: boolean, namespaces: string): void; + + class ZCLNode extends EventEmitter { + constructor(node: ZigBeeNode); + endpoints: Record; + + getLogId(endpointId: number, clusterId: number): string; + } + + class ZCLNodeEndpoint extends EventEmitter { + constructor(node: ZCLNode, descriptor: { + endpointId: number; + inputClusters: number[]; + outputClusters: number[]; + }[]); + clusters: Record>; + bindings: Record; + + bind(clusterName: string, clusterImpl: BoundCluster): void; + unbind(clusterName: string): void; + + makeDefaultResponseFrame(receivedFrame: unknown, success: boolean, status: ZCLEnum8Status): typeof zclFrames.ZCLStandardHeader | typeof zclFrames.ZCLMfgSpecificHeader; + } + + type ZCLDataType = import('@athombv/data-types').DataType; + const ZCLDataTypes: ZCLDataTypes; + const ZCLStruct: typeof import('@athombv/data-types').Struct; + + namespace zclTypes { + type ZCLDataType = import('@athombv/data-types').DataType; + const ZCLDataTypes: ZCLDataTypes; + const ZCLStruct: typeof import('@athombv/data-types').Struct; + } + + type FrameControlFlag = + 'clusterSpecific' + | 'manufacturerSpecific' + | 'directionToClient' + | 'disableDefaultResponse'; + type ZCLFrameControlBitmap = ZCLDataType>; + + namespace zclFrames { + const ZCLStandardHeader: import('@athombv/data-types').StructInstance<{ + frameControl: ZCLFrameControlBitmap, + trxSequenceNumber: ZCLDataTypes["data8"], + cmdId: ZCLDataTypes["data8"], + data: ZCLDataTypes["buffer"], + }>; + const ZCLMfgSpecificHeader: import('@athombv/data-types').StructInstance<{ + frameControl: ZCLFrameControlBitmap, + manufacturerId: ZCLDataTypes["uint16"], + trxSequenceNumber: ZCLDataTypes["data8"], + cmdId: ZCLDataTypes["data8"], + data: ZCLDataTypes["buffer"], + }>; + function ZCLAttributeDataRecord(withStatus: boolean, attributes: AttributeDefinitions): ZCLDataType<{ + id: number, + name: string, + status?: ZCLEnum8Status + value: ZCLDataType + }>; + function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType<{ + attributeId: number, + status?: ZCLEnum8Status, + direction: 'reported' | 'received', + attributeDataType: number, + minInterval: number, + maxInterval: number, + minChange: number, // TODO Check whether this is actually a number, or a buffer like the JS docs imply + }> + } + + class ZCLError extends Error { + zclStatus: ZCLEnum8Status; + } + + const ZIGBEE_PROFILE_ID: { + INDUSTRIAL_PLANT_MONITORING: 0x0101, + HOME_AUTOMATION: 0x0104, + COMMERCIAL_BUILDING_AUTOMATION: 0x0105, + TELECOM_APPLICATIONS: 0x0107, + PERSONAL_HOME_AND_HOSPITAL_CARE: 0x0108, + ADVANCED_METERING_INITIATIVE: 0x0109, + }; + const ZIGBEE_DEVICE_ID: { + GENERIC: { + ON_OFF_SWITCH: 0x0000, + LEVEL_CONTROL_SWITCH: 0x0001, + ON_OFF_OUTPUT: 0x0002, + LEVEL_CONTROLLABLE_OUTPUT: 0x0003, + SCENE_SELECTOR: 0x0004, + CONFIGURATION_TOOL: 0x0005, + REMOTE_CONTROL: 0x0006, + COMBINED_INTERFACE: 0x0007, + RANGE_EXTENDER: 0x0008, + MAINS_POWER_OUTLET: 0x0009, + DOOR_LOCK: 0x000a, + DOOR_LOCK_CONTROLLER: 0x000b, + SIMPLE_SENSOR: 0x000c, + CONSUMPTION_AWARENESS_DEVICE: 0x000d, + HOME_GATEWAY: 0x0050, + SMART_PLUG: 0x0051, + WHITE_GOODS: 0x0052, + METER_INTERFACE: 0x0053, + }, + LIGHTING: { + ON_OFF_LIGHT: 0x0100, + DIMMABLE_LIGHT: 0x0101, + COLOR_DIMMABLE_LIGHT: 0x0102, + ON_OFF_LIGHT_SWITCH: 0x0103, + DIMMER_SWITCH: 0x0104, + COLOR_DIMMER_SWITCH: 0x0105, + LIGHT_SENSOR: 0x0106, + OCCUPANCY_SENSOR: 0x0107, + }, + CLOSURES: { + SHADE: 0x0200, + SHADE_CONTROLLER: 0x0201, + WINDOW_COVERING_DEVICE: 0x0202, + WINDOW_COVERING_CONTROLLER: 0x0203, + }, + HVAC: { + HEATING_COOLING_UNIT: 0x0300, + THERMOSTAT: 0x0301, + TEMPERATURE_SENSOR: 0x0302, + PUMP: 0x0303, + PUMP_CONTROLLER: 0x0304, + PRESSURE_SENSOR: 0x0305, + FLOW_SENSOR: 0x0306, + }, + INTRUDER_ALARM_SYSTEMS: { + IAS_CONTROL_INDICATING_EQUIPMENT: 0x0400, + IAS_ANCILLARY_CONTROL_EQUIPMENT: 0x0401, + IAS_ZONE: 0x0402, + IAS_WARNING_DEVICE: 0x0403, + }, + }; + const IAS_ZONE_TYPE: { + STANDARD_CIE: 0x0000, + MOTION_SENSOR: 0x000d, + CONTACT_SWITCH: 0x0015, + FIRE_SENSOR: 0x0028, + WATER_SENSOR: 0x002a, + CARBON_MONOXIDE_SENSOR: 0x002b, + PERSONAL_EMERGENCY_DEVICE: 0x002c, + VIBRATION_MOVEMENT_SENSOR: 0x002d, + REMOTE_CONTROL: 0x010f, + KEY_FOB: 0x0115, + KEYPAD: 0x021d, + STANDARD_WARNING_DEVICE: 0x0225, + GLASS_BREAK_SENSOR: 0x0226, + SECURITY_REPEATER: 0x0229, + INVALID_ZONE_TYPE: 0xffff, + }; + + abstract class Cluster extends EventEmitter { + static get ID(): number; + static get NAME(): string; + // @ts-expect-error Type should be defined on non-abstract inheritors + static get ATTRIBUTES(): Attributes; + // @ts-expect-error Type should be defined on non-abstract inheritors + static get COMMANDS(): Commands; + + static DIRECTION_SERVER_TO_CLIENT: CommandToClientDirection; + static DIRECTION_CLIENT_TO_SERVER: CommandToServerDirection; + + get logId(): string; + + discoverCommandsGenerated({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; + discoverCommandsReceived({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; + + readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; + writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> + + configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; + readReportingConfiguration(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise>; + + discoverAttributes(opts?: {timeout?: number}): Promise>; + discoverAttributesExtended(opts?: {timeout?: number}): Promise>; + + sendFrame(data: object): Promise; + nextSeqNr(): number; + + static addCluster(clusterClass: typeof Cluster): void; + static removeCluster(clusterIdOrName: string | number): void; + static getCluster(clusterIdOrName: string | number): Cluster; + + on>(eventName: `attr.${Event}`, listener: (value: AttributesFromDefinition[Event]) => void): this; + on = unknown[]>(eventName: string, listener: (...args: Values) => void): this; + + attributes: Attributes; + attributesById: {[Attribute in keyof Attributes as Attributes[Attribute]['id']]: { name: Attribute } & Attributes[Attribute] }; + + commands: Commands; + commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; + } + + // TODO + abstract class BoundCluster { + endpoint: number; + cluster: Cluster; + + get logId(): string; + } +} + +// TODO clean up so these are not global + +type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; +type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; +type CommandDirection = CommandToServerDirection | CommandToClientDirection; + +type FromZCLDataType = DataType extends import('zigbee-clusters').ZCLDataType? InferredValue : DataType; + +type AttributeDefinition = { + id: number, + type: import('zigbee-clusters').ZCLDataType, + manufacturerId?: number, +} + +type AttributeDefinitions = { + [attributeName: string]: AttributeDefinition, +} + +type AttributesFromDefinition = { + [attribute in keyof Definition]: FromZCLDataType +} + +type CommandDefinition = { + id: number, + direction?: CommandDirection, + args?: { + [argName: string]: import('zigbee-clusters').ZCLDataType, + } + response?: CommandDefinition, + frameControl?: import('zigbee-clusters').FrameControlFlag[]; + encodeMissingFieldsBehavior?: 'default' | 'skip'; + global?: boolean; +} + +type CommandDefinitions = { + [commandName: string]: CommandDefinition, +} + +type AttributeReportingConfiguration = { + [attribute in AttributeKey]: { + minInterval?: number, + maxInterval?: number, + minChange?: number + } +} + +type ReadReportingConfigurationResponse = { + status: import('zigbee-clusters').ZCLEnum8Status, + direction: 'reported'|'received'; + attributeId: number; + attributeDataType?: number; + minInterval?: number; + maxInterval?: number; + minChange?: number; + timeoutPeriod?: number; +} + +type ExtendedAttributesResponse = { + name?: string; + id: number; + acl: { + readable: boolean; + writable: boolean; + reportable: boolean; + } +} diff --git a/tsconfig.json b/tsconfig.json index bb561c0..82403b4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,14 @@ { - // Change this to match your project - "include": ["lib/**/*", "index.js"], "compilerOptions": { - // Tells TypeScript to read JS files, as - // normally they are ignored as source files - "allowJs": true, - // Generate d.ts files - "declaration": true, - // This compiler run should - // only output d.ts files - "emitDeclarationOnly": true, - // Types should go into this directory. - // Removing this would place the .d.ts files - // next to the .js files - "outDir": "dist", - // go to js file when using IDE functions like - // "Go to Definition" in VSCode - "declarationMap": true + "lib": ["es2021"], + "module": "Node16", + "target": "es2021", + + "strict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "declaration": false, + "skipLibCheck": false, } } From 77399b822fbf250d637513323b77ac7a4686a1c2 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Thu, 9 Apr 2026 15:47:40 +0200 Subject: [PATCH 6/9] Generate new types --- index.d.ts | 4572 +++++++++++++++++++++---------------- scripts/template.d.ts.txt | 6 +- 2 files changed, 2634 insertions(+), 1944 deletions(-) diff --git a/index.d.ts b/index.d.ts index fb5ae9a..ab795c5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,1994 +1,2686 @@ -// Auto-generated TypeScript definitions for zigbee-clusters -// Generated by scripts/generate-types.js - -import * as EventEmitter from "events"; - -type EndpointDescriptor = { - endpointId: number; - inputClusters: number[]; - outputClusters: number[]; -}; - -type ConstructorOptions = { - endpointDescriptors: EndpointDescriptor[]; - sendFrame: (endpointId: number, clusterId: number, frame: Buffer) => Promise; -}; - -type ClusterCommandOptions = { - timeout?: number; - waitForResponse?: boolean; - disableDefaultResponse?: boolean; -}; - -type ZCLNodeConstructorInput = { - endpointDescriptors?: EndpointDescriptor[]; - sendFrame: (endpointId: number, clusterId: number, frame: Buffer) => Promise; - handleFrame?: ( - endpointId: number, - clusterId: number, - frame: Buffer, - meta?: unknown - ) => Promise; -}; - -export type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; - -export type GlobalClusterAttributes = { - clusterRevision: number; - attributeReportingStatus: 0 | 1; -}; - -export interface ZCLNodeCluster extends EventEmitter { - /** Dynamic command handler methods (e.g. `onZoneStatusChangeNotification`). */ - [key: `on${string}`]: unknown; - - discoverCommandsGenerated(params?: { - startValue?: number; - maxResults?: number; - }, opts?: { timeout?: number }): Promise<(string | number)[]>; - - discoverCommandsReceived(params?: { - startValue?: number; - maxResults?: number; - }, opts?: { timeout?: number }): Promise<(string | number)[]>; - - readAttributes( - attributes: Array, - opts?: { timeout?: number } - ): Promise<{ [x: string]: unknown }>; - - writeAttributes(attributes?: object, opts?: { timeout?: number }): Promise; - - configureReporting(attributes?: object, opts?: { timeout?: number }): Promise; - - readReportingConfiguration(attributes?: (string | number)[], opts?: { timeout?: number }): Promise<{ - status: string; - direction: 'reported' | 'received'; - attributeId: number; - attributeDataType?: number; - minInterval?: number; - maxInterval?: number; - minChange?: number; - timeoutPeriod?: number; - }[]>; - - discoverAttributes(opts?: { timeout?: number }): Promise<(string | number)[]>; - - discoverAttributesExtended(opts?: { timeout?: number }): Promise<{ - name?: string; - id: number; - dataTypeId: number; - acl: { readable: boolean; writable: boolean; reportable: boolean }; - }[]>; -} - -export interface AlarmsCluster extends ZCLNodeCluster { - resetAllAlarms(opts?: ClusterCommandOptions): Promise; - getAlarm(opts?: ClusterCommandOptions): Promise; - resetAlarmLog(opts?: ClusterCommandOptions): Promise; -} - -export interface AnalogInputClusterAttributes extends GlobalClusterAttributes { - description?: string; - maxPresentValue?: number; - minPresentValue?: number; - outOfService?: boolean; - presentValue?: number; - reliability?: 'noFaultDetected' | 'noSensor' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'noOutput' | 'unreliableOther' | 'processError' | 'configurationError'; - resolution?: number; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface AnalogInputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: AnalogInputClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: AnalogInputClusterAttributes[K]) => void): this; -} - -export interface AnalogOutputClusterAttributes extends GlobalClusterAttributes { - description?: string; - maxPresentValue?: number; - minPresentValue?: number; - outOfService?: boolean; - presentValue?: number; - reliability?: 'noFaultDetected' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'unreliableOther' | 'processError' | 'configurationError'; - relinquishDefault?: number; - resolution?: number; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface AnalogOutputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: AnalogOutputClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: AnalogOutputClusterAttributes[K]) => void): this; -} - -export interface AnalogValueClusterAttributes extends GlobalClusterAttributes { - description?: string; - outOfService?: boolean; - presentValue?: number; - reliability?: 'noFaultDetected' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'unreliableOther' | 'processError' | 'configurationError'; - relinquishDefault?: number; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface AnalogValueCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: AnalogValueClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: AnalogValueClusterAttributes[K]) => void): this; -} - -export interface BallastConfigurationClusterAttributes extends GlobalClusterAttributes { - physicalMinLevel?: number; - physicalMaxLevel?: number; - ballastStatus?: Partial<{ nonOperational: boolean; lampNotInSocket: boolean }>; - minLevel?: number; - maxLevel?: number; - powerOnLevel?: number; - powerOnFadeTime?: number; - intrinsicBallastFactor?: number; - ballastFactorAdjustment?: number; - lampQuantity?: number; - lampType?: string; - lampManufacturer?: string; - lampRatedHours?: number; - lampBurnHours?: number; - lampAlarmMode?: Partial<{ lampBurnHours: boolean }>; - lampBurnHoursTripPoint?: number; -} - -export interface BallastConfigurationCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: BallastConfigurationClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: BallastConfigurationClusterAttributes[K]) => void): this; -} - -export interface BasicClusterAttributes extends GlobalClusterAttributes { - zclVersion?: number; - appVersion?: number; - stackVersion?: number; - hwVersion?: number; - manufacturerName?: string; - modelId?: string; - dateCode?: string; - powerSource?: 'unknown' | 'mains' | 'mains3phase' | 'battery' | 'dc' | 'emergencyMains' | 'emergencyTransfer'; - appProfileVersion?: number; - locationDesc?: string; - physicalEnv?: 'Unspecified' | 'Atrium' | 'Bar' | 'Courtyard' | 'Bathroom' | 'Bedroom' | 'BilliardRoom' | 'UtilityRoom' | 'Cellar' | 'StorageCloset' | 'Theater' | 'Office' | 'Deck' | 'Den' | 'DiningRoom' | 'ElectricalRoom' | 'Elevator' | 'Entry' | 'FamilyRoom' | 'MainFloor' | 'Upstairs' | 'Downstairs' | 'Basement' | 'Gallery' | 'GameRoom' | 'Garage' | 'Gym' | 'Hallway' | 'House' | 'Kitchen' | 'LaundryRoom' | 'Library' | 'MasterBedroom' | 'MudRoom' | 'Nursery' | 'Pantry' | 'Outside' | 'Pool' | 'Porch' | 'SewingRoom' | 'SittingRoom' | 'Stairway' | 'Yard' | 'Attic' | 'HotTub' | 'LivingRoom' | 'Sauna' | 'Workshop' | 'GuestBedroom' | 'GuestBath' | 'PowderRoom' | 'BackYard' | 'FrontYard' | 'Patio' | 'Driveway' | 'SunRoom' | 'Spa' | 'Whirlpool' | 'Shed' | 'EquipmentStorage' | 'HobbyRoom' | 'Fountain' | 'Pond' | 'ReceptionRoom' | 'BreakfastRoom' | 'Nook' | 'Garden' | 'Balcony' | 'PanicRoom' | 'Terrace' | 'Roof' | 'Toilet' | 'ToiletMain' | 'OutsideToilet' | 'ShowerRoom' | 'Study' | 'FrontGarden' | 'BackGarden' | 'Kettle' | 'Television' | 'Stove' | 'Microwave' | 'Toaster' | 'Vacuum' | 'Appliance' | 'FrontDoor' | 'BackDoor' | 'FridgeDoor' | 'MedicationCabinetDoor' | 'WardrobeDoor' | 'FrontCupboardDoor' | 'OtherDoor' | 'WaitingRoom' | 'TriageRoom' | 'DoctorsOffice' | 'PatientsPrivateRoom' | 'ConsultationRoom' | 'NurseStation' | 'Ward' | 'Corridor' | 'OperatingTheatre' | 'DentalSurgeryRoom' | 'MedicalImagingRoom' | 'DecontaminationRoom' | 'Unknown'; - deviceEnabled?: boolean; - alarmMask?: Partial<{ hardwareFault: boolean; softwareFault: boolean }>; - disableLocalConfig?: Partial<{ factoryResetDisabled: boolean; configurationDisabled: boolean }>; - swBuildId?: string; -} - -export interface BasicCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: BasicClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: BasicClusterAttributes[K]) => void): this; - factoryReset(opts?: ClusterCommandOptions): Promise; -} - -export interface BinaryInputClusterAttributes extends GlobalClusterAttributes { - activeText?: string; - description?: string; - inactiveText?: string; - outOfService?: boolean; - polarity?: 'normal' | 'reverse'; - presentValue?: boolean; - reliability?: 'noFaultDetected' | 'noSensor' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'noOutput' | 'unreliableOther' | 'processError' | 'configurationError'; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface BinaryInputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: BinaryInputClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: BinaryInputClusterAttributes[K]) => void): this; -} - -export interface BinaryOutputClusterAttributes extends GlobalClusterAttributes { - activeText?: string; - description?: string; - inactiveText?: string; - minimumOffTime?: number; - minimumOnTime?: number; - outOfService?: boolean; - polarity?: 'normal' | 'reverse'; - presentValue?: boolean; - reliability?: 'noFaultDetected' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'unreliableOther' | 'processError' | 'configurationError'; - relinquishDefault?: boolean; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface BinaryOutputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: BinaryOutputClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: BinaryOutputClusterAttributes[K]) => void): this; -} - -export interface BinaryValueClusterAttributes extends GlobalClusterAttributes { - activeText?: string; - description?: string; - inactiveText?: string; - minimumOffTime?: number; - minimumOnTime?: number; - outOfService?: boolean; - polarity?: 'normal' | 'reverse'; - presentValue?: boolean; - reliability?: 'noFaultDetected' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'unreliableOther' | 'processError' | 'configurationError'; - relinquishDefault?: boolean; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface BinaryValueCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: BinaryValueClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: BinaryValueClusterAttributes[K]) => void): this; -} - -export interface ColorControlClusterAttributes extends GlobalClusterAttributes { - currentHue?: number; - currentSaturation?: number; - currentX?: number; - currentY?: number; - colorTemperatureMireds?: number; - colorMode?: 'currentHueAndCurrentSaturation' | 'currentXAndCurrentY' | 'colorTemperatureMireds'; - colorCapabilities?: Partial<{ hueAndSaturation: boolean; enhancedHue: boolean; colorLoop: boolean; xy: boolean; colorTemperature: boolean }>; - colorTempPhysicalMinMireds?: number; - colorTempPhysicalMaxMireds?: number; -} - -export interface ColorControlCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: ColorControlClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: ColorControlClusterAttributes[K]) => void): this; - moveToHue(args: { hue: number; direction: 'shortestDistance' | 'longestDistance' | 'up' | 'down'; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - moveToSaturation(args: { saturation: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - moveToHueAndSaturation(args: { hue: number; saturation: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - moveToColor(args: { colorX: number; colorY: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - moveToColorTemperature(args: { colorTemperature: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; -} - -export interface DehumidificationControlCluster extends ZCLNodeCluster { -} - -export interface DeviceTemperatureClusterAttributes extends GlobalClusterAttributes { - currentTemperature?: number; - minTempExperienced?: number; - maxTempExperienced?: number; - overTempTotalDwell?: number; - deviceTempAlarmMask?: Partial<{ deviceTemperatureTooLow: boolean; deviceTemperatureTooHigh: boolean }>; - lowTempThreshold?: number; - highTempThreshold?: number; - lowTempDwellTripPoint?: number; - highTempDwellTripPoint?: number; -} - -export interface DeviceTemperatureCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: DeviceTemperatureClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: DeviceTemperatureClusterAttributes[K]) => void): this; -} - -export interface DiagnosticsCluster extends ZCLNodeCluster { -} - -export interface DoorLockClusterAttributes extends GlobalClusterAttributes { - lockState?: 'notFullyLocked' | 'locked' | 'unlocked' | 'undefined'; - lockType?: 'deadBolt' | 'magnetic' | 'other' | 'mortise' | 'rim' | 'latchBolt' | 'cylindricalLock' | 'tubularLock' | 'interconnectedLock' | 'deadLatch' | 'doorFurniture'; - actuatorEnabled?: boolean; - doorState?: 'open' | 'closed' | 'errorJammed' | 'errorForcedOpen' | 'errorUnspecified' | 'undefined'; - doorOpenEvents?: number; - doorClosedEvents?: number; - openPeriod?: number; - numberOfLogRecordsSupported?: number; - numberOfTotalUsersSupported?: number; - numberOfPINUsersSupported?: number; - numberOfRFIDUsersSupported?: number; - numberOfWeekDaySchedulesSupportedPerUser?: number; - numberOfYearDaySchedulesSupportedPerUser?: number; - numberOfHolidaySchedulesSupported?: number; - maxPINCodeLength?: number; - minPINCodeLength?: number; - maxRFIDCodeLength?: number; - minRFIDCodeLength?: number; - enableLogging?: boolean; - language?: string; - ledSettings?: number; - autoRelockTime?: number; - soundVolume?: number; - operatingMode?: 'normal' | 'vacation' | 'privacy' | 'noRFLockOrUnlock' | 'passage'; - supportedOperatingModes?: Partial<{ normal: boolean; vacation: boolean; privacy: boolean; noRFLockOrUnlock: boolean; passage: boolean }>; - defaultConfigurationRegister?: Partial<{ enableLocalProgramming: boolean; keypadInterfaceDefaultAccess: boolean; rfInterfaceDefaultAccess: boolean; reserved3: boolean; reserved4: boolean; soundEnabled: boolean; autoRelockTimeSet: boolean; ledSettingsSet: boolean }>; - enableLocalProgramming?: boolean; - enableOneTouchLocking?: boolean; - enableInsideStatusLED?: boolean; - enablePrivacyModeButton?: boolean; - wrongCodeEntryLimit?: number; - userCodeTemporaryDisableTime?: number; - sendPINOverTheAir?: boolean; - requirePINforRFOperation?: boolean; - securityLevel?: 'network' | 'apsSecurity'; - alarmMask?: Partial<{ deadboltJammed: boolean; lockResetToFactoryDefaults: boolean; reserved2: boolean; rfModulePowerCycled: boolean; tamperAlarmWrongCodeEntryLimit: boolean; tamperAlarmFrontEscutcheonRemoved: boolean; forcedDoorOpenUnderDoorLockedCondition: boolean }>; - keypadOperationEventMask?: Partial<{ unknownOrManufacturerSpecificKeypadOperationEvent: boolean; lockSourceKeypad: boolean; unlockSourceKeypad: boolean; lockSourceKeypadErrorInvalidPIN: boolean; lockSourceKeypadErrorInvalidSchedule: boolean; unlockSourceKeypadErrorInvalidCode: boolean; unlockSourceKeypadErrorInvalidSchedule: boolean; nonAccessUserOperationEventSourceKeypad: boolean }>; - rfOperationEventMask?: Partial<{ unknownOrManufacturerSpecificKeypadOperationEvent: boolean; lockSourceRF: boolean; unlockSourceRF: boolean; lockSourceRFErrorInvalidCode: boolean; lockSourceRFErrorInvalidSchedule: boolean; unlockSourceRFErrorInvalidCode: boolean; unlockSourceRFErrorInvalidSchedule: boolean }>; - manualOperationEventMask?: Partial<{ unknownOrManufacturerSpecificManualOperationEvent: boolean; thumbturnLock: boolean; thumbturnUnlock: boolean; oneTouchLock: boolean; keyLock: boolean; keyUnlock: boolean; autoLock: boolean; scheduleLock: boolean; scheduleUnlock: boolean; manualLock: boolean; manualUnlock: boolean }>; - rfidOperationEventMask?: Partial<{ unknownOrManufacturerSpecificKeypadOperationEvent: boolean; lockSourceRFID: boolean; unlockSourceRFID: boolean; lockSourceRFIDErrorInvalidRFIDID: boolean; lockSourceRFIDErrorInvalidSchedule: boolean; unlockSourceRFIDErrorInvalidRFIDID: boolean; unlockSourceRFIDErrorInvalidSchedule: boolean }>; - keypadProgrammingEventMask?: Partial<{ unknownOrManufacturerSpecificKeypadProgrammingEvent: boolean; masterCodeChanged: boolean; pinCodeAdded: boolean; pinCodeDeleted: boolean; pinCodeChanged: boolean }>; - rfProgrammingEventMask?: Partial<{ unknownOrManufacturerSpecificRFProgrammingEvent: boolean; reserved1: boolean; pinCodeAdded: boolean; pinCodeDeleted: boolean; pinCodeChanged: boolean; rfidCodeAdded: boolean; rfidCodeDeleted: boolean }>; - rfidProgrammingEventMask?: Partial<{ unknownOrManufacturerSpecificRFIDProgrammingEvent: boolean; rfidCodeAdded: boolean; rfidCodeDeleted: boolean }>; -} - -export interface DoorLockCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: DoorLockClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: DoorLockClusterAttributes[K]) => void): this; - lockDoor(args?: { pinCode?: Buffer }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - unlockDoor(args?: { pinCode?: Buffer }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - toggle(args?: { pinCode?: Buffer }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - unlockWithTimeout(args: { timeout: number; pinCode?: Buffer }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getLogRecord(args: { logIndex: number }, opts?: ClusterCommandOptions): Promise<{ logEntryId: number; timestamp: number; eventType: number; source: number; eventIdOrAlarmCode: number; userId: number; pin: Buffer }>; - setPINCode(args: { userId: number; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported'; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported'; pinCode?: Buffer }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getPINCode(args: { userId: number }, opts?: ClusterCommandOptions): Promise<{ userId: number; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported'; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported'; pinCode: Buffer }>; - clearPINCode(args: { userId: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - clearAllPINCodes(opts?: ClusterCommandOptions): Promise<{ status: number }>; - setUserStatus(args: { userId: number; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported' }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getUserStatus(args: { userId: number }, opts?: ClusterCommandOptions): Promise<{ userId: number; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported' }>; - setWeekDaySchedule(args: { scheduleId: number; userId: number; daysMask: Partial<{ sunday: boolean; monday: boolean; tuesday: boolean; wednesday: boolean; thursday: boolean; friday: boolean; saturday: boolean }>; startHour: number; startMinute: number; endHour: number; endMinute: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getWeekDaySchedule(args: { scheduleId: number; userId: number }, opts?: ClusterCommandOptions): Promise<{ scheduleId: number; userId: number; status: number; daysMask: Partial<{ sunday: boolean; monday: boolean; tuesday: boolean; wednesday: boolean; thursday: boolean; friday: boolean; saturday: boolean }>; startHour: number; startMinute: number; endHour: number; endMinute: number }>; - clearWeekDaySchedule(args: { scheduleId: number; userId: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - setYearDaySchedule(args: { scheduleId: number; userId: number; localStartTime: number; localEndTime: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getYearDaySchedule(args: { scheduleId: number; userId: number }, opts?: ClusterCommandOptions): Promise<{ scheduleId: number; userId: number; status: number; localStartTime: number; localEndTime: number }>; - clearYearDaySchedule(args: { scheduleId: number; userId: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - setHolidaySchedule(args: { holidayScheduleId: number; localStartTime: number; localEndTime: number; operatingModeDuringHoliday: 'normal' | 'vacation' | 'privacy' | 'noRFLockOrUnlock' | 'passage' }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getHolidaySchedule(args: { holidayScheduleId: number }, opts?: ClusterCommandOptions): Promise<{ holidayScheduleId: number; status: number; localStartTime: number; localEndTime: number; operatingMode: 'normal' | 'vacation' | 'privacy' | 'noRFLockOrUnlock' | 'passage' }>; - clearHolidaySchedule(args: { holidayScheduleId: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - setUserType(args: { userId: number; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported' }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getUserType(args: { userId: number }, opts?: ClusterCommandOptions): Promise<{ userId: number; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported' }>; - setRFIDCode(args: { userId: number; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported'; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported'; rfidCode?: Buffer }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - getRFIDCode(args: { userId: number }, opts?: ClusterCommandOptions): Promise<{ userId: number; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported'; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported'; rfidCode: Buffer }>; - clearRFIDCode(args: { userId: number }, opts?: ClusterCommandOptions): Promise<{ status: number }>; - clearAllRFIDCodes(opts?: ClusterCommandOptions): Promise<{ status: number }>; - operationEventNotification(args: { operationEventSource: number; operationEventCode: number; userId: number; pin?: Buffer; zigBeeLocalTime: number; data?: Buffer }, opts?: ClusterCommandOptions): Promise; - programmingEventNotification(args: { programEventSource: number; programEventCode: number; userId: number; pin?: Buffer; userType: 'unrestricted' | 'yearDayScheduleUser' | 'weekDayScheduleUser' | 'masterUser' | 'nonAccessUser' | 'notSupported'; userStatus: 'available' | 'occupiedEnabled' | 'occupiedDisabled' | 'notSupported'; zigBeeLocalTime: number; data?: Buffer }, opts?: ClusterCommandOptions): Promise; -} - -export interface ElectricalMeasurementClusterAttributes extends GlobalClusterAttributes { - measurementType?: Partial<{ activeMeasurementAC: boolean; reactiveMeasurementAC: boolean; apparentMeasurementAC: boolean; phaseAMeasurement: boolean; phaseBMeasurement: boolean; phaseCMeasurement: boolean; dcMeasurement: boolean; harmonicsMeasurement: boolean; powerQualityMeasurement: boolean }>; - acFrequency?: number; - measuredPhase1stHarmonicCurrent?: number; - acFrequencyMultiplier?: number; - acFrequencyDivisor?: number; - phaseHarmonicCurrentMultiplier?: number; - rmsVoltage?: number; - rmsCurrent?: number; - activePower?: number; - reactivePower?: number; - acVoltageMultiplier?: number; - acVoltageDivisor?: number; - acCurrentMultiplier?: number; - acCurrentDivisor?: number; - acPowerMultiplier?: number; - acPowerDivisor?: number; - acAlarmsMask?: Partial<{ voltageOverload: boolean; currentOverload: boolean; activePowerOverload: boolean; reactivePowerOverload: boolean; averageRMSOverVoltage: boolean; averageRMSUnderVoltage: boolean; rmsExtremeOverVoltage: boolean; rmsExtremeUnderVoltage: boolean; rmsVoltageSag: boolean; rmsVoltageSwell: boolean }>; - acVoltageOverload?: number; - acCurrentOverload?: number; - acActivePowerOverload?: number; -} - -export interface ElectricalMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: ElectricalMeasurementClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: ElectricalMeasurementClusterAttributes[K]) => void): this; -} - -export interface FanControlCluster extends ZCLNodeCluster { -} - -export interface FlowMeasurementClusterAttributes extends GlobalClusterAttributes { - measuredValue?: number; - minMeasuredValue?: number; - maxMeasuredValue?: number; - tolerance?: number; -} - -export interface FlowMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: FlowMeasurementClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: FlowMeasurementClusterAttributes[K]) => void): this; -} - -export interface GroupsClusterAttributes extends GlobalClusterAttributes { - nameSupport?: Partial<{ groupNames: boolean }>; -} - -export interface GroupsCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: GroupsClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: GroupsClusterAttributes[K]) => void): this; - addGroup(args: { groupId: number; groupName: string }, opts?: ClusterCommandOptions): Promise<{ status: ZCLEnum8Status; groupId: number }>; - viewGroup(args: { groupId: number }, opts?: ClusterCommandOptions): Promise<{ status: ZCLEnum8Status; groupId: number; groupNames: string }>; - getGroupMembership(args: { groupIds: number[] }, opts?: ClusterCommandOptions): Promise<{ capacity: number; groups: number[] }>; - removeGroup(args: { groupId: number }, opts?: ClusterCommandOptions): Promise<{ status: ZCLEnum8Status; groupId: number }>; - removeAllGroups(opts?: ClusterCommandOptions): Promise; - addGroupIfIdentify(args: { groupId: number; groupName: string }, opts?: ClusterCommandOptions): Promise; -} - -export interface IASACECluster extends ZCLNodeCluster { -} - -export interface IASWDCluster extends ZCLNodeCluster { -} - -export interface IASZoneClusterAttributes extends GlobalClusterAttributes { - zoneState?: 'notEnrolled' | 'enrolled'; - 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; -} - -export interface IASZoneCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: IASZoneClusterAttributes[K]) => void): this; - 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: '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; -} - -export interface IdentifyClusterAttributes extends GlobalClusterAttributes { - identifyTime?: number; -} - -export interface IdentifyCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: IdentifyClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: IdentifyClusterAttributes[K]) => void): this; - identify(args: { identifyTime: number }, opts?: ClusterCommandOptions): Promise; - identifyQuery(opts?: ClusterCommandOptions): Promise<{ timeout: number }>; - triggerEffect(args: { effectIdentifier: 'blink' | 'breathe' | 'okay' | 'channelChange' | 'finish' | 'stop'; effectVariant: number }, opts?: ClusterCommandOptions): Promise; -} - -export interface IlluminanceLevelSensingClusterAttributes extends GlobalClusterAttributes { - levelStatus?: 'illuminanceOnTarget' | 'illuminanceBelowTarget' | 'illuminanceAboveTarget'; - lightSensorType?: 'photodiode' | 'cmos' | 'unknown'; - illuminanceTargetLevel?: number; -} - -export interface IlluminanceLevelSensingCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: IlluminanceLevelSensingClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: IlluminanceLevelSensingClusterAttributes[K]) => void): this; -} - -export interface IlluminanceMeasurementClusterAttributes extends GlobalClusterAttributes { - measuredValue?: number; - minMeasuredValue?: number; - maxMeasuredValue?: number; - tolerance?: number; - lightSensorType?: 'photodiode' | 'cmos' | 'unknown'; -} - -export interface IlluminanceMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: IlluminanceMeasurementClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: IlluminanceMeasurementClusterAttributes[K]) => void): this; -} - -export interface LevelControlClusterAttributes extends GlobalClusterAttributes { - currentLevel?: number; - remainingTime?: number; - onOffTransitionTime?: number; - onLevel?: number; - onTransitionTime?: number; - offTransitionTime?: number; - defaultMoveRate?: number; -} - -export interface LevelControlCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: LevelControlClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: LevelControlClusterAttributes[K]) => void): this; - moveToLevel(args: { level: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - move(args: { moveMode: 'up' | 'down'; rate: number }, opts?: ClusterCommandOptions): Promise; - step(args: { mode: 'up' | 'down'; stepSize: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - stop(opts?: ClusterCommandOptions): Promise; - moveToLevelWithOnOff(args: { level: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - moveWithOnOff(args: { moveMode: 'up' | 'down'; rate: number }, opts?: ClusterCommandOptions): Promise; - stepWithOnOff(args: { mode: 'up' | 'down'; stepSize: number; transitionTime: number }, opts?: ClusterCommandOptions): Promise; - stopWithOnOff(opts?: ClusterCommandOptions): Promise; -} - -export interface MeteringClusterAttributes extends GlobalClusterAttributes { - currentSummationDelivered?: number; - currentSummationReceived?: number; - currentMaxDemandDelivered?: number; - currentMaxDemandReceived?: number; - dftSummation?: number; - dailyFreezeTime?: number; - powerFactor?: number; - readingSnapShotTime?: number; - currentMaxDemandDeliveredTime?: number; - currentMaxDemandReceivedTime?: number; - defaultUpdatePeriod?: number; - fastPollUpdatePeriod?: number; - currentBlockPeriodConsumptionDelivered?: number; - dailyConsumptionTarget?: number; - currentBlock?: unknown; - profileIntervalPeriod?: unknown; - currentTier1SummationDelivered?: number; - currentTier1SummationReceived?: number; - currentTier2SummationDelivered?: number; - currentTier2SummationReceived?: number; - currentTier3SummationDelivered?: number; - currentTier3SummationReceived?: number; - currentTier4SummationDelivered?: number; - currentTier4SummationReceived?: number; - status?: Partial<{ checkMeter: boolean; lowBattery: boolean; tamperDetect: boolean; powerFailure: boolean; powerQuality: boolean; leakDetect: boolean; serviceDisconnect: boolean }>; - remainingBatteryLife?: number; - hoursInOperation?: number; - hoursInFault?: number; - unitOfMeasure?: unknown; - multiplier?: number; - divisor?: number; - siteId?: Buffer; - meterSerialNumber?: Buffer; - energyCarrierUnitOfMeasure?: unknown; - temperatureUnitOfMeasure?: unknown; - moduleSerialNumber?: Buffer; - operatingTariffLabelDelivered?: Buffer; - operatingTariffLabelReceived?: Buffer; - customerIdNumber?: Buffer; - alternativeUnitOfMeasure?: unknown; - instantaneousDemand?: number; - currentDayConsumptionDelivered?: number; - currentDayConsumptionReceived?: number; - previousDayConsumptionDelivered?: number; - previousDayConsumptionReceived?: number; - currentPartialProfileIntervalStartTimeDelivered?: number; - currentPartialProfileIntervalStartTimeReceived?: number; - currentPartialProfileIntervalValueDelivered?: number; - currentPartialProfileIntervalValueReceived?: number; - currentDayMaxPressure?: number; - currentDayMinPressure?: number; - previousDayMaxPressure?: number; - previousDayMinPressure?: number; - currentDayMaxDemand?: number; - previousDayMaxDemand?: number; - currentMonthMaxDemand?: number; - currentYearMaxDemand?: number; - currentDayMaxEnergyCarrierDemand?: number; - previousDayMaxEnergyCarrierDemand?: number; - currentMonthMaxEnergyCarrierDemand?: number; - currentMonthMinEnergyCarrierDemand?: number; - currentYearMaxEnergyCarrierDemand?: number; - currentYearMinEnergyCarrierDemand?: number; - maxNumberOfPeriodsDelivered?: number; - currentDemandDelivered?: number; - demandLimit?: number; - demandIntegrationPeriod?: number; - numberOfDemandSubintervals?: number; - demandLimitArmDuration?: number; - currentNoTierBlock1SummationDelivered?: number; - currentNoTierBlock2SummationDelivered?: number; - currentNoTierBlock3SummationDelivered?: number; - currentNoTierBlock4SummationDelivered?: number; - currentNoTierBlock5SummationDelivered?: number; - currentNoTierBlock6SummationDelivered?: number; - currentNoTierBlock7SummationDelivered?: number; - currentNoTierBlock8SummationDelivered?: number; - currentNoTierBlock9SummationDelivered?: number; - currentNoTierBlock10SummationDelivered?: number; - currentNoTierBlock11SummationDelivered?: number; - currentNoTierBlock12SummationDelivered?: number; - currentNoTierBlock13SummationDelivered?: number; - currentNoTierBlock14SummationDelivered?: number; - currentNoTierBlock15SummationDelivered?: number; - currentNoTierBlock16SummationDelivered?: number; - currentTier1Block1SummationDelivered?: number; - currentTier1Block2SummationDelivered?: number; - currentTier1Block3SummationDelivered?: number; - currentTier1Block4SummationDelivered?: number; - currentTier1Block5SummationDelivered?: number; - currentTier1Block6SummationDelivered?: number; - currentTier1Block7SummationDelivered?: number; - currentTier1Block8SummationDelivered?: number; - currentTier1Block9SummationDelivered?: number; - currentTier1Block10SummationDelivered?: number; - currentTier1Block11SummationDelivered?: number; - currentTier1Block12SummationDelivered?: number; - currentTier1Block13SummationDelivered?: number; - currentTier1Block14SummationDelivered?: number; - currentTier1Block15SummationDelivered?: number; - currentTier1Block16SummationDelivered?: number; - currentTier2Block1SummationDelivered?: number; - currentTier2Block2SummationDelivered?: number; - currentTier2Block3SummationDelivered?: number; - currentTier2Block4SummationDelivered?: number; - currentTier2Block5SummationDelivered?: number; - currentTier2Block6SummationDelivered?: number; - currentTier2Block7SummationDelivered?: number; - currentTier2Block8SummationDelivered?: number; - currentTier2Block9SummationDelivered?: number; - currentTier2Block10SummationDelivered?: number; - currentTier2Block11SummationDelivered?: number; - currentTier2Block12SummationDelivered?: number; - currentTier2Block13SummationDelivered?: number; - currentTier2Block14SummationDelivered?: number; - currentTier2Block15SummationDelivered?: number; - currentTier2Block16SummationDelivered?: number; - currentTier3Block1SummationDelivered?: number; - currentTier3Block2SummationDelivered?: number; - currentTier3Block3SummationDelivered?: number; - currentTier3Block4SummationDelivered?: number; - currentTier3Block5SummationDelivered?: number; - currentTier3Block6SummationDelivered?: number; - currentTier3Block7SummationDelivered?: number; - currentTier3Block8SummationDelivered?: number; - currentTier3Block9SummationDelivered?: number; - currentTier3Block10SummationDelivered?: number; - currentTier3Block11SummationDelivered?: number; - currentTier3Block12SummationDelivered?: number; - currentTier3Block13SummationDelivered?: number; - currentTier3Block14SummationDelivered?: number; - currentTier3Block15SummationDelivered?: number; - currentTier3Block16SummationDelivered?: number; - currentTier4Block1SummationDelivered?: number; - currentTier4Block2SummationDelivered?: number; - currentTier4Block3SummationDelivered?: number; - currentTier4Block4SummationDelivered?: number; - currentTier4Block5SummationDelivered?: number; - currentTier4Block6SummationDelivered?: number; - currentTier4Block7SummationDelivered?: number; - currentTier4Block8SummationDelivered?: number; - currentTier4Block9SummationDelivered?: number; - currentTier4Block10SummationDelivered?: number; - currentTier4Block11SummationDelivered?: number; - currentTier4Block12SummationDelivered?: number; - currentTier4Block13SummationDelivered?: number; - currentTier4Block14SummationDelivered?: number; - currentTier4Block15SummationDelivered?: number; - currentTier4Block16SummationDelivered?: number; - currentNoTierBlock1SummationReceived?: number; - currentNoTierBlock2SummationReceived?: number; - currentNoTierBlock3SummationReceived?: number; - currentNoTierBlock4SummationReceived?: number; - currentNoTierBlock5SummationReceived?: number; - currentNoTierBlock6SummationReceived?: number; - currentNoTierBlock7SummationReceived?: number; - currentNoTierBlock8SummationReceived?: number; - currentNoTierBlock9SummationReceived?: number; - currentNoTierBlock10SummationReceived?: number; - currentNoTierBlock11SummationReceived?: number; - currentNoTierBlock12SummationReceived?: number; - currentNoTierBlock13SummationReceived?: number; - currentNoTierBlock14SummationReceived?: number; - currentNoTierBlock15SummationReceived?: number; - currentNoTierBlock16SummationReceived?: number; - billToDateDelivered?: number; - billToDateTimeStampDelivered?: number; - projectedBillDelivered?: number; - projectedBillTimeStampDelivered?: number; - billToDateReceived?: number; - billToDateTimeStampReceived?: number; - projectedBillReceived?: number; - projectedBillTimeStampReceived?: number; - proposedChangeSupplyImplementationTime?: number; - proposedChangeSupplyStatus?: unknown; - uncontrolledFlowThreshold?: number; - uncontrolledFlowThresholdUnitOfMeasure?: unknown; - uncontrolledFlowMultiplier?: number; - uncontrolledFlowDivisor?: number; - flowStabilisationPeriod?: number; - flowMeasurementPeriod?: number; -} - -export interface MeteringCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: MeteringClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: MeteringClusterAttributes[K]) => void): this; -} - -export interface MultistateInputClusterAttributes extends GlobalClusterAttributes { - description?: string; - numberOfStates?: number; - outOfService?: boolean; - presentValue?: number; - reliability?: 'noFaultDetected' | 'noSensor' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'noOutput' | 'unreliableOther' | 'processError' | 'multiStateFault' | 'configurationError'; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface MultistateInputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: MultistateInputClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: MultistateInputClusterAttributes[K]) => void): this; -} - -export interface MultistateOutputClusterAttributes extends GlobalClusterAttributes { - description?: string; - numberOfStates?: number; - outOfService?: boolean; - presentValue?: number; - reliability?: 'noFaultDetected' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'unreliableOther' | 'processError' | 'multiStateFault' | 'configurationError'; - relinquishDefault?: number; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface MultistateOutputCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: MultistateOutputClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: MultistateOutputClusterAttributes[K]) => void): this; -} - -export interface MultistateValueClusterAttributes extends GlobalClusterAttributes { - description?: string; - numberOfStates?: number; - outOfService?: boolean; - presentValue?: number; - reliability?: 'noFaultDetected' | 'noSensor' | 'overRange' | 'underRange' | 'openLoop' | 'shortedLoop' | 'noOutput' | 'unreliableOther' | 'processError' | 'multiStateFault' | 'configurationError'; - relinquishDefault?: number; - statusFlags?: Partial<{ inAlarm: boolean; fault: boolean; overridden: boolean; outOfService: boolean }>; - applicationType?: number; -} - -export interface MultistateValueCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: MultistateValueClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: MultistateValueClusterAttributes[K]) => void): this; -} - -export interface OccupancySensingClusterAttributes extends GlobalClusterAttributes { - occupancy?: Partial<{ occupied: boolean }>; - occupancySensorType?: 'pir' | 'ultrasonic' | 'pirAndUltrasonic' | 'physicalContact'; - occupancySensorTypeBitmap?: Partial<{ pir: boolean; ultrasonic: boolean; physicalContact: boolean }>; - pirOccupiedToUnoccupiedDelay?: number; - pirUnoccupiedToOccupiedDelay?: number; - pirUnoccupiedToOccupiedThreshold?: number; - ultrasonicOccupiedToUnoccupiedDelay?: number; - ultrasonicUnoccupiedToOccupiedDelay?: number; - ultrasonicUnoccupiedToOccupiedThreshold?: number; - physicalContactOccupiedToUnoccupiedDelay?: number; - physicalContactUnoccupiedToOccupiedDelay?: number; - physicalContactUnoccupiedToOccupiedThreshold?: number; -} - -export interface OccupancySensingCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: OccupancySensingClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: OccupancySensingClusterAttributes[K]) => void): this; -} - -export interface OnOffClusterAttributes extends GlobalClusterAttributes { - onOff?: boolean; - onTime?: number; - offWaitTime?: number; -} - -export interface OnOffCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: OnOffClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: OnOffClusterAttributes[K]) => void): this; - setOff(opts?: ClusterCommandOptions): Promise; - setOn(opts?: ClusterCommandOptions): Promise; - toggle(opts?: ClusterCommandOptions): Promise; - offWithEffect(args: { effectIdentifier: number; effectVariant: number }, opts?: ClusterCommandOptions): Promise; - onWithRecallGlobalScene(opts?: ClusterCommandOptions): Promise; - onWithTimedOff(args: { onOffControl: number; onTime: number; offWaitTime: number }, opts?: ClusterCommandOptions): Promise; -} - -export interface OnOffSwitchCluster extends ZCLNodeCluster { -} - -export interface OTAClusterAttributes extends GlobalClusterAttributes { - upgradeServerID?: string; - fileOffset?: number; - currentFileVersion?: number; - currentZigBeeStackVersion?: number; - downloadedFileVersion?: number; - downloadedZigBeeStackVersion?: number; - imageUpgradeStatus?: 'normal' | 'downloadInProgress' | 'downloadComplete' | 'waitingToUpgrade' | 'countDown' | 'waitForMore' | 'waitingToUpgradeViaExternalEvent'; - manufacturerID?: number; - imageTypeID?: number; - minimumBlockPeriod?: number; - imageStamp?: number; - upgradeActivationPolicy?: 'otaServerActivationAllowed' | 'outOfBandActivationOnly'; - upgradeTimeoutPolicy?: 'applyUpgradeAfterTimeout' | 'doNotApplyUpgradeAfterTimeout'; -} - -export interface OTACluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: OTAClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: OTAClusterAttributes[K]) => void): this; - imageNotify(args?: { payloadType?: 'queryJitter' | 'queryJitterAndManufacturerCode' | 'queryJitterAndManufacturerCodeAndImageType' | 'queryJitterAndManufacturerCodeAndImageTypeAndNewFileVersion'; queryJitter?: number; manufacturerCode?: number; imageType?: number; newFileVersion?: number }, opts?: ClusterCommandOptions): Promise; - queryNextImageRequest(args?: { fieldControl?: Partial<{ hardwareVersionPresent: boolean }>; manufacturerCode?: number; imageType?: number; fileVersion?: number; hardwareVersion?: number }, opts?: ClusterCommandOptions): Promise<{ status?: ZCLEnum8Status; manufacturerCode?: number; imageType?: number; fileVersion?: number; imageSize?: number }>; - imageBlockRequest(args?: { fieldControl?: Partial<{ requestNodeAddressPresent: boolean; minimumBlockPeriodPresent: boolean }>; manufacturerCode?: number; imageType?: number; fileVersion?: number; fileOffset?: number; maximumDataSize?: number; requestNodeAddress?: string; minimumBlockPeriod?: number }, opts?: ClusterCommandOptions): Promise<{ status?: ZCLEnum8Status; manufacturerCode?: number; imageType?: number; fileVersion?: number; fileOffset?: number; dataSize?: number; imageData?: Buffer; currentTime?: number; requestTime?: number; minimumBlockPeriod?: number }>; - imagePageRequest(args?: { fieldControl?: Partial<{ requestNodeAddressPresent: boolean }>; manufacturerCode?: number; imageType?: number; fileVersion?: number; fileOffset?: number; maximumDataSize?: number; pageSize?: number; responseSpacing?: number; requestNodeAddress?: string }, opts?: ClusterCommandOptions): Promise<{ status?: ZCLEnum8Status; manufacturerCode?: number; imageType?: number; fileVersion?: number; fileOffset?: number; dataSize?: number; imageData?: Buffer; currentTime?: number; requestTime?: number; minimumBlockPeriod?: number }>; - imageBlockResponse(args?: { status?: ZCLEnum8Status; manufacturerCode?: number; imageType?: number; fileVersion?: number; fileOffset?: number; dataSize?: number; imageData?: Buffer; currentTime?: number; requestTime?: number; minimumBlockPeriod?: number }, opts?: ClusterCommandOptions): Promise; - upgradeEndRequest(args: { status: ZCLEnum8Status; manufacturerCode: number; imageType: number; fileVersion: number }, opts?: ClusterCommandOptions): Promise<{ manufacturerCode: number; imageType: number; fileVersion: number; currentTime: number; upgradeTime: number }>; - upgradeEndResponse(args: { manufacturerCode: number; imageType: number; fileVersion: number; currentTime: number; upgradeTime: number }, opts?: ClusterCommandOptions): Promise; - queryDeviceSpecificFileRequest(args: { requestNodeAddress: string; manufacturerCode: number; imageType: number; fileVersion: number; zigBeeStackVersion: number }, opts?: ClusterCommandOptions): Promise<{ status?: ZCLEnum8Status; manufacturerCode?: number; imageType?: number; fileVersion?: number; imageSize?: number }>; -} - -export interface PollControlClusterAttributes extends GlobalClusterAttributes { - checkInInterval?: number; - longPollInterval?: number; - shortPollInterval?: number; - fastPollTimeout?: number; - checkInIntervalMin?: number; - longPollIntervalMin?: number; - fastPollTimeoutMax?: number; -} - -export interface PollControlCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: PollControlClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: PollControlClusterAttributes[K]) => void): this; - fastPollStop(opts?: ClusterCommandOptions): Promise; - setLongPollInterval(args: { newLongPollInterval: number }, opts?: ClusterCommandOptions): Promise; - setShortPollInterval(args: { newShortPollInterval: number }, opts?: ClusterCommandOptions): Promise; -} - -export interface PowerConfigurationClusterAttributes extends GlobalClusterAttributes { - batteryVoltage?: number; - batteryPercentageRemaining?: number; - batterySize?: 'noBattery' | 'builtIn' | 'other' | 'AA' | 'AAA' | 'C' | 'D' | 'CR2' | 'CR123A' | 'unknown'; - batteryQuantity?: number; - batteryRatedVoltage?: number; - batteryVoltageMinThreshold?: number; - batteryAlarmState?: Partial<{ batteryThresholdBatterySource1: boolean; batteryThreshold1BatterySource1: boolean; batteryThreshold2BatterySource1: boolean; batteryThreshold3BatterySource1: boolean; reserved4: boolean; reserved5: boolean; reserved6: boolean; reserved7: boolean; reserved8: boolean; reserved9: boolean; batteryThresholdBatterySource2: boolean; batteryThreshold1BatterySource2: boolean; batteryThreshold2BatterySource2: boolean; batteryThreshold3BatterySource2: boolean; reserved14: boolean; reserved15: boolean; reserved16: boolean; reserved17: boolean; reserved18: boolean; reserved19: boolean; batteryThresholdBatterySource3: boolean; batteryThreshold1BatterySource3: boolean; batteryThreshold2BatterySource3: boolean; batteryThreshold3BatterySource3: boolean; reserved24: boolean; reserved25: boolean; reserved26: boolean; reserved27: boolean; reserved28: boolean; reserved29: boolean; mainsPowerSupplyLostUnavailable: boolean }>; -} - -export interface PowerConfigurationCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: PowerConfigurationClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: PowerConfigurationClusterAttributes[K]) => void): this; -} - -export interface PowerProfileCluster extends ZCLNodeCluster { -} - -export interface PressureMeasurementClusterAttributes extends GlobalClusterAttributes { - measuredValue?: number; - minMeasuredValue?: number; - maxMeasuredValue?: number; - tolerance?: number; - scaledValue?: number; - minScaledValue?: number; - maxScaledValue?: number; - scaledTolerance?: number; - scale?: number; -} - -export interface PressureMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: PressureMeasurementClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: PressureMeasurementClusterAttributes[K]) => void): this; -} - -export interface PumpConfigurationAndControlCluster extends ZCLNodeCluster { -} - -export interface RelativeHumidityClusterAttributes extends GlobalClusterAttributes { - measuredValue?: number; - minMeasuredValue?: number; - maxMeasuredValue?: number; - tolerance?: number; -} - -export interface RelativeHumidityCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: RelativeHumidityClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: RelativeHumidityClusterAttributes[K]) => void): this; -} - -export interface ScenesCluster extends ZCLNodeCluster { -} - -export interface ShadeConfigurationCluster extends ZCLNodeCluster { -} - -export interface TemperatureMeasurementClusterAttributes extends GlobalClusterAttributes { - measuredValue?: number; - minMeasuredValue?: number; - maxMeasuredValue?: number; -} - -export interface TemperatureMeasurementCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: TemperatureMeasurementClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: TemperatureMeasurementClusterAttributes[K]) => void): this; -} - -export interface ThermostatClusterAttributes extends GlobalClusterAttributes { - localTemperature?: number; - outdoorTemperature?: number; - occupancy?: Partial<{ occupied: boolean }>; - absMinHeatSetpointLimit?: number; - absMaxHeatSetpointLimit?: number; - absMinCoolSetpointLimit?: number; - absMaxCoolSetpointLimit?: number; - pICoolingDemand?: number; - pIHeatingDemand?: number; - localTemperatureCalibration?: number; - occupiedCoolingSetpoint?: number; - occupiedHeatingSetpoint?: number; - unoccupiedCoolingSetpoint?: number; - unoccupiedHeatingSetpoint?: number; - minHeatSetpointLimit?: number; - maxHeatSetpointLimit?: number; - minCoolSetpointLimit?: number; - maxCoolSetpointLimit?: number; - minSetpointDeadBand?: number; - remoteSensing?: Partial<{ localTemperature: boolean; outdoorTemperature: boolean; occupancy: boolean }>; - controlSequenceOfOperation?: 'cooling' | 'coolingWithReheat' | 'heating' | 'heatingWithReheat' | 'coolingAndHeating4Pipes' | 'coolingAndHeating4PipesWithReheat'; - systemMode?: 'off' | 'auto' | 'cool' | 'heat' | 'emergencyHeating' | 'precooling' | 'fanOnly' | 'dry' | 'sleep'; - alarmMask?: Partial<{ initializationFailure: boolean; hardwareFailure: boolean; selfCalibrationFailure: boolean }>; -} - -export interface ThermostatCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: ThermostatClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: ThermostatClusterAttributes[K]) => void): this; - setSetpoint(args: { mode: 'heat' | 'cool' | 'both'; amount: number }, opts?: ClusterCommandOptions): Promise; -} - -export interface TimeCluster extends ZCLNodeCluster { -} - -export interface TouchLinkCluster extends ZCLNodeCluster { - getGroups(args: { startIdx: number }, opts?: ClusterCommandOptions): Promise<{ total: number; startIndex: number; groups: unknown[] }>; -} - -export interface WindowCoveringClusterAttributes extends GlobalClusterAttributes { - windowCoveringType?: 'rollershade' | 'rollershade2Motor' | 'rollershadeExterior' | 'rollershadeExterior2Motor' | 'drapery' | 'awning' | 'shutter' | 'tiltBlindTiltOnly' | 'tiltBlindLiftAndTilt' | 'projectorScreen'; - physicalClosedLimitLift?: number; - physicalClosedLimitTilt?: number; - currentPositionLift?: number; - currentPositionTilt?: number; - numberofActuationsLift?: number; - numberofActuationsTilt?: number; - configStatus?: Partial<{ operational: boolean; online: boolean; reversalLiftCommands: boolean; controlLift: boolean; controlTilt: boolean; encoderLift: boolean; encoderTilt: boolean; reserved: boolean }>; - currentPositionLiftPercentage?: number; - currentPositionTiltPercentage?: number; - installedOpenLimitLift?: number; - installedClosedLimitLift?: number; - installedOpenLimitTilt?: number; - installedClosedLimitTilt?: number; - velocityLift?: number; - accelerationTimeLift?: number; - decelerationTimeLift?: number; - mode?: Partial<{ motorDirectionReversed: boolean; calibrationMode: boolean; maintenanceMode: boolean; ledFeedback: boolean }>; - intermediateSetpointsLift?: Buffer; - intermediateSetpointsTilt?: Buffer; -} - -export interface WindowCoveringCluster extends ZCLNodeCluster { - readAttributes(attributeNames: K[], opts?: { timeout?: number }): Promise>; - readAttributes(attributeNames: Array, opts?: { timeout?: number }): Promise & Record>; - writeAttributes(attributes: Partial, opts?: { timeout?: number }): Promise; - on(eventName: `attr.${K}`, listener: (value: WindowCoveringClusterAttributes[K]) => void): this; - once(eventName: `attr.${K}`, listener: (value: WindowCoveringClusterAttributes[K]) => void): this; - upOpen(opts?: ClusterCommandOptions): Promise; - downClose(opts?: ClusterCommandOptions): Promise; - stop(opts?: ClusterCommandOptions): Promise; - goToLiftValue(args: { liftValue: number }, opts?: ClusterCommandOptions): Promise; - goToLiftPercentage(args: { percentageLiftValue: number }, opts?: ClusterCommandOptions): Promise; - goToTiltValue(args: { tiltValue: number }, opts?: ClusterCommandOptions): Promise; - goToTiltPercentage(args: { percentageTiltValue: number }, opts?: ClusterCommandOptions): Promise; -} - -/** Type-safe cluster registry */ -export interface ClusterRegistry { - alarms?: AlarmsCluster; - analogInput?: AnalogInputCluster; - analogOutput?: AnalogOutputCluster; - analogValue?: AnalogValueCluster; - ballastConfiguration?: BallastConfigurationCluster; - basic?: BasicCluster; - binaryInput?: BinaryInputCluster; - binaryOutput?: BinaryOutputCluster; - binaryValue?: BinaryValueCluster; - colorControl?: ColorControlCluster; - dehumidificationControl?: DehumidificationControlCluster; - deviceTemperature?: DeviceTemperatureCluster; - diagnostics?: DiagnosticsCluster; - doorLock?: DoorLockCluster; - electricalMeasurement?: ElectricalMeasurementCluster; - fanControl?: FanControlCluster; - flowMeasurement?: FlowMeasurementCluster; - groups?: GroupsCluster; - iasACE?: IASACECluster; - iasWD?: IASWDCluster; - iasZone?: IASZoneCluster; - identify?: IdentifyCluster; - illuminanceLevelSensing?: IlluminanceLevelSensingCluster; - illuminanceMeasurement?: IlluminanceMeasurementCluster; - levelControl?: LevelControlCluster; - metering?: MeteringCluster; - multistateInput?: MultistateInputCluster; - multistateOutput?: MultistateOutputCluster; - multistateValue?: MultistateValueCluster; - occupancySensing?: OccupancySensingCluster; - onOff?: OnOffCluster; - onOffSwitch?: OnOffSwitchCluster; - ota?: OTACluster; - pollControl?: PollControlCluster; - powerConfiguration?: PowerConfigurationCluster; - powerProfile?: PowerProfileCluster; - pressureMeasurement?: PressureMeasurementCluster; - pumpConfigurationAndControl?: PumpConfigurationAndControlCluster; - relativeHumidity?: RelativeHumidityCluster; - scenes?: ScenesCluster; - shadeConfiguration?: ShadeConfigurationCluster; - temperatureMeasurement?: TemperatureMeasurementCluster; - thermostat?: ThermostatCluster; - time?: TimeCluster; - touchlink?: TouchLinkCluster; - windowCovering?: WindowCoveringCluster; -} - -/** Cluster type lookup by cluster NAME */ -export interface ClusterTypeByName { - alarms: AlarmsCluster; - analogInput: AnalogInputCluster; - analogOutput: AnalogOutputCluster; - analogValue: AnalogValueCluster; - ballastConfiguration: BallastConfigurationCluster; - basic: BasicCluster; - binaryInput: BinaryInputCluster; - binaryOutput: BinaryOutputCluster; - binaryValue: BinaryValueCluster; - colorControl: ColorControlCluster; - dehumidificationControl: DehumidificationControlCluster; - deviceTemperature: DeviceTemperatureCluster; - diagnostics: DiagnosticsCluster; - doorLock: DoorLockCluster; - electricalMeasurement: ElectricalMeasurementCluster; - fanControl: FanControlCluster; - flowMeasurement: FlowMeasurementCluster; - groups: GroupsCluster; - iasACE: IASACECluster; - iasWD: IASWDCluster; - iasZone: IASZoneCluster; - identify: IdentifyCluster; - illuminanceLevelSensing: IlluminanceLevelSensingCluster; - illuminanceMeasurement: IlluminanceMeasurementCluster; - levelControl: LevelControlCluster; - metering: MeteringCluster; - multistateInput: MultistateInputCluster; - multistateOutput: MultistateOutputCluster; - multistateValue: MultistateValueCluster; - occupancySensing: OccupancySensingCluster; - onOff: OnOffCluster; - onOffSwitch: OnOffSwitchCluster; - ota: OTACluster; - pollControl: PollControlCluster; - powerConfiguration: PowerConfigurationCluster; - powerProfile: PowerProfileCluster; - pressureMeasurement: PressureMeasurementCluster; - pumpConfigurationAndControl: PumpConfigurationAndControlCluster; - relativeHumidity: RelativeHumidityCluster; - scenes: ScenesCluster; - shadeConfiguration: ShadeConfigurationCluster; - temperatureMeasurement: TemperatureMeasurementCluster; - thermostat: ThermostatCluster; - time: TimeCluster; - touchlink: TouchLinkCluster; - windowCovering: WindowCoveringCluster; -} - -/** Cluster attributes lookup by cluster NAME */ -export interface ClusterAttributesByName { - alarms: Record; - analogInput: AnalogInputClusterAttributes; - analogOutput: AnalogOutputClusterAttributes; - analogValue: AnalogValueClusterAttributes; - ballastConfiguration: BallastConfigurationClusterAttributes; - basic: BasicClusterAttributes; - binaryInput: BinaryInputClusterAttributes; - binaryOutput: BinaryOutputClusterAttributes; - binaryValue: BinaryValueClusterAttributes; - colorControl: ColorControlClusterAttributes; - dehumidificationControl: Record; - deviceTemperature: DeviceTemperatureClusterAttributes; - diagnostics: Record; - doorLock: DoorLockClusterAttributes; - electricalMeasurement: ElectricalMeasurementClusterAttributes; - fanControl: Record; - flowMeasurement: FlowMeasurementClusterAttributes; - groups: GroupsClusterAttributes; - iasACE: Record; - iasWD: Record; - iasZone: IASZoneClusterAttributes; - identify: IdentifyClusterAttributes; - illuminanceLevelSensing: IlluminanceLevelSensingClusterAttributes; - illuminanceMeasurement: IlluminanceMeasurementClusterAttributes; - levelControl: LevelControlClusterAttributes; - metering: MeteringClusterAttributes; - multistateInput: MultistateInputClusterAttributes; - multistateOutput: MultistateOutputClusterAttributes; - multistateValue: MultistateValueClusterAttributes; - occupancySensing: OccupancySensingClusterAttributes; - onOff: OnOffClusterAttributes; - onOffSwitch: Record; - ota: OTAClusterAttributes; - pollControl: PollControlClusterAttributes; - powerConfiguration: PowerConfigurationClusterAttributes; - powerProfile: Record; - pressureMeasurement: PressureMeasurementClusterAttributes; - pumpConfigurationAndControl: Record; - relativeHumidity: RelativeHumidityClusterAttributes; - scenes: Record; - shadeConfiguration: Record; - temperatureMeasurement: TemperatureMeasurementClusterAttributes; - thermostat: ThermostatClusterAttributes; - time: Record; - touchlink: Record; - windowCovering: WindowCoveringClusterAttributes; -} - -/** Infer a typed cluster interface from a CLUSTER definition object. */ -export type ClusterTypeFromDefinition = - TDef['NAME'] extends keyof ClusterTypeByName - ? ClusterTypeByName[TDef['NAME']] - : ZCLNodeCluster; - -/** Infer typed cluster attribute map from a CLUSTER definition object. */ -export type ClusterAttributesFromDefinition = - TDef['NAME'] extends keyof ClusterAttributesByName - ? ClusterAttributesByName[TDef['NAME']] - : Record; - -export type ZCLNodeEndpoint = { - clusters: ClusterRegistry & { - [clusterName: string]: ZCLNodeCluster | undefined; +/* eslint-disable @typescript-eslint/no-explicit-any */ +declare module "zigbee-clusters" { + import {BitMap} from "@athombv/data-types"; + type BasicClusterAttributes = { + zclVersion: { id: 0x00, type: ZCLDataType }, + appVersion: { id: 0x01, type: ZCLDataType }, + stackVersion: { id: 0x02, type: ZCLDataType }, + hwVersion: { id: 0x03, type: ZCLDataType }, + manufacturerName: { id: 0x04, type: ZCLDataType }, + modelId: { id: 0x05, type: ZCLDataType }, + dateCode: { id: 0x06, type: ZCLDataType }, + powerSource: { id: 0x07, type: ZCLDataType<"unknown" | "mains" | "mains3phase" | "battery" | "dc" | "emergencyMains" | "emergencyTransfer"> }, + appProfileVersion: { id: 0x08, type: ZCLDataType }, + locationDesc: { id: 0x10, type: ZCLDataType }, + physicalEnv: { id: 0x11, type: ZCLDataType<"Unspecified" | "Atrium" | "Bar" | "Courtyard" | "Bathroom" | "Bedroom" | "BilliardRoom" | "UtilityRoom" | "Cellar" | "StorageCloset" | "Theater" | "Office" | "Deck" | "Den" | "DiningRoom" | "ElectricalRoom" | "Elevator" | "Entry" | "FamilyRoom" | "MainFloor" | "Upstairs" | "Downstairs" | "Basement" | "Gallery" | "GameRoom" | "Garage" | "Gym" | "Hallway" | "House" | "Kitchen" | "LaundryRoom" | "Library" | "MasterBedroom" | "MudRoom" | "Nursery" | "Pantry" | "Outside" | "Pool" | "Porch" | "SewingRoom" | "SittingRoom" | "Stairway" | "Yard" | "Attic" | "HotTub" | "LivingRoom" | "Sauna" | "Workshop" | "GuestBedroom" | "GuestBath" | "PowderRoom" | "BackYard" | "FrontYard" | "Patio" | "Driveway" | "SunRoom" | "Spa" | "Whirlpool" | "Shed" | "EquipmentStorage" | "HobbyRoom" | "Fountain" | "Pond" | "ReceptionRoom" | "BreakfastRoom" | "Nook" | "Garden" | "Balcony" | "PanicRoom" | "Terrace" | "Roof" | "Toilet" | "ToiletMain" | "OutsideToilet" | "ShowerRoom" | "Study" | "FrontGarden" | "BackGarden" | "Kettle" | "Television" | "Stove" | "Microwave" | "Toaster" | "Vacuum" | "Appliance" | "FrontDoor" | "BackDoor" | "FridgeDoor" | "MedicationCabinetDoor" | "WardrobeDoor" | "FrontCupboardDoor" | "OtherDoor" | "WaitingRoom" | "TriageRoom" | "DoctorsOffice" | "PatientsPrivateRoom" | "ConsultationRoom" | "NurseStation" | "Ward" | "Corridor" | "OperatingTheatre" | "DentalSurgeryRoom" | "MedicalImagingRoom" | "DecontaminationRoom" | "Unknown"> }, + deviceEnabled: { id: 0x12, type: ZCLDataType }, + alarmMask: { id: 0x13, type: ZCLDataType> }, + disableLocalConfig: { id: 0x14, type: ZCLDataType> }, + swBuildId: { id: 0x4000, type: ZCLDataType }, }; - bind(clusterName: string, impl: BoundCluster): void; -}; - -export interface ZCLNode { - endpoints: { [endpointId: number | string]: ZCLNodeEndpoint }; - handleFrame: ( - endpointId: number, - clusterId: number, - frame: Buffer, - meta?: unknown - ) => Promise; -} - -export const ZCLNode: { - new (node: ZCLNodeConstructorInput): ZCLNode; -}; - -export const CLUSTER: { - - ALARMS: { - ID: number; - NAME: 'alarms'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type BasicClusterCommands = { + factoryReset: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT" }, + }; + class BasicCluster extends Cluster { + factoryReset( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type PowerConfigurationClusterAttributes = { + batteryVoltage: { id: 0x20, type: ZCLDataType }, + batteryPercentageRemaining: { id: 0x21, type: ZCLDataType }, + batterySize: { id: 0x31, type: ZCLDataType<"noBattery" | "builtIn" | "other" | "AA" | "AAA" | "C" | "D" | "CR2" | "CR123A" | "unknown"> }, + batteryQuantity: { id: 0x33, type: ZCLDataType }, + batteryRatedVoltage: { id: 0x34, type: ZCLDataType }, + batteryVoltageMinThreshold: { id: 0x36, type: ZCLDataType }, + batteryAlarmState: { id: 0x3e, type: ZCLDataType> }, + }; + type PowerConfigurationClusterCommands = Record; + class PowerConfigurationCluster extends Cluster { + } + type DeviceTemperatureClusterAttributes = { + currentTemperature: { id: 0x00, type: ZCLDataType }, + minTempExperienced: { id: 0x01, type: ZCLDataType }, + maxTempExperienced: { id: 0x02, type: ZCLDataType }, + overTempTotalDwell: { id: 0x03, type: ZCLDataType }, + deviceTempAlarmMask: { id: 0x10, type: ZCLDataType> }, + lowTempThreshold: { id: 0x11, type: ZCLDataType }, + highTempThreshold: { id: 0x12, type: ZCLDataType }, + lowTempDwellTripPoint: { id: 0x13, type: ZCLDataType }, + highTempDwellTripPoint: { id: 0x14, type: ZCLDataType }, + }; + type DeviceTemperatureClusterCommands = Record; + class DeviceTemperatureCluster extends Cluster { + } + type IdentifyClusterAttributes = { + identifyTime: { id: 0x00, type: ZCLDataType }, }; - ANALOG_INPUT: { - ID: number; - NAME: 'analogInput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type IdentifyClusterCommands = { + identify: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + identifyTime: ZCLDataType, + }, + }, + identifyQuery: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT" }, + triggerEffect: { id: 0x40, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + effectIdentifier: ZCLDataType<"blink" | "breathe" | "okay" | "channelChange" | "finish" | "stop">, + effectVariant: ZCLDataType, + }, + }, }; - ANALOG_OUTPUT: { - ID: number; - NAME: 'analogOutput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class IdentifyCluster extends Cluster { + identify( + args: { + manufacturerId?: number, + identifyTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + identifyQuery( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + triggerEffect( + args: { + manufacturerId?: number, + effectIdentifier: "blink" | "breathe" | "okay" | "channelChange" | "finish" | "stop", + effectVariant: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type GroupsClusterAttributes = { + nameSupport: { id: 0x00, type: ZCLDataType> }, }; - ANALOG_VALUE: { - ID: number; - NAME: 'analogValue'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type GroupsClusterCommands = { + addGroup: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + groupId: ZCLDataType, + groupName: ZCLDataType, + }, + }, + viewGroup: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + groupId: ZCLDataType, + }, + }, + getGroupMembership: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + groupIds: ZCLDataType>, + }, + }, + removeGroup: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + groupId: ZCLDataType, + }, + }, + removeAllGroups: { id: 0x04, direction: "DIRECTION_SERVER_TO_CLIENT" }, + addGroupIfIdentify: { id: 0x05, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + groupId: ZCLDataType, + groupName: ZCLDataType, + }, + }, }; - BALLAST_CONFIGURATION: { - ID: number; - NAME: 'ballastConfiguration'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class GroupsCluster extends Cluster { + addGroup( + args: { + manufacturerId?: number, + groupId: number, + groupName: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + viewGroup( + args: { + manufacturerId?: number, + groupId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getGroupMembership( + args: { + manufacturerId?: number, + groupIds: Array, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + removeGroup( + args: { + manufacturerId?: number, + groupId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + removeAllGroups( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + addGroupIfIdentify( + args: { + manufacturerId?: number, + groupId: number, + groupName: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type ScenesClusterAttributes = Record; + type ScenesClusterCommands = Record; + class ScenesCluster extends Cluster { + } + type OnOffClusterAttributes = { + onOff: { id: 0x00, type: ZCLDataType }, + onTime: { id: 0x4001, type: ZCLDataType }, + offWaitTime: { id: 0x4002, type: ZCLDataType }, }; - BASIC: { - ID: number; - NAME: 'basic'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type OnOffClusterCommands = { + setOff: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT" }, + setOn: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT" }, + toggle: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT" }, + offWithEffect: { id: 0x40, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + effectIdentifier: ZCLDataType, + effectVariant: ZCLDataType, + }, + }, + onWithRecallGlobalScene: { id: 0x41, direction: "DIRECTION_SERVER_TO_CLIENT" }, + onWithTimedOff: { id: 0x42, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + onOffControl: ZCLDataType, + onTime: ZCLDataType, + offWaitTime: ZCLDataType, + }, + }, }; - BINARY_INPUT: { - ID: number; - NAME: 'binaryInput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class OnOffCluster extends Cluster { + setOff( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setOn( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + toggle( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + offWithEffect( + args: { + manufacturerId?: number, + effectIdentifier: number, + effectVariant: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onWithRecallGlobalScene( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onWithTimedOff( + args: { + manufacturerId?: number, + onOffControl: number, + onTime: number, + offWaitTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type OnOffSwitchClusterAttributes = Record; + type OnOffSwitchClusterCommands = Record; + class OnOffSwitchCluster extends Cluster { + } + type LevelControlClusterAttributes = { + currentLevel: { id: 0x00, type: ZCLDataType }, + remainingTime: { id: 0x01, type: ZCLDataType }, + onOffTransitionTime: { id: 0x10, type: ZCLDataType }, + onLevel: { id: 0x11, type: ZCLDataType }, + onTransitionTime: { id: 0x12, type: ZCLDataType }, + offTransitionTime: { id: 0x13, type: ZCLDataType }, + defaultMoveRate: { id: 0x14, type: ZCLDataType }, }; - BINARY_OUTPUT: { - ID: number; - NAME: 'binaryOutput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type LevelControlClusterCommands = { + moveToLevel: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + level: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + move: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + moveMode: ZCLDataType<"up" | "down">, + rate: ZCLDataType, + }, + }, + step: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + mode: ZCLDataType<"up" | "down">, + stepSize: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + stop: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT" }, + moveToLevelWithOnOff: { id: 0x04, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + level: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + moveWithOnOff: { id: 0x05, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + moveMode: ZCLDataType<"up" | "down">, + rate: ZCLDataType, + }, + }, + stepWithOnOff: { id: 0x06, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + mode: ZCLDataType<"up" | "down">, + stepSize: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + stopWithOnOff: { id: 0x07, direction: "DIRECTION_SERVER_TO_CLIENT" }, }; - BINARY_VALUE: { - ID: number; - NAME: 'binaryValue'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class LevelControlCluster extends Cluster { + moveToLevel( + args: { + manufacturerId?: number, + level: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + move( + args: { + manufacturerId?: number, + moveMode: "up" | "down", + rate: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + step( + args: { + manufacturerId?: number, + mode: "up" | "down", + stepSize: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + stop( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + moveToLevelWithOnOff( + args: { + manufacturerId?: number, + level: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + moveWithOnOff( + args: { + manufacturerId?: number, + moveMode: "up" | "down", + rate: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + stepWithOnOff( + args: { + manufacturerId?: number, + mode: "up" | "down", + stepSize: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + stopWithOnOff( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type AlarmsClusterAttributes = Record; + type AlarmsClusterCommands = { + resetAllAlarms: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT", args: Record /* TODO fix */ }, + getAlarm: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT", args: Record /* TODO fix */ }, + resetAlarmLog: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", args: Record /* TODO fix */ }, }; - COLOR_CONTROL: { - ID: number; - NAME: 'colorControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class AlarmsCluster extends Cluster { + resetAllAlarms( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getAlarm( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + resetAlarmLog( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type TimeClusterAttributes = Record; + type TimeClusterCommands = Record; + class TimeCluster extends Cluster { + } + type AnalogInputClusterAttributes = { + description: { id: 0x1c, type: ZCLDataType }, + maxPresentValue: { id: 0x41, type: ZCLDataType }, + minPresentValue: { id: 0x45, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "noSensor" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "noOutput" | "unreliableOther" | "processError" | "configurationError"> }, + resolution: { id: 0x6a, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - DEVICE_TEMPERATURE: { - ID: number; - NAME: 'deviceTemperature'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type AnalogInputClusterCommands = Record; + class AnalogInputCluster extends Cluster { + } + type AnalogOutputClusterAttributes = { + description: { id: 0x1c, type: ZCLDataType }, + maxPresentValue: { id: 0x41, type: ZCLDataType }, + minPresentValue: { id: 0x45, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "unreliableOther" | "processError" | "configurationError"> }, + relinquishDefault: { id: 0x68, type: ZCLDataType }, + resolution: { id: 0x6a, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - DIAGNOSTICS: { - ID: number; - NAME: 'diagnostics'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type AnalogOutputClusterCommands = Record; + class AnalogOutputCluster extends Cluster { + } + type AnalogValueClusterAttributes = { + description: { id: 0x1c, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "unreliableOther" | "processError" | "configurationError"> }, + relinquishDefault: { id: 0x68, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - DOOR_LOCK: { - ID: number; - NAME: 'doorLock'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type AnalogValueClusterCommands = Record; + class AnalogValueCluster extends Cluster { + } + type BinaryInputClusterAttributes = { + activeText: { id: 0x04, type: ZCLDataType }, + description: { id: 0x1c, type: ZCLDataType }, + inactiveText: { id: 0x2e, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + polarity: { id: 0x54, type: ZCLDataType<"normal" | "reverse"> }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "noSensor" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "noOutput" | "unreliableOther" | "processError" | "configurationError"> }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - ELECTRICAL_MEASUREMENT: { - ID: number; - NAME: 'electricalMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type BinaryInputClusterCommands = Record; + class BinaryInputCluster extends Cluster { + } + type BinaryOutputClusterAttributes = { + activeText: { id: 0x04, type: ZCLDataType }, + description: { id: 0x1c, type: ZCLDataType }, + inactiveText: { id: 0x2e, type: ZCLDataType }, + minimumOffTime: { id: 0x42, type: ZCLDataType }, + minimumOnTime: { id: 0x43, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + polarity: { id: 0x54, type: ZCLDataType<"normal" | "reverse"> }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "unreliableOther" | "processError" | "configurationError"> }, + relinquishDefault: { id: 0x68, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - FAN_CONTROL: { - ID: number; - NAME: 'fanControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type BinaryOutputClusterCommands = Record; + class BinaryOutputCluster extends Cluster { + } + type BinaryValueClusterAttributes = { + activeText: { id: 0x04, type: ZCLDataType }, + description: { id: 0x1c, type: ZCLDataType }, + inactiveText: { id: 0x2e, type: ZCLDataType }, + minimumOffTime: { id: 0x42, type: ZCLDataType }, + minimumOnTime: { id: 0x43, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + polarity: { id: 0x54, type: ZCLDataType<"normal" | "reverse"> }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "unreliableOther" | "processError" | "configurationError"> }, + relinquishDefault: { id: 0x68, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - FLOW_MEASUREMENT: { - ID: number; - NAME: 'flowMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type BinaryValueClusterCommands = Record; + class BinaryValueCluster extends Cluster { + } + type MultistateInputClusterAttributes = { + description: { id: 0x1c, type: ZCLDataType }, + numberOfStates: { id: 0x4a, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "noSensor" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "noOutput" | "unreliableOther" | "processError" | "multiStateFault" | "configurationError"> }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - GROUPS: { - ID: number; - NAME: 'groups'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type MultistateInputClusterCommands = Record; + class MultistateInputCluster extends Cluster { + } + type MultistateOutputClusterAttributes = { + description: { id: 0x1c, type: ZCLDataType }, + numberOfStates: { id: 0x4a, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "unreliableOther" | "processError" | "multiStateFault" | "configurationError"> }, + relinquishDefault: { id: 0x68, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - IAS_ACE: { - ID: number; - NAME: 'iasACE'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type MultistateOutputClusterCommands = Record; + class MultistateOutputCluster extends Cluster { + } + type MultistateValueClusterAttributes = { + description: { id: 0x1c, type: ZCLDataType }, + numberOfStates: { id: 0x4a, type: ZCLDataType }, + outOfService: { id: 0x51, type: ZCLDataType }, + presentValue: { id: 0x55, type: ZCLDataType }, + reliability: { id: 0x67, type: ZCLDataType<"noFaultDetected" | "noSensor" | "overRange" | "underRange" | "openLoop" | "shortedLoop" | "noOutput" | "unreliableOther" | "processError" | "multiStateFault" | "configurationError"> }, + relinquishDefault: { id: 0x68, type: ZCLDataType }, + statusFlags: { id: 0x6f, type: ZCLDataType> }, + applicationType: { id: 0x100, type: ZCLDataType }, }; - IAS_WD: { - ID: number; - NAME: 'iasWD'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type MultistateValueClusterCommands = Record; + class MultistateValueCluster extends Cluster { + } + type OTAClusterAttributes = { + upgradeServerID: { id: 0x00, type: ZCLDataType }, + fileOffset: { id: 0x01, type: ZCLDataType }, + currentFileVersion: { id: 0x02, type: ZCLDataType }, + currentZigBeeStackVersion: { id: 0x03, type: ZCLDataType }, + downloadedFileVersion: { id: 0x04, type: ZCLDataType }, + downloadedZigBeeStackVersion: { id: 0x05, type: ZCLDataType }, + imageUpgradeStatus: { id: 0x06, type: ZCLDataType<"normal" | "downloadInProgress" | "downloadComplete" | "waitingToUpgrade" | "countDown" | "waitForMore" | "waitingToUpgradeViaExternalEvent"> }, + manufacturerID: { id: 0x07, type: ZCLDataType }, + imageTypeID: { id: 0x08, type: ZCLDataType }, + minimumBlockPeriod: { id: 0x09, type: ZCLDataType }, + imageStamp: { id: 0x0a, type: ZCLDataType }, + upgradeActivationPolicy: { id: 0x0b, type: ZCLDataType<"otaServerActivationAllowed" | "outOfBandActivationOnly"> }, + upgradeTimeoutPolicy: { id: 0x0c, type: ZCLDataType<"applyUpgradeAfterTimeout" | "doNotApplyUpgradeAfterTimeout"> }, }; - IAS_ZONE: { - ID: number; - NAME: 'iasZone'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type OTAClusterCommands = { + imageNotify: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", frameControl: ["directionToClient","clusterSpecific","disableDefaultResponse"], encodeMissingFieldsBehavior: "skip", args: { + payloadType: ZCLDataType<"queryJitter" | "queryJitterAndManufacturerCode" | "queryJitterAndManufacturerCodeAndImageType" | "queryJitterAndManufacturerCodeAndImageTypeAndNewFileVersion">, + queryJitter: ZCLDataType, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + newFileVersion: ZCLDataType, + }, + }, + queryNextImageRequest: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT", encodeMissingFieldsBehavior: "skip", args: { + fieldControl: ZCLDataType>, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + hardwareVersion: ZCLDataType, + }, + }, + imageBlockRequest: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", encodeMissingFieldsBehavior: "skip", args: { + fieldControl: ZCLDataType>, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + fileOffset: ZCLDataType, + maximumDataSize: ZCLDataType, + requestNodeAddress: ZCLDataType, + minimumBlockPeriod: ZCLDataType, + }, + }, + imagePageRequest: { id: 0x04, direction: "DIRECTION_SERVER_TO_CLIENT", encodeMissingFieldsBehavior: "skip", args: { + fieldControl: ZCLDataType>, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + fileOffset: ZCLDataType, + maximumDataSize: ZCLDataType, + pageSize: ZCLDataType, + responseSpacing: ZCLDataType, + requestNodeAddress: ZCLDataType, + }, + }, + imageBlockResponse: { id: 0x05, direction: "DIRECTION_SERVER_TO_CLIENT", frameControl: ["directionToClient","clusterSpecific","disableDefaultResponse"], encodeMissingFieldsBehavior: "skip", args: { + status: ZCLDataType<"SUCCESS" | "FAILURE" | "NOT_AUTHORIZED" | "RESERVED_FIELD_NOT_ZERO" | "MALFORMED_COMMAND" | "UNSUP_CLUSTER_COMMAND" | "UNSUP_GENERAL_COMMAND" | "UNSUP_MANUF_CLUSTER_COMMAND" | "UNSUP_MANUF_GENERAL_COMMAND" | "INVALID_FIELD" | "UNSUPPORTED_ATTRIBUTE" | "INVALID_VALUE" | "READ_ONLY" | "INSUFFICIENT_SPACE" | "DUPLICATE_EXISTS" | "NOT_FOUND" | "UNREPORTABLE_ATTRIBUTE" | "INVALID_DATA_TYPE" | "INVALID_SELECTOR" | "WRITE_ONLY" | "INCONSISTENT_STARTUP_STATE" | "DEFINED_OUT_OF_BAND" | "INCONSISTENT" | "ACTION_DENIED" | "TIMEOUT" | "ABORT" | "INVALID_IMAGE" | "WAIT_FOR_DATA" | "NO_IMAGE_AVAILABLE" | "REQUIRE_MORE_IMAGE" | "NOTIFICATION_PENDING" | "HARDWARE_FAILURE" | "SOFTWARE_FAILURE" | "CALIBRATION_ERROR" | "UNSUPPORTED_CLUSTER">, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + fileOffset: ZCLDataType, + dataSize: ZCLDataType, + imageData: ZCLDataType, + currentTime: ZCLDataType, + requestTime: ZCLDataType, + minimumBlockPeriod: ZCLDataType, + }, + }, + upgradeEndRequest: { id: 0x06, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + status: ZCLDataType<"SUCCESS" | "FAILURE" | "NOT_AUTHORIZED" | "RESERVED_FIELD_NOT_ZERO" | "MALFORMED_COMMAND" | "UNSUP_CLUSTER_COMMAND" | "UNSUP_GENERAL_COMMAND" | "UNSUP_MANUF_CLUSTER_COMMAND" | "UNSUP_MANUF_GENERAL_COMMAND" | "INVALID_FIELD" | "UNSUPPORTED_ATTRIBUTE" | "INVALID_VALUE" | "READ_ONLY" | "INSUFFICIENT_SPACE" | "DUPLICATE_EXISTS" | "NOT_FOUND" | "UNREPORTABLE_ATTRIBUTE" | "INVALID_DATA_TYPE" | "INVALID_SELECTOR" | "WRITE_ONLY" | "INCONSISTENT_STARTUP_STATE" | "DEFINED_OUT_OF_BAND" | "INCONSISTENT" | "ACTION_DENIED" | "TIMEOUT" | "ABORT" | "INVALID_IMAGE" | "WAIT_FOR_DATA" | "NO_IMAGE_AVAILABLE" | "REQUIRE_MORE_IMAGE" | "NOTIFICATION_PENDING" | "HARDWARE_FAILURE" | "SOFTWARE_FAILURE" | "CALIBRATION_ERROR" | "UNSUPPORTED_CLUSTER">, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + }, + }, + upgradeEndResponse: { id: 0x07, direction: "DIRECTION_SERVER_TO_CLIENT", frameControl: ["directionToClient","clusterSpecific","disableDefaultResponse"], args: { + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + currentTime: ZCLDataType, + upgradeTime: ZCLDataType, + }, + }, + queryDeviceSpecificFileRequest: { id: 0x08, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + requestNodeAddress: ZCLDataType, + manufacturerCode: ZCLDataType, + imageType: ZCLDataType, + fileVersion: ZCLDataType, + zigBeeStackVersion: ZCLDataType, + }, + }, }; - IDENTIFY: { - ID: number; - NAME: 'identify'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class OTACluster extends Cluster { + onImageNotify( + args: { + manufacturerId?: number, + payloadType: "queryJitter" | "queryJitterAndManufacturerCode" | "queryJitterAndManufacturerCodeAndImageType" | "queryJitterAndManufacturerCodeAndImageTypeAndNewFileVersion", + queryJitter: number, + manufacturerCode: number, + imageType: number, + newFileVersion: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + queryNextImageRequest( + args: { + manufacturerId?: number, + fieldControl: BitMap<"hardwareVersionPresent">, + manufacturerCode: number, + imageType: number, + fileVersion: number, + hardwareVersion: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + imageBlockRequest( + args: { + manufacturerId?: number, + fieldControl: BitMap<"requestNodeAddressPresent" | "minimumBlockPeriodPresent">, + manufacturerCode: number, + imageType: number, + fileVersion: number, + fileOffset: number, + maximumDataSize: number, + requestNodeAddress: string, + minimumBlockPeriod: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + imagePageRequest( + args: { + manufacturerId?: number, + fieldControl: BitMap<"requestNodeAddressPresent">, + manufacturerCode: number, + imageType: number, + fileVersion: number, + fileOffset: number, + maximumDataSize: number, + pageSize: number, + responseSpacing: number, + requestNodeAddress: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onImageBlockResponse( + args: { + manufacturerId?: number, + status: "SUCCESS" | "FAILURE" | "NOT_AUTHORIZED" | "RESERVED_FIELD_NOT_ZERO" | "MALFORMED_COMMAND" | "UNSUP_CLUSTER_COMMAND" | "UNSUP_GENERAL_COMMAND" | "UNSUP_MANUF_CLUSTER_COMMAND" | "UNSUP_MANUF_GENERAL_COMMAND" | "INVALID_FIELD" | "UNSUPPORTED_ATTRIBUTE" | "INVALID_VALUE" | "READ_ONLY" | "INSUFFICIENT_SPACE" | "DUPLICATE_EXISTS" | "NOT_FOUND" | "UNREPORTABLE_ATTRIBUTE" | "INVALID_DATA_TYPE" | "INVALID_SELECTOR" | "WRITE_ONLY" | "INCONSISTENT_STARTUP_STATE" | "DEFINED_OUT_OF_BAND" | "INCONSISTENT" | "ACTION_DENIED" | "TIMEOUT" | "ABORT" | "INVALID_IMAGE" | "WAIT_FOR_DATA" | "NO_IMAGE_AVAILABLE" | "REQUIRE_MORE_IMAGE" | "NOTIFICATION_PENDING" | "HARDWARE_FAILURE" | "SOFTWARE_FAILURE" | "CALIBRATION_ERROR" | "UNSUPPORTED_CLUSTER", + manufacturerCode: number, + imageType: number, + fileVersion: number, + fileOffset: number, + dataSize: number, + imageData: Buffer, + currentTime: number, + requestTime: number, + minimumBlockPeriod: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + upgradeEndRequest( + args: { + manufacturerId?: number, + status: "SUCCESS" | "FAILURE" | "NOT_AUTHORIZED" | "RESERVED_FIELD_NOT_ZERO" | "MALFORMED_COMMAND" | "UNSUP_CLUSTER_COMMAND" | "UNSUP_GENERAL_COMMAND" | "UNSUP_MANUF_CLUSTER_COMMAND" | "UNSUP_MANUF_GENERAL_COMMAND" | "INVALID_FIELD" | "UNSUPPORTED_ATTRIBUTE" | "INVALID_VALUE" | "READ_ONLY" | "INSUFFICIENT_SPACE" | "DUPLICATE_EXISTS" | "NOT_FOUND" | "UNREPORTABLE_ATTRIBUTE" | "INVALID_DATA_TYPE" | "INVALID_SELECTOR" | "WRITE_ONLY" | "INCONSISTENT_STARTUP_STATE" | "DEFINED_OUT_OF_BAND" | "INCONSISTENT" | "ACTION_DENIED" | "TIMEOUT" | "ABORT" | "INVALID_IMAGE" | "WAIT_FOR_DATA" | "NO_IMAGE_AVAILABLE" | "REQUIRE_MORE_IMAGE" | "NOTIFICATION_PENDING" | "HARDWARE_FAILURE" | "SOFTWARE_FAILURE" | "CALIBRATION_ERROR" | "UNSUPPORTED_CLUSTER", + manufacturerCode: number, + imageType: number, + fileVersion: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onUpgradeEndResponse( + args: { + manufacturerId?: number, + manufacturerCode: number, + imageType: number, + fileVersion: number, + currentTime: number, + upgradeTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + queryDeviceSpecificFileRequest( + args: { + manufacturerId?: number, + requestNodeAddress: string, + manufacturerCode: number, + imageType: number, + fileVersion: number, + zigBeeStackVersion: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type PowerProfileClusterAttributes = Record; + type PowerProfileClusterCommands = Record; + class PowerProfileCluster extends Cluster { + } + type PollControlClusterAttributes = { + checkInInterval: { id: 0x00, type: ZCLDataType }, + longPollInterval: { id: 0x01, type: ZCLDataType }, + shortPollInterval: { id: 0x02, type: ZCLDataType }, + fastPollTimeout: { id: 0x03, type: ZCLDataType }, + checkInIntervalMin: { id: 0x04, type: ZCLDataType }, + longPollIntervalMin: { id: 0x05, type: ZCLDataType }, + fastPollTimeoutMax: { id: 0x06, type: ZCLDataType }, }; - ILLUMINANCE_LEVEL_SENSING: { - ID: number; - NAME: 'illuminanceLevelSensing'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type PollControlClusterCommands = { + fastPollStop: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT" }, + setLongPollInterval: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + newLongPollInterval: ZCLDataType, + }, + }, + setShortPollInterval: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + newShortPollInterval: ZCLDataType, + }, + }, }; - ILLUMINANCE_MEASUREMENT: { - ID: number; - NAME: 'illuminanceMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class PollControlCluster extends Cluster { + fastPollStop( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setLongPollInterval( + args: { + manufacturerId?: number, + newLongPollInterval: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setShortPollInterval( + args: { + manufacturerId?: number, + newShortPollInterval: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type ShadeConfigurationClusterAttributes = Record; + type ShadeConfigurationClusterCommands = Record; + class ShadeConfigurationCluster extends Cluster { + } + type DoorLockClusterAttributes = { + lockState: { id: 0x00, type: ZCLDataType<"notFullyLocked" | "locked" | "unlocked" | "undefined"> }, + lockType: { id: 0x01, type: ZCLDataType<"deadBolt" | "magnetic" | "other" | "mortise" | "rim" | "latchBolt" | "cylindricalLock" | "tubularLock" | "interconnectedLock" | "deadLatch" | "doorFurniture"> }, + actuatorEnabled: { id: 0x02, type: ZCLDataType }, + doorState: { id: 0x03, type: ZCLDataType<"open" | "closed" | "errorJammed" | "errorForcedOpen" | "errorUnspecified" | "undefined"> }, + doorOpenEvents: { id: 0x04, type: ZCLDataType }, + doorClosedEvents: { id: 0x05, type: ZCLDataType }, + openPeriod: { id: 0x06, type: ZCLDataType }, + numberOfLogRecordsSupported: { id: 0x10, type: ZCLDataType }, + numberOfTotalUsersSupported: { id: 0x11, type: ZCLDataType }, + numberOfPINUsersSupported: { id: 0x12, type: ZCLDataType }, + numberOfRFIDUsersSupported: { id: 0x13, type: ZCLDataType }, + numberOfWeekDaySchedulesSupportedPerUser: { id: 0x14, type: ZCLDataType }, + numberOfYearDaySchedulesSupportedPerUser: { id: 0x15, type: ZCLDataType }, + numberOfHolidaySchedulesSupported: { id: 0x16, type: ZCLDataType }, + maxPINCodeLength: { id: 0x17, type: ZCLDataType }, + minPINCodeLength: { id: 0x18, type: ZCLDataType }, + maxRFIDCodeLength: { id: 0x19, type: ZCLDataType }, + minRFIDCodeLength: { id: 0x1a, type: ZCLDataType }, + enableLogging: { id: 0x20, type: ZCLDataType }, + language: { id: 0x21, type: ZCLDataType }, + ledSettings: { id: 0x22, type: ZCLDataType }, + autoRelockTime: { id: 0x23, type: ZCLDataType }, + soundVolume: { id: 0x24, type: ZCLDataType }, + operatingMode: { id: 0x25, type: ZCLDataType<"normal" | "vacation" | "privacy" | "noRFLockOrUnlock" | "passage"> }, + supportedOperatingModes: { id: 0x26, type: ZCLDataType> }, + defaultConfigurationRegister: { id: 0x27, type: ZCLDataType> }, + enableLocalProgramming: { id: 0x28, type: ZCLDataType }, + enableOneTouchLocking: { id: 0x29, type: ZCLDataType }, + enableInsideStatusLED: { id: 0x2a, type: ZCLDataType }, + enablePrivacyModeButton: { id: 0x2b, type: ZCLDataType }, + wrongCodeEntryLimit: { id: 0x30, type: ZCLDataType }, + userCodeTemporaryDisableTime: { id: 0x31, type: ZCLDataType }, + sendPINOverTheAir: { id: 0x32, type: ZCLDataType }, + requirePINforRFOperation: { id: 0x33, type: ZCLDataType }, + securityLevel: { id: 0x34, type: ZCLDataType<"network" | "apsSecurity"> }, + alarmMask: { id: 0x40, type: ZCLDataType> }, + keypadOperationEventMask: { id: 0x41, type: ZCLDataType> }, + rfOperationEventMask: { id: 0x42, type: ZCLDataType> }, + manualOperationEventMask: { id: 0x43, type: ZCLDataType> }, + rfidOperationEventMask: { id: 0x44, type: ZCLDataType> }, + keypadProgrammingEventMask: { id: 0x45, type: ZCLDataType> }, + rfProgrammingEventMask: { id: 0x46, type: ZCLDataType> }, + rfidProgrammingEventMask: { id: 0x47, type: ZCLDataType> }, }; - LEVEL_CONTROL: { - ID: number; - NAME: 'levelControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type DoorLockClusterCommands = { + lockDoor: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + pinCode: ZCLDataType, + }, + }, + unlockDoor: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + pinCode: ZCLDataType, + }, + }, + toggle: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + pinCode: ZCLDataType, + }, + }, + unlockWithTimeout: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + timeout: ZCLDataType, + pinCode: ZCLDataType, + }, + }, + getLogRecord: { id: 0x04, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + logIndex: ZCLDataType, + }, + }, + setPINCode: { id: 0x05, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + userStatus: ZCLDataType<"available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported">, + userType: ZCLDataType<"unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported">, + pinCode: ZCLDataType, + }, + }, + getPINCode: { id: 0x06, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + }, + }, + clearPINCode: { id: 0x07, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + }, + }, + clearAllPINCodes: { id: 0x08, direction: "DIRECTION_SERVER_TO_CLIENT" }, + setUserStatus: { id: 0x09, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + userStatus: ZCLDataType<"available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported">, + }, + }, + getUserStatus: { id: 0x0a, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + }, + }, + setWeekDaySchedule: { id: 0x0b, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + scheduleId: ZCLDataType, + userId: ZCLDataType, + daysMask: ZCLDataType>, + startHour: ZCLDataType, + startMinute: ZCLDataType, + endHour: ZCLDataType, + endMinute: ZCLDataType, + }, + }, + getWeekDaySchedule: { id: 0x0c, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + scheduleId: ZCLDataType, + userId: ZCLDataType, + }, + }, + clearWeekDaySchedule: { id: 0x0d, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + scheduleId: ZCLDataType, + userId: ZCLDataType, + }, + }, + setYearDaySchedule: { id: 0x0e, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + scheduleId: ZCLDataType, + userId: ZCLDataType, + localStartTime: ZCLDataType, + localEndTime: ZCLDataType, + }, + }, + getYearDaySchedule: { id: 0x0f, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + scheduleId: ZCLDataType, + userId: ZCLDataType, + }, + }, + clearYearDaySchedule: { id: 0x10, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + scheduleId: ZCLDataType, + userId: ZCLDataType, + }, + }, + setHolidaySchedule: { id: 0x11, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + holidayScheduleId: ZCLDataType, + localStartTime: ZCLDataType, + localEndTime: ZCLDataType, + operatingModeDuringHoliday: ZCLDataType<"normal" | "vacation" | "privacy" | "noRFLockOrUnlock" | "passage">, + }, + }, + getHolidaySchedule: { id: 0x12, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + holidayScheduleId: ZCLDataType, + }, + }, + clearHolidaySchedule: { id: 0x13, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + holidayScheduleId: ZCLDataType, + }, + }, + setUserType: { id: 0x14, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + userType: ZCLDataType<"unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported">, + }, + }, + getUserType: { id: 0x15, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + }, + }, + setRFIDCode: { id: 0x16, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + userStatus: ZCLDataType<"available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported">, + userType: ZCLDataType<"unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported">, + rfidCode: ZCLDataType, + }, + }, + getRFIDCode: { id: 0x17, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + }, + }, + clearRFIDCode: { id: 0x18, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + userId: ZCLDataType, + }, + }, + clearAllRFIDCodes: { id: 0x19, direction: "DIRECTION_SERVER_TO_CLIENT" }, + operationEventNotification: { id: 0x20, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + operationEventSource: ZCLDataType, + operationEventCode: ZCLDataType, + userId: ZCLDataType, + pin: ZCLDataType, + zigBeeLocalTime: ZCLDataType, + data: ZCLDataType, + }, + }, + programmingEventNotification: { id: 0x21, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + programEventSource: ZCLDataType, + programEventCode: ZCLDataType, + userId: ZCLDataType, + pin: ZCLDataType, + userType: ZCLDataType<"unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported">, + userStatus: ZCLDataType<"available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported">, + zigBeeLocalTime: ZCLDataType, + data: ZCLDataType, + }, + }, }; - METERING: { - ID: number; - NAME: 'metering'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class DoorLockCluster extends Cluster { + lockDoor( + args: { + manufacturerId?: number, + pinCode: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + unlockDoor( + args: { + manufacturerId?: number, + pinCode: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + toggle( + args: { + manufacturerId?: number, + pinCode: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + unlockWithTimeout( + args: { + manufacturerId?: number, + timeout: number, + pinCode: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getLogRecord( + args: { + manufacturerId?: number, + logIndex: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setPINCode( + args: { + manufacturerId?: number, + userId: number, + userStatus: "available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported", + userType: "unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported", + pinCode: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getPINCode( + args: { + manufacturerId?: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearPINCode( + args: { + manufacturerId?: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearAllPINCodes( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setUserStatus( + args: { + manufacturerId?: number, + userId: number, + userStatus: "available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported", + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getUserStatus( + args: { + manufacturerId?: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setWeekDaySchedule( + args: { + manufacturerId?: number, + scheduleId: number, + userId: number, + daysMask: BitMap<"sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday">, + startHour: number, + startMinute: number, + endHour: number, + endMinute: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getWeekDaySchedule( + args: { + manufacturerId?: number, + scheduleId: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearWeekDaySchedule( + args: { + manufacturerId?: number, + scheduleId: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setYearDaySchedule( + args: { + manufacturerId?: number, + scheduleId: number, + userId: number, + localStartTime: number, + localEndTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getYearDaySchedule( + args: { + manufacturerId?: number, + scheduleId: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearYearDaySchedule( + args: { + manufacturerId?: number, + scheduleId: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setHolidaySchedule( + args: { + manufacturerId?: number, + holidayScheduleId: number, + localStartTime: number, + localEndTime: number, + operatingModeDuringHoliday: "normal" | "vacation" | "privacy" | "noRFLockOrUnlock" | "passage", + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getHolidaySchedule( + args: { + manufacturerId?: number, + holidayScheduleId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearHolidaySchedule( + args: { + manufacturerId?: number, + holidayScheduleId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setUserType( + args: { + manufacturerId?: number, + userId: number, + userType: "unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported", + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getUserType( + args: { + manufacturerId?: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + setRFIDCode( + args: { + manufacturerId?: number, + userId: number, + userStatus: "available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported", + userType: "unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported", + rfidCode: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + getRFIDCode( + args: { + manufacturerId?: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearRFIDCode( + args: { + manufacturerId?: number, + userId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + clearAllRFIDCodes( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onOperationEventNotification( + args: { + manufacturerId?: number, + operationEventSource: number, + operationEventCode: number, + userId: number, + pin: string, + zigBeeLocalTime: number, + data: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onProgrammingEventNotification( + args: { + manufacturerId?: number, + programEventSource: number, + programEventCode: number, + userId: number, + pin: string, + userType: "unrestricted" | "yearDayScheduleUser" | "weekDayScheduleUser" | "masterUser" | "nonAccessUser" | "notSupported", + userStatus: "available" | "occupiedEnabled" | "occupiedDisabled" | "notSupported", + zigBeeLocalTime: number, + data: string, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type WindowCoveringClusterAttributes = { + windowCoveringType: { id: 0x00, type: ZCLDataType<"rollershade" | "rollershade2Motor" | "rollershadeExterior" | "rollershadeExterior2Motor" | "drapery" | "awning" | "shutter" | "tiltBlindTiltOnly" | "tiltBlindLiftAndTilt" | "projectorScreen"> }, + physicalClosedLimitLift: { id: 0x01, type: ZCLDataType }, + physicalClosedLimitTilt: { id: 0x02, type: ZCLDataType }, + currentPositionLift: { id: 0x03, type: ZCLDataType }, + currentPositionTilt: { id: 0x04, type: ZCLDataType }, + numberofActuationsLift: { id: 0x05, type: ZCLDataType }, + numberofActuationsTilt: { id: 0x06, type: ZCLDataType }, + configStatus: { id: 0x07, type: ZCLDataType> }, + currentPositionLiftPercentage: { id: 0x08, type: ZCLDataType }, + currentPositionTiltPercentage: { id: 0x09, type: ZCLDataType }, + installedOpenLimitLift: { id: 0x10, type: ZCLDataType }, + installedClosedLimitLift: { id: 0x11, type: ZCLDataType }, + installedOpenLimitTilt: { id: 0x12, type: ZCLDataType }, + installedClosedLimitTilt: { id: 0x13, type: ZCLDataType }, + velocityLift: { id: 0x14, type: ZCLDataType }, + accelerationTimeLift: { id: 0x15, type: ZCLDataType }, + decelerationTimeLift: { id: 0x16, type: ZCLDataType }, + mode: { id: 0x17, type: ZCLDataType> }, + intermediateSetpointsLift: { id: 0x18, type: ZCLDataType }, + intermediateSetpointsTilt: { id: 0x19, type: ZCLDataType }, }; - MULTI_STATE_INPUT: { - ID: number; - NAME: 'multistateInput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type WindowCoveringClusterCommands = { + upOpen: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT" }, + downClose: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT" }, + stop: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT" }, + goToLiftValue: { id: 0x04, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + liftValue: ZCLDataType, + }, + }, + goToLiftPercentage: { id: 0x05, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + percentageLiftValue: ZCLDataType, + }, + }, + goToTiltValue: { id: 0x07, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + tiltValue: ZCLDataType, + }, + }, + goToTiltPercentage: { id: 0x08, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + percentageTiltValue: ZCLDataType, + }, + }, }; - MULTI_STATE_OUTPUT: { - ID: number; - NAME: 'multistateOutput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class WindowCoveringCluster extends Cluster { + upOpen( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + downClose( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + stop( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + goToLiftValue( + args: { + manufacturerId?: number, + liftValue: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + goToLiftPercentage( + args: { + manufacturerId?: number, + percentageLiftValue: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + goToTiltValue( + args: { + manufacturerId?: number, + tiltValue: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + goToTiltPercentage( + args: { + manufacturerId?: number, + percentageTiltValue: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type ThermostatClusterAttributes = { + localTemperature: { id: 0x00, type: ZCLDataType }, + outdoorTemperature: { id: 0x01, type: ZCLDataType }, + occupancy: { id: 0x02, type: ZCLDataType> }, + absMinHeatSetpointLimit: { id: 0x03, type: ZCLDataType }, + absMaxHeatSetpointLimit: { id: 0x04, type: ZCLDataType }, + absMinCoolSetpointLimit: { id: 0x05, type: ZCLDataType }, + absMaxCoolSetpointLimit: { id: 0x06, type: ZCLDataType }, + pICoolingDemand: { id: 0x07, type: ZCLDataType }, + pIHeatingDemand: { id: 0x08, type: ZCLDataType }, + localTemperatureCalibration: { id: 0x10, type: ZCLDataType }, + occupiedCoolingSetpoint: { id: 0x11, type: ZCLDataType }, + occupiedHeatingSetpoint: { id: 0x12, type: ZCLDataType }, + unoccupiedCoolingSetpoint: { id: 0x13, type: ZCLDataType }, + unoccupiedHeatingSetpoint: { id: 0x14, type: ZCLDataType }, + minHeatSetpointLimit: { id: 0x15, type: ZCLDataType }, + maxHeatSetpointLimit: { id: 0x16, type: ZCLDataType }, + minCoolSetpointLimit: { id: 0x17, type: ZCLDataType }, + maxCoolSetpointLimit: { id: 0x18, type: ZCLDataType }, + minSetpointDeadBand: { id: 0x19, type: ZCLDataType }, + remoteSensing: { id: 0x1a, type: ZCLDataType> }, + controlSequenceOfOperation: { id: 0x1b, type: ZCLDataType<"cooling" | "coolingWithReheat" | "heating" | "heatingWithReheat" | "coolingAndHeating4Pipes" | "coolingAndHeating4PipesWithReheat"> }, + systemMode: { id: 0x1c, type: ZCLDataType<"off" | "auto" | "cool" | "heat" | "emergencyHeating" | "precooling" | "fanOnly" | "dry" | "sleep"> }, + alarmMask: { id: 0x1d, type: ZCLDataType> }, }; - MULTI_STATE_VALUE: { - ID: number; - NAME: 'multistateValue'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type ThermostatClusterCommands = { + setSetpoint: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + mode: ZCLDataType<"heat" | "cool" | "both">, + amount: ZCLDataType, + }, + }, }; - OCCUPANCY_SENSING: { - ID: number; - NAME: 'occupancySensing'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class ThermostatCluster extends Cluster { + setSetpoint( + args: { + manufacturerId?: number, + mode: "heat" | "cool" | "both", + amount: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type PumpConfigurationAndControlClusterAttributes = Record; + type PumpConfigurationAndControlClusterCommands = Record; + class PumpConfigurationAndControlCluster extends Cluster { + } + type FanControlClusterAttributes = Record; + type FanControlClusterCommands = Record; + class FanControlCluster extends Cluster { + } + type DehumidificationControlClusterAttributes = Record; + type DehumidificationControlClusterCommands = Record; + class DehumidificationControlCluster extends Cluster { + } + type ColorControlClusterAttributes = { + currentHue: { id: 0x00, type: ZCLDataType }, + currentSaturation: { id: 0x01, type: ZCLDataType }, + currentX: { id: 0x03, type: ZCLDataType }, + currentY: { id: 0x04, type: ZCLDataType }, + colorTemperatureMireds: { id: 0x07, type: ZCLDataType }, + colorMode: { id: 0x08, type: ZCLDataType<"currentHueAndCurrentSaturation" | "currentXAndCurrentY" | "colorTemperatureMireds"> }, + colorCapabilities: { id: 0x400a, type: ZCLDataType> }, + colorTempPhysicalMinMireds: { id: 0x400b, type: ZCLDataType }, + colorTempPhysicalMaxMireds: { id: 0x400c, type: ZCLDataType }, }; - ON_OFF: { - ID: number; - NAME: 'onOff'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type ColorControlClusterCommands = { + moveToHue: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + hue: ZCLDataType, + direction: ZCLDataType<"shortestDistance" | "longestDistance" | "up" | "down">, + transitionTime: ZCLDataType, + }, + }, + moveToSaturation: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + saturation: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + moveToHueAndSaturation: { id: 0x06, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + hue: ZCLDataType, + saturation: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + moveToColor: { id: 0x07, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + colorX: ZCLDataType, + colorY: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, + moveToColorTemperature: { id: 0x0a, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + colorTemperature: ZCLDataType, + transitionTime: ZCLDataType, + }, + }, }; - ON_OFF_SWITCH: { - ID: number; - NAME: 'onOffSwitch'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class ColorControlCluster extends Cluster { + moveToHue( + args: { + manufacturerId?: number, + hue: number, + direction: "shortestDistance" | "longestDistance" | "up" | "down", + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + moveToSaturation( + args: { + manufacturerId?: number, + saturation: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + moveToHueAndSaturation( + args: { + manufacturerId?: number, + hue: number, + saturation: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + moveToColor( + args: { + manufacturerId?: number, + colorX: number, + colorY: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + moveToColorTemperature( + args: { + manufacturerId?: number, + colorTemperature: number, + transitionTime: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type BallastConfigurationClusterAttributes = { + physicalMinLevel: { id: 0x00, type: ZCLDataType }, + physicalMaxLevel: { id: 0x01, type: ZCLDataType }, + ballastStatus: { id: 0x02, type: ZCLDataType> }, + minLevel: { id: 0x10, type: ZCLDataType }, + maxLevel: { id: 0x11, type: ZCLDataType }, + powerOnLevel: { id: 0x12, type: ZCLDataType }, + powerOnFadeTime: { id: 0x13, type: ZCLDataType }, + intrinsicBallastFactor: { id: 0x14, type: ZCLDataType }, + ballastFactorAdjustment: { id: 0x15, type: ZCLDataType }, + lampQuantity: { id: 0x20, type: ZCLDataType }, + lampType: { id: 0x30, type: ZCLDataType }, + lampManufacturer: { id: 0x31, type: ZCLDataType }, + lampRatedHours: { id: 0x32, type: ZCLDataType }, + lampBurnHours: { id: 0x33, type: ZCLDataType }, + lampAlarmMode: { id: 0x34, type: ZCLDataType> }, + lampBurnHoursTripPoint: { id: 0x35, type: ZCLDataType }, }; - OTA: { - ID: number; - NAME: 'ota'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type BallastConfigurationClusterCommands = Record; + class BallastConfigurationCluster extends Cluster { + } + type IlluminanceMeasurementClusterAttributes = { + measuredValue: { id: 0x00, type: ZCLDataType }, + minMeasuredValue: { id: 0x01, type: ZCLDataType }, + maxMeasuredValue: { id: 0x02, type: ZCLDataType }, + tolerance: { id: 0x03, type: ZCLDataType }, + lightSensorType: { id: 0x04, type: ZCLDataType<"photodiode" | "cmos" | "unknown"> }, }; - POLL_CONTROL: { - ID: number; - NAME: 'pollControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type IlluminanceMeasurementClusterCommands = Record; + class IlluminanceMeasurementCluster extends Cluster { + } + type IlluminanceLevelSensingClusterAttributes = { + levelStatus: { id: 0x00, type: ZCLDataType<"illuminanceOnTarget" | "illuminanceBelowTarget" | "illuminanceAboveTarget"> }, + lightSensorType: { id: 0x01, type: ZCLDataType<"photodiode" | "cmos" | "unknown"> }, + illuminanceTargetLevel: { id: 0x10, type: ZCLDataType }, }; - POWER_CONFIGURATION: { - ID: number; - NAME: 'powerConfiguration'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type IlluminanceLevelSensingClusterCommands = Record; + class IlluminanceLevelSensingCluster extends Cluster { + } + type TemperatureMeasurementClusterAttributes = { + measuredValue: { id: 0x00, type: ZCLDataType }, + minMeasuredValue: { id: 0x01, type: ZCLDataType }, + maxMeasuredValue: { id: 0x02, type: ZCLDataType }, }; - POWER_PROFILE: { - ID: number; - NAME: 'powerProfile'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type TemperatureMeasurementClusterCommands = Record; + class TemperatureMeasurementCluster extends Cluster { + } + type PressureMeasurementClusterAttributes = { + measuredValue: { id: 0x00, type: ZCLDataType }, + minMeasuredValue: { id: 0x01, type: ZCLDataType }, + maxMeasuredValue: { id: 0x02, type: ZCLDataType }, + tolerance: { id: 0x03, type: ZCLDataType }, + scaledValue: { id: 0x10, type: ZCLDataType }, + minScaledValue: { id: 0x11, type: ZCLDataType }, + maxScaledValue: { id: 0x12, type: ZCLDataType }, + scaledTolerance: { id: 0x13, type: ZCLDataType }, + scale: { id: 0x14, type: ZCLDataType }, }; - PRESSURE_MEASUREMENT: { - ID: number; - NAME: 'pressureMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type PressureMeasurementClusterCommands = Record; + class PressureMeasurementCluster extends Cluster { + } + type FlowMeasurementClusterAttributes = { + measuredValue: { id: 0x00, type: ZCLDataType }, + minMeasuredValue: { id: 0x01, type: ZCLDataType }, + maxMeasuredValue: { id: 0x02, type: ZCLDataType }, + tolerance: { id: 0x03, type: ZCLDataType }, }; - PUMP_CONFIGURATION_AND_CONTROL: { - ID: number; - NAME: 'pumpConfigurationAndControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type FlowMeasurementClusterCommands = Record; + class FlowMeasurementCluster extends Cluster { + } + type RelativeHumidityClusterAttributes = { + measuredValue: { id: 0x00, type: ZCLDataType }, + minMeasuredValue: { id: 0x01, type: ZCLDataType }, + maxMeasuredValue: { id: 0x02, type: ZCLDataType }, + tolerance: { id: 0x03, type: ZCLDataType }, }; - RELATIVE_HUMIDITY_MEASUREMENT: { - ID: number; - NAME: 'relativeHumidity'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type RelativeHumidityClusterCommands = Record; + class RelativeHumidityCluster extends Cluster { + } + type OccupancySensingClusterAttributes = { + occupancy: { id: 0x00, type: ZCLDataType> }, + occupancySensorType: { id: 0x01, type: ZCLDataType<"pir" | "ultrasonic" | "pirAndUltrasonic" | "physicalContact"> }, + occupancySensorTypeBitmap: { id: 0x02, type: ZCLDataType> }, + pirOccupiedToUnoccupiedDelay: { id: 0x10, type: ZCLDataType }, + pirUnoccupiedToOccupiedDelay: { id: 0x11, type: ZCLDataType }, + pirUnoccupiedToOccupiedThreshold: { id: 0x12, type: ZCLDataType }, + ultrasonicOccupiedToUnoccupiedDelay: { id: 0x20, type: ZCLDataType }, + ultrasonicUnoccupiedToOccupiedDelay: { id: 0x21, type: ZCLDataType }, + ultrasonicUnoccupiedToOccupiedThreshold: { id: 0x22, type: ZCLDataType }, + physicalContactOccupiedToUnoccupiedDelay: { id: 0x30, type: ZCLDataType }, + physicalContactUnoccupiedToOccupiedDelay: { id: 0x31, type: ZCLDataType }, + physicalContactUnoccupiedToOccupiedThreshold: { id: 0x32, type: ZCLDataType }, }; - SCENES: { - ID: number; - NAME: 'scenes'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type OccupancySensingClusterCommands = Record; + class OccupancySensingCluster extends Cluster { + } + type IASZoneClusterAttributes = { + zoneState: { id: 0x00, type: ZCLDataType<"notEnrolled" | "enrolled"> }, + zoneType: { id: 0x01, type: ZCLDataType<"standardCIE" | "motionSensor" | "contactSwitch" | "doorWindowHandle" | "fireSensor" | "waterSensor" | "carbonMonoxideSensor" | "personalEmergencyDevice" | "vibrationMovementSensor" | "remoteControl" | "keyFob" | "keypad" | "standardWarningDevice" | "glassBreakSensor" | "securityRepeater" | "invalidZoneType"> }, + zoneStatus: { id: 0x02, type: ZCLDataType> }, + iasCIEAddress: { id: 0x10, type: ZCLDataType }, + zoneId: { id: 0x11, type: ZCLDataType }, }; - SHADE_CONFIGURATION: { - ID: number; - NAME: 'shadeConfiguration'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type IASZoneClusterCommands = { + zoneStatusChangeNotification: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + zoneStatus: ZCLDataType>, + extendedStatus: ZCLDataType, + zoneId: ZCLDataType, + delay: ZCLDataType, + }, + }, + zoneEnrollResponse: { id: 0x00, direction: "DIRECTION_CLIENT_TO_SERVER", args: { + enrollResponseCode: ZCLDataType<"success" | "notSupported" | "noEnrollPermit" | "tooManyZones">, + zoneId: ZCLDataType, + }, + }, + zoneEnrollRequest: { id: 0x01, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + zoneType: ZCLDataType<"standardCIE" | "motionSensor" | "contactSwitch" | "doorWindowHandle" | "fireSensor" | "waterSensor" | "carbonMonoxideSensor" | "personalEmergencyDevice" | "vibrationMovementSensor" | "remoteControl" | "keyFob" | "keypad" | "standardWarningDevice" | "glassBreakSensor" | "securityRepeater" | "invalidZoneType">, + manufacturerCode: ZCLDataType, + }, + }, + initiateNormalOperationMode: { id: 0x01, direction: "DIRECTION_CLIENT_TO_SERVER" }, }; - TEMPERATURE_MEASUREMENT: { - ID: number; - NAME: 'temperatureMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class IASZoneCluster extends Cluster { + onZoneStatusChangeNotification( + args: { + manufacturerId?: number, + zoneStatus: BitMap<"alarm1" | "alarm2" | "tamper" | "battery" | "supervisionReports" | "restoreReports" | "trouble" | "acMains" | "test" | "batteryDefect">, + extendedStatus: number, + zoneId: number, + delay: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + zoneEnrollResponse( + args: { + manufacturerId?: number, + enrollResponseCode: "success" | "notSupported" | "noEnrollPermit" | "tooManyZones", + zoneId: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + onZoneEnrollRequest( + args: { + manufacturerId?: number, + zoneType: "standardCIE" | "motionSensor" | "contactSwitch" | "doorWindowHandle" | "fireSensor" | "waterSensor" | "carbonMonoxideSensor" | "personalEmergencyDevice" | "vibrationMovementSensor" | "remoteControl" | "keyFob" | "keypad" | "standardWarningDevice" | "glassBreakSensor" | "securityRepeater" | "invalidZoneType", + manufacturerCode: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + initiateNormalOperationMode( + args: { + manufacturerId?: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + type IASACEClusterAttributes = Record; + type IASACEClusterCommands = Record; + class IASACECluster extends Cluster { + } + type IASWDClusterAttributes = Record; + type IASWDClusterCommands = Record; + class IASWDCluster extends Cluster { + } + type MeteringClusterAttributes = { + currentSummationDelivered: { id: 0x00, type: ZCLDataType }, + currentSummationReceived: { id: 0x01, type: ZCLDataType }, + currentMaxDemandDelivered: { id: 0x02, type: ZCLDataType }, + currentMaxDemandReceived: { id: 0x03, type: ZCLDataType }, + dftSummation: { id: 0x04, type: ZCLDataType }, + dailyFreezeTime: { id: 0x05, type: ZCLDataType }, + powerFactor: { id: 0x06, type: ZCLDataType }, + readingSnapShotTime: { id: 0x07, type: ZCLDataType }, + currentMaxDemandDeliveredTime: { id: 0x08, type: ZCLDataType }, + currentMaxDemandReceivedTime: { id: 0x09, type: ZCLDataType }, + defaultUpdatePeriod: { id: 0x0a, type: ZCLDataType }, + fastPollUpdatePeriod: { id: 0x0b, type: ZCLDataType }, + currentBlockPeriodConsumptionDelivered: { id: 0x0c, type: ZCLDataType }, + dailyConsumptionTarget: { id: 0x0d, type: ZCLDataType }, + currentBlock: { id: 0x0e, type: ZCLDataType }, + profileIntervalPeriod: { id: 0x0f, type: ZCLDataType }, + currentTier1SummationDelivered: { id: 0x100, type: ZCLDataType }, + currentTier1SummationReceived: { id: 0x101, type: ZCLDataType }, + currentTier2SummationDelivered: { id: 0x102, type: ZCLDataType }, + currentTier2SummationReceived: { id: 0x103, type: ZCLDataType }, + currentTier3SummationDelivered: { id: 0x104, type: ZCLDataType }, + currentTier3SummationReceived: { id: 0x105, type: ZCLDataType }, + currentTier4SummationDelivered: { id: 0x106, type: ZCLDataType }, + currentTier4SummationReceived: { id: 0x107, type: ZCLDataType }, + status: { id: 0x200, type: ZCLDataType> }, + remainingBatteryLife: { id: 0x201, type: ZCLDataType }, + hoursInOperation: { id: 0x202, type: ZCLDataType }, + hoursInFault: { id: 0x203, type: ZCLDataType }, + unitOfMeasure: { id: 0x300, type: ZCLDataType }, + multiplier: { id: 0x301, type: ZCLDataType }, + divisor: { id: 0x302, type: ZCLDataType }, + siteId: { id: 0x307, type: ZCLDataType }, + meterSerialNumber: { id: 0x308, type: ZCLDataType }, + energyCarrierUnitOfMeasure: { id: 0x309, type: ZCLDataType }, + temperatureUnitOfMeasure: { id: 0x30c, type: ZCLDataType }, + moduleSerialNumber: { id: 0x30e, type: ZCLDataType }, + operatingTariffLabelDelivered: { id: 0x30f, type: ZCLDataType }, + operatingTariffLabelReceived: { id: 0x310, type: ZCLDataType }, + customerIdNumber: { id: 0x311, type: ZCLDataType }, + alternativeUnitOfMeasure: { id: 0x312, type: ZCLDataType }, + instantaneousDemand: { id: 0x400, type: ZCLDataType }, + currentDayConsumptionDelivered: { id: 0x401, type: ZCLDataType }, + currentDayConsumptionReceived: { id: 0x402, type: ZCLDataType }, + previousDayConsumptionDelivered: { id: 0x403, type: ZCLDataType }, + previousDayConsumptionReceived: { id: 0x404, type: ZCLDataType }, + currentPartialProfileIntervalStartTimeDelivered: { id: 0x405, type: ZCLDataType }, + currentPartialProfileIntervalStartTimeReceived: { id: 0x406, type: ZCLDataType }, + currentPartialProfileIntervalValueDelivered: { id: 0x407, type: ZCLDataType }, + currentPartialProfileIntervalValueReceived: { id: 0x408, type: ZCLDataType }, + currentDayMaxPressure: { id: 0x409, type: ZCLDataType }, + currentDayMinPressure: { id: 0x40a, type: ZCLDataType }, + previousDayMaxPressure: { id: 0x40b, type: ZCLDataType }, + previousDayMinPressure: { id: 0x40c, type: ZCLDataType }, + currentDayMaxDemand: { id: 0x40d, type: ZCLDataType }, + previousDayMaxDemand: { id: 0x40e, type: ZCLDataType }, + currentMonthMaxDemand: { id: 0x40f, type: ZCLDataType }, + currentYearMaxDemand: { id: 0x410, type: ZCLDataType }, + currentDayMaxEnergyCarrierDemand: { id: 0x411, type: ZCLDataType }, + previousDayMaxEnergyCarrierDemand: { id: 0x412, type: ZCLDataType }, + currentMonthMaxEnergyCarrierDemand: { id: 0x413, type: ZCLDataType }, + currentMonthMinEnergyCarrierDemand: { id: 0x414, type: ZCLDataType }, + currentYearMaxEnergyCarrierDemand: { id: 0x415, type: ZCLDataType }, + currentYearMinEnergyCarrierDemand: { id: 0x416, type: ZCLDataType }, + maxNumberOfPeriodsDelivered: { id: 0x500, type: ZCLDataType }, + currentDemandDelivered: { id: 0x600, type: ZCLDataType }, + demandLimit: { id: 0x601, type: ZCLDataType }, + demandIntegrationPeriod: { id: 0x602, type: ZCLDataType }, + numberOfDemandSubintervals: { id: 0x603, type: ZCLDataType }, + demandLimitArmDuration: { id: 0x604, type: ZCLDataType }, + currentNoTierBlock1SummationDelivered: { id: 0x700, type: ZCLDataType }, + currentNoTierBlock2SummationDelivered: { id: 0x701, type: ZCLDataType }, + currentNoTierBlock3SummationDelivered: { id: 0x702, type: ZCLDataType }, + currentNoTierBlock4SummationDelivered: { id: 0x703, type: ZCLDataType }, + currentNoTierBlock5SummationDelivered: { id: 0x704, type: ZCLDataType }, + currentNoTierBlock6SummationDelivered: { id: 0x705, type: ZCLDataType }, + currentNoTierBlock7SummationDelivered: { id: 0x706, type: ZCLDataType }, + currentNoTierBlock8SummationDelivered: { id: 0x707, type: ZCLDataType }, + currentNoTierBlock9SummationDelivered: { id: 0x708, type: ZCLDataType }, + currentNoTierBlock10SummationDelivered: { id: 0x709, type: ZCLDataType }, + currentNoTierBlock11SummationDelivered: { id: 0x70a, type: ZCLDataType }, + currentNoTierBlock12SummationDelivered: { id: 0x70b, type: ZCLDataType }, + currentNoTierBlock13SummationDelivered: { id: 0x70c, type: ZCLDataType }, + currentNoTierBlock14SummationDelivered: { id: 0x70d, type: ZCLDataType }, + currentNoTierBlock15SummationDelivered: { id: 0x70e, type: ZCLDataType }, + currentNoTierBlock16SummationDelivered: { id: 0x70f, type: ZCLDataType }, + currentTier1Block1SummationDelivered: { id: 0x710, type: ZCLDataType }, + currentTier1Block2SummationDelivered: { id: 0x711, type: ZCLDataType }, + currentTier1Block3SummationDelivered: { id: 0x712, type: ZCLDataType }, + currentTier1Block4SummationDelivered: { id: 0x713, type: ZCLDataType }, + currentTier1Block5SummationDelivered: { id: 0x714, type: ZCLDataType }, + currentTier1Block6SummationDelivered: { id: 0x715, type: ZCLDataType }, + currentTier1Block7SummationDelivered: { id: 0x716, type: ZCLDataType }, + currentTier1Block8SummationDelivered: { id: 0x717, type: ZCLDataType }, + currentTier1Block9SummationDelivered: { id: 0x718, type: ZCLDataType }, + currentTier1Block10SummationDelivered: { id: 0x719, type: ZCLDataType }, + currentTier1Block11SummationDelivered: { id: 0x71a, type: ZCLDataType }, + currentTier1Block12SummationDelivered: { id: 0x71b, type: ZCLDataType }, + currentTier1Block13SummationDelivered: { id: 0x71c, type: ZCLDataType }, + currentTier1Block14SummationDelivered: { id: 0x71d, type: ZCLDataType }, + currentTier1Block15SummationDelivered: { id: 0x71e, type: ZCLDataType }, + currentTier1Block16SummationDelivered: { id: 0x71f, type: ZCLDataType }, + currentTier2Block1SummationDelivered: { id: 0x720, type: ZCLDataType }, + currentTier2Block2SummationDelivered: { id: 0x721, type: ZCLDataType }, + currentTier2Block3SummationDelivered: { id: 0x722, type: ZCLDataType }, + currentTier2Block4SummationDelivered: { id: 0x723, type: ZCLDataType }, + currentTier2Block5SummationDelivered: { id: 0x724, type: ZCLDataType }, + currentTier2Block6SummationDelivered: { id: 0x725, type: ZCLDataType }, + currentTier2Block7SummationDelivered: { id: 0x726, type: ZCLDataType }, + currentTier2Block8SummationDelivered: { id: 0x727, type: ZCLDataType }, + currentTier2Block9SummationDelivered: { id: 0x728, type: ZCLDataType }, + currentTier2Block10SummationDelivered: { id: 0x729, type: ZCLDataType }, + currentTier2Block11SummationDelivered: { id: 0x72a, type: ZCLDataType }, + currentTier2Block12SummationDelivered: { id: 0x72b, type: ZCLDataType }, + currentTier2Block13SummationDelivered: { id: 0x72c, type: ZCLDataType }, + currentTier2Block14SummationDelivered: { id: 0x72d, type: ZCLDataType }, + currentTier2Block15SummationDelivered: { id: 0x72e, type: ZCLDataType }, + currentTier2Block16SummationDelivered: { id: 0x72f, type: ZCLDataType }, + currentTier3Block1SummationDelivered: { id: 0x730, type: ZCLDataType }, + currentTier3Block2SummationDelivered: { id: 0x731, type: ZCLDataType }, + currentTier3Block3SummationDelivered: { id: 0x732, type: ZCLDataType }, + currentTier3Block4SummationDelivered: { id: 0x733, type: ZCLDataType }, + currentTier3Block5SummationDelivered: { id: 0x734, type: ZCLDataType }, + currentTier3Block6SummationDelivered: { id: 0x735, type: ZCLDataType }, + currentTier3Block7SummationDelivered: { id: 0x736, type: ZCLDataType }, + currentTier3Block8SummationDelivered: { id: 0x737, type: ZCLDataType }, + currentTier3Block9SummationDelivered: { id: 0x738, type: ZCLDataType }, + currentTier3Block10SummationDelivered: { id: 0x739, type: ZCLDataType }, + currentTier3Block11SummationDelivered: { id: 0x73a, type: ZCLDataType }, + currentTier3Block12SummationDelivered: { id: 0x73b, type: ZCLDataType }, + currentTier3Block13SummationDelivered: { id: 0x73c, type: ZCLDataType }, + currentTier3Block14SummationDelivered: { id: 0x73d, type: ZCLDataType }, + currentTier3Block15SummationDelivered: { id: 0x73e, type: ZCLDataType }, + currentTier3Block16SummationDelivered: { id: 0x73f, type: ZCLDataType }, + currentTier4Block1SummationDelivered: { id: 0x740, type: ZCLDataType }, + currentTier4Block2SummationDelivered: { id: 0x741, type: ZCLDataType }, + currentTier4Block3SummationDelivered: { id: 0x742, type: ZCLDataType }, + currentTier4Block4SummationDelivered: { id: 0x743, type: ZCLDataType }, + currentTier4Block5SummationDelivered: { id: 0x744, type: ZCLDataType }, + currentTier4Block6SummationDelivered: { id: 0x745, type: ZCLDataType }, + currentTier4Block7SummationDelivered: { id: 0x746, type: ZCLDataType }, + currentTier4Block8SummationDelivered: { id: 0x747, type: ZCLDataType }, + currentTier4Block9SummationDelivered: { id: 0x748, type: ZCLDataType }, + currentTier4Block10SummationDelivered: { id: 0x749, type: ZCLDataType }, + currentTier4Block11SummationDelivered: { id: 0x74a, type: ZCLDataType }, + currentTier4Block12SummationDelivered: { id: 0x74b, type: ZCLDataType }, + currentTier4Block13SummationDelivered: { id: 0x74c, type: ZCLDataType }, + currentTier4Block14SummationDelivered: { id: 0x74d, type: ZCLDataType }, + currentTier4Block15SummationDelivered: { id: 0x74e, type: ZCLDataType }, + currentTier4Block16SummationDelivered: { id: 0x74f, type: ZCLDataType }, + currentNoTierBlock1SummationReceived: { id: 0x900, type: ZCLDataType }, + currentNoTierBlock2SummationReceived: { id: 0x901, type: ZCLDataType }, + currentNoTierBlock3SummationReceived: { id: 0x902, type: ZCLDataType }, + currentNoTierBlock4SummationReceived: { id: 0x903, type: ZCLDataType }, + currentNoTierBlock5SummationReceived: { id: 0x904, type: ZCLDataType }, + currentNoTierBlock6SummationReceived: { id: 0x905, type: ZCLDataType }, + currentNoTierBlock7SummationReceived: { id: 0x906, type: ZCLDataType }, + currentNoTierBlock8SummationReceived: { id: 0x907, type: ZCLDataType }, + currentNoTierBlock9SummationReceived: { id: 0x908, type: ZCLDataType }, + currentNoTierBlock10SummationReceived: { id: 0x909, type: ZCLDataType }, + currentNoTierBlock11SummationReceived: { id: 0x90a, type: ZCLDataType }, + currentNoTierBlock12SummationReceived: { id: 0x90b, type: ZCLDataType }, + currentNoTierBlock13SummationReceived: { id: 0x90c, type: ZCLDataType }, + currentNoTierBlock14SummationReceived: { id: 0x90d, type: ZCLDataType }, + currentNoTierBlock15SummationReceived: { id: 0x90e, type: ZCLDataType }, + currentNoTierBlock16SummationReceived: { id: 0x90f, type: ZCLDataType }, + billToDateDelivered: { id: 0xa00, type: ZCLDataType }, + billToDateTimeStampDelivered: { id: 0xa01, type: ZCLDataType }, + projectedBillDelivered: { id: 0xa02, type: ZCLDataType }, + projectedBillTimeStampDelivered: { id: 0xa03, type: ZCLDataType }, + billToDateReceived: { id: 0xa10, type: ZCLDataType }, + billToDateTimeStampReceived: { id: 0xa11, type: ZCLDataType }, + projectedBillReceived: { id: 0xa12, type: ZCLDataType }, + projectedBillTimeStampReceived: { id: 0xa13, type: ZCLDataType }, + proposedChangeSupplyImplementationTime: { id: 0xb00, type: ZCLDataType }, + proposedChangeSupplyStatus: { id: 0xb01, type: ZCLDataType }, + uncontrolledFlowThreshold: { id: 0xb10, type: ZCLDataType }, + uncontrolledFlowThresholdUnitOfMeasure: { id: 0xb11, type: ZCLDataType }, + uncontrolledFlowMultiplier: { id: 0xb12, type: ZCLDataType }, + uncontrolledFlowDivisor: { id: 0xb13, type: ZCLDataType }, + flowStabilisationPeriod: { id: 0xb14, type: ZCLDataType }, + flowMeasurementPeriod: { id: 0xb15, type: ZCLDataType }, }; - THERMOSTAT: { - ID: number; - NAME: 'thermostat'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type MeteringClusterCommands = Record; + class MeteringCluster extends Cluster { + } + type ElectricalMeasurementClusterAttributes = { + measurementType: { id: 0x00, type: ZCLDataType> }, + acFrequency: { id: 0x300, type: ZCLDataType }, + measuredPhase1stHarmonicCurrent: { id: 0x30d, type: ZCLDataType }, + acFrequencyMultiplier: { id: 0x400, type: ZCLDataType }, + acFrequencyDivisor: { id: 0x401, type: ZCLDataType }, + phaseHarmonicCurrentMultiplier: { id: 0x405, type: ZCLDataType }, + rmsVoltage: { id: 0x505, type: ZCLDataType }, + rmsCurrent: { id: 0x508, type: ZCLDataType }, + activePower: { id: 0x50b, type: ZCLDataType }, + reactivePower: { id: 0x50e, type: ZCLDataType }, + acVoltageMultiplier: { id: 0x600, type: ZCLDataType }, + acVoltageDivisor: { id: 0x601, type: ZCLDataType }, + acCurrentMultiplier: { id: 0x602, type: ZCLDataType }, + acCurrentDivisor: { id: 0x603, type: ZCLDataType }, + acPowerMultiplier: { id: 0x604, type: ZCLDataType }, + acPowerDivisor: { id: 0x605, type: ZCLDataType }, + acAlarmsMask: { id: 0x800, type: ZCLDataType> }, + acVoltageOverload: { id: 0x801, type: ZCLDataType }, + acCurrentOverload: { id: 0x802, type: ZCLDataType }, + acActivePowerOverload: { id: 0x803, type: ZCLDataType }, }; - TIME: { - ID: number; - NAME: 'time'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + type ElectricalMeasurementClusterCommands = Record; + class ElectricalMeasurementCluster extends Cluster { + } + type DiagnosticsClusterAttributes = Record; + type DiagnosticsClusterCommands = Record; + class DiagnosticsCluster extends Cluster { + } + type TouchLinkClusterAttributes = Record; + type TouchLinkClusterCommands = { + getGroups: { id: 0x41, direction: "DIRECTION_SERVER_TO_CLIENT", args: { + startIdx: ZCLDataType, + }, + }, }; - TOUCHLINK: { - ID: number; - NAME: 'touchlink'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + class TouchLinkCluster extends Cluster { + getGroups( + args: { + manufacturerId?: number, + startIdx: number, + }, + opts?: { + waitForResponse?: boolean, + timeout?: number, + disableDefaultResponse?: boolean, + }, + ): Promise; + } + const CLUSTER: { + BASIC: { + ID: 0x0000, + NAME: "basic", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + POWER_CONFIGURATION: { + ID: 0x0001, + NAME: "powerConfiguration", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + DEVICE_TEMPERATURE: { + ID: 0x0002, + NAME: "deviceTemperature", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + IDENTIFY: { + ID: 0x0003, + NAME: "identify", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + GROUPS: { + ID: 0x0004, + NAME: "groups", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + SCENES: { + ID: 0x0005, + NAME: "scenes", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ON_OFF: { + ID: 0x0006, + NAME: "onOff", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ON_OFF_SWITCH: { + ID: 0x0007, + NAME: "onOffSwitch", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + LEVEL_CONTROL: { + ID: 0x0008, + NAME: "levelControl", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ALARMS: { + ID: 0x0009, + NAME: "alarms", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + TIME: { + ID: 0x000a, + NAME: "time", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ANALOG_INPUT: { + ID: 0x000c, + NAME: "analogInput", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ANALOG_OUTPUT: { + ID: 0x000d, + NAME: "analogOutput", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ANALOG_VALUE: { + ID: 0x000e, + NAME: "analogValue", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + BINARY_INPUT: { + ID: 0x000f, + NAME: "binaryInput", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + BINARY_OUTPUT: { + ID: 0x0010, + NAME: "binaryOutput", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + BINARY_VALUE: { + ID: 0x0011, + NAME: "binaryValue", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + MULTI_STATE_INPUT: { + ID: 0x0012, + NAME: "multistateInput", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + MULTI_STATE_OUTPUT: { + ID: 0x0013, + NAME: "multistateOutput", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + MULTI_STATE_VALUE: { + ID: 0x0014, + NAME: "multistateValue", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + OTA: { + ID: 0x0019, + NAME: "ota", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + POWER_PROFILE: { + ID: 0x001a, + NAME: "powerProfile", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + POLL_CONTROL: { + ID: 0x0020, + NAME: "pollControl", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + SHADE_CONFIGURATION: { + ID: 0x0100, + NAME: "shadeConfiguration", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + DOOR_LOCK: { + ID: 0x0101, + NAME: "doorLock", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + WINDOW_COVERING: { + ID: 0x0102, + NAME: "windowCovering", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + THERMOSTAT: { + ID: 0x0201, + NAME: "thermostat", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + PUMP_CONFIGURATION_AND_CONTROL: { + ID: 0x0200, + NAME: "pumpConfigurationAndControl", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + FAN_CONTROL: { + ID: 0x0202, + NAME: "fanControl", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + COLOR_CONTROL: { + ID: 0x0300, + NAME: "colorControl", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + BALLAST_CONFIGURATION: { + ID: 0x0301, + NAME: "ballastConfiguration", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ILLUMINANCE_MEASUREMENT: { + ID: 0x0400, + NAME: "illuminanceMeasurement", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ILLUMINANCE_LEVEL_SENSING: { + ID: 0x0401, + NAME: "illuminanceLevelSensing", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + TEMPERATURE_MEASUREMENT: { + ID: 0x0402, + NAME: "temperatureMeasurement", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + PRESSURE_MEASUREMENT: { + ID: 0x0403, + NAME: "pressureMeasurement", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + FLOW_MEASUREMENT: { + ID: 0x0404, + NAME: "flowMeasurement", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + RELATIVE_HUMIDITY_MEASUREMENT: { + ID: 0x0405, + NAME: "relativeHumidity", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + OCCUPANCY_SENSING: { + ID: 0x0406, + NAME: "occupancySensing", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + IAS_ZONE: { + ID: 0x0500, + NAME: "iasZone", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + IAS_ACE: { + ID: 0x0501, + NAME: "iasACE", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + IAS_WD: { + ID: 0x0502, + NAME: "iasWD", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + METERING: { + ID: 0x0702, + NAME: "metering", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + ELECTRICAL_MEASUREMENT: { + ID: 0x0b04, + NAME: "electricalMeasurement", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + DIAGNOSTICS: { + ID: 0x0b05, + NAME: "diagnostics", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, + TOUCHLINK: { + ID: 0x1000, + NAME: "touchlink", + ATTRIBUTES: Readonly, + COMMANDS: Readonly, + }, }; - WINDOW_COVERING: { - ID: number; - NAME: 'windowCovering'; - ATTRIBUTES: unknown; - COMMANDS: unknown; + + import {EventEmitter} from "events"; + import {ZigBeeNode} from "homey"; + type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; + type ZCLDataTypes = typeof import('@athombv/data-types').DataTypes & { + enum8Status: ZCLDataType + }; + + function debug(flag: boolean, namespaces: string): void; + + class ZCLNode extends EventEmitter { + constructor(node: ZigBeeNode); + endpoints: Record; + + getLogId(endpointId: number, clusterId: number): string; + } + + class ZCLNodeEndpoint extends EventEmitter { + constructor(node: ZCLNode, descriptor: { + endpointId: number; + inputClusters: number[]; + outputClusters: number[]; + }[]); + clusters: Record>; + bindings: Record; + + bind(clusterName: string, clusterImpl: BoundCluster): void; + unbind(clusterName: string): void; + + makeDefaultResponseFrame(receivedFrame: unknown, success: boolean, status: ZCLEnum8Status): typeof zclFrames.ZCLStandardHeader | typeof zclFrames.ZCLMfgSpecificHeader; + } + + type ZCLDataType = import('@athombv/data-types').DataType; + const ZCLDataTypes: ZCLDataTypes; + const ZCLStruct: typeof import('@athombv/data-types').Struct; + + namespace zclTypes { + type ZCLDataType = import('@athombv/data-types').DataType; + const ZCLDataTypes: ZCLDataTypes; + const ZCLStruct: typeof import('@athombv/data-types').Struct; + } + + type FrameControlFlag = + 'clusterSpecific' + | 'manufacturerSpecific' + | 'directionToClient' + | 'disableDefaultResponse'; + type ZCLFrameControlBitmap = ZCLDataType>; + + namespace zclFrames { + const ZCLStandardHeader: import('@athombv/data-types').StaticStruct<{ + frameControl: ZCLFrameControlBitmap, + trxSequenceNumber: ZCLDataTypes["data8"], + cmdId: ZCLDataTypes["data8"], + data: ZCLDataTypes["buffer"], + }>; + const ZCLMfgSpecificHeader: import('@athombv/data-types').StaticStruct<{ + frameControl: ZCLFrameControlBitmap, + manufacturerId: ZCLDataTypes["uint16"], + trxSequenceNumber: ZCLDataTypes["data8"], + cmdId: ZCLDataTypes["data8"], + data: ZCLDataTypes["buffer"], + }>; + function ZCLAttributeDataRecord(withStatus: boolean, attributes: AttributeDefinitions): ZCLDataType<{ + id: number, + name: string, + status?: ZCLEnum8Status + value: ZCLDataType + }>; + function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType<{ + attributeId: number, + status?: ZCLEnum8Status, + direction: 'reported' | 'received', + attributeDataType: number, + minInterval: number, + maxInterval: number, + minChange: number, // TODO Check whether this is actually a number, or a buffer like the JS docs imply + }> + } + + class ZCLError extends Error { + zclStatus: ZCLEnum8Status; + } + + const ZIGBEE_PROFILE_ID: { + INDUSTRIAL_PLANT_MONITORING: 0x0101, + HOME_AUTOMATION: 0x0104, + COMMERCIAL_BUILDING_AUTOMATION: 0x0105, + TELECOM_APPLICATIONS: 0x0107, + PERSONAL_HOME_AND_HOSPITAL_CARE: 0x0108, + ADVANCED_METERING_INITIATIVE: 0x0109, + }; + const ZIGBEE_DEVICE_ID: { + GENERIC: { + ON_OFF_SWITCH: 0x0000, + LEVEL_CONTROL_SWITCH: 0x0001, + ON_OFF_OUTPUT: 0x0002, + LEVEL_CONTROLLABLE_OUTPUT: 0x0003, + SCENE_SELECTOR: 0x0004, + CONFIGURATION_TOOL: 0x0005, + REMOTE_CONTROL: 0x0006, + COMBINED_INTERFACE: 0x0007, + RANGE_EXTENDER: 0x0008, + MAINS_POWER_OUTLET: 0x0009, + DOOR_LOCK: 0x000a, + DOOR_LOCK_CONTROLLER: 0x000b, + SIMPLE_SENSOR: 0x000c, + CONSUMPTION_AWARENESS_DEVICE: 0x000d, + HOME_GATEWAY: 0x0050, + SMART_PLUG: 0x0051, + WHITE_GOODS: 0x0052, + METER_INTERFACE: 0x0053, + }, + LIGHTING: { + ON_OFF_LIGHT: 0x0100, + DIMMABLE_LIGHT: 0x0101, + COLOR_DIMMABLE_LIGHT: 0x0102, + ON_OFF_LIGHT_SWITCH: 0x0103, + DIMMER_SWITCH: 0x0104, + COLOR_DIMMER_SWITCH: 0x0105, + LIGHT_SENSOR: 0x0106, + OCCUPANCY_SENSOR: 0x0107, + }, + CLOSURES: { + SHADE: 0x0200, + SHADE_CONTROLLER: 0x0201, + WINDOW_COVERING_DEVICE: 0x0202, + WINDOW_COVERING_CONTROLLER: 0x0203, + }, + HVAC: { + HEATING_COOLING_UNIT: 0x0300, + THERMOSTAT: 0x0301, + TEMPERATURE_SENSOR: 0x0302, + PUMP: 0x0303, + PUMP_CONTROLLER: 0x0304, + PRESSURE_SENSOR: 0x0305, + FLOW_SENSOR: 0x0306, + }, + INTRUDER_ALARM_SYSTEMS: { + IAS_CONTROL_INDICATING_EQUIPMENT: 0x0400, + IAS_ANCILLARY_CONTROL_EQUIPMENT: 0x0401, + IAS_ZONE: 0x0402, + IAS_WARNING_DEVICE: 0x0403, + }, }; -}; -export class BoundCluster { + const IAS_ZONE_TYPE: { + STANDARD_CIE: 0x0000, + MOTION_SENSOR: 0x000d, + CONTACT_SWITCH: 0x0015, + FIRE_SENSOR: 0x0028, + WATER_SENSOR: 0x002a, + CARBON_MONOXIDE_SENSOR: 0x002b, + PERSONAL_EMERGENCY_DEVICE: 0x002c, + VIBRATION_MOVEMENT_SENSOR: 0x002d, + REMOTE_CONTROL: 0x010f, + KEY_FOB: 0x0115, + KEYPAD: 0x021d, + STANDARD_WARNING_DEVICE: 0x0225, + GLASS_BREAK_SENSOR: 0x0226, + SECURITY_REPEATER: 0x0229, + INVALID_ZONE_TYPE: 0xffff, + }; + + abstract class Cluster extends EventEmitter { + static get ID(): number; + static get NAME(): string; + // @ts-expect-error Type should be defined on non-abstract inheritors + static get ATTRIBUTES(): Attributes; + // @ts-expect-error Type should be defined on non-abstract inheritors + static get COMMANDS(): Commands; + + static DIRECTION_SERVER_TO_CLIENT: CommandToClientDirection; + static DIRECTION_CLIENT_TO_SERVER: CommandToServerDirection; + get logId(): string; + + discoverCommandsGenerated({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; + discoverCommandsReceived({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; + + readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; + writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> + + configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; + readReportingConfiguration(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise>; + + discoverAttributes(opts?: {timeout?: number}): Promise>; + discoverAttributesExtended(opts?: {timeout?: number}): Promise>; + + sendFrame(data: object): Promise; + nextSeqNr(): number; + + static addCluster(clusterClass: typeof Cluster): void; + static removeCluster(clusterIdOrName: string | number): void; + static getCluster(clusterIdOrName: string | number): Cluster; + + on>(eventName: `attr.${Event}`, listener: (value: AttributesFromDefinition[Event]) => void): this; + on = unknown[]>(eventName: string, listener: (...args: Values) => void): this; + + attributes: Attributes; + attributesById: {[Attribute in keyof Attributes as Attributes[Attribute]['id']]: { name: Attribute } & Attributes[Attribute] }; + + commands: Commands; + commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; + } + + // TODO + abstract class BoundCluster { + endpoint: number; + cluster: Cluster; + + get logId(): string; + } +} + +type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; +type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; +type CommandDirection = CommandToServerDirection | CommandToClientDirection; + +type FromZCLDataType = DataType extends import('zigbee-clusters').ZCLDataType? InferredValue : DataType; + +type AttributeDefinition = { + id: number, + type: import('zigbee-clusters').ZCLDataType, + manufacturerId?: number, } -export class ZCLError extends Error { - zclStatus: ZCLEnum8Status; - constructor(zclStatus?: ZCLEnum8Status); +type AttributeDefinitions = { + [attributeName: string]: AttributeDefinition, } -export const AlarmsCluster: { - new (...args: any[]): AlarmsCluster; - ID: 9; - NAME: 'alarms'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const AnalogInputCluster: { - new (...args: any[]): AnalogInputCluster; - ID: 12; - NAME: 'analogInput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const AnalogOutputCluster: { - new (...args: any[]): AnalogOutputCluster; - ID: 13; - NAME: 'analogOutput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const AnalogValueCluster: { - new (...args: any[]): AnalogValueCluster; - ID: 14; - NAME: 'analogValue'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const BallastConfigurationCluster: { - new (...args: any[]): BallastConfigurationCluster; - ID: 769; - NAME: 'ballastConfiguration'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const BasicCluster: { - new (...args: any[]): BasicCluster; - ID: 0; - NAME: 'basic'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const BinaryInputCluster: { - new (...args: any[]): BinaryInputCluster; - ID: 15; - NAME: 'binaryInput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const BinaryOutputCluster: { - new (...args: any[]): BinaryOutputCluster; - ID: 16; - NAME: 'binaryOutput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const BinaryValueCluster: { - new (...args: any[]): BinaryValueCluster; - ID: 17; - NAME: 'binaryValue'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const ColorControlCluster: { - new (...args: any[]): ColorControlCluster; - ID: 768; - NAME: 'colorControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const DehumidificationControlCluster: { - new (...args: any[]): DehumidificationControlCluster; - ID: 515; - NAME: 'dehumidificationControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const DeviceTemperatureCluster: { - new (...args: any[]): DeviceTemperatureCluster; - ID: 2; - NAME: 'deviceTemperature'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const DiagnosticsCluster: { - new (...args: any[]): DiagnosticsCluster; - ID: 2821; - NAME: 'diagnostics'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const DoorLockCluster: { - new (...args: any[]): DoorLockCluster; - ID: 257; - NAME: 'doorLock'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const ElectricalMeasurementCluster: { - new (...args: any[]): ElectricalMeasurementCluster; - ID: 2820; - NAME: 'electricalMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const FanControlCluster: { - new (...args: any[]): FanControlCluster; - ID: 514; - NAME: 'fanControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const FlowMeasurementCluster: { - new (...args: any[]): FlowMeasurementCluster; - ID: 1028; - NAME: 'flowMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const GroupsCluster: { - new (...args: any[]): GroupsCluster; - ID: 4; - NAME: 'groups'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const IASACECluster: { - new (...args: any[]): IASACECluster; - ID: 1281; - NAME: 'iasACE'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const IASWDCluster: { - new (...args: any[]): IASWDCluster; - ID: 1282; - NAME: 'iasWD'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const IASZoneCluster: { - new (...args: any[]): IASZoneCluster; - ID: 1280; - NAME: 'iasZone'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const IdentifyCluster: { - new (...args: any[]): IdentifyCluster; - ID: 3; - NAME: 'identify'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const IlluminanceLevelSensingCluster: { - new (...args: any[]): IlluminanceLevelSensingCluster; - ID: 1025; - NAME: 'illuminanceLevelSensing'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const IlluminanceMeasurementCluster: { - new (...args: any[]): IlluminanceMeasurementCluster; - ID: 1024; - NAME: 'illuminanceMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const LevelControlCluster: { - new (...args: any[]): LevelControlCluster; - ID: 8; - NAME: 'levelControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const MeteringCluster: { - new (...args: any[]): MeteringCluster; - ID: 1794; - NAME: 'metering'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const MultistateInputCluster: { - new (...args: any[]): MultistateInputCluster; - ID: 18; - NAME: 'multistateInput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const MultistateOutputCluster: { - new (...args: any[]): MultistateOutputCluster; - ID: 19; - NAME: 'multistateOutput'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const MultistateValueCluster: { - new (...args: any[]): MultistateValueCluster; - ID: 20; - NAME: 'multistateValue'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const OccupancySensingCluster: { - new (...args: any[]): OccupancySensingCluster; - ID: 1030; - NAME: 'occupancySensing'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const OnOffCluster: { - new (...args: any[]): OnOffCluster; - ID: 6; - NAME: 'onOff'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const OnOffSwitchCluster: { - new (...args: any[]): OnOffSwitchCluster; - ID: 7; - NAME: 'onOffSwitch'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const OTACluster: { - new (...args: any[]): OTACluster; - ID: 25; - NAME: 'ota'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const PollControlCluster: { - new (...args: any[]): PollControlCluster; - ID: 32; - NAME: 'pollControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const PowerConfigurationCluster: { - new (...args: any[]): PowerConfigurationCluster; - ID: 1; - NAME: 'powerConfiguration'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const PowerProfileCluster: { - new (...args: any[]): PowerProfileCluster; - ID: 26; - NAME: 'powerProfile'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const PressureMeasurementCluster: { - new (...args: any[]): PressureMeasurementCluster; - ID: 1027; - NAME: 'pressureMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const PumpConfigurationAndControlCluster: { - new (...args: any[]): PumpConfigurationAndControlCluster; - ID: 512; - NAME: 'pumpConfigurationAndControl'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const RelativeHumidityCluster: { - new (...args: any[]): RelativeHumidityCluster; - ID: 1029; - NAME: 'relativeHumidity'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const ScenesCluster: { - new (...args: any[]): ScenesCluster; - ID: 5; - NAME: 'scenes'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const ShadeConfigurationCluster: { - new (...args: any[]): ShadeConfigurationCluster; - ID: 256; - NAME: 'shadeConfiguration'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const TemperatureMeasurementCluster: { - new (...args: any[]): TemperatureMeasurementCluster; - ID: 1026; - NAME: 'temperatureMeasurement'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const ThermostatCluster: { - new (...args: any[]): ThermostatCluster; - ID: 513; - NAME: 'thermostat'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const TimeCluster: { - new (...args: any[]): TimeCluster; - ID: 10; - NAME: 'time'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const TouchLinkCluster: { - new (...args: any[]): TouchLinkCluster; - ID: 4096; - NAME: 'touchlink'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const WindowCoveringCluster: { - new (...args: any[]): WindowCoveringCluster; - ID: 258; - NAME: 'windowCovering'; - ATTRIBUTES: unknown; - COMMANDS: unknown; -}; -export const ZIGBEE_PROFILE_ID: { - INDUSTRIAL_PLANT_MONITORING: 257; - HOME_AUTOMATION: 260; - COMMERCIAL_BUILDING_AUTOMATION: 261; - TELECOM_APPLICATIONS: 263; - PERSONAL_HOME_AND_HOSPITAL_CARE: 264; - ADVANCED_METERING_INITIATIVE: 265; -}; +type AttributesFromDefinition = { + [attribute in keyof Definition]: FromZCLDataType +} -export const ZIGBEE_DEVICE_ID: { - GENERIC: { - ON_OFF_SWITCH: 0; - LEVEL_CONTROL_SWITCH: 1; - ON_OFF_OUTPUT: 2; - LEVEL_CONTROLLABLE_OUTPUT: 3; - SCENE_SELECTOR: 4; - CONFIGURATION_TOOL: 5; - REMOTE_CONTROL: 6; - COMBINED_INTERFACE: 7; - RANGE_EXTENDER: 8; - MAINS_POWER_OUTLET: 9; - DOOR_LOCK: 10; - DOOR_LOCK_CONTROLLER: 11; - SIMPLE_SENSOR: 12; - CONSUMPTION_AWARENESS_DEVICE: 13; - HOME_GATEWAY: 80; - SMART_PLUG: 81; - WHITE_GOODS: 82; - METER_INTERFACE: 83; - }; - LIGHTING: { - ON_OFF_LIGHT: 256; - DIMMABLE_LIGHT: 257; - COLOR_DIMMABLE_LIGHT: 258; - ON_OFF_LIGHT_SWITCH: 259; - DIMMER_SWITCH: 260; - COLOR_DIMMER_SWITCH: 261; - LIGHT_SENSOR: 262; - OCCUPANCY_SENSOR: 263; - }; - CLOSURES: { - SHADE: 512; - SHADE_CONTROLLER: 513; - WINDOW_COVERING_DEVICE: 514; - WINDOW_COVERING_CONTROLLER: 515; - }; - HVAC: { - HEATING_COOLING_UNIT: 768; - THERMOSTAT: 769; - TEMPERATURE_SENSOR: 770; - PUMP: 771; - PUMP_CONTROLLER: 772; - PRESSURE_SENSOR: 773; - FLOW_SENSOR: 774; - }; - INTRUDER_ALARM_SYSTEMS: { - IAS_CONTROL_INDICATING_EQUIPMENT: 1024; - IAS_ANCILLARY_CONTROL_EQUIPMENT: 1025; - IAS_ZONE: 1026; - IAS_WARNING_DEVICE: 1027; - }; -}; +type CommandDefinition = { + id: number, + direction?: CommandDirection, + args?: { + [argName: string]: import('zigbee-clusters').ZCLDataType, + } + response?: CommandDefinition, + frameControl?: import('zigbee-clusters').FrameControlFlag[]; + encodeMissingFieldsBehavior?: 'default' | 'skip'; + global?: boolean; +} + +type CommandDefinitions = { + [commandName: string]: CommandDefinition, +} -export const IAS_ZONE_TYPE: { - STANDARD_CIE: 0; - MOTION_SENSOR: 13; - CONTACT_SWITCH: 21; - FIRE_SENSOR: 40; - WATER_SENSOR: 42; - CARBON_MONOXIDE_SENSOR: 43; - PERSONAL_EMERGENCY_DEVICE: 44; - VIBRATION_MOVEMENT_SENSOR: 45; - REMOTE_CONTROL: 271; - KEY_FOB: 277; - KEYPAD: 541; - STANDARD_WARNING_DEVICE: 549; - GLASS_BREAK_SENSOR: 550; - SECURITY_REPEATER: 553; - INVALID_ZONE_TYPE: 65535; -}; +type AttributeReportingConfiguration = { + [attribute in AttributeKey]: { + minInterval?: number, + maxInterval?: number, + minChange?: number + } +} -declare const _default: { - ZCLNode: typeof ZCLNode; - CLUSTER: typeof CLUSTER; - AlarmsCluster: typeof AlarmsCluster; - AnalogInputCluster: typeof AnalogInputCluster; - AnalogOutputCluster: typeof AnalogOutputCluster; - AnalogValueCluster: typeof AnalogValueCluster; - BallastConfigurationCluster: typeof BallastConfigurationCluster; - BasicCluster: typeof BasicCluster; - BinaryInputCluster: typeof BinaryInputCluster; - BinaryOutputCluster: typeof BinaryOutputCluster; - BinaryValueCluster: typeof BinaryValueCluster; - ColorControlCluster: typeof ColorControlCluster; - DehumidificationControlCluster: typeof DehumidificationControlCluster; - DeviceTemperatureCluster: typeof DeviceTemperatureCluster; - DiagnosticsCluster: typeof DiagnosticsCluster; - DoorLockCluster: typeof DoorLockCluster; - ElectricalMeasurementCluster: typeof ElectricalMeasurementCluster; - FanControlCluster: typeof FanControlCluster; - FlowMeasurementCluster: typeof FlowMeasurementCluster; - GroupsCluster: typeof GroupsCluster; - IASACECluster: typeof IASACECluster; - IASWDCluster: typeof IASWDCluster; - IASZoneCluster: typeof IASZoneCluster; - IdentifyCluster: typeof IdentifyCluster; - IlluminanceLevelSensingCluster: typeof IlluminanceLevelSensingCluster; - IlluminanceMeasurementCluster: typeof IlluminanceMeasurementCluster; - LevelControlCluster: typeof LevelControlCluster; - MeteringCluster: typeof MeteringCluster; - MultistateInputCluster: typeof MultistateInputCluster; - MultistateOutputCluster: typeof MultistateOutputCluster; - MultistateValueCluster: typeof MultistateValueCluster; - OccupancySensingCluster: typeof OccupancySensingCluster; - OnOffCluster: typeof OnOffCluster; - OnOffSwitchCluster: typeof OnOffSwitchCluster; - OTACluster: typeof OTACluster; - PollControlCluster: typeof PollControlCluster; - PowerConfigurationCluster: typeof PowerConfigurationCluster; - PowerProfileCluster: typeof PowerProfileCluster; - PressureMeasurementCluster: typeof PressureMeasurementCluster; - PumpConfigurationAndControlCluster: typeof PumpConfigurationAndControlCluster; - RelativeHumidityCluster: typeof RelativeHumidityCluster; - ScenesCluster: typeof ScenesCluster; - ShadeConfigurationCluster: typeof ShadeConfigurationCluster; - TemperatureMeasurementCluster: typeof TemperatureMeasurementCluster; - ThermostatCluster: typeof ThermostatCluster; - TimeCluster: typeof TimeCluster; - TouchLinkCluster: typeof TouchLinkCluster; - WindowCoveringCluster: typeof WindowCoveringCluster; - ZIGBEE_PROFILE_ID: typeof ZIGBEE_PROFILE_ID; - ZIGBEE_DEVICE_ID: typeof ZIGBEE_DEVICE_ID; - IAS_ZONE_TYPE: typeof IAS_ZONE_TYPE; -}; -export default _default; \ No newline at end of file +type ReadReportingConfigurationResponse = { + status: import('zigbee-clusters').ZCLEnum8Status, + direction: 'reported'|'received'; + attributeId: number; + attributeDataType?: number; + minInterval?: number; + maxInterval?: number; + minChange?: number; + timeoutPeriod?: number; +} + +type ExtendedAttributesResponse = { + name?: string; + id: number; + acl: { + readable: boolean; + writable: boolean; + reportable: boolean; + } +} diff --git a/scripts/template.d.ts.txt b/scripts/template.d.ts.txt index 7cc9604..d7bd402 100644 --- a/scripts/template.d.ts.txt +++ b/scripts/template.d.ts.txt @@ -49,13 +49,13 @@ declare module 'zigbee-clusters' { type ZCLFrameControlBitmap = ZCLDataType>; namespace zclFrames { - const ZCLStandardHeader: import('@athombv/data-types').StructInstance<{ + const ZCLStandardHeader: import('@athombv/data-types').StaticStruct<{ frameControl: ZCLFrameControlBitmap, trxSequenceNumber: ZCLDataTypes["data8"], cmdId: ZCLDataTypes["data8"], data: ZCLDataTypes["buffer"], }>; - const ZCLMfgSpecificHeader: import('@athombv/data-types').StructInstance<{ + const ZCLMfgSpecificHeader: import('@athombv/data-types').StaticStruct<{ frameControl: ZCLFrameControlBitmap, manufacturerId: ZCLDataTypes["uint16"], trxSequenceNumber: ZCLDataTypes["data8"], @@ -213,8 +213,6 @@ declare module 'zigbee-clusters' { } } -// TODO clean up so these are not global - type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; type CommandDirection = CommandToServerDirection | CommandToClientDirection; From 424b0fe045ab2330156af68c27f2db30c02fa71e Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Fri, 10 Apr 2026 10:49:51 +0200 Subject: [PATCH 7/9] Improve new types --- index.d.ts | 262 +++++++++++++++++++++++++++++++++++--- scripts/template.d.ts.txt | 262 +++++++++++++++++++++++++++++++++++--- 2 files changed, 492 insertions(+), 32 deletions(-) diff --git a/index.d.ts b/index.d.ts index ab795c5..35a7397 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2471,19 +2471,20 @@ declare module "zigbee-clusters" { }>; function ZCLAttributeDataRecord(withStatus: boolean, attributes: AttributeDefinitions): ZCLDataType<{ id: number, - name: string, + name?: string, status?: ZCLEnum8Status - value: ZCLDataType + value?: ZCLDataType }>; - function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType<{ + function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType + attributeDataType?: number, + minInterval?: number, + maxInterval?: number, + minChange?: number, + timeoutPeriod?: number, + }>> } class ZCLError extends Error { @@ -2585,11 +2586,11 @@ declare module "zigbee-clusters" { discoverCommandsGenerated({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; discoverCommandsReceived({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; - readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; - writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> + readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; + writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> - configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; - readReportingConfiguration(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise>; + configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; + readReportingConfiguration(attributes: ReadonlyArray | number>, opts?: {timeout?: number}): Promise>; discoverAttributes(opts?: {timeout?: number}): Promise>; discoverAttributesExtended(opts?: {timeout?: number}): Promise>; @@ -2604,11 +2605,11 @@ declare module "zigbee-clusters" { on>(eventName: `attr.${Event}`, listener: (value: AttributesFromDefinition[Event]) => void): this; on = unknown[]>(eventName: string, listener: (...args: Values) => void): this; - attributes: Attributes; - attributesById: {[Attribute in keyof Attributes as Attributes[Attribute]['id']]: { name: Attribute } & Attributes[Attribute] }; + attributes: Attributes & GLOBAL_ATTRIBUTES; + attributesById: {[Attribute in keyof (Attributes & GLOBAL_ATTRIBUTES) as (Attributes & GLOBAL_ATTRIBUTES)[Attribute]['id']]: { name: Attribute } & (Attributes & GLOBAL_ATTRIBUTES)[Attribute] }; - commands: Commands; - commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; + commands: Commands & GLOBAL_COMMANDS; + commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; // Adding the global commands here results in types too big for TypeScript } // TODO @@ -2620,6 +2621,235 @@ declare module "zigbee-clusters" { } } +type ZCLDataTypes = import('zigbee-clusters').ZCLDataTypes; +type ZCLDataType = import('zigbee-clusters').ZCLDataType; +type ZCLStruct>> = import('@athombv/data-types').StructInstance + +type GLOBAL_ATTRIBUTES = { + clusterRevision: { id: 0xfffd, type: ZCLDataTypes["uint16"] }, + attributeReportingStatus: { + id: 0xfffe, + type: ZCLDataType<"PENDING" | "COMPLETE"> + } +}; + +type GLOBAL_COMMANDS = { + readAttributes: { + id: 0x00, + args: { + attributes: ZCLDataType>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, + }, + + writeAttributes: { + id: 0x02, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, + }, + + writeAttributesAtomic: { + id: 0x03, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, + }, + + writeAttributesNoResponse: { + id: 0x05, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, + }, + + configureReporting: { + id: 0x06, + args: { + reports: ReturnType, + }, + response: { + id: 0x07, + args: { + reports: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>> + }, + }, + global: true, + }, + + readReportingConfiguration: { + id: 0x08, + args: { + attributes: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>>, + }, + response: { + id: 0x09, + args: { + reports: ReturnType, + }, + }, + global: true, + }, + + reportAttributes: { + id: 0x0A, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, + }, + + defaultResponse: { + id: 0x0B, + args: { + cmdId: ZCLDataTypes["uint8"], + status: ZCLDataTypes["enum8Status"], + }, + global: true, + }, + + discoverAttributes: { + id: 0x0C, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x0D, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>>, + }, + }, + global: true, + }, + + readAttributesStructured: { + id: 0x0E, + args: { + attributes: ZCLDataType>, + }>>>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, + }, + + writeAttributesStructured: { + id: 0x0F, + args: { + attributes: ZCLDataType>, + dataTypeId: ZCLDataTypes["uint8"], + value: ZCLDataTypes["buffer"], + }>>>, + }, + response: { + id: 0x10, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, + }, + + discoverCommandsReceived: { + id: 0x11, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x12, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, + }, + + discoverCommandsGenerated: { + id: 0x13, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x14, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, + }, + + discoverAttributesExtended: { + id: 0x15, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x16, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>, + }>>>, + }, + }, + global: true, + }, +}; + type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; type CommandDirection = CommandToServerDirection | CommandToClientDirection; diff --git a/scripts/template.d.ts.txt b/scripts/template.d.ts.txt index d7bd402..31a3cef 100644 --- a/scripts/template.d.ts.txt +++ b/scripts/template.d.ts.txt @@ -64,19 +64,20 @@ declare module 'zigbee-clusters' { }>; function ZCLAttributeDataRecord(withStatus: boolean, attributes: AttributeDefinitions): ZCLDataType<{ id: number, - name: string, + name?: string, status?: ZCLEnum8Status - value: ZCLDataType + value?: ZCLDataType }>; - function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType<{ + function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType + attributeDataType?: number, + minInterval?: number, + maxInterval?: number, + minChange?: number, + timeoutPeriod?: number, + }>> } class ZCLError extends Error { @@ -178,11 +179,11 @@ declare module 'zigbee-clusters' { discoverCommandsGenerated({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; discoverCommandsReceived({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; - readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; - writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> + readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; + writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> - configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; - readReportingConfiguration(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise>; + configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; + readReportingConfiguration(attributes: ReadonlyArray | number>, opts?: {timeout?: number}): Promise>; discoverAttributes(opts?: {timeout?: number}): Promise>; discoverAttributesExtended(opts?: {timeout?: number}): Promise>; @@ -197,11 +198,11 @@ declare module 'zigbee-clusters' { on>(eventName: `attr.${Event}`, listener: (value: AttributesFromDefinition[Event]) => void): this; on = unknown[]>(eventName: string, listener: (...args: Values) => void): this; - attributes: Attributes; - attributesById: {[Attribute in keyof Attributes as Attributes[Attribute]['id']]: { name: Attribute } & Attributes[Attribute] }; + attributes: Attributes & GLOBAL_ATTRIBUTES; + attributesById: {[Attribute in keyof (Attributes & GLOBAL_ATTRIBUTES) as (Attributes & GLOBAL_ATTRIBUTES)[Attribute]['id']]: { name: Attribute } & (Attributes & GLOBAL_ATTRIBUTES)[Attribute] }; - commands: Commands; - commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; + commands: Commands & GLOBAL_COMMANDS; + commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; // Adding the global commands here results in types too big for TypeScript } // TODO @@ -213,6 +214,235 @@ declare module 'zigbee-clusters' { } } +type ZCLDataTypes = import('zigbee-clusters').ZCLDataTypes; +type ZCLDataType = import('zigbee-clusters').ZCLDataType; +type ZCLStruct>> = import('@athombv/data-types').StructInstance + +type GLOBAL_ATTRIBUTES = { + clusterRevision: { id: 0xfffd, type: ZCLDataTypes["uint16"] }, + attributeReportingStatus: { + id: 0xfffe, + type: ZCLDataType<"PENDING" | "COMPLETE"> + } +}; + +type GLOBAL_COMMANDS = { + readAttributes: { + id: 0x00, + args: { + attributes: ZCLDataType>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, + }, + + writeAttributes: { + id: 0x02, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, + }, + + writeAttributesAtomic: { + id: 0x03, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, + }, + + writeAttributesNoResponse: { + id: 0x05, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, + }, + + configureReporting: { + id: 0x06, + args: { + reports: ReturnType, + }, + response: { + id: 0x07, + args: { + reports: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>> + }, + }, + global: true, + }, + + readReportingConfiguration: { + id: 0x08, + args: { + attributes: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>>, + }, + response: { + id: 0x09, + args: { + reports: ReturnType, + }, + }, + global: true, + }, + + reportAttributes: { + id: 0x0A, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, + }, + + defaultResponse: { + id: 0x0B, + args: { + cmdId: ZCLDataTypes["uint8"], + status: ZCLDataTypes["enum8Status"], + }, + global: true, + }, + + discoverAttributes: { + id: 0x0C, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x0D, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>>, + }, + }, + global: true, + }, + + readAttributesStructured: { + id: 0x0E, + args: { + attributes: ZCLDataType>, + }>>>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, + }, + + writeAttributesStructured: { + id: 0x0F, + args: { + attributes: ZCLDataType>, + dataTypeId: ZCLDataTypes["uint8"], + value: ZCLDataTypes["buffer"], + }>>>, + }, + response: { + id: 0x10, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, + }, + + discoverCommandsReceived: { + id: 0x11, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x12, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, + }, + + discoverCommandsGenerated: { + id: 0x13, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x14, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, + }, + + discoverAttributesExtended: { + id: 0x15, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x16, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>, + }>>>, + }, + }, + global: true, + }, +}; + type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; type CommandDirection = CommandToServerDirection | CommandToClientDirection; From 48ac6632df9116bca4ac15b3114f253d2adb74c4 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Fri, 10 Apr 2026 11:22:28 +0200 Subject: [PATCH 8/9] Declutter helper types --- index.d.ts | 665 +++++++++++++++++++------------------ scripts/generate-types.mts | 12 +- scripts/template.d.ts.txt | 593 ++++++++++++++++----------------- 3 files changed, 636 insertions(+), 634 deletions(-) diff --git a/index.d.ts b/index.d.ts index 35a7397..badc374 100644 --- a/index.d.ts +++ b/index.d.ts @@ -21,7 +21,7 @@ declare module "zigbee-clusters" { type BasicClusterCommands = { factoryReset: { id: 0x00, direction: "DIRECTION_SERVER_TO_CLIENT" }, }; - class BasicCluster extends Cluster { + class BasicCluster extends Cluster { factoryReset( args: { manufacturerId?: number, @@ -43,7 +43,7 @@ declare module "zigbee-clusters" { batteryAlarmState: { id: 0x3e, type: ZCLDataType> }, }; type PowerConfigurationClusterCommands = Record; - class PowerConfigurationCluster extends Cluster { + class PowerConfigurationCluster extends Cluster { } type DeviceTemperatureClusterAttributes = { currentTemperature: { id: 0x00, type: ZCLDataType }, @@ -57,7 +57,7 @@ declare module "zigbee-clusters" { highTempDwellTripPoint: { id: 0x14, type: ZCLDataType }, }; type DeviceTemperatureClusterCommands = Record; - class DeviceTemperatureCluster extends Cluster { + class DeviceTemperatureCluster extends Cluster { } type IdentifyClusterAttributes = { identifyTime: { id: 0x00, type: ZCLDataType }, @@ -74,7 +74,7 @@ declare module "zigbee-clusters" { }, }, }; - class IdentifyCluster extends Cluster { + class IdentifyCluster extends Cluster { identify( args: { manufacturerId?: number, @@ -137,7 +137,7 @@ declare module "zigbee-clusters" { }, }, }; - class GroupsCluster extends Cluster { + class GroupsCluster extends Cluster { addGroup( args: { manufacturerId?: number, @@ -208,7 +208,7 @@ declare module "zigbee-clusters" { } type ScenesClusterAttributes = Record; type ScenesClusterCommands = Record; - class ScenesCluster extends Cluster { + class ScenesCluster extends Cluster { } type OnOffClusterAttributes = { onOff: { id: 0x00, type: ZCLDataType }, @@ -232,7 +232,7 @@ declare module "zigbee-clusters" { }, }, }; - class OnOffCluster extends Cluster { + class OnOffCluster extends Cluster { setOff( args: { manufacturerId?: number, @@ -301,7 +301,7 @@ declare module "zigbee-clusters" { } type OnOffSwitchClusterAttributes = Record; type OnOffSwitchClusterCommands = Record; - class OnOffSwitchCluster extends Cluster { + class OnOffSwitchCluster extends Cluster { } type LevelControlClusterAttributes = { currentLevel: { id: 0x00, type: ZCLDataType }, @@ -348,7 +348,7 @@ declare module "zigbee-clusters" { }, stopWithOnOff: { id: 0x07, direction: "DIRECTION_SERVER_TO_CLIENT" }, }; - class LevelControlCluster extends Cluster { + class LevelControlCluster extends Cluster { moveToLevel( args: { manufacturerId?: number, @@ -450,7 +450,7 @@ declare module "zigbee-clusters" { getAlarm: { id: 0x02, direction: "DIRECTION_SERVER_TO_CLIENT", args: Record /* TODO fix */ }, resetAlarmLog: { id: 0x03, direction: "DIRECTION_SERVER_TO_CLIENT", args: Record /* TODO fix */ }, }; - class AlarmsCluster extends Cluster { + class AlarmsCluster extends Cluster { resetAllAlarms( args: { manufacturerId?: number, @@ -484,7 +484,7 @@ declare module "zigbee-clusters" { } type TimeClusterAttributes = Record; type TimeClusterCommands = Record; - class TimeCluster extends Cluster { + class TimeCluster extends Cluster { } type AnalogInputClusterAttributes = { description: { id: 0x1c, type: ZCLDataType }, @@ -498,7 +498,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type AnalogInputClusterCommands = Record; - class AnalogInputCluster extends Cluster { + class AnalogInputCluster extends Cluster { } type AnalogOutputClusterAttributes = { description: { id: 0x1c, type: ZCLDataType }, @@ -513,7 +513,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type AnalogOutputClusterCommands = Record; - class AnalogOutputCluster extends Cluster { + class AnalogOutputCluster extends Cluster { } type AnalogValueClusterAttributes = { description: { id: 0x1c, type: ZCLDataType }, @@ -525,7 +525,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type AnalogValueClusterCommands = Record; - class AnalogValueCluster extends Cluster { + class AnalogValueCluster extends Cluster { } type BinaryInputClusterAttributes = { activeText: { id: 0x04, type: ZCLDataType }, @@ -539,7 +539,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type BinaryInputClusterCommands = Record; - class BinaryInputCluster extends Cluster { + class BinaryInputCluster extends Cluster { } type BinaryOutputClusterAttributes = { activeText: { id: 0x04, type: ZCLDataType }, @@ -556,7 +556,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type BinaryOutputClusterCommands = Record; - class BinaryOutputCluster extends Cluster { + class BinaryOutputCluster extends Cluster { } type BinaryValueClusterAttributes = { activeText: { id: 0x04, type: ZCLDataType }, @@ -573,7 +573,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type BinaryValueClusterCommands = Record; - class BinaryValueCluster extends Cluster { + class BinaryValueCluster extends Cluster { } type MultistateInputClusterAttributes = { description: { id: 0x1c, type: ZCLDataType }, @@ -585,7 +585,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type MultistateInputClusterCommands = Record; - class MultistateInputCluster extends Cluster { + class MultistateInputCluster extends Cluster { } type MultistateOutputClusterAttributes = { description: { id: 0x1c, type: ZCLDataType }, @@ -598,7 +598,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type MultistateOutputClusterCommands = Record; - class MultistateOutputCluster extends Cluster { + class MultistateOutputCluster extends Cluster { } type MultistateValueClusterAttributes = { description: { id: 0x1c, type: ZCLDataType }, @@ -611,7 +611,7 @@ declare module "zigbee-clusters" { applicationType: { id: 0x100, type: ZCLDataType }, }; type MultistateValueClusterCommands = Record; - class MultistateValueCluster extends Cluster { + class MultistateValueCluster extends Cluster { } type OTAClusterAttributes = { upgradeServerID: { id: 0x00, type: ZCLDataType }, @@ -705,7 +705,7 @@ declare module "zigbee-clusters" { }, }, }; - class OTACluster extends Cluster { + class OTACluster extends Cluster { onImageNotify( args: { manufacturerId?: number, @@ -840,7 +840,7 @@ declare module "zigbee-clusters" { } type PowerProfileClusterAttributes = Record; type PowerProfileClusterCommands = Record; - class PowerProfileCluster extends Cluster { + class PowerProfileCluster extends Cluster { } type PollControlClusterAttributes = { checkInInterval: { id: 0x00, type: ZCLDataType }, @@ -862,7 +862,7 @@ declare module "zigbee-clusters" { }, }, }; - class PollControlCluster extends Cluster { + class PollControlCluster extends Cluster { fastPollStop( args: { manufacturerId?: number, @@ -898,7 +898,7 @@ declare module "zigbee-clusters" { } type ShadeConfigurationClusterAttributes = Record; type ShadeConfigurationClusterCommands = Record; - class ShadeConfigurationCluster extends Cluster { + class ShadeConfigurationCluster extends Cluster { } type DoorLockClusterAttributes = { lockState: { id: 0x00, type: ZCLDataType<"notFullyLocked" | "locked" | "unlocked" | "undefined"> }, @@ -1090,7 +1090,7 @@ declare module "zigbee-clusters" { }, }, }; - class DoorLockCluster extends Cluster { + class DoorLockCluster extends Cluster { lockDoor( args: { manufacturerId?: number, @@ -1478,7 +1478,7 @@ declare module "zigbee-clusters" { }, }, }; - class WindowCoveringCluster extends Cluster { + class WindowCoveringCluster extends Cluster { upOpen( args: { manufacturerId?: number, @@ -1586,7 +1586,7 @@ declare module "zigbee-clusters" { }, }, }; - class ThermostatCluster extends Cluster { + class ThermostatCluster extends Cluster { setSetpoint( args: { manufacturerId?: number, @@ -1602,15 +1602,15 @@ declare module "zigbee-clusters" { } type PumpConfigurationAndControlClusterAttributes = Record; type PumpConfigurationAndControlClusterCommands = Record; - class PumpConfigurationAndControlCluster extends Cluster { + class PumpConfigurationAndControlCluster extends Cluster { } type FanControlClusterAttributes = Record; type FanControlClusterCommands = Record; - class FanControlCluster extends Cluster { + class FanControlCluster extends Cluster { } type DehumidificationControlClusterAttributes = Record; type DehumidificationControlClusterCommands = Record; - class DehumidificationControlCluster extends Cluster { + class DehumidificationControlCluster extends Cluster { } type ColorControlClusterAttributes = { currentHue: { id: 0x00, type: ZCLDataType }, @@ -1653,7 +1653,7 @@ declare module "zigbee-clusters" { }, }, }; - class ColorControlCluster extends Cluster { + class ColorControlCluster extends Cluster { moveToHue( args: { manufacturerId?: number, @@ -1737,7 +1737,7 @@ declare module "zigbee-clusters" { lampBurnHoursTripPoint: { id: 0x35, type: ZCLDataType }, }; type BallastConfigurationClusterCommands = Record; - class BallastConfigurationCluster extends Cluster { + class BallastConfigurationCluster extends Cluster { } type IlluminanceMeasurementClusterAttributes = { measuredValue: { id: 0x00, type: ZCLDataType }, @@ -1747,7 +1747,7 @@ declare module "zigbee-clusters" { lightSensorType: { id: 0x04, type: ZCLDataType<"photodiode" | "cmos" | "unknown"> }, }; type IlluminanceMeasurementClusterCommands = Record; - class IlluminanceMeasurementCluster extends Cluster { + class IlluminanceMeasurementCluster extends Cluster { } type IlluminanceLevelSensingClusterAttributes = { levelStatus: { id: 0x00, type: ZCLDataType<"illuminanceOnTarget" | "illuminanceBelowTarget" | "illuminanceAboveTarget"> }, @@ -1755,7 +1755,7 @@ declare module "zigbee-clusters" { illuminanceTargetLevel: { id: 0x10, type: ZCLDataType }, }; type IlluminanceLevelSensingClusterCommands = Record; - class IlluminanceLevelSensingCluster extends Cluster { + class IlluminanceLevelSensingCluster extends Cluster { } type TemperatureMeasurementClusterAttributes = { measuredValue: { id: 0x00, type: ZCLDataType }, @@ -1763,7 +1763,7 @@ declare module "zigbee-clusters" { maxMeasuredValue: { id: 0x02, type: ZCLDataType }, }; type TemperatureMeasurementClusterCommands = Record; - class TemperatureMeasurementCluster extends Cluster { + class TemperatureMeasurementCluster extends Cluster { } type PressureMeasurementClusterAttributes = { measuredValue: { id: 0x00, type: ZCLDataType }, @@ -1777,7 +1777,7 @@ declare module "zigbee-clusters" { scale: { id: 0x14, type: ZCLDataType }, }; type PressureMeasurementClusterCommands = Record; - class PressureMeasurementCluster extends Cluster { + class PressureMeasurementCluster extends Cluster { } type FlowMeasurementClusterAttributes = { measuredValue: { id: 0x00, type: ZCLDataType }, @@ -1786,7 +1786,7 @@ declare module "zigbee-clusters" { tolerance: { id: 0x03, type: ZCLDataType }, }; type FlowMeasurementClusterCommands = Record; - class FlowMeasurementCluster extends Cluster { + class FlowMeasurementCluster extends Cluster { } type RelativeHumidityClusterAttributes = { measuredValue: { id: 0x00, type: ZCLDataType }, @@ -1795,7 +1795,7 @@ declare module "zigbee-clusters" { tolerance: { id: 0x03, type: ZCLDataType }, }; type RelativeHumidityClusterCommands = Record; - class RelativeHumidityCluster extends Cluster { + class RelativeHumidityCluster extends Cluster { } type OccupancySensingClusterAttributes = { occupancy: { id: 0x00, type: ZCLDataType> }, @@ -1812,7 +1812,7 @@ declare module "zigbee-clusters" { physicalContactUnoccupiedToOccupiedThreshold: { id: 0x32, type: ZCLDataType }, }; type OccupancySensingClusterCommands = Record; - class OccupancySensingCluster extends Cluster { + class OccupancySensingCluster extends Cluster { } type IASZoneClusterAttributes = { zoneState: { id: 0x00, type: ZCLDataType<"notEnrolled" | "enrolled"> }, @@ -1841,7 +1841,7 @@ declare module "zigbee-clusters" { }, initiateNormalOperationMode: { id: 0x01, direction: "DIRECTION_CLIENT_TO_SERVER" }, }; - class IASZoneCluster extends Cluster { + class IASZoneCluster extends Cluster { onZoneStatusChangeNotification( args: { manufacturerId?: number, @@ -1893,11 +1893,11 @@ declare module "zigbee-clusters" { } type IASACEClusterAttributes = Record; type IASACEClusterCommands = Record; - class IASACECluster extends Cluster { + class IASACECluster extends Cluster { } type IASWDClusterAttributes = Record; type IASWDClusterCommands = Record; - class IASWDCluster extends Cluster { + class IASWDCluster extends Cluster { } type MeteringClusterAttributes = { currentSummationDelivered: { id: 0x00, type: ZCLDataType }, @@ -2083,7 +2083,7 @@ declare module "zigbee-clusters" { flowMeasurementPeriod: { id: 0xb15, type: ZCLDataType }, }; type MeteringClusterCommands = Record; - class MeteringCluster extends Cluster { + class MeteringCluster extends Cluster { } type ElectricalMeasurementClusterAttributes = { measurementType: { id: 0x00, type: ZCLDataType> }, @@ -2108,11 +2108,11 @@ declare module "zigbee-clusters" { acActivePowerOverload: { id: 0x803, type: ZCLDataType }, }; type ElectricalMeasurementClusterCommands = Record; - class ElectricalMeasurementCluster extends Cluster { + class ElectricalMeasurementCluster extends Cluster { } type DiagnosticsClusterAttributes = Record; type DiagnosticsClusterCommands = Record; - class DiagnosticsCluster extends Cluster { + class DiagnosticsCluster extends Cluster { } type TouchLinkClusterAttributes = Record; type TouchLinkClusterCommands = { @@ -2121,7 +2121,7 @@ declare module "zigbee-clusters" { }, }, }; - class TouchLinkCluster extends Cluster { + class TouchLinkCluster extends Cluster { getGroups( args: { manufacturerId?: number, @@ -2409,9 +2409,8 @@ declare module "zigbee-clusters" { import {EventEmitter} from "events"; import {ZigBeeNode} from "homey"; - type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; type ZCLDataTypes = typeof import('@athombv/data-types').DataTypes & { - enum8Status: ZCLDataType + enum8Status: ZCLDataType }; function debug(flag: boolean, namespaces: string): void; @@ -2435,7 +2434,7 @@ declare module "zigbee-clusters" { bind(clusterName: string, clusterImpl: BoundCluster): void; unbind(clusterName: string): void; - makeDefaultResponseFrame(receivedFrame: unknown, success: boolean, status: ZCLEnum8Status): typeof zclFrames.ZCLStandardHeader | typeof zclFrames.ZCLMfgSpecificHeader; + makeDefaultResponseFrame(receivedFrame: unknown, success: boolean, status: types.ZCLEnum8Status): typeof zclFrames.ZCLStandardHeader | typeof zclFrames.ZCLMfgSpecificHeader; } type ZCLDataType = import('@athombv/data-types').DataType; @@ -2448,36 +2447,29 @@ declare module "zigbee-clusters" { const ZCLStruct: typeof import('@athombv/data-types').Struct; } - type FrameControlFlag = - 'clusterSpecific' - | 'manufacturerSpecific' - | 'directionToClient' - | 'disableDefaultResponse'; - type ZCLFrameControlBitmap = ZCLDataType>; - namespace zclFrames { const ZCLStandardHeader: import('@athombv/data-types').StaticStruct<{ - frameControl: ZCLFrameControlBitmap, + frameControl: types.ZCLFrameControlBitmap, trxSequenceNumber: ZCLDataTypes["data8"], cmdId: ZCLDataTypes["data8"], data: ZCLDataTypes["buffer"], }>; const ZCLMfgSpecificHeader: import('@athombv/data-types').StaticStruct<{ - frameControl: ZCLFrameControlBitmap, + frameControl: types.ZCLFrameControlBitmap, manufacturerId: ZCLDataTypes["uint16"], trxSequenceNumber: ZCLDataTypes["data8"], cmdId: ZCLDataTypes["data8"], data: ZCLDataTypes["buffer"], }>; - function ZCLAttributeDataRecord(withStatus: boolean, attributes: AttributeDefinitions): ZCLDataType<{ + function ZCLAttributeDataRecord(withStatus: boolean, attributes: types.AttributeDefinitions): ZCLDataType<{ id: number, name?: string, - status?: ZCLEnum8Status + status?: types.ZCLEnum8Status value?: ZCLDataType }>; function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType extends EventEmitter { + abstract class Cluster extends EventEmitter { static get ID(): number; static get NAME(): string; // @ts-expect-error Type should be defined on non-abstract inheritors @@ -2578,37 +2570,37 @@ declare module "zigbee-clusters" { // @ts-expect-error Type should be defined on non-abstract inheritors static get COMMANDS(): Commands; - static DIRECTION_SERVER_TO_CLIENT: CommandToClientDirection; - static DIRECTION_CLIENT_TO_SERVER: CommandToServerDirection; + static DIRECTION_SERVER_TO_CLIENT: types.CommandToClientDirection; + static DIRECTION_CLIENT_TO_SERVER: types.CommandToServerDirection; get logId(): string; discoverCommandsGenerated({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; discoverCommandsReceived({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; - readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; - writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> + readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: types.AttributesFromDefinition[attribute]}>; + writeAttributes(attributes: {[attribute in K]: types.AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> - configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; - readReportingConfiguration(attributes: ReadonlyArray | number>, opts?: {timeout?: number}): Promise>; + configureReporting(attributes: types.AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; + readReportingConfiguration(attributes: ReadonlyArray | number>, opts?: {timeout?: number}): Promise>; discoverAttributes(opts?: {timeout?: number}): Promise>; - discoverAttributesExtended(opts?: {timeout?: number}): Promise>; + discoverAttributesExtended(opts?: {timeout?: number}): Promise>; sendFrame(data: object): Promise; nextSeqNr(): number; static addCluster(clusterClass: typeof Cluster): void; static removeCluster(clusterIdOrName: string | number): void; - static getCluster(clusterIdOrName: string | number): Cluster; + static getCluster(clusterIdOrName: string | number): Cluster; - on>(eventName: `attr.${Event}`, listener: (value: AttributesFromDefinition[Event]) => void): this; + on>(eventName: `attr.${Event}`, listener: (value: types.AttributesFromDefinition[Event]) => void): this; on = unknown[]>(eventName: string, listener: (...args: Values) => void): this; - attributes: Attributes & GLOBAL_ATTRIBUTES; - attributesById: {[Attribute in keyof (Attributes & GLOBAL_ATTRIBUTES) as (Attributes & GLOBAL_ATTRIBUTES)[Attribute]['id']]: { name: Attribute } & (Attributes & GLOBAL_ATTRIBUTES)[Attribute] }; + attributes: Attributes & types.GLOBAL_ATTRIBUTES; + attributesById: {[Attribute in keyof (Attributes & types.GLOBAL_ATTRIBUTES) as (Attributes & types.GLOBAL_ATTRIBUTES)[Attribute]['id']]: { name: Attribute } & (Attributes & types.GLOBAL_ATTRIBUTES)[Attribute] }; - commands: Commands & GLOBAL_COMMANDS; + commands: Commands & types.GLOBAL_COMMANDS; commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; // Adding the global commands here results in types too big for TypeScript } @@ -2619,298 +2611,307 @@ declare module "zigbee-clusters" { get logId(): string; } -} -type ZCLDataTypes = import('zigbee-clusters').ZCLDataTypes; -type ZCLDataType = import('zigbee-clusters').ZCLDataType; -type ZCLStruct>> = import('@athombv/data-types').StructInstance + namespace types { + type FrameControlFlag = + 'clusterSpecific' + | 'manufacturerSpecific' + | 'directionToClient' + | 'disableDefaultResponse'; + type ZCLFrameControlBitmap = ZCLDataType>; -type GLOBAL_ATTRIBUTES = { - clusterRevision: { id: 0xfffd, type: ZCLDataTypes["uint16"] }, - attributeReportingStatus: { - id: 0xfffe, - type: ZCLDataType<"PENDING" | "COMPLETE"> - } -}; + type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; -type GLOBAL_COMMANDS = { - readAttributes: { - id: 0x00, - args: { - attributes: ZCLDataType>, - }, - response: { - id: 0x01, - args: { - attributes: ZCLDataTypes["buffer"], + type GLOBAL_ATTRIBUTES = { + clusterRevision: { id: 0xfffd, type: ZCLDataTypes["uint16"] }, + attributeReportingStatus: { + id: 0xfffe, + type: ZCLDataType<"PENDING" | "COMPLETE"> + } + }; + + type GLOBAL_COMMANDS = { + readAttributes: { + id: 0x00, + args: { + attributes: ZCLDataType>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, }, - }, - global: true, - }, - writeAttributes: { - id: 0x02, - args: { - attributes: ZCLDataTypes["buffer"], - }, - response: { - id: 0x04, - args: { - attributes: ZCLDataType>> + writeAttributes: { + id: 0x02, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, }, - }, - global: true, - }, - writeAttributesAtomic: { - id: 0x03, - args: { - attributes: ZCLDataTypes["buffer"], - }, - response: { - id: 0x04, - args: { - attributes: ZCLDataType>> + writeAttributesAtomic: { + id: 0x03, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, }, - }, - global: true, - }, - writeAttributesNoResponse: { - id: 0x05, - args: { - attributes: ZCLDataTypes["buffer"], - }, - global: true, - }, + writeAttributesNoResponse: { + id: 0x05, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, + }, - configureReporting: { - id: 0x06, - args: { - reports: ReturnType, - }, - response: { - id: 0x07, - args: { - reports: ZCLDataType - attributeId: ZCLDataTypes["uint16"] - }>>> + configureReporting: { + id: 0x06, + args: { + reports: ReturnType, + }, + response: { + id: 0x07, + args: { + reports: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>> + }, + }, + global: true, }, - }, - global: true, - }, - readReportingConfiguration: { - id: 0x08, - args: { - attributes: ZCLDataType - attributeId: ZCLDataTypes["uint16"] - }>>>, - }, - response: { - id: 0x09, - args: { - reports: ReturnType, + readReportingConfiguration: { + id: 0x08, + args: { + attributes: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>>, + }, + response: { + id: 0x09, + args: { + reports: ReturnType, + }, + }, + global: true, }, - }, - global: true, - }, - reportAttributes: { - id: 0x0A, - args: { - attributes: ZCLDataTypes["buffer"], - }, - global: true, - }, + reportAttributes: { + id: 0x0A, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, + }, - defaultResponse: { - id: 0x0B, - args: { - cmdId: ZCLDataTypes["uint8"], - status: ZCLDataTypes["enum8Status"], - }, - global: true, - }, + defaultResponse: { + id: 0x0B, + args: { + cmdId: ZCLDataTypes["uint8"], + status: ZCLDataTypes["enum8Status"], + }, + global: true, + }, - discoverAttributes: { - id: 0x0C, - args: { - startValue: ZCLDataTypes["uint16"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x0D, - args: { - lastResponse: ZCLDataTypes["bool"], - attributes: ZCLDataType>>, + discoverAttributes: { + id: 0x0C, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x0D, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>>, + }, + }, + global: true, }, - }, - global: true, - }, - readAttributesStructured: { - id: 0x0E, - args: { - attributes: ZCLDataType>, - }>>>, - }, - response: { - id: 0x01, - args: { - attributes: ZCLDataTypes["buffer"], + readAttributesStructured: { + id: 0x0E, + args: { + attributes: ZCLDataType>, + }>>>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, }, - }, - global: true, - }, - writeAttributesStructured: { - id: 0x0F, - args: { - attributes: ZCLDataType>, - dataTypeId: ZCLDataTypes["uint8"], - value: ZCLDataTypes["buffer"], - }>>>, - }, - response: { - id: 0x10, - args: { - attributes: ZCLDataTypes["buffer"], + writeAttributesStructured: { + id: 0x0F, + args: { + attributes: ZCLDataType>, + dataTypeId: ZCLDataTypes["uint8"], + value: ZCLDataTypes["buffer"], + }>>>, + }, + response: { + id: 0x10, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, }, - }, - global: true, - }, - discoverCommandsReceived: { - id: 0x11, - args: { - startValue: ZCLDataTypes["uint8"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x12, - args: { - lastResponse: ZCLDataTypes["bool"], - commandIds: ZCLDataType>, + discoverCommandsReceived: { + id: 0x11, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x12, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, }, - }, - global: true, - }, - discoverCommandsGenerated: { - id: 0x13, - args: { - startValue: ZCLDataTypes["uint8"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x14, - args: { - lastResponse: ZCLDataTypes["bool"], - commandIds: ZCLDataType>, + discoverCommandsGenerated: { + id: 0x13, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x14, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, }, - }, - global: true, - }, - discoverAttributesExtended: { - id: 0x15, - args: { - startValue: ZCLDataTypes["uint16"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x16, - args: { - lastResponse: ZCLDataTypes["bool"], - attributes: ZCLDataType>, - }>>>, - }, - }, - global: true, - }, -}; + discoverAttributesExtended: { + id: 0x15, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x16, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>, + }>>>, + }, + }, + global: true, + }, + }; -type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; -type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; -type CommandDirection = CommandToServerDirection | CommandToClientDirection; + type ZCLStructInstance>> = import('@athombv/data-types').StructInstance -type FromZCLDataType = DataType extends import('zigbee-clusters').ZCLDataType? InferredValue : DataType; + type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; + type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; + type CommandDirection = CommandToServerDirection | CommandToClientDirection; -type AttributeDefinition = { - id: number, - type: import('zigbee-clusters').ZCLDataType, - manufacturerId?: number, -} + type FromZCLDataType = DataType extends ZCLDataType? InferredValue : DataType; -type AttributeDefinitions = { - [attributeName: string]: AttributeDefinition, -} + type AttributeDefinition = { + id: number, + type: ZCLDataType, + manufacturerId?: number, + } -type AttributesFromDefinition = { - [attribute in keyof Definition]: FromZCLDataType -} + type AttributeDefinitions = { + [attributeName: string]: AttributeDefinition, + } -type CommandDefinition = { - id: number, - direction?: CommandDirection, - args?: { - [argName: string]: import('zigbee-clusters').ZCLDataType, - } - response?: CommandDefinition, - frameControl?: import('zigbee-clusters').FrameControlFlag[]; - encodeMissingFieldsBehavior?: 'default' | 'skip'; - global?: boolean; -} + type AttributesFromDefinition = { + [attribute in keyof Definition]: FromZCLDataType + } -type CommandDefinitions = { - [commandName: string]: CommandDefinition, -} + type CommandDefinition = { + id: number, + direction?: CommandDirection, + args?: { + [argName: string]: ZCLDataType, + } + response?: CommandDefinition, + frameControl?: FrameControlFlag[]; + encodeMissingFieldsBehavior?: 'default' | 'skip'; + global?: boolean; + } -type AttributeReportingConfiguration = { - [attribute in AttributeKey]: { - minInterval?: number, - maxInterval?: number, - minChange?: number - } -} + type CommandDefinitions = { + [commandName: string]: CommandDefinition, + } -type ReadReportingConfigurationResponse = { - status: import('zigbee-clusters').ZCLEnum8Status, - direction: 'reported'|'received'; - attributeId: number; - attributeDataType?: number; - minInterval?: number; - maxInterval?: number; - minChange?: number; - timeoutPeriod?: number; -} + type AttributeReportingConfiguration = { + [attribute in AttributeKey]: { + minInterval?: number, + maxInterval?: number, + minChange?: number + } + } + + type ReadReportingConfigurationResponse = { + status: ZCLEnum8Status, + direction: 'reported'|'received'; + attributeId: number; + attributeDataType?: number; + minInterval?: number; + maxInterval?: number; + minChange?: number; + timeoutPeriod?: number; + } -type ExtendedAttributesResponse = { - name?: string; - id: number; - acl: { - readable: boolean; - writable: boolean; - reportable: boolean; + type ExtendedAttributesResponse = { + name?: string; + id: number; + acl: { + readable: boolean; + writable: boolean; + reportable: boolean; + } + } } } diff --git a/scripts/generate-types.mts b/scripts/generate-types.mts index 8faca6f..f33ab05 100644 --- a/scripts/generate-types.mts +++ b/scripts/generate-types.mts @@ -1,7 +1,7 @@ -import {Cluster} from "zigbee-clusters"; +import type {Cluster, types} from "zigbee-clusters"; import path from "node:path"; import * as fs from "node:fs/promises"; -import {DataType, DataTypes} from "@athombv/data-types"; +import type {DataType, DataTypes} from "@athombv/data-types"; const INDENTATION_SPACES = 2; @@ -156,7 +156,7 @@ async function formatCluster(className: string, classDefinition: typeof Cluster) } // Open class - stringBuilder.printLine(`class ${className} extends Cluster {`); + stringBuilder.printLine(`class ${className} extends Cluster {`); stringBuilder.increaseIndent(); for (const command in classDefinition.COMMANDS) { @@ -172,7 +172,7 @@ async function formatCluster(className: string, classDefinition: typeof Cluster) } -function formatAttribute(stringBuilder: StringBuilder, className: string, name: string, definition: AttributeDefinition): void { +function formatAttribute(stringBuilder: StringBuilder, className: string, name: string, definition: types.AttributeDefinition): void { stringBuilder.startLine(); stringBuilder.print(`${name}: { id: 0x${definition.id.toString(16).padStart(2, "0")}`); stringBuilder.print(', type: ZCLDataType<'); @@ -182,7 +182,7 @@ function formatAttribute(stringBuilder: StringBuilder, className: string, name: } -function formatCommand(stringBuilder: StringBuilder, className: string, name: string, definition: CommandDefinition): void { +function formatCommand(stringBuilder: StringBuilder, className: string, name: string, definition: types.CommandDefinition): void { stringBuilder.startLine(); stringBuilder.print(`${name}: { id: 0x${definition.id.toString(16).padStart(2, "0")}`); stringBuilder.print(`, direction: ${JSON.stringify(definition.direction ?? "DIRECTION_SERVER_TO_CLIENT")}`); @@ -232,7 +232,7 @@ function formatCommand(stringBuilder: StringBuilder, className: string, name: st } -function formatCommandMethod(stringBuilder: StringBuilder, className: string, name: string, definition: CommandDefinition): void { +function formatCommandMethod(stringBuilder: StringBuilder, className: string, name: string, definition: types.CommandDefinition): void { // Method name stringBuilder.startLine(); if (definition.direction === 'DIRECTION_SERVER_TO_CLIENT') { diff --git a/scripts/template.d.ts.txt b/scripts/template.d.ts.txt index 31a3cef..74382ea 100644 --- a/scripts/template.d.ts.txt +++ b/scripts/template.d.ts.txt @@ -2,9 +2,8 @@ declare module 'zigbee-clusters' { import {EventEmitter} from "events"; import {ZigBeeNode} from "homey"; - type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; type ZCLDataTypes = typeof import('@athombv/data-types').DataTypes & { - enum8Status: ZCLDataType + enum8Status: ZCLDataType }; function debug(flag: boolean, namespaces: string): void; @@ -28,7 +27,7 @@ declare module 'zigbee-clusters' { bind(clusterName: string, clusterImpl: BoundCluster): void; unbind(clusterName: string): void; - makeDefaultResponseFrame(receivedFrame: unknown, success: boolean, status: ZCLEnum8Status): typeof zclFrames.ZCLStandardHeader | typeof zclFrames.ZCLMfgSpecificHeader; + makeDefaultResponseFrame(receivedFrame: unknown, success: boolean, status: types.ZCLEnum8Status): typeof zclFrames.ZCLStandardHeader | typeof zclFrames.ZCLMfgSpecificHeader; } type ZCLDataType = import('@athombv/data-types').DataType; @@ -41,36 +40,29 @@ declare module 'zigbee-clusters' { const ZCLStruct: typeof import('@athombv/data-types').Struct; } - type FrameControlFlag = - 'clusterSpecific' - | 'manufacturerSpecific' - | 'directionToClient' - | 'disableDefaultResponse'; - type ZCLFrameControlBitmap = ZCLDataType>; - namespace zclFrames { const ZCLStandardHeader: import('@athombv/data-types').StaticStruct<{ - frameControl: ZCLFrameControlBitmap, + frameControl: types.ZCLFrameControlBitmap, trxSequenceNumber: ZCLDataTypes["data8"], cmdId: ZCLDataTypes["data8"], data: ZCLDataTypes["buffer"], }>; const ZCLMfgSpecificHeader: import('@athombv/data-types').StaticStruct<{ - frameControl: ZCLFrameControlBitmap, + frameControl: types.ZCLFrameControlBitmap, manufacturerId: ZCLDataTypes["uint16"], trxSequenceNumber: ZCLDataTypes["data8"], cmdId: ZCLDataTypes["data8"], data: ZCLDataTypes["buffer"], }>; - function ZCLAttributeDataRecord(withStatus: boolean, attributes: AttributeDefinitions): ZCLDataType<{ + function ZCLAttributeDataRecord(withStatus: boolean, attributes: types.AttributeDefinitions): ZCLDataType<{ id: number, name?: string, - status?: ZCLEnum8Status + status?: types.ZCLEnum8Status value?: ZCLDataType }>; function ZCLConfigureReportingRecords({ withStatus }: {withStatus?: boolean}): ZCLDataType extends EventEmitter { + abstract class Cluster extends EventEmitter { static get ID(): number; static get NAME(): string; // @ts-expect-error Type should be defined on non-abstract inheritors @@ -171,37 +163,37 @@ declare module 'zigbee-clusters' { // @ts-expect-error Type should be defined on non-abstract inheritors static get COMMANDS(): Commands; - static DIRECTION_SERVER_TO_CLIENT: CommandToClientDirection; - static DIRECTION_CLIENT_TO_SERVER: CommandToServerDirection; + static DIRECTION_SERVER_TO_CLIENT: types.CommandToClientDirection; + static DIRECTION_CLIENT_TO_SERVER: types.CommandToServerDirection; get logId(): string; discoverCommandsGenerated({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; discoverCommandsReceived({startValue, maxResults}?: {startValue?: number, maxResults?: number}, opts?: {timeout?: number}): Promise>; - readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: AttributesFromDefinition[attribute]}>; - writeAttributes(attributes: {[attribute in K]: AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> + readAttributes(attributes: ReadonlyArray, opts?: {timeout?: number}): Promise<{[attribute in K]: types.AttributesFromDefinition[attribute]}>; + writeAttributes(attributes: {[attribute in K]: types.AttributesFromDefinition[attribute]}, opts?: {timeout?: number}): Promise<{[attribute in K]: {id: number, status: 'SUCCESS' | 'FAILURE'}}> - configureReporting(attributes: AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; - readReportingConfiguration(attributes: ReadonlyArray | number>, opts?: {timeout?: number}): Promise>; + configureReporting(attributes: types.AttributeReportingConfiguration>, opts?: {timeout?: number}): Promise; + readReportingConfiguration(attributes: ReadonlyArray | number>, opts?: {timeout?: number}): Promise>; discoverAttributes(opts?: {timeout?: number}): Promise>; - discoverAttributesExtended(opts?: {timeout?: number}): Promise>; + discoverAttributesExtended(opts?: {timeout?: number}): Promise>; sendFrame(data: object): Promise; nextSeqNr(): number; static addCluster(clusterClass: typeof Cluster): void; static removeCluster(clusterIdOrName: string | number): void; - static getCluster(clusterIdOrName: string | number): Cluster; + static getCluster(clusterIdOrName: string | number): Cluster; - on>(eventName: `attr.${Event}`, listener: (value: AttributesFromDefinition[Event]) => void): this; + on>(eventName: `attr.${Event}`, listener: (value: types.AttributesFromDefinition[Event]) => void): this; on = unknown[]>(eventName: string, listener: (...args: Values) => void): this; - attributes: Attributes & GLOBAL_ATTRIBUTES; - attributesById: {[Attribute in keyof (Attributes & GLOBAL_ATTRIBUTES) as (Attributes & GLOBAL_ATTRIBUTES)[Attribute]['id']]: { name: Attribute } & (Attributes & GLOBAL_ATTRIBUTES)[Attribute] }; + attributes: Attributes & types.GLOBAL_ATTRIBUTES; + attributesById: {[Attribute in keyof (Attributes & types.GLOBAL_ATTRIBUTES) as (Attributes & types.GLOBAL_ATTRIBUTES)[Attribute]['id']]: { name: Attribute } & (Attributes & types.GLOBAL_ATTRIBUTES)[Attribute] }; - commands: Commands & GLOBAL_COMMANDS; + commands: Commands & types.GLOBAL_COMMANDS; commandsById: {[Command in keyof Commands as Commands[Command]['id']]: Array<{name: Command} & Commands[Command]>}; // Adding the global commands here results in types too big for TypeScript } @@ -212,298 +204,307 @@ declare module 'zigbee-clusters' { get logId(): string; } -} -type ZCLDataTypes = import('zigbee-clusters').ZCLDataTypes; -type ZCLDataType = import('zigbee-clusters').ZCLDataType; -type ZCLStruct>> = import('@athombv/data-types').StructInstance - -type GLOBAL_ATTRIBUTES = { - clusterRevision: { id: 0xfffd, type: ZCLDataTypes["uint16"] }, - attributeReportingStatus: { - id: 0xfffe, - type: ZCLDataType<"PENDING" | "COMPLETE"> - } -}; - -type GLOBAL_COMMANDS = { - readAttributes: { - id: 0x00, - args: { - attributes: ZCLDataType>, - }, - response: { - id: 0x01, - args: { - attributes: ZCLDataTypes["buffer"], + namespace types { + type FrameControlFlag = + 'clusterSpecific' + | 'manufacturerSpecific' + | 'directionToClient' + | 'disableDefaultResponse'; + type ZCLFrameControlBitmap = ZCLDataType>; + + type ZCLEnum8Status = 'SUCCESS' | 'FAILURE' | 'NOT_AUTHORIZED' | 'RESERVED_FIELD_NOT_ZERO' | 'MALFORMED_COMMAND' | 'UNSUP_CLUSTER_COMMAND' | 'UNSUP_GENERAL_COMMAND' | 'UNSUP_MANUF_CLUSTER_COMMAND' | 'UNSUP_MANUF_GENERAL_COMMAND' | 'INVALID_FIELD' | 'UNSUPPORTED_ATTRIBUTE' | 'INVALID_VALUE' | 'READ_ONLY' | 'INSUFFICIENT_SPACE' | 'DUPLICATE_EXISTS' | 'NOT_FOUND' | 'UNREPORTABLE_ATTRIBUTE' | 'INVALID_DATA_TYPE' | 'INVALID_SELECTOR' | 'WRITE_ONLY' | 'INCONSISTENT_STARTUP_STATE' | 'DEFINED_OUT_OF_BAND' | 'INCONSISTENT' | 'ACTION_DENIED' | 'TIMEOUT' | 'ABORT' | 'INVALID_IMAGE' | 'WAIT_FOR_DATA' | 'NO_IMAGE_AVAILABLE' | 'REQUIRE_MORE_IMAGE' | 'NOTIFICATION_PENDING' | 'HARDWARE_FAILURE' | 'SOFTWARE_FAILURE' | 'CALIBRATION_ERROR' | 'UNSUPPORTED_CLUSTER'; + + type GLOBAL_ATTRIBUTES = { + clusterRevision: { id: 0xfffd, type: ZCLDataTypes["uint16"] }, + attributeReportingStatus: { + id: 0xfffe, + type: ZCLDataType<"PENDING" | "COMPLETE"> + } + }; + + type GLOBAL_COMMANDS = { + readAttributes: { + id: 0x00, + args: { + attributes: ZCLDataType>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, }, - }, - global: true, - }, - writeAttributes: { - id: 0x02, - args: { - attributes: ZCLDataTypes["buffer"], - }, - response: { - id: 0x04, - args: { - attributes: ZCLDataType>> + writeAttributes: { + id: 0x02, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, }, - }, - global: true, - }, - writeAttributesAtomic: { - id: 0x03, - args: { - attributes: ZCLDataTypes["buffer"], - }, - response: { - id: 0x04, - args: { - attributes: ZCLDataType>> + writeAttributesAtomic: { + id: 0x03, + args: { + attributes: ZCLDataTypes["buffer"], + }, + response: { + id: 0x04, + args: { + attributes: ZCLDataType>> + }, + }, + global: true, }, - }, - global: true, - }, - - writeAttributesNoResponse: { - id: 0x05, - args: { - attributes: ZCLDataTypes["buffer"], - }, - global: true, - }, - configureReporting: { - id: 0x06, - args: { - reports: ReturnType, - }, - response: { - id: 0x07, - args: { - reports: ZCLDataType - attributeId: ZCLDataTypes["uint16"] - }>>> + writeAttributesNoResponse: { + id: 0x05, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, }, - }, - global: true, - }, - - readReportingConfiguration: { - id: 0x08, - args: { - attributes: ZCLDataType - attributeId: ZCLDataTypes["uint16"] - }>>>, - }, - response: { - id: 0x09, - args: { - reports: ReturnType, + + configureReporting: { + id: 0x06, + args: { + reports: ReturnType, + }, + response: { + id: 0x07, + args: { + reports: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>> + }, + }, + global: true, }, - }, - global: true, - }, - reportAttributes: { - id: 0x0A, - args: { - attributes: ZCLDataTypes["buffer"], - }, - global: true, - }, - - defaultResponse: { - id: 0x0B, - args: { - cmdId: ZCLDataTypes["uint8"], - status: ZCLDataTypes["enum8Status"], - }, - global: true, - }, - - discoverAttributes: { - id: 0x0C, - args: { - startValue: ZCLDataTypes["uint16"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x0D, - args: { - lastResponse: ZCLDataTypes["bool"], - attributes: ZCLDataType>>, + readReportingConfiguration: { + id: 0x08, + args: { + attributes: ZCLDataType + attributeId: ZCLDataTypes["uint16"] + }>>>, + }, + response: { + id: 0x09, + args: { + reports: ReturnType, + }, + }, + global: true, }, - }, - global: true, - }, - - readAttributesStructured: { - id: 0x0E, - args: { - attributes: ZCLDataType>, - }>>>, - }, - response: { - id: 0x01, - args: { - attributes: ZCLDataTypes["buffer"], + + reportAttributes: { + id: 0x0A, + args: { + attributes: ZCLDataTypes["buffer"], + }, + global: true, }, - }, - global: true, - }, - - writeAttributesStructured: { - id: 0x0F, - args: { - attributes: ZCLDataType>, - dataTypeId: ZCLDataTypes["uint8"], - value: ZCLDataTypes["buffer"], - }>>>, - }, - response: { - id: 0x10, - args: { - attributes: ZCLDataTypes["buffer"], + + defaultResponse: { + id: 0x0B, + args: { + cmdId: ZCLDataTypes["uint8"], + status: ZCLDataTypes["enum8Status"], + }, + global: true, }, - }, - global: true, - }, - - discoverCommandsReceived: { - id: 0x11, - args: { - startValue: ZCLDataTypes["uint8"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x12, - args: { - lastResponse: ZCLDataTypes["bool"], - commandIds: ZCLDataType>, + + discoverAttributes: { + id: 0x0C, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x0D, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>>, + }, + }, + global: true, }, - }, - global: true, - }, - - discoverCommandsGenerated: { - id: 0x13, - args: { - startValue: ZCLDataTypes["uint8"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x14, - args: { - lastResponse: ZCLDataTypes["bool"], - commandIds: ZCLDataType>, + + readAttributesStructured: { + id: 0x0E, + args: { + attributes: ZCLDataType>, + }>>>, + }, + response: { + id: 0x01, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, }, - }, - global: true, - }, - - discoverAttributesExtended: { - id: 0x15, - args: { - startValue: ZCLDataTypes["uint16"], - maxResults: ZCLDataTypes["uint8"], - }, - response: { - id: 0x16, - args: { - lastResponse: ZCLDataTypes["bool"], - attributes: ZCLDataType>, - }>>>, + + writeAttributesStructured: { + id: 0x0F, + args: { + attributes: ZCLDataType>, + dataTypeId: ZCLDataTypes["uint8"], + value: ZCLDataTypes["buffer"], + }>>>, + }, + response: { + id: 0x10, + args: { + attributes: ZCLDataTypes["buffer"], + }, + }, + global: true, }, - }, - global: true, - }, -}; -type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; -type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; -type CommandDirection = CommandToServerDirection | CommandToClientDirection; + discoverCommandsReceived: { + id: 0x11, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x12, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, + }, -type FromZCLDataType = DataType extends import('zigbee-clusters').ZCLDataType? InferredValue : DataType; + discoverCommandsGenerated: { + id: 0x13, + args: { + startValue: ZCLDataTypes["uint8"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x14, + args: { + lastResponse: ZCLDataTypes["bool"], + commandIds: ZCLDataType>, + }, + }, + global: true, + }, -type AttributeDefinition = { - id: number, - type: import('zigbee-clusters').ZCLDataType, - manufacturerId?: number, -} + discoverAttributesExtended: { + id: 0x15, + args: { + startValue: ZCLDataTypes["uint16"], + maxResults: ZCLDataTypes["uint8"], + }, + response: { + id: 0x16, + args: { + lastResponse: ZCLDataTypes["bool"], + attributes: ZCLDataType>, + }>>>, + }, + }, + global: true, + }, + }; -type AttributeDefinitions = { - [attributeName: string]: AttributeDefinition, -} + type ZCLStructInstance>> = import('@athombv/data-types').StructInstance -type AttributesFromDefinition = { - [attribute in keyof Definition]: FromZCLDataType -} + type CommandToServerDirection = 'DIRECTION_CLIENT_TO_SERVER'; + type CommandToClientDirection = 'DIRECTION_SERVER_TO_CLIENT'; + type CommandDirection = CommandToServerDirection | CommandToClientDirection; -type CommandDefinition = { - id: number, - direction?: CommandDirection, - args?: { - [argName: string]: import('zigbee-clusters').ZCLDataType, - } - response?: CommandDefinition, - frameControl?: import('zigbee-clusters').FrameControlFlag[]; - encodeMissingFieldsBehavior?: 'default' | 'skip'; - global?: boolean; -} + type FromZCLDataType = DataType extends ZCLDataType? InferredValue : DataType; -type CommandDefinitions = { - [commandName: string]: CommandDefinition, -} + type AttributeDefinition = { + id: number, + type: ZCLDataType, + manufacturerId?: number, + } -type AttributeReportingConfiguration = { - [attribute in AttributeKey]: { - minInterval?: number, - maxInterval?: number, - minChange?: number - } -} + type AttributeDefinitions = { + [attributeName: string]: AttributeDefinition, + } -type ReadReportingConfigurationResponse = { - status: import('zigbee-clusters').ZCLEnum8Status, - direction: 'reported'|'received'; - attributeId: number; - attributeDataType?: number; - minInterval?: number; - maxInterval?: number; - minChange?: number; - timeoutPeriod?: number; -} + type AttributesFromDefinition = { + [attribute in keyof Definition]: FromZCLDataType + } -type ExtendedAttributesResponse = { - name?: string; - id: number; - acl: { - readable: boolean; - writable: boolean; - reportable: boolean; + type CommandDefinition = { + id: number, + direction?: CommandDirection, + args?: { + [argName: string]: ZCLDataType, + } + response?: CommandDefinition, + frameControl?: FrameControlFlag[]; + encodeMissingFieldsBehavior?: 'default' | 'skip'; + global?: boolean; + } + + type CommandDefinitions = { + [commandName: string]: CommandDefinition, + } + + type AttributeReportingConfiguration = { + [attribute in AttributeKey]: { + minInterval?: number, + maxInterval?: number, + minChange?: number + } + } + + type ReadReportingConfigurationResponse = { + status: ZCLEnum8Status, + direction: 'reported'|'received'; + attributeId: number; + attributeDataType?: number; + minInterval?: number; + maxInterval?: number; + minChange?: number; + timeoutPeriod?: number; + } + + type ExtendedAttributesResponse = { + name?: string; + id: number; + acl: { + readable: boolean; + writable: boolean; + reportable: boolean; + } + } } } From e7ab90f24569c38991e1ac783ad38b115ab3893a Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Fri, 10 Apr 2026 12:26:26 +0200 Subject: [PATCH 9/9] Fix linting errors --- lib/clusters/metering.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/clusters/metering.js b/lib/clusters/metering.js index d0a24a7..1027cb1 100644 --- a/lib/clusters/metering.js +++ b/lib/clusters/metering.js @@ -63,18 +63,21 @@ const ATTRIBUTES = { // meteringDeviceType: { id: 0x0306, type: ZCLDataTypes.map8() }, // 774, Mandatory siteId: { id: 0x0307, type: ZCLDataTypes.octstr }, // 775, Optional meterSerialNumber: { id: 0x0308, type: ZCLDataTypes.octstr }, // 776, Optional - energyCarrierUnitOfMeasure: { id: 0x0309, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 777, Optional + /* 777, Optional */ + energyCarrierUnitOfMeasure: { id: 0x0309, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros // energyCarrierSummationFormatting: { id: 0x030A, type: ZCLDataTypes.map8() }, // 778, Optional // energyCarrierDemandFormatting: { id: 0x030B, type: ZCLDataTypes.map8() }, // 779, Optional - temperatureUnitOfMeasure: { id: 0x030C, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 780, Optional + /* 780, Optional */ + temperatureUnitOfMeasure: { id: 0x030C, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros // temperatureFormatting: { id: 0x030D, type: ZCLDataTypes.map8() }, // 781, Optional moduleSerialNumber: { id: 0x030E, type: ZCLDataTypes.octstr }, // 782, Optional operatingTariffLabelDelivered: { id: 0x030F, type: ZCLDataTypes.octstr }, // 783, Optional operatingTariffLabelReceived: { id: 0x0310, type: ZCLDataTypes.octstr }, // 784, Optional customerIdNumber: { id: 0x0311, type: ZCLDataTypes.octstr }, // 785, Optional - alternativeUnitOfMeasure: { id: 0x0312, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 786, Optional + /* 786, Optional */ + alternativeUnitOfMeasure: { id: 0x0312, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // TODO: map8 packed fields — bits 0-2: right digits, 3-6: left digits, 7: suppress zeros // alternativeDemandFormatting: { id: 0x0313, type: ZCLDataTypes.map8() }, // 787, Optional // alternativeConsumptionFormatting: { id: 0x0314, type: ZCLDataTypes.map8() }, // 788, Optional @@ -258,7 +261,8 @@ const ATTRIBUTES = { id: 0x0B00, // 2816 type: ZCLDataTypes.uint32, }, - proposedChangeSupplyStatus: { id: 0x0B01, type: ZCLDataTypes.enum8({/* TODO fix */}) }, // 2817, Optional + /* 2817, Optional */ + proposedChangeSupplyStatus: { id: 0x0B01, type: ZCLDataTypes.enum8({/* TODO fix */}) }, uncontrolledFlowThreshold: { id: 0x0B10, type: ZCLDataTypes.uint16 }, // 2832, Optional uncontrolledFlowThresholdUnitOfMeasure: { // Optional id: 0x0B11, // 2833