@camstack/addon-provider-wyze 0.2.122 → 0.2.124

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/addon.js +697 -158
  2. package/dist/addon.mjs +697 -158
  3. package/package.json +1 -3
package/dist/addon.mjs CHANGED
@@ -7433,7 +7433,7 @@ function errMsg(err) {
7433
7433
  return String(err);
7434
7434
  }
7435
7435
  //#endregion
7436
- //#region ../types/dist/composition-43aqsZQj.mjs
7436
+ //#region ../types/dist/composition-Bzr7GwgP.mjs
7437
7437
  /**
7438
7438
  * The ffmpeg build every CamStack node downloads, per platform and arch.
7439
7439
  *
@@ -7487,20 +7487,20 @@ function portable(target) {
7487
7487
  }
7488
7488
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7489
7489
  /**
7490
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7491
- * valutatore puro del suo FRONTE.
7490
+ * THE table "which boolean of this device type counts as HIGH", and the
7491
+ * pure evaluator of its EDGE.
7492
7492
  *
7493
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7494
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7495
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7496
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7497
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7498
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7493
+ * ONE table for everyone who asks "is this device HIGH?": the
7494
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7495
+ * sensor markers, the orchestrator's camera-sensors bridge and
7496
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7497
+ * A second copy would diverge at the first cap added, and the symptom — "the
7498
+ * sensor rings the doorbell but does not record" — is exactly D62.
7499
7499
  *
7500
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7501
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7502
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7503
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7500
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7501
+ * two must not be unified: that one answers "what is the state WORD for a
7502
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7503
+ * boolean's EDGE counts". Deliberately different vocabularies.
7504
7504
  */
7505
7505
  /**
7506
7506
  * Known binary / switch source caps → the boolean slice field whose
@@ -7521,6 +7521,8 @@ var SOURCE_CAP_ACTIVE_FIELD = {
7521
7521
  vibration: "detected",
7522
7522
  tamper: "tampered"
7523
7523
  };
7524
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7525
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7524
7526
  /**
7525
7527
  * Error types for the safe expression engine. Two distinct classes so callers
7526
7528
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
@@ -9127,22 +9129,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9127
9129
  "package"
9128
9130
  ];
9129
9131
  /**
9130
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9131
- * un operatore può selezionare.
9132
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9133
+ * an operator can select.
9132
9134
  *
9133
- * Sono le tre offerte dallo step `object-detection`
9135
+ * They are the three offered by the `object-detection` step
9134
9136
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9135
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9136
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9137
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9138
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9137
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9138
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9139
+ * `package-detection`, whose enablement is driven by zones, and offering the
9140
+ * same word twice has already made an operator turn on the COCO proxy
9139
9141
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9140
9142
  *
9141
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9142
- * dello step e una seconda volta come union `FirstLevelMacro`
9143
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9144
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9145
- * successiva.
9143
+ * ONE list. Before today the same three were hand-written in the step's offer
9144
+ * and a second time as the union `FirstLevelMacro`
9145
+ * (`types/detection.ts`); a third copy for the recording trigger
9146
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9147
+ * invisible.
9146
9148
  */
9147
9149
  var FIRST_LEVEL_MACRO_CLASSES = [
9148
9150
  "person",
@@ -9207,17 +9209,17 @@ var RecordingStorageModeSchema = _enum([
9207
9209
  "on-device-decision"
9208
9210
  ]);
9209
9211
  /**
9210
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9211
- * tre offerte dallo step `object-detection`, da UNA lista
9212
+ * The macro classes that can open a recording window — the same
9213
+ * three offered by the `object-detection` step, from ONE list
9212
9214
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9213
9215
  */
9214
9216
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9215
9217
  /**
9216
- * True quando `values` non ripete un elemento.
9218
+ * True when `values` does not repeat an element.
9217
9219
  *
9218
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9219
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9220
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9220
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9221
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9222
+ * would count its windows twice in `segmentMissedByMs`.
9221
9223
  */
9222
9224
  var noDuplicates = (values) => new Set(values).size === values.length;
9223
9225
  /** Which detectors trigger an `events`-mode band. */
@@ -9225,34 +9227,34 @@ var RecordingTriggersSchema = object({
9225
9227
  motion: boolean().optional(),
9226
9228
  audioThresholdDbfs: number().optional(),
9227
9229
  /**
9228
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9229
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9230
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9231
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9230
+ * The macro classes whose detection opens a window. ABSENT = the source
9231
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9232
+ * trigger on, no class" is the same shape "enabled and records
9233
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9232
9234
  *
9233
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9234
- * quelle che hanno attraversato `enabledMacroClasses`, i
9235
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9236
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9237
- * finestre — vedi `recorder/object-trigger.ts`.
9235
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9236
+ * those that went through `enabledMacroClasses`, the
9237
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9238
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9239
+ * windows — see `recorder/object-trigger.ts`.
9238
9240
  */
9239
9241
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9240
9242
  /**
9241
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9242
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9243
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9244
+ * is not listened to; an empty array is rejected for the same reason as
9243
9245
  * `objectClasses`.
9244
9246
  *
9245
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9246
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9247
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9248
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9249
- * device (D12) — mai un elenco globale di cap.
9247
+ * These are SOURCE device ids, not cameras: the band names them, so the
9248
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9249
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9250
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9251
+ * device (D12) — never a global list of caps.
9250
9252
  *
9251
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9252
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9253
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9254
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9255
- * registrare.
9253
+ * What "high" means depends on the device TYPE and is not decided here:
9254
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9255
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9256
+ * the level: a contact found already open at runner restart does not
9257
+ * record.
9256
9258
  */
9257
9259
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9258
9260
  });
@@ -10329,7 +10331,7 @@ var DecoderSessionConfigSchema = object({
10329
10331
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
10330
10332
  * thing: the logging settings document on the `system` cap. Two authorities
10331
10333
  * over the values is the exact defect
10332
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
10334
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
10333
10335
  * remove; re-introducing it from the cure side would be grotesque.
10334
10336
  *
10335
10337
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -12040,7 +12042,7 @@ var BrokerStatusEnum = _enum([
12040
12042
  "unreachable",
12041
12043
  "error"
12042
12044
  ]);
12043
- var BrokerInfoSchema$1 = object({
12045
+ var BrokerInfoSchema = object({
12044
12046
  /** Stable broker id. Persisted; survives addon restarts. */
12045
12047
  id: string(),
12046
12048
  /** Addon id of the provider that OWNS this broker.
@@ -12173,7 +12175,7 @@ var GetStateInputSchema = object({
12173
12175
  * HA: entity_id (returns the cached entity state). */
12174
12176
  key: string()
12175
12177
  });
12176
- method(ListInputSchema, array(BrokerInfoSchema$1)), method(GetInputSchema, BrokerInfoSchema$1.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12178
+ method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12177
12179
  kind: "mutation",
12178
12180
  auth: "admin"
12179
12181
  }), method(RemoveInputSchema, _void(), {
@@ -13884,7 +13886,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
13884
13886
  *
13885
13887
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
13886
13888
  * was wrong — corrected 2026-08-26 after the hop map
13887
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
13889
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
13888
13890
  * There is **no Zod parse at all** between the door and the engine: the
13889
13891
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
13890
13892
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -14764,7 +14766,17 @@ var SiteZoneSchema = object({
14764
14766
  var ProviderStatusSchema = object({
14765
14767
  connected: boolean(),
14766
14768
  deviceCount: number(),
14767
- error: string().optional()
14769
+ error: string().optional(),
14770
+ /**
14771
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
14772
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
14773
+ * which every provider bundles, so only a provider BUILT from D696-amended
14774
+ * code says it. ABSENT means an older provider that may still write it (raw
14775
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
14776
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
14777
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
14778
+ */
14779
+ motionSliceWriter: literal("orchestrator").optional()
14768
14780
  });
14769
14781
  object({
14770
14782
  externalId: string(),
@@ -15981,7 +15993,7 @@ method(object({
15981
15993
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
15982
15994
  * ends in a log line, and a log line is the thing the operator asked to stop
15983
15995
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
15984
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
15996
+ * 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
15985
15997
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
15986
15998
  * media blackout were both diagnosed. The counters stay; this is where they can
15987
15999
  * be READ.
@@ -17357,7 +17369,7 @@ var BrokerStatusSchema$1 = _enum([
17357
17369
  "unreachable",
17358
17370
  "tls-error"
17359
17371
  ]);
17360
- var BrokerInfoSchema = object({
17372
+ var BrokerInfoSchema$1 = object({
17361
17373
  id: string(),
17362
17374
  name: string(),
17363
17375
  url: string(),
@@ -17420,7 +17432,7 @@ var StatusSchema = object({
17420
17432
  brokerCount: number(),
17421
17433
  embeddedRunning: boolean()
17422
17434
  });
17423
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17435
+ method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17424
17436
  kind: "mutation",
17425
17437
  auth: "admin"
17426
17438
  }), method(IdInputSchema, _void(), {
@@ -19634,78 +19646,16 @@ var NcRuleInputSchema = object({
19634
19646
  */
19635
19647
  confirm: NcConfirmSchema.optional(),
19636
19648
  /**
19637
- * WAIT for face/plate recognition before saying anything.
19638
- *
19639
- * A notification's TEXT is frozen at enqueue and its media is re-resolved at
19640
- * send; the identity is neither. A face is confirmed after `confirmFrames`
19641
- * agreeing observations — p50 **11.4 s** after the track was first seen,
19642
- * measured on this hub — and an `immediate` rule enqueues on the first object
19643
- * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
19644
- * immediate path, and no amount of media re-resolution fixes a sentence.
19645
- *
19646
- * Only two honest answers exist, and this flag picks between them. It has
19647
- * effect ONLY on a rule that declares a recognition scope
19648
- * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
19649
- * other rule there is nothing to wait for and the flag is inert.
19650
- *
19651
- * | value | what happens |
19652
- * | --- | --- |
19653
- * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
19654
- * | 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) |
19655
- *
19656
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19657
- * on the addon cap path, and absent has to keep meaning exactly what every
19658
- * rule authored before this field meant.
19659
- *
19660
- * The cost of `true` is stated here because the editor states it too: a rule
19661
- * that waits also inherits track-close SEMANTICS — its `zones` condition
19662
- * tests every zone the track visited and a `crossing` condition can no longer
19663
- * be satisfied, because a closed track carries no crossing.
19664
- */
19665
- waitForEnhancement: boolean().optional(),
19666
- /**
19667
- * GROUP a burst of subjects into ONE notification that grows.
19668
- *
19669
- * Seconds of quiet after the last matching subject before the burst is
19670
- * considered over. While it is open, the first subject enqueues immediately —
19671
- * **exactly as today, with no added latency** — and every real growth (a new
19672
- * subject, or a name confirmed on one already in it) REPLACES that
19673
- * notification with an updated one naming everybody. The push carries the
19674
- * group's own coalescing tag, so the phone replaces rather than stacks.
19675
- *
19676
- * `0` / absent = off, and off is today's behaviour byte for byte.
19677
- *
19678
- * ### Why an idle cutoff and not a window
19679
- *
19680
- * The measured seven-person arrival on device 590 spans 110 s with every
19681
- * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
19682
- * idle cutoff holds it as one and ends it when the arrival actually ends.
19683
- * 30 s is a widely shipped value for the same decision.
19684
- *
19685
- * ### What it replaces
19686
- *
19687
- * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
19688
- * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
19689
- * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
19690
- * track that did fire and 7 carrying a confirmed identity nobody heard about.
19691
- * A group collapses the same volume by MERGING, so the cooldown becomes a
19692
- * budget over GROUPS — which is what it always meant — and a growth is never
19693
- * throttled by the window its own first member spent.
19694
- *
19695
- * ### Interaction with {@link waitForEnhancement}
19696
- *
19697
- * They compose, and the order matters. `waitForEnhancement` defers the rule to
19698
- * TRACK CLOSE, so with both set the group is opened by the first member to
19699
- * CLOSE — already carrying its name — and grows as later members close. That
19700
- * is later, and complete. With grouping alone the group opens on the first
19701
- * object event and picks up names as they are confirmed, through the growth
19702
- * path. Neither combination fires twice for one subject.
19703
- *
19704
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19705
- * on the addon cap path, so absent must keep meaning what it meant before this
19706
- * field existed.
19649
+ * IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
19650
+ * seconds; the rule sends ONE message when the window closes — early, once every
19651
+ * subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
19652
+ * the rule matched, with one mosaic tile per subject.
19653
+ * Absent = plain immediate (one message per track, at the first match).
19654
+ * Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
19655
+ * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
19656
+ * path does not run Zod defaults.
19707
19657
  */
19708
- groupIdleSec: number().int().min(0).max(600).optional()
19658
+ groupingSec: number().int().min(5).max(60).optional()
19709
19659
  });
19710
19660
  /**
19711
19661
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -19753,9 +19703,10 @@ var NcRuleClearableKeySchema = _enum([
19753
19703
  "targetUsers",
19754
19704
  "snoozeOptions",
19755
19705
  "snoozeAllowGlobal",
19756
- "waitForEnhancement",
19757
19706
  "actions",
19758
19707
  "confirm",
19708
+ "groupingSec",
19709
+ "waitForEnhancement",
19759
19710
  "groupIdleSec"
19760
19711
  ]);
19761
19712
  var NcRuleUpdateInputSchema = object({
@@ -19777,9 +19728,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19777
19728
  */
19778
19729
  disabledTargetIds: array(string()).default([])
19779
19730
  });
19731
+ /**
19732
+ * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19733
+ * still-true state. `backups-exports` and `alarm` are not sections — a completed
19734
+ * job is not an open state, and the alarm stays instant.
19735
+ */
19736
+ var NcStateSummarySectionIdSchema = _enum([
19737
+ "device-state",
19738
+ "streams",
19739
+ "battery",
19740
+ "consumables",
19741
+ "tanks",
19742
+ "detection-blind",
19743
+ "nodes",
19744
+ "addons",
19745
+ "updates"
19746
+ ]);
19780
19747
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
19781
19748
  var NcStateSummaryPreviewSectionSchema = object({
19782
- id: string(),
19749
+ id: NcStateSummarySectionIdSchema,
19783
19750
  status: _enum(["read", "unavailable"]),
19784
19751
  items: number().int().nonnegative(),
19785
19752
  reason: string().optional()
@@ -19789,7 +19756,7 @@ var NcStateSummaryPreviewSectionSchema = object({
19789
19756
  * a `rule` split (no `section`), one section's on a `section` split.
19790
19757
  */
19791
19758
  var NcStateSummaryPreviewRowSchema = object({
19792
- section: string().optional(),
19759
+ section: NcStateSummarySectionIdSchema.optional(),
19793
19760
  /** The section's name on a per-section row; every reported section's, joined, on a combined one. */
19794
19761
  title: string(),
19795
19762
  text: string(),
@@ -20226,6 +20193,29 @@ object({
20226
20193
  firstAt: number(),
20227
20194
  lastAt: number()
20228
20195
  });
20196
+ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20197
+ var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20198
+ var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20199
+ var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20200
+ var NcAlarmModeDelaysListSchema = array(object({
20201
+ mode: AlarmArmModeSchema,
20202
+ exitDelaySec: NcAlarmDelaySecSchema.optional(),
20203
+ entryDelaySec: NcAlarmDelaySecSchema.optional(),
20204
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20205
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20206
+ var NcAlarmModeDelaysEditListSchema = array(object({
20207
+ mode: AlarmArmModeSchema,
20208
+ exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20209
+ entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20210
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20211
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20212
+ /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20213
+ var NcAlarmNonBlockingEditSchema = object({
20214
+ mode: AlarmArmModeSchema,
20215
+ deviceId: number().int().positive(),
20216
+ /** true = on the list (may be open, does not block); false = off the list (blocks). */
20217
+ nonBlocking: boolean()
20218
+ });
20229
20219
  /**
20230
20220
  * The per-mode lists, at most one per mode. Two lists for one mode have no
20231
20221
  * meaning a reader could agree on (union? the last one?), so they are refused
@@ -20234,10 +20224,10 @@ object({
20234
20224
  var NcAlarmNonBlockingListSchema = array(object({
20235
20225
  mode: AlarmArmModeSchema,
20236
20226
  deviceIds: array(number().int()).max(200)
20237
- })).max(8).refine((lists) => new Set(lists.map((l) => l.mode)).size === lists.length, { message: "nonBlocking: at most one list per arm mode" });
20227
+ })).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20238
20228
  /**
20239
- * The three durations the panel's state machine runs on, who hears about its
20240
- * transitions, and which openings each mode tolerates.
20229
+ * The three durations — global, and per mode since D697 — the panel's state
20230
+ * machine runs on, who hears about its transitions, and which openings each mode tolerates.
20241
20231
  *
20242
20232
  * They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
20243
20233
  * `alarm-panel` is `deviceNative` and its other provider mirrors somebody
@@ -20247,15 +20237,15 @@ var NcAlarmNonBlockingListSchema = array(object({
20247
20237
  */
20248
20238
  var NcAlarmSettingsSchema = object({
20249
20239
  /** Grace period between arming and the mode taking effect. 0 = immediate. */
20250
- exitDelaySec: number().int().min(0).max(600),
20240
+ exitDelaySec: NcAlarmDelaySecSchema,
20251
20241
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20252
- entryDelaySec: number().int().min(0).max(600),
20242
+ entryDelaySec: NcAlarmDelaySecSchema,
20253
20243
  /**
20254
20244
  * How long `triggered` lasts before the panel re-arms itself.
20255
20245
  * **0 = until an operator disarms it** — the behaviour before this field
20256
20246
  * existed, and therefore what an untouched install keeps doing.
20257
20247
  */
20258
- triggeredDurationSec: number().int().min(0).max(3600),
20248
+ triggeredDurationSec: NcAlarmTriggeredSecSchema,
20259
20249
  /**
20260
20250
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20261
20251
  * remove after one release. Optional so an older admin's patch (which still
@@ -20278,17 +20268,30 @@ var NcAlarmSettingsSchema = object({
20278
20268
  * per mode is meaningful. Defaulted to `[]` so a blob stored before D630
20279
20269
  * parses as "every opening blocks" — the behaviour it was written under.
20280
20270
  */
20281
- nonBlocking: NcAlarmNonBlockingListSchema.default([])
20271
+ nonBlocking: NcAlarmNonBlockingListSchema.default([]),
20272
+ /**
20273
+ * Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
20274
+ * without a field, uses the global value above — so `[]`, the default, is exactly the
20275
+ * behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
20276
+ */
20277
+ modeDelays: NcAlarmModeDelaysListSchema.default([])
20282
20278
  });
20283
20279
  /**
20284
20280
  * Every field optional — a tab edits one control at a time.
20285
20281
  *
20286
- * `nonBlocking` is re-declared WITHOUT its default: `.partial()` does not
20287
- * remove an inner `.default()`, so a patch that never named the field would
20288
- * parse to `nonBlocking: []` and wipe every mode's list on an unrelated edit
20289
- * (the same trap {@link NcRulePatchSchema} documents).
20282
+ * `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
20283
+ * `.partial()` does not remove an inner `.default()`, so a patch that never
20284
+ * named the field would parse to `[]` and wipe every mode's list on an
20285
+ * unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
20286
+ * `modeDelays` means EDITS, not the stored overrides.
20290
20287
  */
20291
- var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({ nonBlocking: NcAlarmNonBlockingListSchema }).partial();
20288
+ var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
20289
+ nonBlocking: NcAlarmNonBlockingListSchema,
20290
+ /** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
20291
+ modeDelays: NcAlarmModeDelaysEditListSchema,
20292
+ /** ONE membership change; the panel applies it to the list it holds at its turn. */
20293
+ nonBlockingEdit: NcAlarmNonBlockingEditSchema
20294
+ }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
20292
20295
  /**
20293
20296
  * What one arm mode actually arms, DERIVED from the enabled rules gated on it.
20294
20297
  * Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
@@ -20388,6 +20391,28 @@ var NcAlarmConfigSchema = object({
20388
20391
  */
20389
20392
  live: NcAlarmLiveSchema.optional()
20390
20393
  });
20394
+ var NcAlarmSensorReadingSchema = _enum([
20395
+ "open",
20396
+ "closed",
20397
+ "unknown",
20398
+ "not-opening"
20399
+ ]);
20400
+ /** One device's state as the alarm reads it — the classifier the arm check uses. */
20401
+ var NcAlarmSensorStateSchema = object({
20402
+ deviceId: number().int().positive(),
20403
+ reading: NcAlarmSensorReadingSchema,
20404
+ /** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
20405
+ state: string().nullable(),
20406
+ /** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
20407
+ unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
20408
+ /** The device manager's liveness as the centre mirrors it; null = not known. */
20409
+ online: boolean().nullable()
20410
+ });
20411
+ var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
20412
+ var NcAlarmSensorsSchema = object({
20413
+ sensors: array(NcAlarmSensorStateSchema),
20414
+ readAt: number().int().nonnegative()
20415
+ });
20391
20416
  /**
20392
20417
  * ONE rule's demand on ONE camera's clip ring.
20393
20418
  *
@@ -20478,7 +20503,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20478
20503
  }), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
20479
20504
  kind: "mutation",
20480
20505
  auth: "admin"
20481
- });
20506
+ }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
20482
20507
  /**
20483
20508
  * Zod schemas for persisted record types.
20484
20509
  *
@@ -21630,14 +21655,14 @@ var TrackSchema = object({
21630
21655
  * `derive-returned-null tile=standin`,
21631
21656
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
21632
21657
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
21633
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
21658
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
21634
21659
  * tile is a face/plate stand-in, a raster crop, or an icon.
21635
21660
  *
21636
21661
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
21637
21662
  * the TILE ranked below native, so a track whose thumbnail landed natively
21638
21663
  * while its key frame missed carried no reason at all — three of the four
21639
21664
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
21640
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
21665
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
21641
21666
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
21642
21667
  * lastFrame copy source`), so its absence is now on this line whatever the
21643
21668
  * tile ended up being.
@@ -21724,7 +21749,7 @@ var MotionEventSchema = object({
21724
21749
  /**
21725
21750
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
21726
21751
  * first entry is always `0`) of every genuine off→on transition the
21727
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
21752
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
21728
21753
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
21729
21754
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
21730
21755
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -22248,6 +22273,7 @@ var KeyEventSchema = object({
22248
22273
  bestEventId: string(),
22249
22274
  /** Track lifetime in ms (lastSeen - firstSeen). */
22250
22275
  windowMs: number().optional(),
22276
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
22251
22277
  ...TrackFlagFields,
22252
22278
  ...TrackRetrainFields
22253
22279
  });
@@ -27133,7 +27159,7 @@ var ClipPlaybackSchema = object({
27133
27159
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
27134
27160
  * time the camera is awake for its own reasons — is deliberately not a member:
27135
27161
  * it was proposed, it is free on the battery, and the operator declined it on
27136
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
27162
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
27137
27163
  * D558 "Considered and not taken").
27138
27164
  */
27139
27165
  var ClipWakeSchema = _enum(["authorised"]);
@@ -27394,7 +27420,7 @@ DeviceType.Camera, method(object({
27394
27420
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
27395
27421
  * assumed the answer was a fan-out over everything a camera has. The
27396
27422
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
27397
- * solo"* — so the list is asked of one provider at a time and there is
27423
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
27398
27424
  * nothing to filter out of it.
27399
27425
  */
27400
27426
  provider: string().min(1)
@@ -35392,7 +35418,7 @@ var ReadGopBytesResultSchema = object({
35392
35418
  /**
35393
35419
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
35394
35420
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
35395
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
35421
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
35396
35422
  * a replay needs several seconds of native pixels, not one frame.
35397
35423
  *
35398
35424
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -38756,6 +38782,7 @@ var zoneRulesCapability = {
38756
38782
  */
38757
38783
  durability: "restored"
38758
38784
  };
38785
+ SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
38759
38786
  /**
38760
38787
  * Accessory device helpers — shared across drivers.
38761
38788
  *
@@ -39815,13 +39842,14 @@ var BaseDeviceProvider = class extends BaseAddon {
39815
39842
  async getStatus() {
39816
39843
  const all = await this.ctx.kernel.devices?.getAll() ?? [];
39817
39844
  const summary = this.restoreFailureSummary();
39818
- if (summary === null) return {
39845
+ const base = {
39819
39846
  connected: true,
39820
- deviceCount: all.length
39847
+ deviceCount: all.length,
39848
+ motionSliceWriter: "orchestrator"
39821
39849
  };
39850
+ if (summary === null) return base;
39822
39851
  return {
39823
- connected: true,
39824
- deviceCount: all.length,
39852
+ ...base,
39825
39853
  error: summary
39826
39854
  };
39827
39855
  }
@@ -45257,6 +45285,12 @@ Object.freeze({
45257
45285
  addonId: null,
45258
45286
  access: "view"
45259
45287
  },
45288
+ "notificationRules.getAlarmSensors": {
45289
+ capName: "notification-rules",
45290
+ capScope: "system",
45291
+ addonId: null,
45292
+ access: "view"
45293
+ },
45260
45294
  "notificationRules.getClipRetentionAsks": {
45261
45295
  capName: "notification-rules",
45262
45296
  capScope: "system",
@@ -48835,6 +48869,11 @@ Object.freeze({
48835
48869
  }
48836
48870
  });
48837
48871
  Object.freeze({
48872
+ "accessories.getStatus": [{
48873
+ name: "deviceId",
48874
+ form: "single",
48875
+ optional: false
48876
+ }],
48838
48877
  "accessories.setChildHidden": [{
48839
48878
  name: "childDeviceId",
48840
48879
  form: "single",
@@ -48854,6 +48893,11 @@ Object.freeze({
48854
48893
  form: "single",
48855
48894
  optional: false
48856
48895
  }],
48896
+ "airQualitySensor.getStatus": [{
48897
+ name: "deviceId",
48898
+ form: "single",
48899
+ optional: false
48900
+ }],
48857
48901
  "alarmPanel.arm": [{
48858
48902
  name: "deviceId",
48859
48903
  form: "single",
@@ -48864,11 +48908,36 @@ Object.freeze({
48864
48908
  form: "single",
48865
48909
  optional: false
48866
48910
  }],
48911
+ "alarmPanel.getStatus": [{
48912
+ name: "deviceId",
48913
+ form: "single",
48914
+ optional: false
48915
+ }],
48867
48916
  "alarmPanel.trigger": [{
48868
48917
  name: "deviceId",
48869
48918
  form: "single",
48870
48919
  optional: false
48871
48920
  }],
48921
+ "ambientLightSensor.getStatus": [{
48922
+ name: "deviceId",
48923
+ form: "single",
48924
+ optional: false
48925
+ }],
48926
+ "audioAnalysis.applyDeviceSettingsPatch": [{
48927
+ name: "deviceId",
48928
+ form: "single",
48929
+ optional: false
48930
+ }],
48931
+ "audioAnalysis.getDeviceLiveContribution": [{
48932
+ name: "deviceId",
48933
+ form: "single",
48934
+ optional: false
48935
+ }],
48936
+ "audioAnalysis.getDeviceSettingsContribution": [{
48937
+ name: "deviceId",
48938
+ form: "single",
48939
+ optional: false
48940
+ }],
48872
48941
  "audioAnalysis.resolveDeviceSettings": [{
48873
48942
  name: "deviceId",
48874
48943
  form: "single",
@@ -48909,16 +48978,36 @@ Object.freeze({
48909
48978
  form: "single",
48910
48979
  optional: false
48911
48980
  }],
48981
+ "automationControl.getStatus": [{
48982
+ name: "deviceId",
48983
+ form: "single",
48984
+ optional: false
48985
+ }],
48912
48986
  "automationControl.trigger": [{
48913
48987
  name: "deviceId",
48914
48988
  form: "single",
48915
48989
  optional: false
48916
48990
  }],
48991
+ "battery.getStatus": [{
48992
+ name: "deviceId",
48993
+ form: "single",
48994
+ optional: false
48995
+ }],
48917
48996
  "battery.wakeForStream": [{
48918
48997
  name: "deviceId",
48919
48998
  form: "single",
48920
48999
  optional: false
48921
49000
  }],
49001
+ "binary.getStatus": [{
49002
+ name: "deviceId",
49003
+ form: "single",
49004
+ optional: false
49005
+ }],
49006
+ "brightness.getStatus": [{
49007
+ name: "deviceId",
49008
+ form: "single",
49009
+ optional: false
49010
+ }],
48922
49011
  "brightness.setBrightness": [{
48923
49012
  name: "deviceId",
48924
49013
  form: "single",
@@ -48934,6 +49023,26 @@ Object.freeze({
48934
49023
  form: "single",
48935
49024
  optional: false
48936
49025
  }],
49026
+ "cameraCredentials.getStatus": [{
49027
+ name: "deviceId",
49028
+ form: "single",
49029
+ optional: false
49030
+ }],
49031
+ "cameraGridLayout.applyDeviceSettingsPatch": [{
49032
+ name: "deviceId",
49033
+ form: "single",
49034
+ optional: false
49035
+ }],
49036
+ "cameraGridLayout.getDeviceLiveContribution": [{
49037
+ name: "deviceId",
49038
+ form: "single",
49039
+ optional: false
49040
+ }],
49041
+ "cameraGridLayout.getDeviceSettingsContribution": [{
49042
+ name: "deviceId",
49043
+ form: "single",
49044
+ optional: false
49045
+ }],
48937
49046
  "cameraGridLayout.getLayout": [{
48938
49047
  name: "deviceId",
48939
49048
  form: "single",
@@ -48949,6 +49058,21 @@ Object.freeze({
48949
49058
  form: "single",
48950
49059
  optional: false
48951
49060
  }],
49061
+ "cameraPipelineConfig.applyDeviceSettingsPatch": [{
49062
+ name: "deviceId",
49063
+ form: "single",
49064
+ optional: false
49065
+ }],
49066
+ "cameraPipelineConfig.getDeviceLiveContribution": [{
49067
+ name: "deviceId",
49068
+ form: "single",
49069
+ optional: false
49070
+ }],
49071
+ "cameraPipelineConfig.getDeviceSettingsContribution": [{
49072
+ name: "deviceId",
49073
+ form: "single",
49074
+ optional: false
49075
+ }],
48952
49076
  "cameraStreams.getBrokerStreams": [{
48953
49077
  name: "deviceId",
48954
49078
  form: "single",
@@ -48974,6 +49098,16 @@ Object.freeze({
48974
49098
  form: "single",
48975
49099
  optional: false
48976
49100
  }],
49101
+ "carbonMonoxide.getStatus": [{
49102
+ name: "deviceId",
49103
+ form: "single",
49104
+ optional: false
49105
+ }],
49106
+ "climateControl.getStatus": [{
49107
+ name: "deviceId",
49108
+ form: "single",
49109
+ optional: false
49110
+ }],
48977
49111
  "climateControl.setFanMode": [{
48978
49112
  name: "deviceId",
48979
49113
  form: "single",
@@ -49014,16 +49148,41 @@ Object.freeze({
49014
49148
  form: "single",
49015
49149
  optional: false
49016
49150
  }],
49151
+ "color.getStatus": [{
49152
+ name: "deviceId",
49153
+ form: "single",
49154
+ optional: false
49155
+ }],
49017
49156
  "color.setColor": [{
49018
49157
  name: "deviceId",
49019
49158
  form: "single",
49020
49159
  optional: false
49021
49160
  }],
49161
+ "connectivity.getStatus": [{
49162
+ name: "deviceId",
49163
+ form: "single",
49164
+ optional: false
49165
+ }],
49166
+ "consumables.getStatus": [{
49167
+ name: "deviceId",
49168
+ form: "single",
49169
+ optional: false
49170
+ }],
49022
49171
  "consumables.reset": [{
49023
49172
  name: "deviceId",
49024
49173
  form: "single",
49025
49174
  optional: false
49026
49175
  }],
49176
+ "contact.getStatus": [{
49177
+ name: "deviceId",
49178
+ form: "single",
49179
+ optional: false
49180
+ }],
49181
+ "control.getStatus": [{
49182
+ name: "deviceId",
49183
+ form: "single",
49184
+ optional: false
49185
+ }],
49027
49186
  "control.setValue": [{
49028
49187
  name: "deviceId",
49029
49188
  form: "single",
@@ -49034,6 +49193,11 @@ Object.freeze({
49034
49193
  form: "single",
49035
49194
  optional: false
49036
49195
  }],
49196
+ "cover.getStatus": [{
49197
+ name: "deviceId",
49198
+ form: "single",
49199
+ optional: false
49200
+ }],
49037
49201
  "cover.open": [{
49038
49202
  name: "deviceId",
49039
49203
  form: "single",
@@ -49059,6 +49223,11 @@ Object.freeze({
49059
49223
  form: "single",
49060
49224
  optional: false
49061
49225
  }],
49226
+ "dayNight.getStatus": [{
49227
+ name: "deviceId",
49228
+ form: "single",
49229
+ optional: false
49230
+ }],
49062
49231
  "dayNight.setSettings": [{
49063
49232
  name: "deviceId",
49064
49233
  form: "single",
@@ -49069,11 +49238,31 @@ Object.freeze({
49069
49238
  form: "single",
49070
49239
  optional: true
49071
49240
  }],
49241
+ "detectionPipeline.applyDeviceSettingsPatch": [{
49242
+ name: "deviceId",
49243
+ form: "single",
49244
+ optional: false
49245
+ }],
49246
+ "detectionPipeline.getDeviceLiveContribution": [{
49247
+ name: "deviceId",
49248
+ form: "single",
49249
+ optional: false
49250
+ }],
49251
+ "detectionPipeline.getDeviceSettingsContribution": [{
49252
+ name: "deviceId",
49253
+ form: "single",
49254
+ optional: false
49255
+ }],
49072
49256
  "deviceAdminLink.getAdminLink": [{
49073
49257
  name: "deviceId",
49074
49258
  form: "single",
49075
49259
  optional: false
49076
49260
  }],
49261
+ "deviceAdoption.getStatus": [{
49262
+ name: "deviceId",
49263
+ form: "single",
49264
+ optional: false
49265
+ }],
49077
49266
  "deviceAdoption.release": [{
49078
49267
  name: "camDeviceId",
49079
49268
  form: "single",
@@ -49089,6 +49278,11 @@ Object.freeze({
49089
49278
  form: "single",
49090
49279
  optional: false
49091
49280
  }],
49281
+ "deviceDiscovery.getStatus": [{
49282
+ name: "deviceId",
49283
+ form: "single",
49284
+ optional: false
49285
+ }],
49092
49286
  "deviceDiscovery.listDiscovered": [{
49093
49287
  name: "deviceId",
49094
49288
  form: "single",
@@ -49108,6 +49302,21 @@ Object.freeze({
49108
49302
  form: "single",
49109
49303
  optional: false
49110
49304
  }],
49305
+ "deviceExport.applyDeviceSettingsPatch": [{
49306
+ name: "deviceId",
49307
+ form: "single",
49308
+ optional: false
49309
+ }],
49310
+ "deviceExport.getDeviceLiveContribution": [{
49311
+ name: "deviceId",
49312
+ form: "single",
49313
+ optional: false
49314
+ }],
49315
+ "deviceExport.getDeviceSettingsContribution": [{
49316
+ name: "deviceId",
49317
+ form: "single",
49318
+ optional: false
49319
+ }],
49111
49320
  "deviceExtension.listCandidates": [{
49112
49321
  name: "deviceId",
49113
49322
  form: "single",
@@ -49456,6 +49665,26 @@ Object.freeze({
49456
49665
  form: "single",
49457
49666
  optional: false
49458
49667
  }],
49668
+ "deviceStatus.getStatus": [{
49669
+ name: "deviceId",
49670
+ form: "single",
49671
+ optional: false
49672
+ }],
49673
+ "doorbell.getStatus": [{
49674
+ name: "deviceId",
49675
+ form: "single",
49676
+ optional: false
49677
+ }],
49678
+ "enumSensor.getStatus": [{
49679
+ name: "deviceId",
49680
+ form: "single",
49681
+ optional: false
49682
+ }],
49683
+ "eventEmitter.getStatus": [{
49684
+ name: "deviceId",
49685
+ form: "single",
49686
+ optional: false
49687
+ }],
49459
49688
  "faceGallery.getFaceByTrack": [{
49460
49689
  name: "deviceId",
49461
49690
  form: "single",
@@ -49470,6 +49699,11 @@ Object.freeze({
49470
49699
  form: "array",
49471
49700
  optional: true
49472
49701
  }],
49702
+ "fanControl.getStatus": [{
49703
+ name: "deviceId",
49704
+ form: "single",
49705
+ optional: false
49706
+ }],
49473
49707
  "fanControl.setDirection": [{
49474
49708
  name: "deviceId",
49475
49709
  form: "single",
@@ -49490,6 +49724,26 @@ Object.freeze({
49490
49724
  form: "single",
49491
49725
  optional: false
49492
49726
  }],
49727
+ "featureProbe.getStatus": [{
49728
+ name: "deviceId",
49729
+ form: "single",
49730
+ optional: false
49731
+ }],
49732
+ "flood.getStatus": [{
49733
+ name: "deviceId",
49734
+ form: "single",
49735
+ optional: false
49736
+ }],
49737
+ "gas.getStatus": [{
49738
+ name: "deviceId",
49739
+ form: "single",
49740
+ optional: false
49741
+ }],
49742
+ "humidifier.getStatus": [{
49743
+ name: "deviceId",
49744
+ form: "single",
49745
+ optional: false
49746
+ }],
49493
49747
  "humidifier.setMode": [{
49494
49748
  name: "deviceId",
49495
49749
  form: "single",
@@ -49505,11 +49759,26 @@ Object.freeze({
49505
49759
  form: "single",
49506
49760
  optional: false
49507
49761
  }],
49762
+ "humiditySensor.getStatus": [{
49763
+ name: "deviceId",
49764
+ form: "single",
49765
+ optional: false
49766
+ }],
49767
+ "image.getStatus": [{
49768
+ name: "deviceId",
49769
+ form: "single",
49770
+ optional: false
49771
+ }],
49508
49772
  "imageSettings.getOptions": [{
49509
49773
  name: "deviceId",
49510
49774
  form: "single",
49511
49775
  optional: false
49512
49776
  }],
49777
+ "imageSettings.getStatus": [{
49778
+ name: "deviceId",
49779
+ form: "single",
49780
+ optional: false
49781
+ }],
49513
49782
  "imageSettings.setSettings": [{
49514
49783
  name: "deviceId",
49515
49784
  form: "single",
@@ -49520,6 +49789,11 @@ Object.freeze({
49520
49789
  form: "single",
49521
49790
  optional: false
49522
49791
  }],
49792
+ "intercom.getStatus": [{
49793
+ name: "deviceId",
49794
+ form: "single",
49795
+ optional: false
49796
+ }],
49523
49797
  "intercom.handleAnswer": [{
49524
49798
  name: "deviceId",
49525
49799
  form: "single",
@@ -49550,6 +49824,11 @@ Object.freeze({
49550
49824
  form: "single",
49551
49825
  optional: false
49552
49826
  }],
49827
+ "lawnMowerControl.getStatus": [{
49828
+ name: "deviceId",
49829
+ form: "single",
49830
+ optional: false
49831
+ }],
49553
49832
  "lawnMowerControl.pause": [{
49554
49833
  name: "deviceId",
49555
49834
  form: "single",
@@ -49560,6 +49839,11 @@ Object.freeze({
49560
49839
  form: "single",
49561
49840
  optional: false
49562
49841
  }],
49842
+ "lockControl.getStatus": [{
49843
+ name: "deviceId",
49844
+ form: "single",
49845
+ optional: false
49846
+ }],
49563
49847
  "lockControl.lock": [{
49564
49848
  name: "deviceId",
49565
49849
  form: "single",
@@ -49575,6 +49859,11 @@ Object.freeze({
49575
49859
  form: "single",
49576
49860
  optional: false
49577
49861
  }],
49862
+ "mediaPlayer.getStatus": [{
49863
+ name: "deviceId",
49864
+ form: "single",
49865
+ optional: false
49866
+ }],
49578
49867
  "mediaPlayer.next": [{
49579
49868
  name: "deviceId",
49580
49869
  form: "single",
@@ -49635,6 +49924,11 @@ Object.freeze({
49635
49924
  form: "single",
49636
49925
  optional: false
49637
49926
  }],
49927
+ "motion.getStatus": [{
49928
+ name: "deviceId",
49929
+ form: "single",
49930
+ optional: false
49931
+ }],
49638
49932
  "motion.isDetected": [{
49639
49933
  name: "deviceId",
49640
49934
  form: "single",
@@ -49645,11 +49939,31 @@ Object.freeze({
49645
49939
  form: "single",
49646
49940
  optional: false
49647
49941
  }],
49942
+ "motionDetection.applyDeviceSettingsPatch": [{
49943
+ name: "deviceId",
49944
+ form: "single",
49945
+ optional: false
49946
+ }],
49947
+ "motionDetection.getDeviceLiveContribution": [{
49948
+ name: "deviceId",
49949
+ form: "single",
49950
+ optional: false
49951
+ }],
49952
+ "motionDetection.getDeviceSettingsContribution": [{
49953
+ name: "deviceId",
49954
+ form: "single",
49955
+ optional: false
49956
+ }],
49648
49957
  "motionDetection.removeCamera": [{
49649
49958
  name: "deviceId",
49650
49959
  form: "single",
49651
49960
  optional: false
49652
49961
  }],
49962
+ "motionTrigger.getStatus": [{
49963
+ name: "deviceId",
49964
+ form: "single",
49965
+ optional: false
49966
+ }],
49653
49967
  "motionTrigger.setMotionTrigger": [{
49654
49968
  name: "deviceId",
49655
49969
  form: "single",
@@ -49660,6 +49974,11 @@ Object.freeze({
49660
49974
  form: "single",
49661
49975
  optional: false
49662
49976
  }],
49977
+ "motionZones.getStatus": [{
49978
+ name: "deviceId",
49979
+ form: "single",
49980
+ optional: false
49981
+ }],
49663
49982
  "motionZones.setZone": [{
49664
49983
  name: "deviceId",
49665
49984
  form: "single",
@@ -49670,6 +49989,11 @@ Object.freeze({
49670
49989
  form: "single",
49671
49990
  optional: false
49672
49991
  }],
49992
+ "nativeObjectDetection.getStatus": [{
49993
+ name: "deviceId",
49994
+ form: "single",
49995
+ optional: false
49996
+ }],
49673
49997
  "nativeObjectDetection.setEnabled": [{
49674
49998
  name: "deviceId",
49675
49999
  form: "single",
@@ -49685,6 +50009,11 @@ Object.freeze({
49685
50009
  form: "single",
49686
50010
  optional: false
49687
50011
  }],
50012
+ "navigation.getStatus": [{
50013
+ name: "deviceId",
50014
+ form: "single",
50015
+ optional: false
50016
+ }],
49688
50017
  "navigation.goToPoint": [{
49689
50018
  name: "deviceId",
49690
50019
  form: "single",
@@ -49730,6 +50059,11 @@ Object.freeze({
49730
50059
  form: "single",
49731
50060
  optional: false
49732
50061
  }],
50062
+ "networkLink.getStatus": [{
50063
+ name: "deviceId",
50064
+ form: "single",
50065
+ optional: false
50066
+ }],
49733
50067
  "networkQuality.getDeviceStats": [{
49734
50068
  name: "deviceId",
49735
50069
  form: "single",
@@ -49740,6 +50074,11 @@ Object.freeze({
49740
50074
  form: "single",
49741
50075
  optional: false
49742
50076
  }],
50077
+ "notificationRules.getAlarmSensors": [{
50078
+ name: "deviceIds",
50079
+ form: "array",
50080
+ optional: false
50081
+ }],
49743
50082
  "notificationRules.setDeviceMuted": [{
49744
50083
  name: "deviceId",
49745
50084
  form: "single",
@@ -49750,11 +50089,26 @@ Object.freeze({
49750
50089
  form: "single",
49751
50090
  optional: false
49752
50091
  }],
50092
+ "notifier.getStatus": [{
50093
+ name: "deviceId",
50094
+ form: "single",
50095
+ optional: false
50096
+ }],
49753
50097
  "notifier.send": [{
49754
50098
  name: "deviceId",
49755
50099
  form: "single",
49756
50100
  optional: false
49757
50101
  }],
50102
+ "numericSensor.getStatus": [{
50103
+ name: "deviceId",
50104
+ form: "single",
50105
+ optional: false
50106
+ }],
50107
+ "osd.getStatus": [{
50108
+ name: "deviceId",
50109
+ form: "single",
50110
+ optional: false
50111
+ }],
49758
50112
  "osd.setOverlay": [{
49759
50113
  name: "deviceId",
49760
50114
  form: "single",
@@ -49814,6 +50168,11 @@ Object.freeze({
49814
50168
  form: "single",
49815
50169
  optional: false
49816
50170
  }],
50171
+ "petFeeder.getStatus": [{
50172
+ name: "deviceId",
50173
+ form: "single",
50174
+ optional: false
50175
+ }],
49817
50176
  "petFeeder.markFoodReplenished": [{
49818
50177
  name: "deviceId",
49819
50178
  form: "single",
@@ -49849,6 +50208,11 @@ Object.freeze({
49849
50208
  form: "single",
49850
50209
  optional: false
49851
50210
  }],
50211
+ "pipelineAnalytics.applyDeviceSettingsPatch": [{
50212
+ name: "deviceId",
50213
+ form: "single",
50214
+ optional: false
50215
+ }],
49852
50216
  "pipelineAnalytics.clearTrackRelation": [{
49853
50217
  name: "deviceId",
49854
50218
  form: "single",
@@ -49889,6 +50253,16 @@ Object.freeze({
49889
50253
  form: "single",
49890
50254
  optional: false
49891
50255
  }],
50256
+ "pipelineAnalytics.getDeviceLiveContribution": [{
50257
+ name: "deviceId",
50258
+ form: "single",
50259
+ optional: false
50260
+ }],
50261
+ "pipelineAnalytics.getDeviceSettingsContribution": [{
50262
+ name: "deviceId",
50263
+ form: "single",
50264
+ optional: false
50265
+ }],
49892
50266
  "pipelineAnalytics.getEventDensity": [{
49893
50267
  name: "deviceId",
49894
50268
  form: "single",
@@ -50104,6 +50478,11 @@ Object.freeze({
50104
50478
  form: "single",
50105
50479
  optional: true
50106
50480
  }],
50481
+ "pipelineOrchestrator.applyDeviceSettingsPatch": [{
50482
+ name: "deviceId",
50483
+ form: "single",
50484
+ optional: false
50485
+ }],
50107
50486
  "pipelineOrchestrator.assignAudio": [{
50108
50487
  name: "deviceId",
50109
50488
  form: "single",
@@ -50149,6 +50528,16 @@ Object.freeze({
50149
50528
  form: "single",
50150
50529
  optional: false
50151
50530
  }],
50531
+ "pipelineOrchestrator.getDeviceLiveContribution": [{
50532
+ name: "deviceId",
50533
+ form: "single",
50534
+ optional: false
50535
+ }],
50536
+ "pipelineOrchestrator.getDeviceSettingsContribution": [{
50537
+ name: "deviceId",
50538
+ form: "single",
50539
+ optional: false
50540
+ }],
50152
50541
  "pipelineOrchestrator.getPipelineAssignment": [{
50153
50542
  name: "deviceId",
50154
50543
  form: "single",
@@ -50269,11 +50658,31 @@ Object.freeze({
50269
50658
  form: "single",
50270
50659
  optional: true
50271
50660
  }],
50661
+ "powerMeter.getStatus": [{
50662
+ name: "deviceId",
50663
+ form: "single",
50664
+ optional: false
50665
+ }],
50666
+ "presence.getStatus": [{
50667
+ name: "deviceId",
50668
+ form: "single",
50669
+ optional: false
50670
+ }],
50671
+ "pressureSensor.getStatus": [{
50672
+ name: "deviceId",
50673
+ form: "single",
50674
+ optional: false
50675
+ }],
50272
50676
  "privacyMask.getOptions": [{
50273
50677
  name: "deviceId",
50274
50678
  form: "single",
50275
50679
  optional: false
50276
50680
  }],
50681
+ "privacyMask.getStatus": [{
50682
+ name: "deviceId",
50683
+ form: "single",
50684
+ optional: false
50685
+ }],
50277
50686
  "privacyMask.setAudioEnabled": [{
50278
50687
  name: "deviceId",
50279
50688
  form: "single",
@@ -50324,6 +50733,11 @@ Object.freeze({
50324
50733
  form: "single",
50325
50734
  optional: false
50326
50735
  }],
50736
+ "ptz.getStatus": [{
50737
+ name: "deviceId",
50738
+ form: "single",
50739
+ optional: false
50740
+ }],
50327
50741
  "ptz.goHome": [{
50328
50742
  name: "deviceId",
50329
50743
  form: "single",
@@ -50414,6 +50828,11 @@ Object.freeze({
50414
50828
  form: "single",
50415
50829
  optional: false
50416
50830
  }],
50831
+ "recordingArchive.applyDeviceSettingsPatch": [{
50832
+ name: "deviceId",
50833
+ form: "single",
50834
+ optional: false
50835
+ }],
50417
50836
  "recordingArchive.deleteFootprint": [{
50418
50837
  name: "deviceId",
50419
50838
  form: "single",
@@ -50434,6 +50853,21 @@ Object.freeze({
50434
50853
  form: "single",
50435
50854
  optional: false
50436
50855
  }],
50856
+ "recordingArchive.getDeviceLiveContribution": [{
50857
+ name: "deviceId",
50858
+ form: "single",
50859
+ optional: false
50860
+ }],
50861
+ "recordingArchive.getDeviceSettingsContribution": [{
50862
+ name: "deviceId",
50863
+ form: "single",
50864
+ optional: false
50865
+ }],
50866
+ "recordingArchive.getStatus": [{
50867
+ name: "deviceId",
50868
+ form: "single",
50869
+ optional: false
50870
+ }],
50437
50871
  "recordingArchive.listOpsLog": [{
50438
50872
  name: "deviceId",
50439
50873
  form: "single",
@@ -50519,6 +50953,11 @@ Object.freeze({
50519
50953
  form: "single",
50520
50954
  optional: false
50521
50955
  }],
50956
+ "recordingOnboard.getStatus": [{
50957
+ name: "deviceId",
50958
+ form: "single",
50959
+ optional: false
50960
+ }],
50522
50961
  "recordingOnboard.setSettings": [{
50523
50962
  name: "deviceId",
50524
50963
  form: "single",
@@ -50549,6 +50988,11 @@ Object.freeze({
50549
50988
  form: "single",
50550
50989
  optional: false
50551
50990
  }],
50991
+ "sceneMonitor.getStatus": [{
50992
+ name: "deviceId",
50993
+ form: "single",
50994
+ optional: false
50995
+ }],
50552
50996
  "sceneMonitor.listScenes": [{
50553
50997
  name: "deviceId",
50554
50998
  form: "single",
@@ -50574,6 +51018,11 @@ Object.freeze({
50574
51018
  form: "single",
50575
51019
  optional: false
50576
51020
  }],
51021
+ "scriptRunner.getStatus": [{
51022
+ name: "deviceId",
51023
+ form: "single",
51024
+ optional: false
51025
+ }],
50577
51026
  "scriptRunner.run": [{
50578
51027
  name: "deviceId",
50579
51028
  form: "single",
@@ -50584,11 +51033,31 @@ Object.freeze({
50584
51033
  form: "single",
50585
51034
  optional: false
50586
51035
  }],
51036
+ "smoke.getStatus": [{
51037
+ name: "deviceId",
51038
+ form: "single",
51039
+ optional: false
51040
+ }],
51041
+ "snapshot.applyDeviceSettingsPatch": [{
51042
+ name: "deviceId",
51043
+ form: "single",
51044
+ optional: false
51045
+ }],
50587
51046
  "snapshot.getDebugState": [{
50588
51047
  name: "deviceId",
50589
51048
  form: "single",
50590
51049
  optional: false
50591
51050
  }],
51051
+ "snapshot.getDeviceLiveContribution": [{
51052
+ name: "deviceId",
51053
+ form: "single",
51054
+ optional: false
51055
+ }],
51056
+ "snapshot.getDeviceSettingsContribution": [{
51057
+ name: "deviceId",
51058
+ form: "single",
51059
+ optional: false
51060
+ }],
50592
51061
  "snapshot.getSnapshot": [{
50593
51062
  name: "deviceId",
50594
51063
  form: "single",
@@ -50605,6 +51074,11 @@ Object.freeze({
50605
51074
  form: "array",
50606
51075
  optional: false
50607
51076
  }],
51077
+ "snapshot.getStatus": [{
51078
+ name: "deviceId",
51079
+ form: "single",
51080
+ optional: false
51081
+ }],
50608
51082
  "snapshot.invalidateCache": [{
50609
51083
  name: "deviceId",
50610
51084
  form: "single",
@@ -50615,6 +51089,11 @@ Object.freeze({
50615
51089
  form: "single",
50616
51090
  optional: false
50617
51091
  }],
51092
+ "streamBroker.applyDeviceSettingsPatch": [{
51093
+ name: "deviceId",
51094
+ form: "single",
51095
+ optional: false
51096
+ }],
50618
51097
  "streamBroker.assignProfile": [{
50619
51098
  name: "deviceId",
50620
51099
  form: "single",
@@ -50630,6 +51109,16 @@ Object.freeze({
50630
51109
  form: "single",
50631
51110
  optional: false
50632
51111
  }],
51112
+ "streamBroker.getDeviceLiveContribution": [{
51113
+ name: "deviceId",
51114
+ form: "single",
51115
+ optional: false
51116
+ }],
51117
+ "streamBroker.getDeviceSettingsContribution": [{
51118
+ name: "deviceId",
51119
+ form: "single",
51120
+ optional: false
51121
+ }],
50633
51122
  "streamBroker.getStreamWithCodec": [{
50634
51123
  name: "deviceId",
50635
51124
  form: "single",
@@ -50690,16 +51179,46 @@ Object.freeze({
50690
51179
  form: "single",
50691
51180
  optional: false
50692
51181
  }],
51182
+ "streamParams.getStatus": [{
51183
+ name: "deviceId",
51184
+ form: "single",
51185
+ optional: false
51186
+ }],
50693
51187
  "streamParams.setProfile": [{
50694
51188
  name: "deviceId",
50695
51189
  form: "single",
50696
51190
  optional: false
50697
51191
  }],
51192
+ "switch.getStatus": [{
51193
+ name: "deviceId",
51194
+ form: "single",
51195
+ optional: false
51196
+ }],
50698
51197
  "switch.setState": [{
50699
51198
  name: "deviceId",
50700
51199
  form: "single",
50701
51200
  optional: false
50702
51201
  }],
51202
+ "tamper.getStatus": [{
51203
+ name: "deviceId",
51204
+ form: "single",
51205
+ optional: false
51206
+ }],
51207
+ "temperatureSensor.getStatus": [{
51208
+ name: "deviceId",
51209
+ form: "single",
51210
+ optional: false
51211
+ }],
51212
+ "update.getStatus": [{
51213
+ name: "deviceId",
51214
+ form: "single",
51215
+ optional: false
51216
+ }],
51217
+ "vacuumControl.getStatus": [{
51218
+ name: "deviceId",
51219
+ form: "single",
51220
+ optional: false
51221
+ }],
50703
51222
  "vacuumControl.locate": [{
50704
51223
  name: "deviceId",
50705
51224
  form: "single",
@@ -50735,6 +51254,11 @@ Object.freeze({
50735
51254
  form: "single",
50736
51255
  optional: false
50737
51256
  }],
51257
+ "valve.getStatus": [{
51258
+ name: "deviceId",
51259
+ form: "single",
51260
+ optional: false
51261
+ }],
50738
51262
  "valve.open": [{
50739
51263
  name: "deviceId",
50740
51264
  form: "single",
@@ -50750,6 +51274,11 @@ Object.freeze({
50750
51274
  form: "single",
50751
51275
  optional: false
50752
51276
  }],
51277
+ "vibration.getStatus": [{
51278
+ name: "deviceId",
51279
+ form: "single",
51280
+ optional: false
51281
+ }],
50753
51282
  "videoclips.dialClipStream": [{
50754
51283
  name: "deviceId",
50755
51284
  form: "single",
@@ -50785,6 +51314,11 @@ Object.freeze({
50785
51314
  form: "single",
50786
51315
  optional: false
50787
51316
  }],
51317
+ "waterHeater.getStatus": [{
51318
+ name: "deviceId",
51319
+ form: "single",
51320
+ optional: false
51321
+ }],
50788
51322
  "waterHeater.setAway": [{
50789
51323
  name: "deviceId",
50790
51324
  form: "single",
@@ -50800,6 +51334,11 @@ Object.freeze({
50800
51334
  form: "single",
50801
51335
  optional: false
50802
51336
  }],
51337
+ "weather.getStatus": [{
51338
+ name: "deviceId",
51339
+ form: "single",
51340
+ optional: false
51341
+ }],
50803
51342
  "webrtcSession.addIceCandidate": [{
50804
51343
  name: "deviceId",
50805
51344
  form: "single",
@@ -51537,7 +52076,7 @@ var PreviewTextField = string().max(200);
51537
52076
  * Whether the notification's preview is a STILL or a short animation.
51538
52077
  *
51539
52078
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
51540
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
52079
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
51541
52080
  * night reads better as three seconds of motion than as one frame of it. Both
51542
52081
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
51543
52082
  * simply applies it to a dozen frames sampled across the render and assembles