homebridge-melcloud-control 4.4.1-beta.40 → 4.4.1-beta.41

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.
@@ -204,9 +204,10 @@
204
204
  }
205
205
  });
206
206
 
207
+ // Generic remove function
207
208
  // Generic remove function
208
209
  function removeStaleEntities(configEntities, MelcloudEntities, getConfigId, getMelcloudId) {
209
- const serverIds = new Set(MelcloudEntities.map(item => String(getMelcloudId(item))));
210
+ const serverIds = new Set((MelcloudEntities ?? []).map(item => String(getMelcloudId(item))));
210
211
  const removedEntities = [];
211
212
 
212
213
  for (let i = configEntities.length - 1; i >= 0; i--) {
@@ -222,6 +223,7 @@
222
223
  return removedEntities;
223
224
  }
224
225
 
226
+ // Update info on page
225
227
  function updateInfo(id, text, color) {
226
228
  const el = document.getElementById(id);
227
229
  if (el) {
@@ -230,6 +232,22 @@
230
232
  }
231
233
  }
232
234
 
235
+ // Map UnitId → Scenes for quick lookup
236
+ function mapUnitIdToScenes(scenesInMelCloud) {
237
+ const map = new Map();
238
+
239
+ (scenesInMelCloud ?? []).forEach(scene => {
240
+ const allSceneSettings = [...(scene.AtaSceneSettings ?? []), ...(scene.AtwSceneSettings ?? []), ...(scene.ErvSceneSettings ?? [])];
241
+ allSceneSettings.forEach(setting => {
242
+ const unitId = String(setting.UnitId);
243
+ if (!map.has(unitId)) map.set(unitId, []);
244
+ map.get(unitId).push(scene);
245
+ });
246
+ });
247
+
248
+ return map;
249
+ }
250
+
233
251
  // Login & Sync Logic
234
252
  document.getElementById('logIn').addEventListener('click', async () => {
235
253
  homebridge.showSpinner();
@@ -253,12 +271,14 @@
253
271
  const devicesInMelCloudByType = { ata: [], atw: [], erv: [] };
254
272
  const scenesInMelCloud = response.Scenes ?? [];
255
273
 
256
- response.Devices.forEach(device => {
274
+ // Split devices by type
275
+ (response.Devices ?? []).forEach(device => {
257
276
  if (device.Type === 0) devicesInMelCloudByType.ata.push(device);
258
277
  if (device.Type === 1) devicesInMelCloudByType.atw.push(device);
259
278
  if (device.Type === 3) devicesInMelCloudByType.erv.push(device);
260
279
  });
261
280
 
281
+ // Clean up local config
262
282
  account.ataDevices = (account.ataDevices ?? []).filter(d => String(d.id) !== '0');
263
283
  account.atwDevices = (account.atwDevices ?? []).filter(d => String(d.id) !== '0');
264
284
  account.ervDevices = (account.ervDevices ?? []).filter(d => String(d.id) !== '0');
@@ -266,34 +286,31 @@
266
286
  const removedFromConfigAta = removeStaleEntities(account.ataDevices, devicesInMelCloudByType.ata, d => d.id, d => d.DeviceID);
267
287
  const removedFromConfigAtw = removeStaleEntities(account.atwDevices, devicesInMelCloudByType.atw, d => d.id, d => d.DeviceID);
268
288
  const removedFromConfigErv = removeStaleEntities(account.ervDevices, devicesInMelCloudByType.erv, d => d.id, d => d.DeviceID);
289
+
269
290
  const removedFromConfig = { ataPresets: [], atwPresets: [], ervPresets: [], ataSchedules: [], atwSchedules: [], ervSchedules: [], scenes: [] };
270
291
 
292
+ // Map UnitId → Scenes
293
+ const unitIdToScenes = mapUnitIdToScenes(scenesInMelCloud);
271
294
 
272
- // Handle Devices
295
+ // Generic device handler (obsługuje urządzenia, presety, harmonogramy i sceny)
273
296
  const handleDevices = (devicesInMelCloud, devicesInConfig, deviceTypeString, newDevices, newPresets, newSchedules, newScenes) => {
274
297
  const configDevicesMap = new Map(devicesInConfig.map(dev => [String(dev.id), dev]));
275
298
 
276
- devicesInMelCloud.forEach(device => {
277
- const deviceId = String(device.DeviceID); // Make sure this matches MelCloud data
299
+ (devicesInMelCloud ?? []).forEach(device => {
300
+ const deviceId = String(device.DeviceID);
278
301
  let deviceInConfig = configDevicesMap.get(deviceId);
279
302
 
280
303
  if (!deviceInConfig) {
281
- deviceInConfig = {
282
- id: deviceId,
283
- type: device.Type,
284
- deviceTypeString,
285
- displayType: 0,
286
- name: device.DeviceName,
287
- };
304
+ deviceInConfig = { id: deviceId, type: device.Type, deviceTypeString, displayType: 0, name: device.DeviceName };
288
305
  devicesInConfig.push(deviceInConfig);
289
306
  newDevices.push(deviceInConfig);
290
307
  configDevicesMap.set(deviceId, deviceInConfig);
291
308
  }
292
309
 
293
- //ONLY MELCLOUD - PRESETS
310
+ // PRESETS (melcloud)
294
311
  if (account.type === 'melcloud') {
295
312
  deviceInConfig.presets = deviceInConfig.presets ?? [];
296
- const presetsInMelCloud = device.Presets || [];
313
+ const presetsInMelCloud = device.Presets ?? [];
297
314
  removedFromConfig.ataPresets.push(...removeStaleEntities(deviceInConfig.presets, presetsInMelCloud, p => p.id, p => p.ID));
298
315
  const presetIds = new Set(deviceInConfig.presets.map(p => String(p.id)));
299
316
  presetsInMelCloud.forEach((preset, index) => {
@@ -311,11 +328,11 @@
311
328
  });
312
329
  }
313
330
 
314
- //ONLY MELCLOUD HOME - SCHEDULES & SCENES
331
+ // SCHEDULES & SCENES (melcloudhome)
315
332
  if (account.type === 'melcloudhome') {
316
333
  // SCHEDULES
317
334
  deviceInConfig.schedules = deviceInConfig.schedules ?? [];
318
- const schedulesInMelCloud = device.Schedule || [];
335
+ const schedulesInMelCloud = device.Schedule ?? [];
319
336
  removedFromConfig.ataSchedules.push(...removeStaleEntities(deviceInConfig.schedules, schedulesInMelCloud, s => s.id, s => s.Id));
320
337
  const scheduleIds = new Set(deviceInConfig.schedules.map(s => String(s.id)));
321
338
  schedulesInMelCloud.forEach((schedule, index) => {
@@ -334,17 +351,13 @@
334
351
 
335
352
  // SCENES
336
353
  deviceInConfig.scenes = deviceInConfig.scenes ?? [];
337
-
338
- // Usuwanie nieaktualnych scen
339
354
  removedFromConfig.scenes.push(...removeStaleEntities(deviceInConfig.scenes, scenesInMelCloud, s => s.id, s => s.Id));
340
355
  const sceneIds = new Set(deviceInConfig.scenes.map(s => String(s.id)));
341
- scenesInMelCloud.forEach((scene, index) => {
342
- const sceneId = String(scene.Id);
356
+ const scenesForDevice = unitIdToScenes.get(deviceId) ?? [];
343
357
 
344
- // Sprawdzamy, czy scena dotyczy danego urządzenia w AtaSceneSettings lub AtwSceneSettings
345
- const appliesToDevice = (scene.AtaSceneSettings ?? []).some(s => s.UnitId === deviceInConfig.id) || (scene.AtwSceneSettings ?? []).some(s => s.UnitId === deviceInConfig.id) || (scene.ErvSceneSettings ?? []).some(s => s.UnitId === deviceInConfig.id);
346
-
347
- if (appliesToDevice && !sceneIds.has(sceneId)) {
358
+ scenesForDevice.forEach((scene, index) => {
359
+ const sceneId = String(scene.Id);
360
+ if (!sceneIds.has(sceneId)) {
348
361
  const sceneObj = {
349
362
  id: sceneId,
350
363
  displayType: 0,
@@ -355,8 +368,6 @@
355
368
  newScenes.push(sceneObj);
356
369
  }
357
370
  });
358
-
359
-
360
371
  }
361
372
  });
362
373
 
@@ -368,7 +379,7 @@
368
379
  account.atwDevices = handleDevices(devicesInMelCloudByType.atw, account.atwDevices, "Heat Pump", newInMelCloud.atw, newInMelCloud.atwPresets, newInMelCloud.atwSchedules, newInMelCloud.scenes);
369
380
  account.ervDevices = handleDevices(devicesInMelCloudByType.erv, account.ervDevices, "Energy Recovery Ventilation", newInMelCloud.erv, newInMelCloud.ervPresets, newInMelCloud.ervSchedules, newInMelCloud.scenes);
370
381
 
371
- // Summary
382
+ // Summary counts
372
383
  const newDevicesCount = newInMelCloud.ata.length + newInMelCloud.atw.length + newInMelCloud.erv.length;
373
384
  const newPresetsCount = newInMelCloud.ataPresets.length + newInMelCloud.atwPresets.length + newInMelCloud.ervPresets.length;
374
385
  const newSchedulesCount = newInMelCloud.ataSchedules.length + newInMelCloud.atwSchedules.length + newInMelCloud.ervSchedules.length;
@@ -376,7 +387,7 @@
376
387
  const removedDevicesCount = removedFromConfigAta.length + removedFromConfigAtw.length + removedFromConfigErv.length;
377
388
  const removedPresetsCount = removedFromConfig.ataPresets.length + removedFromConfig.atwPresets.length + removedFromConfig.ervPresets.length;
378
389
  const removedSchedulesCount = removedFromConfig.ataSchedules.length + removedFromConfig.atwSchedules.length + removedFromConfig.ervSchedules.length;
379
- const removedScenesCount = removedFromConfig.scenes.length
390
+ const removedScenesCount = removedFromConfig.scenes.length;
380
391
 
381
392
  if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !newScenesCount && !removedDevicesCount && !removedPresetsCount && !removedSchedulesCount && !removedScenesCount) {
382
393
  updateInfo('info', 'No changes detected.', 'white');
@@ -390,9 +401,9 @@
390
401
  if (removedDevicesCount)
391
402
  updateInfo('info', `Removed devices: ${removedFromConfigAta.length ? `ATA: ${removedFromConfigAta.length},` : ''} ${removedFromConfigAtw.length ? `ATW: ${removedFromConfigAtw.length},` : ''} ${removedFromConfigErv.length ? `ERV: ${removedFromConfigErv.length}` : ''}.`, 'orange');
392
403
  if (removedPresetsCount)
393
- 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');
404
+ updateInfo('info1', `Removed presets: ${removedFromConfig.ataPresets.length ? `ATA: ${removedFromConfig.ataPresets.length},` : ''} ${removedFromConfig.atwPresets.length ? `ATW: ${removedFromConfig.atwPresets.length},` : ''} ${removedFromConfig.ervPresets.length ? `ERV: ${removedFromConfig.ervPresets.length}` : ''}.`, 'orange');
394
405
  if (removedSchedulesCount || removedScenesCount)
395
- 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');
406
+ updateInfo('info1', `Removed ${removedScenesCount ? `scenes:` : ''} ${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');
396
407
  }
397
408
 
398
409
  await homebridge.updatePluginConfig(pluginConfig);
@@ -407,5 +418,6 @@
407
418
  });
408
419
 
409
420
 
421
+
410
422
  })();
411
423
  </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.40",
4
+ "version": "4.4.1-beta.41",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",