homebridge-melcloud-control 4.1.3-beta.1 → 4.1.3-beta.3

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/README.md CHANGED
@@ -230,7 +230,6 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
230
230
  | `ataDevices[].frostProtectionSensor` | This enable extra `Frost Protectio` sensor to use with automations in HomeKit app. |
231
231
  | `ataDevices[].overHeatProtectionSensor` | This enable extra `Overheat Protection` sensor to use with automations in HomeKit app. |
232
232
  | `ataDevices[].holidayModeSensor` | This enable extra `Holiday Mode` sensor to use with automations in HomeKit app. |
233
- | `ataDevices[].scheduleSensor` | This enable extra `Shedule` sensor to use with automations in HomeKit app. |
234
233
  | `ataDevices[].errorSensor` | This enable `Error` sensor to use with automations in HomeKit app. |
235
234
  | `ataDevices[].refreshInterval` | Here set the background devices state refresh time in (sec), default `5s`. |
236
235
  | `ataDevices[].presets[]` | Array of ATA device `Presets` created automatically after login to MELCloud from plugin config UI. |
@@ -422,15 +422,6 @@
422
422
  "functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome';"
423
423
  }
424
424
  },
425
- "scheduleSensor": {
426
- "title": "Schedule Enabled",
427
- "type": "boolean",
428
- "default": false,
429
- "description": "This enable extra schedule sensor to use with automations in HomeKit app.",
430
- "condition": {
431
- "functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome';"
432
- }
433
- },
434
425
  "errorSensor": {
435
426
  "title": "Error",
436
427
  "type": "boolean",
@@ -541,7 +532,7 @@
541
532
  "title": "Display Type",
542
533
  "type": "integer",
543
534
  "minimum": 0,
544
- "maximum": 5,
535
+ "maximum": 3,
545
536
  "default": 0,
546
537
  "description": "Select the characteristic type to be displayed in HomeKit app.",
547
538
  "anyOf": [
@@ -551,34 +542,22 @@
551
542
  0
552
543
  ]
553
544
  },
554
- {
555
- "title": "Outlet",
556
- "enum": [
557
- 1
558
- ]
559
- },
560
- {
561
- "title": "Switch",
562
- "enum": [
563
- 2
564
- ]
565
- },
566
545
  {
567
546
  "title": "Motion Sensor",
568
547
  "enum": [
569
- 3
548
+ 1
570
549
  ]
571
550
  },
572
551
  {
573
552
  "title": "Occupancy Sensor",
574
553
  "enum": [
575
- 4
554
+ 2
576
555
  ]
577
556
  },
578
557
  {
579
558
  "title": "Contact Sensor",
580
559
  "enum": [
581
- 5
560
+ 3
582
561
  ]
583
562
  }
584
563
  ]
@@ -2281,7 +2260,6 @@
2281
2260
  "accounts[].ataDevices[].frostProtectionSensor",
2282
2261
  "accounts[].ataDevices[].overheatProtectionSensor",
2283
2262
  "accounts[].ataDevices[].holidayModeSensor",
2284
- "accounts[].ataDevices[].scheduleSensor",
2285
2263
  "accounts[].ataDevices[].errorSensor"
2286
2264
  ]
2287
2265
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.1.3-beta.1",
4
+ "version": "4.1.3-beta.3",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/deviceata.js CHANGED
@@ -32,7 +32,6 @@ class DeviceAta extends EventEmitter {
32
32
  this.frostProtectionSensor = device.frostProtectionSensor || false;
33
33
  this.overheatProtectionSensor = device.overheatProtectionSensor || false;
34
34
  this.holidayModeSensor = device.holidayModeSensor || false;
35
- this.scheduleSensor = device.scheduleSensor || false;
36
35
  this.errorSensor = device.errorSensor || false;
37
36
  this.heatDryFanMode = device.heatDryFanMode || 1; //NONE, HEAT, DRY, FAN
38
37
  this.coolDryFanMode = device.coolDryFanMode || 1; //NONE, COOL, DRY, FAN
@@ -65,8 +64,8 @@ class DeviceAta extends EventEmitter {
65
64
  //schedules configured
66
65
  for (const schedule of this.schedules) {
67
66
  schedule.name = schedule.name || 'Schedule'
68
- schedule.serviceType = [null, Service.Outlet, Service.Switch, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][schedule.displayType];
69
- schedule.characteristicType = [null, Characteristic.On, Characteristic.On, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][schedule.displayType];
67
+ schedule.serviceType = [null, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][schedule.displayType];
68
+ schedule.characteristicType = [null, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][schedule.displayType];
70
69
  schedule.state = false;
71
70
  }
72
71
 
@@ -661,20 +660,6 @@ class DeviceAta extends EventEmitter {
661
660
  accessory.addService(this.holidayModeSensorService);
662
661
  }
663
662
 
664
- //schedule sensor
665
- if (this.scheduleSensor && this.accessory.scheduleEnabled !== null) {
666
- if (this.logDebug) this.emit('debug', `Prepare schedule service`);
667
- this.scheduleSensorService = new Service.ContactSensor(`${serviceName} Schedule`, `Schedule Sensor ${deviceId}`);
668
- this.scheduleSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
669
- this.scheduleSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Schedule`);
670
- this.scheduleSensorService.getCharacteristic(Characteristic.ContactSensorState)
671
- .onGet(async () => {
672
- const state = this.accessory.scheduleEnabled;
673
- return state;
674
- })
675
- accessory.addService(this.scheduleSensorService);
676
- }
677
-
678
663
  //error sensor
679
664
  if (this.errorSensor && this.accessory.isInError !== null) {
680
665
  if (this.logDebug) this.emit('debug', `Prepare error service`);
@@ -747,7 +732,7 @@ class DeviceAta extends EventEmitter {
747
732
  };
748
733
 
749
734
  //schedules services
750
- if (this.schedules.length > 0) {
735
+ if (this.schedules.length > 0 && this.accessory.scheduleEnabled !== null) {
751
736
  if (this.logDebug) this.emit('debug', `Prepare schedules services`);
752
737
  this.schedulesServices = [];
753
738
  this.schedules.forEach((schedule, i) => {
@@ -757,25 +742,52 @@ class DeviceAta extends EventEmitter {
757
742
  //get preset name prefix
758
743
  const namePrefix = schedule.namePrefix;
759
744
 
745
+ //control
746
+ if (i === 0) {
747
+ if (this.logDebug) this.emit('debug', `Prepare schedule control service`);
748
+ const serviceNameSchedule = namePrefix ? `${accessoryName} Schedule Control` : `Schedule Control`;
749
+ this.schedulesControlService = new Service.Switch(serviceNameSchedule, `Schedule Control ${deviceId} ${i}`);
750
+ this.schedulesControlService.addOptionalCharacteristic(Characteristic.ConfiguredName);
751
+ this.schedulesControlService.setCharacteristic(Characteristic.ConfiguredName, serviceNameSchedule);
752
+ this.schedulesControlService.getCharacteristic(Characteristic.On)
753
+ .onGet(async () => {
754
+ const state = this.accessory.scheduleEnabled;
755
+ return state;
756
+ })
757
+ .onSet(async (state) => {
758
+ try {
759
+ deviceData.ScheduleEnabled = state;
760
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'scheduleenabled');
761
+ if (this.logInfo) this.emit('info', `Schedule: ${state ? 'Enabled' : 'Disabled'}`);
762
+ } catch (error) {
763
+ if (this.logWarn) this.emit('warn', `Set schedule error: ${error}`);
764
+ };
765
+ });
766
+ accessory.addService(this.schedulesControlService);
767
+
768
+ if (this.logDebug) this.emit('debug', `Prepare schedule control sensor service`);
769
+ this.scheduleSensorService = new Service.ContactSensor(serviceNameSchedule, `Schedule Control Sensor ${deviceId}`);
770
+ this.scheduleSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
771
+ this.scheduleSensorService.setCharacteristic(Characteristic.ConfiguredName, serviceNameSchedule);
772
+ this.scheduleSensorService.getCharacteristic(Characteristic.ContactSensorState)
773
+ .onGet(async () => {
774
+ const state = this.accessory.scheduleEnabled;
775
+ return state;
776
+ })
777
+ accessory.addService(this.scheduleSensorService);
778
+ }
779
+
780
+ //sensors
760
781
  const serviceName = namePrefix ? `${accessoryName} ${name}` : name;
761
782
  const serviceType = schedule.serviceType;
762
783
  const characteristicType = schedule.characteristicType;
763
- const scheduleService = new serviceType(serviceName, `Schedule ${deviceId} ${i}`);
784
+ const scheduleService = new serviceType(serviceName, `Schedule Sensor ${deviceId} ${i}`);
764
785
  scheduleService.addOptionalCharacteristic(Characteristic.ConfiguredName);
765
786
  scheduleService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
766
787
  scheduleService.getCharacteristic(characteristicType)
767
788
  .onGet(async () => {
768
789
  const state = schedule.state;
769
790
  return state;
770
- })
771
- .onSet(async (state) => {
772
- try {
773
- deviceData.ScheduleEnabled = state;
774
- await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'scheduleenabled');
775
- if (this.logInfo) this.emit('info', `${state ? 'Set:' : 'Unset:'} ${name}`);
776
- } catch (error) {
777
- if (this.logWarn) this.emit('warn', `Set schedule error: ${error}`);
778
- };
779
791
  });
780
792
  this.schedulesServices.push(scheduleService);
781
793
  accessory.addService(scheduleService);
@@ -1324,7 +1336,6 @@ class DeviceAta extends EventEmitter {
1324
1336
  this.frostProtectionSensorService?.updateCharacteristic(Characteristic.ContactSensorState, frostProtectionActive);
1325
1337
  this.overheatProtectionSensorService?.updateCharacteristic(Characteristic.ContactSensorState, overheatProtectionActive);
1326
1338
  this.holidayModeSensorService?.updateCharacteristic(Characteristic.ContactSensorState, holidayModeActive);
1327
- this.scheduleSensorService?.updateCharacteristic(Characteristic.ContactSensorState, scheduleEnabled);
1328
1339
  this.errorService?.updateCharacteristic(Characteristic.ContactSensorState, isInError);
1329
1340
 
1330
1341
  //update presets state
@@ -1345,10 +1356,14 @@ class DeviceAta extends EventEmitter {
1345
1356
  };
1346
1357
 
1347
1358
  //update schedules state
1348
- if (this.schedules.length > 0) {
1359
+ if (this.schedules.length > 0 && scheduleEnabled !== null) {
1349
1360
  this.schedules.forEach((schedule, i) => {
1361
+ //control
1362
+ if (i === 0) this.schedulesControlService?.updateCharacteristic(characteristicType, scheduleEnabled);
1363
+
1364
+ //sensors
1350
1365
  const scheduleData = schedulesOnServer.find(s => s[presetsIdKey] === schedule.id);
1351
- schedule.state = scheduleEnabled; //scheduleData.Enabled : false;
1366
+ schedule.state = scheduleEnabled ? scheduleData.Enabled ?? false : false;
1352
1367
 
1353
1368
  const characteristicType = schedule.characteristicType;
1354
1369
  this.schedulesServices?.[i]?.updateCharacteristic(characteristicType, schedule.state);
@@ -203,19 +203,33 @@ class MelCloudAta extends EventEmitter {
203
203
  }
204
204
  }
205
205
 
206
- const settings = effectiveFlags === 'scheduleenabled' ? { data: { enabled: deviceData.ScheduleEnabled } } : {
207
- data: {
208
- Power: deviceData.Device.Power,
209
- SetTemperature: deviceData.Device.SetTemperature,
210
- SetFanSpeed: String(deviceData.Device.SetFanSpeed),
211
- OperationMode: AirConditioner.OperationModeMapEnumToString[deviceData.Device.OperationMode],
212
- VaneHorizontalDirection: AirConditioner.VaneHorizontalDirectionMapEnumToString[deviceData.Device.VaneHorizontalDirection],
213
- VaneVerticalDirection: AirConditioner.VaneVerticalDirectionMapEnumToString[deviceData.Device.VaneVerticalDirection],
214
- }
215
- };
216
- if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(settings.data, null, 2)}`);
206
+ let settings = {};
207
+ let path = '';
208
+ switch (effectiveFlags) {
209
+ case 'scheduleenabled':
210
+ settings = {
211
+ data: {
212
+ enabled: deviceData.ScheduleEnabled
213
+ }
214
+ };
215
+ path = ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID);
216
+ break;
217
+ default:
218
+ settings = {
219
+ data: {
220
+ Power: deviceData.Device.Power,
221
+ SetTemperature: deviceData.Device.SetTemperature,
222
+ SetFanSpeed: String(deviceData.Device.SetFanSpeed),
223
+ OperationMode: AirConditioner.OperationModeMapEnumToString[deviceData.Device.OperationMode],
224
+ VaneHorizontalDirection: AirConditioner.VaneHorizontalDirectionMapEnumToString[deviceData.Device.VaneHorizontalDirection],
225
+ VaneVerticalDirection: AirConditioner.VaneVerticalDirectionMapEnumToString[deviceData.Device.VaneVerticalDirection],
226
+ }
227
+ };
228
+ path = ApiUrlsHome.SetAta.replace('deviceid', deviceData.DeviceID);
229
+ break
230
+ }
217
231
 
218
- const path = effectiveFlags === 'scheduleenabled' ? ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID) : ApiUrlsHome.SetAta.replace('deviceid', deviceData.DeviceID);
232
+ if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(settings.data, null, 2)}`);
219
233
  await axiosInstancePut(path, settings);
220
234
  this.updateData(deviceData);
221
235
  return true;
@@ -195,26 +195,40 @@ class MelCloudAtw extends EventEmitter {
195
195
  withCredentials: true
196
196
  });
197
197
 
198
- const settings = effectiveFlags === 'scheduleenabled' ? { data: { enabled: deviceData.ScheduleEnabled } } : {
199
- data: {
200
- Power: deviceData.Device.Power,
201
- SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
202
- SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
203
- OperationMode: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationMode],
204
- OperationModeZone1: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationModeZone1],
205
- OperationModeZone2: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationModeZone2],
206
- SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
207
- SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
208
- SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
209
- SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
210
- SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
211
- ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
212
- EcoHotWater: deviceData.Device.EcoHotWater,
213
- }
214
- };
215
- if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(settings.data, null, 2)}`);
198
+ let settings = {};
199
+ let path = '';
200
+ switch (effectiveFlags) {
201
+ case 'scheduleenabled':
202
+ settings = {
203
+ data: {
204
+ enabled: deviceData.ScheduleEnabled
205
+ }
206
+ };
207
+ path = ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID);
208
+ break;
209
+ default:
210
+ settings = {
211
+ data: {
212
+ Power: deviceData.Device.Power,
213
+ SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
214
+ SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
215
+ OperationMode: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationMode],
216
+ OperationModeZone1: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationModeZone1],
217
+ OperationModeZone2: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationModeZone2],
218
+ SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
219
+ SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
220
+ SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
221
+ SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
222
+ SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
223
+ ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
224
+ EcoHotWater: deviceData.Device.EcoHotWater,
225
+ }
226
+ };
227
+ path = ApiUrlsHome.SetAtw.replace('deviceid', deviceData.DeviceID);
228
+ break
229
+ }
216
230
 
217
- const path = effectiveFlags === 'scheduleenabled' ? ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID) : ApiUrlsHome.SetAtw.replace('deviceid', deviceData.DeviceID);
231
+ if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(settings.data, null, 2)}`);
218
232
  await axiosInstancePut(path, settings);
219
233
  this.updateData(deviceData);
220
234
  return true;
@@ -226,7 +240,7 @@ class MelCloudAtw extends EventEmitter {
226
240
  if (error?.response?.status === 500) {
227
241
  return true;
228
242
  }
229
-
243
+
230
244
  throw new Error(`Send data error: ${error.message}`);
231
245
  }
232
246
  }
@@ -211,18 +211,32 @@ class MelCloudErv extends EventEmitter {
211
211
  }
212
212
  }
213
213
 
214
- const settings = effectiveFlags === 'scheduleenabled' ? { data: { enabled: deviceData.ScheduleEnabled } } : {
215
- data: {
216
- Power: deviceData.Device.Power,
217
- SetTemperature: deviceData.Device.SetTemperature,
218
- SetFanSpeed: String(deviceData.Device.SetFanSpeed),
219
- OperationMode: Ventilation.OperationModeMapEnumToString[deviceData.Device.OperationMode],
220
- VentilationMode: Ventilation.VentilationModeMapEnumToString[deviceData.Device.VentilationMode],
221
- }
222
- };
223
- if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(settings.data, null, 2)}`);
214
+ let settings = {};
215
+ let path = '';
216
+ switch (effectiveFlags) {
217
+ case 'scheduleenabled':
218
+ settings = {
219
+ data: {
220
+ enabled: deviceData.ScheduleEnabled
221
+ }
222
+ };
223
+ path = ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID);
224
+ break;
225
+ default:
226
+ settings = {
227
+ data: {
228
+ Power: deviceData.Device.Power,
229
+ SetTemperature: deviceData.Device.SetTemperature,
230
+ SetFanSpeed: String(deviceData.Device.SetFanSpeed),
231
+ OperationMode: Ventilation.OperationModeMapEnumToString[deviceData.Device.OperationMode],
232
+ VentilationMode: Ventilation.VentilationModeMapEnumToString[deviceData.Device.VentilationMode],
233
+ }
234
+ };
235
+ path = ApiUrlsHome.SetErv.replace('deviceid', deviceData.DeviceID);
236
+ break
237
+ }
224
238
 
225
- const path = effectiveFlags === 'scheduleenabled' ? ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID) : ApiUrlsHome.SetErv.replace('deviceid', deviceData.DeviceID);
239
+ if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(settings.data, null, 2)}`);
226
240
  await axiosInstancePut(path, settings);
227
241
  this.updateData(deviceData);
228
242
  return true;