knx.ts 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +51 -21
- package/README.md +274 -61
- package/dist/@types/interfaces/connection.d.ts +80 -13
- package/dist/@types/interfaces/servers.d.ts +18 -0
- package/dist/@types/interfaces/servers.js +2 -0
- package/dist/connection/KNXService.d.ts +13 -30
- package/dist/connection/KNXService.js +4 -164
- package/dist/connection/KNXTunneling.d.ts +4 -4
- package/dist/connection/KNXTunneling.js +35 -62
- package/dist/connection/KNXUSBConnection.d.ts +20 -0
- package/dist/connection/KNXUSBConnection.js +358 -0
- package/dist/connection/KNXnetIPServer.d.ts +29 -12
- package/dist/connection/KNXnetIPServer.js +261 -83
- package/dist/connection/Router.d.ts +52 -32
- package/dist/connection/Router.js +225 -153
- package/dist/connection/TPUART.d.ts +8 -3
- package/dist/connection/TPUART.js +41 -37
- package/dist/connection/TunnelConnection.d.ts +3 -1
- package/dist/connection/TunnelConnection.js +6 -4
- package/dist/core/CEMI.d.ts +7 -2
- package/dist/core/CEMI.js +5 -8
- package/dist/core/EMI.d.ts +312 -200
- package/dist/core/EMI.js +511 -1007
- package/dist/core/KNXnetIPStructures.d.ts +10 -1
- package/dist/core/KNXnetIPStructures.js +15 -10
- package/dist/core/MessageCodeField.d.ts +1 -1
- package/dist/core/cache/GroupAddressCache.d.ts +57 -0
- package/dist/core/cache/GroupAddressCache.js +227 -0
- package/dist/core/data/KNXDataDecode.d.ts +2 -2
- package/dist/core/data/KNXDataDecode.js +198 -183
- package/dist/core/enum/EnumControlField.d.ts +0 -5
- package/dist/core/enum/EnumControlField.js +1 -7
- package/dist/core/enum/EnumControlFieldExtended.d.ts +1 -1
- package/dist/core/enum/EnumShortACKFrame.d.ts +1 -1
- package/dist/core/enum/ErrorCodeSet.js +59 -0
- package/dist/core/enum/KNXnetIPEnum.d.ts +2 -2
- package/dist/core/enum/KNXnetIPEnum.js +19 -1
- package/dist/core/layers/data/NPDU.d.ts +2 -1
- package/dist/core/layers/data/NPDU.js +6 -3
- package/dist/index.d.ts +19 -2
- package/dist/index.js +36 -1
- package/dist/server/KNXMQTTGateway.d.ts +13 -0
- package/dist/server/KNXMQTTGateway.js +164 -0
- package/dist/server/KNXWebSocketServer.d.ts +12 -0
- package/dist/server/KNXWebSocketServer.js +118 -0
- package/dist/utils/CEMIAdapter.d.ts +4 -3
- package/dist/utils/CEMIAdapter.js +26 -30
- package/dist/utils/Logger.d.ts +4 -4
- package/dist/utils/Logger.js +3 -7
- package/package.json +27 -7
|
@@ -239,13 +239,19 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
static get dptEnum() {
|
|
242
|
-
return [
|
|
242
|
+
return [
|
|
243
|
+
1, 2, 3007, 3008, 4001, 4002, 5, 5001, 5002, 6, 6001, 6010, 6020, 7, 7001, 7002, 7003, 7004, 7005, 7006, 7007,
|
|
244
|
+
7011, 7012, 7013, 8, 9, 10001, 11001, 12001, 12002, 13, 13001, 13002, 13010, 13011, 13012, 13013, 13014, 13015,
|
|
245
|
+
13016, 13100, 14, 15000, 16, 16002, 20, 20001, 20002, 20003, 20004, 20005, 20006, 20007, 20008, 20011, 20012,
|
|
246
|
+
20013, 20014, 20017, 20020, 20021, 20022, 27001, 28001, 29, 29010, 29011, 29012, 232600, 238600, 245600, 250600,
|
|
247
|
+
251600,
|
|
248
|
+
];
|
|
243
249
|
}
|
|
244
250
|
static toPercentage(value) {
|
|
245
|
-
return (value / 255) * 100 +
|
|
251
|
+
return (value / 255) * 100 + "%";
|
|
246
252
|
}
|
|
247
253
|
static toAngle(value) {
|
|
248
|
-
return (value / 255) * 360 +
|
|
254
|
+
return (value / 255) * 360 + "ª";
|
|
249
255
|
}
|
|
250
256
|
/**
|
|
251
257
|
* Interpret the underlying data as boolean value
|
|
@@ -269,7 +275,8 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
269
275
|
const raw = buffer[0] & 0x03;
|
|
270
276
|
const c = (raw >> 1) & 0x01; // Bit de control
|
|
271
277
|
const v = raw & 0x01; // Bit de valor
|
|
272
|
-
|
|
278
|
+
// eslint-disable-next-line no-useless-assignment
|
|
279
|
+
let description = "";
|
|
273
280
|
// Según la combinación de bits, asignamos una descripción:
|
|
274
281
|
// - c = 0: sin control.
|
|
275
282
|
// - v = 0: DPT_Enable_Control (2.003)
|
|
@@ -279,19 +286,19 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
279
286
|
// - v = 1: DPT_BinaryValue_Control (2.006)
|
|
280
287
|
if (c === 0) {
|
|
281
288
|
if (v === 0) {
|
|
282
|
-
description =
|
|
289
|
+
description = "No control (DPT_Enable_Control)";
|
|
283
290
|
}
|
|
284
291
|
else {
|
|
285
|
-
description =
|
|
292
|
+
description = "No control (DPT_Ramp_Control)";
|
|
286
293
|
}
|
|
287
294
|
}
|
|
288
295
|
else {
|
|
289
296
|
// c === 1
|
|
290
297
|
if (v === 0) {
|
|
291
|
-
description =
|
|
298
|
+
description = "Control. Function value 0 (DPT_Alarm_Control)";
|
|
292
299
|
}
|
|
293
300
|
else {
|
|
294
|
-
description =
|
|
301
|
+
description = "Control. Function value 1 (DPT_BinaryValue_Control)";
|
|
295
302
|
}
|
|
296
303
|
}
|
|
297
304
|
return {
|
|
@@ -319,13 +326,14 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
319
326
|
const control = (rawNibble >> 3) & 0x01; // Extrae el bit c.
|
|
320
327
|
const stepCode = rawNibble & 0x07; // Extrae los 3 bits de StepCode.
|
|
321
328
|
// Determinar la acción según el bit de control.
|
|
322
|
-
const action = control === 0 ?
|
|
329
|
+
const action = control === 0 ? "Decrease" : "Increase";
|
|
323
330
|
// Descripción basada en el valor de StepCode:
|
|
324
331
|
// - Si StepCode es 0, se interpreta como "Break".
|
|
325
332
|
// - Si StepCode es 1..7, se calcula el número de intervalos como 2^(stepCode - 1)
|
|
326
|
-
|
|
333
|
+
// eslint-disable-next-line no-useless-assignment
|
|
334
|
+
let description = "";
|
|
327
335
|
if (stepCode === 0) {
|
|
328
|
-
description =
|
|
336
|
+
description = "Break";
|
|
329
337
|
}
|
|
330
338
|
else {
|
|
331
339
|
const intervals = Math.pow(2, stepCode - 1);
|
|
@@ -361,8 +369,8 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
361
369
|
const control = (nibble >> 3) & 0x01; // Bit más significativo del nibble
|
|
362
370
|
const stepCode = nibble & 0x07; // Los 3 bits menos significativos
|
|
363
371
|
// Determinar la descripción y el número de intervalos
|
|
364
|
-
const description = control === 0 ?
|
|
365
|
-
const intervals = stepCode === 0 ?
|
|
372
|
+
const description = control === 0 ? "Move Up" : "Move Down";
|
|
373
|
+
const intervals = stepCode === 0 ? "Break indication" : Math.pow(2, stepCode - 1);
|
|
366
374
|
return {
|
|
367
375
|
control: control,
|
|
368
376
|
stepCode: stepCode,
|
|
@@ -413,10 +421,10 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
413
421
|
return buffer.readInt8(0);
|
|
414
422
|
}
|
|
415
423
|
static asDpt6001(buffer) {
|
|
416
|
-
return this.asDpt6(buffer) +
|
|
424
|
+
return this.asDpt6(buffer) + "%";
|
|
417
425
|
}
|
|
418
426
|
static asDpt6010(buffer) {
|
|
419
|
-
return this.asDpt6(buffer) +
|
|
427
|
+
return this.asDpt6(buffer) + " counter pulses";
|
|
420
428
|
}
|
|
421
429
|
static asDpt6020(buffer) {
|
|
422
430
|
// Extraer los primeros 5 bits (estado) de la primera posición
|
|
@@ -424,23 +432,24 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
424
432
|
// Extraer los últimos 3 bits (modo) de la primera posición
|
|
425
433
|
const mode = buffer.readUInt8(0) & 0b111; // Usamos una máscara para obtener los últimos 3 bits
|
|
426
434
|
// Asignar el modo (1: Modo 0, 2: Modo 1, 3: Modo 2)
|
|
427
|
-
|
|
435
|
+
// eslint-disable-next-line no-useless-assignment
|
|
436
|
+
let modeText = "";
|
|
428
437
|
switch (mode) {
|
|
429
438
|
case 0b001:
|
|
430
|
-
modeText =
|
|
439
|
+
modeText = "Modo 0 activo";
|
|
431
440
|
break;
|
|
432
441
|
case 0b010:
|
|
433
|
-
modeText =
|
|
442
|
+
modeText = "Modo 1 activo";
|
|
434
443
|
break;
|
|
435
444
|
case 0b100:
|
|
436
|
-
modeText =
|
|
445
|
+
modeText = "Modo 2 activo";
|
|
437
446
|
break;
|
|
438
447
|
default:
|
|
439
|
-
modeText =
|
|
448
|
+
modeText = "Modo desconocido";
|
|
440
449
|
}
|
|
441
450
|
// Devolver los resultados como un objeto con estado y modo
|
|
442
451
|
return {
|
|
443
|
-
status: status === 1 ?
|
|
452
|
+
status: status === 1 ? "Activo" : "Inactivo", // Si el bit de estado es 1, es activo
|
|
444
453
|
mode: modeText,
|
|
445
454
|
};
|
|
446
455
|
}
|
|
@@ -454,46 +463,46 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
454
463
|
}
|
|
455
464
|
static asDpt7001(buffer) {
|
|
456
465
|
const data = this.asDpt7(buffer);
|
|
457
|
-
return data +
|
|
466
|
+
return data + "pulses";
|
|
458
467
|
}
|
|
459
468
|
static asDpt7002(buffer) {
|
|
460
|
-
return this.asDpt7(buffer) +
|
|
469
|
+
return this.asDpt7(buffer) + "ms";
|
|
461
470
|
}
|
|
462
471
|
static asDpt7003(buffer) {
|
|
463
|
-
return this.asDpt7(buffer) / 100 +
|
|
472
|
+
return this.asDpt7(buffer) / 100 + "s";
|
|
464
473
|
}
|
|
465
474
|
static asDpt7004(buffer) {
|
|
466
|
-
return this.asDpt7(buffer) / 10 +
|
|
475
|
+
return this.asDpt7(buffer) / 10 + "s";
|
|
467
476
|
}
|
|
468
477
|
static asDpt7005(buffer) {
|
|
469
|
-
return this.asDpt7(buffer) +
|
|
478
|
+
return this.asDpt7(buffer) + "s";
|
|
470
479
|
}
|
|
471
480
|
static asDpt7006(buffer) {
|
|
472
|
-
return this.asDpt7(buffer) +
|
|
481
|
+
return this.asDpt7(buffer) + "min";
|
|
473
482
|
}
|
|
474
483
|
static asDpt7007(buffer) {
|
|
475
|
-
return this.asDpt7(buffer) +
|
|
484
|
+
return this.asDpt7(buffer) + "h";
|
|
476
485
|
}
|
|
477
486
|
static asDpt7011(buffer) {
|
|
478
|
-
return this.asDpt7(buffer) +
|
|
487
|
+
return this.asDpt7(buffer) + "mm";
|
|
479
488
|
}
|
|
480
489
|
static asDpt7012(buffer) {
|
|
481
490
|
const data = this.asDpt7(buffer);
|
|
482
491
|
if (data === 0) {
|
|
483
492
|
return {
|
|
484
493
|
value: data,
|
|
485
|
-
status:
|
|
494
|
+
status: "No bus power supply functionality available",
|
|
486
495
|
};
|
|
487
496
|
}
|
|
488
497
|
else {
|
|
489
498
|
return {
|
|
490
|
-
value: data +
|
|
491
|
-
status:
|
|
499
|
+
value: data + "mA",
|
|
500
|
+
status: "",
|
|
492
501
|
};
|
|
493
502
|
}
|
|
494
503
|
}
|
|
495
504
|
static asDpt7013(buffer) {
|
|
496
|
-
return this.asDpt7(buffer) +
|
|
505
|
+
return this.asDpt7(buffer) + "lux";
|
|
497
506
|
}
|
|
498
507
|
static asDpt8(buffer) {
|
|
499
508
|
return buffer.readInt16BE(0);
|
|
@@ -512,7 +521,7 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
512
521
|
const raw = buffer.readUInt16BE(0);
|
|
513
522
|
// Si el valor es 0x7FFF, se considera dato inválido.
|
|
514
523
|
if (raw === 0x7fff) {
|
|
515
|
-
throw new Error(
|
|
524
|
+
throw new Error("DPT9: Invalid data (0x7FFF encountered)");
|
|
516
525
|
}
|
|
517
526
|
const s = raw >> 15;
|
|
518
527
|
const exponent = (raw >> 11) & 0x0f;
|
|
@@ -541,7 +550,7 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
541
550
|
*/
|
|
542
551
|
static asDpt10001(buffer) {
|
|
543
552
|
if (buffer.length < 3) {
|
|
544
|
-
throw new Error(
|
|
553
|
+
throw new Error("No hay suficientes datos para DPT10001");
|
|
545
554
|
}
|
|
546
555
|
// Octeto 1: Día y Hora
|
|
547
556
|
const byte0 = buffer.readUInt8(0);
|
|
@@ -555,18 +564,18 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
555
564
|
const seconds = byte2 & 0x3f; // Máscara 0011 1111
|
|
556
565
|
// Opcional: conversión del número del día a nombre
|
|
557
566
|
const days = {
|
|
558
|
-
0:
|
|
559
|
-
1:
|
|
560
|
-
2:
|
|
561
|
-
3:
|
|
562
|
-
4:
|
|
563
|
-
5:
|
|
564
|
-
6:
|
|
565
|
-
7:
|
|
567
|
+
0: "No day",
|
|
568
|
+
1: "Monday",
|
|
569
|
+
2: "Tuesday",
|
|
570
|
+
3: "Wednesday",
|
|
571
|
+
4: "Thursday",
|
|
572
|
+
5: "Friday",
|
|
573
|
+
6: "Saturday",
|
|
574
|
+
7: "Sunday",
|
|
566
575
|
};
|
|
567
576
|
return {
|
|
568
577
|
day: day,
|
|
569
|
-
dayName: days[day] ||
|
|
578
|
+
dayName: days[day] || "Unknown",
|
|
570
579
|
hour: hour,
|
|
571
580
|
minutes: minutes,
|
|
572
581
|
seconds: seconds,
|
|
@@ -588,7 +597,7 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
588
597
|
*/
|
|
589
598
|
static asDpt11001(buffer) {
|
|
590
599
|
if (buffer.length < 3) {
|
|
591
|
-
throw new Error(
|
|
600
|
+
throw new Error("No hay suficientes datos para DPT11001");
|
|
592
601
|
}
|
|
593
602
|
// Octeto 1: Extraer el día (los 5 bits menos significativos)
|
|
594
603
|
const byte0 = buffer.readUInt8(0);
|
|
@@ -609,7 +618,7 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
609
618
|
month,
|
|
610
619
|
year,
|
|
611
620
|
// Formateamos la fecha en formato DD/MM/YYYY
|
|
612
|
-
dateString: `${day.toString().padStart(2,
|
|
621
|
+
dateString: `${day.toString().padStart(2, "0")}/${month.toString().padStart(2, "0")}/${year}`,
|
|
613
622
|
};
|
|
614
623
|
}
|
|
615
624
|
/**
|
|
@@ -620,12 +629,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
620
629
|
*/
|
|
621
630
|
static asDpt12001(buffer) {
|
|
622
631
|
if (buffer.length < 4) {
|
|
623
|
-
throw new Error(
|
|
632
|
+
throw new Error("No hay suficientes datos para DPT 12.001");
|
|
624
633
|
}
|
|
625
634
|
const value = buffer.readUInt32BE(0);
|
|
626
635
|
return {
|
|
627
636
|
value,
|
|
628
|
-
unit:
|
|
637
|
+
unit: "pulses",
|
|
629
638
|
};
|
|
630
639
|
}
|
|
631
640
|
/**
|
|
@@ -640,21 +649,21 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
640
649
|
*
|
|
641
650
|
* @returns Un objeto con el valor sin signo y la unidad seleccionada.
|
|
642
651
|
*/
|
|
643
|
-
static asDpt12002(buffer, variant =
|
|
652
|
+
static asDpt12002(buffer, variant = "sec") {
|
|
644
653
|
if (buffer.length < 4) {
|
|
645
|
-
throw new Error(
|
|
654
|
+
throw new Error("No hay suficientes datos para el DPT LongTimePeriod");
|
|
646
655
|
}
|
|
647
656
|
const value = buffer.readUInt32BE(0);
|
|
648
657
|
let unit;
|
|
649
658
|
switch (variant) {
|
|
650
|
-
case
|
|
651
|
-
unit =
|
|
659
|
+
case "sec":
|
|
660
|
+
unit = "s";
|
|
652
661
|
break;
|
|
653
|
-
case
|
|
654
|
-
unit =
|
|
662
|
+
case "min":
|
|
663
|
+
unit = "min";
|
|
655
664
|
break;
|
|
656
|
-
case
|
|
657
|
-
unit =
|
|
665
|
+
case "hrs":
|
|
666
|
+
unit = "h";
|
|
658
667
|
break;
|
|
659
668
|
}
|
|
660
669
|
return {
|
|
@@ -675,12 +684,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
675
684
|
*/
|
|
676
685
|
static asDpt13001(buffer) {
|
|
677
686
|
if (buffer.length < 4) {
|
|
678
|
-
throw new Error(
|
|
687
|
+
throw new Error("No hay suficientes datos para DPT 13.001");
|
|
679
688
|
}
|
|
680
689
|
const value = buffer.readInt32BE(0);
|
|
681
690
|
return {
|
|
682
691
|
value,
|
|
683
|
-
unit:
|
|
692
|
+
unit: "pulses",
|
|
684
693
|
};
|
|
685
694
|
}
|
|
686
695
|
/**
|
|
@@ -689,13 +698,13 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
689
698
|
*/
|
|
690
699
|
static asDpt13002(buffer) {
|
|
691
700
|
if (buffer.length < 4) {
|
|
692
|
-
throw new Error(
|
|
701
|
+
throw new Error("No hay suficientes datos para DPT 13.002");
|
|
693
702
|
}
|
|
694
703
|
const rawValue = buffer.readInt32BE(0);
|
|
695
704
|
const value = rawValue * 0.0001;
|
|
696
705
|
return {
|
|
697
706
|
value,
|
|
698
|
-
unit:
|
|
707
|
+
unit: "m³/h",
|
|
699
708
|
};
|
|
700
709
|
}
|
|
701
710
|
/**
|
|
@@ -704,12 +713,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
704
713
|
*/
|
|
705
714
|
static asDpt13010(buffer) {
|
|
706
715
|
if (buffer.length < 4) {
|
|
707
|
-
throw new Error(
|
|
716
|
+
throw new Error("No hay suficientes datos para DPT 13.010");
|
|
708
717
|
}
|
|
709
718
|
const value = buffer.readInt32BE(0);
|
|
710
719
|
return {
|
|
711
720
|
value,
|
|
712
|
-
unit:
|
|
721
|
+
unit: "Wh",
|
|
713
722
|
};
|
|
714
723
|
}
|
|
715
724
|
/**
|
|
@@ -718,12 +727,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
718
727
|
*/
|
|
719
728
|
static asDpt13011(buffer) {
|
|
720
729
|
if (buffer.length < 4) {
|
|
721
|
-
throw new Error(
|
|
730
|
+
throw new Error("No hay suficientes datos para DPT 13.011");
|
|
722
731
|
}
|
|
723
732
|
const value = buffer.readInt32BE(0);
|
|
724
733
|
return {
|
|
725
734
|
value,
|
|
726
|
-
unit:
|
|
735
|
+
unit: "VAh",
|
|
727
736
|
};
|
|
728
737
|
}
|
|
729
738
|
/**
|
|
@@ -732,12 +741,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
732
741
|
*/
|
|
733
742
|
static asDpt13012(buffer) {
|
|
734
743
|
if (buffer.length < 4) {
|
|
735
|
-
throw new Error(
|
|
744
|
+
throw new Error("No hay suficientes datos para DPT 13.012");
|
|
736
745
|
}
|
|
737
746
|
const value = buffer.readInt32BE(0);
|
|
738
747
|
return {
|
|
739
748
|
value,
|
|
740
|
-
unit:
|
|
749
|
+
unit: "VARh",
|
|
741
750
|
};
|
|
742
751
|
}
|
|
743
752
|
/**
|
|
@@ -746,12 +755,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
746
755
|
*/
|
|
747
756
|
static asDpt13013(buffer) {
|
|
748
757
|
if (buffer.length < 4) {
|
|
749
|
-
throw new Error(
|
|
758
|
+
throw new Error("No hay suficientes datos para DPT 13.013");
|
|
750
759
|
}
|
|
751
760
|
const value = buffer.readInt32BE(0);
|
|
752
761
|
return {
|
|
753
762
|
value,
|
|
754
|
-
unit:
|
|
763
|
+
unit: "kWh",
|
|
755
764
|
};
|
|
756
765
|
}
|
|
757
766
|
/**
|
|
@@ -760,12 +769,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
760
769
|
*/
|
|
761
770
|
static asDpt13014(buffer) {
|
|
762
771
|
if (buffer.length < 4) {
|
|
763
|
-
throw new Error(
|
|
772
|
+
throw new Error("No hay suficientes datos para DPT 13.014");
|
|
764
773
|
}
|
|
765
774
|
const value = buffer.readInt32BE(0);
|
|
766
775
|
return {
|
|
767
776
|
value,
|
|
768
|
-
unit:
|
|
777
|
+
unit: "kVAh",
|
|
769
778
|
};
|
|
770
779
|
}
|
|
771
780
|
/**
|
|
@@ -774,12 +783,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
774
783
|
*/
|
|
775
784
|
static asDpt13015(buffer) {
|
|
776
785
|
if (buffer.length < 4) {
|
|
777
|
-
throw new Error(
|
|
786
|
+
throw new Error("No hay suficientes datos para DPT 13.015");
|
|
778
787
|
}
|
|
779
788
|
const value = buffer.readInt32BE(0);
|
|
780
789
|
return {
|
|
781
790
|
value,
|
|
782
|
-
unit:
|
|
791
|
+
unit: "kVARh",
|
|
783
792
|
};
|
|
784
793
|
}
|
|
785
794
|
/**
|
|
@@ -788,12 +797,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
788
797
|
*/
|
|
789
798
|
static asDpt13016(buffer) {
|
|
790
799
|
if (buffer.length < 4) {
|
|
791
|
-
throw new Error(
|
|
800
|
+
throw new Error("No hay suficientes datos para DPT 13.016");
|
|
792
801
|
}
|
|
793
802
|
const value = buffer.readInt32BE(0);
|
|
794
803
|
return {
|
|
795
804
|
value,
|
|
796
|
-
unit:
|
|
805
|
+
unit: "MWh",
|
|
797
806
|
};
|
|
798
807
|
}
|
|
799
808
|
/**
|
|
@@ -802,12 +811,12 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
802
811
|
*/
|
|
803
812
|
static asDpt13100(buffer) {
|
|
804
813
|
if (buffer.length < 4) {
|
|
805
|
-
throw new Error(
|
|
814
|
+
throw new Error("No hay suficientes datos para DPT 13.100");
|
|
806
815
|
}
|
|
807
816
|
const value = buffer.readInt32BE(0);
|
|
808
817
|
return {
|
|
809
818
|
value,
|
|
810
|
-
unit:
|
|
819
|
+
unit: "s",
|
|
811
820
|
};
|
|
812
821
|
}
|
|
813
822
|
/**
|
|
@@ -822,7 +831,7 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
822
831
|
*/
|
|
823
832
|
static asDpt15000(buffer) {
|
|
824
833
|
if (buffer.length < 4) {
|
|
825
|
-
throw new Error(
|
|
834
|
+
throw new Error("No hay suficientes datos para DPT 15.000 (Access Data).");
|
|
826
835
|
}
|
|
827
836
|
const d6 = buffer.readUInt8(0); // Octeto 4
|
|
828
837
|
const d5 = (buffer.readUInt8(1) & 0b11110000) >> 4;
|
|
@@ -849,11 +858,11 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
849
858
|
* Decodifica una cadena de 14 bytes en ASCII o ISO-8859-1.
|
|
850
859
|
*/
|
|
851
860
|
static asDpt16(buffer) {
|
|
852
|
-
if (buffer.length
|
|
853
|
-
throw new Error(
|
|
861
|
+
if (buffer.length > 14) {
|
|
862
|
+
throw new Error("Datos muy grandes para DPT 16 (String).");
|
|
854
863
|
}
|
|
855
|
-
let str =
|
|
856
|
-
for (let i = 0; i <
|
|
864
|
+
let str = "";
|
|
865
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
857
866
|
const charCode = buffer.readUInt8(i);
|
|
858
867
|
if (charCode === 0x00)
|
|
859
868
|
break; // Ignorar caracteres NULL
|
|
@@ -866,18 +875,18 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
866
875
|
* (No oficial en la especificacion del DataPointType de Knx en la version 02.02.01)
|
|
867
876
|
*/
|
|
868
877
|
static asDpt16002(buffer) {
|
|
869
|
-
if (buffer.length
|
|
870
|
-
throw new Error(
|
|
878
|
+
if (buffer.length > 14) {
|
|
879
|
+
throw new Error("Datos muy grandes para DPT 16.002 (Se esperan 14 bytes).");
|
|
871
880
|
}
|
|
872
|
-
let hexString =
|
|
881
|
+
let hexString = "";
|
|
873
882
|
let decimalValue = BigInt(0);
|
|
874
|
-
for (let i = 0; i <
|
|
883
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
875
884
|
if (buffer.readUInt8(i) === 0x00)
|
|
876
885
|
break; // Ignorar caracteres NULL
|
|
877
|
-
hexString += buffer.readUInt8(i).toString(16).padStart(2,
|
|
886
|
+
hexString += buffer.readUInt8(i).toString(16).padStart(2, "0").toUpperCase();
|
|
878
887
|
}
|
|
879
888
|
if (hexString) {
|
|
880
|
-
decimalValue = BigInt(
|
|
889
|
+
decimalValue = BigInt("0x" + hexString); // Convertir de Hex a Decimal
|
|
881
890
|
}
|
|
882
891
|
return { hex: hexString, decimal: decimalValue.toString() };
|
|
883
892
|
}
|
|
@@ -886,154 +895,160 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
886
895
|
}
|
|
887
896
|
static asDpt20001(buffer) {
|
|
888
897
|
const value = buffer.readUInt8(0);
|
|
889
|
-
return [
|
|
898
|
+
return ["autonomous", "slave", "master"][value] || "reserved";
|
|
890
899
|
}
|
|
891
900
|
static asDpt20002(buffer) {
|
|
892
901
|
const value = buffer.readUInt8(0);
|
|
893
|
-
return [
|
|
902
|
+
return ["Building in use", "Building not used", "Building protection"][value] || "reserved";
|
|
894
903
|
}
|
|
895
904
|
static asDpt20003(buffer) {
|
|
896
905
|
const value = buffer.readUInt8(0);
|
|
897
|
-
return [
|
|
906
|
+
return ["occupied", "standby", "not occupied"][value] || "reserved";
|
|
898
907
|
}
|
|
899
908
|
static asDpt20004(buffer) {
|
|
900
909
|
const value = buffer.readUInt8(0);
|
|
901
|
-
return [
|
|
910
|
+
return ["High", "Medium", "Low", "void"][value] || "reserved";
|
|
902
911
|
}
|
|
903
912
|
static asDpt20005(buffer) {
|
|
904
913
|
const value = buffer.readUInt8(0);
|
|
905
|
-
return [
|
|
914
|
+
return ["normal", "presence simulation", "night round"][value] || "manufacturer specific";
|
|
906
915
|
}
|
|
907
916
|
static asDpt20006(buffer) {
|
|
908
917
|
const value = buffer.readUInt8(0);
|
|
909
918
|
const mapping = {
|
|
910
|
-
0:
|
|
911
|
-
1:
|
|
912
|
-
10:
|
|
913
|
-
11:
|
|
914
|
-
12:
|
|
915
|
-
13:
|
|
916
|
-
14:
|
|
917
|
-
20:
|
|
918
|
-
30:
|
|
919
|
-
40:
|
|
920
|
-
50:
|
|
919
|
+
0: "no fault",
|
|
920
|
+
1: "system and functions of common interest",
|
|
921
|
+
10: "HVAC general FBs",
|
|
922
|
+
11: "HVAC Hot Water Heating",
|
|
923
|
+
12: "HVAC Direct Electrical Heating",
|
|
924
|
+
13: "HVAC Terminal Units",
|
|
925
|
+
14: "HVAC VAC",
|
|
926
|
+
20: "Lighting",
|
|
927
|
+
30: "Security",
|
|
928
|
+
40: "Load Management",
|
|
929
|
+
50: "Shutters and blinds",
|
|
921
930
|
};
|
|
922
|
-
return mapping[value] ||
|
|
931
|
+
return mapping[value] || "reserved";
|
|
923
932
|
}
|
|
924
933
|
static asDpt20007(buffer) {
|
|
925
934
|
const value = buffer.readUInt8(0);
|
|
926
|
-
return [
|
|
935
|
+
return ["reserved", "simple alarm", "basic alarm", "extended alarm"][value] || "reserved";
|
|
927
936
|
}
|
|
928
937
|
static asDpt20008(buffer) {
|
|
929
938
|
const value = buffer.readUInt8(0);
|
|
930
|
-
return [
|
|
939
|
+
return ["disabled", "enabled", "auto"][value] || "reserved";
|
|
931
940
|
}
|
|
932
941
|
static asDpt20011(buffer) {
|
|
933
942
|
const value = buffer.readUInt8(0);
|
|
934
943
|
const mapping = [
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
944
|
+
"no fault",
|
|
945
|
+
"general device fault",
|
|
946
|
+
"communication fault",
|
|
947
|
+
"configuration fault",
|
|
948
|
+
"hardware fault",
|
|
949
|
+
"software fault",
|
|
950
|
+
"insufficient non-volatile memory",
|
|
951
|
+
"insufficient volatile memory",
|
|
952
|
+
"memory allocation size 0 received",
|
|
953
|
+
"CRC-error",
|
|
954
|
+
"watchdog reset detected",
|
|
955
|
+
"invalid opcode detected",
|
|
956
|
+
"general protection fault",
|
|
957
|
+
"maximal table length exceeded",
|
|
958
|
+
"undefined load command received",
|
|
959
|
+
"Group Address Table not sorted",
|
|
960
|
+
"invalid connection number (TSAP)",
|
|
961
|
+
"invalid Group Object number (ASAP)",
|
|
962
|
+
"Group Object Type exceeds limit",
|
|
954
963
|
];
|
|
955
|
-
return mapping[value] ||
|
|
964
|
+
return mapping[value] || "reserved";
|
|
956
965
|
}
|
|
957
966
|
static asDpt20012(buffer) {
|
|
958
967
|
const value = buffer.readUInt8(0);
|
|
959
|
-
return [
|
|
968
|
+
return (["no fault", "sensor fault", "process/controller fault", "actuator fault", "other fault"][value] || "reserved");
|
|
960
969
|
}
|
|
961
970
|
static asDpt20013(buffer) {
|
|
962
971
|
const value = buffer.readUInt8(0);
|
|
963
972
|
const mapping = [
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
973
|
+
"not active",
|
|
974
|
+
"1 s",
|
|
975
|
+
"2 s",
|
|
976
|
+
"3 s",
|
|
977
|
+
"5 s",
|
|
978
|
+
"10 s",
|
|
979
|
+
"15 s",
|
|
980
|
+
"20 s",
|
|
981
|
+
"30 s",
|
|
982
|
+
"45 s",
|
|
983
|
+
"1 min",
|
|
984
|
+
"1.25 min",
|
|
985
|
+
"1.5 min",
|
|
986
|
+
"2 min",
|
|
987
|
+
"2.5 min",
|
|
988
|
+
"3 min",
|
|
989
|
+
"5 min",
|
|
990
|
+
"15 min",
|
|
991
|
+
"20 min",
|
|
992
|
+
"30 min",
|
|
993
|
+
"1 h",
|
|
994
|
+
"2 h",
|
|
995
|
+
"3 h",
|
|
996
|
+
"5 h",
|
|
997
|
+
"12 h",
|
|
998
|
+
"24 h",
|
|
990
999
|
];
|
|
991
|
-
return mapping[value] ||
|
|
1000
|
+
return mapping[value] || "reserved";
|
|
992
1001
|
}
|
|
993
1002
|
static asDpt20014(buffer) {
|
|
994
1003
|
const value = buffer.readUInt8(0);
|
|
995
1004
|
return ([
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
][value] ||
|
|
1005
|
+
"calm (no wind)",
|
|
1006
|
+
"light air",
|
|
1007
|
+
"light breeze",
|
|
1008
|
+
"gentle breeze",
|
|
1009
|
+
"moderate breeze",
|
|
1010
|
+
"fresh breeze",
|
|
1011
|
+
"strong breeze",
|
|
1012
|
+
"near gale / moderate gale",
|
|
1013
|
+
"fresh gale",
|
|
1014
|
+
"strong gale",
|
|
1015
|
+
"whole gale / storm",
|
|
1016
|
+
"violent storm",
|
|
1017
|
+
"hurricane",
|
|
1018
|
+
][value] || "reserved");
|
|
1010
1019
|
}
|
|
1011
1020
|
static asDpt20017(buffer) {
|
|
1012
1021
|
const value = buffer.readUInt8(0);
|
|
1013
|
-
return ([
|
|
1022
|
+
return ([
|
|
1023
|
+
"inactive",
|
|
1024
|
+
"digital input not inverted",
|
|
1025
|
+
"digital input inverted",
|
|
1026
|
+
"analog input 0%-100%",
|
|
1027
|
+
"temperature sensor input",
|
|
1028
|
+
][value] || "reserved");
|
|
1014
1029
|
}
|
|
1015
1030
|
static asDpt20020(buffer) {
|
|
1016
1031
|
const value = buffer.readUInt8(0);
|
|
1017
|
-
return [
|
|
1032
|
+
return ["reserved", "SensorConnection", "ControllerConnection"][value] || "reserved";
|
|
1018
1033
|
}
|
|
1019
1034
|
static asDpt20021(buffer) {
|
|
1020
1035
|
const value = buffer.readUInt8(0);
|
|
1021
1036
|
return ([
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
][value] ||
|
|
1037
|
+
"Cloudless",
|
|
1038
|
+
"Sunny",
|
|
1039
|
+
"Sunshiny",
|
|
1040
|
+
"Lightly cloudy",
|
|
1041
|
+
"Scattered clouds",
|
|
1042
|
+
"Cloudy",
|
|
1043
|
+
"Heavily cloudy",
|
|
1044
|
+
"Almost overcast",
|
|
1045
|
+
"Overcast",
|
|
1046
|
+
"Sky obstructed from view",
|
|
1047
|
+
][value] || "reserved");
|
|
1033
1048
|
}
|
|
1034
1049
|
static asDpt20022(buffer) {
|
|
1035
1050
|
const value = buffer.readUInt8(0);
|
|
1036
|
-
return [
|
|
1051
|
+
return ["do not send", "send always", "send if value changed during powerdown"][value] || "reserved";
|
|
1037
1052
|
}
|
|
1038
1053
|
static asDpt27001(buffer) {
|
|
1039
1054
|
// Leer los 4 octetos (32 bits)
|
|
@@ -1053,7 +1068,7 @@ class KnxDataDecode extends KNXData_1.KNXData {
|
|
|
1053
1068
|
static asDpt28001(buffer) {
|
|
1054
1069
|
const utf8Bytes = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
1055
1070
|
// Convertir los bytes a una cadena de texto usando UTF-8
|
|
1056
|
-
const decodedString = new TextDecoder(
|
|
1071
|
+
const decodedString = new TextDecoder("utf-8").decode(utf8Bytes);
|
|
1057
1072
|
// Retornar la cadena decodificada
|
|
1058
1073
|
return decodedString;
|
|
1059
1074
|
}
|