@camstack/addon-provider-wyze 0.2.23 → 0.2.25
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 +136 -22
- package/dist/addon.mjs +136 -22
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -31,7 +31,7 @@ let net = require("net");
|
|
|
31
31
|
net = __toESM(net, 1);
|
|
32
32
|
let node_child_process = require("node:child_process");
|
|
33
33
|
let node_tls = require("node:tls");
|
|
34
|
-
//#region ../types/dist/event-category-
|
|
34
|
+
//#region ../types/dist/event-category-XfKNtfCc.mjs
|
|
35
35
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
36
36
|
EventCategory["SystemBoot"] = "system.boot";
|
|
37
37
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -70,6 +70,22 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
70
70
|
EventCategory["AddonInstalled"] = "addon.installed";
|
|
71
71
|
EventCategory["AddonUninstalled"] = "addon.uninstalled";
|
|
72
72
|
EventCategory["AddonCrashed"] = "addon.crashed";
|
|
73
|
+
/**
|
|
74
|
+
* A RUNNER the D6 crash circuit-breaker gave up on — terminal.
|
|
75
|
+
*
|
|
76
|
+
* `AddonCrashed` is the routine, self-healing fact ("it crashed; it is being
|
|
77
|
+
* respawned"); this is the one that never resolves itself. Emitted exactly
|
|
78
|
+
* once per trip, by `process-service.ts`, carrying the node, the runner, the
|
|
79
|
+
* addons it hosted and the crash count that tripped the breaker.
|
|
80
|
+
*
|
|
81
|
+
* It exists because a runner marked terminally `failed` used to be SILENT:
|
|
82
|
+
* on 2026-08-18 the `recorder` runner died of three unhandled ffmpeg spawn
|
|
83
|
+
* errors, the breaker stopped respawning it (correctly), `/health` kept
|
|
84
|
+
* returning 200, and fleet-wide recording was gone for 3h15 before the
|
|
85
|
+
* operator's phone told him. The Notification Center's system-event intake
|
|
86
|
+
* consumes this category and maps it to the `addon-crash-loop` kind.
|
|
87
|
+
*/
|
|
88
|
+
EventCategory["AddonRunnerFailed"] = "addon.runner-failed";
|
|
73
89
|
EventCategory["AddonError"] = "addon.error";
|
|
74
90
|
EventCategory["AddonPageReady"] = "addon.page-ready";
|
|
75
91
|
EventCategory["AddonWidgetReady"] = "addon.widget-ready";
|
|
@@ -7632,6 +7648,12 @@ var RecordingConfigSchema = object({
|
|
|
7632
7648
|
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
7633
7649
|
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
7634
7650
|
mode: RecordingStorageModeSchema.optional(),
|
|
7651
|
+
/**
|
|
7652
|
+
* Which assigned broker slots to record. Absent / empty = {@link
|
|
7653
|
+
* DEFAULT_RECORDING_PROFILES} (`high`+`low`) intersected with the
|
|
7654
|
+
* camera's currently assigned slots — never `mid` unless the operator
|
|
7655
|
+
* picks it, and never a slot the broker has not assigned.
|
|
7656
|
+
*/
|
|
7635
7657
|
profiles: array(CamProfileSchema).optional(),
|
|
7636
7658
|
segmentSeconds: number().int().positive().optional(),
|
|
7637
7659
|
/**
|
|
@@ -7712,7 +7734,11 @@ var RelocateFootageInputSchema = object({
|
|
|
7712
7734
|
profiles: array(string()).optional(),
|
|
7713
7735
|
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
7714
7736
|
* never allowed to starve live writers. */
|
|
7715
|
-
throttleMbps: number().min(1).max(1e3).optional()
|
|
7737
|
+
throttleMbps: number().min(1).max(1e3).optional(),
|
|
7738
|
+
/** Move only segments whose startMs is >= this. Absent = the whole source
|
|
7739
|
+
* pile. Used when a full drain is too expensive and the operator only
|
|
7740
|
+
* wants the recent window on the new disk. */
|
|
7741
|
+
sinceMs: number().int().optional()
|
|
7716
7742
|
});
|
|
7717
7743
|
/** Internal, lease-scoped participant operation. It is intentionally separate
|
|
7718
7744
|
* from persistent recording settings: a migration never changes
|
|
@@ -14594,6 +14620,7 @@ var NcSystemEventKindSchema = _enum([
|
|
|
14594
14620
|
"node-offline",
|
|
14595
14621
|
"node-inference-unavailable",
|
|
14596
14622
|
"detection-blind",
|
|
14623
|
+
"addon-crash-loop",
|
|
14597
14624
|
"addon-update-available",
|
|
14598
14625
|
"server-update-available",
|
|
14599
14626
|
"alarm-triggered",
|
|
@@ -17167,6 +17194,12 @@ var TrackCascadeCountsSchema = object({
|
|
|
17167
17194
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17168
17195
|
embeddings: number().int()
|
|
17169
17196
|
});
|
|
17197
|
+
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17198
|
+
var DiskReconcileCountsSchema = object({
|
|
17199
|
+
mediaDropped: number().int(),
|
|
17200
|
+
tracks: number().int(),
|
|
17201
|
+
events: number().int()
|
|
17202
|
+
});
|
|
17170
17203
|
/** Event-store footprint for one camera. */
|
|
17171
17204
|
var EventStoreDeviceFootprintSchema = object({
|
|
17172
17205
|
deviceId: number(),
|
|
@@ -17343,6 +17376,9 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17343
17376
|
}), method(object({ deviceId: number() }), TrackCascadeCountsSchema, {
|
|
17344
17377
|
kind: "mutation",
|
|
17345
17378
|
auth: "admin"
|
|
17379
|
+
}), method(object({ deviceId: number() }), DiskReconcileCountsSchema, {
|
|
17380
|
+
kind: "mutation",
|
|
17381
|
+
auth: "admin"
|
|
17346
17382
|
}), method(object({
|
|
17347
17383
|
deviceId: number(),
|
|
17348
17384
|
trackIds: array(string()).min(1)
|
|
@@ -18893,6 +18929,24 @@ var CameraStatusDegradationSchema = object({
|
|
|
18893
18929
|
*
|
|
18894
18930
|
* See spec: `docs/superpowers/specs/2026-06-24-camera-status-aggregator-cap.md`
|
|
18895
18931
|
*/
|
|
18932
|
+
var DiskReconcileJobSchema = object({
|
|
18933
|
+
state: _enum([
|
|
18934
|
+
"idle",
|
|
18935
|
+
"running",
|
|
18936
|
+
"done",
|
|
18937
|
+
"error"
|
|
18938
|
+
]),
|
|
18939
|
+
total: number().int().nonnegative(),
|
|
18940
|
+
completed: number().int().nonnegative(),
|
|
18941
|
+
currentDeviceId: number().int().nullable(),
|
|
18942
|
+
failed: array(number().int()).readonly(),
|
|
18943
|
+
mediaDropped: number().int().nonnegative(),
|
|
18944
|
+
tracks: number().int().nonnegative(),
|
|
18945
|
+
events: number().int().nonnegative(),
|
|
18946
|
+
startedAtMs: number().int().nullable(),
|
|
18947
|
+
finishedAtMs: number().int().nullable(),
|
|
18948
|
+
error: string().nullable()
|
|
18949
|
+
});
|
|
18896
18950
|
var CameraStatusSchema = object({
|
|
18897
18951
|
deviceId: number(),
|
|
18898
18952
|
assignment: CameraAssignmentStatusSchema,
|
|
@@ -19124,7 +19178,10 @@ method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
|
|
|
19124
19178
|
}), CameraSwitchGroupSchema, {
|
|
19125
19179
|
kind: "mutation",
|
|
19126
19180
|
auth: "admin"
|
|
19127
|
-
}), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(),
|
|
19181
|
+
}), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), DiskReconcileJobSchema, {
|
|
19182
|
+
kind: "mutation",
|
|
19183
|
+
auth: "admin"
|
|
19184
|
+
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
|
|
19128
19185
|
name: string(),
|
|
19129
19186
|
description: string().optional(),
|
|
19130
19187
|
config: CameraPipelineConfigSchema
|
|
@@ -20301,20 +20358,6 @@ var VectorStatsResultSchema = object({
|
|
|
20301
20358
|
exact: boolean()
|
|
20302
20359
|
});
|
|
20303
20360
|
method(VectorDeclareIndexInputSchema, _void(), { kind: "mutation" }), method(VectorUpsertInputSchema, VectorUpsertResultSchema, { kind: "mutation" }), method(VectorQueryInputSchema, VectorQueryResultSchema), method(VectorGetInputSchema, VectorGetResultSchema), method(VectorDeleteInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorDeleteByFilterInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorStatsInputSchema, VectorStatsResultSchema);
|
|
20304
|
-
/**
|
|
20305
|
-
* `videoclips` — the unified, navigable-clip surface for a camera.
|
|
20306
|
-
*
|
|
20307
|
-
* A device-scoped WRAPPER cap (like `pipeline-analytics`): exactly one active
|
|
20308
|
-
* provider per device, substitutable. The DEFAULT provider (registered by
|
|
20309
|
-
* `addon-post-analysis`, `defaultActive: true`) composes the analytics event
|
|
20310
|
-
* log (markers + thumbnails) with the recorder's `getPlaybackManifest` — a clip
|
|
20311
|
-
* is a time-WINDOW over existing footage, never a separate file. A camera that
|
|
20312
|
-
* exposes NATIVE onboard clips (Reolink/Hikvision NVR) can later substitute the
|
|
20313
|
-
* wrapper provider for its device and serve its own clip catalog + URLs.
|
|
20314
|
-
*
|
|
20315
|
-
* A `Clip` is purely time-based (subtree-blind): playback resolves segments by
|
|
20316
|
-
* temporal overlap, so the API never decides `continuous` vs `events`.
|
|
20317
|
-
*/
|
|
20318
20361
|
var ClipSchema = object({
|
|
20319
20362
|
/** Opaque, provider-namespaced id. The default provider encodes the time
|
|
20320
20363
|
* window so `getClipPlayback` is self-contained (no event re-query). */
|
|
@@ -20332,6 +20375,14 @@ var ClipSchema = object({
|
|
|
20332
20375
|
endMs: number()
|
|
20333
20376
|
}),
|
|
20334
20377
|
/**
|
|
20378
|
+
* Distinct object classes attached to this visit (`person`, `car`, …),
|
|
20379
|
+
* dominant first, capped at {@link MAX_CLIP_LABELS}. The ribbon renders these
|
|
20380
|
+
* instead of the bare kind — "Object" tells the operator nothing a colour bar
|
|
20381
|
+
* did not. Absent (never empty) when the visit attached no classified object
|
|
20382
|
+
* event, so a motion/audio-only visit keeps its kind label.
|
|
20383
|
+
*/
|
|
20384
|
+
labels: array(string()).max(3).optional(),
|
|
20385
|
+
/**
|
|
20335
20386
|
* Lazy thumbnail URL, never inlined.
|
|
20336
20387
|
*
|
|
20337
20388
|
* Recording-derived clips (events-mode keep-window, and the prepared
|
|
@@ -20340,12 +20391,41 @@ var ClipSchema = object({
|
|
|
20340
20391
|
* of the event that owns `kind` (object > motion > audio). Do not extract
|
|
20341
20392
|
* a keyframe from the recorded segments. Other providers (onboard, HKSV)
|
|
20342
20393
|
* mint their own stills.
|
|
20394
|
+
*
|
|
20395
|
+
* **VOUCHED, never fabricated.** A provider emits this only for an event it
|
|
20396
|
+
* has CONFIRMED owns at least one media row (its own, or its owning track's).
|
|
20397
|
+
* Absent is meaningful — "this visit has no event still" — never "we did not
|
|
20398
|
+
* look". Stamping it from a URL template made 35% of one camera's clips point
|
|
20399
|
+
* at a 404 (device 3836, 2026-08-17: 64 of 179 clips dead, 63 of them motion).
|
|
20400
|
+
* A read that FAILS drops the claim; it never invents it.
|
|
20343
20401
|
*/
|
|
20344
20402
|
thumbnail: string().optional(),
|
|
20345
|
-
/**
|
|
20346
|
-
*
|
|
20347
|
-
*
|
|
20403
|
+
/**
|
|
20404
|
+
* An instant INSIDE this visit's footage, hole-safe, where a recorded still
|
|
20405
|
+
* can be decoded. Present whenever the visit came from recorded availability;
|
|
20406
|
+
* absent on a per-event padded window (there is no footage to promise).
|
|
20407
|
+
*
|
|
20408
|
+
* This is not a thumbnail and not a second byte path: it is the argument to
|
|
20409
|
+
* the recorder's existing still route. The surface — never the provider —
|
|
20410
|
+
* decides whether to use it. It is the midpoint of the visit's LONGEST
|
|
20411
|
+
* contiguous range, not of the visit: a visit spans its holes by
|
|
20412
|
+
* construction, so a naive midpoint lands in dead air.
|
|
20413
|
+
*/
|
|
20414
|
+
stillAtMs: number().optional(),
|
|
20415
|
+
/**
|
|
20416
|
+
* Analytics event ids that overlap this visit — a BOUNDED sample, newest
|
|
20417
|
+
* first within kind (object → motion → audio), capped at
|
|
20418
|
+
* {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
|
|
20419
|
+
*
|
|
20420
|
+
* Bounded because it is not a payload the surface pages through: one visit on
|
|
20421
|
+
* device 615 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
|
|
20422
|
+
* camera-day. Read {@link eventCount} for the true total.
|
|
20423
|
+
*/
|
|
20348
20424
|
eventIds: array(string()).optional(),
|
|
20425
|
+
/** How many analytics events actually overlap this visit. Differs from
|
|
20426
|
+
* `eventIds.length` exactly when the sample was capped — so a truncated
|
|
20427
|
+
* list is never mistaken for a quiet visit. */
|
|
20428
|
+
eventCount: number().int().nonnegative().optional(),
|
|
20349
20429
|
/** Intra-visit footage holes (GOP rolls, discarded segments) still shorter
|
|
20350
20430
|
* than `VISIT_MERGE_GAP_MS`. Playback concatenates around them; the timeline
|
|
20351
20431
|
* bar keeps showing them via `recording.getAvailability`. */
|
|
@@ -20816,7 +20896,14 @@ var SearchResultSchema = object({
|
|
|
20816
20896
|
});
|
|
20817
20897
|
var AutoUpdateSettingsSchema = object({
|
|
20818
20898
|
channel: ChannelSchema,
|
|
20819
|
-
intervalSeconds: number()
|
|
20899
|
+
intervalSeconds: number(),
|
|
20900
|
+
/**
|
|
20901
|
+
* Cadence of the "an update exists" POLLER, in seconds. Independent of
|
|
20902
|
+
* `channel`: the poller runs while auto-apply is `off`, because being told
|
|
20903
|
+
* about a publish and installing it are different decisions. Clamped
|
|
20904
|
+
* server-side to 900 s … 604800 s; defaults to 21600 s (6 h).
|
|
20905
|
+
*/
|
|
20906
|
+
updateCheckIntervalSeconds: number()
|
|
20820
20907
|
});
|
|
20821
20908
|
var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
20822
20909
|
var RestartAddonResultSchema = unknown();
|
|
@@ -20957,7 +21044,9 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
20957
21044
|
auth: "admin"
|
|
20958
21045
|
}), method(_void(), AutoUpdateSettingsSchema, { auth: "admin" }), method(object({
|
|
20959
21046
|
channel: ChannelSchema,
|
|
20960
|
-
intervalSeconds: number().min(300).max(86400).optional()
|
|
21047
|
+
intervalSeconds: number().min(300).max(86400).optional(),
|
|
21048
|
+
/** Availability-poll cadence; see AutoUpdateSettingsSchema. */
|
|
21049
|
+
updateCheckIntervalSeconds: number().min(900).max(604800).optional()
|
|
20961
21050
|
}), unknown(), {
|
|
20962
21051
|
kind: "mutation",
|
|
20963
21052
|
auth: "admin"
|
|
@@ -32987,6 +33076,12 @@ Object.freeze({
|
|
|
32987
33076
|
addonId: null,
|
|
32988
33077
|
access: "create"
|
|
32989
33078
|
},
|
|
33079
|
+
"pipelineAnalytics.reconcileFromDisk": {
|
|
33080
|
+
capName: "pipeline-analytics",
|
|
33081
|
+
capScope: "device",
|
|
33082
|
+
addonId: null,
|
|
33083
|
+
access: "create"
|
|
33084
|
+
},
|
|
32990
33085
|
"pipelineAnalytics.refreshStorageLocationsForMigration": {
|
|
32991
33086
|
capName: "pipeline-analytics",
|
|
32992
33087
|
capScope: "device",
|
|
@@ -33389,6 +33484,12 @@ Object.freeze({
|
|
|
33389
33484
|
addonId: null,
|
|
33390
33485
|
access: "view"
|
|
33391
33486
|
},
|
|
33487
|
+
"pipelineOrchestrator.getReconcileFromDiskStatus": {
|
|
33488
|
+
capName: "pipeline-orchestrator",
|
|
33489
|
+
capScope: "system",
|
|
33490
|
+
addonId: null,
|
|
33491
|
+
access: "view"
|
|
33492
|
+
},
|
|
33392
33493
|
"pipelineOrchestrator.listAgentSettings": {
|
|
33393
33494
|
capName: "pipeline-orchestrator",
|
|
33394
33495
|
capScope: "system",
|
|
@@ -33413,6 +33514,12 @@ Object.freeze({
|
|
|
33413
33514
|
addonId: null,
|
|
33414
33515
|
access: "create"
|
|
33415
33516
|
},
|
|
33517
|
+
"pipelineOrchestrator.reconcileFromDisk": {
|
|
33518
|
+
capName: "pipeline-orchestrator",
|
|
33519
|
+
capScope: "system",
|
|
33520
|
+
addonId: null,
|
|
33521
|
+
access: "create"
|
|
33522
|
+
},
|
|
33416
33523
|
"pipelineOrchestrator.removeAgentSettings": {
|
|
33417
33524
|
capName: "pipeline-orchestrator",
|
|
33418
33525
|
capScope: "system",
|
|
@@ -36404,6 +36511,11 @@ Object.freeze({
|
|
|
36404
36511
|
form: "single",
|
|
36405
36512
|
optional: true
|
|
36406
36513
|
}],
|
|
36514
|
+
"pipelineAnalytics.reconcileFromDisk": [{
|
|
36515
|
+
name: "deviceId",
|
|
36516
|
+
form: "single",
|
|
36517
|
+
optional: false
|
|
36518
|
+
}],
|
|
36407
36519
|
"pipelineAnalytics.restageRetrainTrack": [{
|
|
36408
36520
|
name: "deviceId",
|
|
36409
36521
|
form: "single",
|
|
@@ -37469,6 +37581,8 @@ DEFAULT_NATIVE_LEASE_SETTINGS.budgetMb;
|
|
|
37469
37581
|
DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
37470
37582
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
37471
37583
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
37584
|
+
var MB = 1024 * 1024;
|
|
37585
|
+
1024 * MB, 3072 * MB;
|
|
37472
37586
|
//#endregion
|
|
37473
37587
|
//#region ../../node_modules/@apocaliss92/wyze-bridge-js/dist/index.js
|
|
37474
37588
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
package/dist/addon.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { getCACertificates, setDefaultCACertificates } from "node:tls";
|
|
|
10
10
|
//#region \0rolldown/runtime.js
|
|
11
11
|
var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
|
|
12
12
|
//#endregion
|
|
13
|
-
//#region ../types/dist/event-category-
|
|
13
|
+
//#region ../types/dist/event-category-XfKNtfCc.mjs
|
|
14
14
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
15
15
|
EventCategory["SystemBoot"] = "system.boot";
|
|
16
16
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -49,6 +49,22 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
49
49
|
EventCategory["AddonInstalled"] = "addon.installed";
|
|
50
50
|
EventCategory["AddonUninstalled"] = "addon.uninstalled";
|
|
51
51
|
EventCategory["AddonCrashed"] = "addon.crashed";
|
|
52
|
+
/**
|
|
53
|
+
* A RUNNER the D6 crash circuit-breaker gave up on — terminal.
|
|
54
|
+
*
|
|
55
|
+
* `AddonCrashed` is the routine, self-healing fact ("it crashed; it is being
|
|
56
|
+
* respawned"); this is the one that never resolves itself. Emitted exactly
|
|
57
|
+
* once per trip, by `process-service.ts`, carrying the node, the runner, the
|
|
58
|
+
* addons it hosted and the crash count that tripped the breaker.
|
|
59
|
+
*
|
|
60
|
+
* It exists because a runner marked terminally `failed` used to be SILENT:
|
|
61
|
+
* on 2026-08-18 the `recorder` runner died of three unhandled ffmpeg spawn
|
|
62
|
+
* errors, the breaker stopped respawning it (correctly), `/health` kept
|
|
63
|
+
* returning 200, and fleet-wide recording was gone for 3h15 before the
|
|
64
|
+
* operator's phone told him. The Notification Center's system-event intake
|
|
65
|
+
* consumes this category and maps it to the `addon-crash-loop` kind.
|
|
66
|
+
*/
|
|
67
|
+
EventCategory["AddonRunnerFailed"] = "addon.runner-failed";
|
|
52
68
|
EventCategory["AddonError"] = "addon.error";
|
|
53
69
|
EventCategory["AddonPageReady"] = "addon.page-ready";
|
|
54
70
|
EventCategory["AddonWidgetReady"] = "addon.widget-ready";
|
|
@@ -7611,6 +7627,12 @@ var RecordingConfigSchema = object({
|
|
|
7611
7627
|
/** DERIVED summary of `bands`, stamped by the recorder on every save.
|
|
7612
7628
|
* Authoring it has no effect — see {@link RecordingStorageModeSchema}. */
|
|
7613
7629
|
mode: RecordingStorageModeSchema.optional(),
|
|
7630
|
+
/**
|
|
7631
|
+
* Which assigned broker slots to record. Absent / empty = {@link
|
|
7632
|
+
* DEFAULT_RECORDING_PROFILES} (`high`+`low`) intersected with the
|
|
7633
|
+
* camera's currently assigned slots — never `mid` unless the operator
|
|
7634
|
+
* picks it, and never a slot the broker has not assigned.
|
|
7635
|
+
*/
|
|
7614
7636
|
profiles: array(CamProfileSchema).optional(),
|
|
7615
7637
|
segmentSeconds: number().int().positive().optional(),
|
|
7616
7638
|
/**
|
|
@@ -7691,7 +7713,11 @@ var RelocateFootageInputSchema = object({
|
|
|
7691
7713
|
profiles: array(string()).optional(),
|
|
7692
7714
|
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
7693
7715
|
* never allowed to starve live writers. */
|
|
7694
|
-
throttleMbps: number().min(1).max(1e3).optional()
|
|
7716
|
+
throttleMbps: number().min(1).max(1e3).optional(),
|
|
7717
|
+
/** Move only segments whose startMs is >= this. Absent = the whole source
|
|
7718
|
+
* pile. Used when a full drain is too expensive and the operator only
|
|
7719
|
+
* wants the recent window on the new disk. */
|
|
7720
|
+
sinceMs: number().int().optional()
|
|
7695
7721
|
});
|
|
7696
7722
|
/** Internal, lease-scoped participant operation. It is intentionally separate
|
|
7697
7723
|
* from persistent recording settings: a migration never changes
|
|
@@ -14573,6 +14599,7 @@ var NcSystemEventKindSchema = _enum([
|
|
|
14573
14599
|
"node-offline",
|
|
14574
14600
|
"node-inference-unavailable",
|
|
14575
14601
|
"detection-blind",
|
|
14602
|
+
"addon-crash-loop",
|
|
14576
14603
|
"addon-update-available",
|
|
14577
14604
|
"server-update-available",
|
|
14578
14605
|
"alarm-triggered",
|
|
@@ -17146,6 +17173,12 @@ var TrackCascadeCountsSchema = object({
|
|
|
17146
17173
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17147
17174
|
embeddings: number().int()
|
|
17148
17175
|
});
|
|
17176
|
+
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17177
|
+
var DiskReconcileCountsSchema = object({
|
|
17178
|
+
mediaDropped: number().int(),
|
|
17179
|
+
tracks: number().int(),
|
|
17180
|
+
events: number().int()
|
|
17181
|
+
});
|
|
17149
17182
|
/** Event-store footprint for one camera. */
|
|
17150
17183
|
var EventStoreDeviceFootprintSchema = object({
|
|
17151
17184
|
deviceId: number(),
|
|
@@ -17322,6 +17355,9 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17322
17355
|
}), method(object({ deviceId: number() }), TrackCascadeCountsSchema, {
|
|
17323
17356
|
kind: "mutation",
|
|
17324
17357
|
auth: "admin"
|
|
17358
|
+
}), method(object({ deviceId: number() }), DiskReconcileCountsSchema, {
|
|
17359
|
+
kind: "mutation",
|
|
17360
|
+
auth: "admin"
|
|
17325
17361
|
}), method(object({
|
|
17326
17362
|
deviceId: number(),
|
|
17327
17363
|
trackIds: array(string()).min(1)
|
|
@@ -18872,6 +18908,24 @@ var CameraStatusDegradationSchema = object({
|
|
|
18872
18908
|
*
|
|
18873
18909
|
* See spec: `docs/superpowers/specs/2026-06-24-camera-status-aggregator-cap.md`
|
|
18874
18910
|
*/
|
|
18911
|
+
var DiskReconcileJobSchema = object({
|
|
18912
|
+
state: _enum([
|
|
18913
|
+
"idle",
|
|
18914
|
+
"running",
|
|
18915
|
+
"done",
|
|
18916
|
+
"error"
|
|
18917
|
+
]),
|
|
18918
|
+
total: number().int().nonnegative(),
|
|
18919
|
+
completed: number().int().nonnegative(),
|
|
18920
|
+
currentDeviceId: number().int().nullable(),
|
|
18921
|
+
failed: array(number().int()).readonly(),
|
|
18922
|
+
mediaDropped: number().int().nonnegative(),
|
|
18923
|
+
tracks: number().int().nonnegative(),
|
|
18924
|
+
events: number().int().nonnegative(),
|
|
18925
|
+
startedAtMs: number().int().nullable(),
|
|
18926
|
+
finishedAtMs: number().int().nullable(),
|
|
18927
|
+
error: string().nullable()
|
|
18928
|
+
});
|
|
18875
18929
|
var CameraStatusSchema = object({
|
|
18876
18930
|
deviceId: number(),
|
|
18877
18931
|
assignment: CameraAssignmentStatusSchema,
|
|
@@ -19103,7 +19157,10 @@ method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
|
|
|
19103
19157
|
}), CameraSwitchGroupSchema, {
|
|
19104
19158
|
kind: "mutation",
|
|
19105
19159
|
auth: "admin"
|
|
19106
|
-
}), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(),
|
|
19160
|
+
}), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), DiskReconcileJobSchema, {
|
|
19161
|
+
kind: "mutation",
|
|
19162
|
+
auth: "admin"
|
|
19163
|
+
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
|
|
19107
19164
|
name: string(),
|
|
19108
19165
|
description: string().optional(),
|
|
19109
19166
|
config: CameraPipelineConfigSchema
|
|
@@ -20280,20 +20337,6 @@ var VectorStatsResultSchema = object({
|
|
|
20280
20337
|
exact: boolean()
|
|
20281
20338
|
});
|
|
20282
20339
|
method(VectorDeclareIndexInputSchema, _void(), { kind: "mutation" }), method(VectorUpsertInputSchema, VectorUpsertResultSchema, { kind: "mutation" }), method(VectorQueryInputSchema, VectorQueryResultSchema), method(VectorGetInputSchema, VectorGetResultSchema), method(VectorDeleteInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorDeleteByFilterInputSchema, VectorDeleteResultSchema, { kind: "mutation" }), method(VectorStatsInputSchema, VectorStatsResultSchema);
|
|
20283
|
-
/**
|
|
20284
|
-
* `videoclips` — the unified, navigable-clip surface for a camera.
|
|
20285
|
-
*
|
|
20286
|
-
* A device-scoped WRAPPER cap (like `pipeline-analytics`): exactly one active
|
|
20287
|
-
* provider per device, substitutable. The DEFAULT provider (registered by
|
|
20288
|
-
* `addon-post-analysis`, `defaultActive: true`) composes the analytics event
|
|
20289
|
-
* log (markers + thumbnails) with the recorder's `getPlaybackManifest` — a clip
|
|
20290
|
-
* is a time-WINDOW over existing footage, never a separate file. A camera that
|
|
20291
|
-
* exposes NATIVE onboard clips (Reolink/Hikvision NVR) can later substitute the
|
|
20292
|
-
* wrapper provider for its device and serve its own clip catalog + URLs.
|
|
20293
|
-
*
|
|
20294
|
-
* A `Clip` is purely time-based (subtree-blind): playback resolves segments by
|
|
20295
|
-
* temporal overlap, so the API never decides `continuous` vs `events`.
|
|
20296
|
-
*/
|
|
20297
20340
|
var ClipSchema = object({
|
|
20298
20341
|
/** Opaque, provider-namespaced id. The default provider encodes the time
|
|
20299
20342
|
* window so `getClipPlayback` is self-contained (no event re-query). */
|
|
@@ -20311,6 +20354,14 @@ var ClipSchema = object({
|
|
|
20311
20354
|
endMs: number()
|
|
20312
20355
|
}),
|
|
20313
20356
|
/**
|
|
20357
|
+
* Distinct object classes attached to this visit (`person`, `car`, …),
|
|
20358
|
+
* dominant first, capped at {@link MAX_CLIP_LABELS}. The ribbon renders these
|
|
20359
|
+
* instead of the bare kind — "Object" tells the operator nothing a colour bar
|
|
20360
|
+
* did not. Absent (never empty) when the visit attached no classified object
|
|
20361
|
+
* event, so a motion/audio-only visit keeps its kind label.
|
|
20362
|
+
*/
|
|
20363
|
+
labels: array(string()).max(3).optional(),
|
|
20364
|
+
/**
|
|
20314
20365
|
* Lazy thumbnail URL, never inlined.
|
|
20315
20366
|
*
|
|
20316
20367
|
* Recording-derived clips (events-mode keep-window, and the prepared
|
|
@@ -20319,12 +20370,41 @@ var ClipSchema = object({
|
|
|
20319
20370
|
* of the event that owns `kind` (object > motion > audio). Do not extract
|
|
20320
20371
|
* a keyframe from the recorded segments. Other providers (onboard, HKSV)
|
|
20321
20372
|
* mint their own stills.
|
|
20373
|
+
*
|
|
20374
|
+
* **VOUCHED, never fabricated.** A provider emits this only for an event it
|
|
20375
|
+
* has CONFIRMED owns at least one media row (its own, or its owning track's).
|
|
20376
|
+
* Absent is meaningful — "this visit has no event still" — never "we did not
|
|
20377
|
+
* look". Stamping it from a URL template made 35% of one camera's clips point
|
|
20378
|
+
* at a 404 (device 3836, 2026-08-17: 64 of 179 clips dead, 63 of them motion).
|
|
20379
|
+
* A read that FAILS drops the claim; it never invents it.
|
|
20322
20380
|
*/
|
|
20323
20381
|
thumbnail: string().optional(),
|
|
20324
|
-
/**
|
|
20325
|
-
*
|
|
20326
|
-
*
|
|
20382
|
+
/**
|
|
20383
|
+
* An instant INSIDE this visit's footage, hole-safe, where a recorded still
|
|
20384
|
+
* can be decoded. Present whenever the visit came from recorded availability;
|
|
20385
|
+
* absent on a per-event padded window (there is no footage to promise).
|
|
20386
|
+
*
|
|
20387
|
+
* This is not a thumbnail and not a second byte path: it is the argument to
|
|
20388
|
+
* the recorder's existing still route. The surface — never the provider —
|
|
20389
|
+
* decides whether to use it. It is the midpoint of the visit's LONGEST
|
|
20390
|
+
* contiguous range, not of the visit: a visit spans its holes by
|
|
20391
|
+
* construction, so a naive midpoint lands in dead air.
|
|
20392
|
+
*/
|
|
20393
|
+
stillAtMs: number().optional(),
|
|
20394
|
+
/**
|
|
20395
|
+
* Analytics event ids that overlap this visit — a BOUNDED sample, newest
|
|
20396
|
+
* first within kind (object → motion → audio), capped at
|
|
20397
|
+
* {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
|
|
20398
|
+
*
|
|
20399
|
+
* Bounded because it is not a payload the surface pages through: one visit on
|
|
20400
|
+
* device 615 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
|
|
20401
|
+
* camera-day. Read {@link eventCount} for the true total.
|
|
20402
|
+
*/
|
|
20327
20403
|
eventIds: array(string()).optional(),
|
|
20404
|
+
/** How many analytics events actually overlap this visit. Differs from
|
|
20405
|
+
* `eventIds.length` exactly when the sample was capped — so a truncated
|
|
20406
|
+
* list is never mistaken for a quiet visit. */
|
|
20407
|
+
eventCount: number().int().nonnegative().optional(),
|
|
20328
20408
|
/** Intra-visit footage holes (GOP rolls, discarded segments) still shorter
|
|
20329
20409
|
* than `VISIT_MERGE_GAP_MS`. Playback concatenates around them; the timeline
|
|
20330
20410
|
* bar keeps showing them via `recording.getAvailability`. */
|
|
@@ -20795,7 +20875,14 @@ var SearchResultSchema = object({
|
|
|
20795
20875
|
});
|
|
20796
20876
|
var AutoUpdateSettingsSchema = object({
|
|
20797
20877
|
channel: ChannelSchema,
|
|
20798
|
-
intervalSeconds: number()
|
|
20878
|
+
intervalSeconds: number(),
|
|
20879
|
+
/**
|
|
20880
|
+
* Cadence of the "an update exists" POLLER, in seconds. Independent of
|
|
20881
|
+
* `channel`: the poller runs while auto-apply is `off`, because being told
|
|
20882
|
+
* about a publish and installing it are different decisions. Clamped
|
|
20883
|
+
* server-side to 900 s … 604800 s; defaults to 21600 s (6 h).
|
|
20884
|
+
*/
|
|
20885
|
+
updateCheckIntervalSeconds: number()
|
|
20799
20886
|
});
|
|
20800
20887
|
var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
20801
20888
|
var RestartAddonResultSchema = unknown();
|
|
@@ -20936,7 +21023,9 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
20936
21023
|
auth: "admin"
|
|
20937
21024
|
}), method(_void(), AutoUpdateSettingsSchema, { auth: "admin" }), method(object({
|
|
20938
21025
|
channel: ChannelSchema,
|
|
20939
|
-
intervalSeconds: number().min(300).max(86400).optional()
|
|
21026
|
+
intervalSeconds: number().min(300).max(86400).optional(),
|
|
21027
|
+
/** Availability-poll cadence; see AutoUpdateSettingsSchema. */
|
|
21028
|
+
updateCheckIntervalSeconds: number().min(900).max(604800).optional()
|
|
20940
21029
|
}), unknown(), {
|
|
20941
21030
|
kind: "mutation",
|
|
20942
21031
|
auth: "admin"
|
|
@@ -32966,6 +33055,12 @@ Object.freeze({
|
|
|
32966
33055
|
addonId: null,
|
|
32967
33056
|
access: "create"
|
|
32968
33057
|
},
|
|
33058
|
+
"pipelineAnalytics.reconcileFromDisk": {
|
|
33059
|
+
capName: "pipeline-analytics",
|
|
33060
|
+
capScope: "device",
|
|
33061
|
+
addonId: null,
|
|
33062
|
+
access: "create"
|
|
33063
|
+
},
|
|
32969
33064
|
"pipelineAnalytics.refreshStorageLocationsForMigration": {
|
|
32970
33065
|
capName: "pipeline-analytics",
|
|
32971
33066
|
capScope: "device",
|
|
@@ -33368,6 +33463,12 @@ Object.freeze({
|
|
|
33368
33463
|
addonId: null,
|
|
33369
33464
|
access: "view"
|
|
33370
33465
|
},
|
|
33466
|
+
"pipelineOrchestrator.getReconcileFromDiskStatus": {
|
|
33467
|
+
capName: "pipeline-orchestrator",
|
|
33468
|
+
capScope: "system",
|
|
33469
|
+
addonId: null,
|
|
33470
|
+
access: "view"
|
|
33471
|
+
},
|
|
33371
33472
|
"pipelineOrchestrator.listAgentSettings": {
|
|
33372
33473
|
capName: "pipeline-orchestrator",
|
|
33373
33474
|
capScope: "system",
|
|
@@ -33392,6 +33493,12 @@ Object.freeze({
|
|
|
33392
33493
|
addonId: null,
|
|
33393
33494
|
access: "create"
|
|
33394
33495
|
},
|
|
33496
|
+
"pipelineOrchestrator.reconcileFromDisk": {
|
|
33497
|
+
capName: "pipeline-orchestrator",
|
|
33498
|
+
capScope: "system",
|
|
33499
|
+
addonId: null,
|
|
33500
|
+
access: "create"
|
|
33501
|
+
},
|
|
33395
33502
|
"pipelineOrchestrator.removeAgentSettings": {
|
|
33396
33503
|
capName: "pipeline-orchestrator",
|
|
33397
33504
|
capScope: "system",
|
|
@@ -36383,6 +36490,11 @@ Object.freeze({
|
|
|
36383
36490
|
form: "single",
|
|
36384
36491
|
optional: true
|
|
36385
36492
|
}],
|
|
36493
|
+
"pipelineAnalytics.reconcileFromDisk": [{
|
|
36494
|
+
name: "deviceId",
|
|
36495
|
+
form: "single",
|
|
36496
|
+
optional: false
|
|
36497
|
+
}],
|
|
36386
36498
|
"pipelineAnalytics.restageRetrainTrack": [{
|
|
36387
36499
|
name: "deviceId",
|
|
36388
36500
|
form: "single",
|
|
@@ -37448,6 +37560,8 @@ DEFAULT_NATIVE_LEASE_SETTINGS.budgetMb;
|
|
|
37448
37560
|
DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
37449
37561
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
37450
37562
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
37563
|
+
var MB = 1024 * 1024;
|
|
37564
|
+
1024 * MB, 3072 * MB;
|
|
37451
37565
|
//#endregion
|
|
37452
37566
|
//#region ../../node_modules/@apocaliss92/wyze-bridge-js/dist/index.js
|
|
37453
37567
|
var __require = /* @__PURE__ */ ((x) => typeof __require$1 !== "undefined" ? __require$1 : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof __require$1 !== "undefined" ? __require$1 : a)[b] }) : x)(function(x) {
|
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.25",
|
|
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",
|