homebridge-melcloud-control 2.5.0-beta.19 → 2.5.0-beta.2
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 +54 -16
- package/homebridge-ui/server.js +38 -15
- package/index.js +1 -1
- package/package.json +1 -1
- package/src/melcloud.js +44 -59
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
<input id="language" type="text" class="form-control"><br>
|
|
21
21
|
</div>
|
|
22
22
|
<div class="text-center">
|
|
23
|
-
<button id="logIn" type="button" class="btn btn-primary">
|
|
23
|
+
<button id="logIn" type="button" class="btn btn-primary">Log In</button>
|
|
24
|
+
<button id="getDevices" type="button" class="btn btn-primary">Get Devices</button>
|
|
24
25
|
<button id="configButton" type="button" class="btn btn-primary"><i class="fas fa-gear"></i></button>
|
|
25
26
|
</div>
|
|
26
27
|
</form>
|
|
@@ -100,7 +101,7 @@
|
|
|
100
101
|
|
|
101
102
|
try {
|
|
102
103
|
await homebridge.updatePluginConfig(pluginConfig)
|
|
103
|
-
document.getElementById('info').innerHTML = '
|
|
104
|
+
document.getElementById('info').innerHTML = '';
|
|
104
105
|
|
|
105
106
|
const accountName = pluginConfig[0].accounts[this.deviceIndex].name;
|
|
106
107
|
const user = pluginConfig[0].accounts[this.deviceIndex].user;
|
|
@@ -110,6 +111,7 @@
|
|
|
110
111
|
const refreshInterval = pluginConfig[0].accounts[this.deviceIndex].refreshInterval;
|
|
111
112
|
|
|
112
113
|
const payload = {
|
|
114
|
+
mode: 'connect',
|
|
113
115
|
accountName: accountName,
|
|
114
116
|
user: user,
|
|
115
117
|
passwd: passwd,
|
|
@@ -118,41 +120,77 @@
|
|
|
118
120
|
refreshInterval: refreshInterval
|
|
119
121
|
};
|
|
120
122
|
const response = await homebridge.request('/connect', payload);
|
|
121
|
-
|
|
122
|
-
const info = response.info ?? '';
|
|
123
|
+
const info = response.info;
|
|
123
124
|
const status = response.status;
|
|
124
|
-
const
|
|
125
|
+
const data = response.data;
|
|
126
|
+
const error = response.error;
|
|
125
127
|
|
|
126
128
|
switch (status) {
|
|
127
129
|
case 0:
|
|
130
|
+
document.getElementById('info').innerHTML = info;
|
|
131
|
+
document.getElementById('getDevices').removeAttribute('disabled');
|
|
132
|
+
break;
|
|
133
|
+
case 2:
|
|
134
|
+
document.getElementById('getDevices').setAttribute('disabled');
|
|
135
|
+
document.getElementById('info').innerHTML = `MELCloud error: ${JSON.stringify(error, null, 2)}`;
|
|
136
|
+
document.getElementById('info').style.color = 'red';
|
|
137
|
+
break;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
homebridge.hideSpinner();
|
|
141
|
+
} catch (e) {
|
|
142
|
+
homebridge.toast.error(`Data error: ${e.message}`);
|
|
143
|
+
} finally {
|
|
144
|
+
homebridge.hideSpinner();
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
//get devices
|
|
149
|
+
document.getElementById('getDevices').addEventListener('click', async () => {
|
|
150
|
+
homebridge.showSpinner();
|
|
151
|
+
try {
|
|
152
|
+
const devicesId = [];
|
|
153
|
+
|
|
154
|
+
const payload = {
|
|
155
|
+
mode: 'getdevices'
|
|
156
|
+
};
|
|
157
|
+
const response = await homebridge.request('/getDevices', payload);
|
|
158
|
+
|
|
159
|
+
const info = response.info;
|
|
160
|
+
const status = response.status;
|
|
161
|
+
const devices = response.data;
|
|
162
|
+
const error = response.error;
|
|
163
|
+
|
|
164
|
+
switch (status) {
|
|
165
|
+
case 1:
|
|
128
166
|
//get device info fom devices
|
|
129
167
|
for (const deviceInfo of devices) {
|
|
130
168
|
const deviceId = deviceInfo.DeviceID;
|
|
131
169
|
const deviceName = deviceInfo.DeviceName;
|
|
170
|
+
|
|
171
|
+
//prepare device if not in devices array
|
|
172
|
+
if (!devicesId.includes(deviceId)) {
|
|
173
|
+
devicesId.push(deviceId);
|
|
174
|
+
}
|
|
132
175
|
};
|
|
133
176
|
|
|
134
|
-
document.getElementById('info').innerHTML = `${info} Found: ${
|
|
135
|
-
document.getElementById('info').style.color = 'green';
|
|
177
|
+
document.getElementById('info').innerHTML = `${info} Found: ${devicesId.length} devices. Now You can start configure it.`;
|
|
136
178
|
await homebridge.updatePluginConfig(pluginConfig);
|
|
137
179
|
await homebridge.savePluginConfig(pluginConfig);
|
|
138
180
|
break;
|
|
139
|
-
case
|
|
140
|
-
document.getElementById('info').innerHTML =
|
|
181
|
+
case 2:
|
|
182
|
+
document.getElementById('info').innerHTML = `MELCloud error: ${JSON.stringify(error, null, 2)}`;
|
|
141
183
|
document.getElementById('info').style.color = 'red';
|
|
142
184
|
break;
|
|
143
|
-
default:
|
|
144
|
-
document.getElementById('info').innerHTML = `Received unknown status: ${status}, please try again.`;
|
|
145
|
-
document.getElementById('info').style.color = 'yellow';
|
|
146
|
-
break;
|
|
147
185
|
};
|
|
148
186
|
|
|
149
187
|
homebridge.hideSpinner();
|
|
150
188
|
} catch (e) {
|
|
151
|
-
|
|
152
|
-
homebridge.toast.error(`Data error: ${e.message}`);
|
|
189
|
+
homebridge.toast.error(`Get devices error: ${e.message}`);
|
|
153
190
|
} finally {
|
|
154
191
|
homebridge.hideSpinner();
|
|
155
|
-
}
|
|
192
|
+
}
|
|
156
193
|
});
|
|
194
|
+
|
|
157
195
|
})();
|
|
158
196
|
</script>
|
package/homebridge-ui/server.js
CHANGED
|
@@ -7,6 +7,9 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
super();
|
|
9
9
|
|
|
10
|
+
//get devices
|
|
11
|
+
this.onRequest('/getdevices', this.start.bind(this));
|
|
12
|
+
|
|
10
13
|
//connect
|
|
11
14
|
this.onRequest('/connect', this.start.bind(this));
|
|
12
15
|
|
|
@@ -15,6 +18,8 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
15
18
|
};
|
|
16
19
|
|
|
17
20
|
async start(payload) {
|
|
21
|
+
|
|
22
|
+
const mode = payload.mode;
|
|
18
23
|
const accountName = payload.accountName;
|
|
19
24
|
const user = payload.user;
|
|
20
25
|
const passwd = payload.passwd;
|
|
@@ -24,22 +29,40 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
24
29
|
const accountInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
|
|
25
30
|
const deviceInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Device_`;
|
|
26
31
|
const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
|
|
32
|
+
const melCloud = new MelCloud(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval);
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
let data = {};
|
|
35
|
+
switch (mode) {
|
|
36
|
+
case 'connect':
|
|
37
|
+
try {
|
|
38
|
+
const response = await melCloud.connect();
|
|
39
|
+
return data = {
|
|
40
|
+
info: 'Connect to MELCloud success, now pres the button Get Devices.',
|
|
41
|
+
status: 1,
|
|
42
|
+
data: response
|
|
43
|
+
};
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return data = {
|
|
46
|
+
info: 'Connect error:',
|
|
47
|
+
status: 2,
|
|
48
|
+
data: error
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
case 'getdevices':
|
|
52
|
+
try {
|
|
53
|
+
const response = await melCloud.chackDevicesList();
|
|
54
|
+
return data = {
|
|
55
|
+
info: 'Get devices success.',
|
|
56
|
+
status: 0,
|
|
57
|
+
data: response
|
|
58
|
+
};
|
|
59
|
+
} catch (error) {
|
|
60
|
+
return data = {
|
|
61
|
+
info: 'Get devices error:',
|
|
62
|
+
status: 2,
|
|
63
|
+
data: error
|
|
64
|
+
};
|
|
65
|
+
};
|
|
43
66
|
};
|
|
44
67
|
};
|
|
45
68
|
};
|
package/index.js
CHANGED
|
@@ -78,7 +78,7 @@ class MelCloudPlatform {
|
|
|
78
78
|
const deviceRefreshInterval = account.deviceRefreshInterval * 1000 || 5000;
|
|
79
79
|
|
|
80
80
|
//melcloud account
|
|
81
|
-
const melCloud = new MelCloud(user, passwd, language, accountInfoFile, buildingsFile, deviceInfoFile, enableDebugMode, refreshInterval
|
|
81
|
+
const melCloud = new MelCloud(user, passwd, language, accountInfoFile, buildingsFile, deviceInfoFile, enableDebugMode, refreshInterval);
|
|
82
82
|
melCloud.on('checkDevicesListComplete', (accountInfo, contextKey, deviceInfo) => {
|
|
83
83
|
const deviceId = deviceInfo.DeviceID.toString();
|
|
84
84
|
const deviceType = deviceInfo.Type;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "2.5.0-beta.
|
|
4
|
+
"version": "2.5.0-beta.2",
|
|
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/melcloud.js
CHANGED
|
@@ -8,14 +8,13 @@ const ImpulseGenerator = require('./impulsegenerator.js');
|
|
|
8
8
|
const CONSTANTS = require('./constants.json');
|
|
9
9
|
|
|
10
10
|
class MelCloud extends EventEmitter {
|
|
11
|
-
constructor(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval
|
|
11
|
+
constructor(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval) {
|
|
12
12
|
super();
|
|
13
13
|
this.enableDebugMode = enableDebugMode;
|
|
14
14
|
this.accountInfoFile = accountInfoFile;
|
|
15
15
|
this.buildingsFile = buildingsFile;
|
|
16
16
|
this.deviceInfoFile = deviceInfoFile;
|
|
17
17
|
this.refreshInterval = refreshInterval;
|
|
18
|
-
this.connectForConfig = connectForConfig;
|
|
19
18
|
this.devicesId = [];
|
|
20
19
|
|
|
21
20
|
this.options = {
|
|
@@ -39,9 +38,7 @@ class MelCloud extends EventEmitter {
|
|
|
39
38
|
};
|
|
40
39
|
}).on('state', (state) => { });
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
this.connect();
|
|
44
|
-
};
|
|
41
|
+
this.connect();
|
|
45
42
|
};
|
|
46
43
|
|
|
47
44
|
async connect() {
|
|
@@ -82,26 +79,56 @@ class MelCloud extends EventEmitter {
|
|
|
82
79
|
return;
|
|
83
80
|
};
|
|
84
81
|
|
|
82
|
+
//create axios instance get
|
|
83
|
+
this.axiosInstanceGet = axios.create({
|
|
84
|
+
method: 'GET',
|
|
85
|
+
baseURL: CONSTANTS.ApiUrls.BaseURL,
|
|
86
|
+
timeout: 5000,
|
|
87
|
+
headers: {
|
|
88
|
+
'X-MitsContextKey': contextKey
|
|
89
|
+
},
|
|
90
|
+
maxContentLength: 100000000,
|
|
91
|
+
maxBodyLength: 1000000000,
|
|
92
|
+
withCredentials: true,
|
|
93
|
+
httpsAgent: new https.Agent({
|
|
94
|
+
keepAlive: false,
|
|
95
|
+
rejectUnauthorized: false
|
|
96
|
+
})
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
//create axios instance post
|
|
100
|
+
this.axiosInstancePost = axios.create({
|
|
101
|
+
method: 'POST',
|
|
102
|
+
baseURL: CONSTANTS.ApiUrls.BaseURL,
|
|
103
|
+
timeout: 5000,
|
|
104
|
+
headers: {
|
|
105
|
+
'X-MitsContextKey': contextKey,
|
|
106
|
+
'content-type': 'application/json'
|
|
107
|
+
},
|
|
108
|
+
maxContentLength: 100000000,
|
|
109
|
+
maxBodyLength: 1000000000,
|
|
110
|
+
withCredentials: true,
|
|
111
|
+
httpsAgent: new https.Agent({
|
|
112
|
+
keepAlive: false,
|
|
113
|
+
rejectUnauthorized: false
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
|
|
85
117
|
this.accountInfo = accountInfo;
|
|
86
118
|
this.contextKey = contextKey;
|
|
87
119
|
|
|
88
120
|
//save melcloud info to the file
|
|
89
121
|
await this.saveData(this.accountInfoFile, accountInfo);
|
|
90
122
|
|
|
91
|
-
//return if connect for config
|
|
92
|
-
if (this.connectForConfig) {
|
|
93
|
-
return contextKey;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
123
|
//check devices list
|
|
97
|
-
await this.chackDevicesList(
|
|
124
|
+
await this.chackDevicesList();
|
|
98
125
|
|
|
99
126
|
//emit connect success
|
|
100
127
|
this.emit('success', `Connect to MELCloud Success.`)
|
|
101
128
|
|
|
102
129
|
//start impulse generator
|
|
103
130
|
const timers = [{ name: 'checkDevicesList', sampling: this.refreshInterval }];
|
|
104
|
-
this.impulseGenerator.start(timers)
|
|
131
|
+
this.impulseGenerator.start(timers)
|
|
105
132
|
|
|
106
133
|
return true;
|
|
107
134
|
} catch (error) {
|
|
@@ -109,29 +136,10 @@ class MelCloud extends EventEmitter {
|
|
|
109
136
|
};
|
|
110
137
|
}
|
|
111
138
|
|
|
112
|
-
async chackDevicesList(
|
|
139
|
+
async chackDevicesList() {
|
|
113
140
|
try {
|
|
114
|
-
const contextKey = this.contextKey ?? key;
|
|
115
|
-
|
|
116
|
-
//create axios instance get
|
|
117
|
-
const axiosInstanceGet = axios.create({
|
|
118
|
-
method: 'GET',
|
|
119
|
-
baseURL: CONSTANTS.ApiUrls.BaseURL,
|
|
120
|
-
timeout: 5000,
|
|
121
|
-
headers: {
|
|
122
|
-
'X-MitsContextKey': contextKey
|
|
123
|
-
},
|
|
124
|
-
maxContentLength: 100000000,
|
|
125
|
-
maxBodyLength: 1000000000,
|
|
126
|
-
withCredentials: true,
|
|
127
|
-
httpsAgent: new https.Agent({
|
|
128
|
-
keepAlive: false,
|
|
129
|
-
rejectUnauthorized: false
|
|
130
|
-
})
|
|
131
|
-
});
|
|
132
|
-
|
|
133
141
|
const debug = this.enableDebugMode ? this.emit('debug', `Scanning for devices.`) : false;
|
|
134
|
-
const listDevicesData = await axiosInstanceGet(CONSTANTS.ApiUrls.ListDevices);
|
|
142
|
+
const listDevicesData = await this.axiosInstanceGet(CONSTANTS.ApiUrls.ListDevices);
|
|
135
143
|
const buildingsList = listDevicesData.data;
|
|
136
144
|
const debug1 = this.enableDebugMode ? this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`) : false;
|
|
137
145
|
|
|
@@ -167,11 +175,6 @@ class MelCloud extends EventEmitter {
|
|
|
167
175
|
}
|
|
168
176
|
const debug3 = this.enableDebugMode ? this.emit('debug', `Found: ${devicesCount} devices.`) : false;
|
|
169
177
|
|
|
170
|
-
//return devices list for config
|
|
171
|
-
if (this.connectForConfig) {
|
|
172
|
-
return devices;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
178
|
//get device info fom devices
|
|
176
179
|
for (const deviceInfo of devices) {
|
|
177
180
|
const deviceId = deviceInfo.DeviceID
|
|
@@ -185,11 +188,11 @@ class MelCloud extends EventEmitter {
|
|
|
185
188
|
//prepare device if not in devices array
|
|
186
189
|
if (!this.devicesId.includes(deviceId)) {
|
|
187
190
|
this.devicesId.push(deviceId);
|
|
188
|
-
this.emit('checkDevicesListComplete', this.accountInfo, contextKey, deviceInfo);
|
|
191
|
+
this.emit('checkDevicesListComplete', this.accountInfo, this.contextKey, deviceInfo);
|
|
189
192
|
}
|
|
190
193
|
};
|
|
191
194
|
|
|
192
|
-
return
|
|
195
|
+
return devices;
|
|
193
196
|
} catch (error) {
|
|
194
197
|
this.impulseGenerator.stop();
|
|
195
198
|
throw new Error(`Scanning for devices error: ${error.message ?? error}.`);
|
|
@@ -208,29 +211,11 @@ class MelCloud extends EventEmitter {
|
|
|
208
211
|
|
|
209
212
|
async send(accountInfo) {
|
|
210
213
|
try {
|
|
211
|
-
//create axios instance post
|
|
212
|
-
const axiosInstancePost = axios.create({
|
|
213
|
-
method: 'POST',
|
|
214
|
-
baseURL: CONSTANTS.ApiUrls.BaseURL,
|
|
215
|
-
timeout: 5000,
|
|
216
|
-
headers: {
|
|
217
|
-
'X-MitsContextKey': this.contextKey,
|
|
218
|
-
'content-type': 'application/json'
|
|
219
|
-
},
|
|
220
|
-
maxContentLength: 100000000,
|
|
221
|
-
maxBodyLength: 1000000000,
|
|
222
|
-
withCredentials: true,
|
|
223
|
-
httpsAgent: new https.Agent({
|
|
224
|
-
keepAlive: false,
|
|
225
|
-
rejectUnauthorized: false
|
|
226
|
-
})
|
|
227
|
-
});
|
|
228
|
-
|
|
229
214
|
const options = {
|
|
230
215
|
data: accountInfo
|
|
231
216
|
};
|
|
232
217
|
|
|
233
|
-
await axiosInstancePost(CONSTANTS.ApiUrls.UpdateApplicationOptions, options);
|
|
218
|
+
await this.axiosInstancePost(CONSTANTS.ApiUrls.UpdateApplicationOptions, options);
|
|
234
219
|
await this.saveData(this.accountInfoFile, accountInfo);
|
|
235
220
|
return true;
|
|
236
221
|
} catch (error) {
|