@camstack/addon-import-alexa 0.2.118 → 0.2.120
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 +999 -552
- package/dist/addon.mjs +999 -552
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -38,7 +38,7 @@ let node_os = require("node:os");
|
|
|
38
38
|
let node_fs = require("node:fs");
|
|
39
39
|
let node_path = require("node:path");
|
|
40
40
|
node_path = __toESM(node_path);
|
|
41
|
-
//#region ../types/dist/event-category-
|
|
41
|
+
//#region ../types/dist/event-category-B_0XEcLF.mjs
|
|
42
42
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
43
43
|
EventCategory["SystemBoot"] = "system.boot";
|
|
44
44
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -539,15 +539,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
539
539
|
EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
|
|
540
540
|
EventCategory["AgentBackupActivated"] = "agent.backup.activated";
|
|
541
541
|
EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
|
|
542
|
-
/**
|
|
543
|
-
* Per-agent hwaccel preference changed (user override set, cleared, or
|
|
544
|
-
* re-probed). Observability event — decoders pull the current pref at
|
|
545
|
-
* `createSession`, so running sessions keep their current backend until
|
|
546
|
-
* they rotate naturally (camera add/remove, stream restart). Future
|
|
547
|
-
* work can wire a listener in stream-broker that force-rotates live
|
|
548
|
-
* sessions; for now this event powers logs + admin-UI toast feedback.
|
|
549
|
-
*/
|
|
550
|
-
EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
|
|
551
542
|
EventCategory["MotionAnalysis"] = "detection.motion-analysis";
|
|
552
543
|
/** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
|
|
553
544
|
EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
|
|
@@ -5418,7 +5409,7 @@ var ZodIssueCode = {
|
|
|
5418
5409
|
var ZodFirstPartyTypeKind;
|
|
5419
5410
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5420
5411
|
//#endregion
|
|
5421
|
-
//#region ../types/dist/sleep-
|
|
5412
|
+
//#region ../types/dist/sleep-BNeXenvr.mjs
|
|
5422
5413
|
/**
|
|
5423
5414
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5424
5415
|
* window to float samples (D455).
|
|
@@ -6784,32 +6775,12 @@ object({
|
|
|
6784
6775
|
audioCodec: string().optional(),
|
|
6785
6776
|
metadata: record(string(), unknown()).readonly().optional()
|
|
6786
6777
|
});
|
|
6787
|
-
var EncodedPacketSchema = object({
|
|
6788
|
-
type: _enum(["video", "audio"]),
|
|
6789
|
-
data: _instanceof(Uint8Array),
|
|
6790
|
-
pts: number(),
|
|
6791
|
-
dts: number(),
|
|
6792
|
-
keyframe: boolean(),
|
|
6793
|
-
codec: string()
|
|
6794
|
-
});
|
|
6795
|
-
var DecodedFrameSchema = object({
|
|
6796
|
-
data: _instanceof(Uint8Array),
|
|
6797
|
-
width: number(),
|
|
6798
|
-
height: number(),
|
|
6799
|
-
format: _enum([
|
|
6800
|
-
"jpeg",
|
|
6801
|
-
"rgb",
|
|
6802
|
-
"bgr",
|
|
6803
|
-
"yuv420",
|
|
6804
|
-
"gray"
|
|
6805
|
-
]),
|
|
6806
|
-
timestamp: number()
|
|
6807
|
-
});
|
|
6808
6778
|
/**
|
|
6809
6779
|
* Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
|
|
6810
6780
|
* frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
|
|
6811
|
-
* interface in `interfaces/frame-handle.ts` field-for-field so a
|
|
6812
|
-
*
|
|
6781
|
+
* interface in `interfaces/frame-handle.ts` field-for-field so a cap method
|
|
6782
|
+
* (the runner's native-crop and pipeline-executor inputs) can carry handles
|
|
6783
|
+
* over tRPC / Moleculer.
|
|
6813
6784
|
*
|
|
6814
6785
|
* The `satisfies` assertion below pins this schema to the interface: if a
|
|
6815
6786
|
* field is added to / removed from `FrameHandle` without a matching schema
|
|
@@ -6835,50 +6806,6 @@ var FrameHandleSchema = object({
|
|
|
6835
6806
|
slotCount: number().int().positive()
|
|
6836
6807
|
});
|
|
6837
6808
|
/**
|
|
6838
|
-
* Pixel format a frame-handle subscriber can request from the broker
|
|
6839
|
-
* (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
|
|
6840
|
-
* `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
|
|
6841
|
-
* `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
|
|
6842
|
-
* payload, and no decoded-frame consumer requests it over the shm plane.
|
|
6843
|
-
*/
|
|
6844
|
-
var FrameHandleFormatSchema = _enum([
|
|
6845
|
-
"rgb",
|
|
6846
|
-
"bgr",
|
|
6847
|
-
"yuv420",
|
|
6848
|
-
"gray"
|
|
6849
|
-
]);
|
|
6850
|
-
/**
|
|
6851
|
-
* Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
|
|
6852
|
-
* broker for a `FrameHandle` stream of one `format`; the broker maintains one
|
|
6853
|
-
* shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
|
|
6854
|
-
* subscriber (motion) and an `rgb` subscriber (detection) each read the format
|
|
6855
|
-
* they asked for with no broker-side conversion.
|
|
6856
|
-
*/
|
|
6857
|
-
var SubscribeFramesInputSchema = object({
|
|
6858
|
-
brokerId: string(),
|
|
6859
|
-
format: FrameHandleFormatSchema,
|
|
6860
|
-
/**
|
|
6861
|
-
* Optional reader-side cadence hint in frames per second. The broker does
|
|
6862
|
-
* NOT throttle — latest-wins ring reads drop frames implicitly for a slow
|
|
6863
|
-
* consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
|
|
6864
|
-
* the consumer can pace its own `pullFrameHandles` polling.
|
|
6865
|
-
*/
|
|
6866
|
-
maxFps: number().positive().optional(),
|
|
6867
|
-
/** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
|
|
6868
|
-
tag: string().optional()
|
|
6869
|
-
});
|
|
6870
|
-
/**
|
|
6871
|
-
* Result of `stream-broker.subscribeFrames`. The consumer then polls
|
|
6872
|
-
* `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
|
|
6873
|
-
* `FrameHandle` to a `FrameRingReader`.
|
|
6874
|
-
*/
|
|
6875
|
-
var SubscribeFramesResultSchema = object({
|
|
6876
|
-
/** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
|
|
6877
|
-
subscriptionId: string(),
|
|
6878
|
-
/** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
|
|
6879
|
-
maxFps: number().nonnegative()
|
|
6880
|
-
});
|
|
6881
|
-
/**
|
|
6882
6809
|
* Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
|
|
6883
6810
|
* `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
|
|
6884
6811
|
* sample bytes plus the track parameters a consumer needs to interpret them.
|
|
@@ -6886,8 +6813,8 @@ var SubscribeFramesResultSchema = object({
|
|
|
6886
6813
|
* Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
|
|
6887
6814
|
* Float32 PCM), so unlike video frames they ship their bytes INLINE over
|
|
6888
6815
|
* tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
|
|
6889
|
-
* (the wire-serialisable supertype of `Buffer`)
|
|
6890
|
-
*
|
|
6816
|
+
* (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
|
|
6817
|
+
* it.
|
|
6891
6818
|
*/
|
|
6892
6819
|
var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
|
|
6893
6820
|
var DecodedAudioChunkSchema = object({
|
|
@@ -6905,11 +6832,10 @@ var DecodedAudioChunkSchema = object({
|
|
|
6905
6832
|
format: AudioChunkFormatSchema.optional()
|
|
6906
6833
|
});
|
|
6907
6834
|
/**
|
|
6908
|
-
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9).
|
|
6909
|
-
*
|
|
6910
|
-
*
|
|
6911
|
-
*
|
|
6912
|
-
* `pullAudioChunks`.
|
|
6835
|
+
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
|
|
6836
|
+
* its bytes inline: a consumer asks the broker for the decoded audio-chunk
|
|
6837
|
+
* stream of one broker; the broker keeps a per-subscription bounded FIFO queue
|
|
6838
|
+
* the consumer drains via `pullAudioChunks`.
|
|
6913
6839
|
*/
|
|
6914
6840
|
var SubscribeAudioChunksInputSchema = object({
|
|
6915
6841
|
brokerId: string(),
|
|
@@ -6940,9 +6866,7 @@ var BrokerStatsSchema = object({
|
|
|
6940
6866
|
"stopped"
|
|
6941
6867
|
]),
|
|
6942
6868
|
inputFps: number(),
|
|
6943
|
-
decodeFps: number(),
|
|
6944
6869
|
encodedSubscribers: number(),
|
|
6945
|
-
decodedSubscribers: number(),
|
|
6946
6870
|
uptimeMs: number(),
|
|
6947
6871
|
bitrateKbps: number(),
|
|
6948
6872
|
idrIntervalMs: number(),
|
|
@@ -6955,14 +6879,6 @@ var BrokerStatsSchema = object({
|
|
|
6955
6879
|
preBufferMs: number(),
|
|
6956
6880
|
preBufferPackets: number(),
|
|
6957
6881
|
/**
|
|
6958
|
-
* Moleculer node id of the decoder provider currently servicing this
|
|
6959
|
-
* stream's decoded subscribers. `null` until the deferred decoder is
|
|
6960
|
-
* created (no decoded clients yet, or codec not detected). Surfaces the
|
|
6961
|
-
* runtime decoder placement so the UI can show "Decoder: <agent>" without
|
|
6962
|
-
* a separate cap call per broker.
|
|
6963
|
-
*/
|
|
6964
|
-
decoderNodeId: string().nullable(),
|
|
6965
|
-
/**
|
|
6966
6882
|
* Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
|
|
6967
6883
|
* when the stream has no audio track or the broker is in cold start.
|
|
6968
6884
|
* `supported = false` means the codec was detected but the local
|
|
@@ -10415,70 +10331,6 @@ var StorageLocationDeclarationSchema = object({
|
|
|
10415
10331
|
"backup"
|
|
10416
10332
|
]).optional()
|
|
10417
10333
|
});
|
|
10418
|
-
var DecoderStatsSchema = object({
|
|
10419
|
-
inputFps: number(),
|
|
10420
|
-
outputFps: number(),
|
|
10421
|
-
avgDecodeTimeMs: number(),
|
|
10422
|
-
droppedFrames: number(),
|
|
10423
|
-
/**
|
|
10424
|
-
* Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
|
|
10425
|
-
* lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
|
|
10426
|
-
* the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
|
|
10427
|
-
* is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
|
|
10428
|
-
*/
|
|
10429
|
-
lagMs: number().optional(),
|
|
10430
|
-
effectiveFps: number().optional(),
|
|
10431
|
-
adaptiveFps: number().optional()
|
|
10432
|
-
});
|
|
10433
|
-
var DecoderSessionConfigSchema = object({
|
|
10434
|
-
codec: string(),
|
|
10435
|
-
maxFps: number().default(0),
|
|
10436
|
-
outputFormat: _enum([
|
|
10437
|
-
"jpeg",
|
|
10438
|
-
"rgb",
|
|
10439
|
-
"bgr",
|
|
10440
|
-
"yuv420",
|
|
10441
|
-
"gray"
|
|
10442
|
-
]).default("jpeg"),
|
|
10443
|
-
scale: number().default(1),
|
|
10444
|
-
width: number().optional(),
|
|
10445
|
-
height: number().optional(),
|
|
10446
|
-
/**
|
|
10447
|
-
* Identifier of the camera this decoder session serves. Optional
|
|
10448
|
-
* because the cap is generic (any caller could request decode), but
|
|
10449
|
-
* stream-broker passes it so decoder logs include `deviceId` for
|
|
10450
|
-
* per-camera filtering when diagnosing failures (e.g. node-av
|
|
10451
|
-
* sendPacket errors on a single hung camera).
|
|
10452
|
-
*/
|
|
10453
|
-
deviceId: number().int().nonnegative().optional(),
|
|
10454
|
-
/**
|
|
10455
|
-
* Free-form tag for log scoping. Stream-broker uses
|
|
10456
|
-
* `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
|
|
10457
|
-
* on every line so `grep tag=broker:5/high` filters one camera
|
|
10458
|
-
* profile cleanly.
|
|
10459
|
-
*/
|
|
10460
|
-
tag: string().optional(),
|
|
10461
|
-
/**
|
|
10462
|
-
* Where the session delivers decoded frames (Phase 5 / D9):
|
|
10463
|
-
*
|
|
10464
|
-
* - `'callback'` (default) — the legacy pixel path: decoded frames are
|
|
10465
|
-
* buffered as `DecodedFrame`s and drained via `pullFrames`.
|
|
10466
|
-
* - `'shm'` — the shared-memory frame plane: decoded frames are written
|
|
10467
|
-
* into an OS shared-memory ring and drained as zero-pixel
|
|
10468
|
-
* `FrameHandle`s via `pullHandles`. A session is one mode or the
|
|
10469
|
-
* other — `pullFrames` returns nothing for an `'shm'` session and
|
|
10470
|
-
* `pullHandles` returns nothing for a `'callback'` session.
|
|
10471
|
-
*/
|
|
10472
|
-
frameSink: _enum(["callback", "shm"]).default("callback"),
|
|
10473
|
-
/**
|
|
10474
|
-
* Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
|
|
10475
|
-
* a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
|
|
10476
|
-
* real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
|
|
10477
|
-
* stream-broker's `streamingDebug` gate — off by default so production logs
|
|
10478
|
-
* stay quiet and the emit path pays zero per-frame cost when disabled.
|
|
10479
|
-
*/
|
|
10480
|
-
debug: boolean().optional()
|
|
10481
|
-
});
|
|
10482
10334
|
/**
|
|
10483
10335
|
* Per-component log CHANNELS — the gate a hot path consults, and the registry
|
|
10484
10336
|
* an addon declares its channels in.
|
|
@@ -10621,6 +10473,26 @@ var ClipSearchStrictnessSchema = _enum([
|
|
|
10621
10473
|
"balanced",
|
|
10622
10474
|
"strict"
|
|
10623
10475
|
]);
|
|
10476
|
+
/** Steps whose effect a root label can BE. */
|
|
10477
|
+
var LABEL_SUPPLY_STEP_IDS = [
|
|
10478
|
+
"animal-classifier",
|
|
10479
|
+
"vehicle-classifier",
|
|
10480
|
+
"package-detection"
|
|
10481
|
+
];
|
|
10482
|
+
/** Steps whose box a root detection can BE. */
|
|
10483
|
+
var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
|
|
10484
|
+
/**
|
|
10485
|
+
* Steps whose per-detection MASK a root detection can carry (D737). The live
|
|
10486
|
+
* mask step is `segmentation` — a frame-plane refiner that runs its own model
|
|
10487
|
+
* once per detection crop. (`instance-segmentation` is a dormant step id that
|
|
10488
|
+
* no camera tree carries.)
|
|
10489
|
+
*/
|
|
10490
|
+
var MASK_SUPPLY_STEP_IDS = ["segmentation"];
|
|
10491
|
+
[
|
|
10492
|
+
...LABEL_SUPPLY_STEP_IDS,
|
|
10493
|
+
...CROP_SUPPLY_STEP_IDS,
|
|
10494
|
+
...MASK_SUPPLY_STEP_IDS
|
|
10495
|
+
];
|
|
10624
10496
|
var MODEL_FORMATS = [
|
|
10625
10497
|
"onnx",
|
|
10626
10498
|
"coreml",
|
|
@@ -10649,7 +10521,53 @@ var ModelFormatEntrySchema = object({
|
|
|
10649
10521
|
/** Multi-file payload (directory members or sibling files). */
|
|
10650
10522
|
files: array(string()).readonly().optional(),
|
|
10651
10523
|
/** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
|
|
10652
|
-
runtimes: array(_enum(["python"])).readonly().optional()
|
|
10524
|
+
runtimes: array(_enum(["python"])).readonly().optional(),
|
|
10525
|
+
/**
|
|
10526
|
+
* Content revision of the artefact, for one hosted OFF the CamStack mirror.
|
|
10527
|
+
* A format on the mirror leaves it unset: its revision (the sha256 of its
|
|
10528
|
+
* weight file) comes from the downloader's generated table, kept in step
|
|
10529
|
+
* with the mirror by `scripts/check-hosted-model-revisions.ts` (D744). A
|
|
10530
|
+
* node records the revision it downloaded next to the file
|
|
10531
|
+
* (`<file>.revision`); a copy with no record or a different one is stale
|
|
10532
|
+
* unless its weight file hashes to the revision, and a stale copy is
|
|
10533
|
+
* downloaded again, the old one serving until the new one is complete. No
|
|
10534
|
+
* revision at all ⇒ a file on disk is current, whatever it holds (D743).
|
|
10535
|
+
*/
|
|
10536
|
+
revision: string().min(1).optional()
|
|
10537
|
+
});
|
|
10538
|
+
/**
|
|
10539
|
+
* What a node holds for one (model, format) (D746). `current` is a complete
|
|
10540
|
+
* copy at its catalog revision — exactly what `downloaded: true` means.
|
|
10541
|
+
* `stale` is bytes on disk that are not (yet) proven current under D743/D744:
|
|
10542
|
+
* no or a different revision record, or a missing sibling. `missing` is no
|
|
10543
|
+
* copy. `downloaded` alone folds `stale` into "not downloaded", which hid
|
|
10544
|
+
* reclaimable bytes and a copy about to be replaced.
|
|
10545
|
+
*/
|
|
10546
|
+
var ModelOnDiskStateSchema = _enum([
|
|
10547
|
+
"current",
|
|
10548
|
+
"stale",
|
|
10549
|
+
"missing"
|
|
10550
|
+
]);
|
|
10551
|
+
/**
|
|
10552
|
+
* The numeric precision of one format's BUILD (D746) — reported only when the
|
|
10553
|
+
* build states it (file-name token, an INT8 variant, an EdgeTPU compile, a
|
|
10554
|
+
* CamStack Core ML export). Absent means "not stated", never "fp32".
|
|
10555
|
+
*/
|
|
10556
|
+
var ModelFormatPrecisionSchema = _enum([
|
|
10557
|
+
"fp32",
|
|
10558
|
+
"fp16",
|
|
10559
|
+
"int8"
|
|
10560
|
+
]);
|
|
10561
|
+
/**
|
|
10562
|
+
* One format of one model as a node's `pipelineExecutor.getSchema` reports it.
|
|
10563
|
+
* `onDisk` / `precision` are optional for version skew: a runner that predates
|
|
10564
|
+
* them omits them, and a reader falls back to `downloaded`.
|
|
10565
|
+
*/
|
|
10566
|
+
var PipelineModelFormatStatusSchema = object({
|
|
10567
|
+
downloaded: boolean(),
|
|
10568
|
+
sizeMB: number(),
|
|
10569
|
+
onDisk: ModelOnDiskStateSchema.optional(),
|
|
10570
|
+
precision: ModelFormatPrecisionSchema.optional()
|
|
10653
10571
|
});
|
|
10654
10572
|
/**
|
|
10655
10573
|
* Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
|
|
@@ -10690,11 +10608,11 @@ var ModelVariantGroupSchema = object({
|
|
|
10690
10608
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
10691
10609
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
10692
10610
|
/**
|
|
10693
|
-
*
|
|
10694
|
-
*
|
|
10695
|
-
*
|
|
10611
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
10612
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
10613
|
+
* label is "Test".
|
|
10696
10614
|
*/
|
|
10697
|
-
optimization: _enum(["standard", "
|
|
10615
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
10698
10616
|
/**
|
|
10699
10617
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
10700
10618
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -10717,9 +10635,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
10717
10635
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
10718
10636
|
* string still parses — the string is lifted into `{ weights }`.
|
|
10719
10637
|
*
|
|
10720
|
-
* Every licence surface (the
|
|
10721
|
-
*
|
|
10722
|
-
*
|
|
10638
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
10639
|
+
* model table) is GENERATED from these records by
|
|
10640
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
10641
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
10723
10642
|
*/
|
|
10724
10643
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
10725
10644
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -10752,6 +10671,46 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
|
|
|
10752
10671
|
/** True when the weights or their data forbid commercial use. */
|
|
10753
10672
|
nonCommercial: boolean().optional()
|
|
10754
10673
|
}));
|
|
10674
|
+
/**
|
|
10675
|
+
* One step a ROOT detector can supply from its own output (D730) — see
|
|
10676
|
+
* `ModelCatalogEntry.suppliesSteps`.
|
|
10677
|
+
*
|
|
10678
|
+
* - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
|
|
10679
|
+
* the root's label to the step's vocabulary; `uncovered` is the vocabulary
|
|
10680
|
+
* the root cannot produce (shown as unavailable, never a blocker).
|
|
10681
|
+
* - `crop`: the root draws the box the step would have found (`license_plate`
|
|
10682
|
+
* for plate-detection, `face` for face-detection). The box becomes a detail
|
|
10683
|
+
* child of the `parentMacro` detection that contains it — never a track.
|
|
10684
|
+
* - `mask`: the root's decode emits an instance mask with every detection (a
|
|
10685
|
+
* YOLO26-seg root, D737) — the `segmentation` step's result, carried on the
|
|
10686
|
+
* detection in the shape that step produces. Derived from the model's
|
|
10687
|
+
* postprocessor on read, never stored by an import.
|
|
10688
|
+
*/
|
|
10689
|
+
var RootStepSupplySchema = discriminatedUnion("kind", [
|
|
10690
|
+
object({
|
|
10691
|
+
kind: literal("label"),
|
|
10692
|
+
stepId: _enum(LABEL_SUPPLY_STEP_IDS),
|
|
10693
|
+
labelToEffect: record(string(), string()),
|
|
10694
|
+
uncovered: array(string()).readonly()
|
|
10695
|
+
}),
|
|
10696
|
+
object({
|
|
10697
|
+
kind: literal("crop"),
|
|
10698
|
+
stepId: _enum(CROP_SUPPLY_STEP_IDS),
|
|
10699
|
+
rootLabels: array(string()).readonly(),
|
|
10700
|
+
parentMacro: _enum(["vehicle", "person"]),
|
|
10701
|
+
childClass: _enum(["plate", "face"]),
|
|
10702
|
+
/**
|
|
10703
|
+
* The root's smaller input side, stamped on read by `rootSuppliesOf` from
|
|
10704
|
+
* the model entry — what a step's `minRootInputPx` gate judges. Never
|
|
10705
|
+
* stored by an import.
|
|
10706
|
+
*/
|
|
10707
|
+
rootInputPx: number().int().positive().optional()
|
|
10708
|
+
}),
|
|
10709
|
+
object({
|
|
10710
|
+
kind: literal("mask"),
|
|
10711
|
+
stepId: _enum(MASK_SUPPLY_STEP_IDS)
|
|
10712
|
+
})
|
|
10713
|
+
]);
|
|
10755
10714
|
var ModelCatalogEntrySchema = object({
|
|
10756
10715
|
id: string(),
|
|
10757
10716
|
name: string(),
|
|
@@ -10817,6 +10776,35 @@ var ModelCatalogEntrySchema = object({
|
|
|
10817
10776
|
*/
|
|
10818
10777
|
defaultConfidence: number().min(0).max(1).optional(),
|
|
10819
10778
|
/**
|
|
10779
|
+
* Per-MODEL default of the per-class confidence floors (`minConfidence<Macro>`
|
|
10780
|
+
* on a detector step), keyed by macro class: `{ person: 0.45 }`. A class
|
|
10781
|
+
* absent here runs at the step slider's global default. The same row shape
|
|
10782
|
+
* the floor measurement produces (`model-floors.json`: modelId → floors), so
|
|
10783
|
+
* a measured table is copied in as-is. An operator override is bound to the
|
|
10784
|
+
* model it was made for and does not survive a model change (D738). A custom
|
|
10785
|
+
* / imported model may declare it; without it, the global defaults apply.
|
|
10786
|
+
*/
|
|
10787
|
+
defaultClassFloors: record(string(), number().min(0).max(1)).optional(),
|
|
10788
|
+
/**
|
|
10789
|
+
* The inference precision this model's OpenVINO IR needs on an Intel GPU.
|
|
10790
|
+
* Absent ⇒ the device default (f16 on a GPU). Set to `'f32'` for an FP32 IR
|
|
10791
|
+
* that produces invalid output at f16 — measured 2026-10-07 for YOLO26
|
|
10792
|
+
* base IRs (`yolo26s`: 0 true / 146 false positives; `yolo26m*`: NaN
|
|
10793
|
+
* scores) on the Core Ultra iGPU and the N100. Threaded to the pool as
|
|
10794
|
+
* `PoolModelConfig.gpuInferencePrecision`; the pool sets
|
|
10795
|
+
* INFERENCE_PRECISION_HINT on a GPU only. Costs ~60% latency on the GPU.
|
|
10796
|
+
*/
|
|
10797
|
+
gpuInferencePrecision: _enum(["f32", "f16"]).optional(),
|
|
10798
|
+
/**
|
|
10799
|
+
* ROOT detectors only: per supplied step (`animal-classifier`, …), the
|
|
10800
|
+
* minimum DETECTION score from which this root's own fine label (species,
|
|
10801
|
+
* vehicle type — D736 root supply) is taken (D741). Below it the detection
|
|
10802
|
+
* keeps its macro class without the fine label. `1` = never take it from
|
|
10803
|
+
* this root. Absent ⇒ no floor beyond the macro floor. The supplied step's
|
|
10804
|
+
* `minConfidence` slider, bound to the ROOT model, overrides it.
|
|
10805
|
+
*/
|
|
10806
|
+
suppliedLabelFloors: record(string(), number().min(0).max(1)).optional(),
|
|
10807
|
+
/**
|
|
10820
10808
|
* When true, the executor produces a landmark-aligned crop (similarity warp
|
|
10821
10809
|
* onto the canonical template) before this step runs, instead of a plain
|
|
10822
10810
|
* axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
|
|
@@ -10878,6 +10866,16 @@ var ModelCatalogEntrySchema = object({
|
|
|
10878
10866
|
*/
|
|
10879
10867
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
10880
10868
|
/**
|
|
10869
|
+
* The pipeline steps this ROOT detector can supply from its own output
|
|
10870
|
+
* (D730): its labels name a step's effect (`deer` for `animal-classifier`)
|
|
10871
|
+
* or draw a step's box (`license_plate` for `plate-detection`). Computed at
|
|
10872
|
+
* import from THIS model's labelmap by `deriveRootSupplies`, never written
|
|
10873
|
+
* by hand and never assumed per family; a row without it is derived on read
|
|
10874
|
+
* (`rootSuppliesOf`). Whether a camera uses it is the step's own
|
|
10875
|
+
* `useRootModel` flag (`resolveRootSupply`).
|
|
10876
|
+
*/
|
|
10877
|
+
suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
|
|
10878
|
+
/**
|
|
10881
10879
|
* The model's CLIP feature-space contract (text encoder, dimension, vector
|
|
10882
10880
|
* index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
|
|
10883
10881
|
* CLIP image encoder; its absence is what "not a CLIP model" means to the
|
|
@@ -12547,13 +12545,6 @@ var BrokerRtspClientSchema = object({
|
|
|
12547
12545
|
lastRtpAt: number(),
|
|
12548
12546
|
bytesSent: number()
|
|
12549
12547
|
});
|
|
12550
|
-
var BrokerDecodedClientSchema = object({
|
|
12551
|
-
tag: string(),
|
|
12552
|
-
subscribedAt: number(),
|
|
12553
|
-
maxFps: number(),
|
|
12554
|
-
framesDelivered: number(),
|
|
12555
|
-
framesDropped: number()
|
|
12556
|
-
});
|
|
12557
12548
|
var BrokerAudioClientSchema = object({
|
|
12558
12549
|
tag: string(),
|
|
12559
12550
|
subscribedAt: number(),
|
|
@@ -12645,7 +12636,6 @@ var BrokerEncodedClientSchema = object({
|
|
|
12645
12636
|
});
|
|
12646
12637
|
var BrokerClientsSchema = object({
|
|
12647
12638
|
rtsp: array(BrokerRtspClientSchema).readonly(),
|
|
12648
|
-
decoded: array(BrokerDecodedClientSchema).readonly(),
|
|
12649
12639
|
audio: array(BrokerAudioClientSchema).readonly(),
|
|
12650
12640
|
encoded: array(BrokerEncodedClientSchema).readonly(),
|
|
12651
12641
|
pipeClients: number(),
|
|
@@ -13014,11 +13004,7 @@ method(object({
|
|
|
13014
13004
|
auth: "admin"
|
|
13015
13005
|
}), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
|
|
13016
13006
|
brokerId: string(),
|
|
13017
|
-
channel: _enum([
|
|
13018
|
-
"rtsp",
|
|
13019
|
-
"decoded",
|
|
13020
|
-
"audio"
|
|
13021
|
-
]),
|
|
13007
|
+
channel: _enum(["rtsp", "audio"]),
|
|
13022
13008
|
handle: string()
|
|
13023
13009
|
}), object({ killed: boolean() }), {
|
|
13024
13010
|
kind: "mutation",
|
|
@@ -13053,10 +13039,7 @@ method(object({
|
|
|
13053
13039
|
}), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
|
|
13054
13040
|
subscriptionId: string(),
|
|
13055
13041
|
maxCount: number().int().positive().default(8)
|
|
13056
|
-
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(
|
|
13057
|
-
subscriptionId: string(),
|
|
13058
|
-
maxCount: number().int().positive().default(4)
|
|
13059
|
-
}), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
13042
|
+
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
13060
13043
|
brokerId: string(),
|
|
13061
13044
|
seconds: number().min(0).max(30)
|
|
13062
13045
|
}), _void(), {
|
|
@@ -14315,54 +14298,12 @@ id: union([string(), number()]) }), {
|
|
|
14315
14298
|
kind: "mutation",
|
|
14316
14299
|
auth: "admin"
|
|
14317
14300
|
});
|
|
14318
|
-
|
|
14319
|
-
* shm ring usage stats for a `frameSink: 'shm'` decoder session —
|
|
14320
|
-
* exposed via `decoder.getShmStats` so downstream consumers can
|
|
14321
|
-
* observe ring pressure (slot count, byte budget, hit/miss ratio).
|
|
14322
|
-
*/
|
|
14323
|
-
var ShmRingStatsSchema = object({
|
|
14324
|
-
sessionId: string(),
|
|
14325
|
-
slotCount: number().int(),
|
|
14326
|
-
slotByteLength: number().int(),
|
|
14327
|
-
segmentBytes: number().int(),
|
|
14328
|
-
budgetMb: number().int(),
|
|
14329
|
-
framesWritten: number().int(),
|
|
14330
|
-
getFrameHits: number().int(),
|
|
14331
|
-
getFrameMisses: number().int()
|
|
14332
|
-
});
|
|
14333
|
-
method(object({ codec: string() }), boolean()), method(_void(), object({
|
|
14301
|
+
method(_void(), object({
|
|
14334
14302
|
id: string(),
|
|
14335
14303
|
name: string(),
|
|
14336
|
-
isPullMode: boolean().optional(),
|
|
14337
|
-
priority: number().optional(),
|
|
14338
14304
|
hwaccel: string().optional(),
|
|
14339
14305
|
probedBestHwaccel: string().optional()
|
|
14340
|
-
})), method(
|
|
14341
|
-
sessionId: string(),
|
|
14342
|
-
nodeId: string()
|
|
14343
|
-
})), method(object({ sessionId: string() }), _void()), method(object({
|
|
14344
|
-
sessionId: string(),
|
|
14345
|
-
packet: EncodedPacketSchema
|
|
14346
|
-
}), _void()), method(object({
|
|
14347
|
-
sessionId: string(),
|
|
14348
|
-
url: string()
|
|
14349
|
-
}), _void()), method(object({
|
|
14350
|
-
sessionId: string(),
|
|
14351
|
-
maxCount: number().default(1),
|
|
14352
|
-
waitMs: number().optional()
|
|
14353
|
-
}), array(DecodedFrameSchema)), method(object({
|
|
14354
|
-
sessionId: string(),
|
|
14355
|
-
maxCount: number().default(1),
|
|
14356
|
-
waitMs: number().optional()
|
|
14357
|
-
}), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
|
|
14358
|
-
sessionId: string(),
|
|
14359
|
-
config: DecoderSessionConfigSchema.partial()
|
|
14360
|
-
}), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
|
|
14361
|
-
sessionId: string(),
|
|
14362
|
-
codec: string(),
|
|
14363
|
-
outputFormat: string(),
|
|
14364
|
-
createdAtMs: number()
|
|
14365
|
-
})).readonly()), method(_void(), object({ backend: string() }), {
|
|
14306
|
+
})), method(_void(), object({ backend: string() }), {
|
|
14366
14307
|
kind: "mutation",
|
|
14367
14308
|
auth: "admin"
|
|
14368
14309
|
});
|
|
@@ -14418,7 +14359,7 @@ DeviceType.Camera;
|
|
|
14418
14359
|
* This matters here more than anywhere else in the repo, because every provider
|
|
14419
14360
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
14420
14361
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
14421
|
-
* and `http://admin:hunter2@192.168.
|
|
14362
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
14422
14363
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
14423
14364
|
* filling it is the operator's business, not ours.
|
|
14424
14365
|
*
|
|
@@ -16411,6 +16352,12 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
|
|
|
16411
16352
|
kind: "mutation",
|
|
16412
16353
|
auth: "admin"
|
|
16413
16354
|
});
|
|
16355
|
+
var HUB_ADDRESS_ROLES = [
|
|
16356
|
+
"appConnections",
|
|
16357
|
+
"notificationTaps",
|
|
16358
|
+
"internal",
|
|
16359
|
+
"publicEndpoint"
|
|
16360
|
+
];
|
|
16414
16361
|
/**
|
|
16415
16362
|
* Transport bounds for AI capability methods.
|
|
16416
16363
|
*
|
|
@@ -17607,7 +17554,7 @@ method(object({
|
|
|
17607
17554
|
timeoutMs: 6e5
|
|
17608
17555
|
});
|
|
17609
17556
|
method(object({
|
|
17610
|
-
|
|
17557
|
+
targetNodeId: string(),
|
|
17611
17558
|
modelId: string(),
|
|
17612
17559
|
format: _enum(MODEL_FORMATS),
|
|
17613
17560
|
entry: ModelCatalogEntrySchema
|
|
@@ -19013,6 +18960,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
19013
18960
|
"stream-offline",
|
|
19014
18961
|
"node-online",
|
|
19015
18962
|
"node-offline",
|
|
18963
|
+
"node-restarting",
|
|
18964
|
+
"node-updating",
|
|
19016
18965
|
"node-inference-unavailable",
|
|
19017
18966
|
"detection-blind",
|
|
19018
18967
|
"addon-crash-loop",
|
|
@@ -20111,8 +20060,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
20111
20060
|
disabledTargetIds: array(string()).default([])
|
|
20112
20061
|
});
|
|
20113
20062
|
/**
|
|
20114
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
20115
|
-
* still-true state. `
|
|
20063
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
20064
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
20065
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
20116
20066
|
* job is not an open state, and the alarm stays instant.
|
|
20117
20067
|
*/
|
|
20118
20068
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -20124,6 +20074,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
20124
20074
|
"detection-blind",
|
|
20125
20075
|
"nodes",
|
|
20126
20076
|
"addons",
|
|
20077
|
+
"addon-updates",
|
|
20127
20078
|
"updates"
|
|
20128
20079
|
]);
|
|
20129
20080
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -20604,7 +20555,25 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
20604
20555
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
20605
20556
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
20606
20557
|
*/
|
|
20607
|
-
schedule: NcScheduleSchema.optional()
|
|
20558
|
+
schedule: NcScheduleSchema.optional(),
|
|
20559
|
+
/**
|
|
20560
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
20561
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
20562
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
20563
|
+
*/
|
|
20564
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
20565
|
+
/**
|
|
20566
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
20567
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
20568
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
20569
|
+
*/
|
|
20570
|
+
notifySensorRewatched: boolean().optional(),
|
|
20571
|
+
/**
|
|
20572
|
+
* D735: notify "ignored" when a sensor this arm bypassed really MOVED while armed (its own
|
|
20573
|
+
* change time is after the arm) and set nothing off. Absent = false (logged, not sent). A
|
|
20574
|
+
* re-sync, a recovery from `unavailable` or a duplicate is never announced, switch or not.
|
|
20575
|
+
*/
|
|
20576
|
+
notifySensorIgnored: boolean().optional()
|
|
20608
20577
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20609
20578
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20610
20579
|
mode: AlarmArmModeSchema,
|
|
@@ -20613,7 +20582,13 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
20613
20582
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
20614
20583
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
20615
20584
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
20616
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
20585
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
20586
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20587
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
20588
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20589
|
+
notifySensorRewatched: boolean().nullable().optional(),
|
|
20590
|
+
/** D735: set the switch, or `null` to clear it (back to the default, false). */
|
|
20591
|
+
notifySensorIgnored: boolean().nullable().optional()
|
|
20617
20592
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20618
20593
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20619
20594
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -21574,45 +21549,25 @@ Object.freeze(Object.fromEntries([{
|
|
|
21574
21549
|
label: "Face recognition model",
|
|
21575
21550
|
defaultModelId: "auraface-r100",
|
|
21576
21551
|
indexName: "the enrolled face gallery",
|
|
21577
|
-
options: [
|
|
21578
|
-
|
|
21579
|
-
|
|
21580
|
-
|
|
21581
|
-
},
|
|
21582
|
-
{
|
|
21583
|
-
id: "arcface-r100",
|
|
21584
|
-
label: "ArcFace (ResNet34)"
|
|
21585
|
-
},
|
|
21586
|
-
{
|
|
21587
|
-
id: "inception-resnet-v1",
|
|
21588
|
-
label: "Inception ResNet V1"
|
|
21589
|
-
}
|
|
21590
|
-
]
|
|
21552
|
+
options: [{
|
|
21553
|
+
id: "auraface-r100",
|
|
21554
|
+
label: "AuraFace R100"
|
|
21555
|
+
}]
|
|
21591
21556
|
}, {
|
|
21592
21557
|
stepId: "clip-embedding",
|
|
21593
21558
|
label: "Semantic search model",
|
|
21594
|
-
defaultModelId: "
|
|
21559
|
+
defaultModelId: "siglip2-b16-224",
|
|
21595
21560
|
indexName: "the object semantic-search index",
|
|
21596
|
-
options: [
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
|
|
21600
|
-
},
|
|
21601
|
-
{
|
|
21602
|
-
id: "mobileclip-s2",
|
|
21603
|
-
label: "MobileCLIP S2"
|
|
21604
|
-
},
|
|
21605
|
-
{
|
|
21606
|
-
id: "siglip2-b16-224",
|
|
21607
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21608
|
-
}
|
|
21609
|
-
]
|
|
21561
|
+
options: [{
|
|
21562
|
+
id: "siglip2-b16-224",
|
|
21563
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21564
|
+
}]
|
|
21610
21565
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
21611
21566
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
21612
21567
|
stepId: "face-embedding",
|
|
21613
21568
|
key: "minLandmarkFaceSize",
|
|
21614
|
-
label: "Min face size
|
|
21615
|
-
description: "
|
|
21569
|
+
label: "Min face size to embed (detection-frame px)",
|
|
21570
|
+
description: "Faces smaller than this in the small frame the detector sees are not embedded, so they can never be recognised. Below it the face cannot be aligned reliably and a bad embedding matches everyone. Same value on every node. 0 = no limit.",
|
|
21616
21571
|
type: "slider",
|
|
21617
21572
|
min: 0,
|
|
21618
21573
|
max: 64,
|
|
@@ -23532,6 +23487,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
23532
23487
|
timestamp: number()
|
|
23533
23488
|
});
|
|
23534
23489
|
/**
|
|
23490
|
+
* A root model's boxes standing in for one crop-kind step's own inference
|
|
23491
|
+
* (D730) — see `runPipeline.suppliedRoot`.
|
|
23492
|
+
*/
|
|
23493
|
+
var SuppliedRootOutputSchema = object({
|
|
23494
|
+
stepId: string(),
|
|
23495
|
+
/** The root model that drew the boxes — stamped on the result. */
|
|
23496
|
+
modelId: string(),
|
|
23497
|
+
detections: array(object({
|
|
23498
|
+
/** `[x1, y1, x2, y2]` in the pixels of the call's image. */
|
|
23499
|
+
bbox: tuple([
|
|
23500
|
+
number(),
|
|
23501
|
+
number(),
|
|
23502
|
+
number(),
|
|
23503
|
+
number()
|
|
23504
|
+
]),
|
|
23505
|
+
score: number(),
|
|
23506
|
+
/**
|
|
23507
|
+
* Five facial landmarks in the same pixels — a face the step's own
|
|
23508
|
+
* detector already re-found inside a root face box (D730), so its
|
|
23509
|
+
* embedder child aligns it exactly as it aligns any detected face.
|
|
23510
|
+
*/
|
|
23511
|
+
landmarks: array(object({
|
|
23512
|
+
x: number(),
|
|
23513
|
+
y: number()
|
|
23514
|
+
})).optional()
|
|
23515
|
+
})).min(1)
|
|
23516
|
+
});
|
|
23517
|
+
/**
|
|
23535
23518
|
* Reference to the frame's retained NATIVE surface + the parent crop's placement
|
|
23536
23519
|
* within the frame, so the executor can re-cut a leaf child ROI at native
|
|
23537
23520
|
* resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
|
|
@@ -23579,7 +23562,7 @@ var FrameRefSchema = object({
|
|
|
23579
23562
|
timestamp: number(),
|
|
23580
23563
|
capturedAt: number().optional()
|
|
23581
23564
|
});
|
|
23582
|
-
var ModelFormatSchema$
|
|
23565
|
+
var ModelFormatSchema$2 = _enum([
|
|
23583
23566
|
"onnx",
|
|
23584
23567
|
"coreml",
|
|
23585
23568
|
"openvino",
|
|
@@ -23597,7 +23580,7 @@ var PipelineSlotSchema = _enum([
|
|
|
23597
23580
|
var PipelineEngineChoiceSchema = object({
|
|
23598
23581
|
runtime: literal("python"),
|
|
23599
23582
|
backend: string(),
|
|
23600
|
-
format: ModelFormatSchema$
|
|
23583
|
+
format: ModelFormatSchema$2,
|
|
23601
23584
|
device: string().optional()
|
|
23602
23585
|
});
|
|
23603
23586
|
/**
|
|
@@ -23636,32 +23619,15 @@ var PipelineDefaultStepSchema = lazy(() => object({
|
|
|
23636
23619
|
group: string().optional(),
|
|
23637
23620
|
settings: record(string(), unknown()).optional()
|
|
23638
23621
|
}));
|
|
23639
|
-
var PipelineTemplateStepSchema = lazy(() => object({
|
|
23640
|
-
addonId: string(),
|
|
23641
|
-
enabled: boolean(),
|
|
23642
|
-
modelId: string(),
|
|
23643
|
-
children: array(PipelineTemplateStepSchema).readonly(),
|
|
23644
|
-
settings: record(string(), unknown()).optional()
|
|
23645
|
-
}));
|
|
23646
|
-
var PipelineTemplateSchema$1 = object({
|
|
23647
|
-
id: string(),
|
|
23648
|
-
name: string(),
|
|
23649
|
-
createdAt: string(),
|
|
23650
|
-
updatedAt: string(),
|
|
23651
|
-
engine: PipelineEngineChoiceSchema,
|
|
23652
|
-
steps: array(PipelineTemplateStepSchema).readonly()
|
|
23653
|
-
});
|
|
23654
23622
|
var PipelineModelOptionSchema = object({
|
|
23655
23623
|
id: string(),
|
|
23656
23624
|
name: string(),
|
|
23657
|
-
formats: record(string(),
|
|
23658
|
-
downloaded: boolean(),
|
|
23659
|
-
sizeMB: number()
|
|
23660
|
-
})),
|
|
23625
|
+
formats: record(string(), PipelineModelFormatStatusSchema),
|
|
23661
23626
|
group: ModelVariantGroupSchema.optional(),
|
|
23662
23627
|
legacy: boolean().optional(),
|
|
23663
23628
|
provider: ModelProviderIdSchema.optional(),
|
|
23664
|
-
defaultConfidence: number().optional()
|
|
23629
|
+
defaultConfidence: number().optional(),
|
|
23630
|
+
suppliesSteps: array(RootStepSupplySchema).readonly().optional()
|
|
23665
23631
|
});
|
|
23666
23632
|
var ConfigFieldBridge = custom();
|
|
23667
23633
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -23823,6 +23789,22 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
23823
23789
|
}), {
|
|
23824
23790
|
kind: "mutation",
|
|
23825
23791
|
auth: "admin"
|
|
23792
|
+
}), method(object({
|
|
23793
|
+
nodeId: string(),
|
|
23794
|
+
deviceIds: array(number()).readonly().optional(),
|
|
23795
|
+
dryRun: boolean()
|
|
23796
|
+
}), object({
|
|
23797
|
+
entries: array(object({
|
|
23798
|
+
deviceId: number(),
|
|
23799
|
+
keys: array(string()).readonly()
|
|
23800
|
+
})).readonly(),
|
|
23801
|
+
refused: array(object({
|
|
23802
|
+
deviceId: number(),
|
|
23803
|
+
reason: string()
|
|
23804
|
+
})).readonly()
|
|
23805
|
+
}), {
|
|
23806
|
+
kind: "mutation",
|
|
23807
|
+
auth: "admin"
|
|
23826
23808
|
}), method(object({ nodeId: string() }), object({ unhealthy: array(object({
|
|
23827
23809
|
/** `<backend>:<device>`, e.g. `openvino:gpu`. */
|
|
23828
23810
|
deviceKey: string(),
|
|
@@ -23848,22 +23830,14 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
23848
23830
|
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({
|
|
23849
23831
|
steps: array(PipelineStepInputSchema),
|
|
23850
23832
|
deviceKey: string().optional()
|
|
23851
|
-
}), PipelineValidationResultSchema), method(_void(),
|
|
23852
|
-
name: string(),
|
|
23853
|
-
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
23854
|
-
engine: PipelineEngineChoiceSchema
|
|
23855
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
|
|
23856
|
-
id: string(),
|
|
23857
|
-
name: string().optional(),
|
|
23858
|
-
steps: array(PipelineTemplateStepSchema).readonly().optional()
|
|
23859
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
|
|
23833
|
+
}), PipelineValidationResultSchema), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
|
|
23860
23834
|
addonId: string(),
|
|
23861
23835
|
modelId: string(),
|
|
23862
|
-
format: ModelFormatSchema$
|
|
23836
|
+
format: ModelFormatSchema$2
|
|
23863
23837
|
}), DownloadModelResultSchema, { kind: "mutation" }), method(object({
|
|
23864
23838
|
addonId: string(),
|
|
23865
23839
|
modelId: string(),
|
|
23866
|
-
format: ModelFormatSchema$
|
|
23840
|
+
format: ModelFormatSchema$2
|
|
23867
23841
|
}), object({ success: literal(true) }), { kind: "mutation" }), method(object({
|
|
23868
23842
|
steps: array(PipelineStepInputSchema).min(1),
|
|
23869
23843
|
frame: FrameInputSchema.optional(),
|
|
@@ -23929,7 +23903,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
23929
23903
|
* `device-not-servable`), and nothing reaches the camera's live
|
|
23930
23904
|
* trace stream. Absent ⇒ unchanged behaviour.
|
|
23931
23905
|
*/
|
|
23932
|
-
replay: literal(true).optional()
|
|
23906
|
+
replay: literal(true).optional(),
|
|
23907
|
+
/**
|
|
23908
|
+
* Root-supplied detections for the tree's ROOT step (D730). Set by
|
|
23909
|
+
* `runDetailSubtree` when the camera's root model supplies a crop-kind
|
|
23910
|
+
* step (a Frigate+ `license_plate` for `plate-detection`): the step is
|
|
23911
|
+
* NOT inferred, these boxes are its output, and its children (the plate
|
|
23912
|
+
* reader) run on them through their own crop policy. Boxes are in the
|
|
23913
|
+
* PIXELS of the image this call carries. Absent ⇒ the root step runs.
|
|
23914
|
+
*/
|
|
23915
|
+
suppliedRoot: SuppliedRootOutputSchema.optional()
|
|
23933
23916
|
}), PipelineRunResultBridge, { kind: "mutation" }), method(object({
|
|
23934
23917
|
steps: array(PipelineStepInputSchema).min(1),
|
|
23935
23918
|
frames: array(FrameInputSchema).min(1).max(255),
|
|
@@ -24011,6 +23994,375 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
24011
23994
|
filename: string().optional(),
|
|
24012
23995
|
settings: record(string(), unknown()).optional()
|
|
24013
23996
|
}), AudioTestResultSchema, { kind: "mutation" }), method(_void(), ConfigUISchemaNullableBridge);
|
|
23997
|
+
/**
|
|
23998
|
+
* The wire shapes of the Auto tune plan and apply (D745), used by the
|
|
23999
|
+
* `pipeline-orchestrator` cap. The recommender's own types
|
|
24000
|
+
* (`recommend.ts`) are the TS face of the same data; these
|
|
24001
|
+
* schemas are what crosses the cap boundary.
|
|
24002
|
+
*/
|
|
24003
|
+
var ModelFormatSchema$1 = _enum(MODEL_FORMATS);
|
|
24004
|
+
/** The operator's range for it. */
|
|
24005
|
+
var MIN_SESSIONS_PER_DEVICE_RANGE = {
|
|
24006
|
+
min: 1,
|
|
24007
|
+
max: 8
|
|
24008
|
+
};
|
|
24009
|
+
var HardwareClassIdSchema = _enum([
|
|
24010
|
+
"intel-core-ultra",
|
|
24011
|
+
"intel-n-series",
|
|
24012
|
+
"apple-m-base",
|
|
24013
|
+
"apple-m-pro",
|
|
24014
|
+
"unknown"
|
|
24015
|
+
]);
|
|
24016
|
+
var AcceleratorKindSchema = _enum([
|
|
24017
|
+
"intel-npu",
|
|
24018
|
+
"intel-igpu",
|
|
24019
|
+
"x86-cpu",
|
|
24020
|
+
"arm-cpu",
|
|
24021
|
+
"apple-ane",
|
|
24022
|
+
"coral"
|
|
24023
|
+
]);
|
|
24024
|
+
var RecommendationReasonSchema = discriminatedUnion("kind", [
|
|
24025
|
+
object({
|
|
24026
|
+
kind: literal("capacity"),
|
|
24027
|
+
sessions: number(),
|
|
24028
|
+
minSessions: number()
|
|
24029
|
+
}),
|
|
24030
|
+
object({
|
|
24031
|
+
kind: literal("tie-faster"),
|
|
24032
|
+
over: string(),
|
|
24033
|
+
recallDelta: number()
|
|
24034
|
+
}),
|
|
24035
|
+
object({
|
|
24036
|
+
kind: literal("stepped-down"),
|
|
24037
|
+
from: string(),
|
|
24038
|
+
to: string(),
|
|
24039
|
+
limitedBy: string()
|
|
24040
|
+
}),
|
|
24041
|
+
object({
|
|
24042
|
+
kind: literal("no-fit-lightest"),
|
|
24043
|
+
sessions: number(),
|
|
24044
|
+
minSessions: number()
|
|
24045
|
+
}),
|
|
24046
|
+
object({
|
|
24047
|
+
kind: literal("derived-latency"),
|
|
24048
|
+
modelId: string()
|
|
24049
|
+
}),
|
|
24050
|
+
object({ kind: literal("cpu-device") }),
|
|
24051
|
+
object({ kind: literal("coral-untouched") }),
|
|
24052
|
+
object({ kind: literal("device-disabled") }),
|
|
24053
|
+
object({ kind: literal("device-unavailable") }),
|
|
24054
|
+
object({ kind: literal("node-offline") }),
|
|
24055
|
+
object({ kind: literal("no-hardware-facts") }),
|
|
24056
|
+
object({
|
|
24057
|
+
kind: literal("no-measured-data"),
|
|
24058
|
+
hardwareClass: HardwareClassIdSchema
|
|
24059
|
+
}),
|
|
24060
|
+
object({
|
|
24061
|
+
kind: literal("no-family-build"),
|
|
24062
|
+
format: ModelFormatSchema$1
|
|
24063
|
+
})
|
|
24064
|
+
]);
|
|
24065
|
+
var DeviceModelChoiceSchema = object({
|
|
24066
|
+
modelId: string(),
|
|
24067
|
+
p50Ms: number(),
|
|
24068
|
+
fps: number(),
|
|
24069
|
+
measured: boolean(),
|
|
24070
|
+
/** Parallel sessions at the camera rate with the headroom kept free: ⌊fps × (1 − headroom) / camera fps⌋. */
|
|
24071
|
+
capacitySessions: number(),
|
|
24072
|
+
personRecall: number()
|
|
24073
|
+
});
|
|
24074
|
+
var DeviceRecommendationSchema = object({
|
|
24075
|
+
deviceKey: string(),
|
|
24076
|
+
accelerator: AcceleratorKindSchema.nullable(),
|
|
24077
|
+
enabled: boolean(),
|
|
24078
|
+
available: boolean(),
|
|
24079
|
+
chosen: DeviceModelChoiceSchema.nullable(),
|
|
24080
|
+
reasons: array(RecommendationReasonSchema).readonly()
|
|
24081
|
+
});
|
|
24082
|
+
var NodeRecommendationSchema = object({
|
|
24083
|
+
nodeId: string(),
|
|
24084
|
+
reachable: boolean(),
|
|
24085
|
+
hardwareClass: HardwareClassIdSchema.nullable(),
|
|
24086
|
+
cpuModel: string().nullable(),
|
|
24087
|
+
skipped: boolean(),
|
|
24088
|
+
acceleratorModelId: string().nullable(),
|
|
24089
|
+
devices: array(DeviceRecommendationSchema).readonly(),
|
|
24090
|
+
reasons: array(RecommendationReasonSchema).readonly()
|
|
24091
|
+
});
|
|
24092
|
+
var ModelPinChangeSchema = object({
|
|
24093
|
+
stepId: string(),
|
|
24094
|
+
before: string().nullable(),
|
|
24095
|
+
after: string().nullable()
|
|
24096
|
+
});
|
|
24097
|
+
var NodeDeviceChangeSchema = object({
|
|
24098
|
+
nodeId: string(),
|
|
24099
|
+
deviceKey: string(),
|
|
24100
|
+
madeExplicit: boolean(),
|
|
24101
|
+
modelPins: array(ModelPinChangeSchema).readonly(),
|
|
24102
|
+
thresholds: array(object({
|
|
24103
|
+
stepId: string(),
|
|
24104
|
+
keys: array(string()).readonly()
|
|
24105
|
+
})).readonly()
|
|
24106
|
+
});
|
|
24107
|
+
var CameraOverrideClearSchema = object({
|
|
24108
|
+
deviceId: number(),
|
|
24109
|
+
source: _enum(["step-override", "wholesale"]),
|
|
24110
|
+
nodeId: string(),
|
|
24111
|
+
deviceKey: string().nullable(),
|
|
24112
|
+
stepId: string(),
|
|
24113
|
+
modelIdBefore: string().nullable(),
|
|
24114
|
+
keys: array(string()).readonly()
|
|
24115
|
+
});
|
|
24116
|
+
var DetectorStoreClearSchema = object({
|
|
24117
|
+
deviceId: number(),
|
|
24118
|
+
keys: array(string()).readonly()
|
|
24119
|
+
});
|
|
24120
|
+
var AutoTuneWarningSchema = discriminatedUnion("kind", [
|
|
24121
|
+
object({
|
|
24122
|
+
kind: literal("detector-store-cluster-wide"),
|
|
24123
|
+
skippedNodes: array(string()).readonly()
|
|
24124
|
+
}),
|
|
24125
|
+
object({
|
|
24126
|
+
kind: literal("detector-store-unreadable"),
|
|
24127
|
+
error: string()
|
|
24128
|
+
}),
|
|
24129
|
+
object({
|
|
24130
|
+
kind: literal("coral-enabled"),
|
|
24131
|
+
nodeId: string(),
|
|
24132
|
+
deviceKey: string()
|
|
24133
|
+
})
|
|
24134
|
+
]);
|
|
24135
|
+
var AutoTuneOptionsSchema = object({
|
|
24136
|
+
/** Share of each accelerator's throughput kept free (0.3–0.5). */
|
|
24137
|
+
headroom: number().min(.3).max(.5).default(.4),
|
|
24138
|
+
/**
|
|
24139
|
+
* The least number of parallel sessions every device must sustain at the
|
|
24140
|
+
* camera rate with the headroom kept free (D755). The most accurate model
|
|
24141
|
+
* that reaches it wins.
|
|
24142
|
+
*/
|
|
24143
|
+
minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
|
|
24144
|
+
});
|
|
24145
|
+
var AutoTunePlanSchema = object({
|
|
24146
|
+
/** Hash of everything the apply will write — the apply refuses a different one. */
|
|
24147
|
+
planHash: string(),
|
|
24148
|
+
family: literal("yolov9"),
|
|
24149
|
+
headroom: number(),
|
|
24150
|
+
minSessionsPerDevice: number(),
|
|
24151
|
+
/** The detection rate a session is counted at (the fastest camera running the pipeline root). */
|
|
24152
|
+
cameraFps: number(),
|
|
24153
|
+
generatedAt: number(),
|
|
24154
|
+
nodes: array(NodeRecommendationSchema).readonly(),
|
|
24155
|
+
nodeChanges: array(NodeDeviceChangeSchema).readonly(),
|
|
24156
|
+
cameraClears: array(CameraOverrideClearSchema).readonly(),
|
|
24157
|
+
detectorStoreClears: array(DetectorStoreClearSchema).readonly(),
|
|
24158
|
+
warnings: array(AutoTuneWarningSchema).readonly()
|
|
24159
|
+
});
|
|
24160
|
+
var AutoTuneApplyInputSchema = object({
|
|
24161
|
+
planHash: string(),
|
|
24162
|
+
headroom: number().min(.3).max(.5).default(.4),
|
|
24163
|
+
minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
|
|
24164
|
+
});
|
|
24165
|
+
var AutoTunePhaseResultSchema = object({
|
|
24166
|
+
phase: _enum([
|
|
24167
|
+
"download",
|
|
24168
|
+
"camera-overrides",
|
|
24169
|
+
"detector-thresholds",
|
|
24170
|
+
"node-models",
|
|
24171
|
+
"redispatch"
|
|
24172
|
+
]),
|
|
24173
|
+
ok: boolean(),
|
|
24174
|
+
detail: string()
|
|
24175
|
+
});
|
|
24176
|
+
var AutoTuneApplyResultSchema = discriminatedUnion("kind", [
|
|
24177
|
+
object({
|
|
24178
|
+
kind: literal("applied"),
|
|
24179
|
+
planHash: string(),
|
|
24180
|
+
phases: array(AutoTunePhaseResultSchema).readonly()
|
|
24181
|
+
}),
|
|
24182
|
+
object({
|
|
24183
|
+
kind: literal("aborted"),
|
|
24184
|
+
phases: array(AutoTunePhaseResultSchema).readonly()
|
|
24185
|
+
}),
|
|
24186
|
+
object({
|
|
24187
|
+
kind: literal("stale"),
|
|
24188
|
+
plan: AutoTunePlanSchema
|
|
24189
|
+
}),
|
|
24190
|
+
object({
|
|
24191
|
+
kind: literal("refused"),
|
|
24192
|
+
reason: _enum(["apply-in-progress"])
|
|
24193
|
+
})
|
|
24194
|
+
]);
|
|
24195
|
+
/**
|
|
24196
|
+
* Wire shapes of the Load balancing surface (D748): the session placement
|
|
24197
|
+
* policy, the atomic share write, the observed placement statistics, the
|
|
24198
|
+
* hardware share suggestion and the stale device pins.
|
|
24199
|
+
*/
|
|
24200
|
+
/**
|
|
24201
|
+
* How a new detection session picks its node and device.
|
|
24202
|
+
* - `least-loaded` — the historical rule: lowest `attached / weight`, a
|
|
24203
|
+
* constant node order at a tie (D37). An idle node always ties at 0, so a
|
|
24204
|
+
* weight only bites once a node already holds a session.
|
|
24205
|
+
* - `share` — the share of PARALLEL sessions is held to the weights, and a
|
|
24206
|
+
* full or drowning node yields to a free one (D748).
|
|
24207
|
+
*/
|
|
24208
|
+
var SessionPlacementPolicySchema = _enum(["least-loaded", "share"]);
|
|
24209
|
+
var LoadBalancingSharesInputSchema = object({
|
|
24210
|
+
/** nodeId → share (> 0). A node left out keeps its weight. */
|
|
24211
|
+
nodes: record(string(), number().positive()).default({}),
|
|
24212
|
+
/** nodeId → deviceKey → share (> 0). A device left out keeps its weight. */
|
|
24213
|
+
devices: record(string(), record(string(), number().positive())).default({})
|
|
24214
|
+
});
|
|
24215
|
+
var PlacementStatsInputSchema = object({
|
|
24216
|
+
/** Window the observed shares are averaged over (default 1 h, max 24 h). */
|
|
24217
|
+
windowMs: number().int().min(6e4).max(1440 * 60 * 1e3).default(3600 * 1e3) });
|
|
24218
|
+
var PlacementDeviceStatsSchema = object({
|
|
24219
|
+
deviceKey: string(),
|
|
24220
|
+
/** Sessions running on this device now. */
|
|
24221
|
+
sessionsNow: number(),
|
|
24222
|
+
/** Sessions started on this device inside the window. */
|
|
24223
|
+
sessionsStarted: number(),
|
|
24224
|
+
/** Time-weighted share of the node's parallel sessions over the window (0–1); null = no session ran. */
|
|
24225
|
+
observedShare: number().nullable()
|
|
24226
|
+
});
|
|
24227
|
+
var PlacementNodeStatsSchema = object({
|
|
24228
|
+
nodeId: string(),
|
|
24229
|
+
sessionsNow: number(),
|
|
24230
|
+
sessionsStarted: number(),
|
|
24231
|
+
/** Time-weighted share of the cluster's parallel sessions over the window (0–1); null = none ran. */
|
|
24232
|
+
observedShare: number().nullable(),
|
|
24233
|
+
/** Most sessions this node ran at once inside the window. */
|
|
24234
|
+
peakSessions: number(),
|
|
24235
|
+
/** Sessions a share election handed elsewhere because this node was full or drowning. */
|
|
24236
|
+
yieldsAway: number(),
|
|
24237
|
+
devices: array(PlacementDeviceStatsSchema).readonly()
|
|
24238
|
+
});
|
|
24239
|
+
/** A camera's device pin that the session path cannot honour. */
|
|
24240
|
+
var StaleDevicePinSchema = object({
|
|
24241
|
+
deviceId: number(),
|
|
24242
|
+
deviceKey: string(),
|
|
24243
|
+
/** `disabled` — the key exists on some node but is not enabled anywhere; `absent` — no node has it. */
|
|
24244
|
+
reason: _enum(["disabled", "absent"])
|
|
24245
|
+
});
|
|
24246
|
+
var PlacementStatsSchema = object({
|
|
24247
|
+
policy: SessionPlacementPolicySchema,
|
|
24248
|
+
windowMs: number(),
|
|
24249
|
+
/** How much of the window was actually observed (the hub keeps it in memory). */
|
|
24250
|
+
observedForMs: number(),
|
|
24251
|
+
sessionsNow: number(),
|
|
24252
|
+
/** Most parallel sessions across the cluster inside the window. */
|
|
24253
|
+
clusterPeakSessions: number(),
|
|
24254
|
+
nodes: array(PlacementNodeStatsSchema).readonly(),
|
|
24255
|
+
stalePins: array(StaleDevicePinSchema).readonly()
|
|
24256
|
+
});
|
|
24257
|
+
/**
|
|
24258
|
+
* Where an automatic share's capacity comes from (D755).
|
|
24259
|
+
* - `hardware` — the static capacity of each device at its Auto tune model:
|
|
24260
|
+
* the measured latency table for the node's hardware class.
|
|
24261
|
+
* - `benchmark` — the node's own measured capacity (node benchmark results).
|
|
24262
|
+
* A node with no results falls back to `hardware`, and says so.
|
|
24263
|
+
*/
|
|
24264
|
+
var CapacitySourceSchema = _enum(["hardware", "benchmark"]);
|
|
24265
|
+
/** Why a node under the `benchmark` source was sized from hardware instead. */
|
|
24266
|
+
var CapacityFallbackSchema = _enum(["no-benchmark-results", "partial-benchmark-results"]);
|
|
24267
|
+
var SuggestSharesInputSchema = object({
|
|
24268
|
+
headroom: number().min(.3).max(.5).default(.4),
|
|
24269
|
+
/** Default `hardware`. */
|
|
24270
|
+
source: CapacitySourceSchema.default("hardware")
|
|
24271
|
+
});
|
|
24272
|
+
var SuggestedDeviceShareSchema = object({
|
|
24273
|
+
deviceKey: string(),
|
|
24274
|
+
/** Share of the node (0–100, rounded). */
|
|
24275
|
+
share: number(),
|
|
24276
|
+
modelId: string().nullable(),
|
|
24277
|
+
/** Inferences per second at that model, from the measured table; null when sized by a benchmark. */
|
|
24278
|
+
fps: number().nullable(),
|
|
24279
|
+
/** False for a table cell derived from another chip; true for a measured cell or a benchmark. */
|
|
24280
|
+
measured: boolean(),
|
|
24281
|
+
/**
|
|
24282
|
+
* Advisory session cap: ⌊fps × (1 − headroom) / camera fps⌋ from the table,
|
|
24283
|
+
* or the benchmark's measured max sessions. Never enforced.
|
|
24284
|
+
*/
|
|
24285
|
+
suggestedMaxSessions: number().nullable()
|
|
24286
|
+
});
|
|
24287
|
+
var SuggestedNodeShareSchema = object({
|
|
24288
|
+
nodeId: string(),
|
|
24289
|
+
/** Share of the cluster (0–100, rounded); null = node skipped (offline, unknown hardware). */
|
|
24290
|
+
share: number().nullable(),
|
|
24291
|
+
/** Parallel sessions the node sustains at the suggested models with the headroom kept free. */
|
|
24292
|
+
capacitySessions: number(),
|
|
24293
|
+
devices: array(SuggestedDeviceShareSchema).readonly(),
|
|
24294
|
+
skippedReason: string().nullable(),
|
|
24295
|
+
/** What this node's capacity was read from; null when the node is skipped. */
|
|
24296
|
+
capacitySource: CapacitySourceSchema.nullable(),
|
|
24297
|
+
/** Set when the `benchmark` source was asked for and this node used `hardware`. */
|
|
24298
|
+
capacityFallback: CapacityFallbackSchema.nullable()
|
|
24299
|
+
});
|
|
24300
|
+
var SuggestSharesResultSchema = object({
|
|
24301
|
+
headroom: number(),
|
|
24302
|
+
/** The source asked for; each node says what it actually used. */
|
|
24303
|
+
source: CapacitySourceSchema,
|
|
24304
|
+
/** Camera detection rate the capacity is counted in (the fastest camera's fps). */
|
|
24305
|
+
cameraFps: number(),
|
|
24306
|
+
/** The Auto tune capacity floor the models were picked at. */
|
|
24307
|
+
minSessionsPerDevice: number(),
|
|
24308
|
+
nodes: array(SuggestedNodeShareSchema).readonly()
|
|
24309
|
+
});
|
|
24310
|
+
/**
|
|
24311
|
+
* Where the node and device shares come from (D750, D755).
|
|
24312
|
+
* - `hardware` (default) — computed by the system from each node's static
|
|
24313
|
+
* capacity (its accelerators at their Auto tune models, from the measured
|
|
24314
|
+
* latency table), recomputed whenever a node or device joins, leaves, is
|
|
24315
|
+
* switched on or off, or changes model. No load input.
|
|
24316
|
+
* - `benchmark` — the same, from each node's measured capacity (node
|
|
24317
|
+
* benchmark results); a node without results falls back to `hardware`.
|
|
24318
|
+
* - `manual` — the operator's stored sliders.
|
|
24319
|
+
* Either way a node or device that cannot take sessions gives its share to
|
|
24320
|
+
* the others in proportion; the stored values are never rewritten for that.
|
|
24321
|
+
*/
|
|
24322
|
+
var ShareSourceSchema = _enum([
|
|
24323
|
+
"hardware",
|
|
24324
|
+
"benchmark",
|
|
24325
|
+
"manual"
|
|
24326
|
+
]);
|
|
24327
|
+
var SetShareSourceInputSchema = object({ source: ShareSourceSchema });
|
|
24328
|
+
object({
|
|
24329
|
+
nodes: record(string(), number()),
|
|
24330
|
+
devices: record(string(), record(string(), number()))
|
|
24331
|
+
});
|
|
24332
|
+
var EffectiveDeviceShareSchema = object({
|
|
24333
|
+
deviceKey: string(),
|
|
24334
|
+
/** Can take sessions now (enabled, available, can run the root). */
|
|
24335
|
+
eligible: boolean(),
|
|
24336
|
+
/** The share the source assigns, as a percentage of the node's devices. */
|
|
24337
|
+
configuredPct: number(),
|
|
24338
|
+
/** The share actually used, after an ineligible device's share went to the others. */
|
|
24339
|
+
effectivePct: number()
|
|
24340
|
+
});
|
|
24341
|
+
var EffectiveNodeShareSchema = object({
|
|
24342
|
+
nodeId: string(),
|
|
24343
|
+
eligible: boolean(),
|
|
24344
|
+
configuredPct: number(),
|
|
24345
|
+
effectivePct: number(),
|
|
24346
|
+
/** Automatic sources: what this node's share was computed from; null under `manual` or before the first answer. */
|
|
24347
|
+
capacitySource: CapacitySourceSchema.nullable(),
|
|
24348
|
+
/** Automatic `benchmark`: why this node used `hardware` instead. */
|
|
24349
|
+
capacityFallback: CapacityFallbackSchema.nullable(),
|
|
24350
|
+
devices: array(EffectiveDeviceShareSchema).readonly()
|
|
24351
|
+
});
|
|
24352
|
+
var EffectiveSharesSchema = object({
|
|
24353
|
+
source: ShareSourceSchema,
|
|
24354
|
+
policy: SessionPlacementPolicySchema,
|
|
24355
|
+
/** An automatic source with no computed answer yet: the stored sliders are used meanwhile. */
|
|
24356
|
+
autoPending: boolean(),
|
|
24357
|
+
/** When the automatic shares were last computed (ms epoch); null = never. */
|
|
24358
|
+
computedAt: number().nullable(),
|
|
24359
|
+
/** What made the system recompute them last. */
|
|
24360
|
+
trigger: string().nullable(),
|
|
24361
|
+
nodes: array(EffectiveNodeShareSchema).readonly(),
|
|
24362
|
+
/** The relative weights the election reads (before eligibility). */
|
|
24363
|
+
nodeWeights: record(string(), number()),
|
|
24364
|
+
deviceWeights: record(string(), record(string(), number()))
|
|
24365
|
+
});
|
|
24014
24366
|
object({
|
|
24015
24367
|
activeCameras: number(),
|
|
24016
24368
|
throttledCameras: number(),
|
|
@@ -24494,6 +24846,22 @@ var MotionSourceEnum = _enum([
|
|
|
24494
24846
|
"device-activity"
|
|
24495
24847
|
]);
|
|
24496
24848
|
/**
|
|
24849
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
24850
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
24851
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
24852
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
24853
|
+
* absent when unknown or when the camera itself triggered.
|
|
24854
|
+
*
|
|
24855
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
24856
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
24857
|
+
* runner never decides anything on it.
|
|
24858
|
+
*/
|
|
24859
|
+
var SessionTriggerSchema = object({
|
|
24860
|
+
source: MotionSourceEnum,
|
|
24861
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
24862
|
+
sensorName: string().optional()
|
|
24863
|
+
});
|
|
24864
|
+
/**
|
|
24497
24865
|
* List of motion sources active on a camera. Empty array is valid:
|
|
24498
24866
|
* "no source" — happens for battery cams without firmware motion when
|
|
24499
24867
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -24745,6 +25113,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
24745
25113
|
*/
|
|
24746
25114
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24747
25115
|
/**
|
|
25116
|
+
* What opened this attach, on a SESSION attach only (see
|
|
25117
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
25118
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
25119
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
25120
|
+
* runner then names no source on the phase event.
|
|
25121
|
+
*/
|
|
25122
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
25123
|
+
/**
|
|
24748
25124
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
24749
25125
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
24750
25126
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -24904,14 +25280,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
24904
25280
|
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
24905
25281
|
* this runner currently has attached cameras on, so the orchestrator's second
|
|
24906
25282
|
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
24907
|
-
* counts. Empty on single-device / pre-multi-device runners.
|
|
24908
|
-
* per
|
|
25283
|
+
* counts. Empty on single-device / pre-multi-device runners. There is no
|
|
25284
|
+
* per-device queue depth: the inference pool's backlog has no accessor, and
|
|
25285
|
+
* a field that always read 0 was removed rather than shown as a measurement
|
|
25286
|
+
* (D762).
|
|
24909
25287
|
*/
|
|
24910
25288
|
devices: array(object({
|
|
24911
25289
|
deviceKey: string(),
|
|
24912
25290
|
backend: string(),
|
|
24913
|
-
attachedCameras: number()
|
|
24914
|
-
queueDepthTotal: number()
|
|
25291
|
+
attachedCameras: number()
|
|
24915
25292
|
})).default([]),
|
|
24916
25293
|
/** Hardware capability flags reported by this node. */
|
|
24917
25294
|
hardware: object({
|
|
@@ -25047,7 +25424,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
25047
25424
|
*/
|
|
25048
25425
|
cropJpeg: string().optional(),
|
|
25049
25426
|
parent: DetailParentSchema,
|
|
25050
|
-
steps: array(string()).optional()
|
|
25427
|
+
steps: array(string()).optional(),
|
|
25428
|
+
/**
|
|
25429
|
+
* The camera's root model already drew this step's boxes (D730): a
|
|
25430
|
+
* `license_plate` inside the parent vehicle. The named step is NOT
|
|
25431
|
+
* inferred — these FRAME-space boxes are its output — and its
|
|
25432
|
+
* requested children (the plate reader) run on them. Absent ⇒ every
|
|
25433
|
+
* requested step infers as before.
|
|
25434
|
+
*/
|
|
25435
|
+
supplied: object({
|
|
25436
|
+
stepId: string(),
|
|
25437
|
+
modelId: string(),
|
|
25438
|
+
boxes: array(object({
|
|
25439
|
+
bbox: NativeCropBboxSchema,
|
|
25440
|
+
score: number()
|
|
25441
|
+
})).min(1)
|
|
25442
|
+
}).optional()
|
|
25051
25443
|
}), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
|
|
25052
25444
|
/** Catalog step id, e.g. `clip-embedding`. */
|
|
25053
25445
|
stepId: string(),
|
|
@@ -25110,14 +25502,6 @@ var CameraPipelineConfigSchema = object({
|
|
|
25110
25502
|
settings: record(string(), unknown()).readonly().optional()
|
|
25111
25503
|
}).nullable().optional()
|
|
25112
25504
|
});
|
|
25113
|
-
var PipelineTemplateSchema = object({
|
|
25114
|
-
id: string(),
|
|
25115
|
-
name: string(),
|
|
25116
|
-
description: string().optional(),
|
|
25117
|
-
config: CameraPipelineConfigSchema,
|
|
25118
|
-
createdAt: string(),
|
|
25119
|
-
updatedAt: string()
|
|
25120
|
-
});
|
|
25121
25505
|
var DeviceStepConfigSchema = object({
|
|
25122
25506
|
modelId: string().optional(),
|
|
25123
25507
|
settings: record(string(), unknown()).optional(),
|
|
@@ -25191,9 +25575,10 @@ var CameraStepOverridePatchSchema = object({
|
|
|
25191
25575
|
modelId: string().optional(),
|
|
25192
25576
|
settings: record(string(), unknown()).readonly().optional()
|
|
25193
25577
|
});
|
|
25578
|
+
var CameraStepSettingsSchema = record(string(), record(string(), unknown()).readonly());
|
|
25194
25579
|
var CameraPipelineSettingsSchema = object({
|
|
25195
|
-
pinnedAgentNodeId: string().optional(),
|
|
25196
25580
|
stepToggles: record(string(), boolean()).optional(),
|
|
25581
|
+
stepSettings: CameraStepSettingsSchema.optional(),
|
|
25197
25582
|
stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
|
|
25198
25583
|
pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
|
|
25199
25584
|
});
|
|
@@ -25226,7 +25611,10 @@ var PipelineAssignmentSchema = object({
|
|
|
25226
25611
|
});
|
|
25227
25612
|
/**
|
|
25228
25613
|
* Per-agent load summary surfaced to the load balancer + dashboards.
|
|
25229
|
-
* Aggregated from each runner's `getLocalLoad` cap call.
|
|
25614
|
+
* Aggregated from each runner's `getLocalLoad` cap call. In the
|
|
25615
|
+
* `getAgentLoad` report, a single-device node's default-pool sessions (no
|
|
25616
|
+
* `deviceKey`) are credited to its one eligible device in `load.devices` —
|
|
25617
|
+
* the default pool IS that device (D745); the balancer's census stays raw.
|
|
25230
25618
|
*/
|
|
25231
25619
|
var AgentLoadSummarySchema = object({
|
|
25232
25620
|
nodeId: string(),
|
|
@@ -25315,26 +25703,27 @@ var CameraBrokerStatusSchema = object({
|
|
|
25315
25703
|
width: number(),
|
|
25316
25704
|
height: number(),
|
|
25317
25705
|
subscribers: number(),
|
|
25318
|
-
|
|
25319
|
-
|
|
25706
|
+
/**
|
|
25707
|
+
* Encoded packets/s the broker receives from the camera. null when the
|
|
25708
|
+
* broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
|
|
25709
|
+
* There is no output rate: decoding runs in the session decode workers, not
|
|
25710
|
+
* in the broker, so the broker's own decoded-frame rate is 0 on every live
|
|
25711
|
+
* camera and is not served (D758).
|
|
25712
|
+
*/
|
|
25713
|
+
inFps: number().nullable()
|
|
25320
25714
|
})).readonly(),
|
|
25321
25715
|
webrtcSessions: number(),
|
|
25322
25716
|
rtspRestream: boolean()
|
|
25323
25717
|
});
|
|
25324
|
-
/**
|
|
25325
|
-
|
|
25326
|
-
|
|
25327
|
-
|
|
25328
|
-
|
|
25329
|
-
|
|
25330
|
-
|
|
25331
|
-
|
|
25332
|
-
var CameraDecoderStatusSchema = object({
|
|
25333
|
-
nodeId: string(),
|
|
25334
|
-
formats: array(string()).readonly(),
|
|
25335
|
-
sessionCount: number(),
|
|
25336
|
-
shm: CameraDecoderShmSchema
|
|
25337
|
-
});
|
|
25718
|
+
/**
|
|
25719
|
+
* Decoder block — WHERE decode runs (co-located with the detection node by
|
|
25720
|
+
* construction); null when the camera has no detection node. It carries no
|
|
25721
|
+
* frame counter: the shared-memory plane whose counters it used to serve is
|
|
25722
|
+
* gone, and those fields read 0 forever. Whether frames actually flow is read
|
|
25723
|
+
* from `detection.actualFps` (frames delivered to and processed by the
|
|
25724
|
+
* detector), never from a counter nothing feeds.
|
|
25725
|
+
*/
|
|
25726
|
+
var CameraDecoderStatusSchema = object({ nodeId: string() });
|
|
25338
25727
|
/** Motion block — null when motion detection is not active for this device. */
|
|
25339
25728
|
var CameraMotionStatusSchema = object({
|
|
25340
25729
|
enabled: boolean(),
|
|
@@ -25691,12 +26080,6 @@ method(object({
|
|
|
25691
26080
|
}), object({ success: literal(true) }), {
|
|
25692
26081
|
kind: "mutation",
|
|
25693
26082
|
auth: "admin"
|
|
25694
|
-
}), method(object({
|
|
25695
|
-
agentNodeId: string(),
|
|
25696
|
-
detectWeight: number().positive().nullable()
|
|
25697
|
-
}), object({ success: literal(true) }), {
|
|
25698
|
-
kind: "mutation",
|
|
25699
|
-
auth: "admin"
|
|
25700
26083
|
}), method(object({
|
|
25701
26084
|
agentNodeId: string(),
|
|
25702
26085
|
detect: boolean().nullable().optional(),
|
|
@@ -25738,6 +26121,15 @@ method(object({
|
|
|
25738
26121
|
}), {
|
|
25739
26122
|
kind: "mutation",
|
|
25740
26123
|
auth: "admin"
|
|
26124
|
+
}), method(AutoTuneOptionsSchema, AutoTunePlanSchema, { auth: "admin" }), method(AutoTuneApplyInputSchema, AutoTuneApplyResultSchema, {
|
|
26125
|
+
kind: "mutation",
|
|
26126
|
+
auth: "admin"
|
|
26127
|
+
}), method(LoadBalancingSharesInputSchema, object({ success: literal(true) }), {
|
|
26128
|
+
kind: "mutation",
|
|
26129
|
+
auth: "admin"
|
|
26130
|
+
}), method(PlacementStatsInputSchema, PlacementStatsSchema, { auth: "admin" }), method(SuggestSharesInputSchema, SuggestSharesResultSchema, { auth: "admin" }), method(_void(), EffectiveSharesSchema, { auth: "admin" }), method(SetShareSourceInputSchema, object({ success: literal(true) }), {
|
|
26131
|
+
kind: "mutation",
|
|
26132
|
+
auth: "admin"
|
|
25741
26133
|
}), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
|
|
25742
26134
|
deviceId: number(),
|
|
25743
26135
|
addonId: string(),
|
|
@@ -25754,6 +26146,13 @@ method(object({
|
|
|
25754
26146
|
}), object({ success: literal(true) }), {
|
|
25755
26147
|
kind: "mutation",
|
|
25756
26148
|
auth: "admin"
|
|
26149
|
+
}), method(object({
|
|
26150
|
+
deviceId: number(),
|
|
26151
|
+
addonId: string(),
|
|
26152
|
+
settings: record(string(), unknown()).nullable()
|
|
26153
|
+
}), object({ success: literal(true) }), {
|
|
26154
|
+
kind: "mutation",
|
|
26155
|
+
auth: "admin"
|
|
25757
26156
|
}), method(object({
|
|
25758
26157
|
deviceId: number(),
|
|
25759
26158
|
agentNodeId: string(),
|
|
@@ -25777,25 +26176,7 @@ method(object({
|
|
|
25777
26176
|
}), method(_void(), DiskReconcileJobSchema, {
|
|
25778
26177
|
kind: "mutation",
|
|
25779
26178
|
auth: "admin"
|
|
25780
|
-
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" })
|
|
25781
|
-
name: string(),
|
|
25782
|
-
description: string().optional(),
|
|
25783
|
-
config: CameraPipelineConfigSchema
|
|
25784
|
-
}), PipelineTemplateSchema, {
|
|
25785
|
-
kind: "mutation",
|
|
25786
|
-
auth: "admin"
|
|
25787
|
-
}), method(object({
|
|
25788
|
-
id: string(),
|
|
25789
|
-
name: string().optional(),
|
|
25790
|
-
description: string().optional(),
|
|
25791
|
-
config: CameraPipelineConfigSchema.optional()
|
|
25792
|
-
}), PipelineTemplateSchema, {
|
|
25793
|
-
kind: "mutation",
|
|
25794
|
-
auth: "admin"
|
|
25795
|
-
}), method(object({ id: string() }), object({ success: literal(true) }), {
|
|
25796
|
-
kind: "mutation",
|
|
25797
|
-
auth: "admin"
|
|
25798
|
-
});
|
|
26179
|
+
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" });
|
|
25799
26180
|
/**
|
|
25800
26181
|
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
25801
26182
|
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
@@ -28044,8 +28425,6 @@ var WebrtcStreamChoiceSchema = object({
|
|
|
28044
28425
|
]).nullable(),
|
|
28045
28426
|
/** Input FPS from the camera (null for adaptive). */
|
|
28046
28427
|
inputFps: number().nullable(),
|
|
28047
|
-
/** Decoded FPS (null for adaptive). */
|
|
28048
|
-
decodeFps: number().nullable(),
|
|
28049
28428
|
/** Bitrate in kbps (null for adaptive). */
|
|
28050
28429
|
bitrateKbps: number().nullable()
|
|
28051
28430
|
});
|
|
@@ -28377,6 +28756,14 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
|
|
|
28377
28756
|
*/
|
|
28378
28757
|
alive: boolean()
|
|
28379
28758
|
})), method(object({
|
|
28759
|
+
deviceId: number().int().nonnegative(),
|
|
28760
|
+
sessionId: string(),
|
|
28761
|
+
downlinkMbps: number().nonnegative()
|
|
28762
|
+
}), object({
|
|
28763
|
+
outcome: _enum(["switching", "held"]),
|
|
28764
|
+
tier: CamProfileSchema.nullable(),
|
|
28765
|
+
reason: string()
|
|
28766
|
+
}), { kind: "mutation" }), method(object({
|
|
28380
28767
|
deviceId: number().int().nonnegative(),
|
|
28381
28768
|
sessionId: string()
|
|
28382
28769
|
}), WebrtcSessionDebugSchema, { kind: "query" });
|
|
@@ -32150,7 +32537,7 @@ var LocalInterfaceSchema = object({
|
|
|
32150
32537
|
name: string(),
|
|
32151
32538
|
family: _enum(["IPv4", "IPv6"]),
|
|
32152
32539
|
address: string(),
|
|
32153
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
32540
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
32154
32541
|
cidr: string(),
|
|
32155
32542
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
32156
32543
|
netmask: string(),
|
|
@@ -32204,7 +32591,9 @@ var ConnectionEndpointSchema = object({
|
|
|
32204
32591
|
"lan-ipv4",
|
|
32205
32592
|
"lan-ipv6",
|
|
32206
32593
|
"public",
|
|
32207
|
-
"loopback"
|
|
32594
|
+
"loopback",
|
|
32595
|
+
"app-link",
|
|
32596
|
+
"custom"
|
|
32208
32597
|
]),
|
|
32209
32598
|
/**
|
|
32210
32599
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -32273,15 +32662,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
32273
32662
|
localPort: AdvertisedLocalPortSchema
|
|
32274
32663
|
});
|
|
32275
32664
|
/**
|
|
32276
|
-
* The
|
|
32277
|
-
*
|
|
32278
|
-
*
|
|
32665
|
+
* The address flagged for notification taps (`notificationTaps`). `baseUrl: null` = AUTO, which
|
|
32666
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
32667
|
+
* so the UI can show it either way.
|
|
32279
32668
|
*/
|
|
32280
32669
|
var NotificationEndpointSchema = object({
|
|
32281
32670
|
/** The operator's explicit choice, or null for AUTO. */
|
|
32282
32671
|
baseUrl: string().nullable(),
|
|
32283
|
-
/**
|
|
32284
|
-
|
|
32672
|
+
/**
|
|
32673
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
32674
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
32675
|
+
* answered the public tunnel / mesh here, or null.
|
|
32676
|
+
*/
|
|
32677
|
+
resolved: string().nullable(),
|
|
32678
|
+
/**
|
|
32679
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
32680
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
32681
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
32682
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
32683
|
+
* Absent on a pre-D709 hub.
|
|
32684
|
+
*/
|
|
32685
|
+
appLinkHub: string().nullable()
|
|
32285
32686
|
});
|
|
32286
32687
|
/**
|
|
32287
32688
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -32294,6 +32695,72 @@ var ViewerEndpointsSchema = object({
|
|
|
32294
32695
|
/** What the ranking currently resolves to (may be empty if nothing is up). */
|
|
32295
32696
|
resolved: array(string()).readonly()
|
|
32296
32697
|
});
|
|
32698
|
+
/**
|
|
32699
|
+
* DEPRECATED compatibility shape of `getHubAddresses` (D729 amendment, kept
|
|
32700
|
+
* for addons built against it): `cluster` is the `internal` role, `browser`
|
|
32701
|
+
* the `publicEndpoint` role; `override` is the flagged address.
|
|
32702
|
+
*/
|
|
32703
|
+
var HubAddressSnapshotSchema = object({
|
|
32704
|
+
override: string().nullable(),
|
|
32705
|
+
resolved: string().nullable(),
|
|
32706
|
+
source: _enum([
|
|
32707
|
+
"override",
|
|
32708
|
+
"auto",
|
|
32709
|
+
"none"
|
|
32710
|
+
])
|
|
32711
|
+
});
|
|
32712
|
+
var HubAddressesSchema = object({
|
|
32713
|
+
cluster: HubAddressSnapshotSchema,
|
|
32714
|
+
browser: HubAddressSnapshotSchema
|
|
32715
|
+
});
|
|
32716
|
+
/**
|
|
32717
|
+
* What an address is used for (`hub-address.ts`, D734). `appConnections` is
|
|
32718
|
+
* many-valued; `notificationTaps`, `publicEndpoint` and `internal` are carried
|
|
32719
|
+
* by at most one address.
|
|
32720
|
+
*/
|
|
32721
|
+
var HubAddressRoleSchema = _enum(HUB_ADDRESS_ROLES);
|
|
32722
|
+
var RoleSourceSchema = _enum([
|
|
32723
|
+
"flagged",
|
|
32724
|
+
"auto",
|
|
32725
|
+
"none"
|
|
32726
|
+
]);
|
|
32727
|
+
/** One single-valued role: the flagged address, the one in use, and why. */
|
|
32728
|
+
var HubAddressRoleResolutionSchema = object({
|
|
32729
|
+
/** The address carrying the flag, or null = automatic. */
|
|
32730
|
+
flagged: string().nullable(),
|
|
32731
|
+
/** The address in use, or null when nothing qualifies (never loopback). */
|
|
32732
|
+
resolved: string().nullable(),
|
|
32733
|
+
source: RoleSourceSchema
|
|
32734
|
+
});
|
|
32735
|
+
var HubAppConnectionsResolutionSchema = object({
|
|
32736
|
+
/** The addresses flagged `appConnections`, or empty = automatic. */
|
|
32737
|
+
flagged: array(string()).readonly(),
|
|
32738
|
+
/** What the apps race right now. */
|
|
32739
|
+
resolved: array(string()).readonly(),
|
|
32740
|
+
source: RoleSourceSchema
|
|
32741
|
+
});
|
|
32742
|
+
var HubAddressBookSchema = object({
|
|
32743
|
+
rows: array(ConnectionEndpointSchema.extend({
|
|
32744
|
+
/** In the hub's detected palette right now. */
|
|
32745
|
+
detected: boolean(),
|
|
32746
|
+
/** Entered by the operator (removable). */
|
|
32747
|
+
custom: boolean(),
|
|
32748
|
+
/** The roles explicitly flagged on this address. */
|
|
32749
|
+
flags: array(HubAddressRoleSchema).readonly(),
|
|
32750
|
+
/** The roles this address serves right now — flagged or automatic. */
|
|
32751
|
+
inUse: array(HubAddressRoleSchema).readonly(),
|
|
32752
|
+
/** The roles this address may be flagged with. */
|
|
32753
|
+
eligible: array(HubAddressRoleSchema).readonly()
|
|
32754
|
+
})).readonly(),
|
|
32755
|
+
roles: object({
|
|
32756
|
+
appConnections: HubAppConnectionsResolutionSchema,
|
|
32757
|
+
notificationTaps: HubAddressRoleResolutionSchema,
|
|
32758
|
+
internal: HubAddressRoleResolutionSchema,
|
|
32759
|
+
publicEndpoint: HubAddressRoleResolutionSchema
|
|
32760
|
+
}),
|
|
32761
|
+
/** The `hub=` an app link carries (D709), or null. */
|
|
32762
|
+
appLinkHub: string().nullable()
|
|
32763
|
+
});
|
|
32297
32764
|
var AllowedAddressesSchema = object({
|
|
32298
32765
|
/**
|
|
32299
32766
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -32335,8 +32802,29 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
32335
32802
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
32336
32803
|
* to avoid mixed-content blocks in the browser. The public
|
|
32337
32804
|
* tunnel always emits `https://` regardless. */
|
|
32338
|
-
scheme: _enum(["http", "https"]).optional()
|
|
32339
|
-
|
|
32805
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
32806
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
32807
|
+
* an address notification taps can be flagged with, not a hub
|
|
32808
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
32809
|
+
includeAppLink: boolean().optional()
|
|
32810
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(object({ scheme: _enum(["http", "https"]).optional() }).optional(), HubAddressBookSchema), method(object({
|
|
32811
|
+
baseUrl: string(),
|
|
32812
|
+
label: string().max(80)
|
|
32813
|
+
}), HubAddressBookSchema, {
|
|
32814
|
+
kind: "mutation",
|
|
32815
|
+
auth: "admin"
|
|
32816
|
+
}), method(object({ baseUrl: string() }), HubAddressBookSchema, {
|
|
32817
|
+
kind: "mutation",
|
|
32818
|
+
auth: "admin"
|
|
32819
|
+
}), method(object({
|
|
32820
|
+
role: HubAddressRoleSchema,
|
|
32821
|
+
baseUrl: string().nullable(),
|
|
32822
|
+
enabled: boolean(),
|
|
32823
|
+
acceptInsecureHttp: boolean().optional()
|
|
32824
|
+
}), HubAddressBookSchema, {
|
|
32825
|
+
kind: "mutation",
|
|
32826
|
+
auth: "admin"
|
|
32827
|
+
}), method(_void(), HubAddressesSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
32340
32828
|
kind: "mutation",
|
|
32341
32829
|
auth: "admin"
|
|
32342
32830
|
}), method(object({
|
|
@@ -32664,7 +33152,7 @@ var MeshPeerSchema = object({
|
|
|
32664
33152
|
tags: array(string()).readonly(),
|
|
32665
33153
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
32666
33154
|
exitNodeOption: boolean(),
|
|
32667
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
33155
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
32668
33156
|
advertisedRoutes: array(string()).readonly(),
|
|
32669
33157
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
32670
33158
|
userLogin: string().nullable(),
|
|
@@ -32794,7 +33282,8 @@ var MotionStatusSchema = object({
|
|
|
32794
33282
|
* writes this slice (not even a boot seed), and neither does the runner's
|
|
32795
33283
|
* phase machine: its phase is "a session is attached" for every on-motion
|
|
32796
33284
|
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
32797
|
-
* A provider's `isDetected`
|
|
33285
|
+
* A provider's `isDetected` and `getStatus` answer from the hub's slice
|
|
33286
|
+
* (`hubMotionNativeProvider`).
|
|
32798
33287
|
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
32799
33288
|
* imports) — the provider pushes both edges itself, from the upstream
|
|
32800
33289
|
* system's own state change. That is the sensor's own fact.
|
|
@@ -33992,7 +34481,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
33992
34481
|
*/
|
|
33993
34482
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
33994
34483
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
33995
|
-
readOnly: boolean().optional()
|
|
34484
|
+
readOnly: boolean().optional(),
|
|
34485
|
+
/**
|
|
34486
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
34487
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
34488
|
+
* copy on the binding.
|
|
34489
|
+
*/
|
|
34490
|
+
maxCharacters: number().int().positive().optional()
|
|
33996
34491
|
})).readonly() });
|
|
33997
34492
|
var OsdOverlayPatchSchema = object({
|
|
33998
34493
|
enabled: boolean().optional(),
|
|
@@ -34043,7 +34538,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
34043
34538
|
valuePath: string().min(1).max(64),
|
|
34044
34539
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
34045
34540
|
displayUnit: string().max(16).optional(),
|
|
34046
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
34541
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34542
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
34543
|
+
valueMap: record(string(), string()).optional()
|
|
34047
34544
|
});
|
|
34048
34545
|
/**
|
|
34049
34546
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -34093,18 +34590,11 @@ var OsdSlotBindingSchema = object({
|
|
|
34093
34590
|
source: OsdSourceSchema,
|
|
34094
34591
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
34095
34592
|
template: string().max(96).default("${value}"),
|
|
34096
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
34097
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
34098
34593
|
/**
|
|
34099
34594
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
34100
34595
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
34101
34596
|
*/
|
|
34102
34597
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34103
|
-
/**
|
|
34104
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
34105
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
34106
|
-
*/
|
|
34107
|
-
unitLabel: string().max(8).optional(),
|
|
34108
34598
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
34109
34599
|
valueMap: record(string(), string()).optional(),
|
|
34110
34600
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -34113,9 +34603,7 @@ var OsdSlotBindingSchema = object({
|
|
|
34113
34603
|
* Display gate, in the notification centre's condition vocabulary.
|
|
34114
34604
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
34115
34605
|
*/
|
|
34116
|
-
conditions: NcConditionsSchema.optional()
|
|
34117
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
34118
|
-
fallbackText: string().max(64).default("")
|
|
34606
|
+
conditions: NcConditionsSchema.optional()
|
|
34119
34607
|
});
|
|
34120
34608
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
34121
34609
|
var OsdSlotViewSchema = object({
|
|
@@ -39342,6 +39830,16 @@ var zoneRulesCapability = {
|
|
|
39342
39830
|
durability: "restored"
|
|
39343
39831
|
};
|
|
39344
39832
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
39833
|
+
Object.freeze({
|
|
39834
|
+
person: .5,
|
|
39835
|
+
vehicle: .5,
|
|
39836
|
+
animal: .5
|
|
39837
|
+
});
|
|
39838
|
+
Object.freeze({
|
|
39839
|
+
person: .65,
|
|
39840
|
+
vehicle: .65,
|
|
39841
|
+
animal: .65
|
|
39842
|
+
});
|
|
39345
39843
|
/**
|
|
39346
39844
|
* Accessory device helpers — shared across drivers.
|
|
39347
39845
|
*
|
|
@@ -42222,90 +42720,18 @@ Object.freeze({
|
|
|
42222
42720
|
addonId: null,
|
|
42223
42721
|
access: "create"
|
|
42224
42722
|
},
|
|
42225
|
-
"decoder.createSession": {
|
|
42226
|
-
capName: "decoder",
|
|
42227
|
-
capScope: "system",
|
|
42228
|
-
addonId: null,
|
|
42229
|
-
access: "view"
|
|
42230
|
-
},
|
|
42231
|
-
"decoder.destroySession": {
|
|
42232
|
-
capName: "decoder",
|
|
42233
|
-
capScope: "system",
|
|
42234
|
-
addonId: null,
|
|
42235
|
-
access: "delete"
|
|
42236
|
-
},
|
|
42237
|
-
"decoder.getFrame": {
|
|
42238
|
-
capName: "decoder",
|
|
42239
|
-
capScope: "system",
|
|
42240
|
-
addonId: null,
|
|
42241
|
-
access: "view"
|
|
42242
|
-
},
|
|
42243
42723
|
"decoder.getInfo": {
|
|
42244
42724
|
capName: "decoder",
|
|
42245
42725
|
capScope: "system",
|
|
42246
42726
|
addonId: null,
|
|
42247
42727
|
access: "view"
|
|
42248
42728
|
},
|
|
42249
|
-
"decoder.getShmStats": {
|
|
42250
|
-
capName: "decoder",
|
|
42251
|
-
capScope: "system",
|
|
42252
|
-
addonId: null,
|
|
42253
|
-
access: "view"
|
|
42254
|
-
},
|
|
42255
|
-
"decoder.getStats": {
|
|
42256
|
-
capName: "decoder",
|
|
42257
|
-
capScope: "system",
|
|
42258
|
-
addonId: null,
|
|
42259
|
-
access: "view"
|
|
42260
|
-
},
|
|
42261
|
-
"decoder.listActiveSessions": {
|
|
42262
|
-
capName: "decoder",
|
|
42263
|
-
capScope: "system",
|
|
42264
|
-
addonId: null,
|
|
42265
|
-
access: "view"
|
|
42266
|
-
},
|
|
42267
|
-
"decoder.openStream": {
|
|
42268
|
-
capName: "decoder",
|
|
42269
|
-
capScope: "system",
|
|
42270
|
-
addonId: null,
|
|
42271
|
-
access: "view"
|
|
42272
|
-
},
|
|
42273
|
-
"decoder.pullFrames": {
|
|
42274
|
-
capName: "decoder",
|
|
42275
|
-
capScope: "system",
|
|
42276
|
-
addonId: null,
|
|
42277
|
-
access: "view"
|
|
42278
|
-
},
|
|
42279
|
-
"decoder.pullHandles": {
|
|
42280
|
-
capName: "decoder",
|
|
42281
|
-
capScope: "system",
|
|
42282
|
-
addonId: null,
|
|
42283
|
-
access: "view"
|
|
42284
|
-
},
|
|
42285
|
-
"decoder.pushPacket": {
|
|
42286
|
-
capName: "decoder",
|
|
42287
|
-
capScope: "system",
|
|
42288
|
-
addonId: null,
|
|
42289
|
-
access: "view"
|
|
42290
|
-
},
|
|
42291
42729
|
"decoder.reprobeHwaccel": {
|
|
42292
42730
|
capName: "decoder",
|
|
42293
42731
|
capScope: "system",
|
|
42294
42732
|
addonId: null,
|
|
42295
42733
|
access: "create"
|
|
42296
42734
|
},
|
|
42297
|
-
"decoder.supportsCodec": {
|
|
42298
|
-
capName: "decoder",
|
|
42299
|
-
capScope: "system",
|
|
42300
|
-
addonId: null,
|
|
42301
|
-
access: "view"
|
|
42302
|
-
},
|
|
42303
|
-
"decoder.updateConfig": {
|
|
42304
|
-
capName: "decoder",
|
|
42305
|
-
capScope: "system",
|
|
42306
|
-
addonId: null,
|
|
42307
|
-
access: "view"
|
|
42308
|
-
},
|
|
42309
42735
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
42310
42736
|
capName: "detection-pipeline",
|
|
42311
42737
|
capScope: "device",
|
|
@@ -43794,12 +44220,24 @@ Object.freeze({
|
|
|
43794
44220
|
addonId: null,
|
|
43795
44221
|
access: "view"
|
|
43796
44222
|
},
|
|
44223
|
+
"localNetwork.addCustomAddress": {
|
|
44224
|
+
capName: "local-network",
|
|
44225
|
+
capScope: "system",
|
|
44226
|
+
addonId: null,
|
|
44227
|
+
access: "create"
|
|
44228
|
+
},
|
|
43797
44229
|
"localNetwork.downloadCa": {
|
|
43798
44230
|
capName: "local-network",
|
|
43799
44231
|
capScope: "system",
|
|
43800
44232
|
addonId: null,
|
|
43801
44233
|
access: "view"
|
|
43802
44234
|
},
|
|
44235
|
+
"localNetwork.getAddresses": {
|
|
44236
|
+
capName: "local-network",
|
|
44237
|
+
capScope: "system",
|
|
44238
|
+
addonId: null,
|
|
44239
|
+
access: "view"
|
|
44240
|
+
},
|
|
43803
44241
|
"localNetwork.getAllowedAddresses": {
|
|
43804
44242
|
capName: "local-network",
|
|
43805
44243
|
capScope: "system",
|
|
@@ -43812,6 +44250,12 @@ Object.freeze({
|
|
|
43812
44250
|
addonId: null,
|
|
43813
44251
|
access: "view"
|
|
43814
44252
|
},
|
|
44253
|
+
"localNetwork.getHubAddresses": {
|
|
44254
|
+
capName: "local-network",
|
|
44255
|
+
capScope: "system",
|
|
44256
|
+
addonId: null,
|
|
44257
|
+
access: "view"
|
|
44258
|
+
},
|
|
43815
44259
|
"localNetwork.getNotificationEndpoint": {
|
|
43816
44260
|
capName: "local-network",
|
|
43817
44261
|
capScope: "system",
|
|
@@ -43848,6 +44292,12 @@ Object.freeze({
|
|
|
43848
44292
|
addonId: null,
|
|
43849
44293
|
access: "create"
|
|
43850
44294
|
},
|
|
44295
|
+
"localNetwork.removeCustomAddress": {
|
|
44296
|
+
capName: "local-network",
|
|
44297
|
+
capScope: "system",
|
|
44298
|
+
addonId: null,
|
|
44299
|
+
access: "delete"
|
|
44300
|
+
},
|
|
43851
44301
|
"localNetwork.resetAllowlistToBestMatch": {
|
|
43852
44302
|
capName: "local-network",
|
|
43853
44303
|
capScope: "system",
|
|
@@ -43860,6 +44310,12 @@ Object.freeze({
|
|
|
43860
44310
|
addonId: null,
|
|
43861
44311
|
access: "create"
|
|
43862
44312
|
},
|
|
44313
|
+
"localNetwork.setAddressRole": {
|
|
44314
|
+
capName: "local-network",
|
|
44315
|
+
capScope: "system",
|
|
44316
|
+
addonId: null,
|
|
44317
|
+
access: "create"
|
|
44318
|
+
},
|
|
43863
44319
|
"localNetwork.setAllowedAddresses": {
|
|
43864
44320
|
capName: "local-network",
|
|
43865
44321
|
capScope: "system",
|
|
@@ -45354,13 +45810,13 @@ Object.freeze({
|
|
|
45354
45810
|
addonId: null,
|
|
45355
45811
|
access: "delete"
|
|
45356
45812
|
},
|
|
45357
|
-
"pipelineExecutor.
|
|
45813
|
+
"pipelineExecutor.clearModelBoundDeviceOverrides": {
|
|
45358
45814
|
capName: "pipeline-executor",
|
|
45359
45815
|
capScope: "system",
|
|
45360
45816
|
addonId: null,
|
|
45361
45817
|
access: "delete"
|
|
45362
45818
|
},
|
|
45363
|
-
"pipelineExecutor.
|
|
45819
|
+
"pipelineExecutor.deleteModel": {
|
|
45364
45820
|
capName: "pipeline-executor",
|
|
45365
45821
|
capScope: "system",
|
|
45366
45822
|
addonId: null,
|
|
@@ -45504,12 +45960,6 @@ Object.freeze({
|
|
|
45504
45960
|
addonId: null,
|
|
45505
45961
|
access: "view"
|
|
45506
45962
|
},
|
|
45507
|
-
"pipelineExecutor.listTemplates": {
|
|
45508
|
-
capName: "pipeline-executor",
|
|
45509
|
-
capScope: "system",
|
|
45510
|
-
addonId: null,
|
|
45511
|
-
access: "view"
|
|
45512
|
-
},
|
|
45513
45963
|
"pipelineExecutor.rearmInferenceDevice": {
|
|
45514
45964
|
capName: "pipeline-executor",
|
|
45515
45965
|
capScope: "system",
|
|
@@ -45534,12 +45984,6 @@ Object.freeze({
|
|
|
45534
45984
|
addonId: null,
|
|
45535
45985
|
access: "create"
|
|
45536
45986
|
},
|
|
45537
|
-
"pipelineExecutor.saveTemplate": {
|
|
45538
|
-
capName: "pipeline-executor",
|
|
45539
|
-
capScope: "system",
|
|
45540
|
-
addonId: null,
|
|
45541
|
-
access: "create"
|
|
45542
|
-
},
|
|
45543
45987
|
"pipelineExecutor.setVideoPipelineSteps": {
|
|
45544
45988
|
capName: "pipeline-executor",
|
|
45545
45989
|
capScope: "system",
|
|
@@ -45558,41 +46002,35 @@ Object.freeze({
|
|
|
45558
46002
|
addonId: null,
|
|
45559
46003
|
access: "create"
|
|
45560
46004
|
},
|
|
45561
|
-
"pipelineExecutor.updateTemplate": {
|
|
45562
|
-
capName: "pipeline-executor",
|
|
45563
|
-
capScope: "system",
|
|
45564
|
-
addonId: null,
|
|
45565
|
-
access: "create"
|
|
45566
|
-
},
|
|
45567
46005
|
"pipelineExecutor.validatePipeline": {
|
|
45568
46006
|
capName: "pipeline-executor",
|
|
45569
46007
|
capScope: "system",
|
|
45570
46008
|
addonId: null,
|
|
45571
46009
|
access: "view"
|
|
45572
46010
|
},
|
|
45573
|
-
"pipelineOrchestrator.
|
|
46011
|
+
"pipelineOrchestrator.applyAutoTune": {
|
|
45574
46012
|
capName: "pipeline-orchestrator",
|
|
45575
46013
|
capScope: "system",
|
|
45576
46014
|
addonId: null,
|
|
45577
46015
|
access: "create"
|
|
45578
46016
|
},
|
|
45579
|
-
"pipelineOrchestrator.
|
|
46017
|
+
"pipelineOrchestrator.applyDeviceSettingsPatch": {
|
|
45580
46018
|
capName: "pipeline-orchestrator",
|
|
45581
46019
|
capScope: "system",
|
|
45582
46020
|
addonId: null,
|
|
45583
46021
|
access: "create"
|
|
45584
46022
|
},
|
|
45585
|
-
"pipelineOrchestrator.
|
|
46023
|
+
"pipelineOrchestrator.assignAudio": {
|
|
45586
46024
|
capName: "pipeline-orchestrator",
|
|
45587
46025
|
capScope: "system",
|
|
45588
46026
|
addonId: null,
|
|
45589
46027
|
access: "create"
|
|
45590
46028
|
},
|
|
45591
|
-
"pipelineOrchestrator.
|
|
46029
|
+
"pipelineOrchestrator.assignPipeline": {
|
|
45592
46030
|
capName: "pipeline-orchestrator",
|
|
45593
46031
|
capScope: "system",
|
|
45594
46032
|
addonId: null,
|
|
45595
|
-
access: "
|
|
46033
|
+
access: "create"
|
|
45596
46034
|
},
|
|
45597
46035
|
"pipelineOrchestrator.getAgentLoad": {
|
|
45598
46036
|
capName: "pipeline-orchestrator",
|
|
@@ -45684,6 +46122,12 @@ Object.freeze({
|
|
|
45684
46122
|
addonId: null,
|
|
45685
46123
|
access: "view"
|
|
45686
46124
|
},
|
|
46125
|
+
"pipelineOrchestrator.getEffectiveShares": {
|
|
46126
|
+
capName: "pipeline-orchestrator",
|
|
46127
|
+
capScope: "system",
|
|
46128
|
+
addonId: null,
|
|
46129
|
+
access: "view"
|
|
46130
|
+
},
|
|
45687
46131
|
"pipelineOrchestrator.getGlobalMetrics": {
|
|
45688
46132
|
capName: "pipeline-orchestrator",
|
|
45689
46133
|
capScope: "system",
|
|
@@ -45720,19 +46164,19 @@ Object.freeze({
|
|
|
45720
46164
|
addonId: null,
|
|
45721
46165
|
access: "view"
|
|
45722
46166
|
},
|
|
45723
|
-
"pipelineOrchestrator.
|
|
46167
|
+
"pipelineOrchestrator.getPlacementStats": {
|
|
45724
46168
|
capName: "pipeline-orchestrator",
|
|
45725
46169
|
capScope: "system",
|
|
45726
46170
|
addonId: null,
|
|
45727
46171
|
access: "view"
|
|
45728
46172
|
},
|
|
45729
|
-
"pipelineOrchestrator.
|
|
46173
|
+
"pipelineOrchestrator.getReconcileFromDiskStatus": {
|
|
45730
46174
|
capName: "pipeline-orchestrator",
|
|
45731
46175
|
capScope: "system",
|
|
45732
46176
|
addonId: null,
|
|
45733
46177
|
access: "view"
|
|
45734
46178
|
},
|
|
45735
|
-
"pipelineOrchestrator.
|
|
46179
|
+
"pipelineOrchestrator.listAgentSettings": {
|
|
45736
46180
|
capName: "pipeline-orchestrator",
|
|
45737
46181
|
capScope: "system",
|
|
45738
46182
|
addonId: null,
|
|
@@ -45744,6 +46188,12 @@ Object.freeze({
|
|
|
45744
46188
|
addonId: null,
|
|
45745
46189
|
access: "create"
|
|
45746
46190
|
},
|
|
46191
|
+
"pipelineOrchestrator.planAutoTune": {
|
|
46192
|
+
capName: "pipeline-orchestrator",
|
|
46193
|
+
capScope: "system",
|
|
46194
|
+
addonId: null,
|
|
46195
|
+
access: "view"
|
|
46196
|
+
},
|
|
45747
46197
|
"pipelineOrchestrator.rebalance": {
|
|
45748
46198
|
capName: "pipeline-orchestrator",
|
|
45749
46199
|
capScope: "system",
|
|
@@ -45786,12 +46236,6 @@ Object.freeze({
|
|
|
45786
46236
|
addonId: null,
|
|
45787
46237
|
access: "create"
|
|
45788
46238
|
},
|
|
45789
|
-
"pipelineOrchestrator.saveTemplate": {
|
|
45790
|
-
capName: "pipeline-orchestrator",
|
|
45791
|
-
capScope: "system",
|
|
45792
|
-
addonId: null,
|
|
45793
|
-
access: "create"
|
|
45794
|
-
},
|
|
45795
46239
|
"pipelineOrchestrator.setAgentCapabilities": {
|
|
45796
46240
|
capName: "pipeline-orchestrator",
|
|
45797
46241
|
capScope: "system",
|
|
@@ -45804,12 +46248,6 @@ Object.freeze({
|
|
|
45804
46248
|
addonId: null,
|
|
45805
46249
|
access: "create"
|
|
45806
46250
|
},
|
|
45807
|
-
"pipelineOrchestrator.setAgentDetectWeight": {
|
|
45808
|
-
capName: "pipeline-orchestrator",
|
|
45809
|
-
capScope: "system",
|
|
45810
|
-
addonId: null,
|
|
45811
|
-
access: "create"
|
|
45812
|
-
},
|
|
45813
46251
|
"pipelineOrchestrator.setAgentInferenceDevices": {
|
|
45814
46252
|
capName: "pipeline-orchestrator",
|
|
45815
46253
|
capScope: "system",
|
|
@@ -45846,6 +46284,12 @@ Object.freeze({
|
|
|
45846
46284
|
addonId: null,
|
|
45847
46285
|
access: "create"
|
|
45848
46286
|
},
|
|
46287
|
+
"pipelineOrchestrator.setCameraStepSettings": {
|
|
46288
|
+
capName: "pipeline-orchestrator",
|
|
46289
|
+
capScope: "system",
|
|
46290
|
+
addonId: null,
|
|
46291
|
+
access: "create"
|
|
46292
|
+
},
|
|
45849
46293
|
"pipelineOrchestrator.setCameraStepToggle": {
|
|
45850
46294
|
capName: "pipeline-orchestrator",
|
|
45851
46295
|
capScope: "system",
|
|
@@ -45864,25 +46308,37 @@ Object.freeze({
|
|
|
45864
46308
|
addonId: null,
|
|
45865
46309
|
access: "create"
|
|
45866
46310
|
},
|
|
46311
|
+
"pipelineOrchestrator.setLoadBalancingShares": {
|
|
46312
|
+
capName: "pipeline-orchestrator",
|
|
46313
|
+
capScope: "system",
|
|
46314
|
+
addonId: null,
|
|
46315
|
+
access: "create"
|
|
46316
|
+
},
|
|
45867
46317
|
"pipelineOrchestrator.setPipelineDevicePin": {
|
|
45868
46318
|
capName: "pipeline-orchestrator",
|
|
45869
46319
|
capScope: "system",
|
|
45870
46320
|
addonId: null,
|
|
45871
46321
|
access: "create"
|
|
45872
46322
|
},
|
|
45873
|
-
"pipelineOrchestrator.
|
|
46323
|
+
"pipelineOrchestrator.setShareSource": {
|
|
45874
46324
|
capName: "pipeline-orchestrator",
|
|
45875
46325
|
capScope: "system",
|
|
45876
46326
|
addonId: null,
|
|
45877
46327
|
access: "create"
|
|
45878
46328
|
},
|
|
45879
|
-
"pipelineOrchestrator.
|
|
46329
|
+
"pipelineOrchestrator.suggestShares": {
|
|
46330
|
+
capName: "pipeline-orchestrator",
|
|
46331
|
+
capScope: "system",
|
|
46332
|
+
addonId: null,
|
|
46333
|
+
access: "view"
|
|
46334
|
+
},
|
|
46335
|
+
"pipelineOrchestrator.unassignAudio": {
|
|
45880
46336
|
capName: "pipeline-orchestrator",
|
|
45881
46337
|
capScope: "system",
|
|
45882
46338
|
addonId: null,
|
|
45883
46339
|
access: "create"
|
|
45884
46340
|
},
|
|
45885
|
-
"pipelineOrchestrator.
|
|
46341
|
+
"pipelineOrchestrator.unassignPipeline": {
|
|
45886
46342
|
capName: "pipeline-orchestrator",
|
|
45887
46343
|
capScope: "system",
|
|
45888
46344
|
addonId: null,
|
|
@@ -47322,12 +47778,6 @@ Object.freeze({
|
|
|
47322
47778
|
addonId: null,
|
|
47323
47779
|
access: "view"
|
|
47324
47780
|
},
|
|
47325
|
-
"streamBroker.pullFrameHandles": {
|
|
47326
|
-
capName: "stream-broker",
|
|
47327
|
-
capScope: "system",
|
|
47328
|
-
addonId: null,
|
|
47329
|
-
access: "view"
|
|
47330
|
-
},
|
|
47331
47781
|
"streamBroker.regenerateRtspToken": {
|
|
47332
47782
|
capName: "stream-broker",
|
|
47333
47783
|
capScope: "system",
|
|
@@ -47394,12 +47844,6 @@ Object.freeze({
|
|
|
47394
47844
|
addonId: null,
|
|
47395
47845
|
access: "create"
|
|
47396
47846
|
},
|
|
47397
|
-
"streamBroker.subscribeFrames": {
|
|
47398
|
-
capName: "stream-broker",
|
|
47399
|
-
capScope: "system",
|
|
47400
|
-
addonId: null,
|
|
47401
|
-
access: "create"
|
|
47402
|
-
},
|
|
47403
47847
|
"streamBroker.unassignProfile": {
|
|
47404
47848
|
capName: "stream-broker",
|
|
47405
47849
|
capScope: "system",
|
|
@@ -47412,12 +47856,6 @@ Object.freeze({
|
|
|
47412
47856
|
addonId: null,
|
|
47413
47857
|
access: "create"
|
|
47414
47858
|
},
|
|
47415
|
-
"streamBroker.unsubscribeFrames": {
|
|
47416
|
-
capName: "stream-broker",
|
|
47417
|
-
capScope: "system",
|
|
47418
|
-
addonId: null,
|
|
47419
|
-
access: "create"
|
|
47420
|
-
},
|
|
47421
47859
|
"streamCatalog.getCatalog": {
|
|
47422
47860
|
capName: "stream-catalog",
|
|
47423
47861
|
capScope: "device",
|
|
@@ -48114,6 +48552,12 @@ Object.freeze({
|
|
|
48114
48552
|
addonId: null,
|
|
48115
48553
|
access: "create"
|
|
48116
48554
|
},
|
|
48555
|
+
"webrtcSession.applyDownlinkProbe": {
|
|
48556
|
+
capName: "webrtc-session",
|
|
48557
|
+
capScope: "device",
|
|
48558
|
+
addonId: null,
|
|
48559
|
+
access: "create"
|
|
48560
|
+
},
|
|
48117
48561
|
"webrtcSession.closeSession": {
|
|
48118
48562
|
capName: "webrtc-session",
|
|
48119
48563
|
capScope: "device",
|
|
@@ -49925,11 +50369,6 @@ Object.freeze({
|
|
|
49925
50369
|
form: "single",
|
|
49926
50370
|
optional: false
|
|
49927
50371
|
}],
|
|
49928
|
-
"decoder.createSession": [{
|
|
49929
|
-
name: "deviceId",
|
|
49930
|
-
form: "single",
|
|
49931
|
-
optional: true
|
|
49932
|
-
}],
|
|
49933
50372
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
49934
50373
|
name: "deviceId",
|
|
49935
50374
|
form: "single",
|
|
@@ -51160,6 +51599,11 @@ Object.freeze({
|
|
|
51160
51599
|
form: "single",
|
|
51161
51600
|
optional: false
|
|
51162
51601
|
}],
|
|
51602
|
+
"pipelineExecutor.clearModelBoundDeviceOverrides": [{
|
|
51603
|
+
name: "deviceIds",
|
|
51604
|
+
form: "array",
|
|
51605
|
+
optional: true
|
|
51606
|
+
}],
|
|
51163
51607
|
"pipelineExecutor.runPipeline": [{
|
|
51164
51608
|
name: "deviceId",
|
|
51165
51609
|
form: "single",
|
|
@@ -51265,6 +51709,11 @@ Object.freeze({
|
|
|
51265
51709
|
form: "single",
|
|
51266
51710
|
optional: false
|
|
51267
51711
|
}],
|
|
51712
|
+
"pipelineOrchestrator.setCameraStepSettings": [{
|
|
51713
|
+
name: "deviceId",
|
|
51714
|
+
form: "single",
|
|
51715
|
+
optional: false
|
|
51716
|
+
}],
|
|
51268
51717
|
"pipelineOrchestrator.setCameraStepToggle": [{
|
|
51269
51718
|
name: "deviceId",
|
|
51270
51719
|
form: "single",
|
|
@@ -52036,6 +52485,11 @@ Object.freeze({
|
|
|
52036
52485
|
form: "single",
|
|
52037
52486
|
optional: false
|
|
52038
52487
|
}],
|
|
52488
|
+
"webrtcSession.applyDownlinkProbe": [{
|
|
52489
|
+
name: "deviceId",
|
|
52490
|
+
form: "single",
|
|
52491
|
+
optional: false
|
|
52492
|
+
}],
|
|
52039
52493
|
"webrtcSession.closeSession": [{
|
|
52040
52494
|
name: "deviceId",
|
|
52041
52495
|
form: "single",
|
|
@@ -52265,6 +52719,8 @@ new Map(Object.entries({
|
|
|
52265
52719
|
"detection-blind": "device-events",
|
|
52266
52720
|
"node-online": "system",
|
|
52267
52721
|
"node-offline": "system",
|
|
52722
|
+
"node-restarting": "system",
|
|
52723
|
+
"node-updating": "system",
|
|
52268
52724
|
"node-inference-unavailable": "system",
|
|
52269
52725
|
"addon-crash-loop": "system",
|
|
52270
52726
|
"addon-update-available": "system",
|
|
@@ -52342,18 +52798,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
52342
52798
|
kinds: [
|
|
52343
52799
|
"node-offline",
|
|
52344
52800
|
"node-online",
|
|
52801
|
+
"node-restarting",
|
|
52345
52802
|
"node-inference-unavailable"
|
|
52346
52803
|
]
|
|
52347
52804
|
},
|
|
52348
52805
|
{
|
|
52349
52806
|
id: "addons",
|
|
52350
52807
|
family: "system",
|
|
52351
|
-
label: "Addons",
|
|
52352
|
-
kinds: [
|
|
52353
|
-
|
|
52354
|
-
|
|
52355
|
-
|
|
52356
|
-
|
|
52808
|
+
label: "Addons stopped",
|
|
52809
|
+
kinds: ["addon-crash-loop"]
|
|
52810
|
+
},
|
|
52811
|
+
{
|
|
52812
|
+
id: "addon-updates",
|
|
52813
|
+
family: "system",
|
|
52814
|
+
label: "Addon updates",
|
|
52815
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
52357
52816
|
},
|
|
52358
52817
|
{
|
|
52359
52818
|
id: "updates",
|
|
@@ -52361,6 +52820,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
52361
52820
|
label: "Server & container updates",
|
|
52362
52821
|
kinds: [
|
|
52363
52822
|
"server-update-available",
|
|
52823
|
+
"node-updating",
|
|
52364
52824
|
"server-updated",
|
|
52365
52825
|
"wrapper-update-available"
|
|
52366
52826
|
]
|
|
@@ -52508,18 +52968,21 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
52508
52968
|
kinds: [
|
|
52509
52969
|
"node-offline",
|
|
52510
52970
|
"node-online",
|
|
52971
|
+
"node-restarting",
|
|
52511
52972
|
"node-inference-unavailable"
|
|
52512
52973
|
]
|
|
52513
52974
|
},
|
|
52514
52975
|
{
|
|
52515
52976
|
name: "summaryAddons",
|
|
52516
|
-
label: "Summary: addons",
|
|
52517
|
-
example: "
|
|
52518
|
-
kinds: [
|
|
52519
|
-
|
|
52520
|
-
|
|
52521
|
-
|
|
52522
|
-
|
|
52977
|
+
label: "Summary: addons stopped",
|
|
52978
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
52979
|
+
kinds: ["addon-crash-loop"]
|
|
52980
|
+
},
|
|
52981
|
+
{
|
|
52982
|
+
name: "summaryAddonUpdates",
|
|
52983
|
+
label: "Summary: addon updates",
|
|
52984
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
52985
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
52523
52986
|
},
|
|
52524
52987
|
{
|
|
52525
52988
|
name: "summaryUpdates",
|
|
@@ -52527,6 +52990,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
52527
52990
|
example: "server 1.2.377 → 1.2.378",
|
|
52528
52991
|
kinds: [
|
|
52529
52992
|
"server-update-available",
|
|
52993
|
+
"node-updating",
|
|
52530
52994
|
"server-updated",
|
|
52531
52995
|
"wrapper-update-available"
|
|
52532
52996
|
]
|
|
@@ -52559,7 +53023,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
52559
53023
|
{
|
|
52560
53024
|
name: "summarySection",
|
|
52561
53025
|
label: "Summary: this section",
|
|
52562
|
-
description: "The section a per-section summary row is about
|
|
53026
|
+
description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
|
|
52563
53027
|
example: "Batterie scariche",
|
|
52564
53028
|
group: "system",
|
|
52565
53029
|
families: ["rule"],
|
|
@@ -52603,6 +53067,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
52603
53067
|
[...RULE_BODY_ONLY],
|
|
52604
53068
|
[...RULE_TEXT],
|
|
52605
53069
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
53070
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
52606
53071
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
52607
53072
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
52608
53073
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -52643,6 +53108,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
52643
53108
|
[...RULE_TEXT],
|
|
52644
53109
|
[...RULE_TEXT],
|
|
52645
53110
|
[...RULE_TEXT],
|
|
53111
|
+
[...RULE_TEXT],
|
|
53112
|
+
[...RULE_TEXT],
|
|
52646
53113
|
...STATE_SUMMARY_VARS
|
|
52647
53114
|
];
|
|
52648
53115
|
new Set([
|
|
@@ -96247,26 +96714,6 @@ function setBrokerDevicesOnline(devices, brokerId, online) {
|
|
|
96247
96714
|
}
|
|
96248
96715
|
//#endregion
|
|
96249
96716
|
//#region src/alexa-state-to-cap.ts
|
|
96250
|
-
/**
|
|
96251
|
-
* Pure decoders translating a single polled Alexa property value (as stored on
|
|
96252
|
-
* the {@link AlexaAccountResolver} by interface + property) into the CamStack cap
|
|
96253
|
-
* status field it drives. The inverse of the exporter's report-state mapping.
|
|
96254
|
-
*
|
|
96255
|
-
* Each function takes the raw `unknown` value (provider-specific) and returns a
|
|
96256
|
-
* narrowed primitive or `null` when the value is absent / unrecognised, so the
|
|
96257
|
-
* device class can fall back to its cold-start/runtime default. No I/O, no
|
|
96258
|
-
* alexa-remote2 import — unit-testable with fixtures.
|
|
96259
|
-
*
|
|
96260
|
-
* Alexa property reference (smart-home Phoenix state):
|
|
96261
|
-
* - Alexa.PowerController.powerState → 'ON' | 'OFF'
|
|
96262
|
-
* - Alexa.BrightnessController.brightness → 0..100
|
|
96263
|
-
* - Alexa.LockController.lockState → 'LOCKED' | 'UNLOCKED' | 'JAMMED'
|
|
96264
|
-
* - Alexa.ContactSensor.detectionState → 'DETECTED' | 'NOT_DETECTED'
|
|
96265
|
-
* - Alexa.MotionSensor.detectionState → 'DETECTED' | 'NOT_DETECTED'
|
|
96266
|
-
* - Alexa.TemperatureSensor.temperature → { value:number, scale:'CELSIUS'|'FAHRENHEIT' } | number
|
|
96267
|
-
* - Alexa.PercentageController.percentage → 0..100
|
|
96268
|
-
* - humidity → number (percent)
|
|
96269
|
-
*/
|
|
96270
96717
|
/** Decode an Alexa `powerState` to a boolean on-state, or null. */
|
|
96271
96718
|
function decodePowerState(value) {
|
|
96272
96719
|
if (value === "ON") return true;
|