homebridge-melcloud-control 4.0.0-beta.86 → 4.0.0-beta.88

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.
@@ -97,15 +97,29 @@
97
97
  <script>
98
98
  (async () => {
99
99
  const pluginConfig = await homebridge.getPluginConfig();
100
+
101
+ // Ensure proper structure on load
100
102
  if (!pluginConfig.length) {
101
- pluginConfig.push({});
103
+ pluginConfig.push({ accounts: [] });
102
104
  await homebridge.updatePluginConfig(pluginConfig);
103
105
  homebridge.showSchemaForm();
104
106
  return;
105
107
  }
108
+ pluginConfig[0].accounts ??= [];
109
+
110
+ // Deep clone to prevent shared arrays
111
+ if (Array.isArray(pluginConfig?.[0]?.accounts)) {
112
+ pluginConfig[0].accounts = pluginConfig[0].accounts.map(acc => ({
113
+ ...acc,
114
+ ataDevices: Array.isArray(acc.ataDevices) ? [...acc.ataDevices] : [],
115
+ devices: Array.isArray(acc.devices) ? [...acc.devices] : [],
116
+ buildings: Array.isArray(acc.buildings) ? [...acc.buildings] : [],
117
+ }));
118
+ }
106
119
 
107
120
  this.accountIndex = 0;
108
121
  const accountsCount = pluginConfig[0].accounts.length;
122
+
109
123
  for (let i = 0; i < accountsCount; i++) {
110
124
  const acc = pluginConfig[0].accounts[i];
111
125
  const button = document.createElement("button");
@@ -131,20 +145,25 @@
131
145
  document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.language && acc.displayType);
132
146
  });
133
147
 
134
- if (i === accountsCount - 1) document.getElementById(`button0`).click();
148
+ if (i === accountsCount - 1 && accountsCount > 0)
149
+ document.getElementById(`button0`).click();
150
+
135
151
  this.accountIndex = i;
136
152
  }
137
153
 
138
154
  document.getElementById('melCloudAccount').style.display = 'block';
155
+
156
+ // Safe update
139
157
  document.getElementById('configForm').addEventListener('input', async () => {
140
158
  const acc = pluginConfig[0].accounts[this.accountIndex];
159
+ if (!acc) return;
141
160
  acc.name = document.querySelector('#name').value;
142
161
  acc.user = document.querySelector('#user').value;
143
162
  acc.passwd = document.querySelector('#passwd').value;
144
163
  acc.language = document.querySelector('#language').value;
145
164
  acc.displayType = document.querySelector('#displayType').value;
146
165
 
147
- document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.languaged && acc.displayType);
166
+ document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.language && acc.displayType);
148
167
 
149
168
  await homebridge.updatePluginConfig(pluginConfig);
150
169
  await homebridge.savePluginConfig(pluginConfig);
@@ -200,16 +219,6 @@
200
219
  document.getElementById(`logIn`).className = "btn btn-primary";
201
220
  updateInfo('info', 'Connecting...', 'yellow');
202
221
 
203
- // Ensure each account has independent device arrays (avoid shared references)
204
- if (Array.isArray(pluginConfig?.[0]?.accounts)) {
205
- pluginConfig[0].accounts = pluginConfig[0].accounts.map(acc => ({
206
- ...acc,
207
- ataDevices: Array.isArray(acc.ataDevices) ? structuredClone(acc.ataDevices) : [],
208
- atwDevices: Array.isArray(acc.atwDevices) ? structuredClone(acc.atwDevices) : [],
209
- ervDevices: Array.isArray(acc.ervDevices) ? structuredClone(acc.ervDevices) : []
210
- }));
211
- }
212
-
213
222
  try {
214
223
  const acc = pluginConfig[0].accounts[this.accountIndex];
215
224
  const payload = { accountName: acc.name, user: acc.user, passwd: acc.passwd, language: acc.language, displayType: acc.displayType };
@@ -233,13 +242,9 @@
233
242
  const removedAtw = removeStaleDevices(acc.atwDevices, devicesByType.atw);
234
243
  const removedErv = removeStaleDevices(acc.ervDevices, devicesByType.erv);
235
244
 
236
- // Function to handle device & presets
237
- // Function to handle devices & presets safely (deep cloning)
238
245
  const handleDevices = (devicesInCloud, devicesInConfig, typeString, newArr, newPresets) => {
239
246
  devicesInCloud.forEach(device => {
240
247
  const { DeviceID: id, Type: type, DeviceName: name, Presets: presets = [] } = device;
241
-
242
- // Create a cloned device object
243
248
  const devObj = structuredClone({
244
249
  id,
245
250
  type,
@@ -250,13 +255,11 @@
250
255
  buttonsSensors: []
251
256
  });
252
257
 
253
- // Add device if not exists
254
258
  if (!devicesInConfig.some(d => d.id === id)) {
255
259
  devicesInConfig.push(devObj);
256
- newArr.push(structuredClone(devObj)); // also clone into new devices list
260
+ newArr.push(structuredClone(devObj));
257
261
  }
258
262
 
259
- // Add presets safely
260
263
  presets.forEach(preset => {
261
264
  const p = structuredClone({
262
265
  id: preset.ID,
@@ -274,12 +277,10 @@
274
277
  });
275
278
  };
276
279
 
277
- // Call for each device type
278
280
  handleDevices(devicesByType.ata, acc.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
279
281
  handleDevices(devicesByType.atw, acc.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
280
282
  handleDevices(devicesByType.erv, acc.ervDevices, "Energy Recovery Ventilation", newDevices.erv, newDevices.ervPresets);
281
283
 
282
- // Summary info
283
284
  const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length;
284
285
  const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length;
285
286
  const removedDevicesCount = removedAta.length + removedAtw.length + removedErv.length;
@@ -295,12 +296,10 @@
295
296
  updateInfo('info2', `Removed devices: ATA: ${removedAta.length}, ATW: ${removedAtw.length}, ERV: ${removedErv.length}.`, 'orange');
296
297
  }
297
298
 
298
- // Correct save (must be array)
299
299
  await homebridge.updatePluginConfig(pluginConfig);
300
300
  await homebridge.savePluginConfig(pluginConfig);
301
301
  document.getElementById('logIn').className = "btn btn-secondary";
302
302
 
303
-
304
303
  } catch (error) {
305
304
  updateInfo('info', 'Check Your credentials data and try again.', 'yellow');
306
305
  updateInfo('info1', `Error: ${JSON.stringify(error)}`, 'red');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.0.0-beta.86",
4
+ "version": "4.0.0-beta.88",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",