@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.
Files changed (3) hide show
  1. package/dist/addon.js +138 -56
  2. package/dist/addon.mjs +138 -56
  3. 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: 10,
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
- }).paddingRatio;
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: 10,
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
- }).paddingRatio;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.24",
3
+ "version": "1.2.25",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",