homebridge-melcloud-control 4.0.0-beta.5 → 4.0.0-beta.51

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/CHANGELOG.md CHANGED
@@ -16,6 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
16
  - do not configure it manually, always using Config UI X
17
17
  - required Homebridge v2.0.0 and above
18
18
 
19
+ ## [4.0.0] - (xx.10.2025)
20
+
21
+ ## Changes
22
+
23
+ - added support for MELCloud Home [#215](https://github.com/grzegorz914/homebridge-melcloud-control/issues/215)
24
+ - redme updated
25
+ - config schema updated
26
+ - cleanup
27
+
19
28
  ## [3.9.5] - (02.09.2025)
20
29
 
21
30
  ## Changes
package/README.md CHANGED
@@ -204,9 +204,10 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
204
204
  | Key | Description |
205
205
  | --- | --- |
206
206
  | `name` | Here set the own account name. |
207
- | `user` | Here set the MELCloud username. |
208
- | `passwd` | Here set the MELCloud password. |
209
- | `language` | Here select the MELCloud language. |
207
+ | `user` | Here set the account username. |
208
+ | `passwd` | Here set the account password. |
209
+ | `language` | Here select the account language. |
210
+ | `displayMode` | Here select the account type `None/Disabled`, `MELCloud`, `MELCloud Home`. |
210
211
  | `ataDevices[]` | Array of ATA devices created automatically after login to MELCloud from plugin config UI. |
211
212
  | `ataDevices[].id` | Read only data, do not change it. |
212
213
  | `ataDevices[].type` | Read only data, do not change it. |
@@ -201,6 +201,32 @@
201
201
  }
202
202
  ]
203
203
  },
204
+ "displayType": {
205
+ "title": "Account Type",
206
+ "type": "string",
207
+ "default": "disabled",
208
+ "description": "Here select the language used in MELCloud account.",
209
+ "oneOf": [
210
+ {
211
+ "title": "None/Disabled",
212
+ "enum": [
213
+ "disabled"
214
+ ]
215
+ },
216
+ {
217
+ "title": "MELCLoud",
218
+ "enum": [
219
+ "melcloud"
220
+ ]
221
+ },
222
+ {
223
+ "title": "MELCLoud Home",
224
+ "enum": [
225
+ "melcloudhome"
226
+ ]
227
+ }
228
+ ]
229
+ },
204
230
  "ataDevices": {
205
231
  "title": "Devices ATA",
206
232
  "type": "array",
@@ -1798,7 +1824,8 @@
1798
1824
  "name",
1799
1825
  "user",
1800
1826
  "passwd",
1801
- "language"
1827
+ "language",
1828
+ "displayType"
1802
1829
  ]
1803
1830
  }
1804
1831
  }
@@ -1817,6 +1844,7 @@
1817
1844
  "type": "password"
1818
1845
  },
1819
1846
  "accounts[].language",
1847
+ "accounts[].displayType",
1820
1848
  {
1821
1849
  "key": "accounts[]",
1822
1850
  "type": "tabarray",
@@ -76,14 +76,22 @@
76
76
  </select>
77
77
  </div>
78
78
 
79
+ <div class="mb-2">
80
+ <label for="displayType" class="form-label">Account Type</label>
81
+ <select id="displayType" name="displayType" class="form-control">
82
+ <option value="disabled">None/Disabled</option>
83
+ <option value="melcloud">MELCloud</option>
84
+ <option value="melcloudhome">MELCloud Home</option>
85
+ </select>
86
+ </div>
87
+
79
88
  <div class="text-center">
80
- <button id="logIn" type="button" class="btn btn-secondary">Connect to MELCloud</button>
89
+ <button id="logIn" type="button" class="btn btn-secondary">Log In</button>
81
90
  <button id="configButton" type="button" class="btn btn-secondary"><i class="fas fa-gear"></i></button>
82
91
  </div>
83
92
  </form>
93
+ <div id="accountButton" class="text-center mt-2"></div>
84
94
  </div>
85
-
86
- <div id="accountButton" class="mt-2"></div>
87
95
  </div>
88
96
 
89
97
  <script>
@@ -110,7 +118,7 @@
110
118
 
111
119
  button.addEventListener('click', async () => {
112
120
  for (let j = 0; j < accountsCount; j++) {
113
- document.getElementById(`button${j}`).className = (j === i ? 'btn btn-secondary' : 'btn btn-primary');
121
+ document.getElementById(`button${j}`).className = (j === i ? 'btn btn-primary' : 'btn btn-secondary');
114
122
  }
115
123
 
116
124
  const acc = pluginConfig[0].accounts[i];
@@ -118,8 +126,9 @@
118
126
  document.getElementById('name').value = acc.name || '';
119
127
  document.getElementById('user').value = acc.user || '';
120
128
  document.getElementById('passwd').value = acc.passwd || '';
121
- document.getElementById('language').value = acc.language || '';
122
- document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.language);
129
+ document.getElementById('language').value = acc.language || '0';
130
+ document.getElementById('displayType').value = acc.displayType || 'disabled';
131
+ document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.language && acc.displayType);
123
132
  this.deviceIndex = i;
124
133
  });
125
134
 
@@ -134,8 +143,9 @@
134
143
  acc.user = document.querySelector('#user').value;
135
144
  acc.passwd = document.querySelector('#passwd').value;
136
145
  acc.language = document.querySelector('#language').value;
146
+ acc.displayType = document.querySelector('#displayType').value;
137
147
 
138
- document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.language);
148
+ document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.languaged && acc.displayType);
139
149
 
140
150
  await homebridge.updatePluginConfig(pluginConfig);
141
151
  await homebridge.savePluginConfig(pluginConfig);
@@ -192,7 +202,7 @@
192
202
 
193
203
  try {
194
204
  const acc = pluginConfig[0].accounts[this.deviceIndex];
195
- const payload = { accountName: acc.name, user: acc.user, passwd: acc.passwd, language: acc.language };
205
+ const payload = { accountName: acc.name, user: acc.user, passwd: acc.passwd, language: acc.language, displayType: acc.displayType };
196
206
  const devicesInMelCloud = await homebridge.request('/connect', payload);
197
207
 
198
208
  // Initialize devices arrays
@@ -17,14 +17,15 @@ class PluginUiServer extends HomebridgePluginUiServer {
17
17
  const user = payload.user;
18
18
  const passwd = payload.passwd;
19
19
  const language = payload.language;
20
+ const displayType = payload.displayType;
20
21
  const accountFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
21
22
  const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
22
23
  const devicesFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Devices`;
23
- const melCloud = new MelCloud(user, passwd, language, accountFile, buildingsFile, devicesFile, false, true);
24
+ const melCloud = new MelCloud(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, false, true);
24
25
 
25
26
  try {
26
- const response = await melCloud.connect();
27
- const devices = await melCloud.checkDevicesList(response.contextKey);
27
+ const accountInfo = await melCloud.connect();
28
+ const devices = await melCloud.checkDevicesList(accountInfo.ContextKey);
28
29
  return devices;
29
30
  } catch (error) {
30
31
  throw new Error(`MELCloud error: ${error.message ?? error}.`);
package/index.js CHANGED
@@ -30,6 +30,9 @@ 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;
35
+
33
36
  const accountName = account.name;
34
37
  const user = account.user;
35
38
  const passwd = account.passwd;
@@ -64,7 +67,7 @@ class MelCloudPlatform {
64
67
  passwd: 'removed',
65
68
  mqtt: {
66
69
  auth: {
67
- ...device.mqtt?.auth,
70
+ ...account.mqtt?.auth,
68
71
  passwd: 'removed',
69
72
  }
70
73
  },
@@ -76,7 +79,6 @@ class MelCloudPlatform {
76
79
  const accountFile = `${prefDir}/${accountName}_Account`;
77
80
  const buildingsFile = `${prefDir}/${accountName}_Buildings`;
78
81
  const devicesFile = `${prefDir}/${accountName}_Devices`;
79
- const cookiesFile = `${prefDir}/${accountName}cookies`;
80
82
 
81
83
 
82
84
  //set account refresh interval
@@ -88,31 +90,26 @@ class MelCloudPlatform {
88
90
  .on('start', async () => {
89
91
  try {
90
92
  //melcloud account
91
- const melCloud = new MelCloud(user, passwd, language, accountFile, buildingsFile, devicesFile, coociesFile, logLevel.warn, logLevel.debug, false)
93
+ const melCloud = new MelCloud(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, logLevel.warn, logLevel.debug, false)
92
94
  .on('success', (msg) => logLevel.success && log.success(`${accountName}, ${msg}`))
93
95
  .on('info', (msg) => logLevel.info && log.info(`${accountName}, ${msg}`))
94
96
  .on('debug', (msg) => logLevel.debug && log.info(`${accountName}, debug: ${msg}`))
95
97
  .on('warn', (msg) => logLevel.warn && log.warn(`${accountName}, ${msg}`))
96
98
  .on('error', (msg) => logLevel.error && log.error(`${accountName}, ${msg}`));
97
99
 
98
- await melCloud.connectHomeCoocies()
99
- return;
100
-
101
-
102
100
  //connect
103
- let response;
101
+ let accountInfo;
104
102
  try {
105
- response = await melCloud.connect();
103
+ accountInfo = await melCloud.connect();
106
104
  } catch (error) {
107
105
  if (logLevel.error) log.error(`${accountName}, Connect error: ${error.message ?? error}`);
108
106
  return;
109
107
  }
110
108
 
111
- const accountInfo = response.accountInfo ?? false;
112
- const contextKey = response.contextKey ?? false;
113
- const useFahrenheit = response.useFahrenheit ?? false;
109
+ const contextKey = accountInfo.ContextKey;
110
+ const useFahrenheit = accountInfo.UseFahrenheit;
114
111
 
115
- if (contextKey === false) {
112
+ if (!contextKey) {
116
113
  return;
117
114
  }
118
115
 
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.5",
4
+ "version": "4.0.0-beta.51",
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
@@ -7,15 +7,15 @@ import Functions from './functions.js';
7
7
  import { ApiUrls, ApiUrlsHome } from './constants.js';
8
8
 
9
9
  class MelCloud extends EventEmitter {
10
- constructor(user, passwd, language, accountFile, buildingsFile, devicesFile, cookiesFile, logWarn, logDebug, requestConfig) {
10
+ constructor(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, logWarn, logDebug, requestConfig) {
11
11
  super();
12
+ this.displayType = displayType;
12
13
  this.user = user;
13
14
  this.passwd = passwd;
14
15
  this.language = language;
15
16
  this.accountFile = accountFile;
16
17
  this.buildingsFile = buildingsFile;
17
18
  this.devicesFile = devicesFile;
18
- this.cookiesFile = cookiesFile;
19
19
  this.logWarn = logWarn;
20
20
  this.logDebug = logDebug;
21
21
  this.requestConfig = requestConfig;
@@ -58,7 +58,7 @@ class MelCloud extends EventEmitter {
58
58
  }
59
59
  }
60
60
 
61
- async checkDevicesList(contextKey) {
61
+ async checkMelcloudDevicesList(contextKey) {
62
62
  try {
63
63
  const axiosInstanceGet = axios.create({
64
64
  method: 'GET',
@@ -109,7 +109,7 @@ class MelCloud extends EventEmitter {
109
109
  }
110
110
  }
111
111
 
112
- async connect() {
112
+ async connectToMelCloud() {
113
113
  if (this.logDebug) this.emit('debug', `Connecting to MELCloud`);
114
114
 
115
115
  try {
@@ -123,7 +123,6 @@ class MelCloud extends EventEmitter {
123
123
  const account = accountData.data;
124
124
  const accountInfo = account.LoginData;
125
125
  const contextKey = accountInfo?.ContextKey;
126
- const useFahrenheit = accountInfo?.UseFahrenheit ?? false;
127
126
  this.contextKey = contextKey;
128
127
 
129
128
  const debugData = {
@@ -153,44 +152,24 @@ class MelCloud extends EventEmitter {
153
152
  });
154
153
 
155
154
  await this.functions.saveData(this.accountFile, accountInfo);
156
-
157
155
  this.emit('success', `Connect to MELCloud Success`);
158
156
 
159
- return {
160
- accountInfo,
161
- contextKey,
162
- useFahrenheit
163
- };
157
+ return accountInfo
164
158
  } catch (error) {
165
159
  throw new Error(`Connect to MELCloud error: ${error.message}`);
166
160
  }
167
161
  }
168
162
 
169
- async connectHome(cookieC1, cookieC2) {
170
- if (this.logDebug) this.emit('debug', `Connecting to MELCloud Home`);
171
-
163
+ async checkMelcloudHomeDevicesList(contextKey) {
172
164
  try {
173
- const c1 = cookieC1.trim();
174
- const c2 = cookieC2.trim();
175
-
176
- const cookieString = [
177
- '__Secure-monitorandcontrol=chunks-2',
178
- `__Secure-monitorandcontrolC1=${c1}`,
179
- `__Secure-monitorandcontrolC2=${c2}`,
180
- ].join('; ');
181
-
182
165
  const axiosInstance = axios.create({
166
+ method: 'GET',
183
167
  baseURL: ApiUrlsHome.BaseURL,
184
- timeout: 10000,
185
- httpsAgent: new Agent({
186
- keepAlive: false,
187
- rejectUnauthorized: false
188
- }),
189
168
  headers: {
190
169
  'Accept': '*/*',
191
170
  'Accept-Language': 'en-US,en;q=0.9',
192
- 'Cookie': cookieString,
193
- 'User-Agent': 'homebridge-melcloud-home/0.2.0',
171
+ 'Cookie': contextKey,
172
+ 'User-Agent': 'homebridge-melcloud-control/4.0.0',
194
173
  'DNT': '1',
195
174
  'Origin': 'https://melcloudhome.com',
196
175
  'Referer': 'https://melcloudhome.com/dashboard',
@@ -198,93 +177,149 @@ class MelCloud extends EventEmitter {
198
177
  'Sec-Fetch-Mode': 'cors',
199
178
  'Sec-Fetch-Site': 'same-origin',
200
179
  'X-CSRF': '1'
201
- }
180
+ },
181
+ ...this.axiosDefaults
202
182
  });
203
183
 
204
- const response = await axiosInstance.get(ApiUrlsHome.GetUserContext);
205
- const homeData = response.data;
206
- if (this.logDebug) this.emit('debug', `[MELCloudHome] Response data: ${JSON.stringify(homeData, null, 2)}`);
184
+ if (this.logDebug) this.emit('debug', `Scanning for devices`);
185
+ const listDevicesData = await axiosInstance(ApiUrlsHome.GetUserContext);
186
+ const buildingsList = listDevicesData.data.buildings;
187
+ if (this.logDebug) this.emit('debug', `Buildings: ${JSON.stringify(buildingsList, null, 2)}`);
207
188
 
208
- this.emit('success', `Connect to MELCloud Home Success`);
189
+ if (!buildingsList) {
190
+ if (this.logWarn) this.emit('warn', `No building found`);
191
+ return null;
192
+ }
193
+
194
+ await this.functions.saveData(this.buildingsFile, buildingsList);
195
+ if (this.logDebug) this.emit('debug', `Buildings list saved`);
196
+
197
+ const allDevices = buildingsList.flatMap(building => {
198
+ const capitalizeKeys = obj =>
199
+ Object.fromEntries(Object.entries(obj).map(([key, value]) => [
200
+ key.charAt(0).toUpperCase() + key.slice(1),
201
+ value
202
+ ]));
203
+
204
+ return [
205
+ ...(building.airToAirUnits || []).map(device => ({ ...capitalizeKeys(device), Type: 0 })),
206
+ ...(building.airToWaterUnits || []).map(device => ({ ...capitalizeKeys(device), Type: 1 })),
207
+ ...(building.airToVentilationUnits || []).map(device => ({ ...capitalizeKeys(device), Type: 3 }))
208
+ ];
209
+ });
210
+
211
+ const devicesCount = allDevices.length;
212
+ if (devicesCount === 0) {
213
+ if (this.logWarn) this.emit('warn', `No devices found`);
214
+ return null;
215
+ }
216
+
217
+ const devices = allDevices.map(device => ({
218
+ ...device, // zachowuje wszystkie pola z allDevices
219
+ DeviceID: device.Id,
220
+ DeviceName: device.GivenDisplayName,
221
+ Settings: Object.fromEntries((device.Settings || []).map(({ Name, Value }) => [Name, Value])),
222
+ Device: device.Capabilities
223
+ }));
224
+
225
+ await this.functions.saveData(this.devicesFile, devices);
226
+ if (this.logDebug) this.emit('debug', `${devicesCount} devices saved`);
209
227
 
210
- return
228
+ return devices;
211
229
  } catch (error) {
212
230
  throw new Error(`Connect to MELCloud Home error: ${error.message}`);
213
231
  }
214
232
  }
215
233
 
216
- async connectHomeCookies() {
217
- const loginUrl = new URL('https://live-melcloudhome.auth.eu-west-1.amazoncognito.com/login');
218
- loginUrl.searchParams.set('client_id', '3g4d5l5kivuqi7oia68gib7uso');
219
- loginUrl.searchParams.set('redirect_uri', 'https://auth.melcloudhome.com/signin-oidc-meu');
220
- loginUrl.searchParams.set('response_type', 'code');
221
- loginUrl.searchParams.set('scope', 'openid profile');
222
- loginUrl.searchParams.set('response_mode', 'form_post');
223
-
224
- const browser = await puppeteer.launch({
225
- headless: true,
226
- args: ['--no-sandbox', '--disable-setuid-sandbox']
227
- });
234
+ async connectToMelCloudHome() {
235
+ if (this.logDebug) this.emit('debug', `Connecting to MELCloud Home`);
228
236
 
237
+ const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
229
238
  const page = await browser.newPage();
230
239
 
231
240
  try {
232
- this.emit('warn', 'Opening login page...');
233
- await page.goto(loginUrl.toString(), { waitUntil: 'networkidle2' });
241
+ // Open MELCloud Home
242
+ await page.goto(ApiUrlsHome.BaseURL, { waitUntil: 'networkidle2' });
243
+ const buttons = await page.$$('button.btn--blue');
244
+ let loginBtn = null;
245
+ for (const btn of buttons) {
246
+ const text = await page.evaluate(el => el.textContent, btn);
247
+ if (text.trim() === 'Zaloguj' || text.trim() === 'Log In') {
248
+ loginBtn = btn;
249
+ break;
250
+ }
251
+ }
252
+
253
+ if (!loginBtn && this.logWarn) this.emit('warn', `Login button not found`);
234
254
 
235
- this.emit('warn', 'Typing credentials...');
255
+ // Set credentials and login
256
+ await Promise.all([loginBtn.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })]);
257
+ await page.waitForSelector('input[name="username"]', { timeout: 15000 });
236
258
  await page.type('input[name="username"]', this.user, { delay: 50 });
237
259
  await page.type('input[name="password"]', this.passwd, { delay: 50 });
238
260
 
239
- // Wyszukiwanie przycisku logowania
240
- const buttonSelectors = [
241
- 'button[type="submit"]',
242
- 'input[type="submit"]',
243
- 'button[name="signIn"]',
244
- 'button.btn-primary'
245
- ];
246
-
247
- let buttonFound = false;
248
- for (const selector of buttonSelectors) {
249
- const button = await page.$(selector);
250
- if (button) {
251
- this.emit('warn', `Found submit button: ${selector}`);
252
- await Promise.all([
253
- button.click(),
254
- page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 }) // czekamy na redirect
255
- ]);
256
- buttonFound = true;
257
- break;
258
- }
259
- }
261
+ const button1 = await page.$('input[type="submit"]');
262
+ await Promise.all([button1.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })]);
260
263
 
261
- if (!buttonFound) {
262
- throw new Error('❌ Could not find login button on the page.');
264
+ // Get cookies C1 and C2
265
+ let c1 = null, c2 = null;
266
+ const start = Date.now();
267
+
268
+ // Loop max 20s
269
+ while ((!c1 || !c2) && Date.now() - start < 20000) {
270
+ const cookies = await page.cookies();
271
+ c1 = cookies.find(c => c.name === '__Secure-monitorandcontrolC1')?.value || c1;
272
+ c2 = cookies.find(c => c.name === '__Secure-monitorandcontrolC2')?.value || c2;
273
+ if (!c1 || !c2) await new Promise(r => setTimeout(r, 500));
263
274
  }
264
275
 
265
- // Poczekaj dashboard MELCloud Home będzie gotowy
266
- this.emit('warn', 'Waiting for MELCloud Home dashboard...');
267
- await page.waitForSelector('#dashboard, .dashboard-container', { timeout: 20000 });
276
+ if (!c1 || !c2) {
277
+ if (this.logWarn) this.emit('warn', `Cookies C1/C2 missing`);
278
+ return null;
279
+ }
268
280
 
269
- // Pobranie cookies po zalogowaniu
270
- const cookies = await page.cookies();
271
- const c1 = cookies.find(c => c.name === '__Secure-monitorandcontrolC1')?.value || null;
272
- const c2 = cookies.find(c => c.name === '__Secure-monitorandcontrolC2')?.value || null;
281
+ const contextKey = ['__Secure-monitorandcontrol=chunks-2', `__Secure-monitorandcontrolC1=${c1}`, `__Secure-monitorandcontrolC2=${c2}`,].join('; ');
282
+ const accountInfo = { ContextKey: contextKey, UseFahrenheit: false };
283
+ this.contextKey = contextKey;
273
284
 
274
- const data = { C1: c1, C2: c2, date: new Date().toISOString() };
275
- await this.functions.saveData(this.cookiesFile, data);
285
+ await this.functions.saveData(this.accountFile, accountInfo);
286
+ this.emit('success', `Connect to MELCloud Home Success`);
276
287
 
277
- this.emit('warn', 'Login successful.');
278
- return data;
279
- } catch (err) {
280
- this.emit('error', `Login failed: ${err.message}`);
281
- return null;
288
+ return accountInfo;
289
+ } catch (error) {
290
+ throw new Error(`Connect to MELCloud Home error: ${error.message}`);
282
291
  } finally {
283
292
  await browser.close();
284
293
  }
285
294
  }
286
295
 
296
+ async connect() {
297
+ let response = {};
298
+ switch (this.displayType) {
299
+ case "melcloud":
300
+ response = await this.connectToMelCloud();
301
+ return response
302
+ case "melcloudhome":
303
+ response = await this.connectToMelCloudHome();
304
+ return response
305
+ default:
306
+ return response
307
+ }
308
+ }
287
309
 
310
+ async checkDevicesList(contextKey) {
311
+ let devices = [];
312
+ switch (this.displayType) {
313
+ case "melcloud":
314
+ devices = await this.checkMelcloudDevicesList(contextKey);
315
+ return devices
316
+ case "melcloudhome":
317
+ devices = await this.checkMelcloudHomeDevicesList(contextKey);
318
+ return devices
319
+ default:
320
+ return devices;
321
+ }
322
+ }
288
323
 
289
324
  async send(accountInfo) {
290
325
  try {