homebridge-midea-platform 1.2.5 → 1.2.6-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.
Files changed (48) hide show
  1. package/.zed/settings.json +12 -0
  2. package/CHANGELOG.md +4 -0
  3. package/README.md +1 -0
  4. package/ac.lua +5150 -0
  5. package/biome.json +1 -1
  6. package/config.schema.json +69 -15
  7. package/dist/accessory/AccessoryFactory.d.ts +2 -1
  8. package/dist/accessory/AccessoryFactory.js +3 -0
  9. package/dist/accessory/AccessoryFactory.js.map +1 -1
  10. package/dist/accessory/AirConditionerAccessory.d.ts +3 -0
  11. package/dist/accessory/AirConditionerAccessory.js +82 -56
  12. package/dist/accessory/AirConditionerAccessory.js.map +1 -1
  13. package/dist/accessory/BaseAccessory.d.ts +1 -0
  14. package/dist/accessory/BaseAccessory.js +8 -0
  15. package/dist/accessory/BaseAccessory.js.map +1 -1
  16. package/dist/accessory/DehumidifierAccessory.js +23 -18
  17. package/dist/accessory/DehumidifierAccessory.js.map +1 -1
  18. package/dist/accessory/ElectricWaterHeaterAccessory.js +9 -8
  19. package/dist/accessory/ElectricWaterHeaterAccessory.js.map +1 -1
  20. package/dist/accessory/FreshAirApplianceAccessory.d.ts +37 -0
  21. package/dist/accessory/FreshAirApplianceAccessory.js +140 -0
  22. package/dist/accessory/FreshAirApplianceAccessory.js.map +1 -0
  23. package/dist/accessory/GasWaterHeaterAccessory.js +20 -20
  24. package/dist/accessory/GasWaterHeaterAccessory.js.map +1 -1
  25. package/dist/core/MideaCloud.js +2 -2
  26. package/dist/core/MideaCloud.js.map +1 -1
  27. package/dist/core/MideaConstants.d.ts +4 -0
  28. package/dist/core/MideaConstants.js +14 -0
  29. package/dist/core/MideaConstants.js.map +1 -1
  30. package/dist/devices/DeviceFactory.d.ts +2 -1
  31. package/dist/devices/DeviceFactory.js +3 -0
  32. package/dist/devices/DeviceFactory.js.map +1 -1
  33. package/dist/devices/ce/MideaCEDevice.d.ts +34 -0
  34. package/dist/devices/ce/MideaCEDevice.js +98 -0
  35. package/dist/devices/ce/MideaCEDevice.js.map +1 -0
  36. package/dist/devices/ce/MideaCEMessage.d.ts +43 -0
  37. package/dist/devices/ce/MideaCEMessage.js +84 -0
  38. package/dist/devices/ce/MideaCEMessage.js.map +1 -0
  39. package/dist/platform.d.ts +3 -0
  40. package/dist/platform.js.map +1 -1
  41. package/dist/platformUtils.d.ts +9 -0
  42. package/dist/platformUtils.js +8 -0
  43. package/dist/platformUtils.js.map +1 -1
  44. package/docs/ac.md +6 -3
  45. package/docs/ce.md +19 -0
  46. package/homebridge-ui/public/index.html +57 -7
  47. package/homebridge-ui/server.js +92 -177
  48. package/package.json +1 -1
package/biome.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "files": {
9
9
  "ignoreUnknown": false,
10
- "ignore": ["dist/**", ".vscode/**", ".github/**", "node_modules/**", "homebridge-ui/**"]
10
+ "ignore": ["dist/**", ".vscode/**", ".github/**", "node_modules/**"]
11
11
  },
12
12
  "formatter": {
13
13
  "enabled": true,
@@ -36,7 +36,18 @@
36
36
  "title": "Device Type",
37
37
  "type": "string",
38
38
  "required": true,
39
- "enum": ["Air Conditioner", "Dehumidifier", "Dishwasher", "Electric Water Heater", "Fan", "Front Load Washer", "Gas Water Heater", "Heat Pump WiFi Controller", "Humidifier"],
39
+ "enum": [
40
+ "Air Conditioner",
41
+ "Dehumidifier",
42
+ "Dishwasher",
43
+ "Electric Water Heater",
44
+ "Fan",
45
+ "Fresh Air Appliance",
46
+ "Front Load Washer",
47
+ "Gas Water Heater",
48
+ "Heat Pump WiFi Controller",
49
+ "Humidifier"
50
+ ],
40
51
  "description": "Select the type of device you are adding."
41
52
  },
42
53
  "name": {
@@ -284,6 +295,11 @@
284
295
  "title": "Fan Accessory",
285
296
  "description": "Toggles if the fan accessory is created with the accessory.",
286
297
  "type": "boolean"
298
+ },
299
+ "sleepModeSwitch": {
300
+ "title": "Sleep Mode Switch",
301
+ "description": "Toggles if the sleep mode switch is created with the accessory.",
302
+ "type": "boolean"
287
303
  }
288
304
  }
289
305
  },
@@ -331,14 +347,46 @@
331
347
  }
332
348
  }
333
349
  },
350
+ "CE_options": {
351
+ "title": "Top Load Washer Options",
352
+ "type": "object",
353
+ "condition": {
354
+ "functionBody": "return model.devices && model.devices[arrayIndices].type === 'Top Load Washer';"
355
+ },
356
+ "properties": {
357
+ "silentMode": {
358
+ "title": "Silent Mode",
359
+ "description": "Toggles if the silent mode switch alongside the level slider is created with the accessory.",
360
+ "type": "boolean"
361
+ },
362
+ "minTemp": {
363
+ "title": "Minimum Temperature (°C)",
364
+ "type": "number"
365
+ },
366
+ "maxTemp": {
367
+ "title": "Maximum Temperature (°C)",
368
+ "type": "number"
369
+ },
370
+ "tempStep": {
371
+ "title": "Temperature Step (°C)",
372
+ "type": "number",
373
+ "required": true,
374
+ "enum": [0.5, 1]
375
+ },
376
+ "autoSetModeSwitch": {
377
+ "title": "Auto Set Mode Switch",
378
+ "description": "Toggles if the auto set mode switch is created with the accessory.",
379
+ "type": "boolean"
380
+ }
381
+ }
382
+ },
334
383
  "DB_options": {
335
384
  "title": "Front Load Washer Options",
336
385
  "type": "object",
337
386
  "condition": {
338
387
  "functionBody": "return model.devices && model.devices[arrayIndices].type === 'Front Load Washer';"
339
388
  },
340
- "properties": {
341
- }
389
+ "properties": {}
342
390
  },
343
391
  "E1_options": {
344
392
  "title": "Dishwasher Options",
@@ -346,8 +394,7 @@
346
394
  "condition": {
347
395
  "functionBody": "return model.devices && model.devices[arrayIndices].type === 'Dishwasher';"
348
396
  },
349
- "properties": {
350
- }
397
+ "properties": {}
351
398
  },
352
399
  "E2_options": {
353
400
  "title": "Electric Water Heater Options",
@@ -448,8 +495,7 @@
448
495
  "condition": {
449
496
  "functionBody": "return model.devices && model.devices[arrayIndices].type === 'Fan';"
450
497
  },
451
- "properties": {
452
- }
498
+ "properties": {}
453
499
  },
454
500
  "FD_options": {
455
501
  "title": "Humidifier Options",
@@ -457,8 +503,7 @@
457
503
  "condition": {
458
504
  "functionBody": "return model.devices && model.devices[arrayIndices].type === 'Humidifier';"
459
505
  },
460
- "properties": {
461
- }
506
+ "properties": {}
462
507
  }
463
508
  }
464
509
  }
@@ -521,11 +566,7 @@
521
566
  "items": [
522
567
  {
523
568
  "key": "devices[].AC_options.swing",
524
- "items": [
525
- "devices[].AC_options.swing.mode",
526
- "devices[].AC_options.swing.angleAccessory",
527
- "devices[].AC_options.swing.angleMainControl"
528
- ]
569
+ "items": ["devices[].AC_options.swing.mode", "devices[].AC_options.swing.angleAccessory", "devices[].AC_options.swing.angleMainControl"]
529
570
  },
530
571
  "devices[].AC_options.heatingCapable",
531
572
  "devices[].AC_options.outDoorTemp",
@@ -548,7 +589,8 @@
548
589
  "devices[].AC_options.tempStep",
549
590
  "devices[].AC_options.fahrenheit",
550
591
  "devices[].AC_options.fanOnlyModeSwitch",
551
- "devices[].AC_options.fanAccessory"
592
+ "devices[].AC_options.fanAccessory",
593
+ "devices[].AC_options.sleepModeSwitch"
552
594
  ]
553
595
  },
554
596
  {
@@ -565,6 +607,18 @@
565
607
  "devices[].C3_options.disinfectSwitch"
566
608
  ]
567
609
  },
610
+ {
611
+ "key": "devices[].CE_options",
612
+ "expandable": true,
613
+ "expanded": false,
614
+ "items": [
615
+ "devices[].CE_options.silentMode",
616
+ "devices[].CE_options.minTemp",
617
+ "devices[].CE_options.maxTemp",
618
+ "devices[].CE_options.tempStep",
619
+ "devices[].CE_options.autoSetModeSwitch"
620
+ ]
621
+ },
568
622
  {
569
623
  "key": "devices[].DB_options",
570
624
  "expandable": true,
@@ -8,8 +8,9 @@ import FanAccessory from './FanAccessory.js';
8
8
  import DishwasherAccessory from './DishwasherAccessory.js';
9
9
  import HeatPumpWiFiControllerAccessory from './HeatPumpWiFiControllerAccessory.js';
10
10
  import HumidifierAccessory from './HumidifierAccessory.js';
11
+ import FreshAirApplianceAccessory from './FreshAirApplianceAccessory.js';
11
12
  import type MideaDevice from '../core/MideaDevice.js';
12
13
  import type { DeviceConfig } from '../platformUtils.js';
13
14
  export default class AccessoryFactory {
14
- static createAccessory<T extends MideaDevice>(platform: MideaPlatform, accessory: MideaAccessory, device: T, configDev: DeviceConfig): AirConditionerAccessory | DehumidifierAccessory | FrontLoadWasherAccessory | ElectricWaterHeaterAccessory | GasWaterHeaterAccessory | FanAccessory | DishwasherAccessory | HeatPumpWiFiControllerAccessory | HumidifierAccessory;
15
+ static createAccessory<T extends MideaDevice>(platform: MideaPlatform, accessory: MideaAccessory, device: T, configDev: DeviceConfig): AirConditionerAccessory | DehumidifierAccessory | FrontLoadWasherAccessory | ElectricWaterHeaterAccessory | GasWaterHeaterAccessory | FanAccessory | DishwasherAccessory | HeatPumpWiFiControllerAccessory | HumidifierAccessory | FreshAirApplianceAccessory;
15
16
  }
@@ -8,6 +8,7 @@ import FanAccessory from './FanAccessory.js';
8
8
  import DishwasherAccessory from './DishwasherAccessory.js';
9
9
  import HeatPumpWiFiControllerAccessory from './HeatPumpWiFiControllerAccessory.js';
10
10
  import HumidifierAccessory from './HumidifierAccessory.js';
11
+ import FreshAirApplianceAccessory from './FreshAirApplianceAccessory.js';
11
12
  // biome-ignore lint/complexity/noStaticOnlyClass: static class is used for factory
12
13
  export default class AccessoryFactory {
13
14
  static createAccessory(platform, accessory, device, configDev) {
@@ -30,6 +31,8 @@ export default class AccessoryFactory {
30
31
  return new FanAccessory(platform, accessory, device, configDev);
31
32
  case DeviceType.HUMIDIFIER:
32
33
  return new HumidifierAccessory(platform, accessory, device, configDev);
34
+ case DeviceType.FRESH_AIR_APPLIANCE:
35
+ return new FreshAirApplianceAccessory(platform, accessory, device, configDev);
33
36
  default:
34
37
  throw new Error(`Unsupported device type: ${device.type}`);
35
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AccessoryFactory.js","sourceRoot":"","sources":["../../src/accessory/AccessoryFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,OAAO,uBAAuB,MAAM,8BAA8B,CAAC;AAGnE,OAAO,qBAAqB,MAAM,4BAA4B,CAAC;AAG/D,OAAO,wBAAwB,MAAM,+BAA+B,CAAC;AAGrE,OAAO,4BAA4B,MAAM,mCAAmC,CAAC;AAG7E,OAAO,uBAAuB,MAAM,8BAA8B,CAAC;AAGnE,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAG7C,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAG3D,OAAO,+BAA+B,MAAM,sCAAsC,CAAC;AAGnF,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAK3D,mFAAmF;AACnF,MAAM,CAAC,OAAO,OAAO,gBAAgB;IAC5B,MAAM,CAAC,eAAe,CAAwB,QAAuB,EAAE,SAAyB,EAAE,MAAS,EAAE,SAAuB;QACzI,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,UAAU,CAAC,YAAY;gBAC1B,OAAO,IAAI,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACvG,KAAK,UAAU,CAAC,eAAe;gBAC7B,OAAO,IAAI,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACzG,KAAK,UAAU,CAAC,yBAAyB;gBACvC,OAAO,IAAI,+BAA+B,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACjH,KAAK,UAAU,CAAC,iBAAiB;gBAC/B,OAAO,IAAI,wBAAwB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC1G,KAAK,UAAU,CAAC,UAAU;gBACxB,OAAO,IAAI,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACrG,KAAK,UAAU,CAAC,qBAAqB;gBACnC,OAAO,IAAI,4BAA4B,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC9G,KAAK,UAAU,CAAC,gBAAgB;gBAC9B,OAAO,IAAI,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACzG,KAAK,UAAU,CAAC,GAAG;gBACjB,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC9F,KAAK,UAAU,CAAC,UAAU;gBACxB,OAAO,IAAI,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACrG;gBACE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"AccessoryFactory.js","sourceRoot":"","sources":["../../src/accessory/AccessoryFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,OAAO,uBAAuB,MAAM,8BAA8B,CAAC;AAGnE,OAAO,qBAAqB,MAAM,4BAA4B,CAAC;AAG/D,OAAO,wBAAwB,MAAM,+BAA+B,CAAC;AAGrE,OAAO,4BAA4B,MAAM,mCAAmC,CAAC;AAG7E,OAAO,uBAAuB,MAAM,8BAA8B,CAAC;AAGnE,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAG7C,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAG3D,OAAO,+BAA+B,MAAM,sCAAsC,CAAC;AAGnF,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAG3D,OAAO,0BAA0B,MAAM,iCAAiC,CAAC;AAKzE,mFAAmF;AACnF,MAAM,CAAC,OAAO,OAAO,gBAAgB;IAC5B,MAAM,CAAC,eAAe,CAAwB,QAAuB,EAAE,SAAyB,EAAE,MAAS,EAAE,SAAuB;QACzI,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,UAAU,CAAC,YAAY;gBAC1B,OAAO,IAAI,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACvG,KAAK,UAAU,CAAC,eAAe;gBAC7B,OAAO,IAAI,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACzG,KAAK,UAAU,CAAC,yBAAyB;gBACvC,OAAO,IAAI,+BAA+B,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACjH,KAAK,UAAU,CAAC,iBAAiB;gBAC/B,OAAO,IAAI,wBAAwB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC1G,KAAK,UAAU,CAAC,UAAU;gBACxB,OAAO,IAAI,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACrG,KAAK,UAAU,CAAC,qBAAqB;gBACnC,OAAO,IAAI,4BAA4B,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC9G,KAAK,UAAU,CAAC,gBAAgB;gBAC9B,OAAO,IAAI,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACzG,KAAK,UAAU,CAAC,GAAG;gBACjB,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC9F,KAAK,UAAU,CAAC,UAAU;gBACxB,OAAO,IAAI,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YACrG,KAAK,UAAU,CAAC,mBAAmB;gBACjC,OAAO,IAAI,0BAA0B,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAkC,EAAE,SAAS,CAAC,CAAC;YAC5G;gBACE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;CACF"}
@@ -31,6 +31,7 @@ export default class AirConditionerAccessory extends BaseAccessory<MideaACDevice
31
31
  private selfCleanService?;
32
32
  private ionService?;
33
33
  private rateSelectService?;
34
+ private sleepModeService?;
34
35
  private swingAngleService?;
35
36
  private swingAngleMainControl;
36
37
  /*********************************************************************
@@ -96,4 +97,6 @@ export default class AirConditionerAccessory extends BaseAccessory<MideaACDevice
96
97
  getSwingAngleCurrentVerticalTiltAngle(): CharacteristicValue;
97
98
  getSwingAngleTargetVerticalTiltAngle(): CharacteristicValue;
98
99
  setSwingAngleTargetVerticalTiltAngle(value: CharacteristicValue): Promise<void>;
100
+ getSleepMode(): CharacteristicValue;
101
+ setSleepMode(value: CharacteristicValue): Promise<void>;
99
102
  }
@@ -1,5 +1,20 @@
1
1
  import { SwingAngle, SwingMode } from '../platformUtils.js';
2
2
  import BaseAccessory from './BaseAccessory.js';
3
+ const outDoorTemperatureSubtype = 'outdoor';
4
+ const displaySubtype = 'display';
5
+ const fanOnlySubtype = 'fanOnly';
6
+ const fanSubtype = 'fan';
7
+ const ecoModeSubtype = 'ecoMode';
8
+ const breezeAwaySubtype = 'breezeAway';
9
+ const dryModeSubtype = 'dryMode';
10
+ const boostModeSubtype = 'boostMode';
11
+ const auxSubtype = 'aux';
12
+ const auxHeatingSubtype = 'auxHeating';
13
+ const selfCleanSubtype = 'selfClean';
14
+ const ionSubtype = 'ion';
15
+ const rateSelectSubtype = 'rateSelect';
16
+ const sleepModeSubtype = 'sleepMode';
17
+ const swingAngleSubtype = 'swingAngle';
3
18
  export default class AirConditionerAccessory extends BaseAccessory {
4
19
  device;
5
20
  configDev;
@@ -17,6 +32,7 @@ export default class AirConditionerAccessory extends BaseAccessory {
17
32
  selfCleanService;
18
33
  ionService;
19
34
  rateSelectService;
35
+ sleepModeService;
20
36
  swingAngleService;
21
37
  swingAngleMainControl;
22
38
  /*********************************************************************
@@ -73,11 +89,10 @@ export default class AirConditionerAccessory extends BaseAccessory {
73
89
  this.service.getCharacteristic(this.platform.Characteristic.SwingMode).onGet(this.getSwingMode.bind(this)).onSet(this.setSwingMode.bind(this));
74
90
  }
75
91
  // Outdoor temperature sensor
76
- this.outDoorTemperatureService = this.accessory.getServiceById(this.platform.Service.TemperatureSensor, 'Outdoor');
92
+ this.outDoorTemperatureService = this.accessory.getServiceById(this.platform.Service.TemperatureSensor, outDoorTemperatureSubtype);
77
93
  if (this.configDev.AC_options.outDoorTemp) {
78
- this.outDoorTemperatureService ??= this.accessory.addService(this.platform.Service.TemperatureSensor, `${this.device.name} Outdoor`, 'Outdoor');
79
- this.outDoorTemperatureService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Outdoor`);
80
- this.outDoorTemperatureService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Outdoor`);
94
+ this.outDoorTemperatureService ??= this.accessory.addService(this.platform.Service.TemperatureSensor, undefined, outDoorTemperatureSubtype);
95
+ this.handleConfiguredName(this.outDoorTemperatureService, outDoorTemperatureSubtype, 'Outdoor');
81
96
  this.outDoorTemperatureService.getCharacteristic(this.platform.Characteristic.CurrentTemperature).onGet(this.getOutdoorTemperature.bind(this));
82
97
  this.outDoorTemperatureService
83
98
  .getCharacteristic(this.platform.Characteristic.StatusFault)
@@ -89,22 +104,20 @@ export default class AirConditionerAccessory extends BaseAccessory {
89
104
  this.accessory.removeService(this.outDoorTemperatureService);
90
105
  }
91
106
  // Fan-only mode switch
92
- this.fanOnlyService = this.accessory.getServiceById(this.platform.Service.Switch, 'FanOnly');
107
+ this.fanOnlyService = this.accessory.getServiceById(this.platform.Service.Switch, fanOnlySubtype);
93
108
  if (this.configDev.AC_options.fanOnlyModeSwitch) {
94
- this.fanOnlyService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} FanOnly`, 'FanOnly');
95
- this.fanOnlyService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Fan-only Mode`);
96
- this.fanOnlyService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Fan-only Mode`);
109
+ this.fanOnlyService ??= this.accessory.addService(this.platform.Service.Switch, undefined, fanOnlySubtype);
110
+ this.handleConfiguredName(this.fanOnlyService, fanOnlySubtype, 'Fan-only Mode');
97
111
  this.fanOnlyService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getFanOnlyMode.bind(this)).onSet(this.setFanOnlyMode.bind(this));
98
112
  }
99
113
  else if (this.fanOnlyService) {
100
114
  this.accessory.removeService(this.fanOnlyService);
101
115
  }
102
116
  // Fan accessory
103
- this.fanService = this.accessory.getServiceById(this.platform.Service.Fanv2, 'Fan');
117
+ this.fanService = this.accessory.getServiceById(this.platform.Service.Fanv2, fanSubtype);
104
118
  if (this.configDev.AC_options.fanAccessory) {
105
- this.fanService ??= this.accessory.addService(this.platform.Service.Fanv2, `${this.device.name} Fan`, 'Fan');
106
- this.fanService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Fan`);
107
- this.fanService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Fan`);
119
+ this.fanService ??= this.accessory.addService(this.platform.Service.Fanv2, undefined, fanSubtype);
120
+ this.handleConfiguredName(this.fanService, fanSubtype, 'Fan');
108
121
  this.fanService.getCharacteristic(this.platform.Characteristic.Active).onGet(this.getActive.bind(this)).onSet(this.setActive.bind(this));
109
122
  this.fanService
110
123
  .getCharacteristic(this.platform.Characteristic.RotationSpeed)
@@ -117,88 +130,81 @@ export default class AirConditionerAccessory extends BaseAccessory {
117
130
  this.accessory.removeService(this.fanService);
118
131
  }
119
132
  // Display switch
120
- this.displayService = this.accessory.getServiceById(this.platform.Service.Switch, 'Display');
133
+ this.displayService = this.accessory.getServiceById(this.platform.Service.Switch, displaySubtype);
121
134
  if (this.configDev.AC_options.displaySwitch.flag) {
122
135
  this.device.set_alternate_switch_display(this.configDev.AC_options.displaySwitch.command);
123
- this.displayService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Display`, 'Display');
124
- this.displayService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Display`);
125
- this.displayService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Display`);
136
+ this.displayService ??= this.accessory.addService(this.platform.Service.Switch, undefined, displaySubtype);
137
+ this.handleConfiguredName(this.displayService, displaySubtype, 'Display');
126
138
  this.displayService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getDisplayActive.bind(this)).onSet(this.setDisplayActive.bind(this));
127
139
  }
128
140
  else if (this.displayService) {
129
141
  this.accessory.removeService(this.displayService);
130
142
  }
131
143
  // Eco mode switch
132
- this.ecoModeService = this.accessory.getServiceById(this.platform.Service.Switch, 'EcoMode');
144
+ this.ecoModeService = this.accessory.getServiceById(this.platform.Service.Switch, ecoModeSubtype);
133
145
  if (this.configDev.AC_options.ecoSwitch) {
134
- this.ecoModeService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Eco`, 'EcoMode');
135
- this.ecoModeService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Eco`);
136
- this.ecoModeService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Eco`);
146
+ this.ecoModeService ??= this.accessory.addService(this.platform.Service.Switch, undefined, ecoModeSubtype);
147
+ this.handleConfiguredName(this.ecoModeService, ecoModeSubtype, 'Eco');
137
148
  this.ecoModeService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getEcoMode.bind(this)).onSet(this.setEcoMode.bind(this));
138
149
  }
139
150
  else if (this.ecoModeService) {
140
151
  this.accessory.removeService(this.ecoModeService);
141
152
  }
142
153
  // Breeze away switch
143
- this.breezeAwayService = this.accessory.getServiceById(this.platform.Service.Switch, 'BreezeAway');
154
+ this.breezeAwayService = this.accessory.getServiceById(this.platform.Service.Switch, breezeAwaySubtype);
144
155
  if (this.configDev.AC_options.breezeAwaySwitch) {
145
- this.breezeAwayService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Breeze`, 'BreezeAway');
146
- this.breezeAwayService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Breeze`);
147
- this.breezeAwayService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Breeze`);
156
+ this.breezeAwayService ??= this.accessory.addService(this.platform.Service.Switch, undefined, breezeAwaySubtype);
157
+ this.handleConfiguredName(this.breezeAwayService, breezeAwaySubtype, 'Breeze');
148
158
  this.breezeAwayService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getBreezeAway.bind(this)).onSet(this.setBreezeAway.bind(this));
149
159
  }
150
160
  else if (this.breezeAwayService) {
151
161
  this.accessory.removeService(this.breezeAwayService);
152
162
  }
153
163
  // Dry mode switch
154
- this.dryModeService = this.accessory.getServiceById(this.platform.Service.Switch, 'DryMode');
164
+ this.dryModeService = this.accessory.getServiceById(this.platform.Service.Switch, dryModeSubtype);
155
165
  if (this.configDev.AC_options.dryModeSwitch) {
156
- this.dryModeService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Dry`, 'DryMode');
157
- this.dryModeService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Dry`);
158
- this.dryModeService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Dry`);
166
+ this.dryModeService ??= this.accessory.addService(this.platform.Service.Switch, undefined, dryModeSubtype);
167
+ this.handleConfiguredName(this.dryModeService, dryModeSubtype, 'Dry');
159
168
  this.dryModeService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getDryMode.bind(this)).onSet(this.setDryMode.bind(this));
160
169
  }
161
170
  else if (this.dryModeService) {
162
171
  this.accessory.removeService(this.dryModeService);
163
172
  }
164
- this.boostModeService = this.accessory.getServiceById(this.platform.Service.Switch, 'BoostMode');
173
+ // Boost mode switch
174
+ this.boostModeService = this.accessory.getServiceById(this.platform.Service.Switch, boostModeSubtype);
165
175
  if (this.configDev.AC_options.boostModeSwitch) {
166
- this.boostModeService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Boost`, 'BoostMode');
167
- this.boostModeService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Boost`);
168
- this.boostModeService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Boost`);
176
+ this.boostModeService ??= this.accessory.addService(this.platform.Service.Switch, undefined, boostModeSubtype);
177
+ this.handleConfiguredName(this.boostModeService, boostModeSubtype, 'Boost');
169
178
  this.boostModeService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getBoostMode.bind(this)).onSet(this.setBoostMode.bind(this));
170
179
  }
171
180
  else if (this.boostModeService) {
172
181
  this.accessory.removeService(this.boostModeService);
173
182
  }
174
183
  // Aux switch
175
- this.auxService = this.accessory.getServiceById(this.platform.Service.Switch, 'Aux');
184
+ this.auxService = this.accessory.getServiceById(this.platform.Service.Switch, auxSubtype);
176
185
  if (this.configDev.AC_options.auxHeatingSwitches) {
177
- this.auxService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Aux`, 'Aux');
178
- this.auxService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Aux`);
179
- this.auxService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Aux`);
186
+ this.auxService ??= this.accessory.addService(this.platform.Service.Switch, undefined, auxSubtype);
187
+ this.handleConfiguredName(this.auxService, auxSubtype, 'Aux');
180
188
  this.auxService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getAux.bind(this)).onSet(this.setAux.bind(this));
181
189
  }
182
190
  else if (this.auxService) {
183
191
  this.accessory.removeService(this.auxService);
184
192
  }
185
193
  // Aux+Heat switch
186
- this.auxHeatingService = this.accessory.getServiceById(this.platform.Service.Switch, 'AuxHeating');
194
+ this.auxHeatingService = this.accessory.getServiceById(this.platform.Service.Switch, auxHeatingSubtype);
187
195
  if (this.configDev.AC_options.auxHeatingSwitches) {
188
- this.auxHeatingService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Aux+Heat`, 'AuxHeating');
189
- this.auxHeatingService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Aux+Heat`);
190
- this.auxHeatingService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Aux+Heat`);
196
+ this.auxHeatingService ??= this.accessory.addService(this.platform.Service.Switch, undefined, auxHeatingSubtype);
197
+ this.handleConfiguredName(this.auxHeatingService, auxHeatingSubtype, 'Aux+Heat');
191
198
  this.auxHeatingService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getAuxHeating.bind(this)).onSet(this.setAuxHeating.bind(this));
192
199
  }
193
200
  else if (this.auxHeatingService) {
194
201
  this.accessory.removeService(this.auxHeatingService);
195
202
  }
196
203
  // Self-cleaning switch
197
- this.selfCleanService = this.accessory.getServiceById(this.platform.Service.Switch, 'SelfClean');
204
+ this.selfCleanService = this.accessory.getServiceById(this.platform.Service.Switch, selfCleanSubtype);
198
205
  if (this.configDev.AC_options.selfCleanSwitch) {
199
- this.selfCleanService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} Self-cleaning`, 'SelfClean');
200
- this.selfCleanService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Self-cleaning`);
201
- this.selfCleanService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Self-cleaning`);
206
+ this.selfCleanService ??= this.accessory.addService(this.platform.Service.Switch, undefined, selfCleanSubtype);
207
+ this.handleConfiguredName(this.selfCleanService, selfCleanSubtype, 'Self-cleaning');
202
208
  this.selfCleanService
203
209
  .getCharacteristic(this.platform.Characteristic.On)
204
210
  .onGet(this.getSelfCleanState.bind(this))
@@ -208,22 +214,20 @@ export default class AirConditionerAccessory extends BaseAccessory {
208
214
  this.accessory.removeService(this.selfCleanService);
209
215
  }
210
216
  // ION switch
211
- this.ionService = this.accessory.getServiceById(this.platform.Service.Switch, 'ION');
217
+ this.ionService = this.accessory.getServiceById(this.platform.Service.Switch, ionSubtype);
212
218
  if (this.configDev.AC_options.ionSwitch) {
213
- this.ionService ??= this.accessory.addService(this.platform.Service.Switch, `${this.device.name} ION`, 'ION');
214
- this.ionService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} ION`);
215
- this.ionService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} ION`);
219
+ this.ionService ??= this.accessory.addService(this.platform.Service.Switch, undefined, ionSubtype);
220
+ this.handleConfiguredName(this.ionService, ionSubtype, 'ION');
216
221
  this.ionService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getIonState.bind(this)).onSet(this.setIonState.bind(this));
217
222
  }
218
223
  else if (this.ionService) {
219
224
  this.accessory.removeService(this.ionService);
220
225
  }
221
226
  // Rate select slider
222
- this.rateSelectService = this.accessory.getServiceById(this.platform.Service.Lightbulb, 'Gear');
227
+ this.rateSelectService = this.accessory.getServiceById(this.platform.Service.Lightbulb, rateSelectSubtype);
223
228
  if (this.configDev.AC_options.rateSelector) {
224
- this.rateSelectService ??= this.accessory.addService(this.platform.Service.Lightbulb, `${this.device.name} Gear`, 'Gear');
225
- this.rateSelectService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Gear`);
226
- this.rateSelectService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Gear`);
229
+ this.rateSelectService ??= this.accessory.addService(this.platform.Service.Lightbulb, undefined, rateSelectSubtype);
230
+ this.handleConfiguredName(this.rateSelectService, rateSelectSubtype, 'Gear');
227
231
  this.rateSelectService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getActive.bind(this)).onSet(this.setActive.bind(this));
228
232
  this.rateSelectService
229
233
  .getCharacteristic(this.platform.Characteristic.Brightness)
@@ -236,17 +240,26 @@ export default class AirConditionerAccessory extends BaseAccessory {
236
240
  else if (this.rateSelectService) {
237
241
  this.accessory.removeService(this.rateSelectService);
238
242
  }
243
+ // Sleep mode accessory
244
+ this.sleepModeService = this.accessory.getServiceById(this.platform.Service.Switch, sleepModeSubtype);
245
+ if (this.configDev.AC_options.sleepModeSwitch) {
246
+ this.sleepModeService ??= this.accessory.addService(this.platform.Service.Switch, undefined, sleepModeSubtype);
247
+ this.handleConfiguredName(this.sleepModeService, sleepModeSubtype, 'Sleep');
248
+ this.sleepModeService.getCharacteristic(this.platform.Characteristic.On).onGet(this.getSleepMode.bind(this)).onSet(this.setSleepMode.bind(this));
249
+ }
250
+ else if (this.sleepModeService) {
251
+ this.accessory.removeService(this.sleepModeService);
252
+ }
239
253
  const swingProps = this.configDev.AC_options.swing;
240
254
  this.swingAngleMainControl =
241
255
  swingProps.mode === SwingMode.VERTICAL || (swingProps.mode === SwingMode.BOTH && swingProps.angleMainControl === SwingAngle.VERTICAL)
242
256
  ? SwingAngle.VERTICAL
243
257
  : SwingAngle.HORIZONTAL;
244
258
  // Swing angle accessory
245
- this.swingAngleService = this.accessory.getServiceById(this.platform.Service.WindowCovering, 'SwingAngle');
259
+ this.swingAngleService = this.accessory.getServiceById(this.platform.Service.WindowCovering, swingAngleSubtype);
246
260
  if (swingProps.mode !== SwingMode.NONE && swingProps.angleAccessory) {
247
- this.swingAngleService ??= this.accessory.addService(this.platform.Service.WindowCovering, `${this.device.name} Swing`, 'SwingAngle');
248
- this.swingAngleService.setCharacteristic(this.platform.Characteristic.Name, `${this.device.name} Swing`);
249
- this.swingAngleService.setCharacteristic(this.platform.Characteristic.ConfiguredName, `${this.device.name} Swing`);
261
+ this.swingAngleService ??= this.accessory.addService(this.platform.Service.WindowCovering, undefined, swingAngleSubtype);
262
+ this.handleConfiguredName(this.swingAngleService, swingAngleSubtype, 'Swing');
250
263
  this.swingAngleService.getCharacteristic(this.platform.Characteristic.CurrentPosition).onGet(this.getSwingAngleCurrentPosition.bind(this));
251
264
  this.swingAngleService
252
265
  .getCharacteristic(this.platform.Characteristic.TargetPosition)
@@ -600,5 +613,18 @@ export default class AirConditionerAccessory extends BaseAccessory {
600
613
  async setSwingAngleTargetVerticalTiltAngle(value) {
601
614
  await this.device.set_swing_angle(SwingAngle.VERTICAL, Math.max(1, value));
602
615
  }
616
+ getSleepMode() {
617
+ return this.device.attributes.POWER === true && this.device.attributes.SLEEP_MODE
618
+ ? this.platform.Characteristic.Active.ACTIVE
619
+ : this.platform.Characteristic.Active.INACTIVE;
620
+ }
621
+ async setSleepMode(value) {
622
+ if (value === this.platform.Characteristic.Active.ACTIVE) {
623
+ await this.device.set_attribute({ POWER: true, SLEEP_MODE: true });
624
+ }
625
+ else {
626
+ await this.device.set_attribute({ SLEEP_MODE: false });
627
+ }
628
+ }
603
629
  }
604
630
  //# sourceMappingURL=AirConditionerAccessory.js.map