mclimate-payload-helper 1.2.2 → 1.2.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/dist/decoders/commandsReadingHelper.d.ts.map +1 -1
- package/dist/decoders/commandsReadingHelper.js +182 -41
- package/dist/decoders/commandsReadingHelper.js.map +1 -1
- package/dist/decoders/payloadParsers/index.d.ts +1 -0
- package/dist/decoders/payloadParsers/index.d.ts.map +1 -1
- package/dist/decoders/payloadParsers/index.js +1 -0
- package/dist/decoders/payloadParsers/index.js.map +1 -1
- package/dist/decoders/payloadParsers/melissaLorawanPayloadParser.d.ts.map +1 -1
- package/dist/decoders/payloadParsers/melissaLorawanPayloadParser.js +12 -12
- package/dist/decoders/payloadParsers/melissaLorawanPayloadParser.js.map +1 -1
- package/dist/decoders/payloadParsers/multisensorPayloadParser.d.ts +2 -0
- package/dist/decoders/payloadParsers/multisensorPayloadParser.d.ts.map +1 -0
- package/dist/decoders/payloadParsers/multisensorPayloadParser.js +96 -0
- package/dist/decoders/payloadParsers/multisensorPayloadParser.js.map +1 -0
- package/dist/decoders/payloadParsers/types/allDevices.d.ts +2 -1
- package/dist/decoders/payloadParsers/types/allDevices.d.ts.map +1 -1
- package/dist/decoders/payloadParsers/types/allDevices.js +1 -0
- package/dist/decoders/payloadParsers/types/allDevices.js.map +1 -1
- package/dist/encoders/Co2DisplayCommonCommands.d.ts +0 -4
- package/dist/encoders/Co2DisplayCommonCommands.d.ts.map +1 -1
- package/dist/encoders/Co2DisplayCommonCommands.js +0 -38
- package/dist/encoders/Co2DisplayCommonCommands.js.map +1 -1
- package/dist/encoders/CommandBuilder.d.ts.map +1 -1
- package/dist/encoders/CommandBuilder.js +2 -0
- package/dist/encoders/CommandBuilder.js.map +1 -1
- package/dist/encoders/FanCoilThermostat.d.ts +61 -0
- package/dist/encoders/FanCoilThermostat.d.ts.map +1 -0
- package/dist/encoders/FanCoilThermostat.js +719 -0
- package/dist/encoders/FanCoilThermostat.js.map +1 -0
- package/dist/encoders/MelissaCommands.d.ts +6 -0
- package/dist/encoders/MelissaCommands.d.ts.map +1 -0
- package/dist/encoders/MelissaCommands.js +35 -0
- package/dist/encoders/MelissaCommands.js.map +1 -0
- package/dist/encoders/MultiSensorCommands.d.ts +25 -0
- package/dist/encoders/MultiSensorCommands.d.ts.map +1 -0
- package/dist/encoders/MultiSensorCommands.js +256 -0
- package/dist/encoders/MultiSensorCommands.js.map +1 -0
- package/dist/encoders/SetAqiLed.d.ts +6 -0
- package/dist/encoders/SetAqiLed.d.ts.map +1 -0
- package/dist/encoders/SetAqiLed.js +46 -0
- package/dist/encoders/SetAqiLed.js.map +1 -0
- package/dist/encoders/index.d.ts +2 -0
- package/dist/encoders/index.d.ts.map +1 -1
- package/dist/encoders/index.js +2 -0
- package/dist/encoders/index.js.map +1 -1
- package/dist/encoders/types/enumValidation.d.ts +6 -0
- package/dist/encoders/types/enumValidation.d.ts.map +1 -0
- package/dist/encoders/types/enumValidation.js +50 -0
- package/dist/encoders/types/enumValidation.js.map +1 -0
- package/dist/encoders/types/schemaValidatedEnums.d.ts +40 -0
- package/dist/encoders/types/schemaValidatedEnums.d.ts.map +1 -0
- package/dist/encoders/types/schemaValidatedEnums.js +181 -0
- package/dist/encoders/types/schemaValidatedEnums.js.map +1 -0
- package/dist/encoders/types/schemas.d.ts +352 -0
- package/dist/encoders/types/schemas.d.ts.map +1 -1
- package/dist/encoders/types/schemas.js +29 -3
- package/dist/encoders/types/schemas.js.map +1 -1
- package/dist/test/payloadDecoders.test.js +28 -10
- package/dist/test/payloadDecoders.test.js.map +1 -1
- package/dist/test/payloadEncoders.test.js +6 -0
- package/dist/test/payloadEncoders.test.js.map +1 -1
- package/dist/types/deviceTypes.d.ts +19 -0
- package/dist/types/deviceTypes.d.ts.map +1 -0
- package/dist/types/deviceTypes.js +23 -0
- package/dist/types/deviceTypes.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +18 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/types.d.ts +13 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +9 -0
- package/dist/types/types.js.map +1 -0
- package/dist/validation.d.ts +3 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +8 -0
- package/dist/validation.js.map +1 -0
- package/package.json +1 -1
- package/src/decoders/commandsReadingHelper.ts +327 -186
- package/src/decoders/payloadParsers/index.ts +1 -1
- package/src/decoders/payloadParsers/melissaLorawanPayloadParser.ts +19 -16
- package/src/decoders/payloadParsers/multisensorPayloadParser.ts +97 -0
- package/src/decoders/payloadParsers/types/allDevices.ts +1 -0
- package/src/encoders/CommandBuilder.ts +4 -0
- package/src/encoders/MelissaCommands.ts +33 -0
- package/src/encoders/MultiSensorCommands.ts +253 -0
- package/src/encoders/index.ts +2 -0
- package/src/encoders/types/schemas.ts +74 -4
- package/src/test/payloadDecoders.test.ts +30 -11
- package/src/test/payloadEncoders.test.ts +8 -0
|
@@ -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,
|
|
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,mBA8tFnG,CAAA"}
|
|
@@ -21,6 +21,9 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
21
21
|
else if ((potentialKeepAlive[0] === '00' || potentialKeepAlive[0] === '88') && deviceType === types_1.DeviceType.TFlood) {
|
|
22
22
|
decodeKeepalive = true;
|
|
23
23
|
}
|
|
24
|
+
else if (potentialKeepAlive[0] === '82' && deviceType === types_1.DeviceType.MultiSensor) {
|
|
25
|
+
decodeKeepalive = true;
|
|
26
|
+
}
|
|
24
27
|
else if ((potentialKeepAlive[0] === '01' || potentialKeepAlive[0] === '20' || potentialKeepAlive[0] === '21') &&
|
|
25
28
|
deviceType === types_1.DeviceType.OpenCloseSensor) {
|
|
26
29
|
decodeKeepalive = true;
|
|
@@ -203,6 +206,68 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
203
206
|
}
|
|
204
207
|
}
|
|
205
208
|
break;
|
|
209
|
+
case '0a':
|
|
210
|
+
{
|
|
211
|
+
try {
|
|
212
|
+
let data;
|
|
213
|
+
if (deviceType === types_1.DeviceType.MelissaLorawan) {
|
|
214
|
+
command_len = 4;
|
|
215
|
+
let recordedIrCodeSize = (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16);
|
|
216
|
+
let bytesSent = `${commands[i + 3]}${commands[i + 4]}`;
|
|
217
|
+
data = { recordedIrInfo: { recordedIrCodeSize, bytesSent } };
|
|
218
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (e) {
|
|
222
|
+
throw new utils_1.CustomError({
|
|
223
|
+
message: `Failed to process command '0a'`,
|
|
224
|
+
hexData,
|
|
225
|
+
command,
|
|
226
|
+
deviceType,
|
|
227
|
+
originalError: e,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
case '0b':
|
|
233
|
+
{
|
|
234
|
+
try {
|
|
235
|
+
let data;
|
|
236
|
+
if (deviceType === types_1.DeviceType.MelissaLorawan) {
|
|
237
|
+
// First byte after command indicates how many bytes follow
|
|
238
|
+
const bytesCount = parseInt(commands[i + 1], 16);
|
|
239
|
+
command_len = 1 + bytesCount; // 1 for bytesCount + the actual bytes
|
|
240
|
+
// Next two bytes are buffer offset
|
|
241
|
+
const bufferOffsetMSB = parseInt(commands[i + 2], 16);
|
|
242
|
+
const bufferOffsetLSB = parseInt(commands[i + 3], 16);
|
|
243
|
+
const address = (bufferOffsetMSB << 8) | bufferOffsetLSB;
|
|
244
|
+
// The rest is IR code data
|
|
245
|
+
let irCodeDataString = '';
|
|
246
|
+
for (let j = 4; j < 4 + bytesCount - 2; j++) {
|
|
247
|
+
// -2 to account for the offset bytes
|
|
248
|
+
irCodeDataString += commands[i + j];
|
|
249
|
+
}
|
|
250
|
+
data = {
|
|
251
|
+
irCodeData: {
|
|
252
|
+
bytesCount: bytesCount - 2,
|
|
253
|
+
address,
|
|
254
|
+
data: irCodeDataString,
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
throw new utils_1.CustomError({
|
|
262
|
+
message: `Failed to process command '0b'`,
|
|
263
|
+
hexData,
|
|
264
|
+
command,
|
|
265
|
+
deviceType,
|
|
266
|
+
originalError: e,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
206
271
|
case '0e':
|
|
207
272
|
{
|
|
208
273
|
try {
|
|
@@ -577,6 +642,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
577
642
|
};
|
|
578
643
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
579
644
|
}
|
|
645
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
646
|
+
command_len = 1;
|
|
647
|
+
let data = { lightEnabled: parseInt(commands[i + 1], 16) === 1 };
|
|
648
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
649
|
+
}
|
|
580
650
|
else {
|
|
581
651
|
command_len = 4;
|
|
582
652
|
let good_medium = parseInt(`${commands[i + 1]}${commands[i + 2]}`, 16);
|
|
@@ -620,6 +690,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
620
690
|
};
|
|
621
691
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
622
692
|
}
|
|
693
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
694
|
+
command_len = 1;
|
|
695
|
+
let data = { hallEnabled: parseInt(commands[i + 1], 16) === 1 };
|
|
696
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
697
|
+
}
|
|
623
698
|
else if (deviceType !== types_1.DeviceType.OpenCloseSensor) {
|
|
624
699
|
command_len = 2;
|
|
625
700
|
let data = { autoZeroValue: parseInt(`${commands[i + 1]}${commands[i + 2]}`, 16) };
|
|
@@ -681,6 +756,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
681
756
|
let data = { overcurrentThreshold: parseInt(commands[i + 1], 16) };
|
|
682
757
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
683
758
|
}
|
|
759
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
760
|
+
command_len = 2;
|
|
761
|
+
let data = { hallBlindPeriod: (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16) };
|
|
762
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
763
|
+
}
|
|
684
764
|
else {
|
|
685
765
|
command_len = 3;
|
|
686
766
|
let good_zone = parseInt(commands[i + 1], 16);
|
|
@@ -706,7 +786,7 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
706
786
|
case '25':
|
|
707
787
|
{
|
|
708
788
|
try {
|
|
709
|
-
let data
|
|
789
|
+
let data;
|
|
710
790
|
if (deviceType == types_1.DeviceType.Relay16) {
|
|
711
791
|
command_len = 2;
|
|
712
792
|
data = { overpowerThreshold: (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16) };
|
|
@@ -750,6 +830,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
750
830
|
},
|
|
751
831
|
};
|
|
752
832
|
}
|
|
833
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
834
|
+
command_len = 1;
|
|
835
|
+
data = { microphoneEnabled: parseInt(commands[i + 1], 16) === 1 };
|
|
836
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
837
|
+
}
|
|
753
838
|
else {
|
|
754
839
|
command_len = 3;
|
|
755
840
|
let good_zone = parseInt(commands[i + 1], 16);
|
|
@@ -762,8 +847,8 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
762
847
|
bad_zone: Number(bad_zone),
|
|
763
848
|
},
|
|
764
849
|
};
|
|
850
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
765
851
|
}
|
|
766
|
-
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
767
852
|
}
|
|
768
853
|
catch (e) {
|
|
769
854
|
throw new utils_1.CustomError({
|
|
@@ -784,6 +869,13 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
784
869
|
let data = { OVAC: parseInt(commands[i + 1], 16) };
|
|
785
870
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
786
871
|
}
|
|
872
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
873
|
+
command_len = 2;
|
|
874
|
+
let data = {
|
|
875
|
+
microphoneSamplingPeriod: (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16),
|
|
876
|
+
};
|
|
877
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
878
|
+
}
|
|
787
879
|
else {
|
|
788
880
|
command_len = 9;
|
|
789
881
|
let duration_good_beeping = parseInt(commands[i + 1], 16);
|
|
@@ -839,6 +931,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
839
931
|
let data = { proportionalAlgorithmParameters: { coefficient: Number(coefficient), period: Number(period) } };
|
|
840
932
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
841
933
|
}
|
|
934
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
935
|
+
command_len = 1;
|
|
936
|
+
let data = { gasEnabled: parseInt(commands[i + 1], 16) === 1 };
|
|
937
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
938
|
+
}
|
|
842
939
|
else {
|
|
843
940
|
command_len = 15;
|
|
844
941
|
let red_good = parseInt(commands[i + 1], 16);
|
|
@@ -903,6 +1000,11 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
903
1000
|
let data = { temperatureControlAlgorithm: algo };
|
|
904
1001
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
905
1002
|
}
|
|
1003
|
+
else if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
1004
|
+
command_len = 1;
|
|
1005
|
+
let data = { gasMeasurementPeriodMinutes: parseInt(commands[i + 1], 16) };
|
|
1006
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
1007
|
+
}
|
|
906
1008
|
else {
|
|
907
1009
|
command_len = 1;
|
|
908
1010
|
let data = { autoZeroPeriod: parseInt(commands[i + 1], 16) };
|
|
@@ -920,11 +1022,36 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
920
1022
|
}
|
|
921
1023
|
}
|
|
922
1024
|
break;
|
|
1025
|
+
case '2d':
|
|
1026
|
+
{
|
|
1027
|
+
try {
|
|
1028
|
+
if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
1029
|
+
command_len = 1;
|
|
1030
|
+
let data = { pirEnabled: parseInt(commands[i + 1], 16) === 1 };
|
|
1031
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
catch (e) {
|
|
1035
|
+
throw new utils_1.CustomError({
|
|
1036
|
+
message: `Failed to process command '2d'`,
|
|
1037
|
+
hexData,
|
|
1038
|
+
command,
|
|
1039
|
+
deviceType,
|
|
1040
|
+
originalError: e,
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
break;
|
|
923
1045
|
case '2f':
|
|
924
1046
|
{
|
|
925
1047
|
try {
|
|
926
1048
|
let data;
|
|
927
|
-
if (deviceType === types_1.DeviceType.
|
|
1049
|
+
if (deviceType === types_1.DeviceType.MultiSensor) {
|
|
1050
|
+
command_len = 2;
|
|
1051
|
+
data = { pirBlindPeriod: (parseInt(commands[i + 1], 16) << 8) | parseInt(commands[i + 2], 16) };
|
|
1052
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
1053
|
+
}
|
|
1054
|
+
else if (deviceType === types_1.DeviceType.CO2DisplayLite ||
|
|
928
1055
|
deviceType === types_1.DeviceType.CO2PirLite ||
|
|
929
1056
|
deviceType === types_1.DeviceType.HTPirLite) {
|
|
930
1057
|
command_len = 1;
|
|
@@ -974,6 +1101,24 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
974
1101
|
}
|
|
975
1102
|
}
|
|
976
1103
|
break;
|
|
1104
|
+
case 'a4':
|
|
1105
|
+
{
|
|
1106
|
+
try {
|
|
1107
|
+
command_len = 1;
|
|
1108
|
+
let data = { region: parseInt(commands[i + 1], 16) };
|
|
1109
|
+
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
1110
|
+
}
|
|
1111
|
+
catch (e) {
|
|
1112
|
+
throw new utils_1.CustomError({
|
|
1113
|
+
message: `Failed to process command 'a4'`,
|
|
1114
|
+
hexData,
|
|
1115
|
+
command,
|
|
1116
|
+
deviceType,
|
|
1117
|
+
originalError: e,
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
break;
|
|
977
1122
|
case '32':
|
|
978
1123
|
{
|
|
979
1124
|
try {
|
|
@@ -1688,8 +1833,8 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
1688
1833
|
data = {
|
|
1689
1834
|
notifications: {
|
|
1690
1835
|
temperatureRestoredAfterManualBoost: temperatureRestoredAfterManualBoost,
|
|
1691
|
-
temperatureChangedByHeatingSchedule: temperatureChangedByHeatingSchedule
|
|
1692
|
-
}
|
|
1836
|
+
temperatureChangedByHeatingSchedule: temperatureChangedByHeatingSchedule,
|
|
1837
|
+
},
|
|
1693
1838
|
};
|
|
1694
1839
|
}
|
|
1695
1840
|
else {
|
|
@@ -1821,7 +1966,7 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
1821
1966
|
else if (deviceType === types_1.DeviceType.Vicki) {
|
|
1822
1967
|
command_len = 1;
|
|
1823
1968
|
let offsetByte = parseInt(commands[i + 1], 16);
|
|
1824
|
-
let offsetHours =
|
|
1969
|
+
let offsetHours = offsetByte & 0x80 ? offsetByte - 256 : offsetByte;
|
|
1825
1970
|
data = { deviceTimeZone: offsetHours };
|
|
1826
1971
|
}
|
|
1827
1972
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
@@ -2433,24 +2578,6 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2433
2578
|
}
|
|
2434
2579
|
}
|
|
2435
2580
|
break;
|
|
2436
|
-
case 'a4':
|
|
2437
|
-
{
|
|
2438
|
-
try {
|
|
2439
|
-
command_len = 1;
|
|
2440
|
-
let data = { region: parseInt(commands[i + 1], 16) };
|
|
2441
|
-
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2442
|
-
}
|
|
2443
|
-
catch (e) {
|
|
2444
|
-
throw new utils_1.CustomError({
|
|
2445
|
-
message: `Failed to process command 'a4'`,
|
|
2446
|
-
hexData,
|
|
2447
|
-
command,
|
|
2448
|
-
deviceType,
|
|
2449
|
-
originalError: e,
|
|
2450
|
-
});
|
|
2451
|
-
}
|
|
2452
|
-
}
|
|
2453
|
-
break;
|
|
2454
2581
|
case 'a6':
|
|
2455
2582
|
{
|
|
2456
2583
|
try {
|
|
@@ -2483,10 +2610,10 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2483
2610
|
let eventGroupIndex = ['0-7', '8-15', '16-19'];
|
|
2484
2611
|
let heatingEvents = [];
|
|
2485
2612
|
// Process up to 8 events for groups 0 and 1, but only 4 events for group 2
|
|
2486
|
-
let eventsToProcess =
|
|
2613
|
+
let eventsToProcess = eventsGroup === 2 ? 4 : 8;
|
|
2487
2614
|
for (let eventIdx = 0; eventIdx < eventsToProcess; eventIdx++) {
|
|
2488
2615
|
// Each event takes 5 bytes (hour, minute, temp high, temp low, weekday bitmask)
|
|
2489
|
-
let offset = i + 2 +
|
|
2616
|
+
let offset = i + 2 + eventIdx * 5;
|
|
2490
2617
|
// Check if this event is configured
|
|
2491
2618
|
// Make sure we have valid values at this offset
|
|
2492
2619
|
if (offset >= commands.length || offset + 4 >= commands.length) {
|
|
@@ -2498,12 +2625,16 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2498
2625
|
let tempLow = parseInt(commands[offset + 3], 16);
|
|
2499
2626
|
let weekdayByte = parseInt(commands[offset + 4], 16);
|
|
2500
2627
|
// Skip events that are not configured (zeros or NaN values)
|
|
2501
|
-
if (isNaN(hour) ||
|
|
2628
|
+
if (isNaN(hour) ||
|
|
2629
|
+
isNaN(minute) ||
|
|
2630
|
+
isNaN(tempHigh) ||
|
|
2631
|
+
isNaN(tempLow) ||
|
|
2632
|
+
isNaN(weekdayByte) ||
|
|
2502
2633
|
(hour === 0 && minute === 0 && tempHigh === 0 && tempLow === 0 && weekdayByte === 0)) {
|
|
2503
2634
|
continue;
|
|
2504
2635
|
}
|
|
2505
2636
|
// Calculate actual event index in the full range (0-23)
|
|
2506
|
-
let globalEventIndex =
|
|
2637
|
+
let globalEventIndex = eventsGroup * 8 + eventIdx;
|
|
2507
2638
|
// Decode weekday bitmask (bit 0=Mon, bit 1=Tue, bit 2=Wed, bit 3=Thu, bit 4=Fri, bit 5=Sat, bit 6=Sun)
|
|
2508
2639
|
let weekdays = {
|
|
2509
2640
|
monday: !!(weekdayByte & 0x01), // bit 0
|
|
@@ -2512,20 +2643,20 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2512
2643
|
thursday: !!(weekdayByte & 0x08), // bit 3
|
|
2513
2644
|
friday: !!(weekdayByte & 0x10), // bit 4
|
|
2514
2645
|
saturday: !!(weekdayByte & 0x20), // bit 5
|
|
2515
|
-
sunday: !!(weekdayByte & 0x40) // bit 6
|
|
2646
|
+
sunday: !!(weekdayByte & 0x40), // bit 6
|
|
2516
2647
|
};
|
|
2517
2648
|
// Create heating event object
|
|
2518
2649
|
let heatingEvent = {
|
|
2519
2650
|
index: globalEventIndex,
|
|
2520
2651
|
start: (hour < 10 ? '0' + hour : hour) + ':' + (minute < 10 ? '0' + minute : minute),
|
|
2521
2652
|
targetTemperature: ((tempHigh << 8) | tempLow) / 10,
|
|
2522
|
-
weekdays: weekdays
|
|
2653
|
+
weekdays: weekdays,
|
|
2523
2654
|
};
|
|
2524
2655
|
heatingEvents.push(heatingEvent);
|
|
2525
2656
|
}
|
|
2526
2657
|
data = {
|
|
2527
2658
|
heatingEventGroup: eventGroupIndex[eventsGroup],
|
|
2528
|
-
heatingEvents: heatingEvents
|
|
2659
|
+
heatingEvents: heatingEvents,
|
|
2529
2660
|
};
|
|
2530
2661
|
}
|
|
2531
2662
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
@@ -2554,14 +2685,24 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2554
2685
|
let endDay = parseInt(commands[i + 4], 16);
|
|
2555
2686
|
// Convert to human-readable month names
|
|
2556
2687
|
let monthNames = [
|
|
2557
|
-
'January',
|
|
2558
|
-
'
|
|
2688
|
+
'January',
|
|
2689
|
+
'February',
|
|
2690
|
+
'March',
|
|
2691
|
+
'April',
|
|
2692
|
+
'May',
|
|
2693
|
+
'June',
|
|
2694
|
+
'July',
|
|
2695
|
+
'August',
|
|
2696
|
+
'September',
|
|
2697
|
+
'October',
|
|
2698
|
+
'November',
|
|
2699
|
+
'December',
|
|
2559
2700
|
];
|
|
2560
2701
|
data = {
|
|
2561
2702
|
heatingSchedule: {
|
|
2562
2703
|
start: startDay + ' ' + monthNames[startMonth],
|
|
2563
2704
|
end: endDay + ' ' + monthNames[endMonth],
|
|
2564
|
-
}
|
|
2705
|
+
},
|
|
2565
2706
|
};
|
|
2566
2707
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2567
2708
|
}
|
|
@@ -2596,7 +2737,7 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2596
2737
|
let date = dateObj.getUTCDate() + '/' + (dateObj.getUTCMonth() + 1) + '/' + dateObj.getUTCFullYear();
|
|
2597
2738
|
let time = dateObj.getUTCHours() + ':' + (dateObj.getUTCMinutes() < 10 ? '0' : '') + dateObj.getUTCMinutes();
|
|
2598
2739
|
let data = {
|
|
2599
|
-
deviceTime:
|
|
2740
|
+
deviceTime: '' + date + ' ' + time,
|
|
2600
2741
|
};
|
|
2601
2742
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2602
2743
|
}
|
|
@@ -2618,7 +2759,7 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2618
2759
|
let ledDurationValue = parseInt(commands[i + 1], 16);
|
|
2619
2760
|
let durationInSeconds = ledDurationValue / 2; // As per the docs, value is divided by 2 to get seconds
|
|
2620
2761
|
let data = {
|
|
2621
|
-
ledIndicationDuration: durationInSeconds
|
|
2762
|
+
ledIndicationDuration: durationInSeconds,
|
|
2622
2763
|
};
|
|
2623
2764
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2624
2765
|
}
|
|
@@ -2641,7 +2782,7 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2641
2782
|
let tempLow = parseInt(commands[i + 2], 16);
|
|
2642
2783
|
let targetTemp = (tempHigh << 8) | tempLow;
|
|
2643
2784
|
let data = {
|
|
2644
|
-
offlineTargetTemperature: targetTemp === 0 ? 0 : targetTemp / 10
|
|
2785
|
+
offlineTargetTemperature: targetTemp === 0 ? 0 : targetTemp / 10,
|
|
2645
2786
|
};
|
|
2646
2787
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2647
2788
|
}
|
|
@@ -2681,14 +2822,14 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2681
2822
|
let temperatureLevels = {};
|
|
2682
2823
|
// Process 6 scale levels (0-5), each with a 2-byte temperature value
|
|
2683
2824
|
for (let level = 0; level < 6; level++) {
|
|
2684
|
-
let tempHighByte = parseInt(commands[i + 1 +
|
|
2685
|
-
let tempLowByte = parseInt(commands[i + 2 +
|
|
2825
|
+
let tempHighByte = parseInt(commands[i + 1 + level * 2], 16);
|
|
2826
|
+
let tempLowByte = parseInt(commands[i + 2 + level * 2], 16);
|
|
2686
2827
|
let tempValue = (tempHighByte << 8) | tempLowByte;
|
|
2687
2828
|
// The temperature values are pre-multiplied by 10
|
|
2688
2829
|
temperatureLevels['level' + level] = tempValue / 10;
|
|
2689
2830
|
}
|
|
2690
2831
|
let data = {
|
|
2691
|
-
temperatureLevels: temperatureLevels
|
|
2832
|
+
temperatureLevels: temperatureLevels,
|
|
2692
2833
|
};
|
|
2693
2834
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2694
2835
|
}
|
|
@@ -2732,7 +2873,7 @@ const commandsReadingHelper = (hexData, payloadLength, deviceType) => {
|
|
|
2732
2873
|
}
|
|
2733
2874
|
}
|
|
2734
2875
|
let data = {
|
|
2735
|
-
heatingEventStates: heatingEventStates
|
|
2876
|
+
heatingEventStates: heatingEventStates,
|
|
2736
2877
|
};
|
|
2737
2878
|
Object.assign(resultToPass, Object.assign({}, resultToPass), Object.assign({}, data));
|
|
2738
2879
|
}
|