@camstack/addon-export-alexa 1.2.124 → 1.2.125

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.
@@ -7467,7 +7467,7 @@ function errMsg(err) {
7467
7467
  return String(err);
7468
7468
  }
7469
7469
  //#endregion
7470
- //#region ../types/dist/composition-43aqsZQj.mjs
7470
+ //#region ../types/dist/composition-Bzr7GwgP.mjs
7471
7471
  /**
7472
7472
  * The ffmpeg build every CamStack node downloads, per platform and arch.
7473
7473
  *
@@ -7521,20 +7521,20 @@ function portable(target) {
7521
7521
  }
7522
7522
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7523
7523
  /**
7524
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7525
- * valutatore puro del suo FRONTE.
7524
+ * THE table "which boolean of this device type counts as HIGH", and the
7525
+ * pure evaluator of its EDGE.
7526
7526
  *
7527
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7528
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7529
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7530
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7531
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7532
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7527
+ * ONE table for everyone who asks "is this device HIGH?": the
7528
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7529
+ * sensor markers, the orchestrator's camera-sensors bridge and
7530
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7531
+ * A second copy would diverge at the first cap added, and the symptom — "the
7532
+ * sensor rings the doorbell but does not record" — is exactly D62.
7533
7533
  *
7534
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7535
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7536
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7537
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7534
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7535
+ * two must not be unified: that one answers "what is the state WORD for a
7536
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7537
+ * boolean's EDGE counts". Deliberately different vocabularies.
7538
7538
  */
7539
7539
  /**
7540
7540
  * Known binary / switch source caps → the boolean slice field whose
@@ -7555,6 +7555,8 @@ var SOURCE_CAP_ACTIVE_FIELD = {
7555
7555
  vibration: "detected",
7556
7556
  tamper: "tampered"
7557
7557
  };
7558
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7559
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7558
7560
  /**
7559
7561
  * Error types for the safe expression engine. Two distinct classes so callers
7560
7562
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
@@ -9310,22 +9312,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9310
9312
  "package"
9311
9313
  ];
9312
9314
  /**
9313
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9314
- * un operatore può selezionare.
9315
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9316
+ * an operator can select.
9315
9317
  *
9316
- * Sono le tre offerte dallo step `object-detection`
9318
+ * They are the three offered by the `object-detection` step
9317
9319
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9318
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9319
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9320
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9321
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9320
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9321
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9322
+ * `package-detection`, whose enablement is driven by zones, and offering the
9323
+ * same word twice has already made an operator turn on the COCO proxy
9322
9324
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9323
9325
  *
9324
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9325
- * dello step e una seconda volta come union `FirstLevelMacro`
9326
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9327
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9328
- * successiva.
9326
+ * ONE list. Before today the same three were hand-written in the step's offer
9327
+ * and a second time as the union `FirstLevelMacro`
9328
+ * (`types/detection.ts`); a third copy for the recording trigger
9329
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9330
+ * invisible.
9329
9331
  */
9330
9332
  var FIRST_LEVEL_MACRO_CLASSES = [
9331
9333
  "person",
@@ -9390,17 +9392,17 @@ var RecordingStorageModeSchema = _enum([
9390
9392
  "on-device-decision"
9391
9393
  ]);
9392
9394
  /**
9393
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9394
- * tre offerte dallo step `object-detection`, da UNA lista
9395
+ * The macro classes that can open a recording window — the same
9396
+ * three offered by the `object-detection` step, from ONE list
9395
9397
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9396
9398
  */
9397
9399
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9398
9400
  /**
9399
- * True quando `values` non ripete un elemento.
9401
+ * True when `values` does not repeat an element.
9400
9402
  *
9401
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9402
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9403
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9403
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9404
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9405
+ * would count its windows twice in `segmentMissedByMs`.
9404
9406
  */
9405
9407
  var noDuplicates = (values) => new Set(values).size === values.length;
9406
9408
  /** Which detectors trigger an `events`-mode band. */
@@ -9408,34 +9410,34 @@ var RecordingTriggersSchema = object({
9408
9410
  motion: boolean().optional(),
9409
9411
  audioThresholdDbfs: number().optional(),
9410
9412
  /**
9411
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9412
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9413
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9414
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9413
+ * The macro classes whose detection opens a window. ABSENT = the source
9414
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9415
+ * trigger on, no class" is the same shape "enabled and records
9416
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9415
9417
  *
9416
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9417
- * quelle che hanno attraversato `enabledMacroClasses`, i
9418
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9419
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9420
- * finestre — vedi `recorder/object-trigger.ts`.
9418
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9419
+ * those that went through `enabledMacroClasses`, the
9420
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9421
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9422
+ * windows — see `recorder/object-trigger.ts`.
9421
9423
  */
9422
9424
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9423
9425
  /**
9424
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9425
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9426
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9427
+ * is not listened to; an empty array is rejected for the same reason as
9426
9428
  * `objectClasses`.
9427
9429
  *
9428
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9429
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9430
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9431
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9432
- * device (D12) — mai un elenco globale di cap.
9430
+ * These are SOURCE device ids, not cameras: the band names them, so the
9431
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9432
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9433
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9434
+ * device (D12) — never a global list of caps.
9433
9435
  *
9434
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9435
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9436
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9437
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9438
- * registrare.
9436
+ * What "high" means depends on the device TYPE and is not decided here:
9437
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9438
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9439
+ * the level: a contact found already open at runner restart does not
9440
+ * record.
9439
9441
  */
9440
9442
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9441
9443
  });
@@ -10512,7 +10514,7 @@ var DecoderSessionConfigSchema = object({
10512
10514
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
10513
10515
  * thing: the logging settings document on the `system` cap. Two authorities
10514
10516
  * over the values is the exact defect
10515
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
10517
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
10516
10518
  * remove; re-introducing it from the cure side would be grotesque.
10517
10519
  *
10518
10520
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -12337,7 +12339,7 @@ var BrokerStatusEnum = _enum([
12337
12339
  "unreachable",
12338
12340
  "error"
12339
12341
  ]);
12340
- var BrokerInfoSchema$1 = object({
12342
+ var BrokerInfoSchema = object({
12341
12343
  /** Stable broker id. Persisted; survives addon restarts. */
12342
12344
  id: string(),
12343
12345
  /** Addon id of the provider that OWNS this broker.
@@ -12470,7 +12472,7 @@ var GetStateInputSchema = object({
12470
12472
  * HA: entity_id (returns the cached entity state). */
12471
12473
  key: string()
12472
12474
  });
12473
- method(ListInputSchema, array(BrokerInfoSchema$1)), method(GetInputSchema, BrokerInfoSchema$1.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12475
+ method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12474
12476
  kind: "mutation",
12475
12477
  auth: "admin"
12476
12478
  }), method(RemoveInputSchema, _void(), {
@@ -14079,7 +14081,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
14079
14081
  *
14080
14082
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
14081
14083
  * was wrong — corrected 2026-08-26 after the hop map
14082
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
14084
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
14083
14085
  * There is **no Zod parse at all** between the door and the engine: the
14084
14086
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
14085
14087
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -14860,7 +14862,17 @@ var SiteZoneSchema = object({
14860
14862
  var ProviderStatusSchema = object({
14861
14863
  connected: boolean(),
14862
14864
  deviceCount: number(),
14863
- error: string().optional()
14865
+ error: string().optional(),
14866
+ /**
14867
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
14868
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
14869
+ * which every provider bundles, so only a provider BUILT from D696-amended
14870
+ * code says it. ABSENT means an older provider that may still write it (raw
14871
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
14872
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
14873
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
14874
+ */
14875
+ motionSliceWriter: literal("orchestrator").optional()
14864
14876
  });
14865
14877
  object({
14866
14878
  externalId: string(),
@@ -15996,7 +16008,7 @@ method(object({
15996
16008
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
15997
16009
  * ends in a log line, and a log line is the thing the operator asked to stop
15998
16010
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
15999
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
16011
+ * 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
16000
16012
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
16001
16013
  * media blackout were both diagnosed. The counters stay; this is where they can
16002
16014
  * be READ.
@@ -17372,7 +17384,7 @@ var BrokerStatusSchema$1 = _enum([
17372
17384
  "unreachable",
17373
17385
  "tls-error"
17374
17386
  ]);
17375
- var BrokerInfoSchema = object({
17387
+ var BrokerInfoSchema$1 = object({
17376
17388
  id: string(),
17377
17389
  name: string(),
17378
17390
  url: string(),
@@ -17435,7 +17447,7 @@ var StatusSchema = object({
17435
17447
  brokerCount: number(),
17436
17448
  embeddedRunning: boolean()
17437
17449
  });
17438
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17450
+ method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17439
17451
  kind: "mutation",
17440
17452
  auth: "admin"
17441
17453
  }), method(IdInputSchema, _void(), {
@@ -19611,78 +19623,16 @@ var NcRuleInputSchema = object({
19611
19623
  */
19612
19624
  confirm: NcConfirmSchema.optional(),
19613
19625
  /**
19614
- * WAIT for face/plate recognition before saying anything.
19615
- *
19616
- * A notification's TEXT is frozen at enqueue and its media is re-resolved at
19617
- * send; the identity is neither. A face is confirmed after `confirmFrames`
19618
- * agreeing observations — p50 **11.4 s** after the track was first seen,
19619
- * measured on this hub — and an `immediate` rule enqueues on the first object
19620
- * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
19621
- * immediate path, and no amount of media re-resolution fixes a sentence.
19622
- *
19623
- * Only two honest answers exist, and this flag picks between them. It has
19624
- * effect ONLY on a rule that declares a recognition scope
19625
- * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
19626
- * other rule there is nothing to wait for and the flag is inert.
19627
- *
19628
- * | value | what happens |
19629
- * | --- | --- |
19630
- * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
19631
- * | 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) |
19632
- *
19633
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19634
- * on the addon cap path, and absent has to keep meaning exactly what every
19635
- * rule authored before this field meant.
19636
- *
19637
- * The cost of `true` is stated here because the editor states it too: a rule
19638
- * that waits also inherits track-close SEMANTICS — its `zones` condition
19639
- * tests every zone the track visited and a `crossing` condition can no longer
19640
- * be satisfied, because a closed track carries no crossing.
19626
+ * IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
19627
+ * seconds; the rule sends ONE message when the window closes — early, once every
19628
+ * subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
19629
+ * the rule matched, with one mosaic tile per subject.
19630
+ * Absent = plain immediate (one message per track, at the first match).
19631
+ * Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
19632
+ * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
19633
+ * path does not run Zod defaults.
19641
19634
  */
19642
- waitForEnhancement: boolean().optional(),
19643
- /**
19644
- * GROUP a burst of subjects into ONE notification that grows.
19645
- *
19646
- * Seconds of quiet after the last matching subject before the burst is
19647
- * considered over. While it is open, the first subject enqueues immediately —
19648
- * **exactly as today, with no added latency** — and every real growth (a new
19649
- * subject, or a name confirmed on one already in it) REPLACES that
19650
- * notification with an updated one naming everybody. The push carries the
19651
- * group's own coalescing tag, so the phone replaces rather than stacks.
19652
- *
19653
- * `0` / absent = off, and off is today's behaviour byte for byte.
19654
- *
19655
- * ### Why an idle cutoff and not a window
19656
- *
19657
- * The measured seven-person arrival on device 590 spans 110 s with every
19658
- * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
19659
- * idle cutoff holds it as one and ends it when the arrival actually ends.
19660
- * 30 s is a widely shipped value for the same decision.
19661
- *
19662
- * ### What it replaces
19663
- *
19664
- * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
19665
- * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
19666
- * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
19667
- * track that did fire and 7 carrying a confirmed identity nobody heard about.
19668
- * A group collapses the same volume by MERGING, so the cooldown becomes a
19669
- * budget over GROUPS — which is what it always meant — and a growth is never
19670
- * throttled by the window its own first member spent.
19671
- *
19672
- * ### Interaction with {@link waitForEnhancement}
19673
- *
19674
- * They compose, and the order matters. `waitForEnhancement` defers the rule to
19675
- * TRACK CLOSE, so with both set the group is opened by the first member to
19676
- * CLOSE — already carrying its name — and grows as later members close. That
19677
- * is later, and complete. With grouping alone the group opens on the first
19678
- * object event and picks up names as they are confirmed, through the growth
19679
- * path. Neither combination fires twice for one subject.
19680
- *
19681
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19682
- * on the addon cap path, so absent must keep meaning what it meant before this
19683
- * field existed.
19684
- */
19685
- groupIdleSec: number().int().min(0).max(600).optional()
19635
+ groupingSec: number().int().min(5).max(60).optional()
19686
19636
  });
19687
19637
  /**
19688
19638
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -19730,9 +19680,10 @@ var NcRuleClearableKeySchema = _enum([
19730
19680
  "targetUsers",
19731
19681
  "snoozeOptions",
19732
19682
  "snoozeAllowGlobal",
19733
- "waitForEnhancement",
19734
19683
  "actions",
19735
19684
  "confirm",
19685
+ "groupingSec",
19686
+ "waitForEnhancement",
19736
19687
  "groupIdleSec"
19737
19688
  ]);
19738
19689
  var NcRuleUpdateInputSchema = object({
@@ -19754,9 +19705,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19754
19705
  */
19755
19706
  disabledTargetIds: array(string()).default([])
19756
19707
  });
19708
+ /**
19709
+ * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19710
+ * still-true state. `backups-exports` and `alarm` are not sections — a completed
19711
+ * job is not an open state, and the alarm stays instant.
19712
+ */
19713
+ var NcStateSummarySectionIdSchema = _enum([
19714
+ "device-state",
19715
+ "streams",
19716
+ "battery",
19717
+ "consumables",
19718
+ "tanks",
19719
+ "detection-blind",
19720
+ "nodes",
19721
+ "addons",
19722
+ "updates"
19723
+ ]);
19757
19724
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
19758
19725
  var NcStateSummaryPreviewSectionSchema = object({
19759
- id: string(),
19726
+ id: NcStateSummarySectionIdSchema,
19760
19727
  status: _enum(["read", "unavailable"]),
19761
19728
  items: number().int().nonnegative(),
19762
19729
  reason: string().optional()
@@ -19766,7 +19733,7 @@ var NcStateSummaryPreviewSectionSchema = object({
19766
19733
  * a `rule` split (no `section`), one section's on a `section` split.
19767
19734
  */
19768
19735
  var NcStateSummaryPreviewRowSchema = object({
19769
- section: string().optional(),
19736
+ section: NcStateSummarySectionIdSchema.optional(),
19770
19737
  /** The section's name on a per-section row; every reported section's, joined, on a combined one. */
19771
19738
  title: string(),
19772
19739
  text: string(),
@@ -20203,6 +20170,29 @@ object({
20203
20170
  firstAt: number(),
20204
20171
  lastAt: number()
20205
20172
  });
20173
+ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20174
+ var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20175
+ var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20176
+ var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20177
+ var NcAlarmModeDelaysListSchema = array(object({
20178
+ mode: AlarmArmModeSchema,
20179
+ exitDelaySec: NcAlarmDelaySecSchema.optional(),
20180
+ entryDelaySec: NcAlarmDelaySecSchema.optional(),
20181
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20182
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20183
+ var NcAlarmModeDelaysEditListSchema = array(object({
20184
+ mode: AlarmArmModeSchema,
20185
+ exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20186
+ entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20187
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20188
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20189
+ /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20190
+ var NcAlarmNonBlockingEditSchema = object({
20191
+ mode: AlarmArmModeSchema,
20192
+ deviceId: number().int().positive(),
20193
+ /** true = on the list (may be open, does not block); false = off the list (blocks). */
20194
+ nonBlocking: boolean()
20195
+ });
20206
20196
  /**
20207
20197
  * The per-mode lists, at most one per mode. Two lists for one mode have no
20208
20198
  * meaning a reader could agree on (union? the last one?), so they are refused
@@ -20211,10 +20201,10 @@ object({
20211
20201
  var NcAlarmNonBlockingListSchema = array(object({
20212
20202
  mode: AlarmArmModeSchema,
20213
20203
  deviceIds: array(number().int()).max(200)
20214
- })).max(8).refine((lists) => new Set(lists.map((l) => l.mode)).size === lists.length, { message: "nonBlocking: at most one list per arm mode" });
20204
+ })).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20215
20205
  /**
20216
- * The three durations the panel's state machine runs on, who hears about its
20217
- * transitions, and which openings each mode tolerates.
20206
+ * The three durations — global, and per mode since D697 — the panel's state
20207
+ * machine runs on, who hears about its transitions, and which openings each mode tolerates.
20218
20208
  *
20219
20209
  * They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
20220
20210
  * `alarm-panel` is `deviceNative` and its other provider mirrors somebody
@@ -20224,15 +20214,15 @@ var NcAlarmNonBlockingListSchema = array(object({
20224
20214
  */
20225
20215
  var NcAlarmSettingsSchema = object({
20226
20216
  /** Grace period between arming and the mode taking effect. 0 = immediate. */
20227
- exitDelaySec: number().int().min(0).max(600),
20217
+ exitDelaySec: NcAlarmDelaySecSchema,
20228
20218
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20229
- entryDelaySec: number().int().min(0).max(600),
20219
+ entryDelaySec: NcAlarmDelaySecSchema,
20230
20220
  /**
20231
20221
  * How long `triggered` lasts before the panel re-arms itself.
20232
20222
  * **0 = until an operator disarms it** — the behaviour before this field
20233
20223
  * existed, and therefore what an untouched install keeps doing.
20234
20224
  */
20235
- triggeredDurationSec: number().int().min(0).max(3600),
20225
+ triggeredDurationSec: NcAlarmTriggeredSecSchema,
20236
20226
  /**
20237
20227
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20238
20228
  * remove after one release. Optional so an older admin's patch (which still
@@ -20255,17 +20245,30 @@ var NcAlarmSettingsSchema = object({
20255
20245
  * per mode is meaningful. Defaulted to `[]` so a blob stored before D630
20256
20246
  * parses as "every opening blocks" — the behaviour it was written under.
20257
20247
  */
20258
- nonBlocking: NcAlarmNonBlockingListSchema.default([])
20248
+ nonBlocking: NcAlarmNonBlockingListSchema.default([]),
20249
+ /**
20250
+ * Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
20251
+ * without a field, uses the global value above — so `[]`, the default, is exactly the
20252
+ * behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
20253
+ */
20254
+ modeDelays: NcAlarmModeDelaysListSchema.default([])
20259
20255
  });
20260
20256
  /**
20261
20257
  * Every field optional — a tab edits one control at a time.
20262
20258
  *
20263
- * `nonBlocking` is re-declared WITHOUT its default: `.partial()` does not
20264
- * remove an inner `.default()`, so a patch that never named the field would
20265
- * parse to `nonBlocking: []` and wipe every mode's list on an unrelated edit
20266
- * (the same trap {@link NcRulePatchSchema} documents).
20259
+ * `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
20260
+ * `.partial()` does not remove an inner `.default()`, so a patch that never
20261
+ * named the field would parse to `[]` and wipe every mode's list on an
20262
+ * unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
20263
+ * `modeDelays` means EDITS, not the stored overrides.
20267
20264
  */
20268
- var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({ nonBlocking: NcAlarmNonBlockingListSchema }).partial();
20265
+ var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
20266
+ nonBlocking: NcAlarmNonBlockingListSchema,
20267
+ /** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
20268
+ modeDelays: NcAlarmModeDelaysEditListSchema,
20269
+ /** ONE membership change; the panel applies it to the list it holds at its turn. */
20270
+ nonBlockingEdit: NcAlarmNonBlockingEditSchema
20271
+ }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
20269
20272
  /**
20270
20273
  * What one arm mode actually arms, DERIVED from the enabled rules gated on it.
20271
20274
  * Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
@@ -20365,6 +20368,28 @@ var NcAlarmConfigSchema = object({
20365
20368
  */
20366
20369
  live: NcAlarmLiveSchema.optional()
20367
20370
  });
20371
+ var NcAlarmSensorReadingSchema = _enum([
20372
+ "open",
20373
+ "closed",
20374
+ "unknown",
20375
+ "not-opening"
20376
+ ]);
20377
+ /** One device's state as the alarm reads it — the classifier the arm check uses. */
20378
+ var NcAlarmSensorStateSchema = object({
20379
+ deviceId: number().int().positive(),
20380
+ reading: NcAlarmSensorReadingSchema,
20381
+ /** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
20382
+ state: string().nullable(),
20383
+ /** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
20384
+ unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
20385
+ /** The device manager's liveness as the centre mirrors it; null = not known. */
20386
+ online: boolean().nullable()
20387
+ });
20388
+ var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
20389
+ var NcAlarmSensorsSchema = object({
20390
+ sensors: array(NcAlarmSensorStateSchema),
20391
+ readAt: number().int().nonnegative()
20392
+ });
20368
20393
  /**
20369
20394
  * ONE rule's demand on ONE camera's clip ring.
20370
20395
  *
@@ -20455,7 +20480,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20455
20480
  }), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
20456
20481
  kind: "mutation",
20457
20482
  auth: "admin"
20458
- });
20483
+ }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
20459
20484
  /**
20460
20485
  * Zod schemas for persisted record types.
20461
20486
  *
@@ -21623,14 +21648,14 @@ var TrackSchema = object({
21623
21648
  * `derive-returned-null tile=standin`,
21624
21649
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
21625
21650
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
21626
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
21651
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
21627
21652
  * tile is a face/plate stand-in, a raster crop, or an icon.
21628
21653
  *
21629
21654
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
21630
21655
  * the TILE ranked below native, so a track whose thumbnail landed natively
21631
21656
  * while its key frame missed carried no reason at all — three of the four
21632
21657
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
21633
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
21658
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
21634
21659
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
21635
21660
  * lastFrame copy source`), so its absence is now on this line whatever the
21636
21661
  * tile ended up being.
@@ -21717,7 +21742,7 @@ var MotionEventSchema = object({
21717
21742
  /**
21718
21743
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
21719
21744
  * first entry is always `0`) of every genuine off→on transition the
21720
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
21745
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
21721
21746
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
21722
21747
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
21723
21748
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -22241,6 +22266,7 @@ var KeyEventSchema = object({
22241
22266
  bestEventId: string(),
22242
22267
  /** Track lifetime in ms (lastSeen - firstSeen). */
22243
22268
  windowMs: number().optional(),
22269
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
22244
22270
  ...TrackFlagFields,
22245
22271
  ...TrackRetrainFields
22246
22272
  });
@@ -26953,7 +26979,7 @@ var ClipPlaybackSchema = object({
26953
26979
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
26954
26980
  * time the camera is awake for its own reasons — is deliberately not a member:
26955
26981
  * it was proposed, it is free on the battery, and the operator declined it on
26956
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
26982
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
26957
26983
  * D558 "Considered and not taken").
26958
26984
  */
26959
26985
  var ClipWakeSchema = _enum(["authorised"]);
@@ -27214,7 +27240,7 @@ DeviceType.Camera, method(object({
27214
27240
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
27215
27241
  * assumed the answer was a fan-out over everything a camera has. The
27216
27242
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
27217
- * solo"* — so the list is asked of one provider at a time and there is
27243
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
27218
27244
  * nothing to filter out of it.
27219
27245
  */
27220
27246
  provider: string().min(1)
@@ -33332,7 +33358,7 @@ var ReadGopBytesResultSchema = object({
33332
33358
  /**
33333
33359
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
33334
33360
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
33335
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
33361
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
33336
33362
  * a replay needs several seconds of native pixels, not one frame.
33337
33363
  *
33338
33364
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -35948,6 +35974,7 @@ DeviceType.Camera, method(object({
35948
35974
  detection: array(ZoneRuleSchema).readonly(),
35949
35975
  package: array(ZoneRuleSchema).readonly()
35950
35976
  });
35977
+ SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
35951
35978
  /**
35952
35979
  * Accessory device helpers — shared across drivers.
35953
35980
  *
@@ -40926,6 +40953,12 @@ Object.freeze({
40926
40953
  addonId: null,
40927
40954
  access: "view"
40928
40955
  },
40956
+ "notificationRules.getAlarmSensors": {
40957
+ capName: "notification-rules",
40958
+ capScope: "system",
40959
+ addonId: null,
40960
+ access: "view"
40961
+ },
40929
40962
  "notificationRules.getClipRetentionAsks": {
40930
40963
  capName: "notification-rules",
40931
40964
  capScope: "system",
@@ -44504,6 +44537,11 @@ Object.freeze({
44504
44537
  }
44505
44538
  });
44506
44539
  Object.freeze({
44540
+ "accessories.getStatus": [{
44541
+ name: "deviceId",
44542
+ form: "single",
44543
+ optional: false
44544
+ }],
44507
44545
  "accessories.setChildHidden": [{
44508
44546
  name: "childDeviceId",
44509
44547
  form: "single",
@@ -44523,6 +44561,11 @@ Object.freeze({
44523
44561
  form: "single",
44524
44562
  optional: false
44525
44563
  }],
44564
+ "airQualitySensor.getStatus": [{
44565
+ name: "deviceId",
44566
+ form: "single",
44567
+ optional: false
44568
+ }],
44526
44569
  "alarmPanel.arm": [{
44527
44570
  name: "deviceId",
44528
44571
  form: "single",
@@ -44533,11 +44576,36 @@ Object.freeze({
44533
44576
  form: "single",
44534
44577
  optional: false
44535
44578
  }],
44579
+ "alarmPanel.getStatus": [{
44580
+ name: "deviceId",
44581
+ form: "single",
44582
+ optional: false
44583
+ }],
44536
44584
  "alarmPanel.trigger": [{
44537
44585
  name: "deviceId",
44538
44586
  form: "single",
44539
44587
  optional: false
44540
44588
  }],
44589
+ "ambientLightSensor.getStatus": [{
44590
+ name: "deviceId",
44591
+ form: "single",
44592
+ optional: false
44593
+ }],
44594
+ "audioAnalysis.applyDeviceSettingsPatch": [{
44595
+ name: "deviceId",
44596
+ form: "single",
44597
+ optional: false
44598
+ }],
44599
+ "audioAnalysis.getDeviceLiveContribution": [{
44600
+ name: "deviceId",
44601
+ form: "single",
44602
+ optional: false
44603
+ }],
44604
+ "audioAnalysis.getDeviceSettingsContribution": [{
44605
+ name: "deviceId",
44606
+ form: "single",
44607
+ optional: false
44608
+ }],
44541
44609
  "audioAnalysis.resolveDeviceSettings": [{
44542
44610
  name: "deviceId",
44543
44611
  form: "single",
@@ -44578,16 +44646,36 @@ Object.freeze({
44578
44646
  form: "single",
44579
44647
  optional: false
44580
44648
  }],
44649
+ "automationControl.getStatus": [{
44650
+ name: "deviceId",
44651
+ form: "single",
44652
+ optional: false
44653
+ }],
44581
44654
  "automationControl.trigger": [{
44582
44655
  name: "deviceId",
44583
44656
  form: "single",
44584
44657
  optional: false
44585
44658
  }],
44659
+ "battery.getStatus": [{
44660
+ name: "deviceId",
44661
+ form: "single",
44662
+ optional: false
44663
+ }],
44586
44664
  "battery.wakeForStream": [{
44587
44665
  name: "deviceId",
44588
44666
  form: "single",
44589
44667
  optional: false
44590
44668
  }],
44669
+ "binary.getStatus": [{
44670
+ name: "deviceId",
44671
+ form: "single",
44672
+ optional: false
44673
+ }],
44674
+ "brightness.getStatus": [{
44675
+ name: "deviceId",
44676
+ form: "single",
44677
+ optional: false
44678
+ }],
44591
44679
  "brightness.setBrightness": [{
44592
44680
  name: "deviceId",
44593
44681
  form: "single",
@@ -44603,6 +44691,26 @@ Object.freeze({
44603
44691
  form: "single",
44604
44692
  optional: false
44605
44693
  }],
44694
+ "cameraCredentials.getStatus": [{
44695
+ name: "deviceId",
44696
+ form: "single",
44697
+ optional: false
44698
+ }],
44699
+ "cameraGridLayout.applyDeviceSettingsPatch": [{
44700
+ name: "deviceId",
44701
+ form: "single",
44702
+ optional: false
44703
+ }],
44704
+ "cameraGridLayout.getDeviceLiveContribution": [{
44705
+ name: "deviceId",
44706
+ form: "single",
44707
+ optional: false
44708
+ }],
44709
+ "cameraGridLayout.getDeviceSettingsContribution": [{
44710
+ name: "deviceId",
44711
+ form: "single",
44712
+ optional: false
44713
+ }],
44606
44714
  "cameraGridLayout.getLayout": [{
44607
44715
  name: "deviceId",
44608
44716
  form: "single",
@@ -44618,6 +44726,21 @@ Object.freeze({
44618
44726
  form: "single",
44619
44727
  optional: false
44620
44728
  }],
44729
+ "cameraPipelineConfig.applyDeviceSettingsPatch": [{
44730
+ name: "deviceId",
44731
+ form: "single",
44732
+ optional: false
44733
+ }],
44734
+ "cameraPipelineConfig.getDeviceLiveContribution": [{
44735
+ name: "deviceId",
44736
+ form: "single",
44737
+ optional: false
44738
+ }],
44739
+ "cameraPipelineConfig.getDeviceSettingsContribution": [{
44740
+ name: "deviceId",
44741
+ form: "single",
44742
+ optional: false
44743
+ }],
44621
44744
  "cameraStreams.getBrokerStreams": [{
44622
44745
  name: "deviceId",
44623
44746
  form: "single",
@@ -44643,6 +44766,16 @@ Object.freeze({
44643
44766
  form: "single",
44644
44767
  optional: false
44645
44768
  }],
44769
+ "carbonMonoxide.getStatus": [{
44770
+ name: "deviceId",
44771
+ form: "single",
44772
+ optional: false
44773
+ }],
44774
+ "climateControl.getStatus": [{
44775
+ name: "deviceId",
44776
+ form: "single",
44777
+ optional: false
44778
+ }],
44646
44779
  "climateControl.setFanMode": [{
44647
44780
  name: "deviceId",
44648
44781
  form: "single",
@@ -44683,16 +44816,41 @@ Object.freeze({
44683
44816
  form: "single",
44684
44817
  optional: false
44685
44818
  }],
44819
+ "color.getStatus": [{
44820
+ name: "deviceId",
44821
+ form: "single",
44822
+ optional: false
44823
+ }],
44686
44824
  "color.setColor": [{
44687
44825
  name: "deviceId",
44688
44826
  form: "single",
44689
44827
  optional: false
44690
44828
  }],
44829
+ "connectivity.getStatus": [{
44830
+ name: "deviceId",
44831
+ form: "single",
44832
+ optional: false
44833
+ }],
44834
+ "consumables.getStatus": [{
44835
+ name: "deviceId",
44836
+ form: "single",
44837
+ optional: false
44838
+ }],
44691
44839
  "consumables.reset": [{
44692
44840
  name: "deviceId",
44693
44841
  form: "single",
44694
44842
  optional: false
44695
44843
  }],
44844
+ "contact.getStatus": [{
44845
+ name: "deviceId",
44846
+ form: "single",
44847
+ optional: false
44848
+ }],
44849
+ "control.getStatus": [{
44850
+ name: "deviceId",
44851
+ form: "single",
44852
+ optional: false
44853
+ }],
44696
44854
  "control.setValue": [{
44697
44855
  name: "deviceId",
44698
44856
  form: "single",
@@ -44703,6 +44861,11 @@ Object.freeze({
44703
44861
  form: "single",
44704
44862
  optional: false
44705
44863
  }],
44864
+ "cover.getStatus": [{
44865
+ name: "deviceId",
44866
+ form: "single",
44867
+ optional: false
44868
+ }],
44706
44869
  "cover.open": [{
44707
44870
  name: "deviceId",
44708
44871
  form: "single",
@@ -44728,6 +44891,11 @@ Object.freeze({
44728
44891
  form: "single",
44729
44892
  optional: false
44730
44893
  }],
44894
+ "dayNight.getStatus": [{
44895
+ name: "deviceId",
44896
+ form: "single",
44897
+ optional: false
44898
+ }],
44731
44899
  "dayNight.setSettings": [{
44732
44900
  name: "deviceId",
44733
44901
  form: "single",
@@ -44738,11 +44906,31 @@ Object.freeze({
44738
44906
  form: "single",
44739
44907
  optional: true
44740
44908
  }],
44909
+ "detectionPipeline.applyDeviceSettingsPatch": [{
44910
+ name: "deviceId",
44911
+ form: "single",
44912
+ optional: false
44913
+ }],
44914
+ "detectionPipeline.getDeviceLiveContribution": [{
44915
+ name: "deviceId",
44916
+ form: "single",
44917
+ optional: false
44918
+ }],
44919
+ "detectionPipeline.getDeviceSettingsContribution": [{
44920
+ name: "deviceId",
44921
+ form: "single",
44922
+ optional: false
44923
+ }],
44741
44924
  "deviceAdminLink.getAdminLink": [{
44742
44925
  name: "deviceId",
44743
44926
  form: "single",
44744
44927
  optional: false
44745
44928
  }],
44929
+ "deviceAdoption.getStatus": [{
44930
+ name: "deviceId",
44931
+ form: "single",
44932
+ optional: false
44933
+ }],
44746
44934
  "deviceAdoption.release": [{
44747
44935
  name: "camDeviceId",
44748
44936
  form: "single",
@@ -44758,6 +44946,11 @@ Object.freeze({
44758
44946
  form: "single",
44759
44947
  optional: false
44760
44948
  }],
44949
+ "deviceDiscovery.getStatus": [{
44950
+ name: "deviceId",
44951
+ form: "single",
44952
+ optional: false
44953
+ }],
44761
44954
  "deviceDiscovery.listDiscovered": [{
44762
44955
  name: "deviceId",
44763
44956
  form: "single",
@@ -44777,6 +44970,21 @@ Object.freeze({
44777
44970
  form: "single",
44778
44971
  optional: false
44779
44972
  }],
44973
+ "deviceExport.applyDeviceSettingsPatch": [{
44974
+ name: "deviceId",
44975
+ form: "single",
44976
+ optional: false
44977
+ }],
44978
+ "deviceExport.getDeviceLiveContribution": [{
44979
+ name: "deviceId",
44980
+ form: "single",
44981
+ optional: false
44982
+ }],
44983
+ "deviceExport.getDeviceSettingsContribution": [{
44984
+ name: "deviceId",
44985
+ form: "single",
44986
+ optional: false
44987
+ }],
44780
44988
  "deviceExtension.listCandidates": [{
44781
44989
  name: "deviceId",
44782
44990
  form: "single",
@@ -45125,6 +45333,26 @@ Object.freeze({
45125
45333
  form: "single",
45126
45334
  optional: false
45127
45335
  }],
45336
+ "deviceStatus.getStatus": [{
45337
+ name: "deviceId",
45338
+ form: "single",
45339
+ optional: false
45340
+ }],
45341
+ "doorbell.getStatus": [{
45342
+ name: "deviceId",
45343
+ form: "single",
45344
+ optional: false
45345
+ }],
45346
+ "enumSensor.getStatus": [{
45347
+ name: "deviceId",
45348
+ form: "single",
45349
+ optional: false
45350
+ }],
45351
+ "eventEmitter.getStatus": [{
45352
+ name: "deviceId",
45353
+ form: "single",
45354
+ optional: false
45355
+ }],
45128
45356
  "faceGallery.getFaceByTrack": [{
45129
45357
  name: "deviceId",
45130
45358
  form: "single",
@@ -45139,6 +45367,11 @@ Object.freeze({
45139
45367
  form: "array",
45140
45368
  optional: true
45141
45369
  }],
45370
+ "fanControl.getStatus": [{
45371
+ name: "deviceId",
45372
+ form: "single",
45373
+ optional: false
45374
+ }],
45142
45375
  "fanControl.setDirection": [{
45143
45376
  name: "deviceId",
45144
45377
  form: "single",
@@ -45159,6 +45392,26 @@ Object.freeze({
45159
45392
  form: "single",
45160
45393
  optional: false
45161
45394
  }],
45395
+ "featureProbe.getStatus": [{
45396
+ name: "deviceId",
45397
+ form: "single",
45398
+ optional: false
45399
+ }],
45400
+ "flood.getStatus": [{
45401
+ name: "deviceId",
45402
+ form: "single",
45403
+ optional: false
45404
+ }],
45405
+ "gas.getStatus": [{
45406
+ name: "deviceId",
45407
+ form: "single",
45408
+ optional: false
45409
+ }],
45410
+ "humidifier.getStatus": [{
45411
+ name: "deviceId",
45412
+ form: "single",
45413
+ optional: false
45414
+ }],
45162
45415
  "humidifier.setMode": [{
45163
45416
  name: "deviceId",
45164
45417
  form: "single",
@@ -45174,11 +45427,26 @@ Object.freeze({
45174
45427
  form: "single",
45175
45428
  optional: false
45176
45429
  }],
45430
+ "humiditySensor.getStatus": [{
45431
+ name: "deviceId",
45432
+ form: "single",
45433
+ optional: false
45434
+ }],
45435
+ "image.getStatus": [{
45436
+ name: "deviceId",
45437
+ form: "single",
45438
+ optional: false
45439
+ }],
45177
45440
  "imageSettings.getOptions": [{
45178
45441
  name: "deviceId",
45179
45442
  form: "single",
45180
45443
  optional: false
45181
45444
  }],
45445
+ "imageSettings.getStatus": [{
45446
+ name: "deviceId",
45447
+ form: "single",
45448
+ optional: false
45449
+ }],
45182
45450
  "imageSettings.setSettings": [{
45183
45451
  name: "deviceId",
45184
45452
  form: "single",
@@ -45189,6 +45457,11 @@ Object.freeze({
45189
45457
  form: "single",
45190
45458
  optional: false
45191
45459
  }],
45460
+ "intercom.getStatus": [{
45461
+ name: "deviceId",
45462
+ form: "single",
45463
+ optional: false
45464
+ }],
45192
45465
  "intercom.handleAnswer": [{
45193
45466
  name: "deviceId",
45194
45467
  form: "single",
@@ -45219,6 +45492,11 @@ Object.freeze({
45219
45492
  form: "single",
45220
45493
  optional: false
45221
45494
  }],
45495
+ "lawnMowerControl.getStatus": [{
45496
+ name: "deviceId",
45497
+ form: "single",
45498
+ optional: false
45499
+ }],
45222
45500
  "lawnMowerControl.pause": [{
45223
45501
  name: "deviceId",
45224
45502
  form: "single",
@@ -45229,6 +45507,11 @@ Object.freeze({
45229
45507
  form: "single",
45230
45508
  optional: false
45231
45509
  }],
45510
+ "lockControl.getStatus": [{
45511
+ name: "deviceId",
45512
+ form: "single",
45513
+ optional: false
45514
+ }],
45232
45515
  "lockControl.lock": [{
45233
45516
  name: "deviceId",
45234
45517
  form: "single",
@@ -45244,6 +45527,11 @@ Object.freeze({
45244
45527
  form: "single",
45245
45528
  optional: false
45246
45529
  }],
45530
+ "mediaPlayer.getStatus": [{
45531
+ name: "deviceId",
45532
+ form: "single",
45533
+ optional: false
45534
+ }],
45247
45535
  "mediaPlayer.next": [{
45248
45536
  name: "deviceId",
45249
45537
  form: "single",
@@ -45304,6 +45592,11 @@ Object.freeze({
45304
45592
  form: "single",
45305
45593
  optional: false
45306
45594
  }],
45595
+ "motion.getStatus": [{
45596
+ name: "deviceId",
45597
+ form: "single",
45598
+ optional: false
45599
+ }],
45307
45600
  "motion.isDetected": [{
45308
45601
  name: "deviceId",
45309
45602
  form: "single",
@@ -45314,11 +45607,31 @@ Object.freeze({
45314
45607
  form: "single",
45315
45608
  optional: false
45316
45609
  }],
45610
+ "motionDetection.applyDeviceSettingsPatch": [{
45611
+ name: "deviceId",
45612
+ form: "single",
45613
+ optional: false
45614
+ }],
45615
+ "motionDetection.getDeviceLiveContribution": [{
45616
+ name: "deviceId",
45617
+ form: "single",
45618
+ optional: false
45619
+ }],
45620
+ "motionDetection.getDeviceSettingsContribution": [{
45621
+ name: "deviceId",
45622
+ form: "single",
45623
+ optional: false
45624
+ }],
45317
45625
  "motionDetection.removeCamera": [{
45318
45626
  name: "deviceId",
45319
45627
  form: "single",
45320
45628
  optional: false
45321
45629
  }],
45630
+ "motionTrigger.getStatus": [{
45631
+ name: "deviceId",
45632
+ form: "single",
45633
+ optional: false
45634
+ }],
45322
45635
  "motionTrigger.setMotionTrigger": [{
45323
45636
  name: "deviceId",
45324
45637
  form: "single",
@@ -45329,6 +45642,11 @@ Object.freeze({
45329
45642
  form: "single",
45330
45643
  optional: false
45331
45644
  }],
45645
+ "motionZones.getStatus": [{
45646
+ name: "deviceId",
45647
+ form: "single",
45648
+ optional: false
45649
+ }],
45332
45650
  "motionZones.setZone": [{
45333
45651
  name: "deviceId",
45334
45652
  form: "single",
@@ -45339,6 +45657,11 @@ Object.freeze({
45339
45657
  form: "single",
45340
45658
  optional: false
45341
45659
  }],
45660
+ "nativeObjectDetection.getStatus": [{
45661
+ name: "deviceId",
45662
+ form: "single",
45663
+ optional: false
45664
+ }],
45342
45665
  "nativeObjectDetection.setEnabled": [{
45343
45666
  name: "deviceId",
45344
45667
  form: "single",
@@ -45354,6 +45677,11 @@ Object.freeze({
45354
45677
  form: "single",
45355
45678
  optional: false
45356
45679
  }],
45680
+ "navigation.getStatus": [{
45681
+ name: "deviceId",
45682
+ form: "single",
45683
+ optional: false
45684
+ }],
45357
45685
  "navigation.goToPoint": [{
45358
45686
  name: "deviceId",
45359
45687
  form: "single",
@@ -45399,6 +45727,11 @@ Object.freeze({
45399
45727
  form: "single",
45400
45728
  optional: false
45401
45729
  }],
45730
+ "networkLink.getStatus": [{
45731
+ name: "deviceId",
45732
+ form: "single",
45733
+ optional: false
45734
+ }],
45402
45735
  "networkQuality.getDeviceStats": [{
45403
45736
  name: "deviceId",
45404
45737
  form: "single",
@@ -45409,6 +45742,11 @@ Object.freeze({
45409
45742
  form: "single",
45410
45743
  optional: false
45411
45744
  }],
45745
+ "notificationRules.getAlarmSensors": [{
45746
+ name: "deviceIds",
45747
+ form: "array",
45748
+ optional: false
45749
+ }],
45412
45750
  "notificationRules.setDeviceMuted": [{
45413
45751
  name: "deviceId",
45414
45752
  form: "single",
@@ -45419,11 +45757,26 @@ Object.freeze({
45419
45757
  form: "single",
45420
45758
  optional: false
45421
45759
  }],
45760
+ "notifier.getStatus": [{
45761
+ name: "deviceId",
45762
+ form: "single",
45763
+ optional: false
45764
+ }],
45422
45765
  "notifier.send": [{
45423
45766
  name: "deviceId",
45424
45767
  form: "single",
45425
45768
  optional: false
45426
45769
  }],
45770
+ "numericSensor.getStatus": [{
45771
+ name: "deviceId",
45772
+ form: "single",
45773
+ optional: false
45774
+ }],
45775
+ "osd.getStatus": [{
45776
+ name: "deviceId",
45777
+ form: "single",
45778
+ optional: false
45779
+ }],
45427
45780
  "osd.setOverlay": [{
45428
45781
  name: "deviceId",
45429
45782
  form: "single",
@@ -45483,6 +45836,11 @@ Object.freeze({
45483
45836
  form: "single",
45484
45837
  optional: false
45485
45838
  }],
45839
+ "petFeeder.getStatus": [{
45840
+ name: "deviceId",
45841
+ form: "single",
45842
+ optional: false
45843
+ }],
45486
45844
  "petFeeder.markFoodReplenished": [{
45487
45845
  name: "deviceId",
45488
45846
  form: "single",
@@ -45518,6 +45876,11 @@ Object.freeze({
45518
45876
  form: "single",
45519
45877
  optional: false
45520
45878
  }],
45879
+ "pipelineAnalytics.applyDeviceSettingsPatch": [{
45880
+ name: "deviceId",
45881
+ form: "single",
45882
+ optional: false
45883
+ }],
45521
45884
  "pipelineAnalytics.clearTrackRelation": [{
45522
45885
  name: "deviceId",
45523
45886
  form: "single",
@@ -45558,6 +45921,16 @@ Object.freeze({
45558
45921
  form: "single",
45559
45922
  optional: false
45560
45923
  }],
45924
+ "pipelineAnalytics.getDeviceLiveContribution": [{
45925
+ name: "deviceId",
45926
+ form: "single",
45927
+ optional: false
45928
+ }],
45929
+ "pipelineAnalytics.getDeviceSettingsContribution": [{
45930
+ name: "deviceId",
45931
+ form: "single",
45932
+ optional: false
45933
+ }],
45561
45934
  "pipelineAnalytics.getEventDensity": [{
45562
45935
  name: "deviceId",
45563
45936
  form: "single",
@@ -45773,6 +46146,11 @@ Object.freeze({
45773
46146
  form: "single",
45774
46147
  optional: true
45775
46148
  }],
46149
+ "pipelineOrchestrator.applyDeviceSettingsPatch": [{
46150
+ name: "deviceId",
46151
+ form: "single",
46152
+ optional: false
46153
+ }],
45776
46154
  "pipelineOrchestrator.assignAudio": [{
45777
46155
  name: "deviceId",
45778
46156
  form: "single",
@@ -45818,6 +46196,16 @@ Object.freeze({
45818
46196
  form: "single",
45819
46197
  optional: false
45820
46198
  }],
46199
+ "pipelineOrchestrator.getDeviceLiveContribution": [{
46200
+ name: "deviceId",
46201
+ form: "single",
46202
+ optional: false
46203
+ }],
46204
+ "pipelineOrchestrator.getDeviceSettingsContribution": [{
46205
+ name: "deviceId",
46206
+ form: "single",
46207
+ optional: false
46208
+ }],
45821
46209
  "pipelineOrchestrator.getPipelineAssignment": [{
45822
46210
  name: "deviceId",
45823
46211
  form: "single",
@@ -45938,11 +46326,31 @@ Object.freeze({
45938
46326
  form: "single",
45939
46327
  optional: true
45940
46328
  }],
46329
+ "powerMeter.getStatus": [{
46330
+ name: "deviceId",
46331
+ form: "single",
46332
+ optional: false
46333
+ }],
46334
+ "presence.getStatus": [{
46335
+ name: "deviceId",
46336
+ form: "single",
46337
+ optional: false
46338
+ }],
46339
+ "pressureSensor.getStatus": [{
46340
+ name: "deviceId",
46341
+ form: "single",
46342
+ optional: false
46343
+ }],
45941
46344
  "privacyMask.getOptions": [{
45942
46345
  name: "deviceId",
45943
46346
  form: "single",
45944
46347
  optional: false
45945
46348
  }],
46349
+ "privacyMask.getStatus": [{
46350
+ name: "deviceId",
46351
+ form: "single",
46352
+ optional: false
46353
+ }],
45946
46354
  "privacyMask.setAudioEnabled": [{
45947
46355
  name: "deviceId",
45948
46356
  form: "single",
@@ -45993,6 +46401,11 @@ Object.freeze({
45993
46401
  form: "single",
45994
46402
  optional: false
45995
46403
  }],
46404
+ "ptz.getStatus": [{
46405
+ name: "deviceId",
46406
+ form: "single",
46407
+ optional: false
46408
+ }],
45996
46409
  "ptz.goHome": [{
45997
46410
  name: "deviceId",
45998
46411
  form: "single",
@@ -46083,6 +46496,11 @@ Object.freeze({
46083
46496
  form: "single",
46084
46497
  optional: false
46085
46498
  }],
46499
+ "recordingArchive.applyDeviceSettingsPatch": [{
46500
+ name: "deviceId",
46501
+ form: "single",
46502
+ optional: false
46503
+ }],
46086
46504
  "recordingArchive.deleteFootprint": [{
46087
46505
  name: "deviceId",
46088
46506
  form: "single",
@@ -46103,6 +46521,21 @@ Object.freeze({
46103
46521
  form: "single",
46104
46522
  optional: false
46105
46523
  }],
46524
+ "recordingArchive.getDeviceLiveContribution": [{
46525
+ name: "deviceId",
46526
+ form: "single",
46527
+ optional: false
46528
+ }],
46529
+ "recordingArchive.getDeviceSettingsContribution": [{
46530
+ name: "deviceId",
46531
+ form: "single",
46532
+ optional: false
46533
+ }],
46534
+ "recordingArchive.getStatus": [{
46535
+ name: "deviceId",
46536
+ form: "single",
46537
+ optional: false
46538
+ }],
46106
46539
  "recordingArchive.listOpsLog": [{
46107
46540
  name: "deviceId",
46108
46541
  form: "single",
@@ -46188,6 +46621,11 @@ Object.freeze({
46188
46621
  form: "single",
46189
46622
  optional: false
46190
46623
  }],
46624
+ "recordingOnboard.getStatus": [{
46625
+ name: "deviceId",
46626
+ form: "single",
46627
+ optional: false
46628
+ }],
46191
46629
  "recordingOnboard.setSettings": [{
46192
46630
  name: "deviceId",
46193
46631
  form: "single",
@@ -46218,6 +46656,11 @@ Object.freeze({
46218
46656
  form: "single",
46219
46657
  optional: false
46220
46658
  }],
46659
+ "sceneMonitor.getStatus": [{
46660
+ name: "deviceId",
46661
+ form: "single",
46662
+ optional: false
46663
+ }],
46221
46664
  "sceneMonitor.listScenes": [{
46222
46665
  name: "deviceId",
46223
46666
  form: "single",
@@ -46243,6 +46686,11 @@ Object.freeze({
46243
46686
  form: "single",
46244
46687
  optional: false
46245
46688
  }],
46689
+ "scriptRunner.getStatus": [{
46690
+ name: "deviceId",
46691
+ form: "single",
46692
+ optional: false
46693
+ }],
46246
46694
  "scriptRunner.run": [{
46247
46695
  name: "deviceId",
46248
46696
  form: "single",
@@ -46253,11 +46701,31 @@ Object.freeze({
46253
46701
  form: "single",
46254
46702
  optional: false
46255
46703
  }],
46704
+ "smoke.getStatus": [{
46705
+ name: "deviceId",
46706
+ form: "single",
46707
+ optional: false
46708
+ }],
46709
+ "snapshot.applyDeviceSettingsPatch": [{
46710
+ name: "deviceId",
46711
+ form: "single",
46712
+ optional: false
46713
+ }],
46256
46714
  "snapshot.getDebugState": [{
46257
46715
  name: "deviceId",
46258
46716
  form: "single",
46259
46717
  optional: false
46260
46718
  }],
46719
+ "snapshot.getDeviceLiveContribution": [{
46720
+ name: "deviceId",
46721
+ form: "single",
46722
+ optional: false
46723
+ }],
46724
+ "snapshot.getDeviceSettingsContribution": [{
46725
+ name: "deviceId",
46726
+ form: "single",
46727
+ optional: false
46728
+ }],
46261
46729
  "snapshot.getSnapshot": [{
46262
46730
  name: "deviceId",
46263
46731
  form: "single",
@@ -46274,6 +46742,11 @@ Object.freeze({
46274
46742
  form: "array",
46275
46743
  optional: false
46276
46744
  }],
46745
+ "snapshot.getStatus": [{
46746
+ name: "deviceId",
46747
+ form: "single",
46748
+ optional: false
46749
+ }],
46277
46750
  "snapshot.invalidateCache": [{
46278
46751
  name: "deviceId",
46279
46752
  form: "single",
@@ -46284,6 +46757,11 @@ Object.freeze({
46284
46757
  form: "single",
46285
46758
  optional: false
46286
46759
  }],
46760
+ "streamBroker.applyDeviceSettingsPatch": [{
46761
+ name: "deviceId",
46762
+ form: "single",
46763
+ optional: false
46764
+ }],
46287
46765
  "streamBroker.assignProfile": [{
46288
46766
  name: "deviceId",
46289
46767
  form: "single",
@@ -46299,6 +46777,16 @@ Object.freeze({
46299
46777
  form: "single",
46300
46778
  optional: false
46301
46779
  }],
46780
+ "streamBroker.getDeviceLiveContribution": [{
46781
+ name: "deviceId",
46782
+ form: "single",
46783
+ optional: false
46784
+ }],
46785
+ "streamBroker.getDeviceSettingsContribution": [{
46786
+ name: "deviceId",
46787
+ form: "single",
46788
+ optional: false
46789
+ }],
46302
46790
  "streamBroker.getStreamWithCodec": [{
46303
46791
  name: "deviceId",
46304
46792
  form: "single",
@@ -46359,16 +46847,46 @@ Object.freeze({
46359
46847
  form: "single",
46360
46848
  optional: false
46361
46849
  }],
46850
+ "streamParams.getStatus": [{
46851
+ name: "deviceId",
46852
+ form: "single",
46853
+ optional: false
46854
+ }],
46362
46855
  "streamParams.setProfile": [{
46363
46856
  name: "deviceId",
46364
46857
  form: "single",
46365
46858
  optional: false
46366
46859
  }],
46860
+ "switch.getStatus": [{
46861
+ name: "deviceId",
46862
+ form: "single",
46863
+ optional: false
46864
+ }],
46367
46865
  "switch.setState": [{
46368
46866
  name: "deviceId",
46369
46867
  form: "single",
46370
46868
  optional: false
46371
46869
  }],
46870
+ "tamper.getStatus": [{
46871
+ name: "deviceId",
46872
+ form: "single",
46873
+ optional: false
46874
+ }],
46875
+ "temperatureSensor.getStatus": [{
46876
+ name: "deviceId",
46877
+ form: "single",
46878
+ optional: false
46879
+ }],
46880
+ "update.getStatus": [{
46881
+ name: "deviceId",
46882
+ form: "single",
46883
+ optional: false
46884
+ }],
46885
+ "vacuumControl.getStatus": [{
46886
+ name: "deviceId",
46887
+ form: "single",
46888
+ optional: false
46889
+ }],
46372
46890
  "vacuumControl.locate": [{
46373
46891
  name: "deviceId",
46374
46892
  form: "single",
@@ -46404,6 +46922,11 @@ Object.freeze({
46404
46922
  form: "single",
46405
46923
  optional: false
46406
46924
  }],
46925
+ "valve.getStatus": [{
46926
+ name: "deviceId",
46927
+ form: "single",
46928
+ optional: false
46929
+ }],
46407
46930
  "valve.open": [{
46408
46931
  name: "deviceId",
46409
46932
  form: "single",
@@ -46419,6 +46942,11 @@ Object.freeze({
46419
46942
  form: "single",
46420
46943
  optional: false
46421
46944
  }],
46945
+ "vibration.getStatus": [{
46946
+ name: "deviceId",
46947
+ form: "single",
46948
+ optional: false
46949
+ }],
46422
46950
  "videoclips.dialClipStream": [{
46423
46951
  name: "deviceId",
46424
46952
  form: "single",
@@ -46454,6 +46982,11 @@ Object.freeze({
46454
46982
  form: "single",
46455
46983
  optional: false
46456
46984
  }],
46985
+ "waterHeater.getStatus": [{
46986
+ name: "deviceId",
46987
+ form: "single",
46988
+ optional: false
46989
+ }],
46457
46990
  "waterHeater.setAway": [{
46458
46991
  name: "deviceId",
46459
46992
  form: "single",
@@ -46469,6 +47002,11 @@ Object.freeze({
46469
47002
  form: "single",
46470
47003
  optional: false
46471
47004
  }],
47005
+ "weather.getStatus": [{
47006
+ name: "deviceId",
47007
+ form: "single",
47008
+ optional: false
47009
+ }],
46472
47010
  "webrtcSession.addIceCandidate": [{
46473
47011
  name: "deviceId",
46474
47012
  form: "single",
@@ -47206,7 +47744,7 @@ var PreviewTextField = string().max(200);
47206
47744
  * Whether the notification's preview is a STILL or a short animation.
47207
47745
  *
47208
47746
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
47209
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
47747
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
47210
47748
  * night reads better as three seconds of motion than as one frame of it. Both
47211
47749
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
47212
47750
  * simply applies it to a dozen frames sampled across the render and assembles