homebridge-melcloud-control 4.3.9-beta.1 → 4.3.9-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.
@@ -211,7 +211,7 @@
211
211
 
212
212
  for (let i = configDevices.length - 1; i >= 0; i--) {
213
213
  const device = configDevices[i];
214
- if (device.id !== "0" && !melcloudIds.includes(device.id)) {
214
+ if (!melcloudIds.includes(device.id)) {
215
215
  removedDevices.push(device);
216
216
  configDevices.splice(i, 1);
217
217
  }
@@ -255,15 +255,15 @@
255
255
  if (device.Type === 3) devicesInMelCloudByType.erv.push(device);
256
256
  });
257
257
 
258
- account.ataDevices ??= [];
259
- account.atwDevices ??= [];
260
- account.ervDevices ??= [];
258
+ account.ataDevices = (account.ataDevices ?? []).filter(d => String(d.id) !== '0');
259
+ account.atwDevices = (account.atwDevices ?? []).filter(d => String(d.id) !== '0');
260
+ account.ervDevices = (account.ervDevices ?? []).filter(d => String(d.id) !== '0');
261
261
 
262
262
  const removedAta = removeStaleDevices(account.ataDevices, devicesInMelCloudByType.ata);
263
263
  const removedAtw = removeStaleDevices(account.atwDevices, devicesInMelCloudByType.atw);
264
264
  const removedErv = removeStaleDevices(account.ervDevices, devicesInMelCloudByType.erv);
265
265
 
266
- const handleDevices = (devicesInMelCloud, devicesInConfig, typeString, newDevices, newPresets, newSchedules, newScenes) => {
266
+ const handleDevices = (devicesInMelCloud, devicesInConfig, deviceTypeString, newDevices, newPresets, newSchedules, newScenes) => {
267
267
  try {
268
268
  const configDevicesMap = new Map(devicesInConfig.map(dev => [String(dev.id), dev]));
269
269
 
@@ -276,13 +276,9 @@
276
276
  deviceInConfig = {
277
277
  id: deviceId,
278
278
  type: device.Type,
279
- typeString,
279
+ deviceTypeString,
280
280
  displayType: 0,
281
- name: device.DeviceName,
282
- presets: [],
283
- schedules: [],
284
- scenes: [],
285
- buttonsSensors: []
281
+ name: device.DeviceName
286
282
  };
287
283
  devicesInConfig.push(deviceInConfig);
288
284
  newDevices.push(deviceInConfig);
@@ -294,10 +290,9 @@
294
290
 
295
291
  // === Process presets ===
296
292
  const presetsInMelCloud = device.Presets || [];
297
- const presetsInConfig = deviceInConfig.presets || [];
293
+ const presetsInConfig = (deviceInConfig.presets ?? []).filter(p => String(p.id) !== '0');
298
294
  const presetIds = new Set(presetsInConfig.map(p => String(p.id)));
299
295
 
300
- let addedNewPreset = false;
301
296
  presetsInMelCloud.forEach((preset, index) => {
302
297
  const presetId = String(preset.ID);
303
298
  if (!presetIds.has(presetId)) {
@@ -310,20 +305,8 @@
310
305
  presetsInConfig.push(presetObj);
311
306
  newPresets.push(presetObj);
312
307
  presetIds.add(presetId);
313
- addedNewPreset = true;
314
308
  }
315
309
  });
316
-
317
- // === Remove placeholder presets/schedules (id === '0') if new ones were added ===
318
- if (addedNewPreset) {
319
- const beforeCount = presetsInConfig.length;
320
- deviceInConfig.presets = presetsInConfig.filter(p => String(p.id) !== '0');
321
- const removedCount = beforeCount - deviceInConfig.presets.length;
322
-
323
- if (removedCount > 0 && removedCount < beforeCount) {
324
- updateInfo('info2', `Removed ${removedCount} placeholder preset from device ${device.DeviceID}`, 'yellow');
325
- }
326
- }
327
310
  }
328
311
 
329
312
  //only for melcloudhome
@@ -331,10 +314,9 @@
331
314
 
332
315
  // === Process schedules ===
333
316
  const schedulesInMelCloud = device.Schedule || [];
334
- const schedulesInConfig = deviceInConfig.schedules || [];
317
+ const schedulesInConfig = (deviceInConfig.schedules ?? []).filter(s => String(s.id) !== '0');
335
318
  const scheduleIds = new Set(schedulesInConfig.map(s => String(s.id)));
336
319
 
337
- let addedNewSchedule = false;
338
320
  schedulesInMelCloud.forEach((schedule, index) => {
339
321
  const scheduleId = String(schedule.Id);
340
322
  if (!scheduleIds.has(scheduleId)) {
@@ -347,26 +329,13 @@
347
329
  schedulesInConfig.push(scheduleObj);
348
330
  newSchedules.push(scheduleObj);
349
331
  scheduleIds.add(scheduleId);
350
- addedNewSchedule = true;
351
332
  }
352
333
  });
353
334
 
354
- // === Remove placeholder schedules (id === '0') if new ones were added ===
355
- if (addedNewSchedule) {
356
- const beforeCount = schedulesInConfig.length;
357
- deviceInConfig.schedules = schedulesInConfig.filter(s => String(s.id) !== '0');
358
- const removedCount = beforeCount - deviceInConfig.schedules.length;
359
-
360
- if (removedCount > 0 && removedCount < beforeCount) {
361
- updateInfo('info2', `Removed ${removedCount} placeholder schedule from device ${device.DeviceID}`, 'yellow');
362
- }
363
- }
364
-
365
335
  // === Process scenes ===
366
- const scenesInConfig = deviceInConfig.scenes || [];
336
+ const scenesInConfig = (deviceInConfig.scenes ?? []).filter(s => String(s.id) !== '0');
367
337
  const sceneIds = new Set(scenesInConfig.map(s => String(s.id)));
368
338
 
369
- let addedNewScenes = false;
370
339
  scenesInMelCloud.forEach((scene, index) => {
371
340
  const sceneId = String(scene.Id);
372
341
  if (!sceneIds.has(sceneId)) {
@@ -379,26 +348,13 @@
379
348
  scenesInConfig.push(sceneObj);
380
349
  newScenes.push(sceneObj);
381
350
  sceneIds.add(sceneId);
382
- addedNewScenes = true;
383
351
  }
384
352
  });
385
-
386
- // === Remove placeholder scenes (id === '0') if new ones were added ===
387
- if (addedNewScenes) {
388
- const beforeCount = scenesInConfig.length;
389
- deviceInConfig.scenes = scenesInConfig.filter(s => String(s.id) !== '0');
390
- const removedCount = beforeCount - deviceInConfig.scenes.length;
391
-
392
- if (removedCount > 0 && removedCount < beforeCount) {
393
- updateInfo('info2', `Removed ${removedCount} placeholder scene from device ${device.DeviceID}`, 'yellow');
394
- }
395
- }
396
353
  }
397
354
  });
398
355
 
399
356
  // Return filtered devicesInConfig to make sure upstream code uses it
400
- const filteredDevices = devicesInConfig.filter(d => String(d.id) !== '0');
401
- return filteredDevices;
357
+ return devicesInConfig;
402
358
  } catch (error) {
403
359
  updateInfo('info', `Error while processing device: ${JSON.stringify(error)}`, 'red');
404
360
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.3.9-beta.1",
4
+ "version": "4.3.9-beta.10",
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/constants.js CHANGED
@@ -58,15 +58,19 @@ export const TemperatureDisplayUnits = ["°C", "°F"];
58
58
 
59
59
  export const AirConditioner = {
60
60
  SystemMapEnumToString: { 0: "Air Conditioner Off", 1: "Air Conditioner On", 2: "Air Conditioner Offline" },
61
- OperationModeMapStringToEnum: { "0": 0, "Heat": 1, "Dry": 2, "Cool": 3, "4": 7, "5": 8, "6": 6, "Fan": 7, "Automatic": 8, "Isee Heat": 9, "Isee Dry": 10, "Isee Cool": 11 },
61
+ OperationModeMapStringToEnum: { "0": 0, "Heat": 1, "Dry": 2, "Cool": 3, "4": 4, "5": 5, "6": 6, "Fan": 7, "Automatic": 8, "Isee Heat": 9, "Isee Dry": 10, "Isee Cool": 11 },
62
62
  OperationModeMapEnumToString: { 0: "0", 1: "Heat", 2: "Dry", 3: "Cool", 4: "4", 5: "5", 6: "6", 7: "Fan", 8: "Automatic", 9: "Isee Heat", 10: "Isee Dry", 11: "Isee Cool" },
63
+ OperationModeMapEnumToEnumWs: { 0: 0, 1: 1, 2: 2, 3: 3, 4: 7, 5: 8, 6: 9, 7: 10, 8: 11 },
63
64
  FanSpeedMapStringToEnum: { "Auto": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5 },
64
65
  FanSpeedMapEnumToString: { 0: "Auto", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five" },
66
+ AktualFanSpeedMapStringToEnum: { "Auto": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5 },
65
67
  AktualFanSpeedMapEnumToString: { 0: "Quiet", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five" },
66
68
  VaneVerticalDirectionMapStringToEnum: { "Auto": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5, "Six": 6, "Swing": 7 },
67
69
  VaneVerticalDirectionMapEnumToString: { 0: "Auto", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Swing" },
70
+ VaneVerticalDirectionMapEnumToEnumWs: { 6: 7 },
68
71
  VaneHorizontalDirectionMapStringToEnum: { "Auto": 0, "Left": 1, "LeftCentre": 2, "Centre": 3, "RightCentre": 4, "Right": 5, "Six": 6, "Seven": 7, "Split": 8, "Nine": 9, "Ten": 10, "Eleven": 11, "Swing": 12 },
69
72
  VaneHorizontalDirectionMapEnumToString: { 0: "Auto", 1: "Left", 2: "LeftCentre", 3: "Centre", 4: "RightCentre", 5: "Right", 6: "Six", 7: "Seven", 8: "Split", 9: "Nine", 10: "Ten", 11: "Eleven", 12: "Swing" },
73
+ VaneHorizontalDirectionMapEnumToEnumWs: { 7: 12 },
70
74
  AirDirectionMapEnumToString: { 0: "Auto", 1: "Swing" },
71
75
  CurrentOperationModeMapEnumToStringHeatherCooler: { 0: "Inactive", 1: "Idle", 2: "Heating", 3: "Cooling" },
72
76
  CurrentOperationModeMapEnumToStringThermostat: { 0: "Inactive", 1: "Heating", 2: "Cooling" },
package/src/deviceata.js CHANGED
@@ -439,7 +439,8 @@ class DeviceAta extends EventEmitter {
439
439
  if (supportsSwingFunction) {
440
440
  melCloudService.getCharacteristic(Characteristic.SwingMode)
441
441
  .onGet(async () => {
442
- //Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 7 = Sp;it, 12 = Swing //Vertical: Auto, 1, 2, 3, 4, 5, 7 = Swing
442
+ //Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 7 = Split, 12 = Swing //Vertical: Auto, 1, 2, 3, 4, 5, 7 = Swing
443
+ //Home Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 7 = Swing, 8 = Split //Vertical: Auto, 1, 2, 3, 4, 5, 6 = Swing
443
444
  const value = this.accessory.currentSwingMode;
444
445
  return value;
445
446
  })
@@ -35,6 +35,7 @@ class MelCloudAta extends EventEmitter {
35
35
  deviceData.Scenes = devicesData.Scenes ?? [];
36
36
 
37
37
  //update state
38
+ if (!this.logDebug) this.emit('debug', `Request update device settings: ${JSON.stringify(deviceData.Device, null, 2)}`);
38
39
  await this.updateState(deviceData);
39
40
  }).on('webSocket', async (parsedMessage) => {
40
41
  try {
@@ -62,9 +63,12 @@ class MelCloudAta extends EventEmitter {
62
63
 
63
64
  //update device settings
64
65
  if (key in deviceData.Device) {
65
- deviceData.Device[key] = value;
66
+ let parsedValue = this.functions.convertValue(value);
67
+ deviceData.Device[key] = parsedValue;
66
68
  }
67
69
  }
70
+
71
+ if (!this.logDebug) this.emit('debug', `WS update device settings: ${JSON.stringify(deviceData.Device, null, 2)}`);
68
72
  updateState = true;
69
73
  break;
70
74
  case 'unitHolidayModeTriggered':
@@ -88,21 +92,28 @@ class MelCloudAta extends EventEmitter {
88
92
  }
89
93
 
90
94
  //update state
91
- if (updateState) await this.updateState(deviceData);
95
+ if (updateState) await this.updateState(deviceData, 'ws');
92
96
  } catch (error) {
93
97
  if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
94
98
  }
95
99
  });
96
100
  }
97
101
 
98
- async updateState(deviceData) {
102
+ async updateState(deviceData, type) {
99
103
  try {
100
104
  if (this.accountType === 'melcloudhome') {
101
- deviceData.Device.OperationMode = AirConditioner.OperationModeMapStringToEnum[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
102
- deviceData.Device.ActualFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.ActualFanSpeed] ?? deviceData.Device.ActualFanSpeed;
103
- deviceData.Device.SetFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.SetFanSpeed] ?? deviceData.Device.SetFanSpeed;
104
- deviceData.Device.VaneHorizontalDirection = AirConditioner.VaneHorizontalDirectionMapStringToEnum[deviceData.Device.VaneHorizontalDirection] ?? deviceData.Device.VaneHorizontalDirection
105
- deviceData.Device.VaneVerticalDirection = AirConditioner.VaneVerticalDirectionMapStringToEnum[deviceData.Device.VaneVerticalDirection] ?? deviceData.Device.VaneVerticalDirection;
105
+
106
+ if (type === 'ws') {
107
+ deviceData.Device.OperationMode = AirConditioner.OperationModeMapEnumToEnumWs[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
108
+ deviceData.Device.VaneHorizontalDirection = AirConditioner.VaneHorizontalDirectionMapEnumToEnumWs[deviceData.Device.VaneHorizontalDirection] ?? deviceData.Device.VaneHorizontalDirection;
109
+ deviceData.Device.VaneVerticalDirection = AirConditioner.VaneVerticalDirectionMapEnumToEnumWs[deviceData.Device.VaneVerticalDirection] ?? deviceData.Device.VaneVerticalDirection;
110
+ } else {
111
+ deviceData.Device.OperationMode = AirConditioner.OperationModeMapStringToEnum[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
112
+ deviceData.Device.ActualFanSpeed = AirConditioner.AktualFanSpeedMapStringToEnum[deviceData.Device.ActualFanSpeed] ?? deviceData.Device.ActualFanSpeed;
113
+ deviceData.Device.SetFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.SetFanSpeed] ?? deviceData.Device.SetFanSpeed;
114
+ deviceData.Device.VaneHorizontalDirection = AirConditioner.VaneHorizontalDirectionMapStringToEnum[deviceData.Device.VaneHorizontalDirection] ?? deviceData.Device.VaneHorizontalDirection;
115
+ deviceData.Device.VaneVerticalDirection = AirConditioner.VaneVerticalDirectionMapStringToEnum[deviceData.Device.VaneVerticalDirection] ?? deviceData.Device.VaneVerticalDirection;
116
+ }
106
117
 
107
118
  //read default temps
108
119
  const temps = await this.functions.readData(this.defaultTempsFile, true);
@@ -224,7 +235,7 @@ class MelCloudAta extends EventEmitter {
224
235
  }
225
236
 
226
237
  if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
227
-
238
+
228
239
  await axios(path, {
229
240
  method: 'POST',
230
241
  baseURL: ApiUrls.BaseURL,
@@ -313,7 +324,7 @@ class MelCloudAta extends EventEmitter {
313
324
  //sens payload
314
325
  headers['Content-Type'] = 'application/json; charset=utf-8';
315
326
  headers.Origin = ApiUrlsHome.Origin;
316
- if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
327
+ if (!this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
317
328
 
318
329
  await axios(path, {
319
330
  method: method,