@camstack/addon-provider-reolink 1.2.168 → 1.2.170

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 +631 -172
  2. package/dist/addon.mjs +631 -172
  3. package/package.json +1 -3
package/dist/addon.mjs CHANGED
@@ -7496,7 +7496,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
7496
7496
  return DeviceRole;
7497
7497
  }({});
7498
7498
  //#endregion
7499
- //#region ../types/dist/composition-43aqsZQj.mjs
7499
+ //#region ../types/dist/composition-Bzr7GwgP.mjs
7500
7500
  /**
7501
7501
  * The ffmpeg build every CamStack node downloads, per platform and arch.
7502
7502
  *
@@ -7550,20 +7550,20 @@ function portable(target) {
7550
7550
  }
7551
7551
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7552
7552
  /**
7553
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7554
- * valutatore puro del suo FRONTE.
7553
+ * THE table "which boolean of this device type counts as HIGH", and the
7554
+ * pure evaluator of its EDGE.
7555
7555
  *
7556
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7557
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7558
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7559
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7560
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7561
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7556
+ * ONE table for everyone who asks "is this device HIGH?": the
7557
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7558
+ * sensor markers, the orchestrator's camera-sensors bridge and
7559
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7560
+ * A second copy would diverge at the first cap added, and the symptom — "the
7561
+ * sensor rings the doorbell but does not record" — is exactly D62.
7562
7562
  *
7563
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7564
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7565
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7566
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7563
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7564
+ * two must not be unified: that one answers "what is the state WORD for a
7565
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7566
+ * boolean's EDGE counts". Deliberately different vocabularies.
7567
7567
  */
7568
7568
  /**
7569
7569
  * Known binary / switch source caps → the boolean slice field whose
@@ -7584,6 +7584,8 @@ var SOURCE_CAP_ACTIVE_FIELD = {
7584
7584
  vibration: "detected",
7585
7585
  tamper: "tampered"
7586
7586
  };
7587
+ /** Cap names whose presence in a device's bindings qualify it as a source. */
7588
+ var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
7587
7589
  /**
7588
7590
  * Error types for the safe expression engine. Two distinct classes so callers
7589
7591
  * can tell a compile-time (grammar) failure from a runtime (evaluation)
@@ -9190,22 +9192,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9190
9192
  "package"
9191
9193
  ];
9192
9194
  /**
9193
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9194
- * un operatore può selezionare.
9195
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9196
+ * an operator can select.
9195
9197
  *
9196
- * Sono le tre offerte dallo step `object-detection`
9198
+ * They are the three offered by the `object-detection` step
9197
9199
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9198
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9199
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9200
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9201
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9200
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9201
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9202
+ * `package-detection`, whose enablement is driven by zones, and offering the
9203
+ * same word twice has already made an operator turn on the COCO proxy
9202
9204
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9203
9205
  *
9204
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9205
- * dello step e una seconda volta come union `FirstLevelMacro`
9206
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9207
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9208
- * successiva.
9206
+ * ONE list. Before today the same three were hand-written in the step's offer
9207
+ * and a second time as the union `FirstLevelMacro`
9208
+ * (`types/detection.ts`); a third copy for the recording trigger
9209
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9210
+ * invisible.
9209
9211
  */
9210
9212
  var FIRST_LEVEL_MACRO_CLASSES = [
9211
9213
  "person",
@@ -9270,17 +9272,17 @@ var RecordingStorageModeSchema = _enum([
9270
9272
  "on-device-decision"
9271
9273
  ]);
9272
9274
  /**
9273
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9274
- * tre offerte dallo step `object-detection`, da UNA lista
9275
+ * The macro classes that can open a recording window — the same
9276
+ * three offered by the `object-detection` step, from ONE list
9275
9277
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9276
9278
  */
9277
9279
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9278
9280
  /**
9279
- * True quando `values` non ripete un elemento.
9281
+ * True when `values` does not repeat an element.
9280
9282
  *
9281
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9282
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9283
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9283
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9284
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9285
+ * would count its windows twice in `segmentMissedByMs`.
9284
9286
  */
9285
9287
  var noDuplicates = (values) => new Set(values).size === values.length;
9286
9288
  /** Which detectors trigger an `events`-mode band. */
@@ -9288,34 +9290,34 @@ var RecordingTriggersSchema = object({
9288
9290
  motion: boolean().optional(),
9289
9291
  audioThresholdDbfs: number().optional(),
9290
9292
  /**
9291
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9292
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9293
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9294
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9293
+ * The macro classes whose detection opens a window. ABSENT = the source
9294
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9295
+ * trigger on, no class" is the same shape "enabled and records
9296
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9295
9297
  *
9296
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9297
- * quelle che hanno attraversato `enabledMacroClasses`, i
9298
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9299
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9300
- * finestre — vedi `recorder/object-trigger.ts`.
9298
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9299
+ * those that went through `enabledMacroClasses`, the
9300
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9301
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9302
+ * windows — see `recorder/object-trigger.ts`.
9301
9303
  */
9302
9304
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9303
9305
  /**
9304
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9305
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9306
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9307
+ * is not listened to; an empty array is rejected for the same reason as
9306
9308
  * `objectClasses`.
9307
9309
  *
9308
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9309
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9310
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9311
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9312
- * device (D12) — mai un elenco globale di cap.
9310
+ * These are SOURCE device ids, not cameras: the band names them, so the
9311
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9312
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9313
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9314
+ * device (D12) — never a global list of caps.
9313
9315
  *
9314
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9315
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9316
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9317
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9318
- * registrare.
9316
+ * What "high" means depends on the device TYPE and is not decided here:
9317
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9318
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9319
+ * the level: a contact found already open at runner restart does not
9320
+ * record.
9319
9321
  */
9320
9322
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9321
9323
  });
@@ -10567,7 +10569,7 @@ function findTimezone(id) {
10567
10569
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
10568
10570
  * thing: the logging settings document on the `system` cap. Two authorities
10569
10571
  * over the values is the exact defect
10570
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
10572
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
10571
10573
  * remove; re-introducing it from the cure side would be grotesque.
10572
10574
  *
10573
10575
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -12635,7 +12637,7 @@ var BrokerStatusEnum = _enum([
12635
12637
  "unreachable",
12636
12638
  "error"
12637
12639
  ]);
12638
- var BrokerInfoSchema$1 = object({
12640
+ var BrokerInfoSchema = object({
12639
12641
  /** Stable broker id. Persisted; survives addon restarts. */
12640
12642
  id: string(),
12641
12643
  /** Addon id of the provider that OWNS this broker.
@@ -12768,7 +12770,7 @@ var GetStateInputSchema = object({
12768
12770
  * HA: entity_id (returns the cached entity state). */
12769
12771
  key: string()
12770
12772
  });
12771
- method(ListInputSchema, array(BrokerInfoSchema$1)), method(GetInputSchema, BrokerInfoSchema$1.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12773
+ method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
12772
12774
  kind: "mutation",
12773
12775
  auth: "admin"
12774
12776
  }), method(RemoveInputSchema, _void(), {
@@ -14479,7 +14481,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
14479
14481
  *
14480
14482
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
14481
14483
  * was wrong — corrected 2026-08-26 after the hop map
14482
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
14484
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
14483
14485
  * There is **no Zod parse at all** between the door and the engine: the
14484
14486
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
14485
14487
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -16682,7 +16684,7 @@ method(object({
16682
16684
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
16683
16685
  * ends in a log line, and a log line is the thing the operator asked to stop
16684
16686
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
16685
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
16687
+ * 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
16686
16688
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
16687
16689
  * media blackout were both diagnosed. The counters stay; this is where they can
16688
16690
  * be READ.
@@ -18098,7 +18100,7 @@ var BrokerStatusSchema$1 = _enum([
18098
18100
  "unreachable",
18099
18101
  "tls-error"
18100
18102
  ]);
18101
- var BrokerInfoSchema = object({
18103
+ var BrokerInfoSchema$1 = object({
18102
18104
  id: string(),
18103
18105
  name: string(),
18104
18106
  url: string(),
@@ -18161,7 +18163,7 @@ var StatusSchema = object({
18161
18163
  brokerCount: number(),
18162
18164
  embeddedRunning: boolean()
18163
18165
  });
18164
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
18166
+ method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
18165
18167
  kind: "mutation",
18166
18168
  auth: "admin"
18167
18169
  }), method(IdInputSchema, _void(), {
@@ -20375,78 +20377,16 @@ var NcRuleInputSchema = object({
20375
20377
  */
20376
20378
  confirm: NcConfirmSchema.optional(),
20377
20379
  /**
20378
- * WAIT for face/plate recognition before saying anything.
20379
- *
20380
- * A notification's TEXT is frozen at enqueue and its media is re-resolved at
20381
- * send; the identity is neither. A face is confirmed after `confirmFrames`
20382
- * agreeing observations — p50 **11.4 s** after the track was first seen,
20383
- * measured on this hub — and an `immediate` rule enqueues on the first object
20384
- * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
20385
- * immediate path, and no amount of media re-resolution fixes a sentence.
20386
- *
20387
- * Only two honest answers exist, and this flag picks between them. It has
20388
- * effect ONLY on a rule that declares a recognition scope
20389
- * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
20390
- * other rule there is nothing to wait for and the flag is inert.
20391
- *
20392
- * | value | what happens |
20393
- * | --- | --- |
20394
- * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
20395
- * | 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) |
20396
- *
20397
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
20398
- * on the addon cap path, and absent has to keep meaning exactly what every
20399
- * rule authored before this field meant.
20400
- *
20401
- * The cost of `true` is stated here because the editor states it too: a rule
20402
- * that waits also inherits track-close SEMANTICS — its `zones` condition
20403
- * tests every zone the track visited and a `crossing` condition can no longer
20404
- * be satisfied, because a closed track carries no crossing.
20380
+ * IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
20381
+ * seconds; the rule sends ONE message when the window closes — early, once every
20382
+ * subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
20383
+ * the rule matched, with one mosaic tile per subject.
20384
+ * Absent = plain immediate (one message per track, at the first match).
20385
+ * Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
20386
+ * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
20387
+ * path does not run Zod defaults.
20405
20388
  */
20406
- waitForEnhancement: boolean().optional(),
20407
- /**
20408
- * GROUP a burst of subjects into ONE notification that grows.
20409
- *
20410
- * Seconds of quiet after the last matching subject before the burst is
20411
- * considered over. While it is open, the first subject enqueues immediately —
20412
- * **exactly as today, with no added latency** — and every real growth (a new
20413
- * subject, or a name confirmed on one already in it) REPLACES that
20414
- * notification with an updated one naming everybody. The push carries the
20415
- * group's own coalescing tag, so the phone replaces rather than stacks.
20416
- *
20417
- * `0` / absent = off, and off is today's behaviour byte for byte.
20418
- *
20419
- * ### Why an idle cutoff and not a window
20420
- *
20421
- * The measured seven-person arrival on device 590 spans 110 s with every
20422
- * internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
20423
- * idle cutoff holds it as one and ends it when the arrival actually ends.
20424
- * 30 s is a widely shipped value for the same decision.
20425
- *
20426
- * ### What it replaces
20427
- *
20428
- * The blind cooldown, which collapses a burst by DISCARDING it. Measured on
20429
- * device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
20430
- * notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
20431
- * track that did fire and 7 carrying a confirmed identity nobody heard about.
20432
- * A group collapses the same volume by MERGING, so the cooldown becomes a
20433
- * budget over GROUPS — which is what it always meant — and a growth is never
20434
- * throttled by the window its own first member spent.
20435
- *
20436
- * ### Interaction with {@link waitForEnhancement}
20437
- *
20438
- * They compose, and the order matters. `waitForEnhancement` defers the rule to
20439
- * TRACK CLOSE, so with both set the group is opened by the first member to
20440
- * CLOSE — already carrying its name — and grows as later members close. That
20441
- * is later, and complete. With grouping alone the group opens on the first
20442
- * object event and picks up names as they are confirmed, through the growth
20443
- * path. Neither combination fires twice for one subject.
20444
- *
20445
- * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
20446
- * on the addon cap path, so absent must keep meaning what it meant before this
20447
- * field existed.
20448
- */
20449
- groupIdleSec: number().int().min(0).max(600).optional()
20389
+ groupingSec: number().int().min(5).max(60).optional()
20450
20390
  });
20451
20391
  /**
20452
20392
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -20494,9 +20434,10 @@ var NcRuleClearableKeySchema = _enum([
20494
20434
  "targetUsers",
20495
20435
  "snoozeOptions",
20496
20436
  "snoozeAllowGlobal",
20497
- "waitForEnhancement",
20498
20437
  "actions",
20499
20438
  "confirm",
20439
+ "groupingSec",
20440
+ "waitForEnhancement",
20500
20441
  "groupIdleSec"
20501
20442
  ]);
20502
20443
  var NcRuleUpdateInputSchema = object({
@@ -20518,9 +20459,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20518
20459
  */
20519
20460
  disabledTargetIds: array(string()).default([])
20520
20461
  });
20462
+ /**
20463
+ * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20464
+ * still-true state. `backups-exports` and `alarm` are not sections — a completed
20465
+ * job is not an open state, and the alarm stays instant.
20466
+ */
20467
+ var NcStateSummarySectionIdSchema = _enum([
20468
+ "device-state",
20469
+ "streams",
20470
+ "battery",
20471
+ "consumables",
20472
+ "tanks",
20473
+ "detection-blind",
20474
+ "nodes",
20475
+ "addons",
20476
+ "updates"
20477
+ ]);
20521
20478
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
20522
20479
  var NcStateSummaryPreviewSectionSchema = object({
20523
- id: string(),
20480
+ id: NcStateSummarySectionIdSchema,
20524
20481
  status: _enum(["read", "unavailable"]),
20525
20482
  items: number().int().nonnegative(),
20526
20483
  reason: string().optional()
@@ -20530,7 +20487,7 @@ var NcStateSummaryPreviewSectionSchema = object({
20530
20487
  * a `rule` split (no `section`), one section's on a `section` split.
20531
20488
  */
20532
20489
  var NcStateSummaryPreviewRowSchema = object({
20533
- section: string().optional(),
20490
+ section: NcStateSummarySectionIdSchema.optional(),
20534
20491
  /** The section's name on a per-section row; every reported section's, joined, on a combined one. */
20535
20492
  title: string(),
20536
20493
  text: string(),
@@ -22429,14 +22386,14 @@ var TrackSchema = object({
22429
22386
  * `derive-returned-null tile=standin`,
22430
22387
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
22431
22388
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
22432
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
22389
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
22433
22390
  * tile is a face/plate stand-in, a raster crop, or an icon.
22434
22391
  *
22435
22392
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
22436
22393
  * the TILE ranked below native, so a track whose thumbnail landed natively
22437
22394
  * while its key frame missed carried no reason at all — three of the four
22438
22395
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
22439
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
22396
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
22440
22397
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
22441
22398
  * lastFrame copy source`), so its absence is now on this line whatever the
22442
22399
  * tile ended up being.
@@ -22523,7 +22480,7 @@ var MotionEventSchema = object({
22523
22480
  /**
22524
22481
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
22525
22482
  * first entry is always `0`) of every genuine off→on transition the
22526
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
22483
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
22527
22484
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
22528
22485
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
22529
22486
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -23047,6 +23004,7 @@ var KeyEventSchema = object({
23047
23004
  bestEventId: string(),
23048
23005
  /** Track lifetime in ms (lastSeen - firstSeen). */
23049
23006
  windowMs: number().optional(),
23007
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
23050
23008
  ...TrackFlagFields,
23051
23009
  ...TrackRetrainFields
23052
23010
  });
@@ -27980,7 +27938,7 @@ var ClipPlaybackSchema = object({
27980
27938
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
27981
27939
  * time the camera is awake for its own reasons — is deliberately not a member:
27982
27940
  * it was proposed, it is free on the battery, and the operator declined it on
27983
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
27941
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
27984
27942
  * D558 "Considered and not taken").
27985
27943
  */
27986
27944
  var ClipWakeSchema = _enum(["authorised"]);
@@ -28376,7 +28334,7 @@ var videoclipsCapability = {
28376
28334
  * **It is a SECTION of the Recording tab, at the end of it — not a tab of
28377
28335
  * its own.** It shipped as a `clips` top-tab and the operator rejected the
28378
28336
  * placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
28379
- * necessario, una nuova sezione alla fine per le clips"*. The Recording tab
28337
+ * 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
28380
28338
  * already holds the recorder's panel, the schedule bands and the unified
28381
28339
  * retention policy; footage the camera itself holds is the same question,
28382
28340
  * asked of a different store. `order: 100` puts it after all of them with
@@ -28437,7 +28395,7 @@ var videoclipsCapability = {
28437
28395
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
28438
28396
  * assumed the answer was a fan-out over everything a camera has. The
28439
28397
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
28440
- * solo"* — so the list is asked of one provider at a time and there is
28398
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
28441
28399
  * nothing to filter out of it.
28442
28400
  */
28443
28401
  provider: string().min(1)
@@ -36758,7 +36716,7 @@ var ReadGopBytesResultSchema = object({
36758
36716
  /**
36759
36717
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
36760
36718
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
36761
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
36719
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
36762
36720
  * a replay needs several seconds of native pixels, not one frame.
36763
36721
  *
36764
36722
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -40489,6 +40447,7 @@ var zoneRulesCapability = {
40489
40447
  */
40490
40448
  durability: "restored"
40491
40449
  };
40450
+ SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
40492
40451
  /**
40493
40452
  * Accessory device helpers — shared across drivers.
40494
40453
  *
@@ -50753,6 +50712,11 @@ Object.freeze({
50753
50712
  }
50754
50713
  });
50755
50714
  Object.freeze({
50715
+ "accessories.getStatus": [{
50716
+ name: "deviceId",
50717
+ form: "single",
50718
+ optional: false
50719
+ }],
50756
50720
  "accessories.setChildHidden": [{
50757
50721
  name: "childDeviceId",
50758
50722
  form: "single",
@@ -50772,6 +50736,11 @@ Object.freeze({
50772
50736
  form: "single",
50773
50737
  optional: false
50774
50738
  }],
50739
+ "airQualitySensor.getStatus": [{
50740
+ name: "deviceId",
50741
+ form: "single",
50742
+ optional: false
50743
+ }],
50775
50744
  "alarmPanel.arm": [{
50776
50745
  name: "deviceId",
50777
50746
  form: "single",
@@ -50782,11 +50751,36 @@ Object.freeze({
50782
50751
  form: "single",
50783
50752
  optional: false
50784
50753
  }],
50754
+ "alarmPanel.getStatus": [{
50755
+ name: "deviceId",
50756
+ form: "single",
50757
+ optional: false
50758
+ }],
50785
50759
  "alarmPanel.trigger": [{
50786
50760
  name: "deviceId",
50787
50761
  form: "single",
50788
50762
  optional: false
50789
50763
  }],
50764
+ "ambientLightSensor.getStatus": [{
50765
+ name: "deviceId",
50766
+ form: "single",
50767
+ optional: false
50768
+ }],
50769
+ "audioAnalysis.applyDeviceSettingsPatch": [{
50770
+ name: "deviceId",
50771
+ form: "single",
50772
+ optional: false
50773
+ }],
50774
+ "audioAnalysis.getDeviceLiveContribution": [{
50775
+ name: "deviceId",
50776
+ form: "single",
50777
+ optional: false
50778
+ }],
50779
+ "audioAnalysis.getDeviceSettingsContribution": [{
50780
+ name: "deviceId",
50781
+ form: "single",
50782
+ optional: false
50783
+ }],
50790
50784
  "audioAnalysis.resolveDeviceSettings": [{
50791
50785
  name: "deviceId",
50792
50786
  form: "single",
@@ -50827,16 +50821,36 @@ Object.freeze({
50827
50821
  form: "single",
50828
50822
  optional: false
50829
50823
  }],
50824
+ "automationControl.getStatus": [{
50825
+ name: "deviceId",
50826
+ form: "single",
50827
+ optional: false
50828
+ }],
50830
50829
  "automationControl.trigger": [{
50831
50830
  name: "deviceId",
50832
50831
  form: "single",
50833
50832
  optional: false
50834
50833
  }],
50834
+ "battery.getStatus": [{
50835
+ name: "deviceId",
50836
+ form: "single",
50837
+ optional: false
50838
+ }],
50835
50839
  "battery.wakeForStream": [{
50836
50840
  name: "deviceId",
50837
50841
  form: "single",
50838
50842
  optional: false
50839
50843
  }],
50844
+ "binary.getStatus": [{
50845
+ name: "deviceId",
50846
+ form: "single",
50847
+ optional: false
50848
+ }],
50849
+ "brightness.getStatus": [{
50850
+ name: "deviceId",
50851
+ form: "single",
50852
+ optional: false
50853
+ }],
50840
50854
  "brightness.setBrightness": [{
50841
50855
  name: "deviceId",
50842
50856
  form: "single",
@@ -50852,6 +50866,26 @@ Object.freeze({
50852
50866
  form: "single",
50853
50867
  optional: false
50854
50868
  }],
50869
+ "cameraCredentials.getStatus": [{
50870
+ name: "deviceId",
50871
+ form: "single",
50872
+ optional: false
50873
+ }],
50874
+ "cameraGridLayout.applyDeviceSettingsPatch": [{
50875
+ name: "deviceId",
50876
+ form: "single",
50877
+ optional: false
50878
+ }],
50879
+ "cameraGridLayout.getDeviceLiveContribution": [{
50880
+ name: "deviceId",
50881
+ form: "single",
50882
+ optional: false
50883
+ }],
50884
+ "cameraGridLayout.getDeviceSettingsContribution": [{
50885
+ name: "deviceId",
50886
+ form: "single",
50887
+ optional: false
50888
+ }],
50855
50889
  "cameraGridLayout.getLayout": [{
50856
50890
  name: "deviceId",
50857
50891
  form: "single",
@@ -50867,6 +50901,21 @@ Object.freeze({
50867
50901
  form: "single",
50868
50902
  optional: false
50869
50903
  }],
50904
+ "cameraPipelineConfig.applyDeviceSettingsPatch": [{
50905
+ name: "deviceId",
50906
+ form: "single",
50907
+ optional: false
50908
+ }],
50909
+ "cameraPipelineConfig.getDeviceLiveContribution": [{
50910
+ name: "deviceId",
50911
+ form: "single",
50912
+ optional: false
50913
+ }],
50914
+ "cameraPipelineConfig.getDeviceSettingsContribution": [{
50915
+ name: "deviceId",
50916
+ form: "single",
50917
+ optional: false
50918
+ }],
50870
50919
  "cameraStreams.getBrokerStreams": [{
50871
50920
  name: "deviceId",
50872
50921
  form: "single",
@@ -50892,6 +50941,16 @@ Object.freeze({
50892
50941
  form: "single",
50893
50942
  optional: false
50894
50943
  }],
50944
+ "carbonMonoxide.getStatus": [{
50945
+ name: "deviceId",
50946
+ form: "single",
50947
+ optional: false
50948
+ }],
50949
+ "climateControl.getStatus": [{
50950
+ name: "deviceId",
50951
+ form: "single",
50952
+ optional: false
50953
+ }],
50895
50954
  "climateControl.setFanMode": [{
50896
50955
  name: "deviceId",
50897
50956
  form: "single",
@@ -50932,16 +50991,41 @@ Object.freeze({
50932
50991
  form: "single",
50933
50992
  optional: false
50934
50993
  }],
50994
+ "color.getStatus": [{
50995
+ name: "deviceId",
50996
+ form: "single",
50997
+ optional: false
50998
+ }],
50935
50999
  "color.setColor": [{
50936
51000
  name: "deviceId",
50937
51001
  form: "single",
50938
51002
  optional: false
50939
51003
  }],
51004
+ "connectivity.getStatus": [{
51005
+ name: "deviceId",
51006
+ form: "single",
51007
+ optional: false
51008
+ }],
51009
+ "consumables.getStatus": [{
51010
+ name: "deviceId",
51011
+ form: "single",
51012
+ optional: false
51013
+ }],
50940
51014
  "consumables.reset": [{
50941
51015
  name: "deviceId",
50942
51016
  form: "single",
50943
51017
  optional: false
50944
51018
  }],
51019
+ "contact.getStatus": [{
51020
+ name: "deviceId",
51021
+ form: "single",
51022
+ optional: false
51023
+ }],
51024
+ "control.getStatus": [{
51025
+ name: "deviceId",
51026
+ form: "single",
51027
+ optional: false
51028
+ }],
50945
51029
  "control.setValue": [{
50946
51030
  name: "deviceId",
50947
51031
  form: "single",
@@ -50952,6 +51036,11 @@ Object.freeze({
50952
51036
  form: "single",
50953
51037
  optional: false
50954
51038
  }],
51039
+ "cover.getStatus": [{
51040
+ name: "deviceId",
51041
+ form: "single",
51042
+ optional: false
51043
+ }],
50955
51044
  "cover.open": [{
50956
51045
  name: "deviceId",
50957
51046
  form: "single",
@@ -50977,6 +51066,11 @@ Object.freeze({
50977
51066
  form: "single",
50978
51067
  optional: false
50979
51068
  }],
51069
+ "dayNight.getStatus": [{
51070
+ name: "deviceId",
51071
+ form: "single",
51072
+ optional: false
51073
+ }],
50980
51074
  "dayNight.setSettings": [{
50981
51075
  name: "deviceId",
50982
51076
  form: "single",
@@ -50987,11 +51081,31 @@ Object.freeze({
50987
51081
  form: "single",
50988
51082
  optional: true
50989
51083
  }],
51084
+ "detectionPipeline.applyDeviceSettingsPatch": [{
51085
+ name: "deviceId",
51086
+ form: "single",
51087
+ optional: false
51088
+ }],
51089
+ "detectionPipeline.getDeviceLiveContribution": [{
51090
+ name: "deviceId",
51091
+ form: "single",
51092
+ optional: false
51093
+ }],
51094
+ "detectionPipeline.getDeviceSettingsContribution": [{
51095
+ name: "deviceId",
51096
+ form: "single",
51097
+ optional: false
51098
+ }],
50990
51099
  "deviceAdminLink.getAdminLink": [{
50991
51100
  name: "deviceId",
50992
51101
  form: "single",
50993
51102
  optional: false
50994
51103
  }],
51104
+ "deviceAdoption.getStatus": [{
51105
+ name: "deviceId",
51106
+ form: "single",
51107
+ optional: false
51108
+ }],
50995
51109
  "deviceAdoption.release": [{
50996
51110
  name: "camDeviceId",
50997
51111
  form: "single",
@@ -51007,6 +51121,11 @@ Object.freeze({
51007
51121
  form: "single",
51008
51122
  optional: false
51009
51123
  }],
51124
+ "deviceDiscovery.getStatus": [{
51125
+ name: "deviceId",
51126
+ form: "single",
51127
+ optional: false
51128
+ }],
51010
51129
  "deviceDiscovery.listDiscovered": [{
51011
51130
  name: "deviceId",
51012
51131
  form: "single",
@@ -51026,6 +51145,21 @@ Object.freeze({
51026
51145
  form: "single",
51027
51146
  optional: false
51028
51147
  }],
51148
+ "deviceExport.applyDeviceSettingsPatch": [{
51149
+ name: "deviceId",
51150
+ form: "single",
51151
+ optional: false
51152
+ }],
51153
+ "deviceExport.getDeviceLiveContribution": [{
51154
+ name: "deviceId",
51155
+ form: "single",
51156
+ optional: false
51157
+ }],
51158
+ "deviceExport.getDeviceSettingsContribution": [{
51159
+ name: "deviceId",
51160
+ form: "single",
51161
+ optional: false
51162
+ }],
51029
51163
  "deviceExtension.listCandidates": [{
51030
51164
  name: "deviceId",
51031
51165
  form: "single",
@@ -51374,6 +51508,26 @@ Object.freeze({
51374
51508
  form: "single",
51375
51509
  optional: false
51376
51510
  }],
51511
+ "deviceStatus.getStatus": [{
51512
+ name: "deviceId",
51513
+ form: "single",
51514
+ optional: false
51515
+ }],
51516
+ "doorbell.getStatus": [{
51517
+ name: "deviceId",
51518
+ form: "single",
51519
+ optional: false
51520
+ }],
51521
+ "enumSensor.getStatus": [{
51522
+ name: "deviceId",
51523
+ form: "single",
51524
+ optional: false
51525
+ }],
51526
+ "eventEmitter.getStatus": [{
51527
+ name: "deviceId",
51528
+ form: "single",
51529
+ optional: false
51530
+ }],
51377
51531
  "faceGallery.getFaceByTrack": [{
51378
51532
  name: "deviceId",
51379
51533
  form: "single",
@@ -51388,6 +51542,11 @@ Object.freeze({
51388
51542
  form: "array",
51389
51543
  optional: true
51390
51544
  }],
51545
+ "fanControl.getStatus": [{
51546
+ name: "deviceId",
51547
+ form: "single",
51548
+ optional: false
51549
+ }],
51391
51550
  "fanControl.setDirection": [{
51392
51551
  name: "deviceId",
51393
51552
  form: "single",
@@ -51408,6 +51567,26 @@ Object.freeze({
51408
51567
  form: "single",
51409
51568
  optional: false
51410
51569
  }],
51570
+ "featureProbe.getStatus": [{
51571
+ name: "deviceId",
51572
+ form: "single",
51573
+ optional: false
51574
+ }],
51575
+ "flood.getStatus": [{
51576
+ name: "deviceId",
51577
+ form: "single",
51578
+ optional: false
51579
+ }],
51580
+ "gas.getStatus": [{
51581
+ name: "deviceId",
51582
+ form: "single",
51583
+ optional: false
51584
+ }],
51585
+ "humidifier.getStatus": [{
51586
+ name: "deviceId",
51587
+ form: "single",
51588
+ optional: false
51589
+ }],
51411
51590
  "humidifier.setMode": [{
51412
51591
  name: "deviceId",
51413
51592
  form: "single",
@@ -51423,11 +51602,26 @@ Object.freeze({
51423
51602
  form: "single",
51424
51603
  optional: false
51425
51604
  }],
51605
+ "humiditySensor.getStatus": [{
51606
+ name: "deviceId",
51607
+ form: "single",
51608
+ optional: false
51609
+ }],
51610
+ "image.getStatus": [{
51611
+ name: "deviceId",
51612
+ form: "single",
51613
+ optional: false
51614
+ }],
51426
51615
  "imageSettings.getOptions": [{
51427
51616
  name: "deviceId",
51428
51617
  form: "single",
51429
51618
  optional: false
51430
51619
  }],
51620
+ "imageSettings.getStatus": [{
51621
+ name: "deviceId",
51622
+ form: "single",
51623
+ optional: false
51624
+ }],
51431
51625
  "imageSettings.setSettings": [{
51432
51626
  name: "deviceId",
51433
51627
  form: "single",
@@ -51438,6 +51632,11 @@ Object.freeze({
51438
51632
  form: "single",
51439
51633
  optional: false
51440
51634
  }],
51635
+ "intercom.getStatus": [{
51636
+ name: "deviceId",
51637
+ form: "single",
51638
+ optional: false
51639
+ }],
51441
51640
  "intercom.handleAnswer": [{
51442
51641
  name: "deviceId",
51443
51642
  form: "single",
@@ -51468,6 +51667,11 @@ Object.freeze({
51468
51667
  form: "single",
51469
51668
  optional: false
51470
51669
  }],
51670
+ "lawnMowerControl.getStatus": [{
51671
+ name: "deviceId",
51672
+ form: "single",
51673
+ optional: false
51674
+ }],
51471
51675
  "lawnMowerControl.pause": [{
51472
51676
  name: "deviceId",
51473
51677
  form: "single",
@@ -51478,6 +51682,11 @@ Object.freeze({
51478
51682
  form: "single",
51479
51683
  optional: false
51480
51684
  }],
51685
+ "lockControl.getStatus": [{
51686
+ name: "deviceId",
51687
+ form: "single",
51688
+ optional: false
51689
+ }],
51481
51690
  "lockControl.lock": [{
51482
51691
  name: "deviceId",
51483
51692
  form: "single",
@@ -51493,6 +51702,11 @@ Object.freeze({
51493
51702
  form: "single",
51494
51703
  optional: false
51495
51704
  }],
51705
+ "mediaPlayer.getStatus": [{
51706
+ name: "deviceId",
51707
+ form: "single",
51708
+ optional: false
51709
+ }],
51496
51710
  "mediaPlayer.next": [{
51497
51711
  name: "deviceId",
51498
51712
  form: "single",
@@ -51553,6 +51767,11 @@ Object.freeze({
51553
51767
  form: "single",
51554
51768
  optional: false
51555
51769
  }],
51770
+ "motion.getStatus": [{
51771
+ name: "deviceId",
51772
+ form: "single",
51773
+ optional: false
51774
+ }],
51556
51775
  "motion.isDetected": [{
51557
51776
  name: "deviceId",
51558
51777
  form: "single",
@@ -51563,11 +51782,31 @@ Object.freeze({
51563
51782
  form: "single",
51564
51783
  optional: false
51565
51784
  }],
51785
+ "motionDetection.applyDeviceSettingsPatch": [{
51786
+ name: "deviceId",
51787
+ form: "single",
51788
+ optional: false
51789
+ }],
51790
+ "motionDetection.getDeviceLiveContribution": [{
51791
+ name: "deviceId",
51792
+ form: "single",
51793
+ optional: false
51794
+ }],
51795
+ "motionDetection.getDeviceSettingsContribution": [{
51796
+ name: "deviceId",
51797
+ form: "single",
51798
+ optional: false
51799
+ }],
51566
51800
  "motionDetection.removeCamera": [{
51567
51801
  name: "deviceId",
51568
51802
  form: "single",
51569
51803
  optional: false
51570
51804
  }],
51805
+ "motionTrigger.getStatus": [{
51806
+ name: "deviceId",
51807
+ form: "single",
51808
+ optional: false
51809
+ }],
51571
51810
  "motionTrigger.setMotionTrigger": [{
51572
51811
  name: "deviceId",
51573
51812
  form: "single",
@@ -51578,6 +51817,11 @@ Object.freeze({
51578
51817
  form: "single",
51579
51818
  optional: false
51580
51819
  }],
51820
+ "motionZones.getStatus": [{
51821
+ name: "deviceId",
51822
+ form: "single",
51823
+ optional: false
51824
+ }],
51581
51825
  "motionZones.setZone": [{
51582
51826
  name: "deviceId",
51583
51827
  form: "single",
@@ -51588,6 +51832,11 @@ Object.freeze({
51588
51832
  form: "single",
51589
51833
  optional: false
51590
51834
  }],
51835
+ "nativeObjectDetection.getStatus": [{
51836
+ name: "deviceId",
51837
+ form: "single",
51838
+ optional: false
51839
+ }],
51591
51840
  "nativeObjectDetection.setEnabled": [{
51592
51841
  name: "deviceId",
51593
51842
  form: "single",
@@ -51603,6 +51852,11 @@ Object.freeze({
51603
51852
  form: "single",
51604
51853
  optional: false
51605
51854
  }],
51855
+ "navigation.getStatus": [{
51856
+ name: "deviceId",
51857
+ form: "single",
51858
+ optional: false
51859
+ }],
51606
51860
  "navigation.goToPoint": [{
51607
51861
  name: "deviceId",
51608
51862
  form: "single",
@@ -51648,6 +51902,11 @@ Object.freeze({
51648
51902
  form: "single",
51649
51903
  optional: false
51650
51904
  }],
51905
+ "networkLink.getStatus": [{
51906
+ name: "deviceId",
51907
+ form: "single",
51908
+ optional: false
51909
+ }],
51651
51910
  "networkQuality.getDeviceStats": [{
51652
51911
  name: "deviceId",
51653
51912
  form: "single",
@@ -51673,11 +51932,26 @@ Object.freeze({
51673
51932
  form: "single",
51674
51933
  optional: false
51675
51934
  }],
51935
+ "notifier.getStatus": [{
51936
+ name: "deviceId",
51937
+ form: "single",
51938
+ optional: false
51939
+ }],
51676
51940
  "notifier.send": [{
51677
51941
  name: "deviceId",
51678
51942
  form: "single",
51679
51943
  optional: false
51680
51944
  }],
51945
+ "numericSensor.getStatus": [{
51946
+ name: "deviceId",
51947
+ form: "single",
51948
+ optional: false
51949
+ }],
51950
+ "osd.getStatus": [{
51951
+ name: "deviceId",
51952
+ form: "single",
51953
+ optional: false
51954
+ }],
51681
51955
  "osd.setOverlay": [{
51682
51956
  name: "deviceId",
51683
51957
  form: "single",
@@ -51737,6 +52011,11 @@ Object.freeze({
51737
52011
  form: "single",
51738
52012
  optional: false
51739
52013
  }],
52014
+ "petFeeder.getStatus": [{
52015
+ name: "deviceId",
52016
+ form: "single",
52017
+ optional: false
52018
+ }],
51740
52019
  "petFeeder.markFoodReplenished": [{
51741
52020
  name: "deviceId",
51742
52021
  form: "single",
@@ -51772,6 +52051,11 @@ Object.freeze({
51772
52051
  form: "single",
51773
52052
  optional: false
51774
52053
  }],
52054
+ "pipelineAnalytics.applyDeviceSettingsPatch": [{
52055
+ name: "deviceId",
52056
+ form: "single",
52057
+ optional: false
52058
+ }],
51775
52059
  "pipelineAnalytics.clearTrackRelation": [{
51776
52060
  name: "deviceId",
51777
52061
  form: "single",
@@ -51812,6 +52096,16 @@ Object.freeze({
51812
52096
  form: "single",
51813
52097
  optional: false
51814
52098
  }],
52099
+ "pipelineAnalytics.getDeviceLiveContribution": [{
52100
+ name: "deviceId",
52101
+ form: "single",
52102
+ optional: false
52103
+ }],
52104
+ "pipelineAnalytics.getDeviceSettingsContribution": [{
52105
+ name: "deviceId",
52106
+ form: "single",
52107
+ optional: false
52108
+ }],
51815
52109
  "pipelineAnalytics.getEventDensity": [{
51816
52110
  name: "deviceId",
51817
52111
  form: "single",
@@ -52027,6 +52321,11 @@ Object.freeze({
52027
52321
  form: "single",
52028
52322
  optional: true
52029
52323
  }],
52324
+ "pipelineOrchestrator.applyDeviceSettingsPatch": [{
52325
+ name: "deviceId",
52326
+ form: "single",
52327
+ optional: false
52328
+ }],
52030
52329
  "pipelineOrchestrator.assignAudio": [{
52031
52330
  name: "deviceId",
52032
52331
  form: "single",
@@ -52072,6 +52371,16 @@ Object.freeze({
52072
52371
  form: "single",
52073
52372
  optional: false
52074
52373
  }],
52374
+ "pipelineOrchestrator.getDeviceLiveContribution": [{
52375
+ name: "deviceId",
52376
+ form: "single",
52377
+ optional: false
52378
+ }],
52379
+ "pipelineOrchestrator.getDeviceSettingsContribution": [{
52380
+ name: "deviceId",
52381
+ form: "single",
52382
+ optional: false
52383
+ }],
52075
52384
  "pipelineOrchestrator.getPipelineAssignment": [{
52076
52385
  name: "deviceId",
52077
52386
  form: "single",
@@ -52192,11 +52501,31 @@ Object.freeze({
52192
52501
  form: "single",
52193
52502
  optional: true
52194
52503
  }],
52504
+ "powerMeter.getStatus": [{
52505
+ name: "deviceId",
52506
+ form: "single",
52507
+ optional: false
52508
+ }],
52509
+ "presence.getStatus": [{
52510
+ name: "deviceId",
52511
+ form: "single",
52512
+ optional: false
52513
+ }],
52514
+ "pressureSensor.getStatus": [{
52515
+ name: "deviceId",
52516
+ form: "single",
52517
+ optional: false
52518
+ }],
52195
52519
  "privacyMask.getOptions": [{
52196
52520
  name: "deviceId",
52197
52521
  form: "single",
52198
52522
  optional: false
52199
52523
  }],
52524
+ "privacyMask.getStatus": [{
52525
+ name: "deviceId",
52526
+ form: "single",
52527
+ optional: false
52528
+ }],
52200
52529
  "privacyMask.setAudioEnabled": [{
52201
52530
  name: "deviceId",
52202
52531
  form: "single",
@@ -52247,6 +52576,11 @@ Object.freeze({
52247
52576
  form: "single",
52248
52577
  optional: false
52249
52578
  }],
52579
+ "ptz.getStatus": [{
52580
+ name: "deviceId",
52581
+ form: "single",
52582
+ optional: false
52583
+ }],
52250
52584
  "ptz.goHome": [{
52251
52585
  name: "deviceId",
52252
52586
  form: "single",
@@ -52337,6 +52671,11 @@ Object.freeze({
52337
52671
  form: "single",
52338
52672
  optional: false
52339
52673
  }],
52674
+ "recordingArchive.applyDeviceSettingsPatch": [{
52675
+ name: "deviceId",
52676
+ form: "single",
52677
+ optional: false
52678
+ }],
52340
52679
  "recordingArchive.deleteFootprint": [{
52341
52680
  name: "deviceId",
52342
52681
  form: "single",
@@ -52357,6 +52696,21 @@ Object.freeze({
52357
52696
  form: "single",
52358
52697
  optional: false
52359
52698
  }],
52699
+ "recordingArchive.getDeviceLiveContribution": [{
52700
+ name: "deviceId",
52701
+ form: "single",
52702
+ optional: false
52703
+ }],
52704
+ "recordingArchive.getDeviceSettingsContribution": [{
52705
+ name: "deviceId",
52706
+ form: "single",
52707
+ optional: false
52708
+ }],
52709
+ "recordingArchive.getStatus": [{
52710
+ name: "deviceId",
52711
+ form: "single",
52712
+ optional: false
52713
+ }],
52360
52714
  "recordingArchive.listOpsLog": [{
52361
52715
  name: "deviceId",
52362
52716
  form: "single",
@@ -52442,6 +52796,11 @@ Object.freeze({
52442
52796
  form: "single",
52443
52797
  optional: false
52444
52798
  }],
52799
+ "recordingOnboard.getStatus": [{
52800
+ name: "deviceId",
52801
+ form: "single",
52802
+ optional: false
52803
+ }],
52445
52804
  "recordingOnboard.setSettings": [{
52446
52805
  name: "deviceId",
52447
52806
  form: "single",
@@ -52472,6 +52831,11 @@ Object.freeze({
52472
52831
  form: "single",
52473
52832
  optional: false
52474
52833
  }],
52834
+ "sceneMonitor.getStatus": [{
52835
+ name: "deviceId",
52836
+ form: "single",
52837
+ optional: false
52838
+ }],
52475
52839
  "sceneMonitor.listScenes": [{
52476
52840
  name: "deviceId",
52477
52841
  form: "single",
@@ -52497,6 +52861,11 @@ Object.freeze({
52497
52861
  form: "single",
52498
52862
  optional: false
52499
52863
  }],
52864
+ "scriptRunner.getStatus": [{
52865
+ name: "deviceId",
52866
+ form: "single",
52867
+ optional: false
52868
+ }],
52500
52869
  "scriptRunner.run": [{
52501
52870
  name: "deviceId",
52502
52871
  form: "single",
@@ -52507,11 +52876,31 @@ Object.freeze({
52507
52876
  form: "single",
52508
52877
  optional: false
52509
52878
  }],
52879
+ "smoke.getStatus": [{
52880
+ name: "deviceId",
52881
+ form: "single",
52882
+ optional: false
52883
+ }],
52884
+ "snapshot.applyDeviceSettingsPatch": [{
52885
+ name: "deviceId",
52886
+ form: "single",
52887
+ optional: false
52888
+ }],
52510
52889
  "snapshot.getDebugState": [{
52511
52890
  name: "deviceId",
52512
52891
  form: "single",
52513
52892
  optional: false
52514
52893
  }],
52894
+ "snapshot.getDeviceLiveContribution": [{
52895
+ name: "deviceId",
52896
+ form: "single",
52897
+ optional: false
52898
+ }],
52899
+ "snapshot.getDeviceSettingsContribution": [{
52900
+ name: "deviceId",
52901
+ form: "single",
52902
+ optional: false
52903
+ }],
52515
52904
  "snapshot.getSnapshot": [{
52516
52905
  name: "deviceId",
52517
52906
  form: "single",
@@ -52528,6 +52917,11 @@ Object.freeze({
52528
52917
  form: "array",
52529
52918
  optional: false
52530
52919
  }],
52920
+ "snapshot.getStatus": [{
52921
+ name: "deviceId",
52922
+ form: "single",
52923
+ optional: false
52924
+ }],
52531
52925
  "snapshot.invalidateCache": [{
52532
52926
  name: "deviceId",
52533
52927
  form: "single",
@@ -52538,6 +52932,11 @@ Object.freeze({
52538
52932
  form: "single",
52539
52933
  optional: false
52540
52934
  }],
52935
+ "streamBroker.applyDeviceSettingsPatch": [{
52936
+ name: "deviceId",
52937
+ form: "single",
52938
+ optional: false
52939
+ }],
52541
52940
  "streamBroker.assignProfile": [{
52542
52941
  name: "deviceId",
52543
52942
  form: "single",
@@ -52553,6 +52952,16 @@ Object.freeze({
52553
52952
  form: "single",
52554
52953
  optional: false
52555
52954
  }],
52955
+ "streamBroker.getDeviceLiveContribution": [{
52956
+ name: "deviceId",
52957
+ form: "single",
52958
+ optional: false
52959
+ }],
52960
+ "streamBroker.getDeviceSettingsContribution": [{
52961
+ name: "deviceId",
52962
+ form: "single",
52963
+ optional: false
52964
+ }],
52556
52965
  "streamBroker.getStreamWithCodec": [{
52557
52966
  name: "deviceId",
52558
52967
  form: "single",
@@ -52613,16 +53022,46 @@ Object.freeze({
52613
53022
  form: "single",
52614
53023
  optional: false
52615
53024
  }],
53025
+ "streamParams.getStatus": [{
53026
+ name: "deviceId",
53027
+ form: "single",
53028
+ optional: false
53029
+ }],
52616
53030
  "streamParams.setProfile": [{
52617
53031
  name: "deviceId",
52618
53032
  form: "single",
52619
53033
  optional: false
52620
53034
  }],
53035
+ "switch.getStatus": [{
53036
+ name: "deviceId",
53037
+ form: "single",
53038
+ optional: false
53039
+ }],
52621
53040
  "switch.setState": [{
52622
53041
  name: "deviceId",
52623
53042
  form: "single",
52624
53043
  optional: false
52625
53044
  }],
53045
+ "tamper.getStatus": [{
53046
+ name: "deviceId",
53047
+ form: "single",
53048
+ optional: false
53049
+ }],
53050
+ "temperatureSensor.getStatus": [{
53051
+ name: "deviceId",
53052
+ form: "single",
53053
+ optional: false
53054
+ }],
53055
+ "update.getStatus": [{
53056
+ name: "deviceId",
53057
+ form: "single",
53058
+ optional: false
53059
+ }],
53060
+ "vacuumControl.getStatus": [{
53061
+ name: "deviceId",
53062
+ form: "single",
53063
+ optional: false
53064
+ }],
52626
53065
  "vacuumControl.locate": [{
52627
53066
  name: "deviceId",
52628
53067
  form: "single",
@@ -52658,6 +53097,11 @@ Object.freeze({
52658
53097
  form: "single",
52659
53098
  optional: false
52660
53099
  }],
53100
+ "valve.getStatus": [{
53101
+ name: "deviceId",
53102
+ form: "single",
53103
+ optional: false
53104
+ }],
52661
53105
  "valve.open": [{
52662
53106
  name: "deviceId",
52663
53107
  form: "single",
@@ -52673,6 +53117,11 @@ Object.freeze({
52673
53117
  form: "single",
52674
53118
  optional: false
52675
53119
  }],
53120
+ "vibration.getStatus": [{
53121
+ name: "deviceId",
53122
+ form: "single",
53123
+ optional: false
53124
+ }],
52676
53125
  "videoclips.dialClipStream": [{
52677
53126
  name: "deviceId",
52678
53127
  form: "single",
@@ -52708,6 +53157,11 @@ Object.freeze({
52708
53157
  form: "single",
52709
53158
  optional: false
52710
53159
  }],
53160
+ "waterHeater.getStatus": [{
53161
+ name: "deviceId",
53162
+ form: "single",
53163
+ optional: false
53164
+ }],
52711
53165
  "waterHeater.setAway": [{
52712
53166
  name: "deviceId",
52713
53167
  form: "single",
@@ -52723,6 +53177,11 @@ Object.freeze({
52723
53177
  form: "single",
52724
53178
  optional: false
52725
53179
  }],
53180
+ "weather.getStatus": [{
53181
+ name: "deviceId",
53182
+ form: "single",
53183
+ optional: false
53184
+ }],
52726
53185
  "webrtcSession.addIceCandidate": [{
52727
53186
  name: "deviceId",
52728
53187
  form: "single",
@@ -53460,7 +53919,7 @@ var PreviewTextField = string().max(200);
53460
53919
  * Whether the notification's preview is a STILL or a short animation.
53461
53920
  *
53462
53921
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
53463
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
53922
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
53464
53923
  * night reads better as three seconds of motion than as one frame of it. Both
53465
53924
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
53466
53925
  * simply applies it to a dozen frames sampled across the render and assembles
@@ -161129,37 +161588,37 @@ function buildOnboardWrites(patch, schedule) {
161129
161588
  //#endregion
161130
161589
  //#region src/battery-charging.ts
161131
161590
  /**
161132
- * Da `adapterStatus` + `chargeStatus` alla sorgente di alimentazione.
161133
- *
161134
- * I due campi rispondono a DUE domande diverse, e confonderle è il bug che
161135
- * questo modulo esiste per chiudere:
161136
- *
161137
- * - `adapterStatus` — l'alimentazione è COLLEGATA? Il firmware manda 0/1/2
161138
- * (nessuna · adattatore DC · pannello solare) e il confine dell'hub lo
161139
- * traduce in `'none' | 'dc' | 'solarPanel'` (`mapHubChargeStatus` e
161140
- * `mapHubAdapterStatus` in `reolink-hub.ts`), perché il vocabolario del
161141
- * percorso standalone è già a stringhe.
161142
- * - `chargeStatus` — la CELLA cosa sta facendo? 0 ferma · 1 in carica ·
161143
- * 2 carica completa.
161144
- *
161145
- * La vecchia derivazione consultava l'adattatore SOLO per cercarci 'solar', e
161146
- * un DC collegato cadeva nel ripiego `'none'`. Due Argus 3E lo nascondevano per
161147
- * caso: piene e collegate rispondono `chargeStatus: 2`, che il ramo `isCharging`
161148
- * mappava su `'dc'` per la ragione sbagliata. La Argus MagiCam (batteryVersion
161149
- * 1, firmware 2026) collegata in permanenza risponde `chargeStatus: 0`, e per
161150
- * tutta la sua vita è stata riportata NON in carica.
161151
- *
161152
- * Che `adapterStatus` sia un segnale vero e non una costante è MISURATO: il
161153
- * 2026-09-05 l'operatore ha staccato il device 3628 e il payload grezzo è
161154
- * passato da `adapterStatus: 1` a `0`, con `chargeStatus: 0` da entrambe le
161155
- * parti — cioè `chargeStatus` da solo NON distingue i due stati.
161156
- *
161157
- * Due campi assenti NON sono `'none'`: `'none'` è un negativo che il firmware
161158
- * ha detto ("nessun adattatore, cella ferma"), l'assenza di entrambi è
161159
- * `'unknown'` — lo stesso confine che `percentage` ha chiuso diventando
161160
- * `nullable` (D315). Il chiamante (`mapBatteryInfo`) non arriva qui con un
161161
- * push che non parla di alimentazione: `reportsPowerSource` lo filtra prima e
161162
- * conserva la convinzione precedente.
161591
+ * From `adapterStatus` + `chargeStatus` to the power source.
161592
+ *
161593
+ * The two fields answer TWO different questions, and confusing them is the bug that
161594
+ * this module exists to close:
161595
+ *
161596
+ * - `adapterStatus` — is the power CONNECTED? The firmware sends 0/1/2
161597
+ * (none · DC adapter · solar panel) and the hub boundary
161598
+ * translates it into `'none' | 'dc' | 'solarPanel'` (`mapHubChargeStatus` and
161599
+ * `mapHubAdapterStatus` in `reolink-hub.ts`), because the vocabulary of the
161600
+ * standalone path is already strings.
161601
+ * - `chargeStatus` — what is the CELL doing? 0 stopped · 1 charging ·
161602
+ * 2 fully charged.
161603
+ *
161604
+ * The old derivation consulted the adapter ONLY to look for 'solar' in it, and
161605
+ * a connected DC fell into the fallback `'none'`. Two Argus 3E units hid it by
161606
+ * chance: full and connected they answer `chargeStatus: 2`, which the `isCharging`
161607
+ * branch mapped to `'dc'` for the wrong reason. The Argus MagiCam (batteryVersion
161608
+ * 1, firmware 2026) permanently connected answers `chargeStatus: 0`, and for
161609
+ * its whole life it was reported as NOT charging.
161610
+ *
161611
+ * That `adapterStatus` is a real signal and not a constant is MEASURED: on
161612
+ * 2026-09-05 the operator unplugged device 3628 and the raw payload
161613
+ * went from `adapterStatus: 1` to `0`, with `chargeStatus: 0` on both
161614
+ * sides — i.e. `chargeStatus` alone does NOT distinguish the two states.
161615
+ *
161616
+ * Two absent fields are NOT `'none'`: `'none'` is a negative the firmware
161617
+ * has stated ("no adapter, cell stopped"), the absence of both is
161618
+ * `'unknown'` — the same boundary `percentage` closed by becoming
161619
+ * `nullable` (D315). The caller (`mapBatteryInfo`) does not arrive here with a
161620
+ * push that says nothing about power: `reportsPowerSource` filters it out first and
161621
+ * keeps the previous belief.
161163
161622
  */
161164
161623
  function deriveChargingSource(adapterStatus, chargeStatus) {
161165
161624
  if (adapterStatus === void 0 && chargeStatus === void 0) return "unknown";