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.
@@ -519,7 +519,7 @@
519
519
  "title": "Mode",
520
520
  "type": "integer",
521
521
  "minimum": 0,
522
- "maximum": 53,
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": "MODE PURIFY (not implemented)",
563
+ "title": "VANE H LEFT",
564
564
  "enum": [
565
- 6
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 MIDDLE",
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 MIDDLE",
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 SPLIT",
599
+ "title": "VANE H RIGHT CENTER",
600
600
  "enum": [
601
601
  16
602
602
  ]
603
603
  },
604
604
  {
605
- "title": "VANE H SWING",
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 EVEN",
695
+ "title": "AIR DIRECTION INDIRECT",
690
696
  "enum": [
691
697
  40
692
698
  ]
693
699
  },
694
700
  {
695
- "title": "AIR DIRECTION INDIRECT",
701
+ "title": "AIR DIRECTION DIRECT",
696
702
  "enum": [
697
703
  41
698
704
  ]
699
705
  },
700
706
  {
701
- "title": "AIR DIRECTION DIRECT",
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Tasmota Control",
3
3
  "name": "homebridge-tasmota-control",
4
- "version": "1.6.15-beta.1",
4
+ "version": "1.6.15-beta.10",
5
5
  "description": "Homebridge plugin to control Tasmota flashed devices.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
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
- "even": "HVACSetSwingH%20even",
71
- "indirect": "HVACSetSwingH%20indirect",
72
- "direct": "HVACSetSwingH%20direct",
73
- "off": "HVACSetSwingH%20off"
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
- //operation mode
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][operationModeStageMap[operationModeStage]]; //INACTIVE, IDLE, HEATING, COOLING
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][operationModeStageMap[operationModeStage]];
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][operationModeStageMap[operationModeStage]];
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][operationModeStageMap[operationModeStage]];
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][operationModeStageMap[operationModeStage]];
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][operationModeStageMap[operationModeStage]];
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][operationModeStageMap[operationModeStage]];
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][operationModeStageMap[operationModeStage]];
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
- switch (numberOfFanSpeeds) {
358
- case 2: //Fan speed mode 2
359
- obj.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][fanSpeedMap[fanSpeed]] : [0, 1, 2][fanSpeedMap[fanSpeed]];
360
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
361
- break;
362
- case 3: //Fan speed mode 3
363
- obj.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][fanSpeedMap[fanSpeed]] : [0, 1, 2, 3][fanSpeedMap[fanSpeed]];
364
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
365
- break;
366
- case 4: //Fan speed mode 4
367
- obj.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][fanSpeedMap[fanSpeed]] : [0, 1, 2, 3, 4][fanSpeedMap[fanSpeed]];
368
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
369
- break;
370
- case 5: //Fan speed mode 5
371
- obj.fanSpeed = hasAutomaticFanSpeed ? [6, 1, 2, 3, 4, 5][fanSpeedMap[fanSpeed]] : [0, 1, 2, 3, 4, 5][fanSpeedMap[fanSpeed]];
372
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 6 : 5;
373
- break;
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
- .updateCharacteristic(Characteristic.Active, power)
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
- const updateDefCool = obj.targetOperationMode === 0 || obj.targetOperationMode === 2 ? this.miElHvacService.updateCharacteristic(Characteristic.CoolingThresholdTemperature, obj.targetOperationMode === 0 ? defaultCoolingSetTemperature : setTemperature) : false;
389
- const updateDefHeat = obj.targetOperationMode === 0 || obj.targetOperationMode === 1 ? this.miElHvacService.updateCharacteristic(Characteristic.HeatingThresholdTemperature, obj.targetOperationMode === 0 ? defaultHeatingSetTemperature : setTemperature) : false;
390
- const updateRS = modelSupportsFanSpeed ? this.miElHvacService.updateCharacteristic(Characteristic.RotationSpeed, obj.fanSpeed) : false;
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
- this.miElHvacService
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
- this.miElHvacService.setCharacteristic(Characteristic.Active, false);
439
+ svc.setCharacteristic(Characteristic.Active, false);
404
440
  this.frostProtectActive = false;
405
441
  }
406
442
  }
407
443
  }
408
444
 
409
- //update presets state
445
+ // Update presets state
410
446
  if (this.presetsConfiguredCount > 0) {
411
447
  this.presetsConfigured.forEach((preset, index) => {
412
-
413
448
  let iseeMode = operationMode;
414
- iseeMode = (operationMode === 'heat' || operationMode === 'heat_isee') ? 'heat' : iseeMode;
415
- iseeMode = (operationMode === 'dry' || operationMode === 'dry_isee') ? 'dry' : iseeMode;
416
- iseeMode = (operationMode === 'cool' || operationMode === 'cool_isee') ? 'cool' : iseeMode;
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
- preset.state = power ? (preset.mode === iseeMode
419
- && (preset.setTemp).toFixed(1) === parseFloat(setTemperature).toFixed(1)
420
- && preset.fanSpeed === fanSpeed
421
- && preset.swingV === vaneVerticalDirection
422
- && preset.swingH === vaneHorizontalDirection) : false;
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
- switch (mode) {
437
- case 0: //POWER ON,OFF
438
- button.state = power === 1;
439
- break;
440
- case 1: //OPERATING MODE HEAT
441
- button.state = power ? (operationMode === 'heat' || operationMode === 'heat_isee') : false;
442
- break;
443
- case 2: //OPERATING MODE DRY
444
- button.state = power ? (operationMode === 'dry' || operationMode === 'dry_isee') : false;
445
- break
446
- case 3: //OPERATING MODE COOL
447
- button.state = power ? (operationMode === 'cool' || operationMode === 'cool_isee') : false;
448
- break;
449
- case 4: //OPERATING MODE FAN
450
- button.state = power ? (operationMode === 'fan') : false;
451
- break;
452
- case 5: //OPERATING MODE AUTO
453
- button.state = power ? (operationMode === 'auto') : false;
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
- //update services
549
+ button.state = state;
550
+
545
551
  if (this.buttonsServices) {
546
552
  const characteristicType = button.characteristicType;
547
553
  this.buttonsServices[index]
548
- .updateCharacteristic(characteristicType, button.state);
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
- switch (mode) {
558
- case 0: //POWER ON,OFF
559
- sensor.state = power === 1;
560
- break;
561
- case 1: //OPERATING MODE HEAT
562
- sensor.state = power ? (operationMode === 'heat' || operationMode === 'heat_isee') : false;
563
- break;
564
- case 2: //OPERATING MODE DRY
565
- sensor.state = power ? (operationMode === 'dry' || operationMode === 'dry_isee') : false;
566
- break
567
- case 3: //OPERATING MODE COOL
568
- sensor.state = power ? (operationMode === 'cool' || operationMode === 'cool_isee') : false;
569
- break;
570
- case 4: //OPERATING MODE FAN
571
- sensor.state = power ? (operationMode === 'fan') : false;
572
- break;
573
- case 5: //OPERATING MODE AUTO
574
- sensor.state = power ? (operationMode === 'auto') : false;
575
- break;
576
- case 6: //OPERATING MODE PURIFY
577
- sensor.state = power ? (operationMode === 'purify') : false;
578
- break;
579
- case 10: //VANE H AUTO
580
- sensor.state = power ? (vaneHorizontalDirection === 'auto') : false;
581
- break;
582
- case 11: //VANE H LEFT
583
- sensor.state = power ? (vaneHorizontalDirection === 'left') : false;
584
- break;
585
- case 12: //VANE H LEFT MIDDLE
586
- sensor.state = power ? (vaneHorizontalDirection === 'left_middle') : false;
587
- break;
588
- case 13: //VANE H CENTER
589
- sensor.state = power ? (vaneHorizontalDirection === 'center') : false;
590
- break;
591
- case 14: //VANE H RIGHT MIDDLE
592
- sensor.state = power ? (vaneHorizontalDirection === 'right_middle') : false;
593
- break;
594
- case 15: //VANE H RIGHT
595
- sensor.state = power ? (vaneHorizontalDirection === 'right') : false;
596
- break;
597
- case 16: //VANE H SPLIT
598
- sensor.state = power ? (vaneHorizontalDirection === 'split') : false;
599
- break;
600
- case 17: //VANE H SWING
601
- sensor.state = power ? (vaneHorizontalDirection === 'swing') : false;
602
- break;
603
- case 20: //VANE V AUTO
604
- sensor.state = power ? (vaneVerticalDirection === 'auto') : false;
605
- break;
606
- case 21: //VANE V UP
607
- sensor.state = power ? (vaneVerticalDirection === 'up') : false;
608
- break;
609
- case 22: //VANE V UP MIDDLE
610
- sensor.state = power ? (vaneVerticalDirection === 'up_middle') : false;
611
- break;
612
- case 23: //VANE V CENTER
613
- sensor.state = power ? (vaneVerticalDirection === 'center') : false;
614
- break;
615
- case 24: //VANE V DOWN MIDDLE
616
- sensor.state = power ? (vaneVerticalDirection === 'down_middle') : false;
617
- break;
618
- case 25: //VANE V DOWN
619
- sensor.state = power ? (vaneVerticalDirection === 'down') : false;
620
- break;
621
- case 26: //VANE V SWING
622
- sensor.state = power ? (vaneVerticalDirection === 'swing') : false;
623
- break;
624
- case 27: //VANE H/V CONTROLS HIDE
625
- sensor.state = power ? (hideVaneControls === true) : false;
626
- break;
627
- case 30: //FAN SPEED MODE AUTO
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
- //update services
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
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare presets services`) : false;
987
+ if (this.enableDebugMode) this.emit('debug', 'Prepare presets services');
1070
988
  this.presetsServices = [];
1071
989
 
1072
990
  this.presetsConfigured.forEach((preset, index) => {
1073
- //get preset name
1074
- const presetName = preset.name;
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
- let data = '';
1093
- switch (state) {
1094
- case true:
1095
- const setPower = !this.mielHvac.power ? await this.axiosInstance(MiElHVAC.PowerOn) : false;
1096
- data = MiElHVAC.SetMode[preset.mode];
1097
- await this.axiosInstance(data);
1098
- data = `${MiElHVAC.SetTemp}${preset.setTemp}`;
1099
- await this.axiosInstance(data);
1100
- data = MiElHVAC.SetFanSpeed[preset.fanSpeed];
1101
- await this.axiosInstance(data);
1102
- data = MiElHVAC.SetSwingV[preset.swingV];
1103
- await this.axiosInstance(data);
1104
- data = MiElHVAC.SetSwingH[preset.swingH];
1105
- await this.axiosInstance(data);
1106
- break;
1107
- case false:
1108
- break;
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
- //buttons services
1037
+
1123
1038
  if (this.buttonsConfiguredCount > 0) {
1124
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare buttons services`) : false;
1039
+ if (this.enableDebugMode) this.emit('debug', 'Prepare buttons services');
1125
1040
  this.buttonsServices = [];
1126
1041
 
1127
1042
  this.buttonsConfigured.forEach((button, index) => {
1128
- //get button mode
1129
- const mode = button.mode;
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
- switch (mode) {
1152
- case 0: //POWER ON,OFF
1153
- data = state ? MiElHVAC.PowerOn : MiElHVAC.PowerOff;
1154
- break;
1155
- case 1: //OPERATING MODE HEAT
1156
- button.previousValue = state ? MiElHVAC.SetMode[this.mielHvac.operationMode] : button.previousValue;
1157
- data = state ? MiElHVAC.SetMode.heat : button.previousValue;
1158
- break;
1159
- case 2: //OPERATING MODE DRY
1160
- button.previousValue = state ? MiElHVAC.SetMode[this.mielHvac.operationMode] : button.previousValue;
1161
- data = state ? MiElHVAC.SetMode.dry : button.previousValue;
1162
- break
1163
- case 3: //OPERATING MODE COOL
1164
- button.previousValue = state ? MiElHVAC.SetMode[this.mielHvac.operationMode] : button.previousValue;
1165
- data = state ? MiElHVAC.SetMode.cool : button.previousValue;
1166
- break;
1167
- case 4: //OPERATING MODE FAN
1168
- button.previousValue = state ? MiElHVAC.SetMode[this.mielHvac.operationMode] : button.previousValue;
1169
- data = state ? MiElHVAC.SetMode.fan : button.previousValue;
1170
- break;
1171
- case 5: //OPERATING MODE AUTO
1172
- button.previousValue = state ? MiElHVAC.SetMode[this.mielHvac.operationMode] : button.previousValue;
1173
- data = state ? MiElHVAC.SetMode.auto : button.previousValue;
1174
- break;
1175
- case 6: //OPERATING MODE PURIFY
1176
- button.previousValue = state ? MiElHVAC.SetMode[this.mielHvac.operationMode] : button.previousValue;
1177
- data = state ? MiElHVAC.SetMode.purify : button.previousValue;
1178
- break;
1179
- case 11: //VANE H LEFT
1180
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1181
- data = state ? MiElHVAC.SetSwingH.left : button.previousValue;
1182
- break;
1183
- case 12: //VANE H LEFT MIDDLE
1184
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1185
- data = state ? MiElHVAC.SetSwingH.left_middle : button.previousValue;
1186
- break;
1187
- case 13: //VANE H CENTER
1188
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1189
- data = state ? MiElHVAC.SetSwingH.center : button.previousValue;
1190
- break;
1191
- case 14: //VANE H RIGHT MIDDLE
1192
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1193
- data = state ? MiElHVAC.SetSwingH.right_middle : button.previousValue;
1194
- break;
1195
- case 15: //VANE H RIGHT
1196
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1197
- data = state ? MiElHVAC.SetSwingH.right : button.previousValue;
1198
- break;
1199
- case 16: //VANE H SPLIT
1200
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1201
- data = state ? MiElHVAC.SetSwingH.split : button.previousValue;
1202
- break;
1203
- case 17: //VANE H SWING
1204
- button.previousValue = state ? MiElHVAC.SetSwingH[this.mielHvac.vaneHorizontalDirection] : button.previousValue;
1205
- data = state ? MiElHVAC.SetSwingH.swing : button.previousValue;
1206
- break;
1207
- case 20: //VANE V AUTO
1208
- button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
1209
- data = state ? MiElHVAC.SetSwingV.auto : button.previousValue;
1210
- break;
1211
- case 21: //VANE V UP
1212
- button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
1213
- data = state ? MiElHVAC.SetSwingV.up : button.previousValue;
1214
- break;
1215
- case 22: //VANE V UP MIDDLE
1216
- button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
1217
- data = state ? MiElHVAC.SetSwingV.up_middle : button.previousValue;
1218
- break;
1219
- case 23: //VANE V CENTER
1220
- button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
1221
- data = state ? MiElHVAC.SetSwingV.center : button.previousValue;
1222
- break;
1223
- case 24: //VANE V DOWN MIDDLE
1224
- button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
1225
- data = state ? MiElHVAC.SetSwingV.down_middle : button.previousValue;
1226
- break;
1227
- case 25: //VANE V DOWN
1228
- button.previousValue = state ? MiElHVAC.SetSwingV[this.mielHvac.vaneVerticalDirection] : button.previousValue;
1229
- data = state ? MiElHVAC.SetSwingV.down : button.previousValue;
1230
- break;
1231
- case 26: //VANE V SWING
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
- const info = this.disableLogInfo ? false : mode > 0 ? this.emit('info', `${state ? `Set: ${buttonName}` : `Unset: ${buttonName}, Set: ${button.previousValue}`}`) : `Set: ${buttonName}`;
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;