homebridge-viessmann-vicare 2.0.1 β 2.0.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/config.schema.json +1 -1
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +1 -1
- package/dist/auth-manager.d.ts +61 -0
- package/dist/auth-manager.d.ts.map +1 -1
- package/dist/auth-manager.js +171 -40
- package/dist/settings.js +2 -2
- package/package.json +2 -2
package/config.schema.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"type": "string",
|
|
20
20
|
"required": true,
|
|
21
21
|
"pattern": "^[a-zA-Z0-9_-]+$",
|
|
22
|
-
"description": "Your Viessmann API Client ID from the developer portal. Must contain only alphanumeric characters, underscores, and hyphens. Get it from https://developer.viessmann.com/"
|
|
22
|
+
"description": "Your Viessmann API Client ID from the developer portal. Must contain only alphanumeric characters, underscores, and hyphens. Get it from https://developer.viessmann-climatesolutions.com/"
|
|
23
23
|
},
|
|
24
24
|
"clientSecret": {
|
|
25
25
|
"title": "Client Secret",
|
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAc,EAAiB,aAAa,EAA0C,MAAM,OAAO,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAoB,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAY,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAoB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AASpE,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,yBAAyB,EAAE,OAAO,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAT9B,OAAO,CAAC,QAAQ,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAc,EAAiB,aAAa,EAA0C,MAAM,OAAO,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAoB,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAY,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAoB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AASpE,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,yBAAyB,EAAE,OAAO,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAT9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgD;IACxE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;gBAGd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,WAAW;IA+B3C,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,iBAAiB;IAgFzB,OAAO,CAAC,qBAAqB;IAchB,WAAW,CAAC,CAAC,EACxB,SAAS,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAC1C,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAmF5B,OAAO,CAAC,KAAK;IAKA,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAQ5D,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAQzE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAQxE,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IASrE,kBAAkB;;;;;;;;;IAIlB,aAAa,IAAI,UAAU;IAI3B,iBAAiB,IAAI,MAAM;IAI3B,kBAAkB,IAAI,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU;IAIzE,uBAAuB;;;;;;;IAIvB,qBAAqB;IAIrB,qBAAqB;;;;;;;;IAIrB,eAAe,IAAI,IAAI;IAIvB,aAAa;IAIb,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM;IAK3B,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;IAK9C,OAAO,IAAI,IAAI;CAIvB"}
|
package/dist/api-client.js
CHANGED
package/dist/auth-manager.d.ts
CHANGED
|
@@ -45,6 +45,33 @@ export declare class AuthManager {
|
|
|
45
45
|
private clearStoredTokens;
|
|
46
46
|
private scheduleTokenRefresh;
|
|
47
47
|
authenticate(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
private shouldUseManualAuth(): boolean {
|
|
50
|
+
if (this.config.authMethod === 'manual') {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check if we're in a headless environment
|
|
55
|
+
if (!process.env.DISPLAY && process.platform === 'linux') {
|
|
56
|
+
this.log.debug('π₯οΈ Detected headless Linux environment, using manual auth');
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check if we're in Docker
|
|
61
|
+
if (process.env.DOCKER || process.env.CONTAINER) {
|
|
62
|
+
this.log.debug('π³ Detected container environment, using manual auth');
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Check if we're running as a service (systemd)
|
|
67
|
+
if (process.env.SYSTEMD_EXEC_PID || process.env.INVOCATION_ID) {
|
|
68
|
+
this.log.debug('βοΈ Detected systemd service environment, using manual auth');
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
**/
|
|
48
75
|
private shouldUseManualAuth;
|
|
49
76
|
private performAutoAuth;
|
|
50
77
|
private handleManualAuth;
|
|
@@ -53,6 +80,40 @@ export declare class AuthManager {
|
|
|
53
80
|
private buildAuthUrl;
|
|
54
81
|
private startAuthServer;
|
|
55
82
|
private stopAuthServer;
|
|
83
|
+
/** private openBrowser(url: string): void {
|
|
84
|
+
const { exec } = require('child_process');
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
let command: string;
|
|
88
|
+
|
|
89
|
+
switch (process.platform) {
|
|
90
|
+
case 'darwin': // macOS
|
|
91
|
+
command = `open "${url}"`;
|
|
92
|
+
break;
|
|
93
|
+
case 'win32': // Windows
|
|
94
|
+
command = `start "" "${url}"`;
|
|
95
|
+
break;
|
|
96
|
+
case 'linux': // Linux
|
|
97
|
+
command = `xdg-open "${url}" || firefox "${url}" || google-chrome "${url}" || chromium "${url}"`;
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
this.log.warn('β οΈ Cannot auto-open browser on this platform. Please open the URL manually.');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
exec(command, (error: any) => {
|
|
105
|
+
if (error) {
|
|
106
|
+
this.log.warn('β οΈ Could not auto-open browser:', error.message);
|
|
107
|
+
this.log.info('π Please open the authentication URL manually in your browser.');
|
|
108
|
+
} else {
|
|
109
|
+
this.log.info('π Opening browser for authentication...');
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
} catch (error) {
|
|
113
|
+
this.log.warn('β οΈ Error opening browser:', error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
**/
|
|
56
117
|
private openBrowser;
|
|
57
118
|
private exchangeCodeForTokens;
|
|
58
119
|
refreshAccessToken(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../src/auth-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAiB,MAAM,OAAO,CAAC;AAOrD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAkBD,qBAAa,WAAW;IAuBpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAzBzB,OAAO,CAAC,QAAQ,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../src/auth-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/auth-manager.js
CHANGED
|
@@ -44,7 +44,7 @@ class AuthManager {
|
|
|
44
44
|
config;
|
|
45
45
|
httpClient;
|
|
46
46
|
hostIp;
|
|
47
|
-
authURL = 'https://iam.viessmann.com/idp/v3';
|
|
47
|
+
authURL = 'https://iam.viessmann-climatesolutions.com/idp/v3';
|
|
48
48
|
redirectUri;
|
|
49
49
|
tokenStoragePath;
|
|
50
50
|
// TTL Constants from Viessmann API documentation
|
|
@@ -292,11 +292,24 @@ class AuthManager {
|
|
|
292
292
|
}
|
|
293
293
|
// Determine authentication method
|
|
294
294
|
const authMethod = this.config.authMethod || 'auto';
|
|
295
|
+
/**
|
|
295
296
|
if (authMethod === 'manual' || this.shouldUseManualAuth()) {
|
|
297
|
+
await this.handleManualAuth();
|
|
298
|
+
} else {
|
|
299
|
+
await this.performAutoAuth();
|
|
300
|
+
}
|
|
301
|
+
**/
|
|
302
|
+
if (authMethod === 'manual') {
|
|
296
303
|
await this.handleManualAuth();
|
|
304
|
+
return;
|
|
297
305
|
}
|
|
298
|
-
|
|
299
|
-
|
|
306
|
+
// Prova sempre l'auto-auth; se fallisce, fallback a manual
|
|
307
|
+
try {
|
|
308
|
+
await this.performAutoAuth(); // avvia server di callback + openBrowser()
|
|
309
|
+
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
this.log.warn('β οΈ Auto auth failed, falling back to manual:', e instanceof Error ? e.message : String(e));
|
|
312
|
+
await this.handleManualAuth();
|
|
300
313
|
}
|
|
301
314
|
}
|
|
302
315
|
catch (error) {
|
|
@@ -304,25 +317,48 @@ class AuthManager {
|
|
|
304
317
|
throw error;
|
|
305
318
|
}
|
|
306
319
|
}
|
|
307
|
-
|
|
320
|
+
/**
|
|
321
|
+
private shouldUseManualAuth(): boolean {
|
|
308
322
|
if (this.config.authMethod === 'manual') {
|
|
309
|
-
|
|
323
|
+
return true;
|
|
310
324
|
}
|
|
325
|
+
|
|
311
326
|
// Check if we're in a headless environment
|
|
312
327
|
if (!process.env.DISPLAY && process.platform === 'linux') {
|
|
313
|
-
|
|
314
|
-
|
|
328
|
+
this.log.debug('π₯οΈ Detected headless Linux environment, using manual auth');
|
|
329
|
+
return true;
|
|
315
330
|
}
|
|
331
|
+
|
|
316
332
|
// Check if we're in Docker
|
|
317
333
|
if (process.env.DOCKER || process.env.CONTAINER) {
|
|
318
|
-
|
|
319
|
-
|
|
334
|
+
this.log.debug('π³ Detected container environment, using manual auth');
|
|
335
|
+
return true;
|
|
320
336
|
}
|
|
337
|
+
|
|
321
338
|
// Check if we're running as a service (systemd)
|
|
322
339
|
if (process.env.SYSTEMD_EXEC_PID || process.env.INVOCATION_ID) {
|
|
323
|
-
|
|
340
|
+
this.log.debug('βοΈ Detected systemd service environment, using manual auth');
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
**/
|
|
347
|
+
shouldUseManualAuth() {
|
|
348
|
+
// Rispetta la scelta esplicita dellβutente
|
|
349
|
+
if (this.config.authMethod === 'manual') {
|
|
350
|
+
this.log.debug('π§ Auth method explicitly set to "manual" in config.');
|
|
324
351
|
return true;
|
|
325
352
|
}
|
|
353
|
+
// Diagnostica non-bloccante: non forziamo piΓΉ il manual in headless/systemd/container
|
|
354
|
+
const isHeadlessLinux = (process.platform === 'linux' && !process.env.DISPLAY);
|
|
355
|
+
const isContainer = !!(process.env.DOCKER || process.env.CONTAINER);
|
|
356
|
+
const isSystemd = !!(process.env.SYSTEMD_EXEC_PID || process.env.INVOCATION_ID);
|
|
357
|
+
if (isHeadlessLinux || isContainer || isSystemd) {
|
|
358
|
+
this.log.debug(`βΉοΈ Environment detected (headlessLinux=${isHeadlessLinux}, container=${isContainer}, systemd=${isSystemd}) β ` +
|
|
359
|
+
'proceeding with AUTO auth first; will fallback to MANUAL if AUTO fails.');
|
|
360
|
+
}
|
|
361
|
+
// Di default tentiamo sempre AUTO
|
|
326
362
|
return false;
|
|
327
363
|
}
|
|
328
364
|
async performAutoAuth() {
|
|
@@ -344,7 +380,7 @@ class AuthManager {
|
|
|
344
380
|
this.log.error('');
|
|
345
381
|
this.log.error('π Follow these steps:');
|
|
346
382
|
this.log.error('');
|
|
347
|
-
this.log.error('1. π Visit: https://developer.viessmann.com/');
|
|
383
|
+
this.log.error('1. π Visit: https://developer.viessmann-climatesolutions.com/');
|
|
348
384
|
this.log.error('2. π Create an application with these settings:');
|
|
349
385
|
this.log.error(' β’ Name: homebridge-viessmann-vicare');
|
|
350
386
|
this.log.error(' β’ Type: Public Client');
|
|
@@ -356,7 +392,7 @@ class AuthManager {
|
|
|
356
392
|
this.log.error(` ${authUrl}`);
|
|
357
393
|
this.log.error('');
|
|
358
394
|
this.log.error('4. β‘ QUICKLY exchange authorization code for tokens (20 second limit!):');
|
|
359
|
-
this.log.error(' curl -X POST "https://iam.viessmann.com/idp/v3/token" \\');
|
|
395
|
+
this.log.error(' curl -X POST "https://iam.viessmann-climatesolutions.com/idp/v3/token" \\');
|
|
360
396
|
this.log.error(' -H "Content-Type: application/x-www-form-urlencoded" \\');
|
|
361
397
|
this.log.error(` -d "client_id=${this.config.clientId}&redirect_uri=${encodeURIComponent(this.redirectUri)}&grant_type=authorization_code&code_verifier=${this.codeVerifier}&code=YOUR_AUTH_CODE"`);
|
|
362
398
|
this.log.error('');
|
|
@@ -498,37 +534,132 @@ class AuthManager {
|
|
|
498
534
|
this.authTimeout = undefined;
|
|
499
535
|
}
|
|
500
536
|
}
|
|
537
|
+
/** private openBrowser(url: string): void {
|
|
538
|
+
const { exec } = require('child_process');
|
|
539
|
+
|
|
540
|
+
try {
|
|
541
|
+
let command: string;
|
|
542
|
+
|
|
543
|
+
switch (process.platform) {
|
|
544
|
+
case 'darwin': // macOS
|
|
545
|
+
command = `open "${url}"`;
|
|
546
|
+
break;
|
|
547
|
+
case 'win32': // Windows
|
|
548
|
+
command = `start "" "${url}"`;
|
|
549
|
+
break;
|
|
550
|
+
case 'linux': // Linux
|
|
551
|
+
command = `xdg-open "${url}" || firefox "${url}" || google-chrome "${url}" || chromium "${url}"`;
|
|
552
|
+
break;
|
|
553
|
+
default:
|
|
554
|
+
this.log.warn('β οΈ Cannot auto-open browser on this platform. Please open the URL manually.');
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
exec(command, (error: any) => {
|
|
559
|
+
if (error) {
|
|
560
|
+
this.log.warn('β οΈ Could not auto-open browser:', error.message);
|
|
561
|
+
this.log.info('π Please open the authentication URL manually in your browser.');
|
|
562
|
+
} else {
|
|
563
|
+
this.log.info('π Opening browser for authentication...');
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
} catch (error) {
|
|
567
|
+
this.log.warn('β οΈ Error opening browser:', error);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
**/
|
|
501
571
|
openBrowser(url) {
|
|
502
|
-
const { exec } = require('child_process');
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
572
|
+
const { execFile, exec } = require('child_process');
|
|
573
|
+
const tryExecFile = (cmd, args, env) => new Promise((resolve, reject) => {
|
|
574
|
+
execFile(cmd, args, { env }, (err) => err ? reject(err) : resolve());
|
|
575
|
+
});
|
|
576
|
+
const tryExec = (command, env) => new Promise((resolve, reject) => {
|
|
577
|
+
exec(command, { env }, (err) => err ? reject(err) : resolve());
|
|
578
|
+
});
|
|
579
|
+
// Copia pulita dell'ambiente
|
|
580
|
+
const env = { ...process.env };
|
|
581
|
+
// Migliora compatibilitΓ Linux (X/Wayland) senza toccare il servizio
|
|
582
|
+
if (process.platform === 'linux') {
|
|
583
|
+
if (!env.DISPLAY) {
|
|
584
|
+
// fallback tipico X11
|
|
585
|
+
env.DISPLAY = ':0';
|
|
586
|
+
}
|
|
587
|
+
if (!env.XDG_RUNTIME_DIR && typeof process.getuid === 'function') {
|
|
588
|
+
env.XDG_RUNTIME_DIR = `/run/user/${process.getuid()}`;
|
|
518
589
|
}
|
|
519
|
-
exec(command, (error) => {
|
|
520
|
-
if (error) {
|
|
521
|
-
this.log.warn('β οΈ Could not auto-open browser:', error.message);
|
|
522
|
-
this.log.info('π Please open the authentication URL manually in your browser.');
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
this.log.info('π Opening browser for authentication...');
|
|
526
|
-
}
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
catch (error) {
|
|
530
|
-
this.log.warn('β οΈ Error opening browser:', error);
|
|
531
590
|
}
|
|
591
|
+
const tryLinux = async () => {
|
|
592
|
+
// 1) Standard freedesktop
|
|
593
|
+
try {
|
|
594
|
+
await tryExecFile('xdg-open', [url], env);
|
|
595
|
+
this.log.debug('π xdg-open OK');
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
catch { }
|
|
599
|
+
// 2) Gio / GVFS
|
|
600
|
+
try {
|
|
601
|
+
await tryExec(`gio open "${url}"`, env);
|
|
602
|
+
this.log.debug('π gio open OK');
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
catch { }
|
|
606
|
+
// 3) Debian-like helpers
|
|
607
|
+
try {
|
|
608
|
+
await tryExecFile('sensible-browser', [url], env);
|
|
609
|
+
this.log.debug('π sensible-browser OK');
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
catch { }
|
|
613
|
+
try {
|
|
614
|
+
await tryExecFile('x-www-browser', [url], env);
|
|
615
|
+
this.log.debug('π x-www-browser OK');
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
catch { }
|
|
619
|
+
// 4) xdg-desktop-portal (DBus OpenURI) β compatibile Wayland/X
|
|
620
|
+
try {
|
|
621
|
+
await tryExec(`gdbus call --session ` +
|
|
622
|
+
`--dest org.freedesktop.portal.Desktop ` +
|
|
623
|
+
`--object-path /org/freedesktop/portal/desktop ` +
|
|
624
|
+
`--method org.freedesktop.portal.OpenURI.OpenURI "" "${url}" "{}"`, env);
|
|
625
|
+
this.log.debug('π xdg-desktop-portal OpenURI OK');
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
catch { }
|
|
629
|
+
// 5) backend specifici (best-effort, non bloccanti)
|
|
630
|
+
try {
|
|
631
|
+
await tryExecFile('kde-open5', [url], env);
|
|
632
|
+
this.log.debug('π kde-open5 OK');
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
catch { }
|
|
636
|
+
try {
|
|
637
|
+
await tryExecFile('gnome-open', [url], env);
|
|
638
|
+
this.log.debug('π gnome-open OK');
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
catch { }
|
|
642
|
+
// Nessun metodo disponibile/riuscito
|
|
643
|
+
throw new Error('No Linux opener succeeded');
|
|
644
|
+
};
|
|
645
|
+
(async () => {
|
|
646
|
+
try {
|
|
647
|
+
switch (process.platform) {
|
|
648
|
+
case 'darwin':
|
|
649
|
+
await tryExec(`open "${url}"`, env);
|
|
650
|
+
break;
|
|
651
|
+
case 'win32':
|
|
652
|
+
await tryExec(`start "" "${url}"`, env);
|
|
653
|
+
break;
|
|
654
|
+
default:
|
|
655
|
+
await tryLinux();
|
|
656
|
+
}
|
|
657
|
+
this.log.info('β
Tentativo di apertura browser completato');
|
|
658
|
+
}
|
|
659
|
+
catch (e) {
|
|
660
|
+
this.log.warn(`β οΈ Impossibile aprire automaticamente il browser (${e?.message || e}). Apri lβURL manualmente.`);
|
|
661
|
+
}
|
|
662
|
+
})();
|
|
532
663
|
}
|
|
533
664
|
async exchangeCodeForTokens(authCode) {
|
|
534
665
|
const tokenData = new url_1.URLSearchParams({
|
package/dist/settings.js
CHANGED
|
@@ -65,8 +65,8 @@ exports.DEFAULT_CONFIG = {
|
|
|
65
65
|
* Viessmann API endpoints
|
|
66
66
|
*/
|
|
67
67
|
exports.VIESSMANN_API = {
|
|
68
|
-
baseURL: 'https://api.viessmann.com',
|
|
69
|
-
authURL: 'https://iam.viessmann.com/idp/v3',
|
|
68
|
+
baseURL: 'https://api.viessmann-climatesolutions.com',
|
|
69
|
+
authURL: 'https://iam.viessmann-climatesolutions.com/idp/v3',
|
|
70
70
|
scope: 'IoT User offline_access',
|
|
71
71
|
endpoints: {
|
|
72
72
|
installations: '/iot/v2/equipment/installations',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-viessmann-vicare",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Complete Homebridge plugin for Viessmann ViCare heating systems with full control capabilities, advanced rate limiting protection, and intelligent cache management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -58,4 +58,4 @@
|
|
|
58
58
|
"type": "individual",
|
|
59
59
|
"url": "https://github.com/sponsors/diegoweb100"
|
|
60
60
|
}
|
|
61
|
-
}
|
|
61
|
+
}
|