@camstack/addon-provider-amcrest 0.2.125 → 0.2.127

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 +698 -159
  2. package/dist/addon.mjs +698 -159
  3. package/package.json +1 -3
package/dist/addon.js CHANGED
@@ -7447,7 +7447,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
7447
7447
  return DeviceRole;
7448
7448
  }({});
7449
7449
  //#endregion
7450
- //#region ../types/dist/composition-43aqsZQj.mjs
7450
+ //#region ../types/dist/composition-Bzr7GwgP.mjs
7451
7451
  /**
7452
7452
  * The ffmpeg build every CamStack node downloads, per platform and arch.
7453
7453
  *
@@ -7501,20 +7501,20 @@ function portable(target) {
7501
7501
  }
7502
7502
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7503
7503
  /**
7504
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7505
- * valutatore puro del suo FRONTE.
7504
+ * THE table "which boolean of this device type counts as HIGH", and the
7505
+ * pure evaluator of its EDGE.
7506
7506
  *
7507
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7508
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7509
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7510
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7511
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7512
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7507
+ * ONE table for everyone who asks "is this device HIGH?": the
7508
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7509
+ * sensor markers, the orchestrator's camera-sensors bridge and
7510
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7511
+ * A second copy would diverge at the first cap added, and the symptom — "the
7512
+ * sensor rings the doorbell but does not record" — is exactly D62.
7513
7513
  *
7514
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7515
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7516
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7517
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7514
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7515
+ * two must not be unified: that one answers "what is the state WORD for a
7516
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7517
+ * boolean's EDGE counts". Deliberately different vocabularies.
7518
7518
  */
7519
7519
  /**
7520
7520
  * Known binary / switch source caps → the boolean slice field whose
@@ -7535,6 +7535,8 @@ var SOURCE_CAP_ACTIVE_FIELD = {
7535
7535
  vibration: "detected",
7536
7536
  tamper: "tampered"
7537
7537
  };
7538
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7539
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7538
7540
  /**
7539
7541
  * Error types for the safe expression engine. Two distinct classes so callers
7540
7542
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
@@ -9141,22 +9143,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9141
9143
  "package"
9142
9144
  ];
9143
9145
  /**
9144
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9145
- * un operatore può selezionare.
9146
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9147
+ * an operator can select.
9146
9148
  *
9147
- * Sono le tre offerte dallo step `object-detection`
9149
+ * They are the three offered by the `object-detection` step
9148
9150
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9149
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9150
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9151
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9152
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9151
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9152
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9153
+ * `package-detection`, whose enablement is driven by zones, and offering the
9154
+ * same word twice has already made an operator turn on the COCO proxy
9153
9155
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9154
9156
  *
9155
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9156
- * dello step e una seconda volta come union `FirstLevelMacro`
9157
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9158
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9159
- * successiva.
9157
+ * ONE list. Before today the same three were hand-written in the step's offer
9158
+ * and a second time as the union `FirstLevelMacro`
9159
+ * (`types/detection.ts`); a third copy for the recording trigger
9160
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9161
+ * invisible.
9160
9162
  */
9161
9163
  var FIRST_LEVEL_MACRO_CLASSES = [
9162
9164
  "person",
@@ -9221,17 +9223,17 @@ var RecordingStorageModeSchema = _enum([
9221
9223
  "on-device-decision"
9222
9224
  ]);
9223
9225
  /**
9224
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9225
- * tre offerte dallo step `object-detection`, da UNA lista
9226
+ * The macro classes that can open a recording window — the same
9227
+ * three offered by the `object-detection` step, from ONE list
9226
9228
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9227
9229
  */
9228
9230
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9229
9231
  /**
9230
- * True quando `values` non ripete un elemento.
9232
+ * True when `values` does not repeat an element.
9231
9233
  *
9232
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9233
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9234
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9234
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9235
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9236
+ * would count its windows twice in `segmentMissedByMs`.
9235
9237
  */
9236
9238
  var noDuplicates = (values) => new Set(values).size === values.length;
9237
9239
  /** Which detectors trigger an `events`-mode band. */
@@ -9239,34 +9241,34 @@ var RecordingTriggersSchema = object({
9239
9241
  motion: boolean().optional(),
9240
9242
  audioThresholdDbfs: number().optional(),
9241
9243
  /**
9242
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9243
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9244
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9245
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9244
+ * The macro classes whose detection opens a window. ABSENT = the source
9245
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9246
+ * trigger on, no class" is the same shape "enabled and records
9247
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9246
9248
  *
9247
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9248
- * quelle che hanno attraversato `enabledMacroClasses`, i
9249
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9250
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9251
- * finestre — vedi `recorder/object-trigger.ts`.
9249
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9250
+ * those that went through `enabledMacroClasses`, the
9251
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9252
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9253
+ * windows — see `recorder/object-trigger.ts`.
9252
9254
  */
9253
9255
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9254
9256
  /**
9255
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9256
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9257
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9258
+ * is not listened to; an empty array is rejected for the same reason as
9257
9259
  * `objectClasses`.
9258
9260
  *
9259
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9260
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9261
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9262
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9263
- * device (D12) — mai un elenco globale di cap.
9261
+ * These are SOURCE device ids, not cameras: the band names them, so the
9262
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9263
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9264
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9265
+ * device (D12) — never a global list of caps.
9264
9266
  *
9265
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9266
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9267
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9268
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9269
- * registrare.
9267
+ * What "high" means depends on the device TYPE and is not decided here:
9268
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9269
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9270
+ * the level: a contact found already open at runner restart does not
9271
+ * record.
9270
9272
  */
9271
9273
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9272
9274
  });
@@ -10343,7 +10345,7 @@ var DecoderSessionConfigSchema = object({
10343
10345
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
10344
10346
  * thing: the logging settings document on the `system` cap. Two authorities
10345
10347
  * over the values is the exact defect
10346
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
10348
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
10347
10349
  * remove; re-introducing it from the cure side would be grotesque.
10348
10350
  *
10349
10351
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -12054,7 +12056,7 @@ var BrokerStatusEnum = _enum([
12054
12056
  "unreachable",
12055
12057
  "error"
12056
12058
  ]);
12057
- var BrokerInfoSchema$1 = object({
12059
+ var BrokerInfoSchema = object({
12058
12060
  /** Stable broker id. Persisted; survives addon restarts. */
12059
12061
  id: string(),
12060
12062
  /** Addon id of the provider that OWNS this broker.
@@ -12187,7 +12189,7 @@ var GetStateInputSchema = object({
12187
12189
  * HA: entity_id (returns the cached entity state). */
12188
12190
  key: string()
12189
12191
  });
12190
- method(ListInputSchema, array(BrokerInfoSchema$1)), method(GetInputSchema, BrokerInfoSchema$1.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12192
+ method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12191
12193
  kind: "mutation",
12192
12194
  auth: "admin"
12193
12195
  }), method(RemoveInputSchema, _void(), {
@@ -13898,7 +13900,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
13898
13900
  *
13899
13901
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
13900
13902
  * was wrong — corrected 2026-08-26 after the hop map
13901
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
13903
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
13902
13904
  * There is **no Zod parse at all** between the door and the engine: the
13903
13905
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
13904
13906
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -14874,7 +14876,17 @@ var SiteZoneSchema = object({
14874
14876
  var ProviderStatusSchema = object({
14875
14877
  connected: boolean(),
14876
14878
  deviceCount: number(),
14877
- error: string().optional()
14879
+ error: string().optional(),
14880
+ /**
14881
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
14882
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
14883
+ * which every provider bundles, so only a provider BUILT from D696-amended
14884
+ * code says it. ABSENT means an older provider that may still write it (raw
14885
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
14886
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
14887
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
14888
+ */
14889
+ motionSliceWriter: literal("orchestrator").optional()
14878
14890
  });
14879
14891
  object({
14880
14892
  externalId: string(),
@@ -16091,7 +16103,7 @@ method(object({
16091
16103
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
16092
16104
  * ends in a log line, and a log line is the thing the operator asked to stop
16093
16105
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
16094
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
16106
+ * 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
16095
16107
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
16096
16108
  * media blackout were both diagnosed. The counters stay; this is where they can
16097
16109
  * be READ.
@@ -17467,7 +17479,7 @@ var BrokerStatusSchema$1 = _enum([
17467
17479
  "unreachable",
17468
17480
  "tls-error"
17469
17481
  ]);
17470
- var BrokerInfoSchema = object({
17482
+ var BrokerInfoSchema$1 = object({
17471
17483
  id: string(),
17472
17484
  name: string(),
17473
17485
  url: string(),
@@ -17530,7 +17542,7 @@ var StatusSchema = object({
17530
17542
  brokerCount: number(),
17531
17543
  embeddedRunning: boolean()
17532
17544
  });
17533
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17545
+ method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
17534
17546
  kind: "mutation",
17535
17547
  auth: "admin"
17536
17548
  }), method(IdInputSchema, _void(), {
@@ -19744,78 +19756,16 @@ var NcRuleInputSchema = object({
19744
19756
  */
19745
19757
  confirm: NcConfirmSchema.optional(),
19746
19758
  /**
19747
- * WAIT for face/plate recognition before saying anything.
19748
- *
19749
- * A notification's TEXT is frozen at enqueue and its media is re-resolved at
19750
- * send; the identity is neither. A face is confirmed after `confirmFrames`
19751
- * agreeing observations — p50 **11.4 s** after the track was first seen,
19752
- * measured on this hub — and an `immediate` rule enqueues on the first object
19753
- * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
19754
- * immediate path, and no amount of media re-resolution fixes a sentence.
19755
- *
19756
- * Only two honest answers exist, and this flag picks between them. It has
19757
- * effect ONLY on a rule that declares a recognition scope
19758
- * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
19759
- * other rule there is nothing to wait for and the flag is inert.
19760
- *
19761
- * | value | what happens |
19762
- * | --- | --- |
19763
- * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
19764
- * | 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) |
19765
- *
19766
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19767
- * on the addon cap path, and absent has to keep meaning exactly what every
19768
- * rule authored before this field meant.
19769
- *
19770
- * The cost of `true` is stated here because the editor states it too: a rule
19771
- * that waits also inherits track-close SEMANTICS — its `zones` condition
19772
- * tests every zone the track visited and a `crossing` condition can no longer
19773
- * be satisfied, because a closed track carries no crossing.
19774
- */
19775
- waitForEnhancement: boolean().optional(),
19776
- /**
19777
- * GROUP a burst of subjects into ONE notification that grows.
19778
- *
19779
- * Seconds of quiet after the last matching subject before the burst is
19780
- * considered over. While it is open, the first subject enqueues immediately —
19781
- * **exactly as today, with no added latency** — and every real growth (a new
19782
- * subject, or a name confirmed on one already in it) REPLACES that
19783
- * notification with an updated one naming everybody. The push carries the
19784
- * group's own coalescing tag, so the phone replaces rather than stacks.
19785
- *
19786
- * `0` / absent = off, and off is today's behaviour byte for byte.
19787
- *
19788
- * ### Why an idle cutoff and not a window
19789
- *
19790
- * The measured seven-person arrival on device 590 spans 110 s with every
19791
- * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
19792
- * idle cutoff holds it as one and ends it when the arrival actually ends.
19793
- * 30 s is a widely shipped value for the same decision.
19794
- *
19795
- * ### What it replaces
19796
- *
19797
- * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
19798
- * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
19799
- * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
19800
- * track that did fire and 7 carrying a confirmed identity nobody heard about.
19801
- * A group collapses the same volume by MERGING, so the cooldown becomes a
19802
- * budget over GROUPS — which is what it always meant — and a growth is never
19803
- * throttled by the window its own first member spent.
19804
- *
19805
- * ### Interaction with {@link waitForEnhancement}
19806
- *
19807
- * They compose, and the order matters. `waitForEnhancement` defers the rule to
19808
- * TRACK CLOSE, so with both set the group is opened by the first member to
19809
- * CLOSE — already carrying its name — and grows as later members close. That
19810
- * is later, and complete. With grouping alone the group opens on the first
19811
- * object event and picks up names as they are confirmed, through the growth
19812
- * path. Neither combination fires twice for one subject.
19813
- *
19814
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
19815
- * on the addon cap path, so absent must keep meaning what it meant before this
19816
- * field existed.
19759
+ * IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
19760
+ * seconds; the rule sends ONE message when the window closes — early, once every
19761
+ * subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
19762
+ * the rule matched, with one mosaic tile per subject.
19763
+ * Absent = plain immediate (one message per track, at the first match).
19764
+ * Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
19765
+ * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
19766
+ * path does not run Zod defaults.
19817
19767
  */
19818
- groupIdleSec: number().int().min(0).max(600).optional()
19768
+ groupingSec: number().int().min(5).max(60).optional()
19819
19769
  });
19820
19770
  /**
19821
19771
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -19863,9 +19813,10 @@ var NcRuleClearableKeySchema = _enum([
19863
19813
  "targetUsers",
19864
19814
  "snoozeOptions",
19865
19815
  "snoozeAllowGlobal",
19866
- "waitForEnhancement",
19867
19816
  "actions",
19868
19817
  "confirm",
19818
+ "groupingSec",
19819
+ "waitForEnhancement",
19869
19820
  "groupIdleSec"
19870
19821
  ]);
19871
19822
  var NcRuleUpdateInputSchema = object({
@@ -19887,9 +19838,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
19887
19838
  */
19888
19839
  disabledTargetIds: array(string()).default([])
19889
19840
  });
19841
+ /**
19842
+ * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
19843
+ * still-true state. `backups-exports` and `alarm` are not sections — a completed
19844
+ * job is not an open state, and the alarm stays instant.
19845
+ */
19846
+ var NcStateSummarySectionIdSchema = _enum([
19847
+ "device-state",
19848
+ "streams",
19849
+ "battery",
19850
+ "consumables",
19851
+ "tanks",
19852
+ "detection-blind",
19853
+ "nodes",
19854
+ "addons",
19855
+ "updates"
19856
+ ]);
19890
19857
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
19891
19858
  var NcStateSummaryPreviewSectionSchema = object({
19892
- id: string(),
19859
+ id: NcStateSummarySectionIdSchema,
19893
19860
  status: _enum(["read", "unavailable"]),
19894
19861
  items: number().int().nonnegative(),
19895
19862
  reason: string().optional()
@@ -19899,7 +19866,7 @@ var NcStateSummaryPreviewSectionSchema = object({
19899
19866
  * a `rule` split (no `section`), one section's on a `section` split.
19900
19867
  */
19901
19868
  var NcStateSummaryPreviewRowSchema = object({
19902
- section: string().optional(),
19869
+ section: NcStateSummarySectionIdSchema.optional(),
19903
19870
  /** The section's name on a per-section row; every reported section's, joined, on a combined one. */
19904
19871
  title: string(),
19905
19872
  text: string(),
@@ -20336,6 +20303,29 @@ object({
20336
20303
  firstAt: number(),
20337
20304
  lastAt: number()
20338
20305
  });
20306
+ var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
20307
+ var NcAlarmDelaySecSchema = number().int().min(0).max(600);
20308
+ var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
20309
+ var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
20310
+ var NcAlarmModeDelaysListSchema = array(object({
20311
+ mode: AlarmArmModeSchema,
20312
+ exitDelaySec: NcAlarmDelaySecSchema.optional(),
20313
+ entryDelaySec: NcAlarmDelaySecSchema.optional(),
20314
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
20315
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20316
+ var NcAlarmModeDelaysEditListSchema = array(object({
20317
+ mode: AlarmArmModeSchema,
20318
+ exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20319
+ entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
20320
+ triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
20321
+ })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20322
+ /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20323
+ var NcAlarmNonBlockingEditSchema = object({
20324
+ mode: AlarmArmModeSchema,
20325
+ deviceId: number().int().positive(),
20326
+ /** true = on the list (may be open, does not block); false = off the list (blocks). */
20327
+ nonBlocking: boolean()
20328
+ });
20339
20329
  /**
20340
20330
  * The per-mode lists, at most one per mode. Two lists for one mode have no
20341
20331
  * meaning a reader could agree on (union? the last one?), so they are refused
@@ -20344,10 +20334,10 @@ object({
20344
20334
  var NcAlarmNonBlockingListSchema = array(object({
20345
20335
  mode: AlarmArmModeSchema,
20346
20336
  deviceIds: array(number().int()).max(200)
20347
- })).max(8).refine((lists) => new Set(lists.map((l) => l.mode)).size === lists.length, { message: "nonBlocking: at most one list per arm mode" });
20337
+ })).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
20348
20338
  /**
20349
- * The three durations the panel's state machine runs on, who hears about its
20350
- * transitions, and which openings each mode tolerates.
20339
+ * The three durations — global, and per mode since D697 — the panel's state
20340
+ * machine runs on, who hears about its transitions, and which openings each mode tolerates.
20351
20341
  *
20352
20342
  * They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
20353
20343
  * `alarm-panel` is `deviceNative` and its other provider mirrors somebody
@@ -20357,15 +20347,15 @@ var NcAlarmNonBlockingListSchema = array(object({
20357
20347
  */
20358
20348
  var NcAlarmSettingsSchema = object({
20359
20349
  /** Grace period between arming and the mode taking effect. 0 = immediate. */
20360
- exitDelaySec: number().int().min(0).max(600),
20350
+ exitDelaySec: NcAlarmDelaySecSchema,
20361
20351
  /** Grace period between a trigger and the alarm firing. 0 = immediate. */
20362
- entryDelaySec: number().int().min(0).max(600),
20352
+ entryDelaySec: NcAlarmDelaySecSchema,
20363
20353
  /**
20364
20354
  * How long `triggered` lasts before the panel re-arms itself.
20365
20355
  * **0 = until an operator disarms it** — the behaviour before this field
20366
20356
  * existed, and therefore what an untouched install keeps doing.
20367
20357
  */
20368
- triggeredDurationSec: number().int().min(0).max(3600),
20358
+ triggeredDurationSec: NcAlarmTriggeredSecSchema,
20369
20359
  /**
20370
20360
  * Deprecated by D630 — every transition is announced. Parsed, never read;
20371
20361
  * remove after one release. Optional so an older admin's patch (which still
@@ -20388,17 +20378,30 @@ var NcAlarmSettingsSchema = object({
20388
20378
  * per mode is meaningful. Defaulted to `[]` so a blob stored before D630
20389
20379
  * parses as "every opening blocks" — the behaviour it was written under.
20390
20380
  */
20391
- nonBlocking: NcAlarmNonBlockingListSchema.default([])
20381
+ nonBlocking: NcAlarmNonBlockingListSchema.default([]),
20382
+ /**
20383
+ * Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
20384
+ * without a field, uses the global value above — so `[]`, the default, is exactly the
20385
+ * behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
20386
+ */
20387
+ modeDelays: NcAlarmModeDelaysListSchema.default([])
20392
20388
  });
20393
20389
  /**
20394
20390
  * Every field optional — a tab edits one control at a time.
20395
20391
  *
20396
- * `nonBlocking` is re-declared WITHOUT its default: `.partial()` does not
20397
- * remove an inner `.default()`, so a patch that never named the field would
20398
- * parse to `nonBlocking: []` and wipe every mode's list on an unrelated edit
20399
- * (the same trap {@link NcRulePatchSchema} documents).
20392
+ * `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
20393
+ * `.partial()` does not remove an inner `.default()`, so a patch that never
20394
+ * named the field would parse to `[]` and wipe every mode's list on an
20395
+ * unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
20396
+ * `modeDelays` means EDITS, not the stored overrides.
20400
20397
  */
20401
- var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({ nonBlocking: NcAlarmNonBlockingListSchema }).partial();
20398
+ var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
20399
+ nonBlocking: NcAlarmNonBlockingListSchema,
20400
+ /** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
20401
+ modeDelays: NcAlarmModeDelaysEditListSchema,
20402
+ /** ONE membership change; the panel applies it to the list it holds at its turn. */
20403
+ nonBlockingEdit: NcAlarmNonBlockingEditSchema
20404
+ }).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
20402
20405
  /**
20403
20406
  * What one arm mode actually arms, DERIVED from the enabled rules gated on it.
20404
20407
  * Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
@@ -20498,6 +20501,28 @@ var NcAlarmConfigSchema = object({
20498
20501
  */
20499
20502
  live: NcAlarmLiveSchema.optional()
20500
20503
  });
20504
+ var NcAlarmSensorReadingSchema = _enum([
20505
+ "open",
20506
+ "closed",
20507
+ "unknown",
20508
+ "not-opening"
20509
+ ]);
20510
+ /** One device's state as the alarm reads it — the classifier the arm check uses. */
20511
+ var NcAlarmSensorStateSchema = object({
20512
+ deviceId: number().int().positive(),
20513
+ reading: NcAlarmSensorReadingSchema,
20514
+ /** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
20515
+ state: string().nullable(),
20516
+ /** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
20517
+ unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
20518
+ /** The device manager's liveness as the centre mirrors it; null = not known. */
20519
+ online: boolean().nullable()
20520
+ });
20521
+ var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
20522
+ var NcAlarmSensorsSchema = object({
20523
+ sensors: array(NcAlarmSensorStateSchema),
20524
+ readAt: number().int().nonnegative()
20525
+ });
20501
20526
  /**
20502
20527
  * ONE rule's demand on ONE camera's clip ring.
20503
20528
  *
@@ -20588,7 +20613,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20588
20613
  }), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
20589
20614
  kind: "mutation",
20590
20615
  auth: "admin"
20591
- });
20616
+ }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
20592
20617
  /**
20593
20618
  * Zod schemas for persisted record types.
20594
20619
  *
@@ -21740,14 +21765,14 @@ var TrackSchema = object({
21740
21765
  * `derive-returned-null tile=standin`,
21741
21766
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
21742
21767
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
21743
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
21768
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
21744
21769
  * tile is a face/plate stand-in, a raster crop, or an icon.
21745
21770
  *
21746
21771
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
21747
21772
  * the TILE ranked below native, so a track whose thumbnail landed natively
21748
21773
  * while its key frame missed carried no reason at all — three of the four
21749
21774
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
21750
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
21775
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
21751
21776
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
21752
21777
  * lastFrame copy source`), so its absence is now on this line whatever the
21753
21778
  * tile ended up being.
@@ -21834,7 +21859,7 @@ var MotionEventSchema = object({
21834
21859
  /**
21835
21860
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
21836
21861
  * first entry is always `0`) of every genuine off→on transition the
21837
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
21862
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
21838
21863
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
21839
21864
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
21840
21865
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -22358,6 +22383,7 @@ var KeyEventSchema = object({
22358
22383
  bestEventId: string(),
22359
22384
  /** Track lifetime in ms (lastSeen - firstSeen). */
22360
22385
  windowMs: number().optional(),
22386
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
22361
22387
  ...TrackFlagFields,
22362
22388
  ...TrackRetrainFields
22363
22389
  });
@@ -27282,7 +27308,7 @@ var ClipPlaybackSchema = object({
27282
27308
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
27283
27309
  * time the camera is awake for its own reasons — is deliberately not a member:
27284
27310
  * it was proposed, it is free on the battery, and the operator declined it on
27285
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
27311
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
27286
27312
  * D558 "Considered and not taken").
27287
27313
  */
27288
27314
  var ClipWakeSchema = _enum(["authorised"]);
@@ -27678,7 +27704,7 @@ var videoclipsCapability = {
27678
27704
  * **It is a SECTION of the Recording tab, at the end of it — not a tab of
27679
27705
  * its own.** It shipped as a `clips` top-tab and the operator rejected the
27680
27706
  * placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
27681
- * necessario, una nuova sezione alla fine per le clips"*. The Recording tab
27707
+ * necessario, una nuova sezione alla fine per le clips"* [I would use the same recordings tab, there we already have everything necessary, a new section at the end for the clips]. The Recording tab
27682
27708
  * already holds the recorder's panel, the schedule bands and the unified
27683
27709
  * retention policy; footage the camera itself holds is the same question,
27684
27710
  * asked of a different store. `order: 100` puts it after all of them with
@@ -27739,7 +27765,7 @@ var videoclipsCapability = {
27739
27765
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
27740
27766
  * assumed the answer was a fan-out over everything a camera has. The
27741
27767
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
27742
- * solo"* — so the list is asked of one provider at a time and there is
27768
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
27743
27769
  * nothing to filter out of it.
27744
27770
  */
27745
27771
  provider: string().min(1)
@@ -36061,7 +36087,7 @@ var ReadGopBytesResultSchema = object({
36061
36087
  /**
36062
36088
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
36063
36089
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
36064
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
36090
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
36065
36091
  * a replay needs several seconds of native pixels, not one frame.
36066
36092
  *
36067
36093
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -39729,6 +39755,7 @@ var zoneRulesCapability = {
39729
39755
  */
39730
39756
  durability: "restored"
39731
39757
  };
39758
+ SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
39732
39759
  /**
39733
39760
  * Accessory device helpers — shared across drivers.
39734
39761
  *
@@ -40788,13 +40815,14 @@ var BaseDeviceProvider = class extends BaseAddon {
40788
40815
  async getStatus() {
40789
40816
  const all = await this.ctx.kernel.devices?.getAll() ?? [];
40790
40817
  const summary = this.restoreFailureSummary();
40791
- if (summary === null) return {
40818
+ const base = {
40792
40819
  connected: true,
40793
- deviceCount: all.length
40820
+ deviceCount: all.length,
40821
+ motionSliceWriter: "orchestrator"
40794
40822
  };
40823
+ if (summary === null) return base;
40795
40824
  return {
40796
- connected: true,
40797
- deviceCount: all.length,
40825
+ ...base,
40798
40826
  error: summary
40799
40827
  };
40800
40828
  }
@@ -46436,6 +46464,12 @@ Object.freeze({
46436
46464
  addonId: null,
46437
46465
  access: "view"
46438
46466
  },
46467
+ "notificationRules.getAlarmSensors": {
46468
+ capName: "notification-rules",
46469
+ capScope: "system",
46470
+ addonId: null,
46471
+ access: "view"
46472
+ },
46439
46473
  "notificationRules.getClipRetentionAsks": {
46440
46474
  capName: "notification-rules",
46441
46475
  capScope: "system",
@@ -50014,6 +50048,11 @@ Object.freeze({
50014
50048
  }
50015
50049
  });
50016
50050
  Object.freeze({
50051
+ "accessories.getStatus": [{
50052
+ name: "deviceId",
50053
+ form: "single",
50054
+ optional: false
50055
+ }],
50017
50056
  "accessories.setChildHidden": [{
50018
50057
  name: "childDeviceId",
50019
50058
  form: "single",
@@ -50033,6 +50072,11 @@ Object.freeze({
50033
50072
  form: "single",
50034
50073
  optional: false
50035
50074
  }],
50075
+ "airQualitySensor.getStatus": [{
50076
+ name: "deviceId",
50077
+ form: "single",
50078
+ optional: false
50079
+ }],
50036
50080
  "alarmPanel.arm": [{
50037
50081
  name: "deviceId",
50038
50082
  form: "single",
@@ -50043,11 +50087,36 @@ Object.freeze({
50043
50087
  form: "single",
50044
50088
  optional: false
50045
50089
  }],
50090
+ "alarmPanel.getStatus": [{
50091
+ name: "deviceId",
50092
+ form: "single",
50093
+ optional: false
50094
+ }],
50046
50095
  "alarmPanel.trigger": [{
50047
50096
  name: "deviceId",
50048
50097
  form: "single",
50049
50098
  optional: false
50050
50099
  }],
50100
+ "ambientLightSensor.getStatus": [{
50101
+ name: "deviceId",
50102
+ form: "single",
50103
+ optional: false
50104
+ }],
50105
+ "audioAnalysis.applyDeviceSettingsPatch": [{
50106
+ name: "deviceId",
50107
+ form: "single",
50108
+ optional: false
50109
+ }],
50110
+ "audioAnalysis.getDeviceLiveContribution": [{
50111
+ name: "deviceId",
50112
+ form: "single",
50113
+ optional: false
50114
+ }],
50115
+ "audioAnalysis.getDeviceSettingsContribution": [{
50116
+ name: "deviceId",
50117
+ form: "single",
50118
+ optional: false
50119
+ }],
50051
50120
  "audioAnalysis.resolveDeviceSettings": [{
50052
50121
  name: "deviceId",
50053
50122
  form: "single",
@@ -50088,16 +50157,36 @@ Object.freeze({
50088
50157
  form: "single",
50089
50158
  optional: false
50090
50159
  }],
50160
+ "automationControl.getStatus": [{
50161
+ name: "deviceId",
50162
+ form: "single",
50163
+ optional: false
50164
+ }],
50091
50165
  "automationControl.trigger": [{
50092
50166
  name: "deviceId",
50093
50167
  form: "single",
50094
50168
  optional: false
50095
50169
  }],
50170
+ "battery.getStatus": [{
50171
+ name: "deviceId",
50172
+ form: "single",
50173
+ optional: false
50174
+ }],
50096
50175
  "battery.wakeForStream": [{
50097
50176
  name: "deviceId",
50098
50177
  form: "single",
50099
50178
  optional: false
50100
50179
  }],
50180
+ "binary.getStatus": [{
50181
+ name: "deviceId",
50182
+ form: "single",
50183
+ optional: false
50184
+ }],
50185
+ "brightness.getStatus": [{
50186
+ name: "deviceId",
50187
+ form: "single",
50188
+ optional: false
50189
+ }],
50101
50190
  "brightness.setBrightness": [{
50102
50191
  name: "deviceId",
50103
50192
  form: "single",
@@ -50113,6 +50202,26 @@ Object.freeze({
50113
50202
  form: "single",
50114
50203
  optional: false
50115
50204
  }],
50205
+ "cameraCredentials.getStatus": [{
50206
+ name: "deviceId",
50207
+ form: "single",
50208
+ optional: false
50209
+ }],
50210
+ "cameraGridLayout.applyDeviceSettingsPatch": [{
50211
+ name: "deviceId",
50212
+ form: "single",
50213
+ optional: false
50214
+ }],
50215
+ "cameraGridLayout.getDeviceLiveContribution": [{
50216
+ name: "deviceId",
50217
+ form: "single",
50218
+ optional: false
50219
+ }],
50220
+ "cameraGridLayout.getDeviceSettingsContribution": [{
50221
+ name: "deviceId",
50222
+ form: "single",
50223
+ optional: false
50224
+ }],
50116
50225
  "cameraGridLayout.getLayout": [{
50117
50226
  name: "deviceId",
50118
50227
  form: "single",
@@ -50128,6 +50237,21 @@ Object.freeze({
50128
50237
  form: "single",
50129
50238
  optional: false
50130
50239
  }],
50240
+ "cameraPipelineConfig.applyDeviceSettingsPatch": [{
50241
+ name: "deviceId",
50242
+ form: "single",
50243
+ optional: false
50244
+ }],
50245
+ "cameraPipelineConfig.getDeviceLiveContribution": [{
50246
+ name: "deviceId",
50247
+ form: "single",
50248
+ optional: false
50249
+ }],
50250
+ "cameraPipelineConfig.getDeviceSettingsContribution": [{
50251
+ name: "deviceId",
50252
+ form: "single",
50253
+ optional: false
50254
+ }],
50131
50255
  "cameraStreams.getBrokerStreams": [{
50132
50256
  name: "deviceId",
50133
50257
  form: "single",
@@ -50153,6 +50277,16 @@ Object.freeze({
50153
50277
  form: "single",
50154
50278
  optional: false
50155
50279
  }],
50280
+ "carbonMonoxide.getStatus": [{
50281
+ name: "deviceId",
50282
+ form: "single",
50283
+ optional: false
50284
+ }],
50285
+ "climateControl.getStatus": [{
50286
+ name: "deviceId",
50287
+ form: "single",
50288
+ optional: false
50289
+ }],
50156
50290
  "climateControl.setFanMode": [{
50157
50291
  name: "deviceId",
50158
50292
  form: "single",
@@ -50193,16 +50327,41 @@ Object.freeze({
50193
50327
  form: "single",
50194
50328
  optional: false
50195
50329
  }],
50330
+ "color.getStatus": [{
50331
+ name: "deviceId",
50332
+ form: "single",
50333
+ optional: false
50334
+ }],
50196
50335
  "color.setColor": [{
50197
50336
  name: "deviceId",
50198
50337
  form: "single",
50199
50338
  optional: false
50200
50339
  }],
50340
+ "connectivity.getStatus": [{
50341
+ name: "deviceId",
50342
+ form: "single",
50343
+ optional: false
50344
+ }],
50345
+ "consumables.getStatus": [{
50346
+ name: "deviceId",
50347
+ form: "single",
50348
+ optional: false
50349
+ }],
50201
50350
  "consumables.reset": [{
50202
50351
  name: "deviceId",
50203
50352
  form: "single",
50204
50353
  optional: false
50205
50354
  }],
50355
+ "contact.getStatus": [{
50356
+ name: "deviceId",
50357
+ form: "single",
50358
+ optional: false
50359
+ }],
50360
+ "control.getStatus": [{
50361
+ name: "deviceId",
50362
+ form: "single",
50363
+ optional: false
50364
+ }],
50206
50365
  "control.setValue": [{
50207
50366
  name: "deviceId",
50208
50367
  form: "single",
@@ -50213,6 +50372,11 @@ Object.freeze({
50213
50372
  form: "single",
50214
50373
  optional: false
50215
50374
  }],
50375
+ "cover.getStatus": [{
50376
+ name: "deviceId",
50377
+ form: "single",
50378
+ optional: false
50379
+ }],
50216
50380
  "cover.open": [{
50217
50381
  name: "deviceId",
50218
50382
  form: "single",
@@ -50238,6 +50402,11 @@ Object.freeze({
50238
50402
  form: "single",
50239
50403
  optional: false
50240
50404
  }],
50405
+ "dayNight.getStatus": [{
50406
+ name: "deviceId",
50407
+ form: "single",
50408
+ optional: false
50409
+ }],
50241
50410
  "dayNight.setSettings": [{
50242
50411
  name: "deviceId",
50243
50412
  form: "single",
@@ -50248,11 +50417,31 @@ Object.freeze({
50248
50417
  form: "single",
50249
50418
  optional: true
50250
50419
  }],
50420
+ "detectionPipeline.applyDeviceSettingsPatch": [{
50421
+ name: "deviceId",
50422
+ form: "single",
50423
+ optional: false
50424
+ }],
50425
+ "detectionPipeline.getDeviceLiveContribution": [{
50426
+ name: "deviceId",
50427
+ form: "single",
50428
+ optional: false
50429
+ }],
50430
+ "detectionPipeline.getDeviceSettingsContribution": [{
50431
+ name: "deviceId",
50432
+ form: "single",
50433
+ optional: false
50434
+ }],
50251
50435
  "deviceAdminLink.getAdminLink": [{
50252
50436
  name: "deviceId",
50253
50437
  form: "single",
50254
50438
  optional: false
50255
50439
  }],
50440
+ "deviceAdoption.getStatus": [{
50441
+ name: "deviceId",
50442
+ form: "single",
50443
+ optional: false
50444
+ }],
50256
50445
  "deviceAdoption.release": [{
50257
50446
  name: "camDeviceId",
50258
50447
  form: "single",
@@ -50268,6 +50457,11 @@ Object.freeze({
50268
50457
  form: "single",
50269
50458
  optional: false
50270
50459
  }],
50460
+ "deviceDiscovery.getStatus": [{
50461
+ name: "deviceId",
50462
+ form: "single",
50463
+ optional: false
50464
+ }],
50271
50465
  "deviceDiscovery.listDiscovered": [{
50272
50466
  name: "deviceId",
50273
50467
  form: "single",
@@ -50287,6 +50481,21 @@ Object.freeze({
50287
50481
  form: "single",
50288
50482
  optional: false
50289
50483
  }],
50484
+ "deviceExport.applyDeviceSettingsPatch": [{
50485
+ name: "deviceId",
50486
+ form: "single",
50487
+ optional: false
50488
+ }],
50489
+ "deviceExport.getDeviceLiveContribution": [{
50490
+ name: "deviceId",
50491
+ form: "single",
50492
+ optional: false
50493
+ }],
50494
+ "deviceExport.getDeviceSettingsContribution": [{
50495
+ name: "deviceId",
50496
+ form: "single",
50497
+ optional: false
50498
+ }],
50290
50499
  "deviceExtension.listCandidates": [{
50291
50500
  name: "deviceId",
50292
50501
  form: "single",
@@ -50635,6 +50844,26 @@ Object.freeze({
50635
50844
  form: "single",
50636
50845
  optional: false
50637
50846
  }],
50847
+ "deviceStatus.getStatus": [{
50848
+ name: "deviceId",
50849
+ form: "single",
50850
+ optional: false
50851
+ }],
50852
+ "doorbell.getStatus": [{
50853
+ name: "deviceId",
50854
+ form: "single",
50855
+ optional: false
50856
+ }],
50857
+ "enumSensor.getStatus": [{
50858
+ name: "deviceId",
50859
+ form: "single",
50860
+ optional: false
50861
+ }],
50862
+ "eventEmitter.getStatus": [{
50863
+ name: "deviceId",
50864
+ form: "single",
50865
+ optional: false
50866
+ }],
50638
50867
  "faceGallery.getFaceByTrack": [{
50639
50868
  name: "deviceId",
50640
50869
  form: "single",
@@ -50649,6 +50878,11 @@ Object.freeze({
50649
50878
  form: "array",
50650
50879
  optional: true
50651
50880
  }],
50881
+ "fanControl.getStatus": [{
50882
+ name: "deviceId",
50883
+ form: "single",
50884
+ optional: false
50885
+ }],
50652
50886
  "fanControl.setDirection": [{
50653
50887
  name: "deviceId",
50654
50888
  form: "single",
@@ -50669,6 +50903,26 @@ Object.freeze({
50669
50903
  form: "single",
50670
50904
  optional: false
50671
50905
  }],
50906
+ "featureProbe.getStatus": [{
50907
+ name: "deviceId",
50908
+ form: "single",
50909
+ optional: false
50910
+ }],
50911
+ "flood.getStatus": [{
50912
+ name: "deviceId",
50913
+ form: "single",
50914
+ optional: false
50915
+ }],
50916
+ "gas.getStatus": [{
50917
+ name: "deviceId",
50918
+ form: "single",
50919
+ optional: false
50920
+ }],
50921
+ "humidifier.getStatus": [{
50922
+ name: "deviceId",
50923
+ form: "single",
50924
+ optional: false
50925
+ }],
50672
50926
  "humidifier.setMode": [{
50673
50927
  name: "deviceId",
50674
50928
  form: "single",
@@ -50684,11 +50938,26 @@ Object.freeze({
50684
50938
  form: "single",
50685
50939
  optional: false
50686
50940
  }],
50941
+ "humiditySensor.getStatus": [{
50942
+ name: "deviceId",
50943
+ form: "single",
50944
+ optional: false
50945
+ }],
50946
+ "image.getStatus": [{
50947
+ name: "deviceId",
50948
+ form: "single",
50949
+ optional: false
50950
+ }],
50687
50951
  "imageSettings.getOptions": [{
50688
50952
  name: "deviceId",
50689
50953
  form: "single",
50690
50954
  optional: false
50691
50955
  }],
50956
+ "imageSettings.getStatus": [{
50957
+ name: "deviceId",
50958
+ form: "single",
50959
+ optional: false
50960
+ }],
50692
50961
  "imageSettings.setSettings": [{
50693
50962
  name: "deviceId",
50694
50963
  form: "single",
@@ -50699,6 +50968,11 @@ Object.freeze({
50699
50968
  form: "single",
50700
50969
  optional: false
50701
50970
  }],
50971
+ "intercom.getStatus": [{
50972
+ name: "deviceId",
50973
+ form: "single",
50974
+ optional: false
50975
+ }],
50702
50976
  "intercom.handleAnswer": [{
50703
50977
  name: "deviceId",
50704
50978
  form: "single",
@@ -50729,6 +51003,11 @@ Object.freeze({
50729
51003
  form: "single",
50730
51004
  optional: false
50731
51005
  }],
51006
+ "lawnMowerControl.getStatus": [{
51007
+ name: "deviceId",
51008
+ form: "single",
51009
+ optional: false
51010
+ }],
50732
51011
  "lawnMowerControl.pause": [{
50733
51012
  name: "deviceId",
50734
51013
  form: "single",
@@ -50739,6 +51018,11 @@ Object.freeze({
50739
51018
  form: "single",
50740
51019
  optional: false
50741
51020
  }],
51021
+ "lockControl.getStatus": [{
51022
+ name: "deviceId",
51023
+ form: "single",
51024
+ optional: false
51025
+ }],
50742
51026
  "lockControl.lock": [{
50743
51027
  name: "deviceId",
50744
51028
  form: "single",
@@ -50754,6 +51038,11 @@ Object.freeze({
50754
51038
  form: "single",
50755
51039
  optional: false
50756
51040
  }],
51041
+ "mediaPlayer.getStatus": [{
51042
+ name: "deviceId",
51043
+ form: "single",
51044
+ optional: false
51045
+ }],
50757
51046
  "mediaPlayer.next": [{
50758
51047
  name: "deviceId",
50759
51048
  form: "single",
@@ -50814,6 +51103,11 @@ Object.freeze({
50814
51103
  form: "single",
50815
51104
  optional: false
50816
51105
  }],
51106
+ "motion.getStatus": [{
51107
+ name: "deviceId",
51108
+ form: "single",
51109
+ optional: false
51110
+ }],
50817
51111
  "motion.isDetected": [{
50818
51112
  name: "deviceId",
50819
51113
  form: "single",
@@ -50824,11 +51118,31 @@ Object.freeze({
50824
51118
  form: "single",
50825
51119
  optional: false
50826
51120
  }],
51121
+ "motionDetection.applyDeviceSettingsPatch": [{
51122
+ name: "deviceId",
51123
+ form: "single",
51124
+ optional: false
51125
+ }],
51126
+ "motionDetection.getDeviceLiveContribution": [{
51127
+ name: "deviceId",
51128
+ form: "single",
51129
+ optional: false
51130
+ }],
51131
+ "motionDetection.getDeviceSettingsContribution": [{
51132
+ name: "deviceId",
51133
+ form: "single",
51134
+ optional: false
51135
+ }],
50827
51136
  "motionDetection.removeCamera": [{
50828
51137
  name: "deviceId",
50829
51138
  form: "single",
50830
51139
  optional: false
50831
51140
  }],
51141
+ "motionTrigger.getStatus": [{
51142
+ name: "deviceId",
51143
+ form: "single",
51144
+ optional: false
51145
+ }],
50832
51146
  "motionTrigger.setMotionTrigger": [{
50833
51147
  name: "deviceId",
50834
51148
  form: "single",
@@ -50839,6 +51153,11 @@ Object.freeze({
50839
51153
  form: "single",
50840
51154
  optional: false
50841
51155
  }],
51156
+ "motionZones.getStatus": [{
51157
+ name: "deviceId",
51158
+ form: "single",
51159
+ optional: false
51160
+ }],
50842
51161
  "motionZones.setZone": [{
50843
51162
  name: "deviceId",
50844
51163
  form: "single",
@@ -50849,6 +51168,11 @@ Object.freeze({
50849
51168
  form: "single",
50850
51169
  optional: false
50851
51170
  }],
51171
+ "nativeObjectDetection.getStatus": [{
51172
+ name: "deviceId",
51173
+ form: "single",
51174
+ optional: false
51175
+ }],
50852
51176
  "nativeObjectDetection.setEnabled": [{
50853
51177
  name: "deviceId",
50854
51178
  form: "single",
@@ -50864,6 +51188,11 @@ Object.freeze({
50864
51188
  form: "single",
50865
51189
  optional: false
50866
51190
  }],
51191
+ "navigation.getStatus": [{
51192
+ name: "deviceId",
51193
+ form: "single",
51194
+ optional: false
51195
+ }],
50867
51196
  "navigation.goToPoint": [{
50868
51197
  name: "deviceId",
50869
51198
  form: "single",
@@ -50909,6 +51238,11 @@ Object.freeze({
50909
51238
  form: "single",
50910
51239
  optional: false
50911
51240
  }],
51241
+ "networkLink.getStatus": [{
51242
+ name: "deviceId",
51243
+ form: "single",
51244
+ optional: false
51245
+ }],
50912
51246
  "networkQuality.getDeviceStats": [{
50913
51247
  name: "deviceId",
50914
51248
  form: "single",
@@ -50919,6 +51253,11 @@ Object.freeze({
50919
51253
  form: "single",
50920
51254
  optional: false
50921
51255
  }],
51256
+ "notificationRules.getAlarmSensors": [{
51257
+ name: "deviceIds",
51258
+ form: "array",
51259
+ optional: false
51260
+ }],
50922
51261
  "notificationRules.setDeviceMuted": [{
50923
51262
  name: "deviceId",
50924
51263
  form: "single",
@@ -50929,11 +51268,26 @@ Object.freeze({
50929
51268
  form: "single",
50930
51269
  optional: false
50931
51270
  }],
51271
+ "notifier.getStatus": [{
51272
+ name: "deviceId",
51273
+ form: "single",
51274
+ optional: false
51275
+ }],
50932
51276
  "notifier.send": [{
50933
51277
  name: "deviceId",
50934
51278
  form: "single",
50935
51279
  optional: false
50936
51280
  }],
51281
+ "numericSensor.getStatus": [{
51282
+ name: "deviceId",
51283
+ form: "single",
51284
+ optional: false
51285
+ }],
51286
+ "osd.getStatus": [{
51287
+ name: "deviceId",
51288
+ form: "single",
51289
+ optional: false
51290
+ }],
50937
51291
  "osd.setOverlay": [{
50938
51292
  name: "deviceId",
50939
51293
  form: "single",
@@ -50993,6 +51347,11 @@ Object.freeze({
50993
51347
  form: "single",
50994
51348
  optional: false
50995
51349
  }],
51350
+ "petFeeder.getStatus": [{
51351
+ name: "deviceId",
51352
+ form: "single",
51353
+ optional: false
51354
+ }],
50996
51355
  "petFeeder.markFoodReplenished": [{
50997
51356
  name: "deviceId",
50998
51357
  form: "single",
@@ -51028,6 +51387,11 @@ Object.freeze({
51028
51387
  form: "single",
51029
51388
  optional: false
51030
51389
  }],
51390
+ "pipelineAnalytics.applyDeviceSettingsPatch": [{
51391
+ name: "deviceId",
51392
+ form: "single",
51393
+ optional: false
51394
+ }],
51031
51395
  "pipelineAnalytics.clearTrackRelation": [{
51032
51396
  name: "deviceId",
51033
51397
  form: "single",
@@ -51068,6 +51432,16 @@ Object.freeze({
51068
51432
  form: "single",
51069
51433
  optional: false
51070
51434
  }],
51435
+ "pipelineAnalytics.getDeviceLiveContribution": [{
51436
+ name: "deviceId",
51437
+ form: "single",
51438
+ optional: false
51439
+ }],
51440
+ "pipelineAnalytics.getDeviceSettingsContribution": [{
51441
+ name: "deviceId",
51442
+ form: "single",
51443
+ optional: false
51444
+ }],
51071
51445
  "pipelineAnalytics.getEventDensity": [{
51072
51446
  name: "deviceId",
51073
51447
  form: "single",
@@ -51283,6 +51657,11 @@ Object.freeze({
51283
51657
  form: "single",
51284
51658
  optional: true
51285
51659
  }],
51660
+ "pipelineOrchestrator.applyDeviceSettingsPatch": [{
51661
+ name: "deviceId",
51662
+ form: "single",
51663
+ optional: false
51664
+ }],
51286
51665
  "pipelineOrchestrator.assignAudio": [{
51287
51666
  name: "deviceId",
51288
51667
  form: "single",
@@ -51328,6 +51707,16 @@ Object.freeze({
51328
51707
  form: "single",
51329
51708
  optional: false
51330
51709
  }],
51710
+ "pipelineOrchestrator.getDeviceLiveContribution": [{
51711
+ name: "deviceId",
51712
+ form: "single",
51713
+ optional: false
51714
+ }],
51715
+ "pipelineOrchestrator.getDeviceSettingsContribution": [{
51716
+ name: "deviceId",
51717
+ form: "single",
51718
+ optional: false
51719
+ }],
51331
51720
  "pipelineOrchestrator.getPipelineAssignment": [{
51332
51721
  name: "deviceId",
51333
51722
  form: "single",
@@ -51448,11 +51837,31 @@ Object.freeze({
51448
51837
  form: "single",
51449
51838
  optional: true
51450
51839
  }],
51840
+ "powerMeter.getStatus": [{
51841
+ name: "deviceId",
51842
+ form: "single",
51843
+ optional: false
51844
+ }],
51845
+ "presence.getStatus": [{
51846
+ name: "deviceId",
51847
+ form: "single",
51848
+ optional: false
51849
+ }],
51850
+ "pressureSensor.getStatus": [{
51851
+ name: "deviceId",
51852
+ form: "single",
51853
+ optional: false
51854
+ }],
51451
51855
  "privacyMask.getOptions": [{
51452
51856
  name: "deviceId",
51453
51857
  form: "single",
51454
51858
  optional: false
51455
51859
  }],
51860
+ "privacyMask.getStatus": [{
51861
+ name: "deviceId",
51862
+ form: "single",
51863
+ optional: false
51864
+ }],
51456
51865
  "privacyMask.setAudioEnabled": [{
51457
51866
  name: "deviceId",
51458
51867
  form: "single",
@@ -51503,6 +51912,11 @@ Object.freeze({
51503
51912
  form: "single",
51504
51913
  optional: false
51505
51914
  }],
51915
+ "ptz.getStatus": [{
51916
+ name: "deviceId",
51917
+ form: "single",
51918
+ optional: false
51919
+ }],
51506
51920
  "ptz.goHome": [{
51507
51921
  name: "deviceId",
51508
51922
  form: "single",
@@ -51593,6 +52007,11 @@ Object.freeze({
51593
52007
  form: "single",
51594
52008
  optional: false
51595
52009
  }],
52010
+ "recordingArchive.applyDeviceSettingsPatch": [{
52011
+ name: "deviceId",
52012
+ form: "single",
52013
+ optional: false
52014
+ }],
51596
52015
  "recordingArchive.deleteFootprint": [{
51597
52016
  name: "deviceId",
51598
52017
  form: "single",
@@ -51613,6 +52032,21 @@ Object.freeze({
51613
52032
  form: "single",
51614
52033
  optional: false
51615
52034
  }],
52035
+ "recordingArchive.getDeviceLiveContribution": [{
52036
+ name: "deviceId",
52037
+ form: "single",
52038
+ optional: false
52039
+ }],
52040
+ "recordingArchive.getDeviceSettingsContribution": [{
52041
+ name: "deviceId",
52042
+ form: "single",
52043
+ optional: false
52044
+ }],
52045
+ "recordingArchive.getStatus": [{
52046
+ name: "deviceId",
52047
+ form: "single",
52048
+ optional: false
52049
+ }],
51616
52050
  "recordingArchive.listOpsLog": [{
51617
52051
  name: "deviceId",
51618
52052
  form: "single",
@@ -51698,6 +52132,11 @@ Object.freeze({
51698
52132
  form: "single",
51699
52133
  optional: false
51700
52134
  }],
52135
+ "recordingOnboard.getStatus": [{
52136
+ name: "deviceId",
52137
+ form: "single",
52138
+ optional: false
52139
+ }],
51701
52140
  "recordingOnboard.setSettings": [{
51702
52141
  name: "deviceId",
51703
52142
  form: "single",
@@ -51728,6 +52167,11 @@ Object.freeze({
51728
52167
  form: "single",
51729
52168
  optional: false
51730
52169
  }],
52170
+ "sceneMonitor.getStatus": [{
52171
+ name: "deviceId",
52172
+ form: "single",
52173
+ optional: false
52174
+ }],
51731
52175
  "sceneMonitor.listScenes": [{
51732
52176
  name: "deviceId",
51733
52177
  form: "single",
@@ -51753,6 +52197,11 @@ Object.freeze({
51753
52197
  form: "single",
51754
52198
  optional: false
51755
52199
  }],
52200
+ "scriptRunner.getStatus": [{
52201
+ name: "deviceId",
52202
+ form: "single",
52203
+ optional: false
52204
+ }],
51756
52205
  "scriptRunner.run": [{
51757
52206
  name: "deviceId",
51758
52207
  form: "single",
@@ -51763,11 +52212,31 @@ Object.freeze({
51763
52212
  form: "single",
51764
52213
  optional: false
51765
52214
  }],
52215
+ "smoke.getStatus": [{
52216
+ name: "deviceId",
52217
+ form: "single",
52218
+ optional: false
52219
+ }],
52220
+ "snapshot.applyDeviceSettingsPatch": [{
52221
+ name: "deviceId",
52222
+ form: "single",
52223
+ optional: false
52224
+ }],
51766
52225
  "snapshot.getDebugState": [{
51767
52226
  name: "deviceId",
51768
52227
  form: "single",
51769
52228
  optional: false
51770
52229
  }],
52230
+ "snapshot.getDeviceLiveContribution": [{
52231
+ name: "deviceId",
52232
+ form: "single",
52233
+ optional: false
52234
+ }],
52235
+ "snapshot.getDeviceSettingsContribution": [{
52236
+ name: "deviceId",
52237
+ form: "single",
52238
+ optional: false
52239
+ }],
51771
52240
  "snapshot.getSnapshot": [{
51772
52241
  name: "deviceId",
51773
52242
  form: "single",
@@ -51784,6 +52253,11 @@ Object.freeze({
51784
52253
  form: "array",
51785
52254
  optional: false
51786
52255
  }],
52256
+ "snapshot.getStatus": [{
52257
+ name: "deviceId",
52258
+ form: "single",
52259
+ optional: false
52260
+ }],
51787
52261
  "snapshot.invalidateCache": [{
51788
52262
  name: "deviceId",
51789
52263
  form: "single",
@@ -51794,6 +52268,11 @@ Object.freeze({
51794
52268
  form: "single",
51795
52269
  optional: false
51796
52270
  }],
52271
+ "streamBroker.applyDeviceSettingsPatch": [{
52272
+ name: "deviceId",
52273
+ form: "single",
52274
+ optional: false
52275
+ }],
51797
52276
  "streamBroker.assignProfile": [{
51798
52277
  name: "deviceId",
51799
52278
  form: "single",
@@ -51809,6 +52288,16 @@ Object.freeze({
51809
52288
  form: "single",
51810
52289
  optional: false
51811
52290
  }],
52291
+ "streamBroker.getDeviceLiveContribution": [{
52292
+ name: "deviceId",
52293
+ form: "single",
52294
+ optional: false
52295
+ }],
52296
+ "streamBroker.getDeviceSettingsContribution": [{
52297
+ name: "deviceId",
52298
+ form: "single",
52299
+ optional: false
52300
+ }],
51812
52301
  "streamBroker.getStreamWithCodec": [{
51813
52302
  name: "deviceId",
51814
52303
  form: "single",
@@ -51869,16 +52358,46 @@ Object.freeze({
51869
52358
  form: "single",
51870
52359
  optional: false
51871
52360
  }],
52361
+ "streamParams.getStatus": [{
52362
+ name: "deviceId",
52363
+ form: "single",
52364
+ optional: false
52365
+ }],
51872
52366
  "streamParams.setProfile": [{
51873
52367
  name: "deviceId",
51874
52368
  form: "single",
51875
52369
  optional: false
51876
52370
  }],
52371
+ "switch.getStatus": [{
52372
+ name: "deviceId",
52373
+ form: "single",
52374
+ optional: false
52375
+ }],
51877
52376
  "switch.setState": [{
51878
52377
  name: "deviceId",
51879
52378
  form: "single",
51880
52379
  optional: false
51881
52380
  }],
52381
+ "tamper.getStatus": [{
52382
+ name: "deviceId",
52383
+ form: "single",
52384
+ optional: false
52385
+ }],
52386
+ "temperatureSensor.getStatus": [{
52387
+ name: "deviceId",
52388
+ form: "single",
52389
+ optional: false
52390
+ }],
52391
+ "update.getStatus": [{
52392
+ name: "deviceId",
52393
+ form: "single",
52394
+ optional: false
52395
+ }],
52396
+ "vacuumControl.getStatus": [{
52397
+ name: "deviceId",
52398
+ form: "single",
52399
+ optional: false
52400
+ }],
51882
52401
  "vacuumControl.locate": [{
51883
52402
  name: "deviceId",
51884
52403
  form: "single",
@@ -51914,6 +52433,11 @@ Object.freeze({
51914
52433
  form: "single",
51915
52434
  optional: false
51916
52435
  }],
52436
+ "valve.getStatus": [{
52437
+ name: "deviceId",
52438
+ form: "single",
52439
+ optional: false
52440
+ }],
51917
52441
  "valve.open": [{
51918
52442
  name: "deviceId",
51919
52443
  form: "single",
@@ -51929,6 +52453,11 @@ Object.freeze({
51929
52453
  form: "single",
51930
52454
  optional: false
51931
52455
  }],
52456
+ "vibration.getStatus": [{
52457
+ name: "deviceId",
52458
+ form: "single",
52459
+ optional: false
52460
+ }],
51932
52461
  "videoclips.dialClipStream": [{
51933
52462
  name: "deviceId",
51934
52463
  form: "single",
@@ -51964,6 +52493,11 @@ Object.freeze({
51964
52493
  form: "single",
51965
52494
  optional: false
51966
52495
  }],
52496
+ "waterHeater.getStatus": [{
52497
+ name: "deviceId",
52498
+ form: "single",
52499
+ optional: false
52500
+ }],
51967
52501
  "waterHeater.setAway": [{
51968
52502
  name: "deviceId",
51969
52503
  form: "single",
@@ -51979,6 +52513,11 @@ Object.freeze({
51979
52513
  form: "single",
51980
52514
  optional: false
51981
52515
  }],
52516
+ "weather.getStatus": [{
52517
+ name: "deviceId",
52518
+ form: "single",
52519
+ optional: false
52520
+ }],
51982
52521
  "webrtcSession.addIceCandidate": [{
51983
52522
  name: "deviceId",
51984
52523
  form: "single",
@@ -52716,7 +53255,7 @@ var PreviewTextField = string().max(200);
52716
53255
  * Whether the notification's preview is a STILL or a short animation.
52717
53256
  *
52718
53257
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
52719
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
53258
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
52720
53259
  * night reads better as three seconds of motion than as one frame of it. Both
52721
53260
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
52722
53261
  * simply applies it to a dozen frames sampled across the render and assembles