@camstack/addon-provider-dreo 0.2.22 → 0.2.24
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 +167 -59
- package/dist/addon.mjs +167 -59
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -7602,7 +7602,7 @@ var RecordingBandSchema = object({
|
|
|
7602
7602
|
postBufferSec: number().min(0).optional()
|
|
7603
7603
|
});
|
|
7604
7604
|
({
|
|
7605
|
-
preBufferSec:
|
|
7605
|
+
preBufferSec: 15,
|
|
7606
7606
|
postBufferSec: 30
|
|
7607
7607
|
}).postBufferSec * 1e3;
|
|
7608
7608
|
/**
|
|
@@ -13822,128 +13822,103 @@ var COCO_TO_MACRO = {
|
|
|
13822
13822
|
var AUDIO_MACRO_LABELS = [
|
|
13823
13823
|
{
|
|
13824
13824
|
id: "speech",
|
|
13825
|
-
name: "Speech"
|
|
13826
|
-
icon: "🗣️"
|
|
13825
|
+
name: "Speech"
|
|
13827
13826
|
},
|
|
13828
13827
|
{
|
|
13829
13828
|
id: "scream",
|
|
13830
|
-
name: "Scream / Shout"
|
|
13831
|
-
icon: "😱"
|
|
13829
|
+
name: "Scream / Shout"
|
|
13832
13830
|
},
|
|
13833
13831
|
{
|
|
13834
13832
|
id: "crying",
|
|
13835
|
-
name: "Crying / Baby"
|
|
13836
|
-
icon: "😢"
|
|
13833
|
+
name: "Crying / Baby"
|
|
13837
13834
|
},
|
|
13838
13835
|
{
|
|
13839
13836
|
id: "laughter",
|
|
13840
|
-
name: "Laughter"
|
|
13841
|
-
icon: "😂"
|
|
13837
|
+
name: "Laughter"
|
|
13842
13838
|
},
|
|
13843
13839
|
{
|
|
13844
13840
|
id: "music",
|
|
13845
|
-
name: "Music"
|
|
13846
|
-
icon: "🎵"
|
|
13841
|
+
name: "Music"
|
|
13847
13842
|
},
|
|
13848
13843
|
{
|
|
13849
13844
|
id: "dog",
|
|
13850
|
-
name: "Dog"
|
|
13851
|
-
icon: "🐕"
|
|
13845
|
+
name: "Dog"
|
|
13852
13846
|
},
|
|
13853
13847
|
{
|
|
13854
13848
|
id: "cat",
|
|
13855
|
-
name: "Cat"
|
|
13856
|
-
icon: "🐈"
|
|
13849
|
+
name: "Cat"
|
|
13857
13850
|
},
|
|
13858
13851
|
{
|
|
13859
13852
|
id: "bird",
|
|
13860
|
-
name: "Bird"
|
|
13861
|
-
icon: "🐦"
|
|
13853
|
+
name: "Bird"
|
|
13862
13854
|
},
|
|
13863
13855
|
{
|
|
13864
13856
|
id: "animal",
|
|
13865
|
-
name: "Animal (other)"
|
|
13866
|
-
icon: "🐾"
|
|
13857
|
+
name: "Animal (other)"
|
|
13867
13858
|
},
|
|
13868
13859
|
{
|
|
13869
13860
|
id: "alarm",
|
|
13870
|
-
name: "Alarm / Siren"
|
|
13871
|
-
icon: "🚨"
|
|
13861
|
+
name: "Alarm / Siren"
|
|
13872
13862
|
},
|
|
13873
13863
|
{
|
|
13874
13864
|
id: "doorbell",
|
|
13875
|
-
name: "Doorbell / Knock"
|
|
13876
|
-
icon: "🔔"
|
|
13865
|
+
name: "Doorbell / Knock"
|
|
13877
13866
|
},
|
|
13878
13867
|
{
|
|
13879
13868
|
id: "glass_breaking",
|
|
13880
|
-
name: "Glass Breaking"
|
|
13881
|
-
icon: "💥"
|
|
13869
|
+
name: "Glass Breaking"
|
|
13882
13870
|
},
|
|
13883
13871
|
{
|
|
13884
13872
|
id: "gunshot",
|
|
13885
|
-
name: "Gunshot / Explosion"
|
|
13886
|
-
icon: "💣"
|
|
13873
|
+
name: "Gunshot / Explosion"
|
|
13887
13874
|
},
|
|
13888
13875
|
{
|
|
13889
13876
|
id: "vehicle",
|
|
13890
|
-
name: "Vehicle"
|
|
13891
|
-
icon: "🚗"
|
|
13877
|
+
name: "Vehicle"
|
|
13892
13878
|
},
|
|
13893
13879
|
{
|
|
13894
13880
|
id: "siren",
|
|
13895
|
-
name: "Emergency Siren"
|
|
13896
|
-
icon: "🚑"
|
|
13881
|
+
name: "Emergency Siren"
|
|
13897
13882
|
},
|
|
13898
13883
|
{
|
|
13899
13884
|
id: "fire",
|
|
13900
|
-
name: "Fire / Smoke"
|
|
13901
|
-
icon: "🔥"
|
|
13885
|
+
name: "Fire / Smoke"
|
|
13902
13886
|
},
|
|
13903
13887
|
{
|
|
13904
13888
|
id: "water",
|
|
13905
|
-
name: "Water"
|
|
13906
|
-
icon: "💧"
|
|
13889
|
+
name: "Water"
|
|
13907
13890
|
},
|
|
13908
13891
|
{
|
|
13909
13892
|
id: "wind",
|
|
13910
|
-
name: "Wind / Weather"
|
|
13911
|
-
icon: "🌬️"
|
|
13893
|
+
name: "Wind / Weather"
|
|
13912
13894
|
},
|
|
13913
13895
|
{
|
|
13914
13896
|
id: "door",
|
|
13915
|
-
name: "Door"
|
|
13916
|
-
icon: "🚪"
|
|
13897
|
+
name: "Door"
|
|
13917
13898
|
},
|
|
13918
13899
|
{
|
|
13919
13900
|
id: "footsteps",
|
|
13920
|
-
name: "Footsteps"
|
|
13921
|
-
icon: "👣"
|
|
13901
|
+
name: "Footsteps"
|
|
13922
13902
|
},
|
|
13923
13903
|
{
|
|
13924
13904
|
id: "crowd",
|
|
13925
|
-
name: "Crowd / Chatter"
|
|
13926
|
-
icon: "👥"
|
|
13905
|
+
name: "Crowd / Chatter"
|
|
13927
13906
|
},
|
|
13928
13907
|
{
|
|
13929
13908
|
id: "telephone",
|
|
13930
|
-
name: "Telephone"
|
|
13931
|
-
icon: "📞"
|
|
13909
|
+
name: "Telephone"
|
|
13932
13910
|
},
|
|
13933
13911
|
{
|
|
13934
13912
|
id: "engine",
|
|
13935
|
-
name: "Engine / Motor"
|
|
13936
|
-
icon: "⚙️"
|
|
13913
|
+
name: "Engine / Motor"
|
|
13937
13914
|
},
|
|
13938
13915
|
{
|
|
13939
13916
|
id: "tools",
|
|
13940
|
-
name: "Tools / Construction"
|
|
13941
|
-
icon: "🔨"
|
|
13917
|
+
name: "Tools / Construction"
|
|
13942
13918
|
},
|
|
13943
13919
|
{
|
|
13944
13920
|
id: "silence",
|
|
13945
|
-
name: "Silence"
|
|
13946
|
-
icon: "🤫"
|
|
13921
|
+
name: "Silence"
|
|
13947
13922
|
}
|
|
13948
13923
|
];
|
|
13949
13924
|
var YAMNET_TO_MACRO = {
|
|
@@ -16445,7 +16420,7 @@ var TrackEnvelopeSchema = object({
|
|
|
16445
16420
|
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16446
16421
|
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16447
16422
|
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16448
|
-
* zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
|
|
16423
|
+
* zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
|
|
16449
16424
|
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16450
16425
|
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16451
16426
|
* (`getObjectEvents` et al.).
|
|
@@ -16740,6 +16715,35 @@ var TrackSchema = object({
|
|
|
16740
16715
|
*/
|
|
16741
16716
|
hasFace: boolean().optional(),
|
|
16742
16717
|
/**
|
|
16718
|
+
* This track has a face row IN THE GALLERY: a crop **and** an embedding — a
|
|
16719
|
+
* face an operator could ASSIGN to an identity.
|
|
16720
|
+
*
|
|
16721
|
+
* The STRICT twin of {@link hasFace}, and the pair only earns its keep
|
|
16722
|
+
* because the two disagree. `hasFace` is stamped at the TOP of the face
|
|
16723
|
+
* branch, before every gate, and means no more than "a face detector produced
|
|
16724
|
+
* a face detail". This one is stamped at the single moment the gallery row
|
|
16725
|
+
* LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
|
|
16726
|
+
* past the embedding-magnitude verdict, the `minFacePx` detection gate, the
|
|
16727
|
+
* candidate gate, the imageless-track drop (no crop was ever captured) and
|
|
16728
|
+
* the crop-store drop. Everything between the detector and that insert can
|
|
16729
|
+
* legitimately refuse the face, so a flag written any earlier promises the
|
|
16730
|
+
* operator something to assign and delivers nothing.
|
|
16731
|
+
*
|
|
16732
|
+
* **Independent of recognition.** A face collected but never auto-matched is
|
|
16733
|
+
* still assignable — it is in fact the face an operator most wants to reach —
|
|
16734
|
+
* so this is NOT gated on `recognizedIdentityId`. Recognition lands in
|
|
16735
|
+
* `subLabel`; this says only that the raw material exists.
|
|
16736
|
+
*
|
|
16737
|
+
* **Set once, never cleared.** A track that produced a gallery row produced
|
|
16738
|
+
* one; deleting the row later is the gallery's business, not this flag's.
|
|
16739
|
+
*
|
|
16740
|
+
* **Absent ≠ false**, the same rule as {@link hasFace}: every row written
|
|
16741
|
+
* before the column omits it, and so does every server that predates the
|
|
16742
|
+
* field. A consumer must test `=== true` and render nothing otherwise —
|
|
16743
|
+
* never infer "no assignable face".
|
|
16744
|
+
*/
|
|
16745
|
+
hasEmbeddedFace: boolean().optional(),
|
|
16746
|
+
/**
|
|
16743
16747
|
* This subject CONTAINS a folded rider — a person the rider-pairing step
|
|
16744
16748
|
* ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
|
|
16745
16749
|
* so the passage is tracked once and as a VEHICLE.
|
|
@@ -18129,6 +18133,32 @@ var DetailResultSchema = object({
|
|
|
18129
18133
|
/** FRAME-space bbox (already mapped back from crop space). */
|
|
18130
18134
|
bbox: NativeCropBboxSchema.optional(),
|
|
18131
18135
|
embedding: string().optional(),
|
|
18136
|
+
/**
|
|
18137
|
+
* L2 magnitude of the RAW pre-normalization embedding. Additive and optional
|
|
18138
|
+
* so an older runner that does not send it degrades to "unmeasurable", which
|
|
18139
|
+
* the consuming gate treats as accept — never as reject.
|
|
18140
|
+
*/
|
|
18141
|
+
embeddingMagnitude: number().optional(),
|
|
18142
|
+
/**
|
|
18143
|
+
* Model that produced `embedding` — the SAME contract `labelModelId` has for
|
|
18144
|
+
* `label`, and for the same reason: the producing node is the only side that
|
|
18145
|
+
* knows which model actually ran, and re-deriving it downstream is exactly
|
|
18146
|
+
* the inference this model exists to forbid.
|
|
18147
|
+
*
|
|
18148
|
+
* Additive and optional, so a runner that predates it degrades to
|
|
18149
|
+
* "unmeasurable" rather than to a wrong answer — the consumer falls back to
|
|
18150
|
+
* its previous assumption instead of refusing.
|
|
18151
|
+
*
|
|
18152
|
+
* Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
|
|
18153
|
+
* to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
|
|
18154
|
+
* with nothing on the wire it took the id from the GALLERY, so the gate
|
|
18155
|
+
* compared the gallery against itself and could never fire. That turned the
|
|
18156
|
+
* one guard protecting the face feature space into a tautology, and it is
|
|
18157
|
+
* why swapping `face-embedding`'s model would NOT have stranded the enrolled
|
|
18158
|
+
* gallery as the catalog comment predicts — it would have scored the new
|
|
18159
|
+
* model's vectors against the old model's samples in one cosine space.
|
|
18160
|
+
*/
|
|
18161
|
+
embeddingModelId: string().optional(),
|
|
18132
18162
|
label: string().optional(),
|
|
18133
18163
|
/**
|
|
18134
18164
|
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
@@ -19539,6 +19569,7 @@ DeviceType.Camera, method(object({
|
|
|
19539
19569
|
isBattery: boolean(),
|
|
19540
19570
|
reason: _enum([
|
|
19541
19571
|
"disabled",
|
|
19572
|
+
"offline",
|
|
19542
19573
|
"sleeping",
|
|
19543
19574
|
"unreachable",
|
|
19544
19575
|
"waking"
|
|
@@ -19584,9 +19615,17 @@ targets: array(object({
|
|
|
19584
19615
|
sleeping: boolean(),
|
|
19585
19616
|
/** Current device state rendered over the cached frame. State images
|
|
19586
19617
|
* remain authoritative even when their photographic background is
|
|
19587
|
-
* old; null means the link must carry a current camera frame.
|
|
19618
|
+
* old; null means the link must carry a current camera frame.
|
|
19619
|
+
*
|
|
19620
|
+
* **This is the ONLY source a surface may derive an inactive tile
|
|
19621
|
+
* from.** A client that reads a device's `online`/`disabled` flags and
|
|
19622
|
+
* draws its own verdict will disagree with the pixels it is painting
|
|
19623
|
+
* — the frame comes from here, and so must the sentence over it
|
|
19624
|
+
* (D190). Pair with `ageMs` for the age of the photograph behind the
|
|
19625
|
+
* state. */
|
|
19588
19626
|
stateReason: _enum([
|
|
19589
19627
|
"disabled",
|
|
19628
|
+
"offline",
|
|
19590
19629
|
"sleeping",
|
|
19591
19630
|
"unreachable",
|
|
19592
19631
|
"waking"
|
|
@@ -26313,9 +26352,21 @@ var RecordingLocationUsageSchema = object({
|
|
|
26313
26352
|
* previously rendered as two identical "disks" with a nonsensical used
|
|
26314
26353
|
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
26315
26354
|
locationIds: array(string()).optional(),
|
|
26316
|
-
/**
|
|
26355
|
+
/**
|
|
26356
|
+
* Filesystem root of the physical volume this row accounts — the only
|
|
26357
|
+
* operator-legible identity when a location has no `displayName` yet, and
|
|
26358
|
+
* what a "which disk is full" alert has to name. OPTIONAL for the same
|
|
26359
|
+
* train-skew reason as `oldestMs`: a recorder that predates the field omits
|
|
26360
|
+
* it, and this schema must keep validating that older provider's payload.
|
|
26361
|
+
*/
|
|
26362
|
+
root: string().optional(),
|
|
26363
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). This is
|
|
26364
|
+
* the footage's SHARE of the volume, not how full the volume is — the disk
|
|
26365
|
+
* also holds everything that is not recordings. Volume fill is
|
|
26366
|
+
* `(totalBytes - availableBytes) / totalBytes`. */
|
|
26317
26367
|
usedBytes: number(),
|
|
26318
|
-
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26368
|
+
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26369
|
+
* (remote/unstattable — the recorder logs the statfs failure with the root). */
|
|
26319
26370
|
availableBytes: number().nullable(),
|
|
26320
26371
|
/** Total bytes of the location's volume; null when unknown. */
|
|
26321
26372
|
totalBytes: number().nullable()
|
|
@@ -26327,7 +26378,15 @@ var RecordingStorageUsageSchema = object({
|
|
|
26327
26378
|
nodeId: string(),
|
|
26328
26379
|
totalUsedBytes: number(),
|
|
26329
26380
|
devices: array(RecordingDeviceUsageSchema),
|
|
26330
|
-
|
|
26381
|
+
/**
|
|
26382
|
+
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
26383
|
+
* of the payload without it: the hub serves this method through a BAKED
|
|
26384
|
+
* router, so a hub whose framework train predates a change to this array
|
|
26385
|
+
* strips it out of an answer a newer recorder happily produced. A UI that
|
|
26386
|
+
* dereferences it unconditionally crashes the whole Storage page over a
|
|
26387
|
+
* missing disk bar.
|
|
26388
|
+
*/
|
|
26389
|
+
locations: array(RecordingLocationUsageSchema).optional()
|
|
26331
26390
|
});
|
|
26332
26391
|
/**
|
|
26333
26392
|
* The OPERATOR-ARMED half of multi-location recordings (D116).
|
|
@@ -37112,8 +37171,13 @@ Object.freeze({
|
|
|
37112
37171
|
"network-access": "ingress",
|
|
37113
37172
|
"smtp-provider": "email"
|
|
37114
37173
|
});
|
|
37115
|
-
|
|
37174
|
+
/** Schema defaults — an untouched sub-field must author exactly these. */
|
|
37175
|
+
var NC_AUDIO_DEFAULTS = {
|
|
37176
|
+
hitPercent: 60,
|
|
37177
|
+
samplingSeconds: 10
|
|
37178
|
+
};
|
|
37116
37179
|
new Set(["devices", "classes"]);
|
|
37180
|
+
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
37117
37181
|
/**
|
|
37118
37182
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
37119
37183
|
*
|
|
@@ -37345,6 +37409,39 @@ TimelapseRuleInputSchema.extend({
|
|
|
37345
37409
|
createdAt: number(),
|
|
37346
37410
|
updatedAt: number()
|
|
37347
37411
|
});
|
|
37412
|
+
Object.freeze(Object.fromEntries([{
|
|
37413
|
+
stepId: "face-embedding",
|
|
37414
|
+
label: "Face recognition model",
|
|
37415
|
+
defaultModelId: "arcface-r100",
|
|
37416
|
+
indexName: "the enrolled face gallery",
|
|
37417
|
+
options: [
|
|
37418
|
+
{
|
|
37419
|
+
id: "arcface-r100",
|
|
37420
|
+
label: "ArcFace (ResNet34)"
|
|
37421
|
+
},
|
|
37422
|
+
{
|
|
37423
|
+
id: "auraface-r100",
|
|
37424
|
+
label: "AuraFace R100"
|
|
37425
|
+
},
|
|
37426
|
+
{
|
|
37427
|
+
id: "inception-resnet-v1",
|
|
37428
|
+
label: "Inception ResNet V1"
|
|
37429
|
+
}
|
|
37430
|
+
]
|
|
37431
|
+
}, {
|
|
37432
|
+
stepId: "clip-embedding",
|
|
37433
|
+
label: "Semantic search model",
|
|
37434
|
+
defaultModelId: "mobileclip-s1",
|
|
37435
|
+
indexName: "the object semantic-search index",
|
|
37436
|
+
options: [{
|
|
37437
|
+
id: "mobileclip-s1",
|
|
37438
|
+
label: "MobileCLIP S1"
|
|
37439
|
+
}, {
|
|
37440
|
+
id: "mobileclip-s2",
|
|
37441
|
+
label: "MobileCLIP S2"
|
|
37442
|
+
}]
|
|
37443
|
+
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
37444
|
+
string().min(1);
|
|
37348
37445
|
object({
|
|
37349
37446
|
/**
|
|
37350
37447
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -37365,10 +37462,21 @@ object({
|
|
|
37365
37462
|
*/
|
|
37366
37463
|
square: boolean()
|
|
37367
37464
|
});
|
|
37368
|
-
|
|
37465
|
+
/**
|
|
37466
|
+
* The convention in force when nobody has configured one — byte-for-byte the
|
|
37467
|
+
* behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
|
|
37468
|
+
*/
|
|
37469
|
+
var DEFAULT_DETAIL_CROP_CONVENTION = {
|
|
37369
37470
|
paddingRatio: .15,
|
|
37370
37471
|
square: false
|
|
37371
|
-
}
|
|
37472
|
+
};
|
|
37473
|
+
Object.freeze({
|
|
37474
|
+
x: 0,
|
|
37475
|
+
y: 0,
|
|
37476
|
+
w: 1,
|
|
37477
|
+
h: 1
|
|
37478
|
+
});
|
|
37479
|
+
DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
|
|
37372
37480
|
/**
|
|
37373
37481
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
37374
37482
|
*
|
package/dist/addon.mjs
CHANGED
|
@@ -7603,7 +7603,7 @@ var RecordingBandSchema = object({
|
|
|
7603
7603
|
postBufferSec: number().min(0).optional()
|
|
7604
7604
|
});
|
|
7605
7605
|
({
|
|
7606
|
-
preBufferSec:
|
|
7606
|
+
preBufferSec: 15,
|
|
7607
7607
|
postBufferSec: 30
|
|
7608
7608
|
}).postBufferSec * 1e3;
|
|
7609
7609
|
/**
|
|
@@ -13823,128 +13823,103 @@ var COCO_TO_MACRO = {
|
|
|
13823
13823
|
var AUDIO_MACRO_LABELS = [
|
|
13824
13824
|
{
|
|
13825
13825
|
id: "speech",
|
|
13826
|
-
name: "Speech"
|
|
13827
|
-
icon: "🗣️"
|
|
13826
|
+
name: "Speech"
|
|
13828
13827
|
},
|
|
13829
13828
|
{
|
|
13830
13829
|
id: "scream",
|
|
13831
|
-
name: "Scream / Shout"
|
|
13832
|
-
icon: "😱"
|
|
13830
|
+
name: "Scream / Shout"
|
|
13833
13831
|
},
|
|
13834
13832
|
{
|
|
13835
13833
|
id: "crying",
|
|
13836
|
-
name: "Crying / Baby"
|
|
13837
|
-
icon: "😢"
|
|
13834
|
+
name: "Crying / Baby"
|
|
13838
13835
|
},
|
|
13839
13836
|
{
|
|
13840
13837
|
id: "laughter",
|
|
13841
|
-
name: "Laughter"
|
|
13842
|
-
icon: "😂"
|
|
13838
|
+
name: "Laughter"
|
|
13843
13839
|
},
|
|
13844
13840
|
{
|
|
13845
13841
|
id: "music",
|
|
13846
|
-
name: "Music"
|
|
13847
|
-
icon: "🎵"
|
|
13842
|
+
name: "Music"
|
|
13848
13843
|
},
|
|
13849
13844
|
{
|
|
13850
13845
|
id: "dog",
|
|
13851
|
-
name: "Dog"
|
|
13852
|
-
icon: "🐕"
|
|
13846
|
+
name: "Dog"
|
|
13853
13847
|
},
|
|
13854
13848
|
{
|
|
13855
13849
|
id: "cat",
|
|
13856
|
-
name: "Cat"
|
|
13857
|
-
icon: "🐈"
|
|
13850
|
+
name: "Cat"
|
|
13858
13851
|
},
|
|
13859
13852
|
{
|
|
13860
13853
|
id: "bird",
|
|
13861
|
-
name: "Bird"
|
|
13862
|
-
icon: "🐦"
|
|
13854
|
+
name: "Bird"
|
|
13863
13855
|
},
|
|
13864
13856
|
{
|
|
13865
13857
|
id: "animal",
|
|
13866
|
-
name: "Animal (other)"
|
|
13867
|
-
icon: "🐾"
|
|
13858
|
+
name: "Animal (other)"
|
|
13868
13859
|
},
|
|
13869
13860
|
{
|
|
13870
13861
|
id: "alarm",
|
|
13871
|
-
name: "Alarm / Siren"
|
|
13872
|
-
icon: "🚨"
|
|
13862
|
+
name: "Alarm / Siren"
|
|
13873
13863
|
},
|
|
13874
13864
|
{
|
|
13875
13865
|
id: "doorbell",
|
|
13876
|
-
name: "Doorbell / Knock"
|
|
13877
|
-
icon: "🔔"
|
|
13866
|
+
name: "Doorbell / Knock"
|
|
13878
13867
|
},
|
|
13879
13868
|
{
|
|
13880
13869
|
id: "glass_breaking",
|
|
13881
|
-
name: "Glass Breaking"
|
|
13882
|
-
icon: "💥"
|
|
13870
|
+
name: "Glass Breaking"
|
|
13883
13871
|
},
|
|
13884
13872
|
{
|
|
13885
13873
|
id: "gunshot",
|
|
13886
|
-
name: "Gunshot / Explosion"
|
|
13887
|
-
icon: "💣"
|
|
13874
|
+
name: "Gunshot / Explosion"
|
|
13888
13875
|
},
|
|
13889
13876
|
{
|
|
13890
13877
|
id: "vehicle",
|
|
13891
|
-
name: "Vehicle"
|
|
13892
|
-
icon: "🚗"
|
|
13878
|
+
name: "Vehicle"
|
|
13893
13879
|
},
|
|
13894
13880
|
{
|
|
13895
13881
|
id: "siren",
|
|
13896
|
-
name: "Emergency Siren"
|
|
13897
|
-
icon: "🚑"
|
|
13882
|
+
name: "Emergency Siren"
|
|
13898
13883
|
},
|
|
13899
13884
|
{
|
|
13900
13885
|
id: "fire",
|
|
13901
|
-
name: "Fire / Smoke"
|
|
13902
|
-
icon: "🔥"
|
|
13886
|
+
name: "Fire / Smoke"
|
|
13903
13887
|
},
|
|
13904
13888
|
{
|
|
13905
13889
|
id: "water",
|
|
13906
|
-
name: "Water"
|
|
13907
|
-
icon: "💧"
|
|
13890
|
+
name: "Water"
|
|
13908
13891
|
},
|
|
13909
13892
|
{
|
|
13910
13893
|
id: "wind",
|
|
13911
|
-
name: "Wind / Weather"
|
|
13912
|
-
icon: "🌬️"
|
|
13894
|
+
name: "Wind / Weather"
|
|
13913
13895
|
},
|
|
13914
13896
|
{
|
|
13915
13897
|
id: "door",
|
|
13916
|
-
name: "Door"
|
|
13917
|
-
icon: "🚪"
|
|
13898
|
+
name: "Door"
|
|
13918
13899
|
},
|
|
13919
13900
|
{
|
|
13920
13901
|
id: "footsteps",
|
|
13921
|
-
name: "Footsteps"
|
|
13922
|
-
icon: "👣"
|
|
13902
|
+
name: "Footsteps"
|
|
13923
13903
|
},
|
|
13924
13904
|
{
|
|
13925
13905
|
id: "crowd",
|
|
13926
|
-
name: "Crowd / Chatter"
|
|
13927
|
-
icon: "👥"
|
|
13906
|
+
name: "Crowd / Chatter"
|
|
13928
13907
|
},
|
|
13929
13908
|
{
|
|
13930
13909
|
id: "telephone",
|
|
13931
|
-
name: "Telephone"
|
|
13932
|
-
icon: "📞"
|
|
13910
|
+
name: "Telephone"
|
|
13933
13911
|
},
|
|
13934
13912
|
{
|
|
13935
13913
|
id: "engine",
|
|
13936
|
-
name: "Engine / Motor"
|
|
13937
|
-
icon: "⚙️"
|
|
13914
|
+
name: "Engine / Motor"
|
|
13938
13915
|
},
|
|
13939
13916
|
{
|
|
13940
13917
|
id: "tools",
|
|
13941
|
-
name: "Tools / Construction"
|
|
13942
|
-
icon: "🔨"
|
|
13918
|
+
name: "Tools / Construction"
|
|
13943
13919
|
},
|
|
13944
13920
|
{
|
|
13945
13921
|
id: "silence",
|
|
13946
|
-
name: "Silence"
|
|
13947
|
-
icon: "🤫"
|
|
13922
|
+
name: "Silence"
|
|
13948
13923
|
}
|
|
13949
13924
|
];
|
|
13950
13925
|
var YAMNET_TO_MACRO = {
|
|
@@ -16446,7 +16421,7 @@ var TrackEnvelopeSchema = object({
|
|
|
16446
16421
|
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16447
16422
|
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16448
16423
|
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16449
|
-
* zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
|
|
16424
|
+
* zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
|
|
16450
16425
|
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16451
16426
|
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16452
16427
|
* (`getObjectEvents` et al.).
|
|
@@ -16741,6 +16716,35 @@ var TrackSchema = object({
|
|
|
16741
16716
|
*/
|
|
16742
16717
|
hasFace: boolean().optional(),
|
|
16743
16718
|
/**
|
|
16719
|
+
* This track has a face row IN THE GALLERY: a crop **and** an embedding — a
|
|
16720
|
+
* face an operator could ASSIGN to an identity.
|
|
16721
|
+
*
|
|
16722
|
+
* The STRICT twin of {@link hasFace}, and the pair only earns its keep
|
|
16723
|
+
* because the two disagree. `hasFace` is stamped at the TOP of the face
|
|
16724
|
+
* branch, before every gate, and means no more than "a face detector produced
|
|
16725
|
+
* a face detail". This one is stamped at the single moment the gallery row
|
|
16726
|
+
* LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
|
|
16727
|
+
* past the embedding-magnitude verdict, the `minFacePx` detection gate, the
|
|
16728
|
+
* candidate gate, the imageless-track drop (no crop was ever captured) and
|
|
16729
|
+
* the crop-store drop. Everything between the detector and that insert can
|
|
16730
|
+
* legitimately refuse the face, so a flag written any earlier promises the
|
|
16731
|
+
* operator something to assign and delivers nothing.
|
|
16732
|
+
*
|
|
16733
|
+
* **Independent of recognition.** A face collected but never auto-matched is
|
|
16734
|
+
* still assignable — it is in fact the face an operator most wants to reach —
|
|
16735
|
+
* so this is NOT gated on `recognizedIdentityId`. Recognition lands in
|
|
16736
|
+
* `subLabel`; this says only that the raw material exists.
|
|
16737
|
+
*
|
|
16738
|
+
* **Set once, never cleared.** A track that produced a gallery row produced
|
|
16739
|
+
* one; deleting the row later is the gallery's business, not this flag's.
|
|
16740
|
+
*
|
|
16741
|
+
* **Absent ≠ false**, the same rule as {@link hasFace}: every row written
|
|
16742
|
+
* before the column omits it, and so does every server that predates the
|
|
16743
|
+
* field. A consumer must test `=== true` and render nothing otherwise —
|
|
16744
|
+
* never infer "no assignable face".
|
|
16745
|
+
*/
|
|
16746
|
+
hasEmbeddedFace: boolean().optional(),
|
|
16747
|
+
/**
|
|
16744
16748
|
* This subject CONTAINS a folded rider — a person the rider-pairing step
|
|
16745
16749
|
* ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
|
|
16746
16750
|
* so the passage is tracked once and as a VEHICLE.
|
|
@@ -18130,6 +18134,32 @@ var DetailResultSchema = object({
|
|
|
18130
18134
|
/** FRAME-space bbox (already mapped back from crop space). */
|
|
18131
18135
|
bbox: NativeCropBboxSchema.optional(),
|
|
18132
18136
|
embedding: string().optional(),
|
|
18137
|
+
/**
|
|
18138
|
+
* L2 magnitude of the RAW pre-normalization embedding. Additive and optional
|
|
18139
|
+
* so an older runner that does not send it degrades to "unmeasurable", which
|
|
18140
|
+
* the consuming gate treats as accept — never as reject.
|
|
18141
|
+
*/
|
|
18142
|
+
embeddingMagnitude: number().optional(),
|
|
18143
|
+
/**
|
|
18144
|
+
* Model that produced `embedding` — the SAME contract `labelModelId` has for
|
|
18145
|
+
* `label`, and for the same reason: the producing node is the only side that
|
|
18146
|
+
* knows which model actually ran, and re-deriving it downstream is exactly
|
|
18147
|
+
* the inference this model exists to forbid.
|
|
18148
|
+
*
|
|
18149
|
+
* Additive and optional, so a runner that predates it degrades to
|
|
18150
|
+
* "unmeasurable" rather than to a wrong answer — the consumer falls back to
|
|
18151
|
+
* its previous assumption instead of refusing.
|
|
18152
|
+
*
|
|
18153
|
+
* Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
|
|
18154
|
+
* to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
|
|
18155
|
+
* with nothing on the wire it took the id from the GALLERY, so the gate
|
|
18156
|
+
* compared the gallery against itself and could never fire. That turned the
|
|
18157
|
+
* one guard protecting the face feature space into a tautology, and it is
|
|
18158
|
+
* why swapping `face-embedding`'s model would NOT have stranded the enrolled
|
|
18159
|
+
* gallery as the catalog comment predicts — it would have scored the new
|
|
18160
|
+
* model's vectors against the old model's samples in one cosine space.
|
|
18161
|
+
*/
|
|
18162
|
+
embeddingModelId: string().optional(),
|
|
18133
18163
|
label: string().optional(),
|
|
18134
18164
|
/**
|
|
18135
18165
|
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
@@ -19540,6 +19570,7 @@ DeviceType.Camera, method(object({
|
|
|
19540
19570
|
isBattery: boolean(),
|
|
19541
19571
|
reason: _enum([
|
|
19542
19572
|
"disabled",
|
|
19573
|
+
"offline",
|
|
19543
19574
|
"sleeping",
|
|
19544
19575
|
"unreachable",
|
|
19545
19576
|
"waking"
|
|
@@ -19585,9 +19616,17 @@ targets: array(object({
|
|
|
19585
19616
|
sleeping: boolean(),
|
|
19586
19617
|
/** Current device state rendered over the cached frame. State images
|
|
19587
19618
|
* remain authoritative even when their photographic background is
|
|
19588
|
-
* old; null means the link must carry a current camera frame.
|
|
19619
|
+
* old; null means the link must carry a current camera frame.
|
|
19620
|
+
*
|
|
19621
|
+
* **This is the ONLY source a surface may derive an inactive tile
|
|
19622
|
+
* from.** A client that reads a device's `online`/`disabled` flags and
|
|
19623
|
+
* draws its own verdict will disagree with the pixels it is painting
|
|
19624
|
+
* — the frame comes from here, and so must the sentence over it
|
|
19625
|
+
* (D190). Pair with `ageMs` for the age of the photograph behind the
|
|
19626
|
+
* state. */
|
|
19589
19627
|
stateReason: _enum([
|
|
19590
19628
|
"disabled",
|
|
19629
|
+
"offline",
|
|
19591
19630
|
"sleeping",
|
|
19592
19631
|
"unreachable",
|
|
19593
19632
|
"waking"
|
|
@@ -26314,9 +26353,21 @@ var RecordingLocationUsageSchema = object({
|
|
|
26314
26353
|
* previously rendered as two identical "disks" with a nonsensical used
|
|
26315
26354
|
* split — hydrate attribution across aliases is arbitrary by nature. */
|
|
26316
26355
|
locationIds: array(string()).optional(),
|
|
26317
|
-
/**
|
|
26356
|
+
/**
|
|
26357
|
+
* Filesystem root of the physical volume this row accounts — the only
|
|
26358
|
+
* operator-legible identity when a location has no `displayName` yet, and
|
|
26359
|
+
* what a "which disk is full" alert has to name. OPTIONAL for the same
|
|
26360
|
+
* train-skew reason as `oldestMs`: a recorder that predates the field omits
|
|
26361
|
+
* it, and this schema must keep validating that older provider's payload.
|
|
26362
|
+
*/
|
|
26363
|
+
root: string().optional(),
|
|
26364
|
+
/** Bytes of recordings stored on this PHYSICAL volume (all aliases). This is
|
|
26365
|
+
* the footage's SHARE of the volume, not how full the volume is — the disk
|
|
26366
|
+
* also holds everything that is not recordings. Volume fill is
|
|
26367
|
+
* `(totalBytes - availableBytes) / totalBytes`. */
|
|
26318
26368
|
usedBytes: number(),
|
|
26319
|
-
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26369
|
+
/** Free bytes on the location's volume; null when capacity is unknown
|
|
26370
|
+
* (remote/unstattable — the recorder logs the statfs failure with the root). */
|
|
26320
26371
|
availableBytes: number().nullable(),
|
|
26321
26372
|
/** Total bytes of the location's volume; null when unknown. */
|
|
26322
26373
|
totalBytes: number().nullable()
|
|
@@ -26328,7 +26379,15 @@ var RecordingStorageUsageSchema = object({
|
|
|
26328
26379
|
nodeId: string(),
|
|
26329
26380
|
totalUsedBytes: number(),
|
|
26330
26381
|
devices: array(RecordingDeviceUsageSchema),
|
|
26331
|
-
|
|
26382
|
+
/**
|
|
26383
|
+
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
26384
|
+
* of the payload without it: the hub serves this method through a BAKED
|
|
26385
|
+
* router, so a hub whose framework train predates a change to this array
|
|
26386
|
+
* strips it out of an answer a newer recorder happily produced. A UI that
|
|
26387
|
+
* dereferences it unconditionally crashes the whole Storage page over a
|
|
26388
|
+
* missing disk bar.
|
|
26389
|
+
*/
|
|
26390
|
+
locations: array(RecordingLocationUsageSchema).optional()
|
|
26332
26391
|
});
|
|
26333
26392
|
/**
|
|
26334
26393
|
* The OPERATOR-ARMED half of multi-location recordings (D116).
|
|
@@ -37113,8 +37172,13 @@ Object.freeze({
|
|
|
37113
37172
|
"network-access": "ingress",
|
|
37114
37173
|
"smtp-provider": "email"
|
|
37115
37174
|
});
|
|
37116
|
-
|
|
37175
|
+
/** Schema defaults — an untouched sub-field must author exactly these. */
|
|
37176
|
+
var NC_AUDIO_DEFAULTS = {
|
|
37177
|
+
hitPercent: 60,
|
|
37178
|
+
samplingSeconds: 10
|
|
37179
|
+
};
|
|
37117
37180
|
new Set(["devices", "classes"]);
|
|
37181
|
+
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
37118
37182
|
/**
|
|
37119
37183
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
37120
37184
|
*
|
|
@@ -37346,6 +37410,39 @@ TimelapseRuleInputSchema.extend({
|
|
|
37346
37410
|
createdAt: number(),
|
|
37347
37411
|
updatedAt: number()
|
|
37348
37412
|
});
|
|
37413
|
+
Object.freeze(Object.fromEntries([{
|
|
37414
|
+
stepId: "face-embedding",
|
|
37415
|
+
label: "Face recognition model",
|
|
37416
|
+
defaultModelId: "arcface-r100",
|
|
37417
|
+
indexName: "the enrolled face gallery",
|
|
37418
|
+
options: [
|
|
37419
|
+
{
|
|
37420
|
+
id: "arcface-r100",
|
|
37421
|
+
label: "ArcFace (ResNet34)"
|
|
37422
|
+
},
|
|
37423
|
+
{
|
|
37424
|
+
id: "auraface-r100",
|
|
37425
|
+
label: "AuraFace R100"
|
|
37426
|
+
},
|
|
37427
|
+
{
|
|
37428
|
+
id: "inception-resnet-v1",
|
|
37429
|
+
label: "Inception ResNet V1"
|
|
37430
|
+
}
|
|
37431
|
+
]
|
|
37432
|
+
}, {
|
|
37433
|
+
stepId: "clip-embedding",
|
|
37434
|
+
label: "Semantic search model",
|
|
37435
|
+
defaultModelId: "mobileclip-s1",
|
|
37436
|
+
indexName: "the object semantic-search index",
|
|
37437
|
+
options: [{
|
|
37438
|
+
id: "mobileclip-s1",
|
|
37439
|
+
label: "MobileCLIP S1"
|
|
37440
|
+
}, {
|
|
37441
|
+
id: "mobileclip-s2",
|
|
37442
|
+
label: "MobileCLIP S2"
|
|
37443
|
+
}]
|
|
37444
|
+
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
37445
|
+
string().min(1);
|
|
37349
37446
|
object({
|
|
37350
37447
|
/**
|
|
37351
37448
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -37366,10 +37463,21 @@ object({
|
|
|
37366
37463
|
*/
|
|
37367
37464
|
square: boolean()
|
|
37368
37465
|
});
|
|
37369
|
-
|
|
37466
|
+
/**
|
|
37467
|
+
* The convention in force when nobody has configured one — byte-for-byte the
|
|
37468
|
+
* behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
|
|
37469
|
+
*/
|
|
37470
|
+
var DEFAULT_DETAIL_CROP_CONVENTION = {
|
|
37370
37471
|
paddingRatio: .15,
|
|
37371
37472
|
square: false
|
|
37372
|
-
}
|
|
37473
|
+
};
|
|
37474
|
+
Object.freeze({
|
|
37475
|
+
x: 0,
|
|
37476
|
+
y: 0,
|
|
37477
|
+
w: 1,
|
|
37478
|
+
h: 1
|
|
37479
|
+
});
|
|
37480
|
+
DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
|
|
37373
37481
|
/**
|
|
37374
37482
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
37375
37483
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-dreo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.24",
|
|
4
4
|
"description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|