homebridge-melcloud-control 4.1.2-beta.78 → 4.1.2-beta.79

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.
@@ -233,102 +233,54 @@
233
233
  }
234
234
 
235
235
  document.getElementById('logIn').addEventListener('click', async () => {
236
- document.getElementById(`logIn`).className = "btn btn-primary";
237
- updateInfo('info', '', 'white');
238
- updateInfo('info1', '', 'white');
239
- updateInfo('info2', '', 'white');
240
- homebridge.showSpinner();
236
+ const toggleLoginButton = (loading) => {
237
+ const btn = document.getElementById('logIn');
238
+ btn.className = loading ? "btn btn-primary" : "btn btn-secondary";
239
+ loading ? homebridge.showSpinner() : homebridge.hideSpinner();
240
+ };
241
241
 
242
- try {
243
- await homebridge.updatePluginConfig(pluginConfig);
242
+ toggleLoginButton(true);
243
+ updateInfo('info', ''); updateInfo('info1', ''); updateInfo('info2', '');
244
244
 
245
- const account = this.account;
245
+ try {
246
+ const account = structuredClone(this.account);
246
247
  const response = await homebridge.request('/connect', account);
247
- if (!response.State) {
248
- homebridge.hideSpinner();
249
- updateInfo('info', response.Info);
248
+
249
+ if (!response?.State) {
250
+ updateInfo('info', response?.Info || 'Login failed.', 'red');
250
251
  return;
251
252
  }
252
253
 
253
- // Initialize devices arrays
254
- const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [] };
254
+ // Group devices
255
+ const DEVICE_TYPES = { ATA: 0, ATW: 1, ERV: 3 };
255
256
  const melcloudDevices = { ata: [], atw: [], erv: [] };
257
+ const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [] };
256
258
 
257
- response.Devices.forEach(d => {
258
- if (d.Type === 0) melcloudDevices.ata.push(d);
259
- if (d.Type === 1) melcloudDevices.atw.push(d);
260
- if (d.Type === 3) melcloudDevices.erv.push(d);
259
+ (response.Devices || []).forEach(d => {
260
+ switch (d.Type) {
261
+ case DEVICE_TYPES.ATA: melcloudDevices.ata.push(d); break;
262
+ case DEVICE_TYPES.ATW: melcloudDevices.atw.push(d); break;
263
+ case DEVICE_TYPES.ERV: melcloudDevices.erv.push(d); break;
264
+ }
261
265
  });
262
266
 
267
+ // Filter invalid devices
263
268
  account.ataDevices = (account.ataDevices || []).filter(d => String(d.id) !== '0');
264
269
  account.atwDevices = (account.atwDevices || []).filter(d => String(d.id) !== '0');
265
270
  account.ervDevices = (account.ervDevices || []).filter(d => String(d.id) !== '0');
266
271
 
272
+ // Remove stale devices
267
273
  const removedAta = removeStaleDevices(account.ataDevices, melcloudDevices.ata);
268
274
  const removedAtw = removeStaleDevices(account.atwDevices, melcloudDevices.atw);
269
275
  const removedErv = removeStaleDevices(account.ervDevices, melcloudDevices.erv);
276
+ await homebridge.updatePluginConfig(pluginConfig);
270
277
 
271
- const handleDevices = (devicesInMelCloud, devicesInConfig, typeString, newArr, newPresets) => {
272
- try {
273
- const configDevicesMap = new Map(devicesInConfig.map(dev => [dev.id, dev]));
274
- const isMelcloud = account.type === 'melcloud';
275
-
276
- const idKey = isMelcloud ? 'ID' : 'Id';
277
- const typeKey = isMelcloud ? 'Presets' : 'Schedule';
278
- const typeKey1 = isMelcloud ? 'presets' : 'schedules';
279
-
280
- devicesInMelCloud.forEach(device => {
281
- let deviceInConfig = configDevicesMap.get(device.DeviceID);
282
-
283
- // === Create device if missing ===
284
- if (!deviceInConfig) {
285
- deviceInConfig = {
286
- id: device.DeviceID,
287
- type: device.Type,
288
- typeString,
289
- displayType: 0,
290
- name: device.DeviceName,
291
- presets: [],
292
- schedules: [],
293
- buttonsSensors: []
294
- };
295
- devicesInConfig.push(deviceInConfig);
296
- newArr.push(deviceInConfig);
297
- configDevicesMap.set(device.DeviceID, deviceInConfig);
298
- }
299
-
300
- // === Process presets/schedules ===
301
- const presetsInMelcloud = device[typeKey] || [];
302
- const presetsInConfig = (deviceInConfig[typeKey1] || []).filter(p => String(p.id) !== '0');
303
- const presetIds = new Set(presetsInConfig.map(p => String(p.id)));
304
-
305
- presetsInMelcloud.forEach((preset, index) => {
306
- const presetId = String(preset[idKey]);
307
- if (!presetIds.has(presetId)) {
308
- const presetObj = {
309
- id: presetId,
310
- displayType: 0,
311
- name: preset.NumberDescription || `Schedule ${index}`,
312
- namePrefix: false
313
- };
314
- presetsInConfig.push(presetObj);
315
- newPresets.push(presetObj);
316
- presetIds.add(presetId);
317
- }
318
- });
319
- });
320
-
321
- // Return filtered devicesInConfig to make sure upstream code uses it
322
- return devicesInConfig;
323
- } catch (error) {
324
- updateInfo('info', `Error while processing device: ${JSON.stringify(error)}`, 'red');
325
- }
326
- };
327
-
328
- account.ataDevices = handleDevices(melcloudDevices.ata, account.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
329
- account.atwDevices = handleDevices(melcloudDevices.atw, account.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
330
- account.ervDevices = handleDevices(melcloudDevices.erv, account.ervDevices, "Energy Recovery Ventilation", newDevices.erv, newDevices.ervPresets);
278
+ // Sync devices
279
+ account.ataDevices = handleDevices(account, melcloudDevices.ata, account.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
280
+ account.atwDevices = handleDevices(account, melcloudDevices.atw, account.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
281
+ account.ervDevices = handleDevices(account, melcloudDevices.erv, account.ervDevices, "Energy Recovery Ventilation", newDevices.erv, newDevices.ervPresets);
331
282
 
283
+ // Summaries
332
284
  const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length;
333
285
  const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length;
334
286
  const removedDevicesCount = removedAta.length + removedAtw.length + removedErv.length;
@@ -336,24 +288,21 @@
336
288
  if (!newDevicesCount && !newPresetsCount && !removedDevicesCount) {
337
289
  updateInfo('info', 'No changes detected.', 'white');
338
290
  } else {
339
- if (newDevicesCount)
340
- updateInfo('info', `Found new devices: ATA: ${newDevices.ata.length}, ATW: ${newDevices.atw.length}, ERV: ${newDevices.erv.length}.`, 'green');
341
- if (newPresetsCount)
342
- updateInfo('info1', `Found new ${account.type === 'melcloud' ? 'presets' : 'schedules'}: ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}.`, 'green');
343
- if (removedDevicesCount)
344
- updateInfo('info2', `Removed devices: ATA: ${removedAta.length}, ATW: ${removedAtw.length}, ERV: ${removedErv.length}.`, 'orange');
291
+ if (newDevicesCount) updateInfo('info', `New devices — ATA: ${newDevices.ata.length}, ATW: ${newDevices.atw.length}, ERV: ${newDevices.erv.length}`, 'green');
292
+ if (newPresetsCount) updateInfo('info1', `New ${account.type === 'melcloud' ? 'presets' : 'schedules'} — ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}`, 'green');
293
+ if (removedDevicesCount) updateInfo('info2', `Removed devices — ATA: ${removedAta.length}, ATW: ${removedAtw.length}, ERV: ${removedErv.length}`, 'orange');
345
294
  }
346
295
 
296
+ await homebridge.updatePluginConfig(pluginConfig);
347
297
  await homebridge.savePluginConfig(pluginConfig);
348
298
  } catch (error) {
349
- updateInfo('info', `Connect error ${JSON.stringify(error)}`, 'red');
350
- document.getElementById('logIn').className = "btn btn-secondary";
299
+ updateInfo('info', `Error connecting to MelCloud: ${error.message}`, 'red');
351
300
  } finally {
352
- document.getElementById('logIn').className = "btn btn-secondary";
353
- homebridge.hideSpinner();
301
+ toggleLoginButton(false);
354
302
  }
355
303
  });
356
304
 
305
+
357
306
  })();
358
307
  </script>
359
308
  </body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.1.2-beta.78",
4
+ "version": "4.1.2-beta.79",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",