homebridge-melcloud-control 4.0.0-beta.28 → 4.0.0-beta.3
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 +3 -3
- package/package.json +1 -1
- package/src/melcloud.js +62 -79
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
|
|
79
|
+
const coociesFile = `${prefDir}/${accountName}_Coocies`;
|
|
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,
|
|
91
|
+
const melCloud = new MelCloud(user, passwd, language, accountFile, buildingsFile, devicesFile, coociesFile, 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.
|
|
98
|
+
await melCloud.connectHomeCoocies()
|
|
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.
|
|
4
|
+
"version": "4.0.0-beta.3",
|
|
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,
|
|
10
|
+
constructor(user, passwd, language, accountFile, buildingsFile, devicesFile, coociesFile, 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.
|
|
18
|
+
this.coociesFile = coociesFile;
|
|
19
19
|
this.logWarn = logWarn;
|
|
20
20
|
this.logDebug = logDebug;
|
|
21
21
|
this.requestConfig = requestConfig;
|
|
@@ -213,100 +213,83 @@ class MelCloud extends EventEmitter {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
async
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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');
|
|
221
223
|
|
|
222
|
-
const response = await axios({
|
|
223
|
-
method: 'POST',
|
|
224
|
-
baseURL: EnphaseUrls.BaseUrl,
|
|
225
|
-
url: EnphaseUrls.Login,
|
|
226
|
-
headers: {
|
|
227
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
228
|
-
},
|
|
229
|
-
data: form,
|
|
230
|
-
timeout: 10000
|
|
231
|
-
});
|
|
232
224
|
|
|
233
|
-
if (response.status !== 200) {
|
|
234
|
-
if (this.logError) this.emit('error', `Login failed with status code: ${response.status}`);
|
|
235
|
-
return null;
|
|
236
|
-
}
|
|
237
225
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
226
|
+
const browser = await puppeteer.launch({
|
|
227
|
+
headless: true,
|
|
228
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
229
|
+
});
|
|
243
230
|
|
|
244
|
-
return cookie;
|
|
245
|
-
} catch (error) {
|
|
246
|
-
throw new Error(`Login to Enlighten error: ${error}`);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async connectHomeCookies() {
|
|
251
|
-
const loginUrl = 'https://melcloudhome.com';
|
|
252
|
-
const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
|
|
253
231
|
const page = await browser.newPage();
|
|
254
232
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
+
// Sprawdź kilka możliwych wariantów
|
|
243
|
+
const buttonSelectors = [
|
|
244
|
+
'button[type="submit"]',
|
|
245
|
+
'input[type="submit"]',
|
|
246
|
+
'button[name="signIn"]',
|
|
247
|
+
'button.btn-primary',
|
|
248
|
+
'button:has-text("Sign in")',
|
|
249
|
+
'button:has-text("Zaloguj")'
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
// Kliknij "Sign in" (przycisk AWS Cognito)
|
|
253
|
+
let buttonFound = false;
|
|
254
|
+
for (const selector of buttonSelectors) {
|
|
255
|
+
const button = await page.$(selector);
|
|
256
|
+
if (button) {
|
|
257
|
+
console.log(`Found submit button: ${selector}`);
|
|
258
|
+
await Promise.all([
|
|
259
|
+
button.click(),
|
|
260
|
+
page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 15000 })
|
|
261
|
+
]);
|
|
262
|
+
buttonFound = true;
|
|
263
|
+
break;
|
|
268
264
|
}
|
|
265
|
+
}
|
|
269
266
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
loginBtn.click(),
|
|
274
|
-
page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
|
|
275
|
-
]);
|
|
267
|
+
if (!buttonFound) {
|
|
268
|
+
throw new Error('❌ Could not find login button on the page.');
|
|
269
|
+
}
|
|
276
270
|
|
|
277
|
-
|
|
278
|
-
|
|
271
|
+
// Poczekaj aż załaduje się MELCloud Home
|
|
272
|
+
this.emit('warn', `Waiting for redirect to melcloudhome.com...`);
|
|
273
|
+
await page.waitForTimeout(5000);
|
|
279
274
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
await page.type('input[name="password"]', this.passwd, { delay: 50 });
|
|
275
|
+
// Pobierz cookies dla domeny melcloudhome.com
|
|
276
|
+
const cookies = await page.cookies();
|
|
283
277
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
button1.click(),
|
|
288
|
-
page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 })
|
|
289
|
-
]);
|
|
278
|
+
// Znajdź __Secure-monitorandcontrolC1 i C2
|
|
279
|
+
const c1 = cookies.find(c => c.name === '__Secure-monitorandcontrolC1')?.value || null;
|
|
280
|
+
const c2 = cookies.find(c => c.name === '__Secure-monitorandcontrolC2')?.value || null;
|
|
290
281
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
282
|
+
// Zapisz do pliku
|
|
283
|
+
const data = { C1: c1, C2: c2, date: new Date().toISOString() };
|
|
284
|
+
await this.functions.saveData(this.coociesFile, data);
|
|
294
285
|
|
|
295
|
-
|
|
286
|
+
await browser.close();
|
|
296
287
|
|
|
297
|
-
|
|
298
|
-
return data;
|
|
288
|
+
this.emit('warn', `Login successful.`);
|
|
299
289
|
|
|
300
|
-
|
|
301
|
-
this.emit('error', `Login failed: ${err.message}`);
|
|
302
|
-
return null;
|
|
303
|
-
} finally {
|
|
304
|
-
await browser.close();
|
|
305
|
-
}
|
|
290
|
+
return false;
|
|
306
291
|
}
|
|
307
292
|
|
|
308
|
-
|
|
309
|
-
|
|
310
293
|
async send(accountInfo) {
|
|
311
294
|
try {
|
|
312
295
|
const options = { data: accountInfo };
|