@camstack/addon-import-alexa 0.2.63 → 0.2.65

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
@@ -7711,7 +7711,8 @@ var CameraSwitchAuthoritySchema = discriminatedUnion("kind", [
7711
7711
  var CameraSwitchUnavailableReasonSchema = _enum([
7712
7712
  "no-provider",
7713
7713
  "source-unreachable",
7714
- "not-configured"
7714
+ "not-configured",
7715
+ "device-disabled"
7715
7716
  ]);
7716
7717
  /**
7717
7718
  * One switch, resolved for one camera.
@@ -13286,7 +13287,12 @@ var ConfigEntrySchema = object({
13286
13287
  value: unknown(),
13287
13288
  description: string().optional()
13288
13289
  });
13289
- var LinkedDevicesModeSchema = _enum(["auto", "manual"]);
13290
+ /**
13291
+ * Only `manual` since D356: the operator picks, nothing links itself. The
13292
+ * field survives on the wire because a viewer already OTA'd parses it —
13293
+ * drop it once no shipped client reads `mode`.
13294
+ */
13295
+ var LinkedDevicesModeSchema = _enum(["manual"]);
13290
13296
  /** One resolved linked device — the compact projection consumers need. */
13291
13297
  var LinkedDeviceSchema = object({
13292
13298
  deviceId: number(),
@@ -23814,12 +23820,20 @@ var BatteryStatusSchema = object({
23814
23820
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23815
23821
  * Reolink-specific for the Solar Panel 2 accessory (will become
23816
23822
  * common on other battery cams). `'none'` means running on battery
23817
- * alone.
23823
+ * alone — a NEGATIVE the firmware actually reported.
23824
+ *
23825
+ * `'unknown'` is the absence of an answer: the provider has not read the
23826
+ * power fields yet, or the firmware reported neither. Before it existed,
23827
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
23828
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
23829
+ * by going nullable. Consumers SKIP it (no charger state published, no
23830
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
23818
23831
  */
23819
23832
  charging: _enum([
23820
23833
  "dc",
23821
23834
  "solar",
23822
- "none"
23835
+ "none",
23836
+ "unknown"
23823
23837
  ]),
23824
23838
  /**
23825
23839
  * True when the camera firmware has gone into low-power mode. Battery
@@ -23909,7 +23923,7 @@ onStatusChanged: { data: object({
23909
23923
  kind: "push",
23910
23924
  empty: {
23911
23925
  percentage: 0,
23912
- charging: "none",
23926
+ charging: "unknown",
23913
23927
  sleeping: false,
23914
23928
  lastUpdated: 0
23915
23929
  }
@@ -33334,8 +33348,17 @@ var BaseDeviceProvider = class extends BaseAddon {
33334
33348
  async onRestoreDevices(savedDevices) {
33335
33349
  const restored = /* @__PURE__ */ new Set();
33336
33350
  const failures = [];
33351
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
33337
33352
  const attemptRestore = async (saved) => {
33338
33353
  if (restored.has(saved.id)) return;
33354
+ if (liveStableIds.has(saved.stableId)) {
33355
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
33356
+ deviceId: saved.id,
33357
+ stableId: saved.stableId
33358
+ } });
33359
+ restored.add(saved.id);
33360
+ return;
33361
+ }
33339
33362
  const Class = this.deviceClasses[saved.type];
33340
33363
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33341
33364
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
package/dist/addon.mjs CHANGED
@@ -7711,7 +7711,8 @@ var CameraSwitchAuthoritySchema = discriminatedUnion("kind", [
7711
7711
  var CameraSwitchUnavailableReasonSchema = _enum([
7712
7712
  "no-provider",
7713
7713
  "source-unreachable",
7714
- "not-configured"
7714
+ "not-configured",
7715
+ "device-disabled"
7715
7716
  ]);
7716
7717
  /**
7717
7718
  * One switch, resolved for one camera.
@@ -13286,7 +13287,12 @@ var ConfigEntrySchema = object({
13286
13287
  value: unknown(),
13287
13288
  description: string().optional()
13288
13289
  });
13289
- var LinkedDevicesModeSchema = _enum(["auto", "manual"]);
13290
+ /**
13291
+ * Only `manual` since D356: the operator picks, nothing links itself. The
13292
+ * field survives on the wire because a viewer already OTA'd parses it —
13293
+ * drop it once no shipped client reads `mode`.
13294
+ */
13295
+ var LinkedDevicesModeSchema = _enum(["manual"]);
13290
13296
  /** One resolved linked device — the compact projection consumers need. */
13291
13297
  var LinkedDeviceSchema = object({
13292
13298
  deviceId: number(),
@@ -23814,12 +23820,20 @@ var BatteryStatusSchema = object({
23814
23820
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23815
23821
  * Reolink-specific for the Solar Panel 2 accessory (will become
23816
23822
  * common on other battery cams). `'none'` means running on battery
23817
- * alone.
23823
+ * alone — a NEGATIVE the firmware actually reported.
23824
+ *
23825
+ * `'unknown'` is the absence of an answer: the provider has not read the
23826
+ * power fields yet, or the firmware reported neither. Before it existed,
23827
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
23828
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
23829
+ * by going nullable. Consumers SKIP it (no charger state published, no
23830
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
23818
23831
  */
23819
23832
  charging: _enum([
23820
23833
  "dc",
23821
23834
  "solar",
23822
- "none"
23835
+ "none",
23836
+ "unknown"
23823
23837
  ]),
23824
23838
  /**
23825
23839
  * True when the camera firmware has gone into low-power mode. Battery
@@ -23909,7 +23923,7 @@ onStatusChanged: { data: object({
23909
23923
  kind: "push",
23910
23924
  empty: {
23911
23925
  percentage: 0,
23912
- charging: "none",
23926
+ charging: "unknown",
23913
23927
  sleeping: false,
23914
23928
  lastUpdated: 0
23915
23929
  }
@@ -33334,8 +33348,17 @@ var BaseDeviceProvider = class extends BaseAddon {
33334
33348
  async onRestoreDevices(savedDevices) {
33335
33349
  const restored = /* @__PURE__ */ new Set();
33336
33350
  const failures = [];
33351
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
33337
33352
  const attemptRestore = async (saved) => {
33338
33353
  if (restored.has(saved.id)) return;
33354
+ if (liveStableIds.has(saved.stableId)) {
33355
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
33356
+ deviceId: saved.id,
33357
+ stableId: saved.stableId
33358
+ } });
33359
+ restored.add(saved.id);
33360
+ return;
33361
+ }
33339
33362
  const Class = this.deviceClasses[saved.type];
33340
33363
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33341
33364
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-import-alexa",
3
- "version": "0.2.63",
3
+ "version": "0.2.65",
4
4
  "description": "Alexa device-import provider for CamStack — imports the smart-home devices in a user's Alexa account via the unofficial alexa-remote2 cookie/token client (the inverse of the Alexa exporter)",
5
5
  "keywords": [
6
6
  "camstack",