@camstack/addon-provider-homematic 1.2.50 → 1.2.52

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 +236 -73
  2. package/dist/addon.mjs +236 -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()
@@ -15872,6 +15950,8 @@ var NcSystemEventKindSchema = _enum([
15872
15950
  "device-offline",
15873
15951
  "device-disabled",
15874
15952
  "device-enabled",
15953
+ "device-battery-low",
15954
+ "device-battery-normal",
15875
15955
  "stream-online",
15876
15956
  "stream-offline",
15877
15957
  "node-online",
@@ -19130,46 +19210,6 @@ var RecentTracksPageSchema = object({
19130
19210
  /** Cursor for the next page, or null when this page is the last. */
19131
19211
  nextCursor: string().nullable()
19132
19212
  });
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
19213
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19174
19214
  var KEY_EVENTS_MAX_LIMIT = 200;
19175
19215
  var KeyEventQueryInput = object({
@@ -19273,9 +19313,7 @@ var TrackCascadeCountsSchema = object({
19273
19313
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19274
19314
  plates: number().int(),
19275
19315
  /** 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()
19316
+ embeddings: number().int()
19279
19317
  });
19280
19318
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19281
19319
  var DiskReconcileCountsSchema = object({
@@ -19445,6 +19483,47 @@ var RebuildStatusSchema = object({
19445
19483
  /** Present when the pass ended by throwing. */
19446
19484
  error: string().nullable()
19447
19485
  });
19486
+ /**
19487
+ * Acknowledgement that a debug-media reclaim STARTED.
19488
+ *
19489
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19490
+ * it runs detached and this returns immediately. Awaiting it is how the
19491
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19492
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19493
+ */
19494
+ var MediaReclaimStartResultSchema = object({
19495
+ started: boolean(),
19496
+ /** True when a pass was already running; the new request is ignored. */
19497
+ alreadyRunning: boolean()
19498
+ });
19499
+ var MediaReclaimInputSchema = object({
19500
+ mode: _enum(["report", "reclaim"]).default("report"),
19501
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19502
+ deviceIds: array(number().int()).min(1).optional(),
19503
+ restart: boolean().optional(),
19504
+ pageSize: number().int().min(50).max(5e3).optional(),
19505
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19506
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19507
+ maxBytesPerRun: number().int().min(1).optional(),
19508
+ budgetMinutes: number().int().min(1).max(720).optional(),
19509
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19510
+ graceMinutes: number().int().min(1).max(10080).optional()
19511
+ });
19512
+ var MediaReclaimStatusSchema = object({
19513
+ running: boolean(),
19514
+ mode: _enum(["report", "reclaim"]).nullable(),
19515
+ totalExamined: number(),
19516
+ totalEligible: number(),
19517
+ totalReclaimed: number(),
19518
+ totalBytesReclaimed: number(),
19519
+ totalRefused: number(),
19520
+ /** Device+scope windows finished in this pass. */
19521
+ devicesDone: number(),
19522
+ complete: boolean().nullable(),
19523
+ startedAtMs: number().nullable(),
19524
+ finishedAtMs: number().nullable(),
19525
+ error: string().nullable()
19526
+ });
19448
19527
  var ReplayFrameInputSchema = object({
19449
19528
  timestamp: number(),
19450
19529
  frame: PipelineRunResultBridge
@@ -19483,10 +19562,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19483
19562
  * stationary registry). Default false: the timeline lists passages,
19484
19563
  * not parking records (operator decision, 2026-08-15). */
19485
19564
  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(), {
19565
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19490
19566
  kind: "mutation",
19491
19567
  auth: "admin"
19492
19568
  }), 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 +19662,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19586
19662
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19587
19663
  kind: "query",
19588
19664
  auth: "admin"
19665
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19666
+ kind: "mutation",
19667
+ auth: "admin"
19668
+ }), method(object({}), MediaReclaimStatusSchema, {
19669
+ kind: "query",
19670
+ auth: "admin"
19589
19671
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19590
19672
  kind: "query",
19591
19673
  auth: "admin"
@@ -21556,7 +21638,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21556
21638
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21557
21639
  kind: "mutation",
21558
21640
  auth: "admin"
21559
- });
21641
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21642
+ kind: "mutation",
21643
+ auth: "admin"
21644
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21645
+ kind: "mutation",
21646
+ auth: "admin"
21647
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21560
21648
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21561
21649
  providerId: string().min(1),
21562
21650
  displayName: string().min(1),
@@ -28649,6 +28737,33 @@ var RecordingRebalanceInputSchema = object({
28649
28737
  minMoveGb: number().min(0).optional()
28650
28738
  });
28651
28739
  /**
28740
+ * Operator-facing placement of one camera onto a recordings location.
28741
+ *
28742
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
28743
+ * Auto (the planner may move this camera). `locationId` is where high/mid
28744
+ * currently write — the plan, which may disagree with the pin when Auto.
28745
+ */
28746
+ var RecordingDevicePlacementSchema = object({
28747
+ deviceId: number().int(),
28748
+ profile: string(),
28749
+ locationId: string()
28750
+ });
28751
+ var RecordingDevicePinSchema = object({
28752
+ deviceId: number().int(),
28753
+ /** Recordings-class location this camera is pinned to. */
28754
+ locationId: string()
28755
+ });
28756
+ var RecordingPlacementViewSchema = object({
28757
+ assignments: array(RecordingDevicePlacementSchema),
28758
+ pins: array(RecordingDevicePinSchema),
28759
+ defaultLocations: record(string(), string())
28760
+ });
28761
+ var RecordingSetDevicePlacementInputSchema = object({
28762
+ deviceId: number().int(),
28763
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
28764
+ locationId: string().nullable()
28765
+ });
28766
+ /**
28652
28767
  * Result of locating footage at a wall-clock instant for one device/profile.
28653
28768
  * `segment` carries the covering segment's window; `gap` reports the forward
28654
28769
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -28874,6 +28989,12 @@ method(object({
28874
28989
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
28875
28990
  kind: "mutation",
28876
28991
  auth: "admin"
28992
+ }), method(object({}), RecordingPlacementViewSchema, {
28993
+ kind: "query",
28994
+ auth: "admin"
28995
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
28996
+ kind: "mutation",
28997
+ auth: "admin"
28877
28998
  });
28878
28999
  /**
28879
29000
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -33943,6 +34064,12 @@ Object.freeze({
33943
34064
  addonId: null,
33944
34065
  access: "delete"
33945
34066
  },
34067
+ "deviceManager.renameLocation": {
34068
+ capName: "device-manager",
34069
+ capScope: "system",
34070
+ addonId: null,
34071
+ access: "create"
34072
+ },
33946
34073
  "deviceManager.runDeviceAction": {
33947
34074
  capName: "device-manager",
33948
34075
  capScope: "system",
@@ -35635,19 +35762,19 @@ Object.freeze({
35635
35762
  addonId: null,
35636
35763
  access: "view"
35637
35764
  },
35638
- "pipelineAnalytics.getGroup": {
35765
+ "pipelineAnalytics.getKeyEvents": {
35639
35766
  capName: "pipeline-analytics",
35640
35767
  capScope: "device",
35641
35768
  addonId: null,
35642
35769
  access: "view"
35643
35770
  },
35644
- "pipelineAnalytics.getKeyEvents": {
35771
+ "pipelineAnalytics.getKeyEventsBatch": {
35645
35772
  capName: "pipeline-analytics",
35646
35773
  capScope: "device",
35647
35774
  addonId: null,
35648
35775
  access: "view"
35649
35776
  },
35650
- "pipelineAnalytics.getKeyEventsBatch": {
35777
+ "pipelineAnalytics.getMediaReclaimStatus": {
35651
35778
  capName: "pipeline-analytics",
35652
35779
  capScope: "device",
35653
35780
  addonId: null,
@@ -35737,12 +35864,6 @@ Object.freeze({
35737
35864
  addonId: null,
35738
35865
  access: "view"
35739
35866
  },
35740
- "pipelineAnalytics.listGroups": {
35741
- capName: "pipeline-analytics",
35742
- capScope: "device",
35743
- addonId: null,
35744
- access: "view"
35745
- },
35746
35867
  "pipelineAnalytics.listOpsLog": {
35747
35868
  capName: "pipeline-analytics",
35748
35869
  capScope: "device",
@@ -35827,6 +35948,12 @@ Object.freeze({
35827
35948
  addonId: null,
35828
35949
  access: "create"
35829
35950
  },
35951
+ "pipelineAnalytics.reclaimDebugMedia": {
35952
+ capName: "pipeline-analytics",
35953
+ capScope: "device",
35954
+ addonId: null,
35955
+ access: "create"
35956
+ },
35830
35957
  "pipelineAnalytics.reconcileFromDisk": {
35831
35958
  capName: "pipeline-analytics",
35832
35959
  capScope: "device",
@@ -36751,6 +36878,12 @@ Object.freeze({
36751
36878
  addonId: null,
36752
36879
  access: "view"
36753
36880
  },
36881
+ "recording.getPlacement": {
36882
+ capName: "recording",
36883
+ capScope: "system",
36884
+ addonId: null,
36885
+ access: "view"
36886
+ },
36754
36887
  "recording.getPlaybackManifest": {
36755
36888
  capName: "recording",
36756
36889
  capScope: "system",
@@ -36877,6 +37010,12 @@ Object.freeze({
36877
37010
  addonId: null,
36878
37011
  access: "create"
36879
37012
  },
37013
+ "recording.setDevicePlacement": {
37014
+ capName: "recording",
37015
+ capScope: "system",
37016
+ addonId: null,
37017
+ access: "create"
37018
+ },
36880
37019
  "recording.startStorageMigrationMove": {
36881
37020
  capName: "recording",
36882
37021
  capScope: "system",
@@ -37321,12 +37460,36 @@ Object.freeze({
37321
37460
  addonId: null,
37322
37461
  access: "create"
37323
37462
  },
37463
+ "storageMigration.cleanupCancel": {
37464
+ capName: "storage-migration",
37465
+ capScope: "system",
37466
+ addonId: null,
37467
+ access: "create"
37468
+ },
37469
+ "storageMigration.cleanupStart": {
37470
+ capName: "storage-migration",
37471
+ capScope: "system",
37472
+ addonId: null,
37473
+ access: "create"
37474
+ },
37475
+ "storageMigration.cleanupStatus": {
37476
+ capName: "storage-migration",
37477
+ capScope: "system",
37478
+ addonId: null,
37479
+ access: "view"
37480
+ },
37324
37481
  "storageMigration.drain": {
37325
37482
  capName: "storage-migration",
37326
37483
  capScope: "system",
37327
37484
  addonId: null,
37328
37485
  access: "create"
37329
37486
  },
37487
+ "storageMigration.history": {
37488
+ capName: "storage-migration",
37489
+ capScope: "system",
37490
+ addonId: null,
37491
+ access: "view"
37492
+ },
37330
37493
  "storageMigration.movers": {
37331
37494
  capName: "storage-migration",
37332
37495
  capScope: "system",
@@ -39323,11 +39486,6 @@ Object.freeze({
39323
39486
  form: "single",
39324
39487
  optional: true
39325
39488
  }],
39326
- "pipelineAnalytics.getGroup": [{
39327
- name: "deviceId",
39328
- form: "single",
39329
- optional: false
39330
- }],
39331
39489
  "pipelineAnalytics.getKeyEvents": [{
39332
39490
  name: "deviceId",
39333
39491
  form: "single",
@@ -39393,11 +39551,6 @@ Object.freeze({
39393
39551
  form: "single",
39394
39552
  optional: false
39395
39553
  }],
39396
- "pipelineAnalytics.listGroups": [{
39397
- name: "deviceIds",
39398
- form: "array",
39399
- optional: false
39400
- }],
39401
39554
  "pipelineAnalytics.listOpsLog": [{
39402
39555
  name: "deviceId",
39403
39556
  form: "single",
@@ -39443,6 +39596,11 @@ Object.freeze({
39443
39596
  form: "single",
39444
39597
  optional: true
39445
39598
  }],
39599
+ "pipelineAnalytics.reclaimDebugMedia": [{
39600
+ name: "deviceIds",
39601
+ form: "array",
39602
+ optional: true
39603
+ }],
39446
39604
  "pipelineAnalytics.reconcileFromDisk": [{
39447
39605
  name: "deviceId",
39448
39606
  form: "single",
@@ -39808,6 +39966,11 @@ Object.freeze({
39808
39966
  form: "single",
39809
39967
  optional: false
39810
39968
  }],
39969
+ "recording.setDevicePlacement": [{
39970
+ name: "deviceId",
39971
+ form: "single",
39972
+ optional: false
39973
+ }],
39811
39974
  "recording.startStorageMigrationMove": [{
39812
39975
  name: "deviceId",
39813
39976
  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()
@@ -15873,6 +15951,8 @@ var NcSystemEventKindSchema = _enum([
15873
15951
  "device-offline",
15874
15952
  "device-disabled",
15875
15953
  "device-enabled",
15954
+ "device-battery-low",
15955
+ "device-battery-normal",
15876
15956
  "stream-online",
15877
15957
  "stream-offline",
15878
15958
  "node-online",
@@ -19131,46 +19211,6 @@ var RecentTracksPageSchema = object({
19131
19211
  /** Cursor for the next page, or null when this page is the last. */
19132
19212
  nextCursor: string().nullable()
19133
19213
  });
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
19214
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19175
19215
  var KEY_EVENTS_MAX_LIMIT = 200;
19176
19216
  var KeyEventQueryInput = object({
@@ -19274,9 +19314,7 @@ var TrackCascadeCountsSchema = object({
19274
19314
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19275
19315
  plates: number().int(),
19276
19316
  /** 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()
19317
+ embeddings: number().int()
19280
19318
  });
19281
19319
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19282
19320
  var DiskReconcileCountsSchema = object({
@@ -19446,6 +19484,47 @@ var RebuildStatusSchema = object({
19446
19484
  /** Present when the pass ended by throwing. */
19447
19485
  error: string().nullable()
19448
19486
  });
19487
+ /**
19488
+ * Acknowledgement that a debug-media reclaim STARTED.
19489
+ *
19490
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19491
+ * it runs detached and this returns immediately. Awaiting it is how the
19492
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19493
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19494
+ */
19495
+ var MediaReclaimStartResultSchema = object({
19496
+ started: boolean(),
19497
+ /** True when a pass was already running; the new request is ignored. */
19498
+ alreadyRunning: boolean()
19499
+ });
19500
+ var MediaReclaimInputSchema = object({
19501
+ mode: _enum(["report", "reclaim"]).default("report"),
19502
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19503
+ deviceIds: array(number().int()).min(1).optional(),
19504
+ restart: boolean().optional(),
19505
+ pageSize: number().int().min(50).max(5e3).optional(),
19506
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19507
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19508
+ maxBytesPerRun: number().int().min(1).optional(),
19509
+ budgetMinutes: number().int().min(1).max(720).optional(),
19510
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19511
+ graceMinutes: number().int().min(1).max(10080).optional()
19512
+ });
19513
+ var MediaReclaimStatusSchema = object({
19514
+ running: boolean(),
19515
+ mode: _enum(["report", "reclaim"]).nullable(),
19516
+ totalExamined: number(),
19517
+ totalEligible: number(),
19518
+ totalReclaimed: number(),
19519
+ totalBytesReclaimed: number(),
19520
+ totalRefused: number(),
19521
+ /** Device+scope windows finished in this pass. */
19522
+ devicesDone: number(),
19523
+ complete: boolean().nullable(),
19524
+ startedAtMs: number().nullable(),
19525
+ finishedAtMs: number().nullable(),
19526
+ error: string().nullable()
19527
+ });
19449
19528
  var ReplayFrameInputSchema = object({
19450
19529
  timestamp: number(),
19451
19530
  frame: PipelineRunResultBridge
@@ -19484,10 +19563,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19484
19563
  * stationary registry). Default false: the timeline lists passages,
19485
19564
  * not parking records (operator decision, 2026-08-15). */
19486
19565
  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(), {
19566
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19491
19567
  kind: "mutation",
19492
19568
  auth: "admin"
19493
19569
  }), 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 +19663,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19587
19663
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19588
19664
  kind: "query",
19589
19665
  auth: "admin"
19666
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19667
+ kind: "mutation",
19668
+ auth: "admin"
19669
+ }), method(object({}), MediaReclaimStatusSchema, {
19670
+ kind: "query",
19671
+ auth: "admin"
19590
19672
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19591
19673
  kind: "query",
19592
19674
  auth: "admin"
@@ -21557,7 +21639,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21557
21639
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21558
21640
  kind: "mutation",
21559
21641
  auth: "admin"
21560
- });
21642
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21643
+ kind: "mutation",
21644
+ auth: "admin"
21645
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21646
+ kind: "mutation",
21647
+ auth: "admin"
21648
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21561
21649
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21562
21650
  providerId: string().min(1),
21563
21651
  displayName: string().min(1),
@@ -28650,6 +28738,33 @@ var RecordingRebalanceInputSchema = object({
28650
28738
  minMoveGb: number().min(0).optional()
28651
28739
  });
28652
28740
  /**
28741
+ * Operator-facing placement of one camera onto a recordings location.
28742
+ *
28743
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
28744
+ * Auto (the planner may move this camera). `locationId` is where high/mid
28745
+ * currently write — the plan, which may disagree with the pin when Auto.
28746
+ */
28747
+ var RecordingDevicePlacementSchema = object({
28748
+ deviceId: number().int(),
28749
+ profile: string(),
28750
+ locationId: string()
28751
+ });
28752
+ var RecordingDevicePinSchema = object({
28753
+ deviceId: number().int(),
28754
+ /** Recordings-class location this camera is pinned to. */
28755
+ locationId: string()
28756
+ });
28757
+ var RecordingPlacementViewSchema = object({
28758
+ assignments: array(RecordingDevicePlacementSchema),
28759
+ pins: array(RecordingDevicePinSchema),
28760
+ defaultLocations: record(string(), string())
28761
+ });
28762
+ var RecordingSetDevicePlacementInputSchema = object({
28763
+ deviceId: number().int(),
28764
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
28765
+ locationId: string().nullable()
28766
+ });
28767
+ /**
28653
28768
  * Result of locating footage at a wall-clock instant for one device/profile.
28654
28769
  * `segment` carries the covering segment's window; `gap` reports the forward
28655
28770
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -28875,6 +28990,12 @@ method(object({
28875
28990
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
28876
28991
  kind: "mutation",
28877
28992
  auth: "admin"
28993
+ }), method(object({}), RecordingPlacementViewSchema, {
28994
+ kind: "query",
28995
+ auth: "admin"
28996
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
28997
+ kind: "mutation",
28998
+ auth: "admin"
28878
28999
  });
28879
29000
  /**
28880
29001
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -33944,6 +34065,12 @@ Object.freeze({
33944
34065
  addonId: null,
33945
34066
  access: "delete"
33946
34067
  },
34068
+ "deviceManager.renameLocation": {
34069
+ capName: "device-manager",
34070
+ capScope: "system",
34071
+ addonId: null,
34072
+ access: "create"
34073
+ },
33947
34074
  "deviceManager.runDeviceAction": {
33948
34075
  capName: "device-manager",
33949
34076
  capScope: "system",
@@ -35636,19 +35763,19 @@ Object.freeze({
35636
35763
  addonId: null,
35637
35764
  access: "view"
35638
35765
  },
35639
- "pipelineAnalytics.getGroup": {
35766
+ "pipelineAnalytics.getKeyEvents": {
35640
35767
  capName: "pipeline-analytics",
35641
35768
  capScope: "device",
35642
35769
  addonId: null,
35643
35770
  access: "view"
35644
35771
  },
35645
- "pipelineAnalytics.getKeyEvents": {
35772
+ "pipelineAnalytics.getKeyEventsBatch": {
35646
35773
  capName: "pipeline-analytics",
35647
35774
  capScope: "device",
35648
35775
  addonId: null,
35649
35776
  access: "view"
35650
35777
  },
35651
- "pipelineAnalytics.getKeyEventsBatch": {
35778
+ "pipelineAnalytics.getMediaReclaimStatus": {
35652
35779
  capName: "pipeline-analytics",
35653
35780
  capScope: "device",
35654
35781
  addonId: null,
@@ -35738,12 +35865,6 @@ Object.freeze({
35738
35865
  addonId: null,
35739
35866
  access: "view"
35740
35867
  },
35741
- "pipelineAnalytics.listGroups": {
35742
- capName: "pipeline-analytics",
35743
- capScope: "device",
35744
- addonId: null,
35745
- access: "view"
35746
- },
35747
35868
  "pipelineAnalytics.listOpsLog": {
35748
35869
  capName: "pipeline-analytics",
35749
35870
  capScope: "device",
@@ -35828,6 +35949,12 @@ Object.freeze({
35828
35949
  addonId: null,
35829
35950
  access: "create"
35830
35951
  },
35952
+ "pipelineAnalytics.reclaimDebugMedia": {
35953
+ capName: "pipeline-analytics",
35954
+ capScope: "device",
35955
+ addonId: null,
35956
+ access: "create"
35957
+ },
35831
35958
  "pipelineAnalytics.reconcileFromDisk": {
35832
35959
  capName: "pipeline-analytics",
35833
35960
  capScope: "device",
@@ -36752,6 +36879,12 @@ Object.freeze({
36752
36879
  addonId: null,
36753
36880
  access: "view"
36754
36881
  },
36882
+ "recording.getPlacement": {
36883
+ capName: "recording",
36884
+ capScope: "system",
36885
+ addonId: null,
36886
+ access: "view"
36887
+ },
36755
36888
  "recording.getPlaybackManifest": {
36756
36889
  capName: "recording",
36757
36890
  capScope: "system",
@@ -36878,6 +37011,12 @@ Object.freeze({
36878
37011
  addonId: null,
36879
37012
  access: "create"
36880
37013
  },
37014
+ "recording.setDevicePlacement": {
37015
+ capName: "recording",
37016
+ capScope: "system",
37017
+ addonId: null,
37018
+ access: "create"
37019
+ },
36881
37020
  "recording.startStorageMigrationMove": {
36882
37021
  capName: "recording",
36883
37022
  capScope: "system",
@@ -37322,12 +37461,36 @@ Object.freeze({
37322
37461
  addonId: null,
37323
37462
  access: "create"
37324
37463
  },
37464
+ "storageMigration.cleanupCancel": {
37465
+ capName: "storage-migration",
37466
+ capScope: "system",
37467
+ addonId: null,
37468
+ access: "create"
37469
+ },
37470
+ "storageMigration.cleanupStart": {
37471
+ capName: "storage-migration",
37472
+ capScope: "system",
37473
+ addonId: null,
37474
+ access: "create"
37475
+ },
37476
+ "storageMigration.cleanupStatus": {
37477
+ capName: "storage-migration",
37478
+ capScope: "system",
37479
+ addonId: null,
37480
+ access: "view"
37481
+ },
37325
37482
  "storageMigration.drain": {
37326
37483
  capName: "storage-migration",
37327
37484
  capScope: "system",
37328
37485
  addonId: null,
37329
37486
  access: "create"
37330
37487
  },
37488
+ "storageMigration.history": {
37489
+ capName: "storage-migration",
37490
+ capScope: "system",
37491
+ addonId: null,
37492
+ access: "view"
37493
+ },
37331
37494
  "storageMigration.movers": {
37332
37495
  capName: "storage-migration",
37333
37496
  capScope: "system",
@@ -39324,11 +39487,6 @@ Object.freeze({
39324
39487
  form: "single",
39325
39488
  optional: true
39326
39489
  }],
39327
- "pipelineAnalytics.getGroup": [{
39328
- name: "deviceId",
39329
- form: "single",
39330
- optional: false
39331
- }],
39332
39490
  "pipelineAnalytics.getKeyEvents": [{
39333
39491
  name: "deviceId",
39334
39492
  form: "single",
@@ -39394,11 +39552,6 @@ Object.freeze({
39394
39552
  form: "single",
39395
39553
  optional: false
39396
39554
  }],
39397
- "pipelineAnalytics.listGroups": [{
39398
- name: "deviceIds",
39399
- form: "array",
39400
- optional: false
39401
- }],
39402
39555
  "pipelineAnalytics.listOpsLog": [{
39403
39556
  name: "deviceId",
39404
39557
  form: "single",
@@ -39444,6 +39597,11 @@ Object.freeze({
39444
39597
  form: "single",
39445
39598
  optional: true
39446
39599
  }],
39600
+ "pipelineAnalytics.reclaimDebugMedia": [{
39601
+ name: "deviceIds",
39602
+ form: "array",
39603
+ optional: true
39604
+ }],
39447
39605
  "pipelineAnalytics.reconcileFromDisk": [{
39448
39606
  name: "deviceId",
39449
39607
  form: "single",
@@ -39809,6 +39967,11 @@ Object.freeze({
39809
39967
  form: "single",
39810
39968
  optional: false
39811
39969
  }],
39970
+ "recording.setDevicePlacement": [{
39971
+ name: "deviceId",
39972
+ form: "single",
39973
+ optional: false
39974
+ }],
39812
39975
  "recording.startStorageMigrationMove": [{
39813
39976
  name: "deviceId",
39814
39977
  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.52",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",