homebridge-melcloud-control 4.2.2-beta.1 → 4.2.2-beta.11
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/CHANGELOG.md +10 -0
- package/README.md +6 -0
- package/config.schema.json +42 -0
- package/index.js +1 -1
- package/package.json +1 -1
- package/src/deviceata.js +114 -65
- package/src/deviceatw.js +65 -24
- package/src/deviceerv.js +155 -109
- package/src/melcloud.js +8 -12
- package/src/melcloudata.js +11 -10
- package/src/melcloudatw.js +11 -10
- package/src/melclouderv.js +11 -10
package/src/deviceerv.js
CHANGED
|
@@ -30,6 +30,8 @@ class DeviceErv extends EventEmitter {
|
|
|
30
30
|
this.temperatureSensor = device.temperatureSensor || false;
|
|
31
31
|
this.temperatureOutdoorSensor = device.temperatureOutdoorSensor || false;
|
|
32
32
|
this.temperatureSupplySensor = device.temperatureSupplySensor || false;
|
|
33
|
+
this.inStandbySensor = device.inStandbySensor || false;
|
|
34
|
+
this.connectSensor = device.connectSensor || false;
|
|
33
35
|
this.errorSensor = device.errorSensor || false;
|
|
34
36
|
this.holidayModeSupport = device.holidayModeSupport || false;
|
|
35
37
|
this.presets = this.accountType === 'melcloud' ? (device.presets || []).filter(preset => (preset.displayType ?? 0) > 0 && preset.id !== '0') : [];
|
|
@@ -261,16 +263,17 @@ class DeviceErv extends EventEmitter {
|
|
|
261
263
|
const accountName = this.accountName;
|
|
262
264
|
const presetsOnServer = this.accessory.presets;
|
|
263
265
|
const schedulesOnServer = this.accessory.schedules;
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
const
|
|
272
|
-
const
|
|
273
|
-
const
|
|
266
|
+
const supportsRoomTemperature = this.accessory.supportsRoomTemperature;
|
|
267
|
+
const supportsSupplyTemperature = this.accessory.supportsSupplyTemperature;
|
|
268
|
+
const supportsOutdoorTemperature = this.accessory.supportsOutdoorTemperature;
|
|
269
|
+
const supportsCoolOperationMode = this.accessory.supportsCoolOperationMode;
|
|
270
|
+
const supportsHeatOperationMode = this.accessory.supportsHeatOperationMode;
|
|
271
|
+
const supportsAutoVentilationMode = this.accessory.supportsAutoVentilationMode;
|
|
272
|
+
const supportsBypassVentilationMode = this.accessory.supportsBypassVentilationMode;
|
|
273
|
+
const supportsAutomaticFanSpeed = this.accessory.supportsAutomaticFanSpeed;
|
|
274
|
+
const supportsCO2Sensor = this.accessory.supportsCO2Sensor;
|
|
275
|
+
const supportsPM25Sensor = this.accessory.supportsPM25Sensor;
|
|
276
|
+
const supportsFanSpeed = this.accessory.supportsFanSpeed;
|
|
274
277
|
const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
|
|
275
278
|
|
|
276
279
|
//accessory
|
|
@@ -331,13 +334,13 @@ class DeviceErv extends EventEmitter {
|
|
|
331
334
|
try {
|
|
332
335
|
switch (value) {
|
|
333
336
|
case 0: //AUTO - AUTO
|
|
334
|
-
deviceData.Device.VentilationMode =
|
|
337
|
+
deviceData.Device.VentilationMode = supportsAutoVentilationMode ? 2 : 0;
|
|
335
338
|
break;
|
|
336
339
|
case 1: //HEAT - LOSSNAY
|
|
337
340
|
deviceData.Device.VentilationMode = 0;
|
|
338
341
|
break;
|
|
339
342
|
case 2: //COOL - BYPASS
|
|
340
|
-
deviceData.Device.VentilationMode =
|
|
343
|
+
deviceData.Device.VentilationMode = supportsBypassVentilationMode ? 1 : 0;
|
|
341
344
|
break;
|
|
342
345
|
};
|
|
343
346
|
|
|
@@ -353,42 +356,44 @@ class DeviceErv extends EventEmitter {
|
|
|
353
356
|
const value = this.accessory.roomTemperature;
|
|
354
357
|
return value;
|
|
355
358
|
});
|
|
356
|
-
|
|
357
|
-
.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
359
|
+
if (supportsFanSpeed) {
|
|
360
|
+
this.melCloudService.getCharacteristic(Characteristic.RotationSpeed)
|
|
361
|
+
.setProps({
|
|
362
|
+
minValue: 0,
|
|
363
|
+
maxValue: this.accessory.fanSpeedSetPropsMaxValue,
|
|
364
|
+
minStep: 1
|
|
365
|
+
})
|
|
366
|
+
.onGet(async () => {
|
|
367
|
+
const value = this.accessory.fanSpeed; //STOP, 1, 2, 3, 4, OFF
|
|
368
|
+
return value;
|
|
369
|
+
})
|
|
370
|
+
.onSet(async (value) => {
|
|
371
|
+
try {
|
|
372
|
+
switch (numberOfFanSpeeds) {
|
|
373
|
+
case 2: //Fan speed mode 2
|
|
374
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
|
|
375
|
+
break;
|
|
376
|
+
case 3: //Fan speed mode 3
|
|
377
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
|
|
378
|
+
break;
|
|
379
|
+
case 4: //Fan speed mode 4
|
|
380
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
|
|
381
|
+
break;
|
|
382
|
+
case 5: //Fan speed mode 5
|
|
383
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
|
|
384
|
+
break;;
|
|
385
|
+
};
|
|
382
386
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
387
|
+
deviceData.Device.SetFanSpeed = value
|
|
388
|
+
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, Ventilation.EffectiveFlags.SetFanSpeed);
|
|
389
|
+
if (this.logInfo) this.emit('info', `Set fan speed mode: ${Ventilation.FanSpeedMapEnumToString[value]}`);
|
|
390
|
+
} catch (error) {
|
|
391
|
+
if (this.logWarn) this.emit('warn', `Set fan speed mode error: ${error}`);
|
|
392
|
+
};
|
|
393
|
+
});
|
|
394
|
+
}
|
|
390
395
|
//device can cool
|
|
391
|
-
if (
|
|
396
|
+
if (supportsAutoVentilationMode && supportsCoolOperationMode) {
|
|
392
397
|
this.melCloudService.getCharacteristic(Characteristic.CoolingThresholdTemperature)
|
|
393
398
|
.setProps({
|
|
394
399
|
minValue: this.accessory.minTempCoolDry,
|
|
@@ -410,7 +415,7 @@ class DeviceErv extends EventEmitter {
|
|
|
410
415
|
});
|
|
411
416
|
};
|
|
412
417
|
//device can heat
|
|
413
|
-
if (
|
|
418
|
+
if (supportsAutoVentilationMode && supportsHeatOperationMode) {
|
|
414
419
|
this.melCloudService.getCharacteristic(Characteristic.HeatingThresholdTemperature)
|
|
415
420
|
.setProps({
|
|
416
421
|
minValue: this.accessory.minTempHeat,
|
|
@@ -500,12 +505,12 @@ class DeviceErv extends EventEmitter {
|
|
|
500
505
|
break;
|
|
501
506
|
case 2: //COOL - BYPASS
|
|
502
507
|
deviceData.Device.Power = true;
|
|
503
|
-
deviceData.Device.VentilationMode =
|
|
508
|
+
deviceData.Device.VentilationMode = supportsBypassVentilationMode ? 1 : 0;
|
|
504
509
|
effectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
505
510
|
break;
|
|
506
511
|
case 3: //AUTO - AUTO
|
|
507
512
|
deviceData.Device.Power = true;
|
|
508
|
-
deviceData.Device.VentilationMode =
|
|
513
|
+
deviceData.Device.VentilationMode = supportsAutoVentilationMode ? 2 : 0;
|
|
509
514
|
effectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
510
515
|
break;
|
|
511
516
|
};
|
|
@@ -563,7 +568,7 @@ class DeviceErv extends EventEmitter {
|
|
|
563
568
|
};
|
|
564
569
|
|
|
565
570
|
//temperature sensor service room
|
|
566
|
-
if (this.temperatureSensor &&
|
|
571
|
+
if (this.temperatureSensor && supportsRoomTemperature && this.accessory.roomTemperature !== null) {
|
|
567
572
|
if (this.logDebug) this.emit('debug', `Prepare room temperature sensor service`);
|
|
568
573
|
this.roomTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Room`, `Room Temperature Sensor ${deviceId}`);
|
|
569
574
|
this.roomTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
@@ -582,7 +587,7 @@ class DeviceErv extends EventEmitter {
|
|
|
582
587
|
};
|
|
583
588
|
|
|
584
589
|
//temperature sensor service supply
|
|
585
|
-
if (this.temperatureSupplySensor &&
|
|
590
|
+
if (this.temperatureSupplySensor && supportsSupplyTemperature && this.accessory.supplyTemperature !== null) {
|
|
586
591
|
if (this.logDebug) this.emit('debug', `Prepare supply temperature sensor service`);
|
|
587
592
|
this.supplyTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Supply`, `Supply Temperature Sensor ${deviceId}`);
|
|
588
593
|
this.supplyTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
@@ -601,7 +606,7 @@ class DeviceErv extends EventEmitter {
|
|
|
601
606
|
};
|
|
602
607
|
|
|
603
608
|
//temperature sensor service outdoor
|
|
604
|
-
if (this.temperatureOutdoorSensor &&
|
|
609
|
+
if (this.temperatureOutdoorSensor && supportsOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
|
|
605
610
|
if (this.logDebug) this.emit('debug', `Prepare outdoor temperature sensor service`);
|
|
606
611
|
this.outdoorTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Outdoor`, `Outdoor Temperature Sensor ${deviceId}`);
|
|
607
612
|
this.outdoorTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
@@ -652,7 +657,7 @@ class DeviceErv extends EventEmitter {
|
|
|
652
657
|
}
|
|
653
658
|
|
|
654
659
|
//room CO2 sensor
|
|
655
|
-
if (
|
|
660
|
+
if (supportsCO2Sensor) {
|
|
656
661
|
this.carbonDioxideSensorService = new Service.CarbonDioxideSensor(`${serviceName} CO2 Sensor`, `CO2Sensor ${deviceId}`);
|
|
657
662
|
this.carbonDioxideSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
658
663
|
this.carbonDioxideSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} CO2 Sensor`);
|
|
@@ -670,7 +675,7 @@ class DeviceErv extends EventEmitter {
|
|
|
670
675
|
}
|
|
671
676
|
|
|
672
677
|
//room PM2.5 sensor
|
|
673
|
-
if (
|
|
678
|
+
if (supportsPM25Sensor) {
|
|
674
679
|
this.airQualitySensorService = new Service.AirQualitySensor(`${serviceName} PM2.5 Sensor`, `PM25Sensor ${deviceId}`);
|
|
675
680
|
this.airQualitySensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
676
681
|
this.airQualitySensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} PM2.5 Sensor`);
|
|
@@ -687,10 +692,37 @@ class DeviceErv extends EventEmitter {
|
|
|
687
692
|
accessory.addService(this.airQualitySensorService);
|
|
688
693
|
}
|
|
689
694
|
|
|
695
|
+
if (this.inStandbySensor && this.accessory.inStandbyMode !== null) {
|
|
696
|
+
if (this.logDebug) this.emit('debug', `Prepare in standby mode service`);
|
|
697
|
+
this.inStandbyService = new Service.ContactSensor(`${serviceName} In Standby`, `inStandbyService${deviceId}`);
|
|
698
|
+
this.inStandbyService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
699
|
+
this.inStandbyService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} In Standby`);
|
|
700
|
+
this.inStandbyService.getCharacteristic(Characteristic.ContactSensorState)
|
|
701
|
+
.onGet(async () => {
|
|
702
|
+
const state = this.accessory.isConnected;
|
|
703
|
+
return state;
|
|
704
|
+
})
|
|
705
|
+
accessory.addService(this.inStandbyService);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
//connect sensor
|
|
709
|
+
if (this.connectSensor && this.accessory.isConnected !== null) {
|
|
710
|
+
if (this.logDebug) this.emit('debug', `Prepare connect service`);
|
|
711
|
+
this.connectService = new Service.ContactSensor(`${serviceName} Connected`, `connectService${deviceId}`);
|
|
712
|
+
this.connectService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
713
|
+
this.connectService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Connected`);
|
|
714
|
+
this.connectService.getCharacteristic(Characteristic.ContactSensorState)
|
|
715
|
+
.onGet(async () => {
|
|
716
|
+
const state = this.accessory.isConnected;
|
|
717
|
+
return state;
|
|
718
|
+
})
|
|
719
|
+
accessory.addService(this.connectService);
|
|
720
|
+
}
|
|
721
|
+
|
|
690
722
|
//error sensor
|
|
691
723
|
if (this.errorSensor && this.accessory.isInError !== null) {
|
|
692
724
|
if (this.logDebug) this.emit('debug', `Prepare error service`);
|
|
693
|
-
this.errorService = new Service.ContactSensor(`${serviceName} Error`, `
|
|
725
|
+
this.errorService = new Service.ContactSensor(`${serviceName} Error`, `errorService${deviceId}`);
|
|
694
726
|
this.errorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
695
727
|
this.errorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Error`);
|
|
696
728
|
this.errorService.getCharacteristic(Characteristic.ContactSensorState)
|
|
@@ -1016,8 +1048,11 @@ class DeviceErv extends EventEmitter {
|
|
|
1016
1048
|
this.deviceData = deviceData;
|
|
1017
1049
|
|
|
1018
1050
|
//keys
|
|
1051
|
+
const accountTypeMelcloud = this.accountType === 'melcloud';
|
|
1019
1052
|
const tempStepKey = this.accountType === 'melcloud' ? 'TemperatureIncrement' : 'HasHalfDegreeIncrements';
|
|
1053
|
+
const connectKey = this.accountType === 'melcloud' ? 'Offline' : 'IsConnected';
|
|
1020
1054
|
const errorKey = this.accountType === 'melcloud' ? 'HasError' : 'IsInError';
|
|
1055
|
+
const supportStandbyKey = accountTypeMelcloud ? 'ModelSupportsStandbyMode' : 'HasStandby';
|
|
1021
1056
|
|
|
1022
1057
|
//presets schedule
|
|
1023
1058
|
const scheduleEnabled = deviceData.ScheduleEnabled;
|
|
@@ -1032,26 +1067,28 @@ class DeviceErv extends EventEmitter {
|
|
|
1032
1067
|
const hideOutdoorTemperature = deviceData.HideOutdoorTemperature;
|
|
1033
1068
|
|
|
1034
1069
|
//device info
|
|
1035
|
-
const
|
|
1036
|
-
const
|
|
1037
|
-
const
|
|
1038
|
-
const
|
|
1039
|
-
const
|
|
1040
|
-
const
|
|
1041
|
-
const
|
|
1070
|
+
const supportsCoolOperationMode = deviceData.Device.HasCoolOperationMode ?? false;
|
|
1071
|
+
const supportsHeatOperationMode = deviceData.Device.HasHeatOperationMode ?? false;
|
|
1072
|
+
const supportsAutoOperationMode = deviceData.Device.HasAutoOperationMode ?? false;
|
|
1073
|
+
const supportsRoomTemperature = deviceData.Device.HasRoomTemperature ?? false;
|
|
1074
|
+
const supportsSupplyTemperature = deviceData.Device.HasSupplyTemperature ?? false;
|
|
1075
|
+
const supportsOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
|
|
1076
|
+
const supportsCO2Sensor = deviceData.Device.HasCO2Sensor ?? false;
|
|
1077
|
+
const supportsStanbyMode = deviceData.Device[supportStandbyKey];
|
|
1042
1078
|
const roomCO2Level = deviceData.Device.RoomCO2Level ?? false;
|
|
1043
|
-
const roomCO2Detected =
|
|
1044
|
-
const
|
|
1045
|
-
const pM25SensorStatus =
|
|
1046
|
-
const pM25Level =
|
|
1047
|
-
const pM25AirQuality =
|
|
1048
|
-
const
|
|
1049
|
-
const
|
|
1050
|
-
const
|
|
1079
|
+
const roomCO2Detected = supportsCO2Sensor && roomCO2Level > 1000 ? true : false;
|
|
1080
|
+
const supportsPM25Sensor = deviceData.Device.HasPM25Sensor ?? false;
|
|
1081
|
+
const pM25SensorStatus = supportsPM25Sensor ? deviceData.Device.PM25SensorStatus : 0;
|
|
1082
|
+
const pM25Level = supportsPM25Sensor ? deviceData.Device.PM25Level : 0;
|
|
1083
|
+
const pM25AirQuality = supportsPM25Sensor ? pM25Level <= 13 ? 1 : pM25Level <= 35 ? 2 : pM25Level <= 55 ? 3 : pM25Level <= 75 ? 4 : pM25Level <= 110 ? 5 : 0 : 0;
|
|
1084
|
+
const supportsAutoVentilationMode = deviceData.Device.HasAutoVentilationMode ?? false;
|
|
1085
|
+
const supportsBypassVentilationMode = deviceData.Device.HasBypassVentilationMode ?? false;
|
|
1086
|
+
const supportsAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
|
|
1051
1087
|
const coreMaintenanceRequired = deviceData.Device.CoreMaintenanceRequired;
|
|
1052
1088
|
const filterMaintenanceRequired = deviceData.Device.FilterMaintenanceRequired;
|
|
1053
1089
|
const actualVentilationMode = deviceData.Device.ActualVentilationMode;
|
|
1054
1090
|
const numberOfFanSpeeds = deviceData.Device.NumberOfFanSpeeds;
|
|
1091
|
+
const supportsFanSpeed = numberOfFanSpeeds > 0;
|
|
1055
1092
|
const temperatureIncrement = deviceData.Device[tempStepKey] ?? 1;
|
|
1056
1093
|
const minTempHeat = 10;
|
|
1057
1094
|
const maxTempHeat = 31;
|
|
@@ -1060,6 +1097,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1060
1097
|
|
|
1061
1098
|
//device state
|
|
1062
1099
|
const power = deviceData.Device.Power;
|
|
1100
|
+
const inStandbyMode = deviceData.Device.InStandbyMode;
|
|
1063
1101
|
const roomTemperature = deviceData.Device.RoomTemperature;
|
|
1064
1102
|
const supplyTemperature = deviceData.Device.SupplyTemperature;
|
|
1065
1103
|
const outdoorTemperature = deviceData.Device.OutdoorTemperature;
|
|
@@ -1070,32 +1108,36 @@ class DeviceErv extends EventEmitter {
|
|
|
1070
1108
|
const setFanSpeed = deviceData.Device.SetFanSpeed;
|
|
1071
1109
|
const operationMode = deviceData.Device.OperationMode;
|
|
1072
1110
|
const ventilationMode = deviceData.Device.VentilationMode;
|
|
1111
|
+
const isConnected = accountTypeMelcloud ? !deviceData.Device[connectKey] : deviceData.Device[connectKey];
|
|
1073
1112
|
const isInError = deviceData.Device[errorKey];
|
|
1074
1113
|
|
|
1075
1114
|
//accessory
|
|
1076
1115
|
const obj = {
|
|
1077
1116
|
presets: presetsOnServer,
|
|
1078
1117
|
schedules: schedulesOnServer,
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1118
|
+
supportsRoomTemperature: supportsRoomTemperature,
|
|
1119
|
+
supportsSupplyTemperature: supportsSupplyTemperature,
|
|
1120
|
+
supportsOutdoorTemperature: supportsOutdoorTemperature,
|
|
1121
|
+
supportsCoolOperationMode: supportsCoolOperationMode,
|
|
1122
|
+
supportsHeatOperationMode: supportsHeatOperationMode,
|
|
1123
|
+
supportsCO2Sensor: supportsCO2Sensor,
|
|
1085
1124
|
roomCO2Level: roomCO2Level,
|
|
1086
1125
|
roomCO2Detected: roomCO2Detected,
|
|
1087
|
-
|
|
1126
|
+
supportsPM25Sensor: supportsPM25Sensor,
|
|
1088
1127
|
pM25SensorStatus: pM25SensorStatus,
|
|
1089
1128
|
pM25Level: pM25Level,
|
|
1090
1129
|
pM25AirQuality: pM25AirQuality,
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1130
|
+
supportsAutoVentilationMode: supportsAutoVentilationMode,
|
|
1131
|
+
supportsBypassVentilationMode: supportsBypassVentilationMode,
|
|
1132
|
+
supportsAutomaticFanSpeed: supportsAutomaticFanSpeed,
|
|
1133
|
+
supportsStanbyMode: supportsStanbyMode,
|
|
1094
1134
|
coreMaintenanceRequired: coreMaintenanceRequired,
|
|
1095
1135
|
filterMaintenanceRequired: filterMaintenanceRequired,
|
|
1096
1136
|
actualVentilationMode: actualVentilationMode,
|
|
1097
1137
|
numberOfFanSpeeds: numberOfFanSpeeds,
|
|
1138
|
+
supportsFanSpeed: supportsFanSpeed,
|
|
1098
1139
|
power: power ? 1 : 0,
|
|
1140
|
+
inStandbyMode: inStandbyMode,
|
|
1099
1141
|
operationMode: operationMode,
|
|
1100
1142
|
currentOperationMode: 0,
|
|
1101
1143
|
targetOperationMode: 0,
|
|
@@ -1114,6 +1156,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1114
1156
|
maxTempCoolDry: maxTempCoolDry,
|
|
1115
1157
|
useFahrenheit: this.useFahrenheit,
|
|
1116
1158
|
temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit],
|
|
1159
|
+
isConnected: isConnected,
|
|
1117
1160
|
isInError: isInError,
|
|
1118
1161
|
scheduleEnabled: scheduleEnabled,
|
|
1119
1162
|
holidayModeEnabled: holidayModeEnabled,
|
|
@@ -1154,26 +1197,27 @@ class DeviceErv extends EventEmitter {
|
|
|
1154
1197
|
|
|
1155
1198
|
obj.currentOperationMode = !power ? 0 : obj.currentOperationMode;
|
|
1156
1199
|
obj.targetOperationMode = obj.targetOperationMode;
|
|
1157
|
-
obj.operationModeSetPropsMinValue =
|
|
1158
|
-
obj.operationModeSetPropsMaxValue =
|
|
1159
|
-
obj.operationModeSetPropsValidValues =
|
|
1200
|
+
obj.operationModeSetPropsMinValue = supportsAutoVentilationMode ? 0 : 1;
|
|
1201
|
+
obj.operationModeSetPropsMaxValue = supportsAutoVentilationMode ? 2 : 2;
|
|
1202
|
+
obj.operationModeSetPropsValidValues = supportsAutoVentilationMode ? (supportsBypassVentilationMode ? [0, 1, 2] : [0, 2]) : (supportsBypassVentilationMode ? [1, 2] : [2]);
|
|
1160
1203
|
|
|
1161
1204
|
//fan speed mode
|
|
1162
1205
|
obj.fanSpeedSetPropsMaxValue = 2;
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1206
|
+
|
|
1207
|
+
// fan speed mode
|
|
1208
|
+
if (supportsFanSpeed) {
|
|
1209
|
+
const max = numberOfFanSpeeds;
|
|
1210
|
+
const autoIndex = supportsAutomaticFanSpeed ? max + 1 : 0;
|
|
1211
|
+
|
|
1212
|
+
// Tworzymy tablicę prędkości: [auto?, 1..N]
|
|
1213
|
+
const speeds = [autoIndex];
|
|
1214
|
+
for (let i = 1; i <= max; i++) {
|
|
1215
|
+
speeds.push(i);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
obj.fanSpeed = speeds[setFanSpeed];
|
|
1219
|
+
obj.fanSpeedSetPropsMaxValue = supportsAutomaticFanSpeed ? max + 1 : max;
|
|
1220
|
+
}
|
|
1177
1221
|
|
|
1178
1222
|
//update characteristics
|
|
1179
1223
|
this.melCloudService
|
|
@@ -1184,8 +1228,8 @@ class DeviceErv extends EventEmitter {
|
|
|
1184
1228
|
.updateCharacteristic(Characteristic.RotationSpeed, obj.fanSpeed)
|
|
1185
1229
|
.updateCharacteristic(Characteristic.LockPhysicalControls, obj.lockPhysicalControl)
|
|
1186
1230
|
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, obj.useFahrenheit);
|
|
1187
|
-
const updateDefCool =
|
|
1188
|
-
const updateDefHeat =
|
|
1231
|
+
const updateDefCool = supportsCoolOperationMode ? this.melCloudService?.updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature) : false;
|
|
1232
|
+
const updateDefHeat = supportsHeatOperationMode ? this.melCloudService?.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
|
|
1189
1233
|
break;
|
|
1190
1234
|
case 2: //Thermostat
|
|
1191
1235
|
//operation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
|
|
@@ -1219,9 +1263,9 @@ class DeviceErv extends EventEmitter {
|
|
|
1219
1263
|
|
|
1220
1264
|
obj.currentOperationMode = !power ? 0 : obj.currentOperationMode;
|
|
1221
1265
|
obj.targetOperationMode = !power ? 0 : obj.targetOperationMode;
|
|
1222
|
-
obj.operationModeSetPropsMinValue =
|
|
1223
|
-
obj.operationModeSetPropsMaxValue =
|
|
1224
|
-
obj.operationModeSetPropsValidValues =
|
|
1266
|
+
obj.operationModeSetPropsMinValue = supportsAutoVentilationMode ? 0 : 0;
|
|
1267
|
+
obj.operationModeSetPropsMaxValue = supportsAutoVentilationMode ? 3 : 2;
|
|
1268
|
+
obj.operationModeSetPropsValidValues = supportsAutoVentilationMode ? (supportsBypassVentilationMode ? [0, 1, 2, 3] : [0, 2, 3]) : (supportsBypassVentilationMode ? [0, 1, 2] : [0, 2]);
|
|
1225
1269
|
|
|
1226
1270
|
//update characteristics
|
|
1227
1271
|
this.melCloudService
|
|
@@ -1255,7 +1299,9 @@ class DeviceErv extends EventEmitter {
|
|
|
1255
1299
|
?.updateCharacteristic(Characteristic.AirQuality, pM25AirQuality)
|
|
1256
1300
|
.updateCharacteristic(Characteristic.PM2_5Density, pM25Level);
|
|
1257
1301
|
|
|
1258
|
-
//
|
|
1302
|
+
//other sensors
|
|
1303
|
+
this.inStandbyService?.updateCharacteristic(Characteristic.ContactSensorState, inStandbyMode);
|
|
1304
|
+
this.connectService?.updateCharacteristic(Characteristic.ContactSensorState, isConnected);
|
|
1259
1305
|
this.errorService?.updateCharacteristic(Characteristic.ContactSensorState, isInError);
|
|
1260
1306
|
|
|
1261
1307
|
//holiday mode
|
|
@@ -1361,16 +1407,16 @@ class DeviceErv extends EventEmitter {
|
|
|
1361
1407
|
this.emit('info', `Current ventilation mode: ${Ventilation.OperationModeMapEnumToString[actualVentilationMode]}`);
|
|
1362
1408
|
this.emit('info', `Target temperature: ${setTemperature}${obj.temperatureUnit}`);
|
|
1363
1409
|
this.emit('info', `Room temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
1364
|
-
if (
|
|
1365
|
-
if (
|
|
1410
|
+
if (supportsSupplyTemperature && deviceData.Device.SupplyTemperature !== null) this.emit('info', `Supply temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
1411
|
+
if (supportsOutdoorTemperature && deviceData.Device.OutdoorTemperature !== null) this.emit('info', `Outdoor temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
1366
1412
|
this.emit('info', `Fan speed mode: ${Ventilation.FanSpeedMapEnumToString[setFanSpeed]}`);
|
|
1367
1413
|
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
1368
1414
|
this.emit('info', `Core maintenance: ${Ventilation.CoreMaintenanceMapEnumToString[coreMaintenanceRequired]}`);
|
|
1369
1415
|
this.emit('info', `Filter maintenance: ${Ventilation.FilterMaintenanceMapEnumToString[filterMaintenanceRequired]}`);
|
|
1370
|
-
if (
|
|
1371
|
-
if (
|
|
1372
|
-
if (
|
|
1373
|
-
if (
|
|
1416
|
+
if (supportsCO2Sensor) this.emit('info', `CO2 detected: ${Ventilation.Co2DetectedMapEnumToString[roomCO2Detected]}`);
|
|
1417
|
+
if (supportsCO2Sensor) this.emit('info', `CO2 level: ${roomCO2Level} ppm`);
|
|
1418
|
+
if (supportsPM25Sensor) this.emit('info', `PM2.5 air quality: ${Ventilation.PM25AirQualityMapEnumToString[pM25AirQuality]}`);
|
|
1419
|
+
if (supportsPM25Sensor) this.emit('info', `PM2.5 level: ${pM25Level} µg/m`);
|
|
1374
1420
|
};
|
|
1375
1421
|
})
|
|
1376
1422
|
.on('success', (success) => this.emit('success', success))
|
package/src/melcloud.js
CHANGED
|
@@ -76,22 +76,19 @@ class MelCloud extends EventEmitter {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
if (this.logDebug) this.emit('debug', `Scanning for devices...`);
|
|
79
|
-
|
|
80
79
|
const listDevicesData = await axiosInstance(ApiUrls.ListDevices);
|
|
81
80
|
|
|
82
81
|
if (!listDevicesData || !listDevicesData.data) {
|
|
83
|
-
|
|
84
|
-
return
|
|
82
|
+
devicesList.Info = 'Invalid or empty response from MELCloud API'
|
|
83
|
+
return devicesList;
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
const buildingsList = listDevicesData.data;
|
|
88
|
-
|
|
89
|
-
if (this.logDebug)
|
|
90
|
-
this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`);
|
|
87
|
+
if (this.logDebug) this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`);
|
|
91
88
|
|
|
92
89
|
if (!Array.isArray(buildingsList) || buildingsList.length === 0) {
|
|
93
|
-
|
|
94
|
-
return
|
|
90
|
+
devicesList.Info = 'No building found'
|
|
91
|
+
return devicesList;
|
|
95
92
|
}
|
|
96
93
|
|
|
97
94
|
await this.functions.saveData(this.buildingsFile, buildingsList);
|
|
@@ -137,8 +134,7 @@ class MelCloud extends EventEmitter {
|
|
|
137
134
|
devicesList.Info = `Found ${devicesCount} devices`;
|
|
138
135
|
return devicesList;
|
|
139
136
|
} catch (error) {
|
|
140
|
-
|
|
141
|
-
throw new Error(`Check devices list error: ${msg}`);
|
|
137
|
+
throw new Error(`Check devices list error: ${error.message}`);
|
|
142
138
|
}
|
|
143
139
|
}
|
|
144
140
|
|
|
@@ -227,7 +223,6 @@ class MelCloud extends EventEmitter {
|
|
|
227
223
|
if (this.logDebug) this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`);
|
|
228
224
|
|
|
229
225
|
if (!buildingsList) {
|
|
230
|
-
devicesList.State = false;
|
|
231
226
|
devicesList.Info = 'No building found'
|
|
232
227
|
return devicesList;
|
|
233
228
|
}
|
|
@@ -280,7 +275,8 @@ class MelCloud extends EventEmitter {
|
|
|
280
275
|
const deviceObject = {
|
|
281
276
|
...capitalizeKeys(device.Capabilities || {}),
|
|
282
277
|
...settingsObject,
|
|
283
|
-
DeviceType: type
|
|
278
|
+
DeviceType: type,
|
|
279
|
+
IsConnected: device.IsConnected
|
|
284
280
|
};
|
|
285
281
|
|
|
286
282
|
// Kapitalizacja brakujących obiektów/tablic
|
package/src/melcloudata.js
CHANGED
|
@@ -25,11 +25,9 @@ class MelCloudAta extends EventEmitter {
|
|
|
25
25
|
this.deviceData = {};
|
|
26
26
|
|
|
27
27
|
//lock flags
|
|
28
|
-
this.locks =
|
|
29
|
-
checkState: false,
|
|
30
|
-
};
|
|
28
|
+
this.locks = true;
|
|
31
29
|
this.impulseGenerator = new ImpulseGenerator()
|
|
32
|
-
.on('checkState', () => this.handleWithLock(
|
|
30
|
+
.on('checkState', () => this.handleWithLock(async () => {
|
|
33
31
|
await this.checkState();
|
|
34
32
|
}))
|
|
35
33
|
.on('state', (state) => {
|
|
@@ -37,16 +35,16 @@ class MelCloudAta extends EventEmitter {
|
|
|
37
35
|
});
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
async handleWithLock(
|
|
41
|
-
if (this.locks
|
|
38
|
+
async handleWithLock(fn) {
|
|
39
|
+
if (this.locks) return;
|
|
42
40
|
|
|
43
|
-
this.locks
|
|
41
|
+
this.locks = true;
|
|
44
42
|
try {
|
|
45
43
|
await fn();
|
|
46
44
|
} catch (error) {
|
|
47
45
|
this.emit('error', `Inpulse generator error: ${error}`);
|
|
48
46
|
} finally {
|
|
49
|
-
this.locks
|
|
47
|
+
this.locks = false;
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
|
|
@@ -282,9 +280,12 @@ class MelCloudAta extends EventEmitter {
|
|
|
282
280
|
}
|
|
283
281
|
|
|
284
282
|
updateData(deviceData) {
|
|
283
|
+
this.lock = true;
|
|
284
|
+
this.emit('deviceState', deviceData);
|
|
285
|
+
|
|
285
286
|
setTimeout(() => {
|
|
286
|
-
this.
|
|
287
|
-
},
|
|
287
|
+
this.lock = false
|
|
288
|
+
}, 3000);
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
};
|
package/src/melcloudatw.js
CHANGED
|
@@ -25,11 +25,9 @@ class MelCloudAtw extends EventEmitter {
|
|
|
25
25
|
this.devicesData = {};
|
|
26
26
|
|
|
27
27
|
//lock flags
|
|
28
|
-
this.locks =
|
|
29
|
-
checkState: false,
|
|
30
|
-
};
|
|
28
|
+
this.locks = true;
|
|
31
29
|
this.impulseGenerator = new ImpulseGenerator()
|
|
32
|
-
.on('checkState', () => this.handleWithLock(
|
|
30
|
+
.on('checkState', () => this.handleWithLock(async () => {
|
|
33
31
|
await this.checkState();
|
|
34
32
|
}))
|
|
35
33
|
.on('state', (state) => {
|
|
@@ -37,16 +35,16 @@ class MelCloudAtw extends EventEmitter {
|
|
|
37
35
|
});
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
async handleWithLock(
|
|
41
|
-
if (this.locks
|
|
38
|
+
async handleWithLock(fn) {
|
|
39
|
+
if (this.locks) return;
|
|
42
40
|
|
|
43
|
-
this.locks
|
|
41
|
+
this.locks = true;
|
|
44
42
|
try {
|
|
45
43
|
await fn();
|
|
46
44
|
} catch (error) {
|
|
47
45
|
this.emit('error', `Inpulse generator error: ${error}`);
|
|
48
46
|
} finally {
|
|
49
|
-
this.locks
|
|
47
|
+
this.locks = false;
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
|
|
@@ -252,9 +250,12 @@ class MelCloudAtw extends EventEmitter {
|
|
|
252
250
|
}
|
|
253
251
|
|
|
254
252
|
updateData(deviceData) {
|
|
253
|
+
this.lock = true;
|
|
254
|
+
this.emit('deviceState', deviceData);
|
|
255
|
+
|
|
255
256
|
setTimeout(() => {
|
|
256
|
-
this.
|
|
257
|
-
},
|
|
257
|
+
this.lock = false
|
|
258
|
+
}, 3000);
|
|
258
259
|
}
|
|
259
260
|
};
|
|
260
261
|
export default MelCloudAtw;
|