homebridge-melcloud-control 4.4.1-beta.35 → 4.4.1-beta.36

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.
@@ -205,17 +205,17 @@
205
205
  });
206
206
 
207
207
  // Generic remove function
208
- function removeStaleEntities(configList, serverList, getConfigId, getServerId) {
209
- const serverIds = new Set(serverList.map(item => String(getServerId(item))));
208
+ function removeStaleEntities(configEntities, MelcloudEntities, getConfigId, getMelcloudId) {
209
+ const serverIds = new Set(MelcloudEntities.map(item => String(getMelcloudId(item))));
210
210
  const removedEntities = [];
211
211
 
212
- for (let i = configList.length - 1; i >= 0; i--) {
213
- const entity = configList[i];
212
+ for (let i = configEntities.length - 1; i >= 0; i--) {
213
+ const entity = configEntities[i];
214
214
  const entityId = String(getConfigId(entity));
215
215
 
216
216
  if (!serverIds.has(entityId)) {
217
217
  removedEntities.push(entity);
218
- configList.splice(i, 1);
218
+ configEntities.splice(i, 1);
219
219
  }
220
220
  }
221
221
 
@@ -233,7 +233,6 @@
233
233
  // Login & Sync Logic
234
234
  document.getElementById('logIn').addEventListener('click', async () => {
235
235
  homebridge.showSpinner();
236
-
237
236
  document.getElementById('logIn').className = "btn btn-primary";
238
237
  updateInfo('info', '', 'white');
239
238
  updateInfo('info1', '', 'white');
@@ -250,7 +249,7 @@
250
249
  }
251
250
 
252
251
  // Prepare MELCloud data
253
- const newInMelCloud = { ata: [], ataPresets: [], ataSchedules: [], atw: [], atwPresets: [], atwSchedules: [], erv: [], ervPresets: [], ervSchedules: [], scenes: [] };
252
+ const newInMelCloud = { ata: [], ataPresets: [], ataSchedules: [], ataScenes: [], atw: [], atwPresets: [], atwSchedules: [], atwScenes: [], erv: [], ervPresets: [], ervSchedules: [], ervScenes: [], scenes: [] };
254
253
  const devicesInMelCloudByType = { ata: [], atw: [], erv: [] };
255
254
  const scenesInMelCloud = response.Scenes ?? [];
256
255
 
@@ -264,109 +263,126 @@
264
263
  account.atwDevices = (account.atwDevices ?? []).filter(d => String(d.id) !== '0');
265
264
  account.ervDevices = (account.ervDevices ?? []).filter(d => String(d.id) !== '0');
266
265
 
267
- // Remove stale DEVICES
268
- const removedAta = removeStaleEntities(account.ataDevices, devicesInMelCloudByType.ata, d => d.id, d => d.DeviceID);
269
- const removedAtw = removeStaleEntities(account.atwDevices, devicesInMelCloudByType.atw, d => d.id, d => d.DeviceID);
270
- const removedErv = removeStaleEntities(account.ervDevices, devicesInMelCloudByType.erv, d => d.id, d => d.DeviceID);
266
+ const removedFromConfigAta = removeStaleEntities(account.ataDevices, devicesInMelCloudByType.ata, d => d.id, d => d.DeviceID);
267
+ const removedFromConfigAtw = removeStaleEntities(account.atwDevices, devicesInMelCloudByType.atw, d => d.id, d => d.DeviceID);
268
+ const removedFromConfigErv = removeStaleEntities(account.ervDevices, devicesInMelCloudByType.erv, d => d.id, d => d.DeviceID);
269
+ const removedFromConfig = { ataPresets: [], atwPresets: [], ervPresets: [], ataSchedules: [], atwSchedules: [], ervSchedules: [], scenes: [] };
271
270
 
272
- // Remove stale SCENES (global)
273
- account.scenes = account.scenes ?? [];
274
- removeStaleEntities(account.scenes, scenesInMelCloud, s => s.id, s => s.Id);
275
271
 
276
272
  // Handle Devices
277
- const handleDevices = (devicesInMelCloud, devicesInConfig, deviceTypeString, newDevices, newPresets, newSchedules) => {
273
+ const handleDevices = (devicesInMelCloud, devicesInConfig, deviceTypeString, newDevices, newPresets, newSchedules, newScenes) => {
278
274
  const configDevicesMap = new Map(devicesInConfig.map(dev => [String(dev.id), dev]));
279
275
 
280
276
  devicesInMelCloud.forEach(device => {
281
- const deviceId = String(device.DeviceID);
277
+ const deviceId = String(device.DeviceID); // Make sure this matches MelCloud data
282
278
  let deviceInConfig = configDevicesMap.get(deviceId);
283
279
 
284
- // === Create missing device ===
285
280
  if (!deviceInConfig) {
286
281
  deviceInConfig = {
287
282
  id: deviceId,
288
283
  type: device.Type,
289
284
  deviceTypeString,
290
285
  displayType: 0,
291
- name: device.DeviceName
286
+ name: device.DeviceName,
287
+ presets: [],
288
+ schedules: [],
289
+ scenes: []
292
290
  };
293
291
  devicesInConfig.push(deviceInConfig);
294
292
  newDevices.push(deviceInConfig);
295
293
  configDevicesMap.set(deviceId, deviceInConfig);
296
294
  }
297
295
 
298
- // PRESETS (melcloud)
299
- if (account.type === 'melcloud') {
300
- deviceInConfig.presets = deviceInConfig.presets ?? [];
301
-
302
- const presetsInMelCloud = device.Presets || [];
303
- removeStaleEntities(deviceInConfig.presets, presetsInMelCloud, p => p.id, p => p.ID);
304
-
305
- const presetIds = new Set(deviceInConfig.presets.map(p => String(p.id)));
306
- presetsInMelCloud.forEach((preset, index) => {
307
- const presetId = String(preset.ID);
308
- if (!presetIds.has(presetId)) {
309
- const presetObj = {
310
- id: presetId,
311
- displayType: 0,
312
- name: preset.NumberDescription || `Preset ${index}`,
313
- namePrefix: false
314
- };
315
- deviceInConfig.presets.push(presetObj);
316
- newPresets.push(presetObj);
317
- }
318
- });
319
- }
320
-
321
- // SCHEDULES (melcloudhome)
322
- if (account.type === 'melcloudhome') {
323
- deviceInConfig.schedules = deviceInConfig.schedules ?? [];
324
-
325
- const schedulesInMelCloud = device.Schedule || [];
326
- removeStaleEntities(deviceInConfig.schedules, schedulesInMelCloud, s => s.id, s => s.Id);
327
-
328
- const scheduleIds = new Set(deviceInConfig.schedules.map(s => String(s.id)));
329
- schedulesInMelCloud.forEach((schedule, index) => {
330
- const scheduleId = String(schedule.Id);
331
- if (!scheduleIds.has(scheduleId)) {
332
- const scheduleObj = {
333
- id: scheduleId,
334
- displayType: 0,
335
- name: `Schedule ${index}`,
336
- namePrefix: false
337
- };
338
- deviceInConfig.schedules.push(scheduleObj);
339
- newSchedules.push(scheduleObj);
340
- }
341
- });
342
- }
296
+ // PRESETS
297
+ deviceInConfig.presets = deviceInConfig.presets ?? [];
298
+ const presetsInMelCloud = device.Presets || [];
299
+ removedFromConfig.ataPresets.push(...removeStaleEntities(deviceInConfig.presets, presetsInMelCloud, p => p.id, p => p.ID));
300
+ const presetIds = new Set(deviceInConfig.presets.map(p => String(p.id)));
301
+ presetsInMelCloud.forEach((preset, index) => {
302
+ const presetId = String(preset.ID);
303
+ if (!presetIds.has(presetId)) {
304
+ const presetObj = {
305
+ id: presetId,
306
+ displayType: 0,
307
+ name: preset.NumberDescription || `Preset ${index}`,
308
+ namePrefix: false
309
+ };
310
+ deviceInConfig.presets.push(presetObj);
311
+ newPresets.push(presetObj);
312
+ }
313
+ });
314
+
315
+ // SCHEDULES
316
+ deviceInConfig.schedules = deviceInConfig.schedules ?? [];
317
+ const schedulesInMelCloud = device.Schedule || [];
318
+ removedFromConfig.ataSchedules.push(...removeStaleEntities(deviceInConfig.schedules, schedulesInMelCloud, s => s.id, s => s.Id));
319
+ const scheduleIds = new Set(deviceInConfig.schedules.map(s => String(s.id)));
320
+ schedulesInMelCloud.forEach((schedule, index) => {
321
+ const scheduleId = String(schedule.Id);
322
+ if (!scheduleIds.has(scheduleId)) {
323
+ const scheduleObj = {
324
+ id: scheduleId,
325
+ displayType: 0,
326
+ name: `Schedule ${index}`,
327
+ namePrefix: false
328
+ };
329
+ deviceInConfig.schedules.push(scheduleObj);
330
+ newSchedules.push(scheduleObj);
331
+ }
332
+ });
333
+
334
+ // SCENES
335
+ deviceInConfig.scenes = deviceInConfig.scenes ?? [];
336
+ removedFromConfig.scenes.push(...removeStaleEntities(deviceInConfig.scenes, scenesInMelCloud, s => s.id, s => s.Id));
337
+ const sceneIds = new Set(deviceInConfig.scenes.map(s => String(s.id)));
338
+ scenesInMelCloud.forEach((scene, index) => {
339
+ const sceneId = String(scene.Id);
340
+ if (!sceneIds.has(sceneId)) {
341
+ const sceneObj = {
342
+ id: sceneId,
343
+ displayType: 0,
344
+ name: scene.Name || `Scene ${index}`,
345
+ namePrefix: false
346
+ };
347
+ deviceInConfig.scenes.push(sceneObj);
348
+ newScenes.push(sceneObj);
349
+ }
350
+ });
343
351
  });
344
352
 
345
353
  return devicesInConfig;
346
354
  };
347
355
 
348
356
  // Execute device handlers
349
- account.ataDevices = handleDevices(devicesInMelCloudByType.ata, account.ataDevices, "Air Conditioner", newInMelCloud.ata, newInMelCloud.ataPresets, newInMelCloud.ataSchedules);
350
- account.atwDevices = handleDevices(devicesInMelCloudByType.atw, account.atwDevices, "Heat Pump", newInMelCloud.atw, newInMelCloud.atwPresets, newInMelCloud.atwSchedules);
351
- account.ervDevices = handleDevices(devicesInMelCloudByType.erv, account.ervDevices, "Energy Recovery Ventilation", newInMelCloud.erv, newInMelCloud.ervPresets, newInMelCloud.ervSchedules);
357
+ account.ataDevices = handleDevices(devicesInMelCloudByType.ata, account.ataDevices, "Air Conditioner", newInMelCloud.ata, newInMelCloud.ataPresets, newInMelCloud.ataSchedules, newInMelCloud.ataScenes);
358
+ account.atwDevices = handleDevices(devicesInMelCloudByType.atw, account.atwDevices, "Heat Pump", newInMelCloud.atw, newInMelCloud.atwPresets, newInMelCloud.atwSchedules, newInMelCloud.atwScenes);
359
+ account.ervDevices = handleDevices(devicesInMelCloudByType.erv, account.ervDevices, "Energy Recovery Ventilation", newInMelCloud.erv, newInMelCloud.ervPresets, newInMelCloud.ervSchedules, newInMelCloud.ervScenes);
352
360
 
353
361
  // Summary
354
362
  const newDevicesCount = newInMelCloud.ata.length + newInMelCloud.atw.length + newInMelCloud.erv.length;
355
363
  const newPresetsCount = newInMelCloud.ataPresets.length + newInMelCloud.atwPresets.length + newInMelCloud.ervPresets.length;
356
364
  const newSchedulesCount = newInMelCloud.ataSchedules.length + newInMelCloud.atwSchedules.length + newInMelCloud.ervSchedules.length;
357
- const removedDevicesCount = removedAta.length + removedAtw.length + removedErv.length;
365
+ const newScenesCount = newInMelCloud.scenes.length;
366
+ const removedDevicesCount = removedFromConfigAta.length + removedFromConfigAtw.length + removedFromConfigErv.length;
367
+ const removedPresetsCount = removedFromConfig.ataPresets.length + removedFromConfig.atwPresets.length + removedFromConfig.ervPresets.length;
368
+ const removedSchedulesCount = removedFromConfig.ataSchedules.length + removedFromConfig.atwSchedules.length + removedFromConfig.ervSchedules.length;
369
+ const removedScenesCount = removedFromConfig.scenes.length
358
370
 
359
- if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !removedDevicesCount) {
371
+ if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !newScenesCount && !removedDevicesCount && !removedPresetsCount && !removedSchedulesCount && !removedScenesCount) {
360
372
  updateInfo('info', 'No changes detected.', 'white');
361
373
  } else {
362
374
  if (newDevicesCount)
363
- updateInfo('info', `Found new devices: ${newDevicesCount}`, 'green');
375
+ updateInfo('info', `Found new devices: ${newInMelCloud.ata.length ? `ATA: ${newInMelCloud.ata.length},` : ''} ${newInMelCloud.atw.length ? `ATW: ${newInMelCloud.atw.length},` : ''} ${newInMelCloud.erv.length ? `ERV: ${newInMelCloud.erv.length},` : ''}.`, 'green');
364
376
  if (newPresetsCount)
365
- updateInfo('info1', `Found new presets: ${newPresetsCount}`, 'green');
366
- if (newSchedulesCount)
367
- updateInfo('info1', `Found new schedules: ${newSchedulesCount}`, 'green');
377
+ updateInfo('info1', `Found new presets: ${newInMelCloud.ataPresets.length ? `ATA: ${newInMelCloud.ataPresets.length},` : ''} ${newInMelCloud.atwPresets.length ? `ATW: ${newInMelCloud.atwPresets.length},` : ''} ${newInMelCloud.ervPresets.length ? `ERV: ${newInMelCloud.ervPresets.length}` : ''}.`, 'green');
378
+ if (newScenesCount || newSchedulesCount)
379
+ updateInfo('info1', `Found new ${newSchedulesCount ? `schedules:` : ''} ${newInMelCloud.ataSchedules.length ? `ATA: ${newInMelCloud.ataSchedules.length},` : ''} ${newInMelCloud.atwSchedules.length ? `ATW: ${newInMelCloud.atwSchedules.length},` : ''} ${newInMelCloud.ervSchedules.length ? `ERV: ${newInMelCloud.ervSchedules.length},` : ''} ${newScenesCount ? `scenes: ${newScenesCount}` : ''}.`, 'green');
368
380
  if (removedDevicesCount)
369
- updateInfo('info2', `Removed devices: ${removedDevicesCount}`, 'orange');
381
+ updateInfo('info', `Removed devices: ${removedFromConfigAta.length ? `ATA: ${removedFromConfigAta.length},` : ''} ${removedFromConfigAtw.length ? `ATW: ${removedFromConfigAtw.length},` : ''} ${removedFromConfigErv.length ? `ERV: ${removedFromConfigErv.length}` : ''}.`, 'orange');
382
+ if (removedPresetsCount)
383
+ updateInfo('info1', `Rempved presets: ${removedFromConfig.ataPresets.length ? `ATA: ${removedFromConfig.ataPresets.length},` : ''} ${removedFromConfig.atwPresets.length ? `ATW: ${removedFromConfig.atwPresets.length},` : ''} ${removedFromConfig.ervPresets.length ? `ERV: ${removedFromConfig.ervPresets.length}` : ''}.`, 'orange');
384
+ if (removedSchedulesCount || removedScenesCount)
385
+ updateInfo('info1', `Rempved ${removedScenesCount ? `schedules:` : ''} ${removedFromConfig.ataSchedules.length ? `ATA: ${removedFromConfig.ataSchedules.length},` : ''} ${removedFromConfig.atwSchedules.length ? `ATW: ${removedFromConfig.atwSchedules.length},` : ''} ${removedFromConfig.ervSchedules.length ? `ERV: ${removedFromConfig.ervSchedules.length},` : ''} ${removedScenesCount ? `scenes: ${removedScenesCount}` : ''}.`, 'orange');
370
386
  }
371
387
 
372
388
  await homebridge.updatePluginConfig(pluginConfig);
@@ -380,5 +396,6 @@
380
396
  }
381
397
  });
382
398
 
399
+
383
400
  })();
384
401
  </script>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.4.1-beta.35",
4
+ "version": "4.4.1-beta.36",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",