homebridge-melcloud-control 4.2.2-beta.1 → 4.2.2-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.
- 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 +121 -80
- 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,16 @@ 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;
|
|
274
276
|
const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
|
|
275
277
|
|
|
276
278
|
//accessory
|
|
@@ -331,13 +333,13 @@ class DeviceErv extends EventEmitter {
|
|
|
331
333
|
try {
|
|
332
334
|
switch (value) {
|
|
333
335
|
case 0: //AUTO - AUTO
|
|
334
|
-
deviceData.Device.VentilationMode =
|
|
336
|
+
deviceData.Device.VentilationMode = supportsAutoVentilationMode ? 2 : 0;
|
|
335
337
|
break;
|
|
336
338
|
case 1: //HEAT - LOSSNAY
|
|
337
339
|
deviceData.Device.VentilationMode = 0;
|
|
338
340
|
break;
|
|
339
341
|
case 2: //COOL - BYPASS
|
|
340
|
-
deviceData.Device.VentilationMode =
|
|
342
|
+
deviceData.Device.VentilationMode = supportsBypassVentilationMode ? 1 : 0;
|
|
341
343
|
break;
|
|
342
344
|
};
|
|
343
345
|
|
|
@@ -367,16 +369,16 @@ class DeviceErv extends EventEmitter {
|
|
|
367
369
|
try {
|
|
368
370
|
switch (numberOfFanSpeeds) {
|
|
369
371
|
case 2: //Fan speed mode 2
|
|
370
|
-
value =
|
|
372
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
|
|
371
373
|
break;
|
|
372
374
|
case 3: //Fan speed mode 3
|
|
373
|
-
value =
|
|
375
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
|
|
374
376
|
break;
|
|
375
377
|
case 4: //Fan speed mode 4
|
|
376
|
-
value =
|
|
378
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
|
|
377
379
|
break;
|
|
378
380
|
case 5: //Fan speed mode 5
|
|
379
|
-
value =
|
|
381
|
+
value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
|
|
380
382
|
break;;
|
|
381
383
|
};
|
|
382
384
|
|
|
@@ -388,7 +390,7 @@ class DeviceErv extends EventEmitter {
|
|
|
388
390
|
};
|
|
389
391
|
});
|
|
390
392
|
//device can cool
|
|
391
|
-
if (
|
|
393
|
+
if (supportsAutoVentilationMode && supportsCoolOperationMode) {
|
|
392
394
|
this.melCloudService.getCharacteristic(Characteristic.CoolingThresholdTemperature)
|
|
393
395
|
.setProps({
|
|
394
396
|
minValue: this.accessory.minTempCoolDry,
|
|
@@ -410,7 +412,7 @@ class DeviceErv extends EventEmitter {
|
|
|
410
412
|
});
|
|
411
413
|
};
|
|
412
414
|
//device can heat
|
|
413
|
-
if (
|
|
415
|
+
if (supportsAutoVentilationMode && supportsHeatOperationMode) {
|
|
414
416
|
this.melCloudService.getCharacteristic(Characteristic.HeatingThresholdTemperature)
|
|
415
417
|
.setProps({
|
|
416
418
|
minValue: this.accessory.minTempHeat,
|
|
@@ -500,12 +502,12 @@ class DeviceErv extends EventEmitter {
|
|
|
500
502
|
break;
|
|
501
503
|
case 2: //COOL - BYPASS
|
|
502
504
|
deviceData.Device.Power = true;
|
|
503
|
-
deviceData.Device.VentilationMode =
|
|
505
|
+
deviceData.Device.VentilationMode = supportsBypassVentilationMode ? 1 : 0;
|
|
504
506
|
effectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
505
507
|
break;
|
|
506
508
|
case 3: //AUTO - AUTO
|
|
507
509
|
deviceData.Device.Power = true;
|
|
508
|
-
deviceData.Device.VentilationMode =
|
|
510
|
+
deviceData.Device.VentilationMode = supportsAutoVentilationMode ? 2 : 0;
|
|
509
511
|
effectiveFlags = Ventilation.EffectiveFlags.Power + Ventilation.EffectiveFlags.VentilationMode;
|
|
510
512
|
break;
|
|
511
513
|
};
|
|
@@ -563,7 +565,7 @@ class DeviceErv extends EventEmitter {
|
|
|
563
565
|
};
|
|
564
566
|
|
|
565
567
|
//temperature sensor service room
|
|
566
|
-
if (this.temperatureSensor &&
|
|
568
|
+
if (this.temperatureSensor && supportsRoomTemperature && this.accessory.roomTemperature !== null) {
|
|
567
569
|
if (this.logDebug) this.emit('debug', `Prepare room temperature sensor service`);
|
|
568
570
|
this.roomTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Room`, `Room Temperature Sensor ${deviceId}`);
|
|
569
571
|
this.roomTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
@@ -582,7 +584,7 @@ class DeviceErv extends EventEmitter {
|
|
|
582
584
|
};
|
|
583
585
|
|
|
584
586
|
//temperature sensor service supply
|
|
585
|
-
if (this.temperatureSupplySensor &&
|
|
587
|
+
if (this.temperatureSupplySensor && supportsSupplyTemperature && this.accessory.supplyTemperature !== null) {
|
|
586
588
|
if (this.logDebug) this.emit('debug', `Prepare supply temperature sensor service`);
|
|
587
589
|
this.supplyTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Supply`, `Supply Temperature Sensor ${deviceId}`);
|
|
588
590
|
this.supplyTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
@@ -601,7 +603,7 @@ class DeviceErv extends EventEmitter {
|
|
|
601
603
|
};
|
|
602
604
|
|
|
603
605
|
//temperature sensor service outdoor
|
|
604
|
-
if (this.temperatureOutdoorSensor &&
|
|
606
|
+
if (this.temperatureOutdoorSensor && supportsOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
|
|
605
607
|
if (this.logDebug) this.emit('debug', `Prepare outdoor temperature sensor service`);
|
|
606
608
|
this.outdoorTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Outdoor`, `Outdoor Temperature Sensor ${deviceId}`);
|
|
607
609
|
this.outdoorTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
@@ -652,7 +654,7 @@ class DeviceErv extends EventEmitter {
|
|
|
652
654
|
}
|
|
653
655
|
|
|
654
656
|
//room CO2 sensor
|
|
655
|
-
if (
|
|
657
|
+
if (supportsCO2Sensor) {
|
|
656
658
|
this.carbonDioxideSensorService = new Service.CarbonDioxideSensor(`${serviceName} CO2 Sensor`, `CO2Sensor ${deviceId}`);
|
|
657
659
|
this.carbonDioxideSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
658
660
|
this.carbonDioxideSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} CO2 Sensor`);
|
|
@@ -670,7 +672,7 @@ class DeviceErv extends EventEmitter {
|
|
|
670
672
|
}
|
|
671
673
|
|
|
672
674
|
//room PM2.5 sensor
|
|
673
|
-
if (
|
|
675
|
+
if (supportsPM25Sensor) {
|
|
674
676
|
this.airQualitySensorService = new Service.AirQualitySensor(`${serviceName} PM2.5 Sensor`, `PM25Sensor ${deviceId}`);
|
|
675
677
|
this.airQualitySensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
676
678
|
this.airQualitySensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} PM2.5 Sensor`);
|
|
@@ -687,10 +689,37 @@ class DeviceErv extends EventEmitter {
|
|
|
687
689
|
accessory.addService(this.airQualitySensorService);
|
|
688
690
|
}
|
|
689
691
|
|
|
692
|
+
if (this.inStandbySensor && this.accessory.inStandbyMode !== null) {
|
|
693
|
+
if (this.logDebug) this.emit('debug', `Prepare in standby mode service`);
|
|
694
|
+
this.inStandbyService = new Service.ContactSensor(`${serviceName} In Standby`, `inStandbyService${deviceId}`);
|
|
695
|
+
this.inStandbyService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
696
|
+
this.inStandbyService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} In Standby`);
|
|
697
|
+
this.inStandbyService.getCharacteristic(Characteristic.ContactSensorState)
|
|
698
|
+
.onGet(async () => {
|
|
699
|
+
const state = this.accessory.isConnected;
|
|
700
|
+
return state;
|
|
701
|
+
})
|
|
702
|
+
accessory.addService(this.inStandbyService);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
//connect sensor
|
|
706
|
+
if (this.connectSensor && this.accessory.isConnected !== null) {
|
|
707
|
+
if (this.logDebug) this.emit('debug', `Prepare connect service`);
|
|
708
|
+
this.connectService = new Service.ContactSensor(`${serviceName} Connected`, `connectService${deviceId}`);
|
|
709
|
+
this.connectService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
710
|
+
this.connectService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Connected`);
|
|
711
|
+
this.connectService.getCharacteristic(Characteristic.ContactSensorState)
|
|
712
|
+
.onGet(async () => {
|
|
713
|
+
const state = this.accessory.isConnected;
|
|
714
|
+
return state;
|
|
715
|
+
})
|
|
716
|
+
accessory.addService(this.connectService);
|
|
717
|
+
}
|
|
718
|
+
|
|
690
719
|
//error sensor
|
|
691
720
|
if (this.errorSensor && this.accessory.isInError !== null) {
|
|
692
721
|
if (this.logDebug) this.emit('debug', `Prepare error service`);
|
|
693
|
-
this.errorService = new Service.ContactSensor(`${serviceName} Error`, `
|
|
722
|
+
this.errorService = new Service.ContactSensor(`${serviceName} Error`, `errorService${deviceId}`);
|
|
694
723
|
this.errorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
695
724
|
this.errorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Error`);
|
|
696
725
|
this.errorService.getCharacteristic(Characteristic.ContactSensorState)
|
|
@@ -1016,8 +1045,11 @@ class DeviceErv extends EventEmitter {
|
|
|
1016
1045
|
this.deviceData = deviceData;
|
|
1017
1046
|
|
|
1018
1047
|
//keys
|
|
1048
|
+
const accountTypeMelcloud = this.accountType === 'melcloud';
|
|
1019
1049
|
const tempStepKey = this.accountType === 'melcloud' ? 'TemperatureIncrement' : 'HasHalfDegreeIncrements';
|
|
1050
|
+
const connectKey = this.accountType === 'melcloud' ? 'Offline' : 'IsConnected';
|
|
1020
1051
|
const errorKey = this.accountType === 'melcloud' ? 'HasError' : 'IsInError';
|
|
1052
|
+
const supportStandbyKey = accountTypeMelcloud ? 'ModelSupportsStandbyMode' : 'HasStandby';
|
|
1021
1053
|
|
|
1022
1054
|
//presets schedule
|
|
1023
1055
|
const scheduleEnabled = deviceData.ScheduleEnabled;
|
|
@@ -1032,22 +1064,23 @@ class DeviceErv extends EventEmitter {
|
|
|
1032
1064
|
const hideOutdoorTemperature = deviceData.HideOutdoorTemperature;
|
|
1033
1065
|
|
|
1034
1066
|
//device info
|
|
1035
|
-
const
|
|
1036
|
-
const
|
|
1037
|
-
const
|
|
1038
|
-
const
|
|
1039
|
-
const
|
|
1040
|
-
const
|
|
1041
|
-
const
|
|
1067
|
+
const supportsCoolOperationMode = deviceData.Device.HasCoolOperationMode ?? false;
|
|
1068
|
+
const supportsHeatOperationMode = deviceData.Device.HasHeatOperationMode ?? false;
|
|
1069
|
+
const supportsAutoOperationMode = deviceData.Device.HasAutoOperationMode ?? false;
|
|
1070
|
+
const supportsRoomTemperature = deviceData.Device.HasRoomTemperature ?? false;
|
|
1071
|
+
const supportsSupplyTemperature = deviceData.Device.HasSupplyTemperature ?? false;
|
|
1072
|
+
const supportsOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
|
|
1073
|
+
const supportsCO2Sensor = deviceData.Device.HasCO2Sensor ?? false;
|
|
1074
|
+
const supportsStanbyMode = deviceData.Device[supportStandbyKey];
|
|
1042
1075
|
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
|
|
1076
|
+
const roomCO2Detected = supportsCO2Sensor && roomCO2Level > 1000 ? true : false;
|
|
1077
|
+
const supportsPM25Sensor = deviceData.Device.HasPM25Sensor ?? false;
|
|
1078
|
+
const pM25SensorStatus = supportsPM25Sensor ? deviceData.Device.PM25SensorStatus : 0;
|
|
1079
|
+
const pM25Level = supportsPM25Sensor ? deviceData.Device.PM25Level : 0;
|
|
1080
|
+
const pM25AirQuality = supportsPM25Sensor ? pM25Level <= 13 ? 1 : pM25Level <= 35 ? 2 : pM25Level <= 55 ? 3 : pM25Level <= 75 ? 4 : pM25Level <= 110 ? 5 : 0 : 0;
|
|
1081
|
+
const supportsAutoVentilationMode = deviceData.Device.HasAutoVentilationMode ?? false;
|
|
1082
|
+
const supportsBypassVentilationMode = deviceData.Device.HasBypassVentilationMode ?? false;
|
|
1083
|
+
const supportsAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
|
|
1051
1084
|
const coreMaintenanceRequired = deviceData.Device.CoreMaintenanceRequired;
|
|
1052
1085
|
const filterMaintenanceRequired = deviceData.Device.FilterMaintenanceRequired;
|
|
1053
1086
|
const actualVentilationMode = deviceData.Device.ActualVentilationMode;
|
|
@@ -1060,6 +1093,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1060
1093
|
|
|
1061
1094
|
//device state
|
|
1062
1095
|
const power = deviceData.Device.Power;
|
|
1096
|
+
const inStandbyMode = deviceData.Device.InStandbyMode;
|
|
1063
1097
|
const roomTemperature = deviceData.Device.RoomTemperature;
|
|
1064
1098
|
const supplyTemperature = deviceData.Device.SupplyTemperature;
|
|
1065
1099
|
const outdoorTemperature = deviceData.Device.OutdoorTemperature;
|
|
@@ -1070,32 +1104,35 @@ class DeviceErv extends EventEmitter {
|
|
|
1070
1104
|
const setFanSpeed = deviceData.Device.SetFanSpeed;
|
|
1071
1105
|
const operationMode = deviceData.Device.OperationMode;
|
|
1072
1106
|
const ventilationMode = deviceData.Device.VentilationMode;
|
|
1107
|
+
const isConnected = accountTypeMelcloud ? !deviceData.Device[connectKey] : deviceData.Device[connectKey];
|
|
1073
1108
|
const isInError = deviceData.Device[errorKey];
|
|
1074
1109
|
|
|
1075
1110
|
//accessory
|
|
1076
1111
|
const obj = {
|
|
1077
1112
|
presets: presetsOnServer,
|
|
1078
1113
|
schedules: schedulesOnServer,
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1114
|
+
supportsRoomTemperature: supportsRoomTemperature,
|
|
1115
|
+
supportsSupplyTemperature: supportsSupplyTemperature,
|
|
1116
|
+
supportsOutdoorTemperature: supportsOutdoorTemperature,
|
|
1117
|
+
supportsCoolOperationMode: supportsCoolOperationMode,
|
|
1118
|
+
supportsHeatOperationMode: supportsHeatOperationMode,
|
|
1119
|
+
supportsCO2Sensor: supportsCO2Sensor,
|
|
1085
1120
|
roomCO2Level: roomCO2Level,
|
|
1086
1121
|
roomCO2Detected: roomCO2Detected,
|
|
1087
|
-
|
|
1122
|
+
supportsPM25Sensor: supportsPM25Sensor,
|
|
1088
1123
|
pM25SensorStatus: pM25SensorStatus,
|
|
1089
1124
|
pM25Level: pM25Level,
|
|
1090
1125
|
pM25AirQuality: pM25AirQuality,
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1126
|
+
supportsAutoVentilationMode: supportsAutoVentilationMode,
|
|
1127
|
+
supportsBypassVentilationMode: supportsBypassVentilationMode,
|
|
1128
|
+
supportsAutomaticFanSpeed: supportsAutomaticFanSpeed,
|
|
1129
|
+
supportsStanbyMode: supportsStanbyMode,
|
|
1094
1130
|
coreMaintenanceRequired: coreMaintenanceRequired,
|
|
1095
1131
|
filterMaintenanceRequired: filterMaintenanceRequired,
|
|
1096
1132
|
actualVentilationMode: actualVentilationMode,
|
|
1097
1133
|
numberOfFanSpeeds: numberOfFanSpeeds,
|
|
1098
1134
|
power: power ? 1 : 0,
|
|
1135
|
+
inStandbyMode: inStandbyMode,
|
|
1099
1136
|
operationMode: operationMode,
|
|
1100
1137
|
currentOperationMode: 0,
|
|
1101
1138
|
targetOperationMode: 0,
|
|
@@ -1114,6 +1151,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1114
1151
|
maxTempCoolDry: maxTempCoolDry,
|
|
1115
1152
|
useFahrenheit: this.useFahrenheit,
|
|
1116
1153
|
temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit],
|
|
1154
|
+
isConnected: isConnected,
|
|
1117
1155
|
isInError: isInError,
|
|
1118
1156
|
scheduleEnabled: scheduleEnabled,
|
|
1119
1157
|
holidayModeEnabled: holidayModeEnabled,
|
|
@@ -1154,26 +1192,27 @@ class DeviceErv extends EventEmitter {
|
|
|
1154
1192
|
|
|
1155
1193
|
obj.currentOperationMode = !power ? 0 : obj.currentOperationMode;
|
|
1156
1194
|
obj.targetOperationMode = obj.targetOperationMode;
|
|
1157
|
-
obj.operationModeSetPropsMinValue =
|
|
1158
|
-
obj.operationModeSetPropsMaxValue =
|
|
1159
|
-
obj.operationModeSetPropsValidValues =
|
|
1195
|
+
obj.operationModeSetPropsMinValue = supportsAutoVentilationMode ? 0 : 1;
|
|
1196
|
+
obj.operationModeSetPropsMaxValue = supportsAutoVentilationMode ? 2 : 2;
|
|
1197
|
+
obj.operationModeSetPropsValidValues = supportsAutoVentilationMode ? (supportsBypassVentilationMode ? [0, 1, 2] : [0, 2]) : (supportsBypassVentilationMode ? [1, 2] : [2]);
|
|
1160
1198
|
|
|
1161
1199
|
//fan speed mode
|
|
1162
1200
|
obj.fanSpeedSetPropsMaxValue = 2;
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1201
|
+
|
|
1202
|
+
// fan speed mode
|
|
1203
|
+
if (numberOfFanSpeeds > 0) {
|
|
1204
|
+
const max = numberOfFanSpeeds;
|
|
1205
|
+
const autoIndex = supportsAutomaticFanSpeed ? max + 1 : 0;
|
|
1206
|
+
|
|
1207
|
+
// Tworzymy tablicę prędkości: [auto?, 1..N]
|
|
1208
|
+
const speeds = [autoIndex];
|
|
1209
|
+
for (let i = 1; i <= max; i++) {
|
|
1210
|
+
speeds.push(i);
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
obj.fanSpeed = speeds[setFanSpeed];
|
|
1214
|
+
obj.fanSpeedSetPropsMaxValue = supportsAutomaticFanSpeed ? max + 1 : max;
|
|
1215
|
+
}
|
|
1177
1216
|
|
|
1178
1217
|
//update characteristics
|
|
1179
1218
|
this.melCloudService
|
|
@@ -1184,8 +1223,8 @@ class DeviceErv extends EventEmitter {
|
|
|
1184
1223
|
.updateCharacteristic(Characteristic.RotationSpeed, obj.fanSpeed)
|
|
1185
1224
|
.updateCharacteristic(Characteristic.LockPhysicalControls, obj.lockPhysicalControl)
|
|
1186
1225
|
.updateCharacteristic(Characteristic.TemperatureDisplayUnits, obj.useFahrenheit);
|
|
1187
|
-
const updateDefCool =
|
|
1188
|
-
const updateDefHeat =
|
|
1226
|
+
const updateDefCool = supportsCoolOperationMode ? this.melCloudService?.updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature) : false;
|
|
1227
|
+
const updateDefHeat = supportsHeatOperationMode ? this.melCloudService?.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
|
|
1189
1228
|
break;
|
|
1190
1229
|
case 2: //Thermostat
|
|
1191
1230
|
//operation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
|
|
@@ -1219,9 +1258,9 @@ class DeviceErv extends EventEmitter {
|
|
|
1219
1258
|
|
|
1220
1259
|
obj.currentOperationMode = !power ? 0 : obj.currentOperationMode;
|
|
1221
1260
|
obj.targetOperationMode = !power ? 0 : obj.targetOperationMode;
|
|
1222
|
-
obj.operationModeSetPropsMinValue =
|
|
1223
|
-
obj.operationModeSetPropsMaxValue =
|
|
1224
|
-
obj.operationModeSetPropsValidValues =
|
|
1261
|
+
obj.operationModeSetPropsMinValue = supportsAutoVentilationMode ? 0 : 0;
|
|
1262
|
+
obj.operationModeSetPropsMaxValue = supportsAutoVentilationMode ? 3 : 2;
|
|
1263
|
+
obj.operationModeSetPropsValidValues = supportsAutoVentilationMode ? (supportsBypassVentilationMode ? [0, 1, 2, 3] : [0, 2, 3]) : (supportsBypassVentilationMode ? [0, 1, 2] : [0, 2]);
|
|
1225
1264
|
|
|
1226
1265
|
//update characteristics
|
|
1227
1266
|
this.melCloudService
|
|
@@ -1255,7 +1294,9 @@ class DeviceErv extends EventEmitter {
|
|
|
1255
1294
|
?.updateCharacteristic(Characteristic.AirQuality, pM25AirQuality)
|
|
1256
1295
|
.updateCharacteristic(Characteristic.PM2_5Density, pM25Level);
|
|
1257
1296
|
|
|
1258
|
-
//
|
|
1297
|
+
//other sensors
|
|
1298
|
+
this.inStandbyService?.updateCharacteristic(Characteristic.ContactSensorState, inStandbyMode);
|
|
1299
|
+
this.connectService?.updateCharacteristic(Characteristic.ContactSensorState, isConnected);
|
|
1259
1300
|
this.errorService?.updateCharacteristic(Characteristic.ContactSensorState, isInError);
|
|
1260
1301
|
|
|
1261
1302
|
//holiday mode
|
|
@@ -1361,16 +1402,16 @@ class DeviceErv extends EventEmitter {
|
|
|
1361
1402
|
this.emit('info', `Current ventilation mode: ${Ventilation.OperationModeMapEnumToString[actualVentilationMode]}`);
|
|
1362
1403
|
this.emit('info', `Target temperature: ${setTemperature}${obj.temperatureUnit}`);
|
|
1363
1404
|
this.emit('info', `Room temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
1364
|
-
if (
|
|
1365
|
-
if (
|
|
1405
|
+
if (supportsSupplyTemperature && deviceData.Device.SupplyTemperature !== null) this.emit('info', `Supply temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
1406
|
+
if (supportsOutdoorTemperature && deviceData.Device.OutdoorTemperature !== null) this.emit('info', `Outdoor temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
1366
1407
|
this.emit('info', `Fan speed mode: ${Ventilation.FanSpeedMapEnumToString[setFanSpeed]}`);
|
|
1367
1408
|
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
1368
1409
|
this.emit('info', `Core maintenance: ${Ventilation.CoreMaintenanceMapEnumToString[coreMaintenanceRequired]}`);
|
|
1369
1410
|
this.emit('info', `Filter maintenance: ${Ventilation.FilterMaintenanceMapEnumToString[filterMaintenanceRequired]}`);
|
|
1370
|
-
if (
|
|
1371
|
-
if (
|
|
1372
|
-
if (
|
|
1373
|
-
if (
|
|
1411
|
+
if (supportsCO2Sensor) this.emit('info', `CO2 detected: ${Ventilation.Co2DetectedMapEnumToString[roomCO2Detected]}`);
|
|
1412
|
+
if (supportsCO2Sensor) this.emit('info', `CO2 level: ${roomCO2Level} ppm`);
|
|
1413
|
+
if (supportsPM25Sensor) this.emit('info', `PM2.5 air quality: ${Ventilation.PM25AirQualityMapEnumToString[pM25AirQuality]}`);
|
|
1414
|
+
if (supportsPM25Sensor) this.emit('info', `PM2.5 level: ${pM25Level} µg/m`);
|
|
1374
1415
|
};
|
|
1375
1416
|
})
|
|
1376
1417
|
.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;
|
package/src/melclouderv.js
CHANGED
|
@@ -25,11 +25,9 @@ class MelCloudErv 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 MelCloudErv 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
|
|
|
@@ -260,9 +258,12 @@ class MelCloudErv extends EventEmitter {
|
|
|
260
258
|
}
|
|
261
259
|
|
|
262
260
|
updateData(deviceData) {
|
|
261
|
+
this.lock = true;
|
|
262
|
+
this.emit('deviceState', deviceData);
|
|
263
|
+
|
|
263
264
|
setTimeout(() => {
|
|
264
|
-
this.
|
|
265
|
-
},
|
|
265
|
+
this.lock = false
|
|
266
|
+
}, 3000);
|
|
266
267
|
}
|
|
267
268
|
};
|
|
268
269
|
export default MelCloudErv;
|