@camstack/addon-provider-homematic 1.1.25 → 1.1.26

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
@@ -7367,6 +7367,62 @@ var RecordingConfigSchema = object({
7367
7367
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7368
7368
  });
7369
7369
  /**
7370
+ * Ops-log — the durable, append-only operations audit shared by the
7371
+ * recordings and events management surfaces.
7372
+ *
7373
+ * ONE row shape is reused for both domains so a single "Activity" view can
7374
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7375
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7376
+ * management operation, WHY it ran (reason), and its measurable effect
7377
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7378
+ * never fail the operation it records.
7379
+ */
7380
+ /** Which management domain the operation belongs to. */
7381
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7382
+ /** The kind of management operation performed. */
7383
+ var OpsLogOpSchema = _enum([
7384
+ "prune",
7385
+ "manual-delete",
7386
+ "rescan",
7387
+ "retention-run"
7388
+ ]);
7389
+ /** Why the operation ran. */
7390
+ var OpsLogReasonSchema = _enum([
7391
+ "retention",
7392
+ "quota",
7393
+ "manual",
7394
+ "operator"
7395
+ ]);
7396
+ /** One audit row, shared verbatim by both domains. */
7397
+ var OpsLogEntrySchema = object({
7398
+ /** Unique row id. */
7399
+ id: string(),
7400
+ /** Epoch ms the operation completed. */
7401
+ at: number(),
7402
+ domain: OpsLogDomainSchema,
7403
+ op: OpsLogOpSchema,
7404
+ reason: OpsLogReasonSchema,
7405
+ /** The camera the op targeted; null for a cluster/global op. */
7406
+ deviceId: number().nullable(),
7407
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7408
+ nodeId: string(),
7409
+ /** Buckets / rows deleted (op-specific unit). */
7410
+ itemsAffected: number(),
7411
+ /** Bytes reclaimed by the op (0 when not measurable). */
7412
+ bytesReclaimed: number(),
7413
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7414
+ detail: string().nullable(),
7415
+ /** Who/what triggered the op. */
7416
+ actor: string()
7417
+ });
7418
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7419
+ var OpsLogQueryInputSchema = object({
7420
+ /** Restrict to a single camera; omit for every row. */
7421
+ deviceId: number().optional(),
7422
+ /** Max rows returned, newest-first. */
7423
+ limit: number().int().min(1).max(1e3).optional()
7424
+ });
7425
+ /**
7370
7426
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7371
7427
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7372
7428
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14830,9 +14886,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14830
14886
  * `package` backs the package-drop detector — a package zone is a
14831
14887
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14832
14888
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14833
- * The orchestrator provider that writes this stage lands in a later
14834
- * slice; until then the mirror carries only `{motion, detection}` and
14835
- * consumers read `package` as absent (treat as `[]`).
14889
+ * The orchestrator provider writes this stage as a first-class slice
14890
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14891
+ * package}` shape, so consumers read the current package rules directly
14892
+ * off `device.state.zoneRules.value.package`.
14836
14893
  */
14837
14894
  runtimeState: object({
14838
14895
  motion: array(ZoneRuleSchema).readonly(),
@@ -19215,6 +19272,26 @@ var TrackCascadeCountsSchema = object({
19215
19272
  /** Per-track CLIP search vectors removed (best-effort). */
19216
19273
  embeddings: number().int()
19217
19274
  });
19275
+ /** Event-store footprint for one camera. */
19276
+ var EventStoreDeviceFootprintSchema = object({
19277
+ deviceId: number(),
19278
+ /** Persisted event rows (motion + object + audio) for the camera. */
19279
+ rows: number().int(),
19280
+ /** Event-owned media bytes on disk for the camera. */
19281
+ bytes: number().int()
19282
+ });
19283
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19284
+ var EventStoreFootprintSchema = object({
19285
+ totalRows: number().int(),
19286
+ totalBytes: number().int(),
19287
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19288
+ });
19289
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19290
+ var EventPruneCountsSchema = object({
19291
+ motion: number().int(),
19292
+ object: number().int(),
19293
+ audio: number().int()
19294
+ });
19218
19295
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19219
19296
  deviceId: number(),
19220
19297
  trackId: string()
@@ -19278,6 +19355,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19278
19355
  }), {
19279
19356
  kind: "mutation",
19280
19357
  auth: "admin"
19358
+ }), method(object({}), EventStoreFootprintSchema, {
19359
+ kind: "query",
19360
+ auth: "admin"
19361
+ }), method(object({
19362
+ olderThanMs: number(),
19363
+ reason: OpsLogReasonSchema.optional()
19364
+ }), EventPruneCountsSchema, {
19365
+ kind: "mutation",
19366
+ auth: "admin"
19367
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19368
+ kind: "mutation",
19369
+ auth: "admin"
19370
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19371
+ kind: "query",
19372
+ auth: "admin"
19281
19373
  }), method(object({
19282
19374
  eventId: string(),
19283
19375
  kind: MediaFileKindEnum.optional()
@@ -22511,13 +22603,29 @@ method(object({
22511
22603
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22512
22604
  kind: "mutation",
22513
22605
  auth: "admin"
22514
- }), method(object({ deviceId: number() }), object({
22606
+ }), method(object({
22607
+ deviceId: number(),
22608
+ reason: OpsLogReasonSchema.optional()
22609
+ }), object({
22515
22610
  floorMs: number().nullable(),
22516
22611
  deletedBuckets: number().int(),
22517
22612
  reclaimedBytes: number().int()
22518
22613
  }), {
22519
22614
  kind: "mutation",
22520
22615
  auth: "admin"
22616
+ }), method(object({
22617
+ deviceId: number(),
22618
+ fromMs: number().optional(),
22619
+ toMs: number().optional()
22620
+ }), object({
22621
+ deletedBuckets: number().int(),
22622
+ reclaimedBytes: number().int()
22623
+ }), {
22624
+ kind: "mutation",
22625
+ auth: "admin"
22626
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22627
+ kind: "query",
22628
+ auth: "admin"
22521
22629
  });
22522
22630
  /**
22523
22631
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25639,6 +25747,12 @@ Object.freeze({
25639
25747
  addonId: null,
25640
25748
  access: "delete"
25641
25749
  },
25750
+ "pipelineAnalytics.deleteDeviceEvents": {
25751
+ capName: "pipeline-analytics",
25752
+ capScope: "device",
25753
+ addonId: null,
25754
+ access: "delete"
25755
+ },
25642
25756
  "pipelineAnalytics.deleteTracks": {
25643
25757
  capName: "pipeline-analytics",
25644
25758
  capScope: "device",
@@ -25669,6 +25783,12 @@ Object.freeze({
25669
25783
  addonId: null,
25670
25784
  access: "view"
25671
25785
  },
25786
+ "pipelineAnalytics.getEventStoreFootprint": {
25787
+ capName: "pipeline-analytics",
25788
+ capScope: "device",
25789
+ addonId: null,
25790
+ access: "view"
25791
+ },
25672
25792
  "pipelineAnalytics.getKeyEvents": {
25673
25793
  capName: "pipeline-analytics",
25674
25794
  capScope: "device",
@@ -25711,6 +25831,12 @@ Object.freeze({
25711
25831
  addonId: null,
25712
25832
  access: "view"
25713
25833
  },
25834
+ "pipelineAnalytics.listOpsLog": {
25835
+ capName: "pipeline-analytics",
25836
+ capScope: "device",
25837
+ addonId: null,
25838
+ access: "view"
25839
+ },
25714
25840
  "pipelineAnalytics.listRecentTracks": {
25715
25841
  capName: "pipeline-analytics",
25716
25842
  capScope: "device",
@@ -25723,6 +25849,12 @@ Object.freeze({
25723
25849
  addonId: null,
25724
25850
  access: "view"
25725
25851
  },
25852
+ "pipelineAnalytics.pruneEvents": {
25853
+ capName: "pipeline-analytics",
25854
+ capScope: "device",
25855
+ addonId: null,
25856
+ access: "create"
25857
+ },
25726
25858
  "pipelineAnalytics.pruneEventsBefore": {
25727
25859
  capName: "pipeline-analytics",
25728
25860
  capScope: "device",
@@ -26485,6 +26617,12 @@ Object.freeze({
26485
26617
  addonId: null,
26486
26618
  access: "create"
26487
26619
  },
26620
+ "recording.deleteFootprint": {
26621
+ capName: "recording",
26622
+ capScope: "system",
26623
+ addonId: null,
26624
+ access: "delete"
26625
+ },
26488
26626
  "recording.getAvailability": {
26489
26627
  capName: "recording",
26490
26628
  capScope: "system",
@@ -26515,6 +26653,12 @@ Object.freeze({
26515
26653
  addonId: null,
26516
26654
  access: "view"
26517
26655
  },
26656
+ "recording.listOpsLog": {
26657
+ capName: "recording",
26658
+ capScope: "system",
26659
+ addonId: null,
26660
+ access: "view"
26661
+ },
26518
26662
  "recording.locateSegment": {
26519
26663
  capName: "recording",
26520
26664
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -7368,6 +7368,62 @@ var RecordingConfigSchema = object({
7368
7368
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7369
7369
  });
7370
7370
  /**
7371
+ * Ops-log — the durable, append-only operations audit shared by the
7372
+ * recordings and events management surfaces.
7373
+ *
7374
+ * ONE row shape is reused for both domains so a single "Activity" view can
7375
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7376
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7377
+ * management operation, WHY it ran (reason), and its measurable effect
7378
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7379
+ * never fail the operation it records.
7380
+ */
7381
+ /** Which management domain the operation belongs to. */
7382
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7383
+ /** The kind of management operation performed. */
7384
+ var OpsLogOpSchema = _enum([
7385
+ "prune",
7386
+ "manual-delete",
7387
+ "rescan",
7388
+ "retention-run"
7389
+ ]);
7390
+ /** Why the operation ran. */
7391
+ var OpsLogReasonSchema = _enum([
7392
+ "retention",
7393
+ "quota",
7394
+ "manual",
7395
+ "operator"
7396
+ ]);
7397
+ /** One audit row, shared verbatim by both domains. */
7398
+ var OpsLogEntrySchema = object({
7399
+ /** Unique row id. */
7400
+ id: string(),
7401
+ /** Epoch ms the operation completed. */
7402
+ at: number(),
7403
+ domain: OpsLogDomainSchema,
7404
+ op: OpsLogOpSchema,
7405
+ reason: OpsLogReasonSchema,
7406
+ /** The camera the op targeted; null for a cluster/global op. */
7407
+ deviceId: number().nullable(),
7408
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7409
+ nodeId: string(),
7410
+ /** Buckets / rows deleted (op-specific unit). */
7411
+ itemsAffected: number(),
7412
+ /** Bytes reclaimed by the op (0 when not measurable). */
7413
+ bytesReclaimed: number(),
7414
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7415
+ detail: string().nullable(),
7416
+ /** Who/what triggered the op. */
7417
+ actor: string()
7418
+ });
7419
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7420
+ var OpsLogQueryInputSchema = object({
7421
+ /** Restrict to a single camera; omit for every row. */
7422
+ deviceId: number().optional(),
7423
+ /** Max rows returned, newest-first. */
7424
+ limit: number().int().min(1).max(1e3).optional()
7425
+ });
7426
+ /**
7371
7427
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7372
7428
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7373
7429
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14831,9 +14887,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14831
14887
  * `package` backs the package-drop detector — a package zone is a
14832
14888
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14833
14889
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14834
- * The orchestrator provider that writes this stage lands in a later
14835
- * slice; until then the mirror carries only `{motion, detection}` and
14836
- * consumers read `package` as absent (treat as `[]`).
14890
+ * The orchestrator provider writes this stage as a first-class slice
14891
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14892
+ * package}` shape, so consumers read the current package rules directly
14893
+ * off `device.state.zoneRules.value.package`.
14837
14894
  */
14838
14895
  runtimeState: object({
14839
14896
  motion: array(ZoneRuleSchema).readonly(),
@@ -19216,6 +19273,26 @@ var TrackCascadeCountsSchema = object({
19216
19273
  /** Per-track CLIP search vectors removed (best-effort). */
19217
19274
  embeddings: number().int()
19218
19275
  });
19276
+ /** Event-store footprint for one camera. */
19277
+ var EventStoreDeviceFootprintSchema = object({
19278
+ deviceId: number(),
19279
+ /** Persisted event rows (motion + object + audio) for the camera. */
19280
+ rows: number().int(),
19281
+ /** Event-owned media bytes on disk for the camera. */
19282
+ bytes: number().int()
19283
+ });
19284
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19285
+ var EventStoreFootprintSchema = object({
19286
+ totalRows: number().int(),
19287
+ totalBytes: number().int(),
19288
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19289
+ });
19290
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19291
+ var EventPruneCountsSchema = object({
19292
+ motion: number().int(),
19293
+ object: number().int(),
19294
+ audio: number().int()
19295
+ });
19219
19296
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19220
19297
  deviceId: number(),
19221
19298
  trackId: string()
@@ -19279,6 +19356,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19279
19356
  }), {
19280
19357
  kind: "mutation",
19281
19358
  auth: "admin"
19359
+ }), method(object({}), EventStoreFootprintSchema, {
19360
+ kind: "query",
19361
+ auth: "admin"
19362
+ }), method(object({
19363
+ olderThanMs: number(),
19364
+ reason: OpsLogReasonSchema.optional()
19365
+ }), EventPruneCountsSchema, {
19366
+ kind: "mutation",
19367
+ auth: "admin"
19368
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19369
+ kind: "mutation",
19370
+ auth: "admin"
19371
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19372
+ kind: "query",
19373
+ auth: "admin"
19282
19374
  }), method(object({
19283
19375
  eventId: string(),
19284
19376
  kind: MediaFileKindEnum.optional()
@@ -22512,13 +22604,29 @@ method(object({
22512
22604
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22513
22605
  kind: "mutation",
22514
22606
  auth: "admin"
22515
- }), method(object({ deviceId: number() }), object({
22607
+ }), method(object({
22608
+ deviceId: number(),
22609
+ reason: OpsLogReasonSchema.optional()
22610
+ }), object({
22516
22611
  floorMs: number().nullable(),
22517
22612
  deletedBuckets: number().int(),
22518
22613
  reclaimedBytes: number().int()
22519
22614
  }), {
22520
22615
  kind: "mutation",
22521
22616
  auth: "admin"
22617
+ }), method(object({
22618
+ deviceId: number(),
22619
+ fromMs: number().optional(),
22620
+ toMs: number().optional()
22621
+ }), object({
22622
+ deletedBuckets: number().int(),
22623
+ reclaimedBytes: number().int()
22624
+ }), {
22625
+ kind: "mutation",
22626
+ auth: "admin"
22627
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22628
+ kind: "query",
22629
+ auth: "admin"
22522
22630
  });
22523
22631
  /**
22524
22632
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25640,6 +25748,12 @@ Object.freeze({
25640
25748
  addonId: null,
25641
25749
  access: "delete"
25642
25750
  },
25751
+ "pipelineAnalytics.deleteDeviceEvents": {
25752
+ capName: "pipeline-analytics",
25753
+ capScope: "device",
25754
+ addonId: null,
25755
+ access: "delete"
25756
+ },
25643
25757
  "pipelineAnalytics.deleteTracks": {
25644
25758
  capName: "pipeline-analytics",
25645
25759
  capScope: "device",
@@ -25670,6 +25784,12 @@ Object.freeze({
25670
25784
  addonId: null,
25671
25785
  access: "view"
25672
25786
  },
25787
+ "pipelineAnalytics.getEventStoreFootprint": {
25788
+ capName: "pipeline-analytics",
25789
+ capScope: "device",
25790
+ addonId: null,
25791
+ access: "view"
25792
+ },
25673
25793
  "pipelineAnalytics.getKeyEvents": {
25674
25794
  capName: "pipeline-analytics",
25675
25795
  capScope: "device",
@@ -25712,6 +25832,12 @@ Object.freeze({
25712
25832
  addonId: null,
25713
25833
  access: "view"
25714
25834
  },
25835
+ "pipelineAnalytics.listOpsLog": {
25836
+ capName: "pipeline-analytics",
25837
+ capScope: "device",
25838
+ addonId: null,
25839
+ access: "view"
25840
+ },
25715
25841
  "pipelineAnalytics.listRecentTracks": {
25716
25842
  capName: "pipeline-analytics",
25717
25843
  capScope: "device",
@@ -25724,6 +25850,12 @@ Object.freeze({
25724
25850
  addonId: null,
25725
25851
  access: "view"
25726
25852
  },
25853
+ "pipelineAnalytics.pruneEvents": {
25854
+ capName: "pipeline-analytics",
25855
+ capScope: "device",
25856
+ addonId: null,
25857
+ access: "create"
25858
+ },
25727
25859
  "pipelineAnalytics.pruneEventsBefore": {
25728
25860
  capName: "pipeline-analytics",
25729
25861
  capScope: "device",
@@ -26486,6 +26618,12 @@ Object.freeze({
26486
26618
  addonId: null,
26487
26619
  access: "create"
26488
26620
  },
26621
+ "recording.deleteFootprint": {
26622
+ capName: "recording",
26623
+ capScope: "system",
26624
+ addonId: null,
26625
+ access: "delete"
26626
+ },
26489
26627
  "recording.getAvailability": {
26490
26628
  capName: "recording",
26491
26629
  capScope: "system",
@@ -26516,6 +26654,12 @@ Object.freeze({
26516
26654
  addonId: null,
26517
26655
  access: "view"
26518
26656
  },
26657
+ "recording.listOpsLog": {
26658
+ capName: "recording",
26659
+ capScope: "system",
26660
+ addonId: null,
26661
+ access: "view"
26662
+ },
26519
26663
  "recording.locateSegment": {
26520
26664
  capName: "recording",
26521
26665
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.1.25",
3
+ "version": "1.1.26",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",