@willieee802/zigbee-herdsman 0.49.3 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +0 -3
- package/.github/workflows/ci.yml +1 -2
- package/.github/workflows/release-please.yml +1 -1
- package/.github/workflows/typedoc.yaml +3 -3
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +143 -0
- package/biome.json +1 -1
- package/dist/adapter/adapter.d.ts +14 -1
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/adapter/adapter.js +17 -0
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/adapterDiscovery.d.ts.map +1 -1
- package/dist/adapter/adapterDiscovery.js.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +1 -3
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.js +14 -29
- package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
- package/dist/adapter/deconz/driver/constants.d.ts +1 -1
- package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.d.ts +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.js +19 -10
- package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.d.ts +2 -0
- package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.js +13 -5
- package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +1 -3
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.js +17 -30
- package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
- package/dist/adapter/ezsp/driver/index.d.ts +1 -1
- package/dist/adapter/ezsp/driver/index.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/index.js +1 -1
- package/dist/adapter/ezsp/driver/index.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/index.d.ts +1 -1
- package/dist/adapter/ezsp/driver/types/index.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/types/index.js +3 -3
- package/dist/adapter/ezsp/driver/types/index.js.map +1 -1
- package/dist/adapter/serialPort.d.ts.map +1 -1
- package/dist/adapter/serialPort.js +7 -0
- package/dist/adapter/serialPort.js.map +1 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.js +1 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.js.map +1 -1
- package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +1 -1
- package/dist/adapter/z-stack/adapter/adapter-nv-memory.js.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.js +12 -2
- package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
- package/dist/adapter/z-stack/adapter/tstype.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +1 -3
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +20 -34
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/z-stack/constants/index.d.ts +1 -1
- package/dist/adapter/z-stack/constants/index.d.ts.map +1 -1
- package/dist/adapter/z-stack/constants/index.js +1 -1
- package/dist/adapter/z-stack/constants/index.js.map +1 -1
- package/dist/adapter/z-stack/unpi/constants.d.ts +1 -1
- package/dist/adapter/z-stack/unpi/constants.d.ts.map +1 -1
- package/dist/adapter/z-stack/unpi/constants.js +1 -1
- package/dist/adapter/z-stack/unpi/constants.js.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts +7 -8
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.js +12 -30
- package/dist/adapter/zboss/adapter/zbossAdapter.js.map +1 -1
- package/dist/adapter/zboss/driver.d.ts.map +1 -1
- package/dist/adapter/zboss/driver.js +8 -1
- package/dist/adapter/zboss/driver.js.map +1 -1
- package/dist/adapter/zboss/uart.d.ts.map +1 -1
- package/dist/adapter/zboss/uart.js +14 -2
- package/dist/adapter/zboss/uart.js.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +1 -3
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +8 -29
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/adapter/zoh/adapter/zohAdapter.d.ts +1 -3
- package/dist/adapter/zoh/adapter/zohAdapter.d.ts.map +1 -1
- package/dist/adapter/zoh/adapter/zohAdapter.js +18 -33
- package/dist/adapter/zoh/adapter/zohAdapter.js.map +1 -1
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/controller/controller.js +10 -2
- package/dist/controller/controller.js.map +1 -1
- package/dist/controller/greenPower.d.ts.map +1 -1
- package/dist/controller/greenPower.js +15 -9
- package/dist/controller/greenPower.js.map +1 -1
- package/dist/controller/helpers/ota.d.ts +4 -4
- package/dist/controller/helpers/ota.d.ts.map +1 -1
- package/dist/controller/helpers/ota.js +28 -9
- package/dist/controller/helpers/ota.js.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.js +17 -16
- package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
- package/dist/controller/model/device.d.ts +14 -4
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +167 -85
- package/dist/controller/model/device.js.map +1 -1
- package/dist/controller/model/endpoint.d.ts +7 -3
- package/dist/controller/model/endpoint.d.ts.map +1 -1
- package/dist/controller/model/endpoint.js +34 -21
- package/dist/controller/model/endpoint.js.map +1 -1
- package/dist/controller/model/group.d.ts +0 -1
- package/dist/controller/model/group.d.ts.map +1 -1
- package/dist/controller/model/group.js +14 -19
- package/dist/controller/model/group.js.map +1 -1
- package/dist/controller/touchlink.js +3 -3
- package/dist/controller/touchlink.js.map +1 -1
- package/dist/utils/timeService.js +2 -2
- package/dist/utils/timeService.js.map +1 -1
- package/dist/zspec/zcl/buffaloZcl.d.ts +3 -3
- package/dist/zspec/zcl/buffaloZcl.d.ts.map +1 -1
- package/dist/zspec/zcl/buffaloZcl.js +198 -96
- package/dist/zspec/zcl/buffaloZcl.js.map +1 -1
- package/dist/zspec/zcl/definition/cluster.d.ts +2 -2
- package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/cluster.js +2699 -2808
- package/dist/zspec/zcl/definition/cluster.js.map +1 -1
- package/dist/zspec/zcl/definition/clusters-types.d.ts +63 -1109
- package/dist/zspec/zcl/definition/clusters-types.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/enums.d.ts +0 -1
- package/dist/zspec/zcl/definition/enums.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/enums.js +0 -1
- package/dist/zspec/zcl/definition/enums.js.map +1 -1
- package/dist/zspec/zcl/definition/foundation.d.ts +306 -7
- package/dist/zspec/zcl/definition/foundation.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/foundation.js +552 -207
- package/dist/zspec/zcl/definition/foundation.js.map +1 -1
- package/dist/zspec/zcl/definition/status.d.ts +21 -10
- package/dist/zspec/zcl/definition/status.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/status.js +11 -0
- package/dist/zspec/zcl/definition/status.js.map +1 -1
- package/dist/zspec/zcl/definition/tstype.d.ts +57 -48
- package/dist/zspec/zcl/definition/tstype.d.ts.map +1 -1
- package/dist/zspec/zcl/utils.d.ts +7 -4
- package/dist/zspec/zcl/utils.d.ts.map +1 -1
- package/dist/zspec/zcl/utils.js +133 -240
- package/dist/zspec/zcl/utils.js.map +1 -1
- package/dist/zspec/zcl/zclFrame.d.ts +4 -4
- package/dist/zspec/zcl/zclFrame.d.ts.map +1 -1
- package/dist/zspec/zcl/zclFrame.js +19 -103
- package/dist/zspec/zcl/zclFrame.js.map +1 -1
- package/dist/zspec/zcl/zclStatusError.d.ts +1 -1
- package/dist/zspec/zcl/zclStatusError.d.ts.map +1 -1
- package/dist/zspec/zcl/zclStatusError.js +2 -2
- package/dist/zspec/zcl/zclStatusError.js.map +1 -1
- package/package.json +1 -1
- package/scripts/clusters-typegen.ts +44 -139
- package/src/adapter/adapter.ts +38 -3
- package/src/adapter/adapterDiscovery.ts +2 -1
- package/src/adapter/deconz/adapter/deconzAdapter.ts +24 -51
- package/src/adapter/deconz/driver/constants.ts +1 -1
- package/src/adapter/ember/adapter/emberAdapter.ts +23 -10
- package/src/adapter/ember/adapter/oneWaitress.ts +16 -6
- package/src/adapter/ezsp/adapter/ezspAdapter.ts +27 -48
- package/src/adapter/ezsp/driver/index.ts +1 -1
- package/src/adapter/ezsp/driver/types/index.ts +99 -99
- package/src/adapter/serialPort.ts +9 -0
- package/src/adapter/z-stack/adapter/adapter-backup.ts +1 -1
- package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +1 -1
- package/src/adapter/z-stack/adapter/manager.ts +16 -2
- package/src/adapter/z-stack/adapter/tstype.ts +1 -0
- package/src/adapter/z-stack/adapter/zStackAdapter.ts +34 -81
- package/src/adapter/z-stack/constants/index.ts +1 -1
- package/src/adapter/z-stack/unpi/constants.ts +1 -1
- package/src/adapter/zboss/adapter/zbossAdapter.ts +23 -54
- package/src/adapter/zboss/driver.ts +8 -1
- package/src/adapter/zboss/uart.ts +14 -1
- package/src/adapter/zigate/adapter/zigateAdapter.ts +17 -48
- package/src/adapter/zoh/adapter/zohAdapter.ts +27 -50
- package/src/controller/controller.ts +12 -2
- package/src/controller/greenPower.ts +16 -9
- package/src/controller/helpers/ota.ts +37 -11
- package/src/controller/helpers/zclFrameConverter.ts +20 -17
- package/src/controller/model/device.ts +204 -97
- package/src/controller/model/endpoint.ts +36 -24
- package/src/controller/model/group.ts +14 -20
- package/src/controller/touchlink.ts +3 -3
- package/src/utils/timeService.ts +2 -2
- package/src/zspec/zcl/buffaloZcl.ts +226 -100
- package/src/zspec/zcl/definition/cluster.ts +2713 -2822
- package/src/zspec/zcl/definition/clusters-types.ts +80 -1135
- package/src/zspec/zcl/definition/enums.ts +0 -1
- package/src/zspec/zcl/definition/foundation.ts +703 -216
- package/src/zspec/zcl/definition/status.ts +22 -11
- package/src/zspec/zcl/definition/tstype.ts +59 -58
- package/src/zspec/zcl/utils.ts +137 -264
- package/src/zspec/zcl/zclFrame.ts +25 -130
- package/src/zspec/zcl/zclStatusError.ts +2 -2
- package/test/adapter/ember/emberAdapter.test.ts +191 -4
- package/test/adapter/ezsp/uart.test.ts +10 -10
- package/test/adapter/z-stack/adapter.test.ts +88 -32
- package/test/adapter/zoh/zohAdapter.test.ts +4 -4
- package/test/controller.test.ts +822 -248
- package/test/device-ota.test.ts +141 -16
- package/test/device.test.ts +731 -0
- package/test/requests.bench.ts +2 -0
- package/test/zcl.test.ts +70 -95
- package/test/zspec/zcl/buffalo.test.ts +251 -11
- package/test/zspec/zcl/foundation.test.ts +990 -0
- package/test/zspec/zcl/frame.test.ts +84 -69
- package/test/zspec/zcl/utils.test.ts +105 -81
- package/tsconfig.json +0 -1
- package/scripts/check-clusters-changes.ts +0 -328
- package/scripts/clusters-changes.log +0 -584
- package/scripts/utils.ts +0 -88
- package/scripts/zap-update-clusters-report.json +0 -303
- package/scripts/zap-update-clusters.ts +0 -1520
- package/scripts/zap-update-types.ts +0 -707
- package/scripts/zap-xml-clusters-overrides-data.ts +0 -52
- package/scripts/zap-xml-clusters-overrides.ts +0 -400
- package/scripts/zap-xml-types.ts +0 -146
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Usage:
|
|
3
|
-
* tsx scripts/check-zcl-clusters-changes.ts
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from "node:fs/promises";
|
|
7
|
-
import path from "node:path";
|
|
8
|
-
import {fileURLToPath, pathToFileURL} from "node:url";
|
|
9
|
-
import {BuffaloZclDataType, DataType} from "../src/zspec/zcl/definition/enums";
|
|
10
|
-
import type {ClusterDefinition, ClusterName} from "../src/zspec/zcl/definition/tstype";
|
|
11
|
-
|
|
12
|
-
// #region Types
|
|
13
|
-
|
|
14
|
-
type Loggable = string | number | undefined;
|
|
15
|
-
|
|
16
|
-
type ChangeType = "added" | "removed" | "changed";
|
|
17
|
-
|
|
18
|
-
type Change = {
|
|
19
|
-
type: ChangeType;
|
|
20
|
-
path: Loggable[];
|
|
21
|
-
from?: Loggable;
|
|
22
|
-
to?: Loggable;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// #endregion
|
|
26
|
-
|
|
27
|
-
// #region Config
|
|
28
|
-
|
|
29
|
-
const SCRIPT_DIR = fileURLToPath(new URL(".", import.meta.url));
|
|
30
|
-
const LOG_FILE = path.resolve(SCRIPT_DIR, "clusters-changes.log");
|
|
31
|
-
const CURRENT_FILE = path.resolve(SCRIPT_DIR, "../src/zspec/zcl/definition/cluster.ts");
|
|
32
|
-
|
|
33
|
-
// #endregion
|
|
34
|
-
|
|
35
|
-
// #region Helpers
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Creates a map from a name to an ID for a given record.
|
|
39
|
-
*/
|
|
40
|
-
function createIdMap<T extends {ID: number}>(record: Readonly<Record<string, T>>): Map<string, number> {
|
|
41
|
-
const map = new Map<string, number>();
|
|
42
|
-
|
|
43
|
-
for (const name in record) {
|
|
44
|
-
map.set(name, record[name].ID);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return map;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Creates a reverse map from an ID to a name for a given record.
|
|
52
|
-
*/
|
|
53
|
-
function createReverseIdMap<T extends {ID: number}>(record: Readonly<Record<string, T>>): Map<number, string> {
|
|
54
|
-
const map = new Map<number, string>();
|
|
55
|
-
|
|
56
|
-
for (const name in record) {
|
|
57
|
-
map.set(record[name].ID, name);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return map;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function toHex(value: number, pad: number): string {
|
|
64
|
-
return `0x${value.toString(16).padStart(pad, "0")}`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Formats a log entry for display.
|
|
69
|
-
*/
|
|
70
|
-
function formatChange(change: Change): string {
|
|
71
|
-
const path = change.path.join(" > ");
|
|
72
|
-
const hexTo = typeof change.to === "number" ? ` (${toHex(change.to, 4)})` : "";
|
|
73
|
-
const hexFrom = typeof change.from === "number" ? ` (${toHex(change.from, 4)})` : "";
|
|
74
|
-
|
|
75
|
-
switch (change.type) {
|
|
76
|
-
case "added": {
|
|
77
|
-
return `[ADDED] ${path}${change.to ? `: ${change.to}${hexTo}` : ""}`;
|
|
78
|
-
}
|
|
79
|
-
case "removed": {
|
|
80
|
-
return `[REMOVED] ${path}: ${change.from}${hexFrom}`;
|
|
81
|
-
}
|
|
82
|
-
case "changed": {
|
|
83
|
-
return `[CHANGED] ${path}: ${change.from}${hexFrom} -> ${change.to}${hexTo}`;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// #endregion
|
|
89
|
-
|
|
90
|
-
// #region Comparison logic
|
|
91
|
-
|
|
92
|
-
class ClusterComparator {
|
|
93
|
-
readonly #changes: Change[] = [];
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Compares two records (like `attributes`, `commands`, etc.)
|
|
97
|
-
*/
|
|
98
|
-
#compareRecords<T extends {ID: number; type?: unknown; parameters?: readonly {name: string; type: unknown}[]}>(
|
|
99
|
-
oldRecord: Readonly<Record<string, T>> | undefined,
|
|
100
|
-
newRecord: Readonly<Record<string, T>> | undefined,
|
|
101
|
-
currentPath: Loggable[],
|
|
102
|
-
): void {
|
|
103
|
-
oldRecord ??= {};
|
|
104
|
-
newRecord ??= {};
|
|
105
|
-
|
|
106
|
-
const oldIdMap = createIdMap(oldRecord);
|
|
107
|
-
const newIdMap = createIdMap(newRecord);
|
|
108
|
-
// const oldReverseIdMap = createReverseIdMap(oldRecord);
|
|
109
|
-
const newReverseIdMap = createReverseIdMap(newRecord);
|
|
110
|
-
|
|
111
|
-
// Check for removed and changed items
|
|
112
|
-
for (const oldName of oldIdMap.keys()) {
|
|
113
|
-
// biome-ignore lint/style/noNonNullAssertion: loop
|
|
114
|
-
const oldId = oldIdMap.get(oldName)!;
|
|
115
|
-
const oldItem = oldRecord[oldName];
|
|
116
|
-
|
|
117
|
-
if (!newIdMap.has(oldName)) {
|
|
118
|
-
const newNameForOldId = newReverseIdMap.get(oldId);
|
|
119
|
-
|
|
120
|
-
if (newNameForOldId) {
|
|
121
|
-
// Renamed item
|
|
122
|
-
this.#changes.push({
|
|
123
|
-
type: "changed",
|
|
124
|
-
path: [...currentPath, "name", oldId],
|
|
125
|
-
from: oldName,
|
|
126
|
-
to: newNameForOldId,
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Continue comparison with the new name
|
|
130
|
-
this.#compareItems(oldItem, newRecord[newNameForOldId], [...currentPath, newNameForOldId]);
|
|
131
|
-
} else {
|
|
132
|
-
// Removed item
|
|
133
|
-
this.#changes.push({type: "removed", path: [...currentPath, oldName], from: oldId});
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
// Item exists in both, compare details
|
|
137
|
-
this.#compareItems(oldItem, newRecord[oldName], [...currentPath, oldName]);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Check for added items
|
|
142
|
-
for (const newName of newIdMap.keys()) {
|
|
143
|
-
if (!oldIdMap.has(newName)) {
|
|
144
|
-
// biome-ignore lint/style/noNonNullAssertion: checked above
|
|
145
|
-
const newId = newIdMap.get(newName)!;
|
|
146
|
-
|
|
147
|
-
// if (!oldReverseIdMap.has(newId)) {
|
|
148
|
-
// Added item
|
|
149
|
-
this.#changes.push({type: "added", path: [...currentPath, newName], to: newId});
|
|
150
|
-
// }
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Compares two individual items (e.g., a specific attribute or command).
|
|
157
|
-
*/
|
|
158
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic
|
|
159
|
-
#compareItems(oldItem: any, newItem: any, currentPath: Loggable[]): void {
|
|
160
|
-
// Check ID change
|
|
161
|
-
if (oldItem.ID !== newItem.ID) {
|
|
162
|
-
this.#changes.push({type: "changed", path: [...currentPath, "ID"], from: oldItem.ID, to: newItem.ID});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Check type change (for attributes)
|
|
166
|
-
if ("type" in oldItem && "type" in newItem && oldItem.type !== newItem.type) {
|
|
167
|
-
this.#changes.push({
|
|
168
|
-
type: "changed",
|
|
169
|
-
path: [...currentPath, "type"],
|
|
170
|
-
from: DataType[oldItem.type] ?? BuffaloZclDataType[oldItem.type],
|
|
171
|
-
to: DataType[newItem.type] ?? BuffaloZclDataType[newItem.type],
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Check parameters (for commands)
|
|
176
|
-
if ("parameters" in oldItem || "parameters" in newItem) {
|
|
177
|
-
this.#compareParameters(oldItem.parameters, newItem.parameters, currentPath);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Compares the `parameters` array of two commands.
|
|
183
|
-
*/
|
|
184
|
-
#compareParameters(
|
|
185
|
-
oldParams: readonly {name: string; type: number}[] | undefined,
|
|
186
|
-
newParams: readonly {name: string; type: number}[] | undefined,
|
|
187
|
-
currentPath: Loggable[],
|
|
188
|
-
): void {
|
|
189
|
-
oldParams ??= [];
|
|
190
|
-
newParams ??= [];
|
|
191
|
-
|
|
192
|
-
const oldParamsMap = new Map(oldParams.map((p) => [p.name, p]));
|
|
193
|
-
const newParamsMap = new Map(newParams.map((p) => [p.name, p]));
|
|
194
|
-
|
|
195
|
-
for (const [oldName, oldParam] of oldParamsMap) {
|
|
196
|
-
const newParam = newParamsMap.get(oldName);
|
|
197
|
-
const paramPath = [...currentPath, "parameters", oldName];
|
|
198
|
-
|
|
199
|
-
if (newParam) {
|
|
200
|
-
// Parameter exists in both, check type
|
|
201
|
-
if (oldParam.type !== newParam.type) {
|
|
202
|
-
this.#changes.push({
|
|
203
|
-
type: "changed",
|
|
204
|
-
path: [...paramPath, "type"],
|
|
205
|
-
from: DataType[oldParam.type] ?? BuffaloZclDataType[oldParam.type],
|
|
206
|
-
to: DataType[newParam.type] ?? BuffaloZclDataType[newParam.type],
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
} else {
|
|
210
|
-
// Parameter removed
|
|
211
|
-
this.#changes.push({type: "removed", path: paramPath});
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
for (const newName of newParamsMap.keys()) {
|
|
216
|
-
if (!oldParamsMap.has(newName)) {
|
|
217
|
-
// Parameter added
|
|
218
|
-
this.#changes.push({type: "added", path: [...currentPath, "parameters", newName]});
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Runs the full comparison between two `Clusters` definitions.
|
|
225
|
-
*/
|
|
226
|
-
public run(
|
|
227
|
-
oldClusters: Readonly<Record<ClusterName, Readonly<ClusterDefinition>>>,
|
|
228
|
-
newClusters: Readonly<Record<ClusterName, Readonly<ClusterDefinition>>>,
|
|
229
|
-
): Change[] {
|
|
230
|
-
this.#changes.length = 0;
|
|
231
|
-
const rootPath: Loggable[] = ["Clusters"];
|
|
232
|
-
|
|
233
|
-
this.#compareRecords(oldClusters, newClusters, rootPath);
|
|
234
|
-
|
|
235
|
-
// After the main comparison based on names, check for deeper changes in matching clusters
|
|
236
|
-
for (const clusterName in newClusters) {
|
|
237
|
-
if (clusterName in oldClusters) {
|
|
238
|
-
const oldCluster = oldClusters[clusterName as ClusterName];
|
|
239
|
-
const newCluster = newClusters[clusterName as ClusterName];
|
|
240
|
-
const clusterPath = [...rootPath, clusterName];
|
|
241
|
-
|
|
242
|
-
// Attributes
|
|
243
|
-
this.#compareRecords(oldCluster.attributes, newCluster.attributes, [...clusterPath, "attributes"]);
|
|
244
|
-
|
|
245
|
-
// Commands
|
|
246
|
-
this.#compareRecords(oldCluster.commands, newCluster.commands, [...clusterPath, "commands"]);
|
|
247
|
-
|
|
248
|
-
// Command Responses
|
|
249
|
-
this.#compareRecords(oldCluster.commandsResponse, newCluster.commandsResponse, [...clusterPath, "commandsResponse"]);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return this.#changes;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// #endregion
|
|
258
|
-
|
|
259
|
-
// #region Main
|
|
260
|
-
|
|
261
|
-
async function main(): Promise<void> {
|
|
262
|
-
console.log("Starting ZCL cluster definition comparison...");
|
|
263
|
-
|
|
264
|
-
const oldFilePathArg = process.argv[2];
|
|
265
|
-
|
|
266
|
-
if (!oldFilePathArg) {
|
|
267
|
-
console.error("ERROR: Missing required argument.");
|
|
268
|
-
console.error("Usage: tsx scripts/check-zcl-clusters-changes.ts <path-to-old-cluster-file>");
|
|
269
|
-
process.exit(1);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const oldFilePath = path.resolve(process.cwd(), oldFilePathArg);
|
|
273
|
-
|
|
274
|
-
try {
|
|
275
|
-
await fs.access(oldFilePath);
|
|
276
|
-
} catch {
|
|
277
|
-
console.error(`ERROR: Old file not found at: ${oldFilePath}`);
|
|
278
|
-
process.exit(1);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Dynamically import both files using file:// URLs to ensure Windows compatibility
|
|
282
|
-
const {Clusters: newClusters} = await import(pathToFileURL(CURRENT_FILE).href);
|
|
283
|
-
const {Clusters: oldClusters} = await import(pathToFileURL(oldFilePath).href);
|
|
284
|
-
|
|
285
|
-
// Perform comparison
|
|
286
|
-
const comparator = new ClusterComparator();
|
|
287
|
-
const changes = comparator.run(oldClusters, newClusters);
|
|
288
|
-
|
|
289
|
-
// Output results
|
|
290
|
-
if (changes.length === 0) {
|
|
291
|
-
const message = "No changes detected between the two cluster definition files.";
|
|
292
|
-
console.log(message);
|
|
293
|
-
await fs.writeFile(LOG_FILE, `${message}\n`, "utf8");
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
const logHeader = `Found ${changes.length} changes.\n`;
|
|
298
|
-
|
|
299
|
-
const formattedChanges: string[] = [];
|
|
300
|
-
|
|
301
|
-
for (const change of changes) {
|
|
302
|
-
if (change.type !== "added") {
|
|
303
|
-
formattedChanges.push(formatChange(change));
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
formattedChanges.push("");
|
|
308
|
-
|
|
309
|
-
for (const change of changes) {
|
|
310
|
-
if (change.type === "added") {
|
|
311
|
-
formattedChanges.push(formatChange(change));
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const logContent = [logHeader, ...formattedChanges].join("\n");
|
|
316
|
-
|
|
317
|
-
await fs.writeFile(LOG_FILE, logContent, "utf8");
|
|
318
|
-
|
|
319
|
-
console.log(`\nComparison complete. Found ${changes.length} changes.`);
|
|
320
|
-
console.log(`See the full report in: ${LOG_FILE}`);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
main().catch((error) => {
|
|
324
|
-
console.error("An unexpected error occurred:", error);
|
|
325
|
-
process.exit(1);
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
// #endregion
|