@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.
@@ -7440,7 +7440,7 @@ function errMsg(err) {
7440
7440
  return String(err);
7441
7441
  }
7442
7442
  //#endregion
7443
- //#region ../types/dist/composition-43aqsZQj.mjs
7443
+ //#region ../types/dist/composition-Bzr7GwgP.mjs
7444
7444
  /**
7445
7445
  * The ffmpeg build every CamStack node downloads, per platform and arch.
7446
7446
  *
@@ -7494,20 +7494,20 @@ function portable(target) {
7494
7494
  }
7495
7495
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7496
7496
  /**
7497
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7498
- * valutatore puro del suo FRONTE.
7497
+ * THE table "which boolean of this device type counts as HIGH", and the
7498
+ * pure evaluator of its EDGE.
7499
7499
  *
7500
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7501
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7502
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7503
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7504
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7505
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7500
+ * ONE table for everyone who asks "is this device HIGH?": the
7501
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7502
+ * sensor markers, the orchestrator's camera-sensors bridge and
7503
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7504
+ * A second copy would diverge at the first cap added, and the symptom — "the
7505
+ * sensor rings the doorbell but does not record" — is exactly D62.
7506
7506
  *
7507
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7508
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7509
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7510
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7507
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7508
+ * two must not be unified: that one answers "what is the state WORD for a
7509
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7510
+ * boolean's EDGE counts". Deliberately different vocabularies.
7511
7511
  */
7512
7512
  /**
7513
7513
  * Known binary / switch source caps → the boolean slice field whose
@@ -7528,6 +7528,8 @@ var SOURCE_CAP_ACTIVE_FIELD = {
7528
7528
  vibration: "detected",
7529
7529
  tamper: "tampered"
7530
7530
  };
7531
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7532
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7531
7533
  /**
7532
7534
  * Error types for the safe expression engine. Two distinct classes so callers
7533
7535
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
@@ -9283,22 +9285,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9283
9285
  "package"
9284
9286
  ];
9285
9287
  /**
9286
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9287
- * un operatore può selezionare.
9288
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9289
+ * an operator can select.
9288
9290
  *
9289
- * Sono le tre offerte dallo step `object-detection`
9291
+ * They are the three offered by the `object-detection` step
9290
9292
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9291
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9292
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9293
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9294
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9293
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9294
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9295
+ * `package-detection`, whose enablement is driven by zones, and offering the
9296
+ * same word twice has already made an operator turn on the COCO proxy
9295
9297
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9296
9298
  *
9297
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9298
- * dello step e una seconda volta come union `FirstLevelMacro`
9299
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9300
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9301
- * successiva.
9299
+ * ONE list. Before today the same three were hand-written in the step's offer
9300
+ * and a second time as the union `FirstLevelMacro`
9301
+ * (`types/detection.ts`); a third copy for the recording trigger
9302
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9303
+ * invisible.
9302
9304
  */
9303
9305
  var FIRST_LEVEL_MACRO_CLASSES = [
9304
9306
  "person",
@@ -9363,17 +9365,17 @@ var RecordingStorageModeSchema = _enum([
9363
9365
  "on-device-decision"
9364
9366
  ]);
9365
9367
  /**
9366
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9367
- * tre offerte dallo step `object-detection`, da UNA lista
9368
+ * The macro classes that can open a recording window — the same
9369
+ * three offered by the `object-detection` step, from ONE list
9368
9370
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9369
9371
  */
9370
9372
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9371
9373
  /**
9372
- * True quando `values` non ripete un elemento.
9374
+ * True when `values` does not repeat an element.
9373
9375
  *
9374
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9375
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9376
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9376
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9377
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9378
+ * would count its windows twice in `segmentMissedByMs`.
9377
9379
  */
9378
9380
  var noDuplicates = (values) => new Set(values).size === values.length;
9379
9381
  /** Which detectors trigger an `events`-mode band. */
@@ -9381,34 +9383,34 @@ var RecordingTriggersSchema = object({
9381
9383
  motion: boolean().optional(),
9382
9384
  audioThresholdDbfs: number().optional(),
9383
9385
  /**
9384
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9385
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9386
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9387
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9386
+ * The macro classes whose detection opens a window. ABSENT = the source
9387
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9388
+ * trigger on, no class" is the same shape "enabled and records
9389
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9388
9390
  *
9389
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9390
- * quelle che hanno attraversato `enabledMacroClasses`, i
9391
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9392
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9393
- * finestre — vedi `recorder/object-trigger.ts`.
9391
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9392
+ * those that went through `enabledMacroClasses`, the
9393
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9394
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9395
+ * windows — see `recorder/object-trigger.ts`.
9394
9396
  */
9395
9397
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9396
9398
  /**
9397
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9398
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9399
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9400
+ * is not listened to; an empty array is rejected for the same reason as
9399
9401
  * `objectClasses`.
9400
9402
  *
9401
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9402
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9403
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9404
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9405
- * device (D12) — mai un elenco globale di cap.
9403
+ * These are SOURCE device ids, not cameras: the band names them, so the
9404
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9405
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9406
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9407
+ * device (D12) — never a global list of caps.
9406
9408
  *
9407
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9408
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9409
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9410
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9411
- * registrare.
9409
+ * What "high" means depends on the device TYPE and is not decided here:
9410
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9411
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9412
+ * the level: a contact found already open at runner restart does not
9413
+ * record.
9412
9414
  */
9413
9415
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9414
9416
  });
@@ -10485,7 +10487,7 @@ var DecoderSessionConfigSchema = object({
10485
10487
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
10486
10488
  * thing: the logging settings document on the `system` cap. Two authorities
10487
10489
  * over the values is the exact defect
10488
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
10490
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
10489
10491
  * remove; re-introducing it from the cure side would be grotesque.
10490
10492
  *
10491
10493
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -12310,7 +12312,7 @@ var BrokerStatusEnum = _enum([
12310
12312
  "unreachable",
12311
12313
  "error"
12312
12314
  ]);
12313
- var BrokerInfoSchema$1 = object({
12315
+ var BrokerInfoSchema = object({
12314
12316
  /** Stable broker id. Persisted; survives addon restarts. */
12315
12317
  id: string(),
12316
12318
  /** Addon id of the provider that OWNS this broker.
@@ -12443,7 +12445,7 @@ var GetStateInputSchema = object({
12443
12445
  * HA: entity_id (returns the cached entity state). */
12444
12446
  key: string()
12445
12447
  });
12446
- method(ListInputSchema, array(BrokerInfoSchema$1)), method(GetInputSchema, BrokerInfoSchema$1.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12448
+ method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12447
12449
  kind: "mutation",
12448
12450
  auth: "admin"
12449
12451
  }), method(RemoveInputSchema, _void(), {
@@ -14052,7 +14054,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
14052
14054
  *
14053
14055
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
14054
14056
  * was wrong — corrected 2026-08-26 after the hop map
14055
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
14057
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
14056
14058
  * There is **no Zod parse at all** between the door and the engine: the
14057
14059
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
14058
14060
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -14833,7 +14835,17 @@ var SiteZoneSchema = object({
14833
14835
  var ProviderStatusSchema = object({
14834
14836
  connected: boolean(),
14835
14837
  deviceCount: number(),
14836
- error: string().optional()
14838
+ error: string().optional(),
14839
+ /**
14840
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
14841
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
14842
+ * which every provider bundles, so only a provider BUILT from D696-amended
14843
+ * code says it. ABSENT means an older provider that may still write it (raw
14844
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
14845
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
14846
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
14847
+ */
14848
+ motionSliceWriter: literal("orchestrator").optional()
14837
14849
  });
14838
14850
  object({
14839
14851
  externalId: string(),
@@ -15969,7 +15981,7 @@ method(object({
15969
15981
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
15970
15982
  * ends in a log line, and a log line is the thing the operator asked to stop
15971
15983
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
15972
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
15984
+ * 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
15973
15985
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
15974
15986
  * media blackout were both diagnosed. The counters stay; this is where they can
15975
15987
  * be READ.
@@ -17345,7 +17357,7 @@ var BrokerStatusSchema$1 = _enum([
17345
17357
  "unreachable",
17346
17358
  "tls-error"
17347
17359
  ]);
17348
- var BrokerInfoSchema = object({
17360
+ var BrokerInfoSchema$1 = object({
17349
17361
  id: string(),
17350
17362
  name: string(),
17351
17363
  url: string(),
@@ -17408,7 +17420,7 @@ var StatusSchema = object({
17408
17420
  brokerCount: number(),
17409
17421
  embeddedRunning: boolean()
17410
17422
  });
17411
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17423
+ method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17412
17424
  kind: "mutation",
17413
17425
  auth: "admin"
17414
17426
  }), method(IdInputSchema, _void(), {
@@ -19584,78 +19596,16 @@ var NcRuleInputSchema = object({
19584
19596
  */
19585
19597
  confirm: NcConfirmSchema.optional(),
19586
19598
  /**
19587
- * WAIT for face/plate recognition before saying anything.
19588
- *
19589
- * A notification's TEXT is frozen at enqueue and its media is re-resolved at
19590
- * send; the identity is neither. A face is confirmed after `confirmFrames`
19591
- * agreeing observations — p50 **11.4 s** after the track was first seen,
19592
- * measured on this hub — and an `immediate` rule enqueues on the first object
19593
- * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
19594
- * immediate path, and no amount of media re-resolution fixes a sentence.
19595
- *
19596
- * Only two honest answers exist, and this flag picks between them. It has
19597
- * effect ONLY on a rule that declares a recognition scope
19598
- * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
19599
- * other rule there is nothing to wait for and the flag is inert.
19600
- *
19601
- * | value | what happens |
19602
- * | --- | --- |
19603
- * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
19604
- * | 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) |
19605
- *
19606
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19607
- * on the addon cap path, and absent has to keep meaning exactly what every
19608
- * rule authored before this field meant.
19609
- *
19610
- * The cost of `true` is stated here because the editor states it too: a rule
19611
- * that waits also inherits track-close SEMANTICS — its `zones` condition
19612
- * tests every zone the track visited and a `crossing` condition can no longer
19613
- * be satisfied, because a closed track carries no crossing.
19599
+ * IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
19600
+ * seconds; the rule sends ONE message when the window closes — early, once every
19601
+ * subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
19602
+ * the rule matched, with one mosaic tile per subject.
19603
+ * Absent = plain immediate (one message per track, at the first match).
19604
+ * Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
19605
+ * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
19606
+ * path does not run Zod defaults.
19614
19607
  */
19615
- waitForEnhancement: boolean().optional(),
19616
- /**
19617
- * GROUP a burst of subjects into ONE notification that grows.
19618
- *
19619
- * Seconds of quiet after the last matching subject before the burst is
19620
- * considered over. While it is open, the first subject enqueues immediately —
19621
- * **exactly as today, with no added latency** — and every real growth (a new
19622
- * subject, or a name confirmed on one already in it) REPLACES that
19623
- * notification with an updated one naming everybody. The push carries the
19624
- * group's own coalescing tag, so the phone replaces rather than stacks.
19625
- *
19626
- * `0` / absent = off, and off is today's behaviour byte for byte.
19627
- *
19628
- * ### Why an idle cutoff and not a window
19629
- *
19630
- * The measured seven-person arrival on device 590 spans 110 s with every
19631
- * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
19632
- * idle cutoff holds it as one and ends it when the arrival actually ends.
19633
- * 30 s is a widely shipped value for the same decision.
19634
- *
19635
- * ### What it replaces
19636
- *
19637
- * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
19638
- * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
19639
- * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
19640
- * track that did fire and 7 carrying a confirmed identity nobody heard about.
19641
- * A group collapses the same volume by MERGING, so the cooldown becomes a
19642
- * budget over GROUPS — which is what it always meant — and a growth is never
19643
- * throttled by the window its own first member spent.
19644
- *
19645
- * ### Interaction with {@link waitForEnhancement}
19646
- *
19647
- * They compose, and the order matters. `waitForEnhancement` defers the rule to
19648
- * TRACK CLOSE, so with both set the group is opened by the first member to
19649
- * CLOSE — already carrying its name — and grows as later members close. That
19650
- * is later, and complete. With grouping alone the group opens on the first
19651
- * object event and picks up names as they are confirmed, through the growth
19652
- * path. Neither combination fires twice for one subject.
19653
- *
19654
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19655
- * on the addon cap path, so absent must keep meaning what it meant before this
19656
- * field existed.
19657
- */
19658
- groupIdleSec: number().int().min(0).max(600).optional()
19608
+ groupingSec: number().int().min(5).max(60).optional()
19659
19609
  });
19660
19610
  /**
19661
19611
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -19703,9 +19653,10 @@ var NcRuleClearableKeySchema = _enum([
19703
19653
  "targetUsers",
19704
19654
  "snoozeOptions",
19705
19655
  "snoozeAllowGlobal",
19706
- "waitForEnhancement",
19707
19656
  "actions",
19708
19657
  "confirm",
19658
+ "groupingSec",
19659
+ "waitForEnhancement",
19709
19660
  "groupIdleSec"
19710
19661
  ]);
19711
19662
  var NcRuleUpdateInputSchema = object({
@@ -19727,9 +19678,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19727
19678
  */
19728
19679
  disabledTargetIds: array(string()).default([])
19729
19680
  });
19681
+ /**
19682
+ * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19683
+ * still-true state. `backups-exports` and `alarm` are not sections — a completed
19684
+ * job is not an open state, and the alarm stays instant.
19685
+ */
19686
+ var NcStateSummarySectionIdSchema = _enum([
19687
+ "device-state",
19688
+ "streams",
19689
+ "battery",
19690
+ "consumables",
19691
+ "tanks",
19692
+ "detection-blind",
19693
+ "nodes",
19694
+ "addons",
19695
+ "updates"
19696
+ ]);
19730
19697
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
19731
19698
  var NcStateSummaryPreviewSectionSchema = object({
19732
- id: string(),
19699
+ id: NcStateSummarySectionIdSchema,
19733
19700
  status: _enum(["read", "unavailable"]),
19734
19701
  items: number().int().nonnegative(),
19735
19702
  reason: string().optional()
@@ -19739,7 +19706,7 @@ var NcStateSummaryPreviewSectionSchema = object({
19739
19706
  * a `rule` split (no `section`), one section's on a `section` split.
19740
19707
  */
19741
19708
  var NcStateSummaryPreviewRowSchema = object({
19742
- section: string().optional(),
19709
+ section: NcStateSummarySectionIdSchema.optional(),
19743
19710
  /** The section's name on a per-section row; every reported section's, joined, on a combined one. */
19744
19711
  title: string(),
19745
19712
  text: string(),
@@ -20176,6 +20143,29 @@ object({
20176
20143
  firstAt: number(),
20177
20144
  lastAt: number()
20178
20145
  });
20146
+ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20147
+ var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20148
+ var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20149
+ var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20150
+ var NcAlarmModeDelaysListSchema = array(object({
20151
+ mode: AlarmArmModeSchema,
20152
+ exitDelaySec: NcAlarmDelaySecSchema.optional(),
20153
+ entryDelaySec: NcAlarmDelaySecSchema.optional(),
20154
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20155
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20156
+ var NcAlarmModeDelaysEditListSchema = array(object({
20157
+ mode: AlarmArmModeSchema,
20158
+ exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20159
+ entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20160
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20161
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20162
+ /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20163
+ var NcAlarmNonBlockingEditSchema = object({
20164
+ mode: AlarmArmModeSchema,
20165
+ deviceId: number().int().positive(),
20166
+ /** true = on the list (may be open, does not block); false = off the list (blocks). */
20167
+ nonBlocking: boolean()
20168
+ });
20179
20169
  /**
20180
20170
  * The per-mode lists, at most one per mode. Two lists for one mode have no
20181
20171
  * meaning a reader could agree on (union? the last one?), so they are refused
@@ -20184,10 +20174,10 @@ object({
20184
20174
  var NcAlarmNonBlockingListSchema = array(object({
20185
20175
  mode: AlarmArmModeSchema,
20186
20176
  deviceIds: array(number().int()).max(200)
20187
- })).max(8).refine((lists) => new Set(lists.map((l) => l.mode)).size === lists.length, { message: "nonBlocking: at most one list per arm mode" });
20177
+ })).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20188
20178
  /**
20189
- * The three durations the panel's state machine runs on, who hears about its
20190
- * transitions, and which openings each mode tolerates.
20179
+ * The three durations — global, and per mode since D697 — the panel's state
20180
+ * machine runs on, who hears about its transitions, and which openings each mode tolerates.
20191
20181
  *
20192
20182
  * They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
20193
20183
  * `alarm-panel` is `deviceNative` and its other provider mirrors somebody
@@ -20197,15 +20187,15 @@ var NcAlarmNonBlockingListSchema = array(object({
20197
20187
  */
20198
20188
  var NcAlarmSettingsSchema = object({
20199
20189
  /** Grace period between arming and the mode taking effect. 0 = immediate. */
20200
- exitDelaySec: number().int().min(0).max(600),
20190
+ exitDelaySec: NcAlarmDelaySecSchema,
20201
20191
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20202
- entryDelaySec: number().int().min(0).max(600),
20192
+ entryDelaySec: NcAlarmDelaySecSchema,
20203
20193
  /**
20204
20194
  * How long `triggered` lasts before the panel re-arms itself.
20205
20195
  * **0 = until an operator disarms it** — the behaviour before this field
20206
20196
  * existed, and therefore what an untouched install keeps doing.
20207
20197
  */
20208
- triggeredDurationSec: number().int().min(0).max(3600),
20198
+ triggeredDurationSec: NcAlarmTriggeredSecSchema,
20209
20199
  /**
20210
20200
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20211
20201
  * remove after one release. Optional so an older admin's patch (which still
@@ -20228,17 +20218,30 @@ var NcAlarmSettingsSchema = object({
20228
20218
  * per mode is meaningful. Defaulted to `[]` so a blob stored before D630
20229
20219
  * parses as "every opening blocks" — the behaviour it was written under.
20230
20220
  */
20231
- nonBlocking: NcAlarmNonBlockingListSchema.default([])
20221
+ nonBlocking: NcAlarmNonBlockingListSchema.default([]),
20222
+ /**
20223
+ * Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
20224
+ * without a field, uses the global value above — so `[]`, the default, is exactly the
20225
+ * behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
20226
+ */
20227
+ modeDelays: NcAlarmModeDelaysListSchema.default([])
20232
20228
  });
20233
20229
  /**
20234
20230
  * Every field optional — a tab edits one control at a time.
20235
20231
  *
20236
- * `nonBlocking` is re-declared WITHOUT its default: `.partial()` does not
20237
- * remove an inner `.default()`, so a patch that never named the field would
20238
- * parse to `nonBlocking: []` and wipe every mode's list on an unrelated edit
20239
- * (the same trap {@link NcRulePatchSchema} documents).
20232
+ * `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
20233
+ * `.partial()` does not remove an inner `.default()`, so a patch that never
20234
+ * named the field would parse to `[]` and wipe every mode's list on an
20235
+ * unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
20236
+ * `modeDelays` means EDITS, not the stored overrides.
20240
20237
  */
20241
- var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({ nonBlocking: NcAlarmNonBlockingListSchema }).partial();
20238
+ var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
20239
+ nonBlocking: NcAlarmNonBlockingListSchema,
20240
+ /** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
20241
+ modeDelays: NcAlarmModeDelaysEditListSchema,
20242
+ /** ONE membership change; the panel applies it to the list it holds at its turn. */
20243
+ nonBlockingEdit: NcAlarmNonBlockingEditSchema
20244
+ }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
20242
20245
  /**
20243
20246
  * What one arm mode actually arms, DERIVED from the enabled rules gated on it.
20244
20247
  * Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
@@ -20338,6 +20341,28 @@ var NcAlarmConfigSchema = object({
20338
20341
  */
20339
20342
  live: NcAlarmLiveSchema.optional()
20340
20343
  });
20344
+ var NcAlarmSensorReadingSchema = _enum([
20345
+ "open",
20346
+ "closed",
20347
+ "unknown",
20348
+ "not-opening"
20349
+ ]);
20350
+ /** One device's state as the alarm reads it — the classifier the arm check uses. */
20351
+ var NcAlarmSensorStateSchema = object({
20352
+ deviceId: number().int().positive(),
20353
+ reading: NcAlarmSensorReadingSchema,
20354
+ /** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
20355
+ state: string().nullable(),
20356
+ /** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
20357
+ unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
20358
+ /** The device manager's liveness as the centre mirrors it; null = not known. */
20359
+ online: boolean().nullable()
20360
+ });
20361
+ var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
20362
+ var NcAlarmSensorsSchema = object({
20363
+ sensors: array(NcAlarmSensorStateSchema),
20364
+ readAt: number().int().nonnegative()
20365
+ });
20341
20366
  /**
20342
20367
  * ONE rule's demand on ONE camera's clip ring.
20343
20368
  *
@@ -20428,7 +20453,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20428
20453
  }), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
20429
20454
  kind: "mutation",
20430
20455
  auth: "admin"
20431
- });
20456
+ }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
20432
20457
  /**
20433
20458
  * Zod schemas for persisted record types.
20434
20459
  *
@@ -21596,14 +21621,14 @@ var TrackSchema = object({
21596
21621
  * `derive-returned-null tile=standin`,
21597
21622
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
21598
21623
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
21599
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
21624
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
21600
21625
  * tile is a face/plate stand-in, a raster crop, or an icon.
21601
21626
  *
21602
21627
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
21603
21628
  * the TILE ranked below native, so a track whose thumbnail landed natively
21604
21629
  * while its key frame missed carried no reason at all — three of the four
21605
21630
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
21606
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
21631
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
21607
21632
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
21608
21633
  * lastFrame copy source`), so its absence is now on this line whatever the
21609
21634
  * tile ended up being.
@@ -21690,7 +21715,7 @@ var MotionEventSchema = object({
21690
21715
  /**
21691
21716
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
21692
21717
  * first entry is always `0`) of every genuine off→on transition the
21693
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
21718
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
21694
21719
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
21695
21720
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
21696
21721
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -22214,6 +22239,7 @@ var KeyEventSchema = object({
22214
22239
  bestEventId: string(),
22215
22240
  /** Track lifetime in ms (lastSeen - firstSeen). */
22216
22241
  windowMs: number().optional(),
22242
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
22217
22243
  ...TrackFlagFields,
22218
22244
  ...TrackRetrainFields
22219
22245
  });
@@ -26926,7 +26952,7 @@ var ClipPlaybackSchema = object({
26926
26952
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
26927
26953
  * time the camera is awake for its own reasons — is deliberately not a member:
26928
26954
  * it was proposed, it is free on the battery, and the operator declined it on
26929
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
26955
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
26930
26956
  * D558 "Considered and not taken").
26931
26957
  */
26932
26958
  var ClipWakeSchema = _enum(["authorised"]);
@@ -27187,7 +27213,7 @@ DeviceType.Camera, method(object({
27187
27213
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
27188
27214
  * assumed the answer was a fan-out over everything a camera has. The
27189
27215
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
27190
- * solo"* — so the list is asked of one provider at a time and there is
27216
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
27191
27217
  * nothing to filter out of it.
27192
27218
  */
27193
27219
  provider: string().min(1)
@@ -33305,7 +33331,7 @@ var ReadGopBytesResultSchema = object({
33305
33331
  /**
33306
33332
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
33307
33333
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
33308
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
33334
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
33309
33335
  * a replay needs several seconds of native pixels, not one frame.
33310
33336
  *
33311
33337
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -35921,6 +35947,7 @@ DeviceType.Camera, method(object({
35921
35947
  detection: array(ZoneRuleSchema).readonly(),
35922
35948
  package: array(ZoneRuleSchema).readonly()
35923
35949
  });
35950
+ SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
35924
35951
  /**
35925
35952
  * Accessory device helpers — shared across drivers.
35926
35953
  *
@@ -40899,6 +40926,12 @@ Object.freeze({
40899
40926
  addonId: null,
40900
40927
  access: "view"
40901
40928
  },
40929
+ "notificationRules.getAlarmSensors": {
40930
+ capName: "notification-rules",
40931
+ capScope: "system",
40932
+ addonId: null,
40933
+ access: "view"
40934
+ },
40902
40935
  "notificationRules.getClipRetentionAsks": {
40903
40936
  capName: "notification-rules",
40904
40937
  capScope: "system",
@@ -44477,6 +44510,11 @@ Object.freeze({
44477
44510
  }
44478
44511
  });
44479
44512
  Object.freeze({
44513
+ "accessories.getStatus": [{
44514
+ name: "deviceId",
44515
+ form: "single",
44516
+ optional: false
44517
+ }],
44480
44518
  "accessories.setChildHidden": [{
44481
44519
  name: "childDeviceId",
44482
44520
  form: "single",
@@ -44496,6 +44534,11 @@ Object.freeze({
44496
44534
  form: "single",
44497
44535
  optional: false
44498
44536
  }],
44537
+ "airQualitySensor.getStatus": [{
44538
+ name: "deviceId",
44539
+ form: "single",
44540
+ optional: false
44541
+ }],
44499
44542
  "alarmPanel.arm": [{
44500
44543
  name: "deviceId",
44501
44544
  form: "single",
@@ -44506,11 +44549,36 @@ Object.freeze({
44506
44549
  form: "single",
44507
44550
  optional: false
44508
44551
  }],
44552
+ "alarmPanel.getStatus": [{
44553
+ name: "deviceId",
44554
+ form: "single",
44555
+ optional: false
44556
+ }],
44509
44557
  "alarmPanel.trigger": [{
44510
44558
  name: "deviceId",
44511
44559
  form: "single",
44512
44560
  optional: false
44513
44561
  }],
44562
+ "ambientLightSensor.getStatus": [{
44563
+ name: "deviceId",
44564
+ form: "single",
44565
+ optional: false
44566
+ }],
44567
+ "audioAnalysis.applyDeviceSettingsPatch": [{
44568
+ name: "deviceId",
44569
+ form: "single",
44570
+ optional: false
44571
+ }],
44572
+ "audioAnalysis.getDeviceLiveContribution": [{
44573
+ name: "deviceId",
44574
+ form: "single",
44575
+ optional: false
44576
+ }],
44577
+ "audioAnalysis.getDeviceSettingsContribution": [{
44578
+ name: "deviceId",
44579
+ form: "single",
44580
+ optional: false
44581
+ }],
44514
44582
  "audioAnalysis.resolveDeviceSettings": [{
44515
44583
  name: "deviceId",
44516
44584
  form: "single",
@@ -44551,16 +44619,36 @@ Object.freeze({
44551
44619
  form: "single",
44552
44620
  optional: false
44553
44621
  }],
44622
+ "automationControl.getStatus": [{
44623
+ name: "deviceId",
44624
+ form: "single",
44625
+ optional: false
44626
+ }],
44554
44627
  "automationControl.trigger": [{
44555
44628
  name: "deviceId",
44556
44629
  form: "single",
44557
44630
  optional: false
44558
44631
  }],
44632
+ "battery.getStatus": [{
44633
+ name: "deviceId",
44634
+ form: "single",
44635
+ optional: false
44636
+ }],
44559
44637
  "battery.wakeForStream": [{
44560
44638
  name: "deviceId",
44561
44639
  form: "single",
44562
44640
  optional: false
44563
44641
  }],
44642
+ "binary.getStatus": [{
44643
+ name: "deviceId",
44644
+ form: "single",
44645
+ optional: false
44646
+ }],
44647
+ "brightness.getStatus": [{
44648
+ name: "deviceId",
44649
+ form: "single",
44650
+ optional: false
44651
+ }],
44564
44652
  "brightness.setBrightness": [{
44565
44653
  name: "deviceId",
44566
44654
  form: "single",
@@ -44576,6 +44664,26 @@ Object.freeze({
44576
44664
  form: "single",
44577
44665
  optional: false
44578
44666
  }],
44667
+ "cameraCredentials.getStatus": [{
44668
+ name: "deviceId",
44669
+ form: "single",
44670
+ optional: false
44671
+ }],
44672
+ "cameraGridLayout.applyDeviceSettingsPatch": [{
44673
+ name: "deviceId",
44674
+ form: "single",
44675
+ optional: false
44676
+ }],
44677
+ "cameraGridLayout.getDeviceLiveContribution": [{
44678
+ name: "deviceId",
44679
+ form: "single",
44680
+ optional: false
44681
+ }],
44682
+ "cameraGridLayout.getDeviceSettingsContribution": [{
44683
+ name: "deviceId",
44684
+ form: "single",
44685
+ optional: false
44686
+ }],
44579
44687
  "cameraGridLayout.getLayout": [{
44580
44688
  name: "deviceId",
44581
44689
  form: "single",
@@ -44591,6 +44699,21 @@ Object.freeze({
44591
44699
  form: "single",
44592
44700
  optional: false
44593
44701
  }],
44702
+ "cameraPipelineConfig.applyDeviceSettingsPatch": [{
44703
+ name: "deviceId",
44704
+ form: "single",
44705
+ optional: false
44706
+ }],
44707
+ "cameraPipelineConfig.getDeviceLiveContribution": [{
44708
+ name: "deviceId",
44709
+ form: "single",
44710
+ optional: false
44711
+ }],
44712
+ "cameraPipelineConfig.getDeviceSettingsContribution": [{
44713
+ name: "deviceId",
44714
+ form: "single",
44715
+ optional: false
44716
+ }],
44594
44717
  "cameraStreams.getBrokerStreams": [{
44595
44718
  name: "deviceId",
44596
44719
  form: "single",
@@ -44616,6 +44739,16 @@ Object.freeze({
44616
44739
  form: "single",
44617
44740
  optional: false
44618
44741
  }],
44742
+ "carbonMonoxide.getStatus": [{
44743
+ name: "deviceId",
44744
+ form: "single",
44745
+ optional: false
44746
+ }],
44747
+ "climateControl.getStatus": [{
44748
+ name: "deviceId",
44749
+ form: "single",
44750
+ optional: false
44751
+ }],
44619
44752
  "climateControl.setFanMode": [{
44620
44753
  name: "deviceId",
44621
44754
  form: "single",
@@ -44656,16 +44789,41 @@ Object.freeze({
44656
44789
  form: "single",
44657
44790
  optional: false
44658
44791
  }],
44792
+ "color.getStatus": [{
44793
+ name: "deviceId",
44794
+ form: "single",
44795
+ optional: false
44796
+ }],
44659
44797
  "color.setColor": [{
44660
44798
  name: "deviceId",
44661
44799
  form: "single",
44662
44800
  optional: false
44663
44801
  }],
44802
+ "connectivity.getStatus": [{
44803
+ name: "deviceId",
44804
+ form: "single",
44805
+ optional: false
44806
+ }],
44807
+ "consumables.getStatus": [{
44808
+ name: "deviceId",
44809
+ form: "single",
44810
+ optional: false
44811
+ }],
44664
44812
  "consumables.reset": [{
44665
44813
  name: "deviceId",
44666
44814
  form: "single",
44667
44815
  optional: false
44668
44816
  }],
44817
+ "contact.getStatus": [{
44818
+ name: "deviceId",
44819
+ form: "single",
44820
+ optional: false
44821
+ }],
44822
+ "control.getStatus": [{
44823
+ name: "deviceId",
44824
+ form: "single",
44825
+ optional: false
44826
+ }],
44669
44827
  "control.setValue": [{
44670
44828
  name: "deviceId",
44671
44829
  form: "single",
@@ -44676,6 +44834,11 @@ Object.freeze({
44676
44834
  form: "single",
44677
44835
  optional: false
44678
44836
  }],
44837
+ "cover.getStatus": [{
44838
+ name: "deviceId",
44839
+ form: "single",
44840
+ optional: false
44841
+ }],
44679
44842
  "cover.open": [{
44680
44843
  name: "deviceId",
44681
44844
  form: "single",
@@ -44701,6 +44864,11 @@ Object.freeze({
44701
44864
  form: "single",
44702
44865
  optional: false
44703
44866
  }],
44867
+ "dayNight.getStatus": [{
44868
+ name: "deviceId",
44869
+ form: "single",
44870
+ optional: false
44871
+ }],
44704
44872
  "dayNight.setSettings": [{
44705
44873
  name: "deviceId",
44706
44874
  form: "single",
@@ -44711,11 +44879,31 @@ Object.freeze({
44711
44879
  form: "single",
44712
44880
  optional: true
44713
44881
  }],
44882
+ "detectionPipeline.applyDeviceSettingsPatch": [{
44883
+ name: "deviceId",
44884
+ form: "single",
44885
+ optional: false
44886
+ }],
44887
+ "detectionPipeline.getDeviceLiveContribution": [{
44888
+ name: "deviceId",
44889
+ form: "single",
44890
+ optional: false
44891
+ }],
44892
+ "detectionPipeline.getDeviceSettingsContribution": [{
44893
+ name: "deviceId",
44894
+ form: "single",
44895
+ optional: false
44896
+ }],
44714
44897
  "deviceAdminLink.getAdminLink": [{
44715
44898
  name: "deviceId",
44716
44899
  form: "single",
44717
44900
  optional: false
44718
44901
  }],
44902
+ "deviceAdoption.getStatus": [{
44903
+ name: "deviceId",
44904
+ form: "single",
44905
+ optional: false
44906
+ }],
44719
44907
  "deviceAdoption.release": [{
44720
44908
  name: "camDeviceId",
44721
44909
  form: "single",
@@ -44731,6 +44919,11 @@ Object.freeze({
44731
44919
  form: "single",
44732
44920
  optional: false
44733
44921
  }],
44922
+ "deviceDiscovery.getStatus": [{
44923
+ name: "deviceId",
44924
+ form: "single",
44925
+ optional: false
44926
+ }],
44734
44927
  "deviceDiscovery.listDiscovered": [{
44735
44928
  name: "deviceId",
44736
44929
  form: "single",
@@ -44750,6 +44943,21 @@ Object.freeze({
44750
44943
  form: "single",
44751
44944
  optional: false
44752
44945
  }],
44946
+ "deviceExport.applyDeviceSettingsPatch": [{
44947
+ name: "deviceId",
44948
+ form: "single",
44949
+ optional: false
44950
+ }],
44951
+ "deviceExport.getDeviceLiveContribution": [{
44952
+ name: "deviceId",
44953
+ form: "single",
44954
+ optional: false
44955
+ }],
44956
+ "deviceExport.getDeviceSettingsContribution": [{
44957
+ name: "deviceId",
44958
+ form: "single",
44959
+ optional: false
44960
+ }],
44753
44961
  "deviceExtension.listCandidates": [{
44754
44962
  name: "deviceId",
44755
44963
  form: "single",
@@ -45098,6 +45306,26 @@ Object.freeze({
45098
45306
  form: "single",
45099
45307
  optional: false
45100
45308
  }],
45309
+ "deviceStatus.getStatus": [{
45310
+ name: "deviceId",
45311
+ form: "single",
45312
+ optional: false
45313
+ }],
45314
+ "doorbell.getStatus": [{
45315
+ name: "deviceId",
45316
+ form: "single",
45317
+ optional: false
45318
+ }],
45319
+ "enumSensor.getStatus": [{
45320
+ name: "deviceId",
45321
+ form: "single",
45322
+ optional: false
45323
+ }],
45324
+ "eventEmitter.getStatus": [{
45325
+ name: "deviceId",
45326
+ form: "single",
45327
+ optional: false
45328
+ }],
45101
45329
  "faceGallery.getFaceByTrack": [{
45102
45330
  name: "deviceId",
45103
45331
  form: "single",
@@ -45112,6 +45340,11 @@ Object.freeze({
45112
45340
  form: "array",
45113
45341
  optional: true
45114
45342
  }],
45343
+ "fanControl.getStatus": [{
45344
+ name: "deviceId",
45345
+ form: "single",
45346
+ optional: false
45347
+ }],
45115
45348
  "fanControl.setDirection": [{
45116
45349
  name: "deviceId",
45117
45350
  form: "single",
@@ -45132,6 +45365,26 @@ Object.freeze({
45132
45365
  form: "single",
45133
45366
  optional: false
45134
45367
  }],
45368
+ "featureProbe.getStatus": [{
45369
+ name: "deviceId",
45370
+ form: "single",
45371
+ optional: false
45372
+ }],
45373
+ "flood.getStatus": [{
45374
+ name: "deviceId",
45375
+ form: "single",
45376
+ optional: false
45377
+ }],
45378
+ "gas.getStatus": [{
45379
+ name: "deviceId",
45380
+ form: "single",
45381
+ optional: false
45382
+ }],
45383
+ "humidifier.getStatus": [{
45384
+ name: "deviceId",
45385
+ form: "single",
45386
+ optional: false
45387
+ }],
45135
45388
  "humidifier.setMode": [{
45136
45389
  name: "deviceId",
45137
45390
  form: "single",
@@ -45147,11 +45400,26 @@ Object.freeze({
45147
45400
  form: "single",
45148
45401
  optional: false
45149
45402
  }],
45403
+ "humiditySensor.getStatus": [{
45404
+ name: "deviceId",
45405
+ form: "single",
45406
+ optional: false
45407
+ }],
45408
+ "image.getStatus": [{
45409
+ name: "deviceId",
45410
+ form: "single",
45411
+ optional: false
45412
+ }],
45150
45413
  "imageSettings.getOptions": [{
45151
45414
  name: "deviceId",
45152
45415
  form: "single",
45153
45416
  optional: false
45154
45417
  }],
45418
+ "imageSettings.getStatus": [{
45419
+ name: "deviceId",
45420
+ form: "single",
45421
+ optional: false
45422
+ }],
45155
45423
  "imageSettings.setSettings": [{
45156
45424
  name: "deviceId",
45157
45425
  form: "single",
@@ -45162,6 +45430,11 @@ Object.freeze({
45162
45430
  form: "single",
45163
45431
  optional: false
45164
45432
  }],
45433
+ "intercom.getStatus": [{
45434
+ name: "deviceId",
45435
+ form: "single",
45436
+ optional: false
45437
+ }],
45165
45438
  "intercom.handleAnswer": [{
45166
45439
  name: "deviceId",
45167
45440
  form: "single",
@@ -45192,6 +45465,11 @@ Object.freeze({
45192
45465
  form: "single",
45193
45466
  optional: false
45194
45467
  }],
45468
+ "lawnMowerControl.getStatus": [{
45469
+ name: "deviceId",
45470
+ form: "single",
45471
+ optional: false
45472
+ }],
45195
45473
  "lawnMowerControl.pause": [{
45196
45474
  name: "deviceId",
45197
45475
  form: "single",
@@ -45202,6 +45480,11 @@ Object.freeze({
45202
45480
  form: "single",
45203
45481
  optional: false
45204
45482
  }],
45483
+ "lockControl.getStatus": [{
45484
+ name: "deviceId",
45485
+ form: "single",
45486
+ optional: false
45487
+ }],
45205
45488
  "lockControl.lock": [{
45206
45489
  name: "deviceId",
45207
45490
  form: "single",
@@ -45217,6 +45500,11 @@ Object.freeze({
45217
45500
  form: "single",
45218
45501
  optional: false
45219
45502
  }],
45503
+ "mediaPlayer.getStatus": [{
45504
+ name: "deviceId",
45505
+ form: "single",
45506
+ optional: false
45507
+ }],
45220
45508
  "mediaPlayer.next": [{
45221
45509
  name: "deviceId",
45222
45510
  form: "single",
@@ -45277,6 +45565,11 @@ Object.freeze({
45277
45565
  form: "single",
45278
45566
  optional: false
45279
45567
  }],
45568
+ "motion.getStatus": [{
45569
+ name: "deviceId",
45570
+ form: "single",
45571
+ optional: false
45572
+ }],
45280
45573
  "motion.isDetected": [{
45281
45574
  name: "deviceId",
45282
45575
  form: "single",
@@ -45287,11 +45580,31 @@ Object.freeze({
45287
45580
  form: "single",
45288
45581
  optional: false
45289
45582
  }],
45583
+ "motionDetection.applyDeviceSettingsPatch": [{
45584
+ name: "deviceId",
45585
+ form: "single",
45586
+ optional: false
45587
+ }],
45588
+ "motionDetection.getDeviceLiveContribution": [{
45589
+ name: "deviceId",
45590
+ form: "single",
45591
+ optional: false
45592
+ }],
45593
+ "motionDetection.getDeviceSettingsContribution": [{
45594
+ name: "deviceId",
45595
+ form: "single",
45596
+ optional: false
45597
+ }],
45290
45598
  "motionDetection.removeCamera": [{
45291
45599
  name: "deviceId",
45292
45600
  form: "single",
45293
45601
  optional: false
45294
45602
  }],
45603
+ "motionTrigger.getStatus": [{
45604
+ name: "deviceId",
45605
+ form: "single",
45606
+ optional: false
45607
+ }],
45295
45608
  "motionTrigger.setMotionTrigger": [{
45296
45609
  name: "deviceId",
45297
45610
  form: "single",
@@ -45302,6 +45615,11 @@ Object.freeze({
45302
45615
  form: "single",
45303
45616
  optional: false
45304
45617
  }],
45618
+ "motionZones.getStatus": [{
45619
+ name: "deviceId",
45620
+ form: "single",
45621
+ optional: false
45622
+ }],
45305
45623
  "motionZones.setZone": [{
45306
45624
  name: "deviceId",
45307
45625
  form: "single",
@@ -45312,6 +45630,11 @@ Object.freeze({
45312
45630
  form: "single",
45313
45631
  optional: false
45314
45632
  }],
45633
+ "nativeObjectDetection.getStatus": [{
45634
+ name: "deviceId",
45635
+ form: "single",
45636
+ optional: false
45637
+ }],
45315
45638
  "nativeObjectDetection.setEnabled": [{
45316
45639
  name: "deviceId",
45317
45640
  form: "single",
@@ -45327,6 +45650,11 @@ Object.freeze({
45327
45650
  form: "single",
45328
45651
  optional: false
45329
45652
  }],
45653
+ "navigation.getStatus": [{
45654
+ name: "deviceId",
45655
+ form: "single",
45656
+ optional: false
45657
+ }],
45330
45658
  "navigation.goToPoint": [{
45331
45659
  name: "deviceId",
45332
45660
  form: "single",
@@ -45372,6 +45700,11 @@ Object.freeze({
45372
45700
  form: "single",
45373
45701
  optional: false
45374
45702
  }],
45703
+ "networkLink.getStatus": [{
45704
+ name: "deviceId",
45705
+ form: "single",
45706
+ optional: false
45707
+ }],
45375
45708
  "networkQuality.getDeviceStats": [{
45376
45709
  name: "deviceId",
45377
45710
  form: "single",
@@ -45382,6 +45715,11 @@ Object.freeze({
45382
45715
  form: "single",
45383
45716
  optional: false
45384
45717
  }],
45718
+ "notificationRules.getAlarmSensors": [{
45719
+ name: "deviceIds",
45720
+ form: "array",
45721
+ optional: false
45722
+ }],
45385
45723
  "notificationRules.setDeviceMuted": [{
45386
45724
  name: "deviceId",
45387
45725
  form: "single",
@@ -45392,11 +45730,26 @@ Object.freeze({
45392
45730
  form: "single",
45393
45731
  optional: false
45394
45732
  }],
45733
+ "notifier.getStatus": [{
45734
+ name: "deviceId",
45735
+ form: "single",
45736
+ optional: false
45737
+ }],
45395
45738
  "notifier.send": [{
45396
45739
  name: "deviceId",
45397
45740
  form: "single",
45398
45741
  optional: false
45399
45742
  }],
45743
+ "numericSensor.getStatus": [{
45744
+ name: "deviceId",
45745
+ form: "single",
45746
+ optional: false
45747
+ }],
45748
+ "osd.getStatus": [{
45749
+ name: "deviceId",
45750
+ form: "single",
45751
+ optional: false
45752
+ }],
45400
45753
  "osd.setOverlay": [{
45401
45754
  name: "deviceId",
45402
45755
  form: "single",
@@ -45456,6 +45809,11 @@ Object.freeze({
45456
45809
  form: "single",
45457
45810
  optional: false
45458
45811
  }],
45812
+ "petFeeder.getStatus": [{
45813
+ name: "deviceId",
45814
+ form: "single",
45815
+ optional: false
45816
+ }],
45459
45817
  "petFeeder.markFoodReplenished": [{
45460
45818
  name: "deviceId",
45461
45819
  form: "single",
@@ -45491,6 +45849,11 @@ Object.freeze({
45491
45849
  form: "single",
45492
45850
  optional: false
45493
45851
  }],
45852
+ "pipelineAnalytics.applyDeviceSettingsPatch": [{
45853
+ name: "deviceId",
45854
+ form: "single",
45855
+ optional: false
45856
+ }],
45494
45857
  "pipelineAnalytics.clearTrackRelation": [{
45495
45858
  name: "deviceId",
45496
45859
  form: "single",
@@ -45531,6 +45894,16 @@ Object.freeze({
45531
45894
  form: "single",
45532
45895
  optional: false
45533
45896
  }],
45897
+ "pipelineAnalytics.getDeviceLiveContribution": [{
45898
+ name: "deviceId",
45899
+ form: "single",
45900
+ optional: false
45901
+ }],
45902
+ "pipelineAnalytics.getDeviceSettingsContribution": [{
45903
+ name: "deviceId",
45904
+ form: "single",
45905
+ optional: false
45906
+ }],
45534
45907
  "pipelineAnalytics.getEventDensity": [{
45535
45908
  name: "deviceId",
45536
45909
  form: "single",
@@ -45746,6 +46119,11 @@ Object.freeze({
45746
46119
  form: "single",
45747
46120
  optional: true
45748
46121
  }],
46122
+ "pipelineOrchestrator.applyDeviceSettingsPatch": [{
46123
+ name: "deviceId",
46124
+ form: "single",
46125
+ optional: false
46126
+ }],
45749
46127
  "pipelineOrchestrator.assignAudio": [{
45750
46128
  name: "deviceId",
45751
46129
  form: "single",
@@ -45791,6 +46169,16 @@ Object.freeze({
45791
46169
  form: "single",
45792
46170
  optional: false
45793
46171
  }],
46172
+ "pipelineOrchestrator.getDeviceLiveContribution": [{
46173
+ name: "deviceId",
46174
+ form: "single",
46175
+ optional: false
46176
+ }],
46177
+ "pipelineOrchestrator.getDeviceSettingsContribution": [{
46178
+ name: "deviceId",
46179
+ form: "single",
46180
+ optional: false
46181
+ }],
45794
46182
  "pipelineOrchestrator.getPipelineAssignment": [{
45795
46183
  name: "deviceId",
45796
46184
  form: "single",
@@ -45911,11 +46299,31 @@ Object.freeze({
45911
46299
  form: "single",
45912
46300
  optional: true
45913
46301
  }],
46302
+ "powerMeter.getStatus": [{
46303
+ name: "deviceId",
46304
+ form: "single",
46305
+ optional: false
46306
+ }],
46307
+ "presence.getStatus": [{
46308
+ name: "deviceId",
46309
+ form: "single",
46310
+ optional: false
46311
+ }],
46312
+ "pressureSensor.getStatus": [{
46313
+ name: "deviceId",
46314
+ form: "single",
46315
+ optional: false
46316
+ }],
45914
46317
  "privacyMask.getOptions": [{
45915
46318
  name: "deviceId",
45916
46319
  form: "single",
45917
46320
  optional: false
45918
46321
  }],
46322
+ "privacyMask.getStatus": [{
46323
+ name: "deviceId",
46324
+ form: "single",
46325
+ optional: false
46326
+ }],
45919
46327
  "privacyMask.setAudioEnabled": [{
45920
46328
  name: "deviceId",
45921
46329
  form: "single",
@@ -45966,6 +46374,11 @@ Object.freeze({
45966
46374
  form: "single",
45967
46375
  optional: false
45968
46376
  }],
46377
+ "ptz.getStatus": [{
46378
+ name: "deviceId",
46379
+ form: "single",
46380
+ optional: false
46381
+ }],
45969
46382
  "ptz.goHome": [{
45970
46383
  name: "deviceId",
45971
46384
  form: "single",
@@ -46056,6 +46469,11 @@ Object.freeze({
46056
46469
  form: "single",
46057
46470
  optional: false
46058
46471
  }],
46472
+ "recordingArchive.applyDeviceSettingsPatch": [{
46473
+ name: "deviceId",
46474
+ form: "single",
46475
+ optional: false
46476
+ }],
46059
46477
  "recordingArchive.deleteFootprint": [{
46060
46478
  name: "deviceId",
46061
46479
  form: "single",
@@ -46076,6 +46494,21 @@ Object.freeze({
46076
46494
  form: "single",
46077
46495
  optional: false
46078
46496
  }],
46497
+ "recordingArchive.getDeviceLiveContribution": [{
46498
+ name: "deviceId",
46499
+ form: "single",
46500
+ optional: false
46501
+ }],
46502
+ "recordingArchive.getDeviceSettingsContribution": [{
46503
+ name: "deviceId",
46504
+ form: "single",
46505
+ optional: false
46506
+ }],
46507
+ "recordingArchive.getStatus": [{
46508
+ name: "deviceId",
46509
+ form: "single",
46510
+ optional: false
46511
+ }],
46079
46512
  "recordingArchive.listOpsLog": [{
46080
46513
  name: "deviceId",
46081
46514
  form: "single",
@@ -46161,6 +46594,11 @@ Object.freeze({
46161
46594
  form: "single",
46162
46595
  optional: false
46163
46596
  }],
46597
+ "recordingOnboard.getStatus": [{
46598
+ name: "deviceId",
46599
+ form: "single",
46600
+ optional: false
46601
+ }],
46164
46602
  "recordingOnboard.setSettings": [{
46165
46603
  name: "deviceId",
46166
46604
  form: "single",
@@ -46191,6 +46629,11 @@ Object.freeze({
46191
46629
  form: "single",
46192
46630
  optional: false
46193
46631
  }],
46632
+ "sceneMonitor.getStatus": [{
46633
+ name: "deviceId",
46634
+ form: "single",
46635
+ optional: false
46636
+ }],
46194
46637
  "sceneMonitor.listScenes": [{
46195
46638
  name: "deviceId",
46196
46639
  form: "single",
@@ -46216,6 +46659,11 @@ Object.freeze({
46216
46659
  form: "single",
46217
46660
  optional: false
46218
46661
  }],
46662
+ "scriptRunner.getStatus": [{
46663
+ name: "deviceId",
46664
+ form: "single",
46665
+ optional: false
46666
+ }],
46219
46667
  "scriptRunner.run": [{
46220
46668
  name: "deviceId",
46221
46669
  form: "single",
@@ -46226,11 +46674,31 @@ Object.freeze({
46226
46674
  form: "single",
46227
46675
  optional: false
46228
46676
  }],
46677
+ "smoke.getStatus": [{
46678
+ name: "deviceId",
46679
+ form: "single",
46680
+ optional: false
46681
+ }],
46682
+ "snapshot.applyDeviceSettingsPatch": [{
46683
+ name: "deviceId",
46684
+ form: "single",
46685
+ optional: false
46686
+ }],
46229
46687
  "snapshot.getDebugState": [{
46230
46688
  name: "deviceId",
46231
46689
  form: "single",
46232
46690
  optional: false
46233
46691
  }],
46692
+ "snapshot.getDeviceLiveContribution": [{
46693
+ name: "deviceId",
46694
+ form: "single",
46695
+ optional: false
46696
+ }],
46697
+ "snapshot.getDeviceSettingsContribution": [{
46698
+ name: "deviceId",
46699
+ form: "single",
46700
+ optional: false
46701
+ }],
46234
46702
  "snapshot.getSnapshot": [{
46235
46703
  name: "deviceId",
46236
46704
  form: "single",
@@ -46247,6 +46715,11 @@ Object.freeze({
46247
46715
  form: "array",
46248
46716
  optional: false
46249
46717
  }],
46718
+ "snapshot.getStatus": [{
46719
+ name: "deviceId",
46720
+ form: "single",
46721
+ optional: false
46722
+ }],
46250
46723
  "snapshot.invalidateCache": [{
46251
46724
  name: "deviceId",
46252
46725
  form: "single",
@@ -46257,6 +46730,11 @@ Object.freeze({
46257
46730
  form: "single",
46258
46731
  optional: false
46259
46732
  }],
46733
+ "streamBroker.applyDeviceSettingsPatch": [{
46734
+ name: "deviceId",
46735
+ form: "single",
46736
+ optional: false
46737
+ }],
46260
46738
  "streamBroker.assignProfile": [{
46261
46739
  name: "deviceId",
46262
46740
  form: "single",
@@ -46272,6 +46750,16 @@ Object.freeze({
46272
46750
  form: "single",
46273
46751
  optional: false
46274
46752
  }],
46753
+ "streamBroker.getDeviceLiveContribution": [{
46754
+ name: "deviceId",
46755
+ form: "single",
46756
+ optional: false
46757
+ }],
46758
+ "streamBroker.getDeviceSettingsContribution": [{
46759
+ name: "deviceId",
46760
+ form: "single",
46761
+ optional: false
46762
+ }],
46275
46763
  "streamBroker.getStreamWithCodec": [{
46276
46764
  name: "deviceId",
46277
46765
  form: "single",
@@ -46332,16 +46820,46 @@ Object.freeze({
46332
46820
  form: "single",
46333
46821
  optional: false
46334
46822
  }],
46823
+ "streamParams.getStatus": [{
46824
+ name: "deviceId",
46825
+ form: "single",
46826
+ optional: false
46827
+ }],
46335
46828
  "streamParams.setProfile": [{
46336
46829
  name: "deviceId",
46337
46830
  form: "single",
46338
46831
  optional: false
46339
46832
  }],
46833
+ "switch.getStatus": [{
46834
+ name: "deviceId",
46835
+ form: "single",
46836
+ optional: false
46837
+ }],
46340
46838
  "switch.setState": [{
46341
46839
  name: "deviceId",
46342
46840
  form: "single",
46343
46841
  optional: false
46344
46842
  }],
46843
+ "tamper.getStatus": [{
46844
+ name: "deviceId",
46845
+ form: "single",
46846
+ optional: false
46847
+ }],
46848
+ "temperatureSensor.getStatus": [{
46849
+ name: "deviceId",
46850
+ form: "single",
46851
+ optional: false
46852
+ }],
46853
+ "update.getStatus": [{
46854
+ name: "deviceId",
46855
+ form: "single",
46856
+ optional: false
46857
+ }],
46858
+ "vacuumControl.getStatus": [{
46859
+ name: "deviceId",
46860
+ form: "single",
46861
+ optional: false
46862
+ }],
46345
46863
  "vacuumControl.locate": [{
46346
46864
  name: "deviceId",
46347
46865
  form: "single",
@@ -46377,6 +46895,11 @@ Object.freeze({
46377
46895
  form: "single",
46378
46896
  optional: false
46379
46897
  }],
46898
+ "valve.getStatus": [{
46899
+ name: "deviceId",
46900
+ form: "single",
46901
+ optional: false
46902
+ }],
46380
46903
  "valve.open": [{
46381
46904
  name: "deviceId",
46382
46905
  form: "single",
@@ -46392,6 +46915,11 @@ Object.freeze({
46392
46915
  form: "single",
46393
46916
  optional: false
46394
46917
  }],
46918
+ "vibration.getStatus": [{
46919
+ name: "deviceId",
46920
+ form: "single",
46921
+ optional: false
46922
+ }],
46395
46923
  "videoclips.dialClipStream": [{
46396
46924
  name: "deviceId",
46397
46925
  form: "single",
@@ -46427,6 +46955,11 @@ Object.freeze({
46427
46955
  form: "single",
46428
46956
  optional: false
46429
46957
  }],
46958
+ "waterHeater.getStatus": [{
46959
+ name: "deviceId",
46960
+ form: "single",
46961
+ optional: false
46962
+ }],
46430
46963
  "waterHeater.setAway": [{
46431
46964
  name: "deviceId",
46432
46965
  form: "single",
@@ -46442,6 +46975,11 @@ Object.freeze({
46442
46975
  form: "single",
46443
46976
  optional: false
46444
46977
  }],
46978
+ "weather.getStatus": [{
46979
+ name: "deviceId",
46980
+ form: "single",
46981
+ optional: false
46982
+ }],
46445
46983
  "webrtcSession.addIceCandidate": [{
46446
46984
  name: "deviceId",
46447
46985
  form: "single",
@@ -47179,7 +47717,7 @@ var PreviewTextField = string().max(200);
47179
47717
  * Whether the notification's preview is a STILL or a short animation.
47180
47718
  *
47181
47719
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
47182
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
47720
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
47183
47721
  * night reads better as three seconds of motion than as one frame of it. Both
47184
47722
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
47185
47723
  * simply applies it to a dozen frames sampled across the render and assembles