mclimate-payload-helper 1.2.1 → 1.2.3

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 (70) hide show
  1. package/dist/decoders/commandsReadingHelper.d.ts.map +1 -1
  2. package/dist/decoders/commandsReadingHelper.js +214 -121
  3. package/dist/decoders/commandsReadingHelper.js.map +1 -1
  4. package/dist/decoders/payloadParsers/melissaLorawanPayloadParser.d.ts.map +1 -1
  5. package/dist/decoders/payloadParsers/melissaLorawanPayloadParser.js +12 -12
  6. package/dist/decoders/payloadParsers/melissaLorawanPayloadParser.js.map +1 -1
  7. package/dist/encoders/Co2DisplayCommonCommands.d.ts +4 -0
  8. package/dist/encoders/Co2DisplayCommonCommands.d.ts.map +1 -1
  9. package/dist/encoders/Co2DisplayCommonCommands.js +38 -0
  10. package/dist/encoders/Co2DisplayCommonCommands.js.map +1 -1
  11. package/dist/encoders/CommandBuilder.d.ts.map +1 -1
  12. package/dist/encoders/CommandBuilder.js +1 -0
  13. package/dist/encoders/CommandBuilder.js.map +1 -1
  14. package/dist/encoders/MelissaCommands.d.ts +6 -0
  15. package/dist/encoders/MelissaCommands.d.ts.map +1 -0
  16. package/dist/encoders/MelissaCommands.js +35 -0
  17. package/dist/encoders/MelissaCommands.js.map +1 -0
  18. package/dist/encoders/index.d.ts +1 -0
  19. package/dist/encoders/index.d.ts.map +1 -1
  20. package/dist/encoders/index.js +1 -0
  21. package/dist/encoders/index.js.map +1 -1
  22. package/dist/encoders/types/schemas.d.ts +105 -0
  23. package/dist/encoders/types/schemas.d.ts.map +1 -1
  24. package/dist/encoders/types/schemas.js +5 -0
  25. package/dist/encoders/types/schemas.js.map +1 -1
  26. package/dist/test/payloadDecoders.test.js +28 -10
  27. package/dist/test/payloadDecoders.test.js.map +1 -1
  28. package/dist/test/payloadEncoders.test.js +6 -0
  29. package/dist/test/payloadEncoders.test.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/decoders/commandsReadingHelper.ts +204 -122
  32. package/src/decoders/payloadParsers/melissaLorawanPayloadParser.ts +19 -16
  33. package/src/encoders/CommandBuilder.ts +2 -0
  34. package/src/encoders/MelissaCommands.ts +33 -0
  35. package/src/encoders/index.ts +1 -0
  36. package/src/encoders/types/schemas.ts +17 -0
  37. package/src/test/payloadDecoders.test.ts +30 -11
  38. package/src/test/payloadEncoders.test.ts +8 -0
  39. package/dist/encoders/FanCoilThermostat.d.ts +0 -61
  40. package/dist/encoders/FanCoilThermostat.d.ts.map +0 -1
  41. package/dist/encoders/FanCoilThermostat.js +0 -719
  42. package/dist/encoders/FanCoilThermostat.js.map +0 -1
  43. package/dist/encoders/SetAqiLed.d.ts +0 -6
  44. package/dist/encoders/SetAqiLed.d.ts.map +0 -1
  45. package/dist/encoders/SetAqiLed.js +0 -46
  46. package/dist/encoders/SetAqiLed.js.map +0 -1
  47. package/dist/encoders/types/enumValidation.d.ts +0 -6
  48. package/dist/encoders/types/enumValidation.d.ts.map +0 -1
  49. package/dist/encoders/types/enumValidation.js +0 -50
  50. package/dist/encoders/types/enumValidation.js.map +0 -1
  51. package/dist/encoders/types/schemaValidatedEnums.d.ts +0 -40
  52. package/dist/encoders/types/schemaValidatedEnums.d.ts.map +0 -1
  53. package/dist/encoders/types/schemaValidatedEnums.js +0 -181
  54. package/dist/encoders/types/schemaValidatedEnums.js.map +0 -1
  55. package/dist/types/deviceTypes.d.ts +0 -19
  56. package/dist/types/deviceTypes.d.ts.map +0 -1
  57. package/dist/types/deviceTypes.js +0 -23
  58. package/dist/types/deviceTypes.js.map +0 -1
  59. package/dist/types/index.d.ts +0 -2
  60. package/dist/types/index.d.ts.map +0 -1
  61. package/dist/types/index.js +0 -18
  62. package/dist/types/index.js.map +0 -1
  63. package/dist/types/types.d.ts +0 -13
  64. package/dist/types/types.d.ts.map +0 -1
  65. package/dist/types/types.js +0 -9
  66. package/dist/types/types.js.map +0 -1
  67. package/dist/validation.d.ts +0 -3
  68. package/dist/validation.d.ts.map +0 -1
  69. package/dist/validation.js +0 -8
  70. package/dist/validation.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"commandsReadingHelper.d.ts","sourceRoot":"","sources":["../../src/decoders/commandsReadingHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAG5D,eAAO,MAAM,qBAAqB,YAAa,MAAM,iBAAiB,MAAM,cAAc,UAAU,mBA6jFnG,CAAA"}
1
+ {"version":3,"file":"commandsReadingHelper.d.ts","sourceRoot":"","sources":["../../src/decoders/commandsReadingHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAG5D,eAAO,MAAM,qBAAqB,YAAa,MAAM,iBAAiB,MAAM,cAAc,UAAU,mBA+oFnG,CAAA"}
@@ -203,6 +203,67 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
203
203
  }
204
204
  }
205
205
  break;
206
+ case '0a':
207
+ {
208
+ try {
209
+ let data;
210
+ if (deviceType === types_1.DeviceType.MelissaLorawan) {
211
+ command_len = 4;
212
+ let recordedIrCodeSize = (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16);
213
+ let bytesSent = `${commands[i + 3]}${commands[i + 4]}`;
214
+ data = { recordedIrInfo: { recordedIrCodeSize, bytesSent } };
215
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
216
+ }
217
+ }
218
+ catch (e) {
219
+ throw new utils_1.CustomError({
220
+ message: `Failed to process command '0a'`,
221
+ hexData,
222
+ command,
223
+ deviceType,
224
+ originalError: e,
225
+ });
226
+ }
227
+ }
228
+ break;
229
+ case '0b':
230
+ {
231
+ try {
232
+ let data;
233
+ if (deviceType === types_1.DeviceType.MelissaLorawan) {
234
+ // First byte after command indicates how many bytes follow
235
+ const bytesCount = parseInt(commands[i + 1], 16);
236
+ command_len = 1 + bytesCount; // 1 for bytesCount + the actual bytes
237
+ // Next two bytes are buffer offset
238
+ const bufferOffsetMSB = parseInt(commands[i + 2], 16);
239
+ const bufferOffsetLSB = parseInt(commands[i + 3], 16);
240
+ const address = (bufferOffsetMSB << 8) | bufferOffsetLSB;
241
+ // The rest is IR code data
242
+ let irCodeDataString = '';
243
+ for (let j = 4; j < 4 + bytesCount - 2; j++) { // -2 to account for the offset bytes
244
+ irCodeDataString += commands[i + j];
245
+ }
246
+ data = {
247
+ irCodeData: {
248
+ bytesCount: bytesCount - 2,
249
+ address,
250
+ data: irCodeDataString
251
+ }
252
+ };
253
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
254
+ }
255
+ }
256
+ catch (e) {
257
+ throw new utils_1.CustomError({
258
+ message: `Failed to process command '0b'`,
259
+ hexData,
260
+ command,
261
+ deviceType,
262
+ originalError: e,
263
+ });
264
+ }
265
+ }
266
+ break;
206
267
  case '0e':
207
268
  {
208
269
  try {
@@ -1679,10 +1740,25 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
1679
1740
  {
1680
1741
  try {
1681
1742
  let data;
1682
- command_len = 3;
1683
- let state = parseInt(commands[i + 1], 16);
1684
- let time = (parseInt(commands[i + 2], 16) << 8) | parseInt(commands[i + 3], 16);
1685
- data = { relayTimerInSeconds: { state, time } };
1743
+ if (deviceType === types_1.DeviceType.Vicki) {
1744
+ command_len = 2;
1745
+ let notificationByte = parseInt(commands[i + 1], 16);
1746
+ // Extract notification flags from bits
1747
+ let temperatureRestoredAfterManualBoost = !!(notificationByte & 0x01); // Bit 0
1748
+ let temperatureChangedByHeatingSchedule = !!(notificationByte & 0x02); // Bit 1
1749
+ data = {
1750
+ notifications: {
1751
+ temperatureRestoredAfterManualBoost: temperatureRestoredAfterManualBoost,
1752
+ temperatureChangedByHeatingSchedule: temperatureChangedByHeatingSchedule
1753
+ }
1754
+ };
1755
+ }
1756
+ else {
1757
+ command_len = 3;
1758
+ let state = parseInt(commands[i + 1], 16);
1759
+ let time = (parseInt(commands[i + 2], 16) << 8) | parseInt(commands[i + 3], 16);
1760
+ data = { relayTimerInSeconds: { state, time } };
1761
+ }
1686
1762
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
1687
1763
  }
1688
1764
  catch (e) {
@@ -1751,6 +1827,10 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
1751
1827
  command_len = 1;
1752
1828
  data = { fanSpeedNotOccupied: parseInt(commands[i + 1], 16) };
1753
1829
  }
1830
+ else {
1831
+ command_len = 1;
1832
+ data = { manualChangeRelayState: parseInt(commands[i + 1], 16) };
1833
+ }
1754
1834
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
1755
1835
  }
1756
1836
  catch (e) {
@@ -1799,6 +1879,12 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
1799
1879
  overheatingEvents: { events: parseInt(commands[i + 1], 16), temperature: parseInt(commands[i + 2], 16) },
1800
1880
  };
1801
1881
  }
1882
+ else if (deviceType === types_1.DeviceType.Vicki) {
1883
+ command_len = 1;
1884
+ let offsetByte = parseInt(commands[i + 1], 16);
1885
+ let offsetHours = (offsetByte & 0x80) ? (offsetByte - 256) : offsetByte;
1886
+ data = { deviceTimeZone: offsetHours };
1887
+ }
1802
1888
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
1803
1889
  }
1804
1890
  catch (e) {
@@ -1855,6 +1941,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
1855
1941
  },
1856
1942
  };
1857
1943
  }
1944
+ else {
1945
+ command_len = 1;
1946
+ let timeValue = parseInt(commands[i + 1], 16);
1947
+ data = { autoSetpointRestoreStatus: timeValue === 0 ? 0 : timeValue * 10 };
1948
+ }
1858
1949
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
1859
1950
  }
1860
1951
  catch (e) {
@@ -2000,6 +2091,10 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
2000
2091
  command_len = 1;
2001
2092
  data = { frostProtectionStatus: parseInt(commands[i + 1], 16) };
2002
2093
  }
2094
+ else {
2095
+ command_len = 1;
2096
+ data = { timeRequestByMACcommand: parseInt(commands[i + 1], 16) };
2097
+ }
2003
2098
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2004
2099
  }
2005
2100
  catch (e) {
@@ -2435,22 +2530,6 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
2435
2530
  }
2436
2531
  }
2437
2532
  break;
2438
- case '58':
2439
- {
2440
- command_len = 1;
2441
- let notificationByte = parseInt(commands[i + 1], 16);
2442
- // Extract notification flags from bits
2443
- let temperatureRestoredAfterManualBoost = !!(notificationByte & 0x01); // Bit 0
2444
- let temperatureChangedByHeatingSchedule = !!(notificationByte & 0x02); // Bit 1
2445
- let data = {
2446
- notifications: {
2447
- temperatureRestoredAfterManualBoost: temperatureRestoredAfterManualBoost,
2448
- temperatureChangedByHeatingSchedule: temperatureChangedByHeatingSchedule
2449
- }
2450
- };
2451
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2452
- }
2453
- break;
2454
2533
  case '5a':
2455
2534
  {
2456
2535
  try {
@@ -2564,24 +2643,6 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
2564
2643
  }
2565
2644
  }
2566
2645
  break;
2567
- case '5d':
2568
- {
2569
- try {
2570
- command_len = 1;
2571
- let data = { manualChangeRelayState: parseInt(commands[i + 1], 16) };
2572
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2573
- }
2574
- catch (e) {
2575
- throw new utils_1.CustomError({
2576
- message: `Failed to process command '5d'`,
2577
- hexData,
2578
- command,
2579
- deviceType,
2580
- originalError: e,
2581
- });
2582
- }
2583
- }
2584
- break;
2585
2646
  case '5e':
2586
2647
  {
2587
2648
  try {
@@ -2611,108 +2672,140 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
2611
2672
  }
2612
2673
  }
2613
2674
  break;
2614
- case '60':
2615
- {
2616
- command_len = 1;
2617
- let offsetByte = parseInt(commands[i + 1], 16);
2618
- let offsetHours = (offsetByte & 0x80) ? (offsetByte - 256) : offsetByte;
2619
- let data = { deviceTimeZone: offsetHours };
2620
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2621
- }
2622
- break;
2623
- case '62':
2624
- {
2625
- command_len = 1;
2626
- let timeValue = parseInt(commands[i + 1], 16);
2627
- let data = { autoSetpointRestoreStatus: timeValue === 0 ? 0 : timeValue * 10 };
2628
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2629
- }
2630
- break;
2631
2675
  case '64':
2632
2676
  {
2633
- command_len = 1;
2634
- let ledDurationValue = parseInt(commands[i + 1], 16);
2635
- let durationInSeconds = ledDurationValue / 2; // As per the docs, value is divided by 2 to get seconds
2636
- let data = {
2637
- ledIndicationDuration: durationInSeconds
2638
- };
2639
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2677
+ try {
2678
+ command_len = 1;
2679
+ let ledDurationValue = parseInt(commands[i + 1], 16);
2680
+ let durationInSeconds = ledDurationValue / 2; // As per the docs, value is divided by 2 to get seconds
2681
+ let data = {
2682
+ ledIndicationDuration: durationInSeconds
2683
+ };
2684
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2685
+ }
2686
+ catch (e) {
2687
+ throw new utils_1.CustomError({
2688
+ message: `Failed to process command '64'`,
2689
+ hexData,
2690
+ command,
2691
+ deviceType,
2692
+ originalError: e,
2693
+ });
2694
+ }
2640
2695
  }
2641
2696
  break;
2642
2697
  case '66':
2643
2698
  {
2644
- command_len = 2;
2645
- let tempHigh = parseInt(commands[i + 1], 16);
2646
- let tempLow = parseInt(commands[i + 2], 16);
2647
- let targetTemp = (tempHigh << 8) | tempLow;
2648
- let data = {
2649
- offlineTargetTemperature: targetTemp === 0 ? 0 : targetTemp / 10
2650
- };
2651
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2699
+ try {
2700
+ command_len = 2;
2701
+ let tempHigh = parseInt(commands[i + 1], 16);
2702
+ let tempLow = parseInt(commands[i + 2], 16);
2703
+ let targetTemp = (tempHigh << 8) | tempLow;
2704
+ let data = {
2705
+ offlineTargetTemperature: targetTemp === 0 ? 0 : targetTemp / 10
2706
+ };
2707
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2708
+ }
2709
+ catch (e) {
2710
+ throw new utils_1.CustomError({
2711
+ message: `Failed to process command '66'`,
2712
+ hexData,
2713
+ command,
2714
+ deviceType,
2715
+ originalError: e,
2716
+ });
2717
+ }
2652
2718
  }
2653
2719
  break;
2654
2720
  case '68':
2655
2721
  {
2656
- command_len = 1;
2657
- let data = { internalAlgoTemporaryState: parseInt(commands[i + 1], 16) === 0 ? true : false };
2658
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2722
+ try {
2723
+ command_len = 1;
2724
+ let data = { internalAlgoTemporaryState: parseInt(commands[i + 1], 16) === 0 ? true : false };
2725
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2726
+ }
2727
+ catch (e) {
2728
+ throw new utils_1.CustomError({
2729
+ message: `Failed to process command '68'`,
2730
+ hexData,
2731
+ command,
2732
+ deviceType,
2733
+ originalError: e,
2734
+ });
2735
+ }
2659
2736
  }
2660
2737
  break;
2661
2738
  case '6a':
2662
2739
  {
2663
- command_len = 12;
2664
- let temperatureLevels = {};
2665
- // Process 6 scale levels (0-5), each with a 2-byte temperature value
2666
- for (let level = 0; level < 6; level++) {
2667
- let tempHighByte = parseInt(commands[i + 1 + (level * 2)], 16);
2668
- let tempLowByte = parseInt(commands[i + 2 + (level * 2)], 16);
2669
- let tempValue = (tempHighByte << 8) | tempLowByte;
2670
- // The temperature values are pre-multiplied by 10
2671
- temperatureLevels['level' + level] = tempValue / 10;
2740
+ try {
2741
+ command_len = 12;
2742
+ let temperatureLevels = {};
2743
+ // Process 6 scale levels (0-5), each with a 2-byte temperature value
2744
+ for (let level = 0; level < 6; level++) {
2745
+ let tempHighByte = parseInt(commands[i + 1 + (level * 2)], 16);
2746
+ let tempLowByte = parseInt(commands[i + 2 + (level * 2)], 16);
2747
+ let tempValue = (tempHighByte << 8) | tempLowByte;
2748
+ // The temperature values are pre-multiplied by 10
2749
+ temperatureLevels['level' + level] = tempValue / 10;
2750
+ }
2751
+ let data = {
2752
+ temperatureLevels: temperatureLevels
2753
+ };
2754
+ Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2755
+ }
2756
+ catch (e) {
2757
+ throw new utils_1.CustomError({
2758
+ message: `Failed to process command '6a'`,
2759
+ hexData,
2760
+ command,
2761
+ deviceType,
2762
+ originalError: e,
2763
+ });
2764
+ }
2765
+ }
2766
+ break;
2767
+ case '6c': {
2768
+ try {
2769
+ command_len = 4;
2770
+ let eventsHighByte = parseInt(commands[i + 2], 16); // Events 19-16
2771
+ let eventsMidByte = parseInt(commands[i + 3], 16); // Events 15-8
2772
+ let eventsLowByte = parseInt(commands[i + 4], 16); // Events 7-0
2773
+ // Create a more structured and readable format for heating events
2774
+ let heatingEventStates = {};
2775
+ // Process all 20 events (0-19) in a single loop
2776
+ for (let eventIdx = 0; eventIdx < 20; eventIdx++) {
2777
+ // Calculate which bit to check
2778
+ let bitPosition;
2779
+ if (eventIdx >= 16) {
2780
+ // Events 16-19 in high byte
2781
+ bitPosition = eventIdx - 16;
2782
+ heatingEventStates[eventIdx] = !!(eventsHighByte & (1 << bitPosition));
2783
+ }
2784
+ else if (eventIdx >= 8) {
2785
+ // Events 8-15 in mid byte
2786
+ bitPosition = eventIdx - 8;
2787
+ heatingEventStates[eventIdx] = !!(eventsMidByte & (1 << bitPosition));
2788
+ }
2789
+ else {
2790
+ // Events 0-7 in low byte
2791
+ bitPosition = eventIdx;
2792
+ heatingEventStates[eventIdx] = !!(eventsLowByte & (1 << bitPosition));
2793
+ }
2672
2794
  }
2673
2795
  let data = {
2674
- temperatureLevels: temperatureLevels
2796
+ heatingEventStates: heatingEventStates
2675
2797
  };
2676
2798
  Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2677
2799
  }
2678
- break;
2679
- case '6c': {
2680
- command_len = 4;
2681
- let eventsHighByte = parseInt(commands[i + 2], 16); // Events 19-16
2682
- let eventsMidByte = parseInt(commands[i + 3], 16); // Events 15-8
2683
- let eventsLowByte = parseInt(commands[i + 4], 16); // Events 7-0
2684
- // Create a more structured and readable format for heating events
2685
- let heatingEventStates = {};
2686
- // Process all 20 events (0-19) in a single loop
2687
- for (let eventIdx = 0; eventIdx < 20; eventIdx++) {
2688
- // Calculate which bit to check
2689
- let bitPosition;
2690
- if (eventIdx >= 16) {
2691
- // Events 16-19 in high byte
2692
- bitPosition = eventIdx - 16;
2693
- heatingEventStates[eventIdx] = !!(eventsHighByte & (1 << bitPosition));
2694
- }
2695
- else if (eventIdx >= 8) {
2696
- // Events 8-15 in mid byte
2697
- bitPosition = eventIdx - 8;
2698
- heatingEventStates[eventIdx] = !!(eventsMidByte & (1 << bitPosition));
2699
- }
2700
- else {
2701
- // Events 0-7 in low byte
2702
- bitPosition = eventIdx;
2703
- heatingEventStates[eventIdx] = !!(eventsLowByte & (1 << bitPosition));
2704
- }
2705
- }
2706
- let data = {
2707
- heatingEventStates: heatingEventStates
2708
- };
2709
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2710
- break;
2711
- }
2712
- case '6e': {
2713
- command_len = 1;
2714
- let data = { timeRequestByMACcommand: parseInt(commands[i + 1], 16) };
2715
- Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
2800
+ catch (e) {
2801
+ throw new utils_1.CustomError({
2802
+ message: `Failed to process command '6c'`,
2803
+ hexData,
2804
+ command,
2805
+ deviceType,
2806
+ originalError: e,
2807
+ });
2808
+ }
2716
2809
  break;
2717
2810
  }
2718
2811
  case '9b':