@camstack/addon-provider-amcrest 0.2.70 → 0.2.72

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
@@ -6,7 +6,7 @@ let node_crypto = require("node:crypto");
6
6
  let node_http = require("node:http");
7
7
  let node_https = require("node:https");
8
8
  let node_os = require("node:os");
9
- //#region ../types/dist/event-category-BZL-fdNj.mjs
9
+ //#region ../types/dist/event-category-zAv7pMUz.mjs
10
10
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
11
11
  EventCategory["SystemBoot"] = "system.boot";
12
12
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -378,6 +378,13 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
378
378
  */
379
379
  EventCategory["BatteryOnStatusChanged"] = "battery.onStatusChanged";
380
380
  /**
381
+ * Cap event fired by every device that registers the `network-link`
382
+ * capability. Mirrors the cap definition's `onStatusChanged`. Carries
383
+ * `{ deviceId, status: NetworkLinkStatus }` — a link switch or a signal
384
+ * reading that moved.
385
+ */
386
+ EventCategory["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
387
+ /**
381
388
  * Emitted by the battery cap provider WHEN `wakeForStream` enters the
382
389
  * "wake in progress" window — between the Baichuan wake-up issue and
383
390
  * the camera's first dialed-back RTP packet. The stream-broker
@@ -19384,6 +19391,33 @@ var RecentTracksQueryInput = object({
19384
19391
  */
19385
19392
  classes: array(string()).optional()
19386
19393
  });
19394
+ /**
19395
+ * A Summary (D359): the per-camera session envelope that references tracks.
19396
+ * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19397
+ * served by the event-media plane by key), null until the first frame with a
19398
+ * member visible has been materialised.
19399
+ */
19400
+ var SummarySchema = object({
19401
+ id: string(),
19402
+ deviceId: number(),
19403
+ openedAt: number(),
19404
+ lastActiveAt: number(),
19405
+ sealedAt: number().nullable(),
19406
+ memberCount: number().int().nonnegative(),
19407
+ groupShotKey: string().nullable()
19408
+ });
19409
+ var SummariesQueryInput = object({
19410
+ deviceIds: array(number()).min(1),
19411
+ since: number().optional(),
19412
+ until: number().optional(),
19413
+ limit: number().int().min(1).max(200).default(50)
19414
+ });
19415
+ var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
19416
+ var SummaryDetailSchema = object({
19417
+ summary: SummarySchema,
19418
+ /** Member track ids, in absorption order. */
19419
+ trackIds: array(string()).readonly()
19420
+ });
19387
19421
  var RecentTracksPageSchema = object({
19388
19422
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
19389
19423
  tracks: array(TrackSchema).readonly(),
@@ -19784,7 +19818,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19784
19818
  * timeline would read as a camera that saw nothing.
19785
19819
  */
19786
19820
  classes: array(string()).optional()
19787
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19821
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19788
19822
  kind: "mutation",
19789
19823
  auth: "admin"
19790
19824
  }), 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({
@@ -23821,6 +23855,88 @@ onStatusChanged: { data: object({
23821
23855
  volatileStateFields: ["lastUpdated"]
23822
23856
  };
23823
23857
  /**
23858
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
23859
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
23860
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
23861
+ * one Home Assistant projection.
23862
+ */
23863
+ var NetworkLinkStatusSchema = object({
23864
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
23865
+ type: _enum([
23866
+ "wifi",
23867
+ "ethernet",
23868
+ "cellular",
23869
+ "unknown"
23870
+ ]),
23871
+ /**
23872
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
23873
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
23874
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
23875
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
23876
+ * SKIP a null rather than coerce it.
23877
+ */
23878
+ signalPercent: number().min(0).max(100).nullable(),
23879
+ /** Raw received signal strength in dBm, when the firmware reports one. */
23880
+ rssiDbm: number().optional(),
23881
+ /** Network name of a wireless link, when the firmware reports it. */
23882
+ ssid: string().optional(),
23883
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
23884
+ lastUpdated: number()
23885
+ });
23886
+ var networkLinkCapability = {
23887
+ name: "network-link",
23888
+ scope: "device",
23889
+ deviceNative: true,
23890
+ mode: "singleton",
23891
+ deviceTypes: [
23892
+ DeviceType.Camera,
23893
+ DeviceType.Sensor,
23894
+ DeviceType.Button,
23895
+ DeviceType.Switch,
23896
+ DeviceType.Light,
23897
+ DeviceType.Lock,
23898
+ DeviceType.Siren
23899
+ ],
23900
+ methods: {},
23901
+ events: {
23902
+ /**
23903
+ * Emitted whenever the cached status changes (a link switch, a signal
23904
+ * reading that moved). Mirrored on the parent chain by the
23905
+ * DeviceEventPropagator like `battery.onStatusChanged`.
23906
+ */
23907
+ onStatusChanged: { data: object({
23908
+ deviceId: number(),
23909
+ status: NetworkLinkStatusSchema
23910
+ }) } },
23911
+ status: {
23912
+ schema: NetworkLinkStatusSchema,
23913
+ kind: "push",
23914
+ empty: {
23915
+ type: "unknown",
23916
+ signalPercent: null,
23917
+ lastUpdated: 0
23918
+ }
23919
+ },
23920
+ /**
23921
+ * Runtime-state slice — every provider stores the same shape under
23922
+ * `device.runtimeState['network-link']`, read once by the badge and the
23923
+ * Home Assistant projector regardless of the driver.
23924
+ */
23925
+ runtimeState: NetworkLinkStatusSchema,
23926
+ /**
23927
+ * Runtime-state durability: **restored** — a link reading is slow to
23928
+ * change and a sleeping battery camera may not report for hours; the
23929
+ * restored slice is what the badge shows until the next read.
23930
+ *
23931
+ * See `RuntimeStateDurability`. Enforced by
23932
+ * `scripts/check-runtime-state-durability.ts`.
23933
+ */
23934
+ durability: "restored",
23935
+ /** Clock fields: written, but excluded from the compare that decides
23936
+ * whether persisting is worth a SQLite commit. */
23937
+ volatileStateFields: ["lastUpdated"]
23938
+ };
23939
+ /**
23824
23940
  * Generic boolean sensor — last-resort fallback when no domain-
23825
23941
  * specific binary cap fits (Home Assistant `binary_sensor` without a
23826
23942
  * known `device_class`, or a domain we haven't typed yet). Pure
@@ -32511,6 +32627,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
32511
32627
  motionTrigger: motionTriggerCapability,
32512
32628
  motionZones: motionZonesCapability,
32513
32629
  nativeObjectDetection: nativeObjectDetectionCapability,
32630
+ networkLink: networkLinkCapability,
32514
32631
  notifier: notifierCapability,
32515
32632
  numericSensor: numericSensorCapability,
32516
32633
  petFeeder: petFeederCapability,
@@ -37134,6 +37251,12 @@ Object.freeze({
37134
37251
  addonId: null,
37135
37252
  access: "view"
37136
37253
  },
37254
+ "pipelineAnalytics.getSummary": {
37255
+ capName: "pipeline-analytics",
37256
+ capScope: "device",
37257
+ addonId: null,
37258
+ access: "view"
37259
+ },
37137
37260
  "pipelineAnalytics.getTrack": {
37138
37261
  capName: "pipeline-analytics",
37139
37262
  capScope: "device",
@@ -37212,6 +37335,12 @@ Object.freeze({
37212
37335
  addonId: null,
37213
37336
  access: "view"
37214
37337
  },
37338
+ "pipelineAnalytics.listSummaries": {
37339
+ capName: "pipeline-analytics",
37340
+ capScope: "device",
37341
+ addonId: null,
37342
+ access: "view"
37343
+ },
37215
37344
  "pipelineAnalytics.listTrackMedia": {
37216
37345
  capName: "pipeline-analytics",
37217
37346
  capScope: "device",
@@ -40907,6 +41036,11 @@ Object.freeze({
40907
41036
  form: "array",
40908
41037
  optional: true
40909
41038
  }],
41039
+ "pipelineAnalytics.listSummaries": [{
41040
+ name: "deviceIds",
41041
+ form: "array",
41042
+ optional: false
41043
+ }],
40910
41044
  "pipelineAnalytics.listTrackMedia": [{
40911
41045
  name: "deviceId",
40912
41046
  form: "single",
package/dist/addon.mjs CHANGED
@@ -7,7 +7,7 @@ import { networkInterfaces } from "node:os";
7
7
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
8
8
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
9
9
  //#endregion
10
- //#region ../types/dist/event-category-BZL-fdNj.mjs
10
+ //#region ../types/dist/event-category-zAv7pMUz.mjs
11
11
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
12
12
  EventCategory["SystemBoot"] = "system.boot";
13
13
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -379,6 +379,13 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
379
379
  */
380
380
  EventCategory["BatteryOnStatusChanged"] = "battery.onStatusChanged";
381
381
  /**
382
+ * Cap event fired by every device that registers the `network-link`
383
+ * capability. Mirrors the cap definition's `onStatusChanged`. Carries
384
+ * `{ deviceId, status: NetworkLinkStatus }` — a link switch or a signal
385
+ * reading that moved.
386
+ */
387
+ EventCategory["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
388
+ /**
382
389
  * Emitted by the battery cap provider WHEN `wakeForStream` enters the
383
390
  * "wake in progress" window — between the Baichuan wake-up issue and
384
391
  * the camera's first dialed-back RTP packet. The stream-broker
@@ -19385,6 +19392,33 @@ var RecentTracksQueryInput = object({
19385
19392
  */
19386
19393
  classes: array(string()).optional()
19387
19394
  });
19395
+ /**
19396
+ * A Summary (D359): the per-camera session envelope that references tracks.
19397
+ * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19398
+ * served by the event-media plane by key), null until the first frame with a
19399
+ * member visible has been materialised.
19400
+ */
19401
+ var SummarySchema = object({
19402
+ id: string(),
19403
+ deviceId: number(),
19404
+ openedAt: number(),
19405
+ lastActiveAt: number(),
19406
+ sealedAt: number().nullable(),
19407
+ memberCount: number().int().nonnegative(),
19408
+ groupShotKey: string().nullable()
19409
+ });
19410
+ var SummariesQueryInput = object({
19411
+ deviceIds: array(number()).min(1),
19412
+ since: number().optional(),
19413
+ until: number().optional(),
19414
+ limit: number().int().min(1).max(200).default(50)
19415
+ });
19416
+ var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
19417
+ var SummaryDetailSchema = object({
19418
+ summary: SummarySchema,
19419
+ /** Member track ids, in absorption order. */
19420
+ trackIds: array(string()).readonly()
19421
+ });
19388
19422
  var RecentTracksPageSchema = object({
19389
19423
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
19390
19424
  tracks: array(TrackSchema).readonly(),
@@ -19785,7 +19819,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19785
19819
  * timeline would read as a camera that saw nothing.
19786
19820
  */
19787
19821
  classes: array(string()).optional()
19788
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19822
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19789
19823
  kind: "mutation",
19790
19824
  auth: "admin"
19791
19825
  }), 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({
@@ -23822,6 +23856,88 @@ onStatusChanged: { data: object({
23822
23856
  volatileStateFields: ["lastUpdated"]
23823
23857
  };
23824
23858
  /**
23859
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
23860
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
23861
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
23862
+ * one Home Assistant projection.
23863
+ */
23864
+ var NetworkLinkStatusSchema = object({
23865
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
23866
+ type: _enum([
23867
+ "wifi",
23868
+ "ethernet",
23869
+ "cellular",
23870
+ "unknown"
23871
+ ]),
23872
+ /**
23873
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
23874
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
23875
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
23876
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
23877
+ * SKIP a null rather than coerce it.
23878
+ */
23879
+ signalPercent: number().min(0).max(100).nullable(),
23880
+ /** Raw received signal strength in dBm, when the firmware reports one. */
23881
+ rssiDbm: number().optional(),
23882
+ /** Network name of a wireless link, when the firmware reports it. */
23883
+ ssid: string().optional(),
23884
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
23885
+ lastUpdated: number()
23886
+ });
23887
+ var networkLinkCapability = {
23888
+ name: "network-link",
23889
+ scope: "device",
23890
+ deviceNative: true,
23891
+ mode: "singleton",
23892
+ deviceTypes: [
23893
+ DeviceType.Camera,
23894
+ DeviceType.Sensor,
23895
+ DeviceType.Button,
23896
+ DeviceType.Switch,
23897
+ DeviceType.Light,
23898
+ DeviceType.Lock,
23899
+ DeviceType.Siren
23900
+ ],
23901
+ methods: {},
23902
+ events: {
23903
+ /**
23904
+ * Emitted whenever the cached status changes (a link switch, a signal
23905
+ * reading that moved). Mirrored on the parent chain by the
23906
+ * DeviceEventPropagator like `battery.onStatusChanged`.
23907
+ */
23908
+ onStatusChanged: { data: object({
23909
+ deviceId: number(),
23910
+ status: NetworkLinkStatusSchema
23911
+ }) } },
23912
+ status: {
23913
+ schema: NetworkLinkStatusSchema,
23914
+ kind: "push",
23915
+ empty: {
23916
+ type: "unknown",
23917
+ signalPercent: null,
23918
+ lastUpdated: 0
23919
+ }
23920
+ },
23921
+ /**
23922
+ * Runtime-state slice — every provider stores the same shape under
23923
+ * `device.runtimeState['network-link']`, read once by the badge and the
23924
+ * Home Assistant projector regardless of the driver.
23925
+ */
23926
+ runtimeState: NetworkLinkStatusSchema,
23927
+ /**
23928
+ * Runtime-state durability: **restored** — a link reading is slow to
23929
+ * change and a sleeping battery camera may not report for hours; the
23930
+ * restored slice is what the badge shows until the next read.
23931
+ *
23932
+ * See `RuntimeStateDurability`. Enforced by
23933
+ * `scripts/check-runtime-state-durability.ts`.
23934
+ */
23935
+ durability: "restored",
23936
+ /** Clock fields: written, but excluded from the compare that decides
23937
+ * whether persisting is worth a SQLite commit. */
23938
+ volatileStateFields: ["lastUpdated"]
23939
+ };
23940
+ /**
23825
23941
  * Generic boolean sensor — last-resort fallback when no domain-
23826
23942
  * specific binary cap fits (Home Assistant `binary_sensor` without a
23827
23943
  * known `device_class`, or a domain we haven't typed yet). Pure
@@ -32512,6 +32628,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
32512
32628
  motionTrigger: motionTriggerCapability,
32513
32629
  motionZones: motionZonesCapability,
32514
32630
  nativeObjectDetection: nativeObjectDetectionCapability,
32631
+ networkLink: networkLinkCapability,
32515
32632
  notifier: notifierCapability,
32516
32633
  numericSensor: numericSensorCapability,
32517
32634
  petFeeder: petFeederCapability,
@@ -37135,6 +37252,12 @@ Object.freeze({
37135
37252
  addonId: null,
37136
37253
  access: "view"
37137
37254
  },
37255
+ "pipelineAnalytics.getSummary": {
37256
+ capName: "pipeline-analytics",
37257
+ capScope: "device",
37258
+ addonId: null,
37259
+ access: "view"
37260
+ },
37138
37261
  "pipelineAnalytics.getTrack": {
37139
37262
  capName: "pipeline-analytics",
37140
37263
  capScope: "device",
@@ -37213,6 +37336,12 @@ Object.freeze({
37213
37336
  addonId: null,
37214
37337
  access: "view"
37215
37338
  },
37339
+ "pipelineAnalytics.listSummaries": {
37340
+ capName: "pipeline-analytics",
37341
+ capScope: "device",
37342
+ addonId: null,
37343
+ access: "view"
37344
+ },
37216
37345
  "pipelineAnalytics.listTrackMedia": {
37217
37346
  capName: "pipeline-analytics",
37218
37347
  capScope: "device",
@@ -40908,6 +41037,11 @@ Object.freeze({
40908
41037
  form: "array",
40909
41038
  optional: true
40910
41039
  }],
41040
+ "pipelineAnalytics.listSummaries": [{
41041
+ name: "deviceIds",
41042
+ form: "array",
41043
+ optional: false
41044
+ }],
40911
41045
  "pipelineAnalytics.listTrackMedia": [{
40912
41046
  name: "deviceId",
40913
41047
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-amcrest",
3
- "version": "0.2.70",
3
+ "version": "0.2.72",
4
4
  "description": "Amcrest/Dahua camera device provider addon for CamStack — Dahua CGI over HTTP(S) with digest auth (snapshot, RTSP catalog, PTZ, image/day-night config)",
5
5
  "keywords": [
6
6
  "camstack",