@camstack/addon-import-alexa 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
|
@@ -38,7 +38,7 @@ let node_crypto = require("node:crypto");
|
|
|
38
38
|
let node_fs = require("node:fs");
|
|
39
39
|
let node_path = require("node:path");
|
|
40
40
|
node_path = __toESM(node_path);
|
|
41
|
-
//#region ../types/dist/event-category-
|
|
41
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
42
42
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
43
43
|
EventCategory["SystemBoot"] = "system.boot";
|
|
44
44
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -188,6 +188,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
188
188
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
189
189
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
190
190
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
191
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
192
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
193
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
191
194
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
192
195
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
193
196
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -10952,10 +10955,23 @@ var deviceDiscoveryCapability = {
|
|
|
10952
10955
|
}
|
|
10953
10956
|
};
|
|
10954
10957
|
/**
|
|
10955
|
-
* Doorbell button cap.
|
|
10956
|
-
*
|
|
10957
|
-
*
|
|
10958
|
-
*
|
|
10958
|
+
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
10959
|
+
* name (same pattern as `snapshot`):
|
|
10960
|
+
*
|
|
10961
|
+
* - **Native** providers: registered per-device by device-driver
|
|
10962
|
+
* addons via `ctx.registerNativeCap` — either on a
|
|
10963
|
+
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
10964
|
+
* or directly on the camera (Reolink registers at camera level).
|
|
10965
|
+
* Emits an `onPressed` event every time the firmware pushes a
|
|
10966
|
+
* ring; status tracks the last press and a pressCount since start
|
|
10967
|
+
* (diagnostic).
|
|
10968
|
+
*
|
|
10969
|
+
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
10970
|
+
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
10971
|
+
* device (contact / switch / event-emitter …) into a doorbell for
|
|
10972
|
+
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
10973
|
+
* it per camera in the device-bindings UI, then picks the source
|
|
10974
|
+
* device + trigger in the per-device settings.
|
|
10959
10975
|
*
|
|
10960
10976
|
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
10961
10977
|
* — subscribers listening at the camera level receive ring events
|
|
@@ -10976,7 +10992,10 @@ var doorbellCapability = {
|
|
|
10976
10992
|
scope: "device",
|
|
10977
10993
|
deviceNative: true,
|
|
10978
10994
|
mode: "singleton",
|
|
10979
|
-
|
|
10995
|
+
kind: "wrapper",
|
|
10996
|
+
defaultActive: false,
|
|
10997
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
10998
|
+
exposesDeviceSettings: true,
|
|
10980
10999
|
methods: {},
|
|
10981
11000
|
events: {
|
|
10982
11001
|
/**
|
|
@@ -17413,6 +17432,14 @@ var ConfigEntrySchema = object({
|
|
|
17413
17432
|
value: unknown(),
|
|
17414
17433
|
description: string().optional()
|
|
17415
17434
|
});
|
|
17435
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
17436
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
17437
|
+
var LinkedDeviceSchema = object({
|
|
17438
|
+
deviceId: number(),
|
|
17439
|
+
name: string(),
|
|
17440
|
+
location: string().nullable(),
|
|
17441
|
+
features: array(string())
|
|
17442
|
+
});
|
|
17416
17443
|
var SavedDeviceRowSchema = object({
|
|
17417
17444
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
17418
17445
|
id: number(),
|
|
@@ -17634,7 +17661,10 @@ method(object({
|
|
|
17634
17661
|
}), _void(), {
|
|
17635
17662
|
kind: "mutation",
|
|
17636
17663
|
auth: "admin"
|
|
17637
|
-
}), 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() }),
|
|
17664
|
+
}), 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({
|
|
17665
|
+
mode: DeviceLinkModeSchema,
|
|
17666
|
+
devices: array(LinkedDeviceSchema)
|
|
17667
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
17638
17668
|
deviceId: number(),
|
|
17639
17669
|
values: record(string(), unknown())
|
|
17640
17670
|
}), object({ success: literal(true) }), {
|
|
@@ -18903,6 +18933,61 @@ var EventKindSchema = _enum([
|
|
|
18903
18933
|
"object",
|
|
18904
18934
|
"audio"
|
|
18905
18935
|
]);
|
|
18936
|
+
/**
|
|
18937
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
18938
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
18939
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
18940
|
+
*/
|
|
18941
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
18942
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
18943
|
+
var EventKindIconSchema = _enum([
|
|
18944
|
+
"motion",
|
|
18945
|
+
"audio",
|
|
18946
|
+
"person",
|
|
18947
|
+
"vehicle",
|
|
18948
|
+
"animal",
|
|
18949
|
+
"door",
|
|
18950
|
+
"pir",
|
|
18951
|
+
"smoke",
|
|
18952
|
+
"water",
|
|
18953
|
+
"button",
|
|
18954
|
+
"generic"
|
|
18955
|
+
]);
|
|
18956
|
+
var EventKindCategorySchema = _enum([
|
|
18957
|
+
"motion",
|
|
18958
|
+
"audio",
|
|
18959
|
+
"detection",
|
|
18960
|
+
"sensor",
|
|
18961
|
+
"custom"
|
|
18962
|
+
]);
|
|
18963
|
+
var EventKindDescriptorSchema = object({
|
|
18964
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
18965
|
+
kind: string(),
|
|
18966
|
+
label: string(),
|
|
18967
|
+
/** Hex color for timeline/legend rendering. */
|
|
18968
|
+
color: string(),
|
|
18969
|
+
icon: EventKindIconSchema,
|
|
18970
|
+
category: EventKindCategorySchema,
|
|
18971
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18972
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
18973
|
+
source: object({
|
|
18974
|
+
capName: string(),
|
|
18975
|
+
deviceId: number()
|
|
18976
|
+
})
|
|
18977
|
+
});
|
|
18978
|
+
var SensorEventSchema = object({
|
|
18979
|
+
id: string(),
|
|
18980
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
18981
|
+
* yields N rows, one per camera). */
|
|
18982
|
+
deviceId: number(),
|
|
18983
|
+
/** The linked sensor device whose state changed. */
|
|
18984
|
+
sourceDeviceId: number(),
|
|
18985
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
18986
|
+
kind: string(),
|
|
18987
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
18988
|
+
value: record(string(), unknown()).nullable(),
|
|
18989
|
+
timestamp: number()
|
|
18990
|
+
});
|
|
18906
18991
|
var TrackPositionSchema = object({
|
|
18907
18992
|
x: number(),
|
|
18908
18993
|
y: number(),
|
|
@@ -18916,6 +19001,30 @@ var TrackSnapshotSchema = object({
|
|
|
18916
19001
|
mediaKey: string()
|
|
18917
19002
|
});
|
|
18918
19003
|
/**
|
|
19004
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
19005
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
19006
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
19007
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
19008
|
+
*/
|
|
19009
|
+
var TrackEnvelopeSchema = object({
|
|
19010
|
+
minX: number(),
|
|
19011
|
+
minY: number(),
|
|
19012
|
+
maxX: number(),
|
|
19013
|
+
maxY: number()
|
|
19014
|
+
});
|
|
19015
|
+
/**
|
|
19016
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
19017
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
19018
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
19019
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
19020
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
19021
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
19022
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
19023
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
19024
|
+
* (`getObjectEvents` et al.).
|
|
19025
|
+
*/
|
|
19026
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
19027
|
+
/**
|
|
18919
19028
|
* One audio-classification label heard on the track's camera while the
|
|
18920
19029
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
18921
19030
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -18966,7 +19075,11 @@ var TrackSchema = object({
|
|
|
18966
19075
|
/** Audio-classification labels heard on the camera during the track's
|
|
18967
19076
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
18968
19077
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
18969
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
19078
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
19079
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
19080
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
19081
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
19082
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
18970
19083
|
});
|
|
18971
19084
|
var BaseEventFields = {
|
|
18972
19085
|
id: string(),
|
|
@@ -19076,11 +19189,13 @@ var MediaFileSchema = object({
|
|
|
19076
19189
|
sizeBytes: number(),
|
|
19077
19190
|
timestamp: number()
|
|
19078
19191
|
});
|
|
19192
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
19193
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
19079
19194
|
var DeviceEventQueryInput = object({
|
|
19080
19195
|
deviceId: number(),
|
|
19081
19196
|
since: number().optional(),
|
|
19082
19197
|
until: number().optional(),
|
|
19083
|
-
limit: number().int().min(1).max(
|
|
19198
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
19084
19199
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
19085
19200
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
19086
19201
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -19088,6 +19203,27 @@ var DeviceEventQueryInput = object({
|
|
|
19088
19203
|
projection: _enum(["full", "slim"]).optional()
|
|
19089
19204
|
});
|
|
19090
19205
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
19206
|
+
var RecentTracksQueryInput = object({
|
|
19207
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
19208
|
+
deviceIds: array(number()),
|
|
19209
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
19210
|
+
since: number().optional(),
|
|
19211
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
19212
|
+
until: number().optional(),
|
|
19213
|
+
/** Page size. Default 200, max 1000. */
|
|
19214
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
19215
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
19216
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
19217
|
+
cursor: string().optional(),
|
|
19218
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
19219
|
+
projection: TrackProjectionSchema.optional()
|
|
19220
|
+
});
|
|
19221
|
+
var RecentTracksPageSchema = object({
|
|
19222
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
19223
|
+
tracks: array(TrackSchema).readonly(),
|
|
19224
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
19225
|
+
nextCursor: string().nullable()
|
|
19226
|
+
});
|
|
19091
19227
|
var KeyEventQueryInput = object({
|
|
19092
19228
|
deviceId: number(),
|
|
19093
19229
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -19170,11 +19306,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19170
19306
|
deviceId: number(),
|
|
19171
19307
|
since: number().optional(),
|
|
19172
19308
|
until: number().optional(),
|
|
19173
|
-
limit: number().optional()
|
|
19174
|
-
|
|
19309
|
+
limit: number().optional(),
|
|
19310
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
19311
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
19312
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
19313
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
19314
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
19315
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
19316
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
19317
|
+
projection: TrackProjectionSchema.optional()
|
|
19318
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
19175
19319
|
kind: "mutation",
|
|
19176
19320
|
auth: "admin"
|
|
19177
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(
|
|
19321
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19322
|
+
deviceId: number(),
|
|
19323
|
+
since: number().optional(),
|
|
19324
|
+
until: number().optional(),
|
|
19325
|
+
kinds: array(string()).optional(),
|
|
19326
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19327
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
19178
19328
|
deviceId: number(),
|
|
19179
19329
|
since: number(),
|
|
19180
19330
|
until: number(),
|
|
@@ -22392,7 +22542,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
22392
22542
|
/**
|
|
22393
22543
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
22394
22544
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
22395
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22545
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22546
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
22547
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
22548
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
22549
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
22550
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
22396
22551
|
*/
|
|
22397
22552
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
22398
22553
|
kind: literal("segment"),
|
|
@@ -22401,7 +22556,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
22401
22556
|
bytes: number()
|
|
22402
22557
|
}), object({
|
|
22403
22558
|
kind: literal("gap"),
|
|
22404
|
-
nearestEdgeMs: number().nullable()
|
|
22559
|
+
nearestEdgeMs: number().nullable(),
|
|
22560
|
+
prevEndMs: number().nullable().optional()
|
|
22405
22561
|
})]);
|
|
22406
22562
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
22407
22563
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -23970,6 +24126,12 @@ Object.freeze({
|
|
|
23970
24126
|
addonId: null,
|
|
23971
24127
|
access: "view"
|
|
23972
24128
|
},
|
|
24129
|
+
"deviceManager.getLinkedDevices": {
|
|
24130
|
+
capName: "device-manager",
|
|
24131
|
+
capScope: "system",
|
|
24132
|
+
addonId: null,
|
|
24133
|
+
access: "view"
|
|
24134
|
+
},
|
|
23973
24135
|
"deviceManager.getRoleDisplayDefaults": {
|
|
23974
24136
|
capName: "device-manager",
|
|
23975
24137
|
capScope: "system",
|
|
@@ -25524,6 +25686,12 @@ Object.freeze({
|
|
|
25524
25686
|
addonId: null,
|
|
25525
25687
|
access: "view"
|
|
25526
25688
|
},
|
|
25689
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
25690
|
+
capName: "pipeline-analytics",
|
|
25691
|
+
capScope: "device",
|
|
25692
|
+
addonId: null,
|
|
25693
|
+
access: "view"
|
|
25694
|
+
},
|
|
25527
25695
|
"pipelineAnalytics.getTrack": {
|
|
25528
25696
|
capName: "pipeline-analytics",
|
|
25529
25697
|
capScope: "device",
|
|
@@ -25536,6 +25704,18 @@ Object.freeze({
|
|
|
25536
25704
|
addonId: null,
|
|
25537
25705
|
access: "view"
|
|
25538
25706
|
},
|
|
25707
|
+
"pipelineAnalytics.listEventKinds": {
|
|
25708
|
+
capName: "pipeline-analytics",
|
|
25709
|
+
capScope: "device",
|
|
25710
|
+
addonId: null,
|
|
25711
|
+
access: "view"
|
|
25712
|
+
},
|
|
25713
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
25714
|
+
capName: "pipeline-analytics",
|
|
25715
|
+
capScope: "device",
|
|
25716
|
+
addonId: null,
|
|
25717
|
+
access: "view"
|
|
25718
|
+
},
|
|
25539
25719
|
"pipelineAnalytics.listTracks": {
|
|
25540
25720
|
capName: "pipeline-analytics",
|
|
25541
25721
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -38,7 +38,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
38
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
39
39
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
40
40
|
//#endregion
|
|
41
|
-
//#region ../types/dist/event-category-
|
|
41
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
42
42
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
43
43
|
EventCategory["SystemBoot"] = "system.boot";
|
|
44
44
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -188,6 +188,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
188
188
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
189
189
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
190
190
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
191
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
192
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
193
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
191
194
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
192
195
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
193
196
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -10952,10 +10955,23 @@ var deviceDiscoveryCapability = {
|
|
|
10952
10955
|
}
|
|
10953
10956
|
};
|
|
10954
10957
|
/**
|
|
10955
|
-
* Doorbell button cap.
|
|
10956
|
-
*
|
|
10957
|
-
*
|
|
10958
|
-
*
|
|
10958
|
+
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
10959
|
+
* name (same pattern as `snapshot`):
|
|
10960
|
+
*
|
|
10961
|
+
* - **Native** providers: registered per-device by device-driver
|
|
10962
|
+
* addons via `ctx.registerNativeCap` — either on a
|
|
10963
|
+
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
10964
|
+
* or directly on the camera (Reolink registers at camera level).
|
|
10965
|
+
* Emits an `onPressed` event every time the firmware pushes a
|
|
10966
|
+
* ring; status tracks the last press and a pressCount since start
|
|
10967
|
+
* (diagnostic).
|
|
10968
|
+
*
|
|
10969
|
+
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
10970
|
+
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
10971
|
+
* device (contact / switch / event-emitter …) into a doorbell for
|
|
10972
|
+
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
10973
|
+
* it per camera in the device-bindings UI, then picks the source
|
|
10974
|
+
* device + trigger in the per-device settings.
|
|
10959
10975
|
*
|
|
10960
10976
|
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
10961
10977
|
* — subscribers listening at the camera level receive ring events
|
|
@@ -10976,7 +10992,10 @@ var doorbellCapability = {
|
|
|
10976
10992
|
scope: "device",
|
|
10977
10993
|
deviceNative: true,
|
|
10978
10994
|
mode: "singleton",
|
|
10979
|
-
|
|
10995
|
+
kind: "wrapper",
|
|
10996
|
+
defaultActive: false,
|
|
10997
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
10998
|
+
exposesDeviceSettings: true,
|
|
10980
10999
|
methods: {},
|
|
10981
11000
|
events: {
|
|
10982
11001
|
/**
|
|
@@ -17413,6 +17432,14 @@ var ConfigEntrySchema = object({
|
|
|
17413
17432
|
value: unknown(),
|
|
17414
17433
|
description: string().optional()
|
|
17415
17434
|
});
|
|
17435
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
17436
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
17437
|
+
var LinkedDeviceSchema = object({
|
|
17438
|
+
deviceId: number(),
|
|
17439
|
+
name: string(),
|
|
17440
|
+
location: string().nullable(),
|
|
17441
|
+
features: array(string())
|
|
17442
|
+
});
|
|
17416
17443
|
var SavedDeviceRowSchema = object({
|
|
17417
17444
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
17418
17445
|
id: number(),
|
|
@@ -17634,7 +17661,10 @@ method(object({
|
|
|
17634
17661
|
}), _void(), {
|
|
17635
17662
|
kind: "mutation",
|
|
17636
17663
|
auth: "admin"
|
|
17637
|
-
}), 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() }),
|
|
17664
|
+
}), 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({
|
|
17665
|
+
mode: DeviceLinkModeSchema,
|
|
17666
|
+
devices: array(LinkedDeviceSchema)
|
|
17667
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
17638
17668
|
deviceId: number(),
|
|
17639
17669
|
values: record(string(), unknown())
|
|
17640
17670
|
}), object({ success: literal(true) }), {
|
|
@@ -18903,6 +18933,61 @@ var EventKindSchema = _enum([
|
|
|
18903
18933
|
"object",
|
|
18904
18934
|
"audio"
|
|
18905
18935
|
]);
|
|
18936
|
+
/**
|
|
18937
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
18938
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
18939
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
18940
|
+
*/
|
|
18941
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
18942
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
18943
|
+
var EventKindIconSchema = _enum([
|
|
18944
|
+
"motion",
|
|
18945
|
+
"audio",
|
|
18946
|
+
"person",
|
|
18947
|
+
"vehicle",
|
|
18948
|
+
"animal",
|
|
18949
|
+
"door",
|
|
18950
|
+
"pir",
|
|
18951
|
+
"smoke",
|
|
18952
|
+
"water",
|
|
18953
|
+
"button",
|
|
18954
|
+
"generic"
|
|
18955
|
+
]);
|
|
18956
|
+
var EventKindCategorySchema = _enum([
|
|
18957
|
+
"motion",
|
|
18958
|
+
"audio",
|
|
18959
|
+
"detection",
|
|
18960
|
+
"sensor",
|
|
18961
|
+
"custom"
|
|
18962
|
+
]);
|
|
18963
|
+
var EventKindDescriptorSchema = object({
|
|
18964
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
18965
|
+
kind: string(),
|
|
18966
|
+
label: string(),
|
|
18967
|
+
/** Hex color for timeline/legend rendering. */
|
|
18968
|
+
color: string(),
|
|
18969
|
+
icon: EventKindIconSchema,
|
|
18970
|
+
category: EventKindCategorySchema,
|
|
18971
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18972
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
18973
|
+
source: object({
|
|
18974
|
+
capName: string(),
|
|
18975
|
+
deviceId: number()
|
|
18976
|
+
})
|
|
18977
|
+
});
|
|
18978
|
+
var SensorEventSchema = object({
|
|
18979
|
+
id: string(),
|
|
18980
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
18981
|
+
* yields N rows, one per camera). */
|
|
18982
|
+
deviceId: number(),
|
|
18983
|
+
/** The linked sensor device whose state changed. */
|
|
18984
|
+
sourceDeviceId: number(),
|
|
18985
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
18986
|
+
kind: string(),
|
|
18987
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
18988
|
+
value: record(string(), unknown()).nullable(),
|
|
18989
|
+
timestamp: number()
|
|
18990
|
+
});
|
|
18906
18991
|
var TrackPositionSchema = object({
|
|
18907
18992
|
x: number(),
|
|
18908
18993
|
y: number(),
|
|
@@ -18916,6 +19001,30 @@ var TrackSnapshotSchema = object({
|
|
|
18916
19001
|
mediaKey: string()
|
|
18917
19002
|
});
|
|
18918
19003
|
/**
|
|
19004
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
19005
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
19006
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
19007
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
19008
|
+
*/
|
|
19009
|
+
var TrackEnvelopeSchema = object({
|
|
19010
|
+
minX: number(),
|
|
19011
|
+
minY: number(),
|
|
19012
|
+
maxX: number(),
|
|
19013
|
+
maxY: number()
|
|
19014
|
+
});
|
|
19015
|
+
/**
|
|
19016
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
19017
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
19018
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
19019
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
19020
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
19021
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
19022
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
19023
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
19024
|
+
* (`getObjectEvents` et al.).
|
|
19025
|
+
*/
|
|
19026
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
19027
|
+
/**
|
|
18919
19028
|
* One audio-classification label heard on the track's camera while the
|
|
18920
19029
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
18921
19030
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -18966,7 +19075,11 @@ var TrackSchema = object({
|
|
|
18966
19075
|
/** Audio-classification labels heard on the camera during the track's
|
|
18967
19076
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
18968
19077
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
18969
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
19078
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
19079
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
19080
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
19081
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
19082
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
18970
19083
|
});
|
|
18971
19084
|
var BaseEventFields = {
|
|
18972
19085
|
id: string(),
|
|
@@ -19076,11 +19189,13 @@ var MediaFileSchema = object({
|
|
|
19076
19189
|
sizeBytes: number(),
|
|
19077
19190
|
timestamp: number()
|
|
19078
19191
|
});
|
|
19192
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
19193
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
19079
19194
|
var DeviceEventQueryInput = object({
|
|
19080
19195
|
deviceId: number(),
|
|
19081
19196
|
since: number().optional(),
|
|
19082
19197
|
until: number().optional(),
|
|
19083
|
-
limit: number().int().min(1).max(
|
|
19198
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
19084
19199
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
19085
19200
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
19086
19201
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -19088,6 +19203,27 @@ var DeviceEventQueryInput = object({
|
|
|
19088
19203
|
projection: _enum(["full", "slim"]).optional()
|
|
19089
19204
|
});
|
|
19090
19205
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
19206
|
+
var RecentTracksQueryInput = object({
|
|
19207
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
19208
|
+
deviceIds: array(number()),
|
|
19209
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
19210
|
+
since: number().optional(),
|
|
19211
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
19212
|
+
until: number().optional(),
|
|
19213
|
+
/** Page size. Default 200, max 1000. */
|
|
19214
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
19215
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
19216
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
19217
|
+
cursor: string().optional(),
|
|
19218
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
19219
|
+
projection: TrackProjectionSchema.optional()
|
|
19220
|
+
});
|
|
19221
|
+
var RecentTracksPageSchema = object({
|
|
19222
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
19223
|
+
tracks: array(TrackSchema).readonly(),
|
|
19224
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
19225
|
+
nextCursor: string().nullable()
|
|
19226
|
+
});
|
|
19091
19227
|
var KeyEventQueryInput = object({
|
|
19092
19228
|
deviceId: number(),
|
|
19093
19229
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -19170,11 +19306,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19170
19306
|
deviceId: number(),
|
|
19171
19307
|
since: number().optional(),
|
|
19172
19308
|
until: number().optional(),
|
|
19173
|
-
limit: number().optional()
|
|
19174
|
-
|
|
19309
|
+
limit: number().optional(),
|
|
19310
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
19311
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
19312
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
19313
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
19314
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
19315
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
19316
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
19317
|
+
projection: TrackProjectionSchema.optional()
|
|
19318
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
19175
19319
|
kind: "mutation",
|
|
19176
19320
|
auth: "admin"
|
|
19177
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(
|
|
19321
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19322
|
+
deviceId: number(),
|
|
19323
|
+
since: number().optional(),
|
|
19324
|
+
until: number().optional(),
|
|
19325
|
+
kinds: array(string()).optional(),
|
|
19326
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19327
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
19178
19328
|
deviceId: number(),
|
|
19179
19329
|
since: number(),
|
|
19180
19330
|
until: number(),
|
|
@@ -22392,7 +22542,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
22392
22542
|
/**
|
|
22393
22543
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
22394
22544
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
22395
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22545
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22546
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
22547
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
22548
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
22549
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
22550
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
22396
22551
|
*/
|
|
22397
22552
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
22398
22553
|
kind: literal("segment"),
|
|
@@ -22401,7 +22556,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
22401
22556
|
bytes: number()
|
|
22402
22557
|
}), object({
|
|
22403
22558
|
kind: literal("gap"),
|
|
22404
|
-
nearestEdgeMs: number().nullable()
|
|
22559
|
+
nearestEdgeMs: number().nullable(),
|
|
22560
|
+
prevEndMs: number().nullable().optional()
|
|
22405
22561
|
})]);
|
|
22406
22562
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
22407
22563
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -23970,6 +24126,12 @@ Object.freeze({
|
|
|
23970
24126
|
addonId: null,
|
|
23971
24127
|
access: "view"
|
|
23972
24128
|
},
|
|
24129
|
+
"deviceManager.getLinkedDevices": {
|
|
24130
|
+
capName: "device-manager",
|
|
24131
|
+
capScope: "system",
|
|
24132
|
+
addonId: null,
|
|
24133
|
+
access: "view"
|
|
24134
|
+
},
|
|
23973
24135
|
"deviceManager.getRoleDisplayDefaults": {
|
|
23974
24136
|
capName: "device-manager",
|
|
23975
24137
|
capScope: "system",
|
|
@@ -25524,6 +25686,12 @@ Object.freeze({
|
|
|
25524
25686
|
addonId: null,
|
|
25525
25687
|
access: "view"
|
|
25526
25688
|
},
|
|
25689
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
25690
|
+
capName: "pipeline-analytics",
|
|
25691
|
+
capScope: "device",
|
|
25692
|
+
addonId: null,
|
|
25693
|
+
access: "view"
|
|
25694
|
+
},
|
|
25527
25695
|
"pipelineAnalytics.getTrack": {
|
|
25528
25696
|
capName: "pipeline-analytics",
|
|
25529
25697
|
capScope: "device",
|
|
@@ -25536,6 +25704,18 @@ Object.freeze({
|
|
|
25536
25704
|
addonId: null,
|
|
25537
25705
|
access: "view"
|
|
25538
25706
|
},
|
|
25707
|
+
"pipelineAnalytics.listEventKinds": {
|
|
25708
|
+
capName: "pipeline-analytics",
|
|
25709
|
+
capScope: "device",
|
|
25710
|
+
addonId: null,
|
|
25711
|
+
access: "view"
|
|
25712
|
+
},
|
|
25713
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
25714
|
+
capName: "pipeline-analytics",
|
|
25715
|
+
capScope: "device",
|
|
25716
|
+
addonId: null,
|
|
25717
|
+
access: "view"
|
|
25718
|
+
},
|
|
25539
25719
|
"pipelineAnalytics.listTracks": {
|
|
25540
25720
|
capName: "pipeline-analytics",
|
|
25541
25721
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-import-alexa",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Alexa device-import provider for CamStack — imports the smart-home devices in a user's Alexa account via the unofficial alexa-remote2 cookie/token client (the inverse of the Alexa exporter)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|