homebridge-tasmota-control 1.6.15-beta.0 → 1.6.15-beta.2

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