@camstack/addon-notifiers 1.1.25 → 1.1.26
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 +176 -12
- package/dist/addon.mjs +176 -12
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
let node_zlib = require("node:zlib");
|
|
6
|
-
//#region ../types/dist/event-category-
|
|
6
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
7
7
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
8
8
|
EventCategory["SystemBoot"] = "system.boot";
|
|
9
9
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -153,6 +153,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
153
153
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
154
154
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
155
155
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
156
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
157
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
158
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
156
159
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
157
160
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
158
161
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -10127,7 +10130,7 @@ object({
|
|
|
10127
10130
|
deviceId: number(),
|
|
10128
10131
|
timestamp: number()
|
|
10129
10132
|
});
|
|
10130
|
-
DeviceType.Button;
|
|
10133
|
+
DeviceType.Button, DeviceType.Camera;
|
|
10131
10134
|
/**
|
|
10132
10135
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
10133
10136
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -14516,6 +14519,14 @@ var ConfigEntrySchema = object({
|
|
|
14516
14519
|
value: unknown(),
|
|
14517
14520
|
description: string().optional()
|
|
14518
14521
|
});
|
|
14522
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
14523
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
14524
|
+
var LinkedDeviceSchema = object({
|
|
14525
|
+
deviceId: number(),
|
|
14526
|
+
name: string(),
|
|
14527
|
+
location: string().nullable(),
|
|
14528
|
+
features: array(string())
|
|
14529
|
+
});
|
|
14519
14530
|
var SavedDeviceRowSchema = object({
|
|
14520
14531
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
14521
14532
|
id: number(),
|
|
@@ -14737,7 +14748,10 @@ method(object({
|
|
|
14737
14748
|
}), _void(), {
|
|
14738
14749
|
kind: "mutation",
|
|
14739
14750
|
auth: "admin"
|
|
14740
|
-
}), 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() }),
|
|
14751
|
+
}), 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({
|
|
14752
|
+
mode: DeviceLinkModeSchema,
|
|
14753
|
+
devices: array(LinkedDeviceSchema)
|
|
14754
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
14741
14755
|
deviceId: number(),
|
|
14742
14756
|
values: record(string(), unknown())
|
|
14743
14757
|
}), object({ success: literal(true) }), {
|
|
@@ -16020,6 +16034,61 @@ var EventKindSchema = _enum([
|
|
|
16020
16034
|
"object",
|
|
16021
16035
|
"audio"
|
|
16022
16036
|
]);
|
|
16037
|
+
/**
|
|
16038
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
16039
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
16040
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
16041
|
+
*/
|
|
16042
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
16043
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
16044
|
+
var EventKindIconSchema = _enum([
|
|
16045
|
+
"motion",
|
|
16046
|
+
"audio",
|
|
16047
|
+
"person",
|
|
16048
|
+
"vehicle",
|
|
16049
|
+
"animal",
|
|
16050
|
+
"door",
|
|
16051
|
+
"pir",
|
|
16052
|
+
"smoke",
|
|
16053
|
+
"water",
|
|
16054
|
+
"button",
|
|
16055
|
+
"generic"
|
|
16056
|
+
]);
|
|
16057
|
+
var EventKindCategorySchema = _enum([
|
|
16058
|
+
"motion",
|
|
16059
|
+
"audio",
|
|
16060
|
+
"detection",
|
|
16061
|
+
"sensor",
|
|
16062
|
+
"custom"
|
|
16063
|
+
]);
|
|
16064
|
+
var EventKindDescriptorSchema = object({
|
|
16065
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
16066
|
+
kind: string(),
|
|
16067
|
+
label: string(),
|
|
16068
|
+
/** Hex color for timeline/legend rendering. */
|
|
16069
|
+
color: string(),
|
|
16070
|
+
icon: EventKindIconSchema,
|
|
16071
|
+
category: EventKindCategorySchema,
|
|
16072
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
16073
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
16074
|
+
source: object({
|
|
16075
|
+
capName: string(),
|
|
16076
|
+
deviceId: number()
|
|
16077
|
+
})
|
|
16078
|
+
});
|
|
16079
|
+
var SensorEventSchema = object({
|
|
16080
|
+
id: string(),
|
|
16081
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
16082
|
+
* yields N rows, one per camera). */
|
|
16083
|
+
deviceId: number(),
|
|
16084
|
+
/** The linked sensor device whose state changed. */
|
|
16085
|
+
sourceDeviceId: number(),
|
|
16086
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
16087
|
+
kind: string(),
|
|
16088
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
16089
|
+
value: record(string(), unknown()).nullable(),
|
|
16090
|
+
timestamp: number()
|
|
16091
|
+
});
|
|
16023
16092
|
var TrackPositionSchema = object({
|
|
16024
16093
|
x: number(),
|
|
16025
16094
|
y: number(),
|
|
@@ -16033,6 +16102,30 @@ var TrackSnapshotSchema = object({
|
|
|
16033
16102
|
mediaKey: string()
|
|
16034
16103
|
});
|
|
16035
16104
|
/**
|
|
16105
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
16106
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
16107
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
16108
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
16109
|
+
*/
|
|
16110
|
+
var TrackEnvelopeSchema = object({
|
|
16111
|
+
minX: number(),
|
|
16112
|
+
minY: number(),
|
|
16113
|
+
maxX: number(),
|
|
16114
|
+
maxY: number()
|
|
16115
|
+
});
|
|
16116
|
+
/**
|
|
16117
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
16118
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
16119
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16120
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16121
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16122
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
16123
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16124
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16125
|
+
* (`getObjectEvents` et al.).
|
|
16126
|
+
*/
|
|
16127
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
16128
|
+
/**
|
|
16036
16129
|
* One audio-classification label heard on the track's camera while the
|
|
16037
16130
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
16038
16131
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -16083,7 +16176,11 @@ var TrackSchema = object({
|
|
|
16083
16176
|
/** Audio-classification labels heard on the camera during the track's
|
|
16084
16177
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
16085
16178
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
16086
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
16179
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
16180
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
16181
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
16182
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
16183
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
16087
16184
|
});
|
|
16088
16185
|
var BaseEventFields = {
|
|
16089
16186
|
id: string(),
|
|
@@ -16193,11 +16290,13 @@ var MediaFileSchema = object({
|
|
|
16193
16290
|
sizeBytes: number(),
|
|
16194
16291
|
timestamp: number()
|
|
16195
16292
|
});
|
|
16293
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
16294
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
16196
16295
|
var DeviceEventQueryInput = object({
|
|
16197
16296
|
deviceId: number(),
|
|
16198
16297
|
since: number().optional(),
|
|
16199
16298
|
until: number().optional(),
|
|
16200
|
-
limit: number().int().min(1).max(
|
|
16299
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
16201
16300
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
16202
16301
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
16203
16302
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -16205,6 +16304,27 @@ var DeviceEventQueryInput = object({
|
|
|
16205
16304
|
projection: _enum(["full", "slim"]).optional()
|
|
16206
16305
|
});
|
|
16207
16306
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
16307
|
+
var RecentTracksQueryInput = object({
|
|
16308
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
16309
|
+
deviceIds: array(number()),
|
|
16310
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
16311
|
+
since: number().optional(),
|
|
16312
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
16313
|
+
until: number().optional(),
|
|
16314
|
+
/** Page size. Default 200, max 1000. */
|
|
16315
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
16316
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
16317
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
16318
|
+
cursor: string().optional(),
|
|
16319
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
16320
|
+
projection: TrackProjectionSchema.optional()
|
|
16321
|
+
});
|
|
16322
|
+
var RecentTracksPageSchema = object({
|
|
16323
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
16324
|
+
tracks: array(TrackSchema).readonly(),
|
|
16325
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
16326
|
+
nextCursor: string().nullable()
|
|
16327
|
+
});
|
|
16208
16328
|
var KeyEventQueryInput = object({
|
|
16209
16329
|
deviceId: number(),
|
|
16210
16330
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -16287,11 +16407,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
16287
16407
|
deviceId: number(),
|
|
16288
16408
|
since: number().optional(),
|
|
16289
16409
|
until: number().optional(),
|
|
16290
|
-
limit: number().optional()
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16410
|
+
limit: number().optional(),
|
|
16411
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
16412
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
16413
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
16414
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
16415
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
16416
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
16417
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
16418
|
+
projection: TrackProjectionSchema.optional()
|
|
16419
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
16420
|
+
kind: "mutation",
|
|
16421
|
+
auth: "admin"
|
|
16422
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
16423
|
+
deviceId: number(),
|
|
16424
|
+
since: number().optional(),
|
|
16425
|
+
until: number().optional(),
|
|
16426
|
+
kinds: array(string()).optional(),
|
|
16427
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
16428
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
16295
16429
|
deviceId: number(),
|
|
16296
16430
|
since: number(),
|
|
16297
16431
|
until: number(),
|
|
@@ -19492,7 +19626,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
19492
19626
|
/**
|
|
19493
19627
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
19494
19628
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
19495
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19629
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19630
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
19631
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
19632
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
19633
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
19634
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
19496
19635
|
*/
|
|
19497
19636
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
19498
19637
|
kind: literal("segment"),
|
|
@@ -19501,7 +19640,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
19501
19640
|
bytes: number()
|
|
19502
19641
|
}), object({
|
|
19503
19642
|
kind: literal("gap"),
|
|
19504
|
-
nearestEdgeMs: number().nullable()
|
|
19643
|
+
nearestEdgeMs: number().nullable(),
|
|
19644
|
+
prevEndMs: number().nullable().optional()
|
|
19505
19645
|
})]);
|
|
19506
19646
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
19507
19647
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -21070,6 +21210,12 @@ Object.freeze({
|
|
|
21070
21210
|
addonId: null,
|
|
21071
21211
|
access: "view"
|
|
21072
21212
|
},
|
|
21213
|
+
"deviceManager.getLinkedDevices": {
|
|
21214
|
+
capName: "device-manager",
|
|
21215
|
+
capScope: "system",
|
|
21216
|
+
addonId: null,
|
|
21217
|
+
access: "view"
|
|
21218
|
+
},
|
|
21073
21219
|
"deviceManager.getRoleDisplayDefaults": {
|
|
21074
21220
|
capName: "device-manager",
|
|
21075
21221
|
capScope: "system",
|
|
@@ -22624,6 +22770,12 @@ Object.freeze({
|
|
|
22624
22770
|
addonId: null,
|
|
22625
22771
|
access: "view"
|
|
22626
22772
|
},
|
|
22773
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
22774
|
+
capName: "pipeline-analytics",
|
|
22775
|
+
capScope: "device",
|
|
22776
|
+
addonId: null,
|
|
22777
|
+
access: "view"
|
|
22778
|
+
},
|
|
22627
22779
|
"pipelineAnalytics.getTrack": {
|
|
22628
22780
|
capName: "pipeline-analytics",
|
|
22629
22781
|
capScope: "device",
|
|
@@ -22636,6 +22788,18 @@ Object.freeze({
|
|
|
22636
22788
|
addonId: null,
|
|
22637
22789
|
access: "view"
|
|
22638
22790
|
},
|
|
22791
|
+
"pipelineAnalytics.listEventKinds": {
|
|
22792
|
+
capName: "pipeline-analytics",
|
|
22793
|
+
capScope: "device",
|
|
22794
|
+
addonId: null,
|
|
22795
|
+
access: "view"
|
|
22796
|
+
},
|
|
22797
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
22798
|
+
capName: "pipeline-analytics",
|
|
22799
|
+
capScope: "device",
|
|
22800
|
+
addonId: null,
|
|
22801
|
+
access: "view"
|
|
22802
|
+
},
|
|
22639
22803
|
"pipelineAnalytics.listTracks": {
|
|
22640
22804
|
capName: "pipeline-analytics",
|
|
22641
22805
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
2
|
-
//#region ../types/dist/event-category-
|
|
2
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
3
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
5
5
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -149,6 +149,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
149
149
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
150
150
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
151
151
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
152
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
153
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
154
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
152
155
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
153
156
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
154
157
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -10123,7 +10126,7 @@ object({
|
|
|
10123
10126
|
deviceId: number(),
|
|
10124
10127
|
timestamp: number()
|
|
10125
10128
|
});
|
|
10126
|
-
DeviceType.Button;
|
|
10129
|
+
DeviceType.Button, DeviceType.Camera;
|
|
10127
10130
|
/**
|
|
10128
10131
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
10129
10132
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -14512,6 +14515,14 @@ var ConfigEntrySchema = object({
|
|
|
14512
14515
|
value: unknown(),
|
|
14513
14516
|
description: string().optional()
|
|
14514
14517
|
});
|
|
14518
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
14519
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
14520
|
+
var LinkedDeviceSchema = object({
|
|
14521
|
+
deviceId: number(),
|
|
14522
|
+
name: string(),
|
|
14523
|
+
location: string().nullable(),
|
|
14524
|
+
features: array(string())
|
|
14525
|
+
});
|
|
14515
14526
|
var SavedDeviceRowSchema = object({
|
|
14516
14527
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
14517
14528
|
id: number(),
|
|
@@ -14733,7 +14744,10 @@ method(object({
|
|
|
14733
14744
|
}), _void(), {
|
|
14734
14745
|
kind: "mutation",
|
|
14735
14746
|
auth: "admin"
|
|
14736
|
-
}), 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() }),
|
|
14747
|
+
}), 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({
|
|
14748
|
+
mode: DeviceLinkModeSchema,
|
|
14749
|
+
devices: array(LinkedDeviceSchema)
|
|
14750
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
14737
14751
|
deviceId: number(),
|
|
14738
14752
|
values: record(string(), unknown())
|
|
14739
14753
|
}), object({ success: literal(true) }), {
|
|
@@ -16016,6 +16030,61 @@ var EventKindSchema = _enum([
|
|
|
16016
16030
|
"object",
|
|
16017
16031
|
"audio"
|
|
16018
16032
|
]);
|
|
16033
|
+
/**
|
|
16034
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
16035
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
16036
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
16037
|
+
*/
|
|
16038
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
16039
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
16040
|
+
var EventKindIconSchema = _enum([
|
|
16041
|
+
"motion",
|
|
16042
|
+
"audio",
|
|
16043
|
+
"person",
|
|
16044
|
+
"vehicle",
|
|
16045
|
+
"animal",
|
|
16046
|
+
"door",
|
|
16047
|
+
"pir",
|
|
16048
|
+
"smoke",
|
|
16049
|
+
"water",
|
|
16050
|
+
"button",
|
|
16051
|
+
"generic"
|
|
16052
|
+
]);
|
|
16053
|
+
var EventKindCategorySchema = _enum([
|
|
16054
|
+
"motion",
|
|
16055
|
+
"audio",
|
|
16056
|
+
"detection",
|
|
16057
|
+
"sensor",
|
|
16058
|
+
"custom"
|
|
16059
|
+
]);
|
|
16060
|
+
var EventKindDescriptorSchema = object({
|
|
16061
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
16062
|
+
kind: string(),
|
|
16063
|
+
label: string(),
|
|
16064
|
+
/** Hex color for timeline/legend rendering. */
|
|
16065
|
+
color: string(),
|
|
16066
|
+
icon: EventKindIconSchema,
|
|
16067
|
+
category: EventKindCategorySchema,
|
|
16068
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
16069
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
16070
|
+
source: object({
|
|
16071
|
+
capName: string(),
|
|
16072
|
+
deviceId: number()
|
|
16073
|
+
})
|
|
16074
|
+
});
|
|
16075
|
+
var SensorEventSchema = object({
|
|
16076
|
+
id: string(),
|
|
16077
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
16078
|
+
* yields N rows, one per camera). */
|
|
16079
|
+
deviceId: number(),
|
|
16080
|
+
/** The linked sensor device whose state changed. */
|
|
16081
|
+
sourceDeviceId: number(),
|
|
16082
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
16083
|
+
kind: string(),
|
|
16084
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
16085
|
+
value: record(string(), unknown()).nullable(),
|
|
16086
|
+
timestamp: number()
|
|
16087
|
+
});
|
|
16019
16088
|
var TrackPositionSchema = object({
|
|
16020
16089
|
x: number(),
|
|
16021
16090
|
y: number(),
|
|
@@ -16029,6 +16098,30 @@ var TrackSnapshotSchema = object({
|
|
|
16029
16098
|
mediaKey: string()
|
|
16030
16099
|
});
|
|
16031
16100
|
/**
|
|
16101
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
16102
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
16103
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
16104
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
16105
|
+
*/
|
|
16106
|
+
var TrackEnvelopeSchema = object({
|
|
16107
|
+
minX: number(),
|
|
16108
|
+
minY: number(),
|
|
16109
|
+
maxX: number(),
|
|
16110
|
+
maxY: number()
|
|
16111
|
+
});
|
|
16112
|
+
/**
|
|
16113
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
16114
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
16115
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16116
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16117
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16118
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
16119
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16120
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16121
|
+
* (`getObjectEvents` et al.).
|
|
16122
|
+
*/
|
|
16123
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
16124
|
+
/**
|
|
16032
16125
|
* One audio-classification label heard on the track's camera while the
|
|
16033
16126
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
16034
16127
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -16079,7 +16172,11 @@ var TrackSchema = object({
|
|
|
16079
16172
|
/** Audio-classification labels heard on the camera during the track's
|
|
16080
16173
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
16081
16174
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
16082
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
16175
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
16176
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
16177
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
16178
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
16179
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
16083
16180
|
});
|
|
16084
16181
|
var BaseEventFields = {
|
|
16085
16182
|
id: string(),
|
|
@@ -16189,11 +16286,13 @@ var MediaFileSchema = object({
|
|
|
16189
16286
|
sizeBytes: number(),
|
|
16190
16287
|
timestamp: number()
|
|
16191
16288
|
});
|
|
16289
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
16290
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
16192
16291
|
var DeviceEventQueryInput = object({
|
|
16193
16292
|
deviceId: number(),
|
|
16194
16293
|
since: number().optional(),
|
|
16195
16294
|
until: number().optional(),
|
|
16196
|
-
limit: number().int().min(1).max(
|
|
16295
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
16197
16296
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
16198
16297
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
16199
16298
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -16201,6 +16300,27 @@ var DeviceEventQueryInput = object({
|
|
|
16201
16300
|
projection: _enum(["full", "slim"]).optional()
|
|
16202
16301
|
});
|
|
16203
16302
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
16303
|
+
var RecentTracksQueryInput = object({
|
|
16304
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
16305
|
+
deviceIds: array(number()),
|
|
16306
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
16307
|
+
since: number().optional(),
|
|
16308
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
16309
|
+
until: number().optional(),
|
|
16310
|
+
/** Page size. Default 200, max 1000. */
|
|
16311
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
16312
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
16313
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
16314
|
+
cursor: string().optional(),
|
|
16315
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
16316
|
+
projection: TrackProjectionSchema.optional()
|
|
16317
|
+
});
|
|
16318
|
+
var RecentTracksPageSchema = object({
|
|
16319
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
16320
|
+
tracks: array(TrackSchema).readonly(),
|
|
16321
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
16322
|
+
nextCursor: string().nullable()
|
|
16323
|
+
});
|
|
16204
16324
|
var KeyEventQueryInput = object({
|
|
16205
16325
|
deviceId: number(),
|
|
16206
16326
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -16283,11 +16403,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
16283
16403
|
deviceId: number(),
|
|
16284
16404
|
since: number().optional(),
|
|
16285
16405
|
until: number().optional(),
|
|
16286
|
-
limit: number().optional()
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16406
|
+
limit: number().optional(),
|
|
16407
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
16408
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
16409
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
16410
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
16411
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
16412
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
16413
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
16414
|
+
projection: TrackProjectionSchema.optional()
|
|
16415
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
16416
|
+
kind: "mutation",
|
|
16417
|
+
auth: "admin"
|
|
16418
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
16419
|
+
deviceId: number(),
|
|
16420
|
+
since: number().optional(),
|
|
16421
|
+
until: number().optional(),
|
|
16422
|
+
kinds: array(string()).optional(),
|
|
16423
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
16424
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
16291
16425
|
deviceId: number(),
|
|
16292
16426
|
since: number(),
|
|
16293
16427
|
until: number(),
|
|
@@ -19488,7 +19622,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
19488
19622
|
/**
|
|
19489
19623
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
19490
19624
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
19491
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19625
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19626
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
19627
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
19628
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
19629
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
19630
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
19492
19631
|
*/
|
|
19493
19632
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
19494
19633
|
kind: literal("segment"),
|
|
@@ -19497,7 +19636,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
19497
19636
|
bytes: number()
|
|
19498
19637
|
}), object({
|
|
19499
19638
|
kind: literal("gap"),
|
|
19500
|
-
nearestEdgeMs: number().nullable()
|
|
19639
|
+
nearestEdgeMs: number().nullable(),
|
|
19640
|
+
prevEndMs: number().nullable().optional()
|
|
19501
19641
|
})]);
|
|
19502
19642
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
19503
19643
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -21066,6 +21206,12 @@ Object.freeze({
|
|
|
21066
21206
|
addonId: null,
|
|
21067
21207
|
access: "view"
|
|
21068
21208
|
},
|
|
21209
|
+
"deviceManager.getLinkedDevices": {
|
|
21210
|
+
capName: "device-manager",
|
|
21211
|
+
capScope: "system",
|
|
21212
|
+
addonId: null,
|
|
21213
|
+
access: "view"
|
|
21214
|
+
},
|
|
21069
21215
|
"deviceManager.getRoleDisplayDefaults": {
|
|
21070
21216
|
capName: "device-manager",
|
|
21071
21217
|
capScope: "system",
|
|
@@ -22620,6 +22766,12 @@ Object.freeze({
|
|
|
22620
22766
|
addonId: null,
|
|
22621
22767
|
access: "view"
|
|
22622
22768
|
},
|
|
22769
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
22770
|
+
capName: "pipeline-analytics",
|
|
22771
|
+
capScope: "device",
|
|
22772
|
+
addonId: null,
|
|
22773
|
+
access: "view"
|
|
22774
|
+
},
|
|
22623
22775
|
"pipelineAnalytics.getTrack": {
|
|
22624
22776
|
capName: "pipeline-analytics",
|
|
22625
22777
|
capScope: "device",
|
|
@@ -22632,6 +22784,18 @@ Object.freeze({
|
|
|
22632
22784
|
addonId: null,
|
|
22633
22785
|
access: "view"
|
|
22634
22786
|
},
|
|
22787
|
+
"pipelineAnalytics.listEventKinds": {
|
|
22788
|
+
capName: "pipeline-analytics",
|
|
22789
|
+
capScope: "device",
|
|
22790
|
+
addonId: null,
|
|
22791
|
+
access: "view"
|
|
22792
|
+
},
|
|
22793
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
22794
|
+
capName: "pipeline-analytics",
|
|
22795
|
+
capScope: "device",
|
|
22796
|
+
addonId: null,
|
|
22797
|
+
access: "view"
|
|
22798
|
+
},
|
|
22635
22799
|
"pipelineAnalytics.listTracks": {
|
|
22636
22800
|
capName: "pipeline-analytics",
|
|
22637
22801
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-notifiers",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.26",
|
|
4
4
|
"description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|