@camstack/addon-ai 0.4.119 → 0.4.121
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 +180 -6
- package/dist/addon.mjs +180 -6
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5520,7 +5520,7 @@ function number(params) {
|
|
|
5520
5520
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
5521
5521
|
}
|
|
5522
5522
|
//#endregion
|
|
5523
|
-
//#region ../types/dist/sleep-
|
|
5523
|
+
//#region ../types/dist/sleep-Bs3xPtSh.mjs
|
|
5524
5524
|
/**
|
|
5525
5525
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5526
5526
|
* window to float samples (D455).
|
|
@@ -12024,6 +12024,24 @@ var GetStreamWithCodecInputSchema = object({
|
|
|
12024
12024
|
});
|
|
12025
12025
|
var RtpSourceSchema = object({
|
|
12026
12026
|
url: string(),
|
|
12027
|
+
/**
|
|
12028
|
+
* The SENTRY counterpart of {@link url} — the dial that asks for the stream
|
|
12029
|
+
* WITHOUT asking for the camera — or `null` when this camera offers none.
|
|
12030
|
+
*
|
|
12031
|
+
* The broker answers it because the broker is the only thing that can:
|
|
12032
|
+
* eligibility is `sentryEligible` (a BATTERY camera that DECLARES the signals
|
|
12033
|
+
* cap), asked of facts only the broker holds. A consumer re-deriving it from
|
|
12034
|
+
* cap bindings would be a second authority, and two authorities on the same
|
|
12035
|
+
* question is how a composite camera ends up dialling a sleeping camera
|
|
12036
|
+
* because its own copy of the rule was a release behind.
|
|
12037
|
+
*
|
|
12038
|
+
* `null` is a real answer and is never a live url in disguise: a consumer
|
|
12039
|
+
* that silently fell back to {@link url} would perform exactly the wake this
|
|
12040
|
+
* field exists to prevent. Only a PASSTHROUGH acquisition can offer one — a
|
|
12041
|
+
* transcode hands back an egress the broker is feeding itself, which has no
|
|
12042
|
+
* sentry counterpart.
|
|
12043
|
+
*/
|
|
12044
|
+
sentryUrl: string().nullable().optional(),
|
|
12027
12045
|
videoCodec: _enum(["H264", "H265"]),
|
|
12028
12046
|
audioCodec: string(),
|
|
12029
12047
|
resolution: object({
|
|
@@ -27460,6 +27478,114 @@ DeviceType.Light, DeviceType.Siren, DeviceType.Switch, method(object({
|
|
|
27460
27478
|
lastChangedAt: number$1()
|
|
27461
27479
|
});
|
|
27462
27480
|
/**
|
|
27481
|
+
* camera-grid-layout — the geometry of a COMPOSITE camera, on the camera's own
|
|
27482
|
+
* page.
|
|
27483
|
+
*
|
|
27484
|
+
* ## Why this is a capability and not an addon settings schema
|
|
27485
|
+
*
|
|
27486
|
+
* It was one, and it did not render. The addon declared the editor as a
|
|
27487
|
+
* `type: 'widget'` field inside its own `deviceSettingsSchema()`; the hub
|
|
27488
|
+
* returned that section correctly and `ConfigFormField` renders `type:'widget'`
|
|
27489
|
+
* perfectly well — and nothing ever asked camera-grid for it. The Cluster →
|
|
27490
|
+
* Pipeline → Device Overrides page interrogates a HAND-WRITTEN list of four
|
|
27491
|
+
* addons (`PIPELINE_CLUSTER_DEVICE_ADDONS`), whose own comment says an addon
|
|
27492
|
+
* not on it "falls off silently".
|
|
27493
|
+
*
|
|
27494
|
+
* Adding a fifth name to that list would have been the wrong fix twice over:
|
|
27495
|
+
* that page is per-camera DETECTION tuning, and a grid's geometry belongs
|
|
27496
|
+
* beside PTZ and motion zones on the camera itself — which is exactly where the
|
|
27497
|
+
* framework already puts a widget, when the widget is declared on a CAPABILITY.
|
|
27498
|
+
* `deviceConfig.ui` is the mechanism (`motion-zones`, `ptz`, `ptz-autotrack`
|
|
27499
|
+
* all use it): the framework emits the structural section and the widget
|
|
27500
|
+
* self-persists through the cap's own mutations.
|
|
27501
|
+
*
|
|
27502
|
+
* ## Why one addon may implement it
|
|
27503
|
+
*
|
|
27504
|
+
* It is a device-scoped NATIVE cap, registered by the grid camera device
|
|
27505
|
+
* itself. Nothing else declares a composite camera, so nothing else has a
|
|
27506
|
+
* layout — and the device-scoped route means the widget asks THE camera, not
|
|
27507
|
+
* "the camera-grid addon", which is what let the old custom-action pair be
|
|
27508
|
+
* reached only by a caller that already knew the addon id.
|
|
27509
|
+
*
|
|
27510
|
+
* ## The tab
|
|
27511
|
+
*
|
|
27512
|
+
* `streaming`, not a top-tab of its own. A grid's geometry IS what its stream
|
|
27513
|
+
* is, so the Streaming tab is where it belongs; a `grid` top-tab would need an
|
|
27514
|
+
* entry in `WELL_KNOWN_TAB_MAP` or the device page renders the raw id as the
|
|
27515
|
+
* label (measured on the robot camera, 2026-09-06 — a tab called "navigation"
|
|
27516
|
+
* next to "PTZ").
|
|
27517
|
+
*/
|
|
27518
|
+
/** A rectangle in normalized [0,1] coordinates of whatever contains it. */
|
|
27519
|
+
var GridNormalizedRectSchema = object({
|
|
27520
|
+
x: number$1().min(0).max(1),
|
|
27521
|
+
y: number$1().min(0).max(1),
|
|
27522
|
+
width: number$1().gt(0).max(1),
|
|
27523
|
+
height: number$1().gt(0).max(1)
|
|
27524
|
+
});
|
|
27525
|
+
/**
|
|
27526
|
+
* One source camera, the part of its picture taken, and where that part lands.
|
|
27527
|
+
*
|
|
27528
|
+
* Both rectangles are NORMALIZED (D519): a source camera can change resolution
|
|
27529
|
+
* — a profile switch, a firmware update, a substream that comes back different
|
|
27530
|
+
* — and a stored PIXEL rectangle would quietly start cutting the wrong region,
|
|
27531
|
+
* which is the class of bug nobody files.
|
|
27532
|
+
*/
|
|
27533
|
+
var GridLayoutCellSchema = object({
|
|
27534
|
+
deviceId: number$1().int().positive(),
|
|
27535
|
+
/** The part of the SOURCE taken, normalized against the source. */
|
|
27536
|
+
source: GridNormalizedRectSchema,
|
|
27537
|
+
/** Where it lands, normalized against the CANVAS. */
|
|
27538
|
+
cell: GridNormalizedRectSchema
|
|
27539
|
+
});
|
|
27540
|
+
/**
|
|
27541
|
+
* Which profiles this grid can actually compose, and why not.
|
|
27542
|
+
*
|
|
27543
|
+
* A grid's `high` composes its sources' `high` and its `low` their `low`, so a
|
|
27544
|
+
* profile is on offer only when EVERY source can serve it. The refusal NAMES
|
|
27545
|
+
* the sources, because "this grid has no low" is not a finding — "615 has no
|
|
27546
|
+
* low" is, and it is the one an operator can act on.
|
|
27547
|
+
*/
|
|
27548
|
+
var GridProfileOfferSchema = object({
|
|
27549
|
+
profile: _enum([
|
|
27550
|
+
"high",
|
|
27551
|
+
"mid",
|
|
27552
|
+
"low"
|
|
27553
|
+
]),
|
|
27554
|
+
offered: boolean(),
|
|
27555
|
+
/** Sources that cannot serve it. Empty when it is offered, or when there are no cells. */
|
|
27556
|
+
missingSources: array(number$1().int().positive())
|
|
27557
|
+
});
|
|
27558
|
+
var GridLayoutViewSchema = object({
|
|
27559
|
+
/** The persisted grid row this camera was declared from. */
|
|
27560
|
+
instanceId: string(),
|
|
27561
|
+
deviceId: number$1().int().nonnegative(),
|
|
27562
|
+
name: string(),
|
|
27563
|
+
/** The canvas the operator laid out — this grid's `high`. mid/low are scaled from it. */
|
|
27564
|
+
width: number$1().int(),
|
|
27565
|
+
height: number$1().int(),
|
|
27566
|
+
fps: number$1().int(),
|
|
27567
|
+
cells: array(GridLayoutCellSchema),
|
|
27568
|
+
/** What the catalog will publish, and what it refuses to. Read-only. */
|
|
27569
|
+
profiles: array(GridProfileOfferSchema)
|
|
27570
|
+
});
|
|
27571
|
+
var GridLayoutPatchSchema = object({
|
|
27572
|
+
deviceId: number$1().int().nonnegative(),
|
|
27573
|
+
name: string().min(1).max(160).optional(),
|
|
27574
|
+
width: number$1().int().min(160).max(7680).optional(),
|
|
27575
|
+
height: number$1().int().min(120).max(4320).optional(),
|
|
27576
|
+
fps: number$1().int().min(1).max(60).optional(),
|
|
27577
|
+
/**
|
|
27578
|
+
* The whole cell list at once. A per-cell patch would need an ordering the
|
|
27579
|
+
* editor does not have, and a half-applied layout is a picture nobody asked
|
|
27580
|
+
* for.
|
|
27581
|
+
*/
|
|
27582
|
+
cells: array(GridLayoutCellSchema).max(16)
|
|
27583
|
+
});
|
|
27584
|
+
DeviceType.Camera, method(object({ deviceId: number$1().int().nonnegative() }), GridLayoutViewSchema.nullable(), { auth: "admin" }), method(GridLayoutPatchSchema, GridLayoutViewSchema, {
|
|
27585
|
+
kind: "mutation",
|
|
27586
|
+
auth: "admin"
|
|
27587
|
+
});
|
|
27588
|
+
/**
|
|
27463
27589
|
* Motion-zones share the same MaskShape vocabulary as privacy-mask — the
|
|
27464
27590
|
* on-camera motion-detection mask is a single `grid` region (a row-major
|
|
27465
27591
|
* boolean cell lattice the camera's onboard VMD evaluates). Composing it as
|
|
@@ -29159,6 +29285,26 @@ var PtzHomePresetSchema = object({
|
|
|
29159
29285
|
"none"
|
|
29160
29286
|
])
|
|
29161
29287
|
});
|
|
29288
|
+
/**
|
|
29289
|
+
* The camera's own idle-return behaviour: whether it goes home by itself, and
|
|
29290
|
+
* after how long.
|
|
29291
|
+
*
|
|
29292
|
+
* ONE shape, not two scalars, because on the camera they are ONE fact —
|
|
29293
|
+
* Reolink's guard point carries `benable` and `timeout` in the same element,
|
|
29294
|
+
* written by the same command. Reading them apart means two round-trips that
|
|
29295
|
+
* can disagree.
|
|
29296
|
+
*
|
|
29297
|
+
* `enabled` and `seconds` are INDEPENDENT: a camera can hold a 68 s delay with
|
|
29298
|
+
* the behaviour switched off, which is exactly what the vendor app leaves when
|
|
29299
|
+
* you turn the guard point off without clearing it. The first version of this
|
|
29300
|
+
* cap reported only the delay, so that state was invisible — a camera could be
|
|
29301
|
+
* configured to return after 68 seconds with no way to say whether it should
|
|
29302
|
+
* return at all.
|
|
29303
|
+
*/
|
|
29304
|
+
var PtzHomeReturnSchema = object({
|
|
29305
|
+
enabled: boolean(),
|
|
29306
|
+
seconds: number$1().int()
|
|
29307
|
+
});
|
|
29162
29308
|
DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(PtzMoveCommandSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), array(PtzPresetSchema)), method(object({
|
|
29163
29309
|
deviceId: number$1(),
|
|
29164
29310
|
presetId: string()
|
|
@@ -29184,8 +29330,9 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number$1() }),
|
|
|
29184
29330
|
}), method(object({ deviceId: number$1() }), _void(), {
|
|
29185
29331
|
kind: "mutation",
|
|
29186
29332
|
auth: "admin"
|
|
29187
|
-
}), method(object({ deviceId: number$1() }),
|
|
29333
|
+
}), method(object({ deviceId: number$1() }), PtzHomeReturnSchema.nullable()), method(object({
|
|
29188
29334
|
deviceId: number$1(),
|
|
29335
|
+
enabled: boolean(),
|
|
29189
29336
|
seconds: number$1().int().min(0).max(3600)
|
|
29190
29337
|
}), _void(), {
|
|
29191
29338
|
kind: "mutation",
|
|
@@ -32467,6 +32614,18 @@ Object.freeze({
|
|
|
32467
32614
|
addonId: null,
|
|
32468
32615
|
access: "view"
|
|
32469
32616
|
},
|
|
32617
|
+
"cameraGridLayout.getLayout": {
|
|
32618
|
+
capName: "camera-grid-layout",
|
|
32619
|
+
capScope: "device",
|
|
32620
|
+
addonId: null,
|
|
32621
|
+
access: "view"
|
|
32622
|
+
},
|
|
32623
|
+
"cameraGridLayout.saveLayout": {
|
|
32624
|
+
capName: "camera-grid-layout",
|
|
32625
|
+
capScope: "device",
|
|
32626
|
+
addonId: null,
|
|
32627
|
+
access: "create"
|
|
32628
|
+
},
|
|
32470
32629
|
"cameraStreams.getBrokerStreams": {
|
|
32471
32630
|
capName: "camera-streams",
|
|
32472
32631
|
capScope: "device",
|
|
@@ -36217,7 +36376,7 @@ Object.freeze({
|
|
|
36217
36376
|
addonId: null,
|
|
36218
36377
|
access: "view"
|
|
36219
36378
|
},
|
|
36220
|
-
"ptz.
|
|
36379
|
+
"ptz.getHomeReturn": {
|
|
36221
36380
|
capName: "ptz",
|
|
36222
36381
|
capScope: "device",
|
|
36223
36382
|
addonId: null,
|
|
@@ -36277,7 +36436,7 @@ Object.freeze({
|
|
|
36277
36436
|
addonId: null,
|
|
36278
36437
|
access: "create"
|
|
36279
36438
|
},
|
|
36280
|
-
"ptz.
|
|
36439
|
+
"ptz.setHomeReturn": {
|
|
36281
36440
|
capName: "ptz",
|
|
36282
36441
|
capScope: "device",
|
|
36283
36442
|
addonId: null,
|
|
@@ -38166,6 +38325,21 @@ Object.freeze({
|
|
|
38166
38325
|
form: "single",
|
|
38167
38326
|
optional: false
|
|
38168
38327
|
}],
|
|
38328
|
+
"cameraGridLayout.getLayout": [{
|
|
38329
|
+
name: "deviceId",
|
|
38330
|
+
form: "single",
|
|
38331
|
+
optional: false
|
|
38332
|
+
}],
|
|
38333
|
+
"cameraGridLayout.saveLayout": [{
|
|
38334
|
+
name: "cells",
|
|
38335
|
+
form: "object-array",
|
|
38336
|
+
optional: false,
|
|
38337
|
+
itemField: "deviceId"
|
|
38338
|
+
}, {
|
|
38339
|
+
name: "deviceId",
|
|
38340
|
+
form: "single",
|
|
38341
|
+
optional: false
|
|
38342
|
+
}],
|
|
38169
38343
|
"cameraStreams.getBrokerStreams": [{
|
|
38170
38344
|
name: "deviceId",
|
|
38171
38345
|
form: "single",
|
|
@@ -39466,7 +39640,7 @@ Object.freeze({
|
|
|
39466
39640
|
form: "single",
|
|
39467
39641
|
optional: false
|
|
39468
39642
|
}],
|
|
39469
|
-
"ptz.
|
|
39643
|
+
"ptz.getHomeReturn": [{
|
|
39470
39644
|
name: "deviceId",
|
|
39471
39645
|
form: "single",
|
|
39472
39646
|
optional: false
|
|
@@ -39516,7 +39690,7 @@ Object.freeze({
|
|
|
39516
39690
|
form: "single",
|
|
39517
39691
|
optional: false
|
|
39518
39692
|
}],
|
|
39519
|
-
"ptz.
|
|
39693
|
+
"ptz.setHomeReturn": [{
|
|
39520
39694
|
name: "deviceId",
|
|
39521
39695
|
form: "single",
|
|
39522
39696
|
optional: false
|
package/dist/addon.mjs
CHANGED
|
@@ -5547,7 +5547,7 @@ function number(params) {
|
|
|
5547
5547
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
5548
5548
|
}
|
|
5549
5549
|
//#endregion
|
|
5550
|
-
//#region ../types/dist/sleep-
|
|
5550
|
+
//#region ../types/dist/sleep-Bs3xPtSh.mjs
|
|
5551
5551
|
/**
|
|
5552
5552
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5553
5553
|
* window to float samples (D455).
|
|
@@ -12051,6 +12051,24 @@ var GetStreamWithCodecInputSchema = object({
|
|
|
12051
12051
|
});
|
|
12052
12052
|
var RtpSourceSchema = object({
|
|
12053
12053
|
url: string(),
|
|
12054
|
+
/**
|
|
12055
|
+
* The SENTRY counterpart of {@link url} — the dial that asks for the stream
|
|
12056
|
+
* WITHOUT asking for the camera — or `null` when this camera offers none.
|
|
12057
|
+
*
|
|
12058
|
+
* The broker answers it because the broker is the only thing that can:
|
|
12059
|
+
* eligibility is `sentryEligible` (a BATTERY camera that DECLARES the signals
|
|
12060
|
+
* cap), asked of facts only the broker holds. A consumer re-deriving it from
|
|
12061
|
+
* cap bindings would be a second authority, and two authorities on the same
|
|
12062
|
+
* question is how a composite camera ends up dialling a sleeping camera
|
|
12063
|
+
* because its own copy of the rule was a release behind.
|
|
12064
|
+
*
|
|
12065
|
+
* `null` is a real answer and is never a live url in disguise: a consumer
|
|
12066
|
+
* that silently fell back to {@link url} would perform exactly the wake this
|
|
12067
|
+
* field exists to prevent. Only a PASSTHROUGH acquisition can offer one — a
|
|
12068
|
+
* transcode hands back an egress the broker is feeding itself, which has no
|
|
12069
|
+
* sentry counterpart.
|
|
12070
|
+
*/
|
|
12071
|
+
sentryUrl: string().nullable().optional(),
|
|
12054
12072
|
videoCodec: _enum(["H264", "H265"]),
|
|
12055
12073
|
audioCodec: string(),
|
|
12056
12074
|
resolution: object({
|
|
@@ -27487,6 +27505,114 @@ DeviceType.Light, DeviceType.Siren, DeviceType.Switch, method(object({
|
|
|
27487
27505
|
lastChangedAt: number$1()
|
|
27488
27506
|
});
|
|
27489
27507
|
/**
|
|
27508
|
+
* camera-grid-layout — the geometry of a COMPOSITE camera, on the camera's own
|
|
27509
|
+
* page.
|
|
27510
|
+
*
|
|
27511
|
+
* ## Why this is a capability and not an addon settings schema
|
|
27512
|
+
*
|
|
27513
|
+
* It was one, and it did not render. The addon declared the editor as a
|
|
27514
|
+
* `type: 'widget'` field inside its own `deviceSettingsSchema()`; the hub
|
|
27515
|
+
* returned that section correctly and `ConfigFormField` renders `type:'widget'`
|
|
27516
|
+
* perfectly well — and nothing ever asked camera-grid for it. The Cluster →
|
|
27517
|
+
* Pipeline → Device Overrides page interrogates a HAND-WRITTEN list of four
|
|
27518
|
+
* addons (`PIPELINE_CLUSTER_DEVICE_ADDONS`), whose own comment says an addon
|
|
27519
|
+
* not on it "falls off silently".
|
|
27520
|
+
*
|
|
27521
|
+
* Adding a fifth name to that list would have been the wrong fix twice over:
|
|
27522
|
+
* that page is per-camera DETECTION tuning, and a grid's geometry belongs
|
|
27523
|
+
* beside PTZ and motion zones on the camera itself — which is exactly where the
|
|
27524
|
+
* framework already puts a widget, when the widget is declared on a CAPABILITY.
|
|
27525
|
+
* `deviceConfig.ui` is the mechanism (`motion-zones`, `ptz`, `ptz-autotrack`
|
|
27526
|
+
* all use it): the framework emits the structural section and the widget
|
|
27527
|
+
* self-persists through the cap's own mutations.
|
|
27528
|
+
*
|
|
27529
|
+
* ## Why one addon may implement it
|
|
27530
|
+
*
|
|
27531
|
+
* It is a device-scoped NATIVE cap, registered by the grid camera device
|
|
27532
|
+
* itself. Nothing else declares a composite camera, so nothing else has a
|
|
27533
|
+
* layout — and the device-scoped route means the widget asks THE camera, not
|
|
27534
|
+
* "the camera-grid addon", which is what let the old custom-action pair be
|
|
27535
|
+
* reached only by a caller that already knew the addon id.
|
|
27536
|
+
*
|
|
27537
|
+
* ## The tab
|
|
27538
|
+
*
|
|
27539
|
+
* `streaming`, not a top-tab of its own. A grid's geometry IS what its stream
|
|
27540
|
+
* is, so the Streaming tab is where it belongs; a `grid` top-tab would need an
|
|
27541
|
+
* entry in `WELL_KNOWN_TAB_MAP` or the device page renders the raw id as the
|
|
27542
|
+
* label (measured on the robot camera, 2026-09-06 — a tab called "navigation"
|
|
27543
|
+
* next to "PTZ").
|
|
27544
|
+
*/
|
|
27545
|
+
/** A rectangle in normalized [0,1] coordinates of whatever contains it. */
|
|
27546
|
+
var GridNormalizedRectSchema = object({
|
|
27547
|
+
x: number$1().min(0).max(1),
|
|
27548
|
+
y: number$1().min(0).max(1),
|
|
27549
|
+
width: number$1().gt(0).max(1),
|
|
27550
|
+
height: number$1().gt(0).max(1)
|
|
27551
|
+
});
|
|
27552
|
+
/**
|
|
27553
|
+
* One source camera, the part of its picture taken, and where that part lands.
|
|
27554
|
+
*
|
|
27555
|
+
* Both rectangles are NORMALIZED (D519): a source camera can change resolution
|
|
27556
|
+
* — a profile switch, a firmware update, a substream that comes back different
|
|
27557
|
+
* — and a stored PIXEL rectangle would quietly start cutting the wrong region,
|
|
27558
|
+
* which is the class of bug nobody files.
|
|
27559
|
+
*/
|
|
27560
|
+
var GridLayoutCellSchema = object({
|
|
27561
|
+
deviceId: number$1().int().positive(),
|
|
27562
|
+
/** The part of the SOURCE taken, normalized against the source. */
|
|
27563
|
+
source: GridNormalizedRectSchema,
|
|
27564
|
+
/** Where it lands, normalized against the CANVAS. */
|
|
27565
|
+
cell: GridNormalizedRectSchema
|
|
27566
|
+
});
|
|
27567
|
+
/**
|
|
27568
|
+
* Which profiles this grid can actually compose, and why not.
|
|
27569
|
+
*
|
|
27570
|
+
* A grid's `high` composes its sources' `high` and its `low` their `low`, so a
|
|
27571
|
+
* profile is on offer only when EVERY source can serve it. The refusal NAMES
|
|
27572
|
+
* the sources, because "this grid has no low" is not a finding — "615 has no
|
|
27573
|
+
* low" is, and it is the one an operator can act on.
|
|
27574
|
+
*/
|
|
27575
|
+
var GridProfileOfferSchema = object({
|
|
27576
|
+
profile: _enum([
|
|
27577
|
+
"high",
|
|
27578
|
+
"mid",
|
|
27579
|
+
"low"
|
|
27580
|
+
]),
|
|
27581
|
+
offered: boolean(),
|
|
27582
|
+
/** Sources that cannot serve it. Empty when it is offered, or when there are no cells. */
|
|
27583
|
+
missingSources: array(number$1().int().positive())
|
|
27584
|
+
});
|
|
27585
|
+
var GridLayoutViewSchema = object({
|
|
27586
|
+
/** The persisted grid row this camera was declared from. */
|
|
27587
|
+
instanceId: string(),
|
|
27588
|
+
deviceId: number$1().int().nonnegative(),
|
|
27589
|
+
name: string(),
|
|
27590
|
+
/** The canvas the operator laid out — this grid's `high`. mid/low are scaled from it. */
|
|
27591
|
+
width: number$1().int(),
|
|
27592
|
+
height: number$1().int(),
|
|
27593
|
+
fps: number$1().int(),
|
|
27594
|
+
cells: array(GridLayoutCellSchema),
|
|
27595
|
+
/** What the catalog will publish, and what it refuses to. Read-only. */
|
|
27596
|
+
profiles: array(GridProfileOfferSchema)
|
|
27597
|
+
});
|
|
27598
|
+
var GridLayoutPatchSchema = object({
|
|
27599
|
+
deviceId: number$1().int().nonnegative(),
|
|
27600
|
+
name: string().min(1).max(160).optional(),
|
|
27601
|
+
width: number$1().int().min(160).max(7680).optional(),
|
|
27602
|
+
height: number$1().int().min(120).max(4320).optional(),
|
|
27603
|
+
fps: number$1().int().min(1).max(60).optional(),
|
|
27604
|
+
/**
|
|
27605
|
+
* The whole cell list at once. A per-cell patch would need an ordering the
|
|
27606
|
+
* editor does not have, and a half-applied layout is a picture nobody asked
|
|
27607
|
+
* for.
|
|
27608
|
+
*/
|
|
27609
|
+
cells: array(GridLayoutCellSchema).max(16)
|
|
27610
|
+
});
|
|
27611
|
+
DeviceType.Camera, method(object({ deviceId: number$1().int().nonnegative() }), GridLayoutViewSchema.nullable(), { auth: "admin" }), method(GridLayoutPatchSchema, GridLayoutViewSchema, {
|
|
27612
|
+
kind: "mutation",
|
|
27613
|
+
auth: "admin"
|
|
27614
|
+
});
|
|
27615
|
+
/**
|
|
27490
27616
|
* Motion-zones share the same MaskShape vocabulary as privacy-mask — the
|
|
27491
27617
|
* on-camera motion-detection mask is a single `grid` region (a row-major
|
|
27492
27618
|
* boolean cell lattice the camera's onboard VMD evaluates). Composing it as
|
|
@@ -29186,6 +29312,26 @@ var PtzHomePresetSchema = object({
|
|
|
29186
29312
|
"none"
|
|
29187
29313
|
])
|
|
29188
29314
|
});
|
|
29315
|
+
/**
|
|
29316
|
+
* The camera's own idle-return behaviour: whether it goes home by itself, and
|
|
29317
|
+
* after how long.
|
|
29318
|
+
*
|
|
29319
|
+
* ONE shape, not two scalars, because on the camera they are ONE fact —
|
|
29320
|
+
* Reolink's guard point carries `benable` and `timeout` in the same element,
|
|
29321
|
+
* written by the same command. Reading them apart means two round-trips that
|
|
29322
|
+
* can disagree.
|
|
29323
|
+
*
|
|
29324
|
+
* `enabled` and `seconds` are INDEPENDENT: a camera can hold a 68 s delay with
|
|
29325
|
+
* the behaviour switched off, which is exactly what the vendor app leaves when
|
|
29326
|
+
* you turn the guard point off without clearing it. The first version of this
|
|
29327
|
+
* cap reported only the delay, so that state was invisible — a camera could be
|
|
29328
|
+
* configured to return after 68 seconds with no way to say whether it should
|
|
29329
|
+
* return at all.
|
|
29330
|
+
*/
|
|
29331
|
+
var PtzHomeReturnSchema = object({
|
|
29332
|
+
enabled: boolean(),
|
|
29333
|
+
seconds: number$1().int()
|
|
29334
|
+
});
|
|
29189
29335
|
DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(PtzMoveCommandSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), array(PtzPresetSchema)), method(object({
|
|
29190
29336
|
deviceId: number$1(),
|
|
29191
29337
|
presetId: string()
|
|
@@ -29211,8 +29357,9 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number$1() }),
|
|
|
29211
29357
|
}), method(object({ deviceId: number$1() }), _void(), {
|
|
29212
29358
|
kind: "mutation",
|
|
29213
29359
|
auth: "admin"
|
|
29214
|
-
}), method(object({ deviceId: number$1() }),
|
|
29360
|
+
}), method(object({ deviceId: number$1() }), PtzHomeReturnSchema.nullable()), method(object({
|
|
29215
29361
|
deviceId: number$1(),
|
|
29362
|
+
enabled: boolean(),
|
|
29216
29363
|
seconds: number$1().int().min(0).max(3600)
|
|
29217
29364
|
}), _void(), {
|
|
29218
29365
|
kind: "mutation",
|
|
@@ -32494,6 +32641,18 @@ Object.freeze({
|
|
|
32494
32641
|
addonId: null,
|
|
32495
32642
|
access: "view"
|
|
32496
32643
|
},
|
|
32644
|
+
"cameraGridLayout.getLayout": {
|
|
32645
|
+
capName: "camera-grid-layout",
|
|
32646
|
+
capScope: "device",
|
|
32647
|
+
addonId: null,
|
|
32648
|
+
access: "view"
|
|
32649
|
+
},
|
|
32650
|
+
"cameraGridLayout.saveLayout": {
|
|
32651
|
+
capName: "camera-grid-layout",
|
|
32652
|
+
capScope: "device",
|
|
32653
|
+
addonId: null,
|
|
32654
|
+
access: "create"
|
|
32655
|
+
},
|
|
32497
32656
|
"cameraStreams.getBrokerStreams": {
|
|
32498
32657
|
capName: "camera-streams",
|
|
32499
32658
|
capScope: "device",
|
|
@@ -36244,7 +36403,7 @@ Object.freeze({
|
|
|
36244
36403
|
addonId: null,
|
|
36245
36404
|
access: "view"
|
|
36246
36405
|
},
|
|
36247
|
-
"ptz.
|
|
36406
|
+
"ptz.getHomeReturn": {
|
|
36248
36407
|
capName: "ptz",
|
|
36249
36408
|
capScope: "device",
|
|
36250
36409
|
addonId: null,
|
|
@@ -36304,7 +36463,7 @@ Object.freeze({
|
|
|
36304
36463
|
addonId: null,
|
|
36305
36464
|
access: "create"
|
|
36306
36465
|
},
|
|
36307
|
-
"ptz.
|
|
36466
|
+
"ptz.setHomeReturn": {
|
|
36308
36467
|
capName: "ptz",
|
|
36309
36468
|
capScope: "device",
|
|
36310
36469
|
addonId: null,
|
|
@@ -38193,6 +38352,21 @@ Object.freeze({
|
|
|
38193
38352
|
form: "single",
|
|
38194
38353
|
optional: false
|
|
38195
38354
|
}],
|
|
38355
|
+
"cameraGridLayout.getLayout": [{
|
|
38356
|
+
name: "deviceId",
|
|
38357
|
+
form: "single",
|
|
38358
|
+
optional: false
|
|
38359
|
+
}],
|
|
38360
|
+
"cameraGridLayout.saveLayout": [{
|
|
38361
|
+
name: "cells",
|
|
38362
|
+
form: "object-array",
|
|
38363
|
+
optional: false,
|
|
38364
|
+
itemField: "deviceId"
|
|
38365
|
+
}, {
|
|
38366
|
+
name: "deviceId",
|
|
38367
|
+
form: "single",
|
|
38368
|
+
optional: false
|
|
38369
|
+
}],
|
|
38196
38370
|
"cameraStreams.getBrokerStreams": [{
|
|
38197
38371
|
name: "deviceId",
|
|
38198
38372
|
form: "single",
|
|
@@ -39493,7 +39667,7 @@ Object.freeze({
|
|
|
39493
39667
|
form: "single",
|
|
39494
39668
|
optional: false
|
|
39495
39669
|
}],
|
|
39496
|
-
"ptz.
|
|
39670
|
+
"ptz.getHomeReturn": [{
|
|
39497
39671
|
name: "deviceId",
|
|
39498
39672
|
form: "single",
|
|
39499
39673
|
optional: false
|
|
@@ -39543,7 +39717,7 @@ Object.freeze({
|
|
|
39543
39717
|
form: "single",
|
|
39544
39718
|
optional: false
|
|
39545
39719
|
}],
|
|
39546
|
-
"ptz.
|
|
39720
|
+
"ptz.setHomeReturn": [{
|
|
39547
39721
|
name: "deviceId",
|
|
39548
39722
|
form: "single",
|
|
39549
39723
|
optional: false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-ai",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.121",
|
|
4
4
|
"description": "AI addon for CamStack — the `llm` collection provider (cloud, LAN, and camstack-managed local llama.cpp profiles) plus the per-node `llm-runtime` managed executor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|