homebridge-melcloud-control 4.3.5-beta.17 → 4.3.5-beta.18
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 +5 -7
- 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 +2 -5
- package/src/melcloudata.js +53 -56
- package/src/melcloudatw.js +49 -48
- package/src/melclouderv.js +59 -5
- package/src/melcloudhome.js +4 -7
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}.`);
|
|
@@ -154,7 +153,6 @@ class MelCloudPlatform {
|
|
|
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);
|
|
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);
|
|
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);
|
|
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.18",
|
|
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}`);
|
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,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,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
25
24
|
//set default values
|
|
26
25
|
this.deviceData = {};
|
|
27
26
|
this.headers = {};
|
|
28
|
-
this.firstRun = true;
|
|
29
27
|
|
|
30
28
|
let deviceData = null;
|
|
31
29
|
melcloud.on('devicesList', async (devicesData) => {
|
|
@@ -36,65 +34,63 @@ class MelCloudAta extends EventEmitter {
|
|
|
36
34
|
|
|
37
35
|
//update state
|
|
38
36
|
await this.updateState(deviceData);
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!messageData || !deviceData) return;
|
|
37
|
+
}).on('webSocket', async (parsedMessage) => {
|
|
38
|
+
try {
|
|
39
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
40
|
+
if (!messageData || !deviceData) return;
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
case 'unitStateChanged':
|
|
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':
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
//update values
|
|
52
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
53
|
+
if (!this.functions.isValidValue(value)) continue;
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
//update device settings
|
|
66
|
-
if (key in deviceData.Device) {
|
|
67
|
-
deviceData.Device[key] = value;
|
|
68
|
-
}
|
|
55
|
+
//update holiday mode
|
|
56
|
+
if (key === 'HolidayMode') {
|
|
57
|
+
deviceData.HolidayMode.Enabled = value;
|
|
58
|
+
continue;
|
|
69
59
|
}
|
|
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
60
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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;
|
|
96
86
|
}
|
|
97
|
-
|
|
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
|
+
});
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
async updateState(deviceData) {
|
|
@@ -222,6 +218,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
222
218
|
data: payload
|
|
223
219
|
});
|
|
224
220
|
|
|
221
|
+
this.emit('deviceState', deviceData);
|
|
225
222
|
return true;
|
|
226
223
|
case "melcloudhome":
|
|
227
224
|
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,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) {
|
|
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) {
|