@camstack/addon-provider-homematic 1.2.24 → 1.2.25
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 +138 -56
- package/dist/addon.mjs +138 -56
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -7575,7 +7575,7 @@ var RecordingBandSchema = object({
|
|
|
7575
7575
|
postBufferSec: number().min(0).optional()
|
|
7576
7576
|
});
|
|
7577
7577
|
({
|
|
7578
|
-
preBufferSec:
|
|
7578
|
+
preBufferSec: 15,
|
|
7579
7579
|
postBufferSec: 30
|
|
7580
7580
|
}).postBufferSec * 1e3;
|
|
7581
7581
|
/**
|
|
@@ -13844,128 +13844,103 @@ var COCO_TO_MACRO = {
|
|
|
13844
13844
|
var AUDIO_MACRO_LABELS = [
|
|
13845
13845
|
{
|
|
13846
13846
|
id: "speech",
|
|
13847
|
-
name: "Speech"
|
|
13848
|
-
icon: "🗣️"
|
|
13847
|
+
name: "Speech"
|
|
13849
13848
|
},
|
|
13850
13849
|
{
|
|
13851
13850
|
id: "scream",
|
|
13852
|
-
name: "Scream / Shout"
|
|
13853
|
-
icon: "😱"
|
|
13851
|
+
name: "Scream / Shout"
|
|
13854
13852
|
},
|
|
13855
13853
|
{
|
|
13856
13854
|
id: "crying",
|
|
13857
|
-
name: "Crying / Baby"
|
|
13858
|
-
icon: "😢"
|
|
13855
|
+
name: "Crying / Baby"
|
|
13859
13856
|
},
|
|
13860
13857
|
{
|
|
13861
13858
|
id: "laughter",
|
|
13862
|
-
name: "Laughter"
|
|
13863
|
-
icon: "😂"
|
|
13859
|
+
name: "Laughter"
|
|
13864
13860
|
},
|
|
13865
13861
|
{
|
|
13866
13862
|
id: "music",
|
|
13867
|
-
name: "Music"
|
|
13868
|
-
icon: "🎵"
|
|
13863
|
+
name: "Music"
|
|
13869
13864
|
},
|
|
13870
13865
|
{
|
|
13871
13866
|
id: "dog",
|
|
13872
|
-
name: "Dog"
|
|
13873
|
-
icon: "🐕"
|
|
13867
|
+
name: "Dog"
|
|
13874
13868
|
},
|
|
13875
13869
|
{
|
|
13876
13870
|
id: "cat",
|
|
13877
|
-
name: "Cat"
|
|
13878
|
-
icon: "🐈"
|
|
13871
|
+
name: "Cat"
|
|
13879
13872
|
},
|
|
13880
13873
|
{
|
|
13881
13874
|
id: "bird",
|
|
13882
|
-
name: "Bird"
|
|
13883
|
-
icon: "🐦"
|
|
13875
|
+
name: "Bird"
|
|
13884
13876
|
},
|
|
13885
13877
|
{
|
|
13886
13878
|
id: "animal",
|
|
13887
|
-
name: "Animal (other)"
|
|
13888
|
-
icon: "🐾"
|
|
13879
|
+
name: "Animal (other)"
|
|
13889
13880
|
},
|
|
13890
13881
|
{
|
|
13891
13882
|
id: "alarm",
|
|
13892
|
-
name: "Alarm / Siren"
|
|
13893
|
-
icon: "🚨"
|
|
13883
|
+
name: "Alarm / Siren"
|
|
13894
13884
|
},
|
|
13895
13885
|
{
|
|
13896
13886
|
id: "doorbell",
|
|
13897
|
-
name: "Doorbell / Knock"
|
|
13898
|
-
icon: "🔔"
|
|
13887
|
+
name: "Doorbell / Knock"
|
|
13899
13888
|
},
|
|
13900
13889
|
{
|
|
13901
13890
|
id: "glass_breaking",
|
|
13902
|
-
name: "Glass Breaking"
|
|
13903
|
-
icon: "💥"
|
|
13891
|
+
name: "Glass Breaking"
|
|
13904
13892
|
},
|
|
13905
13893
|
{
|
|
13906
13894
|
id: "gunshot",
|
|
13907
|
-
name: "Gunshot / Explosion"
|
|
13908
|
-
icon: "💣"
|
|
13895
|
+
name: "Gunshot / Explosion"
|
|
13909
13896
|
},
|
|
13910
13897
|
{
|
|
13911
13898
|
id: "vehicle",
|
|
13912
|
-
name: "Vehicle"
|
|
13913
|
-
icon: "🚗"
|
|
13899
|
+
name: "Vehicle"
|
|
13914
13900
|
},
|
|
13915
13901
|
{
|
|
13916
13902
|
id: "siren",
|
|
13917
|
-
name: "Emergency Siren"
|
|
13918
|
-
icon: "🚑"
|
|
13903
|
+
name: "Emergency Siren"
|
|
13919
13904
|
},
|
|
13920
13905
|
{
|
|
13921
13906
|
id: "fire",
|
|
13922
|
-
name: "Fire / Smoke"
|
|
13923
|
-
icon: "🔥"
|
|
13907
|
+
name: "Fire / Smoke"
|
|
13924
13908
|
},
|
|
13925
13909
|
{
|
|
13926
13910
|
id: "water",
|
|
13927
|
-
name: "Water"
|
|
13928
|
-
icon: "💧"
|
|
13911
|
+
name: "Water"
|
|
13929
13912
|
},
|
|
13930
13913
|
{
|
|
13931
13914
|
id: "wind",
|
|
13932
|
-
name: "Wind / Weather"
|
|
13933
|
-
icon: "🌬️"
|
|
13915
|
+
name: "Wind / Weather"
|
|
13934
13916
|
},
|
|
13935
13917
|
{
|
|
13936
13918
|
id: "door",
|
|
13937
|
-
name: "Door"
|
|
13938
|
-
icon: "🚪"
|
|
13919
|
+
name: "Door"
|
|
13939
13920
|
},
|
|
13940
13921
|
{
|
|
13941
13922
|
id: "footsteps",
|
|
13942
|
-
name: "Footsteps"
|
|
13943
|
-
icon: "👣"
|
|
13923
|
+
name: "Footsteps"
|
|
13944
13924
|
},
|
|
13945
13925
|
{
|
|
13946
13926
|
id: "crowd",
|
|
13947
|
-
name: "Crowd / Chatter"
|
|
13948
|
-
icon: "👥"
|
|
13927
|
+
name: "Crowd / Chatter"
|
|
13949
13928
|
},
|
|
13950
13929
|
{
|
|
13951
13930
|
id: "telephone",
|
|
13952
|
-
name: "Telephone"
|
|
13953
|
-
icon: "📞"
|
|
13931
|
+
name: "Telephone"
|
|
13954
13932
|
},
|
|
13955
13933
|
{
|
|
13956
13934
|
id: "engine",
|
|
13957
|
-
name: "Engine / Motor"
|
|
13958
|
-
icon: "⚙️"
|
|
13935
|
+
name: "Engine / Motor"
|
|
13959
13936
|
},
|
|
13960
13937
|
{
|
|
13961
13938
|
id: "tools",
|
|
13962
|
-
name: "Tools / Construction"
|
|
13963
|
-
icon: "🔨"
|
|
13939
|
+
name: "Tools / Construction"
|
|
13964
13940
|
},
|
|
13965
13941
|
{
|
|
13966
13942
|
id: "silence",
|
|
13967
|
-
name: "Silence"
|
|
13968
|
-
icon: "🤫"
|
|
13943
|
+
name: "Silence"
|
|
13969
13944
|
}
|
|
13970
13945
|
];
|
|
13971
13946
|
var YAMNET_TO_MACRO = {
|
|
@@ -16467,7 +16442,7 @@ var TrackEnvelopeSchema = object({
|
|
|
16467
16442
|
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16468
16443
|
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16469
16444
|
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16470
|
-
* zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
|
|
16445
|
+
* zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
|
|
16471
16446
|
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16472
16447
|
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16473
16448
|
* (`getObjectEvents` et al.).
|
|
@@ -16762,6 +16737,35 @@ var TrackSchema = object({
|
|
|
16762
16737
|
*/
|
|
16763
16738
|
hasFace: boolean().optional(),
|
|
16764
16739
|
/**
|
|
16740
|
+
* This track has a face row IN THE GALLERY: a crop **and** an embedding — a
|
|
16741
|
+
* face an operator could ASSIGN to an identity.
|
|
16742
|
+
*
|
|
16743
|
+
* The STRICT twin of {@link hasFace}, and the pair only earns its keep
|
|
16744
|
+
* because the two disagree. `hasFace` is stamped at the TOP of the face
|
|
16745
|
+
* branch, before every gate, and means no more than "a face detector produced
|
|
16746
|
+
* a face detail". This one is stamped at the single moment the gallery row
|
|
16747
|
+
* LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
|
|
16748
|
+
* past the embedding-magnitude verdict, the `minFacePx` detection gate, the
|
|
16749
|
+
* candidate gate, the imageless-track drop (no crop was ever captured) and
|
|
16750
|
+
* the crop-store drop. Everything between the detector and that insert can
|
|
16751
|
+
* legitimately refuse the face, so a flag written any earlier promises the
|
|
16752
|
+
* operator something to assign and delivers nothing.
|
|
16753
|
+
*
|
|
16754
|
+
* **Independent of recognition.** A face collected but never auto-matched is
|
|
16755
|
+
* still assignable — it is in fact the face an operator most wants to reach —
|
|
16756
|
+
* so this is NOT gated on `recognizedIdentityId`. Recognition lands in
|
|
16757
|
+
* `subLabel`; this says only that the raw material exists.
|
|
16758
|
+
*
|
|
16759
|
+
* **Set once, never cleared.** A track that produced a gallery row produced
|
|
16760
|
+
* one; deleting the row later is the gallery's business, not this flag's.
|
|
16761
|
+
*
|
|
16762
|
+
* **Absent ≠ false**, the same rule as {@link hasFace}: every row written
|
|
16763
|
+
* before the column omits it, and so does every server that predates the
|
|
16764
|
+
* field. A consumer must test `=== true` and render nothing otherwise —
|
|
16765
|
+
* never infer "no assignable face".
|
|
16766
|
+
*/
|
|
16767
|
+
hasEmbeddedFace: boolean().optional(),
|
|
16768
|
+
/**
|
|
16765
16769
|
* This subject CONTAINS a folded rider — a person the rider-pairing step
|
|
16766
16770
|
* ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
|
|
16767
16771
|
* so the passage is tracked once and as a VEHICLE.
|
|
@@ -18151,6 +18155,32 @@ var DetailResultSchema = object({
|
|
|
18151
18155
|
/** FRAME-space bbox (already mapped back from crop space). */
|
|
18152
18156
|
bbox: NativeCropBboxSchema.optional(),
|
|
18153
18157
|
embedding: string().optional(),
|
|
18158
|
+
/**
|
|
18159
|
+
* L2 magnitude of the RAW pre-normalization embedding. Additive and optional
|
|
18160
|
+
* so an older runner that does not send it degrades to "unmeasurable", which
|
|
18161
|
+
* the consuming gate treats as accept — never as reject.
|
|
18162
|
+
*/
|
|
18163
|
+
embeddingMagnitude: number().optional(),
|
|
18164
|
+
/**
|
|
18165
|
+
* Model that produced `embedding` — the SAME contract `labelModelId` has for
|
|
18166
|
+
* `label`, and for the same reason: the producing node is the only side that
|
|
18167
|
+
* knows which model actually ran, and re-deriving it downstream is exactly
|
|
18168
|
+
* the inference this model exists to forbid.
|
|
18169
|
+
*
|
|
18170
|
+
* Additive and optional, so a runner that predates it degrades to
|
|
18171
|
+
* "unmeasurable" rather than to a wrong answer — the consumer falls back to
|
|
18172
|
+
* its previous assumption instead of refusing.
|
|
18173
|
+
*
|
|
18174
|
+
* Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
|
|
18175
|
+
* to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
|
|
18176
|
+
* with nothing on the wire it took the id from the GALLERY, so the gate
|
|
18177
|
+
* compared the gallery against itself and could never fire. That turned the
|
|
18178
|
+
* one guard protecting the face feature space into a tautology, and it is
|
|
18179
|
+
* why swapping `face-embedding`'s model would NOT have stranded the enrolled
|
|
18180
|
+
* gallery as the catalog comment predicts — it would have scored the new
|
|
18181
|
+
* model's vectors against the old model's samples in one cosine space.
|
|
18182
|
+
*/
|
|
18183
|
+
embeddingModelId: string().optional(),
|
|
18154
18184
|
label: string().optional(),
|
|
18155
18185
|
/**
|
|
18156
18186
|
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
@@ -19561,6 +19591,7 @@ DeviceType.Camera, method(object({
|
|
|
19561
19591
|
isBattery: boolean(),
|
|
19562
19592
|
reason: _enum([
|
|
19563
19593
|
"disabled",
|
|
19594
|
+
"offline",
|
|
19564
19595
|
"sleeping",
|
|
19565
19596
|
"unreachable",
|
|
19566
19597
|
"waking"
|
|
@@ -19606,9 +19637,17 @@ targets: array(object({
|
|
|
19606
19637
|
sleeping: boolean(),
|
|
19607
19638
|
/** Current device state rendered over the cached frame. State images
|
|
19608
19639
|
* remain authoritative even when their photographic background is
|
|
19609
|
-
* old; null means the link must carry a current camera frame.
|
|
19640
|
+
* old; null means the link must carry a current camera frame.
|
|
19641
|
+
*
|
|
19642
|
+
* **This is the ONLY source a surface may derive an inactive tile
|
|
19643
|
+
* from.** A client that reads a device's `online`/`disabled` flags and
|
|
19644
|
+
* draws its own verdict will disagree with the pixels it is painting
|
|
19645
|
+
* — the frame comes from here, and so must the sentence over it
|
|
19646
|
+
* (D190). Pair with `ageMs` for the age of the photograph behind the
|
|
19647
|
+
* state. */
|
|
19610
19648
|
stateReason: _enum([
|
|
19611
19649
|
"disabled",
|
|
19650
|
+
"offline",
|
|
19612
19651
|
"sleeping",
|
|
19613
19652
|
"unreachable",
|
|
19614
19653
|
"waking"
|
|
@@ -37151,7 +37190,6 @@ var NC_AUDIO_DEFAULTS = {
|
|
|
37151
37190
|
hitPercent: 60,
|
|
37152
37191
|
samplingSeconds: 10
|
|
37153
37192
|
};
|
|
37154
|
-
new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
|
|
37155
37193
|
new Set(["devices", "classes"]);
|
|
37156
37194
|
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
37157
37195
|
/**
|
|
@@ -37385,6 +37423,39 @@ TimelapseRuleInputSchema.extend({
|
|
|
37385
37423
|
createdAt: number(),
|
|
37386
37424
|
updatedAt: number()
|
|
37387
37425
|
});
|
|
37426
|
+
Object.freeze(Object.fromEntries([{
|
|
37427
|
+
stepId: "face-embedding",
|
|
37428
|
+
label: "Face recognition model",
|
|
37429
|
+
defaultModelId: "arcface-r100",
|
|
37430
|
+
indexName: "the enrolled face gallery",
|
|
37431
|
+
options: [
|
|
37432
|
+
{
|
|
37433
|
+
id: "arcface-r100",
|
|
37434
|
+
label: "ArcFace (ResNet34)"
|
|
37435
|
+
},
|
|
37436
|
+
{
|
|
37437
|
+
id: "auraface-r100",
|
|
37438
|
+
label: "AuraFace R100"
|
|
37439
|
+
},
|
|
37440
|
+
{
|
|
37441
|
+
id: "inception-resnet-v1",
|
|
37442
|
+
label: "Inception ResNet V1"
|
|
37443
|
+
}
|
|
37444
|
+
]
|
|
37445
|
+
}, {
|
|
37446
|
+
stepId: "clip-embedding",
|
|
37447
|
+
label: "Semantic search model",
|
|
37448
|
+
defaultModelId: "mobileclip-s1",
|
|
37449
|
+
indexName: "the object semantic-search index",
|
|
37450
|
+
options: [{
|
|
37451
|
+
id: "mobileclip-s1",
|
|
37452
|
+
label: "MobileCLIP S1"
|
|
37453
|
+
}, {
|
|
37454
|
+
id: "mobileclip-s2",
|
|
37455
|
+
label: "MobileCLIP S2"
|
|
37456
|
+
}]
|
|
37457
|
+
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
37458
|
+
string().min(1);
|
|
37388
37459
|
object({
|
|
37389
37460
|
/**
|
|
37390
37461
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -37405,10 +37476,21 @@ object({
|
|
|
37405
37476
|
*/
|
|
37406
37477
|
square: boolean()
|
|
37407
37478
|
});
|
|
37408
|
-
|
|
37479
|
+
/**
|
|
37480
|
+
* The convention in force when nobody has configured one — byte-for-byte the
|
|
37481
|
+
* behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
|
|
37482
|
+
*/
|
|
37483
|
+
var DEFAULT_DETAIL_CROP_CONVENTION = {
|
|
37409
37484
|
paddingRatio: .15,
|
|
37410
37485
|
square: false
|
|
37411
|
-
}
|
|
37486
|
+
};
|
|
37487
|
+
Object.freeze({
|
|
37488
|
+
x: 0,
|
|
37489
|
+
y: 0,
|
|
37490
|
+
w: 1,
|
|
37491
|
+
h: 1
|
|
37492
|
+
});
|
|
37493
|
+
DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
|
|
37412
37494
|
/**
|
|
37413
37495
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
37414
37496
|
*
|
package/dist/addon.mjs
CHANGED
|
@@ -7576,7 +7576,7 @@ var RecordingBandSchema = object({
|
|
|
7576
7576
|
postBufferSec: number().min(0).optional()
|
|
7577
7577
|
});
|
|
7578
7578
|
({
|
|
7579
|
-
preBufferSec:
|
|
7579
|
+
preBufferSec: 15,
|
|
7580
7580
|
postBufferSec: 30
|
|
7581
7581
|
}).postBufferSec * 1e3;
|
|
7582
7582
|
/**
|
|
@@ -13845,128 +13845,103 @@ var COCO_TO_MACRO = {
|
|
|
13845
13845
|
var AUDIO_MACRO_LABELS = [
|
|
13846
13846
|
{
|
|
13847
13847
|
id: "speech",
|
|
13848
|
-
name: "Speech"
|
|
13849
|
-
icon: "🗣️"
|
|
13848
|
+
name: "Speech"
|
|
13850
13849
|
},
|
|
13851
13850
|
{
|
|
13852
13851
|
id: "scream",
|
|
13853
|
-
name: "Scream / Shout"
|
|
13854
|
-
icon: "😱"
|
|
13852
|
+
name: "Scream / Shout"
|
|
13855
13853
|
},
|
|
13856
13854
|
{
|
|
13857
13855
|
id: "crying",
|
|
13858
|
-
name: "Crying / Baby"
|
|
13859
|
-
icon: "😢"
|
|
13856
|
+
name: "Crying / Baby"
|
|
13860
13857
|
},
|
|
13861
13858
|
{
|
|
13862
13859
|
id: "laughter",
|
|
13863
|
-
name: "Laughter"
|
|
13864
|
-
icon: "😂"
|
|
13860
|
+
name: "Laughter"
|
|
13865
13861
|
},
|
|
13866
13862
|
{
|
|
13867
13863
|
id: "music",
|
|
13868
|
-
name: "Music"
|
|
13869
|
-
icon: "🎵"
|
|
13864
|
+
name: "Music"
|
|
13870
13865
|
},
|
|
13871
13866
|
{
|
|
13872
13867
|
id: "dog",
|
|
13873
|
-
name: "Dog"
|
|
13874
|
-
icon: "🐕"
|
|
13868
|
+
name: "Dog"
|
|
13875
13869
|
},
|
|
13876
13870
|
{
|
|
13877
13871
|
id: "cat",
|
|
13878
|
-
name: "Cat"
|
|
13879
|
-
icon: "🐈"
|
|
13872
|
+
name: "Cat"
|
|
13880
13873
|
},
|
|
13881
13874
|
{
|
|
13882
13875
|
id: "bird",
|
|
13883
|
-
name: "Bird"
|
|
13884
|
-
icon: "🐦"
|
|
13876
|
+
name: "Bird"
|
|
13885
13877
|
},
|
|
13886
13878
|
{
|
|
13887
13879
|
id: "animal",
|
|
13888
|
-
name: "Animal (other)"
|
|
13889
|
-
icon: "🐾"
|
|
13880
|
+
name: "Animal (other)"
|
|
13890
13881
|
},
|
|
13891
13882
|
{
|
|
13892
13883
|
id: "alarm",
|
|
13893
|
-
name: "Alarm / Siren"
|
|
13894
|
-
icon: "🚨"
|
|
13884
|
+
name: "Alarm / Siren"
|
|
13895
13885
|
},
|
|
13896
13886
|
{
|
|
13897
13887
|
id: "doorbell",
|
|
13898
|
-
name: "Doorbell / Knock"
|
|
13899
|
-
icon: "🔔"
|
|
13888
|
+
name: "Doorbell / Knock"
|
|
13900
13889
|
},
|
|
13901
13890
|
{
|
|
13902
13891
|
id: "glass_breaking",
|
|
13903
|
-
name: "Glass Breaking"
|
|
13904
|
-
icon: "💥"
|
|
13892
|
+
name: "Glass Breaking"
|
|
13905
13893
|
},
|
|
13906
13894
|
{
|
|
13907
13895
|
id: "gunshot",
|
|
13908
|
-
name: "Gunshot / Explosion"
|
|
13909
|
-
icon: "💣"
|
|
13896
|
+
name: "Gunshot / Explosion"
|
|
13910
13897
|
},
|
|
13911
13898
|
{
|
|
13912
13899
|
id: "vehicle",
|
|
13913
|
-
name: "Vehicle"
|
|
13914
|
-
icon: "🚗"
|
|
13900
|
+
name: "Vehicle"
|
|
13915
13901
|
},
|
|
13916
13902
|
{
|
|
13917
13903
|
id: "siren",
|
|
13918
|
-
name: "Emergency Siren"
|
|
13919
|
-
icon: "🚑"
|
|
13904
|
+
name: "Emergency Siren"
|
|
13920
13905
|
},
|
|
13921
13906
|
{
|
|
13922
13907
|
id: "fire",
|
|
13923
|
-
name: "Fire / Smoke"
|
|
13924
|
-
icon: "🔥"
|
|
13908
|
+
name: "Fire / Smoke"
|
|
13925
13909
|
},
|
|
13926
13910
|
{
|
|
13927
13911
|
id: "water",
|
|
13928
|
-
name: "Water"
|
|
13929
|
-
icon: "💧"
|
|
13912
|
+
name: "Water"
|
|
13930
13913
|
},
|
|
13931
13914
|
{
|
|
13932
13915
|
id: "wind",
|
|
13933
|
-
name: "Wind / Weather"
|
|
13934
|
-
icon: "🌬️"
|
|
13916
|
+
name: "Wind / Weather"
|
|
13935
13917
|
},
|
|
13936
13918
|
{
|
|
13937
13919
|
id: "door",
|
|
13938
|
-
name: "Door"
|
|
13939
|
-
icon: "🚪"
|
|
13920
|
+
name: "Door"
|
|
13940
13921
|
},
|
|
13941
13922
|
{
|
|
13942
13923
|
id: "footsteps",
|
|
13943
|
-
name: "Footsteps"
|
|
13944
|
-
icon: "👣"
|
|
13924
|
+
name: "Footsteps"
|
|
13945
13925
|
},
|
|
13946
13926
|
{
|
|
13947
13927
|
id: "crowd",
|
|
13948
|
-
name: "Crowd / Chatter"
|
|
13949
|
-
icon: "👥"
|
|
13928
|
+
name: "Crowd / Chatter"
|
|
13950
13929
|
},
|
|
13951
13930
|
{
|
|
13952
13931
|
id: "telephone",
|
|
13953
|
-
name: "Telephone"
|
|
13954
|
-
icon: "📞"
|
|
13932
|
+
name: "Telephone"
|
|
13955
13933
|
},
|
|
13956
13934
|
{
|
|
13957
13935
|
id: "engine",
|
|
13958
|
-
name: "Engine / Motor"
|
|
13959
|
-
icon: "⚙️"
|
|
13936
|
+
name: "Engine / Motor"
|
|
13960
13937
|
},
|
|
13961
13938
|
{
|
|
13962
13939
|
id: "tools",
|
|
13963
|
-
name: "Tools / Construction"
|
|
13964
|
-
icon: "🔨"
|
|
13940
|
+
name: "Tools / Construction"
|
|
13965
13941
|
},
|
|
13966
13942
|
{
|
|
13967
13943
|
id: "silence",
|
|
13968
|
-
name: "Silence"
|
|
13969
|
-
icon: "🤫"
|
|
13944
|
+
name: "Silence"
|
|
13970
13945
|
}
|
|
13971
13946
|
];
|
|
13972
13947
|
var YAMNET_TO_MACRO = {
|
|
@@ -16468,7 +16443,7 @@ var TrackEnvelopeSchema = object({
|
|
|
16468
16443
|
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
16469
16444
|
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
16470
16445
|
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
16471
|
-
* zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
|
|
16446
|
+
* zonesVisited, bestEventId, envelope, hasFace, hasEmbeddedFace, hasRider) and returns `positions` /
|
|
16472
16447
|
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
16473
16448
|
* `getTrack`. Mirrors the event-store `projection` convention
|
|
16474
16449
|
* (`getObjectEvents` et al.).
|
|
@@ -16763,6 +16738,35 @@ var TrackSchema = object({
|
|
|
16763
16738
|
*/
|
|
16764
16739
|
hasFace: boolean().optional(),
|
|
16765
16740
|
/**
|
|
16741
|
+
* This track has a face row IN THE GALLERY: a crop **and** an embedding — a
|
|
16742
|
+
* face an operator could ASSIGN to an identity.
|
|
16743
|
+
*
|
|
16744
|
+
* The STRICT twin of {@link hasFace}, and the pair only earns its keep
|
|
16745
|
+
* because the two disagree. `hasFace` is stamped at the TOP of the face
|
|
16746
|
+
* branch, before every gate, and means no more than "a face detector produced
|
|
16747
|
+
* a face detail". This one is stamped at the single moment the gallery row
|
|
16748
|
+
* LANDS — after `FaceRecognizer.onTrackEnd` successfully persists it, i.e.
|
|
16749
|
+
* past the embedding-magnitude verdict, the `minFacePx` detection gate, the
|
|
16750
|
+
* candidate gate, the imageless-track drop (no crop was ever captured) and
|
|
16751
|
+
* the crop-store drop. Everything between the detector and that insert can
|
|
16752
|
+
* legitimately refuse the face, so a flag written any earlier promises the
|
|
16753
|
+
* operator something to assign and delivers nothing.
|
|
16754
|
+
*
|
|
16755
|
+
* **Independent of recognition.** A face collected but never auto-matched is
|
|
16756
|
+
* still assignable — it is in fact the face an operator most wants to reach —
|
|
16757
|
+
* so this is NOT gated on `recognizedIdentityId`. Recognition lands in
|
|
16758
|
+
* `subLabel`; this says only that the raw material exists.
|
|
16759
|
+
*
|
|
16760
|
+
* **Set once, never cleared.** A track that produced a gallery row produced
|
|
16761
|
+
* one; deleting the row later is the gallery's business, not this flag's.
|
|
16762
|
+
*
|
|
16763
|
+
* **Absent ≠ false**, the same rule as {@link hasFace}: every row written
|
|
16764
|
+
* before the column omits it, and so does every server that predates the
|
|
16765
|
+
* field. A consumer must test `=== true` and render nothing otherwise —
|
|
16766
|
+
* never infer "no assignable face".
|
|
16767
|
+
*/
|
|
16768
|
+
hasEmbeddedFace: boolean().optional(),
|
|
16769
|
+
/**
|
|
16766
16770
|
* This subject CONTAINS a folded rider — a person the rider-pairing step
|
|
16767
16771
|
* ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
|
|
16768
16772
|
* so the passage is tracked once and as a VEHICLE.
|
|
@@ -18152,6 +18156,32 @@ var DetailResultSchema = object({
|
|
|
18152
18156
|
/** FRAME-space bbox (already mapped back from crop space). */
|
|
18153
18157
|
bbox: NativeCropBboxSchema.optional(),
|
|
18154
18158
|
embedding: string().optional(),
|
|
18159
|
+
/**
|
|
18160
|
+
* L2 magnitude of the RAW pre-normalization embedding. Additive and optional
|
|
18161
|
+
* so an older runner that does not send it degrades to "unmeasurable", which
|
|
18162
|
+
* the consuming gate treats as accept — never as reject.
|
|
18163
|
+
*/
|
|
18164
|
+
embeddingMagnitude: number().optional(),
|
|
18165
|
+
/**
|
|
18166
|
+
* Model that produced `embedding` — the SAME contract `labelModelId` has for
|
|
18167
|
+
* `label`, and for the same reason: the producing node is the only side that
|
|
18168
|
+
* knows which model actually ran, and re-deriving it downstream is exactly
|
|
18169
|
+
* the inference this model exists to forbid.
|
|
18170
|
+
*
|
|
18171
|
+
* Additive and optional, so a runner that predates it degrades to
|
|
18172
|
+
* "unmeasurable" rather than to a wrong answer — the consumer falls back to
|
|
18173
|
+
* its previous assumption instead of refusing.
|
|
18174
|
+
*
|
|
18175
|
+
* Its absence was not cosmetic. `FaceRecognizer` needs the probe's model id
|
|
18176
|
+
* to use `face-matcher`'s same-model gate (`sample.modelId !== probe.modelId`);
|
|
18177
|
+
* with nothing on the wire it took the id from the GALLERY, so the gate
|
|
18178
|
+
* compared the gallery against itself and could never fire. That turned the
|
|
18179
|
+
* one guard protecting the face feature space into a tautology, and it is
|
|
18180
|
+
* why swapping `face-embedding`'s model would NOT have stranded the enrolled
|
|
18181
|
+
* gallery as the catalog comment predicts — it would have scored the new
|
|
18182
|
+
* model's vectors against the old model's samples in one cosine space.
|
|
18183
|
+
*/
|
|
18184
|
+
embeddingModelId: string().optional(),
|
|
18155
18185
|
label: string().optional(),
|
|
18156
18186
|
/**
|
|
18157
18187
|
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
@@ -19562,6 +19592,7 @@ DeviceType.Camera, method(object({
|
|
|
19562
19592
|
isBattery: boolean(),
|
|
19563
19593
|
reason: _enum([
|
|
19564
19594
|
"disabled",
|
|
19595
|
+
"offline",
|
|
19565
19596
|
"sleeping",
|
|
19566
19597
|
"unreachable",
|
|
19567
19598
|
"waking"
|
|
@@ -19607,9 +19638,17 @@ targets: array(object({
|
|
|
19607
19638
|
sleeping: boolean(),
|
|
19608
19639
|
/** Current device state rendered over the cached frame. State images
|
|
19609
19640
|
* remain authoritative even when their photographic background is
|
|
19610
|
-
* old; null means the link must carry a current camera frame.
|
|
19641
|
+
* old; null means the link must carry a current camera frame.
|
|
19642
|
+
*
|
|
19643
|
+
* **This is the ONLY source a surface may derive an inactive tile
|
|
19644
|
+
* from.** A client that reads a device's `online`/`disabled` flags and
|
|
19645
|
+
* draws its own verdict will disagree with the pixels it is painting
|
|
19646
|
+
* — the frame comes from here, and so must the sentence over it
|
|
19647
|
+
* (D190). Pair with `ageMs` for the age of the photograph behind the
|
|
19648
|
+
* state. */
|
|
19611
19649
|
stateReason: _enum([
|
|
19612
19650
|
"disabled",
|
|
19651
|
+
"offline",
|
|
19613
19652
|
"sleeping",
|
|
19614
19653
|
"unreachable",
|
|
19615
19654
|
"waking"
|
|
@@ -37152,7 +37191,6 @@ var NC_AUDIO_DEFAULTS = {
|
|
|
37152
37191
|
hitPercent: 60,
|
|
37153
37192
|
samplingSeconds: 10
|
|
37154
37193
|
};
|
|
37155
|
-
new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
|
|
37156
37194
|
new Set(["devices", "classes"]);
|
|
37157
37195
|
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
37158
37196
|
/**
|
|
@@ -37386,6 +37424,39 @@ TimelapseRuleInputSchema.extend({
|
|
|
37386
37424
|
createdAt: number(),
|
|
37387
37425
|
updatedAt: number()
|
|
37388
37426
|
});
|
|
37427
|
+
Object.freeze(Object.fromEntries([{
|
|
37428
|
+
stepId: "face-embedding",
|
|
37429
|
+
label: "Face recognition model",
|
|
37430
|
+
defaultModelId: "arcface-r100",
|
|
37431
|
+
indexName: "the enrolled face gallery",
|
|
37432
|
+
options: [
|
|
37433
|
+
{
|
|
37434
|
+
id: "arcface-r100",
|
|
37435
|
+
label: "ArcFace (ResNet34)"
|
|
37436
|
+
},
|
|
37437
|
+
{
|
|
37438
|
+
id: "auraface-r100",
|
|
37439
|
+
label: "AuraFace R100"
|
|
37440
|
+
},
|
|
37441
|
+
{
|
|
37442
|
+
id: "inception-resnet-v1",
|
|
37443
|
+
label: "Inception ResNet V1"
|
|
37444
|
+
}
|
|
37445
|
+
]
|
|
37446
|
+
}, {
|
|
37447
|
+
stepId: "clip-embedding",
|
|
37448
|
+
label: "Semantic search model",
|
|
37449
|
+
defaultModelId: "mobileclip-s1",
|
|
37450
|
+
indexName: "the object semantic-search index",
|
|
37451
|
+
options: [{
|
|
37452
|
+
id: "mobileclip-s1",
|
|
37453
|
+
label: "MobileCLIP S1"
|
|
37454
|
+
}, {
|
|
37455
|
+
id: "mobileclip-s2",
|
|
37456
|
+
label: "MobileCLIP S2"
|
|
37457
|
+
}]
|
|
37458
|
+
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
37459
|
+
string().min(1);
|
|
37389
37460
|
object({
|
|
37390
37461
|
/**
|
|
37391
37462
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -37406,10 +37477,21 @@ object({
|
|
|
37406
37477
|
*/
|
|
37407
37478
|
square: boolean()
|
|
37408
37479
|
});
|
|
37409
|
-
|
|
37480
|
+
/**
|
|
37481
|
+
* The convention in force when nobody has configured one — byte-for-byte the
|
|
37482
|
+
* behaviour of the pre-unification LIVE path (`DETAIL_CROP_PADDING_RATIO`).
|
|
37483
|
+
*/
|
|
37484
|
+
var DEFAULT_DETAIL_CROP_CONVENTION = {
|
|
37410
37485
|
paddingRatio: .15,
|
|
37411
37486
|
square: false
|
|
37412
|
-
}
|
|
37487
|
+
};
|
|
37488
|
+
Object.freeze({
|
|
37489
|
+
x: 0,
|
|
37490
|
+
y: 0,
|
|
37491
|
+
w: 1,
|
|
37492
|
+
h: 1
|
|
37493
|
+
});
|
|
37494
|
+
DEFAULT_DETAIL_CROP_CONVENTION.paddingRatio;
|
|
37413
37495
|
/**
|
|
37414
37496
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
37415
37497
|
*
|
package/package.json
CHANGED