homebridge-melcloud-control 4.3.5-beta.9 → 4.3.5
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 -1
- package/README.md +0 -3
- package/config.schema.json +3 -30
- package/homebridge-ui/server.js +1 -2
- package/index.js +18 -19
- package/package.json +1 -1
- package/src/deviceata.js +5 -4
- package/src/deviceatw.js +5 -4
- package/src/deviceerv.js +5 -4
- package/src/melcloud.js +3 -6
- package/src/melcloudata.js +69 -65
- package/src/melcloudatw.js +63 -48
- package/src/melclouderv.js +73 -5
- package/src/melcloudhome.js +7 -9
package/CHANGELOG.md
CHANGED
|
@@ -22,11 +22,20 @@ 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.5] - (24.11.2025)
|
|
26
|
+
|
|
27
|
+
## Changes
|
|
28
|
+
|
|
29
|
+
- removed device refresh time settings
|
|
30
|
+
- stability and performance improvements
|
|
31
|
+
- redme updated
|
|
32
|
+
- cleanup
|
|
33
|
+
|
|
25
34
|
# [4.3.4] - (23.11.2025)
|
|
26
35
|
|
|
27
36
|
## Changes
|
|
28
37
|
|
|
29
|
-
- fix
|
|
38
|
+
- fix account monitoring start
|
|
30
39
|
- stability improvements
|
|
31
40
|
- cleanup
|
|
32
41
|
|
package/README.md
CHANGED
|
@@ -264,7 +264,6 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
|
|
|
264
264
|
| `ataDevices[].frostProtectionSupport` | This enable extra `Frost Protection` control and sensors to use with automations in HomeKit app. |
|
|
265
265
|
| `ataDevices[].overheatProtectionSupport` | This enable extra `Overheat Protection` control and sensors to use with automations in HomeKit app. |
|
|
266
266
|
| `ataDevices[].holidayModeSupport` | This enable extra `Holiday Mode` control and sensors to use with automations in HomeKit app. |
|
|
267
|
-
| `ataDevices[].refreshInterval` | Here set the background devices state refresh time in (sec), default `5s`. |
|
|
268
267
|
| `ataDevices[].presets[]` | Array of ATA device `Presets` created automatically after login to MELCloud from plugin config UI. |
|
|
269
268
|
| `ataDevices[].presets[].id` | Read only data, do not change it. |
|
|
270
269
|
| `ataDevices[].presets[].name` | Here You can change the `Preset Name` which is exposed to the `Homebridge/HomeKit`. |
|
|
@@ -301,7 +300,6 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
|
|
|
301
300
|
| `atwDevices[].connectSensor` | This enable `Connect State` sensor to use with automations in HomeKit app. |
|
|
302
301
|
| `atwDevices[].errorSensor` | This enable `Error` sensors to use with automations in HomeKit app. |
|
|
303
302
|
| `atwDevices[].holidayModeSupport` | This enable extra `Holiday Mode` control and sensors to use with automations in HomeKit app. |
|
|
304
|
-
| `atwDevices[].refreshInterval` | Here set the background devices state refresh time in (sec), default `5s`. |
|
|
305
303
|
| `atwDevices[].presets[]` | Array of ATW device `Presets` created automatically after login to MELCloud from plugin config UI. |
|
|
306
304
|
| `atwDevices[].presets[].id` | Read only data, do not change it. |
|
|
307
305
|
| `atwDevices[].presets[].name` | Here You can change the `Preset Name` which is exposed to the `Homebridge/HomeKit`. |
|
|
@@ -331,7 +329,6 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
|
|
|
331
329
|
| `ervDevices[].connectSensor` | This enable `Connect State` sensor to use with automations in HomeKit app. |
|
|
332
330
|
| `ervDevices[].errorSensor` | This enable `Error` sensors to use with automations in HomeKit app. |
|
|
333
331
|
| `ervDevices[].holidayModeSupport` | This enable extra `Holiday Mode` control and sensors to use with automations in HomeKit app. |
|
|
334
|
-
| `ervDevices[].refreshInterval` | Here set the background devices state refresh time in (sec), default `5s`. |
|
|
335
332
|
| `ervDevices[].presets[]` | Array of ERV device `Presets` created automatically after login to MELCloud from plugin config UI. |
|
|
336
333
|
| `ervDevices[].presets[].id` | Read only data, do not change it. |
|
|
337
334
|
| `ervDevices[].presets[].name` | Here You can change the `Preset Name` which is exposed to the `Homebridge/HomeKit`. |
|
package/config.schema.json
CHANGED
|
@@ -440,14 +440,6 @@
|
|
|
440
440
|
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome';"
|
|
441
441
|
}
|
|
442
442
|
},
|
|
443
|
-
"refreshInterval": {
|
|
444
|
-
"title": "Refresh Interval",
|
|
445
|
-
"type": "integer",
|
|
446
|
-
"default": 5,
|
|
447
|
-
"minimum": 1,
|
|
448
|
-
"maximum": 60,
|
|
449
|
-
"description": "Set the background device state refresh time in seconds."
|
|
450
|
-
},
|
|
451
443
|
"presets": {
|
|
452
444
|
"title": "Presets",
|
|
453
445
|
"type": "array",
|
|
@@ -1296,14 +1288,6 @@
|
|
|
1296
1288
|
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome';"
|
|
1297
1289
|
}
|
|
1298
1290
|
},
|
|
1299
|
-
"refreshInterval": {
|
|
1300
|
-
"title": "Refresh Interval",
|
|
1301
|
-
"type": "integer",
|
|
1302
|
-
"default": 5,
|
|
1303
|
-
"minimum": 1,
|
|
1304
|
-
"maximum": 60,
|
|
1305
|
-
"description": "Set the background device state refresh time in seconds."
|
|
1306
|
-
},
|
|
1307
1291
|
"presets": {
|
|
1308
1292
|
"title": "Presets",
|
|
1309
1293
|
"type": "array",
|
|
@@ -1921,14 +1905,6 @@
|
|
|
1921
1905
|
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome';"
|
|
1922
1906
|
}
|
|
1923
1907
|
},
|
|
1924
|
-
"refreshInterval": {
|
|
1925
|
-
"title": "Refresh Interval",
|
|
1926
|
-
"type": "integer",
|
|
1927
|
-
"default": 5,
|
|
1928
|
-
"minimum": 1,
|
|
1929
|
-
"maximum": 60,
|
|
1930
|
-
"description": "Set the background device state refresh time in seconds."
|
|
1931
|
-
},
|
|
1932
1908
|
"presets": {
|
|
1933
1909
|
"title": "Presets",
|
|
1934
1910
|
"type": "array",
|
|
@@ -2606,8 +2582,7 @@
|
|
|
2606
2582
|
"accounts[].ataDevices[].autoDryFanMode",
|
|
2607
2583
|
"accounts[].ataDevices[].frostProtectionSupport",
|
|
2608
2584
|
"accounts[].ataDevices[].overheatProtectionSupport",
|
|
2609
|
-
"accounts[].ataDevices[].holidayModeSupport"
|
|
2610
|
-
"accounts[].ataDevices[].refreshInterval"
|
|
2585
|
+
"accounts[].ataDevices[].holidayModeSupport"
|
|
2611
2586
|
],
|
|
2612
2587
|
"condition": {
|
|
2613
2588
|
"functionBody": "return model.accounts[arrayIndices[0]].ataDevices[arrayIndices[1]].displayType > 0;"
|
|
@@ -2779,8 +2754,7 @@
|
|
|
2779
2754
|
"accounts[].atwDevices[].hideZone",
|
|
2780
2755
|
"accounts[].atwDevices[].name",
|
|
2781
2756
|
"accounts[].atwDevices[].frostProtectionSupport",
|
|
2782
|
-
"accounts[].atwDevices[].holidayModeSupport"
|
|
2783
|
-
"accounts[].atwDevices[].refreshInterval"
|
|
2757
|
+
"accounts[].atwDevices[].holidayModeSupport"
|
|
2784
2758
|
],
|
|
2785
2759
|
"condition": {
|
|
2786
2760
|
"functionBody": "return model.accounts[arrayIndices[0]].atwDevices[arrayIndices[1]].displayType > 0;"
|
|
@@ -2957,8 +2931,7 @@
|
|
|
2957
2931
|
"expanded": false,
|
|
2958
2932
|
"items": [
|
|
2959
2933
|
"accounts[].ervDevices[].name",
|
|
2960
|
-
"accounts[].ervDevices[].holidayModeSupport"
|
|
2961
|
-
"accounts[].ervDevices[].refreshInterval"
|
|
2934
|
+
"accounts[].ervDevices[].holidayModeSupport"
|
|
2962
2935
|
],
|
|
2963
2936
|
"condition": {
|
|
2964
2937
|
"functionBody": "return model.accounts[arrayIndices[0]].ervDevices[arrayIndices[1]].displayType > 0;"
|
package/homebridge-ui/server.js
CHANGED
|
@@ -17,8 +17,7 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
17
17
|
const accountName = account.name;
|
|
18
18
|
const accountFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
|
|
19
19
|
const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
|
|
20
|
-
const
|
|
21
|
-
const melCloud = account.type === 'melcloud' ? new MelCloud(account, accountFile, buildingsFile, devicesFile) : new MelCloudHome(account, accountFile, buildingsFile, devicesFile);
|
|
20
|
+
const melCloud = account.type === 'melcloud' ? new MelCloud(account, accountFile, buildingsFile) : new MelCloudHome(account, accountFile, buildingsFile);
|
|
22
21
|
|
|
23
22
|
try {
|
|
24
23
|
const accountInfo = await melCloud.connect();
|
package/index.js
CHANGED
|
@@ -74,10 +74,9 @@ class MelCloudPlatform {
|
|
|
74
74
|
//define directory and file paths
|
|
75
75
|
const accountFile = `${prefDir}/${accountName}_Account`;
|
|
76
76
|
const buildingsFile = `${prefDir}/${accountName}_Buildings`;
|
|
77
|
-
const devicesFile = `${prefDir}/${accountName}_Devices`;
|
|
78
77
|
|
|
79
78
|
//set account refresh interval
|
|
80
|
-
const
|
|
79
|
+
const accountRefreshInterval = (account.refreshInterval ?? 120) * 1000
|
|
81
80
|
|
|
82
81
|
try {
|
|
83
82
|
//create impulse generator
|
|
@@ -89,12 +88,12 @@ class MelCloudPlatform {
|
|
|
89
88
|
let timmers = []
|
|
90
89
|
switch (account.type) {
|
|
91
90
|
case 'melcloud':
|
|
92
|
-
timmers = [{ name: 'checkDevicesList', sampling:
|
|
93
|
-
melcloud = new MelCloud(account, accountFile, buildingsFile,
|
|
91
|
+
timmers = [{ name: 'checkDevicesList', sampling: accountRefreshInterval }];
|
|
92
|
+
melcloud = new MelCloud(account, accountFile, buildingsFile, true);
|
|
94
93
|
break;
|
|
95
94
|
case 'melcloudhome':
|
|
96
95
|
timmers = [{ name: 'connect', sampling: 3300000 }, { name: 'checkDevicesList', sampling: 3000 }];
|
|
97
|
-
melcloud = new MelCloudHome(account, accountFile, buildingsFile,
|
|
96
|
+
melcloud = new MelCloudHome(account, accountFile, buildingsFile, true);
|
|
98
97
|
break;
|
|
99
98
|
default:
|
|
100
99
|
if (logLevel.warn) log.warn(`Unknown account type: ${account.type}.`);
|
|
@@ -118,21 +117,22 @@ class MelCloudPlatform {
|
|
|
118
117
|
if (logLevel.error) log.error(`${accountName}, Connect error: ${error.message ?? error}`);
|
|
119
118
|
return;
|
|
120
119
|
}
|
|
121
|
-
if (logLevel.success) log.success(accountInfo.Info);
|
|
120
|
+
if (logLevel.success) log.success(`${accountName}, ${accountInfo.Info}`);
|
|
122
121
|
|
|
123
122
|
//check devices list
|
|
124
|
-
let
|
|
123
|
+
let melcloudDevicesList;
|
|
125
124
|
try {
|
|
126
|
-
|
|
127
|
-
if (!
|
|
128
|
-
if (logLevel.warn) log.warn(`${accountName}, ${
|
|
125
|
+
melcloudDevicesList = await melcloud.checkDevicesList();
|
|
126
|
+
if (!melcloudDevicesList.State) {
|
|
127
|
+
if (logLevel.warn) log.warn(`${accountName}, ${melcloudDevicesList.Info}`);
|
|
129
128
|
return;
|
|
130
129
|
}
|
|
131
130
|
} catch (error) {
|
|
132
131
|
if (logLevel.error) log.error(`${accountName}, Check devices list error: ${error.message ?? error}`);
|
|
133
132
|
return;
|
|
134
133
|
}
|
|
135
|
-
if (logLevel.debug) log.info(
|
|
134
|
+
if (logLevel.debug) log.info(melcloudDevicesList.Info);
|
|
135
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
136
136
|
|
|
137
137
|
//configured devices
|
|
138
138
|
const ataDevices = (account.ataDevices || []).filter(device => device.id != null && String(device.id) !== '0');
|
|
@@ -144,14 +144,13 @@ class MelCloudPlatform {
|
|
|
144
144
|
for (const [index, device] of devices.entries()) {
|
|
145
145
|
//chack device from config exist on melcloud
|
|
146
146
|
const displayType = device.displayType > 0;
|
|
147
|
-
const deviceExistInMelCloud =
|
|
147
|
+
const deviceExistInMelCloud = melcloudDevicesList.Devices.some(dev => dev.DeviceID === device.id);
|
|
148
148
|
if (!deviceExistInMelCloud || !displayType) continue;
|
|
149
149
|
|
|
150
150
|
device.id = String(device.id);
|
|
151
151
|
const deviceName = device.name;
|
|
152
152
|
const deviceType = device.type;
|
|
153
153
|
const deviceTypeString = device.typeString;
|
|
154
|
-
const deviceRefreshInterval = (device.refreshInterval ?? 5) * 1000;
|
|
155
154
|
const defaultTempsFile = `${prefDir}/${accountName}_${device.id}_Temps`;
|
|
156
155
|
|
|
157
156
|
// set rest ful port
|
|
@@ -179,15 +178,15 @@ class MelCloudPlatform {
|
|
|
179
178
|
let configuredDevice;
|
|
180
179
|
switch (deviceType) {
|
|
181
180
|
case 0: //ATA
|
|
182
|
-
configuredDevice = new DeviceAta(api, account, device,
|
|
181
|
+
configuredDevice = new DeviceAta(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
|
|
183
182
|
break;
|
|
184
183
|
case 1: //ATW
|
|
185
|
-
configuredDevice = new DeviceAtw(api, account, device,
|
|
184
|
+
configuredDevice = new DeviceAtw(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
|
|
186
185
|
break;
|
|
187
186
|
case 2:
|
|
188
187
|
break;
|
|
189
188
|
case 3: //ERV
|
|
190
|
-
configuredDevice = new DeviceErv(api, account, device,
|
|
189
|
+
configuredDevice = new DeviceErv(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
|
|
191
190
|
break;
|
|
192
191
|
default:
|
|
193
192
|
if (logLevel.warn) log.warn(`${accountName}, ${deviceTypeString}, ${deviceName}, unknown device: ${deviceType}.`);
|
|
@@ -208,11 +207,11 @@ class MelCloudPlatform {
|
|
|
208
207
|
}
|
|
209
208
|
}
|
|
210
209
|
|
|
211
|
-
//start account impulse generator
|
|
212
|
-
await melcloud.impulseGenerator.state(true, timmers, false);
|
|
213
|
-
|
|
214
210
|
//stop start impulse generator
|
|
215
211
|
await impulseGenerator.state(false);
|
|
212
|
+
|
|
213
|
+
//start account impulse generator
|
|
214
|
+
await melcloud.impulseGenerator.state(true, timmers, false);
|
|
216
215
|
} catch (error) {
|
|
217
216
|
if (logLevel.error) log.error(`${accountName}, Start impulse generator error, ${error.message ?? error}, trying again.`);
|
|
218
217
|
}
|
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.5
|
|
4
|
+
"version": "4.3.5",
|
|
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
|
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, AirConditioner } from './constants.js';
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceAta extends EventEmitter {
|
|
10
|
-
constructor(api, account, device,
|
|
10
|
+
constructor(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -18,6 +18,7 @@ class DeviceAta extends EventEmitter {
|
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
20
|
this.melcloud = melcloud;
|
|
21
|
+
this.melcloudDevicesList = melcloudDevicesList;
|
|
21
22
|
this.account = account;
|
|
22
23
|
this.accountType = account.type;
|
|
23
24
|
this.accountName = account.name;
|
|
@@ -49,7 +50,6 @@ class DeviceAta extends EventEmitter {
|
|
|
49
50
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
50
51
|
|
|
51
52
|
//files
|
|
52
|
-
this.devicesFile = devicesFile;
|
|
53
53
|
this.defaultTempsFile = defaultTempsFile;
|
|
54
54
|
this.accountInfo = accountInfo;
|
|
55
55
|
this.accountFile = accountFile;
|
|
@@ -1321,7 +1321,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1321
1321
|
async start() {
|
|
1322
1322
|
try {
|
|
1323
1323
|
//melcloud device
|
|
1324
|
-
this.melCloudAta = new MelCloudAta(this.account, this.device, this.
|
|
1324
|
+
this.melCloudAta = new MelCloudAta(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
|
|
1325
1325
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1326
1326
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1327
1327
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
|
@@ -1878,9 +1878,10 @@ class DeviceAta extends EventEmitter {
|
|
|
1878
1878
|
if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
|
|
1879
1879
|
|
|
1880
1880
|
//check state
|
|
1881
|
-
await this.melCloudAta.
|
|
1881
|
+
await this.melCloudAta.checkState(this.melcloudDevicesList);
|
|
1882
1882
|
|
|
1883
1883
|
//prepare accessory
|
|
1884
|
+
await new Promise(r => setTimeout(r, 5000));
|
|
1884
1885
|
const accessory = await this.prepareAccessory();
|
|
1885
1886
|
return accessory;
|
|
1886
1887
|
} catch (error) {
|
package/src/deviceatw.js
CHANGED
|
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, HeatPump } from './constants.js';
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceAtw extends EventEmitter {
|
|
10
|
-
constructor(api, account, device,
|
|
10
|
+
constructor(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -18,6 +18,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
20
|
this.melcloud = melcloud;
|
|
21
|
+
this.melcloudDevicesList = melcloudDevicesList;
|
|
21
22
|
this.account = account;
|
|
22
23
|
this.accountType = account.type;
|
|
23
24
|
this.accountName = account.name;
|
|
@@ -53,7 +54,6 @@ class DeviceAtw extends EventEmitter {
|
|
|
53
54
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
54
55
|
|
|
55
56
|
//files
|
|
56
|
-
this.devicesFile = devicesFile;
|
|
57
57
|
this.defaultTempsFile = defaultTempsFile;
|
|
58
58
|
this.accountInfo = accountInfo;
|
|
59
59
|
this.accountFile = accountFile;
|
|
@@ -1567,7 +1567,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1567
1567
|
async start() {
|
|
1568
1568
|
try {
|
|
1569
1569
|
//melcloud device
|
|
1570
|
-
this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.
|
|
1570
|
+
this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
|
|
1571
1571
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion, supportsHotWaterTank, supportsZone2) => {
|
|
1572
1572
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1573
1573
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
|
@@ -2307,9 +2307,10 @@ class DeviceAtw extends EventEmitter {
|
|
|
2307
2307
|
if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
|
|
2308
2308
|
|
|
2309
2309
|
//check state
|
|
2310
|
-
await this.
|
|
2310
|
+
await this.melCloudAta.checkState(this.melcloudDevicesList);
|
|
2311
2311
|
|
|
2312
2312
|
//prepare accessory
|
|
2313
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
2313
2314
|
const accessory = await this.prepareAccessory();
|
|
2314
2315
|
return accessory;
|
|
2315
2316
|
} catch (error) {
|
package/src/deviceerv.js
CHANGED
|
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, Ventilation } from './constants.js';
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceErv extends EventEmitter {
|
|
10
|
-
constructor(api, account, device,
|
|
10
|
+
constructor(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -18,6 +18,7 @@ class DeviceErv extends EventEmitter {
|
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
20
|
this.melcloud = melcloud;
|
|
21
|
+
this.melcloudDevicesList = melcloudDevicesList;
|
|
21
22
|
this.account = account;
|
|
22
23
|
this.accountType = account.type;
|
|
23
24
|
this.accountName = account.name;
|
|
@@ -45,7 +46,6 @@ class DeviceErv extends EventEmitter {
|
|
|
45
46
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
46
47
|
|
|
47
48
|
//files
|
|
48
|
-
this.devicesFile = devicesFile;
|
|
49
49
|
this.defaultTempsFile = defaultTempsFile;
|
|
50
50
|
this.accountInfo = accountInfo;
|
|
51
51
|
this.accountFile = accountFile;
|
|
@@ -1121,7 +1121,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1121
1121
|
async start() {
|
|
1122
1122
|
try {
|
|
1123
1123
|
//melcloud device
|
|
1124
|
-
this.melCloudErv = new MelCloudErv(this.account, this.device, this.
|
|
1124
|
+
this.melCloudErv = new MelCloudErv(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
|
|
1125
1125
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1126
1126
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1127
1127
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
|
@@ -1581,9 +1581,10 @@ class DeviceErv extends EventEmitter {
|
|
|
1581
1581
|
if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
|
|
1582
1582
|
|
|
1583
1583
|
//check state
|
|
1584
|
-
await this.
|
|
1584
|
+
await this.melCloudAta.checkState(this.melcloudDevicesList);
|
|
1585
1585
|
|
|
1586
1586
|
//prepare accessory
|
|
1587
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
1587
1588
|
const accessory = await this.prepareAccessory();
|
|
1588
1589
|
return accessory;
|
|
1589
1590
|
} catch (error) {
|
package/src/melcloud.js
CHANGED
|
@@ -5,7 +5,7 @@ import Functions from './functions.js';
|
|
|
5
5
|
import { ApiUrls } from './constants.js';
|
|
6
6
|
|
|
7
7
|
class MelCloud extends EventEmitter {
|
|
8
|
-
constructor(account, accountFile, buildingsFile,
|
|
8
|
+
constructor(account, accountFile, buildingsFile, pluginStart = false) {
|
|
9
9
|
super();
|
|
10
10
|
this.accountType = account.type;
|
|
11
11
|
this.user = account.user;
|
|
@@ -14,9 +14,9 @@ class MelCloud extends EventEmitter {
|
|
|
14
14
|
this.logWarn = account.log?.warn;
|
|
15
15
|
this.logError = account.log?.error;
|
|
16
16
|
this.logDebug = account.log?.debug;
|
|
17
|
+
|
|
17
18
|
this.accountFile = accountFile;
|
|
18
19
|
this.buildingsFile = buildingsFile;
|
|
19
|
-
this.devicesFile = devicesFile;
|
|
20
20
|
this.headers = {};
|
|
21
21
|
|
|
22
22
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
@@ -112,9 +112,6 @@ class MelCloud extends EventEmitter {
|
|
|
112
112
|
devicesList.Headers = this.headers;
|
|
113
113
|
this.emit('devicesList', devicesList);
|
|
114
114
|
|
|
115
|
-
await this.functions.saveData(this.devicesFile, devicesList);
|
|
116
|
-
if (this.logDebug) this.emit('debug', `${devicesCount} devices saved`);
|
|
117
|
-
|
|
118
115
|
return devicesList;
|
|
119
116
|
} catch (error) {
|
|
120
117
|
throw new Error(`Check devices list error: ${error.message}`);
|
|
@@ -174,7 +171,7 @@ class MelCloud extends EventEmitter {
|
|
|
174
171
|
});
|
|
175
172
|
|
|
176
173
|
accountInfo.State = true;
|
|
177
|
-
accountInfo.Info = 'Connect
|
|
174
|
+
accountInfo.Info = 'Connect Success';
|
|
178
175
|
accountInfo.UseFahrenheit = loginData.UseFahrenheit;
|
|
179
176
|
accountInfo.Account = account;
|
|
180
177
|
await this.functions.saveData(this.accountFile, accountInfo);
|
package/src/melcloudata.js
CHANGED
|
@@ -4,7 +4,7 @@ import Functions from './functions.js';
|
|
|
4
4
|
import { ApiUrls, ApiUrlsHome, AirConditioner } from './constants.js';
|
|
5
5
|
|
|
6
6
|
class MelCloudAta extends EventEmitter {
|
|
7
|
-
constructor(account, device,
|
|
7
|
+
constructor(account, device, defaultTempsFile, accountFile, melcloud) {
|
|
8
8
|
super();
|
|
9
9
|
this.accountType = account.type;
|
|
10
10
|
this.logSuccess = account.log?.success;
|
|
@@ -14,9 +14,9 @@ class MelCloudAta extends EventEmitter {
|
|
|
14
14
|
this.restFulEnabled = account.restFul?.enable;
|
|
15
15
|
this.mqttEnabled = account.mqtt?.enable;
|
|
16
16
|
this.deviceId = device.id;
|
|
17
|
-
this.devicesFile = devicesFile;
|
|
18
17
|
this.defaultTempsFile = defaultTempsFile;
|
|
19
18
|
this.accountFile = accountFile;
|
|
19
|
+
|
|
20
20
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
21
21
|
.on('warn', warn => this.emit('warn', warn))
|
|
22
22
|
.on('error', error => this.emit('error', error))
|
|
@@ -24,7 +24,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
24
24
|
|
|
25
25
|
//set default values
|
|
26
26
|
this.deviceData = {};
|
|
27
|
-
this.headers = {}
|
|
27
|
+
this.headers = {}
|
|
28
28
|
|
|
29
29
|
let deviceData = null;
|
|
30
30
|
melcloud.on('devicesList', async (devicesData) => {
|
|
@@ -35,73 +35,63 @@ class MelCloudAta extends EventEmitter {
|
|
|
35
35
|
|
|
36
36
|
//update state
|
|
37
37
|
await this.updateState(deviceData);
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
//web cocket message
|
|
41
|
-
if (this.accountType === 'melcloudhome') {
|
|
38
|
+
}).on('webSocket', async (parsedMessage) => {
|
|
42
39
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (!this.functions.isValidValue(value)) continue;
|
|
64
|
-
|
|
65
|
-
//update holiday mode
|
|
66
|
-
if (key === 'HolidayMode') {
|
|
67
|
-
deviceData.HolidayMode.Enabled = value;
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
//update device settings
|
|
72
|
-
if (key in deviceData.Device) {
|
|
73
|
-
deviceData.Device[key] = value;
|
|
74
|
-
}
|
|
40
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
41
|
+
if (!messageData || !deviceData) return;
|
|
42
|
+
|
|
43
|
+
let updateState = false;
|
|
44
|
+
const unitId = messageData?.id;
|
|
45
|
+
switch (unitId) {
|
|
46
|
+
case this.deviceId:
|
|
47
|
+
const messageType = parsedMessage[0].messageType;
|
|
48
|
+
const settings = this.functions.parseArrayNameValue(messageData.settings);
|
|
49
|
+
switch (messageType) {
|
|
50
|
+
case 'unitStateChanged':
|
|
51
|
+
|
|
52
|
+
//update values
|
|
53
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
54
|
+
if (!this.functions.isValidValue(value)) continue;
|
|
55
|
+
|
|
56
|
+
//update holiday mode
|
|
57
|
+
if (key === 'HolidayMode') {
|
|
58
|
+
deviceData.HolidayMode.Enabled = value;
|
|
59
|
+
continue;
|
|
75
60
|
}
|
|
76
|
-
updateState = true;
|
|
77
|
-
break;
|
|
78
|
-
case 'unitHolidayModeTriggered':
|
|
79
|
-
deviceData.Device.Power = settings.Power;
|
|
80
|
-
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
81
|
-
deviceData.HolidayMode.Active = messageData.active;
|
|
82
|
-
updateState = true;
|
|
83
|
-
break;
|
|
84
|
-
case 'unitWifiSignalChanged':
|
|
85
|
-
deviceData.Rssi = messageData.rssi;
|
|
86
|
-
updateState = true;
|
|
87
|
-
break;
|
|
88
|
-
default:
|
|
89
|
-
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
break;
|
|
93
|
-
default:
|
|
94
|
-
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
61
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
62
|
+
//update device settings
|
|
63
|
+
if (key in deviceData.Device) {
|
|
64
|
+
deviceData.Device[key] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
updateState = true;
|
|
68
|
+
break;
|
|
69
|
+
case 'unitHolidayModeTriggered':
|
|
70
|
+
deviceData.Device.Power = settings.Power;
|
|
71
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
72
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
73
|
+
updateState = true;
|
|
74
|
+
break;
|
|
75
|
+
case 'unitWifiSignalChanged':
|
|
76
|
+
deviceData.Rssi = messageData.rssi;
|
|
77
|
+
updateState = true;
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//update state
|
|
90
|
+
if (updateState) await this.updateState(deviceData);
|
|
101
91
|
} catch (error) {
|
|
102
|
-
if (this.logError) this.emit('error', `
|
|
92
|
+
if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
|
|
103
93
|
}
|
|
104
|
-
}
|
|
94
|
+
});
|
|
105
95
|
}
|
|
106
96
|
|
|
107
97
|
async updateState(deviceData) {
|
|
@@ -177,6 +167,19 @@ class MelCloudAta extends EventEmitter {
|
|
|
177
167
|
};
|
|
178
168
|
};
|
|
179
169
|
|
|
170
|
+
async checkState(devicesData) {
|
|
171
|
+
try {
|
|
172
|
+
this.headers = devicesData.Headers;
|
|
173
|
+
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
174
|
+
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
175
|
+
await this.updateState(deviceData);
|
|
176
|
+
|
|
177
|
+
return true;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
throw new Error(`Chaeck state error: ${error.message}`);
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
180
183
|
async send(accountType, displayType, deviceData, flag, flagData) {
|
|
181
184
|
try {
|
|
182
185
|
let method = null
|
|
@@ -229,6 +232,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
229
232
|
data: payload
|
|
230
233
|
});
|
|
231
234
|
|
|
235
|
+
this.emit('deviceState', deviceData);
|
|
232
236
|
return true;
|
|
233
237
|
case "melcloudhome":
|
|
234
238
|
switch (flag) {
|
package/src/melcloudatw.js
CHANGED
|
@@ -4,7 +4,7 @@ import Functions from './functions.js';
|
|
|
4
4
|
import { ApiUrls, ApiUrlsHome, HeatPump } from './constants.js';
|
|
5
5
|
|
|
6
6
|
class MelCloudAtw extends EventEmitter {
|
|
7
|
-
constructor(account, device,
|
|
7
|
+
constructor(account, device, defaultTempsFile, accountFile, melcloud) {
|
|
8
8
|
super();
|
|
9
9
|
this.accountType = account.type;
|
|
10
10
|
this.logSuccess = account.log?.success;
|
|
@@ -14,9 +14,9 @@ class MelCloudAtw extends EventEmitter {
|
|
|
14
14
|
this.restFulEnabled = account.restFul?.enable;
|
|
15
15
|
this.mqttEnabled = account.mqtt?.enable;
|
|
16
16
|
this.deviceId = device.id;
|
|
17
|
-
this.devicesFile = devicesFile;
|
|
18
17
|
this.defaultTempsFile = defaultTempsFile;
|
|
19
18
|
this.accountFile = accountFile;
|
|
19
|
+
|
|
20
20
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
21
21
|
.on('warn', warn => this.emit('warn', warn))
|
|
22
22
|
.on('error', error => this.emit('error', error))
|
|
@@ -35,58 +35,59 @@ class MelCloudAtw extends EventEmitter {
|
|
|
35
35
|
|
|
36
36
|
//update state
|
|
37
37
|
await this.updateState(deviceData);
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
///web cocket message
|
|
41
|
-
if (this.accountType === 'melcloudhome') {
|
|
38
|
+
}).on('message', async (message) => {
|
|
42
39
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (parsedMessage.message === 'Forbidden') return;
|
|
40
|
+
const parsedMessage = JSON.parse(message);
|
|
41
|
+
const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
|
|
42
|
+
if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
43
|
+
if (parsedMessage.message === 'Forbidden') return;
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
46
|
+
if (!messageData || !deviceData) return;
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
let updateState = false;
|
|
49
|
+
const unitId = messageData?.id;
|
|
50
|
+
switch (unitId) {
|
|
51
|
+
case this.deviceId:
|
|
52
|
+
const messageType = parsedMessage[0].messageType;
|
|
53
|
+
switch (messageType) {
|
|
54
|
+
case 'unitStateChanged':
|
|
55
|
+
const settings = Object.fromEntries(
|
|
56
|
+
messageData.settings.map(({ name, value }) => {
|
|
57
|
+
let parsedValue = this.functions.convertValue(value);
|
|
58
|
+
return [name, parsedValue];
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
Object.assign(deviceData.Device, settings);
|
|
62
|
+
updateState = true;
|
|
63
|
+
break;
|
|
64
|
+
case 'unitHolidayModeTriggered':
|
|
65
|
+
deviceData.Device.Power = settings.Power;
|
|
66
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
67
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
68
|
+
updateState = true;
|
|
69
|
+
break;
|
|
70
|
+
case 'unitWifiSignalChanged':
|
|
71
|
+
deviceData.Rssi = messageData.rssi;
|
|
72
|
+
updateState = true;
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
84
|
+
//update state
|
|
85
|
+
if (updateState) await this.updateState(deviceData);
|
|
85
86
|
} catch (error) {
|
|
86
|
-
if (this.logError) this.emit('error', `
|
|
87
|
-
this.cleanupSocket();
|
|
87
|
+
if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
|
|
88
88
|
}
|
|
89
|
-
}
|
|
89
|
+
});
|
|
90
|
+
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
async updateState(deviceData) {
|
|
@@ -156,6 +157,19 @@ class MelCloudAtw extends EventEmitter {
|
|
|
156
157
|
};
|
|
157
158
|
};
|
|
158
159
|
|
|
160
|
+
async checkState(devicesData) {
|
|
161
|
+
try {
|
|
162
|
+
this.headers = devicesData.Headers;
|
|
163
|
+
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
164
|
+
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
165
|
+
await this.updateState(deviceData);
|
|
166
|
+
|
|
167
|
+
return true;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
throw new Error(`Chaeck state error: ${error.message}`);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
159
173
|
async send(accountType, displayType, deviceData, flag, flagData) {
|
|
160
174
|
try {
|
|
161
175
|
|
|
@@ -223,6 +237,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
223
237
|
data: payload
|
|
224
238
|
});
|
|
225
239
|
|
|
240
|
+
this.emit('deviceState', deviceData);
|
|
226
241
|
return true;
|
|
227
242
|
case "melcloudhome":
|
|
228
243
|
switch (flag) {
|
package/src/melclouderv.js
CHANGED
|
@@ -4,7 +4,7 @@ import Functions from './functions.js';
|
|
|
4
4
|
import { ApiUrls, ApiUrlsHome, Ventilation } from './constants.js';
|
|
5
5
|
|
|
6
6
|
class MelCloudErv extends EventEmitter {
|
|
7
|
-
constructor(account, device,
|
|
7
|
+
constructor(account, device, defaultTempsFile, accountFile, melcloud) {
|
|
8
8
|
super();
|
|
9
9
|
this.accountType = account.type;
|
|
10
10
|
this.logSuccess = account.log?.success;
|
|
@@ -14,9 +14,9 @@ class MelCloudErv extends EventEmitter {
|
|
|
14
14
|
this.restFulEnabled = account.restFul?.enable;
|
|
15
15
|
this.mqttEnabled = account.mqtt?.enable;
|
|
16
16
|
this.deviceId = device.id;
|
|
17
|
-
this.devicesFile = devicesFile;
|
|
18
17
|
this.defaultTempsFile = defaultTempsFile;
|
|
19
18
|
this.accountFile = accountFile;
|
|
19
|
+
|
|
20
20
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
21
21
|
.on('warn', warn => this.emit('warn', warn))
|
|
22
22
|
.on('error', error => this.emit('error', error))
|
|
@@ -35,14 +35,68 @@ class MelCloudErv extends EventEmitter {
|
|
|
35
35
|
|
|
36
36
|
//update state
|
|
37
37
|
await this.updateState(deviceData);
|
|
38
|
-
})
|
|
38
|
+
}).on('webSocket', async (parsedMessage) => {
|
|
39
|
+
try {
|
|
40
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
41
|
+
if (!messageData || !deviceData) return;
|
|
42
|
+
|
|
43
|
+
let updateState = false;
|
|
44
|
+
const unitId = messageData?.id;
|
|
45
|
+
switch (unitId) {
|
|
46
|
+
case this.deviceId:
|
|
47
|
+
const messageType = parsedMessage[0].messageType;
|
|
48
|
+
const settings = this.functions.parseArrayNameValue(messageData.settings);
|
|
49
|
+
switch (messageType) {
|
|
50
|
+
case 'unitStateChanged':
|
|
51
|
+
|
|
52
|
+
//update values
|
|
53
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
54
|
+
if (!this.functions.isValidValue(value)) continue;
|
|
55
|
+
|
|
56
|
+
//update holiday mode
|
|
57
|
+
if (key === 'HolidayMode') {
|
|
58
|
+
deviceData.HolidayMode.Enabled = value;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//update device settings
|
|
63
|
+
if (key in deviceData.Device) {
|
|
64
|
+
deviceData.Device[key] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
updateState = true;
|
|
68
|
+
break;
|
|
69
|
+
case 'unitHolidayModeTriggered':
|
|
70
|
+
deviceData.Device.Power = settings.Power;
|
|
71
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
72
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
73
|
+
updateState = true;
|
|
74
|
+
break;
|
|
75
|
+
case 'unitWifiSignalChanged':
|
|
76
|
+
deviceData.Rssi = messageData.rssi;
|
|
77
|
+
updateState = true;
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//update state
|
|
90
|
+
if (updateState) await this.updateState(deviceData);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
39
95
|
}
|
|
40
96
|
|
|
41
97
|
async updateState(deviceData) {
|
|
42
98
|
try {
|
|
43
99
|
if (this.accountType === 'melcloudhome') {
|
|
44
|
-
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
45
|
-
|
|
46
100
|
//read default temps
|
|
47
101
|
const temps = await this.functions.readData(this.defaultTempsFile, true);
|
|
48
102
|
deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
|
|
@@ -106,6 +160,19 @@ class MelCloudErv extends EventEmitter {
|
|
|
106
160
|
};
|
|
107
161
|
};
|
|
108
162
|
|
|
163
|
+
async checkState(devicesData) {
|
|
164
|
+
try {
|
|
165
|
+
this.headers = devicesData.Headers;
|
|
166
|
+
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
167
|
+
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
168
|
+
await this.updateState(deviceData);
|
|
169
|
+
|
|
170
|
+
return true;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
throw new Error(`Chaeck state error: ${error.message}`);
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
109
176
|
async send(accountType, displayType, deviceData, flag, flagData) {
|
|
110
177
|
try {
|
|
111
178
|
let method = null
|
|
@@ -174,6 +241,7 @@ class MelCloudErv extends EventEmitter {
|
|
|
174
241
|
data: payload
|
|
175
242
|
});
|
|
176
243
|
|
|
244
|
+
this.emit('deviceState', deviceData);
|
|
177
245
|
return true;
|
|
178
246
|
case "melcloudhome":
|
|
179
247
|
switch (flag) {
|
package/src/melcloudhome.js
CHANGED
|
@@ -11,7 +11,7 @@ import { ApiUrlsHome, LanguageLocaleMap } from './constants.js';
|
|
|
11
11
|
const execPromise = promisify(exec);
|
|
12
12
|
|
|
13
13
|
class MelCloudHome extends EventEmitter {
|
|
14
|
-
constructor(account, accountFile, buildingsFile,
|
|
14
|
+
constructor(account, accountFile, buildingsFile, pluginStart = false) {
|
|
15
15
|
super();
|
|
16
16
|
this.accountType = account.type;
|
|
17
17
|
this.user = account.user;
|
|
@@ -23,7 +23,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
23
23
|
this.logDebug = account.log?.debug;
|
|
24
24
|
this.accountFile = accountFile;
|
|
25
25
|
this.buildingsFile = buildingsFile;
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
this.headers = {};
|
|
28
28
|
this.webSocketOptions = {};
|
|
29
29
|
this.socket = null;
|
|
@@ -252,8 +252,10 @@ class MelCloudHome extends EventEmitter {
|
|
|
252
252
|
})
|
|
253
253
|
.on('message', (message) => {
|
|
254
254
|
const parsedMessage = JSON.parse(message);
|
|
255
|
-
|
|
256
|
-
if (
|
|
255
|
+
if (this.logDebug) this.emit('debug', `Incoming message: ${JSON.stringify(parsedMessage, null, 2)}`);
|
|
256
|
+
if (parsedMessage.message === 'Forbidden') return;
|
|
257
|
+
|
|
258
|
+
this.emit('webSocket', parsedMessage);
|
|
257
259
|
});
|
|
258
260
|
} catch (error) {
|
|
259
261
|
if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
|
|
@@ -266,12 +268,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
266
268
|
devicesList.Devices = devices;
|
|
267
269
|
devicesList.Scenes = scenes;
|
|
268
270
|
devicesList.Headers = this.headers;
|
|
269
|
-
devicesList.WebSocket = this.socket;
|
|
270
271
|
this.emit('devicesList', devicesList);
|
|
271
272
|
|
|
272
|
-
await this.functions.saveData(this.devicesFile, devicesList);
|
|
273
|
-
if (this.logDebug) this.emit('debug', `${devicesCount} devices saved`);
|
|
274
|
-
|
|
275
273
|
return devicesList;
|
|
276
274
|
} catch (error) {
|
|
277
275
|
throw new Error(`Check devices list error: ${error.message}`);
|
|
@@ -442,7 +440,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
442
440
|
};
|
|
443
441
|
|
|
444
442
|
accountInfo.State = true;
|
|
445
|
-
accountInfo.Info = 'Connect
|
|
443
|
+
accountInfo.Info = 'Connect Success';
|
|
446
444
|
await this.functions.saveData(this.accountFile, accountInfo);
|
|
447
445
|
|
|
448
446
|
return accountInfo;
|