@camstack/addon-provider-tuya 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
@@ -819,7 +819,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
819
819
  return [...byId.values()];
820
820
  }
821
821
  //#endregion
822
- //#region ../types/dist/event-category-BZL-fdNj.mjs
822
+ //#region ../types/dist/event-category-zAv7pMUz.mjs
823
823
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
824
824
  EventCategory["SystemBoot"] = "system.boot";
825
825
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1191,6 +1191,13 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1191
1191
  */
1192
1192
  EventCategory["BatteryOnStatusChanged"] = "battery.onStatusChanged";
1193
1193
  /**
1194
+ * Cap event fired by every device that registers the `network-link`
1195
+ * capability. Mirrors the cap definition's `onStatusChanged`. Carries
1196
+ * `{ deviceId, status: NetworkLinkStatus }` — a link switch or a signal
1197
+ * reading that moved.
1198
+ */
1199
+ EventCategory["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
1200
+ /**
1194
1201
  * Emitted by the battery cap provider WHEN `wakeForStream` enters the
1195
1202
  * "wake in progress" window — between the Baichuan wake-up issue and
1196
1203
  * the camera's first dialed-back RTP packet. The stream-broker
@@ -20226,6 +20233,33 @@ var RecentTracksQueryInput = object({
20226
20233
  */
20227
20234
  classes: array(string()).optional()
20228
20235
  });
20236
+ /**
20237
+ * A Summary (D359): the per-camera session envelope that references tracks.
20238
+ * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
20239
+ * served by the event-media plane by key), null until the first frame with a
20240
+ * member visible has been materialised.
20241
+ */
20242
+ var SummarySchema = object({
20243
+ id: string(),
20244
+ deviceId: number(),
20245
+ openedAt: number(),
20246
+ lastActiveAt: number(),
20247
+ sealedAt: number().nullable(),
20248
+ memberCount: number().int().nonnegative(),
20249
+ groupShotKey: string().nullable()
20250
+ });
20251
+ var SummariesQueryInput = object({
20252
+ deviceIds: array(number()).min(1),
20253
+ since: number().optional(),
20254
+ until: number().optional(),
20255
+ limit: number().int().min(1).max(200).default(50)
20256
+ });
20257
+ var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
20258
+ var SummaryDetailSchema = object({
20259
+ summary: SummarySchema,
20260
+ /** Member track ids, in absorption order. */
20261
+ trackIds: array(string()).readonly()
20262
+ });
20229
20263
  var RecentTracksPageSchema = object({
20230
20264
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
20231
20265
  tracks: array(TrackSchema).readonly(),
@@ -20626,7 +20660,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20626
20660
  * timeline would read as a camera that saw nothing.
20627
20661
  */
20628
20662
  classes: array(string()).optional()
20629
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
20663
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20630
20664
  kind: "mutation",
20631
20665
  auth: "admin"
20632
20666
  }), 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({
@@ -24559,6 +24593,88 @@ onStatusChanged: { data: object({
24559
24593
  volatileStateFields: ["lastUpdated"]
24560
24594
  };
24561
24595
  /**
24596
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
24597
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
24598
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
24599
+ * one Home Assistant projection.
24600
+ */
24601
+ var NetworkLinkStatusSchema = object({
24602
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
24603
+ type: _enum([
24604
+ "wifi",
24605
+ "ethernet",
24606
+ "cellular",
24607
+ "unknown"
24608
+ ]),
24609
+ /**
24610
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
24611
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
24612
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
24613
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
24614
+ * SKIP a null rather than coerce it.
24615
+ */
24616
+ signalPercent: number().min(0).max(100).nullable(),
24617
+ /** Raw received signal strength in dBm, when the firmware reports one. */
24618
+ rssiDbm: number().optional(),
24619
+ /** Network name of a wireless link, when the firmware reports it. */
24620
+ ssid: string().optional(),
24621
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
24622
+ lastUpdated: number()
24623
+ });
24624
+ var networkLinkCapability = {
24625
+ name: "network-link",
24626
+ scope: "device",
24627
+ deviceNative: true,
24628
+ mode: "singleton",
24629
+ deviceTypes: [
24630
+ DeviceType.Camera,
24631
+ DeviceType.Sensor,
24632
+ DeviceType.Button,
24633
+ DeviceType.Switch,
24634
+ DeviceType.Light,
24635
+ DeviceType.Lock,
24636
+ DeviceType.Siren
24637
+ ],
24638
+ methods: {},
24639
+ events: {
24640
+ /**
24641
+ * Emitted whenever the cached status changes (a link switch, a signal
24642
+ * reading that moved). Mirrored on the parent chain by the
24643
+ * DeviceEventPropagator like `battery.onStatusChanged`.
24644
+ */
24645
+ onStatusChanged: { data: object({
24646
+ deviceId: number(),
24647
+ status: NetworkLinkStatusSchema
24648
+ }) } },
24649
+ status: {
24650
+ schema: NetworkLinkStatusSchema,
24651
+ kind: "push",
24652
+ empty: {
24653
+ type: "unknown",
24654
+ signalPercent: null,
24655
+ lastUpdated: 0
24656
+ }
24657
+ },
24658
+ /**
24659
+ * Runtime-state slice — every provider stores the same shape under
24660
+ * `device.runtimeState['network-link']`, read once by the badge and the
24661
+ * Home Assistant projector regardless of the driver.
24662
+ */
24663
+ runtimeState: NetworkLinkStatusSchema,
24664
+ /**
24665
+ * Runtime-state durability: **restored** — a link reading is slow to
24666
+ * change and a sleeping battery camera may not report for hours; the
24667
+ * restored slice is what the badge shows until the next read.
24668
+ *
24669
+ * See `RuntimeStateDurability`. Enforced by
24670
+ * `scripts/check-runtime-state-durability.ts`.
24671
+ */
24672
+ durability: "restored",
24673
+ /** Clock fields: written, but excluded from the compare that decides
24674
+ * whether persisting is worth a SQLite commit. */
24675
+ volatileStateFields: ["lastUpdated"]
24676
+ };
24677
+ /**
24562
24678
  * Generic boolean sensor — last-resort fallback when no domain-
24563
24679
  * specific binary cap fits (Home Assistant `binary_sensor` without a
24564
24680
  * known `device_class`, or a domain we haven't typed yet). Pure
@@ -32951,6 +33067,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
32951
33067
  motionTrigger: motionTriggerCapability,
32952
33068
  motionZones: motionZonesCapability,
32953
33069
  nativeObjectDetection: nativeObjectDetectionCapability,
33070
+ networkLink: networkLinkCapability,
32954
33071
  notifier: notifierCapability,
32955
33072
  numericSensor: numericSensorCapability,
32956
33073
  petFeeder: petFeederCapability,
@@ -37368,6 +37485,12 @@ Object.freeze({
37368
37485
  addonId: null,
37369
37486
  access: "view"
37370
37487
  },
37488
+ "pipelineAnalytics.getSummary": {
37489
+ capName: "pipeline-analytics",
37490
+ capScope: "device",
37491
+ addonId: null,
37492
+ access: "view"
37493
+ },
37371
37494
  "pipelineAnalytics.getTrack": {
37372
37495
  capName: "pipeline-analytics",
37373
37496
  capScope: "device",
@@ -37446,6 +37569,12 @@ Object.freeze({
37446
37569
  addonId: null,
37447
37570
  access: "view"
37448
37571
  },
37572
+ "pipelineAnalytics.listSummaries": {
37573
+ capName: "pipeline-analytics",
37574
+ capScope: "device",
37575
+ addonId: null,
37576
+ access: "view"
37577
+ },
37449
37578
  "pipelineAnalytics.listTrackMedia": {
37450
37579
  capName: "pipeline-analytics",
37451
37580
  capScope: "device",
@@ -41141,6 +41270,11 @@ Object.freeze({
41141
41270
  form: "array",
41142
41271
  optional: true
41143
41272
  }],
41273
+ "pipelineAnalytics.listSummaries": [{
41274
+ name: "deviceIds",
41275
+ form: "array",
41276
+ optional: false
41277
+ }],
41144
41278
  "pipelineAnalytics.listTrackMedia": [{
41145
41279
  name: "deviceId",
41146
41280
  form: "single",
package/dist/addon.mjs CHANGED
@@ -818,7 +818,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
818
818
  return [...byId.values()];
819
819
  }
820
820
  //#endregion
821
- //#region ../types/dist/event-category-BZL-fdNj.mjs
821
+ //#region ../types/dist/event-category-zAv7pMUz.mjs
822
822
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
823
823
  EventCategory["SystemBoot"] = "system.boot";
824
824
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1190,6 +1190,13 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1190
1190
  */
1191
1191
  EventCategory["BatteryOnStatusChanged"] = "battery.onStatusChanged";
1192
1192
  /**
1193
+ * Cap event fired by every device that registers the `network-link`
1194
+ * capability. Mirrors the cap definition's `onStatusChanged`. Carries
1195
+ * `{ deviceId, status: NetworkLinkStatus }` — a link switch or a signal
1196
+ * reading that moved.
1197
+ */
1198
+ EventCategory["NetworkLinkOnStatusChanged"] = "network-link.onStatusChanged";
1199
+ /**
1193
1200
  * Emitted by the battery cap provider WHEN `wakeForStream` enters the
1194
1201
  * "wake in progress" window — between the Baichuan wake-up issue and
1195
1202
  * the camera's first dialed-back RTP packet. The stream-broker
@@ -20225,6 +20232,33 @@ var RecentTracksQueryInput = object({
20225
20232
  */
20226
20233
  classes: array(string()).optional()
20227
20234
  });
20235
+ /**
20236
+ * A Summary (D359): the per-camera session envelope that references tracks.
20237
+ * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
20238
+ * served by the event-media plane by key), null until the first frame with a
20239
+ * member visible has been materialised.
20240
+ */
20241
+ var SummarySchema = object({
20242
+ id: string(),
20243
+ deviceId: number(),
20244
+ openedAt: number(),
20245
+ lastActiveAt: number(),
20246
+ sealedAt: number().nullable(),
20247
+ memberCount: number().int().nonnegative(),
20248
+ groupShotKey: string().nullable()
20249
+ });
20250
+ var SummariesQueryInput = object({
20251
+ deviceIds: array(number()).min(1),
20252
+ since: number().optional(),
20253
+ until: number().optional(),
20254
+ limit: number().int().min(1).max(200).default(50)
20255
+ });
20256
+ var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
20257
+ var SummaryDetailSchema = object({
20258
+ summary: SummarySchema,
20259
+ /** Member track ids, in absorption order. */
20260
+ trackIds: array(string()).readonly()
20261
+ });
20228
20262
  var RecentTracksPageSchema = object({
20229
20263
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
20230
20264
  tracks: array(TrackSchema).readonly(),
@@ -20625,7 +20659,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20625
20659
  * timeline would read as a camera that saw nothing.
20626
20660
  */
20627
20661
  classes: array(string()).optional()
20628
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
20662
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20629
20663
  kind: "mutation",
20630
20664
  auth: "admin"
20631
20665
  }), 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({
@@ -24558,6 +24592,88 @@ onStatusChanged: { data: object({
24558
24592
  volatileStateFields: ["lastUpdated"]
24559
24593
  };
24560
24594
  /**
24595
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
24596
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
24597
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
24598
+ * one Home Assistant projection.
24599
+ */
24600
+ var NetworkLinkStatusSchema = object({
24601
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
24602
+ type: _enum([
24603
+ "wifi",
24604
+ "ethernet",
24605
+ "cellular",
24606
+ "unknown"
24607
+ ]),
24608
+ /**
24609
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
24610
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
24611
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
24612
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
24613
+ * SKIP a null rather than coerce it.
24614
+ */
24615
+ signalPercent: number().min(0).max(100).nullable(),
24616
+ /** Raw received signal strength in dBm, when the firmware reports one. */
24617
+ rssiDbm: number().optional(),
24618
+ /** Network name of a wireless link, when the firmware reports it. */
24619
+ ssid: string().optional(),
24620
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
24621
+ lastUpdated: number()
24622
+ });
24623
+ var networkLinkCapability = {
24624
+ name: "network-link",
24625
+ scope: "device",
24626
+ deviceNative: true,
24627
+ mode: "singleton",
24628
+ deviceTypes: [
24629
+ DeviceType.Camera,
24630
+ DeviceType.Sensor,
24631
+ DeviceType.Button,
24632
+ DeviceType.Switch,
24633
+ DeviceType.Light,
24634
+ DeviceType.Lock,
24635
+ DeviceType.Siren
24636
+ ],
24637
+ methods: {},
24638
+ events: {
24639
+ /**
24640
+ * Emitted whenever the cached status changes (a link switch, a signal
24641
+ * reading that moved). Mirrored on the parent chain by the
24642
+ * DeviceEventPropagator like `battery.onStatusChanged`.
24643
+ */
24644
+ onStatusChanged: { data: object({
24645
+ deviceId: number(),
24646
+ status: NetworkLinkStatusSchema
24647
+ }) } },
24648
+ status: {
24649
+ schema: NetworkLinkStatusSchema,
24650
+ kind: "push",
24651
+ empty: {
24652
+ type: "unknown",
24653
+ signalPercent: null,
24654
+ lastUpdated: 0
24655
+ }
24656
+ },
24657
+ /**
24658
+ * Runtime-state slice — every provider stores the same shape under
24659
+ * `device.runtimeState['network-link']`, read once by the badge and the
24660
+ * Home Assistant projector regardless of the driver.
24661
+ */
24662
+ runtimeState: NetworkLinkStatusSchema,
24663
+ /**
24664
+ * Runtime-state durability: **restored** — a link reading is slow to
24665
+ * change and a sleeping battery camera may not report for hours; the
24666
+ * restored slice is what the badge shows until the next read.
24667
+ *
24668
+ * See `RuntimeStateDurability`. Enforced by
24669
+ * `scripts/check-runtime-state-durability.ts`.
24670
+ */
24671
+ durability: "restored",
24672
+ /** Clock fields: written, but excluded from the compare that decides
24673
+ * whether persisting is worth a SQLite commit. */
24674
+ volatileStateFields: ["lastUpdated"]
24675
+ };
24676
+ /**
24561
24677
  * Generic boolean sensor — last-resort fallback when no domain-
24562
24678
  * specific binary cap fits (Home Assistant `binary_sensor` without a
24563
24679
  * known `device_class`, or a domain we haven't typed yet). Pure
@@ -32950,6 +33066,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
32950
33066
  motionTrigger: motionTriggerCapability,
32951
33067
  motionZones: motionZonesCapability,
32952
33068
  nativeObjectDetection: nativeObjectDetectionCapability,
33069
+ networkLink: networkLinkCapability,
32953
33070
  notifier: notifierCapability,
32954
33071
  numericSensor: numericSensorCapability,
32955
33072
  petFeeder: petFeederCapability,
@@ -37367,6 +37484,12 @@ Object.freeze({
37367
37484
  addonId: null,
37368
37485
  access: "view"
37369
37486
  },
37487
+ "pipelineAnalytics.getSummary": {
37488
+ capName: "pipeline-analytics",
37489
+ capScope: "device",
37490
+ addonId: null,
37491
+ access: "view"
37492
+ },
37370
37493
  "pipelineAnalytics.getTrack": {
37371
37494
  capName: "pipeline-analytics",
37372
37495
  capScope: "device",
@@ -37445,6 +37568,12 @@ Object.freeze({
37445
37568
  addonId: null,
37446
37569
  access: "view"
37447
37570
  },
37571
+ "pipelineAnalytics.listSummaries": {
37572
+ capName: "pipeline-analytics",
37573
+ capScope: "device",
37574
+ addonId: null,
37575
+ access: "view"
37576
+ },
37448
37577
  "pipelineAnalytics.listTrackMedia": {
37449
37578
  capName: "pipeline-analytics",
37450
37579
  capScope: "device",
@@ -41140,6 +41269,11 @@ Object.freeze({
41140
41269
  form: "array",
41141
41270
  optional: true
41142
41271
  }],
41272
+ "pipelineAnalytics.listSummaries": [{
41273
+ name: "deviceIds",
41274
+ form: "array",
41275
+ optional: false
41276
+ }],
41143
41277
  "pipelineAnalytics.listTrackMedia": [{
41144
41278
  name: "deviceId",
41145
41279
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-tuya",
3
- "version": "0.2.68",
3
+ "version": "0.2.70",
4
4
  "description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
5
5
  "keywords": [
6
6
  "camstack",