homebridge-melcloud-control 2.5.0-beta.69 → 2.5.0-beta.7

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,45 +6,18 @@
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</label><br>
9
+ <label id="accountName" style="font-size: 23px">Account Name</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">
13
13
  <label for="name">Name</label>
14
14
  <input id="name" type="text" class="form-control"><br>
15
- <label for="user">User Name</label>
15
+ <label for="user">MELCloud User</label>
16
16
  <input id="user" type="text" class="form-control"><br>
17
- <label for="passwd">Password</label>
18
- <input id="passwd" type="password" class="form-control"><br>
17
+ <label for="passwd">MELCloud Password</label>
18
+ <input id="passwd" type="text" class="form-control"><br>
19
19
  <label for="language">Language</label>
20
- <select id="language" name="language" class="form-control"><br>
21
- <option value="0">English</option>
22
- <option value="1">Български</option>
23
- <option value="2">Čeština</option>
24
- <option value="3">Dansk</option>
25
- <option value="4">Deutsch</option>
26
- <option value="5">Eesti</option>
27
- <option value="6">Español</option>
28
- <option value="7">Français</option>
29
- <option value="8">Հայերեն</option>
30
- <option value="9">Latviešu</option>
31
- <option value="10">Lietuvių</option>
32
- <option value="11">Magyar</option>
33
- <option value="12">Nederlands</option>
34
- <option value="13">Norwegian</option>
35
- <option value="14">Polski</option>
36
- <option value="15">Português</option>
37
- <option value="16">Русский</option>
38
- <option value="17">Suomi</option>
39
- <option value="18">Svenska</option>
40
- <option value="19">Svenska</option>
41
- <option value="20">Українська</option>
42
- <option value="21">Türkçe</option>
43
- <option value="22">Ελληνικά</option>
44
- <option value="23">Hrvatski</option>
45
- <option value="24">Română</option>
46
- <option value="25">Slovenščina</option>
47
- </select>
20
+ <input id="language" type="text" class="form-control"><br>
48
21
  </div>
49
22
  <div class="text-center">
50
23
  <button id="logIn" type="button" class="btn btn-primary">Connect to MELCloud</button>
@@ -83,8 +56,6 @@
83
56
  const setRemoveAtribute = j === i ? document.getElementById(`button${j}`).setAttribute("class", "btn btn-secondary") : document.getElementById(`button${j}`).setAttribute("class", "btn btn-primary");
84
57
  }
85
58
 
86
- //const devicesCount = pluginConfig[0].accounts[i].devicesAta.length ?? 0;
87
- //document.getElementById('info').innerHTML = `MELCloud configured ${devicesCount} ${devicesCount} ${devicesCount !== 1 ? 'devices' : 'device'}.`;
88
59
  document.getElementById('accountName').innerHTML = pluginConfig[0].accounts[i].name || '';
89
60
  document.getElementById('name').value = pluginConfig[0].accounts[i].name || '';
90
61
  document.getElementById('user').value = pluginConfig[0].accounts[i].user || '';
@@ -92,8 +63,7 @@
92
63
  document.getElementById('language').value = pluginConfig[0].accounts[i].language || '';
93
64
 
94
65
  const accountConfigured = pluginConfig[0].accounts[i].name && pluginConfig[0].accounts[i].user && pluginConfig[0].accounts[i].passwd && pluginConfig[0].accounts[i].language;
95
- const setButtonState = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
96
- document.getElementById('configButton').setAttribute('disabled');
66
+ const setButtonName = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
97
67
  await homebridge.updatePluginConfig(pluginConfig);
98
68
  this.deviceIndex = i;
99
69
  });
@@ -112,7 +82,7 @@
112
82
  pluginConfig[0].accounts[this.deviceIndex].language = document.querySelector('#language').value;
113
83
 
114
84
  const accountConfigured = pluginConfig[0].accounts[i].name && pluginConfig[0].accounts[i].user && pluginConfig[0].accounts[i].passwd && pluginConfig[0].accounts[i].language;
115
- const setButtonState = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
85
+ const setButtonMode = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
116
86
 
117
87
  await homebridge.updatePluginConfig(pluginConfig);
118
88
  await homebridge.savePluginConfig(pluginConfig);
@@ -136,109 +106,55 @@
136
106
  const user = pluginConfig[0].accounts[this.deviceIndex].user;
137
107
  const passwd = pluginConfig[0].accounts[this.deviceIndex].passwd;
138
108
  const language = pluginConfig[0].accounts[this.deviceIndex].language;
109
+ const enableDebugMode = pluginConfig[0].accounts[this.deviceIndex].enableDebugMode;
110
+ const refreshInterval = pluginConfig[0].accounts[this.deviceIndex].refreshInterval;
139
111
 
140
112
  const payload = {
141
113
  accountName: accountName,
142
114
  user: user,
143
115
  passwd: passwd,
144
- language: language
116
+ language: language,
117
+ enableDebugMode: enableDebugMode,
118
+ refreshInterval: refreshInterval
145
119
  };
146
120
  const response = await homebridge.request('/connect', payload);
147
- const info = response.info ?? '';
121
+ const info = response.info;
148
122
  const status = response.status;
149
123
  const devices = response.data ?? [];
150
- const newDevices = [];
151
124
 
152
125
  switch (status) {
153
126
  case 0:
154
127
  //get device info fom devices
155
- devices.forEach((deviceInfo, index) => {
156
- const deviceType = deviceInfo.Type;
128
+ for (const deviceInfo of devices) {
157
129
  const deviceId = deviceInfo.DeviceID;
158
130
  const deviceName = deviceInfo.DeviceName;
131
+ };
159
132
 
160
- //config account keys
161
- const accountKeys = Object.keys(pluginConfig[0].accounts[this.deviceIndex]);
162
-
163
- //devices ata
164
- const deviceAta = {
165
- name: deviceName,
166
- id: deviceId,
167
- type: deviceType,
168
- displayMode: 0,
169
- heatDryFanMode: 0,
170
- coolDryFanMode: 0,
171
- autoDryFanMode: 0,
172
- presets: false,
173
- temperatureSensor: false,
174
- temperatureSensorOutdoor: false,
175
- buttonsSensors: []
176
- };
177
- const ataDevices = accountKeys.includes('ataDevices') ? pluginConfig[0].accounts[this.deviceIndex].ataDevices : pluginConfig[0].accounts[this.deviceIndex].ataDevices = [];
178
- const ataDeviceIdExist = ataDevices.some(device => device.id === deviceId)
179
- const pushTypeAta = deviceType === 0 && !ataDeviceIdExist ? ataDevices.push(deviceAta) : false;
180
-
181
- //devices atw
182
- const deviceAtw = {
183
- name: deviceName,
184
- id: deviceId,
185
- type: deviceType,
186
- displayMode: 0,
187
- temperatureSensorFlow: false,
188
- temperatureSensorFlow: false,
189
- temperatureSensorFlow: false,
190
- temperatureSensorFlowZone1: false,
191
- temperatureSensorReturnZone1: false,
192
- temperatureSensorFlowWaterTank: false,
193
- temperatureSensorReturnWaterTank: false,
194
- atemperatureSensorFlowZone2: false,
195
- temperatureSensorReturnZone2: false,
196
- presets: false,
197
- temperatureSensor: false,
198
- temperatureSensorOutdoor: false,
199
- buttonsSensors: []
200
- };
201
- const atwDevices = accountKeys.includes('atwDevices') ? pluginConfig[0].accounts[this.deviceIndex].atwDevices : pluginConfig[0].accounts[this.deviceIndex].atwDevices = [];
202
- const atwDeviceIdExist = atwDevices.some(device => device.id === deviceId)
203
- const pushTypeAtw = deviceType === 1 && !atwDeviceIdExist ? atwDevices.push(deviceAtw) : false;
204
-
205
- //devices erv
206
- const deviceErv = {
207
- name: deviceName,
208
- id: deviceId,
209
- type: deviceType,
210
- displayMode: 0,
211
- temperatureSensor: false,
212
- temperatureSensorOutdoor: false,
213
- temperatureSensorSupply: false,
214
- presets: false,
215
- temperatureSensor: false,
216
- temperatureSensorOutdoor: false,
217
- buttonsSensors: []
218
- };
219
- const ervDevices = accountKeys.includes('ervDevices') ? pluginConfig[0].accounts[this.deviceIndex].ervDevices : pluginConfig[0].accounts[this.deviceIndex].ervDevices = [];
220
- const ervDeviceIdExist = ervDevices.some(device => device.id === deviceId)
221
- const pushTypeErv = deviceType === 3 && !ervDeviceIdExist ? ervDevices.push(deviceErv) : false;
222
-
223
- //push new devices to array
224
- const pushNewDevice = ataDeviceIdExist || atwDeviceIdExist || ervDeviceIdExist ? false : newDevices.push(deviceId);
225
- });
226
-
227
- const devicesCount = newDevices.length;
228
- document.getElementById('info').innerHTML = `Check devices complete, found ${devicesCount} ${devicesCount !== 1 ? 'new devices' : 'new device'}. ${devicesCount === 0 ? '' : 'Now You can start to configure it.'}`;
133
+ document.getElementById('info').innerHTML = `${info} Found: ${devices.length} devices. Now You can start to configure it.`;
229
134
  document.getElementById('info').style.color = 'green';
230
-
231
135
  await homebridge.updatePluginConfig(pluginConfig);
232
136
  await homebridge.savePluginConfig(pluginConfig);
233
137
  break;
234
138
  case 1:
235
139
  document.getElementById('info').innerHTML = info;
236
- document.getElementById('info').style.color = 'red';
140
+ document.getElementById('info').style.color = 'green';
237
141
  break;
238
- default:
239
- document.getElementById('info').innerHTML = `Received unknown status: ${status}, please try again.`;
142
+ case 2:
143
+ document.getElementById('info').innerHTML = info;
144
+ document.getElementById('info').style.color = 'white';
145
+ break;
146
+ case 3:
147
+ document.getElementById('info').innerHTML = info;
148
+ document.getElementById('info').style.color = 'gray';
149
+ break;
150
+ case 4:
151
+ document.getElementById('info').innerHTML = info;
240
152
  document.getElementById('info').style.color = 'yellow';
241
153
  break;
154
+ case 5:
155
+ document.getElementById('info').innerHTML = info;
156
+ document.getElementById('info').style.color = 'red';
157
+ break;
242
158
  };
243
159
 
244
160
  homebridge.hideSpinner();
@@ -19,26 +19,62 @@ class PluginUiServer extends HomebridgePluginUiServer {
19
19
  const user = payload.user;
20
20
  const passwd = payload.passwd;
21
21
  const language = payload.language;
22
+ const enableDebugMode = payload.enableDebugMode;
23
+ const refreshInterval = payload.refreshInterval;
22
24
  const accountInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
23
25
  const deviceInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Device_`;
24
26
  const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
27
+ let data = {};
25
28
 
26
29
  try {
27
- let data = {};
28
- const melCloud = new MelCloud(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, false, 0, true);
29
- const contextKey = await melCloud.connect();
30
- const devices = await melCloud.chackDevicesList(contextKey);
31
- return data = {
32
- info: '',
33
- status: 0,
34
- data: devices
35
- };
30
+ const melCloud = new MelCloud(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval, false);
31
+ melCloud.on('devicesList', (devices) => {
32
+ data = {
33
+ info: 'Check devices list complete.',
34
+ status: 0,
35
+ data: devices
36
+ };
37
+ })
38
+ .on('success', (message) => {
39
+ data = {
40
+ info: message,
41
+ status: 1
42
+ };
43
+ })
44
+ .on('message', (message) => {
45
+ data = {
46
+ info: message,
47
+ status: 2
48
+ };
49
+ })
50
+ .on('debug', (debug) => {
51
+ data = {
52
+ info: debug,
53
+ status: 3
54
+ };
55
+ })
56
+ .on('warn', (warn) => {
57
+ data = {
58
+ info: warn,
59
+ status: 4
60
+ };
61
+ })
62
+ .on('error', async (error) => {
63
+ data = {
64
+ info: error,
65
+ status: 5
66
+ };
67
+ });
68
+
69
+ return data;
36
70
  } catch (error) {
37
- return data = {
71
+ data = {
38
72
  info: error,
39
- status: 1
73
+ status: 5
40
74
  };
75
+ return data;
41
76
  };
77
+
42
78
  };
43
79
  };
44
80
 
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, false);
81
+ const melCloud = new MelCloud(user, passwd, language, accountInfoFile, buildingsFile, deviceInfoFile, enableDebugMode, refreshInterval, true);
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.69",
4
+ "version": "2.5.0-beta.7",
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,15 +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, connectForConfig) {
11
+ constructor(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, enableDebugMode, refreshInterval, startImpulseGenerator) {
12
12
  super();
13
+ this.enableDebugMode = enableDebugMode;
13
14
  this.accountInfoFile = accountInfoFile;
14
15
  this.buildingsFile = buildingsFile;
15
16
  this.deviceInfoFile = deviceInfoFile;
16
- this.enableDebugMode = enableDebugMode;
17
17
  this.refreshInterval = refreshInterval;
18
- this.connectForConfig = connectForConfig;
19
- this.contextKey = '';
18
+ this.startImpulseGenerator = startImpulseGenerator;
20
19
  this.devicesId = [];
21
20
 
22
21
  this.options = {
@@ -31,18 +30,16 @@ class MelCloud extends EventEmitter {
31
30
  }
32
31
  };
33
32
 
34
- if (!connectForConfig) {
35
- this.impulseGenerator = new ImpulseGenerator();
36
- this.impulseGenerator.on('checkDevicesList', async () => {
37
- try {
38
- await this.chackDevicesList(this.contextKey);
39
- } catch (error) {
40
- this.emit('error', `Check devices list: ${error}.`);
41
- };
42
- }).on('state', (state) => { });
43
-
44
- this.connect();
45
- };
33
+ this.impulseGenerator = new ImpulseGenerator();
34
+ this.impulseGenerator.on('checkDevicesList', async () => {
35
+ try {
36
+ await this.chackDevicesList();
37
+ } catch (error) {
38
+ this.emit('error', `Check devices list: ${error}.`);
39
+ };
40
+ }).on('state', (state) => { });
41
+
42
+ this.connect();
46
43
  };
47
44
 
48
45
  async connect() {
@@ -82,26 +79,57 @@ class MelCloud extends EventEmitter {
82
79
  this.emit('warn', `Context key: ${contextKey}, missing.`)
83
80
  return;
84
81
  };
82
+
83
+ //create axios instance get
84
+ this.axiosInstanceGet = axios.create({
85
+ method: 'GET',
86
+ baseURL: CONSTANTS.ApiUrls.BaseURL,
87
+ timeout: 5000,
88
+ headers: {
89
+ 'X-MitsContextKey': contextKey
90
+ },
91
+ maxContentLength: 100000000,
92
+ maxBodyLength: 1000000000,
93
+ withCredentials: true,
94
+ httpsAgent: new https.Agent({
95
+ keepAlive: false,
96
+ rejectUnauthorized: false
97
+ })
98
+ });
99
+
100
+ //create axios instance post
101
+ this.axiosInstancePost = axios.create({
102
+ method: 'POST',
103
+ baseURL: CONSTANTS.ApiUrls.BaseURL,
104
+ timeout: 5000,
105
+ headers: {
106
+ 'X-MitsContextKey': contextKey,
107
+ 'content-type': 'application/json'
108
+ },
109
+ maxContentLength: 100000000,
110
+ maxBodyLength: 1000000000,
111
+ withCredentials: true,
112
+ httpsAgent: new https.Agent({
113
+ keepAlive: false,
114
+ rejectUnauthorized: false
115
+ })
116
+ });
117
+
85
118
  this.accountInfo = accountInfo;
86
119
  this.contextKey = contextKey;
87
120
 
88
- //return if connect for config
89
- if (this.connectForConfig) {
90
- return contextKey;
91
- };
92
-
93
121
  //save melcloud info to the file
94
122
  await this.saveData(this.accountInfoFile, accountInfo);
95
123
 
96
124
  //check devices list
97
- await this.chackDevicesList(contextKey);
125
+ await this.chackDevicesList();
98
126
 
99
127
  //emit connect success
100
128
  this.emit('success', `Connect to MELCloud Success.`)
101
129
 
102
130
  //start impulse generator
103
131
  const timers = [{ name: 'checkDevicesList', sampling: this.refreshInterval }];
104
- this.impulseGenerator.start(timers);
132
+ const startImpulseGenerator = this.startImpulseGenerator ? this.impulseGenerator.start(timers) : false;
105
133
 
106
134
  return true;
107
135
  } catch (error) {
@@ -109,27 +137,10 @@ class MelCloud extends EventEmitter {
109
137
  };
110
138
  }
111
139
 
112
- async chackDevicesList(contextKey) {
140
+ async chackDevicesList() {
113
141
  try {
114
- //create axios instance get
115
- const axiosInstanceGet = axios.create({
116
- method: 'GET',
117
- baseURL: CONSTANTS.ApiUrls.BaseURL,
118
- timeout: 5000,
119
- headers: {
120
- 'X-MitsContextKey': contextKey
121
- },
122
- maxContentLength: 100000000,
123
- maxBodyLength: 1000000000,
124
- withCredentials: true,
125
- httpsAgent: new https.Agent({
126
- keepAlive: false,
127
- rejectUnauthorized: false
128
- })
129
- });
130
-
131
142
  const debug = this.enableDebugMode ? this.emit('debug', `Scanning for devices.`) : false;
132
- const listDevicesData = await axiosInstanceGet(CONSTANTS.ApiUrls.ListDevices);
143
+ const listDevicesData = await this.axiosInstanceGet(CONSTANTS.ApiUrls.ListDevices);
133
144
  const buildingsList = listDevicesData.data;
134
145
  const debug1 = this.enableDebugMode ? this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`) : false;
135
146
 
@@ -165,11 +176,6 @@ class MelCloud extends EventEmitter {
165
176
  }
166
177
  const debug3 = this.enableDebugMode ? this.emit('debug', `Found: ${devicesCount} devices.`) : false;
167
178
 
168
- //return devices list for config
169
- if (this.connectForConfig) {
170
- return devices;
171
- };
172
-
173
179
  //get device info fom devices
174
180
  for (const deviceInfo of devices) {
175
181
  const deviceId = deviceInfo.DeviceID
@@ -183,13 +189,16 @@ class MelCloud extends EventEmitter {
183
189
  //prepare device if not in devices array
184
190
  if (!this.devicesId.includes(deviceId)) {
185
191
  this.devicesId.push(deviceId);
186
- this.emit('checkDevicesListComplete', this.accountInfo, contextKey, deviceInfo);
192
+ this.emit('checkDevicesListComplete', this.accountInfo, this.contextKey, deviceInfo);
187
193
  }
188
194
  };
189
195
 
196
+ //emit devices list
197
+ this.emit('devicesList', devices);
198
+
190
199
  return true;
191
200
  } catch (error) {
192
- const stop = connectForConfig ? false : this.impulseGenerator.stop();
201
+ this.impulseGenerator.stop();
193
202
  throw new Error(`Scanning for devices error: ${error.message ?? error}.`);
194
203
  };
195
204
  }
@@ -206,29 +215,11 @@ class MelCloud extends EventEmitter {
206
215
 
207
216
  async send(accountInfo) {
208
217
  try {
209
- //create axios instance post
210
- const axiosInstancePost = axios.create({
211
- method: 'POST',
212
- baseURL: CONSTANTS.ApiUrls.BaseURL,
213
- timeout: 5000,
214
- headers: {
215
- 'X-MitsContextKey': this.contextKey,
216
- 'content-type': 'application/json'
217
- },
218
- maxContentLength: 100000000,
219
- maxBodyLength: 1000000000,
220
- withCredentials: true,
221
- httpsAgent: new https.Agent({
222
- keepAlive: false,
223
- rejectUnauthorized: false
224
- })
225
- });
226
-
227
218
  const options = {
228
219
  data: accountInfo
229
220
  };
230
221
 
231
- await axiosInstancePost(CONSTANTS.ApiUrls.UpdateApplicationOptions, options);
222
+ await this.axiosInstancePost(CONSTANTS.ApiUrls.UpdateApplicationOptions, options);
232
223
  await this.saveData(this.accountInfoFile, accountInfo);
233
224
  return true;
234
225
  } catch (error) {