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.
- package/homebridge-ui/public/index.html +95 -185
- package/package.json +1 -1
|
@@ -205,17 +205,17 @@
|
|
|
205
205
|
});
|
|
206
206
|
|
|
207
207
|
// Generic remove function
|
|
208
|
-
function removeStaleEntities(
|
|
209
|
-
const serverIds = new Set(
|
|
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 =
|
|
213
|
-
const entity =
|
|
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
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
|
|
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
|
-
|
|
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
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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
|
-
|
|
419
|
-
|
|
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
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
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: ${
|
|
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: ${
|
|
472
|
-
if (newSchedulesCount)
|
|
473
|
-
updateInfo('info1', `Found new schedules: ${
|
|
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('
|
|
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.
|
|
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",
|