@camstack/addon-provider-wyze 0.2.122 → 0.2.124

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/addon.js +697 -158
  2. package/dist/addon.mjs +697 -158
  3. package/package.json +1 -3
package/dist/addon.js CHANGED
@@ -7454,7 +7454,7 @@ function errMsg(err) {
7454
7454
  return String(err);
7455
7455
  }
7456
7456
  //#endregion
7457
- //#region ../types/dist/composition-43aqsZQj.mjs
7457
+ //#region ../types/dist/composition-Bzr7GwgP.mjs
7458
7458
  /**
7459
7459
  * The ffmpeg build every CamStack node downloads, per platform and arch.
7460
7460
  *
@@ -7508,20 +7508,20 @@ function portable(target) {
7508
7508
  }
7509
7509
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7510
7510
  /**
7511
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7512
- * valutatore puro del suo FRONTE.
7511
+ * THE table "which boolean of this device type counts as HIGH", and the
7512
+ * pure evaluator of its EDGE.
7513
7513
  *
7514
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7515
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7516
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7517
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7518
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7519
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7514
+ * ONE table for everyone who asks "is this device HIGH?": the
7515
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7516
+ * sensor markers, the orchestrator's camera-sensors bridge and
7517
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7518
+ * A second copy would diverge at the first cap added, and the symptom — "the
7519
+ * sensor rings the doorbell but does not record" — is exactly D62.
7520
7520
  *
7521
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7522
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7523
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7524
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7521
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7522
+ * two must not be unified: that one answers "what is the state WORD for a
7523
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7524
+ * boolean's EDGE counts". Deliberately different vocabularies.
7525
7525
  */
7526
7526
  /**
7527
7527
  * Known binary / switch source caps → the boolean slice field whose
@@ -7542,6 +7542,8 @@ var SOURCE_CAP_ACTIVE_FIELD = {
7542
7542
  vibration: "detected",
7543
7543
  tamper: "tampered"
7544
7544
  };
7545
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7546
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7545
7547
  /**
7546
7548
  * Error types for the safe expression engine. Two distinct classes so callers
7547
7549
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
@@ -9148,22 +9150,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9148
9150
  "package"
9149
9151
  ];
9150
9152
  /**
9151
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9152
- * un operatore può selezionare.
9153
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9154
+ * an operator can select.
9153
9155
  *
9154
- * Sono le tre offerte dallo step `object-detection`
9156
+ * They are the three offered by the `object-detection` step
9155
9157
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9156
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9157
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9158
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9159
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9158
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9159
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9160
+ * `package-detection`, whose enablement is driven by zones, and offering the
9161
+ * same word twice has already made an operator turn on the COCO proxy
9160
9162
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9161
9163
  *
9162
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9163
- * dello step e una seconda volta come union `FirstLevelMacro`
9164
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9165
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9166
- * successiva.
9164
+ * ONE list. Before today the same three were hand-written in the step's offer
9165
+ * and a second time as the union `FirstLevelMacro`
9166
+ * (`types/detection.ts`); a third copy for the recording trigger
9167
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9168
+ * invisible.
9167
9169
  */
9168
9170
  var FIRST_LEVEL_MACRO_CLASSES = [
9169
9171
  "person",
@@ -9228,17 +9230,17 @@ var RecordingStorageModeSchema = _enum([
9228
9230
  "on-device-decision"
9229
9231
  ]);
9230
9232
  /**
9231
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9232
- * tre offerte dallo step `object-detection`, da UNA lista
9233
+ * The macro classes that can open a recording window — the same
9234
+ * three offered by the `object-detection` step, from ONE list
9233
9235
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9234
9236
  */
9235
9237
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9236
9238
  /**
9237
- * True quando `values` non ripete un elemento.
9239
+ * True when `values` does not repeat an element.
9238
9240
  *
9239
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9240
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9241
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9241
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9242
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9243
+ * would count its windows twice in `segmentMissedByMs`.
9242
9244
  */
9243
9245
  var noDuplicates = (values) => new Set(values).size === values.length;
9244
9246
  /** Which detectors trigger an `events`-mode band. */
@@ -9246,34 +9248,34 @@ var RecordingTriggersSchema = object({
9246
9248
  motion: boolean().optional(),
9247
9249
  audioThresholdDbfs: number().optional(),
9248
9250
  /**
9249
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9250
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9251
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9252
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9251
+ * The macro classes whose detection opens a window. ABSENT = the source
9252
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9253
+ * trigger on, no class" is the same shape "enabled and records
9254
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9253
9255
  *
9254
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9255
- * quelle che hanno attraversato `enabledMacroClasses`, i
9256
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9257
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9258
- * finestre — vedi `recorder/object-trigger.ts`.
9256
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9257
+ * those that went through `enabledMacroClasses`, the
9258
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9259
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9260
+ * windows — see `recorder/object-trigger.ts`.
9259
9261
  */
9260
9262
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9261
9263
  /**
9262
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9263
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9264
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9265
+ * is not listened to; an empty array is rejected for the same reason as
9264
9266
  * `objectClasses`.
9265
9267
  *
9266
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9267
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9268
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9269
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9270
- * device (D12) — mai un elenco globale di cap.
9268
+ * These are SOURCE device ids, not cameras: the band names them, so the
9269
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9270
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9271
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9272
+ * device (D12) — never a global list of caps.
9271
9273
  *
9272
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9273
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9274
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9275
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9276
- * registrare.
9274
+ * What "high" means depends on the device TYPE and is not decided here:
9275
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9276
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9277
+ * the level: a contact found already open at runner restart does not
9278
+ * record.
9277
9279
  */
9278
9280
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9279
9281
  });
@@ -10350,7 +10352,7 @@ var DecoderSessionConfigSchema = object({
10350
10352
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
10351
10353
  * thing: the logging settings document on the `system` cap. Two authorities
10352
10354
  * over the values is the exact defect
10353
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
10355
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
10354
10356
  * remove; re-introducing it from the cure side would be grotesque.
10355
10357
  *
10356
10358
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -12061,7 +12063,7 @@ var BrokerStatusEnum = _enum([
12061
12063
  "unreachable",
12062
12064
  "error"
12063
12065
  ]);
12064
- var BrokerInfoSchema$1 = object({
12066
+ var BrokerInfoSchema = object({
12065
12067
  /** Stable broker id. Persisted; survives addon restarts. */
12066
12068
  id: string(),
12067
12069
  /** Addon id of the provider that OWNS this broker.
@@ -12194,7 +12196,7 @@ var GetStateInputSchema = object({
12194
12196
  * HA: entity_id (returns the cached entity state). */
12195
12197
  key: string()
12196
12198
  });
12197
- method(ListInputSchema, array(BrokerInfoSchema$1)), method(GetInputSchema, BrokerInfoSchema$1.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12199
+ method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12198
12200
  kind: "mutation",
12199
12201
  auth: "admin"
12200
12202
  }), method(RemoveInputSchema, _void(), {
@@ -13905,7 +13907,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
13905
13907
  *
13906
13908
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
13907
13909
  * was wrong — corrected 2026-08-26 after the hop map
13908
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
13910
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
13909
13911
  * There is **no Zod parse at all** between the door and the engine: the
13910
13912
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
13911
13913
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -14785,7 +14787,17 @@ var SiteZoneSchema = object({
14785
14787
  var ProviderStatusSchema = object({
14786
14788
  connected: boolean(),
14787
14789
  deviceCount: number(),
14788
- error: string().optional()
14790
+ error: string().optional(),
14791
+ /**
14792
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
14793
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
14794
+ * which every provider bundles, so only a provider BUILT from D696-amended
14795
+ * code says it. ABSENT means an older provider that may still write it (raw
14796
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
14797
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
14798
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
14799
+ */
14800
+ motionSliceWriter: literal("orchestrator").optional()
14789
14801
  });
14790
14802
  object({
14791
14803
  externalId: string(),
@@ -16002,7 +16014,7 @@ method(object({
16002
16014
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
16003
16015
  * ends in a log line, and a log line is the thing the operator asked to stop
16004
16016
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
16005
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
16017
+ * ricontrolliamo tutti questi punti"* [can we instrument these errors in the meantime? That way next round we recheck all these points]. Reading them meant grepping Loki and
16006
16018
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
16007
16019
  * media blackout were both diagnosed. The counters stay; this is where they can
16008
16020
  * be READ.
@@ -17378,7 +17390,7 @@ var BrokerStatusSchema$1 = _enum([
17378
17390
  "unreachable",
17379
17391
  "tls-error"
17380
17392
  ]);
17381
- var BrokerInfoSchema = object({
17393
+ var BrokerInfoSchema$1 = object({
17382
17394
  id: string(),
17383
17395
  name: string(),
17384
17396
  url: string(),
@@ -17441,7 +17453,7 @@ var StatusSchema = object({
17441
17453
  brokerCount: number(),
17442
17454
  embeddedRunning: boolean()
17443
17455
  });
17444
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17456
+ method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17445
17457
  kind: "mutation",
17446
17458
  auth: "admin"
17447
17459
  }), method(IdInputSchema, _void(), {
@@ -19655,78 +19667,16 @@ var NcRuleInputSchema = object({
19655
19667
  */
19656
19668
  confirm: NcConfirmSchema.optional(),
19657
19669
  /**
19658
- * WAIT for face/plate recognition before saying anything.
19659
- *
19660
- * A notification's TEXT is frozen at enqueue and its media is re-resolved at
19661
- * send; the identity is neither. A face is confirmed after `confirmFrames`
19662
- * agreeing observations — p50 **11.4 s** after the track was first seen,
19663
- * measured on this hub — and an `immediate` rule enqueues on the first object
19664
- * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
19665
- * immediate path, and no amount of media re-resolution fixes a sentence.
19666
- *
19667
- * Only two honest answers exist, and this flag picks between them. It has
19668
- * effect ONLY on a rule that declares a recognition scope
19669
- * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
19670
- * other rule there is nothing to wait for and the flag is inert.
19671
- *
19672
- * | value | what happens |
19673
- * | --- | --- |
19674
- * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
19675
- * | 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) |
19676
- *
19677
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19678
- * on the addon cap path, and absent has to keep meaning exactly what every
19679
- * rule authored before this field meant.
19680
- *
19681
- * The cost of `true` is stated here because the editor states it too: a rule
19682
- * that waits also inherits track-close SEMANTICS — its `zones` condition
19683
- * tests every zone the track visited and a `crossing` condition can no longer
19684
- * be satisfied, because a closed track carries no crossing.
19685
- */
19686
- waitForEnhancement: boolean().optional(),
19687
- /**
19688
- * GROUP a burst of subjects into ONE notification that grows.
19689
- *
19690
- * Seconds of quiet after the last matching subject before the burst is
19691
- * considered over. While it is open, the first subject enqueues immediately —
19692
- * **exactly as today, with no added latency** — and every real growth (a new
19693
- * subject, or a name confirmed on one already in it) REPLACES that
19694
- * notification with an updated one naming everybody. The push carries the
19695
- * group's own coalescing tag, so the phone replaces rather than stacks.
19696
- *
19697
- * `0` / absent = off, and off is today's behaviour byte for byte.
19698
- *
19699
- * ### Why an idle cutoff and not a window
19700
- *
19701
- * The measured seven-person arrival on device 590 spans 110 s with every
19702
- * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
19703
- * idle cutoff holds it as one and ends it when the arrival actually ends.
19704
- * 30 s is a widely shipped value for the same decision.
19705
- *
19706
- * ### What it replaces
19707
- *
19708
- * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
19709
- * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
19710
- * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
19711
- * track that did fire and 7 carrying a confirmed identity nobody heard about.
19712
- * A group collapses the same volume by MERGING, so the cooldown becomes a
19713
- * budget over GROUPS — which is what it always meant — and a growth is never
19714
- * throttled by the window its own first member spent.
19715
- *
19716
- * ### Interaction with {@link waitForEnhancement}
19717
- *
19718
- * They compose, and the order matters. `waitForEnhancement` defers the rule to
19719
- * TRACK CLOSE, so with both set the group is opened by the first member to
19720
- * CLOSE — already carrying its name — and grows as later members close. That
19721
- * is later, and complete. With grouping alone the group opens on the first
19722
- * object event and picks up names as they are confirmed, through the growth
19723
- * path. Neither combination fires twice for one subject.
19724
- *
19725
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19726
- * on the addon cap path, so absent must keep meaning what it meant before this
19727
- * field existed.
19670
+ * IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
19671
+ * seconds; the rule sends ONE message when the window closes — early, once every
19672
+ * subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
19673
+ * the rule matched, with one mosaic tile per subject.
19674
+ * Absent = plain immediate (one message per track, at the first match).
19675
+ * Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
19676
+ * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
19677
+ * path does not run Zod defaults.
19728
19678
  */
19729
- groupIdleSec: number().int().min(0).max(600).optional()
19679
+ groupingSec: number().int().min(5).max(60).optional()
19730
19680
  });
19731
19681
  /**
19732
19682
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -19774,9 +19724,10 @@ var NcRuleClearableKeySchema = _enum([
19774
19724
  "targetUsers",
19775
19725
  "snoozeOptions",
19776
19726
  "snoozeAllowGlobal",
19777
- "waitForEnhancement",
19778
19727
  "actions",
19779
19728
  "confirm",
19729
+ "groupingSec",
19730
+ "waitForEnhancement",
19780
19731
  "groupIdleSec"
19781
19732
  ]);
19782
19733
  var NcRuleUpdateInputSchema = object({
@@ -19798,9 +19749,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19798
19749
  */
19799
19750
  disabledTargetIds: array(string()).default([])
19800
19751
  });
19752
+ /**
19753
+ * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19754
+ * still-true state. `backups-exports` and `alarm` are not sections — a completed
19755
+ * job is not an open state, and the alarm stays instant.
19756
+ */
19757
+ var NcStateSummarySectionIdSchema = _enum([
19758
+ "device-state",
19759
+ "streams",
19760
+ "battery",
19761
+ "consumables",
19762
+ "tanks",
19763
+ "detection-blind",
19764
+ "nodes",
19765
+ "addons",
19766
+ "updates"
19767
+ ]);
19801
19768
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
19802
19769
  var NcStateSummaryPreviewSectionSchema = object({
19803
- id: string(),
19770
+ id: NcStateSummarySectionIdSchema,
19804
19771
  status: _enum(["read", "unavailable"]),
19805
19772
  items: number().int().nonnegative(),
19806
19773
  reason: string().optional()
@@ -19810,7 +19777,7 @@ var NcStateSummaryPreviewSectionSchema = object({
19810
19777
  * a `rule` split (no `section`), one section's on a `section` split.
19811
19778
  */
19812
19779
  var NcStateSummaryPreviewRowSchema = object({
19813
- section: string().optional(),
19780
+ section: NcStateSummarySectionIdSchema.optional(),
19814
19781
  /** The section's name on a per-section row; every reported section's, joined, on a combined one. */
19815
19782
  title: string(),
19816
19783
  text: string(),
@@ -20247,6 +20214,29 @@ object({
20247
20214
  firstAt: number(),
20248
20215
  lastAt: number()
20249
20216
  });
20217
+ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20218
+ var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20219
+ var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20220
+ var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20221
+ var NcAlarmModeDelaysListSchema = array(object({
20222
+ mode: AlarmArmModeSchema,
20223
+ exitDelaySec: NcAlarmDelaySecSchema.optional(),
20224
+ entryDelaySec: NcAlarmDelaySecSchema.optional(),
20225
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20226
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20227
+ var NcAlarmModeDelaysEditListSchema = array(object({
20228
+ mode: AlarmArmModeSchema,
20229
+ exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20230
+ entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20231
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20232
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20233
+ /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20234
+ var NcAlarmNonBlockingEditSchema = object({
20235
+ mode: AlarmArmModeSchema,
20236
+ deviceId: number().int().positive(),
20237
+ /** true = on the list (may be open, does not block); false = off the list (blocks). */
20238
+ nonBlocking: boolean()
20239
+ });
20250
20240
  /**
20251
20241
  * The per-mode lists, at most one per mode. Two lists for one mode have no
20252
20242
  * meaning a reader could agree on (union? the last one?), so they are refused
@@ -20255,10 +20245,10 @@ object({
20255
20245
  var NcAlarmNonBlockingListSchema = array(object({
20256
20246
  mode: AlarmArmModeSchema,
20257
20247
  deviceIds: array(number().int()).max(200)
20258
- })).max(8).refine((lists) => new Set(lists.map((l) => l.mode)).size === lists.length, { message: "nonBlocking: at most one list per arm mode" });
20248
+ })).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20259
20249
  /**
20260
- * The three durations the panel's state machine runs on, who hears about its
20261
- * transitions, and which openings each mode tolerates.
20250
+ * The three durations — global, and per mode since D697 — the panel's state
20251
+ * machine runs on, who hears about its transitions, and which openings each mode tolerates.
20262
20252
  *
20263
20253
  * They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
20264
20254
  * `alarm-panel` is `deviceNative` and its other provider mirrors somebody
@@ -20268,15 +20258,15 @@ var NcAlarmNonBlockingListSchema = array(object({
20268
20258
  */
20269
20259
  var NcAlarmSettingsSchema = object({
20270
20260
  /** Grace period between arming and the mode taking effect. 0 = immediate. */
20271
- exitDelaySec: number().int().min(0).max(600),
20261
+ exitDelaySec: NcAlarmDelaySecSchema,
20272
20262
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20273
- entryDelaySec: number().int().min(0).max(600),
20263
+ entryDelaySec: NcAlarmDelaySecSchema,
20274
20264
  /**
20275
20265
  * How long `triggered` lasts before the panel re-arms itself.
20276
20266
  * **0 = until an operator disarms it** — the behaviour before this field
20277
20267
  * existed, and therefore what an untouched install keeps doing.
20278
20268
  */
20279
- triggeredDurationSec: number().int().min(0).max(3600),
20269
+ triggeredDurationSec: NcAlarmTriggeredSecSchema,
20280
20270
  /**
20281
20271
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20282
20272
  * remove after one release. Optional so an older admin's patch (which still
@@ -20299,17 +20289,30 @@ var NcAlarmSettingsSchema = object({
20299
20289
  * per mode is meaningful. Defaulted to `[]` so a blob stored before D630
20300
20290
  * parses as "every opening blocks" — the behaviour it was written under.
20301
20291
  */
20302
- nonBlocking: NcAlarmNonBlockingListSchema.default([])
20292
+ nonBlocking: NcAlarmNonBlockingListSchema.default([]),
20293
+ /**
20294
+ * Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
20295
+ * without a field, uses the global value above — so `[]`, the default, is exactly the
20296
+ * behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
20297
+ */
20298
+ modeDelays: NcAlarmModeDelaysListSchema.default([])
20303
20299
  });
20304
20300
  /**
20305
20301
  * Every field optional — a tab edits one control at a time.
20306
20302
  *
20307
- * `nonBlocking` is re-declared WITHOUT its default: `.partial()` does not
20308
- * remove an inner `.default()`, so a patch that never named the field would
20309
- * parse to `nonBlocking: []` and wipe every mode's list on an unrelated edit
20310
- * (the same trap {@link NcRulePatchSchema} documents).
20303
+ * `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
20304
+ * `.partial()` does not remove an inner `.default()`, so a patch that never
20305
+ * named the field would parse to `[]` and wipe every mode's list on an
20306
+ * unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
20307
+ * `modeDelays` means EDITS, not the stored overrides.
20311
20308
  */
20312
- var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({ nonBlocking: NcAlarmNonBlockingListSchema }).partial();
20309
+ var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
20310
+ nonBlocking: NcAlarmNonBlockingListSchema,
20311
+ /** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
20312
+ modeDelays: NcAlarmModeDelaysEditListSchema,
20313
+ /** ONE membership change; the panel applies it to the list it holds at its turn. */
20314
+ nonBlockingEdit: NcAlarmNonBlockingEditSchema
20315
+ }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
20313
20316
  /**
20314
20317
  * What one arm mode actually arms, DERIVED from the enabled rules gated on it.
20315
20318
  * Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
@@ -20409,6 +20412,28 @@ var NcAlarmConfigSchema = object({
20409
20412
  */
20410
20413
  live: NcAlarmLiveSchema.optional()
20411
20414
  });
20415
+ var NcAlarmSensorReadingSchema = _enum([
20416
+ "open",
20417
+ "closed",
20418
+ "unknown",
20419
+ "not-opening"
20420
+ ]);
20421
+ /** One device's state as the alarm reads it — the classifier the arm check uses. */
20422
+ var NcAlarmSensorStateSchema = object({
20423
+ deviceId: number().int().positive(),
20424
+ reading: NcAlarmSensorReadingSchema,
20425
+ /** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
20426
+ state: string().nullable(),
20427
+ /** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
20428
+ unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
20429
+ /** The device manager's liveness as the centre mirrors it; null = not known. */
20430
+ online: boolean().nullable()
20431
+ });
20432
+ var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
20433
+ var NcAlarmSensorsSchema = object({
20434
+ sensors: array(NcAlarmSensorStateSchema),
20435
+ readAt: number().int().nonnegative()
20436
+ });
20412
20437
  /**
20413
20438
  * ONE rule's demand on ONE camera's clip ring.
20414
20439
  *
@@ -20499,7 +20524,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20499
20524
  }), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
20500
20525
  kind: "mutation",
20501
20526
  auth: "admin"
20502
- });
20527
+ }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
20503
20528
  /**
20504
20529
  * Zod schemas for persisted record types.
20505
20530
  *
@@ -21651,14 +21676,14 @@ var TrackSchema = object({
21651
21676
  * `derive-returned-null tile=standin`,
21652
21677
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
21653
21678
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
21654
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
21679
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
21655
21680
  * tile is a face/plate stand-in, a raster crop, or an icon.
21656
21681
  *
21657
21682
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
21658
21683
  * the TILE ranked below native, so a track whose thumbnail landed natively
21659
21684
  * while its key frame missed carried no reason at all — three of the four
21660
21685
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
21661
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
21686
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
21662
21687
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
21663
21688
  * lastFrame copy source`), so its absence is now on this line whatever the
21664
21689
  * tile ended up being.
@@ -21745,7 +21770,7 @@ var MotionEventSchema = object({
21745
21770
  /**
21746
21771
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
21747
21772
  * first entry is always `0`) of every genuine off→on transition the
21748
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
21773
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
21749
21774
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
21750
21775
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
21751
21776
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -22269,6 +22294,7 @@ var KeyEventSchema = object({
22269
22294
  bestEventId: string(),
22270
22295
  /** Track lifetime in ms (lastSeen - firstSeen). */
22271
22296
  windowMs: number().optional(),
22297
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
22272
22298
  ...TrackFlagFields,
22273
22299
  ...TrackRetrainFields
22274
22300
  });
@@ -27154,7 +27180,7 @@ var ClipPlaybackSchema = object({
27154
27180
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
27155
27181
  * time the camera is awake for its own reasons — is deliberately not a member:
27156
27182
  * it was proposed, it is free on the battery, and the operator declined it on
27157
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
27183
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
27158
27184
  * D558 "Considered and not taken").
27159
27185
  */
27160
27186
  var ClipWakeSchema = _enum(["authorised"]);
@@ -27415,7 +27441,7 @@ DeviceType.Camera, method(object({
27415
27441
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
27416
27442
  * assumed the answer was a fan-out over everything a camera has. The
27417
27443
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
27418
- * solo"* — so the list is asked of one provider at a time and there is
27444
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
27419
27445
  * nothing to filter out of it.
27420
27446
  */
27421
27447
  provider: string().min(1)
@@ -35413,7 +35439,7 @@ var ReadGopBytesResultSchema = object({
35413
35439
  /**
35414
35440
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
35415
35441
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
35416
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
35442
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
35417
35443
  * a replay needs several seconds of native pixels, not one frame.
35418
35444
  *
35419
35445
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -38777,6 +38803,7 @@ var zoneRulesCapability = {
38777
38803
  */
38778
38804
  durability: "restored"
38779
38805
  };
38806
+ SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
38780
38807
  /**
38781
38808
  * Accessory device helpers — shared across drivers.
38782
38809
  *
@@ -39836,13 +39863,14 @@ var BaseDeviceProvider = class extends BaseAddon {
39836
39863
  async getStatus() {
39837
39864
  const all = await this.ctx.kernel.devices?.getAll() ?? [];
39838
39865
  const summary = this.restoreFailureSummary();
39839
- if (summary === null) return {
39866
+ const base = {
39840
39867
  connected: true,
39841
- deviceCount: all.length
39868
+ deviceCount: all.length,
39869
+ motionSliceWriter: "orchestrator"
39842
39870
  };
39871
+ if (summary === null) return base;
39843
39872
  return {
39844
- connected: true,
39845
- deviceCount: all.length,
39873
+ ...base,
39846
39874
  error: summary
39847
39875
  };
39848
39876
  }
@@ -45278,6 +45306,12 @@ Object.freeze({
45278
45306
  addonId: null,
45279
45307
  access: "view"
45280
45308
  },
45309
+ "notificationRules.getAlarmSensors": {
45310
+ capName: "notification-rules",
45311
+ capScope: "system",
45312
+ addonId: null,
45313
+ access: "view"
45314
+ },
45281
45315
  "notificationRules.getClipRetentionAsks": {
45282
45316
  capName: "notification-rules",
45283
45317
  capScope: "system",
@@ -48856,6 +48890,11 @@ Object.freeze({
48856
48890
  }
48857
48891
  });
48858
48892
  Object.freeze({
48893
+ "accessories.getStatus": [{
48894
+ name: "deviceId",
48895
+ form: "single",
48896
+ optional: false
48897
+ }],
48859
48898
  "accessories.setChildHidden": [{
48860
48899
  name: "childDeviceId",
48861
48900
  form: "single",
@@ -48875,6 +48914,11 @@ Object.freeze({
48875
48914
  form: "single",
48876
48915
  optional: false
48877
48916
  }],
48917
+ "airQualitySensor.getStatus": [{
48918
+ name: "deviceId",
48919
+ form: "single",
48920
+ optional: false
48921
+ }],
48878
48922
  "alarmPanel.arm": [{
48879
48923
  name: "deviceId",
48880
48924
  form: "single",
@@ -48885,11 +48929,36 @@ Object.freeze({
48885
48929
  form: "single",
48886
48930
  optional: false
48887
48931
  }],
48932
+ "alarmPanel.getStatus": [{
48933
+ name: "deviceId",
48934
+ form: "single",
48935
+ optional: false
48936
+ }],
48888
48937
  "alarmPanel.trigger": [{
48889
48938
  name: "deviceId",
48890
48939
  form: "single",
48891
48940
  optional: false
48892
48941
  }],
48942
+ "ambientLightSensor.getStatus": [{
48943
+ name: "deviceId",
48944
+ form: "single",
48945
+ optional: false
48946
+ }],
48947
+ "audioAnalysis.applyDeviceSettingsPatch": [{
48948
+ name: "deviceId",
48949
+ form: "single",
48950
+ optional: false
48951
+ }],
48952
+ "audioAnalysis.getDeviceLiveContribution": [{
48953
+ name: "deviceId",
48954
+ form: "single",
48955
+ optional: false
48956
+ }],
48957
+ "audioAnalysis.getDeviceSettingsContribution": [{
48958
+ name: "deviceId",
48959
+ form: "single",
48960
+ optional: false
48961
+ }],
48893
48962
  "audioAnalysis.resolveDeviceSettings": [{
48894
48963
  name: "deviceId",
48895
48964
  form: "single",
@@ -48930,16 +48999,36 @@ Object.freeze({
48930
48999
  form: "single",
48931
49000
  optional: false
48932
49001
  }],
49002
+ "automationControl.getStatus": [{
49003
+ name: "deviceId",
49004
+ form: "single",
49005
+ optional: false
49006
+ }],
48933
49007
  "automationControl.trigger": [{
48934
49008
  name: "deviceId",
48935
49009
  form: "single",
48936
49010
  optional: false
48937
49011
  }],
49012
+ "battery.getStatus": [{
49013
+ name: "deviceId",
49014
+ form: "single",
49015
+ optional: false
49016
+ }],
48938
49017
  "battery.wakeForStream": [{
48939
49018
  name: "deviceId",
48940
49019
  form: "single",
48941
49020
  optional: false
48942
49021
  }],
49022
+ "binary.getStatus": [{
49023
+ name: "deviceId",
49024
+ form: "single",
49025
+ optional: false
49026
+ }],
49027
+ "brightness.getStatus": [{
49028
+ name: "deviceId",
49029
+ form: "single",
49030
+ optional: false
49031
+ }],
48943
49032
  "brightness.setBrightness": [{
48944
49033
  name: "deviceId",
48945
49034
  form: "single",
@@ -48955,6 +49044,26 @@ Object.freeze({
48955
49044
  form: "single",
48956
49045
  optional: false
48957
49046
  }],
49047
+ "cameraCredentials.getStatus": [{
49048
+ name: "deviceId",
49049
+ form: "single",
49050
+ optional: false
49051
+ }],
49052
+ "cameraGridLayout.applyDeviceSettingsPatch": [{
49053
+ name: "deviceId",
49054
+ form: "single",
49055
+ optional: false
49056
+ }],
49057
+ "cameraGridLayout.getDeviceLiveContribution": [{
49058
+ name: "deviceId",
49059
+ form: "single",
49060
+ optional: false
49061
+ }],
49062
+ "cameraGridLayout.getDeviceSettingsContribution": [{
49063
+ name: "deviceId",
49064
+ form: "single",
49065
+ optional: false
49066
+ }],
48958
49067
  "cameraGridLayout.getLayout": [{
48959
49068
  name: "deviceId",
48960
49069
  form: "single",
@@ -48970,6 +49079,21 @@ Object.freeze({
48970
49079
  form: "single",
48971
49080
  optional: false
48972
49081
  }],
49082
+ "cameraPipelineConfig.applyDeviceSettingsPatch": [{
49083
+ name: "deviceId",
49084
+ form: "single",
49085
+ optional: false
49086
+ }],
49087
+ "cameraPipelineConfig.getDeviceLiveContribution": [{
49088
+ name: "deviceId",
49089
+ form: "single",
49090
+ optional: false
49091
+ }],
49092
+ "cameraPipelineConfig.getDeviceSettingsContribution": [{
49093
+ name: "deviceId",
49094
+ form: "single",
49095
+ optional: false
49096
+ }],
48973
49097
  "cameraStreams.getBrokerStreams": [{
48974
49098
  name: "deviceId",
48975
49099
  form: "single",
@@ -48995,6 +49119,16 @@ Object.freeze({
48995
49119
  form: "single",
48996
49120
  optional: false
48997
49121
  }],
49122
+ "carbonMonoxide.getStatus": [{
49123
+ name: "deviceId",
49124
+ form: "single",
49125
+ optional: false
49126
+ }],
49127
+ "climateControl.getStatus": [{
49128
+ name: "deviceId",
49129
+ form: "single",
49130
+ optional: false
49131
+ }],
48998
49132
  "climateControl.setFanMode": [{
48999
49133
  name: "deviceId",
49000
49134
  form: "single",
@@ -49035,16 +49169,41 @@ Object.freeze({
49035
49169
  form: "single",
49036
49170
  optional: false
49037
49171
  }],
49172
+ "color.getStatus": [{
49173
+ name: "deviceId",
49174
+ form: "single",
49175
+ optional: false
49176
+ }],
49038
49177
  "color.setColor": [{
49039
49178
  name: "deviceId",
49040
49179
  form: "single",
49041
49180
  optional: false
49042
49181
  }],
49182
+ "connectivity.getStatus": [{
49183
+ name: "deviceId",
49184
+ form: "single",
49185
+ optional: false
49186
+ }],
49187
+ "consumables.getStatus": [{
49188
+ name: "deviceId",
49189
+ form: "single",
49190
+ optional: false
49191
+ }],
49043
49192
  "consumables.reset": [{
49044
49193
  name: "deviceId",
49045
49194
  form: "single",
49046
49195
  optional: false
49047
49196
  }],
49197
+ "contact.getStatus": [{
49198
+ name: "deviceId",
49199
+ form: "single",
49200
+ optional: false
49201
+ }],
49202
+ "control.getStatus": [{
49203
+ name: "deviceId",
49204
+ form: "single",
49205
+ optional: false
49206
+ }],
49048
49207
  "control.setValue": [{
49049
49208
  name: "deviceId",
49050
49209
  form: "single",
@@ -49055,6 +49214,11 @@ Object.freeze({
49055
49214
  form: "single",
49056
49215
  optional: false
49057
49216
  }],
49217
+ "cover.getStatus": [{
49218
+ name: "deviceId",
49219
+ form: "single",
49220
+ optional: false
49221
+ }],
49058
49222
  "cover.open": [{
49059
49223
  name: "deviceId",
49060
49224
  form: "single",
@@ -49080,6 +49244,11 @@ Object.freeze({
49080
49244
  form: "single",
49081
49245
  optional: false
49082
49246
  }],
49247
+ "dayNight.getStatus": [{
49248
+ name: "deviceId",
49249
+ form: "single",
49250
+ optional: false
49251
+ }],
49083
49252
  "dayNight.setSettings": [{
49084
49253
  name: "deviceId",
49085
49254
  form: "single",
@@ -49090,11 +49259,31 @@ Object.freeze({
49090
49259
  form: "single",
49091
49260
  optional: true
49092
49261
  }],
49262
+ "detectionPipeline.applyDeviceSettingsPatch": [{
49263
+ name: "deviceId",
49264
+ form: "single",
49265
+ optional: false
49266
+ }],
49267
+ "detectionPipeline.getDeviceLiveContribution": [{
49268
+ name: "deviceId",
49269
+ form: "single",
49270
+ optional: false
49271
+ }],
49272
+ "detectionPipeline.getDeviceSettingsContribution": [{
49273
+ name: "deviceId",
49274
+ form: "single",
49275
+ optional: false
49276
+ }],
49093
49277
  "deviceAdminLink.getAdminLink": [{
49094
49278
  name: "deviceId",
49095
49279
  form: "single",
49096
49280
  optional: false
49097
49281
  }],
49282
+ "deviceAdoption.getStatus": [{
49283
+ name: "deviceId",
49284
+ form: "single",
49285
+ optional: false
49286
+ }],
49098
49287
  "deviceAdoption.release": [{
49099
49288
  name: "camDeviceId",
49100
49289
  form: "single",
@@ -49110,6 +49299,11 @@ Object.freeze({
49110
49299
  form: "single",
49111
49300
  optional: false
49112
49301
  }],
49302
+ "deviceDiscovery.getStatus": [{
49303
+ name: "deviceId",
49304
+ form: "single",
49305
+ optional: false
49306
+ }],
49113
49307
  "deviceDiscovery.listDiscovered": [{
49114
49308
  name: "deviceId",
49115
49309
  form: "single",
@@ -49129,6 +49323,21 @@ Object.freeze({
49129
49323
  form: "single",
49130
49324
  optional: false
49131
49325
  }],
49326
+ "deviceExport.applyDeviceSettingsPatch": [{
49327
+ name: "deviceId",
49328
+ form: "single",
49329
+ optional: false
49330
+ }],
49331
+ "deviceExport.getDeviceLiveContribution": [{
49332
+ name: "deviceId",
49333
+ form: "single",
49334
+ optional: false
49335
+ }],
49336
+ "deviceExport.getDeviceSettingsContribution": [{
49337
+ name: "deviceId",
49338
+ form: "single",
49339
+ optional: false
49340
+ }],
49132
49341
  "deviceExtension.listCandidates": [{
49133
49342
  name: "deviceId",
49134
49343
  form: "single",
@@ -49477,6 +49686,26 @@ Object.freeze({
49477
49686
  form: "single",
49478
49687
  optional: false
49479
49688
  }],
49689
+ "deviceStatus.getStatus": [{
49690
+ name: "deviceId",
49691
+ form: "single",
49692
+ optional: false
49693
+ }],
49694
+ "doorbell.getStatus": [{
49695
+ name: "deviceId",
49696
+ form: "single",
49697
+ optional: false
49698
+ }],
49699
+ "enumSensor.getStatus": [{
49700
+ name: "deviceId",
49701
+ form: "single",
49702
+ optional: false
49703
+ }],
49704
+ "eventEmitter.getStatus": [{
49705
+ name: "deviceId",
49706
+ form: "single",
49707
+ optional: false
49708
+ }],
49480
49709
  "faceGallery.getFaceByTrack": [{
49481
49710
  name: "deviceId",
49482
49711
  form: "single",
@@ -49491,6 +49720,11 @@ Object.freeze({
49491
49720
  form: "array",
49492
49721
  optional: true
49493
49722
  }],
49723
+ "fanControl.getStatus": [{
49724
+ name: "deviceId",
49725
+ form: "single",
49726
+ optional: false
49727
+ }],
49494
49728
  "fanControl.setDirection": [{
49495
49729
  name: "deviceId",
49496
49730
  form: "single",
@@ -49511,6 +49745,26 @@ Object.freeze({
49511
49745
  form: "single",
49512
49746
  optional: false
49513
49747
  }],
49748
+ "featureProbe.getStatus": [{
49749
+ name: "deviceId",
49750
+ form: "single",
49751
+ optional: false
49752
+ }],
49753
+ "flood.getStatus": [{
49754
+ name: "deviceId",
49755
+ form: "single",
49756
+ optional: false
49757
+ }],
49758
+ "gas.getStatus": [{
49759
+ name: "deviceId",
49760
+ form: "single",
49761
+ optional: false
49762
+ }],
49763
+ "humidifier.getStatus": [{
49764
+ name: "deviceId",
49765
+ form: "single",
49766
+ optional: false
49767
+ }],
49514
49768
  "humidifier.setMode": [{
49515
49769
  name: "deviceId",
49516
49770
  form: "single",
@@ -49526,11 +49780,26 @@ Object.freeze({
49526
49780
  form: "single",
49527
49781
  optional: false
49528
49782
  }],
49783
+ "humiditySensor.getStatus": [{
49784
+ name: "deviceId",
49785
+ form: "single",
49786
+ optional: false
49787
+ }],
49788
+ "image.getStatus": [{
49789
+ name: "deviceId",
49790
+ form: "single",
49791
+ optional: false
49792
+ }],
49529
49793
  "imageSettings.getOptions": [{
49530
49794
  name: "deviceId",
49531
49795
  form: "single",
49532
49796
  optional: false
49533
49797
  }],
49798
+ "imageSettings.getStatus": [{
49799
+ name: "deviceId",
49800
+ form: "single",
49801
+ optional: false
49802
+ }],
49534
49803
  "imageSettings.setSettings": [{
49535
49804
  name: "deviceId",
49536
49805
  form: "single",
@@ -49541,6 +49810,11 @@ Object.freeze({
49541
49810
  form: "single",
49542
49811
  optional: false
49543
49812
  }],
49813
+ "intercom.getStatus": [{
49814
+ name: "deviceId",
49815
+ form: "single",
49816
+ optional: false
49817
+ }],
49544
49818
  "intercom.handleAnswer": [{
49545
49819
  name: "deviceId",
49546
49820
  form: "single",
@@ -49571,6 +49845,11 @@ Object.freeze({
49571
49845
  form: "single",
49572
49846
  optional: false
49573
49847
  }],
49848
+ "lawnMowerControl.getStatus": [{
49849
+ name: "deviceId",
49850
+ form: "single",
49851
+ optional: false
49852
+ }],
49574
49853
  "lawnMowerControl.pause": [{
49575
49854
  name: "deviceId",
49576
49855
  form: "single",
@@ -49581,6 +49860,11 @@ Object.freeze({
49581
49860
  form: "single",
49582
49861
  optional: false
49583
49862
  }],
49863
+ "lockControl.getStatus": [{
49864
+ name: "deviceId",
49865
+ form: "single",
49866
+ optional: false
49867
+ }],
49584
49868
  "lockControl.lock": [{
49585
49869
  name: "deviceId",
49586
49870
  form: "single",
@@ -49596,6 +49880,11 @@ Object.freeze({
49596
49880
  form: "single",
49597
49881
  optional: false
49598
49882
  }],
49883
+ "mediaPlayer.getStatus": [{
49884
+ name: "deviceId",
49885
+ form: "single",
49886
+ optional: false
49887
+ }],
49599
49888
  "mediaPlayer.next": [{
49600
49889
  name: "deviceId",
49601
49890
  form: "single",
@@ -49656,6 +49945,11 @@ Object.freeze({
49656
49945
  form: "single",
49657
49946
  optional: false
49658
49947
  }],
49948
+ "motion.getStatus": [{
49949
+ name: "deviceId",
49950
+ form: "single",
49951
+ optional: false
49952
+ }],
49659
49953
  "motion.isDetected": [{
49660
49954
  name: "deviceId",
49661
49955
  form: "single",
@@ -49666,11 +49960,31 @@ Object.freeze({
49666
49960
  form: "single",
49667
49961
  optional: false
49668
49962
  }],
49963
+ "motionDetection.applyDeviceSettingsPatch": [{
49964
+ name: "deviceId",
49965
+ form: "single",
49966
+ optional: false
49967
+ }],
49968
+ "motionDetection.getDeviceLiveContribution": [{
49969
+ name: "deviceId",
49970
+ form: "single",
49971
+ optional: false
49972
+ }],
49973
+ "motionDetection.getDeviceSettingsContribution": [{
49974
+ name: "deviceId",
49975
+ form: "single",
49976
+ optional: false
49977
+ }],
49669
49978
  "motionDetection.removeCamera": [{
49670
49979
  name: "deviceId",
49671
49980
  form: "single",
49672
49981
  optional: false
49673
49982
  }],
49983
+ "motionTrigger.getStatus": [{
49984
+ name: "deviceId",
49985
+ form: "single",
49986
+ optional: false
49987
+ }],
49674
49988
  "motionTrigger.setMotionTrigger": [{
49675
49989
  name: "deviceId",
49676
49990
  form: "single",
@@ -49681,6 +49995,11 @@ Object.freeze({
49681
49995
  form: "single",
49682
49996
  optional: false
49683
49997
  }],
49998
+ "motionZones.getStatus": [{
49999
+ name: "deviceId",
50000
+ form: "single",
50001
+ optional: false
50002
+ }],
49684
50003
  "motionZones.setZone": [{
49685
50004
  name: "deviceId",
49686
50005
  form: "single",
@@ -49691,6 +50010,11 @@ Object.freeze({
49691
50010
  form: "single",
49692
50011
  optional: false
49693
50012
  }],
50013
+ "nativeObjectDetection.getStatus": [{
50014
+ name: "deviceId",
50015
+ form: "single",
50016
+ optional: false
50017
+ }],
49694
50018
  "nativeObjectDetection.setEnabled": [{
49695
50019
  name: "deviceId",
49696
50020
  form: "single",
@@ -49706,6 +50030,11 @@ Object.freeze({
49706
50030
  form: "single",
49707
50031
  optional: false
49708
50032
  }],
50033
+ "navigation.getStatus": [{
50034
+ name: "deviceId",
50035
+ form: "single",
50036
+ optional: false
50037
+ }],
49709
50038
  "navigation.goToPoint": [{
49710
50039
  name: "deviceId",
49711
50040
  form: "single",
@@ -49751,6 +50080,11 @@ Object.freeze({
49751
50080
  form: "single",
49752
50081
  optional: false
49753
50082
  }],
50083
+ "networkLink.getStatus": [{
50084
+ name: "deviceId",
50085
+ form: "single",
50086
+ optional: false
50087
+ }],
49754
50088
  "networkQuality.getDeviceStats": [{
49755
50089
  name: "deviceId",
49756
50090
  form: "single",
@@ -49761,6 +50095,11 @@ Object.freeze({
49761
50095
  form: "single",
49762
50096
  optional: false
49763
50097
  }],
50098
+ "notificationRules.getAlarmSensors": [{
50099
+ name: "deviceIds",
50100
+ form: "array",
50101
+ optional: false
50102
+ }],
49764
50103
  "notificationRules.setDeviceMuted": [{
49765
50104
  name: "deviceId",
49766
50105
  form: "single",
@@ -49771,11 +50110,26 @@ Object.freeze({
49771
50110
  form: "single",
49772
50111
  optional: false
49773
50112
  }],
50113
+ "notifier.getStatus": [{
50114
+ name: "deviceId",
50115
+ form: "single",
50116
+ optional: false
50117
+ }],
49774
50118
  "notifier.send": [{
49775
50119
  name: "deviceId",
49776
50120
  form: "single",
49777
50121
  optional: false
49778
50122
  }],
50123
+ "numericSensor.getStatus": [{
50124
+ name: "deviceId",
50125
+ form: "single",
50126
+ optional: false
50127
+ }],
50128
+ "osd.getStatus": [{
50129
+ name: "deviceId",
50130
+ form: "single",
50131
+ optional: false
50132
+ }],
49779
50133
  "osd.setOverlay": [{
49780
50134
  name: "deviceId",
49781
50135
  form: "single",
@@ -49835,6 +50189,11 @@ Object.freeze({
49835
50189
  form: "single",
49836
50190
  optional: false
49837
50191
  }],
50192
+ "petFeeder.getStatus": [{
50193
+ name: "deviceId",
50194
+ form: "single",
50195
+ optional: false
50196
+ }],
49838
50197
  "petFeeder.markFoodReplenished": [{
49839
50198
  name: "deviceId",
49840
50199
  form: "single",
@@ -49870,6 +50229,11 @@ Object.freeze({
49870
50229
  form: "single",
49871
50230
  optional: false
49872
50231
  }],
50232
+ "pipelineAnalytics.applyDeviceSettingsPatch": [{
50233
+ name: "deviceId",
50234
+ form: "single",
50235
+ optional: false
50236
+ }],
49873
50237
  "pipelineAnalytics.clearTrackRelation": [{
49874
50238
  name: "deviceId",
49875
50239
  form: "single",
@@ -49910,6 +50274,16 @@ Object.freeze({
49910
50274
  form: "single",
49911
50275
  optional: false
49912
50276
  }],
50277
+ "pipelineAnalytics.getDeviceLiveContribution": [{
50278
+ name: "deviceId",
50279
+ form: "single",
50280
+ optional: false
50281
+ }],
50282
+ "pipelineAnalytics.getDeviceSettingsContribution": [{
50283
+ name: "deviceId",
50284
+ form: "single",
50285
+ optional: false
50286
+ }],
49913
50287
  "pipelineAnalytics.getEventDensity": [{
49914
50288
  name: "deviceId",
49915
50289
  form: "single",
@@ -50125,6 +50499,11 @@ Object.freeze({
50125
50499
  form: "single",
50126
50500
  optional: true
50127
50501
  }],
50502
+ "pipelineOrchestrator.applyDeviceSettingsPatch": [{
50503
+ name: "deviceId",
50504
+ form: "single",
50505
+ optional: false
50506
+ }],
50128
50507
  "pipelineOrchestrator.assignAudio": [{
50129
50508
  name: "deviceId",
50130
50509
  form: "single",
@@ -50170,6 +50549,16 @@ Object.freeze({
50170
50549
  form: "single",
50171
50550
  optional: false
50172
50551
  }],
50552
+ "pipelineOrchestrator.getDeviceLiveContribution": [{
50553
+ name: "deviceId",
50554
+ form: "single",
50555
+ optional: false
50556
+ }],
50557
+ "pipelineOrchestrator.getDeviceSettingsContribution": [{
50558
+ name: "deviceId",
50559
+ form: "single",
50560
+ optional: false
50561
+ }],
50173
50562
  "pipelineOrchestrator.getPipelineAssignment": [{
50174
50563
  name: "deviceId",
50175
50564
  form: "single",
@@ -50290,11 +50679,31 @@ Object.freeze({
50290
50679
  form: "single",
50291
50680
  optional: true
50292
50681
  }],
50682
+ "powerMeter.getStatus": [{
50683
+ name: "deviceId",
50684
+ form: "single",
50685
+ optional: false
50686
+ }],
50687
+ "presence.getStatus": [{
50688
+ name: "deviceId",
50689
+ form: "single",
50690
+ optional: false
50691
+ }],
50692
+ "pressureSensor.getStatus": [{
50693
+ name: "deviceId",
50694
+ form: "single",
50695
+ optional: false
50696
+ }],
50293
50697
  "privacyMask.getOptions": [{
50294
50698
  name: "deviceId",
50295
50699
  form: "single",
50296
50700
  optional: false
50297
50701
  }],
50702
+ "privacyMask.getStatus": [{
50703
+ name: "deviceId",
50704
+ form: "single",
50705
+ optional: false
50706
+ }],
50298
50707
  "privacyMask.setAudioEnabled": [{
50299
50708
  name: "deviceId",
50300
50709
  form: "single",
@@ -50345,6 +50754,11 @@ Object.freeze({
50345
50754
  form: "single",
50346
50755
  optional: false
50347
50756
  }],
50757
+ "ptz.getStatus": [{
50758
+ name: "deviceId",
50759
+ form: "single",
50760
+ optional: false
50761
+ }],
50348
50762
  "ptz.goHome": [{
50349
50763
  name: "deviceId",
50350
50764
  form: "single",
@@ -50435,6 +50849,11 @@ Object.freeze({
50435
50849
  form: "single",
50436
50850
  optional: false
50437
50851
  }],
50852
+ "recordingArchive.applyDeviceSettingsPatch": [{
50853
+ name: "deviceId",
50854
+ form: "single",
50855
+ optional: false
50856
+ }],
50438
50857
  "recordingArchive.deleteFootprint": [{
50439
50858
  name: "deviceId",
50440
50859
  form: "single",
@@ -50455,6 +50874,21 @@ Object.freeze({
50455
50874
  form: "single",
50456
50875
  optional: false
50457
50876
  }],
50877
+ "recordingArchive.getDeviceLiveContribution": [{
50878
+ name: "deviceId",
50879
+ form: "single",
50880
+ optional: false
50881
+ }],
50882
+ "recordingArchive.getDeviceSettingsContribution": [{
50883
+ name: "deviceId",
50884
+ form: "single",
50885
+ optional: false
50886
+ }],
50887
+ "recordingArchive.getStatus": [{
50888
+ name: "deviceId",
50889
+ form: "single",
50890
+ optional: false
50891
+ }],
50458
50892
  "recordingArchive.listOpsLog": [{
50459
50893
  name: "deviceId",
50460
50894
  form: "single",
@@ -50540,6 +50974,11 @@ Object.freeze({
50540
50974
  form: "single",
50541
50975
  optional: false
50542
50976
  }],
50977
+ "recordingOnboard.getStatus": [{
50978
+ name: "deviceId",
50979
+ form: "single",
50980
+ optional: false
50981
+ }],
50543
50982
  "recordingOnboard.setSettings": [{
50544
50983
  name: "deviceId",
50545
50984
  form: "single",
@@ -50570,6 +51009,11 @@ Object.freeze({
50570
51009
  form: "single",
50571
51010
  optional: false
50572
51011
  }],
51012
+ "sceneMonitor.getStatus": [{
51013
+ name: "deviceId",
51014
+ form: "single",
51015
+ optional: false
51016
+ }],
50573
51017
  "sceneMonitor.listScenes": [{
50574
51018
  name: "deviceId",
50575
51019
  form: "single",
@@ -50595,6 +51039,11 @@ Object.freeze({
50595
51039
  form: "single",
50596
51040
  optional: false
50597
51041
  }],
51042
+ "scriptRunner.getStatus": [{
51043
+ name: "deviceId",
51044
+ form: "single",
51045
+ optional: false
51046
+ }],
50598
51047
  "scriptRunner.run": [{
50599
51048
  name: "deviceId",
50600
51049
  form: "single",
@@ -50605,11 +51054,31 @@ Object.freeze({
50605
51054
  form: "single",
50606
51055
  optional: false
50607
51056
  }],
51057
+ "smoke.getStatus": [{
51058
+ name: "deviceId",
51059
+ form: "single",
51060
+ optional: false
51061
+ }],
51062
+ "snapshot.applyDeviceSettingsPatch": [{
51063
+ name: "deviceId",
51064
+ form: "single",
51065
+ optional: false
51066
+ }],
50608
51067
  "snapshot.getDebugState": [{
50609
51068
  name: "deviceId",
50610
51069
  form: "single",
50611
51070
  optional: false
50612
51071
  }],
51072
+ "snapshot.getDeviceLiveContribution": [{
51073
+ name: "deviceId",
51074
+ form: "single",
51075
+ optional: false
51076
+ }],
51077
+ "snapshot.getDeviceSettingsContribution": [{
51078
+ name: "deviceId",
51079
+ form: "single",
51080
+ optional: false
51081
+ }],
50613
51082
  "snapshot.getSnapshot": [{
50614
51083
  name: "deviceId",
50615
51084
  form: "single",
@@ -50626,6 +51095,11 @@ Object.freeze({
50626
51095
  form: "array",
50627
51096
  optional: false
50628
51097
  }],
51098
+ "snapshot.getStatus": [{
51099
+ name: "deviceId",
51100
+ form: "single",
51101
+ optional: false
51102
+ }],
50629
51103
  "snapshot.invalidateCache": [{
50630
51104
  name: "deviceId",
50631
51105
  form: "single",
@@ -50636,6 +51110,11 @@ Object.freeze({
50636
51110
  form: "single",
50637
51111
  optional: false
50638
51112
  }],
51113
+ "streamBroker.applyDeviceSettingsPatch": [{
51114
+ name: "deviceId",
51115
+ form: "single",
51116
+ optional: false
51117
+ }],
50639
51118
  "streamBroker.assignProfile": [{
50640
51119
  name: "deviceId",
50641
51120
  form: "single",
@@ -50651,6 +51130,16 @@ Object.freeze({
50651
51130
  form: "single",
50652
51131
  optional: false
50653
51132
  }],
51133
+ "streamBroker.getDeviceLiveContribution": [{
51134
+ name: "deviceId",
51135
+ form: "single",
51136
+ optional: false
51137
+ }],
51138
+ "streamBroker.getDeviceSettingsContribution": [{
51139
+ name: "deviceId",
51140
+ form: "single",
51141
+ optional: false
51142
+ }],
50654
51143
  "streamBroker.getStreamWithCodec": [{
50655
51144
  name: "deviceId",
50656
51145
  form: "single",
@@ -50711,16 +51200,46 @@ Object.freeze({
50711
51200
  form: "single",
50712
51201
  optional: false
50713
51202
  }],
51203
+ "streamParams.getStatus": [{
51204
+ name: "deviceId",
51205
+ form: "single",
51206
+ optional: false
51207
+ }],
50714
51208
  "streamParams.setProfile": [{
50715
51209
  name: "deviceId",
50716
51210
  form: "single",
50717
51211
  optional: false
50718
51212
  }],
51213
+ "switch.getStatus": [{
51214
+ name: "deviceId",
51215
+ form: "single",
51216
+ optional: false
51217
+ }],
50719
51218
  "switch.setState": [{
50720
51219
  name: "deviceId",
50721
51220
  form: "single",
50722
51221
  optional: false
50723
51222
  }],
51223
+ "tamper.getStatus": [{
51224
+ name: "deviceId",
51225
+ form: "single",
51226
+ optional: false
51227
+ }],
51228
+ "temperatureSensor.getStatus": [{
51229
+ name: "deviceId",
51230
+ form: "single",
51231
+ optional: false
51232
+ }],
51233
+ "update.getStatus": [{
51234
+ name: "deviceId",
51235
+ form: "single",
51236
+ optional: false
51237
+ }],
51238
+ "vacuumControl.getStatus": [{
51239
+ name: "deviceId",
51240
+ form: "single",
51241
+ optional: false
51242
+ }],
50724
51243
  "vacuumControl.locate": [{
50725
51244
  name: "deviceId",
50726
51245
  form: "single",
@@ -50756,6 +51275,11 @@ Object.freeze({
50756
51275
  form: "single",
50757
51276
  optional: false
50758
51277
  }],
51278
+ "valve.getStatus": [{
51279
+ name: "deviceId",
51280
+ form: "single",
51281
+ optional: false
51282
+ }],
50759
51283
  "valve.open": [{
50760
51284
  name: "deviceId",
50761
51285
  form: "single",
@@ -50771,6 +51295,11 @@ Object.freeze({
50771
51295
  form: "single",
50772
51296
  optional: false
50773
51297
  }],
51298
+ "vibration.getStatus": [{
51299
+ name: "deviceId",
51300
+ form: "single",
51301
+ optional: false
51302
+ }],
50774
51303
  "videoclips.dialClipStream": [{
50775
51304
  name: "deviceId",
50776
51305
  form: "single",
@@ -50806,6 +51335,11 @@ Object.freeze({
50806
51335
  form: "single",
50807
51336
  optional: false
50808
51337
  }],
51338
+ "waterHeater.getStatus": [{
51339
+ name: "deviceId",
51340
+ form: "single",
51341
+ optional: false
51342
+ }],
50809
51343
  "waterHeater.setAway": [{
50810
51344
  name: "deviceId",
50811
51345
  form: "single",
@@ -50821,6 +51355,11 @@ Object.freeze({
50821
51355
  form: "single",
50822
51356
  optional: false
50823
51357
  }],
51358
+ "weather.getStatus": [{
51359
+ name: "deviceId",
51360
+ form: "single",
51361
+ optional: false
51362
+ }],
50824
51363
  "webrtcSession.addIceCandidate": [{
50825
51364
  name: "deviceId",
50826
51365
  form: "single",
@@ -51558,7 +52097,7 @@ var PreviewTextField = string().max(200);
51558
52097
  * Whether the notification's preview is a STILL or a short animation.
51559
52098
  *
51560
52099
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
51561
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
52100
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
51562
52101
  * night reads better as three seconds of motion than as one frame of it. Both
51563
52102
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
51564
52103
  * simply applies it to a dozen frames sampled across the render and assembles