@camstack/addon-provider-homematic 1.2.115 → 1.2.117

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/dist/index.js CHANGED
@@ -193,6 +193,7 @@ var HomematicDevice = class extends require_addon.BaseDevice {
193
193
  super(ctx, homematicDeviceSchema, { type: ctx.deviceMeta.type });
194
194
  this.address = address;
195
195
  this.brokerId = typeof persisted.brokerId === "string" ? persisted.brokerId : void 0;
196
+ this.registerAdminLinkCap();
196
197
  this.registerCapabilities();
197
198
  this.attachValueChangedListener();
198
199
  this.updateSourceInfo({
@@ -210,6 +211,56 @@ var HomematicDevice = class extends require_addon.BaseDevice {
210
211
  if (!facade) return null;
211
212
  return facade.devices().find((d) => d.address === this.address) ?? null;
212
213
  }
214
+ /**
215
+ * device-admin-link — a Homematic device has no web server; the CCU3 /
216
+ * RaspberryMatic WebUI is where it is configured. The CCU has no stable
217
+ * per-device deep link (the WebUI addresses devices through a session-bound
218
+ * frameset), so every device on a CCU gets that CCU's root, labelled for
219
+ * what it is. A device persisted before multi-CCU support carries no
220
+ * `brokerId` and cannot be attributed to a CCU at all — it answers null.
221
+ *
222
+ * Registered OUTSIDE `registerCapabilities`, which returns early when the
223
+ * facade has not yet seen the device: whether the CCU has a WebUI does not
224
+ * depend on that, and an early return there used to be how a device ended up
225
+ * with no caps at all.
226
+ */
227
+ registerAdminLinkCap() {
228
+ const brokerId = this.brokerId;
229
+ this.ctx.registerNativeCap(require_addon.deviceAdminLinkCapability, { getAdminLink: async ({ deviceId }) => {
230
+ if (deviceId !== this.id) throw new Error(`HomematicDevice: deviceId mismatch, expected ${this.id}, got ${deviceId}`);
231
+ if (brokerId === void 0) {
232
+ this.ctx.logger.debug("homematic admin link unavailable: no brokerId on device", {
233
+ tags: { deviceId: this.id },
234
+ meta: { address: this.address }
235
+ });
236
+ return null;
237
+ }
238
+ const cfg = await this.ctx.api.broker.getBrokerConfig.query({ id: brokerId });
239
+ const host = typeof cfg?.["host"] === "string" ? cfg["host"] : "";
240
+ const built = require_addon.buildDeviceAdminUrl({
241
+ host,
242
+ port: null,
243
+ scheme: cfg?.["tls"] === true ? "https" : "http",
244
+ path: "/"
245
+ });
246
+ if (!built.ok) {
247
+ this.ctx.logger.debug("homematic admin link unavailable", {
248
+ tags: { deviceId: this.id },
249
+ meta: {
250
+ reason: built.reason,
251
+ brokerId
252
+ }
253
+ });
254
+ return null;
255
+ }
256
+ return {
257
+ url: built.url,
258
+ label: "CCU WebUI",
259
+ target: "integration",
260
+ host
261
+ };
262
+ } });
263
+ }
213
264
  registerCapabilities() {
214
265
  const hmDevice = this.resolveHmDevice();
215
266
  if (!hmDevice) {
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as motionCapability, D as object, E as createEvent, HomematicProviderAddon, O as string, S as lockControlCapability, T as DeviceType, _ as toHomematicOptions, a as decodeClimate, b as coverCapability, c as toHmClimateMode, d as mapHmChannel, f as mapHmDeviceChannels, g as homematicConfigSchema, h as homematicAddonConfigSchema, i as registerTemperatureCap, k as EventCategory, l as deriveHmEntitySpecs, m as buildConnectionFormSchema, n as registerHumidityCap, o as decodeCover, p as homematicFacades, r as registerPowerMeterCap, s as decodeLock, t as registerAmbientLightCap, u as inferHmDeviceType, v as BaseDevice, w as switchCapability, x as eventEmitterCapability, y as climateControlCapability } from "./addon.mjs";
1
+ import { A as string, C as eventEmitterCapability, D as DeviceType, E as switchCapability, HomematicProviderAddon, O as createEvent, S as deviceAdminLinkCapability, T as motionCapability, _ as toHomematicOptions, a as decodeClimate, b as climateControlCapability, c as toHmClimateMode, d as mapHmChannel, f as mapHmDeviceChannels, g as homematicConfigSchema, h as homematicAddonConfigSchema, i as registerTemperatureCap, j as EventCategory, k as object, l as deriveHmEntitySpecs, m as buildConnectionFormSchema, n as registerHumidityCap, o as decodeCover, p as homematicFacades, r as registerPowerMeterCap, s as decodeLock, t as registerAmbientLightCap, u as inferHmDeviceType, v as BaseDevice, w as lockControlCapability, x as coverCapability, y as buildDeviceAdminUrl } from "./addon.mjs";
2
2
  //#region src/homematic-device.ts
3
3
  /**
4
4
  * Persisted config every Homematic-backed device carries. `address` is
@@ -192,6 +192,7 @@ var HomematicDevice = class extends BaseDevice {
192
192
  super(ctx, homematicDeviceSchema, { type: ctx.deviceMeta.type });
193
193
  this.address = address;
194
194
  this.brokerId = typeof persisted.brokerId === "string" ? persisted.brokerId : void 0;
195
+ this.registerAdminLinkCap();
195
196
  this.registerCapabilities();
196
197
  this.attachValueChangedListener();
197
198
  this.updateSourceInfo({
@@ -209,6 +210,56 @@ var HomematicDevice = class extends BaseDevice {
209
210
  if (!facade) return null;
210
211
  return facade.devices().find((d) => d.address === this.address) ?? null;
211
212
  }
213
+ /**
214
+ * device-admin-link — a Homematic device has no web server; the CCU3 /
215
+ * RaspberryMatic WebUI is where it is configured. The CCU has no stable
216
+ * per-device deep link (the WebUI addresses devices through a session-bound
217
+ * frameset), so every device on a CCU gets that CCU's root, labelled for
218
+ * what it is. A device persisted before multi-CCU support carries no
219
+ * `brokerId` and cannot be attributed to a CCU at all — it answers null.
220
+ *
221
+ * Registered OUTSIDE `registerCapabilities`, which returns early when the
222
+ * facade has not yet seen the device: whether the CCU has a WebUI does not
223
+ * depend on that, and an early return there used to be how a device ended up
224
+ * with no caps at all.
225
+ */
226
+ registerAdminLinkCap() {
227
+ const brokerId = this.brokerId;
228
+ this.ctx.registerNativeCap(deviceAdminLinkCapability, { getAdminLink: async ({ deviceId }) => {
229
+ if (deviceId !== this.id) throw new Error(`HomematicDevice: deviceId mismatch, expected ${this.id}, got ${deviceId}`);
230
+ if (brokerId === void 0) {
231
+ this.ctx.logger.debug("homematic admin link unavailable: no brokerId on device", {
232
+ tags: { deviceId: this.id },
233
+ meta: { address: this.address }
234
+ });
235
+ return null;
236
+ }
237
+ const cfg = await this.ctx.api.broker.getBrokerConfig.query({ id: brokerId });
238
+ const host = typeof cfg?.["host"] === "string" ? cfg["host"] : "";
239
+ const built = buildDeviceAdminUrl({
240
+ host,
241
+ port: null,
242
+ scheme: cfg?.["tls"] === true ? "https" : "http",
243
+ path: "/"
244
+ });
245
+ if (!built.ok) {
246
+ this.ctx.logger.debug("homematic admin link unavailable", {
247
+ tags: { deviceId: this.id },
248
+ meta: {
249
+ reason: built.reason,
250
+ brokerId
251
+ }
252
+ });
253
+ return null;
254
+ }
255
+ return {
256
+ url: built.url,
257
+ label: "CCU WebUI",
258
+ target: "integration",
259
+ host
260
+ };
261
+ } });
262
+ }
212
263
  registerCapabilities() {
213
264
  const hmDevice = this.resolveHmDevice();
214
265
  if (!hmDevice) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.115",
3
+ "version": "1.2.117",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",