@camstack/addon-notifiers 1.1.25 → 1.1.27
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 +202 -13
- package/dist/addon.mjs +202 -13
- 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";
|
|
@@ -7339,6 +7342,24 @@ var RecordingRetentionSchema = object({
|
|
|
7339
7342
|
maxSizeGb: number().min(0).optional()
|
|
7340
7343
|
});
|
|
7341
7344
|
/**
|
|
7345
|
+
* Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
|
|
7346
|
+
* sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
|
|
7347
|
+
* previews at. Five graduated steps; absent on a config = `standard` (the
|
|
7348
|
+
* shipped default, matching `sheet-geometry`/`sheet-composer`).
|
|
7349
|
+
*
|
|
7350
|
+
* Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
|
|
7351
|
+
* Each window's index sidecar carries its own tile dims, so a camera whose
|
|
7352
|
+
* preset changed over time renders every historical window at the dims it was
|
|
7353
|
+
* written with.
|
|
7354
|
+
*/
|
|
7355
|
+
var ScrubThumbnailPresetSchema = _enum([
|
|
7356
|
+
"minimal",
|
|
7357
|
+
"low",
|
|
7358
|
+
"standard",
|
|
7359
|
+
"high",
|
|
7360
|
+
"max"
|
|
7361
|
+
]);
|
|
7362
|
+
/**
|
|
7342
7363
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7343
7364
|
*
|
|
7344
7365
|
* `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
|
|
@@ -7375,7 +7396,14 @@ var RecordingConfigSchema = object({
|
|
|
7375
7396
|
* derived into bands once via `migrateConfigToBands`.
|
|
7376
7397
|
*/
|
|
7377
7398
|
bands: array(RecordingBandSchema).optional(),
|
|
7378
|
-
retention: RecordingRetentionSchema.optional()
|
|
7399
|
+
retention: RecordingRetentionSchema.optional(),
|
|
7400
|
+
/**
|
|
7401
|
+
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
7402
|
+
* timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
|
|
7403
|
+
* windows only — existing sheets are immutable, and each window's index
|
|
7404
|
+
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7405
|
+
*/
|
|
7406
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7379
7407
|
});
|
|
7380
7408
|
/**
|
|
7381
7409
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -10127,7 +10155,7 @@ object({
|
|
|
10127
10155
|
deviceId: number(),
|
|
10128
10156
|
timestamp: number()
|
|
10129
10157
|
});
|
|
10130
|
-
DeviceType.Button;
|
|
10158
|
+
DeviceType.Button, DeviceType.Camera;
|
|
10131
10159
|
/**
|
|
10132
10160
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
10133
10161
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -14516,6 +14544,14 @@ var ConfigEntrySchema = object({
|
|
|
14516
14544
|
value: unknown(),
|
|
14517
14545
|
description: string().optional()
|
|
14518
14546
|
});
|
|
14547
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
14548
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
14549
|
+
var LinkedDeviceSchema = object({
|
|
14550
|
+
deviceId: number(),
|
|
14551
|
+
name: string(),
|
|
14552
|
+
location: string().nullable(),
|
|
14553
|
+
features: array(string())
|
|
14554
|
+
});
|
|
14519
14555
|
var SavedDeviceRowSchema = object({
|
|
14520
14556
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
14521
14557
|
id: number(),
|
|
@@ -14737,7 +14773,10 @@ method(object({
|
|
|
14737
14773
|
}), _void(), {
|
|
14738
14774
|
kind: "mutation",
|
|
14739
14775
|
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() }),
|
|
14776
|
+
}), 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({
|
|
14777
|
+
mode: DeviceLinkModeSchema,
|
|
14778
|
+
devices: array(LinkedDeviceSchema)
|
|
14779
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
14741
14780
|
deviceId: number(),
|
|
14742
14781
|
values: record(string(), unknown())
|
|
14743
14782
|
}), object({ success: literal(true) }), {
|
|
@@ -16020,6 +16059,61 @@ var EventKindSchema = _enum([
|
|
|
16020
16059
|
"object",
|
|
16021
16060
|
"audio"
|
|
16022
16061
|
]);
|
|
16062
|
+
/**
|
|
16063
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
16064
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
16065
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
16066
|
+
*/
|
|
16067
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
16068
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
16069
|
+
var EventKindIconSchema = _enum([
|
|
16070
|
+
"motion",
|
|
16071
|
+
"audio",
|
|
16072
|
+
"person",
|
|
16073
|
+
"vehicle",
|
|
16074
|
+
"animal",
|
|
16075
|
+
"door",
|
|
16076
|
+
"pir",
|
|
16077
|
+
"smoke",
|
|
16078
|
+
"water",
|
|
16079
|
+
"button",
|
|
16080
|
+
"generic"
|
|
16081
|
+
]);
|
|
16082
|
+
var EventKindCategorySchema = _enum([
|
|
16083
|
+
"motion",
|
|
16084
|
+
"audio",
|
|
16085
|
+
"detection",
|
|
16086
|
+
"sensor",
|
|
16087
|
+
"custom"
|
|
16088
|
+
]);
|
|
16089
|
+
var EventKindDescriptorSchema = object({
|
|
16090
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
16091
|
+
kind: string(),
|
|
16092
|
+
label: string(),
|
|
16093
|
+
/** Hex color for timeline/legend rendering. */
|
|
16094
|
+
color: string(),
|
|
16095
|
+
icon: EventKindIconSchema,
|
|
16096
|
+
category: EventKindCategorySchema,
|
|
16097
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
16098
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
16099
|
+
source: object({
|
|
16100
|
+
capName: string(),
|
|
16101
|
+
deviceId: number()
|
|
16102
|
+
})
|
|
16103
|
+
});
|
|
16104
|
+
var SensorEventSchema = object({
|
|
16105
|
+
id: string(),
|
|
16106
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
16107
|
+
* yields N rows, one per camera). */
|
|
16108
|
+
deviceId: number(),
|
|
16109
|
+
/** The linked sensor device whose state changed. */
|
|
16110
|
+
sourceDeviceId: number(),
|
|
16111
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
16112
|
+
kind: string(),
|
|
16113
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
16114
|
+
value: record(string(), unknown()).nullable(),
|
|
16115
|
+
timestamp: number()
|
|
16116
|
+
});
|
|
16023
16117
|
var TrackPositionSchema = object({
|
|
16024
16118
|
x: number(),
|
|
16025
16119
|
y: number(),
|
|
@@ -16033,6 +16127,30 @@ var TrackSnapshotSchema = object({
|
|
|
16033
16127
|
mediaKey: string()
|
|
16034
16128
|
});
|
|
16035
16129
|
/**
|
|
16130
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
16131
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
16132
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
16133
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
16134
|
+
*/
|
|
16135
|
+
var TrackEnvelopeSchema = object({
|
|
16136
|
+
minX: number(),
|
|
16137
|
+
minY: number(),
|
|
16138
|
+
maxX: number(),
|
|
16139
|
+
maxY: number()
|
|
16140
|
+
});
|
|
16141
|
+
/**
|
|
16142
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
16143
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
16144
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16145
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16146
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16147
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
16148
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16149
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16150
|
+
* (`getObjectEvents` et al.).
|
|
16151
|
+
*/
|
|
16152
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
16153
|
+
/**
|
|
16036
16154
|
* One audio-classification label heard on the track's camera while the
|
|
16037
16155
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
16038
16156
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -16083,7 +16201,11 @@ var TrackSchema = object({
|
|
|
16083
16201
|
/** Audio-classification labels heard on the camera during the track's
|
|
16084
16202
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
16085
16203
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
16086
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
16204
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
16205
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
16206
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
16207
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
16208
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
16087
16209
|
});
|
|
16088
16210
|
var BaseEventFields = {
|
|
16089
16211
|
id: string(),
|
|
@@ -16193,11 +16315,13 @@ var MediaFileSchema = object({
|
|
|
16193
16315
|
sizeBytes: number(),
|
|
16194
16316
|
timestamp: number()
|
|
16195
16317
|
});
|
|
16318
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
16319
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
16196
16320
|
var DeviceEventQueryInput = object({
|
|
16197
16321
|
deviceId: number(),
|
|
16198
16322
|
since: number().optional(),
|
|
16199
16323
|
until: number().optional(),
|
|
16200
|
-
limit: number().int().min(1).max(
|
|
16324
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
16201
16325
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
16202
16326
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
16203
16327
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -16205,6 +16329,27 @@ var DeviceEventQueryInput = object({
|
|
|
16205
16329
|
projection: _enum(["full", "slim"]).optional()
|
|
16206
16330
|
});
|
|
16207
16331
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
16332
|
+
var RecentTracksQueryInput = object({
|
|
16333
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
16334
|
+
deviceIds: array(number()),
|
|
16335
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
16336
|
+
since: number().optional(),
|
|
16337
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
16338
|
+
until: number().optional(),
|
|
16339
|
+
/** Page size. Default 200, max 1000. */
|
|
16340
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
16341
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
16342
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
16343
|
+
cursor: string().optional(),
|
|
16344
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
16345
|
+
projection: TrackProjectionSchema.optional()
|
|
16346
|
+
});
|
|
16347
|
+
var RecentTracksPageSchema = object({
|
|
16348
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
16349
|
+
tracks: array(TrackSchema).readonly(),
|
|
16350
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
16351
|
+
nextCursor: string().nullable()
|
|
16352
|
+
});
|
|
16208
16353
|
var KeyEventQueryInput = object({
|
|
16209
16354
|
deviceId: number(),
|
|
16210
16355
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -16287,11 +16432,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
16287
16432
|
deviceId: number(),
|
|
16288
16433
|
since: number().optional(),
|
|
16289
16434
|
until: number().optional(),
|
|
16290
|
-
limit: number().optional()
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16435
|
+
limit: number().optional(),
|
|
16436
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
16437
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
16438
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
16439
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
16440
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
16441
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
16442
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
16443
|
+
projection: TrackProjectionSchema.optional()
|
|
16444
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
16445
|
+
kind: "mutation",
|
|
16446
|
+
auth: "admin"
|
|
16447
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
16448
|
+
deviceId: number(),
|
|
16449
|
+
since: number().optional(),
|
|
16450
|
+
until: number().optional(),
|
|
16451
|
+
kinds: array(string()).optional(),
|
|
16452
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
16453
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
16295
16454
|
deviceId: number(),
|
|
16296
16455
|
since: number(),
|
|
16297
16456
|
until: number(),
|
|
@@ -19492,7 +19651,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
19492
19651
|
/**
|
|
19493
19652
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
19494
19653
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
19495
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19654
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19655
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
19656
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
19657
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
19658
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
19659
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
19496
19660
|
*/
|
|
19497
19661
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
19498
19662
|
kind: literal("segment"),
|
|
@@ -19501,7 +19665,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
19501
19665
|
bytes: number()
|
|
19502
19666
|
}), object({
|
|
19503
19667
|
kind: literal("gap"),
|
|
19504
|
-
nearestEdgeMs: number().nullable()
|
|
19668
|
+
nearestEdgeMs: number().nullable(),
|
|
19669
|
+
prevEndMs: number().nullable().optional()
|
|
19505
19670
|
})]);
|
|
19506
19671
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
19507
19672
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -21070,6 +21235,12 @@ Object.freeze({
|
|
|
21070
21235
|
addonId: null,
|
|
21071
21236
|
access: "view"
|
|
21072
21237
|
},
|
|
21238
|
+
"deviceManager.getLinkedDevices": {
|
|
21239
|
+
capName: "device-manager",
|
|
21240
|
+
capScope: "system",
|
|
21241
|
+
addonId: null,
|
|
21242
|
+
access: "view"
|
|
21243
|
+
},
|
|
21073
21244
|
"deviceManager.getRoleDisplayDefaults": {
|
|
21074
21245
|
capName: "device-manager",
|
|
21075
21246
|
capScope: "system",
|
|
@@ -22624,6 +22795,12 @@ Object.freeze({
|
|
|
22624
22795
|
addonId: null,
|
|
22625
22796
|
access: "view"
|
|
22626
22797
|
},
|
|
22798
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
22799
|
+
capName: "pipeline-analytics",
|
|
22800
|
+
capScope: "device",
|
|
22801
|
+
addonId: null,
|
|
22802
|
+
access: "view"
|
|
22803
|
+
},
|
|
22627
22804
|
"pipelineAnalytics.getTrack": {
|
|
22628
22805
|
capName: "pipeline-analytics",
|
|
22629
22806
|
capScope: "device",
|
|
@@ -22636,6 +22813,18 @@ Object.freeze({
|
|
|
22636
22813
|
addonId: null,
|
|
22637
22814
|
access: "view"
|
|
22638
22815
|
},
|
|
22816
|
+
"pipelineAnalytics.listEventKinds": {
|
|
22817
|
+
capName: "pipeline-analytics",
|
|
22818
|
+
capScope: "device",
|
|
22819
|
+
addonId: null,
|
|
22820
|
+
access: "view"
|
|
22821
|
+
},
|
|
22822
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
22823
|
+
capName: "pipeline-analytics",
|
|
22824
|
+
capScope: "device",
|
|
22825
|
+
addonId: null,
|
|
22826
|
+
access: "view"
|
|
22827
|
+
},
|
|
22639
22828
|
"pipelineAnalytics.listTracks": {
|
|
22640
22829
|
capName: "pipeline-analytics",
|
|
22641
22830
|
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";
|
|
@@ -7335,6 +7338,24 @@ var RecordingRetentionSchema = object({
|
|
|
7335
7338
|
maxSizeGb: number().min(0).optional()
|
|
7336
7339
|
});
|
|
7337
7340
|
/**
|
|
7341
|
+
* Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
|
|
7342
|
+
* sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
|
|
7343
|
+
* previews at. Five graduated steps; absent on a config = `standard` (the
|
|
7344
|
+
* shipped default, matching `sheet-geometry`/`sheet-composer`).
|
|
7345
|
+
*
|
|
7346
|
+
* Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
|
|
7347
|
+
* Each window's index sidecar carries its own tile dims, so a camera whose
|
|
7348
|
+
* preset changed over time renders every historical window at the dims it was
|
|
7349
|
+
* written with.
|
|
7350
|
+
*/
|
|
7351
|
+
var ScrubThumbnailPresetSchema = _enum([
|
|
7352
|
+
"minimal",
|
|
7353
|
+
"low",
|
|
7354
|
+
"standard",
|
|
7355
|
+
"high",
|
|
7356
|
+
"max"
|
|
7357
|
+
]);
|
|
7358
|
+
/**
|
|
7338
7359
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7339
7360
|
*
|
|
7340
7361
|
* `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
|
|
@@ -7371,7 +7392,14 @@ var RecordingConfigSchema = object({
|
|
|
7371
7392
|
* derived into bands once via `migrateConfigToBands`.
|
|
7372
7393
|
*/
|
|
7373
7394
|
bands: array(RecordingBandSchema).optional(),
|
|
7374
|
-
retention: RecordingRetentionSchema.optional()
|
|
7395
|
+
retention: RecordingRetentionSchema.optional(),
|
|
7396
|
+
/**
|
|
7397
|
+
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
7398
|
+
* timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
|
|
7399
|
+
* windows only — existing sheets are immutable, and each window's index
|
|
7400
|
+
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7401
|
+
*/
|
|
7402
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7375
7403
|
});
|
|
7376
7404
|
/**
|
|
7377
7405
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -10123,7 +10151,7 @@ object({
|
|
|
10123
10151
|
deviceId: number(),
|
|
10124
10152
|
timestamp: number()
|
|
10125
10153
|
});
|
|
10126
|
-
DeviceType.Button;
|
|
10154
|
+
DeviceType.Button, DeviceType.Camera;
|
|
10127
10155
|
/**
|
|
10128
10156
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
10129
10157
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -14512,6 +14540,14 @@ var ConfigEntrySchema = object({
|
|
|
14512
14540
|
value: unknown(),
|
|
14513
14541
|
description: string().optional()
|
|
14514
14542
|
});
|
|
14543
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
14544
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
14545
|
+
var LinkedDeviceSchema = object({
|
|
14546
|
+
deviceId: number(),
|
|
14547
|
+
name: string(),
|
|
14548
|
+
location: string().nullable(),
|
|
14549
|
+
features: array(string())
|
|
14550
|
+
});
|
|
14515
14551
|
var SavedDeviceRowSchema = object({
|
|
14516
14552
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
14517
14553
|
id: number(),
|
|
@@ -14733,7 +14769,10 @@ method(object({
|
|
|
14733
14769
|
}), _void(), {
|
|
14734
14770
|
kind: "mutation",
|
|
14735
14771
|
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() }),
|
|
14772
|
+
}), 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({
|
|
14773
|
+
mode: DeviceLinkModeSchema,
|
|
14774
|
+
devices: array(LinkedDeviceSchema)
|
|
14775
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
14737
14776
|
deviceId: number(),
|
|
14738
14777
|
values: record(string(), unknown())
|
|
14739
14778
|
}), object({ success: literal(true) }), {
|
|
@@ -16016,6 +16055,61 @@ var EventKindSchema = _enum([
|
|
|
16016
16055
|
"object",
|
|
16017
16056
|
"audio"
|
|
16018
16057
|
]);
|
|
16058
|
+
/**
|
|
16059
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
16060
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
16061
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
16062
|
+
*/
|
|
16063
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
16064
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
16065
|
+
var EventKindIconSchema = _enum([
|
|
16066
|
+
"motion",
|
|
16067
|
+
"audio",
|
|
16068
|
+
"person",
|
|
16069
|
+
"vehicle",
|
|
16070
|
+
"animal",
|
|
16071
|
+
"door",
|
|
16072
|
+
"pir",
|
|
16073
|
+
"smoke",
|
|
16074
|
+
"water",
|
|
16075
|
+
"button",
|
|
16076
|
+
"generic"
|
|
16077
|
+
]);
|
|
16078
|
+
var EventKindCategorySchema = _enum([
|
|
16079
|
+
"motion",
|
|
16080
|
+
"audio",
|
|
16081
|
+
"detection",
|
|
16082
|
+
"sensor",
|
|
16083
|
+
"custom"
|
|
16084
|
+
]);
|
|
16085
|
+
var EventKindDescriptorSchema = object({
|
|
16086
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
16087
|
+
kind: string(),
|
|
16088
|
+
label: string(),
|
|
16089
|
+
/** Hex color for timeline/legend rendering. */
|
|
16090
|
+
color: string(),
|
|
16091
|
+
icon: EventKindIconSchema,
|
|
16092
|
+
category: EventKindCategorySchema,
|
|
16093
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
16094
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
16095
|
+
source: object({
|
|
16096
|
+
capName: string(),
|
|
16097
|
+
deviceId: number()
|
|
16098
|
+
})
|
|
16099
|
+
});
|
|
16100
|
+
var SensorEventSchema = object({
|
|
16101
|
+
id: string(),
|
|
16102
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
16103
|
+
* yields N rows, one per camera). */
|
|
16104
|
+
deviceId: number(),
|
|
16105
|
+
/** The linked sensor device whose state changed. */
|
|
16106
|
+
sourceDeviceId: number(),
|
|
16107
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
16108
|
+
kind: string(),
|
|
16109
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
16110
|
+
value: record(string(), unknown()).nullable(),
|
|
16111
|
+
timestamp: number()
|
|
16112
|
+
});
|
|
16019
16113
|
var TrackPositionSchema = object({
|
|
16020
16114
|
x: number(),
|
|
16021
16115
|
y: number(),
|
|
@@ -16029,6 +16123,30 @@ var TrackSnapshotSchema = object({
|
|
|
16029
16123
|
mediaKey: string()
|
|
16030
16124
|
});
|
|
16031
16125
|
/**
|
|
16126
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
16127
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
16128
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
16129
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
16130
|
+
*/
|
|
16131
|
+
var TrackEnvelopeSchema = object({
|
|
16132
|
+
minX: number(),
|
|
16133
|
+
minY: number(),
|
|
16134
|
+
maxX: number(),
|
|
16135
|
+
maxY: number()
|
|
16136
|
+
});
|
|
16137
|
+
/**
|
|
16138
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
16139
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
16140
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16141
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16142
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16143
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
16144
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16145
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16146
|
+
* (`getObjectEvents` et al.).
|
|
16147
|
+
*/
|
|
16148
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
16149
|
+
/**
|
|
16032
16150
|
* One audio-classification label heard on the track's camera while the
|
|
16033
16151
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
16034
16152
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -16079,7 +16197,11 @@ var TrackSchema = object({
|
|
|
16079
16197
|
/** Audio-classification labels heard on the camera during the track's
|
|
16080
16198
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
16081
16199
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
16082
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
16200
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
16201
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
16202
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
16203
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
16204
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
16083
16205
|
});
|
|
16084
16206
|
var BaseEventFields = {
|
|
16085
16207
|
id: string(),
|
|
@@ -16189,11 +16311,13 @@ var MediaFileSchema = object({
|
|
|
16189
16311
|
sizeBytes: number(),
|
|
16190
16312
|
timestamp: number()
|
|
16191
16313
|
});
|
|
16314
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
16315
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
16192
16316
|
var DeviceEventQueryInput = object({
|
|
16193
16317
|
deviceId: number(),
|
|
16194
16318
|
since: number().optional(),
|
|
16195
16319
|
until: number().optional(),
|
|
16196
|
-
limit: number().int().min(1).max(
|
|
16320
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
16197
16321
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
16198
16322
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
16199
16323
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -16201,6 +16325,27 @@ var DeviceEventQueryInput = object({
|
|
|
16201
16325
|
projection: _enum(["full", "slim"]).optional()
|
|
16202
16326
|
});
|
|
16203
16327
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
16328
|
+
var RecentTracksQueryInput = object({
|
|
16329
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
16330
|
+
deviceIds: array(number()),
|
|
16331
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
16332
|
+
since: number().optional(),
|
|
16333
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
16334
|
+
until: number().optional(),
|
|
16335
|
+
/** Page size. Default 200, max 1000. */
|
|
16336
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
16337
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
16338
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
16339
|
+
cursor: string().optional(),
|
|
16340
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
16341
|
+
projection: TrackProjectionSchema.optional()
|
|
16342
|
+
});
|
|
16343
|
+
var RecentTracksPageSchema = object({
|
|
16344
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
16345
|
+
tracks: array(TrackSchema).readonly(),
|
|
16346
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
16347
|
+
nextCursor: string().nullable()
|
|
16348
|
+
});
|
|
16204
16349
|
var KeyEventQueryInput = object({
|
|
16205
16350
|
deviceId: number(),
|
|
16206
16351
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -16283,11 +16428,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
16283
16428
|
deviceId: number(),
|
|
16284
16429
|
since: number().optional(),
|
|
16285
16430
|
until: number().optional(),
|
|
16286
|
-
limit: number().optional()
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16431
|
+
limit: number().optional(),
|
|
16432
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
16433
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
16434
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
16435
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
16436
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
16437
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
16438
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
16439
|
+
projection: TrackProjectionSchema.optional()
|
|
16440
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
16441
|
+
kind: "mutation",
|
|
16442
|
+
auth: "admin"
|
|
16443
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
16444
|
+
deviceId: number(),
|
|
16445
|
+
since: number().optional(),
|
|
16446
|
+
until: number().optional(),
|
|
16447
|
+
kinds: array(string()).optional(),
|
|
16448
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
16449
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
16291
16450
|
deviceId: number(),
|
|
16292
16451
|
since: number(),
|
|
16293
16452
|
until: number(),
|
|
@@ -19488,7 +19647,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
19488
19647
|
/**
|
|
19489
19648
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
19490
19649
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
19491
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19650
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
19651
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
19652
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
19653
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
19654
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
19655
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
19492
19656
|
*/
|
|
19493
19657
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
19494
19658
|
kind: literal("segment"),
|
|
@@ -19497,7 +19661,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
19497
19661
|
bytes: number()
|
|
19498
19662
|
}), object({
|
|
19499
19663
|
kind: literal("gap"),
|
|
19500
|
-
nearestEdgeMs: number().nullable()
|
|
19664
|
+
nearestEdgeMs: number().nullable(),
|
|
19665
|
+
prevEndMs: number().nullable().optional()
|
|
19501
19666
|
})]);
|
|
19502
19667
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
19503
19668
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -21066,6 +21231,12 @@ Object.freeze({
|
|
|
21066
21231
|
addonId: null,
|
|
21067
21232
|
access: "view"
|
|
21068
21233
|
},
|
|
21234
|
+
"deviceManager.getLinkedDevices": {
|
|
21235
|
+
capName: "device-manager",
|
|
21236
|
+
capScope: "system",
|
|
21237
|
+
addonId: null,
|
|
21238
|
+
access: "view"
|
|
21239
|
+
},
|
|
21069
21240
|
"deviceManager.getRoleDisplayDefaults": {
|
|
21070
21241
|
capName: "device-manager",
|
|
21071
21242
|
capScope: "system",
|
|
@@ -22620,6 +22791,12 @@ Object.freeze({
|
|
|
22620
22791
|
addonId: null,
|
|
22621
22792
|
access: "view"
|
|
22622
22793
|
},
|
|
22794
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
22795
|
+
capName: "pipeline-analytics",
|
|
22796
|
+
capScope: "device",
|
|
22797
|
+
addonId: null,
|
|
22798
|
+
access: "view"
|
|
22799
|
+
},
|
|
22623
22800
|
"pipelineAnalytics.getTrack": {
|
|
22624
22801
|
capName: "pipeline-analytics",
|
|
22625
22802
|
capScope: "device",
|
|
@@ -22632,6 +22809,18 @@ Object.freeze({
|
|
|
22632
22809
|
addonId: null,
|
|
22633
22810
|
access: "view"
|
|
22634
22811
|
},
|
|
22812
|
+
"pipelineAnalytics.listEventKinds": {
|
|
22813
|
+
capName: "pipeline-analytics",
|
|
22814
|
+
capScope: "device",
|
|
22815
|
+
addonId: null,
|
|
22816
|
+
access: "view"
|
|
22817
|
+
},
|
|
22818
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
22819
|
+
capName: "pipeline-analytics",
|
|
22820
|
+
capScope: "device",
|
|
22821
|
+
addonId: null,
|
|
22822
|
+
access: "view"
|
|
22823
|
+
},
|
|
22635
22824
|
"pipelineAnalytics.listTracks": {
|
|
22636
22825
|
capName: "pipeline-analytics",
|
|
22637
22826
|
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.27",
|
|
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",
|