homebridge-melcloud-control 4.4.1-beta.34 → 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,13 +249,7 @@
250
249
  }
251
250
 
252
251
  // Prepare MELCloud data
253
- const newInMelCloud = {
254
- ata: [], ataPresets: [], ataSchedules: [],
255
- atw: [], atwPresets: [], atwSchedules: [],
256
- erv: [], ervPresets: [], ervSchedules: [],
257
- scenes: []
258
- };
259
-
252
+ const newInMelCloud = { ata: [], ataPresets: [], ataSchedules: [], ataScenes: [], atw: [], atwPresets: [], atwSchedules: [], atwScenes: [], erv: [], ervPresets: [], ervSchedules: [], ervScenes: [], scenes: [] };
260
253
  const devicesInMelCloudByType = { ata: [], atw: [], erv: [] };
261
254
  const scenesInMelCloud = response.Scenes ?? [];
262
255
 
@@ -270,209 +263,126 @@
270
263
  account.atwDevices = (account.atwDevices ?? []).filter(d => String(d.id) !== '0');
271
264
  account.ervDevices = (account.ervDevices ?? []).filter(d => String(d.id) !== '0');
272
265
 
273
- // ================================
274
- // Remove stale DEVICES
275
- // ================================
276
- const removedAta = removeStaleEntities(
277
- account.ataDevices,
278
- devicesInMelCloudByType.ata,
279
- d => d.id,
280
- d => d.DeviceID
281
- );
282
-
283
- const removedAtw = removeStaleEntities(
284
- account.atwDevices,
285
- devicesInMelCloudByType.atw,
286
- d => d.id,
287
- d => d.DeviceID
288
- );
289
-
290
- const removedErv = removeStaleEntities(
291
- account.ervDevices,
292
- devicesInMelCloudByType.erv,
293
- d => d.id,
294
- d => d.DeviceID
295
- );
296
-
297
- // Remove stale SCENES (global)
298
- account.scenes = account.scenes ?? [];
299
-
300
- const removedScenes = removeStaleEntities(
301
- account.scenes,
302
- scenesInMelCloud,
303
- s => s.id,
304
- s => s.Id
305
- );
306
-
307
- removedScenes.forEach(s =>
308
- newInMelCloud.scenes.push({ ...s, removed: true })
309
- );
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: [] };
270
+
310
271
 
311
272
  // Handle Devices
312
- const handleDevices = (
313
- devicesInMelCloud,
314
- devicesInConfig,
315
- deviceTypeString,
316
- newDevices,
317
- newPresets,
318
- newSchedules
319
- ) => {
320
- const configDevicesMap = new Map(
321
- devicesInConfig.map(dev => [String(dev.id), dev])
322
- );
273
+ const handleDevices = (devicesInMelCloud, devicesInConfig, deviceTypeString, newDevices, newPresets, newSchedules, newScenes) => {
274
+ const configDevicesMap = new Map(devicesInConfig.map(dev => [String(dev.id), dev]));
323
275
 
324
276
  devicesInMelCloud.forEach(device => {
325
- const deviceId = String(device.DeviceID);
277
+ const deviceId = String(device.DeviceID); // Make sure this matches MelCloud data
326
278
  let deviceInConfig = configDevicesMap.get(deviceId);
327
279
 
328
- // === Create missing device ===
329
280
  if (!deviceInConfig) {
330
281
  deviceInConfig = {
331
282
  id: deviceId,
332
283
  type: device.Type,
333
284
  deviceTypeString,
334
285
  displayType: 0,
335
- name: device.DeviceName
286
+ name: device.DeviceName,
287
+ presets: [],
288
+ schedules: [],
289
+ scenes: []
336
290
  };
337
291
  devicesInConfig.push(deviceInConfig);
338
292
  newDevices.push(deviceInConfig);
339
293
  configDevicesMap.set(deviceId, deviceInConfig);
340
294
  }
341
295
 
342
- // PRESETS (melcloud)
343
- if (account.type === 'melcloud') {
344
- deviceInConfig.presets = deviceInConfig.presets ?? [];
345
- const presetsInMelCloud = device.Presets || [];
346
-
347
- const removedPresets = removeStaleEntities(
348
- deviceInConfig.presets,
349
- presetsInMelCloud,
350
- p => p.id,
351
- p => p.ID
352
- );
353
-
354
- removedPresets.forEach(p =>
355
- newPresets.push({ ...p, removed: true })
356
- );
357
-
358
- const presetIds = new Set(
359
- deviceInConfig.presets.map(p => String(p.id))
360
- );
361
-
362
- presetsInMelCloud.forEach((preset, index) => {
363
- const presetId = String(preset.ID);
364
- if (!presetIds.has(presetId)) {
365
- const presetObj = {
366
- id: presetId,
367
- displayType: 0,
368
- name: preset.NumberDescription || `Preset ${index}`,
369
- namePrefix: false
370
- };
371
- deviceInConfig.presets.push(presetObj);
372
- newPresets.push(presetObj);
373
- }
374
- });
375
- }
376
-
377
- // SCHEDULES (melcloudhome)
378
- if (account.type === 'melcloudhome') {
379
- deviceInConfig.schedules = deviceInConfig.schedules ?? [];
380
- const schedulesInMelCloud = device.Schedule || [];
381
-
382
- const removedSchedules = removeStaleEntities(
383
- deviceInConfig.schedules,
384
- schedulesInMelCloud,
385
- s => s.id,
386
- s => s.Id
387
- );
388
-
389
- removedSchedules.forEach(s =>
390
- newSchedules.push({ ...s, removed: true })
391
- );
392
-
393
- const scheduleIds = new Set(
394
- deviceInConfig.schedules.map(s => String(s.id))
395
- );
396
-
397
- schedulesInMelCloud.forEach((schedule, index) => {
398
- const scheduleId = String(schedule.Id);
399
- if (!scheduleIds.has(scheduleId)) {
400
- const scheduleObj = {
401
- id: scheduleId,
402
- displayType: 0,
403
- name: `Schedule ${index}`,
404
- namePrefix: false
405
- };
406
- deviceInConfig.schedules.push(scheduleObj);
407
- newSchedules.push(scheduleObj);
408
- }
409
- });
410
- }
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
+ });
411
351
  });
412
352
 
413
353
  return devicesInConfig;
414
354
  };
415
355
 
416
356
  // Execute device handlers
417
- account.ataDevices = handleDevices(
418
- devicesInMelCloudByType.ata,
419
- account.ataDevices,
420
- "Air Conditioner",
421
- newInMelCloud.ata,
422
- newInMelCloud.ataPresets,
423
- newInMelCloud.ataSchedules
424
- );
425
-
426
- account.atwDevices = handleDevices(
427
- devicesInMelCloudByType.atw,
428
- account.atwDevices,
429
- "Heat Pump",
430
- newInMelCloud.atw,
431
- newInMelCloud.atwPresets,
432
- newInMelCloud.atwSchedules
433
- );
434
-
435
- account.ervDevices = handleDevices(
436
- devicesInMelCloudByType.erv,
437
- account.ervDevices,
438
- "Energy Recovery Ventilation",
439
- newInMelCloud.erv,
440
- newInMelCloud.ervPresets,
441
- newInMelCloud.ervSchedules
442
- );
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);
443
360
 
444
361
  // Summary
445
- const newDevicesCount =
446
- newInMelCloud.ata.length +
447
- newInMelCloud.atw.length +
448
- newInMelCloud.erv.length;
449
-
450
- const newPresetsCount =
451
- newInMelCloud.ataPresets.length +
452
- newInMelCloud.atwPresets.length +
453
- newInMelCloud.ervPresets.length;
454
-
455
- const newSchedulesCount =
456
- newInMelCloud.ataSchedules.length +
457
- newInMelCloud.atwSchedules.length +
458
- newInMelCloud.ervSchedules.length;
459
-
460
- const removedDevicesCount =
461
- removedAta.length +
462
- removedAtw.length +
463
- removedErv.length;
464
-
465
- if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !removedDevicesCount) {
362
+ const newDevicesCount = newInMelCloud.ata.length + newInMelCloud.atw.length + newInMelCloud.erv.length;
363
+ const newPresetsCount = newInMelCloud.ataPresets.length + newInMelCloud.atwPresets.length + newInMelCloud.ervPresets.length;
364
+ const newSchedulesCount = newInMelCloud.ataSchedules.length + newInMelCloud.atwSchedules.length + newInMelCloud.ervSchedules.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
370
+
371
+ if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !newScenesCount && !removedDevicesCount && !removedPresetsCount && !removedSchedulesCount && !removedScenesCount) {
466
372
  updateInfo('info', 'No changes detected.', 'white');
467
373
  } else {
468
374
  if (newDevicesCount)
469
- 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');
470
376
  if (newPresetsCount)
471
- updateInfo('info1', `Found new presets: ${newPresetsCount}`, 'green');
472
- if (newSchedulesCount)
473
- 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');
474
380
  if (removedDevicesCount)
475
- 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');
476
386
  }
477
387
 
478
388
  await homebridge.updatePluginConfig(pluginConfig);
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.34",
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",