homebridge-melcloud-control 2.5.0-beta.2 → 2.5.0-beta.21

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.
@@ -6,7 +6,7 @@
6
6
  <div id="melCloudAccount" style="display: none;" class="card card-body">
7
7
  <form id="configForm">
8
8
  <div class="text-center">
9
- <label id="accountName" style="font-size: 23px">Account Name</label><br>
9
+ <label id="accountName" style="font-size: 23px">Account</label><br>
10
10
  <label id="info" style="text-align: center; font-size: 17px;">MELCloud</label><br><br>
11
11
  </div>
12
12
  <div class="form-group">
@@ -20,8 +20,7 @@
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">Log In</button>
24
- <button id="getDevices" type="button" class="btn btn-primary">Get Devices</button>
23
+ <button id="logIn" type="button" class="btn btn-primary">Connect to MELCloud</button>
25
24
  <button id="configButton" type="button" class="btn btn-primary"><i class="fas fa-gear"></i></button>
26
25
  </div>
27
26
  </form>
@@ -64,7 +63,8 @@
64
63
  document.getElementById('language').value = pluginConfig[0].accounts[i].language || '';
65
64
 
66
65
  const accountConfigured = pluginConfig[0].accounts[i].name && pluginConfig[0].accounts[i].user && pluginConfig[0].accounts[i].passwd && pluginConfig[0].accounts[i].language;
67
- const setButtonName = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
66
+ const setButtonState = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
67
+ document.getElementById('configButton').setAttribute('disabled');
68
68
  await homebridge.updatePluginConfig(pluginConfig);
69
69
  this.deviceIndex = i;
70
70
  });
@@ -83,7 +83,7 @@
83
83
  pluginConfig[0].accounts[this.deviceIndex].language = document.querySelector('#language').value;
84
84
 
85
85
  const accountConfigured = pluginConfig[0].accounts[i].name && pluginConfig[0].accounts[i].user && pluginConfig[0].accounts[i].passwd && pluginConfig[0].accounts[i].language;
86
- const setButtonMode = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
86
+ const setButtonState = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
87
87
 
88
88
  await homebridge.updatePluginConfig(pluginConfig);
89
89
  await homebridge.savePluginConfig(pluginConfig);
@@ -101,7 +101,7 @@
101
101
 
102
102
  try {
103
103
  await homebridge.updatePluginConfig(pluginConfig)
104
- document.getElementById('info').innerHTML = '';
104
+ document.getElementById('info').innerHTML = 'Connecting...';
105
105
 
106
106
  const accountName = pluginConfig[0].accounts[this.deviceIndex].name;
107
107
  const user = pluginConfig[0].accounts[this.deviceIndex].user;
@@ -111,7 +111,6 @@
111
111
  const refreshInterval = pluginConfig[0].accounts[this.deviceIndex].refreshInterval;
112
112
 
113
113
  const payload = {
114
- mode: 'connect',
115
114
  accountName: accountName,
116
115
  user: user,
117
116
  passwd: passwd,
@@ -120,77 +119,42 @@
120
119
  refreshInterval: refreshInterval
121
120
  };
122
121
  const response = await homebridge.request('/connect', payload);
123
- const info = response.info;
122
+ const info = response.info ?? '';
124
123
  const status = response.status;
125
- const data = response.data;
126
- const error = response.error;
124
+ const devices = response.data ?? [];
127
125
 
128
126
  switch (status) {
129
127
  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:
166
128
  //get device info fom devices
167
129
  for (const deviceInfo of devices) {
168
130
  const deviceId = deviceInfo.DeviceID;
169
131
  const deviceName = deviceInfo.DeviceName;
170
-
171
- //prepare device if not in devices array
172
- if (!devicesId.includes(deviceId)) {
173
- devicesId.push(deviceId);
174
- }
175
132
  };
176
133
 
177
- document.getElementById('info').innerHTML = `${info} Found: ${devicesId.length} devices. Now You can start configure it.`;
134
+ const devicesCount = devices.length;
135
+ document.getElementById('info').innerHTML = `Success, found ${devicesCount} ${devicesCount !== 1 ? 'devices' : 'device'}. Now You can start to configure it.`;
136
+ document.getElementById('info').style.color = 'green';
137
+ document.getElementById('configButton').removeAttribute('disabled');
178
138
  await homebridge.updatePluginConfig(pluginConfig);
179
139
  await homebridge.savePluginConfig(pluginConfig);
180
140
  break;
181
- case 2:
182
- document.getElementById('info').innerHTML = `MELCloud error: ${JSON.stringify(error, null, 2)}`;
141
+ case 1:
142
+ document.getElementById('info').innerHTML = info;
183
143
  document.getElementById('info').style.color = 'red';
184
144
  break;
145
+ default:
146
+ document.getElementById('info').innerHTML = `Received unknown status: ${status}, please try again.`;
147
+ document.getElementById('info').style.color = 'yellow';
148
+ break;
185
149
  };
186
150
 
187
151
  homebridge.hideSpinner();
188
152
  } catch (e) {
189
- homebridge.toast.error(`Get devices error: ${e.message}`);
153
+ document.getElementById('info').innerHTML = 'Please try again.';
154
+ homebridge.toast.error(`Data error: ${e.message}`);
190
155
  } finally {
191
156
  homebridge.hideSpinner();
192
- }
157
+ };
193
158
  });
194
-
195
159
  })();
196
160
  </script>
@@ -7,9 +7,6 @@ class PluginUiServer extends HomebridgePluginUiServer {
7
7
  constructor() {
8
8
  super();
9
9
 
10
- //get devices
11
- this.onRequest('/getdevices', this.start.bind(this));
12
-
13
10
  //connect
14
11
  this.onRequest('/connect', this.start.bind(this));
15
12
 
@@ -18,8 +15,6 @@ class PluginUiServer extends HomebridgePluginUiServer {
18
15
  };
19
16
 
20
17
  async start(payload) {
21
-
22
- const mode = payload.mode;
23
18
  const accountName = payload.accountName;
24
19
  const user = payload.user;
25
20
  const passwd = payload.passwd;
@@ -29,40 +24,22 @@ class PluginUiServer extends HomebridgePluginUiServer {
29
24
  const accountInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
30
25
  const deviceInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Device_`;
31
26
  const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
32
- const melCloud = new MelCloud(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval);
33
27
 
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
- };
28
+ try {
29
+ let data = {};
30
+ const melCloud = new MelCloud(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval, true);
31
+ const contextKey = await melCloud.connect();
32
+ const devices = await melCloud.chackDevicesList(contextKey);
33
+ return data = {
34
+ info: '',
35
+ status: 0,
36
+ data: devices
37
+ };
38
+ } catch (error) {
39
+ return data = {
40
+ info: error,
41
+ status: 1
42
+ };
66
43
  };
67
44
  };
68
45
  };
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, false);
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.2",
4
+ "version": "2.5.0-beta.21",
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,13 +8,14 @@ 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, connectForConfig) {
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;
18
19
  this.devicesId = [];
19
20
 
20
21
  this.options = {
@@ -38,7 +39,9 @@ class MelCloud extends EventEmitter {
38
39
  };
39
40
  }).on('state', (state) => { });
40
41
 
41
- this.connect();
42
+ if (!connectForConfig) {
43
+ this.connect();
44
+ };
42
45
  };
43
46
 
44
47
  async connect() {
@@ -79,56 +82,26 @@ class MelCloud extends EventEmitter {
79
82
  return;
80
83
  };
81
84
 
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
-
117
85
  this.accountInfo = accountInfo;
118
86
  this.contextKey = contextKey;
119
87
 
120
88
  //save melcloud info to the file
121
89
  await this.saveData(this.accountInfoFile, accountInfo);
122
90
 
91
+ //return if connect for config
92
+ if (this.connectForConfig) {
93
+ return contextKey;
94
+ };
95
+
123
96
  //check devices list
124
- await this.chackDevicesList();
97
+ await this.chackDevicesList(contextKey);
125
98
 
126
99
  //emit connect success
127
100
  this.emit('success', `Connect to MELCloud Success.`)
128
101
 
129
102
  //start impulse generator
130
103
  const timers = [{ name: 'checkDevicesList', sampling: this.refreshInterval }];
131
- this.impulseGenerator.start(timers)
104
+ this.impulseGenerator.start(timers);
132
105
 
133
106
  return true;
134
107
  } catch (error) {
@@ -136,10 +109,29 @@ class MelCloud extends EventEmitter {
136
109
  };
137
110
  }
138
111
 
139
- async chackDevicesList() {
112
+ async chackDevicesList(key) {
140
113
  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
+
141
133
  const debug = this.enableDebugMode ? this.emit('debug', `Scanning for devices.`) : false;
142
- const listDevicesData = await this.axiosInstanceGet(CONSTANTS.ApiUrls.ListDevices);
134
+ const listDevicesData = await axiosInstanceGet(CONSTANTS.ApiUrls.ListDevices);
143
135
  const buildingsList = listDevicesData.data;
144
136
  const debug1 = this.enableDebugMode ? this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`) : false;
145
137
 
@@ -175,6 +167,11 @@ class MelCloud extends EventEmitter {
175
167
  }
176
168
  const debug3 = this.enableDebugMode ? this.emit('debug', `Found: ${devicesCount} devices.`) : false;
177
169
 
170
+ //return devices list for config
171
+ if (this.connectForConfig) {
172
+ return devices;
173
+ };
174
+
178
175
  //get device info fom devices
179
176
  for (const deviceInfo of devices) {
180
177
  const deviceId = deviceInfo.DeviceID
@@ -188,11 +185,11 @@ class MelCloud extends EventEmitter {
188
185
  //prepare device if not in devices array
189
186
  if (!this.devicesId.includes(deviceId)) {
190
187
  this.devicesId.push(deviceId);
191
- this.emit('checkDevicesListComplete', this.accountInfo, this.contextKey, deviceInfo);
188
+ this.emit('checkDevicesListComplete', this.accountInfo, contextKey, deviceInfo);
192
189
  }
193
190
  };
194
191
 
195
- return devices;
192
+ return true;
196
193
  } catch (error) {
197
194
  this.impulseGenerator.stop();
198
195
  throw new Error(`Scanning for devices error: ${error.message ?? error}.`);
@@ -211,11 +208,29 @@ class MelCloud extends EventEmitter {
211
208
 
212
209
  async send(accountInfo) {
213
210
  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
+
214
229
  const options = {
215
230
  data: accountInfo
216
231
  };
217
232
 
218
- await this.axiosInstancePost(CONSTANTS.ApiUrls.UpdateApplicationOptions, options);
233
+ await axiosInstancePost(CONSTANTS.ApiUrls.UpdateApplicationOptions, options);
219
234
  await this.saveData(this.accountInfoFile, accountInfo);
220
235
  return true;
221
236
  } catch (error) {