@camstack/addon-provider-wyze 0.1.20 → 0.1.21
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 +194 -14
- package/dist/addon.mjs +194 -14
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -30,7 +30,7 @@ let events = require("events");
|
|
|
30
30
|
let net = require("net");
|
|
31
31
|
net = __toESM(net, 1);
|
|
32
32
|
let node_child_process = require("node:child_process");
|
|
33
|
-
//#region ../types/dist/event-category-
|
|
33
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
34
34
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
35
35
|
EventCategory["SystemBoot"] = "system.boot";
|
|
36
36
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -180,6 +180,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
180
180
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
181
181
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
182
182
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
183
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
184
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
185
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
183
186
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
184
187
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
185
188
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -10813,10 +10816,23 @@ var deviceDiscoveryCapability = {
|
|
|
10813
10816
|
}
|
|
10814
10817
|
};
|
|
10815
10818
|
/**
|
|
10816
|
-
* Doorbell button cap.
|
|
10817
|
-
*
|
|
10818
|
-
*
|
|
10819
|
-
*
|
|
10819
|
+
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
10820
|
+
* name (same pattern as `snapshot`):
|
|
10821
|
+
*
|
|
10822
|
+
* - **Native** providers: registered per-device by device-driver
|
|
10823
|
+
* addons via `ctx.registerNativeCap` — either on a
|
|
10824
|
+
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
10825
|
+
* or directly on the camera (Reolink registers at camera level).
|
|
10826
|
+
* Emits an `onPressed` event every time the firmware pushes a
|
|
10827
|
+
* ring; status tracks the last press and a pressCount since start
|
|
10828
|
+
* (diagnostic).
|
|
10829
|
+
*
|
|
10830
|
+
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
10831
|
+
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
10832
|
+
* device (contact / switch / event-emitter …) into a doorbell for
|
|
10833
|
+
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
10834
|
+
* it per camera in the device-bindings UI, then picks the source
|
|
10835
|
+
* device + trigger in the per-device settings.
|
|
10820
10836
|
*
|
|
10821
10837
|
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
10822
10838
|
* — subscribers listening at the camera level receive ring events
|
|
@@ -10837,7 +10853,10 @@ var doorbellCapability = {
|
|
|
10837
10853
|
scope: "device",
|
|
10838
10854
|
deviceNative: true,
|
|
10839
10855
|
mode: "singleton",
|
|
10840
|
-
|
|
10856
|
+
kind: "wrapper",
|
|
10857
|
+
defaultActive: false,
|
|
10858
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
10859
|
+
exposesDeviceSettings: true,
|
|
10841
10860
|
methods: {},
|
|
10842
10861
|
events: {
|
|
10843
10862
|
/**
|
|
@@ -17206,6 +17225,14 @@ var ConfigEntrySchema = object({
|
|
|
17206
17225
|
value: unknown(),
|
|
17207
17226
|
description: string().optional()
|
|
17208
17227
|
});
|
|
17228
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
17229
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
17230
|
+
var LinkedDeviceSchema = object({
|
|
17231
|
+
deviceId: number(),
|
|
17232
|
+
name: string(),
|
|
17233
|
+
location: string().nullable(),
|
|
17234
|
+
features: array(string())
|
|
17235
|
+
});
|
|
17209
17236
|
var SavedDeviceRowSchema = object({
|
|
17210
17237
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
17211
17238
|
id: number(),
|
|
@@ -17427,7 +17454,10 @@ method(object({
|
|
|
17427
17454
|
}), _void(), {
|
|
17428
17455
|
kind: "mutation",
|
|
17429
17456
|
auth: "admin"
|
|
17430
|
-
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }),
|
|
17457
|
+
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
17458
|
+
mode: DeviceLinkModeSchema,
|
|
17459
|
+
devices: array(LinkedDeviceSchema)
|
|
17460
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
17431
17461
|
deviceId: number(),
|
|
17432
17462
|
values: record(string(), unknown())
|
|
17433
17463
|
}), object({ success: literal(true) }), {
|
|
@@ -18696,6 +18726,61 @@ var EventKindSchema = _enum([
|
|
|
18696
18726
|
"object",
|
|
18697
18727
|
"audio"
|
|
18698
18728
|
]);
|
|
18729
|
+
/**
|
|
18730
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
18731
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
18732
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
18733
|
+
*/
|
|
18734
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
18735
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
18736
|
+
var EventKindIconSchema = _enum([
|
|
18737
|
+
"motion",
|
|
18738
|
+
"audio",
|
|
18739
|
+
"person",
|
|
18740
|
+
"vehicle",
|
|
18741
|
+
"animal",
|
|
18742
|
+
"door",
|
|
18743
|
+
"pir",
|
|
18744
|
+
"smoke",
|
|
18745
|
+
"water",
|
|
18746
|
+
"button",
|
|
18747
|
+
"generic"
|
|
18748
|
+
]);
|
|
18749
|
+
var EventKindCategorySchema = _enum([
|
|
18750
|
+
"motion",
|
|
18751
|
+
"audio",
|
|
18752
|
+
"detection",
|
|
18753
|
+
"sensor",
|
|
18754
|
+
"custom"
|
|
18755
|
+
]);
|
|
18756
|
+
var EventKindDescriptorSchema = object({
|
|
18757
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
18758
|
+
kind: string(),
|
|
18759
|
+
label: string(),
|
|
18760
|
+
/** Hex color for timeline/legend rendering. */
|
|
18761
|
+
color: string(),
|
|
18762
|
+
icon: EventKindIconSchema,
|
|
18763
|
+
category: EventKindCategorySchema,
|
|
18764
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18765
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
18766
|
+
source: object({
|
|
18767
|
+
capName: string(),
|
|
18768
|
+
deviceId: number()
|
|
18769
|
+
})
|
|
18770
|
+
});
|
|
18771
|
+
var SensorEventSchema = object({
|
|
18772
|
+
id: string(),
|
|
18773
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
18774
|
+
* yields N rows, one per camera). */
|
|
18775
|
+
deviceId: number(),
|
|
18776
|
+
/** The linked sensor device whose state changed. */
|
|
18777
|
+
sourceDeviceId: number(),
|
|
18778
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
18779
|
+
kind: string(),
|
|
18780
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
18781
|
+
value: record(string(), unknown()).nullable(),
|
|
18782
|
+
timestamp: number()
|
|
18783
|
+
});
|
|
18699
18784
|
var TrackPositionSchema = object({
|
|
18700
18785
|
x: number(),
|
|
18701
18786
|
y: number(),
|
|
@@ -18709,6 +18794,30 @@ var TrackSnapshotSchema = object({
|
|
|
18709
18794
|
mediaKey: string()
|
|
18710
18795
|
});
|
|
18711
18796
|
/**
|
|
18797
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
18798
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
18799
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
18800
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
18801
|
+
*/
|
|
18802
|
+
var TrackEnvelopeSchema = object({
|
|
18803
|
+
minX: number(),
|
|
18804
|
+
minY: number(),
|
|
18805
|
+
maxX: number(),
|
|
18806
|
+
maxY: number()
|
|
18807
|
+
});
|
|
18808
|
+
/**
|
|
18809
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
18810
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
18811
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
18812
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
18813
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
18814
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
18815
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
18816
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
18817
|
+
* (`getObjectEvents` et al.).
|
|
18818
|
+
*/
|
|
18819
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
18820
|
+
/**
|
|
18712
18821
|
* One audio-classification label heard on the track's camera while the
|
|
18713
18822
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
18714
18823
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -18759,7 +18868,11 @@ var TrackSchema = object({
|
|
|
18759
18868
|
/** Audio-classification labels heard on the camera during the track's
|
|
18760
18869
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
18761
18870
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
18762
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
18871
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
18872
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
18873
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
18874
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
18875
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
18763
18876
|
});
|
|
18764
18877
|
var BaseEventFields = {
|
|
18765
18878
|
id: string(),
|
|
@@ -18869,11 +18982,13 @@ var MediaFileSchema = object({
|
|
|
18869
18982
|
sizeBytes: number(),
|
|
18870
18983
|
timestamp: number()
|
|
18871
18984
|
});
|
|
18985
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
18986
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
18872
18987
|
var DeviceEventQueryInput = object({
|
|
18873
18988
|
deviceId: number(),
|
|
18874
18989
|
since: number().optional(),
|
|
18875
18990
|
until: number().optional(),
|
|
18876
|
-
limit: number().int().min(1).max(
|
|
18991
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
18877
18992
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
18878
18993
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
18879
18994
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -18881,6 +18996,27 @@ var DeviceEventQueryInput = object({
|
|
|
18881
18996
|
projection: _enum(["full", "slim"]).optional()
|
|
18882
18997
|
});
|
|
18883
18998
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
18999
|
+
var RecentTracksQueryInput = object({
|
|
19000
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
19001
|
+
deviceIds: array(number()),
|
|
19002
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
19003
|
+
since: number().optional(),
|
|
19004
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
19005
|
+
until: number().optional(),
|
|
19006
|
+
/** Page size. Default 200, max 1000. */
|
|
19007
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
19008
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
19009
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
19010
|
+
cursor: string().optional(),
|
|
19011
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
19012
|
+
projection: TrackProjectionSchema.optional()
|
|
19013
|
+
});
|
|
19014
|
+
var RecentTracksPageSchema = object({
|
|
19015
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
19016
|
+
tracks: array(TrackSchema).readonly(),
|
|
19017
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
19018
|
+
nextCursor: string().nullable()
|
|
19019
|
+
});
|
|
18884
19020
|
var KeyEventQueryInput = object({
|
|
18885
19021
|
deviceId: number(),
|
|
18886
19022
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -18963,11 +19099,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18963
19099
|
deviceId: number(),
|
|
18964
19100
|
since: number().optional(),
|
|
18965
19101
|
until: number().optional(),
|
|
18966
|
-
limit: number().optional()
|
|
18967
|
-
|
|
19102
|
+
limit: number().optional(),
|
|
19103
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
19104
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
19105
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
19106
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
19107
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
19108
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
19109
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
19110
|
+
projection: TrackProjectionSchema.optional()
|
|
19111
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
18968
19112
|
kind: "mutation",
|
|
18969
19113
|
auth: "admin"
|
|
18970
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(
|
|
19114
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19115
|
+
deviceId: number(),
|
|
19116
|
+
since: number().optional(),
|
|
19117
|
+
until: number().optional(),
|
|
19118
|
+
kinds: array(string()).optional(),
|
|
19119
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19120
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
18971
19121
|
deviceId: number(),
|
|
18972
19122
|
since: number(),
|
|
18973
19123
|
until: number(),
|
|
@@ -22270,7 +22420,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
22270
22420
|
/**
|
|
22271
22421
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
22272
22422
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
22273
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22423
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22424
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
22425
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
22426
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
22427
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
22428
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
22274
22429
|
*/
|
|
22275
22430
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
22276
22431
|
kind: literal("segment"),
|
|
@@ -22279,7 +22434,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
22279
22434
|
bytes: number()
|
|
22280
22435
|
}), object({
|
|
22281
22436
|
kind: literal("gap"),
|
|
22282
|
-
nearestEdgeMs: number().nullable()
|
|
22437
|
+
nearestEdgeMs: number().nullable(),
|
|
22438
|
+
prevEndMs: number().nullable().optional()
|
|
22283
22439
|
})]);
|
|
22284
22440
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
22285
22441
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -23861,6 +24017,12 @@ Object.freeze({
|
|
|
23861
24017
|
addonId: null,
|
|
23862
24018
|
access: "view"
|
|
23863
24019
|
},
|
|
24020
|
+
"deviceManager.getLinkedDevices": {
|
|
24021
|
+
capName: "device-manager",
|
|
24022
|
+
capScope: "system",
|
|
24023
|
+
addonId: null,
|
|
24024
|
+
access: "view"
|
|
24025
|
+
},
|
|
23864
24026
|
"deviceManager.getRoleDisplayDefaults": {
|
|
23865
24027
|
capName: "device-manager",
|
|
23866
24028
|
capScope: "system",
|
|
@@ -25415,6 +25577,12 @@ Object.freeze({
|
|
|
25415
25577
|
addonId: null,
|
|
25416
25578
|
access: "view"
|
|
25417
25579
|
},
|
|
25580
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
25581
|
+
capName: "pipeline-analytics",
|
|
25582
|
+
capScope: "device",
|
|
25583
|
+
addonId: null,
|
|
25584
|
+
access: "view"
|
|
25585
|
+
},
|
|
25418
25586
|
"pipelineAnalytics.getTrack": {
|
|
25419
25587
|
capName: "pipeline-analytics",
|
|
25420
25588
|
capScope: "device",
|
|
@@ -25427,6 +25595,18 @@ Object.freeze({
|
|
|
25427
25595
|
addonId: null,
|
|
25428
25596
|
access: "view"
|
|
25429
25597
|
},
|
|
25598
|
+
"pipelineAnalytics.listEventKinds": {
|
|
25599
|
+
capName: "pipeline-analytics",
|
|
25600
|
+
capScope: "device",
|
|
25601
|
+
addonId: null,
|
|
25602
|
+
access: "view"
|
|
25603
|
+
},
|
|
25604
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
25605
|
+
capName: "pipeline-analytics",
|
|
25606
|
+
capScope: "device",
|
|
25607
|
+
addonId: null,
|
|
25608
|
+
access: "view"
|
|
25609
|
+
},
|
|
25430
25610
|
"pipelineAnalytics.listTracks": {
|
|
25431
25611
|
capName: "pipeline-analytics",
|
|
25432
25612
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { spawn } from "node:child_process";
|
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
|
|
11
11
|
//#endregion
|
|
12
|
-
//#region ../types/dist/event-category-
|
|
12
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
13
13
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
14
14
|
EventCategory["SystemBoot"] = "system.boot";
|
|
15
15
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -159,6 +159,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
159
159
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
160
160
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
161
161
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
162
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
163
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
164
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
162
165
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
163
166
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
164
167
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -10792,10 +10795,23 @@ var deviceDiscoveryCapability = {
|
|
|
10792
10795
|
}
|
|
10793
10796
|
};
|
|
10794
10797
|
/**
|
|
10795
|
-
* Doorbell button cap.
|
|
10796
|
-
*
|
|
10797
|
-
*
|
|
10798
|
-
*
|
|
10798
|
+
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
10799
|
+
* name (same pattern as `snapshot`):
|
|
10800
|
+
*
|
|
10801
|
+
* - **Native** providers: registered per-device by device-driver
|
|
10802
|
+
* addons via `ctx.registerNativeCap` — either on a
|
|
10803
|
+
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
10804
|
+
* or directly on the camera (Reolink registers at camera level).
|
|
10805
|
+
* Emits an `onPressed` event every time the firmware pushes a
|
|
10806
|
+
* ring; status tracks the last press and a pressCount since start
|
|
10807
|
+
* (diagnostic).
|
|
10808
|
+
*
|
|
10809
|
+
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
10810
|
+
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
10811
|
+
* device (contact / switch / event-emitter …) into a doorbell for
|
|
10812
|
+
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
10813
|
+
* it per camera in the device-bindings UI, then picks the source
|
|
10814
|
+
* device + trigger in the per-device settings.
|
|
10799
10815
|
*
|
|
10800
10816
|
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
10801
10817
|
* — subscribers listening at the camera level receive ring events
|
|
@@ -10816,7 +10832,10 @@ var doorbellCapability = {
|
|
|
10816
10832
|
scope: "device",
|
|
10817
10833
|
deviceNative: true,
|
|
10818
10834
|
mode: "singleton",
|
|
10819
|
-
|
|
10835
|
+
kind: "wrapper",
|
|
10836
|
+
defaultActive: false,
|
|
10837
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
10838
|
+
exposesDeviceSettings: true,
|
|
10820
10839
|
methods: {},
|
|
10821
10840
|
events: {
|
|
10822
10841
|
/**
|
|
@@ -17185,6 +17204,14 @@ var ConfigEntrySchema = object({
|
|
|
17185
17204
|
value: unknown(),
|
|
17186
17205
|
description: string().optional()
|
|
17187
17206
|
});
|
|
17207
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
17208
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
17209
|
+
var LinkedDeviceSchema = object({
|
|
17210
|
+
deviceId: number(),
|
|
17211
|
+
name: string(),
|
|
17212
|
+
location: string().nullable(),
|
|
17213
|
+
features: array(string())
|
|
17214
|
+
});
|
|
17188
17215
|
var SavedDeviceRowSchema = object({
|
|
17189
17216
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
17190
17217
|
id: number(),
|
|
@@ -17406,7 +17433,10 @@ method(object({
|
|
|
17406
17433
|
}), _void(), {
|
|
17407
17434
|
kind: "mutation",
|
|
17408
17435
|
auth: "admin"
|
|
17409
|
-
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }),
|
|
17436
|
+
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
17437
|
+
mode: DeviceLinkModeSchema,
|
|
17438
|
+
devices: array(LinkedDeviceSchema)
|
|
17439
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
17410
17440
|
deviceId: number(),
|
|
17411
17441
|
values: record(string(), unknown())
|
|
17412
17442
|
}), object({ success: literal(true) }), {
|
|
@@ -18675,6 +18705,61 @@ var EventKindSchema = _enum([
|
|
|
18675
18705
|
"object",
|
|
18676
18706
|
"audio"
|
|
18677
18707
|
]);
|
|
18708
|
+
/**
|
|
18709
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
18710
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
18711
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
18712
|
+
*/
|
|
18713
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
18714
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
18715
|
+
var EventKindIconSchema = _enum([
|
|
18716
|
+
"motion",
|
|
18717
|
+
"audio",
|
|
18718
|
+
"person",
|
|
18719
|
+
"vehicle",
|
|
18720
|
+
"animal",
|
|
18721
|
+
"door",
|
|
18722
|
+
"pir",
|
|
18723
|
+
"smoke",
|
|
18724
|
+
"water",
|
|
18725
|
+
"button",
|
|
18726
|
+
"generic"
|
|
18727
|
+
]);
|
|
18728
|
+
var EventKindCategorySchema = _enum([
|
|
18729
|
+
"motion",
|
|
18730
|
+
"audio",
|
|
18731
|
+
"detection",
|
|
18732
|
+
"sensor",
|
|
18733
|
+
"custom"
|
|
18734
|
+
]);
|
|
18735
|
+
var EventKindDescriptorSchema = object({
|
|
18736
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
18737
|
+
kind: string(),
|
|
18738
|
+
label: string(),
|
|
18739
|
+
/** Hex color for timeline/legend rendering. */
|
|
18740
|
+
color: string(),
|
|
18741
|
+
icon: EventKindIconSchema,
|
|
18742
|
+
category: EventKindCategorySchema,
|
|
18743
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18744
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
18745
|
+
source: object({
|
|
18746
|
+
capName: string(),
|
|
18747
|
+
deviceId: number()
|
|
18748
|
+
})
|
|
18749
|
+
});
|
|
18750
|
+
var SensorEventSchema = object({
|
|
18751
|
+
id: string(),
|
|
18752
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
18753
|
+
* yields N rows, one per camera). */
|
|
18754
|
+
deviceId: number(),
|
|
18755
|
+
/** The linked sensor device whose state changed. */
|
|
18756
|
+
sourceDeviceId: number(),
|
|
18757
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
18758
|
+
kind: string(),
|
|
18759
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
18760
|
+
value: record(string(), unknown()).nullable(),
|
|
18761
|
+
timestamp: number()
|
|
18762
|
+
});
|
|
18678
18763
|
var TrackPositionSchema = object({
|
|
18679
18764
|
x: number(),
|
|
18680
18765
|
y: number(),
|
|
@@ -18688,6 +18773,30 @@ var TrackSnapshotSchema = object({
|
|
|
18688
18773
|
mediaKey: string()
|
|
18689
18774
|
});
|
|
18690
18775
|
/**
|
|
18776
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
18777
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
18778
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
18779
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
18780
|
+
*/
|
|
18781
|
+
var TrackEnvelopeSchema = object({
|
|
18782
|
+
minX: number(),
|
|
18783
|
+
minY: number(),
|
|
18784
|
+
maxX: number(),
|
|
18785
|
+
maxY: number()
|
|
18786
|
+
});
|
|
18787
|
+
/**
|
|
18788
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
18789
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
18790
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
18791
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
18792
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
18793
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
18794
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
18795
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
18796
|
+
* (`getObjectEvents` et al.).
|
|
18797
|
+
*/
|
|
18798
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
18799
|
+
/**
|
|
18691
18800
|
* One audio-classification label heard on the track's camera while the
|
|
18692
18801
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
18693
18802
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -18738,7 +18847,11 @@ var TrackSchema = object({
|
|
|
18738
18847
|
/** Audio-classification labels heard on the camera during the track's
|
|
18739
18848
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
18740
18849
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
18741
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
18850
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
18851
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
18852
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
18853
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
18854
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
18742
18855
|
});
|
|
18743
18856
|
var BaseEventFields = {
|
|
18744
18857
|
id: string(),
|
|
@@ -18848,11 +18961,13 @@ var MediaFileSchema = object({
|
|
|
18848
18961
|
sizeBytes: number(),
|
|
18849
18962
|
timestamp: number()
|
|
18850
18963
|
});
|
|
18964
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
18965
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
18851
18966
|
var DeviceEventQueryInput = object({
|
|
18852
18967
|
deviceId: number(),
|
|
18853
18968
|
since: number().optional(),
|
|
18854
18969
|
until: number().optional(),
|
|
18855
|
-
limit: number().int().min(1).max(
|
|
18970
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
18856
18971
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
18857
18972
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
18858
18973
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -18860,6 +18975,27 @@ var DeviceEventQueryInput = object({
|
|
|
18860
18975
|
projection: _enum(["full", "slim"]).optional()
|
|
18861
18976
|
});
|
|
18862
18977
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
18978
|
+
var RecentTracksQueryInput = object({
|
|
18979
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
18980
|
+
deviceIds: array(number()),
|
|
18981
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
18982
|
+
since: number().optional(),
|
|
18983
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
18984
|
+
until: number().optional(),
|
|
18985
|
+
/** Page size. Default 200, max 1000. */
|
|
18986
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
18987
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
18988
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
18989
|
+
cursor: string().optional(),
|
|
18990
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
18991
|
+
projection: TrackProjectionSchema.optional()
|
|
18992
|
+
});
|
|
18993
|
+
var RecentTracksPageSchema = object({
|
|
18994
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
18995
|
+
tracks: array(TrackSchema).readonly(),
|
|
18996
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
18997
|
+
nextCursor: string().nullable()
|
|
18998
|
+
});
|
|
18863
18999
|
var KeyEventQueryInput = object({
|
|
18864
19000
|
deviceId: number(),
|
|
18865
19001
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -18942,11 +19078,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18942
19078
|
deviceId: number(),
|
|
18943
19079
|
since: number().optional(),
|
|
18944
19080
|
until: number().optional(),
|
|
18945
|
-
limit: number().optional()
|
|
18946
|
-
|
|
19081
|
+
limit: number().optional(),
|
|
19082
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
19083
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
19084
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
19085
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
19086
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
19087
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
19088
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
19089
|
+
projection: TrackProjectionSchema.optional()
|
|
19090
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
18947
19091
|
kind: "mutation",
|
|
18948
19092
|
auth: "admin"
|
|
18949
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(
|
|
19093
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19094
|
+
deviceId: number(),
|
|
19095
|
+
since: number().optional(),
|
|
19096
|
+
until: number().optional(),
|
|
19097
|
+
kinds: array(string()).optional(),
|
|
19098
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19099
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
18950
19100
|
deviceId: number(),
|
|
18951
19101
|
since: number(),
|
|
18952
19102
|
until: number(),
|
|
@@ -22249,7 +22399,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
22249
22399
|
/**
|
|
22250
22400
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
22251
22401
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
22252
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22402
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22403
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
22404
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
22405
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
22406
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
22407
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
22253
22408
|
*/
|
|
22254
22409
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
22255
22410
|
kind: literal("segment"),
|
|
@@ -22258,7 +22413,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
22258
22413
|
bytes: number()
|
|
22259
22414
|
}), object({
|
|
22260
22415
|
kind: literal("gap"),
|
|
22261
|
-
nearestEdgeMs: number().nullable()
|
|
22416
|
+
nearestEdgeMs: number().nullable(),
|
|
22417
|
+
prevEndMs: number().nullable().optional()
|
|
22262
22418
|
})]);
|
|
22263
22419
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
22264
22420
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -23840,6 +23996,12 @@ Object.freeze({
|
|
|
23840
23996
|
addonId: null,
|
|
23841
23997
|
access: "view"
|
|
23842
23998
|
},
|
|
23999
|
+
"deviceManager.getLinkedDevices": {
|
|
24000
|
+
capName: "device-manager",
|
|
24001
|
+
capScope: "system",
|
|
24002
|
+
addonId: null,
|
|
24003
|
+
access: "view"
|
|
24004
|
+
},
|
|
23843
24005
|
"deviceManager.getRoleDisplayDefaults": {
|
|
23844
24006
|
capName: "device-manager",
|
|
23845
24007
|
capScope: "system",
|
|
@@ -25394,6 +25556,12 @@ Object.freeze({
|
|
|
25394
25556
|
addonId: null,
|
|
25395
25557
|
access: "view"
|
|
25396
25558
|
},
|
|
25559
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
25560
|
+
capName: "pipeline-analytics",
|
|
25561
|
+
capScope: "device",
|
|
25562
|
+
addonId: null,
|
|
25563
|
+
access: "view"
|
|
25564
|
+
},
|
|
25397
25565
|
"pipelineAnalytics.getTrack": {
|
|
25398
25566
|
capName: "pipeline-analytics",
|
|
25399
25567
|
capScope: "device",
|
|
@@ -25406,6 +25574,18 @@ Object.freeze({
|
|
|
25406
25574
|
addonId: null,
|
|
25407
25575
|
access: "view"
|
|
25408
25576
|
},
|
|
25577
|
+
"pipelineAnalytics.listEventKinds": {
|
|
25578
|
+
capName: "pipeline-analytics",
|
|
25579
|
+
capScope: "device",
|
|
25580
|
+
addonId: null,
|
|
25581
|
+
access: "view"
|
|
25582
|
+
},
|
|
25583
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
25584
|
+
capName: "pipeline-analytics",
|
|
25585
|
+
capScope: "device",
|
|
25586
|
+
addonId: null,
|
|
25587
|
+
access: "view"
|
|
25588
|
+
},
|
|
25409
25589
|
"pipelineAnalytics.listTracks": {
|
|
25410
25590
|
capName: "pipeline-analytics",
|
|
25411
25591
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-wyze",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
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",
|