@camstack/addon-matter-broker 0.2.67 → 0.2.69

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
@@ -13,7 +13,7 @@ let node_stream_promises = require("node:stream/promises");
13
13
  let node_net = require("node:net");
14
14
  let node_dgram = require("node:dgram");
15
15
  node_dgram = require_esm.__toESM(node_dgram, 1);
16
- //#region ../types/dist/event-category-BZL-fdNj.mjs
16
+ //#region ../types/dist/event-category-zAv7pMUz.mjs
17
17
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
18
18
  EventCategory["SystemBoot"] = "system.boot";
19
19
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -385,6 +385,13 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
385
385
  */
386
386
  EventCategory["BatteryOnStatusChanged"] = "battery.onStatusChanged";
387
387
  /**
388
+ * Cap event fired by every device that registers the `network-link`
389
+ * capability. Mirrors the cap definition's `onStatusChanged`. Carries
390
+ * `{ deviceId, status: NetworkLinkStatus }` — a link switch or a signal
391
+ * reading that moved.
392
+ */
393
+ EventCategory["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
394
+ /**
388
395
  * Emitted by the battery cap provider WHEN `wakeForStream` enters the
389
396
  * "wake in progress" window — between the Baichuan wake-up issue and
390
397
  * the camera's first dialed-back RTP packet. The stream-broker
@@ -19469,6 +19476,33 @@ var RecentTracksQueryInput = object({
19469
19476
  */
19470
19477
  classes: array(string$2()).optional()
19471
19478
  });
19479
+ /**
19480
+ * A Summary (D359): the per-camera session envelope that references tracks.
19481
+ * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19482
+ * served by the event-media plane by key), null until the first frame with a
19483
+ * member visible has been materialised.
19484
+ */
19485
+ var SummarySchema = object({
19486
+ id: string$2(),
19487
+ deviceId: number(),
19488
+ openedAt: number(),
19489
+ lastActiveAt: number(),
19490
+ sealedAt: number().nullable(),
19491
+ memberCount: number().int().nonnegative(),
19492
+ groupShotKey: string$2().nullable()
19493
+ });
19494
+ var SummariesQueryInput = object({
19495
+ deviceIds: array(number()).min(1),
19496
+ since: number().optional(),
19497
+ until: number().optional(),
19498
+ limit: number().int().min(1).max(200).default(50)
19499
+ });
19500
+ var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
19501
+ var SummaryDetailSchema = object({
19502
+ summary: SummarySchema,
19503
+ /** Member track ids, in absorption order. */
19504
+ trackIds: array(string$2()).readonly()
19505
+ });
19472
19506
  var RecentTracksPageSchema = object({
19473
19507
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
19474
19508
  tracks: array(TrackSchema).readonly(),
@@ -19869,7 +19903,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19869
19903
  * timeline would read as a camera that saw nothing.
19870
19904
  */
19871
19905
  classes: array(string$2()).optional()
19872
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19906
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string$2() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19873
19907
  kind: "mutation",
19874
19908
  auth: "admin"
19875
19909
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -23802,6 +23836,88 @@ onStatusChanged: { data: object({
23802
23836
  volatileStateFields: ["lastUpdated"]
23803
23837
  };
23804
23838
  /**
23839
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
23840
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
23841
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
23842
+ * one Home Assistant projection.
23843
+ */
23844
+ var NetworkLinkStatusSchema = object({
23845
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
23846
+ type: _enum([
23847
+ "wifi",
23848
+ "ethernet",
23849
+ "cellular",
23850
+ "unknown"
23851
+ ]),
23852
+ /**
23853
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
23854
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
23855
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
23856
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
23857
+ * SKIP a null rather than coerce it.
23858
+ */
23859
+ signalPercent: number().min(0).max(100).nullable(),
23860
+ /** Raw received signal strength in dBm, when the firmware reports one. */
23861
+ rssiDbm: number().optional(),
23862
+ /** Network name of a wireless link, when the firmware reports it. */
23863
+ ssid: string$2().optional(),
23864
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
23865
+ lastUpdated: number()
23866
+ });
23867
+ var networkLinkCapability = {
23868
+ name: "network-link",
23869
+ scope: "device",
23870
+ deviceNative: true,
23871
+ mode: "singleton",
23872
+ deviceTypes: [
23873
+ DeviceType.Camera,
23874
+ DeviceType.Sensor,
23875
+ DeviceType.Button,
23876
+ DeviceType.Switch,
23877
+ DeviceType.Light,
23878
+ DeviceType.Lock,
23879
+ DeviceType.Siren
23880
+ ],
23881
+ methods: {},
23882
+ events: {
23883
+ /**
23884
+ * Emitted whenever the cached status changes (a link switch, a signal
23885
+ * reading that moved). Mirrored on the parent chain by the
23886
+ * DeviceEventPropagator like `battery.onStatusChanged`.
23887
+ */
23888
+ onStatusChanged: { data: object({
23889
+ deviceId: number(),
23890
+ status: NetworkLinkStatusSchema
23891
+ }) } },
23892
+ status: {
23893
+ schema: NetworkLinkStatusSchema,
23894
+ kind: "push",
23895
+ empty: {
23896
+ type: "unknown",
23897
+ signalPercent: null,
23898
+ lastUpdated: 0
23899
+ }
23900
+ },
23901
+ /**
23902
+ * Runtime-state slice — every provider stores the same shape under
23903
+ * `device.runtimeState['network-link']`, read once by the badge and the
23904
+ * Home Assistant projector regardless of the driver.
23905
+ */
23906
+ runtimeState: NetworkLinkStatusSchema,
23907
+ /**
23908
+ * Runtime-state durability: **restored** — a link reading is slow to
23909
+ * change and a sleeping battery camera may not report for hours; the
23910
+ * restored slice is what the badge shows until the next read.
23911
+ *
23912
+ * See `RuntimeStateDurability`. Enforced by
23913
+ * `scripts/check-runtime-state-durability.ts`.
23914
+ */
23915
+ durability: "restored",
23916
+ /** Clock fields: written, but excluded from the compare that decides
23917
+ * whether persisting is worth a SQLite commit. */
23918
+ volatileStateFields: ["lastUpdated"]
23919
+ };
23920
+ /**
23805
23921
  * Generic boolean sensor — last-resort fallback when no domain-
23806
23922
  * specific binary cap fits (Home Assistant `binary_sensor` without a
23807
23923
  * known `device_class`, or a domain we haven't typed yet). Pure
@@ -32203,6 +32319,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
32203
32319
  motionTrigger: motionTriggerCapability,
32204
32320
  motionZones: motionZonesCapability,
32205
32321
  nativeObjectDetection: nativeObjectDetectionCapability,
32322
+ networkLink: networkLinkCapability,
32206
32323
  notifier: notifierCapability,
32207
32324
  numericSensor: numericSensorCapability,
32208
32325
  petFeeder: petFeederCapability,
@@ -36620,6 +36737,12 @@ Object.freeze({
36620
36737
  addonId: null,
36621
36738
  access: "view"
36622
36739
  },
36740
+ "pipelineAnalytics.getSummary": {
36741
+ capName: "pipeline-analytics",
36742
+ capScope: "device",
36743
+ addonId: null,
36744
+ access: "view"
36745
+ },
36623
36746
  "pipelineAnalytics.getTrack": {
36624
36747
  capName: "pipeline-analytics",
36625
36748
  capScope: "device",
@@ -36698,6 +36821,12 @@ Object.freeze({
36698
36821
  addonId: null,
36699
36822
  access: "view"
36700
36823
  },
36824
+ "pipelineAnalytics.listSummaries": {
36825
+ capName: "pipeline-analytics",
36826
+ capScope: "device",
36827
+ addonId: null,
36828
+ access: "view"
36829
+ },
36701
36830
  "pipelineAnalytics.listTrackMedia": {
36702
36831
  capName: "pipeline-analytics",
36703
36832
  capScope: "device",
@@ -40393,6 +40522,11 @@ Object.freeze({
40393
40522
  form: "array",
40394
40523
  optional: true
40395
40524
  }],
40525
+ "pipelineAnalytics.listSummaries": [{
40526
+ name: "deviceIds",
40527
+ form: "array",
40528
+ optional: false
40529
+ }],
40396
40530
  "pipelineAnalytics.listTrackMedia": [{
40397
40531
  name: "deviceId",
40398
40532
  form: "single",
package/dist/addon.mjs CHANGED
@@ -11,7 +11,7 @@ import { networkInterfaces, tmpdir, uptime } from "node:os";
11
11
  import { finished } from "node:stream/promises";
12
12
  import { createConnection, createServer as createServer$2 } from "node:net";
13
13
  import * as dgram from "node:dgram";
14
- //#region ../types/dist/event-category-BZL-fdNj.mjs
14
+ //#region ../types/dist/event-category-zAv7pMUz.mjs
15
15
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
16
16
  EventCategory["SystemBoot"] = "system.boot";
17
17
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -383,6 +383,13 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
383
383
  */
384
384
  EventCategory["BatteryOnStatusChanged"] = "battery.onStatusChanged";
385
385
  /**
386
+ * Cap event fired by every device that registers the `network-link`
387
+ * capability. Mirrors the cap definition's `onStatusChanged`. Carries
388
+ * `{ deviceId, status: NetworkLinkStatus }` — a link switch or a signal
389
+ * reading that moved.
390
+ */
391
+ EventCategory["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
392
+ /**
386
393
  * Emitted by the battery cap provider WHEN `wakeForStream` enters the
387
394
  * "wake in progress" window — between the Baichuan wake-up issue and
388
395
  * the camera's first dialed-back RTP packet. The stream-broker
@@ -19467,6 +19474,33 @@ var RecentTracksQueryInput = object({
19467
19474
  */
19468
19475
  classes: array(string$2()).optional()
19469
19476
  });
19477
+ /**
19478
+ * A Summary (D359): the per-camera session envelope that references tracks.
19479
+ * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19480
+ * served by the event-media plane by key), null until the first frame with a
19481
+ * member visible has been materialised.
19482
+ */
19483
+ var SummarySchema = object({
19484
+ id: string$2(),
19485
+ deviceId: number(),
19486
+ openedAt: number(),
19487
+ lastActiveAt: number(),
19488
+ sealedAt: number().nullable(),
19489
+ memberCount: number().int().nonnegative(),
19490
+ groupShotKey: string$2().nullable()
19491
+ });
19492
+ var SummariesQueryInput = object({
19493
+ deviceIds: array(number()).min(1),
19494
+ since: number().optional(),
19495
+ until: number().optional(),
19496
+ limit: number().int().min(1).max(200).default(50)
19497
+ });
19498
+ var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
19499
+ var SummaryDetailSchema = object({
19500
+ summary: SummarySchema,
19501
+ /** Member track ids, in absorption order. */
19502
+ trackIds: array(string$2()).readonly()
19503
+ });
19470
19504
  var RecentTracksPageSchema = object({
19471
19505
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
19472
19506
  tracks: array(TrackSchema).readonly(),
@@ -19867,7 +19901,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19867
19901
  * timeline would read as a camera that saw nothing.
19868
19902
  */
19869
19903
  classes: array(string$2()).optional()
19870
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19904
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string$2() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19871
19905
  kind: "mutation",
19872
19906
  auth: "admin"
19873
19907
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -23800,6 +23834,88 @@ onStatusChanged: { data: object({
23800
23834
  volatileStateFields: ["lastUpdated"]
23801
23835
  };
23802
23836
  /**
23837
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
23838
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
23839
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
23840
+ * one Home Assistant projection.
23841
+ */
23842
+ var NetworkLinkStatusSchema = object({
23843
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
23844
+ type: _enum([
23845
+ "wifi",
23846
+ "ethernet",
23847
+ "cellular",
23848
+ "unknown"
23849
+ ]),
23850
+ /**
23851
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
23852
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
23853
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
23854
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
23855
+ * SKIP a null rather than coerce it.
23856
+ */
23857
+ signalPercent: number().min(0).max(100).nullable(),
23858
+ /** Raw received signal strength in dBm, when the firmware reports one. */
23859
+ rssiDbm: number().optional(),
23860
+ /** Network name of a wireless link, when the firmware reports it. */
23861
+ ssid: string$2().optional(),
23862
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
23863
+ lastUpdated: number()
23864
+ });
23865
+ var networkLinkCapability = {
23866
+ name: "network-link",
23867
+ scope: "device",
23868
+ deviceNative: true,
23869
+ mode: "singleton",
23870
+ deviceTypes: [
23871
+ DeviceType.Camera,
23872
+ DeviceType.Sensor,
23873
+ DeviceType.Button,
23874
+ DeviceType.Switch,
23875
+ DeviceType.Light,
23876
+ DeviceType.Lock,
23877
+ DeviceType.Siren
23878
+ ],
23879
+ methods: {},
23880
+ events: {
23881
+ /**
23882
+ * Emitted whenever the cached status changes (a link switch, a signal
23883
+ * reading that moved). Mirrored on the parent chain by the
23884
+ * DeviceEventPropagator like `battery.onStatusChanged`.
23885
+ */
23886
+ onStatusChanged: { data: object({
23887
+ deviceId: number(),
23888
+ status: NetworkLinkStatusSchema
23889
+ }) } },
23890
+ status: {
23891
+ schema: NetworkLinkStatusSchema,
23892
+ kind: "push",
23893
+ empty: {
23894
+ type: "unknown",
23895
+ signalPercent: null,
23896
+ lastUpdated: 0
23897
+ }
23898
+ },
23899
+ /**
23900
+ * Runtime-state slice — every provider stores the same shape under
23901
+ * `device.runtimeState['network-link']`, read once by the badge and the
23902
+ * Home Assistant projector regardless of the driver.
23903
+ */
23904
+ runtimeState: NetworkLinkStatusSchema,
23905
+ /**
23906
+ * Runtime-state durability: **restored** — a link reading is slow to
23907
+ * change and a sleeping battery camera may not report for hours; the
23908
+ * restored slice is what the badge shows until the next read.
23909
+ *
23910
+ * See `RuntimeStateDurability`. Enforced by
23911
+ * `scripts/check-runtime-state-durability.ts`.
23912
+ */
23913
+ durability: "restored",
23914
+ /** Clock fields: written, but excluded from the compare that decides
23915
+ * whether persisting is worth a SQLite commit. */
23916
+ volatileStateFields: ["lastUpdated"]
23917
+ };
23918
+ /**
23803
23919
  * Generic boolean sensor — last-resort fallback when no domain-
23804
23920
  * specific binary cap fits (Home Assistant `binary_sensor` without a
23805
23921
  * known `device_class`, or a domain we haven't typed yet). Pure
@@ -32201,6 +32317,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
32201
32317
  motionTrigger: motionTriggerCapability,
32202
32318
  motionZones: motionZonesCapability,
32203
32319
  nativeObjectDetection: nativeObjectDetectionCapability,
32320
+ networkLink: networkLinkCapability,
32204
32321
  notifier: notifierCapability,
32205
32322
  numericSensor: numericSensorCapability,
32206
32323
  petFeeder: petFeederCapability,
@@ -36618,6 +36735,12 @@ Object.freeze({
36618
36735
  addonId: null,
36619
36736
  access: "view"
36620
36737
  },
36738
+ "pipelineAnalytics.getSummary": {
36739
+ capName: "pipeline-analytics",
36740
+ capScope: "device",
36741
+ addonId: null,
36742
+ access: "view"
36743
+ },
36621
36744
  "pipelineAnalytics.getTrack": {
36622
36745
  capName: "pipeline-analytics",
36623
36746
  capScope: "device",
@@ -36696,6 +36819,12 @@ Object.freeze({
36696
36819
  addonId: null,
36697
36820
  access: "view"
36698
36821
  },
36822
+ "pipelineAnalytics.listSummaries": {
36823
+ capName: "pipeline-analytics",
36824
+ capScope: "device",
36825
+ addonId: null,
36826
+ access: "view"
36827
+ },
36699
36828
  "pipelineAnalytics.listTrackMedia": {
36700
36829
  capName: "pipeline-analytics",
36701
36830
  capScope: "device",
@@ -40391,6 +40520,11 @@ Object.freeze({
40391
40520
  form: "array",
40392
40521
  optional: true
40393
40522
  }],
40523
+ "pipelineAnalytics.listSummaries": [{
40524
+ name: "deviceIds",
40525
+ form: "array",
40526
+ optional: false
40527
+ }],
40394
40528
  "pipelineAnalytics.listTrackMedia": [{
40395
40529
  name: "deviceId",
40396
40530
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-matter-broker",
3
- "version": "0.2.67",
3
+ "version": "0.2.69",
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",