knx.ts 1.0.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -0
  3. package/dist/@types/interfaces/DPTs.d.ts +144 -0
  4. package/dist/@types/interfaces/DPTs.js +3 -0
  5. package/dist/@types/interfaces/EMI.d.ts +396 -0
  6. package/dist/@types/interfaces/EMI.js +2 -0
  7. package/dist/@types/interfaces/ServiceMessage.d.ts +11 -0
  8. package/dist/@types/interfaces/ServiceMessage.js +2 -0
  9. package/dist/@types/interfaces/SystemStatus.d.ts +18 -0
  10. package/dist/@types/interfaces/SystemStatus.js +2 -0
  11. package/dist/@types/interfaces/connection.d.ts +139 -0
  12. package/dist/@types/interfaces/connection.js +2 -0
  13. package/dist/@types/interfaces/localEndPoint.d.ts +5 -0
  14. package/dist/@types/interfaces/localEndPoint.js +2 -0
  15. package/dist/@types/types/AllDpts.d.ts +3 -0
  16. package/dist/@types/types/AllDpts.js +3 -0
  17. package/dist/@types/types/DecodedDPTType.d.ts +21 -0
  18. package/dist/@types/types/DecodedDPTType.js +2 -0
  19. package/dist/connection/KNXService.d.ts +58 -0
  20. package/dist/connection/KNXService.js +242 -0
  21. package/dist/connection/KNXTunneling.d.ts +44 -0
  22. package/dist/connection/KNXTunneling.js +509 -0
  23. package/dist/connection/KNXnetIPServer.d.ts +64 -0
  24. package/dist/connection/KNXnetIPServer.js +900 -0
  25. package/dist/connection/Router.d.ts +49 -0
  26. package/dist/connection/Router.js +269 -0
  27. package/dist/connection/TPUART.d.ts +32 -0
  28. package/dist/connection/TPUART.js +497 -0
  29. package/dist/connection/TunnelConnection.d.ts +57 -0
  30. package/dist/connection/TunnelConnection.js +167 -0
  31. package/dist/core/CEMI.d.ts +1130 -0
  32. package/dist/core/CEMI.js +1281 -0
  33. package/dist/core/ControlField.d.ts +57 -0
  34. package/dist/core/ControlField.js +120 -0
  35. package/dist/core/ControlFieldExtended.d.ts +56 -0
  36. package/dist/core/ControlFieldExtended.js +114 -0
  37. package/dist/core/EMI.d.ts +2515 -0
  38. package/dist/core/EMI.js +3898 -0
  39. package/dist/core/KNXAddInfoTypes.d.ts +225 -0
  40. package/dist/core/KNXAddInfoTypes.js +602 -0
  41. package/dist/core/KNXnetIPHeader.d.ts +10 -0
  42. package/dist/core/KNXnetIPHeader.js +38 -0
  43. package/dist/core/KNXnetIPStructures.d.ts +179 -0
  44. package/dist/core/KNXnetIPStructures.js +622 -0
  45. package/dist/core/MessageCodeField.d.ts +886 -0
  46. package/dist/core/MessageCodeField.js +399 -0
  47. package/dist/core/SystemStatus.d.ts +144 -0
  48. package/dist/core/SystemStatus.js +325 -0
  49. package/dist/core/data/KNXData.d.ts +7 -0
  50. package/dist/core/data/KNXData.js +30 -0
  51. package/dist/core/data/KNXDataDecode.d.ts +396 -0
  52. package/dist/core/data/KNXDataDecode.js +1186 -0
  53. package/dist/core/data/KNXDataEncode.d.ts +332 -0
  54. package/dist/core/data/KNXDataEncode.js +1504 -0
  55. package/dist/core/enum/APCIEnum.d.ts +587 -0
  56. package/dist/core/enum/APCIEnum.js +591 -0
  57. package/dist/core/enum/EnumControlField.d.ts +24 -0
  58. package/dist/core/enum/EnumControlField.js +36 -0
  59. package/dist/core/enum/EnumControlFieldExtended.d.ts +36 -0
  60. package/dist/core/enum/EnumControlFieldExtended.js +41 -0
  61. package/dist/core/enum/EnumShortACKFrame.d.ts +6 -0
  62. package/dist/core/enum/EnumShortACKFrame.js +10 -0
  63. package/dist/core/enum/ErrorCodeSet.d.ts +57 -0
  64. package/dist/core/enum/ErrorCodeSet.js +2 -0
  65. package/dist/core/enum/KNXnetIPEnum.d.ts +95 -0
  66. package/dist/core/enum/KNXnetIPEnum.js +90 -0
  67. package/dist/core/enum/SAP.d.ts +19 -0
  68. package/dist/core/enum/SAP.js +23 -0
  69. package/dist/core/layers/data/APDU.d.ts +38 -0
  70. package/dist/core/layers/data/APDU.js +115 -0
  71. package/dist/core/layers/data/NPDU.d.ts +73 -0
  72. package/dist/core/layers/data/NPDU.js +103 -0
  73. package/dist/core/layers/data/TPDU.d.ts +53 -0
  74. package/dist/core/layers/data/TPDU.js +73 -0
  75. package/dist/core/layers/interfaces/APCI.d.ts +61 -0
  76. package/dist/core/layers/interfaces/APCI.js +92 -0
  77. package/dist/core/layers/interfaces/TPCI.d.ts +110 -0
  78. package/dist/core/layers/interfaces/TPCI.js +196 -0
  79. package/dist/core/resources/DeviceDescriptorType.d.ts +46 -0
  80. package/dist/core/resources/DeviceDescriptorType.js +69 -0
  81. package/dist/errors/DPTNotFound.d.ts +6 -0
  82. package/dist/errors/DPTNotFound.js +15 -0
  83. package/dist/errors/InvalidKnxAddresExeption.d.ts +3 -0
  84. package/dist/errors/InvalidKnxAddresExeption.js +9 -0
  85. package/dist/index.d.ts +7 -0
  86. package/dist/index.js +18 -0
  87. package/dist/utils/CEMIAdapter.d.ts +16 -0
  88. package/dist/utils/CEMIAdapter.js +94 -0
  89. package/dist/utils/KNXHelper.d.ts +78 -0
  90. package/dist/utils/KNXHelper.js +338 -0
  91. package/dist/utils/Logger.d.ts +17 -0
  92. package/dist/utils/Logger.js +96 -0
  93. package/dist/utils/MessageCodeTranslator.d.ts +19 -0
  94. package/dist/utils/MessageCodeTranslator.js +77 -0
  95. package/dist/utils/checksumFrame.d.ts +18 -0
  96. package/dist/utils/checksumFrame.js +41 -0
  97. package/dist/utils/localIp.d.ts +7 -0
  98. package/dist/utils/localIp.js +45 -0
  99. package/package.json +49 -0
@@ -0,0 +1,3898 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EMI = void 0;
4
+ const KNXHelper_1 = require("../utils/KNXHelper");
5
+ const EnumControlFieldExtended_1 = require("./enum/EnumControlFieldExtended");
6
+ const ControlField_1 = require("./ControlField");
7
+ const MessageCodeField_1 = require("./MessageCodeField");
8
+ const APCI_1 = require("./layers/interfaces/APCI");
9
+ const APCIEnum_1 = require("./enum/APCIEnum");
10
+ const checksumFrame_1 = require("../utils/checksumFrame");
11
+ const SystemStatus_1 = require("./SystemStatus");
12
+ class InvalidInputObject extends Error {
13
+ constructor(className) {
14
+ super(`The input object in the ${className} is must be an object with specific properties`);
15
+ }
16
+ }
17
+ /**
18
+ * @alias External_Message_Interface
19
+ * @description The External Message Interface (EMI) is a standardized interface for communication between external devices and KNX systems. It allows for the integration of various external systems, such as building management systems, into the KNX network.
20
+ * @version Version 01.04.02 is a KNX Approved Standard.
21
+ * @author Arnold Beleño Zuletta
22
+ * @todo - En todos los mensajes se debe implementar las clases que corresponden a las capas de los PDU
23
+ */
24
+ class EMI {
25
+ constructor() {
26
+ throw new Error("This class is static");
27
+ }
28
+ /**
29
+ * Crea una instancia de un servicio EMI a partir de un buffer
30
+ * @param buffer Buffer completo del mensaje EMI (incluyendo Message Code)
31
+ * @returns Instancia del servicio correspondiente
32
+ */
33
+ static fromBuffer(buffer) {
34
+ if (buffer.length === 0) {
35
+ throw new Error("Buffer is empty");
36
+ }
37
+ const messageCode = buffer.readUInt8(0);
38
+ // Buscar el nombre del servicio en MESSAGE_CODE_FIELD
39
+ let serviceName;
40
+ // Priorizamos EMI2/IMI2, luego CEMI
41
+ for (const [key, val] of Object.entries(MessageCodeField_1.MESSAGE_CODE_FIELD)) {
42
+ // @ts-ignore
43
+ const codes = val;
44
+ if (codes["EMI2/IMI2"] && codes["EMI2/IMI2"].value === messageCode) {
45
+ serviceName = key;
46
+ break;
47
+ }
48
+ if (codes["CEMI"] && codes["CEMI"].value === messageCode) {
49
+ serviceName = key;
50
+ break;
51
+ }
52
+ }
53
+ if (!serviceName) {
54
+ throw new Error(`Unknown message code: 0x${messageCode.toString(16).toUpperCase()}`);
55
+ }
56
+ // Buscar la clase en los grupos estáticos
57
+ const groups = [
58
+ EMI.LayerAccess,
59
+ EMI.BusmonitorEMI,
60
+ EMI.DataLinkLayerEMI,
61
+ EMI.NetworkLayerEMI,
62
+ EMI.TransportLayerEMI,
63
+ EMI.ApplicationLayerEMI,
64
+ ];
65
+ for (const group of groups) {
66
+ // @ts-ignore
67
+ const ServiceClass = group[serviceName];
68
+ if (ServiceClass && typeof ServiceClass.fromBuffer === "function") {
69
+ return ServiceClass.fromBuffer(buffer);
70
+ }
71
+ }
72
+ throw new Error(`Service class not implemented for ${serviceName} (Code: 0x${messageCode.toString(16).toUpperCase()})`);
73
+ }
74
+ /**
75
+ * @deprecated **No uses esto, está en desuso**
76
+ */
77
+ static LayerAccess = {
78
+ "PEI_Switch.req": class PEISwitchReq {
79
+ constructor(value) {
80
+ this.systemStatus = value.systemStatus;
81
+ this.LL = value.LL;
82
+ this.NL = value.NL;
83
+ this.TLG = value.TLG;
84
+ this.TLC = value.TLC;
85
+ this.TLL = value.TLL;
86
+ this.AL = value.AL;
87
+ this.MAN = value.MAN;
88
+ this.PEI = value.PEI;
89
+ this.USR = value.USR;
90
+ this.res = value.res;
91
+ }
92
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["PEI_Switch.req"]["EMI2/IMI2"].value;
93
+ systemStatus;
94
+ #LL = 0;
95
+ #NL = 0;
96
+ #TLG = 0;
97
+ #TLC = 0;
98
+ #TLL = 0;
99
+ #AL = 0;
100
+ #MAN = 0;
101
+ #PEI = 0;
102
+ #USR = 0;
103
+ #res = 0;
104
+ set LL(value) {
105
+ if (value < 0 || value > 7)
106
+ throw new TypeError("The property 'LL' must be 4 bits");
107
+ this.#LL = value;
108
+ }
109
+ get LL() {
110
+ return this.#LL;
111
+ }
112
+ set NL(value) {
113
+ if (value < 0 || value > 7)
114
+ throw new TypeError("The property 'NL' must be 4 bits");
115
+ this.#NL = value;
116
+ }
117
+ get NL() {
118
+ return this.#NL;
119
+ }
120
+ set TLG(value) {
121
+ if (value < 0 || value > 7)
122
+ throw new TypeError("The property 'TLG' must be 4 bits");
123
+ this.#TLG = value;
124
+ }
125
+ get TLG() {
126
+ return this.#TLG;
127
+ }
128
+ set TLC(value) {
129
+ if (value < 0 || value > 7)
130
+ throw new TypeError("The property 'TLC' must be 4 bits");
131
+ this.#TLC = value;
132
+ }
133
+ get TLC() {
134
+ return this.#TLC;
135
+ }
136
+ set TLL(value) {
137
+ if (value < 0 || value > 7)
138
+ throw new TypeError("The property 'TLL' must be 4 bits");
139
+ this.#TLL = value;
140
+ }
141
+ get TLL() {
142
+ return this.#TLL;
143
+ }
144
+ set AL(value) {
145
+ if (value < 0 || value > 7)
146
+ throw new TypeError("The property 'AL' must be 4 bits");
147
+ this.#AL = value;
148
+ }
149
+ get AL() {
150
+ return this.#AL;
151
+ }
152
+ set MAN(value) {
153
+ if (value < 0 || value > 7)
154
+ throw new TypeError("The property 'MAN' must be 4 bits");
155
+ this.#MAN = value;
156
+ }
157
+ get MAN() {
158
+ return this.#MAN;
159
+ }
160
+ set PEI(value) {
161
+ if (value < 0 || value > 7)
162
+ throw new TypeError("The property 'PEI' must be 4 bits");
163
+ this.#PEI = value;
164
+ }
165
+ get PEI() {
166
+ return this.#PEI;
167
+ }
168
+ set USR(value) {
169
+ if (value < 0 || value > 7)
170
+ throw new TypeError("The property 'USR' must be 4 bits");
171
+ this.#USR = value;
172
+ }
173
+ get USR() {
174
+ return this.#USR;
175
+ }
176
+ set res(value) {
177
+ if (value < 0 || value > 7)
178
+ throw new TypeError("The property 'res' must be 4 bits");
179
+ this.#res = value;
180
+ }
181
+ get res() {
182
+ return this.#res;
183
+ }
184
+ toBuffer() {
185
+ let octet3 = 0;
186
+ octet3 = octet3 | (this.#LL << 4);
187
+ octet3 = octet3 | this.#NL;
188
+ let octet4 = 0;
189
+ octet4 = octet4 | (this.#TLG << 4);
190
+ octet4 = octet4 | this.#TLC;
191
+ let octet5 = 0;
192
+ octet5 = octet5 | (this.#TLL << 4);
193
+ octet5 = octet5 | this.#AL;
194
+ let octet6 = 0;
195
+ octet6 = octet6 | (this.#MAN << 4);
196
+ octet6 = octet6 | this.#PEI;
197
+ let octet7 = 0;
198
+ octet7 = octet7 | (this.#USR << 4);
199
+ octet7 = octet7 | this.#res;
200
+ const buffer = Buffer.alloc(7);
201
+ buffer.writeUInt8(this.messageCode, 0);
202
+ buffer.writeUInt8(this.systemStatus.value, 1);
203
+ buffer.writeUint8(octet3, 2);
204
+ buffer.writeUint8(octet4, 3);
205
+ buffer.writeUint8(octet5, 4);
206
+ buffer.writeUint8(octet6, 5);
207
+ buffer.writeUint8(octet7, 6);
208
+ return buffer;
209
+ }
210
+ describe() {
211
+ return {
212
+ systemStatus: `${this.systemStatus.describe()}`,
213
+ LL: this.#LL.toString(),
214
+ NL: this.#NL.toString(),
215
+ TLG: this.#TLG.toString(),
216
+ TLC: this.#TLC.toString(),
217
+ TLL: this.#TLL.toString(),
218
+ AL: this.#AL.toString(),
219
+ MAN: this.#MAN.toString(),
220
+ PEI: this.#PEI.toString(),
221
+ USR: this.#USR.toString(),
222
+ res: this.#res.toString(),
223
+ };
224
+ }
225
+ },
226
+ };
227
+ /**
228
+ * In Busmonitor mode exactly the L_Busmon.ind message, the L_Plain_Data.req message, and the
229
+ * LM_Reset.ind message shall be available.
230
+ *
231
+ * **Note:** The LM_Reset.ind message is not implemented.
232
+ */
233
+ static BusmonitorEMI = {
234
+ "L_Busmon.ind": class LBusmonInd {
235
+ constructor(value) {
236
+ if (typeof value !== "object" || value === null) {
237
+ throw new Error("L_Busmon.ind must be an object with specific properties.");
238
+ }
239
+ // Initialize properties based on the value provided
240
+ this.status = value.status;
241
+ this.timeStamp = value.timeStamp;
242
+ this.controlField1 = value.controlField1;
243
+ this.LPDU = value.LPDU;
244
+ }
245
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Busmon.ind"]["EMI2/IMI2"].value;
246
+ status;
247
+ #timeStamp = 0;
248
+ controlField1;
249
+ /**
250
+ * Data Link Protocol Data Unit (LPDU) - This is the actual data payload of the message.
251
+ * It contains the information that is being monitored on the bus.
252
+ *
253
+ * For example, a telegram might contain a control field, a source address, a destination address, and the actual data being transmitted.
254
+ */
255
+ LPDU;
256
+ get timeStamp() {
257
+ return this.#timeStamp;
258
+ }
259
+ set timeStamp(value) {
260
+ if (typeof value !== "number" || value < 0 || value > 65535) {
261
+ throw new Error("timeStamp must be a number between 0 and 65535.");
262
+ }
263
+ this.#timeStamp = value;
264
+ }
265
+ toBuffer() {
266
+ const buffer = Buffer.alloc(5 + this.LPDU.length + 1); // bit 5 + lpdu + Checksum
267
+ buffer.writeUInt8(this.messageCode, 0);
268
+ buffer.writeUInt8(this.status.value, 1);
269
+ buffer.writeInt16BE(this.timeStamp, 2);
270
+ this.controlField1.buffer.copy(buffer, 4); // Assuming controlField1 is a Buffer
271
+ this.LPDU.copy(buffer, 5);
272
+ buffer.writeUInt8((0, checksumFrame_1.checksum)(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
273
+ return buffer;
274
+ }
275
+ describe() {
276
+ return {
277
+ messageCode: `Código de mensaje: ${this.messageCode}`,
278
+ status: `Estado: ${this.status.describe()}`,
279
+ timeStamp: `Marca de tiempo: ${this.timeStamp}`,
280
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
281
+ LPDU: `LPDU: ${this.LPDU}`,
282
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
283
+ };
284
+ }
285
+ /**
286
+ * Crea una instancia de LBusmonInd a partir de un buffer
287
+ * @param buffer Buffer completo incluyendo FCS
288
+ * @returns Instancia de LBusmonInd
289
+ */
290
+ static fromBuffer(buffer) {
291
+ // Verificar longitud mínima
292
+ if (buffer.length < 5) {
293
+ throw new Error(`Buffer too short for L_Busmon.ind: ${buffer.length} bytes`);
294
+ }
295
+ // Extraer componentes
296
+ const messageCode = buffer.readUInt8(0);
297
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Busmon.ind"]["EMI2/IMI2"].value;
298
+ if (messageCode !== expectedCode) {
299
+ throw new Error(`Invalid message code for L_Busmon.ind: ${messageCode} (expected ${expectedCode})`);
300
+ }
301
+ // Status byte
302
+ const statusByte = buffer.readUInt8(1);
303
+ const statusObj = {
304
+ frameError: ((statusByte >> 7) & 0x01) === 1,
305
+ bitError: ((statusByte >> 6) & 0x01) === 1,
306
+ parityError: ((statusByte >> 5) & 0x01) === 1,
307
+ overflow: ((statusByte >> 4) & 0x01) === 1,
308
+ lost: ((statusByte >> 3) & 0x01) === 1,
309
+ sequenceNumber: (statusByte & 0x07),
310
+ };
311
+ const status = new SystemStatus_1.Status(statusObj);
312
+ // Timestamp (2 bytes, big endian)
313
+ const timeStamp = buffer.readUInt16BE(2);
314
+ // Control Field (1 byte)
315
+ const controlFieldByte = buffer.readUInt8(4);
316
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
317
+ // LPDU (resto del buffer)
318
+ const LPDU = buffer.subarray(5);
319
+ return new LBusmonInd({
320
+ status,
321
+ timeStamp,
322
+ controlField1,
323
+ LPDU,
324
+ });
325
+ }
326
+ },
327
+ /**
328
+ * It shall be possible to send up to 28 octets of plain data by this service.
329
+ *
330
+ * In “time” optionally a time delay before sending the message on the bus can be specified. If
331
+ * “time”=00000000h the frame shall be sent immediately. Otherwise the frame shall be sent if the free
332
+ * running system counter of the sending device equals the value given in “time”.
333
+ */
334
+ "L_Plain_Data.req": class LPlainDataReq {
335
+ constructor(value) {
336
+ if (typeof value !== "object" || value === null) {
337
+ throw new Error("L_Plain_Data.req must be an object with specific properties.");
338
+ }
339
+ this.time = value.time;
340
+ this.data = value.data;
341
+ }
342
+ time; // Time delay before sending the message
343
+ data; // Data to be sent
344
+ toBuffer() {
345
+ const buffer = Buffer.alloc(6 + this.data.length);
346
+ buffer.writeUInt8(MessageCodeField_1.MESSAGE_CODE_FIELD["L_Plain_Data.req"]["EMI2/IMI2"].value, 0);
347
+ buffer.writeUInt32BE(this.time, 2); // byte 3-6
348
+ this.data.copy(buffer, 6);
349
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
350
+ return buffer;
351
+ }
352
+ describe() {
353
+ return {
354
+ time: `Tiempo: ${this.time}`,
355
+ data: `Datos: ${this.data.toString("hex")}`,
356
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
357
+ };
358
+ }
359
+ /**
360
+ * Crea una instancia de LPlainDataReq a partir de un buffer
361
+ * @param buffer Buffer completo incluyendo FCS
362
+ * @returns Instancia de LPlainDataReq
363
+ */
364
+ static fromBuffer(buffer) {
365
+ // Verificar longitud mínima
366
+ if (buffer.length < 6) {
367
+ throw new Error(`Buffer too short for L_Plain_Data.req: ${buffer.length} bytes`);
368
+ }
369
+ // Extraer componentes
370
+ const messageCode = buffer.readUInt8(0);
371
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Plain_Data.req"]["EMI2/IMI2"].value;
372
+ if (messageCode !== expectedCode) {
373
+ throw new Error(`Invalid message code for L_Plain_Data.req: ${messageCode} (expected ${expectedCode})`);
374
+ }
375
+ // Verificar octeto de control (debe ser 0x00 según especificación)
376
+ const controlByte = buffer.readUInt8(1);
377
+ if (controlByte !== 0x00) {
378
+ console.warn(`Warning: Control byte in L_Plain_Data.req is ${controlByte.toString(16)}, expected 0x00`);
379
+ }
380
+ // Time (4 bytes, big endian, en posición 2-5)
381
+ const time = buffer.readUInt32BE(2);
382
+ // Data (resto del buffer desde posición 6)
383
+ const data = buffer.subarray(6);
384
+ // Verificar longitud máxima (28 octetos según especificación)
385
+ if (data.length > 28) {
386
+ throw new Error(`Data too long for L_Plain_Data.req: ${data.length} bytes (max 28)`);
387
+ }
388
+ return new LPlainDataReq({
389
+ time,
390
+ data,
391
+ });
392
+ }
393
+ },
394
+ };
395
+ /**
396
+ * In normal operation mode of the Data Link Layer, exactly the L_Data.req, the L_Data.ind, the
397
+ * L_Data.con, the L_Poll_Data.req and the L_Poll_Data.con messages shall be available.
398
+ */
399
+ static DataLinkLayerEMI = {
400
+ "L_Data.req": class LDataReq {
401
+ constructor(value) {
402
+ if (typeof value !== "object" || value === null) {
403
+ throw new Error("L_Data.req must be an object with specific properties.");
404
+ }
405
+ this.controlField1 = new ControlField_1.ControlField(0);
406
+ this.controlField1.priority = value.control.priority;
407
+ this.controlField1.ackRequest = value.control.ackRequest;
408
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress) ||
409
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
410
+ this.destinationAddress = value.destinationAddress;
411
+ }
412
+ else {
413
+ throw new Error("The Destination Address is invalid Group Address or Individual Address");
414
+ }
415
+ this.addressType = value.addressType;
416
+ this.NPCI = value.NPCI;
417
+ this.npdu = value.NPDU;
418
+ }
419
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Data.req"]["EMI2/IMI2"].value;
420
+ controlField1; // Control field 1
421
+ destinationAddress; // Destination address
422
+ addressType;
423
+ NPCI;
424
+ octNumber = 0;
425
+ npdu; // Network Protocol Data Unit (NPDU)
426
+ toBuffer() {
427
+ const buffer = Buffer.alloc(7 + this.npdu.length);
428
+ buffer.writeUInt8(this.messageCode, 0);
429
+ this.controlField1.buffer.copy(buffer, 1); // Assuming controlField1 is a Buffer
430
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
431
+ buffer[6] =
432
+ 0x00 |
433
+ ((this.addressType << 7) |
434
+ (this.NPCI << 4) |
435
+ (this.npdu.length & 0x0f));
436
+ this.npdu.copy(buffer, 7);
437
+ return buffer;
438
+ }
439
+ describe() {
440
+ return {
441
+ messageCode: `Código de mensaje: ${this.messageCode}`,
442
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
443
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
444
+ addressType: `AT: ${EnumControlFieldExtended_1.AddressType[this.addressType]}`,
445
+ npci: `NPCI: ${this.NPCI}`,
446
+ npdu: `NPDU: ${this.npdu.toString("hex")}`,
447
+ octNumber: this.npdu.length.toString(),
448
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
449
+ };
450
+ }
451
+ static fromBuffer(buffer) {
452
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Data.req"]["EMI2/IMI2"].value;
453
+ if (buffer.readUInt8(0) !== messageCode) {
454
+ throw new Error(`Invalid message code for L_Data.req. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
455
+ }
456
+ if (buffer.length < 7) {
457
+ throw new Error("Buffer too short for L_Data.req");
458
+ }
459
+ const controlFieldByte = buffer.readUInt8(1);
460
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
461
+ //[cite_start]// Bytes 2 and 3 are unused in Req [cite: 273]
462
+ const destinationAddressBuf = buffer.subarray(4, 6);
463
+ // Nota: Asumimos dirección de grupo por defecto si no podemos distinguir, pero el AT nos dirá
464
+ const octet6 = buffer.readUInt8(6);
465
+ const addressType = (octet6 >> 7) & 0x01;
466
+ const NPCI = (octet6 >> 4) & 0x07;
467
+ const length = octet6 & 0x0f;
468
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, addressType === EnumControlFieldExtended_1.AddressType.GROUP ? "/" : ".");
469
+ const npdu = buffer.subarray(7, 7 + length);
470
+ return new LDataReq({
471
+ control: {
472
+ priority: controlField1.priority,
473
+ ackRequest: controlField1.ackRequest,
474
+ },
475
+ destinationAddress: destinationAddress,
476
+ addressType: addressType,
477
+ NPCI: NPCI,
478
+ NPDU: npdu,
479
+ });
480
+ }
481
+ },
482
+ "L_Data.con": class LDataCon {
483
+ constructor(value) {
484
+ if (typeof value !== "object" || value === null) {
485
+ throw new Error("L_Data.req must be an object with specific properties.");
486
+ }
487
+ this.controlField1 = new ControlField_1.ControlField(0);
488
+ this.controlField1.priority = value.control.priority;
489
+ this.controlField1.confirm = value.control.confirm;
490
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress) ||
491
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
492
+ this.destinationAddress = value.destinationAddress;
493
+ }
494
+ else {
495
+ throw new Error("The Destination Address is invalid Group Address or Individual Address");
496
+ }
497
+ this.addressType = value.addressType;
498
+ this.NPCI = value.NPCI;
499
+ this.npdu = value.NPDU;
500
+ }
501
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Data.con"]["EMI2/IMI2"].value;
502
+ controlField1; // Control field 1
503
+ destinationAddress; // Destination address
504
+ addressType;
505
+ NPCI;
506
+ octNumber = 0;
507
+ npdu; // Network Protocol Data Unit (NPDU)
508
+ toBuffer() {
509
+ const buffer = Buffer.alloc(7 + this.npdu.length);
510
+ buffer.writeUInt8(this.messageCode, 0);
511
+ this.controlField1.buffer.copy(buffer, 1); // Assuming controlField1 is a Buffer
512
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
513
+ buffer[6] =
514
+ 0x00 |
515
+ ((this.addressType << 7) |
516
+ (this.NPCI << 4) |
517
+ (this.npdu.length & 0x0f));
518
+ this.npdu.copy(buffer, 7);
519
+ return buffer;
520
+ }
521
+ describe() {
522
+ return {
523
+ messageCode: `Código de mensaje: ${this.messageCode}`,
524
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
525
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
526
+ addressType: `AT: ${EnumControlFieldExtended_1.AddressType[this.addressType]}`,
527
+ npci: `NPCI: ${this.NPCI}`,
528
+ npdu: `NPDU: ${this.npdu.toString("hex")}`,
529
+ octNumber: this.npdu.length.toString(),
530
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
531
+ };
532
+ }
533
+ static fromBuffer(buffer) {
534
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Data.con"]["EMI2/IMI2"].value;
535
+ if (buffer.readUInt8(0) !== messageCode) {
536
+ throw new Error(`Invalid message code for L_Data.con. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
537
+ }
538
+ if (buffer.length < 7) {
539
+ throw new Error("Buffer too short for L_Data.con");
540
+ }
541
+ const controlFieldByte = buffer.readUInt8(1);
542
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
543
+ const octet6 = buffer.readUInt8(6);
544
+ const addressType = (octet6 >> 7) & 0x01;
545
+ const NPCI = (octet6 >> 4) & 0x07;
546
+ const length = octet6 & 0x0f;
547
+ //[cite_start]// Bytes 2 and 3 unused [cite: 282]
548
+ const destinationAddressBuf = buffer.subarray(4, 6);
549
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, addressType === EnumControlFieldExtended_1.AddressType.GROUP ? "/" : ".");
550
+ const npdu = buffer.subarray(7, 7 + length);
551
+ return new LDataCon({
552
+ control: {
553
+ priority: controlField1.priority,
554
+ confirm: controlField1.confirm,
555
+ },
556
+ destinationAddress: destinationAddress,
557
+ addressType: addressType,
558
+ NPCI: NPCI,
559
+ NPDU: npdu,
560
+ });
561
+ }
562
+ },
563
+ "L_Data.ind": class LDataInd {
564
+ constructor(value) {
565
+ if (typeof value !== "object" || value === null) {
566
+ throw new Error("L_Data.ind must be an object with specific properties.");
567
+ }
568
+ this.controlField1 = new ControlField_1.ControlField(0);
569
+ this.controlField1.priority = value.control.priority;
570
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress) ||
571
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
572
+ this.destinationAddress = value.destinationAddress;
573
+ }
574
+ else {
575
+ throw new Error("The Destination Address is invalid Group Address or Individual Address");
576
+ }
577
+ this.sourceAddress = value.sourceAddress;
578
+ this.addressType = value.addressType;
579
+ this.NPCI = value.NPCI;
580
+ this.npdu = value.NPDU;
581
+ }
582
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Data.ind"]["EMI2/IMI2"].value;
583
+ controlField1; // Control field 1
584
+ sourceAddress;
585
+ destinationAddress; // Destination address
586
+ addressType;
587
+ NPCI;
588
+ octNumber = 0;
589
+ npdu; // Network Protocol Data Unit (NPDU)
590
+ toBuffer() {
591
+ const buffer = Buffer.alloc(7 + this.npdu.length);
592
+ buffer.writeUInt8(this.messageCode, 0);
593
+ this.controlField1.buffer.copy(buffer, 1); // Assuming controlField1 is a Buffer
594
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
595
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
596
+ buffer[6] =
597
+ 0x00 |
598
+ ((this.addressType << 7) |
599
+ (this.NPCI << 4) |
600
+ (this.npdu.length & 0x0f));
601
+ this.npdu.copy(buffer, 7);
602
+ return buffer;
603
+ }
604
+ describe() {
605
+ return {
606
+ messageCode: `Código de mensaje: ${this.messageCode}`,
607
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
608
+ sourceAddress: `Dirección de fuente: ${this.sourceAddress}`,
609
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
610
+ addressType: `AT: ${EnumControlFieldExtended_1.AddressType[this.addressType]}`,
611
+ npci: `NPCI: ${this.NPCI}`,
612
+ npdu: `NPDU: ${this.npdu.toString("hex")}`,
613
+ octNumber: this.npdu.length.toString(),
614
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
615
+ };
616
+ }
617
+ static fromBuffer(buffer) {
618
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Data.ind"]["EMI2/IMI2"].value;
619
+ if (buffer.readUInt8(0) !== messageCode) {
620
+ throw new Error(`Invalid message code for L_Data.ind. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
621
+ }
622
+ if (buffer.length < 7) {
623
+ throw new Error("Buffer too short for L_Data.ind");
624
+ }
625
+ const controlFieldByte = buffer.readUInt8(1);
626
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
627
+ const sourceAddressBuf = buffer.subarray(2, 4);
628
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(sourceAddressBuf, ".");
629
+ const octet6 = buffer.readUInt8(6);
630
+ const addressType = (octet6 >> 7) & 0x01;
631
+ const NPCI = (octet6 >> 4) & 0x07;
632
+ const length = octet6 & 0x0f;
633
+ const destinationAddressBuf = buffer.subarray(4, 6);
634
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, addressType === EnumControlFieldExtended_1.AddressType.GROUP ? "/" : ".");
635
+ const npdu = buffer.subarray(7, 7 + length);
636
+ return new LDataInd({
637
+ control: {
638
+ priority: controlField1.priority,
639
+ },
640
+ sourceAddress: sourceAddress,
641
+ destinationAddress: destinationAddress,
642
+ addressType: addressType,
643
+ NPCI: NPCI,
644
+ NPDU: npdu,
645
+ });
646
+ }
647
+ },
648
+ "L_Poll_Data.req": class LPollDataReq {
649
+ constructor(value) {
650
+ this.#pollingGroup = value.pollingGroup;
651
+ this.#nrOfSlots = value.nrOfSlots;
652
+ }
653
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Poll_Data.req"]["EMI2/IMI2"].value;
654
+ control = 0xf0;
655
+ #pollingGroup = 0;
656
+ #nrOfSlots = 0;
657
+ set pollingGroup(value) {
658
+ if (value < 0 || value > 65.535)
659
+ throw new Error("The value must be 16 bits");
660
+ this.#pollingGroup = value;
661
+ }
662
+ get pollingGroup() {
663
+ return this.#pollingGroup;
664
+ }
665
+ set nrOfSlots(value) {
666
+ if (value < 0 || value > 7)
667
+ throw new Error("The value must be 4 bits");
668
+ this.#nrOfSlots = value;
669
+ }
670
+ get nrOfSlots() {
671
+ return this.#nrOfSlots;
672
+ }
673
+ toBuffer() {
674
+ const buffer = Buffer.alloc(7);
675
+ let octet7 = 0;
676
+ octet7 = octet7 | (this.#nrOfSlots & 0x0f);
677
+ buffer.writeUInt8(this.messageCode, 0);
678
+ buffer.writeUInt8(this.control, 1);
679
+ buffer.writeUInt8(0, 2);
680
+ buffer.writeUInt8(0, 3);
681
+ buffer.writeUInt8(this.#pollingGroup & 0xff00, 4);
682
+ buffer.writeUInt8(this.#pollingGroup & 0x00ff, 5);
683
+ buffer.writeUInt8(octet7, 6);
684
+ return buffer;
685
+ }
686
+ describe() {
687
+ return {
688
+ messageCode: `Codigo de mensaje: ${this.messageCode}`,
689
+ control: `Control: ${this.control}`,
690
+ pollingGroup: `${this.#pollingGroup}`,
691
+ nrOfGroup: `${this.#nrOfSlots}`,
692
+ };
693
+ }
694
+ static fromBuffer(buffer) {
695
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Poll_Data.req"]["EMI2/IMI2"].value;
696
+ if (buffer.readUInt8(0) !== messageCode) {
697
+ throw new Error(`Invalid message code for L_Poll_Data.req. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
698
+ }
699
+ if (buffer.length < 7) {
700
+ throw new Error("Buffer too short for L_Poll_Data.req");
701
+ }
702
+ const pollingGroup = buffer.readUInt16BE(4);
703
+ const nrOfSlots = (buffer.readUInt8(6) & 0x0f);
704
+ return new LPollDataReq({
705
+ pollingGroup,
706
+ nrOfSlots,
707
+ });
708
+ }
709
+ },
710
+ "L_Poll_Data.con": class LPollDataCon {
711
+ constructor(value) {
712
+ this.#pollingGroup = value.pollingGroup;
713
+ this.#nrOfSlots = value.nrOfSlots;
714
+ this.control.confirm = value.control.confirm;
715
+ }
716
+ control = new ControlField_1.ControlField(0xf0);
717
+ #pollingGroup = 0;
718
+ #nrOfSlots = 0;
719
+ set pollingGroup(value) {
720
+ if (value < 0 || value > 65.535)
721
+ throw new Error("The value must be 16 bits");
722
+ this.#pollingGroup = value;
723
+ }
724
+ get pollingGroup() {
725
+ return this.#pollingGroup;
726
+ }
727
+ set nrOfSlots(value) {
728
+ if (value < 0 || value > 7)
729
+ throw new Error("The value must be 4 bits");
730
+ this.#nrOfSlots = value;
731
+ }
732
+ get nrOfSlots() {
733
+ return this.#nrOfSlots;
734
+ }
735
+ toBuffer() {
736
+ const buffer = Buffer.alloc(7);
737
+ let octet7 = 0;
738
+ octet7 = octet7 | (this.#nrOfSlots & 0x0f);
739
+ buffer.writeUInt8(MessageCodeField_1.MESSAGE_CODE_FIELD["L_Poll_Data.con"]["EMI2/IMI2"].value, 0);
740
+ this.control.buffer.copy(buffer, 1);
741
+ buffer.writeUInt8(0, 2);
742
+ buffer.writeUInt8(0, 3);
743
+ buffer.writeUInt8(this.#pollingGroup & 0xff00, 4);
744
+ buffer.writeUInt8(this.#pollingGroup & 0x00ff, 5);
745
+ buffer.writeUInt8(octet7, 6);
746
+ return buffer;
747
+ }
748
+ describe() {
749
+ return {
750
+ messageCode: `Codigo de mensaje: ${MessageCodeField_1.MESSAGE_CODE_FIELD["L_Poll_Data.con"]["EMI2/IMI2"].value}`,
751
+ control: `Control: ${this.control}`,
752
+ pollingGroup: `${this.#pollingGroup}`,
753
+ nrOfGroup: `${this.#nrOfSlots}`,
754
+ };
755
+ }
756
+ static fromBuffer(buffer) {
757
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_Poll_Data.con"]["EMI2/IMI2"].value;
758
+ if (buffer.readUInt8(0) !== messageCode) {
759
+ throw new Error(`Invalid message code for L_Poll_Data.con. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
760
+ }
761
+ const controlByte = buffer.readInt8(1);
762
+ const pollingGroup = buffer.readUInt16BE(4);
763
+ const nrOfSlots = (buffer.readUInt8(6) & 0x0f);
764
+ return new LPollDataCon({
765
+ pollingGroup,
766
+ nrOfSlots,
767
+ control: {
768
+ confirm: controlByte << 7 === 1 ? true : false,
769
+ },
770
+ });
771
+ }
772
+ },
773
+ "L_SystemBroadcast.req": class LSystemBroadcastReq {
774
+ constructor(value) {
775
+ if (typeof value !== "object" || value === null) {
776
+ throw new Error("L_Data.ind must be an object with specific properties.");
777
+ }
778
+ this.controlField1 = new ControlField_1.ControlField(0b10000000);
779
+ this.controlField1.priority = value.control.priority;
780
+ this.controlField1.confirm = value.control.confirm;
781
+ this.messageCode =
782
+ MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.req"]["EMI2/IMI2"].value;
783
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress) ||
784
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
785
+ this.destinationAddress = value.destinationAddress;
786
+ }
787
+ else {
788
+ throw new Error("The Destination Address is invalid Group Address or Individual Address");
789
+ }
790
+ this.addressType = value.addressType;
791
+ this.NPCI = value.NPCI;
792
+ this.npdu = value.NPDU;
793
+ }
794
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.req"]["EMI2/IMI2"].value;
795
+ controlField1; // Control field 1
796
+ destinationAddress; // Destination address
797
+ addressType;
798
+ NPCI;
799
+ octNumber = 0;
800
+ npdu; // Network Protocol Data Unit (NPDU)
801
+ toBuffer() {
802
+ const buffer = Buffer.alloc(7 + this.npdu.length);
803
+ buffer.writeUInt8(this.messageCode, 0);
804
+ this.controlField1.buffer.copy(buffer, 1); // Assuming controlField1 is a Buffer
805
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
806
+ buffer[6] =
807
+ 0x00 |
808
+ ((this.addressType << 7) |
809
+ (this.NPCI << 4) |
810
+ (this.npdu.length & 0x0f));
811
+ this.npdu.copy(buffer, 7);
812
+ return buffer;
813
+ }
814
+ describe() {
815
+ return {
816
+ messageCode: `Código de mensaje: ${this.messageCode}`,
817
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
818
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
819
+ addressType: `AT: ${EnumControlFieldExtended_1.AddressType[this.addressType]}`,
820
+ npci: `NPCI: ${this.NPCI}`,
821
+ npdu: `NPDU: ${this.npdu.toString("hex")}`,
822
+ octNumber: this.npdu.length.toString(),
823
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
824
+ };
825
+ }
826
+ static fromBuffer(buffer) {
827
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.req"]["EMI2/IMI2"].value;
828
+ if (buffer.readUInt8(0) !== messageCode) {
829
+ throw new Error(`Invalid message code for L_SystemBroadcast.req. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
830
+ }
831
+ const controlFieldByte = buffer.readUInt8(1);
832
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
833
+ const octet6 = buffer.readUInt8(6);
834
+ const addressType = (octet6 >> 7) & 0x01;
835
+ const NPCI = (octet6 >> 4) & 0x07;
836
+ const length = octet6 & 0x0f;
837
+ const destinationAddressBuf = buffer.subarray(4, 6);
838
+ //[cite_start]// Usually System Broadcast destination is 0/0/0 or specific [cite: 297]
839
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, addressType === EnumControlFieldExtended_1.AddressType.GROUP ? "/" : ".");
840
+ const npdu = buffer.subarray(7, 7 + length);
841
+ return new LSystemBroadcastReq({
842
+ control: {
843
+ priority: controlField1.priority,
844
+ confirm: controlField1.confirm,
845
+ ackRequest: controlField1.ackRequest,
846
+ },
847
+ destinationAddress: destinationAddress,
848
+ addressType: addressType,
849
+ NPCI: NPCI,
850
+ NPDU: npdu,
851
+ });
852
+ }
853
+ },
854
+ "L_SystemBroadcast.con": class LSystemBroadcastCon {
855
+ constructor(value) {
856
+ if (typeof value !== "object" || value === null) {
857
+ throw new Error("L_Data.ind must be an object with specific properties.");
858
+ }
859
+ this.controlField1 = new ControlField_1.ControlField(0);
860
+ this.controlField1.repeat = value.control.notRepeat;
861
+ this.controlField1.priority = value.control.priority;
862
+ this.controlField1.confirm = value.control.confirm;
863
+ this.messageCode =
864
+ MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.con"]["EMI2/IMI2"].value;
865
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress) ||
866
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
867
+ this.destinationAddress = value.destinationAddress;
868
+ }
869
+ else {
870
+ throw new Error("The Destination Address is invalid Group Address or Individual Address");
871
+ }
872
+ this.addressType = value.addressType;
873
+ this.NPCI = value.NPCI;
874
+ this.npdu = value.NPDU;
875
+ }
876
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.con"]["EMI2/IMI2"].value;
877
+ controlField1; // Control field 1
878
+ destinationAddress; // Destination address
879
+ addressType;
880
+ NPCI;
881
+ octNumber = 0;
882
+ npdu; // Network Protocol Data Unit (NPDU)
883
+ toBuffer() {
884
+ const buffer = Buffer.alloc(7 + this.npdu.length);
885
+ buffer.writeUInt8(this.messageCode, 0);
886
+ this.controlField1.buffer.copy(buffer, 1); // Assuming controlField1 is a Buffer
887
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
888
+ buffer[6] =
889
+ 0x00 |
890
+ ((this.addressType << 7) |
891
+ (this.NPCI << 4) |
892
+ (this.npdu.length & 0x0f));
893
+ this.npdu.copy(buffer, 7);
894
+ return buffer;
895
+ }
896
+ describe() {
897
+ return {
898
+ messageCode: `Código de mensaje: ${this.messageCode}`,
899
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
900
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
901
+ addressType: `AT: ${EnumControlFieldExtended_1.AddressType[this.addressType]}`,
902
+ npci: `NPCI: ${this.NPCI}`,
903
+ npdu: `NPDU: ${this.npdu.toString("hex")}`,
904
+ octNumber: this.npdu.length.toString(),
905
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
906
+ };
907
+ }
908
+ static fromBuffer(buffer) {
909
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.con"]["EMI2/IMI2"].value;
910
+ if (buffer.readUInt8(0) !== messageCode) {
911
+ throw new Error(`Invalid message code for L_SystemBroadcast.con. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
912
+ }
913
+ const controlFieldByte = buffer.readUInt8(1);
914
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
915
+ const octet6 = buffer.readUInt8(6);
916
+ const addressType = (octet6 >> 7) & 0x01;
917
+ const NPCI = (octet6 >> 4) & 0x07;
918
+ const length = octet6 & 0x0f;
919
+ const destinationAddressBuf = buffer.subarray(4, 6);
920
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, addressType === EnumControlFieldExtended_1.AddressType.GROUP ? "/" : ".");
921
+ const npdu = buffer.subarray(7, 7 + length);
922
+ return new LSystemBroadcastCon({
923
+ control: {
924
+ priority: controlField1.priority,
925
+ confirm: controlField1.confirm,
926
+ notRepeat: controlField1.repeat,
927
+ },
928
+ destinationAddress: destinationAddress,
929
+ addressType: addressType,
930
+ NPCI: NPCI,
931
+ NPDU: npdu,
932
+ });
933
+ }
934
+ },
935
+ "L_SystemBroadcast.ind": class LSystemBroadcastInd {
936
+ constructor(value) {
937
+ if (typeof value !== "object" || value === null) {
938
+ throw new Error("L_Data.ind must be an object with specific properties.");
939
+ }
940
+ this.controlField1 = new ControlField_1.ControlField(0);
941
+ this.controlField1.priority = value.control.priority;
942
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress) ||
943
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
944
+ this.destinationAddress = value.destinationAddress;
945
+ }
946
+ else {
947
+ throw new Error("The Destination Address is invalid Group Address or Individual Address");
948
+ }
949
+ if (KNXHelper_1.KNXHelper.isValidGroupAddress(value.sourceAddress) ||
950
+ KNXHelper_1.KNXHelper.isValidIndividualAddress(value.sourceAddress)) {
951
+ this.sourceAddress = value.sourceAddress;
952
+ }
953
+ else {
954
+ throw new Error("The Source Address is invalid Group Address or Individual Address");
955
+ }
956
+ this.addressType = value.addressType;
957
+ this.NPCI = value.NPCI;
958
+ this.npdu = value.NPDU;
959
+ }
960
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.ind"]["EMI2/IMI2"].value;
961
+ controlField1; // Control field 1
962
+ destinationAddress; // Destination address
963
+ sourceAddress; // Source address
964
+ addressType;
965
+ NPCI;
966
+ octNumber = 0;
967
+ npdu; // Network Protocol Data Unit (NPDU)
968
+ toBuffer() {
969
+ const buffer = Buffer.alloc(7 + this.npdu.length);
970
+ buffer.writeUInt8(this.messageCode, 0);
971
+ this.controlField1.buffer.copy(buffer, 1); // Assuming controlField1 is a Buffer
972
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
973
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
974
+ buffer[6] = 0x00 | (this.NPCI << 4) | (this.npdu.length & 0x0f);
975
+ this.npdu.copy(buffer, 7);
976
+ return buffer;
977
+ }
978
+ describe() {
979
+ return {
980
+ messageCode: `Código de mensaje: ${this.messageCode}`,
981
+ controlField1: `Campo de control 1: ${this.controlField1.describe()}`,
982
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
983
+ addressType: `AT: ${EnumControlFieldExtended_1.AddressType[this.addressType]}`,
984
+ npci: `NPCI: ${this.NPCI}`,
985
+ npdu: `NPDU: ${this.npdu.toString("hex")}`,
986
+ octNumber: this.npdu.length.toString(),
987
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
988
+ };
989
+ }
990
+ static fromBuffer(buffer) {
991
+ //[cite_start]// Spec[cite: 147]: L_SystemBroadcast.ind -> 28h
992
+ // Note: The class property 'messageCode' above references L_SystemBroadcast.CON (error in original class?),
993
+ // I will try to match the code found in the buffer.
994
+ // Strict check:
995
+ if (buffer.readUInt8(0) !==
996
+ MessageCodeField_1.MESSAGE_CODE_FIELD["L_SystemBroadcast.ind"]["EMI2/IMI2"].value) {
997
+ throw new Error("This messageCode is not L_SystemBroadcast.ind");
998
+ }
999
+ const controlFieldByte = buffer.readUInt8(1);
1000
+ const controlField1 = new ControlField_1.ControlField(controlFieldByte);
1001
+ const sourceAddressBuf = buffer.subarray(2, 4);
1002
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(sourceAddressBuf, ".");
1003
+ const octet6 = buffer.readUInt8(6);
1004
+ //[cite_start]// Address type not strictly in bit 7 for SystemBroadcast Indication according to [cite: 312] diagram?
1005
+ //[cite_start]// Diagram [cite: 313] shows Octet 6 (byte 7 in 1-based, so index 6) has NPCI and LG.
1006
+ // Address Type is implicit in System Broadcast?
1007
+ // But your constructor demands AddressType.
1008
+ // Assuming standard L_Data frame layout for consistency with your class structure.
1009
+ const addressType = (octet6 >> 7) & 0x01; // May be always 1 (Group)?
1010
+ const NPCI = (octet6 >> 4) & 0x07;
1011
+ const length = octet6 & 0x0f;
1012
+ const destinationAddressBuf = buffer.subarray(4, 6);
1013
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, addressType === EnumControlFieldExtended_1.AddressType.GROUP ? "/" : ".");
1014
+ const npdu = buffer.subarray(7, 7 + length);
1015
+ return new LSystemBroadcastInd({
1016
+ control: {
1017
+ priority: controlField1.priority,
1018
+ confirm: controlField1.confirm,
1019
+ notRepeat: controlField1.repeat,
1020
+ },
1021
+ sourceAddress: sourceAddress,
1022
+ destinationAddress: destinationAddress,
1023
+ addressType: addressType,
1024
+ NPCI: NPCI,
1025
+ NPDU: npdu,
1026
+ });
1027
+ }
1028
+ },
1029
+ };
1030
+ /**
1031
+ * In Network Layer mode exactly the N_Data_Individual.req, N_Data_Individual.con,
1032
+ * N_Data_Individual.ind, N_Data_Group.req, N_Data_Group.con, N_Data_Group.ind,
1033
+ * N_Data_Broadcast.req, N_Data_Broadcast.con, N_Data_Broadcast.ind, N_Poll_Data.req and
1034
+ * N_Poll_Data.con messages are available. All NL services belong to EMI/IMI2 only.
1035
+ */
1036
+ static NetworkLayerEMI = {
1037
+ "N_Data_Individual.req": class NDataIndividualReq {
1038
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Individual.req"]["EMI2/IMI2"].value;
1039
+ controlField;
1040
+ destinationAddress; // Individual address
1041
+ TPDU; // Transport Layer Protocol Data Unit
1042
+ constructor(value) {
1043
+ if (typeof value !== "object" || value === null) {
1044
+ throw new Error("N_Data_Individual.req must be an object with specific properties.");
1045
+ }
1046
+ this.controlField = new ControlField_1.ControlField(0);
1047
+ this.controlField.frameType = value.control.frameType;
1048
+ this.controlField.repeat = value.control.repeat;
1049
+ this.controlField.systemBroadcast = value.control.systemBroadcast;
1050
+ this.controlField.priority = value.control.priority;
1051
+ this.controlField.ackRequest = value.control.ackRequest;
1052
+ this.controlField.confirm = value.control.confirm;
1053
+ if (!KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
1054
+ throw new Error("The Destination Address must be a valid Individual Address");
1055
+ }
1056
+ this.destinationAddress = value.destinationAddress;
1057
+ this.TPDU = value.TPDU;
1058
+ }
1059
+ /**
1060
+ * Converts the N_Data_Individual.req message to a Buffer.
1061
+ * Format: Message Code (1) + Control Field (1) + Unused (2) + Dest Addr (2) + LG (1) + APDU (variable) + FCS (1)
1062
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length = 8 + APDU.length
1063
+ * @returns The Buffer representation of the message.
1064
+ */
1065
+ toBuffer() {
1066
+ const buffer = Buffer.alloc(7 + this.TPDU.length);
1067
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1068
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1069
+ buffer.writeUInt8(0x00, 2); // Octet 3: unused
1070
+ buffer.writeUInt8(0x00, 3); // Octet 6: unused (LG high in diagram, but treated as unused)
1071
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4); // Octets 5-6: Destination Address
1072
+ buffer.writeUInt8(this.TPDU.length, 6); // Octet 7: LG (octet count)
1073
+ this.TPDU.copy(buffer, 7); // Octet 8...n: TPDU
1074
+ return buffer;
1075
+ }
1076
+ /**
1077
+ * Provides a human-readable description of the N_Data_Individual.req message.
1078
+ * @returns A record of message properties and their string values.
1079
+ */
1080
+ describe() {
1081
+ return {
1082
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1083
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1084
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
1085
+ APDU: `APDU: ${this.TPDU.toString("hex")}`,
1086
+ APDU_Length: `${this.TPDU.length} octets`,
1087
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1088
+ };
1089
+ }
1090
+ static fromBuffer(buffer) {
1091
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Individual.req"]["EMI2/IMI2"].value;
1092
+ if (buffer.length < 7) {
1093
+ throw new Error("Buffer too short for N_Data_Individual.req message.");
1094
+ }
1095
+ if (buffer.readUInt8(0) !== messageCode) {
1096
+ throw new Error(`Invalid message code for N_Data_Individual.req. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
1097
+ }
1098
+ const controlFieldByte = buffer.readUInt8(1);
1099
+ const controlField = new ControlField_1.ControlField(controlFieldByte);
1100
+ // Octets 3-4 (index 2-3) son 0x0000 (unused) en la Request.
1101
+ const destinationAddressBuf = buffer.subarray(4, 6);
1102
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, ".");
1103
+ const length = buffer.readUInt8(6) & 0x0f; // Octet 7: LG (lower 4 bits)
1104
+ if (buffer.length < 7 + length) {
1105
+ throw new Error(`Buffer length mismatch. Expected at least ${7 + length} bytes, got ${buffer.length}`);
1106
+ }
1107
+ const TPDU = buffer.subarray(7, 7 + length);
1108
+ return new NDataIndividualReq({
1109
+ control: {
1110
+ frameType: controlField.frameType,
1111
+ repeat: controlField.repeat,
1112
+ systemBroadcast: controlField.systemBroadcast,
1113
+ priority: controlField.priority,
1114
+ ackRequest: controlField.ackRequest,
1115
+ confirm: controlField.confirm,
1116
+ },
1117
+ destinationAddress: destinationAddress,
1118
+ TPDU: TPDU,
1119
+ });
1120
+ }
1121
+ },
1122
+ "N_Data_Individual.con": class NDataIndividualCon {
1123
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Individual.con"]["EMI2/IMI2"].value;
1124
+ controlField;
1125
+ destinationAddress; // Destination address
1126
+ TPDU;
1127
+ constructor(value) {
1128
+ if (typeof value !== "object" || value === null) {
1129
+ throw new Error("N_Data_Individual.con must be an object with specific properties.");
1130
+ }
1131
+ this.controlField = new ControlField_1.ControlField(0);
1132
+ this.controlField.confirm = value.control.confirm; // Set confirm bit
1133
+ // The spec (3.3.5.3) for N_Data_Individual.con control field is "unused c".
1134
+ // Therefore, priority should not be set here.
1135
+ if (!KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
1136
+ throw new Error("The Destination Address must be a valid Individual Address");
1137
+ }
1138
+ this.destinationAddress = value.destinationAddress;
1139
+ this.TPDU = value.TPDU;
1140
+ }
1141
+ /**
1142
+ * Converts the N_Data_Individual.con message to a Buffer.
1143
+ * Format: Message Code (1) + Control Field (1) + Unused (1) + Dest Addr (2) + Unused (1) + LG (1) + APDU (variable) + FCS (1)
1144
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1145
+ * @returns The Buffer representation of the message.
1146
+ */
1147
+ toBuffer() {
1148
+ const buffer = Buffer.alloc(7 + this.TPDU.length);
1149
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1150
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1151
+ buffer.writeUInt8(0x00, 2); // Octet 3: unused
1152
+ buffer.writeUInt8(0x00, 3); // Octet 4: unused (LG high in diagram, but treated as unused)
1153
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4); // Octets 5-6: Destination Address
1154
+ buffer.writeUInt8(this.TPDU.length & 0x0f, 6); // Octet 7: LG (octet count)
1155
+ this.TPDU.copy(buffer, 7); // Octet 8...n: TPDU
1156
+ return buffer;
1157
+ }
1158
+ /**
1159
+ * Provides a human-readable description of the N_Data_Individual.con message.
1160
+ * @returns A record of message properties and their string values.
1161
+ */
1162
+ describe() {
1163
+ return {
1164
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1165
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1166
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
1167
+ TPDU: `TPDU: ${this.TPDU.toString("hex")}`,
1168
+ TPDU_Length: `${this.TPDU.length} octets`,
1169
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1170
+ };
1171
+ }
1172
+ static fromBuffer(buffer) {
1173
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Individual.con"]["EMI2/IMI2"].value;
1174
+ if (buffer.length < 7) {
1175
+ throw new Error("Buffer too short for N_Data_Individual.con message.");
1176
+ }
1177
+ if (buffer.readUInt8(0) !== messageCode) {
1178
+ throw new Error(`Invalid message code for N_Data_Individual.con. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
1179
+ }
1180
+ const controlFieldByte = buffer.readUInt8(1);
1181
+ const controlField = new ControlField_1.ControlField(controlFieldByte);
1182
+ // Octets 3-4 (index 2-3) son 0x0000 (unused).
1183
+ const destinationAddressBuf = buffer.subarray(4, 6);
1184
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, ".");
1185
+ const length = buffer.readUInt8(6) & 0x0f; // Octet 7: LG (lower 4 bits)
1186
+ if (buffer.length < 7 + length) {
1187
+ throw new Error(`Buffer length mismatch. Expected at least ${7 + length} bytes, got ${buffer.length}`);
1188
+ }
1189
+ const TPDU = buffer.subarray(7, 7 + length);
1190
+ return new NDataIndividualCon({
1191
+ control: {
1192
+ confirm: controlField.confirm,
1193
+ },
1194
+ destinationAddress: destinationAddress,
1195
+ TPDU: TPDU,
1196
+ });
1197
+ }
1198
+ },
1199
+ "N_Data_Individual.ind": class NDataIndividualInd {
1200
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Individual.ind"]["EMI2/IMI2"].value;
1201
+ controlField;
1202
+ sourceAddress; // Individual address
1203
+ destinationAddress; // Individual address
1204
+ hopCount; // 4 bits (formerly NPCI)
1205
+ TPDU;
1206
+ constructor(value) {
1207
+ if (typeof value !== "object" || value === null) {
1208
+ throw new Error("N_Data_Individual.ind must be an object with specific properties.");
1209
+ }
1210
+ this.controlField = new ControlField_1.ControlField(0);
1211
+ this.controlField.priority = value.control.priority;
1212
+ if (!KNXHelper_1.KNXHelper.isValidIndividualAddress(value.sourceAddress)) {
1213
+ throw new Error("The Source Address must be a valid Individual Address");
1214
+ }
1215
+ this.sourceAddress = value.sourceAddress;
1216
+ if (!KNXHelper_1.KNXHelper.isValidIndividualAddress(value.destinationAddress)) {
1217
+ throw new Error("The Destination Address must be a valid Individual Address");
1218
+ }
1219
+ this.destinationAddress = value.destinationAddress;
1220
+ this.hopCount = value.hopCount;
1221
+ this.TPDU = value.TPDU;
1222
+ }
1223
+ /**
1224
+ * Converts the N_Data_Individual.ind message to a Buffer.
1225
+ * Format: Message Code (1) + Control Field (1) + Source Addr (2) + Dest Addr (2) + hopCount/LG (1) + APDU (variable) + FCS (1)
1226
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1227
+ * @returns The Buffer representation of the message.
1228
+ */
1229
+ toBuffer() {
1230
+ const buffer = Buffer.alloc(7 + this.TPDU.length);
1231
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1232
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1233
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2); // Octets 3-4: Source Address
1234
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4); // Octets 5-6: Destination Address
1235
+ // Octet 7: hop_count_type (bits 6-4) | octet count (LG) (bits 3-0)
1236
+ buffer.writeUInt8(((this.hopCount & 0x0f) << 4) | (this.TPDU.length & 0x0f), 6);
1237
+ this.TPDU.copy(buffer, 7); // Octet 8...n: TPDU
1238
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1239
+ return buffer;
1240
+ }
1241
+ /**
1242
+ * Provides a human-readable description of the N_Data_Individual.ind message.
1243
+ * @returns A record of message properties and their string values.
1244
+ */
1245
+ describe() {
1246
+ return {
1247
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1248
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1249
+ sourceAddress: `Dirección de fuente: ${this.sourceAddress}`,
1250
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
1251
+ hopCount: `Conteo de saltos: ${this.hopCount}`,
1252
+ APDU: `APDU: ${this.TPDU.toString("hex")}`,
1253
+ APDU_Length: `${this.TPDU.length} octets`,
1254
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1255
+ };
1256
+ }
1257
+ static fromBuffer(buffer) {
1258
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Individual.ind"]["EMI2/IMI2"].value;
1259
+ if (buffer.length < 7) {
1260
+ throw new Error("Buffer too short for N_Data_Individual.ind message.");
1261
+ }
1262
+ if (buffer.readUInt8(0) !== messageCode) {
1263
+ throw new Error(`Invalid message code for N_Data_Individual.ind. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
1264
+ }
1265
+ const controlFieldByte = buffer.readUInt8(1);
1266
+ const controlField = new ControlField_1.ControlField(controlFieldByte);
1267
+ const sourceAddressBuf = buffer.subarray(2, 4);
1268
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(sourceAddressBuf, ".");
1269
+ const destinationAddressBuf = buffer.subarray(4, 6);
1270
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, ".");
1271
+ const octet7 = buffer.readUInt8(6);
1272
+ const hopCount = (octet7 >> 4) & 0x0f; // Octet 7: Hop Count (upper 4 bits)
1273
+ const length = octet7 & 0x0f; // Octet 7: LG (lower 4 bits)
1274
+ if (buffer.length < 7 + length) {
1275
+ throw new Error(`Buffer length mismatch. Expected at least ${7 + length} bytes, got ${buffer.length}`);
1276
+ }
1277
+ const TPDU = buffer.subarray(7, 7 + length);
1278
+ return new NDataIndividualInd({
1279
+ control: {
1280
+ priority: controlField.priority,
1281
+ },
1282
+ sourceAddress: sourceAddress,
1283
+ destinationAddress: destinationAddress,
1284
+ hopCount: hopCount,
1285
+ TPDU: TPDU,
1286
+ });
1287
+ }
1288
+ },
1289
+ "N_Data_Group.req": class NDataGroupReq {
1290
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Group.req"]["EMI2/IMI2"].value;
1291
+ controlField;
1292
+ destinationAddress; // Group address
1293
+ APDU;
1294
+ constructor(value) {
1295
+ if (typeof value !== "object" || value === null) {
1296
+ throw new Error("N_Data_Group.req must be an object with specific properties.");
1297
+ }
1298
+ this.controlField = new ControlField_1.ControlField(0);
1299
+ this.controlField.priority = value.control.priority;
1300
+ // The spec (3.3.5.5) for N_Data_Group.req control field is "unused priority unused".
1301
+ // Therefore, ackRequest should not be set here.
1302
+ if (!KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress)) {
1303
+ throw new Error("The Destination Address must be a valid Group Address");
1304
+ }
1305
+ this.destinationAddress = value.destinationAddress;
1306
+ this.APDU = value.APDU;
1307
+ }
1308
+ /**
1309
+ * Converts the N_Data_Group.req message to a Buffer.
1310
+ * Format: Message Code (1) + Control Field (1) + Unused (2) + Dest Addr (2) + hopCount/LG (1) + APDU (variable) + FCS (1)
1311
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1312
+ * @returns The Buffer representation of the message.
1313
+ */
1314
+ toBuffer() {
1315
+ const buffer = Buffer.alloc(7 + this.APDU.length);
1316
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1317
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1318
+ buffer.writeUInt16BE(0x0000, 2); // Octets 3-4: unused (Source Address)
1319
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4); // Octets 5-6: Destination Address
1320
+ // Octet 7: hop_count_type (bits 7-4, default 0) | octet count (LG) (bits 3-0)
1321
+ buffer.writeUInt8(this.APDU.length & 0x0f, 6); // Default hop_count_type is 0
1322
+ this.APDU.copy(buffer, 7); // Octet 8...n: TPDU
1323
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1324
+ return buffer;
1325
+ }
1326
+ /**
1327
+ * Provides a human-readable description of the N_Data_Group.req message.
1328
+ * @returns A record of message properties and their string values.
1329
+ */
1330
+ describe() {
1331
+ return {
1332
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1333
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1334
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
1335
+ APDU: `APDU: ${this.APDU.toString("hex")}`,
1336
+ APDU_Length: `${this.APDU.length} octets`,
1337
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1338
+ };
1339
+ }
1340
+ static fromBuffer(buffer) {
1341
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Group.req"]["EMI2/IMI2"].value;
1342
+ if (buffer.length < 7) {
1343
+ throw new Error("Buffer too short for N_Data_Group.req message.");
1344
+ }
1345
+ if (buffer.readUInt8(0) !== messageCode) {
1346
+ throw new Error(`Invalid message code for N_Data_Group.req. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
1347
+ }
1348
+ const controlFieldByte = buffer.readUInt8(1);
1349
+ const controlField = new ControlField_1.ControlField(controlFieldByte);
1350
+ // Octets 3-4 (index 2-3) son 0x0000 (unused) en la Request.
1351
+ const destinationAddressBuf = buffer.subarray(4, 6);
1352
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, "/"); // Dirección de Grupo
1353
+ const length = buffer.readUInt8(6) & 0x0f; // Octet 7: LG (lower 4 bits), upper 4 bits unused (hop count = 0)
1354
+ if (buffer.length < 7 + length) {
1355
+ throw new Error(`Buffer length mismatch. Expected at least ${7 + length} bytes, got ${buffer.length}`);
1356
+ }
1357
+ const APDU = buffer.subarray(7, 7 + length);
1358
+ return new NDataGroupReq({
1359
+ control: {
1360
+ priority: controlField.priority,
1361
+ },
1362
+ destinationAddress: destinationAddress,
1363
+ APDU: APDU,
1364
+ });
1365
+ }
1366
+ },
1367
+ "N_Data_Group.con": class NDataGroupCon {
1368
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Group.con"]["EMI2/IMI2"].value;
1369
+ controlField;
1370
+ destinationAddress; // Group address
1371
+ APDU;
1372
+ constructor(value) {
1373
+ if (typeof value !== "object" || value === null) {
1374
+ throw new Error("N_Data_Group.con must be an object with specific properties.");
1375
+ }
1376
+ this.controlField = new ControlField_1.ControlField(0);
1377
+ this.controlField.confirm = value.control.confirm;
1378
+ // The spec (3.3.5.6) for N_Data_Group.con control field is "unused c".
1379
+ // Therefore, priority should not be set here.
1380
+ if (!KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress)) {
1381
+ throw new Error("The Destination Address must be a valid Group Address");
1382
+ }
1383
+ this.destinationAddress = value.destinationAddress;
1384
+ this.APDU = value.APDU;
1385
+ }
1386
+ /**
1387
+ * Converts the N_Data_Group.con message to a Buffer.
1388
+ * Format: Message Code (1) + Control Field (1) + Unused (2) + Dest Addr (2) + LG (1) + APDU (variable) + FCS (1)
1389
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1390
+ * @returns The Buffer representation of the message.
1391
+ */
1392
+ toBuffer() {
1393
+ const buffer = Buffer.alloc(7 + this.APDU.length);
1394
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1395
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1396
+ buffer.writeUInt16BE(0x0000, 2); // Octets 3-4: unused (Source Address)
1397
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4); // Octets 5-6: Destination Address
1398
+ buffer.writeUInt8(this.APDU.length & 0x0f, 6); // Octet 7: LG (octet count), upper 4 bits unused
1399
+ this.APDU.copy(buffer, 7); // Octet 8...n: TPDU
1400
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1401
+ return buffer;
1402
+ }
1403
+ /**
1404
+ * Provides a human-readable description of the N_Data_Group.con message.
1405
+ * @returns A record of message properties and their string values.
1406
+ */
1407
+ describe() {
1408
+ return {
1409
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1410
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1411
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
1412
+ APDU: `APDU: ${this.APDU.toString("hex")}`,
1413
+ APDU_Length: `${this.APDU.length} octets`,
1414
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1415
+ };
1416
+ }
1417
+ static fromBuffer(buffer) {
1418
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Group.con"]["EMI2/IMI2"].value;
1419
+ if (buffer.length < 7) {
1420
+ throw new Error("Buffer too short for N_Data_Group.con message.");
1421
+ }
1422
+ if (buffer.readUInt8(0) !== messageCode) {
1423
+ throw new Error(`Invalid message code for N_Data_Group.con. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
1424
+ }
1425
+ const controlFieldByte = buffer.readUInt8(1);
1426
+ const controlField = new ControlField_1.ControlField(controlFieldByte);
1427
+ // Octets 3-4 (index 2-3) son 0x0000 (unused) en la Confirmation.
1428
+ const destinationAddressBuf = buffer.subarray(4, 6);
1429
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, "/"); // Dirección de Grupo
1430
+ const length = buffer.readUInt8(6) & 0x0f; // Octet 7: LG (lower 4 bits), upper 4 bits unused
1431
+ if (buffer.length < 7 + length) {
1432
+ throw new Error(`Buffer length mismatch. Expected at least ${7 + length} bytes, got ${buffer.length}`);
1433
+ }
1434
+ const APDU = buffer.subarray(7, 7 + length);
1435
+ return new NDataGroupCon({
1436
+ control: {
1437
+ confirm: controlField.confirm,
1438
+ },
1439
+ destinationAddress: destinationAddress,
1440
+ APDU: APDU,
1441
+ });
1442
+ }
1443
+ },
1444
+ "N_Data_Group.ind": class NDataGroupInd {
1445
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Group.ind"]["EMI2/IMI2"].value;
1446
+ controlField;
1447
+ sourceAddress; // Individual address
1448
+ destinationAddress; // Group address
1449
+ hopCount; // 4 bits (formerly NPCI)
1450
+ APDU;
1451
+ constructor(value) {
1452
+ if (typeof value !== "object" || value === null) {
1453
+ throw new Error("N_Data_Group.ind must be an object with specific properties.");
1454
+ }
1455
+ this.controlField = new ControlField_1.ControlField(0);
1456
+ this.controlField.priority = value.control.priority;
1457
+ if (!KNXHelper_1.KNXHelper.isValidIndividualAddress(value.sourceAddress)) {
1458
+ throw new Error("The Source Address must be a valid Individual Address");
1459
+ }
1460
+ this.sourceAddress = value.sourceAddress;
1461
+ if (!KNXHelper_1.KNXHelper.isValidGroupAddress(value.destinationAddress)) {
1462
+ throw new Error("The Destination Address must be a valid Group Address");
1463
+ }
1464
+ this.destinationAddress = value.destinationAddress;
1465
+ this.hopCount = value.hopCount;
1466
+ this.APDU = value.APDU;
1467
+ }
1468
+ /**
1469
+ * Converts the N_Data_Group.ind message to a Buffer.
1470
+ * Format: Message Code (1) + Control Field (1) + Unused (2) + Dest Addr (2) + hopCount/LG (1) + APDU (variable) + FCS (1)
1471
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1472
+ * @returns The Buffer representation of the message.
1473
+ */
1474
+ toBuffer() {
1475
+ const buffer = Buffer.alloc(7 + this.APDU.length);
1476
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1477
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1478
+ buffer.writeUInt16BE(0x0000, 2); // Octets 3-4: unused (Source Address in diagram, but text implies unused for Group.ind)
1479
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4); // Octets 5-6: Destination Address
1480
+ // Octet 7: hop_count_type (bits 7-4) | octet count (LG) (bits 3-0)
1481
+ buffer.writeUInt8(((this.hopCount & 0x0f) << 4) | (this.APDU.length & 0x0f), 6);
1482
+ this.APDU.copy(buffer, 7); // Octet 8...n: TPDU
1483
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1484
+ return buffer;
1485
+ }
1486
+ /**
1487
+ * Provides a human-readable description of the N_Data_Group.ind message.
1488
+ * @returns A record of message properties and their string values.
1489
+ */
1490
+ describe() {
1491
+ return {
1492
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1493
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1494
+ sourceAddress: `Dirección de fuente: ${this.sourceAddress}`,
1495
+ destinationAddress: `Dirección de destino: ${this.destinationAddress}`,
1496
+ hopCount: `Conteo de saltos: ${this.hopCount}`,
1497
+ APDU: `APDU: ${this.APDU.toString("hex")}`,
1498
+ APDU_Length: `${this.APDU.length} octets`,
1499
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1500
+ };
1501
+ }
1502
+ static fromBuffer(buffer) {
1503
+ const messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Group.ind"]["EMI2/IMI2"].value;
1504
+ if (buffer.length < 7) {
1505
+ throw new Error("Buffer too short for N_Data_Group.ind message.");
1506
+ }
1507
+ if (buffer.readUInt8(0) !== messageCode) {
1508
+ throw new Error(`Invalid message code for N_Data_Group.ind. Expected ${messageCode}, got ${buffer.readUInt8(0)}`);
1509
+ }
1510
+ const controlFieldByte = buffer.readUInt8(1);
1511
+ const controlField = new ControlField_1.ControlField(controlFieldByte);
1512
+ // ATENCIÓN: Tu toBuffer para esta clase escribe 0x0000 en el Source Address (índice 2-3).
1513
+ // Sin embargo, la especificación KNX (y tu constructor) requiere una Source Address (Individual).
1514
+ // Asumiré la estructura CORRECTA del protocolo (Source Address en 2-3) para la lectura.
1515
+ const sourceAddressBuf = buffer.subarray(2, 4);
1516
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(sourceAddressBuf, "."); // Dirección Individual
1517
+ const destinationAddressBuf = buffer.subarray(4, 6);
1518
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(destinationAddressBuf, "/"); // Dirección de Grupo
1519
+ const octet7 = buffer.readUInt8(6);
1520
+ const hopCount = (octet7 >> 4) & 0x0f; // Octet 7: Hop Count (upper 4 bits)
1521
+ const length = octet7 & 0x0f; // Octet 7: LG (lower 4 bits)
1522
+ if (buffer.length < 7 + length) {
1523
+ throw new Error(`Buffer length mismatch. Expected at least ${7 + length} bytes, got ${buffer.length}`);
1524
+ }
1525
+ const APDU = buffer.subarray(7, 7 + length);
1526
+ return new NDataGroupInd({
1527
+ control: {
1528
+ priority: controlField.priority,
1529
+ },
1530
+ sourceAddress: sourceAddress,
1531
+ destinationAddress: destinationAddress,
1532
+ hopCount: hopCount,
1533
+ APDU: APDU,
1534
+ });
1535
+ }
1536
+ },
1537
+ "N_Data_Broadcast.req": class NDataBroadcastReq {
1538
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Broadcast.req"]["EMI2/IMI2"].value;
1539
+ controlField;
1540
+ hopCount;
1541
+ TPDU;
1542
+ constructor(value) {
1543
+ if (typeof value !== "object" || value === null) {
1544
+ throw new Error("N_Data_Broadcast.req must be an object with specific properties.");
1545
+ }
1546
+ this.controlField = new ControlField_1.ControlField(0);
1547
+ this.controlField.priority = value.control.priority;
1548
+ // The spec (3.3.5.8) for N_Data_Broadcast.req control field is "unused priority unused".
1549
+ // Therefore, ackRequest should not be set here.
1550
+ this.hopCount = value.hopCountType;
1551
+ this.TPDU = value.TPDU;
1552
+ }
1553
+ /**
1554
+ * Converts the N_Data_Broadcast.req message to a Buffer.
1555
+ * Format: Message Code (1) + Control Field (1) + Unused (2) + Unused (2) + hopCount/LG (1) + APDU (variable) + FCS (1)
1556
+ * Total Length: 1 + 1 + 2 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1557
+ * @returns The Buffer representation of the message.
1558
+ */
1559
+ toBuffer() {
1560
+ const buffer = Buffer.alloc(7 + this.TPDU.length);
1561
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1562
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1563
+ buffer.writeUInt16BE(0x0000, 2); // Octets 3-4: unused (Source Address)
1564
+ buffer.writeUInt16BE(0x0000, 4); // Octets 5-6: unused (Destination Address)
1565
+ // Octet 7: hop_count_type (bits 7-4, default 0) | octet count (LG) (bits 3-0)
1566
+ buffer.writeUInt8((this.hopCount << 4) | (this.TPDU.length & 0x0f), 6); // Default hop_count_type is 0
1567
+ this.TPDU.copy(buffer, 7); // Octet 8...n: TPDU
1568
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1569
+ return buffer;
1570
+ }
1571
+ /**
1572
+ * Provides a human-readable description of the N_Data_Broadcast.req message.
1573
+ * @returns A record of message properties and their string values.
1574
+ */
1575
+ describe() {
1576
+ return {
1577
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1578
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1579
+ TPDU: `TPDU: ${this.TPDU.toString("hex")}`,
1580
+ TPDU_Length: `${this.TPDU.length} octets`,
1581
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1582
+ };
1583
+ }
1584
+ static fromBuffer(buffer) {
1585
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Broadcast.req"]["EMI2/IMI2"].value;
1586
+ if (buffer.readUInt8(0) !== expectedCode)
1587
+ throw new Error(`Invalid message code.`);
1588
+ const controlField = new ControlField_1.ControlField(buffer.readUInt8(1));
1589
+ // Broadcast suele asumir destino 0/0/0 implícito o explícito en bytes 4-5
1590
+ // const dest = KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
1591
+ const octet6 = buffer.readUInt8(6);
1592
+ const hopCount = octet6 & 0x70;
1593
+ const length = octet6 & 0x0f;
1594
+ const TPDU = buffer.subarray(7, 7 + length);
1595
+ return new NDataBroadcastReq({
1596
+ control: {
1597
+ priority: controlField.priority,
1598
+ },
1599
+ hopCountType: hopCount,
1600
+ TPDU: TPDU,
1601
+ });
1602
+ }
1603
+ },
1604
+ "N_Data_Broadcast.con": class NDataBroadcastCon {
1605
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Broadcast.con"]["EMI2/IMI2"].value;
1606
+ controlField;
1607
+ TPDU;
1608
+ constructor(value) {
1609
+ if (typeof value !== "object" || value === null) {
1610
+ throw new Error("N_Data_Broadcast.con must be an object with specific properties.");
1611
+ }
1612
+ this.controlField = new ControlField_1.ControlField(0);
1613
+ this.controlField.confirm = value.control.confirm;
1614
+ // The spec (3.3.5.9) for N_Data_Broadcast.con control field is "unused unused unused c".
1615
+ // Therefore, priority should not be set here.
1616
+ this.TPDU = value.TPDU;
1617
+ }
1618
+ /**
1619
+ * Converts the N_Data_Broadcast.con message to a Buffer.
1620
+ * Format: Message Code (1) + Control Field (1) + Unused (2) + Unused (2) + LG (1) + TPDU (variable)
1621
+ * Total Length: 1 + 1 + 2 + 2 + 1 + TPDU.length + 1 = 7 + TPDU.length
1622
+ * @returns The Buffer representation of the message.
1623
+ */
1624
+ toBuffer() {
1625
+ const buffer = Buffer.alloc(7 + this.TPDU.length);
1626
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1627
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1628
+ buffer.writeUInt16BE(0x0000, 2); // Octets 3-4: unused (Source Address)
1629
+ buffer.writeUInt16BE(0x0000, 4); // Octets 5-6: unused (Destination Address)
1630
+ buffer.writeUInt8(this.TPDU.length & 0x0f, 6); // Octet 7: LG (octet count), upper 4 bits unused
1631
+ this.TPDU.copy(buffer, 7); // Octet 8...n: TPDU
1632
+ return buffer;
1633
+ }
1634
+ /**
1635
+ * Provides a human-readable description of the N_Data_Broadcast.con message.
1636
+ * @returns A record of message properties and their string values.
1637
+ */
1638
+ describe() {
1639
+ return {
1640
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1641
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1642
+ APDU: `APDU: ${this.TPDU.toString("hex")}`,
1643
+ APDU_Length: `${this.TPDU.length} octets`,
1644
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1645
+ };
1646
+ }
1647
+ /**
1648
+ * Creates an instance of NDataBroadcastCon from a Buffer.
1649
+ * Expected Structure based on spec and toBuffer:
1650
+ * [0]: Message Code
1651
+ * [1]: Control Field (Confirm/Error)
1652
+ * [2-3]: Unused (Source Address placeholder)
1653
+ * [4-5]: Unused (Destination Address placeholder)
1654
+ * [6]: Length (lower 4 bits)
1655
+ * [7...]: TPDU
1656
+ */
1657
+ static fromBuffer(buffer) {
1658
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Broadcast.con"]["EMI2/IMI2"].value;
1659
+ const actualCode = buffer.readUInt8(0);
1660
+ if (actualCode !== expectedCode) {
1661
+ throw new Error(`Invalid message code for N_Data_Broadcast.con. Expected 0x${expectedCode.toString(16)}, got 0x${actualCode.toString(16)}`);
1662
+ }
1663
+ if (buffer.length < 7) {
1664
+ throw new Error("Buffer too short for N_Data_Broadcast.con");
1665
+ }
1666
+ // Octet 1: Control Field. Recuperamos el estado de 'confirm' (error flag)
1667
+ const controlField = new ControlField_1.ControlField(buffer.readUInt8(1));
1668
+ // Octet 2-3 y 4-5: Ignoramos Source y Destination ya que son 'unused' en esta trama
1669
+ // Octet 6: Length
1670
+ const length = buffer.readUInt8(6) & 0x0f;
1671
+ // Validación de integridad de datos
1672
+ if (buffer.length < 7 + length) {
1673
+ throw new Error(`Buffer mismatch: Expected ${length} bytes of TPDU, available ${buffer.length - 7}`);
1674
+ }
1675
+ const TPDU = buffer.subarray(7, 7 + length);
1676
+ return new NDataBroadcastCon({
1677
+ control: {
1678
+ confirm: controlField.confirm,
1679
+ },
1680
+ TPDU: TPDU,
1681
+ });
1682
+ }
1683
+ },
1684
+ "N_Data_Broadcast.ind": class NDataBroadcastInd {
1685
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Broadcast.ind"]["EMI2/IMI2"].value;
1686
+ controlField;
1687
+ sourceAddress; // Individual address
1688
+ hopCount; // 4 bits (formerly NPCI)
1689
+ TPDU;
1690
+ constructor(value) {
1691
+ if (typeof value !== "object" || value === null) {
1692
+ throw new Error("N_Data_Broadcast.ind must be an object with specific properties.");
1693
+ }
1694
+ this.controlField = new ControlField_1.ControlField(0);
1695
+ this.controlField.priority = value.control.priority;
1696
+ if (!KNXHelper_1.KNXHelper.isValidIndividualAddress(value.sourceAddress)) {
1697
+ throw new Error("The Source Address must be a valid Individual Address");
1698
+ }
1699
+ this.sourceAddress = value.sourceAddress;
1700
+ this.hopCount = value.hopCount;
1701
+ this.TPDU = value.TPDU;
1702
+ }
1703
+ /**
1704
+ * Converts the N_Data_Broadcast.ind message to a Buffer.
1705
+ * Format: Message Code (1) + Control Field (1) + Source Addr (2) + Unused (2) + hopCount/LG (1) + APDU (variable) + FCS (1)
1706
+ * Total Length: 1 + 1 + 2 + 2 + 1 + TPDU.length + 1 = 8 + TPDU.length
1707
+ * @returns The Buffer representation of the message.
1708
+ */
1709
+ toBuffer() {
1710
+ const buffer = Buffer.alloc(7 + this.TPDU.length);
1711
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1712
+ this.controlField.buffer.copy(buffer, 1); // Octet 2: Control
1713
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2); // Octets 3-4: Source Address
1714
+ buffer.writeUInt16BE(0x0000, 4); // Octets 5-6: unused (Destination Address)
1715
+ // Octet 7: hop_count_type (bits 7-4) | octet count (LG) (bits 3-0)
1716
+ buffer.writeUInt8(((this.hopCount & 0x0f) << 4) | (this.TPDU.length & 0x0f), 6);
1717
+ this.TPDU.copy(buffer, 7); // Octet 8...n: TPDU
1718
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1719
+ return buffer;
1720
+ }
1721
+ /**
1722
+ * Provides a human-readable description of the N_Data_Broadcast.ind message.
1723
+ * @returns A record of message properties and their string values.
1724
+ */
1725
+ describe() {
1726
+ return {
1727
+ messageCode: `Código de mensaje: ${this.messageCode}`,
1728
+ controlField: `Campo de control: ${this.controlField.describe()}`,
1729
+ sourceAddress: `Dirección de fuente: ${this.sourceAddress}`,
1730
+ hopCount: `Conteo de saltos: ${this.hopCount}`,
1731
+ TPDU: `TPDU: ${this.TPDU.toString("hex")}`,
1732
+ TPDU_Length: `${this.TPDU.length} octets`,
1733
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1734
+ };
1735
+ }
1736
+ static fromBuffer(buffer) {
1737
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Data_Broadcast.ind"]["EMI2/IMI2"].value;
1738
+ if (buffer.readUInt8(0) !== expectedCode)
1739
+ throw new Error(`Invalid message code.`);
1740
+ const controlField = new ControlField_1.ControlField(buffer.readUInt8(1));
1741
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
1742
+ if (!sourceAddress)
1743
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
1744
+ if (typeof sourceAddress !== "string")
1745
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
1746
+ const octet6 = buffer.readUInt8(6);
1747
+ const hopCount = octet6 & 0x70;
1748
+ const length = octet6 & 0x0f;
1749
+ const TPDU = buffer.subarray(7, 7 + length);
1750
+ return new NDataBroadcastInd({
1751
+ control: { priority: controlField.priority },
1752
+ sourceAddress: sourceAddress,
1753
+ hopCount: hopCount,
1754
+ TPDU: TPDU,
1755
+ });
1756
+ }
1757
+ },
1758
+ "N_Poll_Data.req": class NPollDataReq {
1759
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Poll_Data.req"]["EMI2/IMI2"].value;
1760
+ control = 0xf0; // Fixed control byte for N_Poll_Data.req (similar to L_Poll_Data)
1761
+ #pollingGroup = Buffer.alloc(1, 0);
1762
+ #nrOfSlots = 0;
1763
+ constructor(value) {
1764
+ if (typeof value !== "object" || value === null) {
1765
+ throw new Error("N_Poll_Data.req must be an object with specific properties.");
1766
+ }
1767
+ this.nrOfSlots = value.nrOfSlots;
1768
+ this.pollingGroup = value.pollingGroup;
1769
+ }
1770
+ set pollingGroup(value) {
1771
+ const convertToAddress = KNXHelper_1.KNXHelper.GetAddress_(value);
1772
+ this.#pollingGroup = convertToAddress;
1773
+ }
1774
+ get pollingGroup() {
1775
+ return KNXHelper_1.KNXHelper.GetAddress(this.#pollingGroup, "/", true); // Se supone que es un dirección de grupo;
1776
+ }
1777
+ set nrOfSlots(value) {
1778
+ if (value < 0 || value > 7)
1779
+ throw new Error("The nrOfSlots value must be 4 bits (0-7)");
1780
+ this.#nrOfSlots = value;
1781
+ }
1782
+ get nrOfSlots() {
1783
+ return this.#nrOfSlots;
1784
+ }
1785
+ /**
1786
+ * Converts the N_Poll_Data.req message to a Buffer.
1787
+ * Format: Message Code (1) + Control (1) + Polling Group (2) + NrOfSlots/Reserved (1)
1788
+ * Total Length: 1 + 1 + 2 + 2 + 1 = 7
1789
+ * @returns The Buffer representation of the message.
1790
+ */
1791
+ toBuffer() {
1792
+ const buffer = Buffer.alloc(7);
1793
+ let octet7 = 0;
1794
+ octet7 = octet7 | (this.#nrOfSlots & 0x0f); // NrOfSlots in lower 4 bits
1795
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1: m_code
1796
+ buffer.writeUInt8(this.control, 1); // Octet 2: Control
1797
+ this.#pollingGroup.copy(buffer, 0); // Octets 5-6: Polling Group
1798
+ buffer.writeUInt8(octet7, 6); // Octet 7: NrOfSlots (bits 3-0)
1799
+ return buffer;
1800
+ }
1801
+ /**
1802
+ * Provides a human-readable description of the N_Poll_Data.req message.
1803
+ * @returns A record of message properties and their string values.
1804
+ */
1805
+ describe() {
1806
+ return {
1807
+ messageCode: `Codigo de mensaje: ${this.messageCode}`,
1808
+ control: `Control: ${this.control.toString(16).padStart(2, "0")}`,
1809
+ pollingGroup: `Grupo de sondeo: ${this.#pollingGroup}`,
1810
+ nrOfSlots: `Número de ranuras: ${this.#nrOfSlots}`,
1811
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1812
+ };
1813
+ }
1814
+ static fromBuffer(buffer) {
1815
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Poll_Data.req"]["EMI2/IMI2"].value;
1816
+ if (buffer.readUInt8(0) !== expectedCode)
1817
+ throw new Error(`Invalid message code.`);
1818
+ // Estructura: MC (1) | Control (1) | Source (2) | PollingGroup (2) | Count (1) | Data...
1819
+ // Nota: Revisa tu especificación exacta, a veces Poll Data tiene estructura propia
1820
+ // !! No es necesario el control field ya que es fijo
1821
+ // const control = buffer.readUInt8(1); // O new ControlField(...)
1822
+ const pollingGroup = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
1823
+ if (!pollingGroup)
1824
+ throw new Error("The pollingGroup is undefined or null, this fatal error is from GetAddress, dont be ignore it");
1825
+ if (typeof pollingGroup !== "string")
1826
+ throw new Error("The pollingGroup is not string, this fatal error is from GetAddress, dont be ignore it");
1827
+ const octet6 = buffer.readUInt8(6);
1828
+ const nrOfSlots = octet6 & 0x0f; // Ejemplo, ver spec
1829
+ return new NPollDataReq({
1830
+ // Ajustar propiedades al constructor
1831
+ pollingGroup: pollingGroup,
1832
+ nrOfSlots: nrOfSlots,
1833
+ });
1834
+ }
1835
+ },
1836
+ "N_Poll_Data.con": class NPollDataCon {
1837
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Poll_Data.con"]["EMI2/IMI2"].value;
1838
+ control = 0xf0; // Fixed control byte for N_Poll_Data.con
1839
+ #pollingGroup = Buffer.alloc(1, 0);
1840
+ #nrOfSlots = 0;
1841
+ pollData; // Polled data
1842
+ constructor(value) {
1843
+ if (typeof value !== "object" || value === null) {
1844
+ throw new Error("N_Poll_Data.con must be an object with specific properties.");
1845
+ }
1846
+ this.pollingGroup = value.pollingGroup;
1847
+ this.nrOfSlots = value.nrOfSlots;
1848
+ this.pollData = value.pollData;
1849
+ }
1850
+ set pollingGroup(value) {
1851
+ const convertToAddress = KNXHelper_1.KNXHelper.GetAddress_(value);
1852
+ this.#pollingGroup = convertToAddress;
1853
+ }
1854
+ get pollingGroup() {
1855
+ return KNXHelper_1.KNXHelper.GetAddress(this.#pollingGroup, "/", true); // Se supone que es un dirección de grupo;
1856
+ }
1857
+ set nrOfSlots(value) {
1858
+ if (value < 0 || value > 7)
1859
+ throw new Error("The nrOfSlots value must be 4 bits (0-7)");
1860
+ this.#nrOfSlots = value;
1861
+ }
1862
+ get nrOfSlots() {
1863
+ return this.#nrOfSlots;
1864
+ }
1865
+ /**
1866
+ * Converts the N_Poll_Data.con message to a Buffer.
1867
+ * Format: Message Code (1) + Control (1) + Polling Group (2) + NrOfSlots/Reserved (1) + PollData (variable)
1868
+ * Total Length: 1 + 1 + 2 + 1 + APDU.length + 1 = 8 + APDU.length
1869
+ * @returns The Buffer representation of the message.
1870
+ */
1871
+ toBuffer() {
1872
+ const buffer = Buffer.alloc(7 + this.pollData.length);
1873
+ buffer.writeUInt8(this.messageCode, 0); // Octet 1
1874
+ buffer.writeUInt8(this.control, 1); // Octet 2
1875
+ // Rellenar Octetos 3-4 (Source) con ceros explícitos si es necesario
1876
+ buffer.writeUInt16BE(0x0000, 2);
1877
+ this.#pollingGroup.copy(buffer, 4); // Octets 5-6
1878
+ const octet7 = this.#nrOfSlots & 0x0f;
1879
+ buffer.writeUInt8(octet7, 6); // Octet 7
1880
+ this.pollData.copy(buffer, 7); // Octet 8...
1881
+ return buffer;
1882
+ }
1883
+ /**
1884
+ * Provides a human-readable description of the N_Poll_Data.con message.
1885
+ * @returns A record of message properties and their string values.
1886
+ */
1887
+ describe() {
1888
+ return {
1889
+ messageCode: `Codigo de mensaje: ${this.messageCode}`,
1890
+ control: `Control: ${this.control.toString(16).padStart(2, "0")}`,
1891
+ pollingGroup: `Grupo de sondeo: ${this.#pollingGroup}`,
1892
+ nrOfSlots: `Número de ranuras: ${this.#nrOfSlots}`,
1893
+ pollData: `pollData: ${this.pollData.toString("hex")}`,
1894
+ pollData_Length: `${this.pollData.length} octets`,
1895
+ rawValue: `Valor numérico: ${this.toBuffer().toString("hex")}`,
1896
+ };
1897
+ }
1898
+ /**
1899
+ * Creates an instance of NPollDataCon from a Buffer.
1900
+ * Expected Structure:
1901
+ * [0]: Message Code
1902
+ * [1]: Control Field (Fixed 0xF0 usually)
1903
+ * [2-3]: Unused / Source Address (Ignored in Con)
1904
+ * [4-5]: Polling Group Address
1905
+ * [6]: NrOfSlots (lower 4 bits)
1906
+ * [7...]: Poll Data
1907
+ */
1908
+ static fromBuffer(buffer) {
1909
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["N_Poll_Data.con"]["EMI2/IMI2"].value;
1910
+ const actualCode = buffer.readUInt8(0);
1911
+ if (actualCode !== expectedCode) {
1912
+ throw new Error(`Invalid message code for N_Poll_Data.con. Expected 0x${expectedCode.toString(16)}, got 0x${actualCode.toString(16)}`);
1913
+ }
1914
+ if (buffer.length < 7) {
1915
+ throw new Error("Buffer too short for N_Poll_Data.con");
1916
+ }
1917
+ // Octet 1: Control (Se ignora o valida según necesidad, el constructor lo fija a 0xF0)
1918
+ // Octet 2-3: Source Address (Se ignora en esta implementación de Con)
1919
+ // Octet 4-5: Polling Group
1920
+ // Asumimos que es una dirección de grupo, usamos separador "/"
1921
+ const pollingGroupStr = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
1922
+ if (!pollingGroupStr)
1923
+ throw new Error("The pollingGroupStr is undefined or null, this fatal error is from GetAddress, dont be ignore it");
1924
+ if (typeof pollingGroupStr !== "string")
1925
+ throw new Error("The pollingGroupStr is not string, this fatal error is from GetAddress, dont be ignore it");
1926
+ // Octet 6: NrOfSlots (bits 0-3)
1927
+ // Nota: El usuario usa los bits bajos. En spec estándar a veces es Length.
1928
+ // Nos ceñimos a tu lógica de 'nrOfSlots & 0x0f'.
1929
+ const nrOfSlots = buffer.readUInt8(6) & 0x0f;
1930
+ // Octet 7...: Poll Data
1931
+ // Todo lo que resta del buffer es data
1932
+ const pollData = buffer.subarray(7);
1933
+ return new NPollDataCon({
1934
+ pollingGroup: pollingGroupStr,
1935
+ nrOfSlots: nrOfSlots, // Cast a 'bits4' o number según tu tipo
1936
+ pollData: pollData,
1937
+ });
1938
+ }
1939
+ },
1940
+ };
1941
+ static TransportLayerEMI = {
1942
+ "T_Connect.req": class TConnectReq {
1943
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Connect.req"]["EMI2/IMI2"].value;
1944
+ control = 0x00;
1945
+ destinationAddress;
1946
+ constructor(value) {
1947
+ if (typeof value !== "object" || value === null) {
1948
+ throw new InvalidInputObject(TConnectReq.name);
1949
+ }
1950
+ this.destinationAddress = value.destinationAddress;
1951
+ }
1952
+ toBuffer() {
1953
+ const buffer = Buffer.alloc(6);
1954
+ buffer.writeUInt8(this.messageCode, 0);
1955
+ buffer.writeUInt8(this.control, 1);
1956
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
1957
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
1958
+ return buffer;
1959
+ }
1960
+ describe() {
1961
+ return {
1962
+ messageCode: this.messageCode,
1963
+ control: this.control,
1964
+ destinationAddress: this.destinationAddress,
1965
+ };
1966
+ }
1967
+ static fromBuffer(buffer) {
1968
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Connect.req"]["EMI2/IMI2"].value;
1969
+ if (buffer.readUInt8(0) !== expectedCode)
1970
+ throw new Error("Invalid Message Code");
1971
+ // T_Connect.req es de 6 bytes: MC | Ctrl | Unused(2) | Dest(2)
1972
+ if (buffer.length < 6)
1973
+ throw new Error("Buffer too short for T_Connect.req");
1974
+ // Destination está en bytes 4-5
1975
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
1976
+ if (!destinationAddress)
1977
+ throw new Error("The destinationAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
1978
+ if (typeof destinationAddress !== "string")
1979
+ throw new Error("The destinationAddress is not string, this fatal error is from GetAddress, dont be ignore it");
1980
+ return new TConnectReq({
1981
+ destinationAddress: destinationAddress,
1982
+ });
1983
+ }
1984
+ },
1985
+ "T_Connect.con": class TConnectCon {
1986
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Connect.con"]["EMI2/IMI2"].value;
1987
+ control = 0x00;
1988
+ destinationAddress;
1989
+ constructor(value) {
1990
+ if (typeof value !== "object" || value === null) {
1991
+ throw new InvalidInputObject(TConnectCon.name);
1992
+ }
1993
+ this.destinationAddress = value.destinationAddress;
1994
+ }
1995
+ toBuffer() {
1996
+ const buffer = Buffer.alloc(6);
1997
+ buffer.writeUInt8(this.messageCode, 0);
1998
+ buffer.writeUInt8(this.control, 1);
1999
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 2);
2000
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
2001
+ return buffer;
2002
+ }
2003
+ describe() {
2004
+ return {
2005
+ messageCode: this.messageCode,
2006
+ control: this.control,
2007
+ destinationAddress: this.destinationAddress,
2008
+ };
2009
+ }
2010
+ static fromBuffer(buffer) {
2011
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Connect.con"]["EMI2/IMI2"].value;
2012
+ if (buffer.readUInt8(0) !== expectedCode)
2013
+ throw new Error("Invalid Message Code");
2014
+ if (buffer.length < 6)
2015
+ throw new Error("Buffer too short for T_Connect.con");
2016
+ // Según tu toBuffer, escribes la dirección en el offset 2 (posición Source)
2017
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2018
+ if (!destinationAddress)
2019
+ throw new Error("The destinationAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2020
+ if (typeof destinationAddress !== "string")
2021
+ throw new Error("The destinationAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2022
+ return new TConnectCon({
2023
+ destinationAddress: destinationAddress,
2024
+ });
2025
+ }
2026
+ },
2027
+ "T_Connect.ind": class TConnectInd {
2028
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Connect.ind"]["EMI2/IMI2"].value;
2029
+ control = new ControlField_1.ControlField();
2030
+ sourceAddress;
2031
+ constructor(value) {
2032
+ if (typeof value !== "object" || value === null) {
2033
+ throw new InvalidInputObject(TConnectInd.name);
2034
+ }
2035
+ this.sourceAddress = value.sourceAddress;
2036
+ this.control.ackRequest = value.control.ackRequest;
2037
+ this.control.frameType = value.control.frameType;
2038
+ this.control.repeat = value.control.repeat;
2039
+ this.control.systemBroadcast = value.control.systemBroadcast;
2040
+ this.control.priority = value.control.priority;
2041
+ }
2042
+ toBuffer() {
2043
+ const buffer = Buffer.alloc(6);
2044
+ buffer.writeUInt8(this.messageCode, 0);
2045
+ this.control.buffer.copy(buffer, 1);
2046
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
2047
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
2048
+ return buffer;
2049
+ }
2050
+ describe() {
2051
+ return {
2052
+ messageCode: this.messageCode,
2053
+ control: this.control,
2054
+ sourceAddress: this.sourceAddress,
2055
+ };
2056
+ }
2057
+ static fromBuffer(buffer) {
2058
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Connect.ind"]["EMI2/IMI2"].value;
2059
+ if (buffer.readUInt8(0) !== expectedCode)
2060
+ throw new Error("Invalid Message Code");
2061
+ if (buffer.length < 6)
2062
+ throw new Error("Buffer too short");
2063
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2064
+ // Source Address en bytes 2-3
2065
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2066
+ if (!sourceAddress)
2067
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2068
+ if (typeof sourceAddress !== "string")
2069
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2070
+ return new TConnectInd({
2071
+ control: {
2072
+ ackRequest: control.ackRequest,
2073
+ frameType: control.frameType,
2074
+ repeat: control.repeat,
2075
+ systemBroadcast: control.systemBroadcast,
2076
+ priority: control.priority,
2077
+ confirm: control.confirm,
2078
+ },
2079
+ sourceAddress: sourceAddress,
2080
+ });
2081
+ }
2082
+ },
2083
+ "T_Disconnect.req": class TDisconnectReq {
2084
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Disconnect.req"]["EMI2/IMI2"].value;
2085
+ control = 0x00;
2086
+ constructor(value) {
2087
+ if (typeof value !== "object" || value === null) {
2088
+ throw new InvalidInputObject(TDisconnectReq.name);
2089
+ }
2090
+ }
2091
+ toBuffer() {
2092
+ const buffer = Buffer.alloc(6);
2093
+ buffer.writeUInt8(this.messageCode, 0);
2094
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
2095
+ return buffer;
2096
+ }
2097
+ describe() {
2098
+ return {
2099
+ messageCode: this.messageCode,
2100
+ };
2101
+ }
2102
+ static fromBuffer(buffer) {
2103
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Disconnect.req"]["EMI2/IMI2"].value;
2104
+ if (buffer.readUInt8(0) !== expectedCode)
2105
+ throw new Error("Invalid Code");
2106
+ if (buffer.length < 6)
2107
+ throw new Error("Buffer too short");
2108
+ // No hay datos adicionales en req
2109
+ return new TDisconnectReq({});
2110
+ }
2111
+ },
2112
+ "T_Disconnect.con": class TDisconnectCon {
2113
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Disconnect.con"]["EMI2/IMI2"].value;
2114
+ control = new ControlField_1.ControlField();
2115
+ constructor(value) {
2116
+ if (typeof value !== "object" || value === null) {
2117
+ throw new InvalidInputObject(TDisconnectCon.name);
2118
+ }
2119
+ this.control.ackRequest = value.control.ackRequest;
2120
+ this.control.frameType = value.control.frameType;
2121
+ this.control.repeat = value.control.repeat;
2122
+ this.control.systemBroadcast = value.control.systemBroadcast;
2123
+ this.control.priority = value.control.priority;
2124
+ }
2125
+ toBuffer() {
2126
+ const buffer = Buffer.alloc(6);
2127
+ buffer.writeUInt8(this.messageCode, 0);
2128
+ this.control.buffer.copy(buffer, 1);
2129
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
2130
+ return buffer;
2131
+ }
2132
+ describe() {
2133
+ return {
2134
+ messageCode: this.messageCode,
2135
+ control: this.control,
2136
+ };
2137
+ }
2138
+ static fromBuffer(buffer) {
2139
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Disconnect.con"]["EMI2/IMI2"].value;
2140
+ if (buffer.readUInt8(0) !== expectedCode)
2141
+ throw new Error("Invalid Code");
2142
+ if (buffer.length < 6)
2143
+ throw new Error("Buffer too short");
2144
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2145
+ return new TDisconnectCon({
2146
+ control: {
2147
+ ackRequest: control.ackRequest,
2148
+ frameType: control.frameType,
2149
+ repeat: control.repeat,
2150
+ systemBroadcast: control.systemBroadcast,
2151
+ priority: control.priority,
2152
+ confirm: control.confirm,
2153
+ },
2154
+ });
2155
+ }
2156
+ },
2157
+ "T_Disconnect.ind": class TDisconnectInd {
2158
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Disconnect.ind"]["EMI2/IMI2"].value;
2159
+ control = new ControlField_1.ControlField();
2160
+ constructor(value) {
2161
+ if (typeof value !== "object" || value === null) {
2162
+ throw new InvalidInputObject(TDisconnectInd.name);
2163
+ }
2164
+ this.control.ackRequest = value.control.ackRequest;
2165
+ this.control.frameType = value.control.frameType;
2166
+ this.control.repeat = value.control.repeat;
2167
+ this.control.systemBroadcast = value.control.systemBroadcast;
2168
+ this.control.priority = value.control.priority;
2169
+ }
2170
+ toBuffer() {
2171
+ const buffer = Buffer.alloc(6);
2172
+ buffer.writeUInt8(this.messageCode, 0);
2173
+ this.control.buffer.copy(buffer, 1);
2174
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
2175
+ return buffer;
2176
+ }
2177
+ describe() {
2178
+ return {
2179
+ messageCode: this.messageCode,
2180
+ control: this.control,
2181
+ };
2182
+ }
2183
+ static fromBuffer(buffer) {
2184
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Disconnect.ind"]["EMI2/IMI2"].value;
2185
+ if (buffer.readUInt8(0) !== expectedCode)
2186
+ throw new Error("Invalid Code");
2187
+ if (buffer.length < 6)
2188
+ throw new Error("Buffer too short");
2189
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2190
+ return new TDisconnectInd({
2191
+ control: {
2192
+ ackRequest: control.ackRequest,
2193
+ frameType: control.frameType,
2194
+ repeat: control.repeat,
2195
+ systemBroadcast: control.systemBroadcast,
2196
+ priority: control.priority,
2197
+ confirm: control.confirm,
2198
+ },
2199
+ });
2200
+ }
2201
+ },
2202
+ "T_Data_Connected.req": class TDataConnectedReq {
2203
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Connected.req"]["EMI2/IMI2"].value;
2204
+ control = new ControlField_1.ControlField();
2205
+ APDU;
2206
+ hopCount;
2207
+ constructor(value) {
2208
+ if (typeof value !== "object" || value === null) {
2209
+ throw new InvalidInputObject(TDataConnectedReq.name);
2210
+ }
2211
+ this.control.priority = value.control.priority;
2212
+ this.APDU = value.APDU;
2213
+ this.hopCount = value.hopCount;
2214
+ }
2215
+ toBuffer() {
2216
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2217
+ buffer.writeUInt8(this.messageCode, 0);
2218
+ this.control.buffer.copy(buffer, 1);
2219
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (buffer.length & 0x0f);
2220
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2221
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1); // Calculate FCS
2222
+ return buffer;
2223
+ }
2224
+ describe() {
2225
+ return {
2226
+ messageCode: this.messageCode,
2227
+ control: this.control,
2228
+ hopCount: this.hopCount,
2229
+ };
2230
+ }
2231
+ static fromBuffer(buffer) {
2232
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Connected.req"]["EMI2/IMI2"].value;
2233
+ if (buffer.readUInt8(0) !== expectedCode)
2234
+ throw new Error("Invalid Code");
2235
+ // Requiere al menos 7 bytes (Header 6 + Len 1) + Data
2236
+ if (buffer.length < 7)
2237
+ throw new Error("Buffer too short");
2238
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2239
+ const octet6 = buffer.readUInt8(6);
2240
+ const hopCount = (octet6 >> 4) & 0x07;
2241
+ const length = octet6 & 0x0f;
2242
+ // Validar integridad
2243
+ if (buffer.length < 7 + length)
2244
+ throw new Error("Buffer data incomplete");
2245
+ const apdu = buffer.subarray(7, 7 + length);
2246
+ return new TDataConnectedReq({
2247
+ control: { priority: control.priority },
2248
+ hopCount: hopCount,
2249
+ APDU: apdu,
2250
+ });
2251
+ }
2252
+ },
2253
+ "T_Data_Connected.con": class TDataConnectedCon {
2254
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Connected.con"]["EMI2/IMI2"].value;
2255
+ control = new ControlField_1.ControlField();
2256
+ APDU;
2257
+ constructor(value) {
2258
+ if (typeof value !== "object" || value === null) {
2259
+ throw new InvalidInputObject(TDataConnectedCon.name);
2260
+ }
2261
+ this.control.confirm = value.control.confirm;
2262
+ this.APDU = value.APDU;
2263
+ }
2264
+ toBuffer() {
2265
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2266
+ buffer.writeUInt8(this.messageCode, 0);
2267
+ this.control.buffer.copy(buffer, 1);
2268
+ // Octetos 3-5 no utilizados
2269
+ buffer[6] |= this.APDU.length & 0x0f;
2270
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2271
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2272
+ return buffer;
2273
+ }
2274
+ describe() {
2275
+ return {
2276
+ messageCode: this.messageCode,
2277
+ control: this.control.describe(),
2278
+ APDU: this.APDU.toString("hex"),
2279
+ };
2280
+ }
2281
+ static fromBuffer(buffer) {
2282
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Connected.con"]["EMI2/IMI2"].value;
2283
+ if (buffer.readUInt8(0) !== expectedCode)
2284
+ throw new Error("Invalid Code");
2285
+ if (buffer.length < 7)
2286
+ throw new Error("Buffer too short");
2287
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2288
+ const length = buffer.readUInt8(6) & 0x0f;
2289
+ const apdu = buffer.subarray(7, 7 + length);
2290
+ return new TDataConnectedCon({
2291
+ control: { confirm: control.confirm },
2292
+ APDU: apdu,
2293
+ });
2294
+ }
2295
+ },
2296
+ "T_Data_Connected.ind": class TDataConnectedInd {
2297
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Connected.ind"]["EMI2/IMI2"].value;
2298
+ control = new ControlField_1.ControlField();
2299
+ sourceAddress;
2300
+ APDU;
2301
+ hopCount;
2302
+ constructor(value) {
2303
+ if (typeof value !== "object" || value === null) {
2304
+ throw new InvalidInputObject(TDataConnectedInd.name);
2305
+ }
2306
+ this.control.priority = value.control.priority;
2307
+ this.sourceAddress = value.sourceAddress;
2308
+ this.APDU = value.APDU;
2309
+ this.hopCount = value.hopCount;
2310
+ }
2311
+ toBuffer() {
2312
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2313
+ buffer.writeUInt8(this.messageCode, 0);
2314
+ this.control.buffer.copy(buffer, 1);
2315
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
2316
+ // Octeto 5-6 no utilizados
2317
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f);
2318
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2319
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2320
+ return buffer;
2321
+ }
2322
+ describe() {
2323
+ return {
2324
+ messageCode: this.messageCode,
2325
+ control: this.control.describe(),
2326
+ sourceAddress: this.sourceAddress,
2327
+ APDU: this.APDU.toString("hex"),
2328
+ };
2329
+ }
2330
+ static fromBuffer(buffer) {
2331
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Connected.ind"]["EMI2/IMI2"].value;
2332
+ if (buffer.readUInt8(0) !== expectedCode)
2333
+ throw new Error("Invalid Code");
2334
+ if (buffer.length < 7)
2335
+ throw new Error("Buffer too short");
2336
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2337
+ // Tu toBuffer escribe Source en offset 2
2338
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2339
+ if (!sourceAddress)
2340
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2341
+ if (typeof sourceAddress !== "string")
2342
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2343
+ const octet6 = buffer.readUInt8(6);
2344
+ const hopCount = (octet6 >> 4) & 0x07;
2345
+ const length = octet6 & 0x0f;
2346
+ const apdu = buffer.subarray(7, 7 + length);
2347
+ return new TDataConnectedInd({
2348
+ control: { priority: control.priority },
2349
+ sourceAddress: sourceAddress,
2350
+ hopCount: hopCount,
2351
+ APDU: apdu,
2352
+ });
2353
+ }
2354
+ },
2355
+ "T_Data_Group.req": class TDataGroupReq {
2356
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Group.req"]["EMI2/IMI2"].value;
2357
+ control = new ControlField_1.ControlField();
2358
+ APDU;
2359
+ hopCount;
2360
+ constructor(value) {
2361
+ if (typeof value !== "object" || value === null) {
2362
+ throw new InvalidInputObject(TDataGroupReq.name);
2363
+ }
2364
+ this.control.priority = value.control.priority;
2365
+ this.APDU = value.APDU;
2366
+ this.hopCount = value.hopCount;
2367
+ }
2368
+ toBuffer() {
2369
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2370
+ buffer.writeUInt8(this.messageCode, 0);
2371
+ this.control.buffer.copy(buffer, 1);
2372
+ // Octetos 3-6 no utilizados
2373
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f);
2374
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2375
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2376
+ return buffer;
2377
+ }
2378
+ describe() {
2379
+ return {
2380
+ messageCode: this.messageCode,
2381
+ control: this.control.describe(),
2382
+ hopCount: this.hopCount,
2383
+ APDU: this.APDU.toString("hex"),
2384
+ };
2385
+ }
2386
+ static fromBuffer(buffer) {
2387
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Group.req"]["EMI2/IMI2"].value;
2388
+ if (buffer.readUInt8(0) !== expectedCode)
2389
+ throw new Error("Invalid Code");
2390
+ if (buffer.length < 7)
2391
+ throw new Error("Buffer too short");
2392
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2393
+ const octet6 = buffer.readUInt8(6);
2394
+ const hopCount = (octet6 >> 4) & 0x07;
2395
+ const length = octet6 & 0x0f;
2396
+ const apdu = buffer.subarray(7, 7 + length);
2397
+ return new TDataGroupReq({
2398
+ control: { priority: control.priority },
2399
+ hopCount: hopCount,
2400
+ APDU: apdu,
2401
+ });
2402
+ }
2403
+ },
2404
+ "T_Data_Group.con": class TDataGroupCon {
2405
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Group.con"]["EMI2/IMI2"].value;
2406
+ control = new ControlField_1.ControlField();
2407
+ data;
2408
+ constructor(value) {
2409
+ if (typeof value !== "object" || value === null) {
2410
+ throw new InvalidInputObject(TDataGroupCon.name);
2411
+ }
2412
+ this.control.confirm = value.control.confirm;
2413
+ this.data = value.data;
2414
+ }
2415
+ toBuffer() {
2416
+ const buffer = Buffer.alloc(8 + this.data.length); // Tamaño mínimo según documento
2417
+ buffer.writeUInt8(this.messageCode, 0);
2418
+ this.control.buffer.copy(buffer, 1);
2419
+ buffer[6] = this.data.length & 0x0f;
2420
+ buffer[7] = 0; // El buffer en la posicion 8 debe ser la otra parte del APCI con APDU
2421
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
2422
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2423
+ return buffer;
2424
+ }
2425
+ describe() {
2426
+ return {
2427
+ messageCode: this.messageCode,
2428
+ control: this.control.describe(),
2429
+ };
2430
+ }
2431
+ static fromBuffer(buffer) {
2432
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Group.con"]["EMI2/IMI2"].value;
2433
+ if (buffer.readUInt8(0) !== expectedCode)
2434
+ throw new Error("Invalid Code");
2435
+ if (buffer.length < 7)
2436
+ throw new Error("Buffer too short");
2437
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2438
+ const length = buffer.readUInt8(6) & 0x0f;
2439
+ const data = buffer.subarray(7, 7 + length);
2440
+ return new TDataGroupCon({
2441
+ control: { confirm: control.confirm },
2442
+ data: data,
2443
+ });
2444
+ }
2445
+ },
2446
+ "T_Data_Group.ind": class TDataGroupInd {
2447
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Group.ind"]["EMI2/IMI2"].value;
2448
+ control = new ControlField_1.ControlField();
2449
+ APDU;
2450
+ constructor(value) {
2451
+ if (typeof value !== "object" || value === null) {
2452
+ throw new InvalidInputObject(TDataGroupInd.name);
2453
+ }
2454
+ this.control.priority = value.control.priority;
2455
+ this.APDU = value.APDU;
2456
+ }
2457
+ toBuffer() {
2458
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2459
+ buffer.writeUInt8(this.messageCode, 0);
2460
+ this.control.buffer.copy(buffer, 1);
2461
+ // Octetos 3-6 no utilizados
2462
+ buffer[6] |= this.APDU.length & 0x0f;
2463
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2464
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2465
+ return buffer;
2466
+ }
2467
+ describe() {
2468
+ return {
2469
+ messageCode: this.messageCode,
2470
+ control: this.control.describe(),
2471
+ APDU: this.APDU.toString("hex"),
2472
+ };
2473
+ }
2474
+ static fromBuffer(buffer) {
2475
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Group.ind"]["EMI2/IMI2"].value;
2476
+ if (buffer.readUInt8(0) !== expectedCode)
2477
+ throw new Error("Invalid Code");
2478
+ if (buffer.length < 7)
2479
+ throw new Error("Buffer too short");
2480
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2481
+ const octet6 = buffer.readUInt8(6);
2482
+ const length = octet6 & 0x0f;
2483
+ const apdu = buffer.subarray(7, 7 + length);
2484
+ return new TDataGroupInd({
2485
+ control: { priority: control.priority },
2486
+ APDU: apdu,
2487
+ });
2488
+ }
2489
+ },
2490
+ "T_Data_Individual.req": class TDataIndividualReq {
2491
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Individual.req"]["EMI2/IMI2"].value;
2492
+ control = new ControlField_1.ControlField();
2493
+ destinationAddress;
2494
+ APDU;
2495
+ hopCount;
2496
+ constructor(value) {
2497
+ if (typeof value !== "object" || value === null) {
2498
+ throw new InvalidInputObject(TDataIndividualReq.name);
2499
+ }
2500
+ this.control.priority = value.control.priority;
2501
+ this.destinationAddress = value.destinationAddress;
2502
+ this.APDU = value.APDU;
2503
+ this.hopCount = value.hopCount;
2504
+ }
2505
+ toBuffer() {
2506
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2507
+ buffer.writeUInt8(this.messageCode, 0);
2508
+ this.control.buffer.copy(buffer, 1);
2509
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
2510
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f);
2511
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2512
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2513
+ return buffer;
2514
+ }
2515
+ describe() {
2516
+ return {
2517
+ messageCode: this.messageCode,
2518
+ control: this.control.describe(),
2519
+ destinationAddress: this.destinationAddress,
2520
+ hopCount: this.hopCount,
2521
+ APDU: this.APDU.toString("hex"),
2522
+ };
2523
+ }
2524
+ static fromBuffer(buffer) {
2525
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Individual.req"]["EMI2/IMI2"].value;
2526
+ if (buffer.readUInt8(0) !== expectedCode)
2527
+ throw new Error("Invalid Code");
2528
+ if (buffer.length < 7)
2529
+ throw new Error("Buffer too short");
2530
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2531
+ // Tu toBuffer usa offset 4 para Destino
2532
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
2533
+ if (!destinationAddress)
2534
+ throw new Error("The destinationAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2535
+ if (typeof destinationAddress !== "string")
2536
+ throw new Error("The destinationAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2537
+ const octet6 = buffer.readUInt8(6);
2538
+ const hopCount = (octet6 >> 4) & 0x07;
2539
+ const length = octet6 & 0x0f;
2540
+ const apdu = buffer.subarray(7, 7 + length);
2541
+ return new TDataIndividualReq({
2542
+ control: { priority: control.priority },
2543
+ destinationAddress: destinationAddress,
2544
+ hopCount: hopCount,
2545
+ APDU: apdu,
2546
+ });
2547
+ }
2548
+ },
2549
+ "T_Data_Individual.con": class TDataIndividualCon {
2550
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Individual.con"]["EMI2/IMI2"].value;
2551
+ control = new ControlField_1.ControlField();
2552
+ destinationAddress;
2553
+ APDU;
2554
+ constructor(value) {
2555
+ if (typeof value !== "object" || value === null) {
2556
+ throw new InvalidInputObject(TDataIndividualCon.name);
2557
+ }
2558
+ this.control.confirm = value.control.confirm;
2559
+ this.destinationAddress = value.destinationAddress;
2560
+ this.APDU = value.APDU;
2561
+ }
2562
+ toBuffer() {
2563
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2564
+ buffer.writeUInt8(this.messageCode, 0);
2565
+ this.control.buffer.copy(buffer, 1);
2566
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
2567
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2568
+ buffer[6] = this.APDU.length & 0x0f;
2569
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2570
+ return buffer;
2571
+ }
2572
+ describe() {
2573
+ return {
2574
+ messageCode: this.messageCode,
2575
+ control: this.control.describe(),
2576
+ destinationAddress: this.destinationAddress,
2577
+ };
2578
+ }
2579
+ static fromBuffer(buffer) {
2580
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Individual.con"]["EMI2/IMI2"].value;
2581
+ if (buffer.readUInt8(0) !== expectedCode)
2582
+ throw new Error("Invalid Code");
2583
+ if (buffer.length < 7)
2584
+ throw new Error("Buffer too short");
2585
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2586
+ // Tu toBuffer usa offset 4 para Destino en .con
2587
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
2588
+ if (!destinationAddress)
2589
+ throw new Error("The destinationAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2590
+ if (typeof destinationAddress !== "string")
2591
+ throw new Error("The destinationAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2592
+ const length = buffer.readUInt8(6) & 0x0f;
2593
+ const apdu = buffer.subarray(7, 7 + length);
2594
+ return new TDataIndividualCon({
2595
+ control: { confirm: control.confirm },
2596
+ destinationAddress: destinationAddress,
2597
+ APDU: apdu,
2598
+ });
2599
+ }
2600
+ },
2601
+ "T_Data_Individual.ind": class TDataIndividualInd {
2602
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Individual.ind"]["EMI2/IMI2"].value;
2603
+ control = new ControlField_1.ControlField();
2604
+ sourceAddress;
2605
+ destinationAddress;
2606
+ APDU;
2607
+ hopCount;
2608
+ constructor(value) {
2609
+ if (typeof value !== "object" || value === null) {
2610
+ throw new InvalidInputObject(TDataIndividualInd.name);
2611
+ }
2612
+ this.control.priority = value.control.priority;
2613
+ this.sourceAddress = value.sourceAddress;
2614
+ this.destinationAddress = value.destinationAddress;
2615
+ this.APDU = value.APDU;
2616
+ this.hopCount = value.hopCount;
2617
+ }
2618
+ toBuffer() {
2619
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2620
+ buffer.writeUInt8(this.messageCode, 0);
2621
+ this.control.buffer.copy(buffer, 1);
2622
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
2623
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
2624
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f);
2625
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2626
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2627
+ return buffer;
2628
+ }
2629
+ describe() {
2630
+ return {
2631
+ messageCode: this.messageCode,
2632
+ control: this.control.describe(),
2633
+ sourceAddress: this.sourceAddress,
2634
+ destinationAddress: this.destinationAddress,
2635
+ APDU: this.APDU.toString("hex"),
2636
+ };
2637
+ }
2638
+ static fromBuffer(buffer) {
2639
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Individual.ind"]["EMI2/IMI2"].value;
2640
+ if (buffer.readUInt8(0) !== expectedCode)
2641
+ throw new Error("Invalid Code");
2642
+ if (buffer.length < 7)
2643
+ throw new Error("Buffer too short");
2644
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2645
+ // Ind: Source en 2, Dest en 4
2646
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2647
+ const destinationAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
2648
+ if (!destinationAddress)
2649
+ throw new Error("The destinationAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2650
+ if (typeof destinationAddress !== "string")
2651
+ throw new Error("The destinationAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2652
+ if (!sourceAddress)
2653
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2654
+ if (typeof sourceAddress !== "string")
2655
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2656
+ const octet6 = buffer.readUInt8(6);
2657
+ const hopCount = (octet6 >> 4) & 0x07;
2658
+ const length = octet6 & 0x0f;
2659
+ const apdu = buffer.subarray(7, 7 + length);
2660
+ return new TDataIndividualInd({
2661
+ control: { priority: control.priority },
2662
+ sourceAddress: sourceAddress,
2663
+ destinationAddress: destinationAddress,
2664
+ hopCount: hopCount,
2665
+ APDU: apdu,
2666
+ });
2667
+ }
2668
+ },
2669
+ "T_Data_Broadcast.req": class TDataBroadcastReq {
2670
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Broadcast.req"]["EMI2/IMI2"].value;
2671
+ control = new ControlField_1.ControlField();
2672
+ APDU;
2673
+ hopCount;
2674
+ constructor(value) {
2675
+ if (typeof value !== "object" || value === null) {
2676
+ throw new InvalidInputObject(TDataBroadcastReq.name);
2677
+ }
2678
+ this.control.priority = value.control.priority;
2679
+ this.APDU = value.APDU;
2680
+ this.hopCount = value.hopCount;
2681
+ }
2682
+ toBuffer() {
2683
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2684
+ buffer.writeUInt8(this.messageCode, 0);
2685
+ this.control.buffer.copy(buffer, 1);
2686
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f); // podría no ser usado
2687
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2688
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2689
+ return buffer;
2690
+ }
2691
+ describe() {
2692
+ return {
2693
+ messageCode: this.messageCode,
2694
+ control: this.control.describe(),
2695
+ hopCount: this.hopCount,
2696
+ APDU: this.APDU.toString("hex"),
2697
+ };
2698
+ }
2699
+ static fromBuffer(buffer) {
2700
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Broadcast.req"]["EMI2/IMI2"].value;
2701
+ if (buffer.readUInt8(0) !== expectedCode)
2702
+ throw new Error("Invalid Code");
2703
+ if (buffer.length < 7)
2704
+ throw new Error("Buffer too short");
2705
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2706
+ const octet6 = buffer.readUInt8(6);
2707
+ const hopCount = (octet6 >> 4) & 0x07;
2708
+ const length = octet6 & 0x0f;
2709
+ const apdu = buffer.subarray(7, 7 + length);
2710
+ return new TDataBroadcastReq({
2711
+ control: { priority: control.priority },
2712
+ hopCount: hopCount,
2713
+ APDU: apdu,
2714
+ });
2715
+ }
2716
+ },
2717
+ "T_Data_Broadcast.con": class TDataBroadcastCon {
2718
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Broadcast.con"]["EMI2/IMI2"].value;
2719
+ control = new ControlField_1.ControlField();
2720
+ APDU;
2721
+ constructor(value) {
2722
+ if (typeof value !== "object" || value === null) {
2723
+ throw new InvalidInputObject(TDataBroadcastCon.name);
2724
+ }
2725
+ this.control.confirm = value.control.confirm;
2726
+ this.APDU = value.APDU;
2727
+ }
2728
+ toBuffer() {
2729
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2730
+ buffer.writeUInt8(this.messageCode, 0);
2731
+ this.control.buffer.copy(buffer, 1);
2732
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2733
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2734
+ return buffer;
2735
+ }
2736
+ describe() {
2737
+ return {
2738
+ messageCode: this.messageCode,
2739
+ control: this.control.describe(),
2740
+ };
2741
+ }
2742
+ static fromBuffer(buffer) {
2743
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Broadcast.con"]["EMI2/IMI2"].value;
2744
+ if (buffer.readUInt8(0) !== expectedCode)
2745
+ throw new Error("Invalid Code");
2746
+ if (buffer.length < 7)
2747
+ throw new Error("Buffer too short");
2748
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2749
+ const length = buffer.readUInt8(6) & 0x0f;
2750
+ const apdu = buffer.subarray(7, 7 + length);
2751
+ return new TDataBroadcastCon({
2752
+ control: { confirm: control.confirm },
2753
+ APDU: apdu,
2754
+ });
2755
+ }
2756
+ },
2757
+ "T_Data_Broadcast.ind": class TDataBroadcastInd {
2758
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Broadcast.ind"]["EMI2/IMI2"].value;
2759
+ control = new ControlField_1.ControlField();
2760
+ sourceAddress;
2761
+ APDU;
2762
+ hopCount;
2763
+ constructor(value) {
2764
+ if (typeof value !== "object" || value === null) {
2765
+ throw new InvalidInputObject(TDataBroadcastInd.name);
2766
+ }
2767
+ this.control.priority = value.control.priority;
2768
+ this.sourceAddress = value.sourceAddress;
2769
+ this.APDU = value.APDU;
2770
+ this.hopCount = value.hopCount;
2771
+ }
2772
+ toBuffer() {
2773
+ const buffer = Buffer.alloc(8 + this.APDU.length);
2774
+ buffer.writeUInt8(this.messageCode, 0);
2775
+ this.control.buffer.copy(buffer, 1);
2776
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
2777
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f);
2778
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
2779
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2780
+ return buffer;
2781
+ }
2782
+ describe() {
2783
+ return {
2784
+ messageCode: this.messageCode,
2785
+ control: this.control.describe(),
2786
+ sourceAddress: this.sourceAddress,
2787
+ APDU: this.APDU.toString("hex"),
2788
+ };
2789
+ }
2790
+ static fromBuffer(buffer) {
2791
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Data_Broadcast.ind"]["EMI2/IMI2"].value;
2792
+ if (buffer.readUInt8(0) !== expectedCode)
2793
+ throw new Error("Invalid Code");
2794
+ if (buffer.length < 7)
2795
+ throw new Error("Buffer too short");
2796
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2797
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2798
+ if (!sourceAddress)
2799
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2800
+ if (typeof sourceAddress !== "string")
2801
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2802
+ const octet6 = buffer.readUInt8(6);
2803
+ const hopCount = (octet6 >> 4) & 0x07;
2804
+ const length = octet6 & 0x0f;
2805
+ const apdu = buffer.subarray(7, 7 + length);
2806
+ return new TDataBroadcastInd({
2807
+ control: { priority: control.priority },
2808
+ sourceAddress: sourceAddress,
2809
+ hopCount: hopCount,
2810
+ APDU: apdu,
2811
+ });
2812
+ }
2813
+ },
2814
+ "T_Poll_Data.req": class TPollDataReq {
2815
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Poll_Data.req"]["EMI2/IMI2"].value;
2816
+ control = new ControlField_1.ControlField(0xf0);
2817
+ pollingGroup;
2818
+ numberOfSlots;
2819
+ constructor(value) {
2820
+ if (typeof value !== "object" || value === null) {
2821
+ throw new InvalidInputObject(TPollDataReq.name);
2822
+ }
2823
+ this.pollingGroup = value.pollingGroup;
2824
+ this.numberOfSlots = value.numberOfSlots;
2825
+ }
2826
+ toBuffer() {
2827
+ const buffer = Buffer.alloc(7);
2828
+ buffer.writeUInt8(this.messageCode, 0);
2829
+ this.control.buffer.copy(buffer, 1);
2830
+ KNXHelper_1.KNXHelper.GetAddress_(this.pollingGroup).copy(buffer, 4);
2831
+ buffer[6] = this.numberOfSlots & 0x0f;
2832
+ // No hay checksum en este mensaje según el documento
2833
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2834
+ return buffer;
2835
+ }
2836
+ describe() {
2837
+ return {
2838
+ messageCode: this.messageCode,
2839
+ control: this.control.describe(),
2840
+ pollingGroup: this.pollingGroup,
2841
+ numberOfSlots: this.numberOfSlots,
2842
+ };
2843
+ }
2844
+ static fromBuffer(buffer) {
2845
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Poll_Data.req"]["EMI2/IMI2"].value;
2846
+ if (buffer.readUInt8(0) !== expectedCode)
2847
+ throw new Error("Invalid Code");
2848
+ if (buffer.length < 7)
2849
+ throw new Error("Buffer too short");
2850
+ // Estructura: MC(0) | Ctrl(1) | Unused(2-3) | PollGroup(4-5) | Slots(6)
2851
+ // Usamos separador "/" para grupos
2852
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2853
+ const pollingGroup = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
2854
+ if (!pollingGroup)
2855
+ throw new Error("The pollingGroup is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2856
+ if (typeof pollingGroup !== "string")
2857
+ throw new Error("The pollingGroup is not string, this fatal error is from GetAddress, dont be ignore it");
2858
+ const slots = buffer.readUInt8(6) & 0x0f;
2859
+ return new TPollDataReq({
2860
+ control,
2861
+ pollingGroup: pollingGroup,
2862
+ numberOfSlots: slots,
2863
+ });
2864
+ }
2865
+ },
2866
+ "T_Poll_Data.con": class TPollDataCon {
2867
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Poll_Data.con"]["EMI2/IMI2"].value;
2868
+ control = new ControlField_1.ControlField(0xf0);
2869
+ sourceAddress;
2870
+ pollingGroup;
2871
+ pollData;
2872
+ nrOfSlots;
2873
+ constructor(value) {
2874
+ if (typeof value !== "object" || value === null) {
2875
+ throw new InvalidInputObject(TPollDataCon.name);
2876
+ }
2877
+ this.sourceAddress = value.sourceAddress;
2878
+ this.pollingGroup = value.pollingGroup;
2879
+ this.pollData = value.pollData;
2880
+ this.nrOfSlots = value.nrOfSlots;
2881
+ }
2882
+ toBuffer() {
2883
+ const buffer = Buffer.alloc(7 + this.pollData.length);
2884
+ buffer.writeUInt8(this.messageCode, 0);
2885
+ this.control.buffer.copy(buffer, 1);
2886
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
2887
+ KNXHelper_1.KNXHelper.GetAddress_(this.pollingGroup).copy(buffer, 4);
2888
+ buffer[6] = this.nrOfSlots & 0x0f;
2889
+ this.pollData.copy(buffer, 7);
2890
+ // No hay checksum en este mensaje según el documento
2891
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2892
+ return buffer;
2893
+ }
2894
+ describe() {
2895
+ return {
2896
+ messageCode: this.messageCode,
2897
+ control: this.control.describe(),
2898
+ sourceAddress: this.sourceAddress,
2899
+ pollingGroup: this.pollingGroup,
2900
+ pollData: this.pollData.toString("hex"),
2901
+ };
2902
+ }
2903
+ static fromBuffer(buffer) {
2904
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["T_Poll_Data.con"]["EMI2/IMI2"].value;
2905
+ if (buffer.readUInt8(0) !== expectedCode)
2906
+ throw new Error("Invalid Code");
2907
+ if (buffer.length < 7)
2908
+ throw new Error("Buffer too short");
2909
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
2910
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2911
+ const pollingGroup = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
2912
+ if (!sourceAddress)
2913
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2914
+ if (typeof sourceAddress !== "string")
2915
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2916
+ if (!pollingGroup)
2917
+ throw new Error("The pollingGroup is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2918
+ if (typeof pollingGroup !== "string")
2919
+ throw new Error("The pollingGroup is not string, this fatal error is from GetAddress, dont be ignore it");
2920
+ const slots = buffer.readUInt8(6) & 0x0f;
2921
+ const data = buffer.subarray(7);
2922
+ return new TPollDataCon({
2923
+ control,
2924
+ sourceAddress: sourceAddress,
2925
+ pollingGroup: pollingGroup,
2926
+ nrOfSlots: slots,
2927
+ pollData: data,
2928
+ });
2929
+ }
2930
+ },
2931
+ };
2932
+ /**
2933
+ * The full Application Layer EMI consists of the group-oriented Application Layer and the management parts.
2934
+ * The group-oriented Application Layer part consists of exactly the A_Data_Group.req,
2935
+ * A_Data_Group.ind, A_Data_Group.con, A_Poll_Data.req and A_Poll_Data.con services.
2936
+ * The management part consists of exactly the M_Connect.ind, M_Disconnect.ind,
2937
+ * M_User_Data_Connected.req, M_User_Data_Connected.ind, M_User_Data_Connected.con,
2938
+ * M_User_Data_Individual.req, M_User_Data_Individual.ind and M_User_Data_Individual.con services.
2939
+ */
2940
+ static ApplicationLayerEMI = {
2941
+ "M_Connect.ind": class MConnectInd {
2942
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_Connect.ind"]["EMI2/IMI2"].value;
2943
+ sourceAddress;
2944
+ constructor(value) {
2945
+ if (typeof value !== "object" || value === null) {
2946
+ throw new InvalidInputObject(MConnectInd.name);
2947
+ }
2948
+ this.sourceAddress = value.sourceAddress;
2949
+ }
2950
+ toBuffer() {
2951
+ const buffer = Buffer.alloc(6);
2952
+ buffer.writeUInt8(this.messageCode, 0);
2953
+ // Octeto 2 no utilizado
2954
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
2955
+ // Octetos 5-6 no utilizados o 0x00
2956
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2957
+ return buffer;
2958
+ }
2959
+ describe() {
2960
+ return {
2961
+ messageCode: this.messageCode,
2962
+ sourceAddress: this.sourceAddress,
2963
+ };
2964
+ }
2965
+ static fromBuffer(buffer) {
2966
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_Connect.ind"]["EMI2/IMI2"].value;
2967
+ if (buffer.readUInt8(0) !== expectedCode)
2968
+ throw new Error("Invalid Message Code");
2969
+ if (buffer.length < 6)
2970
+ throw new Error("Buffer too short");
2971
+ // Según tu toBuffer, Source está en offset 2
2972
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
2973
+ if (!sourceAddress)
2974
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
2975
+ if (typeof sourceAddress !== "string")
2976
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
2977
+ return new MConnectInd({
2978
+ sourceAddress: sourceAddress,
2979
+ });
2980
+ }
2981
+ },
2982
+ "M_Disconnect.ind": class MDisconnectInd {
2983
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_Disconnect.ind"]["EMI2/IMI2"].value;
2984
+ constructor() {
2985
+ // No tiene parámetros
2986
+ }
2987
+ toBuffer() {
2988
+ const buffer = Buffer.alloc(6);
2989
+ buffer.writeUInt8(this.messageCode, 0);
2990
+ // Octetos 2-6 no utilizados o 0x00
2991
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
2992
+ return buffer;
2993
+ }
2994
+ describe() {
2995
+ return {
2996
+ messageCode: this.messageCode,
2997
+ };
2998
+ }
2999
+ static fromBuffer(buffer) {
3000
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_Disconnect.ind"]["EMI2/IMI2"].value;
3001
+ if (buffer.readUInt8(0) !== expectedCode)
3002
+ throw new Error("Invalid Code");
3003
+ // Sin datos extra
3004
+ return new MDisconnectInd();
3005
+ }
3006
+ },
3007
+ "M_User_Data_Connected.req": class MUserDataConnectedReq {
3008
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Connected.req"]["EMI2/IMI2"].value;
3009
+ control = new ControlField_1.ControlField();
3010
+ APDU;
3011
+ hopCount;
3012
+ constructor(value) {
3013
+ if (typeof value !== "object" || value === null) {
3014
+ throw new InvalidInputObject(MUserDataConnectedReq.name);
3015
+ }
3016
+ this.control.priority = value.control.priority;
3017
+ this.APDU = value.APDU;
3018
+ this.hopCount = value.hopCount;
3019
+ }
3020
+ toBuffer() {
3021
+ const buffer = Buffer.alloc(8 + this.APDU.length);
3022
+ buffer.writeUInt8(this.messageCode, 0);
3023
+ this.control.buffer.copy(buffer, 1);
3024
+ // Octetos 2-5 no utilizados
3025
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.APDU.length & 0x0f);
3026
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
3027
+ buffer[7] = 0x02;
3028
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3029
+ return buffer;
3030
+ }
3031
+ describe() {
3032
+ return {
3033
+ messageCode: this.messageCode,
3034
+ control: this.control.describe(),
3035
+ hopCount: this.hopCount,
3036
+ APDU: this.APDU.toString("hex"),
3037
+ };
3038
+ }
3039
+ static fromBuffer(buffer) {
3040
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Connected.req"]["EMI2/IMI2"].value;
3041
+ if (buffer.readUInt8(0) !== expectedCode)
3042
+ throw new Error("Invalid Code");
3043
+ if (buffer.length < 8)
3044
+ throw new Error("Buffer too short");
3045
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3046
+ const octet6 = buffer.readUInt8(6);
3047
+ const hopCount = (octet6 >> 4) & 0x07;
3048
+ const length = octet6 & 0x0f;
3049
+ // Validación del byte hardcodeado en tu toBuffer
3050
+ if (buffer.readUInt8(7) !== 0x02) {
3051
+ console.warn("Byte 7 en M_User_Data_Connected.req no es 0x02");
3052
+ }
3053
+ // Asumiendo que APDU sigue al byte 7 (offset 8?) o si WriteData escribe en 7...
3054
+ // Tu toBuffer escribe Data en 7 pero luego pone 0x02 en 7. ¡ESTO ES UN BUG EN TU TOBUFFER!
3055
+ // Asumiré para leer que la Data real empieza en 8 dado el conflicto, o leeremos desde 7 si el 0x02 es parte de la data.
3056
+ // Estandarizando: Leemos el buffer restante como APDU.
3057
+ const apdu = buffer.subarray(7, 7 + length);
3058
+ return new MUserDataConnectedReq({
3059
+ control: { priority: control.priority },
3060
+ hopCount: hopCount,
3061
+ APDU: apdu,
3062
+ });
3063
+ }
3064
+ },
3065
+ "M_User_Data_Connected.con": class MUserDataConnectedCon {
3066
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Connected.con"]["EMI2/IMI2"].value;
3067
+ control = new ControlField_1.ControlField();
3068
+ APDU;
3069
+ constructor(value) {
3070
+ if (typeof value !== "object" || value === null) {
3071
+ throw new InvalidInputObject(MUserDataConnectedCon.name);
3072
+ }
3073
+ this.control.confirm = value.control.confirm;
3074
+ this.APDU = value.APDU;
3075
+ }
3076
+ toBuffer() {
3077
+ const buffer = Buffer.alloc(8 + this.APDU.length);
3078
+ buffer.writeUInt8(this.messageCode, 0);
3079
+ this.control.buffer.copy(buffer, 1);
3080
+ // Octetos 3-6 no utilizados
3081
+ buffer[6] |= this.APDU.length & 0x0f;
3082
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
3083
+ buffer[7] = 0x02;
3084
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3085
+ return buffer;
3086
+ }
3087
+ describe() {
3088
+ return {
3089
+ messageCode: this.messageCode,
3090
+ control: this.control.describe(),
3091
+ APDU: this.APDU.toString("hex"),
3092
+ };
3093
+ }
3094
+ static fromBuffer(buffer) {
3095
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Connected.con"]["EMI2/IMI2"].value;
3096
+ if (buffer.readUInt8(0) !== expectedCode)
3097
+ throw new Error("Invalid Code");
3098
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3099
+ const length = buffer.readUInt8(6) & 0x0f;
3100
+ // Mismo conflicto del byte 7 (0x02). Leemos length bytes desde 7.
3101
+ const apdu = buffer.subarray(7, 7 + length);
3102
+ return new MUserDataConnectedCon({
3103
+ control: { confirm: control.confirm },
3104
+ APDU: apdu,
3105
+ });
3106
+ }
3107
+ },
3108
+ "M_User_Data_Connected.ind": class MUserDataConnectedInd {
3109
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Connected.ind"]["EMI2/IMI2"].value;
3110
+ control = new ControlField_1.ControlField();
3111
+ sourceAddress;
3112
+ APDU;
3113
+ constructor(value) {
3114
+ if (typeof value !== "object" || value === null) {
3115
+ throw new InvalidInputObject(MUserDataConnectedInd.name);
3116
+ }
3117
+ this.control.priority = value.control.priority;
3118
+ this.sourceAddress = value.sourceAddress;
3119
+ this.APDU = value.APDU;
3120
+ }
3121
+ toBuffer() {
3122
+ const buffer = Buffer.alloc(8 + this.APDU.length);
3123
+ buffer.writeUInt8(this.messageCode, 0);
3124
+ this.control.buffer.copy(buffer, 1);
3125
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
3126
+ // Octetos 5-6 no utilizados
3127
+ buffer[6] |= this.APDU.length & 0x0f;
3128
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.APDU, 7);
3129
+ buffer[7] = 0x02;
3130
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3131
+ return buffer;
3132
+ }
3133
+ describe() {
3134
+ return {
3135
+ messageCode: this.messageCode,
3136
+ control: this.control.describe(),
3137
+ sourceAddress: this.sourceAddress,
3138
+ APDU: this.APDU.toString("hex"),
3139
+ };
3140
+ }
3141
+ static fromBuffer(buffer) {
3142
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Connected.ind"]["EMI2/IMI2"].value;
3143
+ if (buffer.readUInt8(0) !== expectedCode)
3144
+ throw new Error("Invalid Code");
3145
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3146
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
3147
+ if (!sourceAddress)
3148
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3149
+ if (typeof sourceAddress !== "string")
3150
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
3151
+ const length = buffer.readUInt8(6) & 0x0f;
3152
+ const apdu = buffer.subarray(7, 7 + length);
3153
+ return new MUserDataConnectedInd({
3154
+ control: { priority: control.priority },
3155
+ sourceAddress: sourceAddress,
3156
+ APDU: apdu,
3157
+ });
3158
+ }
3159
+ },
3160
+ "A_Data_Group.req": class ADataGroupReq {
3161
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Data_Group.req"]["EMI2/IMI2"].value;
3162
+ control = new ControlField_1.ControlField();
3163
+ sap;
3164
+ apci;
3165
+ data;
3166
+ hopCount;
3167
+ constructor(value) {
3168
+ if (typeof value !== "object" || value === null) {
3169
+ throw new InvalidInputObject(ADataGroupReq.name);
3170
+ }
3171
+ this.control.priority = value.control.priority;
3172
+ this.sap = value.sap;
3173
+ this.apci = value.apci;
3174
+ this.data = value.data;
3175
+ this.hopCount = value.hopCount;
3176
+ }
3177
+ toBuffer() {
3178
+ const buffer = Buffer.alloc(8 + this.data.length);
3179
+ buffer.writeUInt8(this.messageCode, 0);
3180
+ this.control.buffer.copy(buffer, 1);
3181
+ // Octetos 2-4 no utilizados
3182
+ buffer.writeUInt8(this.sap, 5);
3183
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (this.data.length & 0x0f);
3184
+ const apci = this.apci.packNumber();
3185
+ // Esta escritura del APCI se tiene que hacer antes debido a la logica de escritura del metodo WriteData
3186
+ buffer[7] = apci[0];
3187
+ buffer[8] = apci[1];
3188
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
3189
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3190
+ return buffer;
3191
+ }
3192
+ describe() {
3193
+ return {
3194
+ messageCode: this.messageCode,
3195
+ control: this.control.describe(),
3196
+ sap: this.sap,
3197
+ hopCount: this.hopCount,
3198
+ apci: this.apci.describe(),
3199
+ data: this.data.toString("hex"),
3200
+ };
3201
+ }
3202
+ static fromBuffer(buffer) {
3203
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Data_Group.req"]["EMI2/IMI2"].value;
3204
+ if (buffer.readUInt8(0) !== expectedCode)
3205
+ throw new Error("Invalid Code");
3206
+ if (buffer.length < 8)
3207
+ throw new Error("Buffer too short");
3208
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3209
+ const sap = buffer.readUInt8(5); // Offset 5 según tu toBuffer
3210
+ const octet6 = buffer.readUInt8(6);
3211
+ const hopCount = (octet6 >> 4) & 0x07;
3212
+ const length = octet6 & 0x0f;
3213
+ // Recuperar APDU completa (APCI + Data) desde offset 7
3214
+ const fullAPDU = buffer.subarray(7, 7 + length);
3215
+ const apci1 = buffer[7] & 0x03;
3216
+ const apci2 = buffer[8] & 0xc0;
3217
+ const fullAPCI = apci1 | (apci2 >> 4);
3218
+ const newAPCI = new APCI_1.APCI(fullAPCI);
3219
+ // La data suele empezar en el byte 1 de la APDU (masked) o byte 2, depende de la longitud (<= 6 bits o > 6 bits).
3220
+ // Por simplicidad devolvemos el payload crudo, ajusta según tu parser APCI.
3221
+ const data = fullAPDU;
3222
+ return new ADataGroupReq({
3223
+ control: { priority: control.priority },
3224
+ sap: sap,
3225
+ apci: newAPCI,
3226
+ data: data,
3227
+ hopCount: hopCount,
3228
+ });
3229
+ }
3230
+ },
3231
+ "A_Data_Group.con": class ADataGroupCon {
3232
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Data_Group.con"]["EMI2/IMI2"].value;
3233
+ control = new ControlField_1.ControlField();
3234
+ sap;
3235
+ apci;
3236
+ data;
3237
+ constructor(value) {
3238
+ if (typeof value !== "object" || value === null) {
3239
+ throw new InvalidInputObject(ADataGroupCon.name);
3240
+ }
3241
+ this.control.confirm = value.control.confirm;
3242
+ this.sap = value.sap;
3243
+ this.apci = value.apci;
3244
+ this.data = value.data;
3245
+ }
3246
+ toBuffer() {
3247
+ const totalLength = this.data.length;
3248
+ const buffer = Buffer.alloc(8 + totalLength);
3249
+ buffer.writeUInt8(this.messageCode, 0);
3250
+ this.control.buffer.copy(buffer, 1);
3251
+ buffer.writeUInt8(this.sap, 5);
3252
+ buffer[6] |= totalLength & 0x0f;
3253
+ const apci = this.apci.packNumber();
3254
+ // Esta escritura del APCI se tiene que hacer antes debido a la logica de escritura del metodo WriteData
3255
+ buffer[7] = apci[0];
3256
+ buffer[8] = apci[1];
3257
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
3258
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3259
+ return buffer;
3260
+ }
3261
+ describe() {
3262
+ return {
3263
+ messageCode: this.messageCode,
3264
+ control: this.control.describe(),
3265
+ sap: this.sap,
3266
+ apci: this.apci.describe(),
3267
+ data: this.data.toString("hex"),
3268
+ };
3269
+ }
3270
+ static fromBuffer(buffer) {
3271
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Data_Group.con"]["EMI2/IMI2"].value;
3272
+ if (buffer.readUInt8(0) !== expectedCode)
3273
+ throw new Error("Invalid Code");
3274
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3275
+ const sap = buffer.readUInt8(5);
3276
+ const length = buffer.readUInt8(6) & 0x0f;
3277
+ const fullAPDU = buffer.subarray(7, 7 + length);
3278
+ const apci1 = buffer[7] & 0x03;
3279
+ const apci2 = buffer[8] & 0xc0;
3280
+ const fullAPCI = apci1 | (apci2 >> 4);
3281
+ const apci = new APCI_1.APCI(fullAPCI);
3282
+ return new ADataGroupCon({
3283
+ control: { confirm: control.confirm },
3284
+ sap: sap,
3285
+ apci: apci,
3286
+ data: fullAPDU,
3287
+ });
3288
+ }
3289
+ },
3290
+ "A_Data_Group.ind": class ADataGroupInd {
3291
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Data_Group.ind"]["EMI2/IMI2"].value;
3292
+ control = new ControlField_1.ControlField();
3293
+ sap;
3294
+ apci;
3295
+ data;
3296
+ constructor(value) {
3297
+ if (typeof value !== "object" || value === null) {
3298
+ throw new InvalidInputObject(ADataGroupInd.name);
3299
+ }
3300
+ this.control.priority = value.control.priority;
3301
+ this.sap = value.sap;
3302
+ this.apci = value.apci;
3303
+ this.data = value.data;
3304
+ }
3305
+ toBuffer() {
3306
+ const totalLength = this.data.length;
3307
+ const buffer = Buffer.alloc(8 + totalLength);
3308
+ buffer.writeUInt8(this.messageCode, 0);
3309
+ this.control.buffer.copy(buffer, 1);
3310
+ buffer.writeUInt8(this.sap, 5);
3311
+ buffer[6] |= totalLength & 0x0f;
3312
+ const apci = this.apci.packNumber();
3313
+ // Esta escritura del APCI se tiene que hacer antes debido a la logica de escritura del metodo WriteData
3314
+ buffer[7] = apci[0];
3315
+ buffer[8] = apci[1];
3316
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
3317
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3318
+ return buffer;
3319
+ }
3320
+ describe() {
3321
+ return {
3322
+ messageCode: this.messageCode,
3323
+ control: this.control.describe(),
3324
+ sap: this.sap,
3325
+ apci: this.apci.describe(),
3326
+ data: this.data.toString("hex"),
3327
+ };
3328
+ }
3329
+ static fromBuffer(buffer) {
3330
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Data_Group.ind"]["EMI2/IMI2"].value;
3331
+ if (buffer.readUInt8(0) !== expectedCode)
3332
+ throw new Error("Invalid Code");
3333
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3334
+ const sap = buffer.readUInt8(5);
3335
+ const length = buffer.readUInt8(6) & 0x0f;
3336
+ const fullAPDU = buffer.subarray(7, 7 + length);
3337
+ const apci1 = buffer[7] & 0x03;
3338
+ const apci2 = buffer[8] & 0xc0;
3339
+ const fullAPCI = apci1 | (apci2 >> 4);
3340
+ const apci = new APCI_1.APCI(fullAPCI);
3341
+ return new ADataGroupInd({
3342
+ control: { priority: control.priority },
3343
+ sap: sap,
3344
+ apci: apci,
3345
+ data: fullAPDU,
3346
+ });
3347
+ }
3348
+ },
3349
+ "M_User_Data_Individual.req": class MUserDataIndividualReq {
3350
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Individual.req"]["EMI2/IMI2"].value;
3351
+ control = new ControlField_1.ControlField();
3352
+ destinationAddress;
3353
+ apci = new APCI_1.APCI(APCIEnum_1.APCIEnum.A_UserMemory_Read_Protocol_Data_Unit);
3354
+ data;
3355
+ hopCount;
3356
+ constructor(value) {
3357
+ if (typeof value !== "object" || value === null) {
3358
+ throw new InvalidInputObject(MUserDataIndividualReq.name);
3359
+ }
3360
+ this.control.priority = value.control.priority;
3361
+ this.destinationAddress = value.destinationAddress;
3362
+ this.apci.command = APCIEnum_1.APCIEnum.A_UserMemory_Read_Protocol_Data_Unit; // 2C0
3363
+ this.data = value.data;
3364
+ this.hopCount = value.hopCount;
3365
+ }
3366
+ toBuffer() {
3367
+ const totalLength = this.data.length;
3368
+ const buffer = Buffer.alloc(8 + totalLength);
3369
+ buffer.writeUInt8(this.messageCode, 0);
3370
+ this.control.buffer.copy(buffer, 1);
3371
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
3372
+ buffer[6] |= ((this.hopCount & 0x07) << 4) | (totalLength & 0x0f);
3373
+ const apci = this.apci.packNumber();
3374
+ buffer[7] = apci[0];
3375
+ buffer[8] = apci[1];
3376
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
3377
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3378
+ return buffer;
3379
+ }
3380
+ describe() {
3381
+ return {
3382
+ messageCode: this.messageCode,
3383
+ control: this.control.describe(),
3384
+ destinationAddress: this.destinationAddress,
3385
+ hopCount: this.hopCount,
3386
+ apci: this.apci.describe(),
3387
+ data: this.data.toString("hex"),
3388
+ };
3389
+ }
3390
+ static fromBuffer(buffer) {
3391
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Individual.req"]["EMI2/IMI2"].value;
3392
+ if (buffer.readUInt8(0) !== expectedCode)
3393
+ throw new Error("Invalid Code");
3394
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3395
+ const destAddr = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
3396
+ if (!destAddr)
3397
+ throw new Error("The destAddr is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3398
+ if (typeof destAddr !== "string")
3399
+ throw new Error("The destAddr is not string, this fatal error is from GetAddress, dont be ignore it");
3400
+ const octet6 = buffer.readUInt8(6);
3401
+ const hopCount = (octet6 >> 4) & 0x07;
3402
+ const length = octet6 & 0x0f;
3403
+ const data = buffer.subarray(7, 7 + length);
3404
+ return new MUserDataIndividualReq({
3405
+ control: { priority: control.priority },
3406
+ destinationAddress: destAddr,
3407
+ hopCount: hopCount,
3408
+ data: data,
3409
+ });
3410
+ }
3411
+ },
3412
+ "M_User_Data_Individual.con": class MUserDataIndividualCon {
3413
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Individual.con"]["EMI2/IMI2"].value;
3414
+ control = new ControlField_1.ControlField();
3415
+ destinationAddress;
3416
+ apci = new APCI_1.APCI(APCIEnum_1.APCIEnum.A_UserMemory_Read_Protocol_Data_Unit);
3417
+ data;
3418
+ constructor(value) {
3419
+ if (typeof value !== "object" || value === null) {
3420
+ throw new InvalidInputObject(MUserDataIndividualCon.name);
3421
+ }
3422
+ this.control.confirm = value.control.confirm;
3423
+ this.destinationAddress = value.destinationAddress;
3424
+ this.apci.command = APCIEnum_1.APCIEnum.A_UserMemory_Read_Protocol_Data_Unit; // 2C0
3425
+ this.data = value.data;
3426
+ }
3427
+ toBuffer() {
3428
+ const totalLength = this.data.length;
3429
+ const buffer = Buffer.alloc(8 + totalLength);
3430
+ buffer.writeUInt8(this.messageCode, 0);
3431
+ this.control.buffer.copy(buffer, 1);
3432
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
3433
+ buffer[6] |= totalLength & 0x0f;
3434
+ const apci = this.apci.packNumber();
3435
+ buffer[7] = apci[0];
3436
+ buffer[8] = apci[1];
3437
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
3438
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3439
+ return buffer;
3440
+ }
3441
+ describe() {
3442
+ return {
3443
+ messageCode: this.messageCode,
3444
+ control: this.control.describe(),
3445
+ destinationAddress: this.destinationAddress,
3446
+ apci: this.apci.describe(),
3447
+ data: this.data.toString("hex"),
3448
+ };
3449
+ }
3450
+ static fromBuffer(buffer) {
3451
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Individual.con"]["EMI2/IMI2"].value;
3452
+ if (buffer.readUInt8(0) !== expectedCode)
3453
+ throw new Error("Invalid Code");
3454
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3455
+ const destAddr = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
3456
+ if (!destAddr)
3457
+ throw new Error("The destAddr is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3458
+ if (typeof destAddr !== "string")
3459
+ throw new Error("The destAddr is not string, this fatal error is from GetAddress, dont be ignore it");
3460
+ const length = buffer.readUInt8(6) & 0x0f;
3461
+ const data = buffer.subarray(7, 7 + length);
3462
+ return new MUserDataIndividualCon({
3463
+ control: { confirm: control.confirm },
3464
+ destinationAddress: destAddr,
3465
+ data: data,
3466
+ });
3467
+ }
3468
+ },
3469
+ "M_User_Data_Individual.ind": class MUserDataIndividualInd {
3470
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Individual.ind"]["EMI2/IMI2"].value;
3471
+ control = new ControlField_1.ControlField();
3472
+ sourceAddress;
3473
+ destinationAddress;
3474
+ apci = new APCI_1.APCI(APCIEnum_1.APCIEnum.A_UserMemory_Read_Protocol_Data_Unit);
3475
+ data;
3476
+ constructor(value) {
3477
+ if (typeof value !== "object" || value === null) {
3478
+ throw new InvalidInputObject(MUserDataIndividualInd.name);
3479
+ }
3480
+ this.control.priority = value.control.priority;
3481
+ this.sourceAddress = value.sourceAddress;
3482
+ this.destinationAddress = value.destinationAddress;
3483
+ this.apci.command = APCIEnum_1.APCIEnum.A_UserMemory_Read_Protocol_Data_Unit; // 2C0
3484
+ this.data = value.data;
3485
+ }
3486
+ toBuffer() {
3487
+ const totalLength = this.data.length;
3488
+ const buffer = Buffer.alloc(8 + totalLength);
3489
+ buffer.writeUInt8(this.messageCode, 0);
3490
+ this.control.buffer.copy(buffer, 1);
3491
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
3492
+ KNXHelper_1.KNXHelper.GetAddress_(this.destinationAddress).copy(buffer, 4);
3493
+ buffer[6] |= totalLength & 0x0f;
3494
+ const apci = this.apci.packNumber();
3495
+ buffer[7] = apci[0];
3496
+ buffer[8] = apci[1];
3497
+ KNXHelper_1.KNXHelper.WriteData(buffer, this.data, 7);
3498
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3499
+ return buffer;
3500
+ }
3501
+ describe() {
3502
+ return {
3503
+ messageCode: this.messageCode,
3504
+ control: this.control.describe(),
3505
+ sourceAddress: this.sourceAddress,
3506
+ destinationAddress: this.destinationAddress,
3507
+ apci: this.apci.toHex(),
3508
+ data: this.data.toString("hex"),
3509
+ };
3510
+ }
3511
+ static fromBuffer(buffer) {
3512
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_User_Data_Individual.ind"]["EMI2/IMI2"].value;
3513
+ if (buffer.readUInt8(0) !== expectedCode)
3514
+ throw new Error("Invalid Code");
3515
+ const control = new ControlField_1.ControlField(buffer.readUInt8(1));
3516
+ const sourceAddr = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
3517
+ const destAddr = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), ".");
3518
+ if (!sourceAddr)
3519
+ throw new Error("The sourceAddr is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3520
+ if (typeof sourceAddr !== "string")
3521
+ throw new Error("The sourceAddr is not string, this fatal error is from GetAddress, dont be ignore it");
3522
+ if (!destAddr)
3523
+ throw new Error("The destAddr is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3524
+ if (typeof destAddr !== "string")
3525
+ throw new Error("The destAddr is not string, this fatal error is from GetAddress, dont be ignore it");
3526
+ const length = buffer.readUInt8(6) & 0x0f;
3527
+ const data = buffer.subarray(7, 7 + length);
3528
+ return new MUserDataIndividualInd({
3529
+ control: { priority: control.priority },
3530
+ sourceAddress: sourceAddr,
3531
+ destinationAddress: destAddr,
3532
+ data: data,
3533
+ });
3534
+ }
3535
+ },
3536
+ "A_Poll_Data.req": class APollDataReq {
3537
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Poll_Data.req"]["EMI2/IMI2"].value;
3538
+ pollingGroup;
3539
+ numberOfSlots;
3540
+ control;
3541
+ constructor(value) {
3542
+ if (typeof value !== "object" || value === null) {
3543
+ throw new InvalidInputObject(APollDataReq.name);
3544
+ }
3545
+ this.pollingGroup = value.pollingGroup;
3546
+ this.numberOfSlots = value.numberOfSlots;
3547
+ this.control = new ControlField_1.ControlField(0xf0);
3548
+ }
3549
+ toBuffer() {
3550
+ const buffer = Buffer.alloc(7);
3551
+ buffer.writeUInt8(this.messageCode, 0);
3552
+ // Octeto 3-4 no utilizados
3553
+ buffer[1] = this.control.buffer.readUInt8();
3554
+ KNXHelper_1.KNXHelper.GetAddress_(this.pollingGroup).copy(buffer, 4);
3555
+ buffer[6] = this.numberOfSlots & 0x0f;
3556
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3557
+ return buffer;
3558
+ }
3559
+ describe() {
3560
+ return {
3561
+ messageCode: this.messageCode,
3562
+ control: this.control.describe(),
3563
+ pollingGroup: this.pollingGroup,
3564
+ numberOfSlots: this.numberOfSlots,
3565
+ };
3566
+ }
3567
+ static fromBuffer(buffer) {
3568
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Poll_Data.req"]["EMI2/IMI2"].value;
3569
+ if (buffer.readUInt8(0) !== expectedCode)
3570
+ throw new Error("Invalid Code");
3571
+ // Estructura según tu toBuffer: MC(0), Ctrl(1), Unused(2-3), Group(4-5), Slots(6)
3572
+ const pollGroup = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
3573
+ if (!pollGroup)
3574
+ throw new Error("The pollGroup is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3575
+ if (typeof pollGroup !== "string")
3576
+ throw new Error("The pollGroup is not string, this fatal error is from GetAddress, dont be ignore it");
3577
+ const slots = buffer.readUInt8(6) & 0x0f;
3578
+ return new APollDataReq({
3579
+ pollingGroup: pollGroup,
3580
+ numberOfSlots: slots,
3581
+ });
3582
+ }
3583
+ },
3584
+ "A_Poll_Data.con": class APollDataCon {
3585
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Poll_Data.con"]["EMI2/IMI2"].value;
3586
+ sourceAddress;
3587
+ pollingGroup;
3588
+ numberOfSlots;
3589
+ pollData;
3590
+ control;
3591
+ constructor(value) {
3592
+ if (typeof value !== "object" || value === null) {
3593
+ throw new InvalidInputObject(APollDataCon.name);
3594
+ }
3595
+ this.sourceAddress = value.sourceAddress;
3596
+ this.pollingGroup = value.pollingGroup;
3597
+ this.numberOfSlots = value.numberOfSlots;
3598
+ this.pollData = value.pollData;
3599
+ this.control = new ControlField_1.ControlField(0xf0);
3600
+ }
3601
+ toBuffer() {
3602
+ const buffer = Buffer.alloc(7 + this.pollData.length);
3603
+ buffer.writeUInt8(this.messageCode, 0);
3604
+ buffer[1] = this.control.buffer.readUInt8();
3605
+ KNXHelper_1.KNXHelper.GetAddress_(this.sourceAddress).copy(buffer, 2);
3606
+ KNXHelper_1.KNXHelper.GetAddress_(this.pollingGroup).copy(buffer, 4);
3607
+ buffer[6] = this.numberOfSlots & 0x0f;
3608
+ this.pollData.copy(buffer, 7);
3609
+ // buffer.writeUInt8(checksum(buffer.subarray(0, buffer.length - 1)), buffer.length - 1);
3610
+ return buffer;
3611
+ }
3612
+ describe() {
3613
+ return {
3614
+ messageCode: this.messageCode,
3615
+ control: this.control.describe(),
3616
+ sourceAddress: this.sourceAddress,
3617
+ pollingGroup: this.pollingGroup,
3618
+ numberOfSlots: this.numberOfSlots,
3619
+ pollData: this.pollData.toString("hex"),
3620
+ };
3621
+ }
3622
+ static fromBuffer(buffer) {
3623
+ const expectedCode = MessageCodeField_1.MESSAGE_CODE_FIELD["A_Poll_Data.con"]["EMI2/IMI2"].value;
3624
+ if (buffer.readUInt8(0) !== expectedCode)
3625
+ throw new Error("Invalid Code");
3626
+ // Offset 2: Source
3627
+ const sourceAddress = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(2, 4), ".");
3628
+ if (!sourceAddress)
3629
+ throw new Error("The sourceAddress is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3630
+ if (typeof sourceAddress !== "string")
3631
+ throw new Error("The sourceAddress is not string, this fatal error is from GetAddress, dont be ignore it");
3632
+ // Offset 4: Polling Group
3633
+ const pollingGroup = KNXHelper_1.KNXHelper.GetAddress(buffer.subarray(4, 6), "/");
3634
+ if (!pollingGroup)
3635
+ throw new Error("The pollingGroup is undefined or null, this fatal error is from GetAddress, dont be ignore it");
3636
+ if (typeof pollingGroup !== "string")
3637
+ throw new Error("The pollingGroup is not string, this fatal error is from GetAddress, dont be ignore it");
3638
+ // Offset 6: Slots
3639
+ const slots = buffer.readUInt8(6) & 0x0f;
3640
+ // Offset 7: Data
3641
+ const pollData = buffer.subarray(7);
3642
+ return new APollDataCon({
3643
+ sourceAddress: sourceAddress,
3644
+ pollingGroup: pollingGroup,
3645
+ numberOfSlots: slots,
3646
+ pollData: pollData,
3647
+ });
3648
+ }
3649
+ },
3650
+ };
3651
+ static ManagementEMI = {
3652
+ "M_PropRead.req": class MPropReadReq {
3653
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_PropRead.req"].CEMI.value;
3654
+ data;
3655
+ constructor(data) {
3656
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3657
+ }
3658
+ toBuffer() {
3659
+ const buffer = Buffer.alloc(1 + this.data.length);
3660
+ buffer.writeUInt8(this.messageCode, 0);
3661
+ this.data.copy(buffer, 1);
3662
+ return buffer;
3663
+ }
3664
+ describe() {
3665
+ return {
3666
+ messageCode: this.messageCode,
3667
+ data: this.data.toString("hex"),
3668
+ };
3669
+ }
3670
+ static fromBuffer(buffer) {
3671
+ return new MPropReadReq(buffer.subarray(1));
3672
+ }
3673
+ },
3674
+ "M_PropRead.con": class MPropReadCon {
3675
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_PropRead.con"].CEMI.value;
3676
+ data;
3677
+ constructor(data) {
3678
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3679
+ }
3680
+ toBuffer() {
3681
+ const buffer = Buffer.alloc(1 + this.data.length);
3682
+ buffer.writeUInt8(this.messageCode, 0);
3683
+ this.data.copy(buffer, 1);
3684
+ return buffer;
3685
+ }
3686
+ describe() {
3687
+ return {
3688
+ messageCode: this.messageCode,
3689
+ data: this.data.toString("hex"),
3690
+ };
3691
+ }
3692
+ static fromBuffer(buffer) {
3693
+ return new MPropReadCon(buffer.subarray(1));
3694
+ }
3695
+ },
3696
+ "M_PropWrite.req": class MPropWriteReq {
3697
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_PropWrite.req"].CEMI.value;
3698
+ data;
3699
+ constructor(data) {
3700
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3701
+ }
3702
+ toBuffer() {
3703
+ const buffer = Buffer.alloc(1 + this.data.length);
3704
+ buffer.writeUInt8(this.messageCode, 0);
3705
+ this.data.copy(buffer, 1);
3706
+ return buffer;
3707
+ }
3708
+ describe() {
3709
+ return {
3710
+ messageCode: this.messageCode,
3711
+ data: this.data.toString("hex"),
3712
+ };
3713
+ }
3714
+ static fromBuffer(buffer) {
3715
+ return new MPropWriteReq(buffer.subarray(1));
3716
+ }
3717
+ },
3718
+ "M_PropWrite.con": class MPropWriteCon {
3719
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_PropWrite.con"].CEMI.value;
3720
+ data;
3721
+ constructor(data) {
3722
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3723
+ }
3724
+ toBuffer() {
3725
+ const buffer = Buffer.alloc(1 + this.data.length);
3726
+ buffer.writeUInt8(this.messageCode, 0);
3727
+ this.data.copy(buffer, 1);
3728
+ return buffer;
3729
+ }
3730
+ describe() {
3731
+ return {
3732
+ messageCode: this.messageCode,
3733
+ data: this.data.toString("hex"),
3734
+ };
3735
+ }
3736
+ static fromBuffer(buffer) {
3737
+ return new MPropWriteCon(buffer.subarray(1));
3738
+ }
3739
+ },
3740
+ "M_PropInfo.ind": class MPropInfoInd {
3741
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_PropInfo.ind"].CEMI.value;
3742
+ data;
3743
+ constructor(data) {
3744
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3745
+ }
3746
+ toBuffer() {
3747
+ const buffer = Buffer.alloc(1 + this.data.length);
3748
+ buffer.writeUInt8(this.messageCode, 0);
3749
+ this.data.copy(buffer, 1);
3750
+ return buffer;
3751
+ }
3752
+ describe() {
3753
+ return {
3754
+ messageCode: this.messageCode,
3755
+ data: this.data.toString("hex"),
3756
+ };
3757
+ }
3758
+ static fromBuffer(buffer) {
3759
+ return new MPropInfoInd(buffer.subarray(1));
3760
+ }
3761
+ },
3762
+ "M_FuncPropCommand.req": class MFuncPropCommandReq {
3763
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_FuncPropCommand.req"].CEMI.value;
3764
+ data;
3765
+ constructor(data) {
3766
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3767
+ }
3768
+ toBuffer() {
3769
+ const buffer = Buffer.alloc(1 + this.data.length);
3770
+ buffer.writeUInt8(this.messageCode, 0);
3771
+ this.data.copy(buffer, 1);
3772
+ return buffer;
3773
+ }
3774
+ describe() {
3775
+ return {
3776
+ messageCode: this.messageCode,
3777
+ data: this.data.toString("hex"),
3778
+ };
3779
+ }
3780
+ static fromBuffer(buffer) {
3781
+ return new MFuncPropCommandReq(buffer.subarray(1));
3782
+ }
3783
+ },
3784
+ "M_FuncPropStateRead.req": class MFuncPropStateReadReq {
3785
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_FuncPropStateRead.req"].CEMI.value;
3786
+ data;
3787
+ constructor(data) {
3788
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3789
+ }
3790
+ toBuffer() {
3791
+ const buffer = Buffer.alloc(1 + this.data.length);
3792
+ buffer.writeUInt8(this.messageCode, 0);
3793
+ this.data.copy(buffer, 1);
3794
+ return buffer;
3795
+ }
3796
+ describe() {
3797
+ return {
3798
+ messageCode: this.messageCode,
3799
+ data: this.data.toString("hex"),
3800
+ };
3801
+ }
3802
+ static fromBuffer(buffer) {
3803
+ return new MFuncPropStateReadReq(buffer.subarray(1));
3804
+ }
3805
+ },
3806
+ "M_FuncPropCommand.con": class MFuncPropCommandCon {
3807
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_FuncPropCommand.con"].CEMI.value;
3808
+ data;
3809
+ constructor(data) {
3810
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3811
+ }
3812
+ toBuffer() {
3813
+ const buffer = Buffer.alloc(1 + this.data.length);
3814
+ buffer.writeUInt8(this.messageCode, 0);
3815
+ this.data.copy(buffer, 1);
3816
+ return buffer;
3817
+ }
3818
+ describe() {
3819
+ return {
3820
+ messageCode: this.messageCode,
3821
+ data: this.data.toString("hex"),
3822
+ };
3823
+ }
3824
+ static fromBuffer(buffer) {
3825
+ return new MFuncPropCommandCon(buffer.subarray(1));
3826
+ }
3827
+ },
3828
+ "M_FuncPropStateRead.con": class MFuncPropStateReadCon {
3829
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_FuncPropStateRead.con"].CEMI.value;
3830
+ data;
3831
+ constructor(data) {
3832
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3833
+ }
3834
+ toBuffer() {
3835
+ const buffer = Buffer.alloc(1 + this.data.length);
3836
+ buffer.writeUInt8(this.messageCode, 0);
3837
+ this.data.copy(buffer, 1);
3838
+ return buffer;
3839
+ }
3840
+ describe() {
3841
+ return {
3842
+ messageCode: this.messageCode,
3843
+ data: this.data.toString("hex"),
3844
+ };
3845
+ }
3846
+ static fromBuffer(buffer) {
3847
+ return new MFuncPropStateReadCon(buffer.subarray(1));
3848
+ }
3849
+ },
3850
+ "M_Reset.req": class MResetReq {
3851
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_Reset.req"].CEMI.value;
3852
+ data;
3853
+ constructor(data) {
3854
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3855
+ }
3856
+ toBuffer() {
3857
+ const buffer = Buffer.alloc(1 + this.data.length);
3858
+ buffer.writeUInt8(this.messageCode, 0);
3859
+ this.data.copy(buffer, 1);
3860
+ return buffer;
3861
+ }
3862
+ describe() {
3863
+ return {
3864
+ messageCode: this.messageCode,
3865
+ data: this.data.toString("hex"),
3866
+ };
3867
+ }
3868
+ static fromBuffer(buffer) {
3869
+ return new MResetReq(buffer.subarray(1));
3870
+ }
3871
+ },
3872
+ "M_Reset.ind": class MResetInd {
3873
+ messageCode = MessageCodeField_1.MESSAGE_CODE_FIELD["M_Reset.ind"].CEMI.value;
3874
+ data;
3875
+ constructor(data) {
3876
+ this.data = Buffer.isBuffer(data) ? data : data.data;
3877
+ }
3878
+ toBuffer() {
3879
+ const buffer = Buffer.alloc(1 + this.data.length);
3880
+ buffer.writeUInt8(this.messageCode, 0);
3881
+ this.data.copy(buffer, 1);
3882
+ return buffer;
3883
+ }
3884
+ describe() {
3885
+ return {
3886
+ messageCode: this.messageCode,
3887
+ data: this.data.toString("hex"),
3888
+ };
3889
+ }
3890
+ static fromBuffer(buffer) {
3891
+ return new MResetInd(buffer.subarray(1));
3892
+ }
3893
+ },
3894
+ };
3895
+ }
3896
+ exports.EMI = EMI;
3897
+ // !! This is for verify all class if have the method fromBuffer
3898
+ EMI;