homebridge-melcloud-control 4.6.5 → 4.6.6

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.
package/CHANGELOG.md CHANGED
@@ -24,6 +24,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
24
24
  - For plugin < v4.6.0 use Homebridge UI <= v5.5.0
25
25
  - For plugin >= v4.6.0 use Homebridge UI >= v5.13.0
26
26
 
27
+ # [4.6.6] - (23.01.2026)
28
+
29
+ ## Changes
30
+
31
+ - fix devices array initialization from UI on first run, fix [#231](https://github.com/grzegorz914/homebridge-melcloud-control/issues/231)
32
+ - config schema updated
33
+ - bump dependencies
34
+ - cleanup
35
+
27
36
  # [4.6.4] - (10.01.2026)
28
37
 
29
38
  ## Changes
@@ -10,6 +10,11 @@
10
10
  "schema": {
11
11
  "type": "object",
12
12
  "properties": {
13
+ "name": {
14
+ "title": "Platform",
15
+ "type": "string",
16
+ "default": "MELCloud Control"
17
+ },
13
18
  "accounts": {
14
19
  "type": "array",
15
20
  "title": "Accounts",
@@ -236,6 +236,15 @@
236
236
  return map;
237
237
  }
238
238
 
239
+ // Helper to generate summary string
240
+ function summarizeChanges(type, ata, atw, erv) {
241
+ const parts = [];
242
+ if (ata.length) parts.push(`ATA: ${ata.length}`);
243
+ if (atw.length) parts.push(`ATW: ${atw.length}`);
244
+ if (erv.length) parts.push(`ERV: ${erv.length}`);
245
+ return parts.length ? `${type}: ${parts.join(', ')}` : '';
246
+ }
247
+
239
248
  // Login & Sync Logic
240
249
  document.getElementById('logIn').addEventListener('click', async () => {
241
250
  document.getElementById('logIn').className = "btn btn-primary";
@@ -257,8 +266,17 @@
257
266
  return;
258
267
  }
259
268
 
269
+ // Ensure device arrays exist before handling
270
+ account.ataDevices = account.ataDevices ?? [];
271
+ account.atwDevices = account.atwDevices ?? [];
272
+ account.ervDevices = account.ervDevices ?? [];
273
+
260
274
  // Prepare MELCloud data
261
- const newInMelCloud = { ata: [], ataPresets: [], ataSchedules: [], ataScenes: [], atw: [], atwPresets: [], atwSchedules: [], atwScenes: [], erv: [], ervPresets: [], ervSchedules: [], ervScenes: [] };
275
+ const newInMelCloud = {
276
+ ata: [], ataPresets: [], ataSchedules: [], ataScenes: [],
277
+ atw: [], atwPresets: [], atwSchedules: [], atwScenes: [],
278
+ erv: [], ervPresets: [], ervSchedules: [], ervScenes: []
279
+ };
262
280
  const devicesInMelCloudByType = { ata: [], atw: [], erv: [] };
263
281
  const scenesInMelCloud = response.Scenes ?? [];
264
282
 
@@ -279,7 +297,7 @@
279
297
  // Map UnitId → Scenes
280
298
  const unitIdToScenes = mapUnitIdToScenes(scenesInMelCloud);
281
299
 
282
- // Generic device handler (obsługuje urządzenia, presety, harmonogramy i sceny)
300
+ // Generic device handler (handles devices, presets, schedules, and scenes)
283
301
  const handleDevices = (devicesInMelCloud, devicesInConfig, newDevices, newPresets, newSchedules, newScenes) => {
284
302
  const configDevicesMap = new Map(devicesInConfig.map(dev => [String(dev.id), dev]));
285
303
 
@@ -362,10 +380,33 @@
362
380
  return devicesInConfig;
363
381
  };
364
382
 
365
- // Execute device handlers
366
- account.ataDevices = handleDevices(devicesInMelCloudByType.ata, account.ataDevices, newInMelCloud.ata, newInMelCloud.ataPresets, newInMelCloud.ataSchedules, newInMelCloud.ataScenes);
367
- account.atwDevices = handleDevices(devicesInMelCloudByType.atw, account.atwDevices, newInMelCloud.atw, newInMelCloud.atwPresets, newInMelCloud.atwSchedules, newInMelCloud.atwScenes);
368
- account.ervDevices = handleDevices(devicesInMelCloudByType.erv, account.ervDevices, newInMelCloud.erv, newInMelCloud.ervPresets, newInMelCloud.ervSchedules, newInMelCloud.ervScenes);
383
+ // Execute device handlers with safe initialization
384
+ account.ataDevices = handleDevices(
385
+ devicesInMelCloudByType.ata,
386
+ account.ataDevices,
387
+ newInMelCloud.ata,
388
+ newInMelCloud.ataPresets,
389
+ newInMelCloud.ataSchedules,
390
+ newInMelCloud.ataScenes
391
+ );
392
+
393
+ account.atwDevices = handleDevices(
394
+ devicesInMelCloudByType.atw,
395
+ account.atwDevices,
396
+ newInMelCloud.atw,
397
+ newInMelCloud.atwPresets,
398
+ newInMelCloud.atwSchedules,
399
+ newInMelCloud.atwScenes
400
+ );
401
+
402
+ account.ervDevices = handleDevices(
403
+ devicesInMelCloudByType.erv,
404
+ account.ervDevices,
405
+ newInMelCloud.erv,
406
+ newInMelCloud.ervPresets,
407
+ newInMelCloud.ervSchedules,
408
+ newInMelCloud.ervScenes
409
+ );
369
410
 
370
411
  // Summary counts
371
412
  const newDevicesCount = newInMelCloud.ata.length + newInMelCloud.atw.length + newInMelCloud.erv.length;
@@ -376,19 +417,27 @@
376
417
  const removedPresetsCount = removedFromConfig.presets.length;
377
418
  const removedSchedulesCount = removedFromConfig.schedules.length;
378
419
  const removedScenesCount = removedFromConfig.scenes.length;
379
-
380
- if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !newScenesCount && !removedDevicesCount && !removedPresetsCount && !removedSchedulesCount && !removedScenesCount) {
381
- updateInfo('info', 'No changes detected.', fontColor);
382
- }
383
- if (newDevicesCount || newPresetsCount || newSchedulesCount || newScenesCount) {
384
- updateInfo('info', `Found new ${newDevicesCount ? `devices:` : ''} ${newInMelCloud.ata.length ? `ATA: ${newInMelCloud.ata.length},` : ''} ${newInMelCloud.atw.length ? `ATW: ${newInMelCloud.atw.length},` : ''} ${newInMelCloud.erv.length ? `ERV: ${newInMelCloud.erv.length},` : ''} ${newPresetsCount ? `presets:` : ''} ${newInMelCloud.ataPresets.length ? `ATA: ${newInMelCloud.ataPresets.length},` : ''} ${newInMelCloud.atwPresets.length ? `ATW: ${newInMelCloud.atwPresets.length}, ` : ''} ${newInMelCloud.ervPresets.length ? `ERV: ${newInMelCloud.ervPresets.length},` : ''} ${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:` : ''} ${newInMelCloud.ataScenes.length ? `ATA: ${newInMelCloud.ataScenes.length},` : ''} ${newInMelCloud.atwScenes.length ? `ATW: ${newInMelCloud.atwScenes.length},` : ''} ${newInMelCloud.ervScenes.length ? `ERV: ${newInMelCloud.ervScenes.length}` : ''}.`, 'green');
385
- }
386
- if (removedDevicesCount || removedPresetsCount || removedSchedulesCount || removedScenesCount) {
387
- updateInfo('info1', `Removed old ${removedDevicesCount ? `devices:` : ''} ${removedFromConfig.ata.length ? `ATA: ${removedFromConfig.ata.length},` : ''} ${removedFromConfig.atw.length ? `ATW: ${removedFromConfig.atw.length},` : ''} ${removedFromConfig.erv.length ? `ERV: ${removedFromConfig.erv.length},` : ''} ${removedPresetsCount ? `presets: ${removedPresetsCount},` : ''} ${removedSchedulesCount ? `schedules: ${removedSchedulesCount},` : ''} ${removedScenesCount ? `scenes: ${removedScenesCount}` : ''}.`, 'orange');
388
- }
420
+ if (!newDevicesCount && !newPresetsCount && !newSchedulesCount && !newScenesCount && !removedDevicesCount && !removedPresetsCount && !removedSchedulesCount && !removedScenesCount) updateInfo('info', 'No changes detected.', fontColor);
421
+
422
+ // New items
423
+ const newParts = [];
424
+ if (newDevicesCount) newParts.push(summarizeChanges('Devices', newInMelCloud.ata, newInMelCloud.atw, newInMelCloud.erv));
425
+ if (account.type === 'melcloud' && newPresetsCount) newParts.push(summarizeChanges('Presets', newInMelCloud.ataPresets, newInMelCloud.atwPresets, newInMelCloud.ervPresets));
426
+ if (account.type === 'melcloudhome' && newSchedulesCount) newParts.push(summarizeChanges('Schedules', newInMelCloud.ataSchedules, newInMelCloud.atwSchedules, newInMelCloud.ervSchedules));
427
+ if (account.type === 'melcloudhome' && newScenesCount) newParts.push(summarizeChanges('Scenes', newInMelCloud.ataScenes, newInMelCloud.atwScenes, newInMelCloud.ervScenes));
428
+ if (newParts.length) updateInfo('info', `Found new: ${newParts.join('; ')}`, 'green');
429
+
430
+ // Removed items
431
+ const removedParts = [];
432
+ if (removedDevicesCount) removedParts.push(summarizeChanges('Devices', removedFromConfig.ata, removedFromConfig.atw, removedFromConfig.erv));
433
+ if (removedPresetsCount) removedParts.push(`Presets: ${removedPresetsCount}`);
434
+ if (removedSchedulesCount) removedParts.push(`Schedules: ${removedSchedulesCount}`);
435
+ if (removedScenesCount) removedParts.push(`Scenes: ${removedScenesCount}`);
436
+ if (removedParts.length) updateInfo('info1', `Removed old: ${removedParts.join('; ')}`, 'orange');
389
437
 
390
438
  await homebridge.updatePluginConfig(pluginConfig);
391
439
  await homebridge.savePluginConfig();
440
+
392
441
  } catch (error) {
393
442
  updateInfo('info', `Prepare config error`, "red");
394
443
  updateInfo('info1', `Error: ${JSON.stringify(error)}`, "red");
@@ -397,6 +446,5 @@
397
446
  homebridge.hideSpinner();
398
447
  }
399
448
  });
400
-
401
449
  })();
402
450
  </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.6.5",
4
+ "version": "4.6.6",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -39,7 +39,7 @@
39
39
  "mqtt": "^5.14.1",
40
40
  "axios": "^1.13.2",
41
41
  "express": "^5.2.1",
42
- "puppeteer": "^24.34.0",
42
+ "puppeteer": "^24.36.0",
43
43
  "ws": "^8.19.0"
44
44
  },
45
45
  "keywords": [