homebridge-melcloud-control 4.3.5-beta.17 → 4.3.5-beta.19
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/index.js +12 -14
- package/package.json +1 -1
- package/src/deviceata.js +2 -3
- package/src/deviceatw.js +2 -3
- package/src/deviceerv.js +2 -3
- package/src/melcloud.js +3 -6
- package/src/melcloudata.js +55 -56
- package/src/melcloudatw.js +49 -48
- package/src/melclouderv.js +59 -5
- package/src/melcloudhome.js +5 -8
package/index.js
CHANGED
|
@@ -74,7 +74,6 @@ 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
79
|
const refreshInterval = (account.refreshInterval ?? 120) * 1000
|
|
@@ -90,11 +89,11 @@ class MelCloudPlatform {
|
|
|
90
89
|
switch (account.type) {
|
|
91
90
|
case 'melcloud':
|
|
92
91
|
timmers = [{ name: 'checkDevicesList', sampling: refreshInterval }];
|
|
93
|
-
melcloud = new MelCloud(account, accountFile, buildingsFile,
|
|
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,21 @@ 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);
|
|
136
135
|
|
|
137
136
|
//start account impulse generator
|
|
138
137
|
await melcloud.impulseGenerator.state(true, timmers, false);
|
|
@@ -147,14 +146,13 @@ class MelCloudPlatform {
|
|
|
147
146
|
for (const [index, device] of devices.entries()) {
|
|
148
147
|
//chack device from config exist on melcloud
|
|
149
148
|
const displayType = device.displayType > 0;
|
|
150
|
-
const deviceExistInMelCloud =
|
|
149
|
+
const deviceExistInMelCloud = melcloudDevicesList.Devices.some(dev => dev.DeviceID === device.id);
|
|
151
150
|
if (!deviceExistInMelCloud || !displayType) continue;
|
|
152
151
|
|
|
153
152
|
device.id = String(device.id);
|
|
154
153
|
const deviceName = device.name;
|
|
155
154
|
const deviceType = device.type;
|
|
156
155
|
const deviceTypeString = device.typeString;
|
|
157
|
-
const deviceRefreshInterval = (device.refreshInterval ?? 5) * 1000;
|
|
158
156
|
const defaultTempsFile = `${prefDir}/${accountName}_${device.id}_Temps`;
|
|
159
157
|
|
|
160
158
|
// set rest ful port
|
|
@@ -182,15 +180,15 @@ class MelCloudPlatform {
|
|
|
182
180
|
let configuredDevice;
|
|
183
181
|
switch (deviceType) {
|
|
184
182
|
case 0: //ATA
|
|
185
|
-
configuredDevice = new DeviceAta(api, account, device,
|
|
183
|
+
configuredDevice = new DeviceAta(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
|
|
186
184
|
break;
|
|
187
185
|
case 1: //ATW
|
|
188
|
-
configuredDevice = new DeviceAtw(api, account, device,
|
|
186
|
+
configuredDevice = new DeviceAtw(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
|
|
189
187
|
break;
|
|
190
188
|
case 2:
|
|
191
189
|
break;
|
|
192
190
|
case 3: //ERV
|
|
193
|
-
configuredDevice = new DeviceErv(api, account, device,
|
|
191
|
+
configuredDevice = new DeviceErv(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
|
|
194
192
|
break;
|
|
195
193
|
default:
|
|
196
194
|
if (logLevel.warn) log.warn(`${accountName}, ${deviceTypeString}, ${deviceName}, unknown device: ${deviceType}.`);
|
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-beta.
|
|
4
|
+
"version": "4.3.5-beta.19",
|
|
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) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -49,7 +49,6 @@ class DeviceAta extends EventEmitter {
|
|
|
49
49
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
50
50
|
|
|
51
51
|
//files
|
|
52
|
-
this.devicesFile = devicesFile;
|
|
53
52
|
this.defaultTempsFile = defaultTempsFile;
|
|
54
53
|
this.accountInfo = accountInfo;
|
|
55
54
|
this.accountFile = accountFile;
|
|
@@ -1321,7 +1320,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1321
1320
|
async start() {
|
|
1322
1321
|
try {
|
|
1323
1322
|
//melcloud device
|
|
1324
|
-
this.melCloudAta = new MelCloudAta(this.account, this.device, this.
|
|
1323
|
+
this.melCloudAta = new MelCloudAta(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
|
|
1325
1324
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1326
1325
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1327
1326
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
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) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -53,7 +53,6 @@ class DeviceAtw extends EventEmitter {
|
|
|
53
53
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
54
54
|
|
|
55
55
|
//files
|
|
56
|
-
this.devicesFile = devicesFile;
|
|
57
56
|
this.defaultTempsFile = defaultTempsFile;
|
|
58
57
|
this.accountInfo = accountInfo;
|
|
59
58
|
this.accountFile = accountFile;
|
|
@@ -1567,7 +1566,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1567
1566
|
async start() {
|
|
1568
1567
|
try {
|
|
1569
1568
|
//melcloud device
|
|
1570
|
-
this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.
|
|
1569
|
+
this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
|
|
1571
1570
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion, supportsHotWaterTank, supportsZone2) => {
|
|
1572
1571
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1573
1572
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
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) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -45,7 +45,6 @@ class DeviceErv extends EventEmitter {
|
|
|
45
45
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
46
46
|
|
|
47
47
|
//files
|
|
48
|
-
this.devicesFile = devicesFile;
|
|
49
48
|
this.defaultTempsFile = defaultTempsFile;
|
|
50
49
|
this.accountInfo = accountInfo;
|
|
51
50
|
this.accountFile = accountFile;
|
|
@@ -1121,7 +1120,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1121
1120
|
async start() {
|
|
1122
1121
|
try {
|
|
1123
1122
|
//melcloud device
|
|
1124
|
-
this.melCloudErv = new MelCloudErv(this.account, this.device, this.
|
|
1123
|
+
this.melCloudErv = new MelCloudErv(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
|
|
1125
1124
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1126
1125
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1127
1126
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
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, melcloudDevicesList) {
|
|
8
8
|
super();
|
|
9
9
|
this.accountType = account.type;
|
|
10
10
|
this.logSuccess = account.log?.success;
|
|
@@ -14,7 +14,6 @@ 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;
|
|
20
19
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
@@ -25,7 +24,8 @@ class MelCloudAta extends EventEmitter {
|
|
|
25
24
|
//set default values
|
|
26
25
|
this.deviceData = {};
|
|
27
26
|
this.headers = {};
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
if (!this.logDebug) this.emit('debug', `MELCloud: ${JSON.stringify(melcloud, null, 2)}`);
|
|
29
29
|
|
|
30
30
|
let deviceData = null;
|
|
31
31
|
melcloud.on('devicesList', async (devicesData) => {
|
|
@@ -36,65 +36,63 @@ class MelCloudAta extends EventEmitter {
|
|
|
36
36
|
|
|
37
37
|
//update state
|
|
38
38
|
await this.updateState(deviceData);
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!messageData || !deviceData) return;
|
|
44
|
-
|
|
45
|
-
let updateState = false;
|
|
46
|
-
const unitId = messageData?.id;
|
|
47
|
-
switch (unitId) {
|
|
48
|
-
case this.deviceId:
|
|
49
|
-
if (!this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
50
|
-
const messageType = parsedMessage[0].messageType;
|
|
51
|
-
const settings = this.functions.parseArrayNameValue(messageData.settings);
|
|
52
|
-
switch (messageType) {
|
|
53
|
-
case 'unitStateChanged':
|
|
39
|
+
}).on('webSocket', async (parsedMessage) => {
|
|
40
|
+
try {
|
|
41
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
42
|
+
if (!messageData || !deviceData) return;
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
44
|
+
let updateState = false;
|
|
45
|
+
const unitId = messageData?.id;
|
|
46
|
+
switch (unitId) {
|
|
47
|
+
case this.deviceId:
|
|
48
|
+
const messageType = parsedMessage[0].messageType;
|
|
49
|
+
const settings = this.functions.parseArrayNameValue(messageData.settings);
|
|
50
|
+
switch (messageType) {
|
|
51
|
+
case 'unitStateChanged':
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
53
|
+
//update values
|
|
54
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
55
|
+
if (!this.functions.isValidValue(value)) continue;
|
|
64
56
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
57
|
+
//update holiday mode
|
|
58
|
+
if (key === 'HolidayMode') {
|
|
59
|
+
deviceData.HolidayMode.Enabled = value;
|
|
60
|
+
continue;
|
|
69
61
|
}
|
|
70
|
-
updateState = true;
|
|
71
|
-
break;
|
|
72
|
-
case 'unitHolidayModeTriggered':
|
|
73
|
-
deviceData.Device.Power = settings.Power;
|
|
74
|
-
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
75
|
-
deviceData.HolidayMode.Active = messageData.active;
|
|
76
|
-
updateState = true;
|
|
77
|
-
break;
|
|
78
|
-
case 'unitWifiSignalChanged':
|
|
79
|
-
deviceData.Rssi = messageData.rssi;
|
|
80
|
-
updateState = true;
|
|
81
|
-
break;
|
|
82
|
-
default:
|
|
83
|
-
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
break;
|
|
87
|
-
default:
|
|
88
|
-
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
62
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
63
|
+
//update device settings
|
|
64
|
+
if (key in deviceData.Device) {
|
|
65
|
+
deviceData.Device[key] = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
updateState = true;
|
|
69
|
+
break;
|
|
70
|
+
case 'unitHolidayModeTriggered':
|
|
71
|
+
deviceData.Device.Power = settings.Power;
|
|
72
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
73
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
74
|
+
updateState = true;
|
|
75
|
+
break;
|
|
76
|
+
case 'unitWifiSignalChanged':
|
|
77
|
+
deviceData.Rssi = messageData.rssi;
|
|
78
|
+
updateState = true;
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
87
|
+
return;
|
|
96
88
|
}
|
|
97
|
-
|
|
89
|
+
|
|
90
|
+
//update state
|
|
91
|
+
if (updateState) await this.updateState(deviceData);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
async updateState(deviceData) {
|
|
@@ -222,6 +220,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
222
220
|
data: payload
|
|
223
221
|
});
|
|
224
222
|
|
|
223
|
+
this.emit('deviceState', deviceData);
|
|
225
224
|
return true;
|
|
226
225
|
case "melcloudhome":
|
|
227
226
|
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, melcloudDevicesList) {
|
|
8
8
|
super();
|
|
9
9
|
this.accountType = account.type;
|
|
10
10
|
this.logSuccess = account.log?.success;
|
|
@@ -14,7 +14,6 @@ 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;
|
|
20
19
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
@@ -35,58 +34,59 @@ class MelCloudAtw extends EventEmitter {
|
|
|
35
34
|
|
|
36
35
|
//update state
|
|
37
36
|
await this.updateState(deviceData);
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
///web cocket message
|
|
41
|
-
if (this.accountType === 'melcloudhome') {
|
|
37
|
+
}).on('message', async (message) => {
|
|
42
38
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (parsedMessage.message === 'Forbidden') return;
|
|
39
|
+
const parsedMessage = JSON.parse(message);
|
|
40
|
+
const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
|
|
41
|
+
if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
42
|
+
if (parsedMessage.message === 'Forbidden') return;
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
45
|
+
if (!messageData || !deviceData) return;
|
|
51
46
|
|
|
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
|
-
|
|
47
|
+
let updateState = false;
|
|
48
|
+
const unitId = messageData?.id;
|
|
49
|
+
switch (unitId) {
|
|
50
|
+
case this.deviceId:
|
|
51
|
+
const messageType = parsedMessage[0].messageType;
|
|
52
|
+
switch (messageType) {
|
|
53
|
+
case 'unitStateChanged':
|
|
54
|
+
const settings = Object.fromEntries(
|
|
55
|
+
messageData.settings.map(({ name, value }) => {
|
|
56
|
+
let parsedValue = this.functions.convertValue(value);
|
|
57
|
+
return [name, parsedValue];
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
Object.assign(deviceData.Device, settings);
|
|
61
|
+
updateState = true;
|
|
62
|
+
break;
|
|
63
|
+
case 'unitHolidayModeTriggered':
|
|
64
|
+
deviceData.Device.Power = settings.Power;
|
|
65
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
66
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
67
|
+
updateState = true;
|
|
68
|
+
break;
|
|
69
|
+
case 'unitWifiSignalChanged':
|
|
70
|
+
deviceData.Rssi = messageData.rssi;
|
|
71
|
+
updateState = true;
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
83
|
+
//update state
|
|
84
|
+
if (updateState) await this.updateState(deviceData);
|
|
85
85
|
} catch (error) {
|
|
86
|
-
if (this.logError) this.emit('error', `
|
|
87
|
-
this.cleanupSocket();
|
|
86
|
+
if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
|
|
88
87
|
}
|
|
89
|
-
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
async updateState(deviceData) {
|
|
@@ -223,6 +223,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
223
223
|
data: payload
|
|
224
224
|
});
|
|
225
225
|
|
|
226
|
+
this.emit('deviceState', deviceData);
|
|
226
227
|
return true;
|
|
227
228
|
case "melcloudhome":
|
|
228
229
|
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, melcloudDevicesList) {
|
|
8
8
|
super();
|
|
9
9
|
this.accountType = account.type;
|
|
10
10
|
this.logSuccess = account.log?.success;
|
|
@@ -14,7 +14,6 @@ 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;
|
|
20
19
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
@@ -35,14 +34,68 @@ class MelCloudErv extends EventEmitter {
|
|
|
35
34
|
|
|
36
35
|
//update state
|
|
37
36
|
await this.updateState(deviceData);
|
|
38
|
-
})
|
|
37
|
+
}).on('webSocket', async (parsedMessage) => {
|
|
38
|
+
try {
|
|
39
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
40
|
+
if (!messageData || !deviceData) return;
|
|
41
|
+
|
|
42
|
+
let updateState = false;
|
|
43
|
+
const unitId = messageData?.id;
|
|
44
|
+
switch (unitId) {
|
|
45
|
+
case this.deviceId:
|
|
46
|
+
const messageType = parsedMessage[0].messageType;
|
|
47
|
+
const settings = this.functions.parseArrayNameValue(messageData.settings);
|
|
48
|
+
switch (messageType) {
|
|
49
|
+
case 'unitStateChanged':
|
|
50
|
+
|
|
51
|
+
//update values
|
|
52
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
53
|
+
if (!this.functions.isValidValue(value)) continue;
|
|
54
|
+
|
|
55
|
+
//update holiday mode
|
|
56
|
+
if (key === 'HolidayMode') {
|
|
57
|
+
deviceData.HolidayMode.Enabled = value;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//update device settings
|
|
62
|
+
if (key in deviceData.Device) {
|
|
63
|
+
deviceData.Device[key] = value;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
updateState = true;
|
|
67
|
+
break;
|
|
68
|
+
case 'unitHolidayModeTriggered':
|
|
69
|
+
deviceData.Device.Power = settings.Power;
|
|
70
|
+
deviceData.HolidayMode.Enabled = settings.HolidayMode;
|
|
71
|
+
deviceData.HolidayMode.Active = messageData.active;
|
|
72
|
+
updateState = true;
|
|
73
|
+
break;
|
|
74
|
+
case 'unitWifiSignalChanged':
|
|
75
|
+
deviceData.Rssi = messageData.rssi;
|
|
76
|
+
updateState = true;
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//update state
|
|
89
|
+
if (updateState) await this.updateState(deviceData);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
39
94
|
}
|
|
40
95
|
|
|
41
96
|
async updateState(deviceData) {
|
|
42
97
|
try {
|
|
43
98
|
if (this.accountType === 'melcloudhome') {
|
|
44
|
-
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
45
|
-
|
|
46
99
|
//read default temps
|
|
47
100
|
const temps = await this.functions.readData(this.defaultTempsFile, true);
|
|
48
101
|
deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
|
|
@@ -174,6 +227,7 @@ class MelCloudErv extends EventEmitter {
|
|
|
174
227
|
data: payload
|
|
175
228
|
});
|
|
176
229
|
|
|
230
|
+
this.emit('deviceState', deviceData);
|
|
177
231
|
return true;
|
|
178
232
|
case "melcloudhome":
|
|
179
233
|
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;
|
|
@@ -253,7 +253,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
253
253
|
.on('message', (message) => {
|
|
254
254
|
const parsedMessage = JSON.parse(message);
|
|
255
255
|
const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
|
|
256
|
-
if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
256
|
+
if (!this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
257
257
|
if (parsedMessage.message === 'Forbidden') return;
|
|
258
258
|
|
|
259
259
|
this.emit('webSocket', parsedMessage);
|
|
@@ -269,10 +269,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
269
269
|
devicesList.Devices = devices;
|
|
270
270
|
devicesList.Scenes = scenes;
|
|
271
271
|
devicesList.Headers = this.headers;
|
|
272
|
-
this.emit('devicesList', devicesList)
|
|
273
|
-
|
|
274
|
-
await this.functions.saveData(this.devicesFile, devicesList);
|
|
275
|
-
if (this.logDebug) this.emit('debug', `${devicesCount} devices saved`);
|
|
272
|
+
this.emit('devicesList', devicesList);;
|
|
276
273
|
|
|
277
274
|
return devicesList;
|
|
278
275
|
} catch (error) {
|
|
@@ -444,7 +441,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
444
441
|
};
|
|
445
442
|
|
|
446
443
|
accountInfo.State = true;
|
|
447
|
-
accountInfo.Info = 'Connect
|
|
444
|
+
accountInfo.Info = 'Connect Success';
|
|
448
445
|
await this.functions.saveData(this.accountFile, accountInfo);
|
|
449
446
|
|
|
450
447
|
return accountInfo;
|