homebridge-midea-platform 1.2.7-beta.3 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.schema.json +2 -8
- package/dist/accessory/AirConditionerAccessory.d.ts +13 -2
- package/dist/accessory/AirConditionerAccessory.js +167 -104
- package/dist/accessory/AirConditionerAccessory.js.map +1 -1
- package/dist/devices/ac/MideaACDevice.js +1 -4
- package/dist/devices/ac/MideaACDevice.js.map +1 -1
- package/dist/platform.d.ts +3 -0
- package/dist/platform.js.map +1 -1
- package/dist/platformUtils.d.ts +8 -1
- package/dist/platformUtils.js +9 -1
- package/dist/platformUtils.js.map +1 -1
- package/docs/ac.md +11 -0
- package/package.json +2 -2
- package/.luarc.json +0 -5
- package/.zed/settings.json +0 -7
- package/ac.lua +0 -5150
- package/ac_00000Q11.lua +0 -5148
- package/ac_00000Q1D.lua +0 -5148
- package/c3_HeatPump_152832116442666.lua +0 -4681
- package/cd_RSJ000CB.lua +0 -4983
package/config.schema.json
CHANGED
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
},
|
|
121
121
|
"humiditySensor": {
|
|
122
122
|
"title": "Humidity Sensor",
|
|
123
|
-
"description": "Toggles if a seperated humidity sensor is created with the accessory. This sensor can be used for
|
|
123
|
+
"description": "Toggles if a seperated humidity sensor is created with the accessory. This sensor can be used for autmations as for some reason the internal humidity sensor is not usable for this.",
|
|
124
124
|
"type": "boolean"
|
|
125
125
|
},
|
|
126
126
|
"pumpSwitch": {
|
|
@@ -306,11 +306,6 @@
|
|
|
306
306
|
"title": "Comfort Mode Switch",
|
|
307
307
|
"description": "Toggles if the comfort mode switch is created with the accessory.",
|
|
308
308
|
"type": "boolean"
|
|
309
|
-
},
|
|
310
|
-
"temperatureSensor": {
|
|
311
|
-
"title": "Indoor Temperature Sensor",
|
|
312
|
-
"description": "Toggles if a seperated indoor temperature is created with the accessory. This sensor can be used for automations as for some reason the internal sensors are not usable for this.",
|
|
313
|
-
"type": "boolean"
|
|
314
309
|
}
|
|
315
310
|
}
|
|
316
311
|
},
|
|
@@ -657,8 +652,7 @@
|
|
|
657
652
|
"devices[].AC_options.fanOnlyModeSwitch",
|
|
658
653
|
"devices[].AC_options.fanAccessory",
|
|
659
654
|
"devices[].AC_options.sleepModeSwitch",
|
|
660
|
-
"devices[].AC_options.comfortModeSwitch"
|
|
661
|
-
"devices[].AC_options.temperatureSensor"
|
|
655
|
+
"devices[].AC_options.comfortModeSwitch"
|
|
662
656
|
]
|
|
663
657
|
},
|
|
664
658
|
{
|
|
@@ -34,13 +34,15 @@ export default class AirConditionerAccessory extends BaseAccessory<MideaACDevice
|
|
|
34
34
|
private sleepModeService?;
|
|
35
35
|
private swingAngleService?;
|
|
36
36
|
private comfortModeService?;
|
|
37
|
-
private temperatureSensorService?;
|
|
38
37
|
private swingAngleMainControl;
|
|
38
|
+
private heatingThresholdTemperature;
|
|
39
|
+
private coolingThresholdTemperature;
|
|
39
40
|
/*********************************************************************
|
|
40
41
|
* Constructor registers all the service types with Homebridge, registers
|
|
41
42
|
* a callback function with the MideaDevice class, and requests device status.
|
|
42
43
|
*/
|
|
43
44
|
constructor(platform: MideaPlatform, accessory: MideaAccessory, device: MideaACDevice, configDev: DeviceConfig);
|
|
45
|
+
private withoutPromptTone;
|
|
44
46
|
/*********************************************************************
|
|
45
47
|
* Callback function called by MideaDevice whenever there is a change to
|
|
46
48
|
* any attribute value.
|
|
@@ -59,11 +61,20 @@ export default class AirConditionerAccessory extends BaseAccessory<MideaACDevice
|
|
|
59
61
|
setTargetHeaterCoolerState(value: CharacteristicValue): Promise<void>;
|
|
60
62
|
getCurrentTemperature(): CharacteristicValue;
|
|
61
63
|
getTargetTemperature(): CharacteristicValue;
|
|
64
|
+
setTargetTemperature(value: CharacteristicValue): Promise<void>;
|
|
65
|
+
setTargetTemperatureWithinThresholds(): Promise<void>;
|
|
66
|
+
getCoolingThresholdTemperature(): CharacteristicValue;
|
|
67
|
+
getHeatingThresholdTemperature(): CharacteristicValue;
|
|
62
68
|
getFanOnlyMode(): CharacteristicValue;
|
|
63
69
|
setFanOnlyMode(value: CharacteristicValue): Promise<void>;
|
|
64
70
|
getFanState(): CharacteristicValue;
|
|
65
71
|
setFanState(value: CharacteristicValue): Promise<void>;
|
|
66
|
-
|
|
72
|
+
setHeatingCoolingTemperatureThresholds(thresholds: {
|
|
73
|
+
heating?: number;
|
|
74
|
+
cooling?: number;
|
|
75
|
+
}): void;
|
|
76
|
+
setCoolingThresholdTemperature(value: CharacteristicValue): Promise<void>;
|
|
77
|
+
setHeatingThresholdTemperature(value: CharacteristicValue): Promise<void>;
|
|
67
78
|
getSwingMode(): CharacteristicValue;
|
|
68
79
|
setSwingMode(value: CharacteristicValue): Promise<void>;
|
|
69
80
|
getRotationSpeed(): CharacteristicValue;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SwingAngle, SwingMode } from '../platformUtils.js';
|
|
1
|
+
import { ACMode, SwingAngle, SwingMode } from '../platformUtils.js';
|
|
2
2
|
import BaseAccessory, { limitValue } from './BaseAccessory.js';
|
|
3
3
|
const outDoorTemperatureSubtype = 'outdoor';
|
|
4
4
|
const displaySubtype = 'display';
|
|
@@ -16,7 +16,6 @@ const rateSelectSubtype = 'rateSelect';
|
|
|
16
16
|
const sleepModeSubtype = 'sleepMode';
|
|
17
17
|
const swingAngleSubtype = 'swingAngle';
|
|
18
18
|
const comfortModeSubtype = 'comfortMode';
|
|
19
|
-
const temperatureSensorSubtype = 'temperatureSensor';
|
|
20
19
|
export default class AirConditionerAccessory extends BaseAccessory {
|
|
21
20
|
device;
|
|
22
21
|
configDev;
|
|
@@ -37,8 +36,9 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
37
36
|
sleepModeService;
|
|
38
37
|
swingAngleService;
|
|
39
38
|
comfortModeService;
|
|
40
|
-
temperatureSensorService;
|
|
41
39
|
swingAngleMainControl;
|
|
40
|
+
heatingThresholdTemperature;
|
|
41
|
+
coolingThresholdTemperature;
|
|
42
42
|
/*********************************************************************
|
|
43
43
|
* Constructor registers all the service types with Homebridge, registers
|
|
44
44
|
* a callback function with the MideaDevice class, and requests device status.
|
|
@@ -71,8 +71,8 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
71
71
|
this.service.getCharacteristic(this.platform.Characteristic.CurrentTemperature).onGet(this.getCurrentTemperature.bind(this));
|
|
72
72
|
this.service
|
|
73
73
|
.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature)
|
|
74
|
-
.onGet(this.
|
|
75
|
-
.onSet(this.
|
|
74
|
+
.onGet(this.getCoolingThresholdTemperature.bind(this))
|
|
75
|
+
.onSet(this.setCoolingThresholdTemperature.bind(this))
|
|
76
76
|
.setProps({
|
|
77
77
|
minValue: this.configDev.AC_options.minTemp,
|
|
78
78
|
maxValue: this.configDev.AC_options.maxTemp,
|
|
@@ -80,8 +80,8 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
80
80
|
});
|
|
81
81
|
this.service
|
|
82
82
|
.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature)
|
|
83
|
-
.onGet(this.
|
|
84
|
-
.onSet(this.
|
|
83
|
+
.onGet(this.getHeatingThresholdTemperature.bind(this))
|
|
84
|
+
.onSet(this.setHeatingThresholdTemperature.bind(this))
|
|
85
85
|
.setProps({
|
|
86
86
|
minValue: this.configDev.AC_options.minTemp,
|
|
87
87
|
maxValue: this.configDev.AC_options.maxTemp,
|
|
@@ -254,7 +254,6 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
254
254
|
else if (this.sleepModeService) {
|
|
255
255
|
this.accessory.removeService(this.sleepModeService);
|
|
256
256
|
}
|
|
257
|
-
// Comfort mode accessory
|
|
258
257
|
this.comfortModeService = this.accessory.getServiceById(this.platform.Service.Switch, comfortModeSubtype);
|
|
259
258
|
if (this.configDev.AC_options.comfortModeSwitch) {
|
|
260
259
|
this.comfortModeService ??= this.accessory.addService(this.platform.Service.Switch, undefined, comfortModeSubtype);
|
|
@@ -264,16 +263,6 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
264
263
|
else if (this.comfortModeService) {
|
|
265
264
|
this.accessory.removeService(this.comfortModeService);
|
|
266
265
|
}
|
|
267
|
-
// Separate temperature sensor accessory
|
|
268
|
-
this.temperatureSensorService = this.accessory.getServiceById(this.platform.Service.TemperatureSensor, temperatureSensorSubtype);
|
|
269
|
-
if (this.configDev.AC_options.temperatureSensor) {
|
|
270
|
-
this.temperatureSensorService ??= this.accessory.addService(this.platform.Service.TemperatureSensor, undefined, temperatureSensorSubtype);
|
|
271
|
-
this.handleConfiguredName(this.temperatureSensorService, temperatureSensorSubtype, 'Indoor Temperature');
|
|
272
|
-
this.temperatureSensorService.getCharacteristic(this.platform.Characteristic.CurrentTemperature).onGet(this.getCurrentTemperature.bind(this));
|
|
273
|
-
}
|
|
274
|
-
else if (this.temperatureSensorService) {
|
|
275
|
-
this.accessory.removeService(this.temperatureSensorService);
|
|
276
|
-
}
|
|
277
266
|
const swingProps = this.configDev.AC_options.swing;
|
|
278
267
|
this.swingAngleMainControl =
|
|
279
268
|
swingProps.mode === SwingMode.VERTICAL || (swingProps.mode === SwingMode.BOTH && swingProps.angleMainControl === SwingAngle.VERTICAL)
|
|
@@ -308,8 +297,20 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
308
297
|
}
|
|
309
298
|
}
|
|
310
299
|
// Misc
|
|
311
|
-
this.device.attributes.PROMPT_TONE =
|
|
312
|
-
this.device.attributes.TEMP_FAHRENHEIT =
|
|
300
|
+
this.device.attributes.PROMPT_TONE = configDev.AC_options.audioFeedback;
|
|
301
|
+
this.device.attributes.TEMP_FAHRENHEIT = configDev.AC_options.fahrenheit;
|
|
302
|
+
this.heatingThresholdTemperature = accessory.context?.thresholds?.heatingTemperature ?? configDev.AC_options.minTemp;
|
|
303
|
+
this.coolingThresholdTemperature = accessory.context?.thresholds?.coolingTemperature ?? configDev.AC_options.maxTemp;
|
|
304
|
+
}
|
|
305
|
+
async withoutPromptTone(fn) {
|
|
306
|
+
const hadPromptTone = this.device.attributes.PROMPT_TONE;
|
|
307
|
+
this.device.attributes.PROMPT_TONE = false;
|
|
308
|
+
try {
|
|
309
|
+
return await fn();
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
this.device.attributes.PROMPT_TONE = hadPromptTone;
|
|
313
|
+
}
|
|
313
314
|
}
|
|
314
315
|
/*********************************************************************
|
|
315
316
|
* Callback function called by MideaDevice whenever there is a change to
|
|
@@ -324,102 +325,105 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
324
325
|
updateState = true;
|
|
325
326
|
break;
|
|
326
327
|
case 'temp_fahrenheit':
|
|
327
|
-
this.service.
|
|
328
|
+
this.service.updateCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits, this.getTemperatureDisplayUnits());
|
|
328
329
|
break;
|
|
329
330
|
case 'screen_display':
|
|
330
331
|
case 'screen_display_new':
|
|
331
|
-
this.displayService?.
|
|
332
|
+
this.displayService?.updateCharacteristic(this.platform.Characteristic.On, this.getDisplayActive());
|
|
332
333
|
break;
|
|
333
|
-
case 'target_temperature':
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
334
|
+
case 'target_temperature': {
|
|
335
|
+
const target = Number(this.getTargetTemperature());
|
|
336
|
+
/**
|
|
337
|
+
* If the device is heating, we map the target temperature to the heating threshold, if cooling we map to the cooling
|
|
338
|
+
* threshold and otherwise we assume an auto mode and only adjust the thresholds if the target value is outside their
|
|
339
|
+
* range. This should only happen if the temperature is changed outside of HomeKit and in this case we collapse the
|
|
340
|
+
* range to the target temperature set by the user.
|
|
341
|
+
*/
|
|
342
|
+
if (this.device.attributes.MODE === ACMode.HEATING) {
|
|
343
|
+
this.setHeatingCoolingTemperatureThresholds({ heating: target });
|
|
344
|
+
}
|
|
345
|
+
else if (this.device.attributes.MODE === ACMode.COOLING) {
|
|
346
|
+
this.setHeatingCoolingTemperatureThresholds({ cooling: target });
|
|
337
347
|
}
|
|
338
|
-
else {
|
|
339
|
-
this.
|
|
348
|
+
else if (target < this.heatingThresholdTemperature || target > this.coolingThresholdTemperature) {
|
|
349
|
+
this.setHeatingCoolingTemperatureThresholds({ heating: target, cooling: target });
|
|
340
350
|
}
|
|
341
351
|
updateState = true;
|
|
342
352
|
break;
|
|
343
|
-
case 'indoor_temperature': {
|
|
344
|
-
const temperature = this.getCurrentTemperature();
|
|
345
|
-
this.service.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(temperature);
|
|
346
|
-
this.temperatureSensorService?.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(temperature);
|
|
347
|
-
break;
|
|
348
353
|
}
|
|
354
|
+
case 'indoor_temperature':
|
|
355
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.getCurrentTemperature());
|
|
356
|
+
if (this.device.attributes.POWER && this.device.attributes.MODE === ACMode.AUTO) {
|
|
357
|
+
await this.withoutPromptTone(this.setTargetTemperatureWithinThresholds.bind(this));
|
|
358
|
+
updateState = true;
|
|
359
|
+
}
|
|
360
|
+
break;
|
|
349
361
|
case 'outdoor_temperature':
|
|
350
|
-
this.outDoorTemperatureService?.
|
|
362
|
+
this.outDoorTemperatureService?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.getOutdoorTemperature());
|
|
351
363
|
break;
|
|
352
364
|
case 'fan_speed':
|
|
353
365
|
updateState = true;
|
|
354
366
|
break;
|
|
355
367
|
case 'fan_auto':
|
|
356
|
-
this.fanService?.
|
|
368
|
+
this.fanService?.updateCharacteristic(this.platform.Characteristic.TargetFanState, this.getFanState());
|
|
357
369
|
break;
|
|
358
370
|
case 'swing_vertical':
|
|
359
371
|
case 'swing_horizontal':
|
|
360
|
-
this.service.
|
|
372
|
+
this.service.updateCharacteristic(this.platform.Characteristic.SwingMode, this.getSwingMode());
|
|
361
373
|
break;
|
|
362
374
|
case 'mode':
|
|
363
375
|
updateState = true;
|
|
364
376
|
break;
|
|
365
377
|
case 'eco_mode':
|
|
366
|
-
this.ecoModeService?.
|
|
378
|
+
this.ecoModeService?.updateCharacteristic(this.platform.Characteristic.On, this.getEcoMode());
|
|
367
379
|
break;
|
|
368
380
|
case 'indirect_wind':
|
|
369
|
-
this.breezeAwayService?.
|
|
381
|
+
this.breezeAwayService?.updateCharacteristic(this.platform.Characteristic.On, this.getBreezeAway());
|
|
370
382
|
break;
|
|
371
383
|
case 'aux_heating':
|
|
372
|
-
this.auxHeatingService?.
|
|
384
|
+
this.auxHeatingService?.updateCharacteristic(this.platform.Characteristic.On, this.getAuxHeating());
|
|
373
385
|
break;
|
|
374
386
|
case 'smart_eye':
|
|
375
|
-
this.auxService?.
|
|
387
|
+
this.auxService?.updateCharacteristic(this.platform.Characteristic.On, this.getAux());
|
|
376
388
|
break;
|
|
377
389
|
case 'wind_swing_lr_angle':
|
|
378
390
|
case 'wind_swing_ud_angle':
|
|
379
|
-
this.swingAngleService?.
|
|
380
|
-
this.swingAngleService?.
|
|
391
|
+
this.swingAngleService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.getSwingAngleCurrentPosition());
|
|
392
|
+
this.swingAngleService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, this.getSwingAngleTargetPosition());
|
|
381
393
|
if (this.configDev.AC_options.swing.mode === SwingMode.BOTH) {
|
|
382
|
-
this.swingAngleService
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
this.swingAngleService
|
|
386
|
-
?.getCharacteristic(this.platform.Characteristic.CurrentVerticalTiltAngle)
|
|
387
|
-
.updateValue(this.getSwingAngleCurrentVerticalTiltAngle());
|
|
388
|
-
this.swingAngleService
|
|
389
|
-
?.getCharacteristic(this.platform.Characteristic.TargetHorizontalTiltAngle)
|
|
390
|
-
.updateValue(this.getSwingAngleTargetHorizontalTiltAngle());
|
|
391
|
-
this.swingAngleService
|
|
392
|
-
?.getCharacteristic(this.platform.Characteristic.TargetVerticalTiltAngle)
|
|
393
|
-
.updateValue(this.getSwingAngleTargetVerticalTiltAngle());
|
|
394
|
+
this.swingAngleService?.updateCharacteristic(this.platform.Characteristic.CurrentHorizontalTiltAngle, this.getSwingAngleCurrentHorizontalTiltAngle());
|
|
395
|
+
this.swingAngleService?.updateCharacteristic(this.platform.Characteristic.CurrentVerticalTiltAngle, this.getSwingAngleCurrentVerticalTiltAngle());
|
|
396
|
+
this.swingAngleService?.updateCharacteristic(this.platform.Characteristic.TargetHorizontalTiltAngle, this.getSwingAngleTargetHorizontalTiltAngle());
|
|
397
|
+
this.swingAngleService?.updateCharacteristic(this.platform.Characteristic.TargetVerticalTiltAngle, this.getSwingAngleTargetVerticalTiltAngle());
|
|
394
398
|
}
|
|
395
399
|
break;
|
|
396
400
|
case 'self_clean':
|
|
397
401
|
updateState = true;
|
|
398
|
-
this.selfCleanService?.
|
|
402
|
+
this.selfCleanService?.updateCharacteristic(this.platform.Characteristic.On, this.getSelfCleanState());
|
|
399
403
|
break;
|
|
400
404
|
case 'ion':
|
|
401
|
-
this.ionService?.
|
|
405
|
+
this.ionService?.updateCharacteristic(this.platform.Characteristic.On, this.getIonState());
|
|
402
406
|
break;
|
|
403
407
|
case 'rate_select':
|
|
404
|
-
this.rateSelectService?.
|
|
408
|
+
this.rateSelectService?.updateCharacteristic(this.platform.Characteristic.Brightness, this.getRateSelect());
|
|
405
409
|
break;
|
|
406
410
|
default:
|
|
407
411
|
this.platform.log.debug(`[${this.device.name}] Attempt to set unsupported attribute ${k} to ${v}`);
|
|
408
412
|
}
|
|
409
413
|
if (updateState) {
|
|
410
|
-
this.service.
|
|
411
|
-
this.service.
|
|
412
|
-
this.service.
|
|
413
|
-
this.service.
|
|
414
|
-
this.fanOnlyService?.
|
|
415
|
-
this.fanService?.
|
|
416
|
-
this.fanService?.
|
|
417
|
-
this.dryModeService?.
|
|
418
|
-
this.displayService?.
|
|
419
|
-
this.ecoModeService?.
|
|
420
|
-
this.breezeAwayService?.
|
|
421
|
-
this.auxService?.
|
|
422
|
-
this.auxHeatingService?.
|
|
414
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Active, this.getActive());
|
|
415
|
+
this.service.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.getTargetHeaterCoolerState());
|
|
416
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.getCurrentHeaterCoolerState());
|
|
417
|
+
this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.getRotationSpeed());
|
|
418
|
+
this.fanOnlyService?.updateCharacteristic(this.platform.Characteristic.On, this.getFanOnlyMode());
|
|
419
|
+
this.fanService?.updateCharacteristic(this.platform.Characteristic.Active, this.getActive());
|
|
420
|
+
this.fanService?.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.getRotationSpeed());
|
|
421
|
+
this.dryModeService?.updateCharacteristic(this.platform.Characteristic.On, this.getDryMode());
|
|
422
|
+
this.displayService?.updateCharacteristic(this.platform.Characteristic.On, this.getDisplayActive());
|
|
423
|
+
this.ecoModeService?.updateCharacteristic(this.platform.Characteristic.On, this.getEcoMode());
|
|
424
|
+
this.breezeAwayService?.updateCharacteristic(this.platform.Characteristic.On, this.getBreezeAway());
|
|
425
|
+
this.auxService?.updateCharacteristic(this.platform.Characteristic.On, this.getAux());
|
|
426
|
+
this.auxHeatingService?.updateCharacteristic(this.platform.Characteristic.On, this.getAuxHeating());
|
|
423
427
|
}
|
|
424
428
|
}
|
|
425
429
|
}
|
|
@@ -434,7 +438,7 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
434
438
|
async setActive(value) {
|
|
435
439
|
await this.device.set_attribute({ POWER: !!value });
|
|
436
440
|
this.device.attributes.SCREEN_DISPLAY = !!value;
|
|
437
|
-
this.displayService?.
|
|
441
|
+
this.displayService?.updateCharacteristic(this.platform.Characteristic.On, !!value);
|
|
438
442
|
}
|
|
439
443
|
getTemperatureDisplayUnits() {
|
|
440
444
|
return this.device.attributes.TEMP_FAHRENHEIT
|
|
@@ -447,60 +451,97 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
447
451
|
});
|
|
448
452
|
}
|
|
449
453
|
getCurrentHeaterCoolerState() {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
return this.platform.Characteristic.CurrentHeaterCoolerState.COOLING;
|
|
454
|
-
}
|
|
455
|
-
return this.platform.Characteristic.CurrentHeaterCoolerState.IDLE;
|
|
456
|
-
}
|
|
457
|
-
if (this.device.attributes.TARGET_TEMPERATURE === this.device.attributes.INDOOR_TEMPERATURE) {
|
|
458
|
-
return this.platform.Characteristic.CurrentHeaterCoolerState.IDLE;
|
|
459
|
-
}
|
|
460
|
-
if (this.device.attributes.MODE === 4) {
|
|
461
|
-
return this.platform.Characteristic.CurrentHeaterCoolerState.HEATING;
|
|
462
|
-
}
|
|
463
|
-
return this.platform.Characteristic.CurrentHeaterCoolerState.IDLE;
|
|
454
|
+
const { CurrentHeaterCoolerState } = this.platform.Characteristic;
|
|
455
|
+
if (!this.device.attributes.POWER || !this.device.attributes.MODE) {
|
|
456
|
+
return CurrentHeaterCoolerState.INACTIVE;
|
|
464
457
|
}
|
|
465
|
-
|
|
458
|
+
const isPossiblyCooling = [ACMode.COOLING, ACMode.AUTO].includes(this.device.attributes.MODE);
|
|
459
|
+
const isPossiblyHeating = [ACMode.HEATING, ACMode.AUTO].includes(this.device.attributes.MODE) && this.configDev.AC_options.heatingCapable;
|
|
460
|
+
const currentTemperature = Number(this.getCurrentTemperature());
|
|
461
|
+
const heatingThresholdTemperature = Number(this.getHeatingThresholdTemperature());
|
|
462
|
+
const coolingThresholdTemperature = Number(this.getCoolingThresholdTemperature());
|
|
463
|
+
if (isPossiblyCooling && currentTemperature > coolingThresholdTemperature) {
|
|
464
|
+
return CurrentHeaterCoolerState.COOLING;
|
|
465
|
+
}
|
|
466
|
+
if (isPossiblyHeating && currentTemperature < heatingThresholdTemperature) {
|
|
467
|
+
return CurrentHeaterCoolerState.HEATING;
|
|
468
|
+
}
|
|
469
|
+
return CurrentHeaterCoolerState.IDLE;
|
|
466
470
|
}
|
|
467
471
|
getTargetHeaterCoolerState() {
|
|
468
|
-
|
|
469
|
-
|
|
472
|
+
switch (this.device.attributes.MODE) {
|
|
473
|
+
case ACMode.COOLING:
|
|
474
|
+
return this.platform.Characteristic.TargetHeaterCoolerState.COOL;
|
|
475
|
+
case ACMode.HEATING:
|
|
476
|
+
return this.platform.Characteristic.TargetHeaterCoolerState.HEAT;
|
|
477
|
+
default:
|
|
478
|
+
return this.platform.Characteristic.TargetHeaterCoolerState.AUTO;
|
|
470
479
|
}
|
|
471
|
-
if (this.device.attributes.MODE === 4) {
|
|
472
|
-
return this.platform.Characteristic.TargetHeaterCoolerState.HEAT;
|
|
473
|
-
}
|
|
474
|
-
return this.platform.Characteristic.TargetHeaterCoolerState.AUTO;
|
|
475
480
|
}
|
|
476
481
|
async setTargetHeaterCoolerState(value) {
|
|
477
482
|
switch (value) {
|
|
478
483
|
case this.platform.Characteristic.TargetHeaterCoolerState.AUTO:
|
|
479
|
-
await this.device.set_attribute({ POWER: true, MODE:
|
|
484
|
+
await this.device.set_attribute({ POWER: true, MODE: ACMode.AUTO });
|
|
480
485
|
break;
|
|
481
486
|
case this.platform.Characteristic.TargetHeaterCoolerState.COOL:
|
|
482
|
-
await this.device.set_attribute({ POWER: true, MODE:
|
|
487
|
+
await this.device.set_attribute({ POWER: true, MODE: ACMode.COOLING });
|
|
483
488
|
break;
|
|
484
489
|
case this.platform.Characteristic.TargetHeaterCoolerState.HEAT:
|
|
485
|
-
await this.device.set_attribute({ POWER: true, MODE:
|
|
490
|
+
await this.device.set_attribute({ POWER: true, MODE: ACMode.HEATING });
|
|
486
491
|
break;
|
|
487
492
|
}
|
|
493
|
+
await this.setTargetTemperatureWithinThresholds();
|
|
488
494
|
}
|
|
489
495
|
getCurrentTemperature() {
|
|
490
496
|
return this.device.attributes.INDOOR_TEMPERATURE ?? this.configDev.AC_options.minTemp;
|
|
491
497
|
}
|
|
492
498
|
getTargetTemperature() {
|
|
493
|
-
|
|
499
|
+
const { minTemp, maxTemp } = this.configDev.AC_options;
|
|
500
|
+
return limitValue(this.device.attributes.TARGET_TEMPERATURE, minTemp, maxTemp);
|
|
501
|
+
}
|
|
502
|
+
async setTargetTemperature(value) {
|
|
503
|
+
const { minTemp, maxTemp, tempStep } = this.configDev.AC_options;
|
|
504
|
+
const target = limitValue(Math.round(+value / tempStep) * tempStep, minTemp, maxTemp);
|
|
505
|
+
if (this.getTargetTemperature() === target)
|
|
506
|
+
return;
|
|
507
|
+
await this.device.set_target_temperature(target);
|
|
508
|
+
}
|
|
509
|
+
async setTargetTemperatureWithinThresholds() {
|
|
510
|
+
if (this.device.attributes.MODE === ACMode.COOLING) {
|
|
511
|
+
await this.setTargetTemperature(this.getCoolingThresholdTemperature());
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
if (this.device.attributes.MODE === ACMode.HEATING) {
|
|
515
|
+
await this.setTargetTemperature(this.getHeatingThresholdTemperature());
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (this.getCurrentTemperature() > this.getCoolingThresholdTemperature()) {
|
|
519
|
+
await this.setTargetTemperature(this.getCoolingThresholdTemperature());
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
if (this.getCurrentTemperature() < this.getHeatingThresholdTemperature()) {
|
|
523
|
+
await this.setTargetTemperature(this.getHeatingThresholdTemperature());
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
await this.setTargetTemperature(this.getCurrentTemperature());
|
|
527
|
+
}
|
|
528
|
+
getCoolingThresholdTemperature() {
|
|
529
|
+
const { minTemp, maxTemp } = this.configDev.AC_options;
|
|
530
|
+
return limitValue(this.coolingThresholdTemperature, minTemp, maxTemp);
|
|
531
|
+
}
|
|
532
|
+
getHeatingThresholdTemperature() {
|
|
533
|
+
const { minTemp, maxTemp } = this.configDev.AC_options;
|
|
534
|
+
return limitValue(this.heatingThresholdTemperature, minTemp, maxTemp);
|
|
494
535
|
}
|
|
495
536
|
getFanOnlyMode() {
|
|
496
|
-
return this.device.attributes.POWER === true && this.device.attributes.MODE ===
|
|
537
|
+
return this.device.attributes.POWER === true && this.device.attributes.MODE === ACMode.FAN_ONLY;
|
|
497
538
|
}
|
|
498
539
|
async setFanOnlyMode(value) {
|
|
499
540
|
if (value) {
|
|
500
|
-
await this.device.set_attribute({ POWER: true, MODE:
|
|
541
|
+
await this.device.set_attribute({ POWER: true, MODE: ACMode.FAN_ONLY });
|
|
501
542
|
}
|
|
502
543
|
else {
|
|
503
|
-
await this.device.set_attribute({ POWER: false, MODE:
|
|
544
|
+
await this.device.set_attribute({ POWER: false, MODE: ACMode.OFF });
|
|
504
545
|
}
|
|
505
546
|
}
|
|
506
547
|
getFanState() {
|
|
@@ -509,8 +550,30 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
509
550
|
async setFanState(value) {
|
|
510
551
|
await this.device.set_fan_auto(value === this.platform.Characteristic.TargetFanState.AUTO);
|
|
511
552
|
}
|
|
512
|
-
|
|
513
|
-
|
|
553
|
+
setHeatingCoolingTemperatureThresholds(thresholds) {
|
|
554
|
+
const { minTemp, maxTemp, tempStep } = this.configDev.AC_options;
|
|
555
|
+
const heating = limitValue(thresholds?.heating ?? this.heatingThresholdTemperature, minTemp, maxTemp);
|
|
556
|
+
const cooling = limitValue(thresholds?.cooling ?? this.coolingThresholdTemperature, minTemp, maxTemp);
|
|
557
|
+
if (heating === this.heatingThresholdTemperature && cooling === this.coolingThresholdTemperature)
|
|
558
|
+
return;
|
|
559
|
+
this.heatingThresholdTemperature = !thresholds?.cooling || heating < cooling ? heating : cooling - tempStep;
|
|
560
|
+
this.coolingThresholdTemperature = !thresholds?.heating || heating < cooling ? cooling : heating + tempStep;
|
|
561
|
+
this.service.updateCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature, this.getHeatingThresholdTemperature());
|
|
562
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature, this.getCoolingThresholdTemperature());
|
|
563
|
+
const { context: ctx } = this.accessory;
|
|
564
|
+
ctx.thresholds ??= {};
|
|
565
|
+
this.platform.log.debug(`[${this.device.name}] Persisting updated heating and cooling thresholds`);
|
|
566
|
+
ctx.thresholds.heatingTemperature = this.heatingThresholdTemperature;
|
|
567
|
+
ctx.thresholds.coolingTemperature = this.coolingThresholdTemperature;
|
|
568
|
+
this.platform.api.updatePlatformAccessories([this.accessory]);
|
|
569
|
+
}
|
|
570
|
+
async setCoolingThresholdTemperature(value) {
|
|
571
|
+
this.setHeatingCoolingTemperatureThresholds({ cooling: Number(value) });
|
|
572
|
+
await this.setTargetTemperatureWithinThresholds();
|
|
573
|
+
}
|
|
574
|
+
async setHeatingThresholdTemperature(value) {
|
|
575
|
+
this.setHeatingCoolingTemperatureThresholds({ heating: Number(value) });
|
|
576
|
+
await this.setTargetTemperatureWithinThresholds();
|
|
514
577
|
}
|
|
515
578
|
getSwingMode() {
|
|
516
579
|
return this.device.attributes.SWING_HORIZONTAL || this.device.attributes.SWING_VERTICAL
|
|
@@ -557,14 +620,14 @@ export default class AirConditionerAccessory extends BaseAccessory {
|
|
|
557
620
|
await this.device.set_attribute({ INDIRECT_WIND: !!value });
|
|
558
621
|
}
|
|
559
622
|
getDryMode() {
|
|
560
|
-
return this.device.attributes.POWER === true && this.device.attributes.MODE ===
|
|
623
|
+
return this.device.attributes.POWER === true && this.device.attributes.MODE === ACMode.DRY;
|
|
561
624
|
}
|
|
562
625
|
async setDryMode(value) {
|
|
563
626
|
if (value) {
|
|
564
|
-
await this.device.set_attribute({ POWER: true, MODE:
|
|
627
|
+
await this.device.set_attribute({ POWER: true, MODE: ACMode.DRY });
|
|
565
628
|
}
|
|
566
629
|
else {
|
|
567
|
-
await this.device.set_attribute({ POWER: false, MODE:
|
|
630
|
+
await this.device.set_attribute({ POWER: false, MODE: ACMode.OFF });
|
|
568
631
|
}
|
|
569
632
|
}
|
|
570
633
|
getBoostMode() {
|