@camstack/addon-provider-wyze 0.2.68 → 0.2.70

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
@@ -7585,7 +7585,8 @@ var CameraSwitchAuthoritySchema = discriminatedUnion("kind", [
7585
7585
  var CameraSwitchUnavailableReasonSchema = _enum([
7586
7586
  "no-provider",
7587
7587
  "source-unreachable",
7588
- "not-configured"
7588
+ "not-configured",
7589
+ "device-disabled"
7589
7590
  ]);
7590
7591
  /**
7591
7592
  * One switch, resolved for one camera.
@@ -13092,7 +13093,12 @@ var ConfigEntrySchema = object({
13092
13093
  value: unknown(),
13093
13094
  description: string().optional()
13094
13095
  });
13095
- var LinkedDevicesModeSchema = _enum(["auto", "manual"]);
13096
+ /**
13097
+ * Only `manual` since D356: the operator picks, nothing links itself. The
13098
+ * field survives on the wire because a viewer already OTA'd parses it —
13099
+ * drop it once no shipped client reads `mode`.
13100
+ */
13101
+ var LinkedDevicesModeSchema = _enum(["manual"]);
13096
13102
  /** One resolved linked device — the compact projection consumers need. */
13097
13103
  var LinkedDeviceSchema = object({
13098
13104
  deviceId: number(),
@@ -23724,12 +23730,20 @@ var BatteryStatusSchema = object({
23724
23730
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23725
23731
  * Reolink-specific for the Solar Panel 2 accessory (will become
23726
23732
  * common on other battery cams). `'none'` means running on battery
23727
- * alone.
23733
+ * alone — a NEGATIVE the firmware actually reported.
23734
+ *
23735
+ * `'unknown'` is the absence of an answer: the provider has not read the
23736
+ * power fields yet, or the firmware reported neither. Before it existed,
23737
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
23738
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
23739
+ * by going nullable. Consumers SKIP it (no charger state published, no
23740
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
23728
23741
  */
23729
23742
  charging: _enum([
23730
23743
  "dc",
23731
23744
  "solar",
23732
- "none"
23745
+ "none",
23746
+ "unknown"
23733
23747
  ]),
23734
23748
  /**
23735
23749
  * True when the camera firmware has gone into low-power mode. Battery
@@ -23819,7 +23833,7 @@ onStatusChanged: { data: object({
23819
23833
  kind: "push",
23820
23834
  empty: {
23821
23835
  percentage: 0,
23822
- charging: "none",
23836
+ charging: "unknown",
23823
23837
  sleeping: false,
23824
23838
  lastUpdated: 0
23825
23839
  }
@@ -33235,8 +33249,17 @@ var BaseDeviceProvider = class extends BaseAddon {
33235
33249
  async onRestoreDevices(savedDevices) {
33236
33250
  const restored = /* @__PURE__ */ new Set();
33237
33251
  const failures = [];
33252
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
33238
33253
  const attemptRestore = async (saved) => {
33239
33254
  if (restored.has(saved.id)) return;
33255
+ if (liveStableIds.has(saved.stableId)) {
33256
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
33257
+ deviceId: saved.id,
33258
+ stableId: saved.stableId
33259
+ } });
33260
+ restored.add(saved.id);
33261
+ return;
33262
+ }
33240
33263
  const Class = this.deviceClasses[saved.type];
33241
33264
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33242
33265
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
package/dist/addon.mjs CHANGED
@@ -7564,7 +7564,8 @@ var CameraSwitchAuthoritySchema = discriminatedUnion("kind", [
7564
7564
  var CameraSwitchUnavailableReasonSchema = _enum([
7565
7565
  "no-provider",
7566
7566
  "source-unreachable",
7567
- "not-configured"
7567
+ "not-configured",
7568
+ "device-disabled"
7568
7569
  ]);
7569
7570
  /**
7570
7571
  * One switch, resolved for one camera.
@@ -13071,7 +13072,12 @@ var ConfigEntrySchema = object({
13071
13072
  value: unknown(),
13072
13073
  description: string().optional()
13073
13074
  });
13074
- var LinkedDevicesModeSchema = _enum(["auto", "manual"]);
13075
+ /**
13076
+ * Only `manual` since D356: the operator picks, nothing links itself. The
13077
+ * field survives on the wire because a viewer already OTA'd parses it —
13078
+ * drop it once no shipped client reads `mode`.
13079
+ */
13080
+ var LinkedDevicesModeSchema = _enum(["manual"]);
13075
13081
  /** One resolved linked device — the compact projection consumers need. */
13076
13082
  var LinkedDeviceSchema = object({
13077
13083
  deviceId: number(),
@@ -23703,12 +23709,20 @@ var BatteryStatusSchema = object({
23703
23709
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23704
23710
  * Reolink-specific for the Solar Panel 2 accessory (will become
23705
23711
  * common on other battery cams). `'none'` means running on battery
23706
- * alone.
23712
+ * alone — a NEGATIVE the firmware actually reported.
23713
+ *
23714
+ * `'unknown'` is the absence of an answer: the provider has not read the
23715
+ * power fields yet, or the firmware reported neither. Before it existed,
23716
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
23717
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
23718
+ * by going nullable. Consumers SKIP it (no charger state published, no
23719
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
23707
23720
  */
23708
23721
  charging: _enum([
23709
23722
  "dc",
23710
23723
  "solar",
23711
- "none"
23724
+ "none",
23725
+ "unknown"
23712
23726
  ]),
23713
23727
  /**
23714
23728
  * True when the camera firmware has gone into low-power mode. Battery
@@ -23798,7 +23812,7 @@ onStatusChanged: { data: object({
23798
23812
  kind: "push",
23799
23813
  empty: {
23800
23814
  percentage: 0,
23801
- charging: "none",
23815
+ charging: "unknown",
23802
23816
  sleeping: false,
23803
23817
  lastUpdated: 0
23804
23818
  }
@@ -33214,8 +33228,17 @@ var BaseDeviceProvider = class extends BaseAddon {
33214
33228
  async onRestoreDevices(savedDevices) {
33215
33229
  const restored = /* @__PURE__ */ new Set();
33216
33230
  const failures = [];
33231
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
33217
33232
  const attemptRestore = async (saved) => {
33218
33233
  if (restored.has(saved.id)) return;
33234
+ if (liveStableIds.has(saved.stableId)) {
33235
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
33236
+ deviceId: saved.id,
33237
+ stableId: saved.stableId
33238
+ } });
33239
+ restored.add(saved.id);
33240
+ return;
33241
+ }
33219
33242
  const Class = this.deviceClasses[saved.type];
33220
33243
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33221
33244
  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-provider-wyze",
3
- "version": "0.2.68",
3
+ "version": "0.2.70",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",