@camstack/addon-provider-amcrest 0.1.3 → 0.1.5
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 +207 -226
- package/dist/addon.mjs +207 -226
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -4633,7 +4633,7 @@ function _instanceof(cls, params = {}) {
|
|
|
4633
4633
|
return inst;
|
|
4634
4634
|
}
|
|
4635
4635
|
//#endregion
|
|
4636
|
-
//#region ../types/dist/sleep-
|
|
4636
|
+
//#region ../types/dist/sleep-Cc14_yxc.mjs
|
|
4637
4637
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4638
4638
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4639
4639
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -4819,6 +4819,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
4819
4819
|
*/
|
|
4820
4820
|
EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
|
|
4821
4821
|
/**
|
|
4822
|
+
* The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
|
|
4823
|
+
* Emitted by addon-pipeline-orchestrator whenever it (re)derives node
|
|
4824
|
+
* capabilities — at boot, on agent online/offline, and on an ingest-node
|
|
4825
|
+
* flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
|
|
4826
|
+
* keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
|
|
4827
|
+
* cross-process `getIngestOwner` query (push the authority's decision instead
|
|
4828
|
+
* of polling it on the hot path). Idempotent state — re-emitted on every
|
|
4829
|
+
* topology change, so a dropped event self-heals on the next one (plus the
|
|
4830
|
+
* broker's long backstop reconcile query).
|
|
4831
|
+
*/
|
|
4832
|
+
EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
|
|
4833
|
+
/**
|
|
4822
4834
|
* Periodic snapshot of per-node pipeline-runner load
|
|
4823
4835
|
* (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
|
|
4824
4836
|
* subscribe instead of polling `pipelineRunner.getLocalLoad`.
|
|
@@ -6902,6 +6914,28 @@ var ModelFormatsSchema = object({
|
|
|
6902
6914
|
tflite: ModelFormatEntrySchema.optional(),
|
|
6903
6915
|
pt: ModelFormatEntrySchema.optional()
|
|
6904
6916
|
});
|
|
6917
|
+
/**
|
|
6918
|
+
* Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
|
|
6919
|
+
* the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
|
|
6920
|
+
* grouped Family→Tier→Variant picker renders identically in the config UI and
|
|
6921
|
+
* in the pipeline/device steppers. The flat `id` stays the source of truth for
|
|
6922
|
+
* resolution/download/persistence; this is a presentation overlay resolved back
|
|
6923
|
+
* to an `id`.
|
|
6924
|
+
*/
|
|
6925
|
+
var ModelVariantGroupSchema = object({
|
|
6926
|
+
/** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
|
|
6927
|
+
family: string(),
|
|
6928
|
+
/** Size within the family, e.g. `n` | `s` | `m` | `l`. */
|
|
6929
|
+
tier: string(),
|
|
6930
|
+
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
6931
|
+
precision: _enum(["fp32", "int8"]).optional(),
|
|
6932
|
+
/**
|
|
6933
|
+
* Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
|
|
6934
|
+
* latency-optimized export (e.g. ReLU-activation / reduced-input variant)
|
|
6935
|
+
* — the slot the future performance variants plug into.
|
|
6936
|
+
*/
|
|
6937
|
+
optimization: _enum(["standard", "fast"]).optional()
|
|
6938
|
+
});
|
|
6905
6939
|
var ModelCatalogEntrySchema = object({
|
|
6906
6940
|
id: string(),
|
|
6907
6941
|
name: string(),
|
|
@@ -6931,7 +6965,43 @@ var ModelCatalogEntrySchema = object({
|
|
|
6931
6965
|
* Auxiliary files required at runtime (labels JSON, charset dict, etc.).
|
|
6932
6966
|
* Downloaded into the same modelsDir alongside the model file.
|
|
6933
6967
|
*/
|
|
6934
|
-
extraFiles: array(ModelExtraFileSchema).readonly().optional()
|
|
6968
|
+
extraFiles: array(ModelExtraFileSchema).readonly().optional(),
|
|
6969
|
+
/**
|
|
6970
|
+
* LEGACY entry — retained in the catalog so a persisted operator selection
|
|
6971
|
+
* still RESOLVES (and can be re-activated), but hidden from the selectable
|
|
6972
|
+
* model list and excluded from the auto format-default pick. Set on the
|
|
6973
|
+
* superseded / consolidated models (older lineages, redundant fp16 IRs) so
|
|
6974
|
+
* the active lineup stays the coherent curated ladder without deleting a
|
|
6975
|
+
* model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
|
|
6976
|
+
* an explicit legacy id that has a build for the node's format.
|
|
6977
|
+
*/
|
|
6978
|
+
legacy: boolean().optional(),
|
|
6979
|
+
/**
|
|
6980
|
+
* Measured quality/latency metadata — populated from the benchmark addon on
|
|
6981
|
+
* the real node classes. Absent = not yet measured (most entries today; the
|
|
6982
|
+
* catalog historically carried only `sizeMB`, a poor cross-architecture
|
|
6983
|
+
* speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
|
|
6984
|
+
*/
|
|
6985
|
+
metrics: object({
|
|
6986
|
+
map50: number().optional(),
|
|
6987
|
+
p95LatencyMs: record(string(), number()).optional()
|
|
6988
|
+
}).optional(),
|
|
6989
|
+
/**
|
|
6990
|
+
* SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
|
|
6991
|
+
* YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
|
|
6992
|
+
* the retraining addon and any future commercial distribution.
|
|
6993
|
+
*/
|
|
6994
|
+
license: string().optional(),
|
|
6995
|
+
/**
|
|
6996
|
+
* Variant-selector grouping. The UI groups models by `family` + `tier` and
|
|
6997
|
+
* offers `precision` / `optimization` as variant axes WITHIN a tier — so all
|
|
6998
|
+
* of a family's sizes and quantizations collapse into one grouped picker
|
|
6999
|
+
* instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
|
|
7000
|
+
* (legacy / custom models) — never shown in the grouped selector. The flat
|
|
7001
|
+
* `id` stays the source of truth for resolution/download/persistence; grouping
|
|
7002
|
+
* is a presentation overlay resolved back to an `id`.
|
|
7003
|
+
*/
|
|
7004
|
+
group: ModelVariantGroupSchema.optional()
|
|
6935
7005
|
});
|
|
6936
7006
|
var ConvertTargetSchema = discriminatedUnion("format", [object({
|
|
6937
7007
|
format: literal("openvino"),
|
|
@@ -6992,8 +7062,8 @@ var RecordingModeSchema = _enum([
|
|
|
6992
7062
|
"onAudioThreshold"
|
|
6993
7063
|
]);
|
|
6994
7064
|
/**
|
|
6995
|
-
* First-class, authoritative per-camera storage mode — the
|
|
6996
|
-
* reads directly (never inferred from `rules`):
|
|
7065
|
+
* First-class, authoritative per-camera storage mode — the explicit choice the
|
|
7066
|
+
* UI reads directly (never inferred from `rules`):
|
|
6997
7067
|
* - `off` — not recording.
|
|
6998
7068
|
* - `events` — record only around triggers (motion / audio threshold),
|
|
6999
7069
|
* with pre/post-buffer.
|
|
@@ -9180,26 +9250,13 @@ onBrightnessChanged: { data: object({
|
|
|
9180
9250
|
*/
|
|
9181
9251
|
runtimeState: BrightnessStatusSchema
|
|
9182
9252
|
};
|
|
9253
|
+
/** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
|
|
9183
9254
|
var StreamFormatSchema = _enum([
|
|
9184
9255
|
"webrtc",
|
|
9185
9256
|
"hls",
|
|
9186
9257
|
"mjpeg",
|
|
9187
9258
|
"rtsp"
|
|
9188
9259
|
]);
|
|
9189
|
-
var StreamInfoSchema = object({
|
|
9190
|
-
streamId: string(),
|
|
9191
|
-
format: StreamFormatSchema,
|
|
9192
|
-
url: string().nullable(),
|
|
9193
|
-
active: boolean()
|
|
9194
|
-
});
|
|
9195
|
-
method(object({
|
|
9196
|
-
streamId: string(),
|
|
9197
|
-
sourceUrl: string(),
|
|
9198
|
-
codec: string().optional()
|
|
9199
|
-
}), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
|
|
9200
|
-
streamId: string(),
|
|
9201
|
-
format: StreamFormatSchema
|
|
9202
|
-
}), string().nullable()), method(_void(), array(StreamInfoSchema));
|
|
9203
9260
|
var RtspRestreamEntrySchema = object({
|
|
9204
9261
|
brokerId: string(),
|
|
9205
9262
|
url: string(),
|
|
@@ -10067,37 +10124,7 @@ var consumablesCapability = {
|
|
|
10067
10124
|
scope: "device",
|
|
10068
10125
|
deviceNative: true,
|
|
10069
10126
|
mode: "singleton",
|
|
10070
|
-
deviceTypes:
|
|
10071
|
-
DeviceType.Camera,
|
|
10072
|
-
DeviceType.Hub,
|
|
10073
|
-
DeviceType.Light,
|
|
10074
|
-
DeviceType.Siren,
|
|
10075
|
-
DeviceType.Switch,
|
|
10076
|
-
DeviceType.Sensor,
|
|
10077
|
-
DeviceType.Thermostat,
|
|
10078
|
-
DeviceType.Button,
|
|
10079
|
-
DeviceType.EventEmitter,
|
|
10080
|
-
DeviceType.Update,
|
|
10081
|
-
DeviceType.Generic,
|
|
10082
|
-
DeviceType.Notifier,
|
|
10083
|
-
DeviceType.Script,
|
|
10084
|
-
DeviceType.Automation,
|
|
10085
|
-
DeviceType.Lock,
|
|
10086
|
-
DeviceType.Cover,
|
|
10087
|
-
DeviceType.Valve,
|
|
10088
|
-
DeviceType.Humidifier,
|
|
10089
|
-
DeviceType.WaterHeater,
|
|
10090
|
-
DeviceType.Fan,
|
|
10091
|
-
DeviceType.MediaPlayer,
|
|
10092
|
-
DeviceType.AlarmPanel,
|
|
10093
|
-
DeviceType.Control,
|
|
10094
|
-
DeviceType.Presence,
|
|
10095
|
-
DeviceType.Weather,
|
|
10096
|
-
DeviceType.Vacuum,
|
|
10097
|
-
DeviceType.LawnMower,
|
|
10098
|
-
DeviceType.Container,
|
|
10099
|
-
DeviceType.Image
|
|
10100
|
-
],
|
|
10127
|
+
deviceTypes: Object.values(DeviceType),
|
|
10101
10128
|
deviceConfig: { ui: {
|
|
10102
10129
|
kind: "widget",
|
|
10103
10130
|
widgetId: "host/consumables-panel",
|
|
@@ -11690,7 +11717,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
|
|
|
11690
11717
|
enabled: boolean(),
|
|
11691
11718
|
modelId: string(),
|
|
11692
11719
|
children: array(PipelineDefaultStepSchema).readonly(),
|
|
11693
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
11694
11720
|
group: string().optional(),
|
|
11695
11721
|
settings: record(string(), unknown()).optional()
|
|
11696
11722
|
}));
|
|
@@ -11715,7 +11741,9 @@ var PipelineModelOptionSchema = object({
|
|
|
11715
11741
|
formats: record(string(), object({
|
|
11716
11742
|
downloaded: boolean(),
|
|
11717
11743
|
sizeMB: number()
|
|
11718
|
-
}))
|
|
11744
|
+
})),
|
|
11745
|
+
group: ModelVariantGroupSchema.optional(),
|
|
11746
|
+
legacy: boolean().optional()
|
|
11719
11747
|
});
|
|
11720
11748
|
var ConfigFieldBridge = custom();
|
|
11721
11749
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -11766,15 +11794,42 @@ var EngineProvisioningSchema = object({
|
|
|
11766
11794
|
]),
|
|
11767
11795
|
progress: number().optional(),
|
|
11768
11796
|
error: string().optional(),
|
|
11769
|
-
nextRetryAt: number().optional()
|
|
11797
|
+
nextRetryAt: number().optional(),
|
|
11798
|
+
/**
|
|
11799
|
+
* Gate A (config-correctness gate at engine change): human-readable
|
|
11800
|
+
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
11801
|
+
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
11802
|
+
* has a <format> build"). Additive/optional: informational only, never
|
|
11803
|
+
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
11804
|
+
* Absent/empty when the node-default tree resolves cleanly.
|
|
11805
|
+
*/
|
|
11806
|
+
configIssues: array(string()).optional()
|
|
11770
11807
|
});
|
|
11771
11808
|
var PipelineStepInputSchema = lazy(() => object({
|
|
11772
11809
|
addonId: string(),
|
|
11773
|
-
modelId: string(),
|
|
11810
|
+
modelId: string().optional(),
|
|
11774
11811
|
enabled: boolean().default(true),
|
|
11775
11812
|
children: array(PipelineStepInputSchema).optional(),
|
|
11776
11813
|
settings: record(string(), unknown()).optional()
|
|
11777
11814
|
}));
|
|
11815
|
+
var ModelSubstitutionSchema = object({
|
|
11816
|
+
addonId: string(),
|
|
11817
|
+
chosen: string(),
|
|
11818
|
+
running: string(),
|
|
11819
|
+
format: string()
|
|
11820
|
+
});
|
|
11821
|
+
var PipelineValidationIssueSchema = object({
|
|
11822
|
+
addonId: string(),
|
|
11823
|
+
kind: _enum(["unknown-addon", "no-format-build"]),
|
|
11824
|
+
detail: string()
|
|
11825
|
+
});
|
|
11826
|
+
var PipelineValidationResultSchema = object({
|
|
11827
|
+
ok: boolean(),
|
|
11828
|
+
issues: array(PipelineValidationIssueSchema).readonly(),
|
|
11829
|
+
substitutions: array(ModelSubstitutionSchema).readonly(),
|
|
11830
|
+
/** The node's `currentEngine.format` this validation ran against. */
|
|
11831
|
+
format: string()
|
|
11832
|
+
});
|
|
11778
11833
|
var ReferenceImageEntrySchema = object({
|
|
11779
11834
|
filename: string(),
|
|
11780
11835
|
stepIds: array(string()).readonly().optional()
|
|
@@ -11845,7 +11900,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
11845
11900
|
})) }), object({ success: literal(true) }), {
|
|
11846
11901
|
kind: "mutation",
|
|
11847
11902
|
auth: "admin"
|
|
11848
|
-
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
11903
|
+
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
11849
11904
|
name: string(),
|
|
11850
11905
|
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
11851
11906
|
engine: PipelineEngineChoiceSchema
|
|
@@ -12138,6 +12193,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
|
|
|
12138
12193
|
kind: literal("remote-restream"),
|
|
12139
12194
|
/** The camera's source-owner node (slice 1: always the hub). */
|
|
12140
12195
|
ownerNodeId: string(),
|
|
12196
|
+
/**
|
|
12197
|
+
* The owner's LAN-reachable host, resolved by the orchestrator from the
|
|
12198
|
+
* per-node `reachableHost` override (Cluster UI). When present the runner
|
|
12199
|
+
* dials THIS host for the owner's restream, in preference to the
|
|
12200
|
+
* `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
|
|
12201
|
+
*/
|
|
12202
|
+
ownerReachableHost: string().optional(),
|
|
12141
12203
|
/** Operator override for the owner host the runner dials. */
|
|
12142
12204
|
hubHostnameOverride: string().optional()
|
|
12143
12205
|
})]).describe("Per-camera frame-source mode for the runner (P2c)");
|
|
@@ -12146,13 +12208,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
|
|
|
12146
12208
|
* specific runner instance via `attachCamera`. Carries everything the
|
|
12147
12209
|
* runner needs to subscribe to the local broker and execute inference.
|
|
12148
12210
|
*
|
|
12149
|
-
* Stateless-pipeline model: the
|
|
12150
|
-
*
|
|
12151
|
-
*
|
|
12152
|
-
*
|
|
12153
|
-
*
|
|
12154
|
-
* `engine`/`steps`/`audio` are optional during the additive migration
|
|
12155
|
-
* window; once orchestrator + UI are migrated they become required.
|
|
12211
|
+
* Stateless-pipeline model: the pipeline content (`steps`, optional
|
|
12212
|
+
* `audio`) travels with the attach payload. The runner keeps it in RAM
|
|
12213
|
+
* for the lifetime of the attach — on rebalance, edit, or restart the
|
|
12214
|
+
* orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
|
|
12215
|
+
* node-local, resolved by the executing runner at dispatch time.
|
|
12156
12216
|
*/
|
|
12157
12217
|
var RunnerCameraConfigSchema = object({
|
|
12158
12218
|
deviceId: number(),
|
|
@@ -12203,14 +12263,11 @@ var RunnerCameraConfigSchema = object({
|
|
|
12203
12263
|
*/
|
|
12204
12264
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
12205
12265
|
pipelineEnabled: boolean().default(true),
|
|
12206
|
-
/** Engine choice for video steps (runtime+backend+format). */
|
|
12207
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
12208
12266
|
/** Ordered tree of video steps. Absent → runner skips video detection. */
|
|
12209
12267
|
steps: array(PipelineStepInputSchema).readonly().optional(),
|
|
12210
12268
|
/** Audio classification branch. `enabled:false` disables, null skips. */
|
|
12211
12269
|
audio: object({
|
|
12212
|
-
|
|
12213
|
-
modelId: string(),
|
|
12270
|
+
modelId: string().optional(),
|
|
12214
12271
|
enabled: boolean()
|
|
12215
12272
|
}).nullable().optional(),
|
|
12216
12273
|
/**
|
|
@@ -18073,11 +18130,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18073
18130
|
timestamp: number()
|
|
18074
18131
|
});
|
|
18075
18132
|
var CameraPipelineConfigSchema = object({
|
|
18076
|
-
engine: PipelineEngineChoiceSchema,
|
|
18133
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
18077
18134
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
18078
18135
|
audio: object({
|
|
18079
|
-
engine: PipelineEngineChoiceSchema,
|
|
18080
|
-
modelId: string(),
|
|
18136
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
18137
|
+
modelId: string().optional(),
|
|
18081
18138
|
enabled: boolean(),
|
|
18082
18139
|
settings: record(string(), unknown()).readonly().optional()
|
|
18083
18140
|
}).nullable().optional()
|
|
@@ -18092,7 +18149,7 @@ var PipelineTemplateSchema = object({
|
|
|
18092
18149
|
});
|
|
18093
18150
|
var AgentAddonConfigSchema = object({
|
|
18094
18151
|
enabled: boolean(),
|
|
18095
|
-
modelId: string(),
|
|
18152
|
+
modelId: string().optional(),
|
|
18096
18153
|
settings: record(string(), unknown()).readonly()
|
|
18097
18154
|
});
|
|
18098
18155
|
var AgentPipelineSettingsSchema = object({
|
|
@@ -18107,7 +18164,15 @@ var AgentPipelineSettingsSchema = object({
|
|
|
18107
18164
|
/** Node is eligible to run audio-analyzer sessions. */
|
|
18108
18165
|
audio: boolean().optional(),
|
|
18109
18166
|
/** Node is eligible to be the ingest / source-owner (serve the restream). */
|
|
18110
|
-
ingest: boolean().optional()
|
|
18167
|
+
ingest: boolean().optional(),
|
|
18168
|
+
/**
|
|
18169
|
+
* Operator override for the LAN host a cross-node decoder dials to reach
|
|
18170
|
+
* THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
|
|
18171
|
+
* falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
|
|
18172
|
+
* it already uses to reach the hub). Set this only when the auto-detected
|
|
18173
|
+
* address is wrong (multi-homed host, NAT, custom interface).
|
|
18174
|
+
*/
|
|
18175
|
+
reachableHost: string().optional()
|
|
18111
18176
|
});
|
|
18112
18177
|
var CameraPipelineForAgentSchema = object({
|
|
18113
18178
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -18213,6 +18278,15 @@ var GlobalMetricsSchema = object({
|
|
|
18213
18278
|
* capability providers.
|
|
18214
18279
|
*/
|
|
18215
18280
|
var CapabilityBindingsSchema = record(string(), string());
|
|
18281
|
+
/**
|
|
18282
|
+
* The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
|
|
18283
|
+
* its LAN-reachable host, if one is registered. See `getIngestOwner`.
|
|
18284
|
+
*/
|
|
18285
|
+
var IngestOwnerSchema = object({
|
|
18286
|
+
ownerNodeId: string(),
|
|
18287
|
+
reachableHost: string().optional(),
|
|
18288
|
+
configIssue: string().optional()
|
|
18289
|
+
});
|
|
18216
18290
|
/** Source block — always present; derives from the stream catalog. */
|
|
18217
18291
|
var CameraSourceStatusSchema = object({ streams: array(object({
|
|
18218
18292
|
camStreamId: string(),
|
|
@@ -18227,6 +18301,14 @@ var CameraAssignmentStatusSchema = object({
|
|
|
18227
18301
|
detectionNodeId: string().nullable(),
|
|
18228
18302
|
decoderNodeId: string().nullable(),
|
|
18229
18303
|
audioNodeId: string().nullable(),
|
|
18304
|
+
/**
|
|
18305
|
+
* The node that OWNS this camera's physical source pull (dials the RTSP and
|
|
18306
|
+
* hosts the broker/restream) — the cluster ingest owner today
|
|
18307
|
+
* (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
|
|
18308
|
+
* the UI show WHERE a camera is sourced without SSH/logs, and is the node the
|
|
18309
|
+
* broker block below was read from (pinned). Nullable only pre-wiring.
|
|
18310
|
+
*/
|
|
18311
|
+
sourceNodeId: string().nullable(),
|
|
18230
18312
|
pinned: object({
|
|
18231
18313
|
detection: boolean(),
|
|
18232
18314
|
decoder: boolean(),
|
|
@@ -18359,7 +18441,7 @@ method(object({
|
|
|
18359
18441
|
}), object({ success: literal(true) }), {
|
|
18360
18442
|
kind: "mutation",
|
|
18361
18443
|
auth: "admin"
|
|
18362
|
-
}), method(object({
|
|
18444
|
+
}), method(_void(), IngestOwnerSchema), method(object({
|
|
18363
18445
|
deviceId: number(),
|
|
18364
18446
|
nodeId: string()
|
|
18365
18447
|
}), _void(), {
|
|
@@ -18428,6 +18510,12 @@ method(object({
|
|
|
18428
18510
|
}), object({ success: literal(true) }), {
|
|
18429
18511
|
kind: "mutation",
|
|
18430
18512
|
auth: "admin"
|
|
18513
|
+
}), method(object({
|
|
18514
|
+
agentNodeId: string(),
|
|
18515
|
+
reachableHost: string().nullable()
|
|
18516
|
+
}), object({ success: literal(true) }), {
|
|
18517
|
+
kind: "mutation",
|
|
18518
|
+
auth: "admin"
|
|
18431
18519
|
}), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
|
|
18432
18520
|
deviceId: number(),
|
|
18433
18521
|
addonId: string(),
|
|
@@ -18472,22 +18560,6 @@ method(object({
|
|
|
18472
18560
|
kind: "mutation",
|
|
18473
18561
|
auth: "admin"
|
|
18474
18562
|
});
|
|
18475
|
-
var RegisteredStreamSchema = object({
|
|
18476
|
-
streamId: string(),
|
|
18477
|
-
label: string().optional(),
|
|
18478
|
-
codec: string(),
|
|
18479
|
-
type: _enum(["video", "audio"]),
|
|
18480
|
-
sourceUrl: string()
|
|
18481
|
-
});
|
|
18482
|
-
var ExposedResourceSchema = object({
|
|
18483
|
-
streamId: string(),
|
|
18484
|
-
format: string(),
|
|
18485
|
-
value: string()
|
|
18486
|
-
});
|
|
18487
|
-
method(object({
|
|
18488
|
-
deviceId: number(),
|
|
18489
|
-
streams: array(RegisteredStreamSchema).readonly()
|
|
18490
|
-
}), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
|
|
18491
18563
|
/**
|
|
18492
18564
|
* Query filter for settings-store collections.
|
|
18493
18565
|
*/
|
|
@@ -18640,9 +18712,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
|
|
|
18640
18712
|
/**
|
|
18641
18713
|
* A single device snapshot returned as base64 JPEG/PNG.
|
|
18642
18714
|
*
|
|
18643
|
-
*
|
|
18644
|
-
*
|
|
18645
|
-
*
|
|
18715
|
+
* The `SnapshotAddon` wrapper returns this shape whether the frame came from
|
|
18716
|
+
* the device-native provider (onboard capture) or from the stream-broker
|
|
18717
|
+
* prebuffer fallback.
|
|
18646
18718
|
*/
|
|
18647
18719
|
var SnapshotImageSchema = object({
|
|
18648
18720
|
base64: string(),
|
|
@@ -18717,10 +18789,6 @@ var snapshotCapability = {
|
|
|
18717
18789
|
kind: "poll"
|
|
18718
18790
|
}
|
|
18719
18791
|
};
|
|
18720
|
-
method(object({ deviceId: number() }), boolean()), method(object({
|
|
18721
|
-
deviceId: number(),
|
|
18722
|
-
streamId: string().optional()
|
|
18723
|
-
}), SnapshotImageSchema.nullable());
|
|
18724
18792
|
/**
|
|
18725
18793
|
* `sso-bridge` — internal hub-only cap that lets SSO-style auth
|
|
18726
18794
|
* providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
|
|
@@ -19081,9 +19149,10 @@ method(object({
|
|
|
19081
19149
|
auth: "admin"
|
|
19082
19150
|
});
|
|
19083
19151
|
/**
|
|
19084
|
-
* Optional client-side hints sent at session creation to help the
|
|
19085
|
-
*
|
|
19086
|
-
*
|
|
19152
|
+
* Optional client-side hints sent at session creation to help the provider
|
|
19153
|
+
* pick the best native source. All fields optional — a viewer that knows
|
|
19154
|
+
* nothing still gets a sane default. (Relocated from the retired `webrtc`
|
|
19155
|
+
* collection cap; this `webrtc-session` cap is the live signaling surface.)
|
|
19087
19156
|
*/
|
|
19088
19157
|
var webrtcClientHintsSchema = object({
|
|
19089
19158
|
viewportWidth: number().int().positive().optional(),
|
|
@@ -19094,22 +19163,6 @@ var webrtcClientHintsSchema = object({
|
|
|
19094
19163
|
/** Hard tier override; takes precedence over scoring when registered. */
|
|
19095
19164
|
prefersTier: string().optional()
|
|
19096
19165
|
}).partial();
|
|
19097
|
-
method(object({
|
|
19098
|
-
streamId: string(),
|
|
19099
|
-
sdpOffer: string()
|
|
19100
|
-
}), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
|
|
19101
|
-
streamId: string(),
|
|
19102
|
-
codec: string()
|
|
19103
|
-
}), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
|
|
19104
|
-
streamId: string(),
|
|
19105
|
-
hints: webrtcClientHintsSchema.optional()
|
|
19106
|
-
}), object({
|
|
19107
|
-
sessionId: string(),
|
|
19108
|
-
sdpOffer: string()
|
|
19109
|
-
}), { kind: "mutation" }), method(object({
|
|
19110
|
-
sessionId: string(),
|
|
19111
|
-
sdpAnswer: string()
|
|
19112
|
-
}), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
|
|
19113
19166
|
/**
|
|
19114
19167
|
* Discriminated target for a WebRTC session. The client sends this
|
|
19115
19168
|
* structured object instead of building / parsing brokerId strings;
|
|
@@ -24499,6 +24552,12 @@ Object.freeze({
|
|
|
24499
24552
|
addonId: null,
|
|
24500
24553
|
access: "create"
|
|
24501
24554
|
},
|
|
24555
|
+
"pipelineExecutor.validatePipeline": {
|
|
24556
|
+
capName: "pipeline-executor",
|
|
24557
|
+
capScope: "system",
|
|
24558
|
+
addonId: null,
|
|
24559
|
+
access: "view"
|
|
24560
|
+
},
|
|
24502
24561
|
"pipelineOrchestrator.assignAudio": {
|
|
24503
24562
|
capName: "pipeline-orchestrator",
|
|
24504
24563
|
capScope: "system",
|
|
@@ -24607,6 +24666,12 @@ Object.freeze({
|
|
|
24607
24666
|
addonId: null,
|
|
24608
24667
|
access: "view"
|
|
24609
24668
|
},
|
|
24669
|
+
"pipelineOrchestrator.getIngestOwner": {
|
|
24670
|
+
capName: "pipeline-orchestrator",
|
|
24671
|
+
capScope: "system",
|
|
24672
|
+
addonId: null,
|
|
24673
|
+
access: "view"
|
|
24674
|
+
},
|
|
24610
24675
|
"pipelineOrchestrator.getPipelineAssignment": {
|
|
24611
24676
|
capName: "pipeline-orchestrator",
|
|
24612
24677
|
capScope: "system",
|
|
@@ -24679,6 +24744,12 @@ Object.freeze({
|
|
|
24679
24744
|
addonId: null,
|
|
24680
24745
|
access: "create"
|
|
24681
24746
|
},
|
|
24747
|
+
"pipelineOrchestrator.setAgentReachableHost": {
|
|
24748
|
+
capName: "pipeline-orchestrator",
|
|
24749
|
+
capScope: "system",
|
|
24750
|
+
addonId: null,
|
|
24751
|
+
access: "create"
|
|
24752
|
+
},
|
|
24682
24753
|
"pipelineOrchestrator.setCameraPipelineForAgent": {
|
|
24683
24754
|
capName: "pipeline-orchestrator",
|
|
24684
24755
|
capScope: "system",
|
|
@@ -25009,24 +25080,6 @@ Object.freeze({
|
|
|
25009
25080
|
addonId: null,
|
|
25010
25081
|
access: "create"
|
|
25011
25082
|
},
|
|
25012
|
-
"restreamer.getExposedResources": {
|
|
25013
|
-
capName: "restreamer",
|
|
25014
|
-
capScope: "system",
|
|
25015
|
-
addonId: null,
|
|
25016
|
-
access: "view"
|
|
25017
|
-
},
|
|
25018
|
-
"restreamer.registerDevice": {
|
|
25019
|
-
capName: "restreamer",
|
|
25020
|
-
capScope: "system",
|
|
25021
|
-
addonId: null,
|
|
25022
|
-
access: "create"
|
|
25023
|
-
},
|
|
25024
|
-
"restreamer.unregisterDevice": {
|
|
25025
|
-
capName: "restreamer",
|
|
25026
|
-
capScope: "system",
|
|
25027
|
-
addonId: null,
|
|
25028
|
-
access: "delete"
|
|
25029
|
-
},
|
|
25030
25083
|
"scriptRunner.run": {
|
|
25031
25084
|
capName: "script-runner",
|
|
25032
25085
|
capScope: "device",
|
|
@@ -25129,18 +25182,6 @@ Object.freeze({
|
|
|
25129
25182
|
addonId: null,
|
|
25130
25183
|
access: "create"
|
|
25131
25184
|
},
|
|
25132
|
-
"snapshotProvider.getSnapshot": {
|
|
25133
|
-
capName: "snapshot-provider",
|
|
25134
|
-
capScope: "system",
|
|
25135
|
-
addonId: null,
|
|
25136
|
-
access: "view"
|
|
25137
|
-
},
|
|
25138
|
-
"snapshotProvider.supportsDevice": {
|
|
25139
|
-
capName: "snapshot-provider",
|
|
25140
|
-
capScope: "system",
|
|
25141
|
-
addonId: null,
|
|
25142
|
-
access: "view"
|
|
25143
|
-
},
|
|
25144
25185
|
"ssoBridge.signBridgeToken": {
|
|
25145
25186
|
capName: "sso-bridge",
|
|
25146
25187
|
capScope: "system",
|
|
@@ -25567,30 +25608,6 @@ Object.freeze({
|
|
|
25567
25608
|
addonId: null,
|
|
25568
25609
|
access: "view"
|
|
25569
25610
|
},
|
|
25570
|
-
"streamingEngine.getStreamUrl": {
|
|
25571
|
-
capName: "streaming-engine",
|
|
25572
|
-
capScope: "system",
|
|
25573
|
-
addonId: null,
|
|
25574
|
-
access: "view"
|
|
25575
|
-
},
|
|
25576
|
-
"streamingEngine.listStreams": {
|
|
25577
|
-
capName: "streaming-engine",
|
|
25578
|
-
capScope: "system",
|
|
25579
|
-
addonId: null,
|
|
25580
|
-
access: "view"
|
|
25581
|
-
},
|
|
25582
|
-
"streamingEngine.registerStream": {
|
|
25583
|
-
capName: "streaming-engine",
|
|
25584
|
-
capScope: "system",
|
|
25585
|
-
addonId: null,
|
|
25586
|
-
access: "create"
|
|
25587
|
-
},
|
|
25588
|
-
"streamingEngine.unregisterStream": {
|
|
25589
|
-
capName: "streaming-engine",
|
|
25590
|
-
capScope: "system",
|
|
25591
|
-
addonId: null,
|
|
25592
|
-
access: "delete"
|
|
25593
|
-
},
|
|
25594
25611
|
"streamParams.getConfigSchema": {
|
|
25595
25612
|
capName: "stream-params",
|
|
25596
25613
|
capScope: "device",
|
|
@@ -25957,54 +25974,6 @@ Object.freeze({
|
|
|
25957
25974
|
addonId: null,
|
|
25958
25975
|
access: "create"
|
|
25959
25976
|
},
|
|
25960
|
-
"webrtc.closeSession": {
|
|
25961
|
-
capName: "webrtc",
|
|
25962
|
-
capScope: "system",
|
|
25963
|
-
addonId: null,
|
|
25964
|
-
access: "create"
|
|
25965
|
-
},
|
|
25966
|
-
"webrtc.createSession": {
|
|
25967
|
-
capName: "webrtc",
|
|
25968
|
-
capScope: "system",
|
|
25969
|
-
addonId: null,
|
|
25970
|
-
access: "create"
|
|
25971
|
-
},
|
|
25972
|
-
"webrtc.handleAnswer": {
|
|
25973
|
-
capName: "webrtc",
|
|
25974
|
-
capScope: "system",
|
|
25975
|
-
addonId: null,
|
|
25976
|
-
access: "create"
|
|
25977
|
-
},
|
|
25978
|
-
"webrtc.handleOffer": {
|
|
25979
|
-
capName: "webrtc",
|
|
25980
|
-
capScope: "system",
|
|
25981
|
-
addonId: null,
|
|
25982
|
-
access: "create"
|
|
25983
|
-
},
|
|
25984
|
-
"webrtc.hasAdaptiveBitrate": {
|
|
25985
|
-
capName: "webrtc",
|
|
25986
|
-
capScope: "system",
|
|
25987
|
-
addonId: null,
|
|
25988
|
-
access: "view"
|
|
25989
|
-
},
|
|
25990
|
-
"webrtc.registerStream": {
|
|
25991
|
-
capName: "webrtc",
|
|
25992
|
-
capScope: "system",
|
|
25993
|
-
addonId: null,
|
|
25994
|
-
access: "create"
|
|
25995
|
-
},
|
|
25996
|
-
"webrtc.supportsStream": {
|
|
25997
|
-
capName: "webrtc",
|
|
25998
|
-
capScope: "system",
|
|
25999
|
-
addonId: null,
|
|
26000
|
-
access: "view"
|
|
26001
|
-
},
|
|
26002
|
-
"webrtc.unregisterStream": {
|
|
26003
|
-
capName: "webrtc",
|
|
26004
|
-
capScope: "system",
|
|
26005
|
-
addonId: null,
|
|
26006
|
-
access: "delete"
|
|
26007
|
-
},
|
|
26008
25977
|
"webrtcSession.addIceCandidate": {
|
|
26009
25978
|
capName: "webrtc-session",
|
|
26010
25979
|
capScope: "device",
|
|
@@ -26534,17 +26503,21 @@ var AmcrestCgiClient = class AmcrestCgiClient {
|
|
|
26534
26503
|
} catch {
|
|
26535
26504
|
return [];
|
|
26536
26505
|
}
|
|
26537
|
-
const out = /* @__PURE__ */ new Map();
|
|
26538
26506
|
const ch = channel - 1;
|
|
26507
|
+
const names = /* @__PURE__ */ new Map();
|
|
26508
|
+
const enabled = /* @__PURE__ */ new Set();
|
|
26539
26509
|
for (const [key, value] of t) {
|
|
26540
|
-
const
|
|
26541
|
-
if (
|
|
26542
|
-
|
|
26543
|
-
|
|
26510
|
+
const nameMatch = new RegExp(`^PtzPreset\\[${ch}\\]\\[(\\d+)\\]\\.Name$`).exec(key);
|
|
26511
|
+
if (nameMatch) {
|
|
26512
|
+
names.set(Number.parseInt(nameMatch[1], 10), value);
|
|
26513
|
+
continue;
|
|
26514
|
+
}
|
|
26515
|
+
const enableMatch = new RegExp(`^PtzPreset\\[${ch}\\]\\[(\\d+)\\]\\.Enable$`).exec(key);
|
|
26516
|
+
if (enableMatch && value.trim().toLowerCase() === "true") enabled.add(Number.parseInt(enableMatch[1], 10));
|
|
26544
26517
|
}
|
|
26545
|
-
return [...
|
|
26546
|
-
id,
|
|
26547
|
-
name:
|
|
26518
|
+
return [...enabled].toSorted((a, b) => a - b).map((idx) => ({
|
|
26519
|
+
id: idx + 1,
|
|
26520
|
+
name: names.get(idx) || `Preset ${idx + 1}`
|
|
26548
26521
|
}));
|
|
26549
26522
|
}
|
|
26550
26523
|
};
|
|
@@ -27178,9 +27151,17 @@ var AmcrestCamera = class AmcrestCamera extends BaseDevice {
|
|
|
27178
27151
|
},
|
|
27179
27152
|
savePreset: async ({ deviceId, presetId, name }) => {
|
|
27180
27153
|
if (deviceId !== this.id) return;
|
|
27181
|
-
const
|
|
27182
|
-
|
|
27183
|
-
|
|
27154
|
+
const client = this.ensureClient();
|
|
27155
|
+
const requested = Number.parseInt(presetId, 10);
|
|
27156
|
+
const DAHUA_MAX_PRESETS = 25;
|
|
27157
|
+
let slot;
|
|
27158
|
+
if (Number.isInteger(requested) && requested >= 1 && requested <= DAHUA_MAX_PRESETS) slot = requested;
|
|
27159
|
+
else {
|
|
27160
|
+
const used = new Set((await client.getPtzPresets(this.channel)).map((p) => p.id));
|
|
27161
|
+
slot = 1;
|
|
27162
|
+
while (used.has(slot)) slot += 1;
|
|
27163
|
+
}
|
|
27164
|
+
await client.ptzSetPreset(this.channel, slot);
|
|
27184
27165
|
},
|
|
27185
27166
|
deletePreset: async ({ deviceId, presetId }) => {
|
|
27186
27167
|
if (deviceId !== this.id) return;
|
package/dist/addon.mjs
CHANGED
|
@@ -4634,7 +4634,7 @@ function _instanceof(cls, params = {}) {
|
|
|
4634
4634
|
return inst;
|
|
4635
4635
|
}
|
|
4636
4636
|
//#endregion
|
|
4637
|
-
//#region ../types/dist/sleep-
|
|
4637
|
+
//#region ../types/dist/sleep-Cc14_yxc.mjs
|
|
4638
4638
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4639
4639
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4640
4640
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -4820,6 +4820,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
4820
4820
|
*/
|
|
4821
4821
|
EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
|
|
4822
4822
|
/**
|
|
4823
|
+
* The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
|
|
4824
|
+
* Emitted by addon-pipeline-orchestrator whenever it (re)derives node
|
|
4825
|
+
* capabilities — at boot, on agent online/offline, and on an ingest-node
|
|
4826
|
+
* flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
|
|
4827
|
+
* keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
|
|
4828
|
+
* cross-process `getIngestOwner` query (push the authority's decision instead
|
|
4829
|
+
* of polling it on the hot path). Idempotent state — re-emitted on every
|
|
4830
|
+
* topology change, so a dropped event self-heals on the next one (plus the
|
|
4831
|
+
* broker's long backstop reconcile query).
|
|
4832
|
+
*/
|
|
4833
|
+
EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
|
|
4834
|
+
/**
|
|
4823
4835
|
* Periodic snapshot of per-node pipeline-runner load
|
|
4824
4836
|
* (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
|
|
4825
4837
|
* subscribe instead of polling `pipelineRunner.getLocalLoad`.
|
|
@@ -6903,6 +6915,28 @@ var ModelFormatsSchema = object({
|
|
|
6903
6915
|
tflite: ModelFormatEntrySchema.optional(),
|
|
6904
6916
|
pt: ModelFormatEntrySchema.optional()
|
|
6905
6917
|
});
|
|
6918
|
+
/**
|
|
6919
|
+
* Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
|
|
6920
|
+
* the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
|
|
6921
|
+
* grouped Family→Tier→Variant picker renders identically in the config UI and
|
|
6922
|
+
* in the pipeline/device steppers. The flat `id` stays the source of truth for
|
|
6923
|
+
* resolution/download/persistence; this is a presentation overlay resolved back
|
|
6924
|
+
* to an `id`.
|
|
6925
|
+
*/
|
|
6926
|
+
var ModelVariantGroupSchema = object({
|
|
6927
|
+
/** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
|
|
6928
|
+
family: string(),
|
|
6929
|
+
/** Size within the family, e.g. `n` | `s` | `m` | `l`. */
|
|
6930
|
+
tier: string(),
|
|
6931
|
+
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
6932
|
+
precision: _enum(["fp32", "int8"]).optional(),
|
|
6933
|
+
/**
|
|
6934
|
+
* Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
|
|
6935
|
+
* latency-optimized export (e.g. ReLU-activation / reduced-input variant)
|
|
6936
|
+
* — the slot the future performance variants plug into.
|
|
6937
|
+
*/
|
|
6938
|
+
optimization: _enum(["standard", "fast"]).optional()
|
|
6939
|
+
});
|
|
6906
6940
|
var ModelCatalogEntrySchema = object({
|
|
6907
6941
|
id: string(),
|
|
6908
6942
|
name: string(),
|
|
@@ -6932,7 +6966,43 @@ var ModelCatalogEntrySchema = object({
|
|
|
6932
6966
|
* Auxiliary files required at runtime (labels JSON, charset dict, etc.).
|
|
6933
6967
|
* Downloaded into the same modelsDir alongside the model file.
|
|
6934
6968
|
*/
|
|
6935
|
-
extraFiles: array(ModelExtraFileSchema).readonly().optional()
|
|
6969
|
+
extraFiles: array(ModelExtraFileSchema).readonly().optional(),
|
|
6970
|
+
/**
|
|
6971
|
+
* LEGACY entry — retained in the catalog so a persisted operator selection
|
|
6972
|
+
* still RESOLVES (and can be re-activated), but hidden from the selectable
|
|
6973
|
+
* model list and excluded from the auto format-default pick. Set on the
|
|
6974
|
+
* superseded / consolidated models (older lineages, redundant fp16 IRs) so
|
|
6975
|
+
* the active lineup stays the coherent curated ladder without deleting a
|
|
6976
|
+
* model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
|
|
6977
|
+
* an explicit legacy id that has a build for the node's format.
|
|
6978
|
+
*/
|
|
6979
|
+
legacy: boolean().optional(),
|
|
6980
|
+
/**
|
|
6981
|
+
* Measured quality/latency metadata — populated from the benchmark addon on
|
|
6982
|
+
* the real node classes. Absent = not yet measured (most entries today; the
|
|
6983
|
+
* catalog historically carried only `sizeMB`, a poor cross-architecture
|
|
6984
|
+
* speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
|
|
6985
|
+
*/
|
|
6986
|
+
metrics: object({
|
|
6987
|
+
map50: number().optional(),
|
|
6988
|
+
p95LatencyMs: record(string(), number()).optional()
|
|
6989
|
+
}).optional(),
|
|
6990
|
+
/**
|
|
6991
|
+
* SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
|
|
6992
|
+
* YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
|
|
6993
|
+
* the retraining addon and any future commercial distribution.
|
|
6994
|
+
*/
|
|
6995
|
+
license: string().optional(),
|
|
6996
|
+
/**
|
|
6997
|
+
* Variant-selector grouping. The UI groups models by `family` + `tier` and
|
|
6998
|
+
* offers `precision` / `optimization` as variant axes WITHIN a tier — so all
|
|
6999
|
+
* of a family's sizes and quantizations collapse into one grouped picker
|
|
7000
|
+
* instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
|
|
7001
|
+
* (legacy / custom models) — never shown in the grouped selector. The flat
|
|
7002
|
+
* `id` stays the source of truth for resolution/download/persistence; grouping
|
|
7003
|
+
* is a presentation overlay resolved back to an `id`.
|
|
7004
|
+
*/
|
|
7005
|
+
group: ModelVariantGroupSchema.optional()
|
|
6936
7006
|
});
|
|
6937
7007
|
var ConvertTargetSchema = discriminatedUnion("format", [object({
|
|
6938
7008
|
format: literal("openvino"),
|
|
@@ -6993,8 +7063,8 @@ var RecordingModeSchema = _enum([
|
|
|
6993
7063
|
"onAudioThreshold"
|
|
6994
7064
|
]);
|
|
6995
7065
|
/**
|
|
6996
|
-
* First-class, authoritative per-camera storage mode — the
|
|
6997
|
-
* reads directly (never inferred from `rules`):
|
|
7066
|
+
* First-class, authoritative per-camera storage mode — the explicit choice the
|
|
7067
|
+
* UI reads directly (never inferred from `rules`):
|
|
6998
7068
|
* - `off` — not recording.
|
|
6999
7069
|
* - `events` — record only around triggers (motion / audio threshold),
|
|
7000
7070
|
* with pre/post-buffer.
|
|
@@ -9181,26 +9251,13 @@ onBrightnessChanged: { data: object({
|
|
|
9181
9251
|
*/
|
|
9182
9252
|
runtimeState: BrightnessStatusSchema
|
|
9183
9253
|
};
|
|
9254
|
+
/** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
|
|
9184
9255
|
var StreamFormatSchema = _enum([
|
|
9185
9256
|
"webrtc",
|
|
9186
9257
|
"hls",
|
|
9187
9258
|
"mjpeg",
|
|
9188
9259
|
"rtsp"
|
|
9189
9260
|
]);
|
|
9190
|
-
var StreamInfoSchema = object({
|
|
9191
|
-
streamId: string(),
|
|
9192
|
-
format: StreamFormatSchema,
|
|
9193
|
-
url: string().nullable(),
|
|
9194
|
-
active: boolean()
|
|
9195
|
-
});
|
|
9196
|
-
method(object({
|
|
9197
|
-
streamId: string(),
|
|
9198
|
-
sourceUrl: string(),
|
|
9199
|
-
codec: string().optional()
|
|
9200
|
-
}), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
|
|
9201
|
-
streamId: string(),
|
|
9202
|
-
format: StreamFormatSchema
|
|
9203
|
-
}), string().nullable()), method(_void(), array(StreamInfoSchema));
|
|
9204
9261
|
var RtspRestreamEntrySchema = object({
|
|
9205
9262
|
brokerId: string(),
|
|
9206
9263
|
url: string(),
|
|
@@ -10068,37 +10125,7 @@ var consumablesCapability = {
|
|
|
10068
10125
|
scope: "device",
|
|
10069
10126
|
deviceNative: true,
|
|
10070
10127
|
mode: "singleton",
|
|
10071
|
-
deviceTypes:
|
|
10072
|
-
DeviceType.Camera,
|
|
10073
|
-
DeviceType.Hub,
|
|
10074
|
-
DeviceType.Light,
|
|
10075
|
-
DeviceType.Siren,
|
|
10076
|
-
DeviceType.Switch,
|
|
10077
|
-
DeviceType.Sensor,
|
|
10078
|
-
DeviceType.Thermostat,
|
|
10079
|
-
DeviceType.Button,
|
|
10080
|
-
DeviceType.EventEmitter,
|
|
10081
|
-
DeviceType.Update,
|
|
10082
|
-
DeviceType.Generic,
|
|
10083
|
-
DeviceType.Notifier,
|
|
10084
|
-
DeviceType.Script,
|
|
10085
|
-
DeviceType.Automation,
|
|
10086
|
-
DeviceType.Lock,
|
|
10087
|
-
DeviceType.Cover,
|
|
10088
|
-
DeviceType.Valve,
|
|
10089
|
-
DeviceType.Humidifier,
|
|
10090
|
-
DeviceType.WaterHeater,
|
|
10091
|
-
DeviceType.Fan,
|
|
10092
|
-
DeviceType.MediaPlayer,
|
|
10093
|
-
DeviceType.AlarmPanel,
|
|
10094
|
-
DeviceType.Control,
|
|
10095
|
-
DeviceType.Presence,
|
|
10096
|
-
DeviceType.Weather,
|
|
10097
|
-
DeviceType.Vacuum,
|
|
10098
|
-
DeviceType.LawnMower,
|
|
10099
|
-
DeviceType.Container,
|
|
10100
|
-
DeviceType.Image
|
|
10101
|
-
],
|
|
10128
|
+
deviceTypes: Object.values(DeviceType),
|
|
10102
10129
|
deviceConfig: { ui: {
|
|
10103
10130
|
kind: "widget",
|
|
10104
10131
|
widgetId: "host/consumables-panel",
|
|
@@ -11691,7 +11718,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
|
|
|
11691
11718
|
enabled: boolean(),
|
|
11692
11719
|
modelId: string(),
|
|
11693
11720
|
children: array(PipelineDefaultStepSchema).readonly(),
|
|
11694
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
11695
11721
|
group: string().optional(),
|
|
11696
11722
|
settings: record(string(), unknown()).optional()
|
|
11697
11723
|
}));
|
|
@@ -11716,7 +11742,9 @@ var PipelineModelOptionSchema = object({
|
|
|
11716
11742
|
formats: record(string(), object({
|
|
11717
11743
|
downloaded: boolean(),
|
|
11718
11744
|
sizeMB: number()
|
|
11719
|
-
}))
|
|
11745
|
+
})),
|
|
11746
|
+
group: ModelVariantGroupSchema.optional(),
|
|
11747
|
+
legacy: boolean().optional()
|
|
11720
11748
|
});
|
|
11721
11749
|
var ConfigFieldBridge = custom();
|
|
11722
11750
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -11767,15 +11795,42 @@ var EngineProvisioningSchema = object({
|
|
|
11767
11795
|
]),
|
|
11768
11796
|
progress: number().optional(),
|
|
11769
11797
|
error: string().optional(),
|
|
11770
|
-
nextRetryAt: number().optional()
|
|
11798
|
+
nextRetryAt: number().optional(),
|
|
11799
|
+
/**
|
|
11800
|
+
* Gate A (config-correctness gate at engine change): human-readable
|
|
11801
|
+
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
11802
|
+
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
11803
|
+
* has a <format> build"). Additive/optional: informational only, never
|
|
11804
|
+
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
11805
|
+
* Absent/empty when the node-default tree resolves cleanly.
|
|
11806
|
+
*/
|
|
11807
|
+
configIssues: array(string()).optional()
|
|
11771
11808
|
});
|
|
11772
11809
|
var PipelineStepInputSchema = lazy(() => object({
|
|
11773
11810
|
addonId: string(),
|
|
11774
|
-
modelId: string(),
|
|
11811
|
+
modelId: string().optional(),
|
|
11775
11812
|
enabled: boolean().default(true),
|
|
11776
11813
|
children: array(PipelineStepInputSchema).optional(),
|
|
11777
11814
|
settings: record(string(), unknown()).optional()
|
|
11778
11815
|
}));
|
|
11816
|
+
var ModelSubstitutionSchema = object({
|
|
11817
|
+
addonId: string(),
|
|
11818
|
+
chosen: string(),
|
|
11819
|
+
running: string(),
|
|
11820
|
+
format: string()
|
|
11821
|
+
});
|
|
11822
|
+
var PipelineValidationIssueSchema = object({
|
|
11823
|
+
addonId: string(),
|
|
11824
|
+
kind: _enum(["unknown-addon", "no-format-build"]),
|
|
11825
|
+
detail: string()
|
|
11826
|
+
});
|
|
11827
|
+
var PipelineValidationResultSchema = object({
|
|
11828
|
+
ok: boolean(),
|
|
11829
|
+
issues: array(PipelineValidationIssueSchema).readonly(),
|
|
11830
|
+
substitutions: array(ModelSubstitutionSchema).readonly(),
|
|
11831
|
+
/** The node's `currentEngine.format` this validation ran against. */
|
|
11832
|
+
format: string()
|
|
11833
|
+
});
|
|
11779
11834
|
var ReferenceImageEntrySchema = object({
|
|
11780
11835
|
filename: string(),
|
|
11781
11836
|
stepIds: array(string()).readonly().optional()
|
|
@@ -11846,7 +11901,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
11846
11901
|
})) }), object({ success: literal(true) }), {
|
|
11847
11902
|
kind: "mutation",
|
|
11848
11903
|
auth: "admin"
|
|
11849
|
-
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
11904
|
+
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
11850
11905
|
name: string(),
|
|
11851
11906
|
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
11852
11907
|
engine: PipelineEngineChoiceSchema
|
|
@@ -12139,6 +12194,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
|
|
|
12139
12194
|
kind: literal("remote-restream"),
|
|
12140
12195
|
/** The camera's source-owner node (slice 1: always the hub). */
|
|
12141
12196
|
ownerNodeId: string(),
|
|
12197
|
+
/**
|
|
12198
|
+
* The owner's LAN-reachable host, resolved by the orchestrator from the
|
|
12199
|
+
* per-node `reachableHost` override (Cluster UI). When present the runner
|
|
12200
|
+
* dials THIS host for the owner's restream, in preference to the
|
|
12201
|
+
* `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
|
|
12202
|
+
*/
|
|
12203
|
+
ownerReachableHost: string().optional(),
|
|
12142
12204
|
/** Operator override for the owner host the runner dials. */
|
|
12143
12205
|
hubHostnameOverride: string().optional()
|
|
12144
12206
|
})]).describe("Per-camera frame-source mode for the runner (P2c)");
|
|
@@ -12147,13 +12209,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
|
|
|
12147
12209
|
* specific runner instance via `attachCamera`. Carries everything the
|
|
12148
12210
|
* runner needs to subscribe to the local broker and execute inference.
|
|
12149
12211
|
*
|
|
12150
|
-
* Stateless-pipeline model: the
|
|
12151
|
-
*
|
|
12152
|
-
*
|
|
12153
|
-
*
|
|
12154
|
-
*
|
|
12155
|
-
* `engine`/`steps`/`audio` are optional during the additive migration
|
|
12156
|
-
* window; once orchestrator + UI are migrated they become required.
|
|
12212
|
+
* Stateless-pipeline model: the pipeline content (`steps`, optional
|
|
12213
|
+
* `audio`) travels with the attach payload. The runner keeps it in RAM
|
|
12214
|
+
* for the lifetime of the attach — on rebalance, edit, or restart the
|
|
12215
|
+
* orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
|
|
12216
|
+
* node-local, resolved by the executing runner at dispatch time.
|
|
12157
12217
|
*/
|
|
12158
12218
|
var RunnerCameraConfigSchema = object({
|
|
12159
12219
|
deviceId: number(),
|
|
@@ -12204,14 +12264,11 @@ var RunnerCameraConfigSchema = object({
|
|
|
12204
12264
|
*/
|
|
12205
12265
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
12206
12266
|
pipelineEnabled: boolean().default(true),
|
|
12207
|
-
/** Engine choice for video steps (runtime+backend+format). */
|
|
12208
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
12209
12267
|
/** Ordered tree of video steps. Absent → runner skips video detection. */
|
|
12210
12268
|
steps: array(PipelineStepInputSchema).readonly().optional(),
|
|
12211
12269
|
/** Audio classification branch. `enabled:false` disables, null skips. */
|
|
12212
12270
|
audio: object({
|
|
12213
|
-
|
|
12214
|
-
modelId: string(),
|
|
12271
|
+
modelId: string().optional(),
|
|
12215
12272
|
enabled: boolean()
|
|
12216
12273
|
}).nullable().optional(),
|
|
12217
12274
|
/**
|
|
@@ -18074,11 +18131,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18074
18131
|
timestamp: number()
|
|
18075
18132
|
});
|
|
18076
18133
|
var CameraPipelineConfigSchema = object({
|
|
18077
|
-
engine: PipelineEngineChoiceSchema,
|
|
18134
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
18078
18135
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
18079
18136
|
audio: object({
|
|
18080
|
-
engine: PipelineEngineChoiceSchema,
|
|
18081
|
-
modelId: string(),
|
|
18137
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
18138
|
+
modelId: string().optional(),
|
|
18082
18139
|
enabled: boolean(),
|
|
18083
18140
|
settings: record(string(), unknown()).readonly().optional()
|
|
18084
18141
|
}).nullable().optional()
|
|
@@ -18093,7 +18150,7 @@ var PipelineTemplateSchema = object({
|
|
|
18093
18150
|
});
|
|
18094
18151
|
var AgentAddonConfigSchema = object({
|
|
18095
18152
|
enabled: boolean(),
|
|
18096
|
-
modelId: string(),
|
|
18153
|
+
modelId: string().optional(),
|
|
18097
18154
|
settings: record(string(), unknown()).readonly()
|
|
18098
18155
|
});
|
|
18099
18156
|
var AgentPipelineSettingsSchema = object({
|
|
@@ -18108,7 +18165,15 @@ var AgentPipelineSettingsSchema = object({
|
|
|
18108
18165
|
/** Node is eligible to run audio-analyzer sessions. */
|
|
18109
18166
|
audio: boolean().optional(),
|
|
18110
18167
|
/** Node is eligible to be the ingest / source-owner (serve the restream). */
|
|
18111
|
-
ingest: boolean().optional()
|
|
18168
|
+
ingest: boolean().optional(),
|
|
18169
|
+
/**
|
|
18170
|
+
* Operator override for the LAN host a cross-node decoder dials to reach
|
|
18171
|
+
* THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
|
|
18172
|
+
* falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
|
|
18173
|
+
* it already uses to reach the hub). Set this only when the auto-detected
|
|
18174
|
+
* address is wrong (multi-homed host, NAT, custom interface).
|
|
18175
|
+
*/
|
|
18176
|
+
reachableHost: string().optional()
|
|
18112
18177
|
});
|
|
18113
18178
|
var CameraPipelineForAgentSchema = object({
|
|
18114
18179
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -18214,6 +18279,15 @@ var GlobalMetricsSchema = object({
|
|
|
18214
18279
|
* capability providers.
|
|
18215
18280
|
*/
|
|
18216
18281
|
var CapabilityBindingsSchema = record(string(), string());
|
|
18282
|
+
/**
|
|
18283
|
+
* The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
|
|
18284
|
+
* its LAN-reachable host, if one is registered. See `getIngestOwner`.
|
|
18285
|
+
*/
|
|
18286
|
+
var IngestOwnerSchema = object({
|
|
18287
|
+
ownerNodeId: string(),
|
|
18288
|
+
reachableHost: string().optional(),
|
|
18289
|
+
configIssue: string().optional()
|
|
18290
|
+
});
|
|
18217
18291
|
/** Source block — always present; derives from the stream catalog. */
|
|
18218
18292
|
var CameraSourceStatusSchema = object({ streams: array(object({
|
|
18219
18293
|
camStreamId: string(),
|
|
@@ -18228,6 +18302,14 @@ var CameraAssignmentStatusSchema = object({
|
|
|
18228
18302
|
detectionNodeId: string().nullable(),
|
|
18229
18303
|
decoderNodeId: string().nullable(),
|
|
18230
18304
|
audioNodeId: string().nullable(),
|
|
18305
|
+
/**
|
|
18306
|
+
* The node that OWNS this camera's physical source pull (dials the RTSP and
|
|
18307
|
+
* hosts the broker/restream) — the cluster ingest owner today
|
|
18308
|
+
* (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
|
|
18309
|
+
* the UI show WHERE a camera is sourced without SSH/logs, and is the node the
|
|
18310
|
+
* broker block below was read from (pinned). Nullable only pre-wiring.
|
|
18311
|
+
*/
|
|
18312
|
+
sourceNodeId: string().nullable(),
|
|
18231
18313
|
pinned: object({
|
|
18232
18314
|
detection: boolean(),
|
|
18233
18315
|
decoder: boolean(),
|
|
@@ -18360,7 +18442,7 @@ method(object({
|
|
|
18360
18442
|
}), object({ success: literal(true) }), {
|
|
18361
18443
|
kind: "mutation",
|
|
18362
18444
|
auth: "admin"
|
|
18363
|
-
}), method(object({
|
|
18445
|
+
}), method(_void(), IngestOwnerSchema), method(object({
|
|
18364
18446
|
deviceId: number(),
|
|
18365
18447
|
nodeId: string()
|
|
18366
18448
|
}), _void(), {
|
|
@@ -18429,6 +18511,12 @@ method(object({
|
|
|
18429
18511
|
}), object({ success: literal(true) }), {
|
|
18430
18512
|
kind: "mutation",
|
|
18431
18513
|
auth: "admin"
|
|
18514
|
+
}), method(object({
|
|
18515
|
+
agentNodeId: string(),
|
|
18516
|
+
reachableHost: string().nullable()
|
|
18517
|
+
}), object({ success: literal(true) }), {
|
|
18518
|
+
kind: "mutation",
|
|
18519
|
+
auth: "admin"
|
|
18432
18520
|
}), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
|
|
18433
18521
|
deviceId: number(),
|
|
18434
18522
|
addonId: string(),
|
|
@@ -18473,22 +18561,6 @@ method(object({
|
|
|
18473
18561
|
kind: "mutation",
|
|
18474
18562
|
auth: "admin"
|
|
18475
18563
|
});
|
|
18476
|
-
var RegisteredStreamSchema = object({
|
|
18477
|
-
streamId: string(),
|
|
18478
|
-
label: string().optional(),
|
|
18479
|
-
codec: string(),
|
|
18480
|
-
type: _enum(["video", "audio"]),
|
|
18481
|
-
sourceUrl: string()
|
|
18482
|
-
});
|
|
18483
|
-
var ExposedResourceSchema = object({
|
|
18484
|
-
streamId: string(),
|
|
18485
|
-
format: string(),
|
|
18486
|
-
value: string()
|
|
18487
|
-
});
|
|
18488
|
-
method(object({
|
|
18489
|
-
deviceId: number(),
|
|
18490
|
-
streams: array(RegisteredStreamSchema).readonly()
|
|
18491
|
-
}), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
|
|
18492
18564
|
/**
|
|
18493
18565
|
* Query filter for settings-store collections.
|
|
18494
18566
|
*/
|
|
@@ -18641,9 +18713,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
|
|
|
18641
18713
|
/**
|
|
18642
18714
|
* A single device snapshot returned as base64 JPEG/PNG.
|
|
18643
18715
|
*
|
|
18644
|
-
*
|
|
18645
|
-
*
|
|
18646
|
-
*
|
|
18716
|
+
* The `SnapshotAddon` wrapper returns this shape whether the frame came from
|
|
18717
|
+
* the device-native provider (onboard capture) or from the stream-broker
|
|
18718
|
+
* prebuffer fallback.
|
|
18647
18719
|
*/
|
|
18648
18720
|
var SnapshotImageSchema = object({
|
|
18649
18721
|
base64: string(),
|
|
@@ -18718,10 +18790,6 @@ var snapshotCapability = {
|
|
|
18718
18790
|
kind: "poll"
|
|
18719
18791
|
}
|
|
18720
18792
|
};
|
|
18721
|
-
method(object({ deviceId: number() }), boolean()), method(object({
|
|
18722
|
-
deviceId: number(),
|
|
18723
|
-
streamId: string().optional()
|
|
18724
|
-
}), SnapshotImageSchema.nullable());
|
|
18725
18793
|
/**
|
|
18726
18794
|
* `sso-bridge` — internal hub-only cap that lets SSO-style auth
|
|
18727
18795
|
* providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
|
|
@@ -19082,9 +19150,10 @@ method(object({
|
|
|
19082
19150
|
auth: "admin"
|
|
19083
19151
|
});
|
|
19084
19152
|
/**
|
|
19085
|
-
* Optional client-side hints sent at session creation to help the
|
|
19086
|
-
*
|
|
19087
|
-
*
|
|
19153
|
+
* Optional client-side hints sent at session creation to help the provider
|
|
19154
|
+
* pick the best native source. All fields optional — a viewer that knows
|
|
19155
|
+
* nothing still gets a sane default. (Relocated from the retired `webrtc`
|
|
19156
|
+
* collection cap; this `webrtc-session` cap is the live signaling surface.)
|
|
19088
19157
|
*/
|
|
19089
19158
|
var webrtcClientHintsSchema = object({
|
|
19090
19159
|
viewportWidth: number().int().positive().optional(),
|
|
@@ -19095,22 +19164,6 @@ var webrtcClientHintsSchema = object({
|
|
|
19095
19164
|
/** Hard tier override; takes precedence over scoring when registered. */
|
|
19096
19165
|
prefersTier: string().optional()
|
|
19097
19166
|
}).partial();
|
|
19098
|
-
method(object({
|
|
19099
|
-
streamId: string(),
|
|
19100
|
-
sdpOffer: string()
|
|
19101
|
-
}), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
|
|
19102
|
-
streamId: string(),
|
|
19103
|
-
codec: string()
|
|
19104
|
-
}), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
|
|
19105
|
-
streamId: string(),
|
|
19106
|
-
hints: webrtcClientHintsSchema.optional()
|
|
19107
|
-
}), object({
|
|
19108
|
-
sessionId: string(),
|
|
19109
|
-
sdpOffer: string()
|
|
19110
|
-
}), { kind: "mutation" }), method(object({
|
|
19111
|
-
sessionId: string(),
|
|
19112
|
-
sdpAnswer: string()
|
|
19113
|
-
}), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
|
|
19114
19167
|
/**
|
|
19115
19168
|
* Discriminated target for a WebRTC session. The client sends this
|
|
19116
19169
|
* structured object instead of building / parsing brokerId strings;
|
|
@@ -24500,6 +24553,12 @@ Object.freeze({
|
|
|
24500
24553
|
addonId: null,
|
|
24501
24554
|
access: "create"
|
|
24502
24555
|
},
|
|
24556
|
+
"pipelineExecutor.validatePipeline": {
|
|
24557
|
+
capName: "pipeline-executor",
|
|
24558
|
+
capScope: "system",
|
|
24559
|
+
addonId: null,
|
|
24560
|
+
access: "view"
|
|
24561
|
+
},
|
|
24503
24562
|
"pipelineOrchestrator.assignAudio": {
|
|
24504
24563
|
capName: "pipeline-orchestrator",
|
|
24505
24564
|
capScope: "system",
|
|
@@ -24608,6 +24667,12 @@ Object.freeze({
|
|
|
24608
24667
|
addonId: null,
|
|
24609
24668
|
access: "view"
|
|
24610
24669
|
},
|
|
24670
|
+
"pipelineOrchestrator.getIngestOwner": {
|
|
24671
|
+
capName: "pipeline-orchestrator",
|
|
24672
|
+
capScope: "system",
|
|
24673
|
+
addonId: null,
|
|
24674
|
+
access: "view"
|
|
24675
|
+
},
|
|
24611
24676
|
"pipelineOrchestrator.getPipelineAssignment": {
|
|
24612
24677
|
capName: "pipeline-orchestrator",
|
|
24613
24678
|
capScope: "system",
|
|
@@ -24680,6 +24745,12 @@ Object.freeze({
|
|
|
24680
24745
|
addonId: null,
|
|
24681
24746
|
access: "create"
|
|
24682
24747
|
},
|
|
24748
|
+
"pipelineOrchestrator.setAgentReachableHost": {
|
|
24749
|
+
capName: "pipeline-orchestrator",
|
|
24750
|
+
capScope: "system",
|
|
24751
|
+
addonId: null,
|
|
24752
|
+
access: "create"
|
|
24753
|
+
},
|
|
24683
24754
|
"pipelineOrchestrator.setCameraPipelineForAgent": {
|
|
24684
24755
|
capName: "pipeline-orchestrator",
|
|
24685
24756
|
capScope: "system",
|
|
@@ -25010,24 +25081,6 @@ Object.freeze({
|
|
|
25010
25081
|
addonId: null,
|
|
25011
25082
|
access: "create"
|
|
25012
25083
|
},
|
|
25013
|
-
"restreamer.getExposedResources": {
|
|
25014
|
-
capName: "restreamer",
|
|
25015
|
-
capScope: "system",
|
|
25016
|
-
addonId: null,
|
|
25017
|
-
access: "view"
|
|
25018
|
-
},
|
|
25019
|
-
"restreamer.registerDevice": {
|
|
25020
|
-
capName: "restreamer",
|
|
25021
|
-
capScope: "system",
|
|
25022
|
-
addonId: null,
|
|
25023
|
-
access: "create"
|
|
25024
|
-
},
|
|
25025
|
-
"restreamer.unregisterDevice": {
|
|
25026
|
-
capName: "restreamer",
|
|
25027
|
-
capScope: "system",
|
|
25028
|
-
addonId: null,
|
|
25029
|
-
access: "delete"
|
|
25030
|
-
},
|
|
25031
25084
|
"scriptRunner.run": {
|
|
25032
25085
|
capName: "script-runner",
|
|
25033
25086
|
capScope: "device",
|
|
@@ -25130,18 +25183,6 @@ Object.freeze({
|
|
|
25130
25183
|
addonId: null,
|
|
25131
25184
|
access: "create"
|
|
25132
25185
|
},
|
|
25133
|
-
"snapshotProvider.getSnapshot": {
|
|
25134
|
-
capName: "snapshot-provider",
|
|
25135
|
-
capScope: "system",
|
|
25136
|
-
addonId: null,
|
|
25137
|
-
access: "view"
|
|
25138
|
-
},
|
|
25139
|
-
"snapshotProvider.supportsDevice": {
|
|
25140
|
-
capName: "snapshot-provider",
|
|
25141
|
-
capScope: "system",
|
|
25142
|
-
addonId: null,
|
|
25143
|
-
access: "view"
|
|
25144
|
-
},
|
|
25145
25186
|
"ssoBridge.signBridgeToken": {
|
|
25146
25187
|
capName: "sso-bridge",
|
|
25147
25188
|
capScope: "system",
|
|
@@ -25568,30 +25609,6 @@ Object.freeze({
|
|
|
25568
25609
|
addonId: null,
|
|
25569
25610
|
access: "view"
|
|
25570
25611
|
},
|
|
25571
|
-
"streamingEngine.getStreamUrl": {
|
|
25572
|
-
capName: "streaming-engine",
|
|
25573
|
-
capScope: "system",
|
|
25574
|
-
addonId: null,
|
|
25575
|
-
access: "view"
|
|
25576
|
-
},
|
|
25577
|
-
"streamingEngine.listStreams": {
|
|
25578
|
-
capName: "streaming-engine",
|
|
25579
|
-
capScope: "system",
|
|
25580
|
-
addonId: null,
|
|
25581
|
-
access: "view"
|
|
25582
|
-
},
|
|
25583
|
-
"streamingEngine.registerStream": {
|
|
25584
|
-
capName: "streaming-engine",
|
|
25585
|
-
capScope: "system",
|
|
25586
|
-
addonId: null,
|
|
25587
|
-
access: "create"
|
|
25588
|
-
},
|
|
25589
|
-
"streamingEngine.unregisterStream": {
|
|
25590
|
-
capName: "streaming-engine",
|
|
25591
|
-
capScope: "system",
|
|
25592
|
-
addonId: null,
|
|
25593
|
-
access: "delete"
|
|
25594
|
-
},
|
|
25595
25612
|
"streamParams.getConfigSchema": {
|
|
25596
25613
|
capName: "stream-params",
|
|
25597
25614
|
capScope: "device",
|
|
@@ -25958,54 +25975,6 @@ Object.freeze({
|
|
|
25958
25975
|
addonId: null,
|
|
25959
25976
|
access: "create"
|
|
25960
25977
|
},
|
|
25961
|
-
"webrtc.closeSession": {
|
|
25962
|
-
capName: "webrtc",
|
|
25963
|
-
capScope: "system",
|
|
25964
|
-
addonId: null,
|
|
25965
|
-
access: "create"
|
|
25966
|
-
},
|
|
25967
|
-
"webrtc.createSession": {
|
|
25968
|
-
capName: "webrtc",
|
|
25969
|
-
capScope: "system",
|
|
25970
|
-
addonId: null,
|
|
25971
|
-
access: "create"
|
|
25972
|
-
},
|
|
25973
|
-
"webrtc.handleAnswer": {
|
|
25974
|
-
capName: "webrtc",
|
|
25975
|
-
capScope: "system",
|
|
25976
|
-
addonId: null,
|
|
25977
|
-
access: "create"
|
|
25978
|
-
},
|
|
25979
|
-
"webrtc.handleOffer": {
|
|
25980
|
-
capName: "webrtc",
|
|
25981
|
-
capScope: "system",
|
|
25982
|
-
addonId: null,
|
|
25983
|
-
access: "create"
|
|
25984
|
-
},
|
|
25985
|
-
"webrtc.hasAdaptiveBitrate": {
|
|
25986
|
-
capName: "webrtc",
|
|
25987
|
-
capScope: "system",
|
|
25988
|
-
addonId: null,
|
|
25989
|
-
access: "view"
|
|
25990
|
-
},
|
|
25991
|
-
"webrtc.registerStream": {
|
|
25992
|
-
capName: "webrtc",
|
|
25993
|
-
capScope: "system",
|
|
25994
|
-
addonId: null,
|
|
25995
|
-
access: "create"
|
|
25996
|
-
},
|
|
25997
|
-
"webrtc.supportsStream": {
|
|
25998
|
-
capName: "webrtc",
|
|
25999
|
-
capScope: "system",
|
|
26000
|
-
addonId: null,
|
|
26001
|
-
access: "view"
|
|
26002
|
-
},
|
|
26003
|
-
"webrtc.unregisterStream": {
|
|
26004
|
-
capName: "webrtc",
|
|
26005
|
-
capScope: "system",
|
|
26006
|
-
addonId: null,
|
|
26007
|
-
access: "delete"
|
|
26008
|
-
},
|
|
26009
25978
|
"webrtcSession.addIceCandidate": {
|
|
26010
25979
|
capName: "webrtc-session",
|
|
26011
25980
|
capScope: "device",
|
|
@@ -26535,17 +26504,21 @@ var AmcrestCgiClient = class AmcrestCgiClient {
|
|
|
26535
26504
|
} catch {
|
|
26536
26505
|
return [];
|
|
26537
26506
|
}
|
|
26538
|
-
const out = /* @__PURE__ */ new Map();
|
|
26539
26507
|
const ch = channel - 1;
|
|
26508
|
+
const names = /* @__PURE__ */ new Map();
|
|
26509
|
+
const enabled = /* @__PURE__ */ new Set();
|
|
26540
26510
|
for (const [key, value] of t) {
|
|
26541
|
-
const
|
|
26542
|
-
if (
|
|
26543
|
-
|
|
26544
|
-
|
|
26511
|
+
const nameMatch = new RegExp(`^PtzPreset\\[${ch}\\]\\[(\\d+)\\]\\.Name$`).exec(key);
|
|
26512
|
+
if (nameMatch) {
|
|
26513
|
+
names.set(Number.parseInt(nameMatch[1], 10), value);
|
|
26514
|
+
continue;
|
|
26515
|
+
}
|
|
26516
|
+
const enableMatch = new RegExp(`^PtzPreset\\[${ch}\\]\\[(\\d+)\\]\\.Enable$`).exec(key);
|
|
26517
|
+
if (enableMatch && value.trim().toLowerCase() === "true") enabled.add(Number.parseInt(enableMatch[1], 10));
|
|
26545
26518
|
}
|
|
26546
|
-
return [...
|
|
26547
|
-
id,
|
|
26548
|
-
name:
|
|
26519
|
+
return [...enabled].toSorted((a, b) => a - b).map((idx) => ({
|
|
26520
|
+
id: idx + 1,
|
|
26521
|
+
name: names.get(idx) || `Preset ${idx + 1}`
|
|
26549
26522
|
}));
|
|
26550
26523
|
}
|
|
26551
26524
|
};
|
|
@@ -27179,9 +27152,17 @@ var AmcrestCamera = class AmcrestCamera extends BaseDevice {
|
|
|
27179
27152
|
},
|
|
27180
27153
|
savePreset: async ({ deviceId, presetId, name }) => {
|
|
27181
27154
|
if (deviceId !== this.id) return;
|
|
27182
|
-
const
|
|
27183
|
-
|
|
27184
|
-
|
|
27155
|
+
const client = this.ensureClient();
|
|
27156
|
+
const requested = Number.parseInt(presetId, 10);
|
|
27157
|
+
const DAHUA_MAX_PRESETS = 25;
|
|
27158
|
+
let slot;
|
|
27159
|
+
if (Number.isInteger(requested) && requested >= 1 && requested <= DAHUA_MAX_PRESETS) slot = requested;
|
|
27160
|
+
else {
|
|
27161
|
+
const used = new Set((await client.getPtzPresets(this.channel)).map((p) => p.id));
|
|
27162
|
+
slot = 1;
|
|
27163
|
+
while (used.has(slot)) slot += 1;
|
|
27164
|
+
}
|
|
27165
|
+
await client.ptzSetPreset(this.channel, slot);
|
|
27185
27166
|
},
|
|
27186
27167
|
deletePreset: async ({ deviceId, presetId }) => {
|
|
27187
27168
|
if (deviceId !== this.id) return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-amcrest",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Amcrest/Dahua camera device provider addon for CamStack — Dahua CGI over HTTP(S) with digest auth (snapshot, RTSP catalog, PTZ, image/day-night config)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|