@camstack/addon-provider-wyze 0.2.52 → 0.2.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +246 -2
- package/dist/addon.mjs +246 -2
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -8050,6 +8050,20 @@ var RelocateJobSchema = object({
|
|
|
8050
8050
|
* in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
|
|
8051
8051
|
*/
|
|
8052
8052
|
rowsReconciled: number().int().nonnegative().optional(),
|
|
8053
|
+
/**
|
|
8054
|
+
* Rows this run FORGOT because the file they name is not on disk.
|
|
8055
|
+
*
|
|
8056
|
+
* The mover derived the path from the row's own fields and `stat`ed it; an
|
|
8057
|
+
* ENOENT there is a per-path confirmation that the segment is gone (D296),
|
|
8058
|
+
* and the durable row is dropped through the same channel eviction uses. It
|
|
8059
|
+
* is reported for the same reason `rowsReconciled` is: this is a durable
|
|
8060
|
+
* mutation nobody asked for, and a migration that quietly erases hour rows is
|
|
8061
|
+
* the same failure as one that quietly skips them (D295).
|
|
8062
|
+
*
|
|
8063
|
+
* The production drain of 2026-08-30 would have reported 11 074 here — the
|
|
8064
|
+
* ledger claimed 5.65 GB of footage that no longer existed.
|
|
8065
|
+
*/
|
|
8066
|
+
rowsForgotten: number().int().nonnegative().optional(),
|
|
8053
8067
|
startedAt: number(),
|
|
8054
8068
|
finishedAt: number().nullable(),
|
|
8055
8069
|
error: string().nullable()
|
|
@@ -8413,6 +8427,91 @@ var RelocateResidueSchema = object({
|
|
|
8413
8427
|
segments: number().int().nonnegative(),
|
|
8414
8428
|
bytes: number().int().nonnegative()
|
|
8415
8429
|
}).nullable();
|
|
8430
|
+
/**
|
|
8431
|
+
* Ask one location whether its durable hour rows describe the disk — the walk
|
|
8432
|
+
* (D319).
|
|
8433
|
+
*
|
|
8434
|
+
* `apply` DEFAULTS TO FALSE and that default is the product: the operator's
|
|
8435
|
+
* missing tool is the question, and the dry run is how they sanity-check the
|
|
8436
|
+
* destructive run before authorising it.
|
|
8437
|
+
*/
|
|
8438
|
+
var LedgerWalkInputSchema = object({
|
|
8439
|
+
locationId: string().min(1),
|
|
8440
|
+
/** Forget the confirmed-absent rows, rather than only counting them. */
|
|
8441
|
+
apply: boolean().optional(),
|
|
8442
|
+
/** Narrow to one camera. */
|
|
8443
|
+
deviceId: number().int().positive().optional(),
|
|
8444
|
+
/** Narrow to these recording profiles; empty/absent = every profile. */
|
|
8445
|
+
profiles: array(string().min(1)).optional()
|
|
8446
|
+
});
|
|
8447
|
+
/** Why a whole walk did nothing. Every one leaves the ledger untouched. */
|
|
8448
|
+
var LedgerWalkRefusalSchema = _enum([
|
|
8449
|
+
"location-unknown",
|
|
8450
|
+
"source-writable",
|
|
8451
|
+
"no-ledger",
|
|
8452
|
+
"archive-unreadable",
|
|
8453
|
+
"anchor-absent",
|
|
8454
|
+
"anchor-unreadable",
|
|
8455
|
+
"anchor-moved"
|
|
8456
|
+
]);
|
|
8457
|
+
_enum([
|
|
8458
|
+
"live-tail",
|
|
8459
|
+
"listing-error",
|
|
8460
|
+
"path-mismatch",
|
|
8461
|
+
"durable-refused"
|
|
8462
|
+
]);
|
|
8463
|
+
/** Every skip reason, always present, always a number — so a reason that never
|
|
8464
|
+
* fired reports as zero rather than absent and the report shape is constant
|
|
8465
|
+
* between passes. Spelled out rather than `z.record` for exactly that. */
|
|
8466
|
+
var LedgerWalkSkipCountsSchema = object({
|
|
8467
|
+
"live-tail": number().int().nonnegative(),
|
|
8468
|
+
"listing-error": number().int().nonnegative(),
|
|
8469
|
+
"path-mismatch": number().int().nonnegative(),
|
|
8470
|
+
"durable-refused": number().int().nonnegative()
|
|
8471
|
+
});
|
|
8472
|
+
/** One camera's share of a walk, so a report names cameras and not rows. */
|
|
8473
|
+
var LedgerWalkDeviceReportSchema = object({
|
|
8474
|
+
deviceId: number().int(),
|
|
8475
|
+
hoursWalked: number().int().nonnegative(),
|
|
8476
|
+
hoursMissing: number().int().nonnegative(),
|
|
8477
|
+
ghostSegments: number().int().nonnegative(),
|
|
8478
|
+
ghostBytes: number().int().nonnegative(),
|
|
8479
|
+
forgottenSegments: number().int().nonnegative(),
|
|
8480
|
+
orphanFiles: number().int().nonnegative()
|
|
8481
|
+
});
|
|
8482
|
+
/**
|
|
8483
|
+
* What one walk claimed, listed, found and (only when armed) forgot.
|
|
8484
|
+
*
|
|
8485
|
+
* `archiveSegments` is the **M** and `segmentsClaimed` the **N** (D295), so a
|
|
8486
|
+
* walk that saw a fraction of the location is visible in its own report rather
|
|
8487
|
+
* than in the absence of one.
|
|
8488
|
+
*/
|
|
8489
|
+
var LedgerWalkReportSchema = object({
|
|
8490
|
+
locationId: string(),
|
|
8491
|
+
applied: boolean(),
|
|
8492
|
+
refused: LedgerWalkRefusalSchema.nullable(),
|
|
8493
|
+
archiveSegments: number().int().nonnegative().nullable(),
|
|
8494
|
+
archiveBytes: number().int().nonnegative().nullable(),
|
|
8495
|
+
hoursClaimed: number().int().nonnegative(),
|
|
8496
|
+
hoursWalked: number().int().nonnegative(),
|
|
8497
|
+
hoursMissing: number().int().nonnegative(),
|
|
8498
|
+
/** `readdir` calls issued — the cost, stated in the unit that is paid. */
|
|
8499
|
+
listings: number().int().nonnegative(),
|
|
8500
|
+
segmentsClaimed: number().int().nonnegative(),
|
|
8501
|
+
ghostSegments: number().int().nonnegative(),
|
|
8502
|
+
ghostBytes: number().int().nonnegative(),
|
|
8503
|
+
ghostHoursWhole: number().int().nonnegative(),
|
|
8504
|
+
forgottenSegments: number().int().nonnegative(),
|
|
8505
|
+
forgottenBytes: number().int().nonnegative(),
|
|
8506
|
+
/** Files under a claimed hour that no durable row names. Never deleted. */
|
|
8507
|
+
orphanFiles: number().int().nonnegative(),
|
|
8508
|
+
orphanSample: array(string()).readonly(),
|
|
8509
|
+
hoursSkipped: number().int().nonnegative(),
|
|
8510
|
+
skippedByReason: LedgerWalkSkipCountsSchema,
|
|
8511
|
+
/** The walk stopped at its per-pass hour bound with claims unwalked. */
|
|
8512
|
+
bounded: boolean(),
|
|
8513
|
+
byDevice: array(LedgerWalkDeviceReportSchema).readonly()
|
|
8514
|
+
});
|
|
8416
8515
|
/** How many rows a media pass would still act on against a given target — the
|
|
8417
8516
|
* media lane's denominator AND its residue, from ONE derivation so the two can
|
|
8418
8517
|
* never disagree. `null` = the count could not be taken. */
|
|
@@ -19045,13 +19144,15 @@ var ListGroupsPageSchema = object({
|
|
|
19045
19144
|
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
19046
19145
|
nextCursor: string().nullable()
|
|
19047
19146
|
});
|
|
19147
|
+
var KEY_EVENTS_DEFAULT_LIMIT = 50;
|
|
19148
|
+
var KEY_EVENTS_MAX_LIMIT = 200;
|
|
19048
19149
|
var KeyEventQueryInput = object({
|
|
19049
19150
|
deviceId: number(),
|
|
19050
19151
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
19051
19152
|
since: number(),
|
|
19052
19153
|
/** Window upper bound (track firstSeen ≤ until). */
|
|
19053
19154
|
until: number(),
|
|
19054
|
-
limit: number().int().min(1).max(
|
|
19155
|
+
limit: number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
19055
19156
|
/** Drop tracks scoring below this importance. */
|
|
19056
19157
|
minImportance: number().min(0).max(1).optional(),
|
|
19057
19158
|
/** Restrict to a single class (e.g. 'person'). */
|
|
@@ -19073,6 +19174,32 @@ var KeyEventSchema = object({
|
|
|
19073
19174
|
...TrackFlagFields,
|
|
19074
19175
|
...TrackRetrainFields
|
|
19075
19176
|
});
|
|
19177
|
+
/** `getKeyEvents`' window and filters, asked of a SET of cameras at once. */
|
|
19178
|
+
var KeyEventBatchQueryInput = object({
|
|
19179
|
+
deviceIds: array(number()).min(1).max(200),
|
|
19180
|
+
since: number(),
|
|
19181
|
+
until: number(),
|
|
19182
|
+
/** Applied PER CAMERA, exactly as `getKeyEvents.limit` is — never a total
|
|
19183
|
+
* across the set, which would let a busy camera starve a quiet one of its
|
|
19184
|
+
* rows and change what the merged feed contains. */
|
|
19185
|
+
limit: number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
19186
|
+
minImportance: number().min(0).max(1).optional(),
|
|
19187
|
+
classFilter: string().optional()
|
|
19188
|
+
});
|
|
19189
|
+
/**
|
|
19190
|
+
* One camera's key events in a batch answer.
|
|
19191
|
+
*
|
|
19192
|
+
* The row exists for every requested id. `getKeyEvents` degrades to `[]` on
|
|
19193
|
+
* error rather than throwing, so a camera whose store read failed and one with
|
|
19194
|
+
* no events in the window were ALREADY indistinguishable per camera — the
|
|
19195
|
+
* batch does not make that worse, and the row keeps the deviceId the single
|
|
19196
|
+
* method's output never carried (the caller used to stamp it from the fan-out
|
|
19197
|
+
* key, which only worked because there was one query per camera).
|
|
19198
|
+
*/
|
|
19199
|
+
var KeyEventsForDeviceSchema = object({
|
|
19200
|
+
deviceId: number(),
|
|
19201
|
+
events: array(KeyEventSchema).readonly()
|
|
19202
|
+
});
|
|
19076
19203
|
object({
|
|
19077
19204
|
trackId: string(),
|
|
19078
19205
|
className: string(),
|
|
@@ -19342,7 +19469,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19342
19469
|
until: number().optional(),
|
|
19343
19470
|
kinds: array(string()).optional(),
|
|
19344
19471
|
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19345
|
-
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
19472
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(KeyEventBatchQueryInput, array(KeyEventsForDeviceSchema).readonly()), method(object({
|
|
19346
19473
|
deviceId: number(),
|
|
19347
19474
|
since: number(),
|
|
19348
19475
|
until: number(),
|
|
@@ -28821,6 +28948,9 @@ method(object({
|
|
|
28821
28948
|
}), method(RelocateResidueInputSchema, RelocateResidueSchema, {
|
|
28822
28949
|
kind: "query",
|
|
28823
28950
|
auth: "admin"
|
|
28951
|
+
}), method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
|
|
28952
|
+
kind: "mutation",
|
|
28953
|
+
auth: "admin"
|
|
28824
28954
|
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
28825
28955
|
kind: "mutation",
|
|
28826
28956
|
auth: "admin"
|
|
@@ -29212,6 +29342,25 @@ var SceneMonitorStatusSchema = object({
|
|
|
29212
29342
|
monitors: array(SceneMonitorSchema),
|
|
29213
29343
|
lastFetchedAt: number()
|
|
29214
29344
|
});
|
|
29345
|
+
/**
|
|
29346
|
+
* One camera's row in a `listScenesBatch` answer.
|
|
29347
|
+
*
|
|
29348
|
+
* `status` is NULLABLE and the nullability is the whole point. `scene-monitor`
|
|
29349
|
+
* is a `defaultActive` wrapper, so every camera is asked; a camera whose
|
|
29350
|
+
* provider is absent (pipeline-analytics not deployed, the post-processing node
|
|
29351
|
+
* down) cannot answer, and that is not the same fact as a camera with no scenes
|
|
29352
|
+
* configured. Fanned out per camera the difference was visible — one query
|
|
29353
|
+
* errored while the others resolved — and a batch that returned only the rows
|
|
29354
|
+
* it managed would have destroyed it, silently, by making an unreachable camera
|
|
29355
|
+
* indistinguishable from one that answered `monitors: []`.
|
|
29356
|
+
*
|
|
29357
|
+
* So: EVERY requested deviceId gets a row. `status: null` means "this camera
|
|
29358
|
+
* could not be read"; `status.monitors: []` means "read, and it has none".
|
|
29359
|
+
*/
|
|
29360
|
+
var SceneMonitorStatusForDeviceSchema = object({
|
|
29361
|
+
deviceId: number(),
|
|
29362
|
+
status: SceneMonitorStatusSchema.nullable()
|
|
29363
|
+
});
|
|
29215
29364
|
var sceneMonitorCapability = {
|
|
29216
29365
|
name: "scene-monitor",
|
|
29217
29366
|
scope: "device",
|
|
@@ -29221,6 +29370,22 @@ var sceneMonitorCapability = {
|
|
|
29221
29370
|
deviceTypes: [DeviceType.Camera],
|
|
29222
29371
|
methods: {
|
|
29223
29372
|
listScenes: method(object({ deviceId: number() }), SceneMonitorStatusSchema),
|
|
29373
|
+
/**
|
|
29374
|
+
* The same answer, for a SET of cameras, in one round trip.
|
|
29375
|
+
*
|
|
29376
|
+
* `/scenes` renders every camera and re-reads them on a 30s safety-net
|
|
29377
|
+
* poll behind the push slice. Fanned out client-side that was one query
|
|
29378
|
+
* per camera — 29 round trips through the browser, the hub and the
|
|
29379
|
+
* post-analysis runner every 30 seconds to read an in-memory map the
|
|
29380
|
+
* owner had already merged. The work is unchanged (`statusFor` per
|
|
29381
|
+
* device, all in-process at the owner); what collapses is the transport.
|
|
29382
|
+
*
|
|
29383
|
+
* A camera that cannot answer still gets a row, with `status: null` —
|
|
29384
|
+
* see {@link SceneMonitorStatusForDeviceSchema}. Never fewer rows than
|
|
29385
|
+
* ids: a caller that asked for twenty-nine and got twenty-seven cannot
|
|
29386
|
+
* tell which two are missing, or that any are.
|
|
29387
|
+
*/
|
|
29388
|
+
listScenesBatch: method(object({ deviceIds: array(number()).min(1).max(200) }), array(SceneMonitorStatusForDeviceSchema).readonly()),
|
|
29224
29389
|
createScene: method(object({
|
|
29225
29390
|
deviceId: number(),
|
|
29226
29391
|
label: string(),
|
|
@@ -31056,6 +31221,27 @@ var CameraOccupancySnapshotSchema = object({
|
|
|
31056
31221
|
stationaryObjects: array(StationaryObjectSchema).readonly().optional()
|
|
31057
31222
|
});
|
|
31058
31223
|
/**
|
|
31224
|
+
* One camera's row in a `getCurrentSnapshotBatch` answer.
|
|
31225
|
+
*
|
|
31226
|
+
* THREE outcomes, and the single-camera method could only express two of them
|
|
31227
|
+
* because `snapshot: null` was already spoken for:
|
|
31228
|
+
*
|
|
31229
|
+
* - `read: 'read'`, `snapshot` present — the live occupancy reading.
|
|
31230
|
+
* - `read: 'read'`, `snapshot: null` — read, and this camera has no reading
|
|
31231
|
+
* yet: no frame since boot, and no parked-object registry to hydrate from.
|
|
31232
|
+
* - `read: 'unreadable'` — the owner could not answer for this
|
|
31233
|
+
* camera. `snapshot` is null, and it does NOT mean "nothing parked here".
|
|
31234
|
+
*
|
|
31235
|
+
* Collapsing the last two is the failure this field exists to prevent: a
|
|
31236
|
+
* hydration that threw would otherwise render as an empty Stationary section,
|
|
31237
|
+
* which is a definite claim about a camera nobody could read.
|
|
31238
|
+
*/
|
|
31239
|
+
var CameraOccupancySnapshotForDeviceSchema = object({
|
|
31240
|
+
deviceId: number(),
|
|
31241
|
+
read: _enum(["read", "unreadable"]),
|
|
31242
|
+
snapshot: CameraOccupancySnapshotSchema.nullable()
|
|
31243
|
+
});
|
|
31244
|
+
/**
|
|
31059
31245
|
* Time-series resolution. The history methods return one bucket per
|
|
31060
31246
|
* step over the requested range. Smaller resolutions cost more
|
|
31061
31247
|
* memory + bandwidth; bound to discrete steps so caller cannot ask
|
|
@@ -31112,6 +31298,20 @@ var zoneAnalyticsCapability = {
|
|
|
31112
31298
|
* (no inference result emitted since boot or since binding was
|
|
31113
31299
|
* activated). */
|
|
31114
31300
|
getCurrentSnapshot: method(object({ deviceId: number() }), CameraOccupancySnapshotSchema.nullable()),
|
|
31301
|
+
/**
|
|
31302
|
+
* The same snapshot, for a SET of cameras, in one round trip.
|
|
31303
|
+
*
|
|
31304
|
+
* The Events page's Stationary section polls this every 15s for every
|
|
31305
|
+
* selected camera. Fanned out client-side that is one query per camera to
|
|
31306
|
+
* read a `Map.get` at the owner — the answer costs nothing, the round trip
|
|
31307
|
+
* costs everything. Batched, N transports become one and the per-device
|
|
31308
|
+
* work is unchanged.
|
|
31309
|
+
*
|
|
31310
|
+
* Every requested deviceId gets a row, tagged `read` — see
|
|
31311
|
+
* {@link CameraOccupancySnapshotForDeviceSchema}. A camera the owner could
|
|
31312
|
+
* not answer for is `'unreadable'`, never an empty reading.
|
|
31313
|
+
*/
|
|
31314
|
+
getCurrentSnapshotBatch: method(object({ deviceIds: array(number()).min(1).max(200) }), array(CameraOccupancySnapshotForDeviceSchema).readonly()),
|
|
31115
31315
|
/** Time-series object count inside one zone. `className` optional —
|
|
31116
31316
|
* omit to count every class in the zone. */
|
|
31117
31317
|
getZoneHistory: method(object({
|
|
@@ -35533,6 +35733,12 @@ Object.freeze({
|
|
|
35533
35733
|
addonId: null,
|
|
35534
35734
|
access: "view"
|
|
35535
35735
|
},
|
|
35736
|
+
"pipelineAnalytics.getKeyEventsBatch": {
|
|
35737
|
+
capName: "pipeline-analytics",
|
|
35738
|
+
capScope: "device",
|
|
35739
|
+
addonId: null,
|
|
35740
|
+
access: "view"
|
|
35741
|
+
},
|
|
35536
35742
|
"pipelineAnalytics.getMotionEvents": {
|
|
35537
35743
|
capName: "pipeline-analytics",
|
|
35538
35744
|
capScope: "device",
|
|
@@ -36709,6 +36915,12 @@ Object.freeze({
|
|
|
36709
36915
|
addonId: null,
|
|
36710
36916
|
access: "view"
|
|
36711
36917
|
},
|
|
36918
|
+
"recording.reconcileLedgerAgainstDisk": {
|
|
36919
|
+
capName: "recording",
|
|
36920
|
+
capScope: "system",
|
|
36921
|
+
addonId: null,
|
|
36922
|
+
access: "create"
|
|
36923
|
+
},
|
|
36712
36924
|
"recording.refreshStorageLocationsForMigration": {
|
|
36713
36925
|
capName: "recording",
|
|
36714
36926
|
capScope: "system",
|
|
@@ -36835,6 +37047,12 @@ Object.freeze({
|
|
|
36835
37047
|
addonId: null,
|
|
36836
37048
|
access: "view"
|
|
36837
37049
|
},
|
|
37050
|
+
"sceneMonitor.listScenesBatch": {
|
|
37051
|
+
capName: "scene-monitor",
|
|
37052
|
+
capScope: "device",
|
|
37053
|
+
addonId: null,
|
|
37054
|
+
access: "view"
|
|
37055
|
+
},
|
|
36838
37056
|
"sceneMonitor.recheckNow": {
|
|
36839
37057
|
capName: "scene-monitor",
|
|
36840
37058
|
capScope: "device",
|
|
@@ -38191,6 +38409,12 @@ Object.freeze({
|
|
|
38191
38409
|
addonId: null,
|
|
38192
38410
|
access: "view"
|
|
38193
38411
|
},
|
|
38412
|
+
"zoneAnalytics.getCurrentSnapshotBatch": {
|
|
38413
|
+
capName: "zone-analytics",
|
|
38414
|
+
capScope: "device",
|
|
38415
|
+
addonId: null,
|
|
38416
|
+
access: "view"
|
|
38417
|
+
},
|
|
38194
38418
|
"zoneAnalytics.getUnzonedHistory": {
|
|
38195
38419
|
capName: "zone-analytics",
|
|
38196
38420
|
capScope: "device",
|
|
@@ -39195,6 +39419,11 @@ Object.freeze({
|
|
|
39195
39419
|
form: "single",
|
|
39196
39420
|
optional: false
|
|
39197
39421
|
}],
|
|
39422
|
+
"pipelineAnalytics.getKeyEventsBatch": [{
|
|
39423
|
+
name: "deviceIds",
|
|
39424
|
+
form: "array",
|
|
39425
|
+
optional: false
|
|
39426
|
+
}],
|
|
39198
39427
|
"pipelineAnalytics.getMotionEvents": [{
|
|
39199
39428
|
name: "deviceId",
|
|
39200
39429
|
form: "single",
|
|
@@ -39635,6 +39864,11 @@ Object.freeze({
|
|
|
39635
39864
|
form: "single",
|
|
39636
39865
|
optional: false
|
|
39637
39866
|
}],
|
|
39867
|
+
"recording.reconcileLedgerAgainstDisk": [{
|
|
39868
|
+
name: "deviceId",
|
|
39869
|
+
form: "single",
|
|
39870
|
+
optional: true
|
|
39871
|
+
}],
|
|
39638
39872
|
"recording.relocateFootage": [{
|
|
39639
39873
|
name: "deviceId",
|
|
39640
39874
|
form: "single",
|
|
@@ -39700,6 +39934,11 @@ Object.freeze({
|
|
|
39700
39934
|
form: "single",
|
|
39701
39935
|
optional: false
|
|
39702
39936
|
}],
|
|
39937
|
+
"sceneMonitor.listScenesBatch": [{
|
|
39938
|
+
name: "deviceIds",
|
|
39939
|
+
form: "array",
|
|
39940
|
+
optional: false
|
|
39941
|
+
}],
|
|
39703
39942
|
"sceneMonitor.recheckNow": [{
|
|
39704
39943
|
name: "deviceId",
|
|
39705
39944
|
form: "single",
|
|
@@ -39961,6 +40200,11 @@ Object.freeze({
|
|
|
39961
40200
|
form: "single",
|
|
39962
40201
|
optional: false
|
|
39963
40202
|
}],
|
|
40203
|
+
"zoneAnalytics.getCurrentSnapshotBatch": [{
|
|
40204
|
+
name: "deviceIds",
|
|
40205
|
+
form: "array",
|
|
40206
|
+
optional: false
|
|
40207
|
+
}],
|
|
39964
40208
|
"zoneAnalytics.getUnzonedHistory": [{
|
|
39965
40209
|
name: "deviceId",
|
|
39966
40210
|
form: "single",
|
package/dist/addon.mjs
CHANGED
|
@@ -8029,6 +8029,20 @@ var RelocateJobSchema = object({
|
|
|
8029
8029
|
* in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
|
|
8030
8030
|
*/
|
|
8031
8031
|
rowsReconciled: number().int().nonnegative().optional(),
|
|
8032
|
+
/**
|
|
8033
|
+
* Rows this run FORGOT because the file they name is not on disk.
|
|
8034
|
+
*
|
|
8035
|
+
* The mover derived the path from the row's own fields and `stat`ed it; an
|
|
8036
|
+
* ENOENT there is a per-path confirmation that the segment is gone (D296),
|
|
8037
|
+
* and the durable row is dropped through the same channel eviction uses. It
|
|
8038
|
+
* is reported for the same reason `rowsReconciled` is: this is a durable
|
|
8039
|
+
* mutation nobody asked for, and a migration that quietly erases hour rows is
|
|
8040
|
+
* the same failure as one that quietly skips them (D295).
|
|
8041
|
+
*
|
|
8042
|
+
* The production drain of 2026-08-30 would have reported 11 074 here — the
|
|
8043
|
+
* ledger claimed 5.65 GB of footage that no longer existed.
|
|
8044
|
+
*/
|
|
8045
|
+
rowsForgotten: number().int().nonnegative().optional(),
|
|
8032
8046
|
startedAt: number(),
|
|
8033
8047
|
finishedAt: number().nullable(),
|
|
8034
8048
|
error: string().nullable()
|
|
@@ -8392,6 +8406,91 @@ var RelocateResidueSchema = object({
|
|
|
8392
8406
|
segments: number().int().nonnegative(),
|
|
8393
8407
|
bytes: number().int().nonnegative()
|
|
8394
8408
|
}).nullable();
|
|
8409
|
+
/**
|
|
8410
|
+
* Ask one location whether its durable hour rows describe the disk — the walk
|
|
8411
|
+
* (D319).
|
|
8412
|
+
*
|
|
8413
|
+
* `apply` DEFAULTS TO FALSE and that default is the product: the operator's
|
|
8414
|
+
* missing tool is the question, and the dry run is how they sanity-check the
|
|
8415
|
+
* destructive run before authorising it.
|
|
8416
|
+
*/
|
|
8417
|
+
var LedgerWalkInputSchema = object({
|
|
8418
|
+
locationId: string().min(1),
|
|
8419
|
+
/** Forget the confirmed-absent rows, rather than only counting them. */
|
|
8420
|
+
apply: boolean().optional(),
|
|
8421
|
+
/** Narrow to one camera. */
|
|
8422
|
+
deviceId: number().int().positive().optional(),
|
|
8423
|
+
/** Narrow to these recording profiles; empty/absent = every profile. */
|
|
8424
|
+
profiles: array(string().min(1)).optional()
|
|
8425
|
+
});
|
|
8426
|
+
/** Why a whole walk did nothing. Every one leaves the ledger untouched. */
|
|
8427
|
+
var LedgerWalkRefusalSchema = _enum([
|
|
8428
|
+
"location-unknown",
|
|
8429
|
+
"source-writable",
|
|
8430
|
+
"no-ledger",
|
|
8431
|
+
"archive-unreadable",
|
|
8432
|
+
"anchor-absent",
|
|
8433
|
+
"anchor-unreadable",
|
|
8434
|
+
"anchor-moved"
|
|
8435
|
+
]);
|
|
8436
|
+
_enum([
|
|
8437
|
+
"live-tail",
|
|
8438
|
+
"listing-error",
|
|
8439
|
+
"path-mismatch",
|
|
8440
|
+
"durable-refused"
|
|
8441
|
+
]);
|
|
8442
|
+
/** Every skip reason, always present, always a number — so a reason that never
|
|
8443
|
+
* fired reports as zero rather than absent and the report shape is constant
|
|
8444
|
+
* between passes. Spelled out rather than `z.record` for exactly that. */
|
|
8445
|
+
var LedgerWalkSkipCountsSchema = object({
|
|
8446
|
+
"live-tail": number().int().nonnegative(),
|
|
8447
|
+
"listing-error": number().int().nonnegative(),
|
|
8448
|
+
"path-mismatch": number().int().nonnegative(),
|
|
8449
|
+
"durable-refused": number().int().nonnegative()
|
|
8450
|
+
});
|
|
8451
|
+
/** One camera's share of a walk, so a report names cameras and not rows. */
|
|
8452
|
+
var LedgerWalkDeviceReportSchema = object({
|
|
8453
|
+
deviceId: number().int(),
|
|
8454
|
+
hoursWalked: number().int().nonnegative(),
|
|
8455
|
+
hoursMissing: number().int().nonnegative(),
|
|
8456
|
+
ghostSegments: number().int().nonnegative(),
|
|
8457
|
+
ghostBytes: number().int().nonnegative(),
|
|
8458
|
+
forgottenSegments: number().int().nonnegative(),
|
|
8459
|
+
orphanFiles: number().int().nonnegative()
|
|
8460
|
+
});
|
|
8461
|
+
/**
|
|
8462
|
+
* What one walk claimed, listed, found and (only when armed) forgot.
|
|
8463
|
+
*
|
|
8464
|
+
* `archiveSegments` is the **M** and `segmentsClaimed` the **N** (D295), so a
|
|
8465
|
+
* walk that saw a fraction of the location is visible in its own report rather
|
|
8466
|
+
* than in the absence of one.
|
|
8467
|
+
*/
|
|
8468
|
+
var LedgerWalkReportSchema = object({
|
|
8469
|
+
locationId: string(),
|
|
8470
|
+
applied: boolean(),
|
|
8471
|
+
refused: LedgerWalkRefusalSchema.nullable(),
|
|
8472
|
+
archiveSegments: number().int().nonnegative().nullable(),
|
|
8473
|
+
archiveBytes: number().int().nonnegative().nullable(),
|
|
8474
|
+
hoursClaimed: number().int().nonnegative(),
|
|
8475
|
+
hoursWalked: number().int().nonnegative(),
|
|
8476
|
+
hoursMissing: number().int().nonnegative(),
|
|
8477
|
+
/** `readdir` calls issued — the cost, stated in the unit that is paid. */
|
|
8478
|
+
listings: number().int().nonnegative(),
|
|
8479
|
+
segmentsClaimed: number().int().nonnegative(),
|
|
8480
|
+
ghostSegments: number().int().nonnegative(),
|
|
8481
|
+
ghostBytes: number().int().nonnegative(),
|
|
8482
|
+
ghostHoursWhole: number().int().nonnegative(),
|
|
8483
|
+
forgottenSegments: number().int().nonnegative(),
|
|
8484
|
+
forgottenBytes: number().int().nonnegative(),
|
|
8485
|
+
/** Files under a claimed hour that no durable row names. Never deleted. */
|
|
8486
|
+
orphanFiles: number().int().nonnegative(),
|
|
8487
|
+
orphanSample: array(string()).readonly(),
|
|
8488
|
+
hoursSkipped: number().int().nonnegative(),
|
|
8489
|
+
skippedByReason: LedgerWalkSkipCountsSchema,
|
|
8490
|
+
/** The walk stopped at its per-pass hour bound with claims unwalked. */
|
|
8491
|
+
bounded: boolean(),
|
|
8492
|
+
byDevice: array(LedgerWalkDeviceReportSchema).readonly()
|
|
8493
|
+
});
|
|
8395
8494
|
/** How many rows a media pass would still act on against a given target — the
|
|
8396
8495
|
* media lane's denominator AND its residue, from ONE derivation so the two can
|
|
8397
8496
|
* never disagree. `null` = the count could not be taken. */
|
|
@@ -19024,13 +19123,15 @@ var ListGroupsPageSchema = object({
|
|
|
19024
19123
|
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
19025
19124
|
nextCursor: string().nullable()
|
|
19026
19125
|
});
|
|
19126
|
+
var KEY_EVENTS_DEFAULT_LIMIT = 50;
|
|
19127
|
+
var KEY_EVENTS_MAX_LIMIT = 200;
|
|
19027
19128
|
var KeyEventQueryInput = object({
|
|
19028
19129
|
deviceId: number(),
|
|
19029
19130
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
19030
19131
|
since: number(),
|
|
19031
19132
|
/** Window upper bound (track firstSeen ≤ until). */
|
|
19032
19133
|
until: number(),
|
|
19033
|
-
limit: number().int().min(1).max(
|
|
19134
|
+
limit: number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
19034
19135
|
/** Drop tracks scoring below this importance. */
|
|
19035
19136
|
minImportance: number().min(0).max(1).optional(),
|
|
19036
19137
|
/** Restrict to a single class (e.g. 'person'). */
|
|
@@ -19052,6 +19153,32 @@ var KeyEventSchema = object({
|
|
|
19052
19153
|
...TrackFlagFields,
|
|
19053
19154
|
...TrackRetrainFields
|
|
19054
19155
|
});
|
|
19156
|
+
/** `getKeyEvents`' window and filters, asked of a SET of cameras at once. */
|
|
19157
|
+
var KeyEventBatchQueryInput = object({
|
|
19158
|
+
deviceIds: array(number()).min(1).max(200),
|
|
19159
|
+
since: number(),
|
|
19160
|
+
until: number(),
|
|
19161
|
+
/** Applied PER CAMERA, exactly as `getKeyEvents.limit` is — never a total
|
|
19162
|
+
* across the set, which would let a busy camera starve a quiet one of its
|
|
19163
|
+
* rows and change what the merged feed contains. */
|
|
19164
|
+
limit: number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
19165
|
+
minImportance: number().min(0).max(1).optional(),
|
|
19166
|
+
classFilter: string().optional()
|
|
19167
|
+
});
|
|
19168
|
+
/**
|
|
19169
|
+
* One camera's key events in a batch answer.
|
|
19170
|
+
*
|
|
19171
|
+
* The row exists for every requested id. `getKeyEvents` degrades to `[]` on
|
|
19172
|
+
* error rather than throwing, so a camera whose store read failed and one with
|
|
19173
|
+
* no events in the window were ALREADY indistinguishable per camera — the
|
|
19174
|
+
* batch does not make that worse, and the row keeps the deviceId the single
|
|
19175
|
+
* method's output never carried (the caller used to stamp it from the fan-out
|
|
19176
|
+
* key, which only worked because there was one query per camera).
|
|
19177
|
+
*/
|
|
19178
|
+
var KeyEventsForDeviceSchema = object({
|
|
19179
|
+
deviceId: number(),
|
|
19180
|
+
events: array(KeyEventSchema).readonly()
|
|
19181
|
+
});
|
|
19055
19182
|
object({
|
|
19056
19183
|
trackId: string(),
|
|
19057
19184
|
className: string(),
|
|
@@ -19321,7 +19448,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19321
19448
|
until: number().optional(),
|
|
19322
19449
|
kinds: array(string()).optional(),
|
|
19323
19450
|
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19324
|
-
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
19451
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(KeyEventBatchQueryInput, array(KeyEventsForDeviceSchema).readonly()), method(object({
|
|
19325
19452
|
deviceId: number(),
|
|
19326
19453
|
since: number(),
|
|
19327
19454
|
until: number(),
|
|
@@ -28800,6 +28927,9 @@ method(object({
|
|
|
28800
28927
|
}), method(RelocateResidueInputSchema, RelocateResidueSchema, {
|
|
28801
28928
|
kind: "query",
|
|
28802
28929
|
auth: "admin"
|
|
28930
|
+
}), method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
|
|
28931
|
+
kind: "mutation",
|
|
28932
|
+
auth: "admin"
|
|
28803
28933
|
}), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
28804
28934
|
kind: "mutation",
|
|
28805
28935
|
auth: "admin"
|
|
@@ -29191,6 +29321,25 @@ var SceneMonitorStatusSchema = object({
|
|
|
29191
29321
|
monitors: array(SceneMonitorSchema),
|
|
29192
29322
|
lastFetchedAt: number()
|
|
29193
29323
|
});
|
|
29324
|
+
/**
|
|
29325
|
+
* One camera's row in a `listScenesBatch` answer.
|
|
29326
|
+
*
|
|
29327
|
+
* `status` is NULLABLE and the nullability is the whole point. `scene-monitor`
|
|
29328
|
+
* is a `defaultActive` wrapper, so every camera is asked; a camera whose
|
|
29329
|
+
* provider is absent (pipeline-analytics not deployed, the post-processing node
|
|
29330
|
+
* down) cannot answer, and that is not the same fact as a camera with no scenes
|
|
29331
|
+
* configured. Fanned out per camera the difference was visible — one query
|
|
29332
|
+
* errored while the others resolved — and a batch that returned only the rows
|
|
29333
|
+
* it managed would have destroyed it, silently, by making an unreachable camera
|
|
29334
|
+
* indistinguishable from one that answered `monitors: []`.
|
|
29335
|
+
*
|
|
29336
|
+
* So: EVERY requested deviceId gets a row. `status: null` means "this camera
|
|
29337
|
+
* could not be read"; `status.monitors: []` means "read, and it has none".
|
|
29338
|
+
*/
|
|
29339
|
+
var SceneMonitorStatusForDeviceSchema = object({
|
|
29340
|
+
deviceId: number(),
|
|
29341
|
+
status: SceneMonitorStatusSchema.nullable()
|
|
29342
|
+
});
|
|
29194
29343
|
var sceneMonitorCapability = {
|
|
29195
29344
|
name: "scene-monitor",
|
|
29196
29345
|
scope: "device",
|
|
@@ -29200,6 +29349,22 @@ var sceneMonitorCapability = {
|
|
|
29200
29349
|
deviceTypes: [DeviceType.Camera],
|
|
29201
29350
|
methods: {
|
|
29202
29351
|
listScenes: method(object({ deviceId: number() }), SceneMonitorStatusSchema),
|
|
29352
|
+
/**
|
|
29353
|
+
* The same answer, for a SET of cameras, in one round trip.
|
|
29354
|
+
*
|
|
29355
|
+
* `/scenes` renders every camera and re-reads them on a 30s safety-net
|
|
29356
|
+
* poll behind the push slice. Fanned out client-side that was one query
|
|
29357
|
+
* per camera — 29 round trips through the browser, the hub and the
|
|
29358
|
+
* post-analysis runner every 30 seconds to read an in-memory map the
|
|
29359
|
+
* owner had already merged. The work is unchanged (`statusFor` per
|
|
29360
|
+
* device, all in-process at the owner); what collapses is the transport.
|
|
29361
|
+
*
|
|
29362
|
+
* A camera that cannot answer still gets a row, with `status: null` —
|
|
29363
|
+
* see {@link SceneMonitorStatusForDeviceSchema}. Never fewer rows than
|
|
29364
|
+
* ids: a caller that asked for twenty-nine and got twenty-seven cannot
|
|
29365
|
+
* tell which two are missing, or that any are.
|
|
29366
|
+
*/
|
|
29367
|
+
listScenesBatch: method(object({ deviceIds: array(number()).min(1).max(200) }), array(SceneMonitorStatusForDeviceSchema).readonly()),
|
|
29203
29368
|
createScene: method(object({
|
|
29204
29369
|
deviceId: number(),
|
|
29205
29370
|
label: string(),
|
|
@@ -31035,6 +31200,27 @@ var CameraOccupancySnapshotSchema = object({
|
|
|
31035
31200
|
stationaryObjects: array(StationaryObjectSchema).readonly().optional()
|
|
31036
31201
|
});
|
|
31037
31202
|
/**
|
|
31203
|
+
* One camera's row in a `getCurrentSnapshotBatch` answer.
|
|
31204
|
+
*
|
|
31205
|
+
* THREE outcomes, and the single-camera method could only express two of them
|
|
31206
|
+
* because `snapshot: null` was already spoken for:
|
|
31207
|
+
*
|
|
31208
|
+
* - `read: 'read'`, `snapshot` present — the live occupancy reading.
|
|
31209
|
+
* - `read: 'read'`, `snapshot: null` — read, and this camera has no reading
|
|
31210
|
+
* yet: no frame since boot, and no parked-object registry to hydrate from.
|
|
31211
|
+
* - `read: 'unreadable'` — the owner could not answer for this
|
|
31212
|
+
* camera. `snapshot` is null, and it does NOT mean "nothing parked here".
|
|
31213
|
+
*
|
|
31214
|
+
* Collapsing the last two is the failure this field exists to prevent: a
|
|
31215
|
+
* hydration that threw would otherwise render as an empty Stationary section,
|
|
31216
|
+
* which is a definite claim about a camera nobody could read.
|
|
31217
|
+
*/
|
|
31218
|
+
var CameraOccupancySnapshotForDeviceSchema = object({
|
|
31219
|
+
deviceId: number(),
|
|
31220
|
+
read: _enum(["read", "unreadable"]),
|
|
31221
|
+
snapshot: CameraOccupancySnapshotSchema.nullable()
|
|
31222
|
+
});
|
|
31223
|
+
/**
|
|
31038
31224
|
* Time-series resolution. The history methods return one bucket per
|
|
31039
31225
|
* step over the requested range. Smaller resolutions cost more
|
|
31040
31226
|
* memory + bandwidth; bound to discrete steps so caller cannot ask
|
|
@@ -31091,6 +31277,20 @@ var zoneAnalyticsCapability = {
|
|
|
31091
31277
|
* (no inference result emitted since boot or since binding was
|
|
31092
31278
|
* activated). */
|
|
31093
31279
|
getCurrentSnapshot: method(object({ deviceId: number() }), CameraOccupancySnapshotSchema.nullable()),
|
|
31280
|
+
/**
|
|
31281
|
+
* The same snapshot, for a SET of cameras, in one round trip.
|
|
31282
|
+
*
|
|
31283
|
+
* The Events page's Stationary section polls this every 15s for every
|
|
31284
|
+
* selected camera. Fanned out client-side that is one query per camera to
|
|
31285
|
+
* read a `Map.get` at the owner — the answer costs nothing, the round trip
|
|
31286
|
+
* costs everything. Batched, N transports become one and the per-device
|
|
31287
|
+
* work is unchanged.
|
|
31288
|
+
*
|
|
31289
|
+
* Every requested deviceId gets a row, tagged `read` — see
|
|
31290
|
+
* {@link CameraOccupancySnapshotForDeviceSchema}. A camera the owner could
|
|
31291
|
+
* not answer for is `'unreadable'`, never an empty reading.
|
|
31292
|
+
*/
|
|
31293
|
+
getCurrentSnapshotBatch: method(object({ deviceIds: array(number()).min(1).max(200) }), array(CameraOccupancySnapshotForDeviceSchema).readonly()),
|
|
31094
31294
|
/** Time-series object count inside one zone. `className` optional —
|
|
31095
31295
|
* omit to count every class in the zone. */
|
|
31096
31296
|
getZoneHistory: method(object({
|
|
@@ -35512,6 +35712,12 @@ Object.freeze({
|
|
|
35512
35712
|
addonId: null,
|
|
35513
35713
|
access: "view"
|
|
35514
35714
|
},
|
|
35715
|
+
"pipelineAnalytics.getKeyEventsBatch": {
|
|
35716
|
+
capName: "pipeline-analytics",
|
|
35717
|
+
capScope: "device",
|
|
35718
|
+
addonId: null,
|
|
35719
|
+
access: "view"
|
|
35720
|
+
},
|
|
35515
35721
|
"pipelineAnalytics.getMotionEvents": {
|
|
35516
35722
|
capName: "pipeline-analytics",
|
|
35517
35723
|
capScope: "device",
|
|
@@ -36688,6 +36894,12 @@ Object.freeze({
|
|
|
36688
36894
|
addonId: null,
|
|
36689
36895
|
access: "view"
|
|
36690
36896
|
},
|
|
36897
|
+
"recording.reconcileLedgerAgainstDisk": {
|
|
36898
|
+
capName: "recording",
|
|
36899
|
+
capScope: "system",
|
|
36900
|
+
addonId: null,
|
|
36901
|
+
access: "create"
|
|
36902
|
+
},
|
|
36691
36903
|
"recording.refreshStorageLocationsForMigration": {
|
|
36692
36904
|
capName: "recording",
|
|
36693
36905
|
capScope: "system",
|
|
@@ -36814,6 +37026,12 @@ Object.freeze({
|
|
|
36814
37026
|
addonId: null,
|
|
36815
37027
|
access: "view"
|
|
36816
37028
|
},
|
|
37029
|
+
"sceneMonitor.listScenesBatch": {
|
|
37030
|
+
capName: "scene-monitor",
|
|
37031
|
+
capScope: "device",
|
|
37032
|
+
addonId: null,
|
|
37033
|
+
access: "view"
|
|
37034
|
+
},
|
|
36817
37035
|
"sceneMonitor.recheckNow": {
|
|
36818
37036
|
capName: "scene-monitor",
|
|
36819
37037
|
capScope: "device",
|
|
@@ -38170,6 +38388,12 @@ Object.freeze({
|
|
|
38170
38388
|
addonId: null,
|
|
38171
38389
|
access: "view"
|
|
38172
38390
|
},
|
|
38391
|
+
"zoneAnalytics.getCurrentSnapshotBatch": {
|
|
38392
|
+
capName: "zone-analytics",
|
|
38393
|
+
capScope: "device",
|
|
38394
|
+
addonId: null,
|
|
38395
|
+
access: "view"
|
|
38396
|
+
},
|
|
38173
38397
|
"zoneAnalytics.getUnzonedHistory": {
|
|
38174
38398
|
capName: "zone-analytics",
|
|
38175
38399
|
capScope: "device",
|
|
@@ -39174,6 +39398,11 @@ Object.freeze({
|
|
|
39174
39398
|
form: "single",
|
|
39175
39399
|
optional: false
|
|
39176
39400
|
}],
|
|
39401
|
+
"pipelineAnalytics.getKeyEventsBatch": [{
|
|
39402
|
+
name: "deviceIds",
|
|
39403
|
+
form: "array",
|
|
39404
|
+
optional: false
|
|
39405
|
+
}],
|
|
39177
39406
|
"pipelineAnalytics.getMotionEvents": [{
|
|
39178
39407
|
name: "deviceId",
|
|
39179
39408
|
form: "single",
|
|
@@ -39614,6 +39843,11 @@ Object.freeze({
|
|
|
39614
39843
|
form: "single",
|
|
39615
39844
|
optional: false
|
|
39616
39845
|
}],
|
|
39846
|
+
"recording.reconcileLedgerAgainstDisk": [{
|
|
39847
|
+
name: "deviceId",
|
|
39848
|
+
form: "single",
|
|
39849
|
+
optional: true
|
|
39850
|
+
}],
|
|
39617
39851
|
"recording.relocateFootage": [{
|
|
39618
39852
|
name: "deviceId",
|
|
39619
39853
|
form: "single",
|
|
@@ -39679,6 +39913,11 @@ Object.freeze({
|
|
|
39679
39913
|
form: "single",
|
|
39680
39914
|
optional: false
|
|
39681
39915
|
}],
|
|
39916
|
+
"sceneMonitor.listScenesBatch": [{
|
|
39917
|
+
name: "deviceIds",
|
|
39918
|
+
form: "array",
|
|
39919
|
+
optional: false
|
|
39920
|
+
}],
|
|
39682
39921
|
"sceneMonitor.recheckNow": [{
|
|
39683
39922
|
name: "deviceId",
|
|
39684
39923
|
form: "single",
|
|
@@ -39940,6 +40179,11 @@ Object.freeze({
|
|
|
39940
40179
|
form: "single",
|
|
39941
40180
|
optional: false
|
|
39942
40181
|
}],
|
|
40182
|
+
"zoneAnalytics.getCurrentSnapshotBatch": [{
|
|
40183
|
+
name: "deviceIds",
|
|
40184
|
+
form: "array",
|
|
40185
|
+
optional: false
|
|
40186
|
+
}],
|
|
39943
40187
|
"zoneAnalytics.getUnzonedHistory": [{
|
|
39944
40188
|
name: "deviceId",
|
|
39945
40189
|
form: "single",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-wyze",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.53",
|
|
4
4
|
"description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|