@camstack/addon-provider-homeassistant 1.2.28 → 1.2.30

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.
@@ -1,4 +1,4 @@
1
- //#region ../types/dist/event-category-Cv9dO26A.mjs
1
+ //#region ../types/dist/event-category-Bxo5yJjt.mjs
2
2
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
3
3
  EventCategory["SystemBoot"] = "system.boot";
4
4
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -205,6 +205,33 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
205
205
  EventCategory["PipelineCameraAssigned"] = "pipeline.camera-assigned";
206
206
  EventCategory["PipelineCameraUnassigned"] = "pipeline.camera-unassigned";
207
207
  /**
208
+ * A node the orchestrator would otherwise place cameras on has NO usable
209
+ * inference device: the operator enabled one or more accelerators there and
210
+ * the live probe reports every one of them unavailable. Emitted once per
211
+ * TRANSITION into that state (never per dispatch), and the node is dropped
212
+ * from the placement candidate set for as long as it holds.
213
+ *
214
+ * This exists because the state was previously invisible: little-unraid
215
+ * absorbed 283k inference errors in a day while still being handed cameras,
216
+ * and nothing in the system said so.
217
+ *
218
+ * A node with no accelerators configured at all is NOT this — its devices
219
+ * are `disabled`, not `unavailable`, and the runner's default CPU pool
220
+ * serves it exactly as before.
221
+ */
222
+ EventCategory["PipelineNodeInferenceUnavailable"] = "pipeline.node-inference-unavailable";
223
+ /**
224
+ * A camera has an OPEN detection session and has produced no detection at
225
+ * all for longer than the blind threshold — the camera is being decoded and
226
+ * inferred and is returning nothing. Emitted once per transition into blind,
227
+ * per camera.
228
+ *
229
+ * The failure it reports: a 1h43 detection blackout on the entrance camera
230
+ * that nobody noticed, because "a camera that detects nothing" and "a quiet
231
+ * camera" produce byte-identical silence.
232
+ */
233
+ EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
234
+ /**
208
235
  * Per-camera pipeline config was mutated by the orchestrator
209
236
  * (3-level settings change via `setAgentAddonDefaults` /
210
237
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -2996,6 +3023,9 @@ function handlePipeResult(left, next, ctx) {
2996
3023
  fallback: left.fallback
2997
3024
  }, ctx);
2998
3025
  }
3026
+ var $ZodPreprocess = /*@__PURE__*/ $constructor("$ZodPreprocess", (inst, def) => {
3027
+ $ZodPipe.init(inst, def);
3028
+ });
2999
3029
  var $ZodReadonly = /*@__PURE__*/ $constructor("$ZodReadonly", (inst, def) => {
3000
3030
  $ZodType.init(inst, def);
3001
3031
  defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
@@ -5181,6 +5211,10 @@ function pipe(in_, out) {
5181
5211
  out
5182
5212
  });
5183
5213
  }
5214
+ var ZodPreprocess = /*@__PURE__*/ $constructor("ZodPreprocess", (inst, def) => {
5215
+ ZodPipe.init(inst, def);
5216
+ $ZodPreprocess.init(inst, def);
5217
+ });
5184
5218
  var ZodReadonly = /*@__PURE__*/ $constructor("ZodReadonly", (inst, def) => {
5185
5219
  $ZodReadonly.init(inst, def);
5186
5220
  ZodType.init(inst, def);
@@ -5239,6 +5273,13 @@ function _instanceof(cls, params = {}) {
5239
5273
  };
5240
5274
  return inst;
5241
5275
  }
5276
+ function preprocess(fn, schema) {
5277
+ return new ZodPreprocess({
5278
+ type: "pipe",
5279
+ in: transform(fn),
5280
+ out: schema
5281
+ });
5282
+ }
5242
5283
  //#endregion
5243
5284
  //#region ../../node_modules/zod/v4/classic/compat.js
5244
5285
  /** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
@@ -12687,6 +12728,17 @@ var LlmImageSchema = object({
12687
12728
  bytes: _instanceof(Uint8Array),
12688
12729
  mimeType: string()
12689
12730
  });
12731
+ /**
12732
+ * Retry policy. `enabled: false` is NOT the same as `maxAttempts: 1` in intent —
12733
+ * the flag is what a consumer table flips, the count is what the operator tunes.
12734
+ * A retry doubles the wall time of a call, so the two gates that run inside a
12735
+ * notification's budget keep it off (see `CONSUMER_RETRY_POLICY` in addon-ai).
12736
+ */
12737
+ var LlmRetryPolicySchema = object({
12738
+ enabled: boolean().default(false),
12739
+ /** Total attempts INCLUDING the first. 1 = no retry. */
12740
+ maxAttempts: number().int().min(1).max(5).default(1)
12741
+ });
12690
12742
  var LlmGenerateBaseInputSchema = object({
12691
12743
  /** Collection routing (the notification-output posture). */
12692
12744
  addonId: string().optional(),
@@ -12701,7 +12753,28 @@ var LlmGenerateBaseInputSchema = object({
12701
12753
  jsonSchema: record(string(), unknown()).optional(),
12702
12754
  /** Per-call override of the profile default. */
12703
12755
  maxTokens: number().int().positive().optional(),
12704
- temperature: number().optional()
12756
+ temperature: number().optional(),
12757
+ /** Per-call override of the profile default (nucleus sampling). */
12758
+ topP: number().min(0).max(1).optional(),
12759
+ /** Per-call override of the profile default (top-k sampling). */
12760
+ topK: number().int().positive().optional(),
12761
+ /** Per-call override of `profile.timeoutMs` — the total generation bound. */
12762
+ timeoutMs: number().int().positive().optional(),
12763
+ /** Per-call override; beats both the consumer table and the profile. */
12764
+ retry: LlmRetryPolicySchema.optional(),
12765
+ /**
12766
+ * Caller-minted id that makes this generation CANCELLABLE.
12767
+ *
12768
+ * Without it a caller that stops waiting cannot stop the work: the gates race
12769
+ * the call against 8 s and free their own slot when the timer wins, while the
12770
+ * generation upstream keeps running to `profile.timeoutMs` — 60 s by default,
12771
+ * on a single-threaded local model. The per-camera bound then counts WAITS,
12772
+ * not generations, and the real load is unbounded.
12773
+ *
12774
+ * `AbortSignal` cannot cross a process boundary; an id can. Pass one here and
12775
+ * `llm.cancel({ requestId })` tears the socket down.
12776
+ */
12777
+ requestId: string().optional()
12705
12778
  });
12706
12779
  /**
12707
12780
  * `llm-runtime` — node-side managed llama.cpp executor (spec §4). Registered
@@ -12740,8 +12813,49 @@ var ManagedRuntimeConfigSchema = object({
12740
12813
  gpuLayers: number().int().default(0),
12741
12814
  /** Default: cpus-2, clamped ≥1 (resolved node-side). */
12742
12815
  threads: number().int().optional(),
12743
- /** Concurrent slots. */
12816
+ /** Concurrent slots (`--parallel`). */
12744
12817
  parallel: number().int().default(1),
12818
+ /** Logical batch size (`-b`). Larger = faster prompt ingest, more RAM. */
12819
+ batchSize: number().int().positive().optional(),
12820
+ /** Physical batch / micro-batch (`-ub`). */
12821
+ ubatchSize: number().int().positive().optional(),
12822
+ /**
12823
+ * `--flash-attn`. Cuts KV-cache memory on the backends that implement it and
12824
+ * is a no-op elsewhere, so it is offered rather than assumed.
12825
+ */
12826
+ flashAttention: boolean().default(false),
12827
+ /**
12828
+ * `--mlock`. Pins the weights in RAM so the OS cannot page them out mid
12829
+ * inference. Costs the full model size in resident memory — which is exactly
12830
+ * what the RAM budget is counting.
12831
+ */
12832
+ mlock: boolean().default(false),
12833
+ /**
12834
+ * `--no-mmap`. Reads the whole GGUF up front instead of mapping it. Slower to
12835
+ * start, but avoids the page-fault stalls a network or spinning-disk model
12836
+ * store produces on every first token.
12837
+ */
12838
+ noMmap: boolean().default(false),
12839
+ /** `--cache-type-k` / `--cache-type-v` — quantising the KV cache is the
12840
+ * cheapest way to fit a longer context in the same RAM. */
12841
+ cacheTypeK: _enum([
12842
+ "f32",
12843
+ "f16",
12844
+ "q8_0",
12845
+ "q5_1",
12846
+ "q5_0",
12847
+ "q4_1",
12848
+ "q4_0"
12849
+ ]).optional(),
12850
+ cacheTypeV: _enum([
12851
+ "f32",
12852
+ "f16",
12853
+ "q8_0",
12854
+ "q5_1",
12855
+ "q5_0",
12856
+ "q4_1",
12857
+ "q4_0"
12858
+ ]).optional(),
12745
12859
  /** Else lazy: first generate boots it. */
12746
12860
  autoStart: boolean().default(false),
12747
12861
  /** 0 = never; frees RAM after quiet periods. */
@@ -12829,10 +12943,44 @@ var LlmProfileSchema = object({
12829
12943
  baseUrl: string().optional(),
12830
12944
  /** ConfigUISchema type:'password' — never round-trips (spec §5). */
12831
12945
  apiKey: string().optional(),
12946
+ /** Vision on/off. A vision call against a `false` profile is REFUSED, never
12947
+ * degraded to text — that shipped once and produced a confident answer to a
12948
+ * question about a picture nobody sent. */
12832
12949
  supportsVision: boolean(),
12833
12950
  temperature: number().min(0).max(2).optional(),
12951
+ /** Nucleus sampling. Every wire we speak has it. */
12952
+ topP: number().min(0).max(1).optional(),
12953
+ /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
12954
+ * wire does, and the client drops it there (measured: the request body gets
12955
+ * `top_p` and no `top_k`). The profile editor hides the field wherever it
12956
+ * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
12957
+ topK: number().int().positive().optional(),
12834
12958
  maxTokens: number().int().positive().optional(),
12959
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own);
12960
+ * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
12961
+ * the model with, so it is the one field that changes a PROCESS. */
12962
+ contextLength: number().int().positive().optional(),
12963
+ /** Default system prompt. A caller's `system` REPLACES it (never appends —
12964
+ * two system prompts fighting is worse than either alone). */
12965
+ systemPrompt: string().optional(),
12966
+ /** Total generation bound — the only one a unary call has. */
12835
12967
  timeoutMs: number().int().positive().default(6e4),
12968
+ /** Wait for response headers only. */
12969
+ connectTimeoutMs: number().int().positive().default(1e4),
12970
+ /** Accepted, but no output yet — a cold GPU load lives here. */
12971
+ firstTokenTimeoutMs: number().int().positive().default(12e4),
12972
+ /** Output started then stopped. */
12973
+ idleTimeoutMs: number().int().positive().default(6e4),
12974
+ /** Profile-level default. The per-consumer table and a per-call override
12975
+ * both beat it — see `resolveRetryPolicy`. */
12976
+ retry: LlmRetryPolicySchema.default({
12977
+ enabled: false,
12978
+ maxAttempts: 1
12979
+ }),
12980
+ /** Whether this profile may use tools. The tool-call plumbing rides the
12981
+ * library; the REGISTRY of callable tools is ours and is empty in v1, so a
12982
+ * `true` here buys the wiring, not behaviour, until tools are registered. */
12983
+ toolsEnabled: boolean().default(false),
12836
12984
  extraHeaders: record(string(), string()).optional(),
12837
12985
  /** kind === 'managed-local' only (spec §4). */
12838
12986
  runtime: ManagedRuntimeConfigSchema.optional()
@@ -12894,7 +13042,10 @@ var ProfileRefInputSchema = object({
12894
13042
  addonId: string(),
12895
13043
  profileId: string()
12896
13044
  });
12897
- method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
13045
+ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
13046
+ addonId: string().optional(),
13047
+ requestId: string()
13048
+ }), _void(), { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
12898
13049
  kind: "mutation",
12899
13050
  auth: "admin"
12900
13051
  }), method(ProfileRefInputSchema, _void(), {
@@ -14576,6 +14727,8 @@ var NcSystemEventKindSchema = _enum([
14576
14727
  "stream-offline",
14577
14728
  "node-online",
14578
14729
  "node-offline",
14730
+ "node-inference-unavailable",
14731
+ "detection-blind",
14579
14732
  "addon-update-available",
14580
14733
  "server-update-available",
14581
14734
  "alarm-triggered",
@@ -14637,7 +14790,16 @@ var NcScheduleSchema = object({
14637
14790
  });
14638
14791
  /** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
14639
14792
  var NcPlateMatcherSchema = object({
14640
- values: array(string().min(1)).min(1),
14793
+ /**
14794
+ * Plate texts (or gallery vehicle names) to match. EMPTY = **any plate the
14795
+ * pipeline could read** — the plate half of "no selection = no narrowing",
14796
+ * and the switch that says this rule is about vehicles that were IDENTIFIED
14797
+ * rather than merely seen. A subject carrying no plate still fails.
14798
+ *
14799
+ * The `.min(1)` this used to carry made that state unauthorable; nothing has
14800
+ * ever persisted an empty list, so widening it cannot change an existing rule.
14801
+ */
14802
+ values: array(string().min(1)),
14641
14803
  /** Max Levenshtein distance after normalization (uppercase alphanumeric). */
14642
14804
  maxDistance: number().int().min(0).max(3).default(1)
14643
14805
  });
@@ -14671,28 +14833,36 @@ var NcOccupancyConditionSchema = object({
14671
14833
  /**
14672
14834
  * Audio condition (IMMEDIATE trigger) — a rule on SOUND, not on a picture.
14673
14835
  *
14674
- * Operator-approved vocabulary (2026-08-12, option A — the same one the
14675
- * reference notifier uses, so an operator moving between them re-uses what
14676
- * they already know): a rule matches when, over a sampling window of
14677
- * `samplingSeconds`, at least `hitPercent`% of the audio samples in that
14678
- * window are HITS. A sample is a hit when it satisfies BOTH present filters:
14679
- *
14680
- * - `dbThreshold` its level is at or above this many dBFS (see
14681
- * {@link NC_AUDIO_DBFS_FLOOR}: negative-going, `0` = full scale);
14682
- * - `labels` the classifier put at least one of these labels on it.
14683
- *
14684
- * Both are OPTIONAL and independent, which is the point of the shape: a
14685
- * loudness rule ("something loud at 3am") needs no model to be right, and a
14686
- * label rule ("a dog barked") needs no threshold. **Fail-closed when NEITHER
14687
- * is given** a window in which every sample is trivially a hit would fire on
14688
- * silence, so the engine refuses such a condition rather than notifying on
14689
- * nothing (the schema cannot express "at least one of" without becoming a
14690
- * ZodEffects the cap path would have to special-case).
14691
- *
14692
- * `hitPercent` is over the samples the window actually HOLDS, and the window
14693
- * must be FULL before it can match a window that has been open for two
14694
- * seconds of its ten is 100% of nothing, and firing on it would make
14695
- * `samplingSeconds` decorative.
14836
+ * **TWO EXCLUSIVE MODES** (operator decision 2026-08-14, D157). Which one a
14837
+ * rule is in is not a stored field it is WHICH FILTER the rule carries, so
14838
+ * there is no second switch that can disagree with the first and every rule
14839
+ * authored before the decision migrates for free (`audioModeOf`):
14840
+ *
14841
+ * - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
14842
+ * classifier labels with one of them. No window, no percentage:
14843
+ * `hitPercent` and `samplingSeconds` are ignored, and the rule's own
14844
+ * `throttle` cooldown is the only brake. The per-label confidence floor is
14845
+ * the analyzer's (`classificationMinScore`, per device) — a label only
14846
+ * reaches this condition if the classifier was already confident enough.
14847
+ * - **LEVEL mode `dbThreshold` present, no labels.** The sampling window IS
14848
+ * the condition: at least `hitPercent`% of the samples over
14849
+ * `samplingSeconds` must be at or above `dbThreshold` dBFS (see
14850
+ * {@link NC_AUDIO_DBFS_FLOOR}: negative-going, `0` = full scale). The window
14851
+ * must be FULL before it can match a window open for two of its ten
14852
+ * seconds is 100% of nothing.
14853
+ *
14854
+ * **Why label mode has no window.** It had one, and it never fired: the
14855
+ * analyzer emits ~1 audio frame per second but YAMNet only LABELS one to three
14856
+ * of them per episode, even through continuous crying. The measured maximum
14857
+ * `hitPercent` over the whole live history was 40 — under the shipped default
14858
+ * of 60, so a label rule could not fire at all, ever. A percentage of frames is
14859
+ * the wrong question to ask of a sparse classifier.
14860
+ *
14861
+ * **Fail-closed when NEITHER is given** — every sample would be a trivial hit
14862
+ * and the rule would fire on silence. The schema cannot express "exactly one
14863
+ * of" without becoming a ZodEffects the cap path would have to special-case, so
14864
+ * the exclusivity is enforced where every editor writes (`patchAudio`) and a
14865
+ * legacy rule carrying both resolves to LABEL (the mode that fires).
14696
14866
  *
14697
14867
  * Labels are the audio macro classes (`AUDIO_MACRO_LABELS` / the NC taxonomy's
14698
14868
  * `audio-*` ids). Both spellings are accepted — the matcher normalizes the
@@ -14700,13 +14870,13 @@ var NcOccupancyConditionSchema = object({
14700
14870
  * an operator who typed `dog` mean the same thing.
14701
14871
  */
14702
14872
  var NcAudioConditionSchema = object({
14703
- /** Audio macro labels; absent = any sound (level-only rule). */
14873
+ /** LABEL MODE: audio macro labels. Present fires on the first labelled frame. */
14704
14874
  labels: array(string().min(1)).min(1).optional(),
14705
- /** Level floor in dBFS (negative-going, `0` = full scale); absent = any level. */
14875
+ /** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
14706
14876
  dbThreshold: number().min(-96).max(0).optional(),
14707
- /** Percentage of the window's samples that must be hits (1–100). */
14877
+ /** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
14708
14878
  hitPercent: number().int().min(1).max(100).default(60),
14709
- /** Length of the sampling window in seconds. */
14879
+ /** LEVEL MODE ONLY: length of the sampling window in seconds. */
14710
14880
  samplingSeconds: number().int().min(1).max(300).default(10)
14711
14881
  });
14712
14882
  /**
@@ -14876,18 +15046,47 @@ var NcConditionsSchema = object({
14876
15046
  */
14877
15047
  labelEquals: array(string().min(1)).optional(),
14878
15048
  /**
14879
- * Identity matcher. P1 boundary: matched against the record's collapsed
14880
- * `label` (the identity display name propagated by the face pipeline) —
14881
- * identity-ID matching rides in P2 when identity ids reach the record.
15049
+ * KNOWN FACES the rule's identity scope, and the switch that says the rule
15050
+ * is about recognised people at all.
15051
+ *
15052
+ * Three states, and the empty one is the point:
15053
+ *
15054
+ * | value | meaning |
15055
+ * | --- | --- |
15056
+ * | absent | the rule does not care who it is; an unrecognised person matches |
15057
+ * | `[]` | **only known faces** — any identity in the gallery, nobody in particular |
15058
+ * | a list | only these identities |
15059
+ *
15060
+ * `[]` is the repo-wide "no selection = no narrowing" reading (an absent
15061
+ * `devices` list is every device), applied one level down: the operator has
15062
+ * turned the face scope ON and narrowed it to nothing, which is every known
15063
+ * face. No second field states the same thing — a switch that can disagree
15064
+ * with the list under it is worse than no switch (D62).
15065
+ *
15066
+ * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
15067
+ * renameable, and a rule authored on "Gianluca" went silently dark the moment
15068
+ * the operator fixed the spelling. The id reaches the record on
15069
+ * `LabelAttribution.identityId`; the name is what the editor shows and what
15070
+ * `{{label}}` renders.
15071
+ *
15072
+ * Rules written before this carry NAMES, and are resolved to ids lazily at
15073
+ * load (`NcRuleStore.load`) against the live gallery — a name nothing answers
15074
+ * for is left as it stands and reported, never dropped. The engine also
15075
+ * accepts a display-name hit as a compatibility leg, so a rule whose
15076
+ * migration could not resolve keeps matching exactly what it matched before.
14882
15077
  */
14883
15078
  identities: array(string().min(1)).optional(),
14884
- /** Fuzzy plate matcher against the record's `label` (plate text). */
15079
+ /**
15080
+ * KNOWN PLATES / VEHICLES — the plate mirror of {@link identities}, including
15081
+ * the empty-list reading: `values: []` is "any plate the OCR could read",
15082
+ * a non-empty list is those plates (fuzzily). See {@link NcPlateMatcherSchema}.
15083
+ */
14885
15084
  plates: NcPlateMatcherSchema.optional(),
14886
15085
  /**
14887
- * Identity EXCLUDE — mirror of {@link identities} with `notIn` semantics.
14888
- * Same P1 boundary: matched against the record's collapsed `label` (the
14889
- * identity display name). A record with NO label passes (nothing to
14890
- * exclude), unlike the include variant which fails on an absent label.
15086
+ * Identity EXCLUDE — mirror of {@link identities} with `notIn` semantics, and
15087
+ * the same id members and the same lazy name→id migration. A record with NO
15088
+ * identity passes (nothing to exclude), unlike the include variant which
15089
+ * fails on an unrecognised subject. An EMPTY list excludes nobody.
14891
15090
  */
14892
15091
  identitiesExclude: array(string().min(1)).optional(),
14893
15092
  /**
@@ -15279,7 +15478,80 @@ var NcRuleInputSchema = object({
15279
15478
  * a rule that predates the gate must keep delivering byte-for-byte as it
15280
15479
  * did, and absent is the only way to say that without a migration.
15281
15480
  */
15282
- confirm: NcConfirmSchema.optional()
15481
+ confirm: NcConfirmSchema.optional(),
15482
+ /**
15483
+ * WAIT for face/plate recognition before saying anything.
15484
+ *
15485
+ * A notification's TEXT is frozen at enqueue and its media is re-resolved at
15486
+ * send; the identity is neither. A face is confirmed after `confirmFrames`
15487
+ * agreeing observations — p50 **11.4 s** after the track was first seen,
15488
+ * measured on this hub — and an `immediate` rule enqueues on the first object
15489
+ * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
15490
+ * immediate path, and no amount of media re-resolution fixes a sentence.
15491
+ *
15492
+ * Only two honest answers exist, and this flag picks between them. It has
15493
+ * effect ONLY on a rule that declares a recognition scope
15494
+ * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
15495
+ * other rule there is nothing to wait for and the flag is inert.
15496
+ *
15497
+ * | value | what happens |
15498
+ * | --- | --- |
15499
+ * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
15500
+ * | absent / `false` | it fires at once WITHOUT the name, and if recognition lands before the track closes a SECOND, "…is Gianluca" notification follows (one per track, per rule, per target) |
15501
+ *
15502
+ * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
15503
+ * on the addon cap path, and absent has to keep meaning exactly what every
15504
+ * rule authored before this field meant.
15505
+ *
15506
+ * The cost of `true` is stated here because the editor states it too: a rule
15507
+ * that waits also inherits track-close SEMANTICS — its `zones` condition
15508
+ * tests every zone the track visited and a `crossing` condition can no longer
15509
+ * be satisfied, because a closed track carries no crossing.
15510
+ */
15511
+ waitForEnhancement: boolean().optional(),
15512
+ /**
15513
+ * GROUP a burst of subjects into ONE notification that grows.
15514
+ *
15515
+ * Seconds of quiet after the last matching subject before the burst is
15516
+ * considered over. While it is open, the first subject enqueues immediately —
15517
+ * **exactly as today, with no added latency** — and every real growth (a new
15518
+ * subject, or a name confirmed on one already in it) REPLACES that
15519
+ * notification with an updated one naming everybody. The push carries the
15520
+ * group's own coalescing tag, so the phone replaces rather than stacks.
15521
+ *
15522
+ * `0` / absent = off, and off is today's behaviour byte for byte.
15523
+ *
15524
+ * ### Why an idle cutoff and not a window
15525
+ *
15526
+ * The measured seven-person arrival on device 590 spans 110 s with every
15527
+ * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
15528
+ * idle cutoff holds it as one and ends it when the arrival actually ends.
15529
+ * 30 is Frigate's shipped value for the same decision.
15530
+ *
15531
+ * ### What it replaces
15532
+ *
15533
+ * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
15534
+ * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
15535
+ * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
15536
+ * track that did fire and 7 carrying a confirmed identity nobody heard about.
15537
+ * A group collapses the same volume by MERGING, so the cooldown becomes a
15538
+ * budget over GROUPS — which is what it always meant — and a growth is never
15539
+ * throttled by the window its own first member spent.
15540
+ *
15541
+ * ### Interaction with {@link waitForEnhancement}
15542
+ *
15543
+ * They compose, and the order matters. `waitForEnhancement` defers the rule to
15544
+ * TRACK CLOSE, so with both set the group is opened by the first member to
15545
+ * CLOSE — already carrying its name — and grows as later members close. That
15546
+ * is later, and complete. With grouping alone the group opens on the first
15547
+ * object event and picks up names as they are confirmed, through the growth
15548
+ * path. Neither combination fires twice for one subject.
15549
+ *
15550
+ * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
15551
+ * on the addon cap path, so absent must keep meaning what it meant before this
15552
+ * field existed.
15553
+ */
15554
+ groupIdleSec: number().int().min(0).max(600).optional()
15283
15555
  });
15284
15556
  /**
15285
15557
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -15791,7 +16063,87 @@ var MethodAccessSchema = _enum([
15791
16063
  var AllowedProviderSchema = union([literal("*"), array(string())]);
15792
16064
  var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
15793
16065
  var CapScopeSchema = _enum(["device", "system"]);
15794
- var TokenScopeSchema = discriminatedUnion("type", [
16066
+ /**
16067
+ * DeviceSelector (scope model v3 — 2026-08-12).
16068
+ *
16069
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
16070
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
16071
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
16072
+ * AFTER the grant was minted — no re-grant, no re-login.
16073
+ *
16074
+ * - `all` — every device in the deployment. The broad viewer/operator
16075
+ * lever without a `category` grant (a `category` grant also covers device
16076
+ * caps that carry no deviceId; `all` is specifically the device set).
16077
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
16078
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
16079
+ * is NOT covered until the grant is edited.
16080
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
16081
+ * DYNAMIC. A device that changes type, or a new device of the type,
16082
+ * re-resolves on the next request.
16083
+ * - `locations` — every device whose operator-assigned `location` label is
16084
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
16085
+ * null/unset location matches NO `locations` selector.
16086
+ */
16087
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
16088
+ object({ kind: literal("all") }),
16089
+ object({
16090
+ kind: literal("ids"),
16091
+ ids: array(number().int()).min(1)
16092
+ }),
16093
+ object({
16094
+ kind: literal("types"),
16095
+ types: array(_enum(DeviceType)).min(1)
16096
+ }),
16097
+ object({
16098
+ kind: literal("locations"),
16099
+ locations: array(string().min(1)).min(1)
16100
+ })
16101
+ ]);
16102
+ var DeviceTokenScopeSchema = object({
16103
+ type: literal("device"),
16104
+ /** The device SET this grant covers — resolved against the live fleet. */
16105
+ selector: DeviceSelectorSchema,
16106
+ access: array(MethodAccessSchema).min(1),
16107
+ /**
16108
+ * Whether a grant on a PARENT device transparently covers its accessory
16109
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
16110
+ * Direction is parent → children ONLY.
16111
+ *
16112
+ * Absent → the matcher DERIVES it from the access flavour: `view`
16113
+ * inherits (a camera viewer sees the camera's accessories), `create` /
16114
+ * `delete` do NOT (actuating/removing a child is an explicit act the
16115
+ * operator must grant on the child, not inherit from the parent). Set it
16116
+ * explicitly to override that default per grant.
16117
+ */
16118
+ includeLinked: boolean().optional()
16119
+ });
16120
+ /**
16121
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
16122
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
16123
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
16124
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
16125
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
16126
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
16127
+ * migration cannot reach a JWT already in a client's hands; parse-time
16128
+ * migration covers both without a flag day. No cast — the raw object is read
16129
+ * through `Reflect.get` (its static type is `unknown`).
16130
+ */
16131
+ function migrateLegacyTokenScope(raw) {
16132
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
16133
+ if (Reflect.get(raw, "type") !== "device") return raw;
16134
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
16135
+ const targets = Reflect.get(raw, "targets");
16136
+ if (!Array.isArray(targets)) return raw;
16137
+ return {
16138
+ type: "device",
16139
+ selector: {
16140
+ kind: "ids",
16141
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
16142
+ },
16143
+ access: Reflect.get(raw, "access")
16144
+ };
16145
+ }
16146
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
15795
16147
  object({
15796
16148
  type: literal("category"),
15797
16149
  target: CapScopeSchema,
@@ -15807,18 +16159,8 @@ var TokenScopeSchema = discriminatedUnion("type", [
15807
16159
  target: string(),
15808
16160
  access: array(MethodAccessSchema).min(1)
15809
16161
  }),
15810
- object({
15811
- type: literal("device"),
15812
- /**
15813
- * One or more deviceIds (serialised as strings for wire-format
15814
- * consistency with the rest of the union). Matcher accepts if
15815
- * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
15816
- * of one scope-per-device when granting access to a set of cameras.
15817
- */
15818
- targets: array(string()).min(1),
15819
- access: array(MethodAccessSchema).min(1)
15820
- })
15821
- ]);
16162
+ DeviceTokenScopeSchema
16163
+ ]));
15822
16164
  object({
15823
16165
  id: string(),
15824
16166
  username: string(),
@@ -16141,7 +16483,7 @@ var TrackEnvelopeSchema = object({
16141
16483
  * `snapshots[]` references — megabytes across a page of tracks. `slim`
16142
16484
  * keeps every scalar the list surfaces actually render (ids, class(es),
16143
16485
  * label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
16144
- * zonesVisited, bestEventId, envelope, hasFace) and returns `positions` /
16486
+ * zonesVisited, bestEventId, envelope, hasFace, hasRider) and returns `positions` /
16145
16487
  * `snapshots` as EMPTY arrays — detail views re-fetch the full row via
16146
16488
  * `getTrack`. Mirrors the event-store `projection` convention
16147
16489
  * (`getObjectEvents` et al.).
@@ -16277,7 +16619,21 @@ union([literal(1), literal(2)]);
16277
16619
  var LabelAttributionSchema = object({
16278
16620
  stepId: string(),
16279
16621
  modelId: string().optional(),
16280
- decidedAt: number()
16622
+ decidedAt: number(),
16623
+ /**
16624
+ * The GALLERY id behind a recognised tier-2 label — a face-gallery
16625
+ * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
16626
+ *
16627
+ * The text alone is a DISPLAY NAME, and a display name is renameable: a
16628
+ * notification rule authored on "Gianluca" stopped matching the moment the
16629
+ * operator fixed the spelling in the gallery, and nothing said so. The id is
16630
+ * the thing that does not move, so it is what a rule matches on
16631
+ * (`NcConditions.identities`) and the text is what a human is shown.
16632
+ *
16633
+ * Absent when the label names no gallery row — a plate the OCR read but no
16634
+ * vehicle claims, a sub-class, a species, any tier-1 value.
16635
+ */
16636
+ identityId: string().optional()
16281
16637
  });
16282
16638
  /**
16283
16639
  * The TIERED label model (roadmap 4g), spread into `TrackSchema` and
@@ -16414,6 +16770,28 @@ var TrackSchema = object({
16414
16770
  * `=== true` and render nothing otherwise, never infer "no face".
16415
16771
  */
16416
16772
  hasFace: boolean().optional(),
16773
+ /**
16774
+ * This subject CONTAINS a folded rider — a person the rider-pairing step
16775
+ * ([D34](../decisions/adr-0034.md)) removed from the frame BEFORE the tracker,
16776
+ * so the passage is tracked once and as a VEHICLE.
16777
+ *
16778
+ * It exists because the fold's record was dishonest. D34 and the code both
16779
+ * said "the person is not lost — it is reported so both entities stay on the
16780
+ * record"; in fact the pair went into a per-processor RAM field behind an
16781
+ * accessor nobody called, and every durable surface said `vehicle`, full
16782
+ * stop. This is the composition note that makes the row true.
16783
+ *
16784
+ * A COMPOSITION, never a class and never a label. "This vehicle contains a
16785
+ * person" is not an answer to "what is this" — both label tiers would refuse
16786
+ * a macro token anyway (D89), and correctly. Nothing here changes what the
16787
+ * subject IS: a cyclist stays one vehicle track, occupancy still counts one,
16788
+ * and a `person` rule still does not fire for someone cycling past.
16789
+ *
16790
+ * **Absent ≠ false**, exactly like {@link hasFace}: every row written before
16791
+ * the column, and every hub that predates the field, omits it. Test
16792
+ * `=== true` and render nothing otherwise — never infer "no rider".
16793
+ */
16794
+ hasRider: boolean().optional(),
16417
16795
  ...TrackFlagFields,
16418
16796
  ...TrackRetrainFields
16419
16797
  });
@@ -17880,7 +18258,7 @@ var detectionFpsField = {
17880
18258
  var occupancyRecheckSecField = {
17881
18259
  min: 0,
17882
18260
  max: 300,
17883
- default: 30,
18261
+ default: 300,
17884
18262
  step: 5
17885
18263
  };
17886
18264
  var occupancyRecheckFramesField = {
@@ -23143,54 +23521,139 @@ var TalkAudioCodecSchema = _enum([
23143
23521
  "g711ulaw",
23144
23522
  "g711alaw"
23145
23523
  ]);
23146
- DeviceType.Camera, method(object({ deviceId: number() }), object({
23147
- sessionId: string(),
23148
- sdpOffer: string()
23149
- }), {
23150
- kind: "mutation",
23151
- auth: "admin"
23152
- }), method(object({
23153
- deviceId: number(),
23154
- sessionId: string(),
23155
- sdpAnswer: string()
23156
- }), _void(), {
23157
- kind: "mutation",
23158
- auth: "admin"
23159
- }), method(object({
23160
- deviceId: number(),
23161
- sessionId: string()
23162
- }), _void(), {
23163
- kind: "mutation",
23164
- auth: "admin"
23165
- }), method(object({ deviceId: number() }), object({ sessionId: string() }), {
23166
- kind: "mutation",
23167
- auth: "admin"
23168
- }), method(object({
23169
- deviceId: number(),
23170
- /** Audio bytes for ONE frame, base64-encoded so the payload
23171
- * survives tRPC JSON serialization. */
23172
- audioBase64: string(),
23173
- /** Wire codec of the payload. Omit to let the provider default
23174
- * to its native expected format (s16le @ provider-native rate,
23175
- * mono). See {@link TalkAudioCodecSchema} for the supported set. */
23176
- codec: TalkAudioCodecSchema.optional(),
23177
- /** Sample rate (Hz). REQUIRED for `s16le`; advisory for
23178
- * `opus` (encoder clock); ignored for `g711*` (implied 8000). */
23179
- sampleRate: number().int().positive().optional(),
23180
- /** Channel count. Default 1. */
23181
- channels: number().int().positive().optional(),
23182
- /** Sequence number for ordering / dropping out-of-order frames. */
23183
- sequenceNumber: number().int()
23184
- }), object({ accepted: boolean() }), {
23185
- kind: "mutation",
23186
- auth: "admin"
23187
- }), method(object({ deviceId: number() }), _void(), {
23188
- kind: "mutation",
23189
- auth: "admin"
23190
- }), object({
23191
- deviceId: number(),
23192
- status: IntercomStatusSchema
23193
- });
23524
+ var intercomCapability = {
23525
+ name: "intercom",
23526
+ scope: "device",
23527
+ deviceNative: true,
23528
+ mode: "singleton",
23529
+ deviceTypes: [DeviceType.Camera],
23530
+ methods: {
23531
+ /**
23532
+ * Open a server-side WebRTC audio-only session. Returns an SDP
23533
+ * offer with a single sendonly audio m-line the client answers
23534
+ * (client → server direction). The server wakes battery cams
23535
+ * transparently before opening the upstream talk channel.
23536
+ */
23537
+ startSession: method(object({ deviceId: number() }), object({
23538
+ sessionId: string(),
23539
+ sdpOffer: string()
23540
+ }), {
23541
+ kind: "mutation",
23542
+ auth: "admin"
23543
+ }),
23544
+ handleAnswer: method(object({
23545
+ deviceId: number(),
23546
+ sessionId: string(),
23547
+ sdpAnswer: string()
23548
+ }), _void(), {
23549
+ kind: "mutation",
23550
+ auth: "admin"
23551
+ }),
23552
+ /** Close explicitly. Server also auto-closes on 30s idle. */
23553
+ stopSession: method(object({
23554
+ deviceId: number(),
23555
+ sessionId: string()
23556
+ }), _void(), {
23557
+ kind: "mutation",
23558
+ auth: "admin"
23559
+ }),
23560
+ /**
23561
+ * Open a raw-PCM talk session (no WebRTC SDP plumbing). Used by
23562
+ * non-WebRTC consumers (HomeKit export, Alexa raw audio, test
23563
+ * harnesses) that already have decoded PCM frames and just need a
23564
+ * direct path onto the camera's talk channel. Mutually exclusive
23565
+ * with `startSession` (an active WebRTC session must be stopped
23566
+ * before a raw-PCM session can be opened on the same device, and
23567
+ * vice versa).
23568
+ */
23569
+ startTalkSession: method(object({ deviceId: number() }), object({ sessionId: string() }), {
23570
+ kind: "mutation",
23571
+ auth: "admin"
23572
+ }),
23573
+ /**
23574
+ * Push one chunk of talk-back audio onto the active talk session.
23575
+ * The cap is codec-agnostic: the caller declares (or omits) the
23576
+ * wire format via `codec`; the provider decides between passthrough
23577
+ * (when the wire codec matches the camera's native talk channel),
23578
+ * transcoding via the `audio-codec` cap, or rejecting the call.
23579
+ *
23580
+ * Callers do NOT need to know the camera's wire format or sample
23581
+ * rate — that information lives entirely inside the provider.
23582
+ *
23583
+ * Sequence numbers MUST be monotonic per talk session; older frames
23584
+ * arriving after newer ones are dropped to avoid smearing the
23585
+ * downstream encoder state (G.711 is stateless but IMA ADPCM's
23586
+ * predictor would corrupt with re-ordering).
23587
+ */
23588
+ pushTalkAudio: method(object({
23589
+ deviceId: number(),
23590
+ /** Audio bytes for ONE frame, base64-encoded so the payload
23591
+ * survives tRPC JSON serialization. */
23592
+ audioBase64: string(),
23593
+ /** Wire codec of the payload. Omit to let the provider default
23594
+ * to its native expected format (s16le @ provider-native rate,
23595
+ * mono). See {@link TalkAudioCodecSchema} for the supported set. */
23596
+ codec: TalkAudioCodecSchema.optional(),
23597
+ /** Sample rate (Hz). REQUIRED for `s16le`; advisory for
23598
+ * `opus` (encoder clock); ignored for `g711*` (implied 8000). */
23599
+ sampleRate: number().int().positive().optional(),
23600
+ /** Channel count. Default 1. */
23601
+ channels: number().int().positive().optional(),
23602
+ /** Sequence number for ordering / dropping out-of-order frames. */
23603
+ sequenceNumber: number().int()
23604
+ }), object({ accepted: boolean() }), {
23605
+ kind: "mutation",
23606
+ auth: "admin"
23607
+ }),
23608
+ /** Close the raw-PCM talk session. Idempotent. */
23609
+ endTalkSession: method(object({ deviceId: number() }), _void(), {
23610
+ kind: "mutation",
23611
+ auth: "admin"
23612
+ })
23613
+ },
23614
+ events: { onStatusChanged: { data: object({
23615
+ deviceId: number(),
23616
+ status: IntercomStatusSchema
23617
+ }) } },
23618
+ status: {
23619
+ schema: IntercomStatusSchema,
23620
+ kind: "command-driven"
23621
+ },
23622
+ /**
23623
+ * Runtime-state slice — mirrored by the kernel.
23624
+ *
23625
+ * The cap declared `status` and nothing else, so the only two sources an
23626
+ * exporter has for a value — the `device.state-changed` slice event and the
23627
+ * `deviceState.getAllSnapshots` snapshot, both built from runtime state —
23628
+ * carried nothing for `intercom`. A talk-back entity in Home Assistant would
23629
+ * have been published and never received a value, which is the defect the
23630
+ * export's two classification tables exist to prevent (177 of them, once), so
23631
+ * `intercom` was excluded rather than exported.
23632
+ *
23633
+ * The shape is the status shape: there is exactly one truth about talk-back
23634
+ * and duplicating it into a second schema is how two halves of one capability
23635
+ * come to disagree. Providers write it through
23636
+ * `this.runtimeState.setCapState('intercom', …)` at the four points that open
23637
+ * and close a session, and seed it at registration so the slice exists before
23638
+ * the first session rather than after it.
23639
+ *
23640
+ * **Bound, named rather than hidden:** `talking` mirrors the provider's own
23641
+ * session handle, so a session torn down by a transport death that never
23642
+ * reaches `stopSession` / `endTalkSession` leaves it latched until the next
23643
+ * session or the next restart. That is why the slice is `session` and not
23644
+ * `restored` — a restart must never restore "talking".
23645
+ */
23646
+ runtimeState: IntercomStatusSchema,
23647
+ /**
23648
+ * Runtime-state durability: **session** — `talking` describes a live audio
23649
+ * session, which by definition does not survive the process that held it.
23650
+ * Restoring it would publish a camera as talking to nobody.
23651
+ *
23652
+ * See `RuntimeStateDurability`. Enforced by
23653
+ * `scripts/check-runtime-state-durability.ts`.
23654
+ */
23655
+ durability: "session"
23656
+ };
23194
23657
  /**
23195
23658
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
23196
23659
  * with a mowing lifecycle plus a dock action.
@@ -25887,7 +26350,7 @@ method(object({
25887
26350
  toMs: number()
25888
26351
  }), RecordingAvailabilitySchema, {
25889
26352
  kind: "query",
25890
- auth: "admin"
26353
+ auth: "protected"
25891
26354
  }), method(object({
25892
26355
  deviceId: number(),
25893
26356
  fromMs: number(),
@@ -25895,14 +26358,14 @@ method(object({
25895
26358
  tzOffsetMinutes: number()
25896
26359
  }), RecordingDaysSchema, {
25897
26360
  kind: "query",
25898
- auth: "admin"
26361
+ auth: "protected"
25899
26362
  }), method(object({
25900
26363
  deviceId: number(),
25901
26364
  fromMs: number(),
25902
26365
  toMs: number()
25903
26366
  }), RecordingManifestSchema, {
25904
26367
  kind: "query",
25905
- auth: "admin"
26368
+ auth: "protected"
25906
26369
  }), method(object({}), RecordingStorageUsageSchema, {
25907
26370
  kind: "query",
25908
26371
  auth: "admin"
@@ -26192,14 +26655,50 @@ method(object({
26192
26655
  * thing except the comparator: `similarity` (CLIP cosine at the same ROI coords
26193
26656
  * vs condition-tagged references) and `llm` (vision-LLM judgment over the crop).
26194
26657
  *
26195
- * D14 device-config archetype (`deviceConfig.ui.kind:'widget'`) the framework
26196
- * derives the device-detail contribution; the provider carries NO hand-written
26197
- * settings-contribution methods. `status.kind:'push'` the engine pushes on
26198
- * every hysteresis flip / availability change; consumers never poll.
26199
- */
26200
- /** Extensible condition tag. Seeded 'day' | 'night'; open by design so more can
26201
- * be added without a wire break (matching falls back to any-condition refs). */
26658
+ * **No `deviceConfig`, deliberately.** This shipped as the D14 widget archetype,
26659
+ * which put a "Scenes" tab on one camera's detail page. That is the wrong shape
26660
+ * for the thing: a scene is a standing question about the property ("is the bin
26661
+ * still out"), and the operator's question is "which of my scenes have tripped",
26662
+ * across every camera at once — not "what does camera 617 think". Buried one
26663
+ * camera deep it also could not be found. The surface is now a top-level admin
26664
+ * page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
26665
+ * picks the camera inside the create flow, the same shape Events and Faces have.
26666
+ *
26667
+ * The consequence to keep in mind: `host/scene-monitor-editor` is gone from
26668
+ * `HOST_WIDGETS` too. `scripts/check-host-widget-resolves.ts` asserts BOTH
26669
+ * directions, so a registration nobody declares fails exactly as loudly as a
26670
+ * declaration nobody registers. The editor is imported directly by the page.
26671
+ *
26672
+ * `status.kind:'push'` — the engine pushes on every hysteresis flip /
26673
+ * availability change; consumers never poll.
26674
+ */
26675
+ /** Extensible condition tag. Seeded 'day' | 'ir' (the two variants the operator
26676
+ * captures) plus 'night' | 'dawn' | 'dusk' from the resolver's sun-times band.
26677
+ * Open by design so more can be added without a wire break.
26678
+ *
26679
+ * Matching does NOT fall back across conditions: cross-condition cosines are
26680
+ * not comparable, so "I have never seen this scene in this light" is reported
26681
+ * as `unknown`, never guessed. A day reference scored against an IR frame
26682
+ * collapses the cosine and would latch a false alarm every single night. */
26202
26683
  var SceneConditionSchema = string();
26684
+ /** `matched` = the baseline is what we see; `diverged` = it demonstrably is not;
26685
+ * `unknown` = we cannot judge (no reference for this condition, encoder model
26686
+ * changed, view shifted, no snapshot). `unknown` is a real value, not a null,
26687
+ * and never counts toward hysteresis in either direction. */
26688
+ var SceneVerdictSchema = _enum([
26689
+ "matched",
26690
+ "diverged",
26691
+ "unknown"
26692
+ ]);
26693
+ /** Why a scene cannot judge. Named, because this feature's failure mode is
26694
+ * silence that reads as "nothing has happened". */
26695
+ var SceneUnavailableSchema = _enum([
26696
+ "no-reference-for-condition",
26697
+ "view-shifted",
26698
+ "no-vision-profile",
26699
+ "encoder-model-changed",
26700
+ "no-snapshot"
26701
+ ]);
26203
26702
  /** One captured reference — condition-tagged, model-version-gated. `embedding`
26204
26703
  * is `number[]` (Float32Array does NOT survive MsgPack/UDS). */
26205
26704
  var SceneReferenceSchema = object({
@@ -26207,7 +26706,14 @@ var SceneReferenceSchema = object({
26207
26706
  modelId: string(),
26208
26707
  condition: SceneConditionSchema,
26209
26708
  capturedAt: number(),
26210
- thumbnailMediaId: string().optional()
26709
+ thumbnailMediaId: string().optional(),
26710
+ /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
26711
+ * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
26712
+ * normalized rect frame a different piece of world, and the scene would
26713
+ * diverge forever with a perfectly plausible cosine. Checked LAZILY, only
26714
+ * when hysteresis is about to flip — one extra encode per candidate
26715
+ * transition, not per poll. */
26716
+ anchorEmbedding: array(number()).optional()
26211
26717
  });
26212
26718
  var SceneMonitorStateSchema = object({
26213
26719
  id: string(),
@@ -26229,6 +26735,25 @@ var SceneCheckSchema = discriminatedUnion("mode", [object({
26229
26735
  profileId: string().optional(),
26230
26736
  hysteresisCount: number().int().positive()
26231
26737
  })]);
26738
+ var SCENE_DEFAULT_ANCHOR_THRESHOLD = .85;
26739
+ /**
26740
+ * Vision-model adjudication of a candidate flip. Field names deliberately
26741
+ * mirror `NcConfirmSchema` so an operator meets one vocabulary, not two.
26742
+ *
26743
+ * `onTimeout` defaults to **'hold'**, the OPPOSITE of `NcConfirmGate`'s
26744
+ * fail-open: a notification suppressed is the worse error there, but a vision
26745
+ * model that timed out has not told us the bin is gone, and a latch is a
26746
+ * stateful claim that costs the operator a trip to reset.
26747
+ */
26748
+ var SceneConfirmSchema = object({
26749
+ enabled: boolean().default(false),
26750
+ prompt: string().min(1).max(1e3),
26751
+ profileId: string().optional(),
26752
+ timeoutMs: number().int().min(1e3).max(2e4).default(8e3),
26753
+ maxImagePx: number().int().min(64).max(2048).default(448),
26754
+ /** What a timeout / unavailable model means for the PENDING flip. */
26755
+ onTimeout: _enum(["flip", "hold"]).default("hold")
26756
+ });
26232
26757
  var SceneMonitorSchema = object({
26233
26758
  id: string(),
26234
26759
  label: string(),
@@ -26247,7 +26772,41 @@ var SceneMonitorSchema = object({
26247
26772
  lastConfidence: number().nullable(),
26248
26773
  currentCondition: SceneConditionSchema.nullable(),
26249
26774
  availability: _enum(["ok", "unavailable"]),
26250
- unavailableReason: string().nullable()
26775
+ unavailableReason: string().nullable(),
26776
+ /** Which state is "the initial screen". `null` until the first capture. */
26777
+ baselineStateId: string().nullable(),
26778
+ /** Which boolean drives notification rules and any export. */
26779
+ emit: _enum(["latched", "live"]).default("latched"),
26780
+ /** Live: does the region match the baseline RIGHT NOW. */
26781
+ verdict: SceneVerdictSchema,
26782
+ /** Has it been `diverged` at least once since `armedAt` — the operator's boolean. */
26783
+ latched: boolean(),
26784
+ /** Last reset (or creation). */
26785
+ armedAt: number(),
26786
+ divergedAt: number().nullable(),
26787
+ restoredAt: number().nullable(),
26788
+ /** A check is only COUNTED when the device has been quiet this long. Motion
26789
+ * during the window DISCARDS the observation — a car pulling up in front of
26790
+ * the bin must not be able to spend hysteresis credit. */
26791
+ quietSeconds: number().int().min(0).max(3600).default(60),
26792
+ /** An observation only advances the pending count when it is at least this
26793
+ * far from the previously counted one, so N agreeing checks span real time
26794
+ * rather than N adjacent polls inside one occlusion. */
26795
+ minObservationSpacingSec: number().int().min(0).max(3600).default(120),
26796
+ /** Vision-model adjudication of a candidate flip. Similarity primary only. */
26797
+ confirm: SceneConfirmSchema.optional(),
26798
+ /** Whole-frame anchor cosine below which a flip is REFUSED as `view-shifted`. */
26799
+ anchorThreshold: number().min(0).max(1).default(SCENE_DEFAULT_ANCHOR_THRESHOLD),
26800
+ /** Clear the latch on its own when the scene matches again? Default false —
26801
+ * `restoredAt` and the `scene-restored` edge are recorded regardless, so an
26802
+ * automation can react to the bin coming back without the operator's own
26803
+ * alarm silently clearing itself. */
26804
+ autoRestore: boolean().default(false),
26805
+ /** Named cause when `verdict === 'unknown'`. */
26806
+ unavailable: SceneUnavailableSchema.nullable(),
26807
+ /** Conditions that have at least one comparable reference — the coverage line
26808
+ * ("day ✓ · ir ✓ · dusk ✗") that turns a silent fallback into a visible fact. */
26809
+ coveredConditions: array(SceneConditionSchema)
26251
26810
  });
26252
26811
  var SceneMonitorStatusSchema = object({
26253
26812
  monitors: array(SceneMonitorSchema),
@@ -26260,12 +26819,6 @@ var sceneMonitorCapability = {
26260
26819
  kind: "wrapper",
26261
26820
  defaultActive: true,
26262
26821
  deviceTypes: [DeviceType.Camera],
26263
- deviceConfig: { ui: {
26264
- kind: "widget",
26265
- widgetId: "host/scene-monitor-editor",
26266
- tab: "scenes",
26267
- label: "Scenes"
26268
- } },
26269
26822
  methods: {
26270
26823
  listScenes: method(object({ deviceId: number() }), SceneMonitorStatusSchema),
26271
26824
  createScene: method(object({
@@ -26296,7 +26849,14 @@ var sceneMonitorCapability = {
26296
26849
  "both"
26297
26850
  ]).optional(),
26298
26851
  checkIntervalSec: number().optional(),
26299
- check: SceneCheckSchema.optional()
26852
+ check: SceneCheckSchema.optional(),
26853
+ emit: _enum(["latched", "live"]).optional(),
26854
+ quietSeconds: number().int().min(0).max(3600).optional(),
26855
+ minObservationSpacingSec: number().int().min(0).max(3600).optional(),
26856
+ anchorThreshold: number().min(0).max(1).optional(),
26857
+ autoRestore: boolean().optional(),
26858
+ /** `null` clears the vision-model adjudicator. */
26859
+ confirm: SceneConfirmSchema.nullable().optional()
26300
26860
  })
26301
26861
  }), _void(), {
26302
26862
  kind: "mutation",
@@ -26337,6 +26897,26 @@ var sceneMonitorCapability = {
26337
26897
  }), _void(), {
26338
26898
  kind: "mutation",
26339
26899
  auth: "admin"
26900
+ }),
26901
+ /**
26902
+ * Clear the latch, re-arm, and — by default — RE-CAPTURE the baseline for
26903
+ * the CURRENT condition. The bin never goes back in exactly the same spot;
26904
+ * "reset" in the operator's head means *this is the new normal*, and
26905
+ * re-capture is what makes the feature self-healing against slow drift
26906
+ * instead of failing silently weeks later.
26907
+ *
26908
+ * Reachable from three surfaces on this one mutation: the scene card, a
26909
+ * notification button (an `onTrigger` sequence with a `kind:'cap'` step —
26910
+ * no new Notification-Center code at all), and tRPC for scripts.
26911
+ */
26912
+ resetScene: method(object({
26913
+ deviceId: number(),
26914
+ monitorId: string(),
26915
+ /** Defaults to TRUE at the provider seam — see `SCENE_RESET_RECAPTURES`. */
26916
+ recapture: boolean().optional()
26917
+ }), _void(), {
26918
+ kind: "mutation",
26919
+ auth: "admin"
26340
26920
  })
26341
26921
  },
26342
26922
  status: {
@@ -26827,12 +27407,64 @@ var NetworkAddressSchema = object({
26827
27407
  family: string(),
26828
27408
  internal: boolean()
26829
27409
  });
27410
+ /**
27411
+ * Provenance of the site coordinates, and the whole reason this is not just two
27412
+ * numbers.
27413
+ *
27414
+ * - `operator-set` — a human typed it, or accepted a detection. Authoritative;
27415
+ * nothing overwrites it.
27416
+ * - `derived-from-ip` — the hub geolocated its own public IP once, because a
27417
+ * default that is right to a few kilometres beats the coarse UTC clock split
27418
+ * the sun-times consumers otherwise fall back to.
27419
+ *
27420
+ * The UI shows which one it is. An operator who cannot tell a guess from their
27421
+ * own input will eventually trust the guess.
27422
+ */
27423
+ var SiteLocationSourceSchema = _enum(["operator-set", "derived-from-ip"]);
27424
+ /**
27425
+ * The read shape: the location plus the honest state of the one-shot derivation.
27426
+ *
27427
+ * `derivationAttemptedAt` is what makes the "one call, ever" contract
27428
+ * inspectable. When it is set and `location` is null, the geo-IP lookup ran and
27429
+ * failed; the hub will NOT try again on its own — the fallback is declared
27430
+ * (consumers degrade to their own last resort) and the operator either types the
27431
+ * coordinates or presses detect.
27432
+ */
27433
+ var SiteLocationStatusSchema = object({
27434
+ location: object({
27435
+ /** WGS84 decimal degrees. */
27436
+ latitude: number().min(-90).max(90),
27437
+ longitude: number().min(-180).max(180),
27438
+ source: SiteLocationSourceSchema,
27439
+ /** Epoch ms the value was last written. */
27440
+ updatedAt: number(),
27441
+ /**
27442
+ * Human-readable place the geo-IP service reported ("Napoli, IT"). Display
27443
+ * only — never parsed, never matched on. Absent for an operator-typed value.
27444
+ */
27445
+ label: string().optional()
27446
+ }).nullable(),
27447
+ derivationAttemptedAt: number().nullable(),
27448
+ /** Why the last derivation failed, for the UI to show instead of a shrug. */
27449
+ derivationError: string().nullable()
27450
+ });
27451
+ /** `null` clears the location and re-arms nothing — the derivation stays spent. */
27452
+ var SetSiteLocationInputSchema = object({
27453
+ latitude: number().min(-90).max(90),
27454
+ longitude: number().min(-180).max(180)
27455
+ }).nullable();
26830
27456
  method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
26831
27457
  kind: "mutation",
26832
27458
  auth: "admin"
26833
27459
  }), method(_void(), _void(), {
26834
27460
  kind: "mutation",
26835
27461
  auth: "admin"
27462
+ }), method(_void(), SiteLocationStatusSchema), method(SetSiteLocationInputSchema, SiteLocationStatusSchema, {
27463
+ kind: "mutation",
27464
+ auth: "admin"
27465
+ }), method(_void(), SiteLocationStatusSchema, {
27466
+ kind: "mutation",
27467
+ auth: "admin"
26836
27468
  });
26837
27469
  /**
26838
27470
  * Tamper / case-open detection sensor. Drives Home Assistant
@@ -28152,6 +28784,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
28152
28784
  humiditySensor: humiditySensorCapability,
28153
28785
  image: imageCapability,
28154
28786
  imageSettings: imageSettingsCapability,
28787
+ intercom: intercomCapability,
28155
28788
  lawnMowerControl: lawnMowerControlCapability,
28156
28789
  lockControl: lockControlCapability,
28157
28790
  mediaPlayer: mediaPlayerCapability,
@@ -30967,6 +31600,12 @@ Object.freeze({
30967
31600
  addonId: null,
30968
31601
  access: "create"
30969
31602
  },
31603
+ "llm.cancel": {
31604
+ capName: "llm",
31605
+ capScope: "system",
31606
+ addonId: null,
31607
+ access: "create"
31608
+ },
30970
31609
  "llm.deleteModel": {
30971
31610
  capName: "llm",
30972
31611
  capScope: "system",
@@ -33217,6 +33856,12 @@ Object.freeze({
33217
33856
  addonId: null,
33218
33857
  access: "create"
33219
33858
  },
33859
+ "sceneMonitor.resetScene": {
33860
+ capName: "scene-monitor",
33861
+ capScope: "device",
33862
+ addonId: null,
33863
+ access: "delete"
33864
+ },
33220
33865
  "sceneMonitor.updateScene": {
33221
33866
  capName: "scene-monitor",
33222
33867
  capScope: "device",
@@ -33895,6 +34540,12 @@ Object.freeze({
33895
34540
  addonId: null,
33896
34541
  access: "create"
33897
34542
  },
34543
+ "system.detectSiteLocation": {
34544
+ capName: "system",
34545
+ capScope: "system",
34546
+ addonId: null,
34547
+ access: "create"
34548
+ },
33898
34549
  "system.featureFlags": {
33899
34550
  capName: "system",
33900
34551
  capScope: "system",
@@ -33913,6 +34564,12 @@ Object.freeze({
33913
34564
  addonId: null,
33914
34565
  access: "view"
33915
34566
  },
34567
+ "system.getSiteLocation": {
34568
+ capName: "system",
34569
+ capScope: "system",
34570
+ addonId: null,
34571
+ access: "view"
34572
+ },
33916
34573
  "system.health": {
33917
34574
  capName: "system",
33918
34575
  capScope: "system",
@@ -33937,6 +34594,12 @@ Object.freeze({
33937
34594
  addonId: null,
33938
34595
  access: "create"
33939
34596
  },
34597
+ "system.setSiteLocation": {
34598
+ capName: "system",
34599
+ capScope: "system",
34600
+ addonId: null,
34601
+ access: "create"
34602
+ },
33940
34603
  "terminalSession.adoptLegacyMonitor": {
33941
34604
  capName: "terminal-session",
33942
34605
  capScope: "system",
@@ -34508,6 +35171,1683 @@ Object.freeze({
34508
35171
  access: "create"
34509
35172
  }
34510
35173
  });
35174
+ Object.freeze({
35175
+ "accessories.setChildHidden": [{
35176
+ name: "childDeviceId",
35177
+ form: "single",
35178
+ optional: false
35179
+ }, {
35180
+ name: "deviceId",
35181
+ form: "single",
35182
+ optional: false
35183
+ }],
35184
+ "addonSettings.getDeviceSettings": [{
35185
+ name: "deviceId",
35186
+ form: "single",
35187
+ optional: false
35188
+ }],
35189
+ "addonSettings.updateDeviceSettings": [{
35190
+ name: "deviceId",
35191
+ form: "single",
35192
+ optional: false
35193
+ }],
35194
+ "alarmPanel.arm": [{
35195
+ name: "deviceId",
35196
+ form: "single",
35197
+ optional: false
35198
+ }],
35199
+ "alarmPanel.disarm": [{
35200
+ name: "deviceId",
35201
+ form: "single",
35202
+ optional: false
35203
+ }],
35204
+ "alarmPanel.trigger": [{
35205
+ name: "deviceId",
35206
+ form: "single",
35207
+ optional: false
35208
+ }],
35209
+ "audioAnalysis.resolveDeviceSettings": [{
35210
+ name: "deviceId",
35211
+ form: "single",
35212
+ optional: false
35213
+ }],
35214
+ "audioAnalyzer.classify": [{
35215
+ name: "deviceId",
35216
+ form: "single",
35217
+ optional: true
35218
+ }],
35219
+ "audioMetrics.getCurrentSnapshot": [{
35220
+ name: "deviceId",
35221
+ form: "single",
35222
+ optional: false
35223
+ }],
35224
+ "audioMetrics.getHistory": [{
35225
+ name: "deviceId",
35226
+ form: "single",
35227
+ optional: false
35228
+ }],
35229
+ "automationControl.disable": [{
35230
+ name: "deviceId",
35231
+ form: "single",
35232
+ optional: false
35233
+ }],
35234
+ "automationControl.enable": [{
35235
+ name: "deviceId",
35236
+ form: "single",
35237
+ optional: false
35238
+ }],
35239
+ "automationControl.trigger": [{
35240
+ name: "deviceId",
35241
+ form: "single",
35242
+ optional: false
35243
+ }],
35244
+ "battery.wakeForStream": [{
35245
+ name: "deviceId",
35246
+ form: "single",
35247
+ optional: false
35248
+ }],
35249
+ "brightness.setBrightness": [{
35250
+ name: "deviceId",
35251
+ form: "single",
35252
+ optional: false
35253
+ }],
35254
+ "button.press": [{
35255
+ name: "deviceId",
35256
+ form: "single",
35257
+ optional: false
35258
+ }],
35259
+ "cameraCredentials.getCredentials": [{
35260
+ name: "deviceId",
35261
+ form: "single",
35262
+ optional: false
35263
+ }],
35264
+ "cameraStreams.getBrokerStreams": [{
35265
+ name: "deviceId",
35266
+ form: "single",
35267
+ optional: false
35268
+ }],
35269
+ "cameraStreams.getCameraStreams": [{
35270
+ name: "deviceId",
35271
+ form: "single",
35272
+ optional: false
35273
+ }],
35274
+ "cameraStreams.getProfileRtspEntries": [{
35275
+ name: "deviceId",
35276
+ form: "single",
35277
+ optional: false
35278
+ }],
35279
+ "cameraStreams.getRtspEntries": [{
35280
+ name: "deviceId",
35281
+ form: "single",
35282
+ optional: false
35283
+ }],
35284
+ "cameraStreams.pickStream": [{
35285
+ name: "deviceId",
35286
+ form: "single",
35287
+ optional: false
35288
+ }],
35289
+ "climateControl.setFanMode": [{
35290
+ name: "deviceId",
35291
+ form: "single",
35292
+ optional: false
35293
+ }],
35294
+ "climateControl.setMode": [{
35295
+ name: "deviceId",
35296
+ form: "single",
35297
+ optional: false
35298
+ }],
35299
+ "climateControl.setPreset": [{
35300
+ name: "deviceId",
35301
+ form: "single",
35302
+ optional: false
35303
+ }],
35304
+ "climateControl.setSwingHorizontal": [{
35305
+ name: "deviceId",
35306
+ form: "single",
35307
+ optional: false
35308
+ }],
35309
+ "climateControl.setSwingVertical": [{
35310
+ name: "deviceId",
35311
+ form: "single",
35312
+ optional: false
35313
+ }],
35314
+ "climateControl.setTarget": [{
35315
+ name: "deviceId",
35316
+ form: "single",
35317
+ optional: false
35318
+ }],
35319
+ "climateControl.setTargetHumidity": [{
35320
+ name: "deviceId",
35321
+ form: "single",
35322
+ optional: false
35323
+ }],
35324
+ "climateControl.setTargetRange": [{
35325
+ name: "deviceId",
35326
+ form: "single",
35327
+ optional: false
35328
+ }],
35329
+ "color.setColor": [{
35330
+ name: "deviceId",
35331
+ form: "single",
35332
+ optional: false
35333
+ }],
35334
+ "consumables.reset": [{
35335
+ name: "deviceId",
35336
+ form: "single",
35337
+ optional: false
35338
+ }],
35339
+ "control.setValue": [{
35340
+ name: "deviceId",
35341
+ form: "single",
35342
+ optional: false
35343
+ }],
35344
+ "cover.close": [{
35345
+ name: "deviceId",
35346
+ form: "single",
35347
+ optional: false
35348
+ }],
35349
+ "cover.open": [{
35350
+ name: "deviceId",
35351
+ form: "single",
35352
+ optional: false
35353
+ }],
35354
+ "cover.setPosition": [{
35355
+ name: "deviceId",
35356
+ form: "single",
35357
+ optional: false
35358
+ }],
35359
+ "cover.setTiltPosition": [{
35360
+ name: "deviceId",
35361
+ form: "single",
35362
+ optional: false
35363
+ }],
35364
+ "cover.stop": [{
35365
+ name: "deviceId",
35366
+ form: "single",
35367
+ optional: false
35368
+ }],
35369
+ "dayNight.getOptions": [{
35370
+ name: "deviceId",
35371
+ form: "single",
35372
+ optional: false
35373
+ }],
35374
+ "dayNight.setSettings": [{
35375
+ name: "deviceId",
35376
+ form: "single",
35377
+ optional: false
35378
+ }],
35379
+ "decoder.createSession": [{
35380
+ name: "deviceId",
35381
+ form: "single",
35382
+ optional: true
35383
+ }],
35384
+ "deviceAdoption.release": [{
35385
+ name: "camDeviceId",
35386
+ form: "single",
35387
+ optional: false
35388
+ }],
35389
+ "deviceAdoption.resync": [{
35390
+ name: "camDeviceId",
35391
+ form: "single",
35392
+ optional: false
35393
+ }],
35394
+ "deviceDiscovery.adoptDevice": [{
35395
+ name: "deviceId",
35396
+ form: "single",
35397
+ optional: false
35398
+ }],
35399
+ "deviceDiscovery.listDiscovered": [{
35400
+ name: "deviceId",
35401
+ form: "single",
35402
+ optional: false
35403
+ }],
35404
+ "deviceDiscovery.refreshDiscovery": [{
35405
+ name: "deviceId",
35406
+ form: "single",
35407
+ optional: false
35408
+ }],
35409
+ "deviceDiscovery.releaseDevice": [{
35410
+ name: "childDeviceId",
35411
+ form: "single",
35412
+ optional: false
35413
+ }, {
35414
+ name: "deviceId",
35415
+ form: "single",
35416
+ optional: false
35417
+ }],
35418
+ "deviceManager.adoptionRelease": [{
35419
+ name: "camDeviceId",
35420
+ form: "single",
35421
+ optional: false
35422
+ }],
35423
+ "deviceManager.adoptionResync": [{
35424
+ name: "camDeviceId",
35425
+ form: "single",
35426
+ optional: false
35427
+ }],
35428
+ "deviceManager.applyInitialMeta": [{
35429
+ name: "deviceId",
35430
+ form: "single",
35431
+ optional: false
35432
+ }, {
35433
+ name: "linkDeviceId",
35434
+ form: "single",
35435
+ optional: true
35436
+ }],
35437
+ "deviceManager.disable": [{
35438
+ name: "deviceId",
35439
+ form: "single",
35440
+ optional: false
35441
+ }],
35442
+ "deviceManager.enable": [{
35443
+ name: "deviceId",
35444
+ form: "single",
35445
+ optional: false
35446
+ }],
35447
+ "deviceManager.getBindings": [{
35448
+ name: "deviceId",
35449
+ form: "single",
35450
+ optional: false
35451
+ }],
35452
+ "deviceManager.getChildren": [{
35453
+ name: "parentDeviceId",
35454
+ form: "single",
35455
+ optional: false
35456
+ }],
35457
+ "deviceManager.getConfigSchema": [{
35458
+ name: "deviceId",
35459
+ form: "single",
35460
+ optional: false
35461
+ }],
35462
+ "deviceManager.getDevice": [{
35463
+ name: "deviceId",
35464
+ form: "single",
35465
+ optional: false
35466
+ }],
35467
+ "deviceManager.getDeviceAggregate": [{
35468
+ name: "deviceId",
35469
+ form: "single",
35470
+ optional: false
35471
+ }],
35472
+ "deviceManager.getDeviceLiveInfoAggregate": [{
35473
+ name: "deviceId",
35474
+ form: "single",
35475
+ optional: false
35476
+ }],
35477
+ "deviceManager.getDeviceSettingsAggregate": [{
35478
+ name: "deviceId",
35479
+ form: "single",
35480
+ optional: false
35481
+ }],
35482
+ "deviceManager.getDeviceStatusAggregate": [{
35483
+ name: "deviceId",
35484
+ form: "single",
35485
+ optional: false
35486
+ }],
35487
+ "deviceManager.getDeviceStatusAggregateBatch": [{
35488
+ name: "deviceIds",
35489
+ form: "array",
35490
+ optional: false
35491
+ }],
35492
+ "deviceManager.getLinkedDevices": [{
35493
+ name: "deviceId",
35494
+ form: "single",
35495
+ optional: false
35496
+ }],
35497
+ "deviceManager.getSettingsSchema": [{
35498
+ name: "deviceId",
35499
+ form: "single",
35500
+ optional: false
35501
+ }],
35502
+ "deviceManager.getStreamProfileMap": [{
35503
+ name: "deviceId",
35504
+ form: "single",
35505
+ optional: false
35506
+ }],
35507
+ "deviceManager.getStreamSources": [{
35508
+ name: "deviceId",
35509
+ form: "single",
35510
+ optional: false
35511
+ }],
35512
+ "deviceManager.getWireableFields": [{
35513
+ name: "deviceId",
35514
+ form: "single",
35515
+ optional: false
35516
+ }],
35517
+ "deviceManager.loadConfig": [{
35518
+ name: "deviceId",
35519
+ form: "single",
35520
+ optional: false
35521
+ }],
35522
+ "deviceManager.loadMeta": [{
35523
+ name: "deviceId",
35524
+ form: "single",
35525
+ optional: false
35526
+ }],
35527
+ "deviceManager.loadRuntimeState": [{
35528
+ name: "deviceId",
35529
+ form: "single",
35530
+ optional: false
35531
+ }],
35532
+ "deviceManager.persistConfig": [{
35533
+ name: "deviceId",
35534
+ form: "single",
35535
+ optional: false
35536
+ }],
35537
+ "deviceManager.probeStreams": [{
35538
+ name: "deviceId",
35539
+ form: "single",
35540
+ optional: false
35541
+ }],
35542
+ "deviceManager.registerDevice": [{
35543
+ name: "parentDeviceId",
35544
+ form: "single",
35545
+ optional: true
35546
+ }],
35547
+ "deviceManager.remove": [{
35548
+ name: "deviceId",
35549
+ form: "single",
35550
+ optional: false
35551
+ }],
35552
+ "deviceManager.removeDevice": [{
35553
+ name: "deviceId",
35554
+ form: "single",
35555
+ optional: false
35556
+ }],
35557
+ "deviceManager.runDeviceAction": [{
35558
+ name: "deviceId",
35559
+ form: "single",
35560
+ optional: false
35561
+ }],
35562
+ "deviceManager.setChildLayout": [{
35563
+ name: "deviceId",
35564
+ form: "single",
35565
+ optional: false
35566
+ }],
35567
+ "deviceManager.setDisabled": [{
35568
+ name: "deviceId",
35569
+ form: "single",
35570
+ optional: false
35571
+ }],
35572
+ "deviceManager.setDisplay": [{
35573
+ name: "deviceId",
35574
+ form: "single",
35575
+ optional: false
35576
+ }],
35577
+ "deviceManager.setIntegrationId": [{
35578
+ name: "deviceId",
35579
+ form: "single",
35580
+ optional: false
35581
+ }],
35582
+ "deviceManager.setLinkDeviceId": [{
35583
+ name: "deviceId",
35584
+ form: "single",
35585
+ optional: false
35586
+ }, {
35587
+ name: "linkDeviceId",
35588
+ form: "single",
35589
+ optional: true
35590
+ }],
35591
+ "deviceManager.setLocation": [{
35592
+ name: "deviceId",
35593
+ form: "single",
35594
+ optional: false
35595
+ }],
35596
+ "deviceManager.setMetadata": [{
35597
+ name: "deviceId",
35598
+ form: "single",
35599
+ optional: false
35600
+ }],
35601
+ "deviceManager.setName": [{
35602
+ name: "deviceId",
35603
+ form: "single",
35604
+ optional: false
35605
+ }],
35606
+ "deviceManager.setPrimaryChildEntityId": [{
35607
+ name: "deviceId",
35608
+ form: "single",
35609
+ optional: false
35610
+ }],
35611
+ "deviceManager.setRole": [{
35612
+ name: "deviceId",
35613
+ form: "single",
35614
+ optional: false
35615
+ }],
35616
+ "deviceManager.setStreamProfileMap": [{
35617
+ name: "deviceId",
35618
+ form: "single",
35619
+ optional: false
35620
+ }],
35621
+ "deviceManager.setType": [{
35622
+ name: "deviceId",
35623
+ form: "single",
35624
+ optional: false
35625
+ }],
35626
+ "deviceManager.setWrapperActive": [{
35627
+ name: "deviceId",
35628
+ form: "single",
35629
+ optional: false
35630
+ }],
35631
+ "deviceManager.testField": [{
35632
+ name: "deviceId",
35633
+ form: "single",
35634
+ optional: false
35635
+ }],
35636
+ "deviceManager.updateConfig": [{
35637
+ name: "deviceId",
35638
+ form: "single",
35639
+ optional: false
35640
+ }],
35641
+ "deviceManager.updateDeviceField": [{
35642
+ name: "deviceId",
35643
+ form: "single",
35644
+ optional: false
35645
+ }],
35646
+ "deviceManager.updateDeviceFieldsBatch": [{
35647
+ name: "deviceId",
35648
+ form: "single",
35649
+ optional: false
35650
+ }],
35651
+ "deviceOps.getConfigEntries": [{
35652
+ name: "deviceId",
35653
+ form: "single",
35654
+ optional: false
35655
+ }],
35656
+ "deviceOps.getRawState": [{
35657
+ name: "deviceId",
35658
+ form: "single",
35659
+ optional: false
35660
+ }],
35661
+ "deviceOps.getSettingsSchema": [{
35662
+ name: "deviceId",
35663
+ form: "single",
35664
+ optional: false
35665
+ }],
35666
+ "deviceOps.getStreamSources": [{
35667
+ name: "deviceId",
35668
+ form: "single",
35669
+ optional: false
35670
+ }],
35671
+ "deviceOps.removeDevice": [{
35672
+ name: "deviceId",
35673
+ form: "single",
35674
+ optional: false
35675
+ }],
35676
+ "deviceOps.runAction": [{
35677
+ name: "deviceId",
35678
+ form: "single",
35679
+ optional: false
35680
+ }],
35681
+ "deviceOps.setConfig": [{
35682
+ name: "deviceId",
35683
+ form: "single",
35684
+ optional: false
35685
+ }],
35686
+ "deviceState.getCapSlice": [{
35687
+ name: "deviceId",
35688
+ form: "single",
35689
+ optional: false
35690
+ }],
35691
+ "deviceState.getSnapshot": [{
35692
+ name: "deviceId",
35693
+ form: "single",
35694
+ optional: false
35695
+ }],
35696
+ "deviceState.setCapSlice": [{
35697
+ name: "deviceId",
35698
+ form: "single",
35699
+ optional: false
35700
+ }],
35701
+ "events.getEventClipUrl": [{
35702
+ name: "deviceId",
35703
+ form: "single",
35704
+ optional: false
35705
+ }],
35706
+ "events.getEvents": [{
35707
+ name: "deviceId",
35708
+ form: "single",
35709
+ optional: false
35710
+ }],
35711
+ "events.getEventThumbnail": [{
35712
+ name: "deviceId",
35713
+ form: "single",
35714
+ optional: false
35715
+ }],
35716
+ "faceGallery.getFaceByTrack": [{
35717
+ name: "deviceId",
35718
+ form: "single",
35719
+ optional: false
35720
+ }],
35721
+ "faceGallery.listRecentFaces": [{
35722
+ name: "deviceId",
35723
+ form: "single",
35724
+ optional: true
35725
+ }],
35726
+ "fanControl.setDirection": [{
35727
+ name: "deviceId",
35728
+ form: "single",
35729
+ optional: false
35730
+ }],
35731
+ "fanControl.setOscillating": [{
35732
+ name: "deviceId",
35733
+ form: "single",
35734
+ optional: false
35735
+ }],
35736
+ "fanControl.setPercentage": [{
35737
+ name: "deviceId",
35738
+ form: "single",
35739
+ optional: false
35740
+ }],
35741
+ "fanControl.setPreset": [{
35742
+ name: "deviceId",
35743
+ form: "single",
35744
+ optional: false
35745
+ }],
35746
+ "humidifier.setMode": [{
35747
+ name: "deviceId",
35748
+ form: "single",
35749
+ optional: false
35750
+ }],
35751
+ "humidifier.setOn": [{
35752
+ name: "deviceId",
35753
+ form: "single",
35754
+ optional: false
35755
+ }],
35756
+ "humidifier.setTargetHumidity": [{
35757
+ name: "deviceId",
35758
+ form: "single",
35759
+ optional: false
35760
+ }],
35761
+ "imageSettings.getOptions": [{
35762
+ name: "deviceId",
35763
+ form: "single",
35764
+ optional: false
35765
+ }],
35766
+ "imageSettings.setSettings": [{
35767
+ name: "deviceId",
35768
+ form: "single",
35769
+ optional: false
35770
+ }],
35771
+ "intercom.endTalkSession": [{
35772
+ name: "deviceId",
35773
+ form: "single",
35774
+ optional: false
35775
+ }],
35776
+ "intercom.handleAnswer": [{
35777
+ name: "deviceId",
35778
+ form: "single",
35779
+ optional: false
35780
+ }],
35781
+ "intercom.pushTalkAudio": [{
35782
+ name: "deviceId",
35783
+ form: "single",
35784
+ optional: false
35785
+ }],
35786
+ "intercom.startSession": [{
35787
+ name: "deviceId",
35788
+ form: "single",
35789
+ optional: false
35790
+ }],
35791
+ "intercom.startTalkSession": [{
35792
+ name: "deviceId",
35793
+ form: "single",
35794
+ optional: false
35795
+ }],
35796
+ "intercom.stopSession": [{
35797
+ name: "deviceId",
35798
+ form: "single",
35799
+ optional: false
35800
+ }],
35801
+ "lawnMowerControl.dock": [{
35802
+ name: "deviceId",
35803
+ form: "single",
35804
+ optional: false
35805
+ }],
35806
+ "lawnMowerControl.pause": [{
35807
+ name: "deviceId",
35808
+ form: "single",
35809
+ optional: false
35810
+ }],
35811
+ "lawnMowerControl.startMowing": [{
35812
+ name: "deviceId",
35813
+ form: "single",
35814
+ optional: false
35815
+ }],
35816
+ "lockControl.lock": [{
35817
+ name: "deviceId",
35818
+ form: "single",
35819
+ optional: false
35820
+ }],
35821
+ "lockControl.open": [{
35822
+ name: "deviceId",
35823
+ form: "single",
35824
+ optional: false
35825
+ }],
35826
+ "lockControl.unlock": [{
35827
+ name: "deviceId",
35828
+ form: "single",
35829
+ optional: false
35830
+ }],
35831
+ "mediaPlayer.next": [{
35832
+ name: "deviceId",
35833
+ form: "single",
35834
+ optional: false
35835
+ }],
35836
+ "mediaPlayer.pause": [{
35837
+ name: "deviceId",
35838
+ form: "single",
35839
+ optional: false
35840
+ }],
35841
+ "mediaPlayer.play": [{
35842
+ name: "deviceId",
35843
+ form: "single",
35844
+ optional: false
35845
+ }],
35846
+ "mediaPlayer.playMedia": [{
35847
+ name: "deviceId",
35848
+ form: "single",
35849
+ optional: false
35850
+ }],
35851
+ "mediaPlayer.previous": [{
35852
+ name: "deviceId",
35853
+ form: "single",
35854
+ optional: false
35855
+ }],
35856
+ "mediaPlayer.seek": [{
35857
+ name: "deviceId",
35858
+ form: "single",
35859
+ optional: false
35860
+ }],
35861
+ "mediaPlayer.selectSource": [{
35862
+ name: "deviceId",
35863
+ form: "single",
35864
+ optional: false
35865
+ }],
35866
+ "mediaPlayer.setMute": [{
35867
+ name: "deviceId",
35868
+ form: "single",
35869
+ optional: false
35870
+ }],
35871
+ "mediaPlayer.setRepeat": [{
35872
+ name: "deviceId",
35873
+ form: "single",
35874
+ optional: false
35875
+ }],
35876
+ "mediaPlayer.setShuffle": [{
35877
+ name: "deviceId",
35878
+ form: "single",
35879
+ optional: false
35880
+ }],
35881
+ "mediaPlayer.setVolume": [{
35882
+ name: "deviceId",
35883
+ form: "single",
35884
+ optional: false
35885
+ }],
35886
+ "mediaPlayer.stop": [{
35887
+ name: "deviceId",
35888
+ form: "single",
35889
+ optional: false
35890
+ }],
35891
+ "motion.isDetected": [{
35892
+ name: "deviceId",
35893
+ form: "single",
35894
+ optional: false
35895
+ }],
35896
+ "motionDetection.analyze": [{
35897
+ name: "deviceId",
35898
+ form: "single",
35899
+ optional: false
35900
+ }],
35901
+ "motionDetection.removeCamera": [{
35902
+ name: "deviceId",
35903
+ form: "single",
35904
+ optional: false
35905
+ }],
35906
+ "motionTrigger.setMotionTrigger": [{
35907
+ name: "deviceId",
35908
+ form: "single",
35909
+ optional: false
35910
+ }],
35911
+ "motionZones.getOptions": [{
35912
+ name: "deviceId",
35913
+ form: "single",
35914
+ optional: false
35915
+ }],
35916
+ "motionZones.setZone": [{
35917
+ name: "deviceId",
35918
+ form: "single",
35919
+ optional: false
35920
+ }],
35921
+ "nativeObjectDetection.setEnabled": [{
35922
+ name: "deviceId",
35923
+ form: "single",
35924
+ optional: false
35925
+ }],
35926
+ "networkQuality.getDeviceStats": [{
35927
+ name: "deviceId",
35928
+ form: "single",
35929
+ optional: false
35930
+ }],
35931
+ "networkQuality.reportClientStats": [{
35932
+ name: "deviceId",
35933
+ form: "single",
35934
+ optional: false
35935
+ }],
35936
+ "notificationRules.setDeviceMuted": [{
35937
+ name: "deviceId",
35938
+ form: "single",
35939
+ optional: false
35940
+ }],
35941
+ "notifier.cancel": [{
35942
+ name: "deviceId",
35943
+ form: "single",
35944
+ optional: false
35945
+ }],
35946
+ "notifier.send": [{
35947
+ name: "deviceId",
35948
+ form: "single",
35949
+ optional: false
35950
+ }],
35951
+ "osd.setOverlay": [{
35952
+ name: "deviceId",
35953
+ form: "single",
35954
+ optional: false
35955
+ }],
35956
+ "osdManager.clearSlotBinding": [{
35957
+ name: "deviceId",
35958
+ form: "single",
35959
+ optional: false
35960
+ }],
35961
+ "osdManager.copyDeviceConfiguration": [{
35962
+ name: "sourceDeviceId",
35963
+ form: "single",
35964
+ optional: false
35965
+ }, {
35966
+ name: "targetDeviceId",
35967
+ form: "single",
35968
+ optional: false
35969
+ }],
35970
+ "osdManager.getDeviceOsd": [{
35971
+ name: "deviceId",
35972
+ form: "single",
35973
+ optional: false
35974
+ }],
35975
+ "osdManager.getSourceCatalog": [{
35976
+ name: "deviceId",
35977
+ form: "single",
35978
+ optional: false
35979
+ }],
35980
+ "osdManager.previewSlot": [{
35981
+ name: "deviceId",
35982
+ form: "single",
35983
+ optional: false
35984
+ }],
35985
+ "osdManager.renderDevice": [{
35986
+ name: "deviceId",
35987
+ form: "single",
35988
+ optional: false
35989
+ }],
35990
+ "osdManager.setSlotBinding": [{
35991
+ name: "deviceId",
35992
+ form: "single",
35993
+ optional: false
35994
+ }],
35995
+ "petFeeder.callPet": [{
35996
+ name: "deviceId",
35997
+ form: "single",
35998
+ optional: false
35999
+ }],
36000
+ "petFeeder.cancelFeed": [{
36001
+ name: "deviceId",
36002
+ form: "single",
36003
+ optional: false
36004
+ }],
36005
+ "petFeeder.feed": [{
36006
+ name: "deviceId",
36007
+ form: "single",
36008
+ optional: false
36009
+ }],
36010
+ "petFeeder.markFoodReplenished": [{
36011
+ name: "deviceId",
36012
+ form: "single",
36013
+ optional: false
36014
+ }],
36015
+ "petFeeder.playSound": [{
36016
+ name: "deviceId",
36017
+ form: "single",
36018
+ optional: false
36019
+ }],
36020
+ "petFeeder.resetDesiccant": [{
36021
+ name: "deviceId",
36022
+ form: "single",
36023
+ optional: false
36024
+ }],
36025
+ "petFeeder.setChildLock": [{
36026
+ name: "deviceId",
36027
+ form: "single",
36028
+ optional: false
36029
+ }],
36030
+ "petFeeder.setFeedSound": [{
36031
+ name: "deviceId",
36032
+ form: "single",
36033
+ optional: false
36034
+ }],
36035
+ "petFeeder.setIndicatorLight": [{
36036
+ name: "deviceId",
36037
+ form: "single",
36038
+ optional: false
36039
+ }],
36040
+ "petFeeder.setVolume": [{
36041
+ name: "deviceId",
36042
+ form: "single",
36043
+ optional: false
36044
+ }],
36045
+ "pipelineAnalytics.clearTracks": [{
36046
+ name: "deviceId",
36047
+ form: "single",
36048
+ optional: false
36049
+ }],
36050
+ "pipelineAnalytics.completeRetrainTrack": [{
36051
+ name: "deviceId",
36052
+ form: "single",
36053
+ optional: false
36054
+ }],
36055
+ "pipelineAnalytics.deleteDeviceEvents": [{
36056
+ name: "deviceId",
36057
+ form: "single",
36058
+ optional: false
36059
+ }],
36060
+ "pipelineAnalytics.deleteTracks": [{
36061
+ name: "deviceId",
36062
+ form: "single",
36063
+ optional: false
36064
+ }],
36065
+ "pipelineAnalytics.deselectRetrainFrame": [{
36066
+ name: "deviceId",
36067
+ form: "single",
36068
+ optional: false
36069
+ }],
36070
+ "pipelineAnalytics.getActiveTracks": [{
36071
+ name: "deviceId",
36072
+ form: "single",
36073
+ optional: false
36074
+ }],
36075
+ "pipelineAnalytics.getAudioEvents": [{
36076
+ name: "deviceId",
36077
+ form: "single",
36078
+ optional: false
36079
+ }],
36080
+ "pipelineAnalytics.getEventDensity": [{
36081
+ name: "deviceId",
36082
+ form: "single",
36083
+ optional: false
36084
+ }],
36085
+ "pipelineAnalytics.getKeyEvents": [{
36086
+ name: "deviceId",
36087
+ form: "single",
36088
+ optional: false
36089
+ }],
36090
+ "pipelineAnalytics.getMotionEvents": [{
36091
+ name: "deviceId",
36092
+ form: "single",
36093
+ optional: false
36094
+ }],
36095
+ "pipelineAnalytics.getObjectEvents": [{
36096
+ name: "deviceId",
36097
+ form: "single",
36098
+ optional: false
36099
+ }],
36100
+ "pipelineAnalytics.getRetrainExportUrl": [{
36101
+ name: "deviceIds",
36102
+ form: "array",
36103
+ optional: true
36104
+ }],
36105
+ "pipelineAnalytics.getSensorEvents": [{
36106
+ name: "deviceId",
36107
+ form: "single",
36108
+ optional: false
36109
+ }],
36110
+ "pipelineAnalytics.getTrack": [{
36111
+ name: "deviceId",
36112
+ form: "single",
36113
+ optional: false
36114
+ }],
36115
+ "pipelineAnalytics.getTrainingExportSummary": [{
36116
+ name: "deviceIds",
36117
+ form: "array",
36118
+ optional: true
36119
+ }],
36120
+ "pipelineAnalytics.getTrainingExportUrl": [{
36121
+ name: "deviceIds",
36122
+ form: "array",
36123
+ optional: true
36124
+ }],
36125
+ "pipelineAnalytics.listEventKinds": [{
36126
+ name: "deviceId",
36127
+ form: "single",
36128
+ optional: false
36129
+ }],
36130
+ "pipelineAnalytics.listEventKindsBatch": [{
36131
+ name: "deviceIds",
36132
+ form: "array",
36133
+ optional: false
36134
+ }],
36135
+ "pipelineAnalytics.listOpsLog": [{
36136
+ name: "deviceId",
36137
+ form: "single",
36138
+ optional: true
36139
+ }],
36140
+ "pipelineAnalytics.listRecentTracks": [{
36141
+ name: "deviceIds",
36142
+ form: "array",
36143
+ optional: false
36144
+ }],
36145
+ "pipelineAnalytics.listRetrainStaging": [{
36146
+ name: "deviceIds",
36147
+ form: "array",
36148
+ optional: true
36149
+ }],
36150
+ "pipelineAnalytics.listTracks": [{
36151
+ name: "deviceId",
36152
+ form: "single",
36153
+ optional: false
36154
+ }],
36155
+ "pipelineAnalytics.proposeRetrainAnnotations": [{
36156
+ name: "deviceId",
36157
+ form: "single",
36158
+ optional: false
36159
+ }],
36160
+ "pipelineAnalytics.pruneEventsBefore": [{
36161
+ name: "deviceId",
36162
+ form: "single",
36163
+ optional: false
36164
+ }],
36165
+ "pipelineAnalytics.pruneTracksBefore": [{
36166
+ name: "deviceId",
36167
+ form: "single",
36168
+ optional: false
36169
+ }],
36170
+ "pipelineAnalytics.rebuildObjectEmbeddings": [{
36171
+ name: "deviceId",
36172
+ form: "single",
36173
+ optional: true
36174
+ }],
36175
+ "pipelineAnalytics.restageRetrainTrack": [{
36176
+ name: "deviceId",
36177
+ form: "single",
36178
+ optional: false
36179
+ }],
36180
+ "pipelineAnalytics.saveRetrainAnnotations": [{
36181
+ name: "deviceId",
36182
+ form: "single",
36183
+ optional: false
36184
+ }],
36185
+ "pipelineAnalytics.searchObjectEvents": [{
36186
+ name: "deviceId",
36187
+ form: "single",
36188
+ optional: true
36189
+ }],
36190
+ "pipelineAnalytics.selectRetrainFrames": [{
36191
+ name: "deviceId",
36192
+ form: "single",
36193
+ optional: false
36194
+ }],
36195
+ "pipelineAnalytics.setTrackFlags": [{
36196
+ name: "deviceId",
36197
+ form: "single",
36198
+ optional: false
36199
+ }],
36200
+ "pipelineAnalytics.wipeAllAnalytics": [{
36201
+ name: "deviceId",
36202
+ form: "single",
36203
+ optional: false
36204
+ }],
36205
+ "pipelineExecutor.runPipeline": [{
36206
+ name: "deviceId",
36207
+ form: "single",
36208
+ optional: true
36209
+ }],
36210
+ "pipelineExecutor.runPipelineBatch": [{
36211
+ name: "deviceId",
36212
+ form: "single",
36213
+ optional: true
36214
+ }],
36215
+ "pipelineOrchestrator.assignAudio": [{
36216
+ name: "deviceId",
36217
+ form: "single",
36218
+ optional: false
36219
+ }],
36220
+ "pipelineOrchestrator.assignPipeline": [{
36221
+ name: "deviceId",
36222
+ form: "single",
36223
+ optional: false
36224
+ }],
36225
+ "pipelineOrchestrator.getAudioAssignment": [{
36226
+ name: "deviceId",
36227
+ form: "single",
36228
+ optional: false
36229
+ }],
36230
+ "pipelineOrchestrator.getCameraMetrics": [{
36231
+ name: "deviceId",
36232
+ form: "single",
36233
+ optional: false
36234
+ }],
36235
+ "pipelineOrchestrator.getCameraSettings": [{
36236
+ name: "deviceId",
36237
+ form: "single",
36238
+ optional: false
36239
+ }],
36240
+ "pipelineOrchestrator.getCameraStatus": [{
36241
+ name: "deviceId",
36242
+ form: "single",
36243
+ optional: false
36244
+ }],
36245
+ "pipelineOrchestrator.getCameraStatuses": [{
36246
+ name: "deviceIds",
36247
+ form: "array",
36248
+ optional: true
36249
+ }],
36250
+ "pipelineOrchestrator.getCameraStepOverrides": [{
36251
+ name: "deviceId",
36252
+ form: "single",
36253
+ optional: false
36254
+ }],
36255
+ "pipelineOrchestrator.getCameraSwitches": [{
36256
+ name: "deviceId",
36257
+ form: "single",
36258
+ optional: false
36259
+ }],
36260
+ "pipelineOrchestrator.getPipelineAssignment": [{
36261
+ name: "deviceId",
36262
+ form: "single",
36263
+ optional: false
36264
+ }],
36265
+ "pipelineOrchestrator.getPipelineDevicePin": [{
36266
+ name: "deviceId",
36267
+ form: "single",
36268
+ optional: false
36269
+ }],
36270
+ "pipelineOrchestrator.resolvePipeline": [{
36271
+ name: "deviceId",
36272
+ form: "single",
36273
+ optional: false
36274
+ }],
36275
+ "pipelineOrchestrator.setCameraPipelineForAgent": [{
36276
+ name: "deviceId",
36277
+ form: "single",
36278
+ optional: false
36279
+ }],
36280
+ "pipelineOrchestrator.setCameraStepOverride": [{
36281
+ name: "deviceId",
36282
+ form: "single",
36283
+ optional: false
36284
+ }],
36285
+ "pipelineOrchestrator.setCameraStepToggle": [{
36286
+ name: "deviceId",
36287
+ form: "single",
36288
+ optional: false
36289
+ }],
36290
+ "pipelineOrchestrator.setCameraSwitch": [{
36291
+ name: "deviceId",
36292
+ form: "single",
36293
+ optional: false
36294
+ }],
36295
+ "pipelineOrchestrator.setPipelineDevicePin": [{
36296
+ name: "deviceId",
36297
+ form: "single",
36298
+ optional: false
36299
+ }],
36300
+ "pipelineOrchestrator.unassignAudio": [{
36301
+ name: "deviceId",
36302
+ form: "single",
36303
+ optional: false
36304
+ }],
36305
+ "pipelineOrchestrator.unassignPipeline": [{
36306
+ name: "deviceId",
36307
+ form: "single",
36308
+ optional: false
36309
+ }],
36310
+ "pipelineRunner.attachCamera": [{
36311
+ name: "deviceId",
36312
+ form: "single",
36313
+ optional: false
36314
+ }],
36315
+ "pipelineRunner.detachCamera": [{
36316
+ name: "deviceId",
36317
+ form: "single",
36318
+ optional: false
36319
+ }],
36320
+ "pipelineRunner.getCameraMetrics": [{
36321
+ name: "deviceId",
36322
+ form: "single",
36323
+ optional: false
36324
+ }],
36325
+ "pipelineRunner.reportMotion": [{
36326
+ name: "deviceId",
36327
+ form: "single",
36328
+ optional: false
36329
+ }],
36330
+ "pipelineRunner.runDetailSubtree": [{
36331
+ name: "deviceId",
36332
+ form: "single",
36333
+ optional: false
36334
+ }],
36335
+ "pipelineRunner.runStatelessStep": [{
36336
+ name: "sourceDeviceId",
36337
+ form: "single",
36338
+ optional: false
36339
+ }],
36340
+ "plateGallery.getPlateByTrack": [{
36341
+ name: "deviceId",
36342
+ form: "single",
36343
+ optional: false
36344
+ }],
36345
+ "plateGallery.listPlates": [{
36346
+ name: "deviceId",
36347
+ form: "single",
36348
+ optional: true
36349
+ }],
36350
+ "privacyMask.getOptions": [{
36351
+ name: "deviceId",
36352
+ form: "single",
36353
+ optional: false
36354
+ }],
36355
+ "privacyMask.setAudioEnabled": [{
36356
+ name: "deviceId",
36357
+ form: "single",
36358
+ optional: false
36359
+ }],
36360
+ "privacyMask.setMask": [{
36361
+ name: "deviceId",
36362
+ form: "single",
36363
+ optional: false
36364
+ }],
36365
+ "ptz.continuousMove": [{
36366
+ name: "deviceId",
36367
+ form: "single",
36368
+ optional: false
36369
+ }],
36370
+ "ptz.deletePreset": [{
36371
+ name: "deviceId",
36372
+ form: "single",
36373
+ optional: false
36374
+ }],
36375
+ "ptz.getOptions": [{
36376
+ name: "deviceId",
36377
+ form: "single",
36378
+ optional: false
36379
+ }],
36380
+ "ptz.getPosition": [{
36381
+ name: "deviceId",
36382
+ form: "single",
36383
+ optional: false
36384
+ }],
36385
+ "ptz.getPresets": [{
36386
+ name: "deviceId",
36387
+ form: "single",
36388
+ optional: false
36389
+ }],
36390
+ "ptz.goHome": [{
36391
+ name: "deviceId",
36392
+ form: "single",
36393
+ optional: false
36394
+ }],
36395
+ "ptz.goToPreset": [{
36396
+ name: "deviceId",
36397
+ form: "single",
36398
+ optional: false
36399
+ }],
36400
+ "ptz.move": [{
36401
+ name: "deviceId",
36402
+ form: "single",
36403
+ optional: false
36404
+ }],
36405
+ "ptz.savePreset": [{
36406
+ name: "deviceId",
36407
+ form: "single",
36408
+ optional: false
36409
+ }],
36410
+ "ptz.setAutofocus": [{
36411
+ name: "deviceId",
36412
+ form: "single",
36413
+ optional: false
36414
+ }],
36415
+ "ptz.stop": [{
36416
+ name: "deviceId",
36417
+ form: "single",
36418
+ optional: false
36419
+ }],
36420
+ "ptzAutotrack.getSettings": [{
36421
+ name: "deviceId",
36422
+ form: "single",
36423
+ optional: false
36424
+ }],
36425
+ "ptzAutotrack.getStatus": [{
36426
+ name: "deviceId",
36427
+ form: "single",
36428
+ optional: false
36429
+ }],
36430
+ "ptzAutotrack.setEnabled": [{
36431
+ name: "deviceId",
36432
+ form: "single",
36433
+ optional: false
36434
+ }],
36435
+ "ptzAutotrack.setSettings": [{
36436
+ name: "deviceId",
36437
+ form: "single",
36438
+ optional: false
36439
+ }],
36440
+ "reboot.reboot": [{
36441
+ name: "deviceId",
36442
+ form: "single",
36443
+ optional: false
36444
+ }],
36445
+ "recording.deleteFootprint": [{
36446
+ name: "deviceId",
36447
+ form: "single",
36448
+ optional: false
36449
+ }],
36450
+ "recording.getAvailability": [{
36451
+ name: "deviceId",
36452
+ form: "single",
36453
+ optional: false
36454
+ }],
36455
+ "recording.getDaysWithRecordings": [{
36456
+ name: "deviceId",
36457
+ form: "single",
36458
+ optional: false
36459
+ }],
36460
+ "recording.getDeviceConfig": [{
36461
+ name: "deviceId",
36462
+ form: "single",
36463
+ optional: false
36464
+ }],
36465
+ "recording.getPlaybackManifest": [{
36466
+ name: "deviceId",
36467
+ form: "single",
36468
+ optional: false
36469
+ }],
36470
+ "recording.listOpsLog": [{
36471
+ name: "deviceId",
36472
+ form: "single",
36473
+ optional: true
36474
+ }],
36475
+ "recording.locateSegment": [{
36476
+ name: "deviceId",
36477
+ form: "single",
36478
+ optional: false
36479
+ }],
36480
+ "recording.pruneFootage": [{
36481
+ name: "deviceId",
36482
+ form: "single",
36483
+ optional: false
36484
+ }],
36485
+ "recording.readGopBytes": [{
36486
+ name: "deviceId",
36487
+ form: "single",
36488
+ optional: false
36489
+ }],
36490
+ "recording.readSegmentBytes": [{
36491
+ name: "deviceId",
36492
+ form: "single",
36493
+ optional: false
36494
+ }],
36495
+ "recording.relocateFootage": [{
36496
+ name: "deviceId",
36497
+ form: "single",
36498
+ optional: true
36499
+ }],
36500
+ "recording.renderClip": [{
36501
+ name: "deviceId",
36502
+ form: "single",
36503
+ optional: false
36504
+ }],
36505
+ "recording.renderGif": [{
36506
+ name: "deviceId",
36507
+ form: "single",
36508
+ optional: false
36509
+ }],
36510
+ "recording.rescanStorage": [{
36511
+ name: "deviceId",
36512
+ form: "single",
36513
+ optional: false
36514
+ }],
36515
+ "recording.setDeviceConfig": [{
36516
+ name: "deviceId",
36517
+ form: "single",
36518
+ optional: false
36519
+ }],
36520
+ "recording.startStorageMigrationMove": [{
36521
+ name: "deviceId",
36522
+ form: "single",
36523
+ optional: true
36524
+ }],
36525
+ "recordingExport.createExport": [{
36526
+ name: "deviceId",
36527
+ form: "single",
36528
+ optional: false
36529
+ }],
36530
+ "recordingExport.listExports": [{
36531
+ name: "deviceId",
36532
+ form: "single",
36533
+ optional: true
36534
+ }],
36535
+ "sceneMonitor.captureReference": [{
36536
+ name: "deviceId",
36537
+ form: "single",
36538
+ optional: false
36539
+ }],
36540
+ "sceneMonitor.createScene": [{
36541
+ name: "deviceId",
36542
+ form: "single",
36543
+ optional: false
36544
+ }],
36545
+ "sceneMonitor.deleteReference": [{
36546
+ name: "deviceId",
36547
+ form: "single",
36548
+ optional: false
36549
+ }],
36550
+ "sceneMonitor.deleteScene": [{
36551
+ name: "deviceId",
36552
+ form: "single",
36553
+ optional: false
36554
+ }],
36555
+ "sceneMonitor.listScenes": [{
36556
+ name: "deviceId",
36557
+ form: "single",
36558
+ optional: false
36559
+ }],
36560
+ "sceneMonitor.recheckNow": [{
36561
+ name: "deviceId",
36562
+ form: "single",
36563
+ optional: false
36564
+ }],
36565
+ "sceneMonitor.resetScene": [{
36566
+ name: "deviceId",
36567
+ form: "single",
36568
+ optional: false
36569
+ }],
36570
+ "sceneMonitor.updateScene": [{
36571
+ name: "deviceId",
36572
+ form: "single",
36573
+ optional: false
36574
+ }],
36575
+ "scriptRunner.run": [{
36576
+ name: "deviceId",
36577
+ form: "single",
36578
+ optional: false
36579
+ }],
36580
+ "scriptRunner.stop": [{
36581
+ name: "deviceId",
36582
+ form: "single",
36583
+ optional: false
36584
+ }],
36585
+ "snapshot.getSnapshot": [{
36586
+ name: "deviceId",
36587
+ form: "single",
36588
+ optional: false
36589
+ }],
36590
+ "snapshot.getSnapshotOverview": [{
36591
+ name: "deviceIds",
36592
+ form: "array",
36593
+ optional: false
36594
+ }],
36595
+ "snapshot.invalidateCache": [{
36596
+ name: "deviceId",
36597
+ form: "single",
36598
+ optional: false
36599
+ }],
36600
+ "streamBroker.acquireEgressTranscode": [{
36601
+ name: "deviceId",
36602
+ form: "single",
36603
+ optional: false
36604
+ }],
36605
+ "streamBroker.assignProfile": [{
36606
+ name: "deviceId",
36607
+ form: "single",
36608
+ optional: false
36609
+ }],
36610
+ "streamBroker.getDeviceAudioMute": [{
36611
+ name: "deviceId",
36612
+ form: "single",
36613
+ optional: false
36614
+ }],
36615
+ "streamBroker.getStreamWithCodec": [{
36616
+ name: "deviceId",
36617
+ form: "single",
36618
+ optional: false
36619
+ }],
36620
+ "streamBroker.produceEventMedia": [{
36621
+ name: "deviceId",
36622
+ form: "single",
36623
+ optional: false
36624
+ }],
36625
+ "streamBroker.publishCameraStream": [{
36626
+ name: "deviceId",
36627
+ form: "single",
36628
+ optional: false
36629
+ }],
36630
+ "streamBroker.renderPreBufferClip": [{
36631
+ name: "deviceId",
36632
+ form: "single",
36633
+ optional: false
36634
+ }],
36635
+ "streamBroker.restartProfile": [{
36636
+ name: "deviceId",
36637
+ form: "single",
36638
+ optional: false
36639
+ }],
36640
+ "streamBroker.retractCameraStream": [{
36641
+ name: "deviceId",
36642
+ form: "single",
36643
+ optional: false
36644
+ }],
36645
+ "streamBroker.setDeviceAudioMute": [{
36646
+ name: "deviceId",
36647
+ form: "single",
36648
+ optional: false
36649
+ }],
36650
+ "streamBroker.unassignProfile": [{
36651
+ name: "deviceId",
36652
+ form: "single",
36653
+ optional: false
36654
+ }],
36655
+ "streamCatalog.getCatalog": [{
36656
+ name: "deviceId",
36657
+ form: "single",
36658
+ optional: false
36659
+ }],
36660
+ "streamParams.getConfigSchema": [{
36661
+ name: "deviceId",
36662
+ form: "single",
36663
+ optional: false
36664
+ }],
36665
+ "streamParams.getOptions": [{
36666
+ name: "deviceId",
36667
+ form: "single",
36668
+ optional: false
36669
+ }],
36670
+ "streamParams.setProfile": [{
36671
+ name: "deviceId",
36672
+ form: "single",
36673
+ optional: false
36674
+ }],
36675
+ "switch.setState": [{
36676
+ name: "deviceId",
36677
+ form: "single",
36678
+ optional: false
36679
+ }],
36680
+ "vacuumControl.locate": [{
36681
+ name: "deviceId",
36682
+ form: "single",
36683
+ optional: false
36684
+ }],
36685
+ "vacuumControl.pause": [{
36686
+ name: "deviceId",
36687
+ form: "single",
36688
+ optional: false
36689
+ }],
36690
+ "vacuumControl.returnToBase": [{
36691
+ name: "deviceId",
36692
+ form: "single",
36693
+ optional: false
36694
+ }],
36695
+ "vacuumControl.setFanSpeed": [{
36696
+ name: "deviceId",
36697
+ form: "single",
36698
+ optional: false
36699
+ }],
36700
+ "vacuumControl.start": [{
36701
+ name: "deviceId",
36702
+ form: "single",
36703
+ optional: false
36704
+ }],
36705
+ "vacuumControl.stop": [{
36706
+ name: "deviceId",
36707
+ form: "single",
36708
+ optional: false
36709
+ }],
36710
+ "valve.close": [{
36711
+ name: "deviceId",
36712
+ form: "single",
36713
+ optional: false
36714
+ }],
36715
+ "valve.open": [{
36716
+ name: "deviceId",
36717
+ form: "single",
36718
+ optional: false
36719
+ }],
36720
+ "valve.setPosition": [{
36721
+ name: "deviceId",
36722
+ form: "single",
36723
+ optional: false
36724
+ }],
36725
+ "valve.stop": [{
36726
+ name: "deviceId",
36727
+ form: "single",
36728
+ optional: false
36729
+ }],
36730
+ "videoclips.getClipPlayback": [{
36731
+ name: "deviceId",
36732
+ form: "single",
36733
+ optional: false
36734
+ }],
36735
+ "videoclips.listClips": [{
36736
+ name: "deviceId",
36737
+ form: "single",
36738
+ optional: false
36739
+ }],
36740
+ "waterHeater.setAway": [{
36741
+ name: "deviceId",
36742
+ form: "single",
36743
+ optional: false
36744
+ }],
36745
+ "waterHeater.setOperationMode": [{
36746
+ name: "deviceId",
36747
+ form: "single",
36748
+ optional: false
36749
+ }],
36750
+ "waterHeater.setTargetTemp": [{
36751
+ name: "deviceId",
36752
+ form: "single",
36753
+ optional: false
36754
+ }],
36755
+ "webrtcSession.addIceCandidate": [{
36756
+ name: "deviceId",
36757
+ form: "single",
36758
+ optional: false
36759
+ }],
36760
+ "webrtcSession.closeSession": [{
36761
+ name: "deviceId",
36762
+ form: "single",
36763
+ optional: false
36764
+ }],
36765
+ "webrtcSession.createSession": [{
36766
+ name: "deviceId",
36767
+ form: "single",
36768
+ optional: false
36769
+ }],
36770
+ "webrtcSession.getIceCandidates": [{
36771
+ name: "deviceId",
36772
+ form: "single",
36773
+ optional: false
36774
+ }],
36775
+ "webrtcSession.getSessionState": [{
36776
+ name: "deviceId",
36777
+ form: "single",
36778
+ optional: false
36779
+ }],
36780
+ "webrtcSession.handleAnswer": [{
36781
+ name: "deviceId",
36782
+ form: "single",
36783
+ optional: false
36784
+ }],
36785
+ "webrtcSession.handleOffer": [{
36786
+ name: "deviceId",
36787
+ form: "single",
36788
+ optional: false
36789
+ }],
36790
+ "webrtcSession.hasAdaptiveBitrate": [{
36791
+ name: "deviceId",
36792
+ form: "single",
36793
+ optional: false
36794
+ }],
36795
+ "webrtcSession.listStreams": [{
36796
+ name: "deviceId",
36797
+ form: "single",
36798
+ optional: false
36799
+ }],
36800
+ "zoneAnalytics.getCameraHistory": [{
36801
+ name: "deviceId",
36802
+ form: "single",
36803
+ optional: false
36804
+ }],
36805
+ "zoneAnalytics.getCurrentSnapshot": [{
36806
+ name: "deviceId",
36807
+ form: "single",
36808
+ optional: false
36809
+ }],
36810
+ "zoneAnalytics.getUnzonedHistory": [{
36811
+ name: "deviceId",
36812
+ form: "single",
36813
+ optional: false
36814
+ }],
36815
+ "zoneAnalytics.getZoneHistory": [{
36816
+ name: "deviceId",
36817
+ form: "single",
36818
+ optional: false
36819
+ }],
36820
+ "zoneRules.listRules": [{
36821
+ name: "deviceId",
36822
+ form: "single",
36823
+ optional: false
36824
+ }],
36825
+ "zoneRules.setRules": [{
36826
+ name: "deviceId",
36827
+ form: "single",
36828
+ optional: false
36829
+ }],
36830
+ "zones.addZone": [{
36831
+ name: "deviceId",
36832
+ form: "single",
36833
+ optional: false
36834
+ }],
36835
+ "zones.listZones": [{
36836
+ name: "deviceId",
36837
+ form: "single",
36838
+ optional: false
36839
+ }],
36840
+ "zones.removeZone": [{
36841
+ name: "deviceId",
36842
+ form: "single",
36843
+ optional: false
36844
+ }],
36845
+ "zones.updateZone": [{
36846
+ name: "deviceId",
36847
+ form: "single",
36848
+ optional: false
36849
+ }]
36850
+ });
34511
36851
  Object.freeze({
34512
36852
  "broker": "broker",
34513
36853
  "device-export": "device-export",
@@ -35146,4 +37486,4 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
35146
37486
  return best;
35147
37487
  }
35148
37488
  //#endregion
35149
- export { tamperCapability as $, eventEmitterCapability as A, motionCapability as B, connectivityCapability as C, url as Ct, deviceAdoptionCapability as D, coverCapability as E, humiditySensorCapability as F, oauthIntegrationCapability as G, notificationOutputCapability as H, imageCapability as I, presenceCapability as J, powerMeterCapability as K, lawnMowerControlCapability as L, floodCapability as M, gasCapability as N, deviceExportCapability as O, humidifierCapability as P, switchCapability as Q, lockControlCapability as R, colorCapability as S, unknown as St, controlCapability as T, notifierCapability as U, normalizeUnit as V, numericSensorCapability as W, scriptRunnerCapability as X, pressureSensorCapability as Y, smokeCapability as Z, brokerCapability as _, number as _t, EnumSensorDateTimeFormatSchema as a, waterHeaterCapability as at, carbonMonoxideCapability as b, string as bt, addonRoutesCapability as c, BaseAddon as ct, ambientLightSensorCapability as d, DeviceType as dt, temperatureSensorCapability as et, automationControlCapability as f, createEvent as ft, brightnessCapability as g, literal as gt, binaryCapability as h, discriminatedUnion as ht, CameraSwitchIdSchema as i, vibrationCapability as it, fanControlCapability as j, enumSensorCapability as k, airQualitySensorCapability as l, DeviceFeature as lt, bestLocationMatch as m, array as mt, BaseDeviceProvider as n, vacuumControlCapability as nt, TargetSchema as o, weatherCapability as ot, batteryCapability as p, _enum as pt, prepareNotification as q, COCO_TO_MACRO as r, valveCapability as rt, accessoriesCapability as s, errMsg as st, BaseDevice as t, updateCapability as tt, alarmPanelCapability as u, DeviceRole as ut, buildAddonRouteProvider as v, object as vt, contactCapability as w, EventCategory as wt, climateControlCapability as x, union as xt, buttonCapability as y, record as yt, mediaPlayerCapability as z };
37489
+ export { pressureSensorCapability as $, coverCapability as A, imageCapability as B, buttonCapability as C, record as Ct, connectivityCapability as D, url as Dt, colorCapability as E, unknown as Et, fanControlCapability as F, normalizeUnit as G, lockControlCapability as H, floodCapability as I, numericSensorCapability as J, notificationOutputCapability as K, gasCapability as L, deviceExportCapability as M, enumSensorCapability as N, contactCapability as O, EventCategory as Ot, eventEmitterCapability as P, presenceCapability as Q, humidifierCapability as R, buildAddonRouteProvider as S, object as St, climateControlCapability as T, union as Tt, mediaPlayerCapability as U, lawnMowerControlCapability as V, motionCapability as W, powerMeterCapability as X, oauthIntegrationCapability as Y, prepareNotification as Z, batteryCapability as _, _enum as _t, CameraSwitchIdSchema as a, updateCapability as at, brightnessCapability as b, literal as bt, HvacModeSchema as c, vibrationCapability as ct, accessoriesCapability as d, errMsg as dt, scriptRunnerCapability as et, addonRoutesCapability as f, BaseAddon as ft, automationControlCapability as g, createEvent as gt, ambientLightSensorCapability as h, DeviceType as ht, COCO_TO_MACRO as i, temperatureSensorCapability as it, deviceAdoptionCapability as j, controlCapability as k, MediaPlayerRepeatSchema as l, waterHeaterCapability as lt, alarmPanelCapability as m, DeviceRole as mt, BaseDevice as n, switchCapability as nt, EnumSensorDateTimeFormatSchema as o, vacuumControlCapability as ot, airQualitySensorCapability as p, DeviceFeature as pt, notifierCapability as q, BaseDeviceProvider as r, tamperCapability as rt, FanDirectionSchema as s, valveCapability as st, AlarmArmModeSchema as t, smokeCapability as tt, TargetSchema as u, weatherCapability as ut, bestLocationMatch as v, array as vt, carbonMonoxideCapability as w, string as wt, brokerCapability as x, number as xt, binaryCapability as y, discriminatedUnion as yt, humiditySensorCapability as z };