homebridge-melcloud-control 4.1.2-beta.77 → 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,101 +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
+
242
+ toggleLoginButton(true);
243
+ updateInfo('info', ''); updateInfo('info1', ''); updateInfo('info2', '');
241
244
 
242
245
  try {
243
- const account = this.account;
246
+ const account = structuredClone(this.account);
244
247
  const response = await homebridge.request('/connect', account);
245
- if (!response.State) {
246
- homebridge.hideSpinner();
247
- updateInfo('info', response.Info);
248
+
249
+ if (!response?.State) {
250
+ updateInfo('info', response?.Info || 'Login failed.', 'red');
248
251
  return;
249
252
  }
250
253
 
251
- // Initialize devices arrays
252
- const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [] };
254
+ // Group devices
255
+ const DEVICE_TYPES = { ATA: 0, ATW: 1, ERV: 3 };
253
256
  const melcloudDevices = { ata: [], atw: [], erv: [] };
257
+ const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [] };
254
258
 
255
- response.Devices.forEach(d => {
256
- if (d.Type === 0) melcloudDevices.ata.push(d);
257
- if (d.Type === 1) melcloudDevices.atw.push(d);
258
- 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
+ }
259
265
  });
260
266
 
267
+ // Filter invalid devices
261
268
  account.ataDevices = (account.ataDevices || []).filter(d => String(d.id) !== '0');
262
269
  account.atwDevices = (account.atwDevices || []).filter(d => String(d.id) !== '0');
263
270
  account.ervDevices = (account.ervDevices || []).filter(d => String(d.id) !== '0');
264
271
 
272
+ // Remove stale devices
265
273
  const removedAta = removeStaleDevices(account.ataDevices, melcloudDevices.ata);
266
274
  const removedAtw = removeStaleDevices(account.atwDevices, melcloudDevices.atw);
267
275
  const removedErv = removeStaleDevices(account.ervDevices, melcloudDevices.erv);
268
276
  await homebridge.updatePluginConfig(pluginConfig);
269
277
 
270
- const handleDevices = (devicesInMelCloud, devicesInConfig, typeString, newArr, newPresets) => {
271
- try {
272
- const configDevicesMap = new Map(devicesInConfig.map(dev => [dev.id, dev]));
273
- const isMelcloud = account.type === 'melcloud';
274
-
275
- const idKey = isMelcloud ? 'ID' : 'Id';
276
- const typeKey = isMelcloud ? 'Presets' : 'Schedule';
277
- const typeKey1 = isMelcloud ? 'presets' : 'schedules';
278
-
279
- devicesInMelCloud.forEach(device => {
280
- let deviceInConfig = configDevicesMap.get(device.DeviceID);
281
-
282
- // === Create device if missing ===
283
- if (!deviceInConfig) {
284
- deviceInConfig = {
285
- id: device.DeviceID,
286
- type: device.Type,
287
- typeString,
288
- displayType: 0,
289
- name: device.DeviceName,
290
- presets: [],
291
- schedules: [],
292
- buttonsSensors: []
293
- };
294
- devicesInConfig.push(deviceInConfig);
295
- newArr.push(deviceInConfig);
296
- configDevicesMap.set(device.DeviceID, deviceInConfig);
297
- }
298
-
299
- // === Process presets/schedules ===
300
- const presetsInMelcloud = device[typeKey] || [];
301
- const presetsInConfig = (deviceInConfig[typeKey1] || []).filter(p => String(p.id) !== '0');
302
- const presetIds = new Set(presetsInConfig.map(p => String(p.id)));
303
-
304
- presetsInMelcloud.forEach((preset, index) => {
305
- const presetId = String(preset[idKey]);
306
- if (!presetIds.has(presetId)) {
307
- const presetObj = {
308
- id: presetId,
309
- displayType: 0,
310
- name: preset.NumberDescription || `Schedule ${index}`,
311
- namePrefix: false
312
- };
313
- presetsInConfig.push(presetObj);
314
- newPresets.push(presetObj);
315
- presetIds.add(presetId);
316
- }
317
- });
318
- });
319
-
320
- // Return filtered devicesInConfig to make sure upstream code uses it
321
- return devicesInConfig;
322
- } catch (error) {
323
- updateInfo('info', `Error while processing device: ${JSON.stringify(error)}`, 'red');
324
- }
325
- };
326
-
327
- account.ataDevices = handleDevices(melcloudDevices.ata, account.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
328
- account.atwDevices = handleDevices(melcloudDevices.atw, account.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
329
- 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);
330
282
 
283
+ // Summaries
331
284
  const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length;
332
285
  const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length;
333
286
  const removedDevicesCount = removedAta.length + removedAtw.length + removedErv.length;
@@ -335,25 +288,21 @@
335
288
  if (!newDevicesCount && !newPresetsCount && !removedDevicesCount) {
336
289
  updateInfo('info', 'No changes detected.', 'white');
337
290
  } else {
338
- if (newDevicesCount)
339
- updateInfo('info', `Found new devices: ATA: ${newDevices.ata.length}, ATW: ${newDevices.atw.length}, ERV: ${newDevices.erv.length}.`, 'green');
340
- if (newPresetsCount)
341
- updateInfo('info1', `Found new ${account.type === 'melcloud' ? 'presets' : 'schedules'}: ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}.`, 'green');
342
- if (removedDevicesCount)
343
- 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');
344
294
  }
345
295
 
346
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.77",
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",