homebridge-melcloud-control 3.1.2-beta.9 → 3.1.3-beta.0
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 +10 -3
- package/README.md +3 -3
- package/config.schema.json +1 -1
- package/homebridge-ui/public/index.html +45 -3
- package/index.js +9 -3
- package/package.json +1 -1
- package/src/deviceata.js +5 -6
- package/src/deviceatw.js +19 -19
- package/src/deviceerv.js +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -12,15 +12,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
12
12
|
- v1 After update to v1 and above from v0 the devices need to be added to the Home app again and the old unresponsive remove!!! This devices will be removed from all automations and scenes!!!
|
|
13
13
|
- v2 After update to v2 from v1 only RESTFull and MQTT config settings need to be updated in config.
|
|
14
14
|
- v2.4 and above require upcomming homebridge v2
|
|
15
|
-
- v3 After update to v3
|
|
15
|
+
- v3 After update to v3 the plugin need to be configured using Config UI X.
|
|
16
16
|
- do not configure it manually, always using Config UI X
|
|
17
|
+
- required Homebridge v2.0.0 and above
|
|
18
|
+
|
|
19
|
+
## [3.1.2] - (31.08.2024)
|
|
20
|
+
|
|
21
|
+
## Changes
|
|
22
|
+
|
|
23
|
+
- fix presets configured array
|
|
17
24
|
|
|
18
25
|
## [3.1.0] - (31.08.2024)
|
|
19
26
|
|
|
20
27
|
## Changes
|
|
21
28
|
|
|
22
29
|
- improvements in plugin config UI
|
|
23
|
-
- added
|
|
30
|
+
- added presets config indyvidually
|
|
24
31
|
- config schema update
|
|
25
32
|
- bump dependencies
|
|
26
33
|
- cleanup
|
|
@@ -39,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
39
46
|
|
|
40
47
|
- added homebridge UI server
|
|
41
48
|
- whole new concept get all devices from melcloud usin config UI X
|
|
42
|
-
- added
|
|
49
|
+
- added device config indyvidually
|
|
43
50
|
- config schema updated
|
|
44
51
|
- cleanup
|
|
45
52
|
|
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
|
|
|
21
21
|
|
|
22
22
|
| Package | Installation | Role | Required |
|
|
23
23
|
| --- | --- | --- | --- |
|
|
24
|
-
| [Homebridge](https://github.com/homebridge/homebridge) | [Homebridge Wiki](https://github.com/homebridge/homebridge/wiki) | HomeKit Bridge | Required |
|
|
25
|
-
| [Config UI X](https://github.com/homebridge/homebridge-config-ui-x) | [Config UI X Wiki](https://github.com/homebridge/homebridge-config-ui-x/wiki) | Homebridge Web User Interface |
|
|
24
|
+
| [Homebridge v2.0](https://github.com/homebridge/homebridge) | [Homebridge Wiki](https://github.com/homebridge/homebridge/wiki) | HomeKit Bridge | Required ab v3.0.0 |
|
|
25
|
+
| [Config UI X](https://github.com/homebridge/homebridge-config-ui-x) | [Config UI X Wiki](https://github.com/homebridge/homebridge-config-ui-x/wiki) | Homebridge Web User Interface | Required ab v3.0.0|
|
|
26
26
|
| [MELCloud](https://github.com/grzegorz914/homebridge-melcloud-control) | [Plug-In Wiki](https://github.com/grzegorz914/homebridge-melcloud-control/wiki) | Homebridge Plug-In | Required |
|
|
27
27
|
|
|
28
28
|
### About The Plugin
|
|
@@ -161,7 +161,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
|
|
|
161
161
|
### Configuration
|
|
162
162
|
|
|
163
163
|
* Run this plugin as a [Child Bridge](https://github.com/homebridge/homebridge/wiki/Child-Bridges) (Highly Recommended), this prevent crash Homebridge if plugin crashes.
|
|
164
|
-
* Install and use [Homebridge Config UI X](https://github.com/homebridge/homebridge-config-ui-x/wiki) to configure this plugin
|
|
164
|
+
* Install and use [Homebridge Config UI X](https://github.com/homebridge/homebridge-config-ui-x/wiki) to configure this plugin, required for version v3 and above.
|
|
165
165
|
* The `sample-config.json` can be edited and used as an alternative.
|
|
166
166
|
|
|
167
167
|
<p align="center">
|
package/config.schema.json
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
};
|
|
188
188
|
|
|
189
189
|
//get device info fom devices ata
|
|
190
|
-
devicesByType.ata.forEach((device, index) => {
|
|
190
|
+
devicesByType.ata.forEach(async (device, index) => {
|
|
191
191
|
const deviceId = device.DeviceID;
|
|
192
192
|
const deviceType = device.Type;
|
|
193
193
|
const deviceTypeText = "Air Conditioner";
|
|
@@ -212,6 +212,7 @@
|
|
|
212
212
|
|
|
213
213
|
const ataDevicesExist = pluginConfig[0].accounts[this.deviceIndex].ataDevices ?? false;
|
|
214
214
|
const ataDevices = ataDevicesExist ? pluginConfig[0].accounts[this.deviceIndex].ataDevices : pluginConfig[0].accounts[this.deviceIndex].ataDevices = [];
|
|
215
|
+
|
|
215
216
|
const ataDeviceIdExist = ataDevices.some(device => device.id === deviceId);
|
|
216
217
|
const pushTypeAta = ataDeviceIdExist ? false : ataDevices.push(deviceAta);
|
|
217
218
|
const pushNewDevice = ataDeviceIdExist ? false : newDevices.ata.push(device);
|
|
@@ -236,10 +237,15 @@
|
|
|
236
237
|
const presetsCount = newDevices.ataPresets.length;
|
|
237
238
|
textAtaPresets = `ATA Presets: ${presetsCount}`
|
|
238
239
|
};
|
|
240
|
+
|
|
241
|
+
//compare presets
|
|
242
|
+
const presetsOnMelCloud = devicePresets;
|
|
243
|
+
const presetsAtaInConfig = pluginConfig[0].accounts[this.deviceIndex].ataDevices[index].presets;
|
|
244
|
+
presetsAtaInConfig = syncArrays(presetsOnMelCloud, presetsAtaInConfig);
|
|
239
245
|
});
|
|
240
246
|
|
|
241
247
|
//get device info fom devices atw
|
|
242
|
-
devicesByType.atw.forEach((device, index) => {
|
|
248
|
+
devicesByType.atw.forEach(async (device, index) => {
|
|
243
249
|
const deviceId = device.DeviceID;
|
|
244
250
|
const deviceType = device.Type;
|
|
245
251
|
const deviceTypeText = "Heat Pump";
|
|
@@ -293,10 +299,14 @@
|
|
|
293
299
|
const presetsCount = newDevices.atwPresets.length;
|
|
294
300
|
textAtwPresets = `ATW Presets: ${presetsCount}`
|
|
295
301
|
};
|
|
302
|
+
|
|
303
|
+
const presetsOnMelCloud = devicePresets;
|
|
304
|
+
const presetsAtwInConfig = pluginConfig[0].accounts[this.deviceIndex].atwDevices[index].presets;
|
|
305
|
+
presetsAtwInConfig = syncArrays(presetsOnMelCloud, presetsAtwInConfig);
|
|
296
306
|
});
|
|
297
307
|
|
|
298
308
|
//get device info fom devices erv
|
|
299
|
-
devicesByType.erv.forEach((device, index) => {
|
|
309
|
+
devicesByType.erv.forEach(async (device, index) => {
|
|
300
310
|
const deviceId = device.DeviceID;
|
|
301
311
|
const deviceType = device.Type;
|
|
302
312
|
const deviceTypeText = "Energy Recovery Ventilation";
|
|
@@ -344,8 +354,23 @@
|
|
|
344
354
|
const presetsCount = newDevices.ervPresets.length;
|
|
345
355
|
textErvPresets = `ERV Presets: ${presetsCount}`
|
|
346
356
|
};
|
|
357
|
+
|
|
358
|
+
const presetsOnMelCloud = devicePresets;
|
|
359
|
+
const presetsErvInConfig = pluginConfig[0].accounts[this.deviceIndex].ervDevices[index].presets;
|
|
360
|
+
presetsErvInConfig = await syncArrays(presetsOnMelCloud, presetsErvInConfig);
|
|
347
361
|
});
|
|
348
362
|
|
|
363
|
+
//compare arrays and update array in config
|
|
364
|
+
const devicesOnMelCloud = devices;
|
|
365
|
+
const devicesAtaInConfig = pluginConfig[0].accounts[this.deviceIndex].ataDevices;
|
|
366
|
+
devicesAtaInConfig = await syncArrays(devicesOnMelCloud, devicesAtaInConfig);
|
|
367
|
+
|
|
368
|
+
const devicesAtwInConfig = pluginConfig[0].accounts[this.deviceIndex].atwDevices;
|
|
369
|
+
devicesAtwInConfig = await syncArrays(devicesOnMelCloud, devicesAtwInConfig);
|
|
370
|
+
|
|
371
|
+
const devicesErvInConfig = pluginConfig[0].accounts[this.deviceIndex].ervDevices;
|
|
372
|
+
devicesErvInConfig = await syncArrays(devicesOnMelCloud, devicesErvInConfig);
|
|
373
|
+
|
|
349
374
|
const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length ?? 0;
|
|
350
375
|
const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length ?? 0;
|
|
351
376
|
if (newDevicesCount === 0 && newPresetsCount === 0) {
|
|
@@ -389,6 +414,23 @@
|
|
|
389
414
|
break;
|
|
390
415
|
};
|
|
391
416
|
|
|
417
|
+
async function syncArrays(devicesOnMelCloud, devicesInConfig) {
|
|
418
|
+
// Create a Set of IDs from devicesOnMelCloud for quick lookup
|
|
419
|
+
const devicesOnMelCloudId = new Set(devicesOnMelCloud.map(device => device.DeviceID));
|
|
420
|
+
|
|
421
|
+
// Filter devicesInConfig to keep only objects that exist in devicesOnMelCloud
|
|
422
|
+
devicesInConfig = devicesInConfig.filter(device => devicesOnMelCloudId.has(device.DeviceID));
|
|
423
|
+
|
|
424
|
+
// Add objects from devicesOnMelCloud to devicesInConfig that do not exist in devicesInConfig
|
|
425
|
+
devicesOnMelCloud.forEach(device => {
|
|
426
|
+
if (!devicesInConfig.some(item => item.id === device.id)) {
|
|
427
|
+
devicesInConfig.push(device);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
return devicesInConfig;
|
|
432
|
+
}
|
|
433
|
+
|
|
392
434
|
homebridge.hideSpinner();
|
|
393
435
|
} catch (e) {
|
|
394
436
|
document.getElementById('info').innerHTML = 'Please try again.';
|
package/index.js
CHANGED
|
@@ -105,7 +105,9 @@ class MelCloudPlatform {
|
|
|
105
105
|
|
|
106
106
|
//Air Conditioner
|
|
107
107
|
for (const device of account.ataDevices) {
|
|
108
|
-
|
|
108
|
+
//chack device from config exist on melcloud
|
|
109
|
+
const deviceExistInMelCloud = devices.some(dev => dev.DeviceID === device.id);
|
|
110
|
+
if (!deviceExistInMelCloud || device.displayMode === 0) {
|
|
109
111
|
continue;
|
|
110
112
|
};
|
|
111
113
|
|
|
@@ -142,7 +144,9 @@ class MelCloudPlatform {
|
|
|
142
144
|
|
|
143
145
|
//Heat Pump
|
|
144
146
|
for (const device of account.atwDevices) {
|
|
145
|
-
|
|
147
|
+
//chack device from config exist on melcloud
|
|
148
|
+
const deviceExistInMelCloud = devices.some(dev => dev.DeviceID === device.id);
|
|
149
|
+
if (!deviceExistInMelCloud || device.displayMode === 0) {
|
|
146
150
|
continue;
|
|
147
151
|
};
|
|
148
152
|
|
|
@@ -180,7 +184,9 @@ class MelCloudPlatform {
|
|
|
180
184
|
|
|
181
185
|
//Energy Recovery Ventilation
|
|
182
186
|
for (const device of account.ervDevices) {
|
|
183
|
-
|
|
187
|
+
//chack device from config exist on melcloud
|
|
188
|
+
const deviceExistInMelCloud = devices.some(dev => dev.DeviceID === device.id);
|
|
189
|
+
if (!deviceExistInMelCloud || device.displayMode === 0) {
|
|
184
190
|
continue;
|
|
185
191
|
};
|
|
186
192
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.3-beta.0",
|
|
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
|
@@ -20,7 +20,6 @@ class DeviceAta extends EventEmitter {
|
|
|
20
20
|
this.displayMode = device.displayMode;
|
|
21
21
|
this.temperatureSensor = device.temperatureSensor || false;
|
|
22
22
|
this.temperatureSensorOutdoor = device.temperatureSensorOutdoor || false;
|
|
23
|
-
this.presetsEnabled = device.presets || false;
|
|
24
23
|
this.heatDryFanMode = device.heatDryFanMode || 1; //NONE, HEAT, DRY, FAN
|
|
25
24
|
this.coolDryFanMode = device.coolDryFanMode || 1; //NONE, COOL, DRY, FAN
|
|
26
25
|
this.autoDryFanMode = device.autoDryFanMode || 1; //NONE, AUTO, DRY, FAN
|
|
@@ -46,13 +45,13 @@ class DeviceAta extends EventEmitter {
|
|
|
46
45
|
const presetDisplayType = preset.displayType ?? 0;
|
|
47
46
|
const presetNamePrefix = preset.namePrefix ?? false;
|
|
48
47
|
if (presetName && presetDisplayType > 0) {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
48
|
+
const presetyServiceType = ['', Service.Outlet, Service.Switch, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][presetDisplayType];
|
|
49
|
+
const presetCharacteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][presetDisplayType];
|
|
51
50
|
preset.namePrefix = presetNamePrefix;
|
|
52
|
-
preset.serviceType =
|
|
53
|
-
preset.characteristicType =
|
|
51
|
+
preset.serviceType = presetyServiceType;
|
|
52
|
+
preset.characteristicType = presetCharacteristicType;
|
|
54
53
|
preset.state = false;
|
|
55
|
-
this.
|
|
54
|
+
this.presetsConfigured.push(preset);
|
|
56
55
|
} else {
|
|
57
56
|
const log = presetDisplayType === 0 ? false : this.emit('message', `Preset Name: ${preset ? preset : 'Missing'}.`);
|
|
58
57
|
};
|
package/src/deviceatw.js
CHANGED
|
@@ -42,25 +42,25 @@ class DeviceAtw extends EventEmitter {
|
|
|
42
42
|
//function
|
|
43
43
|
this.melCloud = melCloud; //function
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
45
|
+
//presets configured
|
|
46
|
+
this.presetsConfigured = [];
|
|
47
|
+
for (const preset of this.presets) {
|
|
48
|
+
const presetName = preset.name ?? false;
|
|
49
|
+
const presetDisplayType = preset.displayType ?? 0;
|
|
50
|
+
const presetNamePrefix = preset.namePrefix ?? false;
|
|
51
|
+
if (presetName && presetDisplayType > 0) {
|
|
52
|
+
const presetyServiceType = ['', Service.Outlet, Service.Switch, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][presetDisplayType];
|
|
53
|
+
const presetCharacteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][presetDisplayType];
|
|
54
|
+
preset.namePrefix = presetNamePrefix;
|
|
55
|
+
preset.serviceType = presetyServiceType;
|
|
56
|
+
preset.characteristicType = presetCharacteristicType;
|
|
57
|
+
preset.state = false;
|
|
58
|
+
this.presetsConfigured.push(preset);
|
|
59
|
+
} else {
|
|
60
|
+
const log = presetDisplayType === 0 ? false : this.emit('message', `Preset Name: ${preset ? preset : 'Missing'}.`);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
this.presetsConfiguredCount = this.presetsConfigured.length || 0;
|
|
64
64
|
|
|
65
65
|
//buttons configured
|
|
66
66
|
this.buttonsConfigured = [];
|
package/src/deviceerv.js
CHANGED
|
@@ -43,13 +43,13 @@ class DeviceErv extends EventEmitter {
|
|
|
43
43
|
const presetDisplayType = preset.displayType ?? 0;
|
|
44
44
|
const presetNamePrefix = preset.namePrefix ?? false;
|
|
45
45
|
if (presetName && presetDisplayType > 0) {
|
|
46
|
-
const
|
|
47
|
-
const
|
|
46
|
+
const presetyServiceType = ['', Service.Outlet, Service.Switch, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][presetDisplayType];
|
|
47
|
+
const presetCharacteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][presetDisplayType];
|
|
48
48
|
preset.namePrefix = presetNamePrefix;
|
|
49
|
-
preset.serviceType =
|
|
50
|
-
preset.characteristicType =
|
|
49
|
+
preset.serviceType = presetyServiceType;
|
|
50
|
+
preset.characteristicType = presetCharacteristicType;
|
|
51
51
|
preset.state = false;
|
|
52
|
-
this.
|
|
52
|
+
this.presetsConfigured.push(preset);
|
|
53
53
|
} else {
|
|
54
54
|
const log = presetDisplayType === 0 ? false : this.emit('message', `Preset Name: ${preset ? preset : 'Missing'}.`);
|
|
55
55
|
};
|