@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.
Files changed (211) hide show
  1. package/.github/dependabot.yml +0 -3
  2. package/.github/workflows/ci.yml +1 -2
  3. package/.github/workflows/release-please.yml +1 -1
  4. package/.github/workflows/typedoc.yaml +3 -3
  5. package/.release-please-manifest.json +1 -1
  6. package/CHANGELOG.md +143 -0
  7. package/biome.json +1 -1
  8. package/dist/adapter/adapter.d.ts +14 -1
  9. package/dist/adapter/adapter.d.ts.map +1 -1
  10. package/dist/adapter/adapter.js +17 -0
  11. package/dist/adapter/adapter.js.map +1 -1
  12. package/dist/adapter/adapterDiscovery.d.ts.map +1 -1
  13. package/dist/adapter/adapterDiscovery.js.map +1 -1
  14. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +1 -3
  15. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
  16. package/dist/adapter/deconz/adapter/deconzAdapter.js +14 -29
  17. package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
  18. package/dist/adapter/deconz/driver/constants.d.ts +1 -1
  19. package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
  20. package/dist/adapter/ember/adapter/emberAdapter.d.ts +1 -1
  21. package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
  22. package/dist/adapter/ember/adapter/emberAdapter.js +19 -10
  23. package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
  24. package/dist/adapter/ember/adapter/oneWaitress.d.ts +2 -0
  25. package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
  26. package/dist/adapter/ember/adapter/oneWaitress.js +13 -5
  27. package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
  28. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +1 -3
  29. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
  30. package/dist/adapter/ezsp/adapter/ezspAdapter.js +17 -30
  31. package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
  32. package/dist/adapter/ezsp/driver/index.d.ts +1 -1
  33. package/dist/adapter/ezsp/driver/index.d.ts.map +1 -1
  34. package/dist/adapter/ezsp/driver/index.js +1 -1
  35. package/dist/adapter/ezsp/driver/index.js.map +1 -1
  36. package/dist/adapter/ezsp/driver/types/index.d.ts +1 -1
  37. package/dist/adapter/ezsp/driver/types/index.d.ts.map +1 -1
  38. package/dist/adapter/ezsp/driver/types/index.js +3 -3
  39. package/dist/adapter/ezsp/driver/types/index.js.map +1 -1
  40. package/dist/adapter/serialPort.d.ts.map +1 -1
  41. package/dist/adapter/serialPort.js +7 -0
  42. package/dist/adapter/serialPort.js.map +1 -1
  43. package/dist/adapter/z-stack/adapter/adapter-backup.js +1 -1
  44. package/dist/adapter/z-stack/adapter/adapter-backup.js.map +1 -1
  45. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +1 -1
  46. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js.map +1 -1
  47. package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
  48. package/dist/adapter/z-stack/adapter/manager.js +12 -2
  49. package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
  50. package/dist/adapter/z-stack/adapter/tstype.d.ts.map +1 -1
  51. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +1 -3
  52. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
  53. package/dist/adapter/z-stack/adapter/zStackAdapter.js +20 -34
  54. package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
  55. package/dist/adapter/z-stack/constants/index.d.ts +1 -1
  56. package/dist/adapter/z-stack/constants/index.d.ts.map +1 -1
  57. package/dist/adapter/z-stack/constants/index.js +1 -1
  58. package/dist/adapter/z-stack/constants/index.js.map +1 -1
  59. package/dist/adapter/z-stack/unpi/constants.d.ts +1 -1
  60. package/dist/adapter/z-stack/unpi/constants.d.ts.map +1 -1
  61. package/dist/adapter/z-stack/unpi/constants.js +1 -1
  62. package/dist/adapter/z-stack/unpi/constants.js.map +1 -1
  63. package/dist/adapter/zboss/adapter/zbossAdapter.d.ts +7 -8
  64. package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
  65. package/dist/adapter/zboss/adapter/zbossAdapter.js +12 -30
  66. package/dist/adapter/zboss/adapter/zbossAdapter.js.map +1 -1
  67. package/dist/adapter/zboss/driver.d.ts.map +1 -1
  68. package/dist/adapter/zboss/driver.js +8 -1
  69. package/dist/adapter/zboss/driver.js.map +1 -1
  70. package/dist/adapter/zboss/uart.d.ts.map +1 -1
  71. package/dist/adapter/zboss/uart.js +14 -2
  72. package/dist/adapter/zboss/uart.js.map +1 -1
  73. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +1 -3
  74. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
  75. package/dist/adapter/zigate/adapter/zigateAdapter.js +8 -29
  76. package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
  77. package/dist/adapter/zoh/adapter/zohAdapter.d.ts +1 -3
  78. package/dist/adapter/zoh/adapter/zohAdapter.d.ts.map +1 -1
  79. package/dist/adapter/zoh/adapter/zohAdapter.js +18 -33
  80. package/dist/adapter/zoh/adapter/zohAdapter.js.map +1 -1
  81. package/dist/controller/controller.d.ts.map +1 -1
  82. package/dist/controller/controller.js +10 -2
  83. package/dist/controller/controller.js.map +1 -1
  84. package/dist/controller/greenPower.d.ts.map +1 -1
  85. package/dist/controller/greenPower.js +15 -9
  86. package/dist/controller/greenPower.js.map +1 -1
  87. package/dist/controller/helpers/ota.d.ts +4 -4
  88. package/dist/controller/helpers/ota.d.ts.map +1 -1
  89. package/dist/controller/helpers/ota.js +28 -9
  90. package/dist/controller/helpers/ota.js.map +1 -1
  91. package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
  92. package/dist/controller/helpers/zclFrameConverter.js +17 -16
  93. package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
  94. package/dist/controller/model/device.d.ts +14 -4
  95. package/dist/controller/model/device.d.ts.map +1 -1
  96. package/dist/controller/model/device.js +167 -85
  97. package/dist/controller/model/device.js.map +1 -1
  98. package/dist/controller/model/endpoint.d.ts +7 -3
  99. package/dist/controller/model/endpoint.d.ts.map +1 -1
  100. package/dist/controller/model/endpoint.js +34 -21
  101. package/dist/controller/model/endpoint.js.map +1 -1
  102. package/dist/controller/model/group.d.ts +0 -1
  103. package/dist/controller/model/group.d.ts.map +1 -1
  104. package/dist/controller/model/group.js +14 -19
  105. package/dist/controller/model/group.js.map +1 -1
  106. package/dist/controller/touchlink.js +3 -3
  107. package/dist/controller/touchlink.js.map +1 -1
  108. package/dist/utils/timeService.js +2 -2
  109. package/dist/utils/timeService.js.map +1 -1
  110. package/dist/zspec/zcl/buffaloZcl.d.ts +3 -3
  111. package/dist/zspec/zcl/buffaloZcl.d.ts.map +1 -1
  112. package/dist/zspec/zcl/buffaloZcl.js +198 -96
  113. package/dist/zspec/zcl/buffaloZcl.js.map +1 -1
  114. package/dist/zspec/zcl/definition/cluster.d.ts +2 -2
  115. package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -1
  116. package/dist/zspec/zcl/definition/cluster.js +2699 -2808
  117. package/dist/zspec/zcl/definition/cluster.js.map +1 -1
  118. package/dist/zspec/zcl/definition/clusters-types.d.ts +63 -1109
  119. package/dist/zspec/zcl/definition/clusters-types.d.ts.map +1 -1
  120. package/dist/zspec/zcl/definition/enums.d.ts +0 -1
  121. package/dist/zspec/zcl/definition/enums.d.ts.map +1 -1
  122. package/dist/zspec/zcl/definition/enums.js +0 -1
  123. package/dist/zspec/zcl/definition/enums.js.map +1 -1
  124. package/dist/zspec/zcl/definition/foundation.d.ts +306 -7
  125. package/dist/zspec/zcl/definition/foundation.d.ts.map +1 -1
  126. package/dist/zspec/zcl/definition/foundation.js +552 -207
  127. package/dist/zspec/zcl/definition/foundation.js.map +1 -1
  128. package/dist/zspec/zcl/definition/status.d.ts +21 -10
  129. package/dist/zspec/zcl/definition/status.d.ts.map +1 -1
  130. package/dist/zspec/zcl/definition/status.js +11 -0
  131. package/dist/zspec/zcl/definition/status.js.map +1 -1
  132. package/dist/zspec/zcl/definition/tstype.d.ts +57 -48
  133. package/dist/zspec/zcl/definition/tstype.d.ts.map +1 -1
  134. package/dist/zspec/zcl/utils.d.ts +7 -4
  135. package/dist/zspec/zcl/utils.d.ts.map +1 -1
  136. package/dist/zspec/zcl/utils.js +133 -240
  137. package/dist/zspec/zcl/utils.js.map +1 -1
  138. package/dist/zspec/zcl/zclFrame.d.ts +4 -4
  139. package/dist/zspec/zcl/zclFrame.d.ts.map +1 -1
  140. package/dist/zspec/zcl/zclFrame.js +19 -103
  141. package/dist/zspec/zcl/zclFrame.js.map +1 -1
  142. package/dist/zspec/zcl/zclStatusError.d.ts +1 -1
  143. package/dist/zspec/zcl/zclStatusError.d.ts.map +1 -1
  144. package/dist/zspec/zcl/zclStatusError.js +2 -2
  145. package/dist/zspec/zcl/zclStatusError.js.map +1 -1
  146. package/package.json +1 -1
  147. package/scripts/clusters-typegen.ts +44 -139
  148. package/src/adapter/adapter.ts +38 -3
  149. package/src/adapter/adapterDiscovery.ts +2 -1
  150. package/src/adapter/deconz/adapter/deconzAdapter.ts +24 -51
  151. package/src/adapter/deconz/driver/constants.ts +1 -1
  152. package/src/adapter/ember/adapter/emberAdapter.ts +23 -10
  153. package/src/adapter/ember/adapter/oneWaitress.ts +16 -6
  154. package/src/adapter/ezsp/adapter/ezspAdapter.ts +27 -48
  155. package/src/adapter/ezsp/driver/index.ts +1 -1
  156. package/src/adapter/ezsp/driver/types/index.ts +99 -99
  157. package/src/adapter/serialPort.ts +9 -0
  158. package/src/adapter/z-stack/adapter/adapter-backup.ts +1 -1
  159. package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +1 -1
  160. package/src/adapter/z-stack/adapter/manager.ts +16 -2
  161. package/src/adapter/z-stack/adapter/tstype.ts +1 -0
  162. package/src/adapter/z-stack/adapter/zStackAdapter.ts +34 -81
  163. package/src/adapter/z-stack/constants/index.ts +1 -1
  164. package/src/adapter/z-stack/unpi/constants.ts +1 -1
  165. package/src/adapter/zboss/adapter/zbossAdapter.ts +23 -54
  166. package/src/adapter/zboss/driver.ts +8 -1
  167. package/src/adapter/zboss/uart.ts +14 -1
  168. package/src/adapter/zigate/adapter/zigateAdapter.ts +17 -48
  169. package/src/adapter/zoh/adapter/zohAdapter.ts +27 -50
  170. package/src/controller/controller.ts +12 -2
  171. package/src/controller/greenPower.ts +16 -9
  172. package/src/controller/helpers/ota.ts +37 -11
  173. package/src/controller/helpers/zclFrameConverter.ts +20 -17
  174. package/src/controller/model/device.ts +204 -97
  175. package/src/controller/model/endpoint.ts +36 -24
  176. package/src/controller/model/group.ts +14 -20
  177. package/src/controller/touchlink.ts +3 -3
  178. package/src/utils/timeService.ts +2 -2
  179. package/src/zspec/zcl/buffaloZcl.ts +226 -100
  180. package/src/zspec/zcl/definition/cluster.ts +2713 -2822
  181. package/src/zspec/zcl/definition/clusters-types.ts +80 -1135
  182. package/src/zspec/zcl/definition/enums.ts +0 -1
  183. package/src/zspec/zcl/definition/foundation.ts +703 -216
  184. package/src/zspec/zcl/definition/status.ts +22 -11
  185. package/src/zspec/zcl/definition/tstype.ts +59 -58
  186. package/src/zspec/zcl/utils.ts +137 -264
  187. package/src/zspec/zcl/zclFrame.ts +25 -130
  188. package/src/zspec/zcl/zclStatusError.ts +2 -2
  189. package/test/adapter/ember/emberAdapter.test.ts +191 -4
  190. package/test/adapter/ezsp/uart.test.ts +10 -10
  191. package/test/adapter/z-stack/adapter.test.ts +88 -32
  192. package/test/adapter/zoh/zohAdapter.test.ts +4 -4
  193. package/test/controller.test.ts +822 -248
  194. package/test/device-ota.test.ts +141 -16
  195. package/test/device.test.ts +731 -0
  196. package/test/requests.bench.ts +2 -0
  197. package/test/zcl.test.ts +70 -95
  198. package/test/zspec/zcl/buffalo.test.ts +251 -11
  199. package/test/zspec/zcl/foundation.test.ts +990 -0
  200. package/test/zspec/zcl/frame.test.ts +84 -69
  201. package/test/zspec/zcl/utils.test.ts +105 -81
  202. package/tsconfig.json +0 -1
  203. package/scripts/check-clusters-changes.ts +0 -328
  204. package/scripts/clusters-changes.log +0 -584
  205. package/scripts/utils.ts +0 -88
  206. package/scripts/zap-update-clusters-report.json +0 -303
  207. package/scripts/zap-update-clusters.ts +0 -1520
  208. package/scripts/zap-update-types.ts +0 -707
  209. package/scripts/zap-xml-clusters-overrides-data.ts +0 -52
  210. package/scripts/zap-xml-clusters-overrides.ts +0 -400
  211. package/scripts/zap-xml-types.ts +0 -146
@@ -1,52 +0,0 @@
1
- import type {XmlOverride} from "./zap-xml-clusters-overrides.js";
2
-
3
- /**
4
- * This file contains overrides for the raw XML data before it is parsed into the ZCL format.
5
- * Use this to correct errors in the source XML files.
6
- */
7
- export const OVERRIDES: XmlOverride[] = [
8
- {
9
- clusterId: 0x0102, // Closures
10
- attributes: [
11
- // Original incorrect ID for "InstalledOpenLimitLift"
12
- {id: 0x0100, new: {id: "0010"}},
13
- // Original incorrect ID for "InstalledClosedLimitLift"
14
- {id: 0x0101, new: {id: "0011"}},
15
- // Original incorrect ID for "InstalledOpenLimitTilt"
16
- {id: 0x0102, new: {id: "0012"}},
17
- // Original incorrect ID for "InstalledClosedLimitTilt"
18
- {id: 0x0103, new: {id: "0013"}},
19
- // Original incorrect ID for "VelocityLift"
20
- {id: 0x0104, new: {id: "0014"}},
21
- // Original incorrect ID for "AccelerationTimeLift"
22
- {id: 0x0105, new: {id: "0015"}},
23
- // Original incorrect ID for "DecelerationTimeLift"
24
- {id: 0x0106, new: {id: "0016"}},
25
- // Original incorrect ID for "Mode"
26
- {id: 0x0107, new: {id: "0017"}},
27
- // Original incorrect ID for "IntermediateSetpointsLift"
28
- {id: 0x0108, new: {id: "0018"}},
29
- // Original incorrect ID for "IntermediateSetpointsTilt"
30
- {id: 0x0109, new: {id: "0019"}},
31
- ],
32
- },
33
- // {
34
- // clusterId: 0x0005, // Scenes
35
- // commands: [
36
- // {
37
- // id: 0x06,
38
- // parameters: [
39
- // {
40
- // name: "Capacity",
41
- // restrictions: [
42
- // {
43
- // type: "type:maxInclusive",
44
- // new: {value: "253"}, // Original as "fd" (most entries are number strings, so have to correct this)
45
- // },
46
- // ],
47
- // },
48
- // ],
49
- // },
50
- // ],
51
- // },
52
- ];
@@ -1,400 +0,0 @@
1
- import ts from "typescript";
2
- import type {XMLAttributeDefinition, XMLCluster, XMLCommandDefinition, XMLFieldDefinition, XMLRestriction} from "./zap-update-clusters.js";
3
-
4
- type RestrictionOverride = {
5
- type: string;
6
- index?: number;
7
- new: Record<string, string>;
8
- };
9
-
10
- type CommandParameterOverride = {
11
- name: string;
12
- new?: Partial<XMLFieldDefinition["$"]>;
13
- restrictions?: RestrictionOverride[];
14
- };
15
-
16
- type AttributeOverride = {
17
- id: number;
18
- new?: Partial<XMLAttributeDefinition["$"]>;
19
- restrictions?: RestrictionOverride[];
20
- };
21
-
22
- type CommandOverride = {
23
- id: number;
24
- new?: Partial<XMLCommandDefinition["$"]>;
25
- parameters?: CommandParameterOverride[];
26
- };
27
-
28
- export type XmlOverride = {
29
- clusterId: number;
30
- attributes?: AttributeOverride[];
31
- commands?: CommandOverride[];
32
- };
33
-
34
- function getObjectLiteralProperties(node: ts.ObjectLiteralExpression): Map<string, ts.Expression> {
35
- const props = new Map<string, ts.Expression>();
36
-
37
- for (const prop of node.properties) {
38
- if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
39
- props.set(prop.name.text, prop.initializer);
40
- }
41
- }
42
-
43
- return props;
44
- }
45
-
46
- // biome-ignore lint/suspicious/noExplicitAny: generic
47
- function expressionToValue(expr: ts.Expression | undefined): any {
48
- if (!expr) {
49
- return undefined;
50
- }
51
-
52
- if (ts.isStringLiteral(expr)) {
53
- return expr.text;
54
- }
55
-
56
- if (ts.isNumericLiteral(expr)) {
57
- const text = expr.text;
58
- return text.startsWith("0x") ? Number.parseInt(text, 16) : Number(text);
59
- }
60
-
61
- if (expr.kind === ts.SyntaxKind.TrueKeyword) {
62
- return true;
63
- }
64
-
65
- if (expr.kind === ts.SyntaxKind.FalseKeyword) {
66
- return false;
67
- }
68
-
69
- return undefined;
70
- }
71
-
72
- function parseRestrictionOverrides(restrictionsProp: ts.Expression | undefined): RestrictionOverride[] | undefined {
73
- if (!restrictionsProp || !ts.isArrayLiteralExpression(restrictionsProp)) {
74
- return undefined;
75
- }
76
-
77
- const restrictions: RestrictionOverride[] = [];
78
-
79
- for (const r of restrictionsProp.elements) {
80
- if (ts.isObjectLiteralExpression(r)) {
81
- const rProps = getObjectLiteralProperties(r);
82
- const rTypeExpr = rProps.get("type");
83
- const rNewExpr = rProps.get("new");
84
-
85
- if (rTypeExpr && rNewExpr && ts.isObjectLiteralExpression(rNewExpr)) {
86
- const rType = expressionToValue(rTypeExpr);
87
- const rIndex = expressionToValue(rProps.get("index"));
88
- const newValues: Record<string, string> = {};
89
-
90
- for (const [key, val] of getObjectLiteralProperties(rNewExpr).entries()) {
91
- newValues[key] = expressionToValue(val);
92
- }
93
-
94
- restrictions.push({type: rType, index: rIndex, new: newValues});
95
- }
96
- }
97
- }
98
-
99
- return restrictions.length > 0 ? restrictions : undefined;
100
- }
101
-
102
- export function parseOverrides(sourceFile: ts.SourceFile): XmlOverride[] {
103
- const overrides: XmlOverride[] = [];
104
- let overridesVariable: ts.VariableDeclaration | undefined;
105
-
106
- ts.forEachChild(sourceFile, (node) => {
107
- if (ts.isVariableStatement(node)) {
108
- for (const decl of node.declarationList.declarations) {
109
- if (ts.isIdentifier(decl.name) && decl.name.text === "OVERRIDES") {
110
- overridesVariable = decl;
111
-
112
- break;
113
- }
114
- }
115
- }
116
- });
117
-
118
- if (overridesVariable?.initializer && ts.isArrayLiteralExpression(overridesVariable.initializer)) {
119
- for (const element of overridesVariable.initializer.elements) {
120
- if (ts.isObjectLiteralExpression(element)) {
121
- const props = getObjectLiteralProperties(element);
122
- const clusterIdExpr = props.get("clusterId");
123
-
124
- if (!clusterIdExpr) {
125
- continue;
126
- }
127
-
128
- const clusterId = expressionToValue(clusterIdExpr);
129
-
130
- if (clusterId === undefined) {
131
- continue;
132
- }
133
-
134
- const override: XmlOverride = {clusterId};
135
- const attributesProp = props.get("attributes");
136
-
137
- if (attributesProp && ts.isArrayLiteralExpression(attributesProp)) {
138
- override.attributes = [];
139
-
140
- for (const attrElement of attributesProp.elements) {
141
- if (ts.isObjectLiteralExpression(attrElement)) {
142
- const attrProps = getObjectLiteralProperties(attrElement);
143
- const idExpr = attrProps.get("id");
144
-
145
- if (!idExpr) {
146
- continue;
147
- }
148
-
149
- const id = expressionToValue(idExpr);
150
- const attrOverride: AttributeOverride = {id};
151
- const newPropsExpr = attrProps.get("new");
152
-
153
- if (newPropsExpr && ts.isObjectLiteralExpression(newPropsExpr)) {
154
- const newValues: Partial<XMLAttributeDefinition["$"]> = {};
155
-
156
- for (const [key, val] of getObjectLiteralProperties(newPropsExpr).entries()) {
157
- newValues[key as keyof typeof newValues] = expressionToValue(val);
158
- }
159
-
160
- attrOverride.new = newValues;
161
- }
162
-
163
- attrOverride.restrictions = parseRestrictionOverrides(attrProps.get("restrictions"));
164
-
165
- if (Object.keys(attrOverride).length > 1) {
166
- override.attributes.push(attrOverride);
167
- }
168
- }
169
- }
170
- }
171
-
172
- const commandsProp = props.get("commands");
173
-
174
- if (commandsProp && ts.isArrayLiteralExpression(commandsProp)) {
175
- override.commands = [];
176
-
177
- for (const cmdElement of commandsProp.elements) {
178
- if (ts.isObjectLiteralExpression(cmdElement)) {
179
- const cmdProps = getObjectLiteralProperties(cmdElement);
180
- const idExpr = cmdProps.get("id");
181
-
182
- if (!idExpr) {
183
- continue;
184
- }
185
-
186
- const id = expressionToValue(idExpr);
187
- const cmdOverride: CommandOverride = {id};
188
- const newPropsExpr = cmdProps.get("new");
189
-
190
- if (newPropsExpr && ts.isObjectLiteralExpression(newPropsExpr)) {
191
- const newValues: Partial<XMLCommandDefinition["$"]> = {};
192
-
193
- for (const [key, val] of getObjectLiteralProperties(newPropsExpr).entries()) {
194
- newValues[key as keyof typeof newValues] = expressionToValue(val);
195
- }
196
-
197
- cmdOverride.new = newValues;
198
- }
199
-
200
- const paramsProp = cmdProps.get("parameters");
201
-
202
- if (paramsProp && ts.isArrayLiteralExpression(paramsProp)) {
203
- cmdOverride.parameters = [];
204
-
205
- for (const p of paramsProp.elements) {
206
- if (ts.isObjectLiteralExpression(p)) {
207
- const pProps = getObjectLiteralProperties(p);
208
- const pNameExpr = pProps.get("name");
209
-
210
- if (!pNameExpr) {
211
- continue;
212
- }
213
-
214
- const pName = expressionToValue(pNameExpr);
215
- const pOverride: CommandParameterOverride = {name: pName};
216
- const pNewExpr = pProps.get("new");
217
-
218
- if (pNewExpr && ts.isObjectLiteralExpression(pNewExpr)) {
219
- const newValues: Partial<XMLFieldDefinition["$"]> = {};
220
-
221
- for (const [key, val] of getObjectLiteralProperties(pNewExpr).entries()) {
222
- newValues[key as keyof typeof newValues] = expressionToValue(val);
223
- }
224
-
225
- pOverride.new = newValues;
226
- }
227
-
228
- pOverride.restrictions = parseRestrictionOverrides(pProps.get("restrictions"));
229
-
230
- if (Object.keys(pOverride).length > 1) {
231
- cmdOverride.parameters.push(pOverride);
232
- }
233
- }
234
- }
235
- }
236
-
237
- if (Object.keys(cmdOverride).length > 1) {
238
- override.commands.push(cmdOverride);
239
- }
240
- }
241
- }
242
- }
243
-
244
- overrides.push(override);
245
- }
246
- }
247
- }
248
-
249
- return overrides;
250
- }
251
-
252
- export function applyXmlOverrides(clusters: XMLCluster[], overrides: XmlOverride[]): void {
253
- if (overrides.length === 0) {
254
- return;
255
- }
256
-
257
- const overridesByCluster = new Map<number, XmlOverride>();
258
-
259
- for (const override of overrides) {
260
- overridesByCluster.set(override.clusterId, override);
261
- }
262
-
263
- const applyRestrictionOverrides = (
264
- target: {restriction?: XMLRestriction[]},
265
- restrictions: RestrictionOverride[] | undefined,
266
- logPrefix: string,
267
- ): void => {
268
- if (!restrictions) {
269
- return;
270
- }
271
-
272
- // 1. Ensure the base restriction object exists.
273
- if (!target.restriction) {
274
- target.restriction = [{}];
275
- }
276
-
277
- // biome-ignore lint/style/noNonNullAssertion: set above
278
- const targetRestriction = target.restriction[0]!;
279
-
280
- for (const r of restrictions) {
281
- const key = r.type as keyof XMLRestriction;
282
-
283
- // 2. Reflect on the target to see if the restriction key (e.g., "type:maxInclusive") already exists.
284
- if (Object.hasOwn(targetRestriction, key)) {
285
- // The restriction key exists, so we update it.
286
- // biome-ignore lint/style/noNonNullAssertion: checked with hasOwnProperty
287
- const existing = targetRestriction[key]!;
288
-
289
- if (existing.length > 1 && r.index === undefined) {
290
- throw new Error(`${logPrefix}, restriction type '${r.type}' has multiple entries but no index was provided in override.`);
291
- }
292
-
293
- const index = r.index ?? 0;
294
- if (index >= existing.length) {
295
- throw new Error(
296
- `${logPrefix}, restriction type '${r.type}' override index ${index} is out of bounds for length ${existing.length}.`,
297
- );
298
- }
299
-
300
- console.log(`${logPrefix}, restriction type '${r.type}[${index}]'`);
301
- Object.assign(existing[index].$, r.new);
302
- } else {
303
- // 3. The restriction key does NOT exist, so we create it.
304
- // This is a type-safe way to create the property with the correct structure.
305
- console.log(`${logPrefix}, restriction type '${r.type}': creating new`);
306
- targetRestriction[key] = [
307
- {
308
- // The 'new' object from the override becomes the content of the '$' property.
309
- // biome-ignore lint/style/useNamingConvention: API
310
- $: r.new,
311
- },
312
- // biome-ignore lint/suspicious/noExplicitAny: dynamically creating a known-good structure.
313
- ] as any;
314
- }
315
- }
316
-
317
- console.log(targetRestriction["type:maxInclusive"]);
318
- };
319
-
320
- for (const cluster of clusters) {
321
- const clusterId = Number.parseInt(cluster.$.id, 16);
322
- const override = overridesByCluster.get(clusterId);
323
-
324
- if (!override) {
325
- continue;
326
- }
327
-
328
- const sides = [
329
- {side: cluster.server, name: "server"},
330
- {side: cluster.client, name: "client"},
331
- ];
332
-
333
- for (const {side, name} of sides) {
334
- if (!side?.[0]) {
335
- continue;
336
- }
337
-
338
- if (override.attributes && side[0].attributes?.[0]?.attribute) {
339
- for (const attr of side[0].attributes[0].attribute) {
340
- const attrId = Number.parseInt(attr.$.id, 16);
341
- const attrOverride = override.attributes.find((a) => a.id === attrId);
342
-
343
- if (!attrOverride) {
344
- continue;
345
- }
346
-
347
- const logPrefix = `Applying override to cluster 0x${clusterId.toString(16).padStart(4, "0")}, ${name} attribute 0x${attrId
348
- .toString(16)
349
- .padStart(4, "0")}`;
350
-
351
- if (attrOverride.new) {
352
- console.log(`${logPrefix} (props)`);
353
- Object.assign(attr.$, attrOverride.new);
354
- }
355
-
356
- applyRestrictionOverrides(attr, attrOverride.restrictions, logPrefix);
357
- }
358
- }
359
-
360
- if (override.commands && side[0].commands?.[0]?.command) {
361
- for (const cmd of side[0].commands[0].command) {
362
- const cmdId = Number.parseInt(cmd.$.id, 16);
363
- const cmdOverride = override.commands.find((c) => c.id === cmdId);
364
-
365
- if (!cmdOverride) {
366
- continue;
367
- }
368
-
369
- const logPrefix = `Applying override to cluster 0x${clusterId.toString(16).padStart(4, "0")}, ${name} command 0x${cmdId
370
- .toString(16)
371
- .padStart(2, "0")}`;
372
-
373
- if (cmdOverride.new) {
374
- console.log(`${logPrefix} (props)`);
375
- Object.assign(cmd.$, cmdOverride.new);
376
- }
377
-
378
- if (cmdOverride.parameters && cmd.fields?.[0]?.field) {
379
- for (const field of cmd.fields[0].field) {
380
- const paramOverride = cmdOverride.parameters.find((p) => p.name === field.$.name);
381
-
382
- if (!paramOverride) {
383
- continue;
384
- }
385
-
386
- const paramLogPrefix = `${logPrefix}, parameter '${paramOverride.name}'`;
387
-
388
- if (paramOverride.new) {
389
- console.log(`${paramLogPrefix} (props)`);
390
- Object.assign(field.$, paramOverride.new);
391
- }
392
-
393
- applyRestrictionOverrides(field, paramOverride.restrictions, paramLogPrefix);
394
- }
395
- }
396
- }
397
- }
398
- }
399
- }
400
- }
@@ -1,146 +0,0 @@
1
- export interface XMLAttr<T> {
2
- // biome-ignore lint/style/useNamingConvention: API
3
- $: T;
4
- }
5
-
6
- export interface XMLEnumeration extends XMLAttr<{name: string; value: string}> {}
7
-
8
- export interface XMLBitmapDefinition {
9
- element: XMLBitmapElement[];
10
- }
11
-
12
- export interface XMLBitmapElement extends XMLAttr<{name: string; mask: string; shiftRight?: string}> {}
13
-
14
- export interface XMLSequence {
15
- field: XMLSequenceField[];
16
- }
17
-
18
- export interface XMLSequenceField
19
- extends XMLAttr<{
20
- name: string;
21
- type: string;
22
- presentIf?: string;
23
- }> {}
24
-
25
- export interface XMLTypeType
26
- extends XMLAttr<{
27
- id: string;
28
- name: string;
29
- short: string;
30
- inheritsFrom?: string;
31
- discrete?: string;
32
- }> {
33
- restriction?: XMLRestriction[];
34
- bitmap?: XMLBitmapDefinition[];
35
- }
36
-
37
- export interface XMLLibrary {
38
- "xi:include"?: XMLAttr<{href: string; parse?: string}>[];
39
- "type:type"?: XMLTypeType[];
40
- }
41
-
42
- export interface XMLGlobal {
43
- "type:type"?: XMLTypeType[];
44
- attributes?: {attribute: XMLAttributeDefinition[]}[];
45
- commands?: {command: XMLCommandDefinition[]}[];
46
- }
47
-
48
- export interface XMLRestriction {
49
- "type:length"?: XMLAttr<{value: string}>[];
50
- "type:minLength"?: XMLAttr<{value: string}>[];
51
- "type:maxLength"?: XMLAttr<{value: string}>[];
52
- "type:minExclusive"?: XMLAttr<{value: string}>[];
53
- "type:minInclusive"?: XMLAttr<{value: string}>[];
54
- "type:maxExclusive"?: XMLAttr<{value: string}>[];
55
- "type:maxInclusive"?: XMLAttr<{value: string}>[];
56
- "type:minInclusiveRef"?: XMLAttr<{ref: string}>[];
57
- "type:minExclusiveRef"?: XMLAttr<{ref: string}>[];
58
- "type:maxInclusiveRef"?: XMLAttr<{ref: string}>[];
59
- "type:maxExclusiveRef"?: XMLAttr<{ref: string}>[];
60
- "type:special"?: XMLAttr<{name: string; value: string}>[];
61
- /** only used for `type:type` (data type non-value) */
62
- "type:invalid"?: XMLAttr<{value: string}>[];
63
- /** for types gen */
64
- "type:enumeration"?: XMLEnumeration[];
65
- "type:sequence"?: XMLSequence[];
66
- }
67
-
68
- export interface XMLAttributeDefinition
69
- extends XMLAttr<{
70
- id: string;
71
- name: string;
72
- type: string;
73
- readable?: string; // default="true"
74
- writable?: string; // default="false"
75
- writeOptional?: string; // default="false"
76
- writableIf?: string; // DependencyExpression
77
- reportRequired?: string; // default="false"
78
- sceneRequired?: string; // default="false"
79
- required?: string; // default="false"
80
- requiredIf?: string; // DependencyExpression
81
- min?: string; // default="0"
82
- max?: string;
83
- default?: string;
84
- defaultRef?: string; // NamedElement
85
- deprecated?: string; // default="false"
86
- }> {
87
- restriction?: XMLRestriction[];
88
- bitmap?: XMLBitmapDefinition[];
89
- }
90
-
91
- export interface XMLFieldDefinition
92
- extends XMLAttr<{
93
- name: string;
94
- type: string;
95
- array?: string;
96
- arrayLengthSize?: string;
97
- arrayLengthField?: string;
98
- presentIf?: string;
99
- deprecated?: string;
100
- }> {
101
- restriction?: XMLRestriction[];
102
- bitmap?: XMLBitmapDefinition[];
103
- }
104
-
105
- export interface XMLCommandDefinition
106
- extends XMLAttr<{
107
- id: string;
108
- name: string;
109
- required?: string; // default="false"
110
- requiredIf?: string; // DependencyExpression
111
- deprecated?: string; // default="false"
112
- }> {
113
- fields?: {field: XMLFieldDefinition[]}[];
114
- }
115
-
116
- export interface XMLClusterSide {
117
- attributes?: {attribute: XMLAttributeDefinition[]}[];
118
- commands?: {command: XMLCommandDefinition[]}[];
119
- }
120
-
121
- export interface XMLCluster
122
- extends XMLAttr<{
123
- id: string;
124
- revision: string;
125
- name: string;
126
- manufacturer?: string;
127
- }> {
128
- classification: XMLAttr<{role?: string; picsCode: string; primaryTransaction?: string}>[];
129
- server?: XMLClusterSide[];
130
- client?: XMLClusterSide[];
131
- "type:type"?: XMLTypeType[];
132
- }
133
-
134
- export interface XMLDerivedCluster extends XMLCluster {
135
- // biome-ignore lint/style/useNamingConvention: API
136
- $: {
137
- inheritsFrom: string;
138
- } & XMLCluster["$"];
139
- }
140
-
141
- export interface XMLRoot {
142
- "zcl:cluster"?: XMLCluster | XMLCluster[];
143
- "zcl:derivedCluster"?: XMLDerivedCluster | XMLDerivedCluster[];
144
- "zcl:library"?: XMLLibrary | XMLLibrary[];
145
- "zcl:global"?: XMLGlobal | XMLGlobal[];
146
- }