homebridge-melcloud-control 4.0.0-beta.114 → 4.0.0-beta.116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -30,8 +30,8 @@ class MelCloudPlatform {
30
30
  api.on('didFinishLaunching', async () => {
31
31
  //loop through accounts
32
32
  for (const account of config.accounts) {
33
- const displayType = account.displayType || 'disabled';
34
- if (displayType === 'disabled') continue;
33
+ const accountType = account.accountType || 'disabled';
34
+ if (accountType === 'disabled') continue;
35
35
 
36
36
  const accountName = account.name;
37
37
  const user = account.user;
@@ -90,7 +90,7 @@ class MelCloudPlatform {
90
90
  .on('start', async () => {
91
91
  try {
92
92
  //melcloud account
93
- const melCloud = new MelCloud(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, logLevel.warn, logLevel.debug, false)
93
+ const melCloud = new MelCloud(accountType, user, passwd, language, accountFile, buildingsFile, devicesFile, logLevel.warn, logLevel.debug, false)
94
94
  .on('success', (msg) => logLevel.success && log.success(`${accountName}, ${msg}`))
95
95
  .on('info', (msg) => logLevel.info && log.info(`${accountName}, ${msg}`))
96
96
  .on('debug', (msg) => logLevel.debug && log.info(`${accountName}, debug: ${msg}`))
@@ -146,7 +146,7 @@ class MelCloudPlatform {
146
146
  let configuredDevice;
147
147
  switch (deviceType) {
148
148
  case 0: //ATA
149
- configuredDevice = new DeviceAta(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt);
149
+ configuredDevice = new DeviceAta(api, account, device, devicesFile, useFahrenheit, restFul, mqtt);
150
150
  break;
151
151
  case 1: //ATW
152
152
  configuredDevice = new DeviceAtw(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt);
@@ -181,8 +181,10 @@ class MelCloudPlatform {
181
181
  api.publishExternalAccessories(PluginName, [accessory]);
182
182
  if (logLevel.success) log.success(`${accountName}, ${deviceTypeText}, ${deviceName}, Published as external accessory.`);
183
183
 
184
- //start impulse generators
185
- await melCloud.impulseGenerator.state(true, [{ name: 'checkDevicesList', sampling: refreshInterval }]);
184
+ //start impulse generators\
185
+ const timmers = accountType === 'melcloudhome' ? [{ name: 'connect', sampling: 150000 }, { name: 'checkDevicesList', sampling: deviceRefreshInterval }] : [{ name: 'checkDevicesList', sampling: refreshInterval }];
186
+ const impulseGenerator = configuredDevice.getImpulseGenerator();
187
+ await melCloud.impulseGenerator.state(true, timmers);
186
188
  await configuredDevice.startStopImpulseGenerator(true, [{ name: 'checkState', sampling: deviceRefreshInterval }]);
187
189
 
188
190
  //stop impulse generator
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.0.0-beta.114",
4
+ "version": "4.0.0-beta.116",
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
@@ -6,7 +6,7 @@ import { TemperatureDisplayUnits, AirConditioner, ApiUrlsHome } from './constant
6
6
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
7
7
 
8
8
  class DeviceAta extends EventEmitter {
9
- constructor(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt) {
9
+ constructor(api, account, device, devicesFile, useFahrenheit, restFul, mqtt) {
10
10
  super();
11
11
 
12
12
  Accessory = api.platformAccessory;
@@ -31,7 +31,6 @@ class DeviceAta extends EventEmitter {
31
31
  this.logInfo = account.log?.info || false;
32
32
  this.logWarn = account.log?.warn || false;
33
33
  this.logDebug = account.log?.debug || false;
34
- this.contextKey = contextKey;
35
34
  this.accountName = account.name;
36
35
  this.deviceId = device.id;
37
36
  this.deviceName = device.name;
@@ -920,7 +919,7 @@ class DeviceAta extends EventEmitter {
920
919
  async start() {
921
920
  try {
922
921
  //melcloud device
923
- this.melCloudAta = new MelCloudAta(this.device, this.contextKey, this.devicesFile)
922
+ this.melCloudAta = new MelCloudAta(this.device, this.devicesFile)
924
923
  .on('deviceInfo', (manufacturer, modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
925
924
  if (this.logDeviceInfo && this.displayDeviceInfo) {
926
925
  this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
package/src/melcloud.js CHANGED
@@ -7,9 +7,9 @@ import Functions from './functions.js';
7
7
  import { ApiUrls, ApiUrlsHome } from './constants.js';
8
8
 
9
9
  class MelCloud extends EventEmitter {
10
- constructor(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, logWarn, logDebug, requestConfig) {
10
+ constructor(accountType, user, passwd, language, accountFile, buildingsFile, devicesFile, logWarn, logDebug, requestConfig) {
11
11
  super();
12
- this.displayType = displayType;
12
+ this.accountType = accountType;
13
13
  this.user = user;
14
14
  this.passwd = passwd;
15
15
  this.language = language;
@@ -45,6 +45,13 @@ class MelCloud extends EventEmitter {
45
45
 
46
46
  if (!requestConfig) {
47
47
  this.impulseGenerator = new ImpulseGenerator()
48
+ .on('connect', async () => {
49
+ try {
50
+ await this.connect();
51
+ } catch (error) {
52
+ this.emit('error', `Impulse generator error: ${error}`);
53
+ }
54
+ })
48
55
  .on('checkDevicesList', async () => {
49
56
  try {
50
57
  await this.checkDevicesList(this.contextKey);
@@ -213,7 +220,7 @@ class MelCloud extends EventEmitter {
213
220
  );
214
221
 
215
222
  // Funkcja tworząca finalny obiekt Device
216
- const createDevice = (device, type) => {
223
+ const createDevice = (device, type, contextKey) => {
217
224
  // Settings już kapitalizowane w nazwach
218
225
  const settingsArray = device.Settings || [];
219
226
 
@@ -241,6 +248,7 @@ class MelCloud extends EventEmitter {
241
248
 
242
249
  return {
243
250
  ...rest,
251
+ ContextKey: contextKey,
244
252
  Type: type,
245
253
  DeviceID: Id,
246
254
  DeviceName: GivenDisplayName,
@@ -249,9 +257,9 @@ class MelCloud extends EventEmitter {
249
257
  };
250
258
 
251
259
  return [
252
- ...(building.airToAirUnits || []).map(d => createDevice(capitalizeKeys(d), 0)),
253
- ...(building.airToWaterUnits || []).map(d => createDevice(capitalizeKeys(d), 1)),
254
- ...(building.airToVentilationUnits || []).map(d => createDevice(capitalizeKeys(d), 3))
260
+ ...(building.airToAirUnits || []).map(d => createDevice(capitalizeKeys(d), 0, this.contextKey)),
261
+ ...(building.airToWaterUnits || []).map(d => createDevice(capitalizeKeys(d), 1, this.contextKey)),
262
+ ...(building.airToVentilationUnits || []).map(d => createDevice(capitalizeKeys(d), 3, this.contextKey))
255
263
  ];
256
264
  });
257
265
 
@@ -292,13 +300,13 @@ class MelCloud extends EventEmitter {
292
300
  if (!loginBtn && this.logWarn) this.emit('warn', `Login button not found`);
293
301
 
294
302
  // Set credentials and login
295
- await Promise.all([loginBtn.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })]);
296
- await page.waitForSelector('input[name="username"]', { timeout: 15000 });
303
+ await Promise.all([loginBtn.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 5000 })]);
304
+ await page.waitForSelector('input[name="username"]', { timeout: 5000 });
297
305
  await page.type('input[name="username"]', this.user, { delay: 50 });
298
306
  await page.type('input[name="password"]', this.passwd, { delay: 50 });
299
307
 
300
308
  const button1 = await page.$('input[type="submit"]');
301
- await Promise.all([button1.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })]);
309
+ await Promise.all([button1.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 5000 })]);
302
310
 
303
311
  // Get cookies C1 and C2
304
312
  let c1 = null, c2 = null;
@@ -332,23 +340,9 @@ class MelCloud extends EventEmitter {
332
340
  }
333
341
  }
334
342
 
335
- async connect() {
336
- let response = {};
337
- switch (this.displayType) {
338
- case "melcloud":
339
- response = await this.connectToMelCloud();
340
- return response
341
- case "melcloudhome":
342
- response = await this.connectToMelCloudHome();
343
- return response
344
- default:
345
- return response
346
- }
347
- }
348
-
349
343
  async checkDevicesList(contextKey) {
350
344
  let devices = [];
351
- switch (this.displayType) {
345
+ switch (this.accountType) {
352
346
  case "melcloud":
353
347
  devices = await this.checkMelcloudDevicesList(contextKey);
354
348
  return devices
@@ -360,6 +354,20 @@ class MelCloud extends EventEmitter {
360
354
  }
361
355
  }
362
356
 
357
+ async connect() {
358
+ let response = {};
359
+ switch (this.accountType) {
360
+ case "melcloud":
361
+ response = await this.connectToMelCloud();
362
+ return response
363
+ case "melcloudhome":
364
+ response = await this.connectToMelCloudHome();
365
+ return response
366
+ default:
367
+ return response
368
+ }
369
+ }
370
+
363
371
  async send(accountInfo) {
364
372
  try {
365
373
  const options = { data: accountInfo };
@@ -6,7 +6,7 @@ import Functions from './functions.js';
6
6
  import { ApiUrls, ApiUrlsHome, AirConditioner } from './constants.js';
7
7
 
8
8
  class MelCloudAta extends EventEmitter {
9
- constructor(device, contextKey, devicesFile) {
9
+ constructor(device, devicesFile) {
10
10
  super();
11
11
  this.accountType = device.displayType
12
12
  this.deviceId = device.id;
@@ -26,37 +26,7 @@ class MelCloudAta extends EventEmitter {
26
26
  keepAlive: false,
27
27
  rejectUnauthorized: false
28
28
  })
29
- };
30
-
31
- this.axiosInstancePost = axios.create({
32
- method: 'POST',
33
- baseURL: ApiUrls.BaseURL,
34
- headers: {
35
- 'X-MitsContextKey': contextKey,
36
- 'content-type': 'application/json'
37
- },
38
- withCredentials: true,
39
- ...this.axiosDefaults
40
- });
41
-
42
- this.axiosInstancePut = axios.create({
43
- method: 'PUT',
44
- baseURL: ApiUrlsHome.BaseURL,
45
- headers: {
46
- 'Accept': '*/*',
47
- 'Accept-Language': 'en-US,en;q=0.9',
48
- 'Cookie': contextKey,
49
- 'User-Agent': 'homebridge-melcloud-control/4.0.0',
50
- 'DNT': '1',
51
- 'Origin': 'https://melcloudhome.com',
52
- 'Referer': 'https://melcloudhome.com/dashboard',
53
- 'Sec-Fetch-Dest': 'empty',
54
- 'Sec-Fetch-Mode': 'cors',
55
- 'Sec-Fetch-Site': 'same-origin',
56
- 'X-CSRF': '1'
57
- },
58
- ...this.axiosDefaults
59
- });
29
+ };;
60
30
 
61
31
  //lock flags
62
32
  this.locks = {
@@ -241,6 +211,17 @@ class MelCloudAta extends EventEmitter {
241
211
  switch (accountType) {
242
212
  case "melcloud":
243
213
  try {
214
+ const axiosInstancePost = axios.create({
215
+ method: 'POST',
216
+ baseURL: ApiUrls.BaseURL,
217
+ headers: {
218
+ 'X-MitsContextKey': deviceData.ContextKey,
219
+ 'content-type': 'application/json'
220
+ },
221
+ withCredentials: true,
222
+ ...this.axiosDefaults
223
+ });
224
+
244
225
  //set target temp based on display mode and operation mode
245
226
  switch (displayMode) {
246
227
  case 1: //Heather/Cooler
@@ -297,7 +278,7 @@ class MelCloudAta extends EventEmitter {
297
278
  }
298
279
  }
299
280
 
300
- await this.axiosInstancePost(ApiUrls.SetAta, payload);
281
+ await axiosInstancePost(ApiUrls.SetAta, payload);
301
282
  this.updateData(deviceData);
302
283
  return true;
303
284
  } catch (error) {
@@ -305,6 +286,25 @@ class MelCloudAta extends EventEmitter {
305
286
  };
306
287
  case "melcloudhome":
307
288
  try {
289
+ const axiosInstancePut = axios.create({
290
+ method: 'PUT',
291
+ baseURL: ApiUrlsHome.BaseURL,
292
+ headers: {
293
+ 'Accept': '*/*',
294
+ 'Accept-Language': 'en-US,en;q=0.9',
295
+ 'Cookie': deviceData.ContextKey,
296
+ 'User-Agent': 'homebridge-melcloud-control/4.0.0',
297
+ 'DNT': '1',
298
+ 'Origin': 'https://melcloudhome.com',
299
+ 'Referer': 'https://melcloudhome.com/dashboard',
300
+ 'Sec-Fetch-Dest': 'empty',
301
+ 'Sec-Fetch-Mode': 'cors',
302
+ 'Sec-Fetch-Site': 'same-origin',
303
+ 'X-CSRF': '1'
304
+ },
305
+ ...this.axiosDefaults
306
+ });
307
+
308
308
  //set target temp based on display mode and operation mode
309
309
  switch (displayMode) {
310
310
  case 1: //Heather/Cooler
@@ -354,7 +354,7 @@ class MelCloudAta extends EventEmitter {
354
354
  this.emit('warn', JSON.stringify(deviceData.Device, null, 2));
355
355
  this.emit('warn', JSON.stringify(payload, null, 2));
356
356
  const path = ApiUrlsHome.SetAta.replace('deviceid', deviceData.DeviceID);
357
- await this.axiosInstancePut(path, payload);
357
+ await axiosInstancePut(path, payload);
358
358
  this.updateData(deviceData);
359
359
  return true;
360
360
  } catch (error) {