@camstack/addon-mqtt-broker 1.2.89 → 1.2.92
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/mqtt-broker.addon.js +201 -14
- package/dist/mqtt-broker.addon.mjs +201 -14
- package/package.json +1 -1
|
@@ -44,7 +44,7 @@ let crypto$10 = __toESM(crypto$1, 1);
|
|
|
44
44
|
crypto$1 = __toESM(crypto$1);
|
|
45
45
|
let node_fs = require("node:fs");
|
|
46
46
|
let node_path = require("node:path");
|
|
47
|
-
//#region ../types/dist/event-category-
|
|
47
|
+
//#region ../types/dist/event-category-DAXzJeTX.mjs
|
|
48
48
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
49
49
|
EventCategory["SystemBoot"] = "system.boot";
|
|
50
50
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -636,7 +636,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
636
636
|
* issue. Payload `PipelineAnalyticsPlateGalleryChangedPayload`.
|
|
637
637
|
*/
|
|
638
638
|
EventCategory["PipelineAnalyticsPlateGalleryChanged"] = "pipeline-analytics.plate-gallery-changed";
|
|
639
|
-
EventCategory["FrigateLiveEvent"] = "frigate.live-event";
|
|
640
639
|
EventCategory["CameraStreamsProfileSlotsChanged"] = "camera-streams.onProfileSlotsChanged";
|
|
641
640
|
/**
|
|
642
641
|
* Stream-broker health watchdog. Per-broker (deviceId/profile) emission.
|
|
@@ -12601,7 +12600,7 @@ DeviceType.Camera;
|
|
|
12601
12600
|
var SourceInfoSchema = object({
|
|
12602
12601
|
/** Live dispatch key — mutable when the source system allows rename. */
|
|
12603
12602
|
id: string(),
|
|
12604
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | '
|
|
12603
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
12605
12604
|
system: string(),
|
|
12606
12605
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
12607
12606
|
* Used to detect rename when `id` changes. */
|
|
@@ -13088,7 +13087,7 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
|
|
|
13088
13087
|
* - `device-management.router.ts` (deleted in Phase 2)
|
|
13089
13088
|
* - `device-ops.router.ts` (compat layer — deleted; device-provider ops absorbed here)
|
|
13090
13089
|
*
|
|
13091
|
-
* All device provider addons (rtsp, onvif,
|
|
13090
|
+
* All device provider addons (rtsp, onvif, …) are hub-local: they may
|
|
13092
13091
|
* fork into separate processes but never run on remote cluster agents. Therefore:
|
|
13093
13092
|
* - No nodeId routing needed — this is a pure hub singleton.
|
|
13094
13093
|
* - The hub's DeviceRegistry is the single source of truth for all live devices.
|
|
@@ -17117,7 +17116,7 @@ var NcRuleInputSchema = object({
|
|
|
17117
17116
|
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
17118
17117
|
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
17119
17118
|
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
17120
|
-
* 30 is
|
|
17119
|
+
* 30 s is a widely shipped value for the same decision.
|
|
17121
17120
|
*
|
|
17122
17121
|
* ### What it replaces
|
|
17123
17122
|
*
|
|
@@ -19159,6 +19158,13 @@ var ZoneCrossingSchema = object({
|
|
|
19159
19158
|
/** Zone display name at crossing time (falls back to the id). */
|
|
19160
19159
|
zoneName: string().optional()
|
|
19161
19160
|
});
|
|
19161
|
+
/** One zone a box was stamped with, and how much of the BOX fell inside it. */
|
|
19162
|
+
var ZoneOverlapSchema = object({
|
|
19163
|
+
zoneId: string(),
|
|
19164
|
+
zoneName: string().optional(),
|
|
19165
|
+
/** Percentage of the BOX area inside the zone, 0–100. */
|
|
19166
|
+
overlapPct: number()
|
|
19167
|
+
});
|
|
19162
19168
|
var ObjectEventSchema = object({
|
|
19163
19169
|
...BaseEventFields,
|
|
19164
19170
|
kind: literal("object"),
|
|
@@ -19183,6 +19189,35 @@ var ObjectEventSchema = object({
|
|
|
19183
19189
|
bbox: BoundingBoxSchema.optional(),
|
|
19184
19190
|
/** Heavy JSON — omitted in slim projection. */
|
|
19185
19191
|
zones: array(string()).readonly().optional(),
|
|
19192
|
+
/**
|
|
19193
|
+
* How far inside each stamped zone the box actually was, as a percentage of
|
|
19194
|
+
* the BOX area.
|
|
19195
|
+
*
|
|
19196
|
+
* Membership alone cannot express "at least a third of it inside", which is
|
|
19197
|
+
* the bar an operator argues with — and the number already existed: the
|
|
19198
|
+
* engine computed it, the pipeline logged it, and then discarded it. It
|
|
19199
|
+
* matters most on the events that carry no track, where a rule has nothing
|
|
19200
|
+
* else to judge by.
|
|
19201
|
+
*/
|
|
19202
|
+
zoneOverlaps: array(ZoneOverlapSchema).readonly().optional(),
|
|
19203
|
+
/**
|
|
19204
|
+
* Present when this event describes a detection the TRACKER refused, so it
|
|
19205
|
+
* has no track and never will.
|
|
19206
|
+
*
|
|
19207
|
+
* A zone-scoped immediate rule asks "is there an animal in the flowerbed
|
|
19208
|
+
* NOW?"; tracking answers a different question ("is this the same subject as
|
|
19209
|
+
* before?") whose confirmation threshold presumes continuity. On 2026-09-09 a
|
|
19210
|
+
* dog at 0.7729, 100% inside a watched zone, was refused three times in six
|
|
19211
|
+
* seconds with three different candidate ids — seven analysed frames in the
|
|
19212
|
+
* window, the subject in a handful of them, metres apart — and produced no
|
|
19213
|
+
* event at all.
|
|
19214
|
+
*
|
|
19215
|
+
* It is NAMED rather than merely implied by a missing `trackId`: an event
|
|
19216
|
+
* with no track and no reason is indistinguishable from a track whose media
|
|
19217
|
+
* went missing, and a consumer that asks this one for a best shot or a
|
|
19218
|
+
* history is asking for something that never existed.
|
|
19219
|
+
*/
|
|
19220
|
+
spawnRefused: string().optional(),
|
|
19186
19221
|
/** Omitted in slim projection. */
|
|
19187
19222
|
state: TrackStateSchema.optional(),
|
|
19188
19223
|
/**
|
|
@@ -20256,6 +20291,60 @@ var NativeCropResultSchema = object({
|
|
|
20256
20291
|
*/
|
|
20257
20292
|
tier: _enum(["native", "ram-fullframe"]).optional()
|
|
20258
20293
|
});
|
|
20294
|
+
/**
|
|
20295
|
+
* What a PARKED frame is for — the `kind` half of the `(deviceId, trackId,
|
|
20296
|
+
* kind)` key ([D422](../../../docs/decisions/adr-0422-a-relevant-frame-is-parked-when-it-becomes-relevant.md)).
|
|
20297
|
+
*
|
|
20298
|
+
* - `keyFrame` — the track's clean best FULL frame at native width (capped by
|
|
20299
|
+
* the caller's `maxWidth`). What `keyFrame` + `keyFrameSmall` are written
|
|
20300
|
+
* from, and what the detail plane's full-frame rung cuts from.
|
|
20301
|
+
* - `thumbnail` — the best-shot subject slab: the caller's 16:9 central-square
|
|
20302
|
+
* window, cut by the runner at uncapped native resolution.
|
|
20303
|
+
*
|
|
20304
|
+
* The runner never interprets `trackId`; it is an opaque key the hub owns.
|
|
20305
|
+
*/
|
|
20306
|
+
var ParkedFrameKindSchema = _enum(["keyFrame", "thumbnail"]);
|
|
20307
|
+
/**
|
|
20308
|
+
* Why a park did NOT happen. Every one is logged on the runner with
|
|
20309
|
+
* `tags: { deviceId }` and the handle's measured age, because a handle already
|
|
20310
|
+
* gone at park time IS the defect the 150–500 ms window exists to prevent —
|
|
20311
|
+
* never a reason to retry in a loop.
|
|
20312
|
+
*
|
|
20313
|
+
* - `handle-gone` — the native surface no longer resolves this handle (never
|
|
20314
|
+
* registered, past the lease bound, or the worker released it). `detail`
|
|
20315
|
+
* carries the runner's own miss reason.
|
|
20316
|
+
* - `encode-failed` — pixels resolved and the JPEG encode threw.
|
|
20317
|
+
*/
|
|
20318
|
+
var ParkRefusalSchema = _enum(["handle-gone", "encode-failed"]);
|
|
20319
|
+
/** Answer to `parkTrackFrame` — a discriminated union, so "not parked" always names why. */
|
|
20320
|
+
var ParkTrackFrameResultSchema = discriminatedUnion("parked", [object({
|
|
20321
|
+
parked: literal(true),
|
|
20322
|
+
/** The node holding the parcel — what a later retrieval must be pinned to. */
|
|
20323
|
+
nodeId: string(),
|
|
20324
|
+
width: number().int().positive(),
|
|
20325
|
+
height: number().int().positive(),
|
|
20326
|
+
/** JPEG bytes the parcel costs on the node. */
|
|
20327
|
+
bytes: number().int().nonnegative(),
|
|
20328
|
+
/** Whether this park replaced a parcel already held for the key. */
|
|
20329
|
+
replaced: boolean()
|
|
20330
|
+
}), object({
|
|
20331
|
+
parked: literal(false),
|
|
20332
|
+
nodeId: string(),
|
|
20333
|
+
reason: ParkRefusalSchema,
|
|
20334
|
+
/** Age of the handle at the park, on the runner's clock; null if unknown. */
|
|
20335
|
+
handleAgeMs: number().nullable(),
|
|
20336
|
+
detail: string().optional()
|
|
20337
|
+
})]);
|
|
20338
|
+
/** A retrieved parcel — the runner's own JPEG, base64 for the wire. */
|
|
20339
|
+
var ParkedTrackFrameSchema = object({
|
|
20340
|
+
jpeg: string(),
|
|
20341
|
+
width: number().int().positive(),
|
|
20342
|
+
height: number().int().positive(),
|
|
20343
|
+
/** The frame instant the parcel shows (the caller's clock, echoed back). */
|
|
20344
|
+
timestamp: number(),
|
|
20345
|
+
/** When the node stored it (the node's clock). */
|
|
20346
|
+
parkedAt: number()
|
|
20347
|
+
});
|
|
20259
20348
|
/** Parent detection context passed to `runDetailSubtree` — the crop's
|
|
20260
20349
|
* originating detection, in FRAME-space coordinates. Reuses
|
|
20261
20350
|
* `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
|
|
@@ -20645,7 +20734,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
20645
20734
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
20646
20735
|
* analyzer providers) running on decoded frames in this runner.
|
|
20647
20736
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
20648
|
-
* analytics
|
|
20737
|
+
* analytics). The provider emits ProviderMotion
|
|
20649
20738
|
* events; the orchestrator forwards to `reportMotion`.
|
|
20650
20739
|
*/
|
|
20651
20740
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
@@ -20887,7 +20976,26 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
20887
20976
|
className: string(),
|
|
20888
20977
|
/** Camera the pixels came from. Diagnostics + log tags ONLY — never routing. */
|
|
20889
20978
|
sourceDeviceId: number()
|
|
20890
|
-
}), RunStatelessStepResultSchema, { kind: "mutation" })
|
|
20979
|
+
}), RunStatelessStepResultSchema, { kind: "mutation" }), method(object({
|
|
20980
|
+
deviceId: number(),
|
|
20981
|
+
/** Opaque to the runner — the hub's track id. */
|
|
20982
|
+
trackId: string(),
|
|
20983
|
+
kind: ParkedFrameKindSchema,
|
|
20984
|
+
handle: FrameHandleSchema,
|
|
20985
|
+
/** Normalized [0,1] window to cut. `{0,0,1,1}` for a full frame. */
|
|
20986
|
+
bbox: NativeCropBboxSchema,
|
|
20987
|
+
/** Width cap for a full-frame park (the `keyFrame` native cap). */
|
|
20988
|
+
maxWidth: number().int().positive().optional(),
|
|
20989
|
+
/** The frame instant (caller's clock) — orders parks for one key. */
|
|
20990
|
+
timestamp: number()
|
|
20991
|
+
}), ParkTrackFrameResultSchema, { kind: "mutation" }), method(object({
|
|
20992
|
+
deviceId: number(),
|
|
20993
|
+
trackId: string(),
|
|
20994
|
+
kind: ParkedFrameKindSchema
|
|
20995
|
+
}), ParkedTrackFrameSchema.nullable()), method(object({
|
|
20996
|
+
deviceId: number(),
|
|
20997
|
+
trackId: string()
|
|
20998
|
+
}), object({ released: number().int().nonnegative() }), { kind: "mutation" });
|
|
20891
20999
|
var CameraPipelineConfigSchema = object({
|
|
20892
21000
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
20893
21001
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -23816,7 +23924,7 @@ DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _v
|
|
|
23816
23924
|
*
|
|
23817
23925
|
* Implementations:
|
|
23818
23926
|
* - Each camera-providing addon registers this cap natively per
|
|
23819
|
-
* device (Reolink, Hikvision, RTSP,
|
|
23927
|
+
* device (Reolink, Hikvision, RTSP, ONVIF self).
|
|
23820
23928
|
* - Returns a snapshot from the persisted device config blob — no
|
|
23821
23929
|
* extra round-trip to the camera, no probing.
|
|
23822
23930
|
* - The cap is admin-only (`auth: 'admin'`) — credentials must not
|
|
@@ -25202,7 +25310,7 @@ var AvailableIntegrationTypeSchema = object({
|
|
|
25202
25310
|
* Which integration-marker cap the addon declared, so the wizard can
|
|
25203
25311
|
* branch on CAP — never on addon name. `device-adoption` integrations
|
|
25204
25312
|
* (Home Assistant, …) route through the broker step (Approach A);
|
|
25205
|
-
* `device-provider` integrations (Reolink/
|
|
25313
|
+
* `device-provider` integrations (Reolink/ONVIF) keep the
|
|
25206
25314
|
* legacy config → discovery flow.
|
|
25207
25315
|
*/
|
|
25208
25316
|
kind: _enum(["device-adoption", "device-provider"]),
|
|
@@ -27759,13 +27867,31 @@ var RecordingManifestSchema = object({
|
|
|
27759
27867
|
*/
|
|
27760
27868
|
playbackEndpoints: array(string())
|
|
27761
27869
|
});
|
|
27762
|
-
/**
|
|
27763
|
-
*
|
|
27870
|
+
/**
|
|
27871
|
+
* Recording storage usage for one camera — what the ARCHIVE holds for it,
|
|
27872
|
+
* across every profile and every resolvable location on this node.
|
|
27873
|
+
*
|
|
27874
|
+
* ## Archive vs residency, which is the whole point of this shape (D418)
|
|
27875
|
+
*
|
|
27876
|
+
* `usedBytes` / `oldestMs` / `segments` are the durable hour ledger's numbers:
|
|
27877
|
+
* the same quantity `RecordingLocationUsage.usedBytes` reports for the volume
|
|
27878
|
+
* this camera writes to, so the two can be added up and compared.
|
|
27879
|
+
*
|
|
27880
|
+
* They were not always. Until D418 this row came from the recorder's in-RAM
|
|
27881
|
+
* `RecordingIndex`, which since D287 holds only the live tail plus the hours
|
|
27882
|
+
* somebody hydrated — so a hub with 1.9 TB and 3.3 days of footage reported
|
|
27883
|
+
* 60.5 GB and "oldest: three hours ago" on the same page as the volume row
|
|
27884
|
+
* that said otherwise, and two people read it as retention eating recent
|
|
27885
|
+
* footage. Residency is still reported, under `residentBytes` /
|
|
27886
|
+
* `residentOldestMs`, which answer a different question and say so.
|
|
27887
|
+
*/
|
|
27764
27888
|
var RecordingDeviceUsageSchema = object({
|
|
27765
27889
|
deviceId: number(),
|
|
27890
|
+
/** Bytes the ARCHIVE holds for this camera on this node's resolvable
|
|
27891
|
+
* recordings locations. */
|
|
27766
27892
|
usedBytes: number(),
|
|
27767
27893
|
/**
|
|
27768
|
-
* Start of this camera's OLDEST
|
|
27894
|
+
* Start of this camera's OLDEST ARCHIVED segment, across every profile and
|
|
27769
27895
|
* location — the "Oldest footage" column in Recordings → Storage, and the
|
|
27770
27896
|
* only honest answer to "is retention actually holding?" per camera.
|
|
27771
27897
|
*
|
|
@@ -27775,7 +27901,24 @@ var RecordingDeviceUsageSchema = object({
|
|
|
27775
27901
|
* (types) and the addon ship on different trains, and the addon is usually
|
|
27776
27902
|
* the later of the two.
|
|
27777
27903
|
*/
|
|
27778
|
-
oldestMs: number().nullable().optional()
|
|
27904
|
+
oldestMs: number().nullable().optional(),
|
|
27905
|
+
/** Segments the archive holds for this camera — the "M" beside `usedBytes`.
|
|
27906
|
+
* OPTIONAL for the same train-skew reason as `oldestMs`. */
|
|
27907
|
+
segments: number().optional(),
|
|
27908
|
+
/**
|
|
27909
|
+
* RESIDENCY, not the archive: bytes the recorder process currently holds in
|
|
27910
|
+
* its RAM index — the live tail plus the hours a reader hydrated.
|
|
27911
|
+
*
|
|
27912
|
+
* It answers "what can be served without touching the disk", never "how much
|
|
27913
|
+
* footage this camera has". A UI that renders it must label it as such, and
|
|
27914
|
+
* must never total it as storage. OPTIONAL: a recorder predating D418 omits
|
|
27915
|
+
* it, and so does a node whose ledger could not answer.
|
|
27916
|
+
*/
|
|
27917
|
+
residentBytes: number().optional(),
|
|
27918
|
+
/** The residency counterpart of `oldestMs` — the oldest segment currently in
|
|
27919
|
+
* RAM, which on a healthy recorder is minutes ago and means nothing about
|
|
27920
|
+
* retention. `null` = nothing resident. */
|
|
27921
|
+
residentOldestMs: number().nullable().optional()
|
|
27779
27922
|
});
|
|
27780
27923
|
/** Recording storage usage + capacity for one storage location. */
|
|
27781
27924
|
var RecordingLocationUsageSchema = object({
|
|
@@ -27813,6 +27956,17 @@ var RecordingStorageUsageSchema = object({
|
|
|
27813
27956
|
totalUsedBytes: number(),
|
|
27814
27957
|
devices: array(RecordingDeviceUsageSchema),
|
|
27815
27958
|
/**
|
|
27959
|
+
* WHERE `devices[]` came from, so an empty table is never mistaken for empty
|
|
27960
|
+
* disks (D418).
|
|
27961
|
+
*
|
|
27962
|
+
* `archive` = the durable hour ledger answered. `unavailable` = this node
|
|
27963
|
+
* declared no ledger and the recorder REFUSED rather than answering the
|
|
27964
|
+
* question with the resident index (D295 rule 3) — the rows are UNKNOWN, not
|
|
27965
|
+
* zero, and a UI must say so. OPTIONAL: a recorder predating D418 omits it,
|
|
27966
|
+
* and its rows are residency.
|
|
27967
|
+
*/
|
|
27968
|
+
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
27969
|
+
/**
|
|
27816
27970
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
27817
27971
|
* of the payload without it: the hub serves this method through a BAKED
|
|
27818
27972
|
* router, so a hub whose framework train predates a change to this array
|
|
@@ -34200,6 +34354,24 @@ Object.freeze({
|
|
|
34200
34354
|
addonId: null,
|
|
34201
34355
|
access: "view"
|
|
34202
34356
|
},
|
|
34357
|
+
"pipelineRunner.getParkedTrackFrame": {
|
|
34358
|
+
capName: "pipeline-runner",
|
|
34359
|
+
capScope: "system",
|
|
34360
|
+
addonId: null,
|
|
34361
|
+
access: "view"
|
|
34362
|
+
},
|
|
34363
|
+
"pipelineRunner.parkTrackFrame": {
|
|
34364
|
+
capName: "pipeline-runner",
|
|
34365
|
+
capScope: "system",
|
|
34366
|
+
addonId: null,
|
|
34367
|
+
access: "create"
|
|
34368
|
+
},
|
|
34369
|
+
"pipelineRunner.releaseParkedTrackFrames": {
|
|
34370
|
+
capName: "pipeline-runner",
|
|
34371
|
+
capScope: "system",
|
|
34372
|
+
addonId: null,
|
|
34373
|
+
access: "create"
|
|
34374
|
+
},
|
|
34203
34375
|
"pipelineRunner.reportMotion": {
|
|
34204
34376
|
capName: "pipeline-runner",
|
|
34205
34377
|
capScope: "system",
|
|
@@ -37477,6 +37649,21 @@ Object.freeze({
|
|
|
37477
37649
|
form: "single",
|
|
37478
37650
|
optional: false
|
|
37479
37651
|
}],
|
|
37652
|
+
"pipelineRunner.getParkedTrackFrame": [{
|
|
37653
|
+
name: "deviceId",
|
|
37654
|
+
form: "single",
|
|
37655
|
+
optional: false
|
|
37656
|
+
}],
|
|
37657
|
+
"pipelineRunner.parkTrackFrame": [{
|
|
37658
|
+
name: "deviceId",
|
|
37659
|
+
form: "single",
|
|
37660
|
+
optional: false
|
|
37661
|
+
}],
|
|
37662
|
+
"pipelineRunner.releaseParkedTrackFrames": [{
|
|
37663
|
+
name: "deviceId",
|
|
37664
|
+
form: "single",
|
|
37665
|
+
optional: false
|
|
37666
|
+
}],
|
|
37480
37667
|
"pipelineRunner.reportMotion": [{
|
|
37481
37668
|
name: "deviceId",
|
|
37482
37669
|
form: "single",
|
|
@@ -38168,7 +38355,7 @@ var PreviewTextField = string().max(200);
|
|
|
38168
38355
|
* Whether the notification's preview is a STILL or a short animation.
|
|
38169
38356
|
*
|
|
38170
38357
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
38171
|
-
* rule)"* —
|
|
38358
|
+
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
38172
38359
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
38173
38360
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
38174
38361
|
* simply applies it to a dozen frames sampled across the render and assembles
|
|
@@ -39,7 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
39
39
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
40
40
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
41
41
|
//#endregion
|
|
42
|
-
//#region ../types/dist/event-category-
|
|
42
|
+
//#region ../types/dist/event-category-DAXzJeTX.mjs
|
|
43
43
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
44
44
|
EventCategory["SystemBoot"] = "system.boot";
|
|
45
45
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -631,7 +631,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
631
631
|
* issue. Payload `PipelineAnalyticsPlateGalleryChangedPayload`.
|
|
632
632
|
*/
|
|
633
633
|
EventCategory["PipelineAnalyticsPlateGalleryChanged"] = "pipeline-analytics.plate-gallery-changed";
|
|
634
|
-
EventCategory["FrigateLiveEvent"] = "frigate.live-event";
|
|
635
634
|
EventCategory["CameraStreamsProfileSlotsChanged"] = "camera-streams.onProfileSlotsChanged";
|
|
636
635
|
/**
|
|
637
636
|
* Stream-broker health watchdog. Per-broker (deviceId/profile) emission.
|
|
@@ -12596,7 +12595,7 @@ DeviceType.Camera;
|
|
|
12596
12595
|
var SourceInfoSchema = object({
|
|
12597
12596
|
/** Live dispatch key — mutable when the source system allows rename. */
|
|
12598
12597
|
id: string(),
|
|
12599
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | '
|
|
12598
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
12600
12599
|
system: string(),
|
|
12601
12600
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
12602
12601
|
* Used to detect rename when `id` changes. */
|
|
@@ -13083,7 +13082,7 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
|
|
|
13083
13082
|
* - `device-management.router.ts` (deleted in Phase 2)
|
|
13084
13083
|
* - `device-ops.router.ts` (compat layer — deleted; device-provider ops absorbed here)
|
|
13085
13084
|
*
|
|
13086
|
-
* All device provider addons (rtsp, onvif,
|
|
13085
|
+
* All device provider addons (rtsp, onvif, …) are hub-local: they may
|
|
13087
13086
|
* fork into separate processes but never run on remote cluster agents. Therefore:
|
|
13088
13087
|
* - No nodeId routing needed — this is a pure hub singleton.
|
|
13089
13088
|
* - The hub's DeviceRegistry is the single source of truth for all live devices.
|
|
@@ -17112,7 +17111,7 @@ var NcRuleInputSchema = object({
|
|
|
17112
17111
|
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
17113
17112
|
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
17114
17113
|
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
17115
|
-
* 30 is
|
|
17114
|
+
* 30 s is a widely shipped value for the same decision.
|
|
17116
17115
|
*
|
|
17117
17116
|
* ### What it replaces
|
|
17118
17117
|
*
|
|
@@ -19154,6 +19153,13 @@ var ZoneCrossingSchema = object({
|
|
|
19154
19153
|
/** Zone display name at crossing time (falls back to the id). */
|
|
19155
19154
|
zoneName: string().optional()
|
|
19156
19155
|
});
|
|
19156
|
+
/** One zone a box was stamped with, and how much of the BOX fell inside it. */
|
|
19157
|
+
var ZoneOverlapSchema = object({
|
|
19158
|
+
zoneId: string(),
|
|
19159
|
+
zoneName: string().optional(),
|
|
19160
|
+
/** Percentage of the BOX area inside the zone, 0–100. */
|
|
19161
|
+
overlapPct: number()
|
|
19162
|
+
});
|
|
19157
19163
|
var ObjectEventSchema = object({
|
|
19158
19164
|
...BaseEventFields,
|
|
19159
19165
|
kind: literal("object"),
|
|
@@ -19178,6 +19184,35 @@ var ObjectEventSchema = object({
|
|
|
19178
19184
|
bbox: BoundingBoxSchema.optional(),
|
|
19179
19185
|
/** Heavy JSON — omitted in slim projection. */
|
|
19180
19186
|
zones: array(string()).readonly().optional(),
|
|
19187
|
+
/**
|
|
19188
|
+
* How far inside each stamped zone the box actually was, as a percentage of
|
|
19189
|
+
* the BOX area.
|
|
19190
|
+
*
|
|
19191
|
+
* Membership alone cannot express "at least a third of it inside", which is
|
|
19192
|
+
* the bar an operator argues with — and the number already existed: the
|
|
19193
|
+
* engine computed it, the pipeline logged it, and then discarded it. It
|
|
19194
|
+
* matters most on the events that carry no track, where a rule has nothing
|
|
19195
|
+
* else to judge by.
|
|
19196
|
+
*/
|
|
19197
|
+
zoneOverlaps: array(ZoneOverlapSchema).readonly().optional(),
|
|
19198
|
+
/**
|
|
19199
|
+
* Present when this event describes a detection the TRACKER refused, so it
|
|
19200
|
+
* has no track and never will.
|
|
19201
|
+
*
|
|
19202
|
+
* A zone-scoped immediate rule asks "is there an animal in the flowerbed
|
|
19203
|
+
* NOW?"; tracking answers a different question ("is this the same subject as
|
|
19204
|
+
* before?") whose confirmation threshold presumes continuity. On 2026-09-09 a
|
|
19205
|
+
* dog at 0.7729, 100% inside a watched zone, was refused three times in six
|
|
19206
|
+
* seconds with three different candidate ids — seven analysed frames in the
|
|
19207
|
+
* window, the subject in a handful of them, metres apart — and produced no
|
|
19208
|
+
* event at all.
|
|
19209
|
+
*
|
|
19210
|
+
* It is NAMED rather than merely implied by a missing `trackId`: an event
|
|
19211
|
+
* with no track and no reason is indistinguishable from a track whose media
|
|
19212
|
+
* went missing, and a consumer that asks this one for a best shot or a
|
|
19213
|
+
* history is asking for something that never existed.
|
|
19214
|
+
*/
|
|
19215
|
+
spawnRefused: string().optional(),
|
|
19181
19216
|
/** Omitted in slim projection. */
|
|
19182
19217
|
state: TrackStateSchema.optional(),
|
|
19183
19218
|
/**
|
|
@@ -20251,6 +20286,60 @@ var NativeCropResultSchema = object({
|
|
|
20251
20286
|
*/
|
|
20252
20287
|
tier: _enum(["native", "ram-fullframe"]).optional()
|
|
20253
20288
|
});
|
|
20289
|
+
/**
|
|
20290
|
+
* What a PARKED frame is for — the `kind` half of the `(deviceId, trackId,
|
|
20291
|
+
* kind)` key ([D422](../../../docs/decisions/adr-0422-a-relevant-frame-is-parked-when-it-becomes-relevant.md)).
|
|
20292
|
+
*
|
|
20293
|
+
* - `keyFrame` — the track's clean best FULL frame at native width (capped by
|
|
20294
|
+
* the caller's `maxWidth`). What `keyFrame` + `keyFrameSmall` are written
|
|
20295
|
+
* from, and what the detail plane's full-frame rung cuts from.
|
|
20296
|
+
* - `thumbnail` — the best-shot subject slab: the caller's 16:9 central-square
|
|
20297
|
+
* window, cut by the runner at uncapped native resolution.
|
|
20298
|
+
*
|
|
20299
|
+
* The runner never interprets `trackId`; it is an opaque key the hub owns.
|
|
20300
|
+
*/
|
|
20301
|
+
var ParkedFrameKindSchema = _enum(["keyFrame", "thumbnail"]);
|
|
20302
|
+
/**
|
|
20303
|
+
* Why a park did NOT happen. Every one is logged on the runner with
|
|
20304
|
+
* `tags: { deviceId }` and the handle's measured age, because a handle already
|
|
20305
|
+
* gone at park time IS the defect the 150–500 ms window exists to prevent —
|
|
20306
|
+
* never a reason to retry in a loop.
|
|
20307
|
+
*
|
|
20308
|
+
* - `handle-gone` — the native surface no longer resolves this handle (never
|
|
20309
|
+
* registered, past the lease bound, or the worker released it). `detail`
|
|
20310
|
+
* carries the runner's own miss reason.
|
|
20311
|
+
* - `encode-failed` — pixels resolved and the JPEG encode threw.
|
|
20312
|
+
*/
|
|
20313
|
+
var ParkRefusalSchema = _enum(["handle-gone", "encode-failed"]);
|
|
20314
|
+
/** Answer to `parkTrackFrame` — a discriminated union, so "not parked" always names why. */
|
|
20315
|
+
var ParkTrackFrameResultSchema = discriminatedUnion("parked", [object({
|
|
20316
|
+
parked: literal(true),
|
|
20317
|
+
/** The node holding the parcel — what a later retrieval must be pinned to. */
|
|
20318
|
+
nodeId: string(),
|
|
20319
|
+
width: number().int().positive(),
|
|
20320
|
+
height: number().int().positive(),
|
|
20321
|
+
/** JPEG bytes the parcel costs on the node. */
|
|
20322
|
+
bytes: number().int().nonnegative(),
|
|
20323
|
+
/** Whether this park replaced a parcel already held for the key. */
|
|
20324
|
+
replaced: boolean()
|
|
20325
|
+
}), object({
|
|
20326
|
+
parked: literal(false),
|
|
20327
|
+
nodeId: string(),
|
|
20328
|
+
reason: ParkRefusalSchema,
|
|
20329
|
+
/** Age of the handle at the park, on the runner's clock; null if unknown. */
|
|
20330
|
+
handleAgeMs: number().nullable(),
|
|
20331
|
+
detail: string().optional()
|
|
20332
|
+
})]);
|
|
20333
|
+
/** A retrieved parcel — the runner's own JPEG, base64 for the wire. */
|
|
20334
|
+
var ParkedTrackFrameSchema = object({
|
|
20335
|
+
jpeg: string(),
|
|
20336
|
+
width: number().int().positive(),
|
|
20337
|
+
height: number().int().positive(),
|
|
20338
|
+
/** The frame instant the parcel shows (the caller's clock, echoed back). */
|
|
20339
|
+
timestamp: number(),
|
|
20340
|
+
/** When the node stored it (the node's clock). */
|
|
20341
|
+
parkedAt: number()
|
|
20342
|
+
});
|
|
20254
20343
|
/** Parent detection context passed to `runDetailSubtree` — the crop's
|
|
20255
20344
|
* originating detection, in FRAME-space coordinates. Reuses
|
|
20256
20345
|
* `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
|
|
@@ -20640,7 +20729,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
20640
20729
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
20641
20730
|
* analyzer providers) running on decoded frames in this runner.
|
|
20642
20731
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
20643
|
-
* analytics
|
|
20732
|
+
* analytics). The provider emits ProviderMotion
|
|
20644
20733
|
* events; the orchestrator forwards to `reportMotion`.
|
|
20645
20734
|
*/
|
|
20646
20735
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
@@ -20882,7 +20971,26 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
20882
20971
|
className: string(),
|
|
20883
20972
|
/** Camera the pixels came from. Diagnostics + log tags ONLY — never routing. */
|
|
20884
20973
|
sourceDeviceId: number()
|
|
20885
|
-
}), RunStatelessStepResultSchema, { kind: "mutation" })
|
|
20974
|
+
}), RunStatelessStepResultSchema, { kind: "mutation" }), method(object({
|
|
20975
|
+
deviceId: number(),
|
|
20976
|
+
/** Opaque to the runner — the hub's track id. */
|
|
20977
|
+
trackId: string(),
|
|
20978
|
+
kind: ParkedFrameKindSchema,
|
|
20979
|
+
handle: FrameHandleSchema,
|
|
20980
|
+
/** Normalized [0,1] window to cut. `{0,0,1,1}` for a full frame. */
|
|
20981
|
+
bbox: NativeCropBboxSchema,
|
|
20982
|
+
/** Width cap for a full-frame park (the `keyFrame` native cap). */
|
|
20983
|
+
maxWidth: number().int().positive().optional(),
|
|
20984
|
+
/** The frame instant (caller's clock) — orders parks for one key. */
|
|
20985
|
+
timestamp: number()
|
|
20986
|
+
}), ParkTrackFrameResultSchema, { kind: "mutation" }), method(object({
|
|
20987
|
+
deviceId: number(),
|
|
20988
|
+
trackId: string(),
|
|
20989
|
+
kind: ParkedFrameKindSchema
|
|
20990
|
+
}), ParkedTrackFrameSchema.nullable()), method(object({
|
|
20991
|
+
deviceId: number(),
|
|
20992
|
+
trackId: string()
|
|
20993
|
+
}), object({ released: number().int().nonnegative() }), { kind: "mutation" });
|
|
20886
20994
|
var CameraPipelineConfigSchema = object({
|
|
20887
20995
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
20888
20996
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -23811,7 +23919,7 @@ DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _v
|
|
|
23811
23919
|
*
|
|
23812
23920
|
* Implementations:
|
|
23813
23921
|
* - Each camera-providing addon registers this cap natively per
|
|
23814
|
-
* device (Reolink, Hikvision, RTSP,
|
|
23922
|
+
* device (Reolink, Hikvision, RTSP, ONVIF self).
|
|
23815
23923
|
* - Returns a snapshot from the persisted device config blob — no
|
|
23816
23924
|
* extra round-trip to the camera, no probing.
|
|
23817
23925
|
* - The cap is admin-only (`auth: 'admin'`) — credentials must not
|
|
@@ -25197,7 +25305,7 @@ var AvailableIntegrationTypeSchema = object({
|
|
|
25197
25305
|
* Which integration-marker cap the addon declared, so the wizard can
|
|
25198
25306
|
* branch on CAP — never on addon name. `device-adoption` integrations
|
|
25199
25307
|
* (Home Assistant, …) route through the broker step (Approach A);
|
|
25200
|
-
* `device-provider` integrations (Reolink/
|
|
25308
|
+
* `device-provider` integrations (Reolink/ONVIF) keep the
|
|
25201
25309
|
* legacy config → discovery flow.
|
|
25202
25310
|
*/
|
|
25203
25311
|
kind: _enum(["device-adoption", "device-provider"]),
|
|
@@ -27754,13 +27862,31 @@ var RecordingManifestSchema = object({
|
|
|
27754
27862
|
*/
|
|
27755
27863
|
playbackEndpoints: array(string())
|
|
27756
27864
|
});
|
|
27757
|
-
/**
|
|
27758
|
-
*
|
|
27865
|
+
/**
|
|
27866
|
+
* Recording storage usage for one camera — what the ARCHIVE holds for it,
|
|
27867
|
+
* across every profile and every resolvable location on this node.
|
|
27868
|
+
*
|
|
27869
|
+
* ## Archive vs residency, which is the whole point of this shape (D418)
|
|
27870
|
+
*
|
|
27871
|
+
* `usedBytes` / `oldestMs` / `segments` are the durable hour ledger's numbers:
|
|
27872
|
+
* the same quantity `RecordingLocationUsage.usedBytes` reports for the volume
|
|
27873
|
+
* this camera writes to, so the two can be added up and compared.
|
|
27874
|
+
*
|
|
27875
|
+
* They were not always. Until D418 this row came from the recorder's in-RAM
|
|
27876
|
+
* `RecordingIndex`, which since D287 holds only the live tail plus the hours
|
|
27877
|
+
* somebody hydrated — so a hub with 1.9 TB and 3.3 days of footage reported
|
|
27878
|
+
* 60.5 GB and "oldest: three hours ago" on the same page as the volume row
|
|
27879
|
+
* that said otherwise, and two people read it as retention eating recent
|
|
27880
|
+
* footage. Residency is still reported, under `residentBytes` /
|
|
27881
|
+
* `residentOldestMs`, which answer a different question and say so.
|
|
27882
|
+
*/
|
|
27759
27883
|
var RecordingDeviceUsageSchema = object({
|
|
27760
27884
|
deviceId: number(),
|
|
27885
|
+
/** Bytes the ARCHIVE holds for this camera on this node's resolvable
|
|
27886
|
+
* recordings locations. */
|
|
27761
27887
|
usedBytes: number(),
|
|
27762
27888
|
/**
|
|
27763
|
-
* Start of this camera's OLDEST
|
|
27889
|
+
* Start of this camera's OLDEST ARCHIVED segment, across every profile and
|
|
27764
27890
|
* location — the "Oldest footage" column in Recordings → Storage, and the
|
|
27765
27891
|
* only honest answer to "is retention actually holding?" per camera.
|
|
27766
27892
|
*
|
|
@@ -27770,7 +27896,24 @@ var RecordingDeviceUsageSchema = object({
|
|
|
27770
27896
|
* (types) and the addon ship on different trains, and the addon is usually
|
|
27771
27897
|
* the later of the two.
|
|
27772
27898
|
*/
|
|
27773
|
-
oldestMs: number().nullable().optional()
|
|
27899
|
+
oldestMs: number().nullable().optional(),
|
|
27900
|
+
/** Segments the archive holds for this camera — the "M" beside `usedBytes`.
|
|
27901
|
+
* OPTIONAL for the same train-skew reason as `oldestMs`. */
|
|
27902
|
+
segments: number().optional(),
|
|
27903
|
+
/**
|
|
27904
|
+
* RESIDENCY, not the archive: bytes the recorder process currently holds in
|
|
27905
|
+
* its RAM index — the live tail plus the hours a reader hydrated.
|
|
27906
|
+
*
|
|
27907
|
+
* It answers "what can be served without touching the disk", never "how much
|
|
27908
|
+
* footage this camera has". A UI that renders it must label it as such, and
|
|
27909
|
+
* must never total it as storage. OPTIONAL: a recorder predating D418 omits
|
|
27910
|
+
* it, and so does a node whose ledger could not answer.
|
|
27911
|
+
*/
|
|
27912
|
+
residentBytes: number().optional(),
|
|
27913
|
+
/** The residency counterpart of `oldestMs` — the oldest segment currently in
|
|
27914
|
+
* RAM, which on a healthy recorder is minutes ago and means nothing about
|
|
27915
|
+
* retention. `null` = nothing resident. */
|
|
27916
|
+
residentOldestMs: number().nullable().optional()
|
|
27774
27917
|
});
|
|
27775
27918
|
/** Recording storage usage + capacity for one storage location. */
|
|
27776
27919
|
var RecordingLocationUsageSchema = object({
|
|
@@ -27808,6 +27951,17 @@ var RecordingStorageUsageSchema = object({
|
|
|
27808
27951
|
totalUsedBytes: number(),
|
|
27809
27952
|
devices: array(RecordingDeviceUsageSchema),
|
|
27810
27953
|
/**
|
|
27954
|
+
* WHERE `devices[]` came from, so an empty table is never mistaken for empty
|
|
27955
|
+
* disks (D418).
|
|
27956
|
+
*
|
|
27957
|
+
* `archive` = the durable hour ledger answered. `unavailable` = this node
|
|
27958
|
+
* declared no ledger and the recorder REFUSED rather than answering the
|
|
27959
|
+
* question with the resident index (D295 rule 3) — the rows are UNKNOWN, not
|
|
27960
|
+
* zero, and a UI must say so. OPTIONAL: a recorder predating D418 omits it,
|
|
27961
|
+
* and its rows are residency.
|
|
27962
|
+
*/
|
|
27963
|
+
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
27964
|
+
/**
|
|
27811
27965
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
27812
27966
|
* of the payload without it: the hub serves this method through a BAKED
|
|
27813
27967
|
* router, so a hub whose framework train predates a change to this array
|
|
@@ -34195,6 +34349,24 @@ Object.freeze({
|
|
|
34195
34349
|
addonId: null,
|
|
34196
34350
|
access: "view"
|
|
34197
34351
|
},
|
|
34352
|
+
"pipelineRunner.getParkedTrackFrame": {
|
|
34353
|
+
capName: "pipeline-runner",
|
|
34354
|
+
capScope: "system",
|
|
34355
|
+
addonId: null,
|
|
34356
|
+
access: "view"
|
|
34357
|
+
},
|
|
34358
|
+
"pipelineRunner.parkTrackFrame": {
|
|
34359
|
+
capName: "pipeline-runner",
|
|
34360
|
+
capScope: "system",
|
|
34361
|
+
addonId: null,
|
|
34362
|
+
access: "create"
|
|
34363
|
+
},
|
|
34364
|
+
"pipelineRunner.releaseParkedTrackFrames": {
|
|
34365
|
+
capName: "pipeline-runner",
|
|
34366
|
+
capScope: "system",
|
|
34367
|
+
addonId: null,
|
|
34368
|
+
access: "create"
|
|
34369
|
+
},
|
|
34198
34370
|
"pipelineRunner.reportMotion": {
|
|
34199
34371
|
capName: "pipeline-runner",
|
|
34200
34372
|
capScope: "system",
|
|
@@ -37472,6 +37644,21 @@ Object.freeze({
|
|
|
37472
37644
|
form: "single",
|
|
37473
37645
|
optional: false
|
|
37474
37646
|
}],
|
|
37647
|
+
"pipelineRunner.getParkedTrackFrame": [{
|
|
37648
|
+
name: "deviceId",
|
|
37649
|
+
form: "single",
|
|
37650
|
+
optional: false
|
|
37651
|
+
}],
|
|
37652
|
+
"pipelineRunner.parkTrackFrame": [{
|
|
37653
|
+
name: "deviceId",
|
|
37654
|
+
form: "single",
|
|
37655
|
+
optional: false
|
|
37656
|
+
}],
|
|
37657
|
+
"pipelineRunner.releaseParkedTrackFrames": [{
|
|
37658
|
+
name: "deviceId",
|
|
37659
|
+
form: "single",
|
|
37660
|
+
optional: false
|
|
37661
|
+
}],
|
|
37475
37662
|
"pipelineRunner.reportMotion": [{
|
|
37476
37663
|
name: "deviceId",
|
|
37477
37664
|
form: "single",
|
|
@@ -38163,7 +38350,7 @@ var PreviewTextField = string().max(200);
|
|
|
38163
38350
|
* Whether the notification's preview is a STILL or a short animation.
|
|
38164
38351
|
*
|
|
38165
38352
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
38166
|
-
* rule)"* —
|
|
38353
|
+
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
38167
38354
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
38168
38355
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
38169
38356
|
* simply applies it to a dozen frames sampled across the render and assembles
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-mqtt-broker",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.92",
|
|
4
4
|
"description": "MQTT broker registry addon for CamStack — manages external broker entries + an optional embedded aedes broker. Consumers spin up their own `mqtt.js` clients via the `mqtt-broker` cap.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|