@camstack/addon-provider-homematic 1.2.171 → 1.2.172
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 +6 -0
- package/dist/addon.js +26 -6
- package/dist/addon.mjs +26 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.172] - 2026-10-31
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- The CCU network scan now finds a CCU that answers the probe with a JSON-RPC error, a WebUI username alone (empty password) now unlocks device names, and a missing-names warning is logged.
|
|
15
|
+
|
|
10
16
|
## [1.2.171] - 2026-10-31
|
|
11
17
|
|
|
12
18
|
### Changed
|
package/dist/addon.js
CHANGED
|
@@ -117895,11 +117895,12 @@ function enabledInterfaces(config) {
|
|
|
117895
117895
|
/**
|
|
117896
117896
|
* Build the `HomematicOptions` the wrapped library constructor expects
|
|
117897
117897
|
* from the validated addon config. Pure: same config in → same options
|
|
117898
|
-
* out. Credentials are
|
|
117899
|
-
*
|
|
117898
|
+
* out. Credentials are forwarded when a username is set (the password may be
|
|
117899
|
+
* empty on a CCU without WebUI authentication); without one the library skips
|
|
117900
|
+
* the JSON-RPC hub layer cleanly.
|
|
117900
117901
|
*/
|
|
117901
117902
|
function toHomematicOptions(config) {
|
|
117902
|
-
const hasCredentials = config.username.length > 0
|
|
117903
|
+
const hasCredentials = config.username.length > 0;
|
|
117903
117904
|
const callbackHost = config.callbackHost.length > 0 ? config.callbackHost : inferCallbackHost(config.host) ?? "";
|
|
117904
117905
|
const interfaces = enabledInterfaces(config);
|
|
117905
117906
|
return {
|
|
@@ -120780,6 +120781,10 @@ var HOMEMATIC_DISCOVERY_MODES = [{
|
|
|
120780
120781
|
tls: false,
|
|
120781
120782
|
acceptStatus: [200]
|
|
120782
120783
|
}];
|
|
120784
|
+
/** A JSON-RPC reply: it echoes `version` or `id`, and carries a `result` and an `error` member. */
|
|
120785
|
+
function isJsonRpcEnvelope(parsed) {
|
|
120786
|
+
return (Reflect.has(parsed, "version") || Reflect.has(parsed, "id")) && Reflect.has(parsed, "result") && Reflect.has(parsed, "error");
|
|
120787
|
+
}
|
|
120783
120788
|
/**
|
|
120784
120789
|
* Read the answer of `CCU.getAuthEnabled`, the question the WebUI asks before
|
|
120785
120790
|
* it shows a login. A CCU answers a boolean; one that already requires a login
|
|
@@ -120799,7 +120804,7 @@ function parseAuthEnabledAnswer(status, text) {
|
|
|
120799
120804
|
if (typeof error !== "object") return null;
|
|
120800
120805
|
const message = Reflect.get(error, "message");
|
|
120801
120806
|
const code = Reflect.get(error, "code");
|
|
120802
|
-
return typeof message === "string" && message.toLowerCase().startsWith("access denied") || code === 401 || code === -32001 ? { authEnabled: true } : null;
|
|
120807
|
+
return typeof message === "string" && message.toLowerCase().startsWith("access denied") || code === 401 || code === -32001 || isJsonRpcEnvelope(parsed) ? { authEnabled: true } : null;
|
|
120803
120808
|
}
|
|
120804
120809
|
const result = Reflect.get(parsed, "result");
|
|
120805
120810
|
if (result === true || result === "true") return { authEnabled: true };
|
|
@@ -120910,6 +120915,7 @@ var HmIntegrationManager = class {
|
|
|
120910
120915
|
#facade = null;
|
|
120911
120916
|
#status = "disconnected";
|
|
120912
120917
|
#deviceCount = 0;
|
|
120918
|
+
#namesAvailable = true;
|
|
120913
120919
|
#lastCheckedAt = null;
|
|
120914
120920
|
#error = null;
|
|
120915
120921
|
/** Active event-listener disposers, cleared on stop. */
|
|
@@ -120960,7 +120966,8 @@ var HmIntegrationManager = class {
|
|
|
120960
120966
|
info: {
|
|
120961
120967
|
host: this.#connection.host,
|
|
120962
120968
|
tls: this.#connection.tls,
|
|
120963
|
-
deviceCount: this.#deviceCount
|
|
120969
|
+
deviceCount: this.#deviceCount,
|
|
120970
|
+
namesAvailable: this.#namesAvailable
|
|
120964
120971
|
},
|
|
120965
120972
|
lastCheckedAt: this.#lastCheckedAt,
|
|
120966
120973
|
error: this.#error
|
|
@@ -120983,7 +120990,20 @@ var HmIntegrationManager = class {
|
|
|
120983
120990
|
this.#facade = facade;
|
|
120984
120991
|
this.#attachListeners(facade);
|
|
120985
120992
|
await facade.start();
|
|
120986
|
-
|
|
120993
|
+
const devices = facade.devices();
|
|
120994
|
+
this.#deviceCount = devices.length;
|
|
120995
|
+
this.#namesAvailable = devices.length === 0 || devices.some((d) => (d.name ?? "").length > 0);
|
|
120996
|
+
if (!this.#namesAvailable) {
|
|
120997
|
+
const credentialsSet = this.#connection.username.length > 0;
|
|
120998
|
+
this.#logger.warn("HmIntegrationManager: device names unavailable — devices are listed by address", {
|
|
120999
|
+
tags: { integrationId: this.#id },
|
|
121000
|
+
meta: {
|
|
121001
|
+
devices: devices.length,
|
|
121002
|
+
credentialsSet,
|
|
121003
|
+
hint: credentialsSet ? "WebUI login set but the CCU returned no names; check the username (an empty password is valid on a CCU without WebUI authentication)" : "set a WebUI username (and password if the CCU has one) on the integration"
|
|
121004
|
+
}
|
|
121005
|
+
});
|
|
121006
|
+
}
|
|
120987
121007
|
this.#lastCheckedAt = Date.now();
|
|
120988
121008
|
this.#status = "connected";
|
|
120989
121009
|
this.#error = null;
|
package/dist/addon.mjs
CHANGED
|
@@ -117896,11 +117896,12 @@ function enabledInterfaces(config) {
|
|
|
117896
117896
|
/**
|
|
117897
117897
|
* Build the `HomematicOptions` the wrapped library constructor expects
|
|
117898
117898
|
* from the validated addon config. Pure: same config in → same options
|
|
117899
|
-
* out. Credentials are
|
|
117900
|
-
*
|
|
117899
|
+
* out. Credentials are forwarded when a username is set (the password may be
|
|
117900
|
+
* empty on a CCU without WebUI authentication); without one the library skips
|
|
117901
|
+
* the JSON-RPC hub layer cleanly.
|
|
117901
117902
|
*/
|
|
117902
117903
|
function toHomematicOptions(config) {
|
|
117903
|
-
const hasCredentials = config.username.length > 0
|
|
117904
|
+
const hasCredentials = config.username.length > 0;
|
|
117904
117905
|
const callbackHost = config.callbackHost.length > 0 ? config.callbackHost : inferCallbackHost(config.host) ?? "";
|
|
117905
117906
|
const interfaces = enabledInterfaces(config);
|
|
117906
117907
|
return {
|
|
@@ -120781,6 +120782,10 @@ var HOMEMATIC_DISCOVERY_MODES = [{
|
|
|
120781
120782
|
tls: false,
|
|
120782
120783
|
acceptStatus: [200]
|
|
120783
120784
|
}];
|
|
120785
|
+
/** A JSON-RPC reply: it echoes `version` or `id`, and carries a `result` and an `error` member. */
|
|
120786
|
+
function isJsonRpcEnvelope(parsed) {
|
|
120787
|
+
return (Reflect.has(parsed, "version") || Reflect.has(parsed, "id")) && Reflect.has(parsed, "result") && Reflect.has(parsed, "error");
|
|
120788
|
+
}
|
|
120784
120789
|
/**
|
|
120785
120790
|
* Read the answer of `CCU.getAuthEnabled`, the question the WebUI asks before
|
|
120786
120791
|
* it shows a login. A CCU answers a boolean; one that already requires a login
|
|
@@ -120800,7 +120805,7 @@ function parseAuthEnabledAnswer(status, text) {
|
|
|
120800
120805
|
if (typeof error !== "object") return null;
|
|
120801
120806
|
const message = Reflect.get(error, "message");
|
|
120802
120807
|
const code = Reflect.get(error, "code");
|
|
120803
|
-
return typeof message === "string" && message.toLowerCase().startsWith("access denied") || code === 401 || code === -32001 ? { authEnabled: true } : null;
|
|
120808
|
+
return typeof message === "string" && message.toLowerCase().startsWith("access denied") || code === 401 || code === -32001 || isJsonRpcEnvelope(parsed) ? { authEnabled: true } : null;
|
|
120804
120809
|
}
|
|
120805
120810
|
const result = Reflect.get(parsed, "result");
|
|
120806
120811
|
if (result === true || result === "true") return { authEnabled: true };
|
|
@@ -120911,6 +120916,7 @@ var HmIntegrationManager = class {
|
|
|
120911
120916
|
#facade = null;
|
|
120912
120917
|
#status = "disconnected";
|
|
120913
120918
|
#deviceCount = 0;
|
|
120919
|
+
#namesAvailable = true;
|
|
120914
120920
|
#lastCheckedAt = null;
|
|
120915
120921
|
#error = null;
|
|
120916
120922
|
/** Active event-listener disposers, cleared on stop. */
|
|
@@ -120961,7 +120967,8 @@ var HmIntegrationManager = class {
|
|
|
120961
120967
|
info: {
|
|
120962
120968
|
host: this.#connection.host,
|
|
120963
120969
|
tls: this.#connection.tls,
|
|
120964
|
-
deviceCount: this.#deviceCount
|
|
120970
|
+
deviceCount: this.#deviceCount,
|
|
120971
|
+
namesAvailable: this.#namesAvailable
|
|
120965
120972
|
},
|
|
120966
120973
|
lastCheckedAt: this.#lastCheckedAt,
|
|
120967
120974
|
error: this.#error
|
|
@@ -120984,7 +120991,20 @@ var HmIntegrationManager = class {
|
|
|
120984
120991
|
this.#facade = facade;
|
|
120985
120992
|
this.#attachListeners(facade);
|
|
120986
120993
|
await facade.start();
|
|
120987
|
-
|
|
120994
|
+
const devices = facade.devices();
|
|
120995
|
+
this.#deviceCount = devices.length;
|
|
120996
|
+
this.#namesAvailable = devices.length === 0 || devices.some((d) => (d.name ?? "").length > 0);
|
|
120997
|
+
if (!this.#namesAvailable) {
|
|
120998
|
+
const credentialsSet = this.#connection.username.length > 0;
|
|
120999
|
+
this.#logger.warn("HmIntegrationManager: device names unavailable — devices are listed by address", {
|
|
121000
|
+
tags: { integrationId: this.#id },
|
|
121001
|
+
meta: {
|
|
121002
|
+
devices: devices.length,
|
|
121003
|
+
credentialsSet,
|
|
121004
|
+
hint: credentialsSet ? "WebUI login set but the CCU returned no names; check the username (an empty password is valid on a CCU without WebUI authentication)" : "set a WebUI username (and password if the CCU has one) on the integration"
|
|
121005
|
+
}
|
|
121006
|
+
});
|
|
121007
|
+
}
|
|
120988
121008
|
this.#lastCheckedAt = Date.now();
|
|
120989
121009
|
this.#status = "connected";
|
|
120990
121010
|
this.#error = null;
|
package/package.json
CHANGED