homebridge-melcloud-control 4.0.0-beta.2 → 4.0.0-beta.20

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
@@ -76,7 +76,7 @@ class MelCloudPlatform {
76
76
  const accountFile = `${prefDir}/${accountName}_Account`;
77
77
  const buildingsFile = `${prefDir}/${accountName}_Buildings`;
78
78
  const devicesFile = `${prefDir}/${accountName}_Devices`;
79
- const coociesFile = `${prefDir}/${accountName}_Coocies`;
79
+ const cookiesFile = `${prefDir}/${accountName}_Cookies`;
80
80
 
81
81
 
82
82
  //set account refresh interval
@@ -88,14 +88,14 @@ class MelCloudPlatform {
88
88
  .on('start', async () => {
89
89
  try {
90
90
  //melcloud account
91
- const melCloud = new MelCloud(user, passwd, language, accountFile, buildingsFile, devicesFile, coociesFile, logLevel.warn, logLevel.debug, false)
91
+ const melCloud = new MelCloud(user, passwd, language, accountFile, buildingsFile, devicesFile, cookiesFile, logLevel.warn, logLevel.debug, false)
92
92
  .on('success', (msg) => logLevel.success && log.success(`${accountName}, ${msg}`))
93
93
  .on('info', (msg) => logLevel.info && log.info(`${accountName}, ${msg}`))
94
94
  .on('debug', (msg) => logLevel.debug && log.info(`${accountName}, debug: ${msg}`))
95
95
  .on('warn', (msg) => logLevel.warn && log.warn(`${accountName}, ${msg}`))
96
96
  .on('error', (msg) => logLevel.error && log.error(`${accountName}, ${msg}`));
97
97
 
98
- await melCloud.connectHomeCoocies()
98
+ await melCloud.connectHomeCookies();
99
99
  return;
100
100
 
101
101
 
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.2",
4
+ "version": "4.0.0-beta.20",
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,7 +7,7 @@ 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, coociesFile, logWarn, logDebug, requestConfig) {
10
+ constructor(user, passwd, language, accountFile, buildingsFile, devicesFile, cookiesFile, logWarn, logDebug, requestConfig) {
11
11
  super();
12
12
  this.user = user;
13
13
  this.passwd = passwd;
@@ -15,7 +15,7 @@ class MelCloud extends EventEmitter {
15
15
  this.accountFile = accountFile;
16
16
  this.buildingsFile = buildingsFile;
17
17
  this.devicesFile = devicesFile;
18
- this.coociesFile = coociesFile;
18
+ this.cookiesFile = cookiesFile;
19
19
  this.logWarn = logWarn;
20
20
  this.logDebug = logDebug;
21
21
  this.requestConfig = requestConfig;
@@ -213,72 +213,69 @@ class MelCloud extends EventEmitter {
213
213
  }
214
214
  }
215
215
 
216
- async connectHomeCoocies() {
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
-
225
-
226
- const browser = await puppeteer.launch({
227
- headless: true,
228
- args: ['--no-sandbox', '--disable-setuid-sandbox']
229
- });
230
-
231
- const page = await browser.newPage();
232
-
233
- // Otwórz stronę logowania
234
- this.emit('warn', `Opening login page...`);
235
- await page.goto(loginUrl, { waitUntil: 'networkidle2' });
236
-
237
- // Wpisz login i hasło
238
- this.emit('warn', `Typing credentials...`);
239
- await page.type('input[name="username"]', this.user, { delay: 50 });
240
- await page.type('input[name="password"]', this.passwd, { delay: 50 });
241
-
242
- // Kliknij "Sign in" (przycisk AWS Cognito)
243
- let buttonFound = false;
244
- for (const selector of buttonSelectors) {
245
- const button = await page.$(selector);
246
- if (button) {
247
- console.log(`Found submit button: ${selector}`);
248
- await Promise.all([
249
- button.click(),
250
- page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 15000 })
251
- ]);
252
- buttonFound = true;
253
- break;
216
+ async connectHomeCookies() {
217
+ try {
218
+ const loginUrl = 'https://melcloudhome.com';
219
+ const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
220
+ const page = await browser.newPage();
221
+
222
+ this.emit('warn', 'Opening login page...');
223
+ await page.goto(loginUrl, { waitUntil: 'networkidle2' });
224
+
225
+ // Kliknij przycisk logowania
226
+ const loginBtn = await page.$x("//button[contains(text(), 'Zaloguj')]");
227
+ if (!loginBtn || loginBtn.length === 0) throw new Error('Login button not found on homepage');
228
+ await Promise.all([
229
+ loginBtn[0].click(),
230
+ page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
231
+ ]);
232
+
233
+ // Poczekaj, strona przekieruje do Cognito login
234
+ await page.waitForSelector('input[name="username"]', { timeout: 15000 });
235
+
236
+ this.emit('warn', 'Typing credentials...');
237
+ await page.type('input[name="username"]', this.user, { delay: 50 });
238
+ await page.type('input[name="password"]', this.passwd, { delay: 50 });
239
+
240
+ // Kliknij przycisk logowania
241
+ const button1 = await page.$('input[type="submit"]');
242
+ await Promise.all([
243
+ button1.click(),
244
+ page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
245
+ ]);
246
+
247
+ let c1 = null, c2 = null;
248
+ const start = Date.now();
249
+
250
+ // Loop max 20s, czekamy pojawią się cookies
251
+ while ((!c1 || !c2) && Date.now() - start < 20000) {
252
+ const cookies = await page.cookies();
253
+ c1 = cookies.find(c => c.name === '__Secure-monitorandcontrolC1')?.value || c1;
254
+ c2 = cookies.find(c => c.name === '__Secure-monitorandcontrolC2')?.value || c2;
255
+ if (!c1 || !c2) await new Promise(r => setTimeout(r, 500));
254
256
  }
255
- }
256
-
257
- if (!buttonFound) {
258
- throw new Error('❌ Could not find login button on the page.');
259
- }
260
-
261
- // Poczekaj aż załaduje się MELCloud Home
262
- this.emit('warn', `Waiting for redirect to melcloudhome.com...`);
263
- await page.waitForTimeout(5000);
264
257
 
265
- // Pobierz cookies dla domeny melcloudhome.com
266
- const cookies = await page.cookies();
258
+ if (!c1 || !c2) {
259
+ await browser.close();
260
+ throw new Error('❌ Cookies C1/C2 not found after login');
261
+ }
267
262
 
268
- // Znajdź __Secure-monitorandcontrolC1 i C2
269
- const c1 = cookies.find(c => c.name === '__Secure-monitorandcontrolC1')?.value || null;
270
- const c2 = cookies.find(c => c.name === '__Secure-monitorandcontrolC2')?.value || null;
263
+ // Zapis do pliku
264
+ const data = { C1: c1, C2: c2, date: new Date().toISOString() };
265
+ await this.functions.saveData(this.cookiesFile, data);
271
266
 
272
- // Zapisz do pliku
273
- const data = { C1: c1, C2: c2, date: new Date().toISOString() };
274
- await this.functions.saveData(this.coociesFile, data);
267
+ this.emit('warn', 'Login successful.');
268
+ return data;
275
269
 
276
- await browser.close();
270
+ } catch (err) {
271
+ this.emit('error', `Login failed: ${err.message}`);
272
+ return null;
273
+ } finally {
274
+ await browser.close();
275
+ }
276
+ }
277
277
 
278
- this.emit('warn', `Login successful.`);
279
278
 
280
- return false;
281
- }
282
279
 
283
280
  async send(accountInfo) {
284
281
  try {