homebridge-melcloud-control 4.7.6-beta.3 → 4.7.6-beta.4
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/homebridge-ui/public/index.html +5 -5
- package/homebridge-ui/server.js +5 -8
- package/index.js +25 -29
- package/package.json +1 -1
- package/src/deviceata.js +12 -13
- package/src/deviceatw.js +12 -13
- package/src/deviceerv.js +12 -13
- package/src/melcloud.js +24 -36
- package/src/melcloudata.js +3 -5
- package/src/melcloudatw.js +3 -5
- package/src/melclouderv.js +3 -5
- package/src/melcloudhome.js +34 -41
|
@@ -255,10 +255,10 @@
|
|
|
255
255
|
|
|
256
256
|
try {
|
|
257
257
|
const account = this.account;
|
|
258
|
-
const
|
|
258
|
+
const melCloudDevicesData = await homebridge.request('/connect', account);
|
|
259
259
|
|
|
260
|
-
if (!
|
|
261
|
-
updateInfo('info',
|
|
260
|
+
if (!melCloudDevicesData.State) {
|
|
261
|
+
updateInfo('info', melCloudDevicesData.Status, 'red');
|
|
262
262
|
document.getElementById('logIn').disabled = false;
|
|
263
263
|
homebridge.hideSpinner();
|
|
264
264
|
return;
|
|
@@ -272,10 +272,10 @@
|
|
|
272
272
|
// Prepare MELCloud data
|
|
273
273
|
const newInMelCloud = { ata: [], ataPresets: [], ataSchedules: [], ataScenes: [], atw: [], atwPresets: [], atwSchedules: [], atwScenes: [], erv: [], ervPresets: [], ervSchedules: [], ervScenes: [] };
|
|
274
274
|
const devicesInMelCloudByType = { ata: [], atw: [], erv: [] };
|
|
275
|
-
const scenesInMelCloud =
|
|
275
|
+
const scenesInMelCloud = melCloudDevicesData.Scenes ?? [];
|
|
276
276
|
|
|
277
277
|
// Split devices by type
|
|
278
|
-
const devices =
|
|
278
|
+
const devices = melCloudDevicesData.Devices;
|
|
279
279
|
for (const device of devices) {
|
|
280
280
|
if (device.Type === 0) devicesInMelCloudByType.ata.push(device);
|
|
281
281
|
if (device.Type === 1) devicesInMelCloudByType.atw.push(device);
|
package/homebridge-ui/server.js
CHANGED
|
@@ -14,17 +14,14 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
async start(account) {
|
|
17
|
-
const
|
|
18
|
-
const accountFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
|
|
19
|
-
const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
|
|
20
|
-
const melCloud = account.type === 'melcloud' ? new MelCloud(account, accountFile, buildingsFile) : new MelCloudHome(account, accountFile, buildingsFile);
|
|
17
|
+
const melCloudClass = account.type === 'melcloud' ? new MelCloud(account) : new MelCloudHome(account);
|
|
21
18
|
|
|
22
19
|
try {
|
|
23
|
-
const
|
|
24
|
-
if (!
|
|
20
|
+
const melCloudAccountData = await melCloudClass.connect();
|
|
21
|
+
if (!melCloudAccountData.State) return melCloudAccountData;
|
|
25
22
|
|
|
26
|
-
const
|
|
27
|
-
return
|
|
23
|
+
const melCloudDevicesData = await melCloudClass.checkDevicesList();
|
|
24
|
+
return melCloudDevicesData;
|
|
28
25
|
} catch (error) {
|
|
29
26
|
throw new Error(error);
|
|
30
27
|
}
|
package/index.js
CHANGED
|
@@ -64,59 +64,55 @@ class MelCloudPlatform {
|
|
|
64
64
|
log.info(`${name}, Config: ${JSON.stringify(safeConfig, null, 2)}`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
//define directory and file paths
|
|
68
|
-
const accountFile = `${prefDir}/${name}_Account`;
|
|
69
|
-
const buildingsFile = `${prefDir}/${name}_Buildings`;
|
|
70
|
-
|
|
71
67
|
try {
|
|
72
68
|
//create impulse generator
|
|
73
69
|
const impulseGenerator = new ImpulseGenerator()
|
|
74
70
|
.on('start', async () => {
|
|
75
71
|
try {
|
|
76
72
|
//melcloud account
|
|
77
|
-
let
|
|
73
|
+
let melCloudClass;
|
|
78
74
|
let timmers = []
|
|
79
75
|
switch (account.type) {
|
|
80
76
|
case 'melcloud':
|
|
81
77
|
timmers = [{ name: 'checkDevicesList', sampling: accountRefreshInterval }];
|
|
82
|
-
|
|
78
|
+
melCloudClass = new MelCloud(account, true);
|
|
83
79
|
break;
|
|
84
80
|
case 'melcloudhome':
|
|
85
81
|
timmers = [{ name: 'connect', sampling: 3300000 }, { name: 'checkDevicesList', sampling: 5000 }];
|
|
86
|
-
|
|
82
|
+
melCloudClass = new MelCloudHome(account, true);
|
|
87
83
|
break;
|
|
88
84
|
default:
|
|
89
85
|
if (logLevel.warn) log.warn(`Unknown account type: ${account.type}.`);
|
|
90
86
|
return;
|
|
91
87
|
}
|
|
92
|
-
|
|
88
|
+
melCloudClass.on('success', (msg) => logLevel.success && log.success(`${name}, ${msg}`))
|
|
93
89
|
.on('info', (msg) => log.info(`${name}, ${msg}`))
|
|
94
90
|
.on('debug', (msg) => log.info(`${name}, debug: ${msg}`))
|
|
95
91
|
.on('warn', (msg) => log.warn(`${name}, ${msg}`))
|
|
96
92
|
.on('error', (msg) => log.error(`${name}, ${msg}`));
|
|
97
93
|
|
|
98
94
|
//connect
|
|
99
|
-
const
|
|
100
|
-
if (!
|
|
101
|
-
if (logLevel.warn) log.warn(`${name}, ${
|
|
95
|
+
const melCloudAccountData = await melCloudClass.connect();
|
|
96
|
+
if (!melCloudAccountData?.State) {
|
|
97
|
+
if (logLevel.warn) log.warn(`${name}, ${melCloudAccountData.Status}`);
|
|
102
98
|
return;
|
|
103
99
|
}
|
|
104
|
-
if (logLevel.success) log.success(`${name}, ${
|
|
100
|
+
if (logLevel.success) log.success(`${name}, ${melCloudAccountData.Status}`);
|
|
105
101
|
|
|
106
102
|
//check devices list
|
|
107
|
-
const
|
|
108
|
-
if (!
|
|
109
|
-
if (logLevel.warn) log.warn(`${name}, ${
|
|
103
|
+
const melCloudDevicesData = await melCloudClass.checkDevicesList();
|
|
104
|
+
if (!melCloudDevicesData.State) {
|
|
105
|
+
if (logLevel.warn) log.warn(`${name}, ${melCloudDevicesData.Status}`);
|
|
110
106
|
return;
|
|
111
107
|
}
|
|
112
|
-
if (logLevel.debug) log.info(
|
|
108
|
+
if (logLevel.debug) log.info(melCloudDevicesData.Status);
|
|
113
109
|
await new Promise(r => setTimeout(r, 1000));
|
|
114
110
|
|
|
115
111
|
//start account impulse generator
|
|
116
|
-
await
|
|
112
|
+
await melCloudClass.impulseGenerator.state(true, timmers, false);
|
|
117
113
|
|
|
118
114
|
//filter configured devices
|
|
119
|
-
const devicesIds = (
|
|
115
|
+
const devicesIds = (melCloudDevicesData.Devices ?? []).map(d => String(d.DeviceID));
|
|
120
116
|
const ataDevices = (account.ataDevices || []).filter(d => (d.displayType ?? 0) > 0 && devicesIds.includes(d.id));
|
|
121
117
|
const atwDevices = (account.atwDevices || []).filter(d => (d.displayType ?? 0) > 0 && devicesIds.includes(d.id));
|
|
122
118
|
const ervDevices = (account.ervDevices || []).filter(d => (d.displayType ?? 0) > 0 && devicesIds.includes(d.id));
|
|
@@ -132,19 +128,19 @@ class MelCloudPlatform {
|
|
|
132
128
|
const defaultTempsFile = `${prefDir}/${name}_${device.id}_Temps`;
|
|
133
129
|
|
|
134
130
|
//device in melcloud
|
|
135
|
-
const
|
|
136
|
-
|
|
131
|
+
const melCloudDeviceData = melCloudDevicesData.Devices.find(d => d.DeviceID === device.id);
|
|
132
|
+
melCloudDeviceData.Scenes = melCloudDevicesData.Scenes ?? [];
|
|
137
133
|
|
|
138
134
|
//presets
|
|
139
|
-
const presetIds = (
|
|
135
|
+
const presetIds = (melCloudDeviceData.Presets ?? []).map(p => String(p.ID));
|
|
140
136
|
const presets = account.type === 'melcloud' ? (device.presets || []).filter(p => (p.displayType ?? 0) > 0 && presetIds.includes(p.id)) : [];
|
|
141
137
|
|
|
142
138
|
//schedules
|
|
143
|
-
const schedulesIds = (
|
|
139
|
+
const schedulesIds = (melCloudDeviceData.Schedule ?? []).map(s => String(s.Id));
|
|
144
140
|
const schedules = account.type === 'melcloudhome' ? (device.schedules || []).filter(s => (s.displayType ?? 0) > 0 && schedulesIds.includes(s.id)) : [];
|
|
145
141
|
|
|
146
142
|
//scenes
|
|
147
|
-
const scenesIds = (
|
|
143
|
+
const scenesIds = (melCloudDevicesData.Scenes ?? []).map(s => String(s.Id));
|
|
148
144
|
const scenes = account.type === 'melcloudhome' ? (device.scenes || []).filter(s => (s.displayType ?? 0) > 0 && scenesIds.includes(s.id)) : [];
|
|
149
145
|
|
|
150
146
|
//buttons
|
|
@@ -172,32 +168,32 @@ class MelCloudPlatform {
|
|
|
172
168
|
}
|
|
173
169
|
}
|
|
174
170
|
|
|
175
|
-
let
|
|
171
|
+
let deviceClass;
|
|
176
172
|
switch (deviceType) {
|
|
177
173
|
case 0: //ATA
|
|
178
|
-
|
|
174
|
+
deviceClass = new DeviceAta(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile, melCloudClass, melCloudAccountData, melCloudDeviceData);
|
|
179
175
|
break;
|
|
180
176
|
case 1: //ATW
|
|
181
|
-
|
|
177
|
+
deviceClass = new DeviceAtw(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile, melCloudClass, melCloudAccountData, melCloudDeviceData);
|
|
182
178
|
break;
|
|
183
179
|
case 2:
|
|
184
180
|
break;
|
|
185
181
|
case 3: //ERV
|
|
186
|
-
|
|
182
|
+
deviceClass = new DeviceErv(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile, melCloudClass, melCloudAccountData, melCloudDeviceData);
|
|
187
183
|
break;
|
|
188
184
|
default:
|
|
189
185
|
if (logLevel.warn) log.warn(`${name}, ${deviceTypeString}, ${deviceName}, unknown device: ${deviceType}.`);
|
|
190
186
|
return;
|
|
191
187
|
}
|
|
192
188
|
|
|
193
|
-
|
|
189
|
+
deviceClass.on('devInfo', (info) => logLevel.devInfo && log.info(info))
|
|
194
190
|
.on('success', (msg) => logLevel.success && log.success(`${name}, ${deviceTypeString}, ${deviceName}, ${msg}`))
|
|
195
191
|
.on('info', (msg) => log.info(`${name}, ${deviceTypeString}, ${deviceName}, ${msg}`))
|
|
196
192
|
.on('debug', (msg) => log.info(`${name}, ${deviceTypeString}, ${deviceName}, debug: ${msg}`))
|
|
197
193
|
.on('warn', (msg) => log.warn(`${name}, ${deviceTypeString}, ${deviceName}, ${msg}`))
|
|
198
194
|
.on('error', (msg) => log.error(`${name}, ${deviceTypeString}, ${deviceName}, ${msg}`));
|
|
199
195
|
|
|
200
|
-
const accessory = await
|
|
196
|
+
const accessory = await deviceClass.start();
|
|
201
197
|
if (accessory) {
|
|
202
198
|
api.publishExternalAccessories(PluginName, [accessory]);
|
|
203
199
|
if (logLevel.success) log.success(`${name}, ${deviceTypeString}, ${deviceName}, Published as external accessory.`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.7.6-beta.
|
|
4
|
+
"version": "4.7.6-beta.4",
|
|
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, DeviceType } from './constants
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceAta extends EventEmitter {
|
|
10
|
-
constructor(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile,
|
|
10
|
+
constructor(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile, melCloudClass, melCloudAccountData, melCloudDeviceData) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -17,8 +17,8 @@ class DeviceAta extends EventEmitter {
|
|
|
17
17
|
AccessoryUUID = api.hap.uuid;
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
20
|
+
this.melCloudClass = melCloudClass;
|
|
21
|
+
this.melCloudDeviceData = melCloudDeviceData;
|
|
22
22
|
this.account = account;
|
|
23
23
|
this.accountType = account.type;
|
|
24
24
|
this.accountName = account.name;
|
|
@@ -51,8 +51,7 @@ class DeviceAta extends EventEmitter {
|
|
|
51
51
|
|
|
52
52
|
//files
|
|
53
53
|
this.defaultTempsFile = defaultTempsFile;
|
|
54
|
-
this.
|
|
55
|
-
this.accountFile = accountFile;
|
|
54
|
+
this.melCloudAccountData = melCloudAccountData;
|
|
56
55
|
|
|
57
56
|
//external integrations
|
|
58
57
|
this.restFul = account.restFul ?? {};
|
|
@@ -518,9 +517,9 @@ class DeviceAta extends EventEmitter {
|
|
|
518
517
|
|
|
519
518
|
try {
|
|
520
519
|
this.accessory.useFahrenheit = value ? true : false;
|
|
521
|
-
this.
|
|
520
|
+
this.melCloudAccountData.UseFahrenheit = value ? true : false;
|
|
522
521
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
523
|
-
await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'account', this.
|
|
522
|
+
await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'account', this.melCloudAccountData);
|
|
524
523
|
} catch (error) {
|
|
525
524
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
526
525
|
};
|
|
@@ -617,9 +616,9 @@ class DeviceAta extends EventEmitter {
|
|
|
617
616
|
|
|
618
617
|
try {
|
|
619
618
|
this.accessory.useFahrenheit = value ? true : false;
|
|
620
|
-
this.
|
|
619
|
+
this.melCloudAccountData.UseFahrenheit = value ? true : false;
|
|
621
620
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
622
|
-
await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'account', this.
|
|
621
|
+
await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'account', this.melCloudAccountData);
|
|
623
622
|
} catch (error) {
|
|
624
623
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
625
624
|
};
|
|
@@ -1467,7 +1466,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1467
1466
|
async start() {
|
|
1468
1467
|
try {
|
|
1469
1468
|
//melcloud device
|
|
1470
|
-
this.melCloudAta = new MelCloudAta(this.account, this.device, this.defaultTempsFile, this.
|
|
1469
|
+
this.melCloudAta = new MelCloudAta(this.account, this.device, this.defaultTempsFile, this.melCloudClass)
|
|
1471
1470
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1472
1471
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1473
1472
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
|
@@ -1607,8 +1606,8 @@ class DeviceAta extends EventEmitter {
|
|
|
1607
1606
|
currentSwingMode: currentSwingMode,
|
|
1608
1607
|
lockPhysicalControl: prohibitSetTemperature && prohibitOperationMode && prohibitPower ? 1 : 0,
|
|
1609
1608
|
temperatureStep: temperatureStep,
|
|
1610
|
-
useFahrenheit: this.
|
|
1611
|
-
temperatureUnit: TemperatureDisplayUnits[this.
|
|
1609
|
+
useFahrenheit: this.melCloudAccountData.useFahrenheit ? 1 : 0,
|
|
1610
|
+
temperatureUnit: TemperatureDisplayUnits[this.melCloudAccountData.useFahrenheit ? 1 : 0],
|
|
1612
1611
|
isConnected: isConnected,
|
|
1613
1612
|
isInError: isInError
|
|
1614
1613
|
};
|
|
@@ -2035,7 +2034,7 @@ class DeviceAta extends EventEmitter {
|
|
|
2035
2034
|
if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
|
|
2036
2035
|
|
|
2037
2036
|
//check state
|
|
2038
|
-
await this.melCloudAta.updateState('request', this.
|
|
2037
|
+
await this.melCloudAta.updateState('request', this.melCloudDeviceData);
|
|
2039
2038
|
|
|
2040
2039
|
//prepare accessory
|
|
2041
2040
|
const accessory = await this.prepareAccessory();
|
package/src/deviceatw.js
CHANGED
|
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, HeatPump, DeviceType } from './constants.js';
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceAtw extends EventEmitter {
|
|
10
|
-
constructor(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile,
|
|
10
|
+
constructor(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile, melCloudClass, melCloudAccountData, melCloudDeviceData) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -17,8 +17,8 @@ class DeviceAtw extends EventEmitter {
|
|
|
17
17
|
AccessoryUUID = api.hap.uuid;
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
20
|
+
this.melCloudClass = melCloudClass;
|
|
21
|
+
this.melCloudDeviceData = melCloudDeviceData;
|
|
22
22
|
this.account = account;
|
|
23
23
|
this.accountType = account.type;
|
|
24
24
|
this.accountName = account.name;
|
|
@@ -59,8 +59,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
59
59
|
|
|
60
60
|
//files
|
|
61
61
|
this.defaultTempsFile = defaultTempsFile;
|
|
62
|
-
this.
|
|
63
|
-
this.accountFile = accountFile;
|
|
62
|
+
this.melCloudAccountData = melCloudAccountData;
|
|
64
63
|
|
|
65
64
|
//external integrations
|
|
66
65
|
this.restFul = account.restFul ?? {};
|
|
@@ -692,9 +691,9 @@ class DeviceAtw extends EventEmitter {
|
|
|
692
691
|
|
|
693
692
|
try {
|
|
694
693
|
this.accessory.useFahrenheit = value ? true : false;
|
|
695
|
-
this.
|
|
694
|
+
this.melCloudAccountData.UseFahrenheit = value ? true : false;
|
|
696
695
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
697
|
-
await this.melCloudAtw.send(this.accountType, this.displayType, deviceData, 'account', this.
|
|
696
|
+
await this.melCloudAtw.send(this.accountType, this.displayType, deviceData, 'account', this.melCloudAccountData);
|
|
698
697
|
} catch (error) {
|
|
699
698
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
700
699
|
};
|
|
@@ -918,9 +917,9 @@ class DeviceAtw extends EventEmitter {
|
|
|
918
917
|
|
|
919
918
|
try {
|
|
920
919
|
this.accessory.useFahrenheit = value ? true : false;
|
|
921
|
-
this.
|
|
920
|
+
this.melCloudAccountData.UseFahrenheit = value ? true : false;
|
|
922
921
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
923
|
-
await this.melCloudAtw.send(this.accountType, this.displayType, deviceData, 'account', this.
|
|
922
|
+
await this.melCloudAtw.send(this.accountType, this.displayType, deviceData, 'account', this.melCloudAccountData);
|
|
924
923
|
} catch (error) {
|
|
925
924
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
926
925
|
};
|
|
@@ -1742,7 +1741,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1742
1741
|
async start() {
|
|
1743
1742
|
try {
|
|
1744
1743
|
//melcloud device
|
|
1745
|
-
this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.defaultTempsFile, this.
|
|
1744
|
+
this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.defaultTempsFile, this.melCloudClass)
|
|
1746
1745
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion, supportsHotWaterTank, supportsZone2) => {
|
|
1747
1746
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1748
1747
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
|
@@ -1907,8 +1906,8 @@ class DeviceAtw extends EventEmitter {
|
|
|
1907
1906
|
caseHotWaterSensor: caseHotWaterSensor,
|
|
1908
1907
|
caseZone2Sensor: caseZone2Sensor,
|
|
1909
1908
|
sensorsCount: zonesSensorsCount,
|
|
1910
|
-
useFahrenheit: this.
|
|
1911
|
-
temperatureUnit: TemperatureDisplayUnits[this.
|
|
1909
|
+
useFahrenheit: this.melCloudAccountData.useFahrenheit ? 1 : 0,
|
|
1910
|
+
temperatureUnit: TemperatureDisplayUnits[this.melCloudAccountData.useFahrenheit ? 1 : 0],
|
|
1912
1911
|
isConnected: isConnected,
|
|
1913
1912
|
isInError: isInError,
|
|
1914
1913
|
zones: [],
|
|
@@ -2588,7 +2587,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
2588
2587
|
if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
|
|
2589
2588
|
|
|
2590
2589
|
//check state
|
|
2591
|
-
await this.melCloudAtw.updateState('request', this.
|
|
2590
|
+
await this.melCloudAtw.updateState('request', this.melCloudDeviceData);
|
|
2592
2591
|
|
|
2593
2592
|
//prepare accessory
|
|
2594
2593
|
const accessory = await this.prepareAccessory();
|
package/src/deviceerv.js
CHANGED
|
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, Ventilation, DeviceType } from './constants.js
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceErv extends EventEmitter {
|
|
10
|
-
constructor(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile,
|
|
10
|
+
constructor(api, account, device, presets, schedules, scenes, buttons, defaultTempsFile, melCloudClass, melCloudAccountData, melCloudDeviceData) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -17,8 +17,8 @@ class DeviceErv extends EventEmitter {
|
|
|
17
17
|
AccessoryUUID = api.hap.uuid;
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
20
|
+
this.melCloudClass = melCloudClass;
|
|
21
|
+
this.melCloudDeviceData = melCloudDeviceData;
|
|
22
22
|
this.account = account;
|
|
23
23
|
this.accountType = account.type;
|
|
24
24
|
this.accountName = account.name;
|
|
@@ -47,8 +47,7 @@ class DeviceErv extends EventEmitter {
|
|
|
47
47
|
|
|
48
48
|
//files
|
|
49
49
|
this.defaultTempsFile = defaultTempsFile;
|
|
50
|
-
this.
|
|
51
|
-
this.accountFile = accountFile;
|
|
50
|
+
this.melCloudAccountData = melCloudAccountData;
|
|
52
51
|
|
|
53
52
|
//external integrations
|
|
54
53
|
this.restFul = account.restFul ?? {};
|
|
@@ -450,9 +449,9 @@ class DeviceErv extends EventEmitter {
|
|
|
450
449
|
|
|
451
450
|
try {
|
|
452
451
|
this.accessory.useFahrenheit = value ? true : false;
|
|
453
|
-
this.
|
|
452
|
+
this.melCloudAccountData.UseFahrenheit = value ? true : false;
|
|
454
453
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
455
|
-
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.
|
|
454
|
+
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.melCloudAccountData);
|
|
456
455
|
} catch (error) {
|
|
457
456
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
458
457
|
};
|
|
@@ -544,9 +543,9 @@ class DeviceErv extends EventEmitter {
|
|
|
544
543
|
|
|
545
544
|
try {
|
|
546
545
|
this.accessory.useFahrenheit = value ? true : false;
|
|
547
|
-
this.
|
|
546
|
+
this.melCloudAccountData.UseFahrenheit = value ? true : false;
|
|
548
547
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
549
|
-
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.
|
|
548
|
+
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.melCloudAccountData);
|
|
550
549
|
} catch (error) {
|
|
551
550
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
552
551
|
};
|
|
@@ -1113,7 +1112,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1113
1112
|
async start() {
|
|
1114
1113
|
try {
|
|
1115
1114
|
//melcloud device
|
|
1116
|
-
this.melCloudErv = new MelCloudErv(this.account, this.device, this.defaultTempsFile, this.
|
|
1115
|
+
this.melCloudErv = new MelCloudErv(this.account, this.device, this.defaultTempsFile, this.melCloudClass)
|
|
1117
1116
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1118
1117
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1119
1118
|
this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
|
|
@@ -1250,8 +1249,8 @@ class DeviceErv extends EventEmitter {
|
|
|
1250
1249
|
defaultCoolingSetTemperature: defaultCoolingSetTemperature,
|
|
1251
1250
|
lockPhysicalControl: 0,
|
|
1252
1251
|
temperatureIncrement: temperatureIncrement,
|
|
1253
|
-
useFahrenheit: this.
|
|
1254
|
-
temperatureUnit: TemperatureDisplayUnits[this.
|
|
1252
|
+
useFahrenheit: this.melCloudAccountData.useFahrenheit ? 1 : 0,
|
|
1253
|
+
temperatureUnit: TemperatureDisplayUnits[this.melCloudAccountData.useFahrenheit ? 1 : 0],
|
|
1255
1254
|
isConnected: isConnected,
|
|
1256
1255
|
isInError: isInError
|
|
1257
1256
|
};
|
|
@@ -1582,7 +1581,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1582
1581
|
if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
|
|
1583
1582
|
|
|
1584
1583
|
//check state
|
|
1585
|
-
await this.melCloudErv.updateState('request', this.
|
|
1584
|
+
await this.melCloudErv.updateState('request', this.melCloudDeviceData);
|
|
1586
1585
|
|
|
1587
1586
|
//prepare accessory
|
|
1588
1587
|
const accessory = await this.prepareAccessory();
|
package/src/melcloud.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
3
|
import ImpulseGenerator from './impulsegenerator.js';
|
|
4
|
-
import Functions from './functions.js';
|
|
5
4
|
import { ApiUrls } from './constants.js';
|
|
6
5
|
|
|
7
6
|
class MelCloud extends EventEmitter {
|
|
8
|
-
constructor(account,
|
|
7
|
+
constructor(account, pluginStart = false) {
|
|
9
8
|
super();
|
|
10
9
|
this.accountType = account.type;
|
|
11
10
|
this.user = account.user;
|
|
@@ -15,14 +14,7 @@ class MelCloud extends EventEmitter {
|
|
|
15
14
|
this.logError = account.log?.error;
|
|
16
15
|
this.logDebug = account.log?.debug;
|
|
17
16
|
|
|
18
|
-
this.accountFile = accountFile;
|
|
19
|
-
this.buildingsFile = buildingsFile;
|
|
20
|
-
|
|
21
17
|
this.client = null;
|
|
22
|
-
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
23
|
-
.on('warn', warn => this.emit('warn', warn))
|
|
24
|
-
.on('error', error => this.emit('error', error))
|
|
25
|
-
.on('debug', debug => this.emit('debug', debug));
|
|
26
18
|
|
|
27
19
|
if (pluginStart) {
|
|
28
20
|
//lock flags
|
|
@@ -54,21 +46,21 @@ class MelCloud extends EventEmitter {
|
|
|
54
46
|
|
|
55
47
|
async checkDevicesList() {
|
|
56
48
|
try {
|
|
57
|
-
const
|
|
49
|
+
const melCloudDevicesData = { State: false, Status: null, Buildings: [], Devices: [], Scenes: [] }
|
|
58
50
|
if (this.logDebug) this.emit('debug', `Scanning for devices...`);
|
|
59
51
|
const listDevicesData = await this.client(ApiUrls.Get.ListDevices, { method: 'GET', });
|
|
60
52
|
|
|
61
53
|
if (!listDevicesData || !listDevicesData.data) {
|
|
62
|
-
|
|
63
|
-
return
|
|
54
|
+
melCloudDevicesData.Status = 'Invalid or empty response from MELCloud API'
|
|
55
|
+
return melCloudDevicesData;
|
|
64
56
|
}
|
|
65
57
|
|
|
66
58
|
const buildingsList = listDevicesData.data;
|
|
67
59
|
if (this.logDebug) this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`);
|
|
68
60
|
|
|
69
61
|
if (!Array.isArray(buildingsList) || buildingsList.length === 0) {
|
|
70
|
-
|
|
71
|
-
return
|
|
62
|
+
melCloudDevicesData.Status = 'No building found'
|
|
63
|
+
return melCloudDevicesData;
|
|
72
64
|
}
|
|
73
65
|
|
|
74
66
|
const devices = [];
|
|
@@ -99,26 +91,23 @@ class MelCloud extends EventEmitter {
|
|
|
99
91
|
|
|
100
92
|
const devicesCount = devices.length;
|
|
101
93
|
if (devicesCount === 0) {
|
|
102
|
-
|
|
103
|
-
return
|
|
94
|
+
melCloudDevicesData.Status = 'No devices found'
|
|
95
|
+
return melCloudDevicesData;
|
|
104
96
|
}
|
|
105
97
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
await this.functions.saveData(this.buildingsFile, devicesList);
|
|
112
|
-
if (this.logDebug) this.emit('debug', `Buildings list saved`);
|
|
98
|
+
melCloudDevicesData.State = true;
|
|
99
|
+
melCloudDevicesData.Status = `Found ${devicesCount} devices`;
|
|
100
|
+
melCloudDevicesData.Buildings = buildingsList;
|
|
101
|
+
melCloudDevicesData.Devices = devices;
|
|
113
102
|
|
|
114
103
|
//emit device event
|
|
115
|
-
for (const deviceData of
|
|
104
|
+
for (const deviceData of melCloudDevicesData.Devices) {
|
|
116
105
|
const deviceId = deviceData.DeviceID;
|
|
117
|
-
deviceData.Scenes =
|
|
106
|
+
deviceData.Scenes = melCloudDevicesData.Devices.Scenes ?? [];
|
|
118
107
|
this.emit(deviceId, 'request', deviceData);
|
|
119
108
|
}
|
|
120
109
|
|
|
121
|
-
return
|
|
110
|
+
return melCloudDevicesData;
|
|
122
111
|
} catch (error) {
|
|
123
112
|
throw new Error(`Check devices list error: ${error.message}`);
|
|
124
113
|
}
|
|
@@ -128,7 +117,7 @@ class MelCloud extends EventEmitter {
|
|
|
128
117
|
if (this.logDebug) this.emit('debug', `Connecting to MELCloud`);
|
|
129
118
|
|
|
130
119
|
try {
|
|
131
|
-
const
|
|
120
|
+
const melCloudAccountData = { State: false, Status: '', Account: null, UseFahrenheit: false }
|
|
132
121
|
|
|
133
122
|
const payload = {
|
|
134
123
|
Email: this.user,
|
|
@@ -158,11 +147,11 @@ class MelCloud extends EventEmitter {
|
|
|
158
147
|
MapLongitude: 'removed',
|
|
159
148
|
MapLatitude: 'removed'
|
|
160
149
|
};
|
|
161
|
-
if (this.logDebug) this.emit('debug', `
|
|
150
|
+
if (this.logDebug) this.emit('debug', `Account Info: ${JSON.stringify(safeConfig, null, 2)}`);
|
|
162
151
|
|
|
163
152
|
if (!contextKey) {
|
|
164
|
-
|
|
165
|
-
return
|
|
153
|
+
melCloudAccountData.Status = 'Context key missing'
|
|
154
|
+
return melCloudAccountData;
|
|
166
155
|
}
|
|
167
156
|
|
|
168
157
|
const headers = {
|
|
@@ -177,13 +166,12 @@ class MelCloud extends EventEmitter {
|
|
|
177
166
|
});
|
|
178
167
|
this.emit('client', this.client);
|
|
179
168
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
await this.functions.saveData(this.accountFile, accountInfo);
|
|
169
|
+
melCloudAccountData.State = true;
|
|
170
|
+
melCloudAccountData.Status = 'Connect Success';
|
|
171
|
+
melCloudAccountData.UseFahrenheit = loginData.UseFahrenheit;
|
|
172
|
+
melCloudAccountData.Account = account;
|
|
185
173
|
|
|
186
|
-
return
|
|
174
|
+
return melCloudAccountData
|
|
187
175
|
} catch (error) {
|
|
188
176
|
throw new Error(`Connect error: ${error.message}`);
|
|
189
177
|
}
|
package/src/melcloudata.js
CHANGED
|
@@ -3,7 +3,7 @@ import Functions from './functions.js';
|
|
|
3
3
|
import { ApiUrls, AirConditioner } from './constants.js';
|
|
4
4
|
|
|
5
5
|
class MelCloudAta extends EventEmitter {
|
|
6
|
-
constructor(account, device, defaultTempsFile,
|
|
6
|
+
constructor(account, device, defaultTempsFile, melCloudClass) {
|
|
7
7
|
super();
|
|
8
8
|
this.accountType = account.type;
|
|
9
9
|
this.logSuccess = account.log?.success;
|
|
@@ -14,7 +14,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
14
14
|
this.mqttEnabled = account.mqtt?.enable;
|
|
15
15
|
this.deviceId = device.id;
|
|
16
16
|
this.defaultTempsFile = defaultTempsFile;
|
|
17
|
-
this.accountFile = accountFile;
|
|
18
17
|
|
|
19
18
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
20
19
|
.on('warn', warn => this.emit('warn', warn))
|
|
@@ -23,12 +22,12 @@ class MelCloudAta extends EventEmitter {
|
|
|
23
22
|
|
|
24
23
|
//set default values
|
|
25
24
|
this.deviceData = {};
|
|
26
|
-
this.client =
|
|
25
|
+
this.client = melCloudClass.client;
|
|
27
26
|
this.lock = false;
|
|
28
27
|
|
|
29
28
|
//handle melcloud events
|
|
30
29
|
let deviceData = null;
|
|
31
|
-
|
|
30
|
+
melCloudClass.on('client', (client) => {
|
|
32
31
|
this.client = client;
|
|
33
32
|
}).on(this.deviceId, async (type, message) => {
|
|
34
33
|
switch (type) {
|
|
@@ -209,7 +208,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
209
208
|
flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
|
|
210
209
|
payload = { data: flagData.LoginData };
|
|
211
210
|
path = ApiUrls.Post.UpdateApplicationOptions;
|
|
212
|
-
await this.functions.saveData(this.accountFile, flagData);
|
|
213
211
|
break;
|
|
214
212
|
default:
|
|
215
213
|
if (displayType === 1 && deviceData.Device.OperationMode === 8) {
|
package/src/melcloudatw.js
CHANGED
|
@@ -3,7 +3,7 @@ import Functions from './functions.js';
|
|
|
3
3
|
import { ApiUrls, HeatPump } from './constants.js';
|
|
4
4
|
|
|
5
5
|
class MelCloudAtw extends EventEmitter {
|
|
6
|
-
constructor(account, device, defaultTempsFile,
|
|
6
|
+
constructor(account, device, defaultTempsFile, melCloudClass) {
|
|
7
7
|
super();
|
|
8
8
|
this.accountType = account.type;
|
|
9
9
|
this.logSuccess = account.log?.success;
|
|
@@ -14,7 +14,6 @@ class MelCloudAtw extends EventEmitter {
|
|
|
14
14
|
this.mqttEnabled = account.mqtt?.enable;
|
|
15
15
|
this.deviceId = device.id;
|
|
16
16
|
this.defaultTempsFile = defaultTempsFile;
|
|
17
|
-
this.accountFile = accountFile;
|
|
18
17
|
|
|
19
18
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
20
19
|
.on('warn', warn => this.emit('warn', warn))
|
|
@@ -23,11 +22,11 @@ class MelCloudAtw extends EventEmitter {
|
|
|
23
22
|
|
|
24
23
|
//set default values
|
|
25
24
|
this.deviceData = {};
|
|
26
|
-
this.client =
|
|
25
|
+
this.client = melCloudClass.client;
|
|
27
26
|
|
|
28
27
|
//handle melcloud events
|
|
29
28
|
let deviceData = null;
|
|
30
|
-
|
|
29
|
+
melCloudClass.on('client', (client) => {
|
|
31
30
|
this.client = client;
|
|
32
31
|
}).on(this.deviceId, async (type, message) => {
|
|
33
32
|
switch (type) {
|
|
@@ -185,7 +184,6 @@ class MelCloudAtw extends EventEmitter {
|
|
|
185
184
|
flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
|
|
186
185
|
payload = { data: flagData.LoginData };
|
|
187
186
|
path = ApiUrls.Post.UpdateApplicationOptions;
|
|
188
|
-
await this.functions.saveData(this.accountFile, flagData);
|
|
189
187
|
break;
|
|
190
188
|
default:
|
|
191
189
|
deviceData.Device.EffectiveFlags = flag;
|
package/src/melclouderv.js
CHANGED
|
@@ -3,7 +3,7 @@ import Functions from './functions.js';
|
|
|
3
3
|
import { ApiUrls, Ventilation } from './constants.js';
|
|
4
4
|
|
|
5
5
|
class MelCloudErv extends EventEmitter {
|
|
6
|
-
constructor(account, device, defaultTempsFile,
|
|
6
|
+
constructor(account, device, defaultTempsFile, melCloudClass) {
|
|
7
7
|
super();
|
|
8
8
|
this.accountType = account.type;
|
|
9
9
|
this.logSuccess = account.log?.success;
|
|
@@ -14,7 +14,6 @@ class MelCloudErv extends EventEmitter {
|
|
|
14
14
|
this.mqttEnabled = account.mqtt?.enable;
|
|
15
15
|
this.deviceId = device.id;
|
|
16
16
|
this.defaultTempsFile = defaultTempsFile;
|
|
17
|
-
this.accountFile = accountFile;
|
|
18
17
|
|
|
19
18
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
20
19
|
.on('warn', warn => this.emit('warn', warn))
|
|
@@ -23,11 +22,11 @@ class MelCloudErv extends EventEmitter {
|
|
|
23
22
|
|
|
24
23
|
//set default values
|
|
25
24
|
this.deviceData = {};
|
|
26
|
-
this.client =
|
|
25
|
+
this.client = melCloudClass.client;
|
|
27
26
|
|
|
28
27
|
//handle melcloud events
|
|
29
28
|
let deviceData = null;
|
|
30
|
-
|
|
29
|
+
melCloudClass.on('client', (client) => {
|
|
31
30
|
this.client = client;
|
|
32
31
|
}).on(this.deviceId, async (type, message) => {
|
|
33
32
|
switch (type) {
|
|
@@ -185,7 +184,6 @@ class MelCloudErv extends EventEmitter {
|
|
|
185
184
|
flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
|
|
186
185
|
payload = { data: flagData.LoginData };
|
|
187
186
|
path = ApiUrls.Post.UpdateApplicationOptions;
|
|
188
|
-
await this.functions.saveData(this.accountFile, flagData);
|
|
189
187
|
break;
|
|
190
188
|
default:
|
|
191
189
|
//set target temp based on display mode and ventilation mode
|
package/src/melcloudhome.js
CHANGED
|
@@ -10,7 +10,7 @@ import { ApiUrls, LanguageLocaleMap } from './constants.js';
|
|
|
10
10
|
const execPromise = promisify(exec);
|
|
11
11
|
|
|
12
12
|
class MelCloudHome extends EventEmitter {
|
|
13
|
-
constructor(account,
|
|
13
|
+
constructor(account, pluginStart = false) {
|
|
14
14
|
super();
|
|
15
15
|
this.accountType = account.type;
|
|
16
16
|
this.user = account.user;
|
|
@@ -20,9 +20,6 @@ class MelCloudHome extends EventEmitter {
|
|
|
20
20
|
this.logError = account.log?.error;
|
|
21
21
|
this.logDebug = account.log?.debug;
|
|
22
22
|
|
|
23
|
-
this.accountFile = accountFile;
|
|
24
|
-
this.buildingsFile = buildingsFile;
|
|
25
|
-
|
|
26
23
|
this.client = null;
|
|
27
24
|
this.connecting = false;
|
|
28
25
|
this.socketConnected = false;
|
|
@@ -107,7 +104,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
107
104
|
|
|
108
105
|
async checkDevicesList() {
|
|
109
106
|
try {
|
|
110
|
-
const
|
|
107
|
+
const melCloudDevicesData = { State: false, Status: null, Buildings: {}, Devices: [], Scenes: [] }
|
|
111
108
|
if (this.logDebug) this.emit('debug', `Scanning for devices`);
|
|
112
109
|
const listDevicesData = await this.client(ApiUrls.Home.Get.ListDevices, { method: 'GET' });
|
|
113
110
|
|
|
@@ -118,8 +115,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
118
115
|
if (this.logDebug) this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`);
|
|
119
116
|
|
|
120
117
|
if (!buildingsList) {
|
|
121
|
-
|
|
122
|
-
return
|
|
118
|
+
melCloudDevicesData.Status = 'No buildings found'
|
|
119
|
+
return melCloudDevicesData;
|
|
123
120
|
}
|
|
124
121
|
|
|
125
122
|
const devices = buildingsList.flatMap(building => {
|
|
@@ -184,8 +181,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
184
181
|
|
|
185
182
|
const devicesCount = devices.length;
|
|
186
183
|
if (devicesCount === 0) {
|
|
187
|
-
|
|
188
|
-
return
|
|
184
|
+
melCloudDevicesData.Status = 'No devices found'
|
|
185
|
+
return melCloudDevicesData;
|
|
189
186
|
}
|
|
190
187
|
|
|
191
188
|
// Get scenes
|
|
@@ -200,23 +197,20 @@ class MelCloudHome extends EventEmitter {
|
|
|
200
197
|
if (this.logError) this.emit('error', `Get scenes error: ${error}`);
|
|
201
198
|
}
|
|
202
199
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
await this.functions.saveData(this.buildingsFile, devicesList);
|
|
210
|
-
if (this.logDebug) this.emit('debug', `Buildings list saved`);
|
|
200
|
+
melCloudDevicesData.State = true;
|
|
201
|
+
melCloudDevicesData.Status = `Found ${devicesCount} devices ${scenes.length > 0 ? `and ${scenes.length} scenes` : ''}`;
|
|
202
|
+
melCloudDevicesData.Buildings = userContext;
|
|
203
|
+
melCloudDevicesData.Devices = devices;
|
|
204
|
+
melCloudDevicesData.Scenes = scenes;
|
|
211
205
|
|
|
212
206
|
//emit device event
|
|
213
|
-
for (const deviceData of
|
|
214
|
-
deviceData.Scenes =
|
|
207
|
+
for (const deviceData of melCloudDevicesData.Devices) {
|
|
208
|
+
deviceData.Scenes = melCloudDevicesData.Devices.Scenes ?? [];
|
|
215
209
|
const deviceId = deviceData.DeviceID;
|
|
216
210
|
this.emit(deviceId, 'request', deviceData);
|
|
217
211
|
}
|
|
218
212
|
|
|
219
|
-
return
|
|
213
|
+
return melCloudDevicesData;
|
|
220
214
|
} catch (error) {
|
|
221
215
|
throw new Error(`Check devices list error: ${error.message}`);
|
|
222
216
|
}
|
|
@@ -228,7 +222,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
228
222
|
|
|
229
223
|
let browser;
|
|
230
224
|
try {
|
|
231
|
-
const
|
|
225
|
+
const connectInfo = { State: false, Status: '', Account: {}, UseFahrenheit: false };
|
|
232
226
|
|
|
233
227
|
// Get Chromium path from resolver
|
|
234
228
|
const chromiumInfo = await this.functions.ensureChromiumInstalled();
|
|
@@ -241,15 +235,15 @@ class MelCloudHome extends EventEmitter {
|
|
|
241
235
|
if (this.logDebug) this.emit('debug', `Using Chromium for ${system} (${arch}) at ${chromiumPath}`);
|
|
242
236
|
} else {
|
|
243
237
|
if (arch === 'arm') {
|
|
244
|
-
|
|
245
|
-
return
|
|
238
|
+
connectInfo.Status = `No Chromium found for ${system} (${arch}). Please install it manually and try again.`;
|
|
239
|
+
return connectInfo;
|
|
246
240
|
} else {
|
|
247
241
|
try {
|
|
248
242
|
chromiumPath = puppeteer.executablePath();
|
|
249
243
|
if (this.logDebug) this.emit('debug', `Using Puppeteer Chromium for ${system} (${arch}) at ${chromiumPath}`);
|
|
250
244
|
} catch (error) {
|
|
251
|
-
|
|
252
|
-
return
|
|
245
|
+
connectInfo.Status = `No Puppeteer Chromium for ${system} (${arch}), error: ${error.message}`;
|
|
246
|
+
return connectInfo;
|
|
253
247
|
}
|
|
254
248
|
}
|
|
255
249
|
}
|
|
@@ -259,8 +253,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
259
253
|
const { stdout } = await execPromise(`"${chromiumPath}" --version`);
|
|
260
254
|
if (this.logDebug) this.emit('debug', `Chromium for ${system} (${arch}) detected: ${stdout.trim()}`);
|
|
261
255
|
} catch (error) {
|
|
262
|
-
|
|
263
|
-
return
|
|
256
|
+
connectInfo.Status = `Chromium for ${system} (${arch}) found at ${chromiumPath}, but execute error: ${error.message}. Please install it manually and try again.`;
|
|
257
|
+
return connectInfo;
|
|
264
258
|
}
|
|
265
259
|
|
|
266
260
|
// Launch Chromium
|
|
@@ -355,8 +349,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
355
349
|
try {
|
|
356
350
|
await page.goto(ApiUrls.Home.Base, { waitUntil: ['domcontentloaded', 'networkidle2'], timeout: GLOBAL_TIMEOUT });
|
|
357
351
|
} catch (error) {
|
|
358
|
-
|
|
359
|
-
return
|
|
352
|
+
connectInfo.Status = `Navigation to ${ApiUrls.Home.Base} failed: ${error.message}`;
|
|
353
|
+
return connectInfo;
|
|
360
354
|
}
|
|
361
355
|
|
|
362
356
|
// Wait extra to ensure UI is rendered
|
|
@@ -365,8 +359,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
365
359
|
const loginText = await page.evaluate(el => el.textContent.trim(), loginBtn);
|
|
366
360
|
|
|
367
361
|
if (!['Zaloguj', 'Sign In', 'Login'].includes(loginText)) {
|
|
368
|
-
|
|
369
|
-
return
|
|
362
|
+
connectInfo.Status = `Login button ${loginText} not found`;
|
|
363
|
+
return connectInfo;
|
|
370
364
|
}
|
|
371
365
|
|
|
372
366
|
await loginBtn.click();
|
|
@@ -375,8 +369,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
375
369
|
const usernameInput = await page.$('input[name="username"]');
|
|
376
370
|
const passwordInput = await page.$('input[name="password"]');
|
|
377
371
|
if (!usernameInput || !passwordInput) {
|
|
378
|
-
|
|
379
|
-
return
|
|
372
|
+
connectInfo.Status = 'Username or password input not found';
|
|
373
|
+
return connectInfo;
|
|
380
374
|
}
|
|
381
375
|
|
|
382
376
|
await page.type('input[name="username"]', this.user, { delay: 50 });
|
|
@@ -384,8 +378,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
384
378
|
|
|
385
379
|
const submitButton = await page.$('input[type="submit"], button[type="submit"]');
|
|
386
380
|
if (!submitButton) {
|
|
387
|
-
|
|
388
|
-
return
|
|
381
|
+
connectInfo.Status = 'Submit button not found';
|
|
382
|
+
return connectInfo;
|
|
389
383
|
}
|
|
390
384
|
await Promise.race([Promise.all([submitButton.click(), page.waitForNavigation({ waitUntil: ['domcontentloaded', 'networkidle2'], timeout: GLOBAL_TIMEOUT / 3 })]), new Promise(r => setTimeout(r, GLOBAL_TIMEOUT / 3))]);
|
|
391
385
|
|
|
@@ -400,8 +394,8 @@ class MelCloudHome extends EventEmitter {
|
|
|
400
394
|
}
|
|
401
395
|
|
|
402
396
|
if (!c1 || !c2) {
|
|
403
|
-
|
|
404
|
-
return
|
|
397
|
+
connectInfo.Status = 'Cookies C1/C2 missing';
|
|
398
|
+
return connectInfo;
|
|
405
399
|
}
|
|
406
400
|
|
|
407
401
|
const cookies = [
|
|
@@ -432,11 +426,10 @@ class MelCloudHome extends EventEmitter {
|
|
|
432
426
|
});
|
|
433
427
|
this.emit('client', this.client);
|
|
434
428
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
await this.functions.saveData(this.accountFile, accountInfo);
|
|
429
|
+
connectInfo.State = true;
|
|
430
|
+
connectInfo.Status = `Connect Success${this.socketConnected ? ', Web Socket Connected' : ''}`;
|
|
438
431
|
|
|
439
|
-
return
|
|
432
|
+
return connectInfo;
|
|
440
433
|
} catch (error) {
|
|
441
434
|
throw new Error(`Connect error: ${error.message}`);
|
|
442
435
|
} finally {
|