homebridge-tasmota-control 1.6.15-beta.1 → 1.6.15-beta.10
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/config.schema.json +30 -12
- package/package.json +1 -1
- package/src/constants.js +10 -9
- package/src/mielhvac.js +374 -522
package/config.schema.json
CHANGED
|
@@ -519,7 +519,7 @@
|
|
|
519
519
|
"title": "Mode",
|
|
520
520
|
"type": "integer",
|
|
521
521
|
"minimum": 0,
|
|
522
|
-
"maximum":
|
|
522
|
+
"maximum": 60,
|
|
523
523
|
"default": 0,
|
|
524
524
|
"description": "Here select function.",
|
|
525
525
|
"oneOf": [
|
|
@@ -560,19 +560,19 @@
|
|
|
560
560
|
]
|
|
561
561
|
},
|
|
562
562
|
{
|
|
563
|
-
"title": "
|
|
563
|
+
"title": "VANE H LEFT",
|
|
564
564
|
"enum": [
|
|
565
|
-
|
|
565
|
+
10
|
|
566
566
|
]
|
|
567
567
|
},
|
|
568
568
|
{
|
|
569
|
-
"title": "VANE H LEFT",
|
|
569
|
+
"title": "VANE H LEFT MIDDLE",
|
|
570
570
|
"enum": [
|
|
571
571
|
11
|
|
572
572
|
]
|
|
573
573
|
},
|
|
574
574
|
{
|
|
575
|
-
"title": "VANE H LEFT
|
|
575
|
+
"title": "VANE H LEFT CENTER",
|
|
576
576
|
"enum": [
|
|
577
577
|
12
|
|
578
578
|
]
|
|
@@ -584,29 +584,35 @@
|
|
|
584
584
|
]
|
|
585
585
|
},
|
|
586
586
|
{
|
|
587
|
-
"title": "VANE H RIGHT
|
|
587
|
+
"title": "VANE H RIGHT",
|
|
588
588
|
"enum": [
|
|
589
589
|
14
|
|
590
590
|
]
|
|
591
591
|
},
|
|
592
592
|
{
|
|
593
|
-
"title": "VANE H RIGHT",
|
|
593
|
+
"title": "VANE H RIGHT MIDDLE",
|
|
594
594
|
"enum": [
|
|
595
595
|
15
|
|
596
596
|
]
|
|
597
597
|
},
|
|
598
598
|
{
|
|
599
|
-
"title": "VANE H
|
|
599
|
+
"title": "VANE H RIGHT CENTER",
|
|
600
600
|
"enum": [
|
|
601
601
|
16
|
|
602
602
|
]
|
|
603
603
|
},
|
|
604
604
|
{
|
|
605
|
-
"title": "VANE H
|
|
605
|
+
"title": "VANE H SPLIT",
|
|
606
606
|
"enum": [
|
|
607
607
|
17
|
|
608
608
|
]
|
|
609
609
|
},
|
|
610
|
+
{
|
|
611
|
+
"title": "VANE H SWING",
|
|
612
|
+
"enum": [
|
|
613
|
+
18
|
|
614
|
+
]
|
|
615
|
+
},
|
|
610
616
|
{
|
|
611
617
|
"title": "VANE V AUTO",
|
|
612
618
|
"enum": [
|
|
@@ -686,23 +692,29 @@
|
|
|
686
692
|
]
|
|
687
693
|
},
|
|
688
694
|
{
|
|
689
|
-
"title": "AIR DIRECTION
|
|
695
|
+
"title": "AIR DIRECTION INDIRECT",
|
|
690
696
|
"enum": [
|
|
691
697
|
40
|
|
692
698
|
]
|
|
693
699
|
},
|
|
694
700
|
{
|
|
695
|
-
"title": "AIR DIRECTION
|
|
701
|
+
"title": "AIR DIRECTION DIRECT",
|
|
696
702
|
"enum": [
|
|
697
703
|
41
|
|
698
704
|
]
|
|
699
705
|
},
|
|
700
706
|
{
|
|
701
|
-
"title": "AIR DIRECTION
|
|
707
|
+
"title": "AIR DIRECTION EVEN",
|
|
702
708
|
"enum": [
|
|
703
709
|
42
|
|
704
710
|
]
|
|
705
711
|
},
|
|
712
|
+
{
|
|
713
|
+
"title": "AIR DIRECTION OFF",
|
|
714
|
+
"enum": [
|
|
715
|
+
43
|
|
716
|
+
]
|
|
717
|
+
},
|
|
706
718
|
{
|
|
707
719
|
"title": "LOCK CONTROL All (only as sensor now)",
|
|
708
720
|
"enum": [
|
|
@@ -726,6 +738,12 @@
|
|
|
726
738
|
"enum": [
|
|
727
739
|
53
|
|
728
740
|
]
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
"title": "PURIFY (not implemented)",
|
|
744
|
+
"enum": [
|
|
745
|
+
60
|
|
746
|
+
]
|
|
729
747
|
}
|
|
730
748
|
],
|
|
731
749
|
"required": false
|
package/package.json
CHANGED
package/src/constants.js
CHANGED
|
@@ -34,7 +34,6 @@ export const MiElHVAC = {
|
|
|
34
34
|
"cool": "HVACSetMode%20cool",
|
|
35
35
|
"fan": "HVACSetMode%20fan",
|
|
36
36
|
"auto": "HVACSetMode%20auto",
|
|
37
|
-
"purify": "HVACSetMode%20purify"
|
|
38
37
|
},
|
|
39
38
|
"SetFanSpeed": {
|
|
40
39
|
"auto": "HVACSetFanSpeed%20auto",
|
|
@@ -57,20 +56,19 @@ export const MiElHVAC = {
|
|
|
57
56
|
"SetSwingH": {
|
|
58
57
|
"left": "HVACSetSwingH%20left",
|
|
59
58
|
"left_middle": "HVACSetSwingH%20left_middle",
|
|
59
|
+
"left_center": "HVACSetSwingH%20left_center",
|
|
60
60
|
"center": "HVACSetSwingH%20center",
|
|
61
|
-
"right_middle": "HVACSetSwingH%20right_middle",
|
|
62
61
|
"right": "HVACSetSwingH%20right",
|
|
62
|
+
"right_middle": "HVACSetSwingH%20right_middle",
|
|
63
|
+
"right_center": "HVACSetSwingH%20right_center",
|
|
63
64
|
"split": "HVACSetSwingH%20split",
|
|
64
65
|
"swing": "HVACSetSwingH%20swing",
|
|
65
|
-
"even": "HVACSetSwingH%20even",
|
|
66
|
-
"indirect": "HVACSetSwingH%20indirect",
|
|
67
|
-
"direct": "HVACSetSwingH%20direct",
|
|
68
66
|
},
|
|
69
67
|
"SetAirDirection": {
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"off": "
|
|
68
|
+
"indirect": "HVACSetAirDirection%20indirect",
|
|
69
|
+
"direct": "HVACSetAirDirection%20direct",
|
|
70
|
+
"even": "HVACSetAirDirection%20even",
|
|
71
|
+
"off": "HVACSetAirDirection%20off"
|
|
74
72
|
},
|
|
75
73
|
"SetProhibit": {
|
|
76
74
|
"off": "HVACSetProhibit%20off",
|
|
@@ -86,6 +84,9 @@ export const MiElHVAC = {
|
|
|
86
84
|
"c": "HVACSetDisplayUnit%20c",
|
|
87
85
|
"f": "HVACSetDisplayUnit%20f"
|
|
88
86
|
},
|
|
87
|
+
"SetPurify": {
|
|
88
|
+
"purify": "HVACSetPurify%20purify"
|
|
89
|
+
},
|
|
89
90
|
"RemoteTemp": "HVACRemoteTemp%20",
|
|
90
91
|
"RemoteTempClearTime": "HVACRemoteTempClearTime%20",
|
|
91
92
|
"OperationMode": [
|
package/src/mielhvac.js
CHANGED
|
@@ -200,15 +200,18 @@ class MiElHvac extends EventEmitter {
|
|
|
200
200
|
const statusSnsSupported = sensorStatusKeys.includes('StatusSNS');
|
|
201
201
|
const statusSns = statusSnsSupported ? sensorStatus.StatusSNS : {};
|
|
202
202
|
|
|
203
|
-
//power
|
|
204
|
-
const power1 = powerStatus.POWER == 'ON' ? 1 : 0;
|
|
205
|
-
|
|
206
203
|
//status SNS
|
|
207
204
|
const time = statusSns.Time ?? '';
|
|
208
205
|
const temperatureUnit = statusSns.TempUnit === 'C' ? '°C' : 'F';
|
|
209
206
|
|
|
210
207
|
//mielhvac
|
|
211
|
-
const miElHvac = statusSns.MiElHVAC
|
|
208
|
+
const miElHvac = statusSns.MiElHVAC;
|
|
209
|
+
|
|
210
|
+
if (!miElHvac || Object.keys(miElHvac).length === 0) {
|
|
211
|
+
this.emit('warn', "Empty data received");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
212
215
|
const power = miElHvac.Power === 'on' ? 1 : 0;
|
|
213
216
|
const roomTemperature = miElHvac.Temperature ?? null;
|
|
214
217
|
const outdoorTemperature = miElHvac.OutdoorTemperature ?? null;
|
|
@@ -220,6 +223,7 @@ class MiElHvac extends EventEmitter {
|
|
|
220
223
|
const vaneVerticalDirection = miElHvac.SwingV ?? 'Unknown';
|
|
221
224
|
const vaneHorizontalDirection = miElHvac.SwingH ?? 'Unknown';
|
|
222
225
|
const prohibit = miElHvac.Prohibit ?? 'Unknown';
|
|
226
|
+
const purify = miElHvac.Purify ?? 'Unknown';
|
|
223
227
|
const airDirection = miElHvac.AirDirection ?? 'Unknown';
|
|
224
228
|
const compressor = miElHvac.Compressor ?? 'Unknown';
|
|
225
229
|
const compressorFrequency = miElHvac.CompressorFrequency ?? 0;
|
|
@@ -259,6 +263,7 @@ class MiElHvac extends EventEmitter {
|
|
|
259
263
|
vaneVerticalDirection: vaneVerticalDirection,
|
|
260
264
|
vaneHorizontalDirection: vaneHorizontalDirection,
|
|
261
265
|
prohibit: prohibit,
|
|
266
|
+
purify: purify,
|
|
262
267
|
airDirection: airDirection,
|
|
263
268
|
swingMode: swingMode,
|
|
264
269
|
compressor: compressor,
|
|
@@ -285,7 +290,7 @@ class MiElHvac extends EventEmitter {
|
|
|
285
290
|
hideVaneControls: hideVaneControls
|
|
286
291
|
};
|
|
287
292
|
|
|
288
|
-
//
|
|
293
|
+
// Map stages to index safely, fallback to 0 if not found
|
|
289
294
|
const operationModeStageMap = {
|
|
290
295
|
'manual': 0,
|
|
291
296
|
'heat': 2,
|
|
@@ -300,37 +305,39 @@ class MiElHvac extends EventEmitter {
|
|
|
300
305
|
'auto_cool': 3,
|
|
301
306
|
'auto_leader': 4
|
|
302
307
|
};
|
|
308
|
+
|
|
309
|
+
const stageIndex = operationModeStageMap[operationModeStage] ?? 0;
|
|
303
310
|
switch (operationMode) {
|
|
304
311
|
case 'heat':
|
|
305
|
-
obj.currentOperationMode = [2, 1, 2, 3, 0][
|
|
306
|
-
obj.targetOperationMode = 1; //AUTO, HEAT, COOL
|
|
312
|
+
obj.currentOperationMode = [2, 1, 2, 3, 0][stageIndex]; // INACTIVE, IDLE, HEATING, COOLING
|
|
313
|
+
obj.targetOperationMode = 1; // AUTO, HEAT, COOL
|
|
307
314
|
break;
|
|
308
315
|
case 'dry':
|
|
309
|
-
obj.currentOperationMode = [1, 1, 2, 3, 0][
|
|
316
|
+
obj.currentOperationMode = [1, 1, 2, 3, 0][stageIndex];
|
|
310
317
|
obj.targetOperationMode = this.autoDryFanMode === 2 ? 0 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : obj.targetOperationMode;
|
|
311
318
|
break;
|
|
312
319
|
case 'cool':
|
|
313
|
-
obj.currentOperationMode = [3, 1, 2, 3, 0][
|
|
320
|
+
obj.currentOperationMode = [3, 1, 2, 3, 0][stageIndex];
|
|
314
321
|
obj.targetOperationMode = 2;
|
|
315
322
|
break;
|
|
316
323
|
case 'fan':
|
|
317
|
-
obj.currentOperationMode = [1, 1, 2, 3, 0][
|
|
324
|
+
obj.currentOperationMode = [1, 1, 2, 3, 0][stageIndex];
|
|
318
325
|
obj.targetOperationMode = this.autoDryFanMode === 3 ? 0 : this.heatDryFanMode === 3 ? 1 : this.coolDryFanMode === 3 ? 2 : obj.targetOperationMode;
|
|
319
326
|
break;
|
|
320
327
|
case 'auto':
|
|
321
|
-
obj.currentOperationMode = [2, 1, 2, 3, 0][
|
|
328
|
+
obj.currentOperationMode = [2, 1, 2, 3, 0][stageIndex];
|
|
322
329
|
obj.targetOperationMode = 0;
|
|
323
330
|
break;
|
|
324
331
|
case 'heat_isee':
|
|
325
|
-
obj.currentOperationMode = [2, 1, 2, 3, 0][
|
|
332
|
+
obj.currentOperationMode = [2, 1, 2, 3, 0][stageIndex];
|
|
326
333
|
obj.targetOperationMode = 1;
|
|
327
334
|
break;
|
|
328
335
|
case 'dry_isee':
|
|
329
|
-
obj.currentOperationMode = [1, 1, 2, 3, 0][
|
|
336
|
+
obj.currentOperationMode = [1, 1, 2, 3, 0][stageIndex];
|
|
330
337
|
obj.targetOperationMode = this.autoDryFanMode === 2 ? 0 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : obj.targetOperationMode;
|
|
331
338
|
break;
|
|
332
339
|
case 'cool_isee':
|
|
333
|
-
obj.currentOperationMode = [3, 1, 2, 3, 0][
|
|
340
|
+
obj.currentOperationMode = [3, 1, 2, 3, 0][stageIndex];
|
|
334
341
|
obj.targetOperationMode = 2;
|
|
335
342
|
break;
|
|
336
343
|
default:
|
|
@@ -338,13 +345,16 @@ class MiElHvac extends EventEmitter {
|
|
|
338
345
|
return;
|
|
339
346
|
}
|
|
340
347
|
|
|
348
|
+
// If power is off, force currentOperationMode to 0 (inactive)
|
|
341
349
|
obj.currentOperationMode = !power ? 0 : obj.currentOperationMode;
|
|
350
|
+
|
|
351
|
+
// Set min/max/valid values for operation mode controls
|
|
342
352
|
obj.operationModeSetPropsMinValue = modelSupportsAuto && modelSupportsHeat ? 0 : !modelSupportsAuto && modelSupportsHeat ? 1 : modelSupportsAuto && !modelSupportsHeat ? 0 : 2;
|
|
343
|
-
obj.operationModeSetPropsMaxValue = 2
|
|
353
|
+
obj.operationModeSetPropsMaxValue = 2;
|
|
344
354
|
obj.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : !modelSupportsAuto && modelSupportsHeat ? [1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2] : [2];
|
|
345
355
|
|
|
356
|
+
|
|
346
357
|
if (modelSupportsFanSpeed) {
|
|
347
|
-
//fan speed mode
|
|
348
358
|
const fanSpeedMap = {
|
|
349
359
|
'auto': 0,
|
|
350
360
|
'quiet': 1,
|
|
@@ -354,376 +364,284 @@ class MiElHvac extends EventEmitter {
|
|
|
354
364
|
'4': 5
|
|
355
365
|
};
|
|
356
366
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
367
|
+
const fanIndex = fanSpeedMap[fanSpeed];
|
|
368
|
+
obj.fanSpeed = 0;
|
|
369
|
+
obj.fanSpeedSetPropsMaxValue = 0;
|
|
370
|
+
|
|
371
|
+
if (typeof fanIndex === 'number') {
|
|
372
|
+
switch (numberOfFanSpeeds) {
|
|
373
|
+
case 2:
|
|
374
|
+
obj.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][fanIndex] ?? 1 : [0, 1, 2][fanIndex] ?? 1;
|
|
375
|
+
obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
|
|
376
|
+
break;
|
|
377
|
+
case 3:
|
|
378
|
+
obj.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][fanIndex] ?? 1 : [0, 1, 2, 3][fanIndex] ?? 1;
|
|
379
|
+
obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
|
|
380
|
+
break;
|
|
381
|
+
case 4:
|
|
382
|
+
obj.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][fanIndex] ?? 1 : [0, 1, 2, 3, 4][fanIndex] ?? 1;
|
|
383
|
+
obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
|
|
384
|
+
break;
|
|
385
|
+
case 5:
|
|
386
|
+
obj.fanSpeed = hasAutomaticFanSpeed ? [6, 1, 2, 3, 4, 5][fanIndex] ?? 1 : [0, 1, 2, 3, 4, 5][fanIndex] ?? 1;
|
|
387
|
+
obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 6 : 5;
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Cap value to max
|
|
392
|
+
if (obj.fanSpeed > obj.fanSpeedSetPropsMaxValue) {
|
|
393
|
+
obj.fanSpeed = obj.fanSpeedSetPropsMaxValue;
|
|
394
|
+
}
|
|
374
395
|
}
|
|
375
396
|
}
|
|
397
|
+
|
|
376
398
|
this.mielHvac = obj;
|
|
377
399
|
|
|
378
400
|
//update characteristics
|
|
379
401
|
if (this.miElHvacService) {
|
|
380
|
-
this.miElHvacService
|
|
381
|
-
|
|
402
|
+
const svc = this.miElHvacService;
|
|
403
|
+
|
|
404
|
+
svc.updateCharacteristic(Characteristic.Active, power)
|
|
382
405
|
.updateCharacteristic(Characteristic.CurrentHeaterCoolerState, obj.currentOperationMode)
|
|
383
406
|
.updateCharacteristic(Characteristic.TargetHeaterCoolerState, obj.targetOperationMode)
|
|
384
407
|
.updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
|
|
385
408
|
.updateCharacteristic(Characteristic.LockPhysicalControls, lockPhysicalControl)
|
|
386
409
|
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, useFahrenheit)
|
|
387
410
|
.updateCharacteristic(Characteristic.SwingMode, swingMode);
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
411
|
+
|
|
412
|
+
if (obj.targetOperationMode === 0 || obj.targetOperationMode === 2) {
|
|
413
|
+
svc.updateCharacteristic(
|
|
414
|
+
Characteristic.CoolingThresholdTemperature,
|
|
415
|
+
obj.targetOperationMode === 0 ? defaultCoolingSetTemperature : setTemperature
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (obj.targetOperationMode === 0 || obj.targetOperationMode === 1) {
|
|
420
|
+
svc.updateCharacteristic(
|
|
421
|
+
Characteristic.HeatingThresholdTemperature,
|
|
422
|
+
obj.targetOperationMode === 0 ? defaultHeatingSetTemperature : setTemperature
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (modelSupportsFanSpeed) {
|
|
427
|
+
svc.updateCharacteristic(Characteristic.RotationSpeed, obj.fanSpeed);
|
|
428
|
+
}
|
|
391
429
|
|
|
392
430
|
if (this.frostProtectEnable) {
|
|
393
431
|
if (roomTemperature <= this.frostProtectLowTemp && !power) {
|
|
394
|
-
|
|
395
|
-
.setCharacteristic(Characteristic.Active, true)
|
|
432
|
+
svc.setCharacteristic(Characteristic.Active, true)
|
|
396
433
|
.setCharacteristic(Characteristic.TargetHeaterCoolerState, 1)
|
|
397
434
|
.setCharacteristic(Characteristic.HeatingThresholdTemperature, this.frostProtectHighTemp);
|
|
398
435
|
this.frostProtectActive = true;
|
|
399
|
-
|
|
400
436
|
}
|
|
401
437
|
|
|
402
438
|
if (roomTemperature >= this.frostProtectHighTemp && this.frostProtectActive) {
|
|
403
|
-
|
|
439
|
+
svc.setCharacteristic(Characteristic.Active, false);
|
|
404
440
|
this.frostProtectActive = false;
|
|
405
441
|
}
|
|
406
442
|
}
|
|
407
443
|
}
|
|
408
444
|
|
|
409
|
-
//
|
|
445
|
+
// Update presets state
|
|
410
446
|
if (this.presetsConfiguredCount > 0) {
|
|
411
447
|
this.presetsConfigured.forEach((preset, index) => {
|
|
412
|
-
|
|
413
448
|
let iseeMode = operationMode;
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
449
|
+
if (iseeMode === 'heat_isee') iseeMode = 'heat';
|
|
450
|
+
else if (iseeMode === 'dry_isee') iseeMode = 'dry';
|
|
451
|
+
else if (iseeMode === 'cool_isee') iseeMode = 'cool';
|
|
417
452
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
453
|
+
const sameTemp = Number(preset.setTemp).toFixed(1) === Number(setTemperature).toFixed(1);
|
|
454
|
+
const sameFan = preset.fanSpeed === fanSpeed;
|
|
455
|
+
const sameSwingV = preset.swingV === vaneVerticalDirection;
|
|
456
|
+
const sameSwingH = preset.swingH === vaneHorizontalDirection;
|
|
457
|
+
const sameMode = preset.mode === iseeMode;
|
|
458
|
+
|
|
459
|
+
preset.state = power ? (sameMode && sameTemp && sameFan && sameSwingV && sameSwingH) : false;
|
|
423
460
|
|
|
424
461
|
if (this.presetsServices) {
|
|
425
|
-
const characteristicType = preset.characteristicType;
|
|
426
462
|
this.presetsServices[index]
|
|
427
|
-
.updateCharacteristic(characteristicType, preset.state);
|
|
463
|
+
.updateCharacteristic(preset.characteristicType, preset.state);
|
|
428
464
|
}
|
|
429
465
|
});
|
|
430
466
|
}
|
|
431
467
|
|
|
432
|
-
//update buttons state
|
|
433
468
|
if (this.buttonsConfiguredCount > 0) {
|
|
469
|
+
const modeMap = {
|
|
470
|
+
0: () => power === 1,
|
|
471
|
+
1: () => power && ['heat', 'heat_isee'].includes(operationMode),
|
|
472
|
+
2: () => power && ['dry', 'dry_isee'].includes(operationMode),
|
|
473
|
+
3: () => power && ['cool', 'cool_isee'].includes(operationMode),
|
|
474
|
+
4: () => power && operationMode === 'fan',
|
|
475
|
+
5: () => power && operationMode === 'auto',
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const vaneHMap = {
|
|
479
|
+
10: 'left',
|
|
480
|
+
11: 'left_middle',
|
|
481
|
+
12: 'left_center',
|
|
482
|
+
13: 'center',
|
|
483
|
+
14: 'right',
|
|
484
|
+
15: 'right_middle',
|
|
485
|
+
16: 'right_center',
|
|
486
|
+
17: 'split',
|
|
487
|
+
18: 'swing',
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
const vaneVMap = {
|
|
491
|
+
20: 'auto',
|
|
492
|
+
21: 'up',
|
|
493
|
+
22: 'up_middle',
|
|
494
|
+
23: 'center',
|
|
495
|
+
24: 'down_middle',
|
|
496
|
+
25: 'down',
|
|
497
|
+
26: 'swing',
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
const fanSpeedMap = {
|
|
501
|
+
30: 'auto',
|
|
502
|
+
31: 'quiet',
|
|
503
|
+
32: '1',
|
|
504
|
+
33: '2',
|
|
505
|
+
34: '3',
|
|
506
|
+
35: '4',
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
const airDirMap = {
|
|
510
|
+
40: () => power && airDirection === 'indirect',
|
|
511
|
+
41: () => power && airDirection === 'direct',
|
|
512
|
+
42: () => power && airDirection === 'even',
|
|
513
|
+
43: () => power && !['indirect', 'direct', 'even'].includes(airDirection),
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const prohibitMap = {
|
|
517
|
+
50: 'all',
|
|
518
|
+
51: 'power',
|
|
519
|
+
52: 'mode',
|
|
520
|
+
53: 'temp',
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
const purifyMap = {
|
|
524
|
+
60: () => power && purify === 'on',
|
|
525
|
+
};
|
|
526
|
+
|
|
434
527
|
this.buttonsConfigured.forEach((button, index) => {
|
|
435
528
|
const mode = button.mode;
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
break;
|
|
455
|
-
case 6: //OPERATING MODE PURIFY
|
|
456
|
-
button.state = power ? (operationMode === 'purify') : false;
|
|
457
|
-
break;
|
|
458
|
-
case 11: //VANE H LEFT
|
|
459
|
-
button.state = power ? (vaneHorizontalDirection === 'left') : false;
|
|
460
|
-
break;
|
|
461
|
-
case 12: //VANE H LEFT MIDDLE
|
|
462
|
-
button.state = power ? (vaneHorizontalDirection === 'left_middle') : false;
|
|
463
|
-
break;
|
|
464
|
-
case 13: //VANE H CENTER
|
|
465
|
-
button.state = power ? (vaneHorizontalDirection === 'center') : false;
|
|
466
|
-
break;
|
|
467
|
-
case 14: //VANE H RIGHT MIDDLE
|
|
468
|
-
button.state = power ? (vaneHorizontalDirection === 'right_middle') : false;
|
|
469
|
-
break;
|
|
470
|
-
case 15: //VANE H RIGHT
|
|
471
|
-
button.state = power ? (vaneHorizontalDirection === 'right') : false;
|
|
472
|
-
break;
|
|
473
|
-
case 16: //VANE H SPLIT
|
|
474
|
-
button.state = power ? (vaneHorizontalDirection === 'split') : false;
|
|
475
|
-
break;
|
|
476
|
-
case 17: //VANE H SWING
|
|
477
|
-
button.state = power ? (vaneHorizontalDirection === 'swing') : false;
|
|
478
|
-
break;
|
|
479
|
-
case 20: //VANE V AUTO
|
|
480
|
-
button.state = power ? (vaneVerticalDirection === 'auto') : false;
|
|
481
|
-
break;
|
|
482
|
-
case 21: //VANE V UP
|
|
483
|
-
button.state = power ? (vaneVerticalDirection === 'up') : false;
|
|
484
|
-
break;
|
|
485
|
-
case 22: //VANE V UP MIDDLE
|
|
486
|
-
button.state = power ? (vaneVerticalDirection === 'up_middle') : false;
|
|
487
|
-
break;
|
|
488
|
-
case 23: //VANE V CENTER
|
|
489
|
-
button.state = power ? (vaneVerticalDirection === 'center') : false;
|
|
490
|
-
break;
|
|
491
|
-
case 24: //VANE V DOWN MIDDLE
|
|
492
|
-
button.state = power ? (vaneVerticalDirection === 'down_middle') : false;
|
|
493
|
-
break;
|
|
494
|
-
case 25: //VANE V DOWN
|
|
495
|
-
button.state = power ? (vaneVerticalDirection === 'down') : false;
|
|
496
|
-
break;
|
|
497
|
-
case 26: //VANE V SWING
|
|
498
|
-
button.state = power ? (vaneVerticalDirection === 'swing') : false;
|
|
499
|
-
break;
|
|
500
|
-
case 30: //FAN SPEED MODE AUTO
|
|
501
|
-
button.state = power ? (fanSpeed === 'auto') : false;
|
|
502
|
-
break;
|
|
503
|
-
case 31: //FAN SPEED MODE 1
|
|
504
|
-
button.state = power ? (fanSpeed === 'quiet') : false;
|
|
505
|
-
break;
|
|
506
|
-
case 32: //FAN SPEED MODE 2
|
|
507
|
-
button.state = power ? (fanSpeed === '1') : false;
|
|
508
|
-
break;
|
|
509
|
-
case 33: //FAN SPEED MODE 3
|
|
510
|
-
button.state = power ? (fanSpeed === '2') : false;
|
|
511
|
-
break;
|
|
512
|
-
case 34: //FAN SPEED MODE 4
|
|
513
|
-
button.state = power ? (fanSpeed === '3') : false;
|
|
514
|
-
break;
|
|
515
|
-
case 35: //FAN SPEED MODE 5
|
|
516
|
-
button.state = power ? (fanSpeed === '4') : false;
|
|
517
|
-
break;
|
|
518
|
-
case 40: //AIR DIRECTION EVEN
|
|
519
|
-
button.state = power ? (airDirection === 'even') : false;
|
|
520
|
-
break;
|
|
521
|
-
case 41: //AIR DIRECTION INDIRECT
|
|
522
|
-
button.state = power ? (airDirection === 'indirect') : false;
|
|
523
|
-
break;
|
|
524
|
-
case 42: //AIR DIRECTION DIRECT
|
|
525
|
-
button.state = power ? (airDirection === 'direct') : false;
|
|
526
|
-
break;
|
|
527
|
-
case 50: //PHYSICAL LOCK CONTROLS ALL
|
|
528
|
-
button.state = prohibit === 'all';
|
|
529
|
-
break;
|
|
530
|
-
case 51: //PHYSICAL LOCK CONTROLS POWER
|
|
531
|
-
button.state = prohibit === 'power';
|
|
532
|
-
break;
|
|
533
|
-
case 52: //PHYSICAL LOCK CONTROLS MODE
|
|
534
|
-
button.state = prohibit === 'mode';
|
|
535
|
-
break;
|
|
536
|
-
case 53: //PHYSICAL LOCK CONTROLS TEMP
|
|
537
|
-
button.state = prohibit === 'temp';
|
|
538
|
-
break;
|
|
539
|
-
default: //Unknown button
|
|
540
|
-
this.emit('warn', `Unknown button mode: ${mode} detected`);
|
|
541
|
-
break;
|
|
529
|
+
let state = false;
|
|
530
|
+
|
|
531
|
+
if (modeMap[mode] !== undefined) {
|
|
532
|
+
state = modeMap[mode]();
|
|
533
|
+
} else if (vaneHMap[mode]) {
|
|
534
|
+
state = power && vaneHorizontalDirection === vaneHMap[mode];
|
|
535
|
+
} else if (vaneVMap[mode]) {
|
|
536
|
+
state = power && vaneVerticalDirection === vaneVMap[mode];
|
|
537
|
+
} else if (fanSpeedMap[mode]) {
|
|
538
|
+
state = power && fanSpeed === fanSpeedMap[mode];
|
|
539
|
+
} else if (airDirMap[mode]) {
|
|
540
|
+
state = airDirMap[mode]();
|
|
541
|
+
} else if (prohibitMap[mode] !== undefined) {
|
|
542
|
+
state = prohibit === prohibitMap[mode];
|
|
543
|
+
} else if (purifyMap[mode] !== undefined) {
|
|
544
|
+
state = purify === purifyMap[mode];
|
|
545
|
+
} else {
|
|
546
|
+
this.emit('warn', `Unknown button mode: ${mode} detected`);
|
|
542
547
|
}
|
|
543
548
|
|
|
544
|
-
|
|
549
|
+
button.state = state;
|
|
550
|
+
|
|
545
551
|
if (this.buttonsServices) {
|
|
546
552
|
const characteristicType = button.characteristicType;
|
|
547
553
|
this.buttonsServices[index]
|
|
548
|
-
.updateCharacteristic(characteristicType,
|
|
554
|
+
.updateCharacteristic(characteristicType, state);
|
|
549
555
|
}
|
|
550
556
|
});
|
|
551
557
|
}
|
|
552
558
|
|
|
553
|
-
//update sensors state
|
|
554
559
|
if (this.sensorsConfiguredCount > 0) {
|
|
560
|
+
const powerOn = power === 1;
|
|
561
|
+
|
|
562
|
+
// Helper: match by value with power check
|
|
563
|
+
const is = (val, match) => powerOn && val === match;
|
|
564
|
+
const isOneOf = (val, matches) => powerOn && matches.includes(val);
|
|
565
|
+
|
|
555
566
|
this.sensorsConfigured.forEach((sensor, index) => {
|
|
556
567
|
const mode = sensor.mode;
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
sensor.state = power ? (fanSpeed === 'auto') : false;
|
|
629
|
-
break;
|
|
630
|
-
case 31: //FAN SPEED MODE 1
|
|
631
|
-
sensor.state = power ? (fanSpeed === 'quiet') : false;
|
|
632
|
-
break;
|
|
633
|
-
case 32: //FAN SPEED MODE 2
|
|
634
|
-
sensor.state = power ? (fanSpeed === '1') : false;
|
|
635
|
-
break;
|
|
636
|
-
case 33: //FAN SPEED MODE 3
|
|
637
|
-
sensor.state = power ? (fanSpeed === '2') : false;
|
|
638
|
-
break;
|
|
639
|
-
case 34: //FAN SPEED MODE 4
|
|
640
|
-
sensor.state = power ? (fanSpeed === '3') : false;
|
|
641
|
-
break;
|
|
642
|
-
case 35: //FAN SPEED MODE 5
|
|
643
|
-
sensor.state = power ? (fanSpeed === '4') : false;
|
|
644
|
-
break;
|
|
645
|
-
case 40: //AIR DIRECTION EVEN
|
|
646
|
-
sensor.state = power ? (airDirection === 'even') : false;
|
|
647
|
-
break;
|
|
648
|
-
case 41: //AIR DIRECTION INDIRECT
|
|
649
|
-
sensor.state = power ? (airDirection === 'indirect') : false;
|
|
650
|
-
break;
|
|
651
|
-
case 42: //AIR DIRECTION DIRECT
|
|
652
|
-
sensor.state = power ? (airDirection === 'direct') : false;
|
|
653
|
-
break;
|
|
654
|
-
case 50: //PHYSICAL LOCK CONTROLS ALL
|
|
655
|
-
sensor.state = prohibit === 'all';
|
|
656
|
-
break;
|
|
657
|
-
case 51: //PHYSICAL LOCK CONTROLS POWER
|
|
658
|
-
sensor.state = prohibit === 'power';
|
|
659
|
-
break;
|
|
660
|
-
case 52: //PHYSICAL LOCK CONTROLS MODE
|
|
661
|
-
sensor.state = prohibit === 'mode';
|
|
662
|
-
break;
|
|
663
|
-
case 53: //PHYSICAL LOCK CONTROLS TEMP
|
|
664
|
-
sensor.state = prohibit === 'temp';
|
|
665
|
-
break;
|
|
666
|
-
case 60: //REMOTE TEMPERATURE STATE
|
|
667
|
-
sensor.state = remoteTemperatureSensorState;
|
|
668
|
-
break;
|
|
669
|
-
case 70: //OPERATION STAGE NORMAL
|
|
670
|
-
sensor.state = operationStage === 'normal';
|
|
671
|
-
break;
|
|
672
|
-
case 71: //OPERATION STAGE DEFROST
|
|
673
|
-
sensor.state = operationStage === 'defrost';
|
|
674
|
-
break;
|
|
675
|
-
case 72: //OPERATION STAGE PREHEAT
|
|
676
|
-
sensor.state = operationStage === 'preheat';
|
|
677
|
-
break;
|
|
678
|
-
case 73: //OPERATION STAGE STANDBY
|
|
679
|
-
sensor.state = operationStage === 'standby';
|
|
680
|
-
break;
|
|
681
|
-
case 80: //FAN STAGE OFF
|
|
682
|
-
sensor.state = fanSpeedStage === 'off';
|
|
683
|
-
break;
|
|
684
|
-
case 81: //FAN STAGE QUIET
|
|
685
|
-
sensor.state = fanSpeedStage === 'quiet';;
|
|
686
|
-
break;
|
|
687
|
-
case 82: //FAN STAGE 1
|
|
688
|
-
sensor.state = fanSpeedStage === '1';;
|
|
689
|
-
break;
|
|
690
|
-
case 83: //FAN STAGE 2
|
|
691
|
-
sensor.state = fanSpeedStage === '2';;
|
|
692
|
-
break;
|
|
693
|
-
case 84: //FAN STAGE 3
|
|
694
|
-
sensor.state = fanSpeedStage === '3';;
|
|
695
|
-
break;
|
|
696
|
-
case 85: //FAN STAGE 4
|
|
697
|
-
sensor.state = fanSpeedStage === '4';;
|
|
698
|
-
break;
|
|
699
|
-
case 86: //FAN STAGE 5
|
|
700
|
-
sensor.state = fanSpeedStage === '5';;
|
|
701
|
-
break;
|
|
702
|
-
case 90: //MODE STAGE AUTO OFF
|
|
703
|
-
sensor.state = operationMode !== 'auto';
|
|
704
|
-
break;
|
|
705
|
-
case 91: //MODE STAGE AUTO FAN
|
|
706
|
-
sensor.state = operationModeStage === 'auto_fan';
|
|
707
|
-
break;
|
|
708
|
-
case 92: //MODE STAGE AUTO HEAT
|
|
709
|
-
sensor.state = operationModeStage === 'auto_heat';
|
|
710
|
-
break;
|
|
711
|
-
case 93: //MODE STAGE AUTO COOL
|
|
712
|
-
sensor.state = operationModeStage === 'auto_cool';;
|
|
713
|
-
break;
|
|
714
|
-
case 94: //MODE STAGE AUTO LEADER
|
|
715
|
-
sensor.state = operationModeStage === 'auto_leader';;
|
|
716
|
-
break;
|
|
717
|
-
default: //Unknown sensor
|
|
718
|
-
this.emit('warn', `Unknown sensor mode: ${mode} detected`);
|
|
719
|
-
break;
|
|
568
|
+
|
|
569
|
+
const sensorStates = {
|
|
570
|
+
0: powerOn,
|
|
571
|
+
1: isOneOf(operationMode, ['heat', 'heat_isee']),
|
|
572
|
+
2: isOneOf(operationMode, ['dry', 'dry_isee']),
|
|
573
|
+
3: isOneOf(operationMode, ['cool', 'cool_isee']),
|
|
574
|
+
4: is(operationMode, 'fan'),
|
|
575
|
+
5: is(operationMode, 'auto'),
|
|
576
|
+
6: is(operationMode, 'purify'),
|
|
577
|
+
|
|
578
|
+
11: is(vaneHorizontalDirection, 'left'),
|
|
579
|
+
12: is(vaneHorizontalDirection, 'left_middle'),
|
|
580
|
+
13: is(vaneHorizontalDirection, 'center'),
|
|
581
|
+
14: is(vaneHorizontalDirection, 'right_middle'),
|
|
582
|
+
15: is(vaneHorizontalDirection, 'right'),
|
|
583
|
+
16: is(vaneHorizontalDirection, 'split'),
|
|
584
|
+
17: is(vaneHorizontalDirection, 'swing'),
|
|
585
|
+
|
|
586
|
+
20: is(vaneVerticalDirection, 'auto'),
|
|
587
|
+
21: is(vaneVerticalDirection, 'up'),
|
|
588
|
+
22: is(vaneVerticalDirection, 'up_middle'),
|
|
589
|
+
23: is(vaneVerticalDirection, 'center'),
|
|
590
|
+
24: is(vaneVerticalDirection, 'down_middle'),
|
|
591
|
+
25: is(vaneVerticalDirection, 'down'),
|
|
592
|
+
26: is(vaneVerticalDirection, 'swing'),
|
|
593
|
+
|
|
594
|
+
27: is(hideVaneControls, true),
|
|
595
|
+
|
|
596
|
+
30: is(fanSpeed, 'auto'),
|
|
597
|
+
31: is(fanSpeed, 'quiet'),
|
|
598
|
+
32: is(fanSpeed, '1'),
|
|
599
|
+
33: is(fanSpeed, '2'),
|
|
600
|
+
34: is(fanSpeed, '3'),
|
|
601
|
+
35: is(fanSpeed, '4'),
|
|
602
|
+
|
|
603
|
+
40: is(airDirection, 'indirect'),
|
|
604
|
+
41: is(airDirection, 'direct'),
|
|
605
|
+
42: is(airDirection, 'even'),
|
|
606
|
+
43: powerOn && !['indirect', 'direct', 'even'].includes(airDirection),
|
|
607
|
+
|
|
608
|
+
50: prohibit === 'all',
|
|
609
|
+
51: prohibit === 'power',
|
|
610
|
+
52: prohibit === 'mode',
|
|
611
|
+
53: prohibit === 'temp',
|
|
612
|
+
|
|
613
|
+
60: remoteTemperatureSensorState,
|
|
614
|
+
|
|
615
|
+
70: operationStage === 'normal',
|
|
616
|
+
71: operationStage === 'defrost',
|
|
617
|
+
72: operationStage === 'preheat',
|
|
618
|
+
73: operationStage === 'standby',
|
|
619
|
+
|
|
620
|
+
80: fanSpeedStage === 'off',
|
|
621
|
+
81: fanSpeedStage === 'quiet',
|
|
622
|
+
82: fanSpeedStage === '1',
|
|
623
|
+
83: fanSpeedStage === '2',
|
|
624
|
+
84: fanSpeedStage === '3',
|
|
625
|
+
85: fanSpeedStage === '4',
|
|
626
|
+
86: fanSpeedStage === '5',
|
|
627
|
+
|
|
628
|
+
90: operationMode !== 'auto',
|
|
629
|
+
91: operationModeStage === 'auto_fan',
|
|
630
|
+
92: operationModeStage === 'auto_heat',
|
|
631
|
+
93: operationModeStage === 'auto_cool',
|
|
632
|
+
94: operationModeStage === 'auto_leader',
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
if (mode in sensorStates) {
|
|
636
|
+
sensor.state = sensorStates[mode];
|
|
637
|
+
} else {
|
|
638
|
+
this.emit('warn', `Unknown sensor mode: ${mode} detected`);
|
|
720
639
|
}
|
|
721
640
|
|
|
722
|
-
//
|
|
641
|
+
// Update characteristic
|
|
723
642
|
if (this.sensorsServices) {
|
|
724
643
|
const characteristicType = sensor.characteristicType;
|
|
725
|
-
this.sensorsServices[index]
|
|
726
|
-
.updateCharacteristic(characteristicType, sensor.state);
|
|
644
|
+
this.sensorsServices[index]?.updateCharacteristic(characteristicType, sensor.state);
|
|
727
645
|
}
|
|
728
646
|
});
|
|
729
647
|
}
|
|
@@ -1066,242 +984,176 @@ class MiElHvac extends EventEmitter {
|
|
|
1066
984
|
|
|
1067
985
|
//presets services
|
|
1068
986
|
if (this.presetsConfiguredCount > 0) {
|
|
1069
|
-
|
|
987
|
+
if (this.enableDebugMode) this.emit('debug', 'Prepare presets services');
|
|
1070
988
|
this.presetsServices = [];
|
|
1071
989
|
|
|
1072
990
|
this.presetsConfigured.forEach((preset, index) => {
|
|
1073
|
-
|
|
1074
|
-
const
|
|
991
|
+
const { name: presetName, namePrefix, serviceType, characteristicType, mode, setTemp, fanSpeed, swingV, swingH } = preset;
|
|
992
|
+
const serviceName = namePrefix ? `${accessoryName} ${presetName}` : presetName;
|
|
1075
993
|
|
|
1076
|
-
//get preset name prefix
|
|
1077
|
-
const presetNamePrefix = preset.namePrefix;
|
|
1078
|
-
|
|
1079
|
-
const serviceName = presetNamePrefix ? `${accessoryName} ${presetName}` : presetName;
|
|
1080
|
-
const serviceType = preset.serviceType;
|
|
1081
|
-
const characteristicType = preset.characteristicType;
|
|
1082
994
|
const presetService = new serviceType(serviceName, `Preset ${index}`);
|
|
1083
995
|
presetService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
1084
996
|
presetService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
997
|
+
|
|
1085
998
|
presetService.getCharacteristic(characteristicType)
|
|
1086
|
-
.onGet(async () =>
|
|
1087
|
-
const state = preset.state;
|
|
1088
|
-
return state;
|
|
1089
|
-
})
|
|
999
|
+
.onGet(async () => preset.state)
|
|
1090
1000
|
.onSet(async (state) => {
|
|
1091
1001
|
try {
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1002
|
+
if (state) {
|
|
1003
|
+
// Power on if needed
|
|
1004
|
+
if (!this.mielHvac.power) {
|
|
1005
|
+
await this.axiosInstance(MiElHVAC.PowerOn);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// Apply preset commands in sequence
|
|
1009
|
+
const commands = [
|
|
1010
|
+
MiElHVAC.SetMode[mode],
|
|
1011
|
+
`${MiElHVAC.SetTemp}${setTemp}`,
|
|
1012
|
+
MiElHVAC.SetFanSpeed[fanSpeed],
|
|
1013
|
+
MiElHVAC.SetSwingV[swingV],
|
|
1014
|
+
MiElHVAC.SetSwingH[swingH]
|
|
1015
|
+
];
|
|
1016
|
+
|
|
1017
|
+
for (const cmd of commands) {
|
|
1018
|
+
await this.axiosInstance(cmd);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (!this.disableLogInfo) {
|
|
1022
|
+
this.emit('info', `Set: ${presetName}`);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
await new Promise(resolve => setTimeout(resolve, 250));
|
|
1109
1026
|
}
|
|
1110
|
-
|
|
1111
|
-
const info = this.disableLogInfo || !state ? false : this.emit('info', `Set: ${presetName}`);
|
|
1112
|
-
await new Promise(resolve => setTimeout(resolve, 250));
|
|
1113
1027
|
} catch (error) {
|
|
1114
1028
|
this.emit('warn', `Set preset error: ${error}`);
|
|
1115
1029
|
}
|
|
1116
1030
|
});
|
|
1031
|
+
|
|
1117
1032
|
this.presetsServices.push(presetService);
|
|
1118
1033
|
accessory.addService(presetService);
|
|
1119
1034
|
});
|
|
1120
1035
|
}
|
|
1121
1036
|
|
|
1122
|
-
|
|
1037
|
+
|
|
1123
1038
|
if (this.buttonsConfiguredCount > 0) {
|
|
1124
|
-
|
|
1039
|
+
if (this.enableDebugMode) this.emit('debug', 'Prepare buttons services');
|
|
1125
1040
|
this.buttonsServices = [];
|
|
1126
1041
|
|
|
1127
1042
|
this.buttonsConfigured.forEach((button, index) => {
|
|
1128
|
-
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1131
|
-
//get button name
|
|
1132
|
-
const buttonName = button.name;
|
|
1043
|
+
const { mode, name: buttonName, namePrefix, serviceType, characteristicType } = button;
|
|
1044
|
+
const serviceName = namePrefix ? `${accessoryName} ${buttonName}` : buttonName;
|
|
1133
1045
|
|
|
1134
|
-
//get button name prefix
|
|
1135
|
-
const buttonNamePrefix = button.namePrefix;
|
|
1136
|
-
|
|
1137
|
-
const serviceName = buttonNamePrefix ? `${accessoryName} ${buttonName}` : buttonName;
|
|
1138
|
-
const serviceType = button.serviceType;
|
|
1139
|
-
const characteristicType = button.characteristicType;
|
|
1140
1046
|
const buttonService = new serviceType(serviceName, `Button ${index}`);
|
|
1141
1047
|
buttonService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
1142
1048
|
buttonService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
|
|
1049
|
+
|
|
1143
1050
|
buttonService.getCharacteristic(characteristicType)
|
|
1144
|
-
.onGet(async () =>
|
|
1145
|
-
const state = button.state;
|
|
1146
|
-
return state;
|
|
1147
|
-
})
|
|
1051
|
+
.onGet(async () => button.state)
|
|
1148
1052
|
.onSet(async (state) => {
|
|
1149
1053
|
try {
|
|
1150
|
-
let data
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
|
|
1233
|
-
data = state ? MiElHVAC.SetSwingV.swing : button.previousValue;
|
|
1234
|
-
break;
|
|
1235
|
-
case 30: //FAN SPEED AUTO
|
|
1236
|
-
button.previousValue = state ? MiElHVAC.SetFanSpeed[this.mielHvac.fanSpeed] : button.previousValue;
|
|
1237
|
-
data = state ? MiElHVAC.SetFanSpeed.auto : button.previousValue;
|
|
1238
|
-
break;
|
|
1239
|
-
case 31: //FAN SPEED QUIET
|
|
1240
|
-
button.previousValue = state ? MiElHVAC.SetFanSpeed[this.mielHvac.fanSpeed] : button.previousValue;
|
|
1241
|
-
data = state ? MiElHVAC.SetFanSpeed.quiet : button.previousValue;
|
|
1242
|
-
break;
|
|
1243
|
-
case 32: //FAN SPEED 1
|
|
1244
|
-
button.previousValue = state ? MiElHVAC.SetFanSpeed[this.mielHvac.fanSpeed] : button.previousValue;
|
|
1245
|
-
data = state ? MiElHVAC.SetFanSpeed['1'] : button.previousValue;
|
|
1246
|
-
break;
|
|
1247
|
-
case 33: //FAN SPEED 2
|
|
1248
|
-
button.previousValue = state ? MiElHVAC.SetFanSpeed[this.mielHvac.fanSpeed] : button.previousValue;
|
|
1249
|
-
data = state ? MiElHVAC.SetFanSpeed['2'] : button.previousValue;
|
|
1250
|
-
break;
|
|
1251
|
-
case 34: //FAN 3
|
|
1252
|
-
button.previousValue = state ? MiElHVAC.SetFanSpeed[this.mielHvac.fanSpeed] : button.previousValue;
|
|
1253
|
-
data = state ? MiElHVAC.SetFanSpeed['3'] : button.previousValue;
|
|
1254
|
-
break;
|
|
1255
|
-
case 35: //FAN SPEED 4
|
|
1256
|
-
button.previousValue = state ? MiElHVAC.SetFanSpeed[this.mielHvac.fanSpeed] : button.previousValue;
|
|
1257
|
-
data = state ? MiElHVAC.SetFanSpeed['4'] : button.previousValue;
|
|
1258
|
-
break;
|
|
1259
|
-
case 40: //AIR DIRECTION EVEN
|
|
1260
|
-
button.previousValue = state ? MiElHVAC.SetAirDirection[this.mielHvac.airDirection] : button.previousValue;
|
|
1261
|
-
data = state ? MiElHVAC.SetAirDirection.even : button.previousValue;
|
|
1262
|
-
break;
|
|
1263
|
-
case 41: //AIR DIRECTION INDIRECT
|
|
1264
|
-
button.previousValue = state ? MiElHVAC.SetAirDirection[this.mielHvac.airDirection] : button.previousValue;
|
|
1265
|
-
data = state ? MiElHVAC.SetAirDirection.indirect : button.previousValue;
|
|
1266
|
-
break;
|
|
1267
|
-
case 42: //AIR DIRECTION DIRECT
|
|
1268
|
-
button.previousValue = state ? MiElHVAC.SetAirDirection[this.mielHvac.airDirection] : button.previousValue;
|
|
1269
|
-
data = state ? MiElHVAC.SetAirDirection.direct : button.previousValue;
|
|
1270
|
-
break;
|
|
1271
|
-
case 50: //PHYSICAL LOCK CONTROLS
|
|
1272
|
-
button.previousValue = state ? MiElHVAC.SetProhibit[this.mielHvac.prohibit] : button.previousValue;
|
|
1273
|
-
data = state ? MiElHVAC.SetProhibit.all : button.previousValue;
|
|
1274
|
-
break;
|
|
1275
|
-
case 51: //PHYSICAL LOCK CONTROLS POWER
|
|
1276
|
-
button.previousValue = state ? MiElHVAC.SetProhibit[this.mielHvac.prohibit] : button.previousValue;
|
|
1277
|
-
data = state ? MiElHVAC.SetProhibit.power : button.previousValue;
|
|
1278
|
-
break;
|
|
1279
|
-
case 52: //PHYSICAL LOCK CONTROLS MODE
|
|
1280
|
-
button.previousValue = state ? MiElHVAC.SetProhibit[this.mielHvac.prohibit] : button.previousValue;
|
|
1281
|
-
data = state ? MiElHVAC.SetProhibit.mode : button.previousValue;
|
|
1282
|
-
break;
|
|
1283
|
-
case 53: //PHYSICAL LOCK CONTROLS TEMP
|
|
1284
|
-
button.previousValue = state ? MiElHVAC.SetProhibit[this.mielHvac.prohibit] : button.previousValue;
|
|
1285
|
-
data = state ? MiElHVAC.SetProhibit.temp : button.previousValue;
|
|
1286
|
-
break;
|
|
1287
|
-
default:
|
|
1288
|
-
this.emit('warn', `Unknown button mode: ${mode}`);
|
|
1289
|
-
return;
|
|
1054
|
+
let data;
|
|
1055
|
+
const mappings = {
|
|
1056
|
+
0: () => state ? MiElHVAC.PowerOn : MiElHVAC.PowerOff,
|
|
1057
|
+
|
|
1058
|
+
// Modes
|
|
1059
|
+
1: () => getCommand('SetMode', 'heat'),
|
|
1060
|
+
2: () => getCommand('SetMode', 'dry'),
|
|
1061
|
+
3: () => getCommand('SetMode', 'cool'),
|
|
1062
|
+
4: () => getCommand('SetMode', 'fan'),
|
|
1063
|
+
5: () => getCommand('SetMode', 'auto'),
|
|
1064
|
+
|
|
1065
|
+
// Horizontal Swing
|
|
1066
|
+
10: () => getCommand('SetSwingH', 'left'),
|
|
1067
|
+
11: () => getCommand('SetSwingH', 'left_middle'),
|
|
1068
|
+
12: () => getCommand('SetSwingH', 'left_center'),
|
|
1069
|
+
13: () => getCommand('SetSwingH', 'center'),
|
|
1070
|
+
14: () => getCommand('SetSwingH', 'right_middle'),
|
|
1071
|
+
15: () => getCommand('SetSwingH', 'right'),
|
|
1072
|
+
16: () => getCommand('SetSwingH', 'right_center'),
|
|
1073
|
+
17: () => getCommand('SetSwingH', 'split'),
|
|
1074
|
+
18: () => getCommand('SetSwingH', 'swing'),
|
|
1075
|
+
|
|
1076
|
+
// Vertical Swing
|
|
1077
|
+
20: () => getCommand('SetSwingV', 'auto'),
|
|
1078
|
+
21: () => getCommand('SetSwingV', 'up'),
|
|
1079
|
+
22: () => getCommand('SetSwingV', 'up_middle'),
|
|
1080
|
+
23: () => getCommand('SetSwingV', 'center'),
|
|
1081
|
+
24: () => getCommand('SetSwingV', 'down_middle'),
|
|
1082
|
+
25: () => getCommand('SetSwingV', 'down'),
|
|
1083
|
+
26: () => getCommand('SetSwingV', 'swing'),
|
|
1084
|
+
|
|
1085
|
+
// Fan Speeds
|
|
1086
|
+
30: () => getCommand('SetFanSpeed', 'auto'),
|
|
1087
|
+
31: () => getCommand('SetFanSpeed', 'quiet'),
|
|
1088
|
+
32: () => getCommand('SetFanSpeed', '1'),
|
|
1089
|
+
33: () => getCommand('SetFanSpeed', '2'),
|
|
1090
|
+
34: () => getCommand('SetFanSpeed', '3'),
|
|
1091
|
+
35: () => getCommand('SetFanSpeed', '4'),
|
|
1092
|
+
|
|
1093
|
+
// Air Direction
|
|
1094
|
+
40: () => getCommand('SetAirDirection', 'indirect'),
|
|
1095
|
+
41: () => getCommand('SetAirDirection', 'direct'),
|
|
1096
|
+
42: () => getCommand('SetAirDirection', 'even'),
|
|
1097
|
+
43: () => getCommand('SetAirDirection', 'off'),
|
|
1098
|
+
|
|
1099
|
+
// Prohibit
|
|
1100
|
+
50: () => getCommand('SetProhibit', 'all'),
|
|
1101
|
+
51: () => getCommand('SetProhibit', 'power'),
|
|
1102
|
+
52: () => getCommand('SetProhibit', 'mode'),
|
|
1103
|
+
53: () => getCommand('SetProhibit', 'temp'),
|
|
1104
|
+
|
|
1105
|
+
// Purify
|
|
1106
|
+
60: () => getCommand('SetPurify', 'purify'),
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
const getCommand = (type, target) => {
|
|
1110
|
+
const current = this.mielHvac[getCurrentKey(type)];
|
|
1111
|
+
button.previousValue = state ? MiElHVAC[type][current] : button.previousValue;
|
|
1112
|
+
return state ? MiElHVAC[type][target] : button.previousValue;
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
const getCurrentKey = (type) => {
|
|
1116
|
+
switch (type) {
|
|
1117
|
+
case 'SetMode': return 'operationMode';
|
|
1118
|
+
case 'SetSwingH': return 'vaneHorizontalDirection';
|
|
1119
|
+
case 'SetSwingV': return 'vaneVerticalDirection';
|
|
1120
|
+
case 'SetFanSpeed': return 'fanSpeed';
|
|
1121
|
+
case 'SetAirDirection': return 'airDirection';
|
|
1122
|
+
case 'SetProhibit': return 'prohibit';
|
|
1123
|
+
case 'SetPurify': return 'purify';
|
|
1124
|
+
default: return '';
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
if (!mappings.hasOwnProperty(mode)) {
|
|
1129
|
+
this.emit('warn', `Unknown button mode: ${mode}`);
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
data = mappings[mode]();
|
|
1134
|
+
if (!this.mielHvac.power && state && mode > 0 && mode <= 60) {
|
|
1135
|
+
await this.axiosInstance(MiElHVAC.PowerOn);
|
|
1290
1136
|
}
|
|
1291
1137
|
|
|
1292
|
-
const setPower = !this.mielHvac.power && state && (mode > 0 && mode < 50) ? await this.axiosInstance(MiElHVAC.PowerOn) : false;
|
|
1293
1138
|
await this.axiosInstance(data);
|
|
1294
|
-
|
|
1139
|
+
|
|
1140
|
+
if (!this.disableLogInfo) {
|
|
1141
|
+
const action = state ? `Set: ${buttonName}` : `Unset: ${buttonName}, Set: ${button.previousValue}`;
|
|
1142
|
+
if (mode > 0) this.emit('info', action);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1295
1145
|
await new Promise(resolve => setTimeout(resolve, 250));
|
|
1296
1146
|
} catch (error) {
|
|
1297
1147
|
this.emit('warn', `Set button error: ${error}`);
|
|
1298
1148
|
}
|
|
1299
1149
|
});
|
|
1150
|
+
|
|
1300
1151
|
this.buttonsServices.push(buttonService);
|
|
1301
1152
|
accessory.addService(buttonService);
|
|
1302
1153
|
});
|
|
1303
1154
|
}
|
|
1304
1155
|
|
|
1156
|
+
|
|
1305
1157
|
//sensors services
|
|
1306
1158
|
if (this.sensorsConfiguredCount > 0) {
|
|
1307
1159
|
const debug = this.enableDebugMode ? this.emit('debug', `Prepare sensors services`) : false;
|