@camstack/addon-provider-homeassistant 1.2.74 → 1.2.76

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/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("./dist-Ccw8gsKE.js");
2
+ const require_dist = require("./dist-gv0Gmrm1.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_zlib = require("node:zlib");
5
5
  //#region src/ha-device-source.ts
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as presenceCapability, A as controlCapability, At as EventCategory, B as humiditySensorCapability, C as buildAddonRouteProvider, Ct as number, D as colorCapability, Dt as union, E as climateControlCapability, Et as string, F as eventEmitterCapability, G as motionCapability, H as lawnMowerControlCapability, I as fanControlCapability, J as notifierCapability, K as normalizeUnit, L as floodCapability, M as deviceAdoptionCapability, O as connectivityCapability, Ot as unknown, P as enumSensorCapability, Q as prepareNotification, R as gasCapability, S as brokerCapability, St as literal, T as carbonMonoxideCapability, Tt as record, U as lockControlCapability, V as imageCapability, W as mediaPlayerCapability, Y as numericSensorCapability, Z as powerMeterCapability, _ as automationControlCapability, _t as createEvent, at as temperatureSensorCapability, b as binaryCapability, bt as array, ct as valveCapability, d as TargetSchema, dt as weatherCapability, et as pressureSensorCapability, f as accessoriesCapability, ft as errMsg, g as ambientLightSensorCapability, gt as DeviceType, h as alarmPanelCapability, ht as DeviceRole, it as tamperCapability, j as coverCapability, k as contactCapability, kt as url, lt as vibrationCapability, m as airQualitySensorCapability, mt as DeviceFeature, n as BaseDevice, nt as smokeCapability, ot as updateCapability, p as addonRoutesCapability, q as notificationOutputCapability, r as BaseDeviceProvider, rt as switchCapability, s as EnumSensorDateTimeFormatSchema, st as vacuumControlCapability, tt as scriptRunnerCapability, ut as waterHeaterCapability, v as batteryCapability, w as buttonCapability, wt as object, x as brightnessCapability, xt as discriminatedUnion, y as bestLocationMatch, yt as _enum, z as humidifierCapability } from "./dist-CrzCO0F_.mjs";
1
+ import { $ as presenceCapability, A as controlCapability, At as EventCategory, B as humiditySensorCapability, C as buildAddonRouteProvider, Ct as number, D as colorCapability, Dt as union, E as climateControlCapability, Et as string, F as eventEmitterCapability, G as motionCapability, H as lawnMowerControlCapability, I as fanControlCapability, J as notifierCapability, K as normalizeUnit, L as floodCapability, M as deviceAdoptionCapability, O as connectivityCapability, Ot as unknown, P as enumSensorCapability, Q as prepareNotification, R as gasCapability, S as brokerCapability, St as literal, T as carbonMonoxideCapability, Tt as record, U as lockControlCapability, V as imageCapability, W as mediaPlayerCapability, Y as numericSensorCapability, Z as powerMeterCapability, _ as automationControlCapability, _t as createEvent, at as temperatureSensorCapability, b as binaryCapability, bt as array, ct as valveCapability, d as TargetSchema, dt as weatherCapability, et as pressureSensorCapability, f as accessoriesCapability, ft as errMsg, g as ambientLightSensorCapability, gt as DeviceType, h as alarmPanelCapability, ht as DeviceRole, it as tamperCapability, j as coverCapability, k as contactCapability, kt as url, lt as vibrationCapability, m as airQualitySensorCapability, mt as DeviceFeature, n as BaseDevice, nt as smokeCapability, ot as updateCapability, p as addonRoutesCapability, q as notificationOutputCapability, r as BaseDeviceProvider, rt as switchCapability, s as EnumSensorDateTimeFormatSchema, st as vacuumControlCapability, tt as scriptRunnerCapability, ut as waterHeaterCapability, v as batteryCapability, w as buttonCapability, wt as object, x as brightnessCapability, xt as discriminatedUnion, y as bestLocationMatch, yt as _enum, z as humidifierCapability } from "./dist-CQzCvoCx.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
4
4
  //#region src/ha-device-source.ts
@@ -13114,7 +13114,26 @@ var DiscoveryCandidateSchema = object({
13114
13114
  * identity ahead of adoption. Rendering metadata (unit, precision)
13115
13115
  * flows live through the cap STATUS SLICE after adoption.
13116
13116
  */
13117
- sourceInfo: SourceInfoSchema.optional()
13117
+ sourceInfo: SourceInfoSchema.optional(),
13118
+ /**
13119
+ * Set when this candidate is a device the provider ALREADY owns.
13120
+ *
13121
+ * A scan cannot generally produce the identity a device was onboarded under
13122
+ * (Reolink keys on `mac-<mac>`, learned at adopt time), so a stableId
13123
+ * comparison never matches and an owned device looks addable. Re-adopting one
13124
+ * overwrites its config with scan-derived values — that is how a Home Hub's
13125
+ * Baichuan port was overwritten with its ONVIF port, taking the hub and its
13126
+ * three child cameras offline for four hours.
13127
+ *
13128
+ * A provider that can recognise its own devices says so here. Absent means
13129
+ * "not recognised", which is not the same as "known to be new" — a provider
13130
+ * that cannot tell simply never sets it.
13131
+ */
13132
+ alreadyOnboarded: boolean().optional(),
13133
+ /** Numeric id of the device this candidate was matched to. Set with `alreadyOnboarded`. */
13134
+ onboardedDeviceId: number().optional(),
13135
+ /** Operator-facing name of the matched device, so the UI can say WHICH one it is. */
13136
+ onboardedName: string().optional()
13118
13137
  });
13119
13138
  /**
13120
13139
  * Flat device summary returned by `createDevice` / `adoptDiscoveredDevice`.
@@ -33471,6 +33490,22 @@ var BaseDeviceProvider = class extends BaseAddon {
33471
33490
  * failed — logged at ERROR with `tags.deviceId` and surfaced via
33472
33491
  * `getStatus().error`.
33473
33492
  */
33493
+ /**
33494
+ * Repair a row's PERSISTED config blob immediately before it is restored.
33495
+ * Default: no-op — most providers have nothing to heal.
33496
+ *
33497
+ * This exists because a restored device self-hydrates from the DB: `create()`
33498
+ * passes `{}` and `BaseDevice` parses the stored blob against the device
33499
+ * schema. A blob that lost a REQUIRED field therefore fails restore forever,
33500
+ * and no later pass revisits it — a hub-adopted Reolink camera whose blob had
33501
+ * been emptied failed all four bounded attempts against fields
33502
+ * (`host`, `password`) it inherits from its parent and never dials itself.
33503
+ *
33504
+ * Implementations get every saved row, so a child can read its parent's blob.
33505
+ * A heal that throws is treated like any other restore failure: retried under
33506
+ * the bound, then reported — never swallowed.
33507
+ */
33508
+ async healSavedConfig(_saved, _allSaved) {}
33474
33509
  async onRestoreDevices(savedDevices) {
33475
33510
  const restored = /* @__PURE__ */ new Set();
33476
33511
  const failures = [];
@@ -33479,6 +33514,7 @@ var BaseDeviceProvider = class extends BaseAddon {
33479
33514
  const Class = this.deviceClasses[saved.type];
33480
33515
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33481
33516
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
33517
+ await this.healSavedConfig(saved, savedDevices);
33482
33518
  await this.ctx.kernel.devices.create(saved.stableId, Class, {}, saved.parentDeviceId);
33483
33519
  restored.add(saved.id);
33484
33520
  };
@@ -13114,7 +13114,26 @@ var DiscoveryCandidateSchema = object({
13114
13114
  * identity ahead of adoption. Rendering metadata (unit, precision)
13115
13115
  * flows live through the cap STATUS SLICE after adoption.
13116
13116
  */
13117
- sourceInfo: SourceInfoSchema.optional()
13117
+ sourceInfo: SourceInfoSchema.optional(),
13118
+ /**
13119
+ * Set when this candidate is a device the provider ALREADY owns.
13120
+ *
13121
+ * A scan cannot generally produce the identity a device was onboarded under
13122
+ * (Reolink keys on `mac-<mac>`, learned at adopt time), so a stableId
13123
+ * comparison never matches and an owned device looks addable. Re-adopting one
13124
+ * overwrites its config with scan-derived values — that is how a Home Hub's
13125
+ * Baichuan port was overwritten with its ONVIF port, taking the hub and its
13126
+ * three child cameras offline for four hours.
13127
+ *
13128
+ * A provider that can recognise its own devices says so here. Absent means
13129
+ * "not recognised", which is not the same as "known to be new" — a provider
13130
+ * that cannot tell simply never sets it.
13131
+ */
13132
+ alreadyOnboarded: boolean().optional(),
13133
+ /** Numeric id of the device this candidate was matched to. Set with `alreadyOnboarded`. */
13134
+ onboardedDeviceId: number().optional(),
13135
+ /** Operator-facing name of the matched device, so the UI can say WHICH one it is. */
13136
+ onboardedName: string().optional()
13118
13137
  });
13119
13138
  /**
13120
13139
  * Flat device summary returned by `createDevice` / `adoptDiscoveredDevice`.
@@ -33471,6 +33490,22 @@ var BaseDeviceProvider = class extends BaseAddon {
33471
33490
  * failed — logged at ERROR with `tags.deviceId` and surfaced via
33472
33491
  * `getStatus().error`.
33473
33492
  */
33493
+ /**
33494
+ * Repair a row's PERSISTED config blob immediately before it is restored.
33495
+ * Default: no-op — most providers have nothing to heal.
33496
+ *
33497
+ * This exists because a restored device self-hydrates from the DB: `create()`
33498
+ * passes `{}` and `BaseDevice` parses the stored blob against the device
33499
+ * schema. A blob that lost a REQUIRED field therefore fails restore forever,
33500
+ * and no later pass revisits it — a hub-adopted Reolink camera whose blob had
33501
+ * been emptied failed all four bounded attempts against fields
33502
+ * (`host`, `password`) it inherits from its parent and never dials itself.
33503
+ *
33504
+ * Implementations get every saved row, so a child can read its parent's blob.
33505
+ * A heal that throws is treated like any other restore failure: retried under
33506
+ * the bound, then reported — never swallowed.
33507
+ */
33508
+ async healSavedConfig(_saved, _allSaved) {}
33474
33509
  async onRestoreDevices(savedDevices) {
33475
33510
  const restored = /* @__PURE__ */ new Set();
33476
33511
  const failures = [];
@@ -33479,6 +33514,7 @@ var BaseDeviceProvider = class extends BaseAddon {
33479
33514
  const Class = this.deviceClasses[saved.type];
33480
33515
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33481
33516
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
33517
+ await this.healSavedConfig(saved, savedDevices);
33482
33518
  await this.ctx.kernel.devices.create(saved.stableId, Class, {}, saved.parentDeviceId);
33483
33519
  restored.add(saved.id);
33484
33520
  };
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  //#endregion
6
- const require_dist = require("../dist-Ccw8gsKE.js");
6
+ const require_dist = require("../dist-gv0Gmrm1.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  //#region src/ha-export/topics.ts
9
9
  /**
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, C as buildAddonRouteProvider, Et as string, N as deviceExportCapability, X as oauthIntegrationCapability, a as COCO_TO_MACRO, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, pt as BaseAddon, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema, vt as nodePin } from "../dist-CrzCO0F_.mjs";
1
+ import { At as EventCategory, C as buildAddonRouteProvider, Et as string, N as deviceExportCapability, X as oauthIntegrationCapability, a as COCO_TO_MACRO, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, pt as BaseAddon, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema, vt as nodePin } from "../dist-CQzCvoCx.mjs";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/ha-export/topics.ts
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.2.74",
3
+ "version": "1.2.76",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",