homebridge-melcloud-control 4.1.2-beta.20 → 4.1.2-beta.4

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.
@@ -224,6 +224,8 @@
224
224
 
225
225
  document.getElementById('logIn').addEventListener('click', async () => {
226
226
  document.getElementById(`logIn`).className = "btn btn-primary";
227
+
228
+ updateInfo('info', 'Connecting...', 'yellow');
227
229
  homebridge.showSpinner();
228
230
 
229
231
  try {
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.20",
4
+ "version": "4.1.2-beta.4",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/deviceata.js CHANGED
@@ -766,7 +766,7 @@ class DeviceAta extends EventEmitter {
766
766
  })
767
767
  .onSet(async (state) => {
768
768
  try {
769
- const fanKey = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
769
+ const key = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
770
770
  let effectiveFlags = null;
771
771
  switch (mode) {
772
772
  case 0: //POWER ON,OFF
@@ -1018,7 +1018,7 @@ class DeviceAta extends EventEmitter {
1018
1018
 
1019
1019
  //keys
1020
1020
  const presetsKey = this.accountType === 'melcloud' ? 'Presets' : 'Schedule';
1021
- const presetsIdKey = this.accountType === 'melcloud' ? 'ID' : 'Id';
1021
+ const presetsIdKey = accountType === 'melcloud' ? 'ID' : 'Id';
1022
1022
  const setTempKey = this.accountType === 'melcloud' ? 'SetTemperature' : 'SetPoint';
1023
1023
  const fanKey = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
1024
1024
  const tempStepKey = this.accountType === 'melcloud' ? 'TemperatureIncrement' : 'HasHalfDegreeIncrements';
@@ -1035,12 +1035,12 @@ class DeviceAta extends EventEmitter {
1035
1035
  const presetsOnServer = deviceData[presetsKey] ?? [];
1036
1036
 
1037
1037
  //protection
1038
- const frostProtectionEnabled = deviceData.FrostProtection?.Enabled;
1039
- const frostProtectionActive = deviceData.FrostProtection?.Active;
1040
- const overheatProtectionEnabled = deviceData.OverheatProtection?.Enabled;
1041
- const overheatProtectionActive = deviceData.OverheatProtection?.Active;
1042
- const holidayModeEnabled = deviceData.HolidayMode?.Enabled;
1043
- const holidayModeActive = deviceData.HolidayMode?.Active;
1038
+ const frostProtectionEnabled = deviceData.FrostProtection?.enabled;
1039
+ const frostProtectionActive = deviceData.FrostProtection?.active;
1040
+ const overheatProtectionEnabled = deviceData.OverheatProtection?.enabled;
1041
+ const overheatProtectionActive = deviceData.OverheatProtection?.active;
1042
+ const holidayModeEnabled = deviceData.HolidayMode?.enabled;
1043
+ const holidayModeActive = deviceData.HolidayMode?.active;
1044
1044
  const scheduleEnabled = deviceData.ScheduleEnabled;
1045
1045
 
1046
1046
  //device control
package/src/melcloud.js CHANGED
@@ -235,67 +235,51 @@ class MelCloud extends EventEmitter {
235
235
  if (this.logDebug) this.emit('debug', `Buildings list saved`);
236
236
 
237
237
  const devices = buildingsList.flatMap(building => {
238
- // Funkcja kapitalizująca klucze obiektu
239
- const capitalizeKeys = obj =>
240
- Object.fromEntries(
241
- Object.entries(obj).map(([key, value]) => [
242
- key.charAt(0).toUpperCase() + key.slice(1),
243
- value
244
- ])
245
- );
246
-
247
- // Rekurencyjna kapitalizacja kluczy w obiekcie lub tablicy
238
+ // Rekurencyjna funkcja kapitalizująca klucze w całym obiekcie (bezpieczna)
248
239
  const capitalizeKeysDeep = obj => {
249
- if (Array.isArray(obj)) return obj.map(capitalizeKeysDeep);
250
- if (obj && typeof obj === 'object') {
240
+ if (Array.isArray(obj)) {
241
+ return obj.map(item => capitalizeKeysDeep(item));
242
+ } else if (obj && typeof obj === 'object' && obj.constructor === Object) {
251
243
  return Object.fromEntries(
252
- Object.entries(obj).map(([key, value]) => [
253
- key.charAt(0).toUpperCase() + key.slice(1),
254
- capitalizeKeysDeep(value)
255
- ])
244
+ Object.entries(obj).map(([key, value]) => {
245
+ const safeKey = typeof key === 'string'
246
+ ? key.charAt(0).toUpperCase() + key.slice(1)
247
+ : key;
248
+ return [safeKey, capitalizeKeysDeep(value)];
249
+ })
256
250
  );
257
251
  }
258
252
  return obj;
259
253
  };
260
254
 
261
255
  // Funkcja tworząca finalny obiekt Device
262
- const createDevice = (device, type) => {
263
- // Settings już kapitalizowane w nazwach
264
- const settingsArray = device.Settings || [];
256
+ const createDevice = (device, type, headers = {}) => {
257
+ const settingsArray = Array.isArray(device.Settings) ? device.Settings : [];
265
258
 
266
259
  const settingsObject = Object.fromEntries(
267
- settingsArray.map(({ name, value }) => {
268
- let parsedValue = value;
269
- if (value === "True") parsedValue = true;
270
- else if (value === "False") parsedValue = false;
271
- else if (!isNaN(value) && value !== "") parsedValue = Number(value);
272
-
273
- const key = name.charAt(0).toUpperCase() + name.slice(1);
274
- return [key, parsedValue];
275
- })
260
+ settingsArray
261
+ .filter(item => item && typeof item.name === 'string') // 🔒 tylko poprawne wpisy
262
+ .map(({ name, value }) => {
263
+ let parsedValue = value;
264
+ if (value === "True") parsedValue = true;
265
+ else if (value === "False") parsedValue = false;
266
+ else if (typeof value === 'string' && !isNaN(Number(value)) && value.trim() !== "") parsedValue = Number(value);
267
+
268
+ const key = name.charAt(0).toUpperCase() + name.slice(1);
269
+ return [key, parsedValue];
270
+ })
276
271
  );
277
272
 
278
- // Scal Capabilities + Settings + DeviceType w Device
279
273
  const deviceObject = {
280
- ...capitalizeKeys(device.Capabilities || {}),
274
+ ...capitalizeKeysDeep(device.Capabilities || {}),
281
275
  ...settingsObject,
282
276
  DeviceType: type
283
277
  };
284
278
 
285
- // Kapitalizacja brakujących obiektów/tablic
286
- if (device.FrostProtection) device.FrostProtection = { ...capitalizeKeys(device.FrostProtection || {}) };
287
- if (device.OverheatProtection) device.OverheatProtection = { ...capitalizeKeys(device.OverheatProtection || {}) };
288
- if (device.HolidayMode) device.HolidayMode = { ...capitalizeKeys(device.HolidayMode || {}) };
289
-
290
- if (Array.isArray(device.Schedule)) {
291
- device.Schedule = device.Schedule.map(capitalizeKeysDeep);
292
- }
293
-
294
- // Usuń stare pola Settings i Capabilities
295
279
  const { Settings, Capabilities, Id, GivenDisplayName, ...rest } = device;
296
280
 
297
281
  return {
298
- ...rest,
282
+ ...capitalizeKeysDeep(rest),
299
283
  Type: type,
300
284
  DeviceID: Id,
301
285
  DeviceName: GivenDisplayName,
@@ -304,13 +288,14 @@ class MelCloud extends EventEmitter {
304
288
  };
305
289
  };
306
290
 
291
+ // Mapowanie urządzeń
307
292
  return [
308
- ...(building.airToAirUnits || []).map(d => createDevice(capitalizeKeys(d), 0)),
309
- ...(building.airToWaterUnits || []).map(d => createDevice(capitalizeKeys(d), 1)),
310
- ...(building.airToVentilationUnits || []).map(d => createDevice(capitalizeKeys(d), 3))
293
+ ...(building.airToAirUnits || []).map(d => createDevice(capitalizeKeysDeep(d), 0)),
294
+ ...(building.airToWaterUnits || []).map(d => createDevice(capitalizeKeysDeep(d), 1)),
295
+ ...(building.airToVentilationUnits || []).map(d => createDevice(capitalizeKeysDeep(d), 3))
311
296
  ];
312
- });
313
297
 
298
+ });
314
299
 
315
300
  const devicesCount = devices.length;
316
301
  if (devicesCount === 0) {