@camstack/addon-provider-homematic 1.2.50 → 1.2.51

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.
Files changed (3) hide show
  1. package/dist/addon.js +234 -73
  2. package/dist/addon.mjs +234 -73
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8105,6 +8105,13 @@ var MediaRelocateModeSchema = _enum([
8105
8105
  ]);
8106
8106
  var RelocateMediaInputSchema = object({
8107
8107
  toLocationId: string(),
8108
+ /**
8109
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8110
+ * every row that is not already on `toLocationId` (the historical
8111
+ * behaviour). A named source is what a from→to migration needs: without it
8112
+ * "move events off disk 2" also emptied disk 1.
8113
+ */
8114
+ fromLocationId: string().optional(),
8108
8115
  throttleMbps: number().min(1).max(1e3).optional(),
8109
8116
  /** Omitted = `move`, the pre-existing behaviour. */
8110
8117
  mode: MediaRelocateModeSchema.optional()
@@ -8172,6 +8179,19 @@ var StorageMigrationDestinationsSchema = object({
8172
8179
  galleryMedia: string().min(1).optional()
8173
8180
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8174
8181
  /**
8182
+ * Optional named source per class. Omitted = the class's current default
8183
+ * (the historical behaviour). A named source that is NOT the default is a
8184
+ * drain of that disk: bytes move, the default stays, and the source is
8185
+ * disabled when the move finishes.
8186
+ */
8187
+ var StorageMigrationSourcesSchema = object({
8188
+ recordings: string().min(1).optional(),
8189
+ recordingsLow: string().min(1).optional(),
8190
+ eventMedia: string().min(1).optional(),
8191
+ backups: string().min(1).optional(),
8192
+ galleryMedia: string().min(1).optional()
8193
+ }).optional();
8194
+ /**
8175
8195
  * How a migration sequences the cutover against the byte move.
8176
8196
  *
8177
8197
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8193,6 +8213,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8193
8213
  /** Shared input for planning and starting an orchestrated storage migration. */
8194
8214
  var StorageMigrationInputSchema = object({
8195
8215
  destinations: StorageMigrationDestinationsSchema,
8216
+ /** Omitted = each class's current default. */
8217
+ sources: StorageMigrationSourcesSchema,
8196
8218
  throttleMbps: number().min(1).max(1e3).optional(),
8197
8219
  /** Omitted = `blocking`, which stays the default. */
8198
8220
  mode: StorageMigrationModeSchema.optional()
@@ -8272,6 +8294,13 @@ var StorageMigrationMoveSchema = object({
8272
8294
  storageClass: StorageMigrationClassSchema,
8273
8295
  fromLocationId: string(),
8274
8296
  toLocationId: string(),
8297
+ /**
8298
+ * True when `from` was NOT the class default at plan time. The move still
8299
+ * copies bytes, but the default is left alone and the source is disabled
8300
+ * once the copy verifies. Absent on jobs planned before this field existed
8301
+ * — those jobs always repointed, which is `false`.
8302
+ */
8303
+ freezeSource: boolean().optional(),
8275
8304
  moverJobId: string().nullable(),
8276
8305
  state: RelocateJobStateSchema.nullable(),
8277
8306
  error: string().nullable(),
@@ -8285,6 +8314,7 @@ var StorageMigrationJobSchema = object({
8285
8314
  * can tell a seconds-long cutover from a thirty-hour one. */
8286
8315
  mode: StorageMigrationModeSchema,
8287
8316
  destinations: StorageMigrationDestinationsSchema,
8317
+ sources: StorageMigrationSourcesSchema,
8288
8318
  throttleMbps: number(),
8289
8319
  moves: array(StorageMigrationMoveSchema),
8290
8320
  pauseLeaseId: string().nullable(),
@@ -8310,6 +8340,7 @@ var StorageMigrationFindingSchema = object({
8310
8340
  });
8311
8341
  var StorageMigrationPlanSchema = object({
8312
8342
  destinations: StorageMigrationDestinationsSchema,
8343
+ sources: StorageMigrationSourcesSchema,
8313
8344
  /** The mode this plan was built for. A plan is only valid for its mode: the
8314
8345
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8315
8346
  * it. */
@@ -8317,7 +8348,8 @@ var StorageMigrationPlanSchema = object({
8317
8348
  moves: array(object({
8318
8349
  storageClass: StorageMigrationClassSchema,
8319
8350
  fromLocationId: string(),
8320
- toLocationId: string()
8351
+ toLocationId: string(),
8352
+ freezeSource: boolean().optional()
8321
8353
  })),
8322
8354
  findings: array(StorageMigrationFindingSchema)
8323
8355
  });
@@ -8495,10 +8527,51 @@ var LedgerWalkReportSchema = object({
8495
8527
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8496
8528
  var RelocatableMediaCountInputSchema = object({
8497
8529
  toLocationId: string().min(1),
8530
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8531
+ fromLocationId: string().optional(),
8498
8532
  /** Omitted = `move`. */
8499
8533
  mode: MediaRelocateModeSchema.optional()
8500
8534
  });
8501
8535
  /**
8536
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8537
+ * ghost ledger entries on frozen footage locations.
8538
+ *
8539
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8540
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8541
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8542
+ * with no operator-visible status.
8543
+ */
8544
+ var StorageCleanupPhaseSchema = _enum([
8545
+ "orphans",
8546
+ "debug-media",
8547
+ "ghost-ledger",
8548
+ "done",
8549
+ "failed",
8550
+ "cancelled"
8551
+ ]);
8552
+ var StorageCleanupInputSchema = object({
8553
+ /** Also walk motion stills / track filmstrips. Off by default. */
8554
+ includeDebugMedia: boolean().optional() });
8555
+ var StorageCleanupJobSchema = object({
8556
+ jobId: string(),
8557
+ phase: StorageCleanupPhaseSchema,
8558
+ includeDebugMedia: boolean(),
8559
+ orphansReclaimed: number().int().nonnegative(),
8560
+ orphanBytesReclaimed: number().int().nonnegative(),
8561
+ debugMediaReclaimed: number().int().nonnegative(),
8562
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8563
+ ghostsForgotten: number().int().nonnegative(),
8564
+ ghostBytesForgotten: number().int().nonnegative(),
8565
+ /** Short operator-facing line: current collection, pass, or location. */
8566
+ detail: string().nullable(),
8567
+ cancelRequested: boolean(),
8568
+ startedAt: number(),
8569
+ updatedAt: number(),
8570
+ finishedAt: number().nullable(),
8571
+ error: string().nullable()
8572
+ });
8573
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8574
+ /**
8502
8575
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8503
8576
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8504
8577
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8526,11 +8599,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8526
8599
  * The default location for a type uses `id === <type>:default` by
8527
8600
  * convention (the bare type ref like `'backups'` resolves to it).
8528
8601
  *
8529
- * `isSystem: true` marks a location as orchestrator-seeded and
8530
- * undeletable. The bootstrap-installed defaults (one per type) carry
8531
- * this flag; operator-added locations don't. Editing the config of
8532
- * a system location is allowed (path migration, provider swap) but
8533
- * deleting it is rejected at the cap level.
8602
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8603
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8604
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8605
+ * / last-enabled, not on this bit.
8534
8606
  */
8535
8607
  var StorageLocationSchema = object({
8536
8608
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13122,6 +13194,12 @@ method(object({
13122
13194
  }), _void(), {
13123
13195
  kind: "mutation",
13124
13196
  auth: "admin"
13197
+ }), method(object({
13198
+ from: string(),
13199
+ to: string()
13200
+ }), object({ moved: number() }), {
13201
+ kind: "mutation",
13202
+ auth: "admin"
13125
13203
  }), method(object({
13126
13204
  deviceId: number(),
13127
13205
  disabled: boolean()
@@ -19130,46 +19208,6 @@ var RecentTracksPageSchema = object({
19130
19208
  /** Cursor for the next page, or null when this page is the last. */
19131
19209
  nextCursor: string().nullable()
19132
19210
  });
19133
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
19134
- var LIST_GROUPS_MAX_LIMIT = 100;
19135
- var AnalyticsGroupRecordSchema = object({
19136
- id: string(),
19137
- deviceId: number().int(),
19138
- openedAt: number().int(),
19139
- closedAt: number().int(),
19140
- timestamp: number().int(),
19141
- memberCount: number().int(),
19142
- memberTrackIds: array(string()).readonly(),
19143
- className: string(),
19144
- classes: array(string()).readonly(),
19145
- /** Relative event-media path, or null when the group has no picture yet. */
19146
- mediaUrl: string().nullable(),
19147
- singleton: boolean()
19148
- });
19149
- var AnalyticsGroupMemberSchema = object({
19150
- trackId: string(),
19151
- deviceId: number().int(),
19152
- className: string(),
19153
- firstSeen: number().int(),
19154
- lastSeen: number().int(),
19155
- mediaUrl: string().nullable()
19156
- });
19157
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19158
- var ListGroupsQueryInput = object({
19159
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19160
- deviceIds: array(number()),
19161
- /** Window lower bound on `closedAt` (inclusive). */
19162
- since: number().optional(),
19163
- /** Window upper bound on `openedAt` (inclusive). */
19164
- until: number().optional(),
19165
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19166
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19167
- cursor: string().optional()
19168
- });
19169
- var ListGroupsPageSchema = object({
19170
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19171
- nextCursor: string().nullable()
19172
- });
19173
19211
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19174
19212
  var KEY_EVENTS_MAX_LIMIT = 200;
19175
19213
  var KeyEventQueryInput = object({
@@ -19273,9 +19311,7 @@ var TrackCascadeCountsSchema = object({
19273
19311
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19274
19312
  plates: number().int(),
19275
19313
  /** Per-track CLIP search vectors removed (best-effort). */
19276
- embeddings: number().int(),
19277
- /** Group membership + group rows removed with their last member (best-effort). */
19278
- groups: number().int()
19314
+ embeddings: number().int()
19279
19315
  });
19280
19316
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19281
19317
  var DiskReconcileCountsSchema = object({
@@ -19445,6 +19481,47 @@ var RebuildStatusSchema = object({
19445
19481
  /** Present when the pass ended by throwing. */
19446
19482
  error: string().nullable()
19447
19483
  });
19484
+ /**
19485
+ * Acknowledgement that a debug-media reclaim STARTED.
19486
+ *
19487
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19488
+ * it runs detached and this returns immediately. Awaiting it is how the
19489
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19490
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19491
+ */
19492
+ var MediaReclaimStartResultSchema = object({
19493
+ started: boolean(),
19494
+ /** True when a pass was already running; the new request is ignored. */
19495
+ alreadyRunning: boolean()
19496
+ });
19497
+ var MediaReclaimInputSchema = object({
19498
+ mode: _enum(["report", "reclaim"]).default("report"),
19499
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19500
+ deviceIds: array(number().int()).min(1).optional(),
19501
+ restart: boolean().optional(),
19502
+ pageSize: number().int().min(50).max(5e3).optional(),
19503
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19504
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19505
+ maxBytesPerRun: number().int().min(1).optional(),
19506
+ budgetMinutes: number().int().min(1).max(720).optional(),
19507
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19508
+ graceMinutes: number().int().min(1).max(10080).optional()
19509
+ });
19510
+ var MediaReclaimStatusSchema = object({
19511
+ running: boolean(),
19512
+ mode: _enum(["report", "reclaim"]).nullable(),
19513
+ totalExamined: number(),
19514
+ totalEligible: number(),
19515
+ totalReclaimed: number(),
19516
+ totalBytesReclaimed: number(),
19517
+ totalRefused: number(),
19518
+ /** Device+scope windows finished in this pass. */
19519
+ devicesDone: number(),
19520
+ complete: boolean().nullable(),
19521
+ startedAtMs: number().nullable(),
19522
+ finishedAtMs: number().nullable(),
19523
+ error: string().nullable()
19524
+ });
19448
19525
  var ReplayFrameInputSchema = object({
19449
19526
  timestamp: number(),
19450
19527
  frame: PipelineRunResultBridge
@@ -19483,10 +19560,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19483
19560
  * stationary registry). Default false: the timeline lists passages,
19484
19561
  * not parking records (operator decision, 2026-08-15). */
19485
19562
  includeStationary: boolean().optional()
19486
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19487
- deviceId: number(),
19488
- groupId: string().min(1)
19489
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19563
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19490
19564
  kind: "mutation",
19491
19565
  auth: "admin"
19492
19566
  }), 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({
@@ -19586,6 +19660,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19586
19660
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19587
19661
  kind: "query",
19588
19662
  auth: "admin"
19663
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19664
+ kind: "mutation",
19665
+ auth: "admin"
19666
+ }), method(object({}), MediaReclaimStatusSchema, {
19667
+ kind: "query",
19668
+ auth: "admin"
19589
19669
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19590
19670
  kind: "query",
19591
19671
  auth: "admin"
@@ -21556,7 +21636,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21556
21636
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21557
21637
  kind: "mutation",
21558
21638
  auth: "admin"
21559
- });
21639
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21640
+ kind: "mutation",
21641
+ auth: "admin"
21642
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21643
+ kind: "mutation",
21644
+ auth: "admin"
21645
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21560
21646
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21561
21647
  providerId: string().min(1),
21562
21648
  displayName: string().min(1),
@@ -28649,6 +28735,33 @@ var RecordingRebalanceInputSchema = object({
28649
28735
  minMoveGb: number().min(0).optional()
28650
28736
  });
28651
28737
  /**
28738
+ * Operator-facing placement of one camera onto a recordings location.
28739
+ *
28740
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
28741
+ * Auto (the planner may move this camera). `locationId` is where high/mid
28742
+ * currently write — the plan, which may disagree with the pin when Auto.
28743
+ */
28744
+ var RecordingDevicePlacementSchema = object({
28745
+ deviceId: number().int(),
28746
+ profile: string(),
28747
+ locationId: string()
28748
+ });
28749
+ var RecordingDevicePinSchema = object({
28750
+ deviceId: number().int(),
28751
+ /** Recordings-class location this camera is pinned to. */
28752
+ locationId: string()
28753
+ });
28754
+ var RecordingPlacementViewSchema = object({
28755
+ assignments: array(RecordingDevicePlacementSchema),
28756
+ pins: array(RecordingDevicePinSchema),
28757
+ defaultLocations: record(string(), string())
28758
+ });
28759
+ var RecordingSetDevicePlacementInputSchema = object({
28760
+ deviceId: number().int(),
28761
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
28762
+ locationId: string().nullable()
28763
+ });
28764
+ /**
28652
28765
  * Result of locating footage at a wall-clock instant for one device/profile.
28653
28766
  * `segment` carries the covering segment's window; `gap` reports the forward
28654
28767
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -28874,6 +28987,12 @@ method(object({
28874
28987
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
28875
28988
  kind: "mutation",
28876
28989
  auth: "admin"
28990
+ }), method(object({}), RecordingPlacementViewSchema, {
28991
+ kind: "query",
28992
+ auth: "admin"
28993
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
28994
+ kind: "mutation",
28995
+ auth: "admin"
28877
28996
  });
28878
28997
  /**
28879
28998
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -33943,6 +34062,12 @@ Object.freeze({
33943
34062
  addonId: null,
33944
34063
  access: "delete"
33945
34064
  },
34065
+ "deviceManager.renameLocation": {
34066
+ capName: "device-manager",
34067
+ capScope: "system",
34068
+ addonId: null,
34069
+ access: "create"
34070
+ },
33946
34071
  "deviceManager.runDeviceAction": {
33947
34072
  capName: "device-manager",
33948
34073
  capScope: "system",
@@ -35635,19 +35760,19 @@ Object.freeze({
35635
35760
  addonId: null,
35636
35761
  access: "view"
35637
35762
  },
35638
- "pipelineAnalytics.getGroup": {
35763
+ "pipelineAnalytics.getKeyEvents": {
35639
35764
  capName: "pipeline-analytics",
35640
35765
  capScope: "device",
35641
35766
  addonId: null,
35642
35767
  access: "view"
35643
35768
  },
35644
- "pipelineAnalytics.getKeyEvents": {
35769
+ "pipelineAnalytics.getKeyEventsBatch": {
35645
35770
  capName: "pipeline-analytics",
35646
35771
  capScope: "device",
35647
35772
  addonId: null,
35648
35773
  access: "view"
35649
35774
  },
35650
- "pipelineAnalytics.getKeyEventsBatch": {
35775
+ "pipelineAnalytics.getMediaReclaimStatus": {
35651
35776
  capName: "pipeline-analytics",
35652
35777
  capScope: "device",
35653
35778
  addonId: null,
@@ -35737,12 +35862,6 @@ Object.freeze({
35737
35862
  addonId: null,
35738
35863
  access: "view"
35739
35864
  },
35740
- "pipelineAnalytics.listGroups": {
35741
- capName: "pipeline-analytics",
35742
- capScope: "device",
35743
- addonId: null,
35744
- access: "view"
35745
- },
35746
35865
  "pipelineAnalytics.listOpsLog": {
35747
35866
  capName: "pipeline-analytics",
35748
35867
  capScope: "device",
@@ -35827,6 +35946,12 @@ Object.freeze({
35827
35946
  addonId: null,
35828
35947
  access: "create"
35829
35948
  },
35949
+ "pipelineAnalytics.reclaimDebugMedia": {
35950
+ capName: "pipeline-analytics",
35951
+ capScope: "device",
35952
+ addonId: null,
35953
+ access: "create"
35954
+ },
35830
35955
  "pipelineAnalytics.reconcileFromDisk": {
35831
35956
  capName: "pipeline-analytics",
35832
35957
  capScope: "device",
@@ -36751,6 +36876,12 @@ Object.freeze({
36751
36876
  addonId: null,
36752
36877
  access: "view"
36753
36878
  },
36879
+ "recording.getPlacement": {
36880
+ capName: "recording",
36881
+ capScope: "system",
36882
+ addonId: null,
36883
+ access: "view"
36884
+ },
36754
36885
  "recording.getPlaybackManifest": {
36755
36886
  capName: "recording",
36756
36887
  capScope: "system",
@@ -36877,6 +37008,12 @@ Object.freeze({
36877
37008
  addonId: null,
36878
37009
  access: "create"
36879
37010
  },
37011
+ "recording.setDevicePlacement": {
37012
+ capName: "recording",
37013
+ capScope: "system",
37014
+ addonId: null,
37015
+ access: "create"
37016
+ },
36880
37017
  "recording.startStorageMigrationMove": {
36881
37018
  capName: "recording",
36882
37019
  capScope: "system",
@@ -37321,12 +37458,36 @@ Object.freeze({
37321
37458
  addonId: null,
37322
37459
  access: "create"
37323
37460
  },
37461
+ "storageMigration.cleanupCancel": {
37462
+ capName: "storage-migration",
37463
+ capScope: "system",
37464
+ addonId: null,
37465
+ access: "create"
37466
+ },
37467
+ "storageMigration.cleanupStart": {
37468
+ capName: "storage-migration",
37469
+ capScope: "system",
37470
+ addonId: null,
37471
+ access: "create"
37472
+ },
37473
+ "storageMigration.cleanupStatus": {
37474
+ capName: "storage-migration",
37475
+ capScope: "system",
37476
+ addonId: null,
37477
+ access: "view"
37478
+ },
37324
37479
  "storageMigration.drain": {
37325
37480
  capName: "storage-migration",
37326
37481
  capScope: "system",
37327
37482
  addonId: null,
37328
37483
  access: "create"
37329
37484
  },
37485
+ "storageMigration.history": {
37486
+ capName: "storage-migration",
37487
+ capScope: "system",
37488
+ addonId: null,
37489
+ access: "view"
37490
+ },
37330
37491
  "storageMigration.movers": {
37331
37492
  capName: "storage-migration",
37332
37493
  capScope: "system",
@@ -39323,11 +39484,6 @@ Object.freeze({
39323
39484
  form: "single",
39324
39485
  optional: true
39325
39486
  }],
39326
- "pipelineAnalytics.getGroup": [{
39327
- name: "deviceId",
39328
- form: "single",
39329
- optional: false
39330
- }],
39331
39487
  "pipelineAnalytics.getKeyEvents": [{
39332
39488
  name: "deviceId",
39333
39489
  form: "single",
@@ -39393,11 +39549,6 @@ Object.freeze({
39393
39549
  form: "single",
39394
39550
  optional: false
39395
39551
  }],
39396
- "pipelineAnalytics.listGroups": [{
39397
- name: "deviceIds",
39398
- form: "array",
39399
- optional: false
39400
- }],
39401
39552
  "pipelineAnalytics.listOpsLog": [{
39402
39553
  name: "deviceId",
39403
39554
  form: "single",
@@ -39443,6 +39594,11 @@ Object.freeze({
39443
39594
  form: "single",
39444
39595
  optional: true
39445
39596
  }],
39597
+ "pipelineAnalytics.reclaimDebugMedia": [{
39598
+ name: "deviceIds",
39599
+ form: "array",
39600
+ optional: true
39601
+ }],
39446
39602
  "pipelineAnalytics.reconcileFromDisk": [{
39447
39603
  name: "deviceId",
39448
39604
  form: "single",
@@ -39808,6 +39964,11 @@ Object.freeze({
39808
39964
  form: "single",
39809
39965
  optional: false
39810
39966
  }],
39967
+ "recording.setDevicePlacement": [{
39968
+ name: "deviceId",
39969
+ form: "single",
39970
+ optional: false
39971
+ }],
39811
39972
  "recording.startStorageMigrationMove": [{
39812
39973
  name: "deviceId",
39813
39974
  form: "single",
package/dist/addon.mjs CHANGED
@@ -8106,6 +8106,13 @@ var MediaRelocateModeSchema = _enum([
8106
8106
  ]);
8107
8107
  var RelocateMediaInputSchema = object({
8108
8108
  toLocationId: string(),
8109
+ /**
8110
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8111
+ * every row that is not already on `toLocationId` (the historical
8112
+ * behaviour). A named source is what a from→to migration needs: without it
8113
+ * "move events off disk 2" also emptied disk 1.
8114
+ */
8115
+ fromLocationId: string().optional(),
8109
8116
  throttleMbps: number().min(1).max(1e3).optional(),
8110
8117
  /** Omitted = `move`, the pre-existing behaviour. */
8111
8118
  mode: MediaRelocateModeSchema.optional()
@@ -8173,6 +8180,19 @@ var StorageMigrationDestinationsSchema = object({
8173
8180
  galleryMedia: string().min(1).optional()
8174
8181
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8175
8182
  /**
8183
+ * Optional named source per class. Omitted = the class's current default
8184
+ * (the historical behaviour). A named source that is NOT the default is a
8185
+ * drain of that disk: bytes move, the default stays, and the source is
8186
+ * disabled when the move finishes.
8187
+ */
8188
+ var StorageMigrationSourcesSchema = object({
8189
+ recordings: string().min(1).optional(),
8190
+ recordingsLow: string().min(1).optional(),
8191
+ eventMedia: string().min(1).optional(),
8192
+ backups: string().min(1).optional(),
8193
+ galleryMedia: string().min(1).optional()
8194
+ }).optional();
8195
+ /**
8176
8196
  * How a migration sequences the cutover against the byte move.
8177
8197
  *
8178
8198
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8194,6 +8214,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8194
8214
  /** Shared input for planning and starting an orchestrated storage migration. */
8195
8215
  var StorageMigrationInputSchema = object({
8196
8216
  destinations: StorageMigrationDestinationsSchema,
8217
+ /** Omitted = each class's current default. */
8218
+ sources: StorageMigrationSourcesSchema,
8197
8219
  throttleMbps: number().min(1).max(1e3).optional(),
8198
8220
  /** Omitted = `blocking`, which stays the default. */
8199
8221
  mode: StorageMigrationModeSchema.optional()
@@ -8273,6 +8295,13 @@ var StorageMigrationMoveSchema = object({
8273
8295
  storageClass: StorageMigrationClassSchema,
8274
8296
  fromLocationId: string(),
8275
8297
  toLocationId: string(),
8298
+ /**
8299
+ * True when `from` was NOT the class default at plan time. The move still
8300
+ * copies bytes, but the default is left alone and the source is disabled
8301
+ * once the copy verifies. Absent on jobs planned before this field existed
8302
+ * — those jobs always repointed, which is `false`.
8303
+ */
8304
+ freezeSource: boolean().optional(),
8276
8305
  moverJobId: string().nullable(),
8277
8306
  state: RelocateJobStateSchema.nullable(),
8278
8307
  error: string().nullable(),
@@ -8286,6 +8315,7 @@ var StorageMigrationJobSchema = object({
8286
8315
  * can tell a seconds-long cutover from a thirty-hour one. */
8287
8316
  mode: StorageMigrationModeSchema,
8288
8317
  destinations: StorageMigrationDestinationsSchema,
8318
+ sources: StorageMigrationSourcesSchema,
8289
8319
  throttleMbps: number(),
8290
8320
  moves: array(StorageMigrationMoveSchema),
8291
8321
  pauseLeaseId: string().nullable(),
@@ -8311,6 +8341,7 @@ var StorageMigrationFindingSchema = object({
8311
8341
  });
8312
8342
  var StorageMigrationPlanSchema = object({
8313
8343
  destinations: StorageMigrationDestinationsSchema,
8344
+ sources: StorageMigrationSourcesSchema,
8314
8345
  /** The mode this plan was built for. A plan is only valid for its mode: the
8315
8346
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8316
8347
  * it. */
@@ -8318,7 +8349,8 @@ var StorageMigrationPlanSchema = object({
8318
8349
  moves: array(object({
8319
8350
  storageClass: StorageMigrationClassSchema,
8320
8351
  fromLocationId: string(),
8321
- toLocationId: string()
8352
+ toLocationId: string(),
8353
+ freezeSource: boolean().optional()
8322
8354
  })),
8323
8355
  findings: array(StorageMigrationFindingSchema)
8324
8356
  });
@@ -8496,10 +8528,51 @@ var LedgerWalkReportSchema = object({
8496
8528
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8497
8529
  var RelocatableMediaCountInputSchema = object({
8498
8530
  toLocationId: string().min(1),
8531
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8532
+ fromLocationId: string().optional(),
8499
8533
  /** Omitted = `move`. */
8500
8534
  mode: MediaRelocateModeSchema.optional()
8501
8535
  });
8502
8536
  /**
8537
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8538
+ * ghost ledger entries on frozen footage locations.
8539
+ *
8540
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8541
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8542
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8543
+ * with no operator-visible status.
8544
+ */
8545
+ var StorageCleanupPhaseSchema = _enum([
8546
+ "orphans",
8547
+ "debug-media",
8548
+ "ghost-ledger",
8549
+ "done",
8550
+ "failed",
8551
+ "cancelled"
8552
+ ]);
8553
+ var StorageCleanupInputSchema = object({
8554
+ /** Also walk motion stills / track filmstrips. Off by default. */
8555
+ includeDebugMedia: boolean().optional() });
8556
+ var StorageCleanupJobSchema = object({
8557
+ jobId: string(),
8558
+ phase: StorageCleanupPhaseSchema,
8559
+ includeDebugMedia: boolean(),
8560
+ orphansReclaimed: number().int().nonnegative(),
8561
+ orphanBytesReclaimed: number().int().nonnegative(),
8562
+ debugMediaReclaimed: number().int().nonnegative(),
8563
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8564
+ ghostsForgotten: number().int().nonnegative(),
8565
+ ghostBytesForgotten: number().int().nonnegative(),
8566
+ /** Short operator-facing line: current collection, pass, or location. */
8567
+ detail: string().nullable(),
8568
+ cancelRequested: boolean(),
8569
+ startedAt: number(),
8570
+ updatedAt: number(),
8571
+ finishedAt: number().nullable(),
8572
+ error: string().nullable()
8573
+ });
8574
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8575
+ /**
8503
8576
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8504
8577
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8505
8578
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8527,11 +8600,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8527
8600
  * The default location for a type uses `id === <type>:default` by
8528
8601
  * convention (the bare type ref like `'backups'` resolves to it).
8529
8602
  *
8530
- * `isSystem: true` marks a location as orchestrator-seeded and
8531
- * undeletable. The bootstrap-installed defaults (one per type) carry
8532
- * this flag; operator-added locations don't. Editing the config of
8533
- * a system location is allowed (path migration, provider swap) but
8534
- * deleting it is rejected at the cap level.
8603
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8604
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8605
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8606
+ * / last-enabled, not on this bit.
8535
8607
  */
8536
8608
  var StorageLocationSchema = object({
8537
8609
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13123,6 +13195,12 @@ method(object({
13123
13195
  }), _void(), {
13124
13196
  kind: "mutation",
13125
13197
  auth: "admin"
13198
+ }), method(object({
13199
+ from: string(),
13200
+ to: string()
13201
+ }), object({ moved: number() }), {
13202
+ kind: "mutation",
13203
+ auth: "admin"
13126
13204
  }), method(object({
13127
13205
  deviceId: number(),
13128
13206
  disabled: boolean()
@@ -19131,46 +19209,6 @@ var RecentTracksPageSchema = object({
19131
19209
  /** Cursor for the next page, or null when this page is the last. */
19132
19210
  nextCursor: string().nullable()
19133
19211
  });
19134
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
19135
- var LIST_GROUPS_MAX_LIMIT = 100;
19136
- var AnalyticsGroupRecordSchema = object({
19137
- id: string(),
19138
- deviceId: number().int(),
19139
- openedAt: number().int(),
19140
- closedAt: number().int(),
19141
- timestamp: number().int(),
19142
- memberCount: number().int(),
19143
- memberTrackIds: array(string()).readonly(),
19144
- className: string(),
19145
- classes: array(string()).readonly(),
19146
- /** Relative event-media path, or null when the group has no picture yet. */
19147
- mediaUrl: string().nullable(),
19148
- singleton: boolean()
19149
- });
19150
- var AnalyticsGroupMemberSchema = object({
19151
- trackId: string(),
19152
- deviceId: number().int(),
19153
- className: string(),
19154
- firstSeen: number().int(),
19155
- lastSeen: number().int(),
19156
- mediaUrl: string().nullable()
19157
- });
19158
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19159
- var ListGroupsQueryInput = object({
19160
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19161
- deviceIds: array(number()),
19162
- /** Window lower bound on `closedAt` (inclusive). */
19163
- since: number().optional(),
19164
- /** Window upper bound on `openedAt` (inclusive). */
19165
- until: number().optional(),
19166
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19167
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19168
- cursor: string().optional()
19169
- });
19170
- var ListGroupsPageSchema = object({
19171
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19172
- nextCursor: string().nullable()
19173
- });
19174
19212
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19175
19213
  var KEY_EVENTS_MAX_LIMIT = 200;
19176
19214
  var KeyEventQueryInput = object({
@@ -19274,9 +19312,7 @@ var TrackCascadeCountsSchema = object({
19274
19312
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19275
19313
  plates: number().int(),
19276
19314
  /** Per-track CLIP search vectors removed (best-effort). */
19277
- embeddings: number().int(),
19278
- /** Group membership + group rows removed with their last member (best-effort). */
19279
- groups: number().int()
19315
+ embeddings: number().int()
19280
19316
  });
19281
19317
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19282
19318
  var DiskReconcileCountsSchema = object({
@@ -19446,6 +19482,47 @@ var RebuildStatusSchema = object({
19446
19482
  /** Present when the pass ended by throwing. */
19447
19483
  error: string().nullable()
19448
19484
  });
19485
+ /**
19486
+ * Acknowledgement that a debug-media reclaim STARTED.
19487
+ *
19488
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19489
+ * it runs detached and this returns immediately. Awaiting it is how the
19490
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19491
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19492
+ */
19493
+ var MediaReclaimStartResultSchema = object({
19494
+ started: boolean(),
19495
+ /** True when a pass was already running; the new request is ignored. */
19496
+ alreadyRunning: boolean()
19497
+ });
19498
+ var MediaReclaimInputSchema = object({
19499
+ mode: _enum(["report", "reclaim"]).default("report"),
19500
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19501
+ deviceIds: array(number().int()).min(1).optional(),
19502
+ restart: boolean().optional(),
19503
+ pageSize: number().int().min(50).max(5e3).optional(),
19504
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19505
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19506
+ maxBytesPerRun: number().int().min(1).optional(),
19507
+ budgetMinutes: number().int().min(1).max(720).optional(),
19508
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19509
+ graceMinutes: number().int().min(1).max(10080).optional()
19510
+ });
19511
+ var MediaReclaimStatusSchema = object({
19512
+ running: boolean(),
19513
+ mode: _enum(["report", "reclaim"]).nullable(),
19514
+ totalExamined: number(),
19515
+ totalEligible: number(),
19516
+ totalReclaimed: number(),
19517
+ totalBytesReclaimed: number(),
19518
+ totalRefused: number(),
19519
+ /** Device+scope windows finished in this pass. */
19520
+ devicesDone: number(),
19521
+ complete: boolean().nullable(),
19522
+ startedAtMs: number().nullable(),
19523
+ finishedAtMs: number().nullable(),
19524
+ error: string().nullable()
19525
+ });
19449
19526
  var ReplayFrameInputSchema = object({
19450
19527
  timestamp: number(),
19451
19528
  frame: PipelineRunResultBridge
@@ -19484,10 +19561,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19484
19561
  * stationary registry). Default false: the timeline lists passages,
19485
19562
  * not parking records (operator decision, 2026-08-15). */
19486
19563
  includeStationary: boolean().optional()
19487
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19488
- deviceId: number(),
19489
- groupId: string().min(1)
19490
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19564
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19491
19565
  kind: "mutation",
19492
19566
  auth: "admin"
19493
19567
  }), 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({
@@ -19587,6 +19661,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19587
19661
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19588
19662
  kind: "query",
19589
19663
  auth: "admin"
19664
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19665
+ kind: "mutation",
19666
+ auth: "admin"
19667
+ }), method(object({}), MediaReclaimStatusSchema, {
19668
+ kind: "query",
19669
+ auth: "admin"
19590
19670
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19591
19671
  kind: "query",
19592
19672
  auth: "admin"
@@ -21557,7 +21637,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21557
21637
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21558
21638
  kind: "mutation",
21559
21639
  auth: "admin"
21560
- });
21640
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21641
+ kind: "mutation",
21642
+ auth: "admin"
21643
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21644
+ kind: "mutation",
21645
+ auth: "admin"
21646
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21561
21647
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21562
21648
  providerId: string().min(1),
21563
21649
  displayName: string().min(1),
@@ -28650,6 +28736,33 @@ var RecordingRebalanceInputSchema = object({
28650
28736
  minMoveGb: number().min(0).optional()
28651
28737
  });
28652
28738
  /**
28739
+ * Operator-facing placement of one camera onto a recordings location.
28740
+ *
28741
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
28742
+ * Auto (the planner may move this camera). `locationId` is where high/mid
28743
+ * currently write — the plan, which may disagree with the pin when Auto.
28744
+ */
28745
+ var RecordingDevicePlacementSchema = object({
28746
+ deviceId: number().int(),
28747
+ profile: string(),
28748
+ locationId: string()
28749
+ });
28750
+ var RecordingDevicePinSchema = object({
28751
+ deviceId: number().int(),
28752
+ /** Recordings-class location this camera is pinned to. */
28753
+ locationId: string()
28754
+ });
28755
+ var RecordingPlacementViewSchema = object({
28756
+ assignments: array(RecordingDevicePlacementSchema),
28757
+ pins: array(RecordingDevicePinSchema),
28758
+ defaultLocations: record(string(), string())
28759
+ });
28760
+ var RecordingSetDevicePlacementInputSchema = object({
28761
+ deviceId: number().int(),
28762
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
28763
+ locationId: string().nullable()
28764
+ });
28765
+ /**
28653
28766
  * Result of locating footage at a wall-clock instant for one device/profile.
28654
28767
  * `segment` carries the covering segment's window; `gap` reports the forward
28655
28768
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -28875,6 +28988,12 @@ method(object({
28875
28988
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
28876
28989
  kind: "mutation",
28877
28990
  auth: "admin"
28991
+ }), method(object({}), RecordingPlacementViewSchema, {
28992
+ kind: "query",
28993
+ auth: "admin"
28994
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
28995
+ kind: "mutation",
28996
+ auth: "admin"
28878
28997
  });
28879
28998
  /**
28880
28999
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -33944,6 +34063,12 @@ Object.freeze({
33944
34063
  addonId: null,
33945
34064
  access: "delete"
33946
34065
  },
34066
+ "deviceManager.renameLocation": {
34067
+ capName: "device-manager",
34068
+ capScope: "system",
34069
+ addonId: null,
34070
+ access: "create"
34071
+ },
33947
34072
  "deviceManager.runDeviceAction": {
33948
34073
  capName: "device-manager",
33949
34074
  capScope: "system",
@@ -35636,19 +35761,19 @@ Object.freeze({
35636
35761
  addonId: null,
35637
35762
  access: "view"
35638
35763
  },
35639
- "pipelineAnalytics.getGroup": {
35764
+ "pipelineAnalytics.getKeyEvents": {
35640
35765
  capName: "pipeline-analytics",
35641
35766
  capScope: "device",
35642
35767
  addonId: null,
35643
35768
  access: "view"
35644
35769
  },
35645
- "pipelineAnalytics.getKeyEvents": {
35770
+ "pipelineAnalytics.getKeyEventsBatch": {
35646
35771
  capName: "pipeline-analytics",
35647
35772
  capScope: "device",
35648
35773
  addonId: null,
35649
35774
  access: "view"
35650
35775
  },
35651
- "pipelineAnalytics.getKeyEventsBatch": {
35776
+ "pipelineAnalytics.getMediaReclaimStatus": {
35652
35777
  capName: "pipeline-analytics",
35653
35778
  capScope: "device",
35654
35779
  addonId: null,
@@ -35738,12 +35863,6 @@ Object.freeze({
35738
35863
  addonId: null,
35739
35864
  access: "view"
35740
35865
  },
35741
- "pipelineAnalytics.listGroups": {
35742
- capName: "pipeline-analytics",
35743
- capScope: "device",
35744
- addonId: null,
35745
- access: "view"
35746
- },
35747
35866
  "pipelineAnalytics.listOpsLog": {
35748
35867
  capName: "pipeline-analytics",
35749
35868
  capScope: "device",
@@ -35828,6 +35947,12 @@ Object.freeze({
35828
35947
  addonId: null,
35829
35948
  access: "create"
35830
35949
  },
35950
+ "pipelineAnalytics.reclaimDebugMedia": {
35951
+ capName: "pipeline-analytics",
35952
+ capScope: "device",
35953
+ addonId: null,
35954
+ access: "create"
35955
+ },
35831
35956
  "pipelineAnalytics.reconcileFromDisk": {
35832
35957
  capName: "pipeline-analytics",
35833
35958
  capScope: "device",
@@ -36752,6 +36877,12 @@ Object.freeze({
36752
36877
  addonId: null,
36753
36878
  access: "view"
36754
36879
  },
36880
+ "recording.getPlacement": {
36881
+ capName: "recording",
36882
+ capScope: "system",
36883
+ addonId: null,
36884
+ access: "view"
36885
+ },
36755
36886
  "recording.getPlaybackManifest": {
36756
36887
  capName: "recording",
36757
36888
  capScope: "system",
@@ -36878,6 +37009,12 @@ Object.freeze({
36878
37009
  addonId: null,
36879
37010
  access: "create"
36880
37011
  },
37012
+ "recording.setDevicePlacement": {
37013
+ capName: "recording",
37014
+ capScope: "system",
37015
+ addonId: null,
37016
+ access: "create"
37017
+ },
36881
37018
  "recording.startStorageMigrationMove": {
36882
37019
  capName: "recording",
36883
37020
  capScope: "system",
@@ -37322,12 +37459,36 @@ Object.freeze({
37322
37459
  addonId: null,
37323
37460
  access: "create"
37324
37461
  },
37462
+ "storageMigration.cleanupCancel": {
37463
+ capName: "storage-migration",
37464
+ capScope: "system",
37465
+ addonId: null,
37466
+ access: "create"
37467
+ },
37468
+ "storageMigration.cleanupStart": {
37469
+ capName: "storage-migration",
37470
+ capScope: "system",
37471
+ addonId: null,
37472
+ access: "create"
37473
+ },
37474
+ "storageMigration.cleanupStatus": {
37475
+ capName: "storage-migration",
37476
+ capScope: "system",
37477
+ addonId: null,
37478
+ access: "view"
37479
+ },
37325
37480
  "storageMigration.drain": {
37326
37481
  capName: "storage-migration",
37327
37482
  capScope: "system",
37328
37483
  addonId: null,
37329
37484
  access: "create"
37330
37485
  },
37486
+ "storageMigration.history": {
37487
+ capName: "storage-migration",
37488
+ capScope: "system",
37489
+ addonId: null,
37490
+ access: "view"
37491
+ },
37331
37492
  "storageMigration.movers": {
37332
37493
  capName: "storage-migration",
37333
37494
  capScope: "system",
@@ -39324,11 +39485,6 @@ Object.freeze({
39324
39485
  form: "single",
39325
39486
  optional: true
39326
39487
  }],
39327
- "pipelineAnalytics.getGroup": [{
39328
- name: "deviceId",
39329
- form: "single",
39330
- optional: false
39331
- }],
39332
39488
  "pipelineAnalytics.getKeyEvents": [{
39333
39489
  name: "deviceId",
39334
39490
  form: "single",
@@ -39394,11 +39550,6 @@ Object.freeze({
39394
39550
  form: "single",
39395
39551
  optional: false
39396
39552
  }],
39397
- "pipelineAnalytics.listGroups": [{
39398
- name: "deviceIds",
39399
- form: "array",
39400
- optional: false
39401
- }],
39402
39553
  "pipelineAnalytics.listOpsLog": [{
39403
39554
  name: "deviceId",
39404
39555
  form: "single",
@@ -39444,6 +39595,11 @@ Object.freeze({
39444
39595
  form: "single",
39445
39596
  optional: true
39446
39597
  }],
39598
+ "pipelineAnalytics.reclaimDebugMedia": [{
39599
+ name: "deviceIds",
39600
+ form: "array",
39601
+ optional: true
39602
+ }],
39447
39603
  "pipelineAnalytics.reconcileFromDisk": [{
39448
39604
  name: "deviceId",
39449
39605
  form: "single",
@@ -39809,6 +39965,11 @@ Object.freeze({
39809
39965
  form: "single",
39810
39966
  optional: false
39811
39967
  }],
39968
+ "recording.setDevicePlacement": [{
39969
+ name: "deviceId",
39970
+ form: "single",
39971
+ optional: false
39972
+ }],
39812
39973
  "recording.startStorageMigrationMove": [{
39813
39974
  name: "deviceId",
39814
39975
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.50",
3
+ "version": "1.2.51",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",