homebridge-melcloud-control 3.1.3-beta.9 → 3.1.4-beta.0

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.
@@ -151,33 +151,25 @@
151
151
  const info = response.info ?? '';
152
152
  const status = response.status;
153
153
  const devices = response.data ?? [];
154
- const devicesByType = {
155
- ata: [],
156
- atw: [],
157
- erv: []
158
- };
159
-
160
- //new found devices
161
- const newDevices = {
162
- ata: [],
163
- ataPresets: [],
164
- atw: [],
165
- atwPresets: [],
166
- erv: [],
167
- ervPresets: [],
168
- };
169
-
170
- //info text
171
- let textAta = 'ATA: 0';
172
- let textAtaPresets = 'ATA Presets: 0';
173
- let textAtw = 'ATW: 0';
174
- let textAtwPresets = 'ATW Presets: 0';
175
- let textErv = 'ERV: 0';
176
- let textErvPresets = 'ERV Presets: 0';
177
154
 
178
155
  //response status
179
156
  switch (status) {
180
157
  case 0:
158
+ //new found devices
159
+ const newDevices = {
160
+ ata: [],
161
+ ataPresets: [],
162
+ atw: [],
163
+ atwPresets: [],
164
+ erv: [],
165
+ ervPresets: [],
166
+ };
167
+
168
+ const devicesByType = {
169
+ ata: [],
170
+ atw: [],
171
+ erv: []
172
+ };
181
173
 
182
174
  //get devices by type
183
175
  for (const device of devices) {
@@ -187,9 +179,26 @@
187
179
  const pusDeviceTypeErv = deviceType === 3 ? devicesByType.erv.push(device) : false;
188
180
  };
189
181
 
182
+ //devices from config
183
+ const ataDevices = pluginConfig[0].accounts[this.deviceIndex].ataDevices ?? [];
184
+ const atwDevices = pluginConfig[0].accounts[this.deviceIndex].atwDevices ?? [];
185
+ const ervDevices = pluginConfig[0].accounts[this.deviceIndex].ervDevices ?? [];
186
+
187
+ //info text
188
+ let textAta = 'ATA: 0';
189
+ let textAtaPresets = 'ATA Presets: 0';
190
+ let ataPresetsCount = 0;
191
+ let textAtw = 'ATW: 0';
192
+ let textAtwPresets = 'ATW Presets: 0';
193
+ let atwPresetsCount = 0;
194
+ let textErv = 'ERV: 0';
195
+ let textErvPresets = 'ERV Presets: 0';
196
+ let ervPresetsCount = 0;
197
+
190
198
  //device ata
191
- for (const device of devicesByType.ata) {
199
+ devicesByType.ata.forEach((device, index) => {
192
200
  const deviceId = device.DeviceID;
201
+ const deviceType = device.Type;
193
202
  const deviceName = device.DeviceName;
194
203
  const devicePresets = device.Presets ?? [];
195
204
 
@@ -208,6 +217,12 @@
208
217
  buttonsSensors: []
209
218
  };
210
219
 
220
+ const deviceExistsInConfig = ataDevices.find(device => device.id === deviceId);
221
+ if (!deviceExistsInConfig) {
222
+ ataDevices.push(deviceAta);
223
+ newDevices.ata.push(deviceAta);
224
+ };
225
+
211
226
  //presets
212
227
  for (const preset of devicePresets) {
213
228
  const presetId = preset.ID;
@@ -217,19 +232,29 @@
217
232
  preset.name = presetName;
218
233
  preset.displayType == 0;
219
234
  preset.namePrefix = false;
220
- newDevices.ataPresets.push(preset);
221
- };
222
- deviceAta.presets = newDevices.ataPresets;
223
- textAtaPresets = `ATA Presets: ${newDevices.ataPresets.length}`
224
235
 
225
- newDevices.ata.push(deviceAta);
226
- };
227
- pluginConfig[0].accounts[this.deviceIndex].ataDevices = newDevices.ata;
236
+ let presetExistsInConfig = false;
237
+ for (const ataDevice of ataDevices) {
238
+ if (ataDevice.presets?.some(preset => preset.id === presetId)) {
239
+ presetExistsInConfig = true;
240
+ break;
241
+ }
242
+ }
243
+
244
+ if (!presetExistsInConfig) {
245
+ ataDevices[index].presets.push(preset);
246
+ newDevices.ataPresets.push(preset);
247
+ };
248
+ };
249
+ ataPresetsCount = newDevices.ataPresets.length;
250
+ textAtaPresets = `ATA Presets: ${ataPresetsCount}`
251
+ });
228
252
  textAta = `ATA: ${newDevices.ata.length}`
229
253
 
230
254
  //device atw
231
- for (const device of devicesByType.atw) {
255
+ devicesByType.atw.forEach((device, index) => {
232
256
  const deviceId = device.DeviceID;
257
+ const deviceType = device.Type;
233
258
  const deviceName = device.DeviceName;
234
259
  const devicePresets = device.Presets ?? [];
235
260
 
@@ -254,6 +279,12 @@
254
279
  buttonsSensors: []
255
280
  };
256
281
 
282
+ const deviceExistsInConfig = atwDevices.find(device => device.id === deviceId);
283
+ if (!deviceExistsInConfig) {
284
+ atwDevices.push(deviceAtw);
285
+ newDevices.atw.push(deviceAtw);
286
+ };
287
+
257
288
  //presets
258
289
  for (const preset of devicePresets) {
259
290
  const presetId = preset.ID;
@@ -263,19 +294,29 @@
263
294
  preset.name = presetName;
264
295
  preset.displayType == 0;
265
296
  preset.namePrefix = false;
266
- newDevices.atwPresets.push(preset);
267
- };
268
- textAtwPresets = `ATW Presets: ${newDevices.atwPresets.length}`
269
297
 
270
- deviceAtw.presets = deviceAtw.atwPresets;
271
- newDevices.ata.push(deviceAtw);
272
- };
273
- pluginConfig[0].accounts[this.deviceIndex].atwDevices = newDevices.atw;
298
+ let presetExistsInConfig = false;
299
+ for (const atwDevice of atwDevices) {
300
+ if (atwDevice.presets?.some(preset => preset.id === presetId)) {
301
+ presetExistsInConfig = true;
302
+ break;
303
+ }
304
+ }
305
+
306
+ if (!presetExistsInConfig) {
307
+ atwDevices[index].presets.push(preset);
308
+ newDevices.atwPresets.push(preset);
309
+ };
310
+ };
311
+ atwPresetsCount = newDevices.atwPresets.length;
312
+ textAtwPresets = `ATW Presets: ${atwPresetsCount}`
313
+ });
274
314
  textAtw = `ATW: ${newDevices.atw.length}`
275
315
 
276
316
  //device erv
277
- for (const device of devicesByType.erv) {
317
+ devicesByType.erv.forEach((device, index) => {
278
318
  const deviceId = device.DeviceID;
319
+ const deviceType = device.Type;
279
320
  const deviceName = device.DeviceName;
280
321
  const devicePresets = device.Presets ?? [];
281
322
 
@@ -294,6 +335,12 @@
294
335
  buttonsSensors: []
295
336
  };
296
337
 
338
+ const deviceExistsInConfig = ervDevices.find(device => device.id === deviceId);
339
+ if (!deviceExistsInConfig) {
340
+ ervDevices.push(deviceErv);
341
+ newDevices.erv.push(deviceErv);
342
+ };
343
+
297
344
  //presets
298
345
  for (const preset of devicePresets) {
299
346
  const presetId = preset.ID;
@@ -303,18 +350,27 @@
303
350
  preset.name = presetName;
304
351
  preset.displayType == 0;
305
352
  preset.namePrefix = false;
306
- newDevices.atwPresets.push(preset);
307
- };
308
- textErvPresets = `ERV Presets: ${newDevices.ErvPresets.length}`
309
353
 
310
- deviceErv.presets = deviceErv.ervPresets;
311
- newDevices.erv.push(deviceErv);
312
- };
313
- pluginConfig[0].accounts[this.deviceIndex].ervDevices = newDevices.erv;
354
+ let presetExistsInConfig = false;
355
+ for (const ervDevice of ervDevices) {
356
+ if (ervDevice.presets?.some(preset => preset.id === presetId)) {
357
+ presetExistsInConfig = true;
358
+ break;
359
+ }
360
+ }
361
+
362
+ if (!presetExistsInConfig) {
363
+ ervDevices[index].presets.push(preset);
364
+ newDevices.ervPresets.push(preset);
365
+ };
366
+ };
367
+ ervPresetsCount = newDevices.ervPresets.length;
368
+ textErvPresets = `ERV Presets: ${ervPresetsCount}`
369
+ });
314
370
  textErv = `ERV: ${newDevices.erv.length}`
315
371
 
316
372
  const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length ?? 0;
317
- const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length ?? 0;
373
+ const newPresetsCount = ataPresetsCount + atwPresetsCount + ervPresetsCount ?? 0;
318
374
  if (newDevicesCount === 0 && newPresetsCount === 0) {
319
375
  document.getElementById('info').innerHTML = 'No new devices found.';
320
376
  document.getElementById('info').style.color = 'white';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "3.1.3-beta.9",
4
+ "version": "3.1.4-beta.0",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -28,8 +28,8 @@
28
28
  "LICENSE"
29
29
  ],
30
30
  "engines": {
31
- "node": ">=18.0.0",
32
- "homebridge": ">=2.0.0"
31
+ "homebridge": "^1.6.0 || ^2.0.0-beta.0",
32
+ "node": "^18.20.4 || ^20.15.1"
33
33
  },
34
34
  "dependencies": {
35
35
  "@homebridge/plugin-ui-utils": "^1.0.3",
package/src/deviceata.js CHANGED
@@ -86,6 +86,11 @@ class DeviceAta extends EventEmitter {
86
86
  this.accessory.targetOperationMode = 0;
87
87
  this.accessory.fanSpeed = 0;
88
88
 
89
+ this.accessory.operationModeSetPropsMinValue = 0;
90
+ this.accessory.operationModeSetPropsMaxValue = 3;
91
+ this.accessory.operationModeSetPropsValidValues = [0];
92
+ this.accessory.fanSpeedSetPropsMaxValue = 2;
93
+
89
94
  //melcloud device
90
95
  this.melCloudAta = new MelCloudAta({
91
96
  contextKey: contextKey,
@@ -187,6 +192,7 @@ class DeviceAta extends EventEmitter {
187
192
  .on('deviceState', async (deviceData, deviceState, useFahrenheit) => {
188
193
  //device info
189
194
  const displayMode = this.displayMode;
195
+ const inStandbyMode = deviceData.Device.InStandbyMode;
190
196
  const hasAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
191
197
  const airDirectionFunction = deviceData.Device.AirDirectionFunction ?? false;
192
198
  const hasOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
@@ -215,7 +221,6 @@ class DeviceAta extends EventEmitter {
215
221
  const vaneVertical = deviceState.VaneVertical;
216
222
  const hideVaneControls = deviceState.HideVaneControls;
217
223
  const hideDryModeControl = deviceState.HideDryModeControl;
218
- const inStandbyMode = deviceState.InStandbyMode;
219
224
  const prohibitSetTemperature = deviceState.ProhibitSetTemperature;
220
225
  const prohibitOperationMode = deviceState.ProhibitOperationMode;
221
226
  const prohibitPower = deviceState.ProhibitPower;
@@ -244,10 +249,6 @@ class DeviceAta extends EventEmitter {
244
249
  this.accessory.numberOfFanSpeeds = numberOfFanSpeeds;
245
250
  this.accessory.modelSupportsFanSpeed = modelSupportsFanSpeed;
246
251
  this.accessory.modelSupportsDry = modelSupportsDry;
247
- this.accessory.operationModeSetPropsMinValue = 0;
248
- this.accessory.operationModeSetPropsMaxValue = 3;
249
- this.accessory.operationModeSetPropsValidValues = [0];
250
- this.accessory.fanSpeedSetPropsMaxValue = 2;
251
252
 
252
253
  //operating mode
253
254
  switch (displayMode) {
@@ -808,32 +809,30 @@ class DeviceAta extends EventEmitter {
808
809
  })
809
810
  .onSet(async (value) => {
810
811
  try {
811
- let fanSpeed = 0; //AUTO, 1, 2, 3, 4, 5, 6
812
812
  let fanSpeedModeText = 0; //AUTO, 1, 2, 3, 4, 5, 6, OFF
813
813
  switch (numberOfFanSpeeds) {
814
814
  case 2: //Fan speed mode 2
815
- fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
815
+ deviceState.fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
816
816
  fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 0][value] : [7, 1, 2][value];
817
817
  break;
818
818
  case 3: //Fan speed mode 3
819
- fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
819
+ deviceState.fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
820
820
  fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 0][value] : [7, 1, 2, 3][value];
821
821
  break;
822
822
  case 4: //Fan speed mode 4
823
- fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
823
+ deviceState.fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
824
824
  fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 0][value] : [7, 1, 2, 3, 4][value];
825
825
  break;
826
826
  case 5: //Fan speed mode 5
827
- fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
827
+ deviceState.fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
828
828
  fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 0][value] : [7, 1, 2, 3, 4, 5][value];
829
829
  break;
830
830
  case 6: //Fan speed mode 6
831
- fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 6, 0][value] : [1, 1, 2, 3, 4, 5, 6][value];
831
+ deviceState.fanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 6, 0][value] : [1, 1, 2, 3, 4, 5, 6][value];
832
832
  fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6, 0][value] : [7, 1, 2, 3, 4, 5, 6][value];
833
833
  break;
834
834
  };
835
835
 
836
- deviceState.SetFanSpeed = fanSpeed;
837
836
  deviceState.EffectiveFlags = CONSTANTS.AirConditioner.EffectiveFlags.SetFanSpeed;
838
837
  await this.melCloudAta.send(deviceState);
839
838
  const info = this.disableLogInfo ? false : this.emit('message', `Set fan speed mode: ${CONSTANTS.AirConditioner.FanSpeed[fanSpeedModeText]}`);
package/src/deviceatw.js CHANGED
@@ -42,25 +42,25 @@ class DeviceAtw extends EventEmitter {
42
42
  //function
43
43
  this.melCloud = melCloud; //function
44
44
 
45
- //presets configured
46
- this.presetsConfigured = [];
47
- for (const preset of this.presets) {
48
- const presetName = preset.name ?? false;
49
- const presetDisplayType = preset.displayType ?? 0;
50
- const presetNamePrefix = preset.namePrefix ?? false;
51
- if (presetName && presetDisplayType > 0) {
52
- const presetyServiceType = ['', Service.Outlet, Service.Switch, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][presetDisplayType];
53
- const presetCharacteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][presetDisplayType];
54
- preset.namePrefix = presetNamePrefix;
55
- preset.serviceType = presetyServiceType;
56
- preset.characteristicType = presetCharacteristicType;
57
- preset.state = false;
58
- this.presetsConfigured.push(preset);
59
- } else {
60
- const log = presetDisplayType === 0 ? false : this.emit('message', `Preset Name: ${preset ? preset : 'Missing'}.`);
61
- };
62
- }
63
- this.presetsConfiguredCount = this.presetsConfigured.length || 0;
45
+ //presets configured
46
+ this.presetsConfigured = [];
47
+ for (const preset of this.presets) {
48
+ const presetName = preset.name ?? false;
49
+ const presetDisplayType = preset.displayType ?? 0;
50
+ const presetNamePrefix = preset.namePrefix ?? false;
51
+ if (presetName && presetDisplayType > 0) {
52
+ const presetyServiceType = ['', Service.Outlet, Service.Switch, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][presetDisplayType];
53
+ const presetCharacteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][presetDisplayType];
54
+ preset.namePrefix = presetNamePrefix;
55
+ preset.serviceType = presetyServiceType;
56
+ preset.characteristicType = presetCharacteristicType;
57
+ preset.state = false;
58
+ this.presetsConfigured.push(preset);
59
+ } else {
60
+ const log = presetDisplayType === 0 ? false : this.emit('message', `Preset Name: ${preset ? preset : 'Missing'}.`);
61
+ };
62
+ }
63
+ this.presetsConfiguredCount = this.presetsConfigured.length || 0;
64
64
 
65
65
  //buttons configured
66
66
  this.buttonsConfigured = [];
@@ -453,11 +453,15 @@ class DeviceAtw extends EventEmitter {
453
453
  this.accessory.zones[i].lockPhysicalControl = lockPhysicalControl;
454
454
  this.accessory.zones[i].flowTemperature = flowTemperature;
455
455
  this.accessory.zones[i].returnTemperature = returnTemperature;
456
- this.accessory.zones[i].operationModesSetPropsMinValue = operationModeSetPropsMinValue;
457
- this.accessory.zones[i].operationModesSetPropsMaxValue = operationModeSetPropsMaxValue;
458
- this.accessory.zones[i].operationModesSetPropsValidValues = operationModeSetPropsValidValues;
459
- this.accessory.zones[i].temperaturesSetPropsMinValue = temperatureSetPropsMinValue;
460
- this.accessory.zones[i].temperaturesSetPropsMaxValue = temperatureSetPropsMaxValue;
456
+
457
+ //only on first run
458
+ if (this.startPrepareAccessory) {
459
+ this.accessory.zones[i].operationModesSetPropsMinValue = operationModeSetPropsMinValue;
460
+ this.accessory.zones[i].operationModesSetPropsMaxValue = operationModeSetPropsMaxValue;
461
+ this.accessory.zones[i].operationModesSetPropsValidValues = operationModeSetPropsValidValues;
462
+ this.accessory.zones[i].temperaturesSetPropsMinValue = temperatureSetPropsMinValue;
463
+ this.accessory.zones[i].temperaturesSetPropsMaxValue = temperatureSetPropsMaxValue;
464
+ };
461
465
 
462
466
  //update temperature sensors
463
467
  switch (i) {
package/src/deviceerv.js CHANGED
@@ -85,6 +85,11 @@ class DeviceErv extends EventEmitter {
85
85
  this.accessory.fanSpeed = 0;
86
86
  this.accessory.lockPhysicalControl = 0;
87
87
 
88
+ this.accessory.operationModeSetPropsMinValue = 0;
89
+ this.accessory.operationModeSetPropsMaxValue = 3;
90
+ this.accessory.operationModeSetPropsValidValues = [0];
91
+ this.accessory.fanSpeedSetPropsMaxValue = 2;
92
+
88
93
  //melcloud device
89
94
  this.melCloudErv = new MelCloudErv({
90
95
  contextKey: contextKey,
@@ -266,10 +271,6 @@ class DeviceErv extends EventEmitter {
266
271
  this.accessory.coreMaintenanceRequired = coreMaintenanceRequired;
267
272
  this.accessory.filterMaintenanceRequired = filterMaintenanceRequired;
268
273
  this.accessory.actualVentilationMode = actualVentilationMode;
269
- this.accessory.operationModeSetPropsMinValue = 0;
270
- this.accessory.operationModeSetPropsMaxValue = 3;
271
- this.accessory.operationModeSetPropsValidValues = [0];
272
- this.accessory.fanSpeedSetPropsMaxValue = 2;
273
274
 
274
275
  //operation mode - 0, HEAT, 2, COOL, 4, 5, 6, FAN, AUTO
275
276
  switch (displayMode) {