@camstack/addon-provider-wyze 0.2.126 → 0.2.128
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 +244 -135
- package/dist/addon.mjs +244 -135
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -10517,6 +10517,57 @@ var ClipSearchStrictnessSchema = _enum([
|
|
|
10517
10517
|
"balanced",
|
|
10518
10518
|
"strict"
|
|
10519
10519
|
]);
|
|
10520
|
+
new Set([
|
|
10521
|
+
{
|
|
10522
|
+
id: "person",
|
|
10523
|
+
name: "Person"
|
|
10524
|
+
},
|
|
10525
|
+
{
|
|
10526
|
+
id: "vehicle",
|
|
10527
|
+
name: "Vehicle"
|
|
10528
|
+
},
|
|
10529
|
+
{
|
|
10530
|
+
id: "animal",
|
|
10531
|
+
name: "Animal"
|
|
10532
|
+
},
|
|
10533
|
+
{
|
|
10534
|
+
id: "package",
|
|
10535
|
+
name: "Package"
|
|
10536
|
+
}
|
|
10537
|
+
].map((l) => l.id));
|
|
10538
|
+
var COCO_TO_MACRO = {
|
|
10539
|
+
mapping: {
|
|
10540
|
+
person: "person",
|
|
10541
|
+
bicycle: "vehicle",
|
|
10542
|
+
car: "vehicle",
|
|
10543
|
+
motorcycle: "vehicle",
|
|
10544
|
+
airplane: "vehicle",
|
|
10545
|
+
bus: "vehicle",
|
|
10546
|
+
train: "vehicle",
|
|
10547
|
+
truck: "vehicle",
|
|
10548
|
+
boat: "vehicle",
|
|
10549
|
+
bird: "animal",
|
|
10550
|
+
cat: "animal",
|
|
10551
|
+
dog: "animal",
|
|
10552
|
+
horse: "animal",
|
|
10553
|
+
sheep: "animal",
|
|
10554
|
+
cow: "animal",
|
|
10555
|
+
elephant: "animal",
|
|
10556
|
+
bear: "animal",
|
|
10557
|
+
zebra: "animal",
|
|
10558
|
+
giraffe: "animal",
|
|
10559
|
+
suitcase: "package",
|
|
10560
|
+
backpack: "package",
|
|
10561
|
+
handbag: "package"
|
|
10562
|
+
},
|
|
10563
|
+
preserveOriginal: false
|
|
10564
|
+
};
|
|
10565
|
+
/** Steps a root detector may declare it fills. */
|
|
10566
|
+
var FILLABLE_STEP_IDS = [
|
|
10567
|
+
"animal-classifier",
|
|
10568
|
+
"vehicle-classifier",
|
|
10569
|
+
"package-detection"
|
|
10570
|
+
];
|
|
10520
10571
|
var MODEL_FORMATS = [
|
|
10521
10572
|
"onnx",
|
|
10522
10573
|
"coreml",
|
|
@@ -10586,11 +10637,11 @@ var ModelVariantGroupSchema = object({
|
|
|
10586
10637
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
10587
10638
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
10588
10639
|
/**
|
|
10589
|
-
*
|
|
10590
|
-
*
|
|
10591
|
-
*
|
|
10640
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
10641
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
10642
|
+
* label is "Test".
|
|
10592
10643
|
*/
|
|
10593
|
-
optimization: _enum(["standard", "
|
|
10644
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
10594
10645
|
/**
|
|
10595
10646
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
10596
10647
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -10613,9 +10664,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
10613
10664
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
10614
10665
|
* string still parses — the string is lifted into `{ weights }`.
|
|
10615
10666
|
*
|
|
10616
|
-
* Every licence surface (the
|
|
10617
|
-
*
|
|
10618
|
-
*
|
|
10667
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
10668
|
+
* model table) is GENERATED from these records by
|
|
10669
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
10670
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
10619
10671
|
*/
|
|
10620
10672
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
10621
10673
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -10648,6 +10700,12 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
|
|
|
10648
10700
|
/** True when the weights or their data forbid commercial use. */
|
|
10649
10701
|
nonCommercial: boolean().optional()
|
|
10650
10702
|
}));
|
|
10703
|
+
/** One `fillsClassifierEffects` entry — see `ModelCatalogEntry.fillsClassifierEffects`. */
|
|
10704
|
+
var FillsClassifierEffectSchema = object({
|
|
10705
|
+
stepId: _enum(FILLABLE_STEP_IDS),
|
|
10706
|
+
labelToEffect: record(string(), string()),
|
|
10707
|
+
uncovered: array(string()).readonly()
|
|
10708
|
+
});
|
|
10651
10709
|
var ModelCatalogEntrySchema = object({
|
|
10652
10710
|
id: string(),
|
|
10653
10711
|
name: string(),
|
|
@@ -10774,6 +10832,16 @@ var ModelCatalogEntrySchema = object({
|
|
|
10774
10832
|
*/
|
|
10775
10833
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
10776
10834
|
/**
|
|
10835
|
+
* The pipeline steps this ROOT detector already does the work of (D715):
|
|
10836
|
+
* its labels name the effect the step exists to produce (`deer` for
|
|
10837
|
+
* `animal-classifier`, `package` for `package-detection`). Derived from the
|
|
10838
|
+
* labelmap by `deriveClassifierFills`, never hand-written; a COCO model
|
|
10839
|
+
* declares none. Whether a declaration is honoured is the step's own
|
|
10840
|
+
* `labelLink` policy (`resolveLabelLink`). `labelToEffect` values are in
|
|
10841
|
+
* `FILLABLE_STEP_VOCABULARIES` (guard `check-label-link-vocabulary`).
|
|
10842
|
+
*/
|
|
10843
|
+
fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional(),
|
|
10844
|
+
/**
|
|
10777
10845
|
* The model's CLIP feature-space contract (text encoder, dimension, vector
|
|
10778
10846
|
* index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
|
|
10779
10847
|
* CLIP image encoder; its absence is what "not a CLIP model" means to the
|
|
@@ -14246,7 +14314,7 @@ DeviceType.Camera;
|
|
|
14246
14314
|
* This matters here more than anywhere else in the repo, because every provider
|
|
14247
14315
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
14248
14316
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
14249
|
-
* and `http://admin:hunter2@192.168.
|
|
14317
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
14250
14318
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
14251
14319
|
* filling it is the operator's business, not ours.
|
|
14252
14320
|
*
|
|
@@ -17435,7 +17503,7 @@ method(object({
|
|
|
17435
17503
|
timeoutMs: 6e5
|
|
17436
17504
|
});
|
|
17437
17505
|
method(object({
|
|
17438
|
-
|
|
17506
|
+
targetNodeId: string(),
|
|
17439
17507
|
modelId: string(),
|
|
17440
17508
|
format: _enum(MODEL_FORMATS),
|
|
17441
17509
|
entry: ModelCatalogEntrySchema
|
|
@@ -18001,51 +18069,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
18001
18069
|
kind: "mutation",
|
|
18002
18070
|
auth: "admin"
|
|
18003
18071
|
});
|
|
18004
|
-
new Set([
|
|
18005
|
-
{
|
|
18006
|
-
id: "person",
|
|
18007
|
-
name: "Person"
|
|
18008
|
-
},
|
|
18009
|
-
{
|
|
18010
|
-
id: "vehicle",
|
|
18011
|
-
name: "Vehicle"
|
|
18012
|
-
},
|
|
18013
|
-
{
|
|
18014
|
-
id: "animal",
|
|
18015
|
-
name: "Animal"
|
|
18016
|
-
},
|
|
18017
|
-
{
|
|
18018
|
-
id: "package",
|
|
18019
|
-
name: "Package"
|
|
18020
|
-
}
|
|
18021
|
-
].map((l) => l.id));
|
|
18022
|
-
var COCO_TO_MACRO = {
|
|
18023
|
-
mapping: {
|
|
18024
|
-
person: "person",
|
|
18025
|
-
bicycle: "vehicle",
|
|
18026
|
-
car: "vehicle",
|
|
18027
|
-
motorcycle: "vehicle",
|
|
18028
|
-
airplane: "vehicle",
|
|
18029
|
-
bus: "vehicle",
|
|
18030
|
-
train: "vehicle",
|
|
18031
|
-
truck: "vehicle",
|
|
18032
|
-
boat: "vehicle",
|
|
18033
|
-
bird: "animal",
|
|
18034
|
-
cat: "animal",
|
|
18035
|
-
dog: "animal",
|
|
18036
|
-
horse: "animal",
|
|
18037
|
-
sheep: "animal",
|
|
18038
|
-
cow: "animal",
|
|
18039
|
-
elephant: "animal",
|
|
18040
|
-
bear: "animal",
|
|
18041
|
-
zebra: "animal",
|
|
18042
|
-
giraffe: "animal",
|
|
18043
|
-
suitcase: "package",
|
|
18044
|
-
backpack: "package",
|
|
18045
|
-
handbag: "package"
|
|
18046
|
-
},
|
|
18047
|
-
preserveOriginal: false
|
|
18048
|
-
};
|
|
18049
18072
|
var AUDIO_MACRO_LABELS = [
|
|
18050
18073
|
{
|
|
18051
18074
|
id: "speech",
|
|
@@ -18841,6 +18864,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
18841
18864
|
"stream-offline",
|
|
18842
18865
|
"node-online",
|
|
18843
18866
|
"node-offline",
|
|
18867
|
+
"node-restarting",
|
|
18868
|
+
"node-updating",
|
|
18844
18869
|
"node-inference-unavailable",
|
|
18845
18870
|
"detection-blind",
|
|
18846
18871
|
"addon-crash-loop",
|
|
@@ -19939,8 +19964,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
19939
19964
|
disabledTargetIds: array(string()).default([])
|
|
19940
19965
|
});
|
|
19941
19966
|
/**
|
|
19942
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
19943
|
-
* still-true state. `
|
|
19967
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
19968
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
19969
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
19944
19970
|
* job is not an open state, and the alarm stays instant.
|
|
19945
19971
|
*/
|
|
19946
19972
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -19952,6 +19978,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
19952
19978
|
"detection-blind",
|
|
19953
19979
|
"nodes",
|
|
19954
19980
|
"addons",
|
|
19981
|
+
"addon-updates",
|
|
19955
19982
|
"updates"
|
|
19956
19983
|
]);
|
|
19957
19984
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -20432,7 +20459,19 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
20432
20459
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
20433
20460
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
20434
20461
|
*/
|
|
20435
|
-
schedule: NcScheduleSchema.optional()
|
|
20462
|
+
schedule: NcScheduleSchema.optional(),
|
|
20463
|
+
/**
|
|
20464
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
20465
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
20466
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
20467
|
+
*/
|
|
20468
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
20469
|
+
/**
|
|
20470
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
20471
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
20472
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
20473
|
+
*/
|
|
20474
|
+
notifySensorRewatched: boolean().optional()
|
|
20436
20475
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20437
20476
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20438
20477
|
mode: AlarmArmModeSchema,
|
|
@@ -20441,7 +20480,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
20441
20480
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
20442
20481
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
20443
20482
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
20444
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
20483
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
20484
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20485
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
20486
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20487
|
+
notifySensorRewatched: boolean().nullable().optional()
|
|
20445
20488
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20446
20489
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20447
20490
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -21402,39 +21445,19 @@ Object.freeze(Object.fromEntries([{
|
|
|
21402
21445
|
label: "Face recognition model",
|
|
21403
21446
|
defaultModelId: "auraface-r100",
|
|
21404
21447
|
indexName: "the enrolled face gallery",
|
|
21405
|
-
options: [
|
|
21406
|
-
|
|
21407
|
-
|
|
21408
|
-
|
|
21409
|
-
},
|
|
21410
|
-
{
|
|
21411
|
-
id: "arcface-r100",
|
|
21412
|
-
label: "ArcFace (ResNet34)"
|
|
21413
|
-
},
|
|
21414
|
-
{
|
|
21415
|
-
id: "inception-resnet-v1",
|
|
21416
|
-
label: "Inception ResNet V1"
|
|
21417
|
-
}
|
|
21418
|
-
]
|
|
21448
|
+
options: [{
|
|
21449
|
+
id: "auraface-r100",
|
|
21450
|
+
label: "AuraFace R100"
|
|
21451
|
+
}]
|
|
21419
21452
|
}, {
|
|
21420
21453
|
stepId: "clip-embedding",
|
|
21421
21454
|
label: "Semantic search model",
|
|
21422
|
-
defaultModelId: "
|
|
21455
|
+
defaultModelId: "siglip2-b16-224",
|
|
21423
21456
|
indexName: "the object semantic-search index",
|
|
21424
|
-
options: [
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
},
|
|
21429
|
-
{
|
|
21430
|
-
id: "mobileclip-s2",
|
|
21431
|
-
label: "MobileCLIP S2"
|
|
21432
|
-
},
|
|
21433
|
-
{
|
|
21434
|
-
id: "siglip2-b16-224",
|
|
21435
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21436
|
-
}
|
|
21437
|
-
]
|
|
21457
|
+
options: [{
|
|
21458
|
+
id: "siglip2-b16-224",
|
|
21459
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21460
|
+
}]
|
|
21438
21461
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
21439
21462
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
21440
21463
|
stepId: "face-embedding",
|
|
@@ -23489,7 +23512,8 @@ var PipelineModelOptionSchema = object({
|
|
|
23489
23512
|
group: ModelVariantGroupSchema.optional(),
|
|
23490
23513
|
legacy: boolean().optional(),
|
|
23491
23514
|
provider: ModelProviderIdSchema.optional(),
|
|
23492
|
-
defaultConfidence: number().optional()
|
|
23515
|
+
defaultConfidence: number().optional(),
|
|
23516
|
+
fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional()
|
|
23493
23517
|
});
|
|
23494
23518
|
var ConfigFieldBridge = custom();
|
|
23495
23519
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -24322,6 +24346,22 @@ var MotionSourceEnum = _enum([
|
|
|
24322
24346
|
"device-activity"
|
|
24323
24347
|
]);
|
|
24324
24348
|
/**
|
|
24349
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
24350
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
24351
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
24352
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
24353
|
+
* absent when unknown or when the camera itself triggered.
|
|
24354
|
+
*
|
|
24355
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
24356
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
24357
|
+
* runner never decides anything on it.
|
|
24358
|
+
*/
|
|
24359
|
+
var SessionTriggerSchema = object({
|
|
24360
|
+
source: MotionSourceEnum,
|
|
24361
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
24362
|
+
sensorName: string().optional()
|
|
24363
|
+
});
|
|
24364
|
+
/**
|
|
24325
24365
|
* List of motion sources active on a camera. Empty array is valid:
|
|
24326
24366
|
* "no source" — happens for battery cams without firmware motion when
|
|
24327
24367
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -24573,6 +24613,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
24573
24613
|
*/
|
|
24574
24614
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24575
24615
|
/**
|
|
24616
|
+
* What opened this attach, on a SESSION attach only (see
|
|
24617
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
24618
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
24619
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
24620
|
+
* runner then names no source on the phase event.
|
|
24621
|
+
*/
|
|
24622
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
24623
|
+
/**
|
|
24576
24624
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
24577
24625
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
24578
24626
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -32073,7 +32121,7 @@ var LocalInterfaceSchema = object({
|
|
|
32073
32121
|
name: string(),
|
|
32074
32122
|
family: _enum(["IPv4", "IPv6"]),
|
|
32075
32123
|
address: string(),
|
|
32076
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
32124
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
32077
32125
|
cidr: string(),
|
|
32078
32126
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
32079
32127
|
netmask: string(),
|
|
@@ -32127,7 +32175,8 @@ var ConnectionEndpointSchema = object({
|
|
|
32127
32175
|
"lan-ipv4",
|
|
32128
32176
|
"lan-ipv6",
|
|
32129
32177
|
"public",
|
|
32130
|
-
"loopback"
|
|
32178
|
+
"loopback",
|
|
32179
|
+
"app-link"
|
|
32131
32180
|
]),
|
|
32132
32181
|
/**
|
|
32133
32182
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -32196,15 +32245,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
32196
32245
|
localPort: AdvertisedLocalPortSchema
|
|
32197
32246
|
});
|
|
32198
32247
|
/**
|
|
32199
|
-
* The
|
|
32200
|
-
*
|
|
32201
|
-
*
|
|
32248
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
32249
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
32250
|
+
* so the UI can show it either way.
|
|
32202
32251
|
*/
|
|
32203
32252
|
var NotificationEndpointSchema = object({
|
|
32204
32253
|
/** The operator's explicit choice, or null for AUTO. */
|
|
32205
32254
|
baseUrl: string().nullable(),
|
|
32206
|
-
/**
|
|
32207
|
-
|
|
32255
|
+
/**
|
|
32256
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
32257
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
32258
|
+
* answered the public tunnel / mesh here, or null.
|
|
32259
|
+
*/
|
|
32260
|
+
resolved: string().nullable(),
|
|
32261
|
+
/**
|
|
32262
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
32263
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
32264
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
32265
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
32266
|
+
* Absent on a pre-D709 hub.
|
|
32267
|
+
*/
|
|
32268
|
+
appLinkHub: string().nullable()
|
|
32208
32269
|
});
|
|
32209
32270
|
/**
|
|
32210
32271
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -32258,7 +32319,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
32258
32319
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
32259
32320
|
* to avoid mixed-content blocks in the browser. The public
|
|
32260
32321
|
* tunnel always emits `https://` regardless. */
|
|
32261
|
-
scheme: _enum(["http", "https"]).optional()
|
|
32322
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
32323
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
32324
|
+
* an address notification links can be flagged with, not a hub
|
|
32325
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
32326
|
+
includeAppLink: boolean().optional()
|
|
32262
32327
|
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
32263
32328
|
kind: "mutation",
|
|
32264
32329
|
auth: "admin"
|
|
@@ -32587,7 +32652,7 @@ var MeshPeerSchema = object({
|
|
|
32587
32652
|
tags: array(string()).readonly(),
|
|
32588
32653
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
32589
32654
|
exitNodeOption: boolean(),
|
|
32590
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
32655
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
32591
32656
|
advertisedRoutes: array(string()).readonly(),
|
|
32592
32657
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
32593
32658
|
userLogin: string().nullable(),
|
|
@@ -32717,7 +32782,8 @@ var MotionStatusSchema = object({
|
|
|
32717
32782
|
* writes this slice (not even a boot seed), and neither does the runner's
|
|
32718
32783
|
* phase machine: its phase is "a session is attached" for every on-motion
|
|
32719
32784
|
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
32720
|
-
* A provider's `isDetected`
|
|
32785
|
+
* A provider's `isDetected` and `getStatus` answer from the hub's slice
|
|
32786
|
+
* (`hubMotionNativeProvider`).
|
|
32721
32787
|
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
32722
32788
|
* imports) — the provider pushes both edges itself, from the upstream
|
|
32723
32789
|
* system's own state change. That is the sensor's own fact.
|
|
@@ -33915,7 +33981,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
33915
33981
|
*/
|
|
33916
33982
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
33917
33983
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
33918
|
-
readOnly: boolean().optional()
|
|
33984
|
+
readOnly: boolean().optional(),
|
|
33985
|
+
/**
|
|
33986
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
33987
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
33988
|
+
* copy on the binding.
|
|
33989
|
+
*/
|
|
33990
|
+
maxCharacters: number().int().positive().optional()
|
|
33919
33991
|
})).readonly() });
|
|
33920
33992
|
var OsdOverlayPatchSchema = object({
|
|
33921
33993
|
enabled: boolean().optional(),
|
|
@@ -33966,7 +34038,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
33966
34038
|
valuePath: string().min(1).max(64),
|
|
33967
34039
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
33968
34040
|
displayUnit: string().max(16).optional(),
|
|
33969
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
34041
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34042
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
34043
|
+
valueMap: record(string(), string()).optional()
|
|
33970
34044
|
});
|
|
33971
34045
|
/**
|
|
33972
34046
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -34016,18 +34090,11 @@ var OsdSlotBindingSchema = object({
|
|
|
34016
34090
|
source: OsdSourceSchema,
|
|
34017
34091
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
34018
34092
|
template: string().max(96).default("${value}"),
|
|
34019
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
34020
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
34021
34093
|
/**
|
|
34022
34094
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
34023
34095
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
34024
34096
|
*/
|
|
34025
34097
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34026
|
-
/**
|
|
34027
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
34028
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
34029
|
-
*/
|
|
34030
|
-
unitLabel: string().max(8).optional(),
|
|
34031
34098
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
34032
34099
|
valueMap: record(string(), string()).optional(),
|
|
34033
34100
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -34036,9 +34103,7 @@ var OsdSlotBindingSchema = object({
|
|
|
34036
34103
|
* Display gate, in the notification centre's condition vocabulary.
|
|
34037
34104
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
34038
34105
|
*/
|
|
34039
|
-
conditions: NcConditionsSchema.optional()
|
|
34040
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
34041
|
-
fallbackText: string().max(64).default("")
|
|
34106
|
+
conditions: NcConditionsSchema.optional()
|
|
34042
34107
|
});
|
|
34043
34108
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
34044
34109
|
var OsdSlotViewSchema = object({
|
|
@@ -52188,6 +52253,8 @@ new Map(Object.entries({
|
|
|
52188
52253
|
"detection-blind": "device-events",
|
|
52189
52254
|
"node-online": "system",
|
|
52190
52255
|
"node-offline": "system",
|
|
52256
|
+
"node-restarting": "system",
|
|
52257
|
+
"node-updating": "system",
|
|
52191
52258
|
"node-inference-unavailable": "system",
|
|
52192
52259
|
"addon-crash-loop": "system",
|
|
52193
52260
|
"addon-update-available": "system",
|
|
@@ -52265,18 +52332,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
52265
52332
|
kinds: [
|
|
52266
52333
|
"node-offline",
|
|
52267
52334
|
"node-online",
|
|
52335
|
+
"node-restarting",
|
|
52268
52336
|
"node-inference-unavailable"
|
|
52269
52337
|
]
|
|
52270
52338
|
},
|
|
52271
52339
|
{
|
|
52272
52340
|
id: "addons",
|
|
52273
52341
|
family: "system",
|
|
52274
|
-
label: "Addons",
|
|
52275
|
-
kinds: [
|
|
52276
|
-
|
|
52277
|
-
|
|
52278
|
-
|
|
52279
|
-
|
|
52342
|
+
label: "Addons stopped",
|
|
52343
|
+
kinds: ["addon-crash-loop"]
|
|
52344
|
+
},
|
|
52345
|
+
{
|
|
52346
|
+
id: "addon-updates",
|
|
52347
|
+
family: "system",
|
|
52348
|
+
label: "Addon updates",
|
|
52349
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
52280
52350
|
},
|
|
52281
52351
|
{
|
|
52282
52352
|
id: "updates",
|
|
@@ -52284,6 +52354,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
52284
52354
|
label: "Server & container updates",
|
|
52285
52355
|
kinds: [
|
|
52286
52356
|
"server-update-available",
|
|
52357
|
+
"node-updating",
|
|
52287
52358
|
"server-updated",
|
|
52288
52359
|
"wrapper-update-available"
|
|
52289
52360
|
]
|
|
@@ -52431,18 +52502,21 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
52431
52502
|
kinds: [
|
|
52432
52503
|
"node-offline",
|
|
52433
52504
|
"node-online",
|
|
52505
|
+
"node-restarting",
|
|
52434
52506
|
"node-inference-unavailable"
|
|
52435
52507
|
]
|
|
52436
52508
|
},
|
|
52437
52509
|
{
|
|
52438
52510
|
name: "summaryAddons",
|
|
52439
|
-
label: "Summary: addons",
|
|
52440
|
-
example: "
|
|
52441
|
-
kinds: [
|
|
52442
|
-
|
|
52443
|
-
|
|
52444
|
-
|
|
52445
|
-
|
|
52511
|
+
label: "Summary: addons stopped",
|
|
52512
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
52513
|
+
kinds: ["addon-crash-loop"]
|
|
52514
|
+
},
|
|
52515
|
+
{
|
|
52516
|
+
name: "summaryAddonUpdates",
|
|
52517
|
+
label: "Summary: addon updates",
|
|
52518
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
52519
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
52446
52520
|
},
|
|
52447
52521
|
{
|
|
52448
52522
|
name: "summaryUpdates",
|
|
@@ -52450,6 +52524,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
52450
52524
|
example: "server 1.2.377 → 1.2.378",
|
|
52451
52525
|
kinds: [
|
|
52452
52526
|
"server-update-available",
|
|
52527
|
+
"node-updating",
|
|
52453
52528
|
"server-updated",
|
|
52454
52529
|
"wrapper-update-available"
|
|
52455
52530
|
]
|
|
@@ -52526,6 +52601,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
52526
52601
|
[...RULE_BODY_ONLY],
|
|
52527
52602
|
[...RULE_TEXT],
|
|
52528
52603
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
52604
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
52529
52605
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
52530
52606
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
52531
52607
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -52566,6 +52642,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
52566
52642
|
[...RULE_TEXT],
|
|
52567
52643
|
[...RULE_TEXT],
|
|
52568
52644
|
[...RULE_TEXT],
|
|
52645
|
+
[...RULE_TEXT],
|
|
52646
|
+
[...RULE_TEXT],
|
|
52569
52647
|
...STATE_SUMMARY_VARS
|
|
52570
52648
|
];
|
|
52571
52649
|
new Set([
|
|
@@ -52902,10 +52980,9 @@ TimelapseRuleInputSchema.extend({
|
|
|
52902
52980
|
createdAt: number(),
|
|
52903
52981
|
updatedAt: number()
|
|
52904
52982
|
});
|
|
52905
|
-
async function
|
|
52906
|
-
let slice;
|
|
52983
|
+
async function readSlice(deviceState, deviceId) {
|
|
52907
52984
|
try {
|
|
52908
|
-
|
|
52985
|
+
return await deviceState.getCapSlice.query({
|
|
52909
52986
|
deviceId,
|
|
52910
52987
|
capName: "motion"
|
|
52911
52988
|
});
|
|
@@ -52913,10 +52990,44 @@ async function readHubMotionDetected(deviceState, deviceId) {
|
|
|
52913
52990
|
const reason = err instanceof Error ? err.message : String(err);
|
|
52914
52991
|
throw new Error(`motion state of device ${deviceId} is unreadable: ${reason}`, { cause: err });
|
|
52915
52992
|
}
|
|
52916
|
-
|
|
52993
|
+
}
|
|
52994
|
+
/**
|
|
52995
|
+
* The hub's `motion` slice as a `MotionStatus`, or `null` when nobody has
|
|
52996
|
+
* published it since the hub started. Throws when the hub does not answer or
|
|
52997
|
+
* the slice is malformed — never a made-up "no motion".
|
|
52998
|
+
*/
|
|
52999
|
+
async function readHubMotionStatus(deviceState, deviceId) {
|
|
53000
|
+
const slice = await readSlice(deviceState, deviceId);
|
|
53001
|
+
if (slice === null) return null;
|
|
53002
|
+
const parsed = MotionStatusSchema.safeParse(slice);
|
|
53003
|
+
if (!parsed.success) throw new Error(`motion state of device ${deviceId} is malformed on the hub: ${parsed.error.message}`);
|
|
53004
|
+
return parsed.data;
|
|
53005
|
+
}
|
|
53006
|
+
async function readHubMotionDetected(deviceState, deviceId) {
|
|
53007
|
+
const detected = (await readSlice(deviceState, deviceId))?.["detected"];
|
|
52917
53008
|
if (typeof detected !== "boolean") throw new Error(`motion state of device ${deviceId} is not published yet (unknown)`);
|
|
52918
53009
|
return detected;
|
|
52919
53010
|
}
|
|
53011
|
+
/**
|
|
53012
|
+
* The native `motion` provider of a camera whose slice the orchestrator writes
|
|
53013
|
+
* (D696): `isDetected` AND `getStatus`, both from the hub. `owner` names the
|
|
53014
|
+
* provider class in the deviceId-mismatch error.
|
|
53015
|
+
*/
|
|
53016
|
+
function hubMotionNativeProvider(deviceState, deviceId, owner) {
|
|
53017
|
+
const ownDevice = (asked) => {
|
|
53018
|
+
if (asked !== deviceId) throw new Error(`${owner}: motion deviceId mismatch, expected ${deviceId}, got ${asked}`);
|
|
53019
|
+
};
|
|
53020
|
+
return {
|
|
53021
|
+
isDetected: async ({ deviceId: asked }) => {
|
|
53022
|
+
ownDevice(asked);
|
|
53023
|
+
return readHubMotionDetected(deviceState, deviceId);
|
|
53024
|
+
},
|
|
53025
|
+
getStatus: async ({ deviceId: asked }) => {
|
|
53026
|
+
ownDevice(asked);
|
|
53027
|
+
return readHubMotionStatus(deviceState, deviceId);
|
|
53028
|
+
}
|
|
53029
|
+
};
|
|
53030
|
+
}
|
|
52920
53031
|
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
52921
53032
|
function providerMotionEvent(source, data) {
|
|
52922
53033
|
return createEvent(EventCategory.ProviderMotion, source, data);
|
|
@@ -56517,7 +56628,7 @@ function buildCreationFormSchema() {
|
|
|
56517
56628
|
key: "ip",
|
|
56518
56629
|
label: "Local IP",
|
|
56519
56630
|
required: true,
|
|
56520
|
-
placeholder: "192.168.
|
|
56631
|
+
placeholder: "192.168.10.41"
|
|
56521
56632
|
},
|
|
56522
56633
|
{
|
|
56523
56634
|
type: "text",
|
|
@@ -57392,15 +57503,13 @@ var WyzeCamera = class extends BaseDevice {
|
|
|
57392
57503
|
/**
|
|
57393
57504
|
* The native `motion` cap. This provider writes NO `motion` slice (D696): the
|
|
57394
57505
|
* orchestrator is its only writer, with the EFFECTIVE motion, on the hub.
|
|
57395
|
-
* `isDetected`
|
|
57396
|
-
*
|
|
57397
|
-
* (D49, D393).
|
|
57506
|
+
* `isDetected` and `getStatus` answer from the HUB's slice
|
|
57507
|
+
* (`hubMotionNativeProvider`); an unreadable hub fails both — never `false`
|
|
57508
|
+
* for unknown (D49, D393).
|
|
57398
57509
|
*/
|
|
57399
57510
|
registerMotionProvider() {
|
|
57400
|
-
this.ctx.
|
|
57401
|
-
|
|
57402
|
-
return readHubMotionDetected(this.ctx.api.deviceState, this.id);
|
|
57403
|
-
} });
|
|
57511
|
+
const provider = hubMotionNativeProvider(this.ctx.api.deviceState, this.id, "WyzeCamera");
|
|
57512
|
+
this.ctx.registerNativeCap(motionCapability, provider);
|
|
57404
57513
|
}
|
|
57405
57514
|
/**
|
|
57406
57515
|
* Start the configured motion source. `cloud` polls the Wyze events API
|
package/dist/addon.mjs
CHANGED
|
@@ -10496,6 +10496,57 @@ var ClipSearchStrictnessSchema = _enum([
|
|
|
10496
10496
|
"balanced",
|
|
10497
10497
|
"strict"
|
|
10498
10498
|
]);
|
|
10499
|
+
new Set([
|
|
10500
|
+
{
|
|
10501
|
+
id: "person",
|
|
10502
|
+
name: "Person"
|
|
10503
|
+
},
|
|
10504
|
+
{
|
|
10505
|
+
id: "vehicle",
|
|
10506
|
+
name: "Vehicle"
|
|
10507
|
+
},
|
|
10508
|
+
{
|
|
10509
|
+
id: "animal",
|
|
10510
|
+
name: "Animal"
|
|
10511
|
+
},
|
|
10512
|
+
{
|
|
10513
|
+
id: "package",
|
|
10514
|
+
name: "Package"
|
|
10515
|
+
}
|
|
10516
|
+
].map((l) => l.id));
|
|
10517
|
+
var COCO_TO_MACRO = {
|
|
10518
|
+
mapping: {
|
|
10519
|
+
person: "person",
|
|
10520
|
+
bicycle: "vehicle",
|
|
10521
|
+
car: "vehicle",
|
|
10522
|
+
motorcycle: "vehicle",
|
|
10523
|
+
airplane: "vehicle",
|
|
10524
|
+
bus: "vehicle",
|
|
10525
|
+
train: "vehicle",
|
|
10526
|
+
truck: "vehicle",
|
|
10527
|
+
boat: "vehicle",
|
|
10528
|
+
bird: "animal",
|
|
10529
|
+
cat: "animal",
|
|
10530
|
+
dog: "animal",
|
|
10531
|
+
horse: "animal",
|
|
10532
|
+
sheep: "animal",
|
|
10533
|
+
cow: "animal",
|
|
10534
|
+
elephant: "animal",
|
|
10535
|
+
bear: "animal",
|
|
10536
|
+
zebra: "animal",
|
|
10537
|
+
giraffe: "animal",
|
|
10538
|
+
suitcase: "package",
|
|
10539
|
+
backpack: "package",
|
|
10540
|
+
handbag: "package"
|
|
10541
|
+
},
|
|
10542
|
+
preserveOriginal: false
|
|
10543
|
+
};
|
|
10544
|
+
/** Steps a root detector may declare it fills. */
|
|
10545
|
+
var FILLABLE_STEP_IDS = [
|
|
10546
|
+
"animal-classifier",
|
|
10547
|
+
"vehicle-classifier",
|
|
10548
|
+
"package-detection"
|
|
10549
|
+
];
|
|
10499
10550
|
var MODEL_FORMATS = [
|
|
10500
10551
|
"onnx",
|
|
10501
10552
|
"coreml",
|
|
@@ -10565,11 +10616,11 @@ var ModelVariantGroupSchema = object({
|
|
|
10565
10616
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
10566
10617
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
10567
10618
|
/**
|
|
10568
|
-
*
|
|
10569
|
-
*
|
|
10570
|
-
*
|
|
10619
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
10620
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
10621
|
+
* label is "Test".
|
|
10571
10622
|
*/
|
|
10572
|
-
optimization: _enum(["standard", "
|
|
10623
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
10573
10624
|
/**
|
|
10574
10625
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
10575
10626
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -10592,9 +10643,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
10592
10643
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
10593
10644
|
* string still parses — the string is lifted into `{ weights }`.
|
|
10594
10645
|
*
|
|
10595
|
-
* Every licence surface (the
|
|
10596
|
-
*
|
|
10597
|
-
*
|
|
10646
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
10647
|
+
* model table) is GENERATED from these records by
|
|
10648
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
10649
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
10598
10650
|
*/
|
|
10599
10651
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
10600
10652
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -10627,6 +10679,12 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
|
|
|
10627
10679
|
/** True when the weights or their data forbid commercial use. */
|
|
10628
10680
|
nonCommercial: boolean().optional()
|
|
10629
10681
|
}));
|
|
10682
|
+
/** One `fillsClassifierEffects` entry — see `ModelCatalogEntry.fillsClassifierEffects`. */
|
|
10683
|
+
var FillsClassifierEffectSchema = object({
|
|
10684
|
+
stepId: _enum(FILLABLE_STEP_IDS),
|
|
10685
|
+
labelToEffect: record(string(), string()),
|
|
10686
|
+
uncovered: array(string()).readonly()
|
|
10687
|
+
});
|
|
10630
10688
|
var ModelCatalogEntrySchema = object({
|
|
10631
10689
|
id: string(),
|
|
10632
10690
|
name: string(),
|
|
@@ -10753,6 +10811,16 @@ var ModelCatalogEntrySchema = object({
|
|
|
10753
10811
|
*/
|
|
10754
10812
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
10755
10813
|
/**
|
|
10814
|
+
* The pipeline steps this ROOT detector already does the work of (D715):
|
|
10815
|
+
* its labels name the effect the step exists to produce (`deer` for
|
|
10816
|
+
* `animal-classifier`, `package` for `package-detection`). Derived from the
|
|
10817
|
+
* labelmap by `deriveClassifierFills`, never hand-written; a COCO model
|
|
10818
|
+
* declares none. Whether a declaration is honoured is the step's own
|
|
10819
|
+
* `labelLink` policy (`resolveLabelLink`). `labelToEffect` values are in
|
|
10820
|
+
* `FILLABLE_STEP_VOCABULARIES` (guard `check-label-link-vocabulary`).
|
|
10821
|
+
*/
|
|
10822
|
+
fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional(),
|
|
10823
|
+
/**
|
|
10756
10824
|
* The model's CLIP feature-space contract (text encoder, dimension, vector
|
|
10757
10825
|
* index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
|
|
10758
10826
|
* CLIP image encoder; its absence is what "not a CLIP model" means to the
|
|
@@ -14225,7 +14293,7 @@ DeviceType.Camera;
|
|
|
14225
14293
|
* This matters here more than anywhere else in the repo, because every provider
|
|
14226
14294
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
14227
14295
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
14228
|
-
* and `http://admin:hunter2@192.168.
|
|
14296
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
14229
14297
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
14230
14298
|
* filling it is the operator's business, not ours.
|
|
14231
14299
|
*
|
|
@@ -17414,7 +17482,7 @@ method(object({
|
|
|
17414
17482
|
timeoutMs: 6e5
|
|
17415
17483
|
});
|
|
17416
17484
|
method(object({
|
|
17417
|
-
|
|
17485
|
+
targetNodeId: string(),
|
|
17418
17486
|
modelId: string(),
|
|
17419
17487
|
format: _enum(MODEL_FORMATS),
|
|
17420
17488
|
entry: ModelCatalogEntrySchema
|
|
@@ -17980,51 +18048,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
17980
18048
|
kind: "mutation",
|
|
17981
18049
|
auth: "admin"
|
|
17982
18050
|
});
|
|
17983
|
-
new Set([
|
|
17984
|
-
{
|
|
17985
|
-
id: "person",
|
|
17986
|
-
name: "Person"
|
|
17987
|
-
},
|
|
17988
|
-
{
|
|
17989
|
-
id: "vehicle",
|
|
17990
|
-
name: "Vehicle"
|
|
17991
|
-
},
|
|
17992
|
-
{
|
|
17993
|
-
id: "animal",
|
|
17994
|
-
name: "Animal"
|
|
17995
|
-
},
|
|
17996
|
-
{
|
|
17997
|
-
id: "package",
|
|
17998
|
-
name: "Package"
|
|
17999
|
-
}
|
|
18000
|
-
].map((l) => l.id));
|
|
18001
|
-
var COCO_TO_MACRO = {
|
|
18002
|
-
mapping: {
|
|
18003
|
-
person: "person",
|
|
18004
|
-
bicycle: "vehicle",
|
|
18005
|
-
car: "vehicle",
|
|
18006
|
-
motorcycle: "vehicle",
|
|
18007
|
-
airplane: "vehicle",
|
|
18008
|
-
bus: "vehicle",
|
|
18009
|
-
train: "vehicle",
|
|
18010
|
-
truck: "vehicle",
|
|
18011
|
-
boat: "vehicle",
|
|
18012
|
-
bird: "animal",
|
|
18013
|
-
cat: "animal",
|
|
18014
|
-
dog: "animal",
|
|
18015
|
-
horse: "animal",
|
|
18016
|
-
sheep: "animal",
|
|
18017
|
-
cow: "animal",
|
|
18018
|
-
elephant: "animal",
|
|
18019
|
-
bear: "animal",
|
|
18020
|
-
zebra: "animal",
|
|
18021
|
-
giraffe: "animal",
|
|
18022
|
-
suitcase: "package",
|
|
18023
|
-
backpack: "package",
|
|
18024
|
-
handbag: "package"
|
|
18025
|
-
},
|
|
18026
|
-
preserveOriginal: false
|
|
18027
|
-
};
|
|
18028
18051
|
var AUDIO_MACRO_LABELS = [
|
|
18029
18052
|
{
|
|
18030
18053
|
id: "speech",
|
|
@@ -18820,6 +18843,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
18820
18843
|
"stream-offline",
|
|
18821
18844
|
"node-online",
|
|
18822
18845
|
"node-offline",
|
|
18846
|
+
"node-restarting",
|
|
18847
|
+
"node-updating",
|
|
18823
18848
|
"node-inference-unavailable",
|
|
18824
18849
|
"detection-blind",
|
|
18825
18850
|
"addon-crash-loop",
|
|
@@ -19918,8 +19943,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
19918
19943
|
disabledTargetIds: array(string()).default([])
|
|
19919
19944
|
});
|
|
19920
19945
|
/**
|
|
19921
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
19922
|
-
* still-true state. `
|
|
19946
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
19947
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
19948
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
19923
19949
|
* job is not an open state, and the alarm stays instant.
|
|
19924
19950
|
*/
|
|
19925
19951
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -19931,6 +19957,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
19931
19957
|
"detection-blind",
|
|
19932
19958
|
"nodes",
|
|
19933
19959
|
"addons",
|
|
19960
|
+
"addon-updates",
|
|
19934
19961
|
"updates"
|
|
19935
19962
|
]);
|
|
19936
19963
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -20411,7 +20438,19 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
20411
20438
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
20412
20439
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
20413
20440
|
*/
|
|
20414
|
-
schedule: NcScheduleSchema.optional()
|
|
20441
|
+
schedule: NcScheduleSchema.optional(),
|
|
20442
|
+
/**
|
|
20443
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
20444
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
20445
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
20446
|
+
*/
|
|
20447
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
20448
|
+
/**
|
|
20449
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
20450
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
20451
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
20452
|
+
*/
|
|
20453
|
+
notifySensorRewatched: boolean().optional()
|
|
20415
20454
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20416
20455
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20417
20456
|
mode: AlarmArmModeSchema,
|
|
@@ -20420,7 +20459,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
20420
20459
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
20421
20460
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
20422
20461
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
20423
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
20462
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
20463
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20464
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
20465
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20466
|
+
notifySensorRewatched: boolean().nullable().optional()
|
|
20424
20467
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20425
20468
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20426
20469
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -21381,39 +21424,19 @@ Object.freeze(Object.fromEntries([{
|
|
|
21381
21424
|
label: "Face recognition model",
|
|
21382
21425
|
defaultModelId: "auraface-r100",
|
|
21383
21426
|
indexName: "the enrolled face gallery",
|
|
21384
|
-
options: [
|
|
21385
|
-
|
|
21386
|
-
|
|
21387
|
-
|
|
21388
|
-
},
|
|
21389
|
-
{
|
|
21390
|
-
id: "arcface-r100",
|
|
21391
|
-
label: "ArcFace (ResNet34)"
|
|
21392
|
-
},
|
|
21393
|
-
{
|
|
21394
|
-
id: "inception-resnet-v1",
|
|
21395
|
-
label: "Inception ResNet V1"
|
|
21396
|
-
}
|
|
21397
|
-
]
|
|
21427
|
+
options: [{
|
|
21428
|
+
id: "auraface-r100",
|
|
21429
|
+
label: "AuraFace R100"
|
|
21430
|
+
}]
|
|
21398
21431
|
}, {
|
|
21399
21432
|
stepId: "clip-embedding",
|
|
21400
21433
|
label: "Semantic search model",
|
|
21401
|
-
defaultModelId: "
|
|
21434
|
+
defaultModelId: "siglip2-b16-224",
|
|
21402
21435
|
indexName: "the object semantic-search index",
|
|
21403
|
-
options: [
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
|
|
21407
|
-
},
|
|
21408
|
-
{
|
|
21409
|
-
id: "mobileclip-s2",
|
|
21410
|
-
label: "MobileCLIP S2"
|
|
21411
|
-
},
|
|
21412
|
-
{
|
|
21413
|
-
id: "siglip2-b16-224",
|
|
21414
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21415
|
-
}
|
|
21416
|
-
]
|
|
21436
|
+
options: [{
|
|
21437
|
+
id: "siglip2-b16-224",
|
|
21438
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21439
|
+
}]
|
|
21417
21440
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
21418
21441
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
21419
21442
|
stepId: "face-embedding",
|
|
@@ -23468,7 +23491,8 @@ var PipelineModelOptionSchema = object({
|
|
|
23468
23491
|
group: ModelVariantGroupSchema.optional(),
|
|
23469
23492
|
legacy: boolean().optional(),
|
|
23470
23493
|
provider: ModelProviderIdSchema.optional(),
|
|
23471
|
-
defaultConfidence: number().optional()
|
|
23494
|
+
defaultConfidence: number().optional(),
|
|
23495
|
+
fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional()
|
|
23472
23496
|
});
|
|
23473
23497
|
var ConfigFieldBridge = custom();
|
|
23474
23498
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -24301,6 +24325,22 @@ var MotionSourceEnum = _enum([
|
|
|
24301
24325
|
"device-activity"
|
|
24302
24326
|
]);
|
|
24303
24327
|
/**
|
|
24328
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
24329
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
24330
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
24331
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
24332
|
+
* absent when unknown or when the camera itself triggered.
|
|
24333
|
+
*
|
|
24334
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
24335
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
24336
|
+
* runner never decides anything on it.
|
|
24337
|
+
*/
|
|
24338
|
+
var SessionTriggerSchema = object({
|
|
24339
|
+
source: MotionSourceEnum,
|
|
24340
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
24341
|
+
sensorName: string().optional()
|
|
24342
|
+
});
|
|
24343
|
+
/**
|
|
24304
24344
|
* List of motion sources active on a camera. Empty array is valid:
|
|
24305
24345
|
* "no source" — happens for battery cams without firmware motion when
|
|
24306
24346
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -24552,6 +24592,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
24552
24592
|
*/
|
|
24553
24593
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24554
24594
|
/**
|
|
24595
|
+
* What opened this attach, on a SESSION attach only (see
|
|
24596
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
24597
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
24598
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
24599
|
+
* runner then names no source on the phase event.
|
|
24600
|
+
*/
|
|
24601
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
24602
|
+
/**
|
|
24555
24603
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
24556
24604
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
24557
24605
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -32052,7 +32100,7 @@ var LocalInterfaceSchema = object({
|
|
|
32052
32100
|
name: string(),
|
|
32053
32101
|
family: _enum(["IPv4", "IPv6"]),
|
|
32054
32102
|
address: string(),
|
|
32055
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
32103
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
32056
32104
|
cidr: string(),
|
|
32057
32105
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
32058
32106
|
netmask: string(),
|
|
@@ -32106,7 +32154,8 @@ var ConnectionEndpointSchema = object({
|
|
|
32106
32154
|
"lan-ipv4",
|
|
32107
32155
|
"lan-ipv6",
|
|
32108
32156
|
"public",
|
|
32109
|
-
"loopback"
|
|
32157
|
+
"loopback",
|
|
32158
|
+
"app-link"
|
|
32110
32159
|
]),
|
|
32111
32160
|
/**
|
|
32112
32161
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -32175,15 +32224,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
32175
32224
|
localPort: AdvertisedLocalPortSchema
|
|
32176
32225
|
});
|
|
32177
32226
|
/**
|
|
32178
|
-
* The
|
|
32179
|
-
*
|
|
32180
|
-
*
|
|
32227
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
32228
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
32229
|
+
* so the UI can show it either way.
|
|
32181
32230
|
*/
|
|
32182
32231
|
var NotificationEndpointSchema = object({
|
|
32183
32232
|
/** The operator's explicit choice, or null for AUTO. */
|
|
32184
32233
|
baseUrl: string().nullable(),
|
|
32185
|
-
/**
|
|
32186
|
-
|
|
32234
|
+
/**
|
|
32235
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
32236
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
32237
|
+
* answered the public tunnel / mesh here, or null.
|
|
32238
|
+
*/
|
|
32239
|
+
resolved: string().nullable(),
|
|
32240
|
+
/**
|
|
32241
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
32242
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
32243
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
32244
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
32245
|
+
* Absent on a pre-D709 hub.
|
|
32246
|
+
*/
|
|
32247
|
+
appLinkHub: string().nullable()
|
|
32187
32248
|
});
|
|
32188
32249
|
/**
|
|
32189
32250
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -32237,7 +32298,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
32237
32298
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
32238
32299
|
* to avoid mixed-content blocks in the browser. The public
|
|
32239
32300
|
* tunnel always emits `https://` regardless. */
|
|
32240
|
-
scheme: _enum(["http", "https"]).optional()
|
|
32301
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
32302
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
32303
|
+
* an address notification links can be flagged with, not a hub
|
|
32304
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
32305
|
+
includeAppLink: boolean().optional()
|
|
32241
32306
|
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
32242
32307
|
kind: "mutation",
|
|
32243
32308
|
auth: "admin"
|
|
@@ -32566,7 +32631,7 @@ var MeshPeerSchema = object({
|
|
|
32566
32631
|
tags: array(string()).readonly(),
|
|
32567
32632
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
32568
32633
|
exitNodeOption: boolean(),
|
|
32569
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
32634
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
32570
32635
|
advertisedRoutes: array(string()).readonly(),
|
|
32571
32636
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
32572
32637
|
userLogin: string().nullable(),
|
|
@@ -32696,7 +32761,8 @@ var MotionStatusSchema = object({
|
|
|
32696
32761
|
* writes this slice (not even a boot seed), and neither does the runner's
|
|
32697
32762
|
* phase machine: its phase is "a session is attached" for every on-motion
|
|
32698
32763
|
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
32699
|
-
* A provider's `isDetected`
|
|
32764
|
+
* A provider's `isDetected` and `getStatus` answer from the hub's slice
|
|
32765
|
+
* (`hubMotionNativeProvider`).
|
|
32700
32766
|
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
32701
32767
|
* imports) — the provider pushes both edges itself, from the upstream
|
|
32702
32768
|
* system's own state change. That is the sensor's own fact.
|
|
@@ -33894,7 +33960,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
33894
33960
|
*/
|
|
33895
33961
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
33896
33962
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
33897
|
-
readOnly: boolean().optional()
|
|
33963
|
+
readOnly: boolean().optional(),
|
|
33964
|
+
/**
|
|
33965
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
33966
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
33967
|
+
* copy on the binding.
|
|
33968
|
+
*/
|
|
33969
|
+
maxCharacters: number().int().positive().optional()
|
|
33898
33970
|
})).readonly() });
|
|
33899
33971
|
var OsdOverlayPatchSchema = object({
|
|
33900
33972
|
enabled: boolean().optional(),
|
|
@@ -33945,7 +34017,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
33945
34017
|
valuePath: string().min(1).max(64),
|
|
33946
34018
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
33947
34019
|
displayUnit: string().max(16).optional(),
|
|
33948
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
34020
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34021
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
34022
|
+
valueMap: record(string(), string()).optional()
|
|
33949
34023
|
});
|
|
33950
34024
|
/**
|
|
33951
34025
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -33995,18 +34069,11 @@ var OsdSlotBindingSchema = object({
|
|
|
33995
34069
|
source: OsdSourceSchema,
|
|
33996
34070
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
33997
34071
|
template: string().max(96).default("${value}"),
|
|
33998
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
33999
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
34000
34072
|
/**
|
|
34001
34073
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
34002
34074
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
34003
34075
|
*/
|
|
34004
34076
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34005
|
-
/**
|
|
34006
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
34007
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
34008
|
-
*/
|
|
34009
|
-
unitLabel: string().max(8).optional(),
|
|
34010
34077
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
34011
34078
|
valueMap: record(string(), string()).optional(),
|
|
34012
34079
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -34015,9 +34082,7 @@ var OsdSlotBindingSchema = object({
|
|
|
34015
34082
|
* Display gate, in the notification centre's condition vocabulary.
|
|
34016
34083
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
34017
34084
|
*/
|
|
34018
|
-
conditions: NcConditionsSchema.optional()
|
|
34019
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
34020
|
-
fallbackText: string().max(64).default("")
|
|
34085
|
+
conditions: NcConditionsSchema.optional()
|
|
34021
34086
|
});
|
|
34022
34087
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
34023
34088
|
var OsdSlotViewSchema = object({
|
|
@@ -52167,6 +52232,8 @@ new Map(Object.entries({
|
|
|
52167
52232
|
"detection-blind": "device-events",
|
|
52168
52233
|
"node-online": "system",
|
|
52169
52234
|
"node-offline": "system",
|
|
52235
|
+
"node-restarting": "system",
|
|
52236
|
+
"node-updating": "system",
|
|
52170
52237
|
"node-inference-unavailable": "system",
|
|
52171
52238
|
"addon-crash-loop": "system",
|
|
52172
52239
|
"addon-update-available": "system",
|
|
@@ -52244,18 +52311,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
52244
52311
|
kinds: [
|
|
52245
52312
|
"node-offline",
|
|
52246
52313
|
"node-online",
|
|
52314
|
+
"node-restarting",
|
|
52247
52315
|
"node-inference-unavailable"
|
|
52248
52316
|
]
|
|
52249
52317
|
},
|
|
52250
52318
|
{
|
|
52251
52319
|
id: "addons",
|
|
52252
52320
|
family: "system",
|
|
52253
|
-
label: "Addons",
|
|
52254
|
-
kinds: [
|
|
52255
|
-
|
|
52256
|
-
|
|
52257
|
-
|
|
52258
|
-
|
|
52321
|
+
label: "Addons stopped",
|
|
52322
|
+
kinds: ["addon-crash-loop"]
|
|
52323
|
+
},
|
|
52324
|
+
{
|
|
52325
|
+
id: "addon-updates",
|
|
52326
|
+
family: "system",
|
|
52327
|
+
label: "Addon updates",
|
|
52328
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
52259
52329
|
},
|
|
52260
52330
|
{
|
|
52261
52331
|
id: "updates",
|
|
@@ -52263,6 +52333,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
52263
52333
|
label: "Server & container updates",
|
|
52264
52334
|
kinds: [
|
|
52265
52335
|
"server-update-available",
|
|
52336
|
+
"node-updating",
|
|
52266
52337
|
"server-updated",
|
|
52267
52338
|
"wrapper-update-available"
|
|
52268
52339
|
]
|
|
@@ -52410,18 +52481,21 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
52410
52481
|
kinds: [
|
|
52411
52482
|
"node-offline",
|
|
52412
52483
|
"node-online",
|
|
52484
|
+
"node-restarting",
|
|
52413
52485
|
"node-inference-unavailable"
|
|
52414
52486
|
]
|
|
52415
52487
|
},
|
|
52416
52488
|
{
|
|
52417
52489
|
name: "summaryAddons",
|
|
52418
|
-
label: "Summary: addons",
|
|
52419
|
-
example: "
|
|
52420
|
-
kinds: [
|
|
52421
|
-
|
|
52422
|
-
|
|
52423
|
-
|
|
52424
|
-
|
|
52490
|
+
label: "Summary: addons stopped",
|
|
52491
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
52492
|
+
kinds: ["addon-crash-loop"]
|
|
52493
|
+
},
|
|
52494
|
+
{
|
|
52495
|
+
name: "summaryAddonUpdates",
|
|
52496
|
+
label: "Summary: addon updates",
|
|
52497
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
52498
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
52425
52499
|
},
|
|
52426
52500
|
{
|
|
52427
52501
|
name: "summaryUpdates",
|
|
@@ -52429,6 +52503,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
52429
52503
|
example: "server 1.2.377 → 1.2.378",
|
|
52430
52504
|
kinds: [
|
|
52431
52505
|
"server-update-available",
|
|
52506
|
+
"node-updating",
|
|
52432
52507
|
"server-updated",
|
|
52433
52508
|
"wrapper-update-available"
|
|
52434
52509
|
]
|
|
@@ -52505,6 +52580,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
52505
52580
|
[...RULE_BODY_ONLY],
|
|
52506
52581
|
[...RULE_TEXT],
|
|
52507
52582
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
52583
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
52508
52584
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
52509
52585
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
52510
52586
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -52545,6 +52621,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
52545
52621
|
[...RULE_TEXT],
|
|
52546
52622
|
[...RULE_TEXT],
|
|
52547
52623
|
[...RULE_TEXT],
|
|
52624
|
+
[...RULE_TEXT],
|
|
52625
|
+
[...RULE_TEXT],
|
|
52548
52626
|
...STATE_SUMMARY_VARS
|
|
52549
52627
|
];
|
|
52550
52628
|
new Set([
|
|
@@ -52881,10 +52959,9 @@ TimelapseRuleInputSchema.extend({
|
|
|
52881
52959
|
createdAt: number(),
|
|
52882
52960
|
updatedAt: number()
|
|
52883
52961
|
});
|
|
52884
|
-
async function
|
|
52885
|
-
let slice;
|
|
52962
|
+
async function readSlice(deviceState, deviceId) {
|
|
52886
52963
|
try {
|
|
52887
|
-
|
|
52964
|
+
return await deviceState.getCapSlice.query({
|
|
52888
52965
|
deviceId,
|
|
52889
52966
|
capName: "motion"
|
|
52890
52967
|
});
|
|
@@ -52892,10 +52969,44 @@ async function readHubMotionDetected(deviceState, deviceId) {
|
|
|
52892
52969
|
const reason = err instanceof Error ? err.message : String(err);
|
|
52893
52970
|
throw new Error(`motion state of device ${deviceId} is unreadable: ${reason}`, { cause: err });
|
|
52894
52971
|
}
|
|
52895
|
-
|
|
52972
|
+
}
|
|
52973
|
+
/**
|
|
52974
|
+
* The hub's `motion` slice as a `MotionStatus`, or `null` when nobody has
|
|
52975
|
+
* published it since the hub started. Throws when the hub does not answer or
|
|
52976
|
+
* the slice is malformed — never a made-up "no motion".
|
|
52977
|
+
*/
|
|
52978
|
+
async function readHubMotionStatus(deviceState, deviceId) {
|
|
52979
|
+
const slice = await readSlice(deviceState, deviceId);
|
|
52980
|
+
if (slice === null) return null;
|
|
52981
|
+
const parsed = MotionStatusSchema.safeParse(slice);
|
|
52982
|
+
if (!parsed.success) throw new Error(`motion state of device ${deviceId} is malformed on the hub: ${parsed.error.message}`);
|
|
52983
|
+
return parsed.data;
|
|
52984
|
+
}
|
|
52985
|
+
async function readHubMotionDetected(deviceState, deviceId) {
|
|
52986
|
+
const detected = (await readSlice(deviceState, deviceId))?.["detected"];
|
|
52896
52987
|
if (typeof detected !== "boolean") throw new Error(`motion state of device ${deviceId} is not published yet (unknown)`);
|
|
52897
52988
|
return detected;
|
|
52898
52989
|
}
|
|
52990
|
+
/**
|
|
52991
|
+
* The native `motion` provider of a camera whose slice the orchestrator writes
|
|
52992
|
+
* (D696): `isDetected` AND `getStatus`, both from the hub. `owner` names the
|
|
52993
|
+
* provider class in the deviceId-mismatch error.
|
|
52994
|
+
*/
|
|
52995
|
+
function hubMotionNativeProvider(deviceState, deviceId, owner) {
|
|
52996
|
+
const ownDevice = (asked) => {
|
|
52997
|
+
if (asked !== deviceId) throw new Error(`${owner}: motion deviceId mismatch, expected ${deviceId}, got ${asked}`);
|
|
52998
|
+
};
|
|
52999
|
+
return {
|
|
53000
|
+
isDetected: async ({ deviceId: asked }) => {
|
|
53001
|
+
ownDevice(asked);
|
|
53002
|
+
return readHubMotionDetected(deviceState, deviceId);
|
|
53003
|
+
},
|
|
53004
|
+
getStatus: async ({ deviceId: asked }) => {
|
|
53005
|
+
ownDevice(asked);
|
|
53006
|
+
return readHubMotionStatus(deviceState, deviceId);
|
|
53007
|
+
}
|
|
53008
|
+
};
|
|
53009
|
+
}
|
|
52899
53010
|
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
52900
53011
|
function providerMotionEvent(source, data) {
|
|
52901
53012
|
return createEvent(EventCategory.ProviderMotion, source, data);
|
|
@@ -56496,7 +56607,7 @@ function buildCreationFormSchema() {
|
|
|
56496
56607
|
key: "ip",
|
|
56497
56608
|
label: "Local IP",
|
|
56498
56609
|
required: true,
|
|
56499
|
-
placeholder: "192.168.
|
|
56610
|
+
placeholder: "192.168.10.41"
|
|
56500
56611
|
},
|
|
56501
56612
|
{
|
|
56502
56613
|
type: "text",
|
|
@@ -57371,15 +57482,13 @@ var WyzeCamera = class extends BaseDevice {
|
|
|
57371
57482
|
/**
|
|
57372
57483
|
* The native `motion` cap. This provider writes NO `motion` slice (D696): the
|
|
57373
57484
|
* orchestrator is its only writer, with the EFFECTIVE motion, on the hub.
|
|
57374
|
-
* `isDetected`
|
|
57375
|
-
*
|
|
57376
|
-
* (D49, D393).
|
|
57485
|
+
* `isDetected` and `getStatus` answer from the HUB's slice
|
|
57486
|
+
* (`hubMotionNativeProvider`); an unreadable hub fails both — never `false`
|
|
57487
|
+
* for unknown (D49, D393).
|
|
57377
57488
|
*/
|
|
57378
57489
|
registerMotionProvider() {
|
|
57379
|
-
this.ctx.
|
|
57380
|
-
|
|
57381
|
-
return readHubMotionDetected(this.ctx.api.deviceState, this.id);
|
|
57382
|
-
} });
|
|
57490
|
+
const provider = hubMotionNativeProvider(this.ctx.api.deviceState, this.id, "WyzeCamera");
|
|
57491
|
+
this.ctx.registerNativeCap(motionCapability, provider);
|
|
57383
57492
|
}
|
|
57384
57493
|
/**
|
|
57385
57494
|
* Start the configured motion source. `cloud` polls the Wyze events API
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-wyze",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.128",
|
|
4
4
|
"description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|