homebridge-melcloud-control 4.3.3-beta.2 → 4.3.3-beta.21
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/CHANGELOG.md +9 -0
- package/homebridge-ui/public/index.html +1 -1
- package/package.json +2 -2
- package/src/deviceata.js +1 -1
- package/src/deviceatw.js +1 -1
- package/src/deviceerv.js +1 -1
- package/src/functions.js +11 -0
- package/src/melcloud.js +1 -1
- package/src/melcloudata.js +29 -19
- package/src/melcloudatw.js +1 -0
- package/src/melclouderv.js +1 -0
- package/src/melcloudhome.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -22,6 +22,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
22
22
|
|
|
23
23
|
- Do not use Homebridge UI > v5.5.0 because of break config.json
|
|
24
24
|
|
|
25
|
+
# [4.3.2] - (xx.11.2025)
|
|
26
|
+
|
|
27
|
+
## Changes
|
|
28
|
+
|
|
29
|
+
- fix presets report wrong state
|
|
30
|
+
- stability improvements
|
|
31
|
+
- bump dependencies
|
|
32
|
+
- cleanup
|
|
33
|
+
|
|
25
34
|
# [4.3.2] - (21.11.2025)
|
|
26
35
|
|
|
27
36
|
## Changes
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
const devicesByType = { ata: [], atw: [], erv: [] };
|
|
251
251
|
|
|
252
252
|
response.Devices.forEach(d => {
|
|
253
|
-
d.Scenes = response.Scenes
|
|
253
|
+
d.Scenes = Array.isArray(response.Scenes) ? [...response.Scenes] : [];
|
|
254
254
|
if (d.Type === 0) devicesByType.ata.push(d);
|
|
255
255
|
if (d.Type === 1) devicesByType.atw.push(d);
|
|
256
256
|
if (d.Type === 3) devicesByType.erv.push(d);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.3.3-beta.
|
|
4
|
+
"version": "4.3.3-beta.21",
|
|
5
5
|
"description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "grzegorz914",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"node": "^20 || ^22 || ^24 || ^25"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@homebridge/plugin-ui-utils": "^2.1.
|
|
38
|
+
"@homebridge/plugin-ui-utils": "^2.1.2",
|
|
39
39
|
"async-mqtt": "^2.6.3",
|
|
40
40
|
"axios": "^1.13.2",
|
|
41
41
|
"express": "^5.1.0",
|
package/src/deviceata.js
CHANGED
|
@@ -915,7 +915,7 @@ class DeviceAta extends EventEmitter {
|
|
|
915
915
|
presetControlSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName1} Control`);
|
|
916
916
|
presetControlSensorService.getCharacteristic(characteristicType)
|
|
917
917
|
.onGet(async () => {
|
|
918
|
-
const state =
|
|
918
|
+
const state = preset.state;
|
|
919
919
|
return state;
|
|
920
920
|
})
|
|
921
921
|
this.presetControlSensorServices.push(presetControlSensorService);
|
package/src/deviceatw.js
CHANGED
|
@@ -1230,7 +1230,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1230
1230
|
presetControlSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName1} Control`);
|
|
1231
1231
|
presetControlSensorService.getCharacteristic(characteristicType)
|
|
1232
1232
|
.onGet(async () => {
|
|
1233
|
-
const state =
|
|
1233
|
+
const state = preset.state;
|
|
1234
1234
|
return state;
|
|
1235
1235
|
})
|
|
1236
1236
|
this.presetControlSensorServices.push(presetControlSensorService);
|
package/src/deviceerv.js
CHANGED
|
@@ -842,7 +842,7 @@ class DeviceErv extends EventEmitter {
|
|
|
842
842
|
presetControlSensorService.setCharacteristic(Characteristic.ConfiguredName, `${serviceName1} Control`);
|
|
843
843
|
presetControlSensorService.getCharacteristic(characteristicType)
|
|
844
844
|
.onGet(async () => {
|
|
845
|
-
const state =
|
|
845
|
+
const state = preset.state;
|
|
846
846
|
return state;
|
|
847
847
|
})
|
|
848
848
|
this.presetControlSensorServices.push(presetControlSensorService);
|
package/src/functions.js
CHANGED
|
@@ -167,5 +167,16 @@ class Functions extends EventEmitter {
|
|
|
167
167
|
else if (!isNaN(v) && v !== "") parsedValue = Number(v);
|
|
168
168
|
return parsedValue;
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
parseArrayNameValue(data) {
|
|
172
|
+
if (!Array.isArray(data)) return {};
|
|
173
|
+
|
|
174
|
+
return Object.fromEntries(
|
|
175
|
+
data.map(({ name, value }) => {
|
|
176
|
+
const parsedValue = this.convertValue(value);
|
|
177
|
+
return [name, parsedValue];
|
|
178
|
+
})
|
|
179
|
+
);
|
|
180
|
+
}
|
|
170
181
|
}
|
|
171
182
|
export default Functions
|
package/src/melcloud.js
CHANGED
|
@@ -143,7 +143,7 @@ class MelCloud extends EventEmitter {
|
|
|
143
143
|
data: payload
|
|
144
144
|
});
|
|
145
145
|
const account = accountData.data;
|
|
146
|
-
const loginData = account.LoginData ??
|
|
146
|
+
const loginData = account.LoginData ?? {};
|
|
147
147
|
const contextKey = loginData.ContextKey;
|
|
148
148
|
|
|
149
149
|
const safeConfig = {
|
package/src/melcloudata.js
CHANGED
|
@@ -76,8 +76,8 @@ class MelCloudAta extends EventEmitter {
|
|
|
76
76
|
deviceData.Device.OperationMode = AirConditioner.OperationModeMapStringToEnum[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
|
|
77
77
|
deviceData.Device.ActualFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.ActualFanSpeed] ?? deviceData.Device.ActualFanSpeed;
|
|
78
78
|
deviceData.Device.SetFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.SetFanSpeed] ?? deviceData.Device.SetFanSpeed;
|
|
79
|
-
deviceData.Device.VaneVerticalDirection = AirConditioner.VaneVerticalDirectionMapStringToEnum[deviceData.Device.VaneVerticalDirection] ?? deviceData.Device.VaneVerticalDirection;
|
|
80
79
|
deviceData.Device.VaneHorizontalDirection = AirConditioner.VaneHorizontalDirectionMapStringToEnum[deviceData.Device.VaneHorizontalDirection] ?? deviceData.Device.VaneHorizontalDirection
|
|
80
|
+
deviceData.Device.VaneVerticalDirection = AirConditioner.VaneVerticalDirectionMapStringToEnum[deviceData.Device.VaneVerticalDirection] ?? deviceData.Device.VaneVerticalDirection;
|
|
81
81
|
|
|
82
82
|
//read default temps
|
|
83
83
|
const temps = await this.functions.readData(this.defaultTempsFile, true);
|
|
@@ -151,6 +151,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
151
151
|
|
|
152
152
|
this.headers = devicesData.Headers;
|
|
153
153
|
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
154
|
+
if (!deviceData) return;
|
|
154
155
|
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
155
156
|
|
|
156
157
|
//web cocket connection
|
|
@@ -188,7 +189,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
188
189
|
.on('message', async (message) => {
|
|
189
190
|
const parsedMessage = JSON.parse(message);
|
|
190
191
|
const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
|
|
191
|
-
if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
192
192
|
if (parsedMessage.message === 'Forbidden') return;
|
|
193
193
|
|
|
194
194
|
const messageData = parsedMessage?.[0]?.Data;
|
|
@@ -198,16 +198,32 @@ class MelCloudAta extends EventEmitter {
|
|
|
198
198
|
const unitId = messageData?.id;
|
|
199
199
|
switch (unitId) {
|
|
200
200
|
case this.deviceId:
|
|
201
|
+
if (!this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
201
202
|
const messageType = parsedMessage[0].messageType;
|
|
203
|
+
const settings = this.functions.parseArrayNameValue(messageData.settings);
|
|
202
204
|
switch (messageType) {
|
|
203
205
|
case 'unitStateChanged':
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
206
|
+
|
|
207
|
+
//update values
|
|
208
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
209
|
+
if (!this.functions.isValidValue(value)) continue;
|
|
210
|
+
|
|
211
|
+
if (key === 'HolidayMode') {
|
|
212
|
+
deviceData.HolidayMode.Enabled = value;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
//skip HolidayMode, update generic device fields
|
|
217
|
+
if (key in deviceData.Device) {
|
|
218
|
+
deviceData.Device[key] = value;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
updateState = true;
|
|
222
|
+
break;
|
|
223
|
+
case 'unitHolidayModeTriggered':
|
|
224
|
+
deviceData.Device.Power = settings.Power;
|
|
225
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
226
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
211
227
|
updateState = true;
|
|
212
228
|
break;
|
|
213
229
|
case 'unitWifiSignalChanged':
|
|
@@ -215,12 +231,12 @@ class MelCloudAta extends EventEmitter {
|
|
|
215
231
|
updateState = true;
|
|
216
232
|
break;
|
|
217
233
|
default:
|
|
218
|
-
if (
|
|
234
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
219
235
|
return;
|
|
220
236
|
}
|
|
221
237
|
break;
|
|
222
238
|
default:
|
|
223
|
-
if (
|
|
239
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
224
240
|
return;
|
|
225
241
|
}
|
|
226
242
|
|
|
@@ -329,6 +345,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
329
345
|
method = 'POST';
|
|
330
346
|
path = ApiUrlsHome.PostHolidayMode;
|
|
331
347
|
headers.Referer = ApiUrlsHome.Referers.PostHolidayMode.replace('deviceid', deviceData.DeviceID);
|
|
348
|
+
updateState = false;
|
|
332
349
|
break;
|
|
333
350
|
case 'schedule':
|
|
334
351
|
payload = { enabled: deviceData.ScheduleEnabled };
|
|
@@ -368,14 +385,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
368
385
|
path = ApiUrlsHome.PutAta.replace('deviceid', deviceData.DeviceID);
|
|
369
386
|
headers.Referer = ApiUrlsHome.Referers.PutDeviceSettings;
|
|
370
387
|
updateState = false;
|
|
371
|
-
|
|
372
|
-
messageType: 'setUnitSettings',
|
|
373
|
-
Data: {
|
|
374
|
-
id: deviceData.DeviceID,
|
|
375
|
-
settings: payload
|
|
376
|
-
}
|
|
377
|
-
}]));
|
|
378
|
-
return;
|
|
388
|
+
break;
|
|
379
389
|
}
|
|
380
390
|
|
|
381
391
|
//sens payload
|
package/src/melcloudatw.js
CHANGED
|
@@ -145,6 +145,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
145
145
|
|
|
146
146
|
this.headers = devicesData.Headers;
|
|
147
147
|
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
148
|
+
if (!deviceData) return;
|
|
148
149
|
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
149
150
|
|
|
150
151
|
//web cocket connection
|
package/src/melclouderv.js
CHANGED
|
@@ -60,6 +60,7 @@ class MelCloudErv extends EventEmitter {
|
|
|
60
60
|
|
|
61
61
|
this.headers = devicesData.Headers;
|
|
62
62
|
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
63
|
+
if (!deviceData) return;
|
|
63
64
|
if (this.accountType === 'melcloudhome') {
|
|
64
65
|
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
65
66
|
|
package/src/melcloudhome.js
CHANGED
|
@@ -142,7 +142,6 @@ class MelCloudHome extends EventEmitter {
|
|
|
142
142
|
const createDevice = (device, type) => {
|
|
143
143
|
// Settings już kapitalizowane w nazwach
|
|
144
144
|
const settingsArray = device.Settings || [];
|
|
145
|
-
|
|
146
145
|
const settingsObject = Object.fromEntries(
|
|
147
146
|
settingsArray.map(({ name, value }) => {
|
|
148
147
|
let parsedValue = this.functions.convertValue(value);
|