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/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 hasRoomTemperature = this.accessory.hasRoomTemperature;
265
- const hasSupplyTemperature = this.accessory.hasSupplyTemperature;
266
- const hasOutdoorTemperature = this.accessory.hasOutdoorTemperature;
267
- const hasCoolOperationMode = this.accessory.hasCoolOperationMode;
268
- const hasHeatOperationMode = this.accessory.hasHeatOperationMode;
269
- const hasAutoVentilationMode = this.accessory.hasAutoVentilationMode;
270
- const hasBypassVentilationMode = this.accessory.hasBypassVentilationMode;
271
- const hasAutomaticFanSpeed = this.accessory.hasAutomaticFanSpeed;
272
- const hasCO2Sensor = this.accessory.hasCO2Sensor;
273
- const hasPM25Sensor = this.accessory.hasPM25Sensor;
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 = hasAutoVentilationMode ? 2 : 0;
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 = hasBypassVentilationMode ? 1 : 0;
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
- this.melCloudService.getCharacteristic(Characteristic.RotationSpeed)
357
- .setProps({
358
- minValue: 0,
359
- maxValue: this.accessory.fanSpeedSetPropsMaxValue,
360
- minStep: 1
361
- })
362
- .onGet(async () => {
363
- const value = this.accessory.fanSpeed; //STOP, 1, 2, 3, 4, OFF
364
- return value;
365
- })
366
- .onSet(async (value) => {
367
- try {
368
- switch (numberOfFanSpeeds) {
369
- case 2: //Fan speed mode 2
370
- value = hasAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
371
- break;
372
- case 3: //Fan speed mode 3
373
- value = hasAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
374
- break;
375
- case 4: //Fan speed mode 4
376
- value = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
377
- break;
378
- case 5: //Fan speed mode 5
379
- value = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
380
- break;;
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
- deviceData.Device.SetFanSpeed = value
384
- await this.melCloudErv.send(this.accountType, this.displayType, deviceData, Ventilation.EffectiveFlags.SetFanSpeed);
385
- if (this.logInfo) this.emit('info', `Set fan speed mode: ${Ventilation.FanSpeedMapEnumToString[value]}`);
386
- } catch (error) {
387
- if (this.logWarn) this.emit('warn', `Set fan speed mode error: ${error}`);
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 (hasAutoVentilationMode && hasCoolOperationMode) {
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 (hasAutoVentilationMode && hasHeatOperationMode) {
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 = hasBypassVentilationMode ? 1 : 0;
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 = hasAutoVentilationMode ? 2 : 0;
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 && hasRoomTemperature && this.accessory.roomTemperature !== null) {
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 && hasSupplyTemperature && this.accessory.supplyTemperature !== null) {
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 && hasOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
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 (hasCO2Sensor) {
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 (hasPM25Sensor) {
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`, `Error Sensor ${deviceId}`);
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 hasCoolOperationMode = deviceData.Device.HasCoolOperationMode ?? false;
1036
- const hasHeatOperationMode = deviceData.Device.HasHeatOperationMode ?? false;
1037
- const hasAutoOperationMode = deviceData.Device.HasAutoOperationMode ?? false;
1038
- const hasRoomTemperature = deviceData.Device.HasRoomTemperature ?? false;
1039
- const hasSupplyTemperature = deviceData.Device.HasSupplyTemperature ?? false;
1040
- const hasOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
1041
- const hasCO2Sensor = deviceData.Device.HasCO2Sensor ?? false;
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 = hasCO2Sensor && roomCO2Level > 1000 ? true : false;
1044
- const hasPM25Sensor = deviceData.Device.HasPM25Sensor ?? false;
1045
- const pM25SensorStatus = hasPM25Sensor ? deviceData.Device.PM25SensorStatus : 0;
1046
- const pM25Level = hasPM25Sensor ? deviceData.Device.PM25Level : 0;
1047
- const pM25AirQuality = hasPM25Sensor ? pM25Level <= 13 ? 1 : pM25Level <= 35 ? 2 : pM25Level <= 55 ? 3 : pM25Level <= 75 ? 4 : pM25Level <= 110 ? 5 : 0 : 0;
1048
- const hasAutoVentilationMode = deviceData.Device.HasAutoVentilationMode ?? false;
1049
- const hasBypassVentilationMode = deviceData.Device.HasBypassVentilationMode ?? false;
1050
- const hasAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
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
- hasRoomTemperature: hasRoomTemperature,
1080
- hasSupplyTemperature: hasSupplyTemperature,
1081
- hasOutdoorTemperature: hasOutdoorTemperature,
1082
- hasCoolOperationMode: hasCoolOperationMode,
1083
- hasHeatOperationMode: hasHeatOperationMode,
1084
- hasCO2Sensor: hasCO2Sensor,
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
- hasPM25Sensor: hasPM25Sensor,
1126
+ supportsPM25Sensor: supportsPM25Sensor,
1088
1127
  pM25SensorStatus: pM25SensorStatus,
1089
1128
  pM25Level: pM25Level,
1090
1129
  pM25AirQuality: pM25AirQuality,
1091
- hasAutoVentilationMode: hasAutoVentilationMode,
1092
- hasBypassVentilationMode: hasBypassVentilationMode,
1093
- hasAutomaticFanSpeed: hasAutomaticFanSpeed,
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 = hasAutoVentilationMode ? 0 : 1;
1158
- obj.operationModeSetPropsMaxValue = hasAutoVentilationMode ? 2 : 2;
1159
- obj.operationModeSetPropsValidValues = hasAutoVentilationMode ? (hasBypassVentilationMode ? [0, 1, 2] : [0, 2]) : (hasBypassVentilationMode ? [1, 2] : [2]);
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
- switch (numberOfFanSpeeds) {
1164
- case 2: //Fan speed mode 2
1165
- obj.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][setFanSpeed] : [0, 1, 2][setFanSpeed];
1166
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
1167
- break;
1168
- case 3: //Fan speed mode 3
1169
- this.obj.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][setFanSpeed] : [0, 1, 2, 3][setFanSpeed];
1170
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
1171
- break;
1172
- case 4: //Fan speed mode 4
1173
- obj.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][setFanSpeed] : [0, 1, 2, 3, 4][setFanSpeed];
1174
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
1175
- break;
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 = hasCoolOperationMode ? this.melCloudService?.updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature) : false;
1188
- const updateDefHeat = hasHeatOperationMode ? this.melCloudService?.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
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 = hasAutoVentilationMode ? 0 : 0;
1223
- obj.operationModeSetPropsMaxValue = hasAutoVentilationMode ? 3 : 2;
1224
- obj.operationModeSetPropsValidValues = hasAutoVentilationMode ? (hasBypassVentilationMode ? [0, 1, 2, 3] : [0, 2, 3]) : (hasBypassVentilationMode ? [0, 1, 2] : [0, 2]);
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
- //error sensor
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 (hasSupplyTemperature && deviceData.Device.SupplyTemperature !== null) this.emit('info', `Supply temperature: ${roomTemperature}${obj.temperatureUnit}`);
1365
- if (hasOutdoorTemperature && deviceData.Device.OutdoorTemperature !== null) this.emit('info', `Outdoor temperature: ${roomTemperature}${obj.temperatureUnit}`);
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 (hasCO2Sensor) this.emit('info', `CO2 detected: ${Ventilation.Co2DetectedMapEnumToString[roomCO2Detected]}`);
1371
- if (hasCO2Sensor) this.emit('info', `CO2 level: ${roomCO2Level} ppm`);
1372
- if (hasPM25Sensor) this.emit('info', `PM2.5 air quality: ${Ventilation.PM25AirQualityMapEnumToString[pM25AirQuality]}`);
1373
- if (hasPM25Sensor) this.emit('info', `PM2.5 level: ${pM25Level} µg/m`);
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
- if (this.logWarn) this.emit('warn', `Invalid or empty response from MELCloud API`);
84
- return null;
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
- if (this.logWarn) this.emit('warn', `No buildings found in MELCloud account`);
94
- return null;
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
- const msg = error.response ? `HTTP ${error.response.status}: ${error.response.statusText}` : error.message;
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
@@ -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('checkState', async () => {
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(lockKey, fn) {
41
- if (this.locks[lockKey]) return;
38
+ async handleWithLock(fn) {
39
+ if (this.locks) return;
42
40
 
43
- this.locks[lockKey] = true;
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[lockKey] = false;
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.emit('deviceState', deviceData);
287
- }, 300);
287
+ this.lock = false
288
+ }, 3000);
288
289
  }
289
290
 
290
291
  };
@@ -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('checkState', async () => {
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(lockKey, fn) {
41
- if (this.locks[lockKey]) return;
38
+ async handleWithLock(fn) {
39
+ if (this.locks) return;
42
40
 
43
- this.locks[lockKey] = true;
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[lockKey] = false;
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.emit('deviceState', deviceData);
257
- }, 300);
257
+ this.lock = false
258
+ }, 3000);
258
259
  }
259
260
  };
260
261
  export default MelCloudAtw;