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.
- package/homebridge-ui/public/index.html +2 -0
- package/package.json +1 -1
- package/src/deviceata.js +8 -8
- package/src/melcloud.js +30 -45
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.
|
|
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
|
|
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 =
|
|
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?.
|
|
1039
|
-
const frostProtectionActive = deviceData.FrostProtection?.
|
|
1040
|
-
const overheatProtectionEnabled = deviceData.OverheatProtection?.
|
|
1041
|
-
const overheatProtectionActive = deviceData.OverheatProtection?.
|
|
1042
|
-
const holidayModeEnabled = deviceData.HolidayMode?.
|
|
1043
|
-
const holidayModeActive = deviceData.HolidayMode?.
|
|
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
|
-
//
|
|
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))
|
|
250
|
-
|
|
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
|
|
254
|
-
|
|
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
|
-
|
|
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
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
...
|
|
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(
|
|
309
|
-
...(building.airToWaterUnits || []).map(d => createDevice(
|
|
310
|
-
...(building.airToVentilationUnits || []).map(d => createDevice(
|
|
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) {
|