homebridge-melcloud-control 4.0.0-beta.0 → 4.0.0-beta.10

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.0",
4
+ "version": "4.0.0-beta.10",
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,7 +213,14 @@ class MelCloud extends EventEmitter {
213
213
  }
214
214
  }
215
215
 
216
- async connectHomeCoocies() {
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
+
217
224
  const browser = await puppeteer.launch({
218
225
  headless: true,
219
226
  args: ['--no-sandbox', '--disable-setuid-sandbox']
@@ -221,43 +228,68 @@ class MelCloud extends EventEmitter {
221
228
 
222
229
  const page = await browser.newPage();
223
230
 
224
- // Otwórz stronę logowania
225
- this.emit('warn', `Opening login page...`);
226
- await page.goto(ApiUrls.LoginUrl, { waitUntil: 'networkidle2' });
231
+ try {
232
+ this.emit('warn', 'Opening login page...');
233
+ await page.goto(loginUrl.toString(), { waitUntil: 'networkidle2' });
234
+
235
+ // Wpisz login i hasło
236
+ await page.type('input[name="username"]', this.user);
237
+ await page.type('input[name="password"]', thispasswd);
238
+
239
+ // Kliknij przycisk logowania
240
+ const button = await page.$('button[type="submit"]');
241
+ await Promise.all([
242
+ button.click(),
243
+ page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
244
+ ]);
245
+
246
+ // Opcjonalnie obsłuż "Stay signed in?" jeśli występuje
247
+ const staySignedInBtn = await page.$('input[type="submit"]');
248
+ if (staySignedInBtn) {
249
+ await Promise.all([
250
+ staySignedInBtn.click(),
251
+ page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
252
+ ]);
253
+ }
227
254
 
228
- // Wpisz login i hasło
229
- this.emit('warn', `Typing credentials...`);
230
- await page.type('input[name="username"]', this.user, { delay: 50 });
231
- await page.type('input[name="password"]', this.passwd, { delay: 50 });
255
+ // Opcjonalnie obsługa "Stay signed in?"
256
+ const staySignedInSelector = 'input[name="rememberDevice"], button[type="submit"]';
257
+ if (await page.$(staySignedInSelector)) {
258
+ console.log('Handling "Stay signed in?" screen...');
259
+ await Promise.all([
260
+ page.click(staySignedInSelector),
261
+ page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
262
+ ]);
263
+ }
232
264
 
233
- // Kliknij "Sign in" (przycisk AWS Cognito)
234
- this.emit('warn', `Submitting form...`);
235
- await Promise.all([
236
- page.click('button[type="submit"]'),
237
- page.waitForNavigation({ waitUntil: 'networkidle2' })
238
- ]);
265
+ // Monitorowanie requestów i oczekiwanie na cookies C1 i C2
266
+ let c1 = null, c2 = null;
267
+ const start = Date.now();
239
268
 
240
- // Poczekaj załaduje się MELCloud Home
241
- this.emit('warn', `Waiting for redirect to melcloudhome.com...`);
242
- await page.waitForTimeout(5000);
269
+ while ((!c1 || !c2) && Date.now() - start < 20000) { // max 20s
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));
274
+ }
243
275
 
244
- // Pobierz cookies dla domeny melcloudhome.com
245
- const cookies = await page.cookies();
276
+ if (!c1 || !c2) throw new Error('Cookies C1/C2 not found');
246
277
 
247
- // Znajdź __Secure-monitorandcontrolC1 i C2
248
- const c1 = cookies.find(c => c.name === '__Secure-monitorandcontrolC1')?.value || null;
249
- const c2 = cookies.find(c => c.name === '__Secure-monitorandcontrolC2')?.value || null;
278
+ const data = { C1: c1, C2: c2, date: new Date().toISOString() };
279
+ await this.functions.saveData(this.cookiesFile, data);
250
280
 
251
- // Zapisz do pliku
252
- const data = { C1: c1, C2: c2, date: new Date().toISOString() };
253
- await this.functions.saveData(this.coociesFile, data);
281
+ this.emit('warn', 'Login successful.');
282
+ return data;
254
283
 
255
- await browser.close();
284
+ } catch (err) {
285
+ this.emit('error', `Login failed: ${err.message}`);
286
+ return null;
287
+ } finally {
288
+ await browser.close();
289
+ }
290
+ }
256
291
 
257
- this.emit('warn', `Login successful.`);
258
292
 
259
- return false;
260
- }
261
293
 
262
294
  async send(accountInfo) {
263
295
  try {