@camstack/addon-matter-broker 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
@@ -7567,7 +7567,8 @@ var CameraSwitchAuthoritySchema = discriminatedUnion("kind", [
7567
7567
  var CameraSwitchUnavailableReasonSchema = _enum([
7568
7568
  "no-provider",
7569
7569
  "source-unreachable",
7570
- "not-configured"
7570
+ "not-configured",
7571
+ "device-disabled"
7571
7572
  ]);
7572
7573
  /**
7573
7574
  * One switch, resolved for one camera.
@@ -13123,7 +13124,12 @@ var ConfigEntrySchema = object({
13123
13124
  value: unknown(),
13124
13125
  description: string$2().optional()
13125
13126
  });
13126
- var LinkedDevicesModeSchema = _enum(["auto", "manual"]);
13127
+ /**
13128
+ * Only `manual` since D356: the operator picks, nothing links itself. The
13129
+ * field survives on the wire because a viewer already OTA'd parses it —
13130
+ * drop it once no shipped client reads `mode`.
13131
+ */
13132
+ var LinkedDevicesModeSchema = _enum(["manual"]);
13127
13133
  /** One resolved linked device — the compact projection consumers need. */
13128
13134
  var LinkedDeviceSchema = object({
13129
13135
  deviceId: number(),
@@ -23651,12 +23657,20 @@ var BatteryStatusSchema = object({
23651
23657
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23652
23658
  * Reolink-specific for the Solar Panel 2 accessory (will become
23653
23659
  * common on other battery cams). `'none'` means running on battery
23654
- * alone.
23660
+ * alone — a NEGATIVE the firmware actually reported.
23661
+ *
23662
+ * `'unknown'` is the absence of an answer: the provider has not read the
23663
+ * power fields yet, or the firmware reported neither. Before it existed,
23664
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
23665
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
23666
+ * by going nullable. Consumers SKIP it (no charger state published, no
23667
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
23655
23668
  */
23656
23669
  charging: _enum([
23657
23670
  "dc",
23658
23671
  "solar",
23659
- "none"
23672
+ "none",
23673
+ "unknown"
23660
23674
  ]),
23661
23675
  /**
23662
23676
  * True when the camera firmware has gone into low-power mode. Battery
@@ -23746,7 +23760,7 @@ onStatusChanged: { data: object({
23746
23760
  kind: "push",
23747
23761
  empty: {
23748
23762
  percentage: 0,
23749
- charging: "none",
23763
+ charging: "unknown",
23750
23764
  sleeping: false,
23751
23765
  lastUpdated: 0
23752
23766
  }
@@ -33171,8 +33185,17 @@ var BaseDeviceProvider = class extends BaseAddon {
33171
33185
  async onRestoreDevices(savedDevices) {
33172
33186
  const restored = /* @__PURE__ */ new Set();
33173
33187
  const failures = [];
33188
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
33174
33189
  const attemptRestore = async (saved) => {
33175
33190
  if (restored.has(saved.id)) return;
33191
+ if (liveStableIds.has(saved.stableId)) {
33192
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
33193
+ deviceId: saved.id,
33194
+ stableId: saved.stableId
33195
+ } });
33196
+ restored.add(saved.id);
33197
+ return;
33198
+ }
33176
33199
  const Class = this.deviceClasses[saved.type];
33177
33200
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33178
33201
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
@@ -152437,7 +152460,7 @@ var MatterEndpointDevice = class extends BaseDevice {
152437
152460
  registerBattery() {
152438
152461
  const COLD = {
152439
152462
  percentage: 0,
152440
- charging: "none",
152463
+ charging: "unknown",
152441
152464
  sleeping: false,
152442
152465
  lastUpdated: 0
152443
152466
  };
package/dist/addon.mjs CHANGED
@@ -7565,7 +7565,8 @@ var CameraSwitchAuthoritySchema = discriminatedUnion("kind", [
7565
7565
  var CameraSwitchUnavailableReasonSchema = _enum([
7566
7566
  "no-provider",
7567
7567
  "source-unreachable",
7568
- "not-configured"
7568
+ "not-configured",
7569
+ "device-disabled"
7569
7570
  ]);
7570
7571
  /**
7571
7572
  * One switch, resolved for one camera.
@@ -13121,7 +13122,12 @@ var ConfigEntrySchema = object({
13121
13122
  value: unknown(),
13122
13123
  description: string$2().optional()
13123
13124
  });
13124
- var LinkedDevicesModeSchema = _enum(["auto", "manual"]);
13125
+ /**
13126
+ * Only `manual` since D356: the operator picks, nothing links itself. The
13127
+ * field survives on the wire because a viewer already OTA'd parses it —
13128
+ * drop it once no shipped client reads `mode`.
13129
+ */
13130
+ var LinkedDevicesModeSchema = _enum(["manual"]);
13125
13131
  /** One resolved linked device — the compact projection consumers need. */
13126
13132
  var LinkedDeviceSchema = object({
13127
13133
  deviceId: number(),
@@ -23649,12 +23655,20 @@ var BatteryStatusSchema = object({
23649
23655
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23650
23656
  * Reolink-specific for the Solar Panel 2 accessory (will become
23651
23657
  * common on other battery cams). `'none'` means running on battery
23652
- * alone.
23658
+ * alone — a NEGATIVE the firmware actually reported.
23659
+ *
23660
+ * `'unknown'` is the absence of an answer: the provider has not read the
23661
+ * power fields yet, or the firmware reported neither. Before it existed,
23662
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
23663
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
23664
+ * by going nullable. Consumers SKIP it (no charger state published, no
23665
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
23653
23666
  */
23654
23667
  charging: _enum([
23655
23668
  "dc",
23656
23669
  "solar",
23657
- "none"
23670
+ "none",
23671
+ "unknown"
23658
23672
  ]),
23659
23673
  /**
23660
23674
  * True when the camera firmware has gone into low-power mode. Battery
@@ -23744,7 +23758,7 @@ onStatusChanged: { data: object({
23744
23758
  kind: "push",
23745
23759
  empty: {
23746
23760
  percentage: 0,
23747
- charging: "none",
23761
+ charging: "unknown",
23748
23762
  sleeping: false,
23749
23763
  lastUpdated: 0
23750
23764
  }
@@ -33169,8 +33183,17 @@ var BaseDeviceProvider = class extends BaseAddon {
33169
33183
  async onRestoreDevices(savedDevices) {
33170
33184
  const restored = /* @__PURE__ */ new Set();
33171
33185
  const failures = [];
33186
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
33172
33187
  const attemptRestore = async (saved) => {
33173
33188
  if (restored.has(saved.id)) return;
33189
+ if (liveStableIds.has(saved.stableId)) {
33190
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
33191
+ deviceId: saved.id,
33192
+ stableId: saved.stableId
33193
+ } });
33194
+ restored.add(saved.id);
33195
+ return;
33196
+ }
33174
33197
  const Class = this.deviceClasses[saved.type];
33175
33198
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
33176
33199
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
@@ -152435,7 +152458,7 @@ var MatterEndpointDevice = class extends BaseDevice {
152435
152458
  registerBattery() {
152436
152459
  const COLD = {
152437
152460
  percentage: 0,
152438
- charging: "none",
152461
+ charging: "unknown",
152439
152462
  sleeping: false,
152440
152463
  lastUpdated: 0
152441
152464
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-matter-broker",
3
- "version": "0.2.63",
3
+ "version": "0.2.65",
4
4
  "description": "Matter broker addon for CamStack — owns a Matter fabric (commissioning + the long-lived controller) via the matter.js controller and brokers commissioned Matter nodes into CamStack",
5
5
  "keywords": [
6
6
  "camstack",