@camstack/addon-provider-dreame 0.2.119 → 0.2.120
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.
- package/dist/addon.js +892 -325
- package/dist/addon.mjs +892 -325
- package/package.json +1 -3
package/dist/addon.mjs
CHANGED
|
@@ -52899,7 +52899,7 @@ var DreameCameraStream = class extends TypedEmitter {
|
|
|
52899
52899
|
}
|
|
52900
52900
|
};
|
|
52901
52901
|
//#endregion
|
|
52902
|
-
//#region ../types/dist/event-category-
|
|
52902
|
+
//#region ../types/dist/event-category-BGmz_oxW.mjs
|
|
52903
52903
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
52904
52904
|
EventCategory["SystemBoot"] = "system.boot";
|
|
52905
52905
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -53432,6 +53432,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
53432
53432
|
*/
|
|
53433
53433
|
EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
|
|
53434
53434
|
EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
|
|
53435
|
+
/**
|
|
53436
|
+
* A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
|
|
53437
|
+
* data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
|
|
53438
|
+
* consumer is the orchestrator's camera-sensors bridge, which re-emits the
|
|
53439
|
+
* camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
|
|
53440
|
+
* for a camera with no attached sensor). Providers must not emit
|
|
53441
|
+
* `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
|
|
53442
|
+
* keeps it so (camera-grid is a named, deferred exception).
|
|
53443
|
+
*/
|
|
53435
53444
|
EventCategory["ProviderMotion"] = "provider.motion";
|
|
53436
53445
|
EventCategory["ProviderDetection"] = "provider.detection";
|
|
53437
53446
|
EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
|
|
@@ -58270,7 +58279,7 @@ var ZodIssueCode = {
|
|
|
58270
58279
|
var ZodFirstPartyTypeKind;
|
|
58271
58280
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
58272
58281
|
//#endregion
|
|
58273
|
-
//#region ../types/dist/sleep-
|
|
58282
|
+
//#region ../types/dist/sleep-CDCONfkt.mjs
|
|
58274
58283
|
/**
|
|
58275
58284
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
58276
58285
|
* window to float samples (D455).
|
|
@@ -60313,7 +60322,7 @@ function errMsg(err) {
|
|
|
60313
60322
|
return String(err);
|
|
60314
60323
|
}
|
|
60315
60324
|
//#endregion
|
|
60316
|
-
//#region ../types/dist/composition-
|
|
60325
|
+
//#region ../types/dist/composition-Bzr7GwgP.mjs
|
|
60317
60326
|
/**
|
|
60318
60327
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
60319
60328
|
*
|
|
@@ -60367,21 +60376,20 @@ function portable(target) {
|
|
|
60367
60376
|
}
|
|
60368
60377
|
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
60369
60378
|
/**
|
|
60370
|
-
*
|
|
60371
|
-
*
|
|
60379
|
+
* THE table "which boolean of this device type counts as HIGH", and the
|
|
60380
|
+
* pure evaluator of its EDGE.
|
|
60372
60381
|
*
|
|
60373
|
-
*
|
|
60374
|
-
*
|
|
60375
|
-
*
|
|
60376
|
-
*
|
|
60377
|
-
*
|
|
60378
|
-
*
|
|
60379
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
60382
|
+
* ONE table for everyone who asks "is this device HIGH?": the
|
|
60383
|
+
* recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
|
|
60384
|
+
* sensor markers, the orchestrator's camera-sensors bridge and
|
|
60385
|
+
* the sources of a composite doorbell (`doorbellFeatureSources`, D671).
|
|
60386
|
+
* A second copy would diverge at the first cap added, and the symptom — "the
|
|
60387
|
+
* sensor rings the doorbell but does not record" — is exactly D62.
|
|
60380
60388
|
*
|
|
60381
|
-
* ⚠
|
|
60382
|
-
*
|
|
60383
|
-
*
|
|
60384
|
-
*
|
|
60389
|
+
* ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
|
|
60390
|
+
* two must not be unified: that one answers "what is the state WORD for a
|
|
60391
|
+
* rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
|
|
60392
|
+
* boolean's EDGE counts". Deliberately different vocabularies.
|
|
60385
60393
|
*/
|
|
60386
60394
|
/**
|
|
60387
60395
|
* Known binary / switch source caps → the boolean slice field whose
|
|
@@ -61990,22 +61998,22 @@ var CLASS_MAP_MACRO_TARGETS = [
|
|
|
61990
61998
|
"package"
|
|
61991
61999
|
];
|
|
61992
62000
|
/**
|
|
61993
|
-
*
|
|
61994
|
-
*
|
|
62001
|
+
* The FIRST-LEVEL macro classes: those an object detector emits and that
|
|
62002
|
+
* an operator can select.
|
|
61995
62003
|
*
|
|
61996
|
-
*
|
|
62004
|
+
* They are the three offered by the `object-detection` step
|
|
61997
62005
|
* (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
|
|
61998
|
-
* `enabledMacroClasses`). `package`
|
|
61999
|
-
* `MACRO_LABELS` —
|
|
62000
|
-
* `package-detection`,
|
|
62001
|
-
*
|
|
62006
|
+
* `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
|
|
62007
|
+
* `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
|
|
62008
|
+
* `package-detection`, whose enablement is driven by zones, and offering the
|
|
62009
|
+
* same word twice has already made an operator turn on the COCO proxy
|
|
62002
62010
|
* (suitcase/backpack/handbag) lasciando spento il detector dedicato.
|
|
62003
62011
|
*
|
|
62004
|
-
*
|
|
62005
|
-
*
|
|
62006
|
-
* (`types/detection.ts`);
|
|
62007
|
-
* (`RecordingTriggers.objectClasses`)
|
|
62008
|
-
*
|
|
62012
|
+
* ONE list. Before today the same three were hand-written in the step's offer
|
|
62013
|
+
* and a second time as the union `FirstLevelMacro`
|
|
62014
|
+
* (`types/detection.ts`); a third copy for the recording trigger
|
|
62015
|
+
* (`RecordingTriggers.objectClasses`) would have made the later divergence
|
|
62016
|
+
* invisible.
|
|
62009
62017
|
*/
|
|
62010
62018
|
var FIRST_LEVEL_MACRO_CLASSES = [
|
|
62011
62019
|
"person",
|
|
@@ -62070,17 +62078,17 @@ var RecordingStorageModeSchema = _enum([
|
|
|
62070
62078
|
"on-device-decision"
|
|
62071
62079
|
]);
|
|
62072
62080
|
/**
|
|
62073
|
-
*
|
|
62074
|
-
*
|
|
62081
|
+
* The macro classes that can open a recording window — the same
|
|
62082
|
+
* three offered by the `object-detection` step, from ONE list
|
|
62075
62083
|
* ({@link FIRST_LEVEL_MACRO_CLASSES}).
|
|
62076
62084
|
*/
|
|
62077
62085
|
var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
|
|
62078
62086
|
/**
|
|
62079
|
-
* True
|
|
62087
|
+
* True when `values` does not repeat an element.
|
|
62080
62088
|
*
|
|
62081
|
-
*
|
|
62082
|
-
*
|
|
62083
|
-
*
|
|
62089
|
+
* A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
|
|
62090
|
+
* becomes a SOURCE in `bandTriggerSources`, and the same source twice
|
|
62091
|
+
* would count its windows twice in `segmentMissedByMs`.
|
|
62084
62092
|
*/
|
|
62085
62093
|
var noDuplicates = (values) => new Set(values).size === values.length;
|
|
62086
62094
|
/** Which detectors trigger an `events`-mode band. */
|
|
@@ -62088,34 +62096,34 @@ var RecordingTriggersSchema = object({
|
|
|
62088
62096
|
motion: boolean().optional(),
|
|
62089
62097
|
audioThresholdDbfs: number().optional(),
|
|
62090
62098
|
/**
|
|
62091
|
-
*
|
|
62092
|
-
*
|
|
62093
|
-
*
|
|
62094
|
-
*
|
|
62099
|
+
* The macro classes whose detection opens a window. ABSENT = the source
|
|
62100
|
+
* is not listened to; an EMPTY array is rejected, because "events band, object
|
|
62101
|
+
* trigger on, no class" is the same shape "enabled and records
|
|
62102
|
+
* nothing, forever" that `eventsBandCanEverDemand` is written against.
|
|
62095
62103
|
*
|
|
62096
|
-
*
|
|
62097
|
-
*
|
|
62098
|
-
* `minConfidence<Macro>`
|
|
62099
|
-
* (`source: 'onboard'`)
|
|
62100
|
-
*
|
|
62104
|
+
* The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
|
|
62105
|
+
* those that went through `enabledMacroClasses`, the
|
|
62106
|
+
* `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
|
|
62107
|
+
* (`source: 'onboard'`) goes through none of those gates and does NOT open
|
|
62108
|
+
* windows — see `recorder/object-trigger.ts`.
|
|
62101
62109
|
*/
|
|
62102
62110
|
objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
|
|
62103
62111
|
/**
|
|
62104
|
-
*
|
|
62105
|
-
*
|
|
62112
|
+
* The LINKED devices whose RISING EDGE opens a window. Absent = the source
|
|
62113
|
+
* is not listened to; an empty array is rejected for the same reason as
|
|
62106
62114
|
* `objectClasses`.
|
|
62107
62115
|
*
|
|
62108
|
-
*
|
|
62109
|
-
*
|
|
62110
|
-
*
|
|
62111
|
-
*
|
|
62112
|
-
* device (D12) —
|
|
62116
|
+
* These are SOURCE device ids, not cameras: the band names them, so the
|
|
62117
|
+
* hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
|
|
62118
|
+
* does no RPC. The OFFER from which the operator picks them is another question, and
|
|
62119
|
+
* is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
|
|
62120
|
+
* device (D12) — never a global list of caps.
|
|
62113
62121
|
*
|
|
62114
|
-
*
|
|
62115
|
-
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`)
|
|
62116
|
-
*
|
|
62117
|
-
*
|
|
62118
|
-
*
|
|
62122
|
+
* What "high" means depends on the device TYPE and is not decided here:
|
|
62123
|
+
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
|
|
62124
|
+
* the same one as the composite doorbell (D671). And it is the EDGE, not
|
|
62125
|
+
* the level: a contact found already open at runner restart does not
|
|
62126
|
+
* record.
|
|
62119
62127
|
*/
|
|
62120
62128
|
sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
|
|
62121
62129
|
});
|
|
@@ -63192,7 +63200,7 @@ var DecoderSessionConfigSchema = object({
|
|
|
63192
63200
|
* - **VALUE** — at which level, for which scope, until when. That stays ONE
|
|
63193
63201
|
* thing: the logging settings document on the `system` cap. Two authorities
|
|
63194
63202
|
* over the values is the exact defect
|
|
63195
|
-
* `docs/design/plans/2026-08-26-
|
|
63203
|
+
* `docs/design/plans/2026-08-26-per-component-logging.md` was written to
|
|
63196
63204
|
* remove; re-introducing it from the cure side would be grotesque.
|
|
63197
63205
|
*
|
|
63198
63206
|
* Nothing in this file reads a clock, an env var or a store. The registry is
|
|
@@ -64903,7 +64911,7 @@ var BrokerStatusEnum = _enum([
|
|
|
64903
64911
|
"unreachable",
|
|
64904
64912
|
"error"
|
|
64905
64913
|
]);
|
|
64906
|
-
var BrokerInfoSchema
|
|
64914
|
+
var BrokerInfoSchema = object({
|
|
64907
64915
|
/** Stable broker id. Persisted; survives addon restarts. */
|
|
64908
64916
|
id: string(),
|
|
64909
64917
|
/** Addon id of the provider that OWNS this broker.
|
|
@@ -65036,7 +65044,7 @@ var GetStateInputSchema = object({
|
|
|
65036
65044
|
* HA: entity_id (returns the cached entity state). */
|
|
65037
65045
|
key: string()
|
|
65038
65046
|
});
|
|
65039
|
-
method(ListInputSchema, array(BrokerInfoSchema
|
|
65047
|
+
method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
|
|
65040
65048
|
kind: "mutation",
|
|
65041
65049
|
auth: "admin"
|
|
65042
65050
|
}), method(RemoveInputSchema, _void(), {
|
|
@@ -66747,7 +66755,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
66747
66755
|
*
|
|
66748
66756
|
* ⚠ An earlier version of this comment blamed Zod stripping, and that
|
|
66749
66757
|
* was wrong — corrected 2026-08-26 after the hop map
|
|
66750
|
-
* (`docs/design/2026-08-26-
|
|
66758
|
+
* (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
|
|
66751
66759
|
* There is **no Zod parse at all** between the door and the engine: the
|
|
66752
66760
|
* dispatcher forwards the payload verbatim and UDS carries it whole. A
|
|
66753
66761
|
* field declared here reaches `SqliteSettingsBackend` either way.
|
|
@@ -67627,7 +67635,17 @@ var SiteZoneSchema = object({
|
|
|
67627
67635
|
var ProviderStatusSchema = object({
|
|
67628
67636
|
connected: boolean(),
|
|
67629
67637
|
deviceCount: number(),
|
|
67630
|
-
error: string().optional()
|
|
67638
|
+
error: string().optional(),
|
|
67639
|
+
/**
|
|
67640
|
+
* `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
|
|
67641
|
+
* — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
|
|
67642
|
+
* which every provider bundles, so only a provider BUILT from D696-amended
|
|
67643
|
+
* code says it. ABSENT means an older provider that may still write it (raw
|
|
67644
|
+
* VMD writes, a boot seed), and the orchestrator's provider gate keeps that
|
|
67645
|
+
* provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
|
|
67646
|
+
* — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
|
|
67647
|
+
*/
|
|
67648
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
67631
67649
|
});
|
|
67632
67650
|
object({
|
|
67633
67651
|
externalId: string(),
|
|
@@ -68506,109 +68524,10 @@ method(object({
|
|
|
68506
68524
|
deviceIds: array(number()).readonly(),
|
|
68507
68525
|
caps: array(string()).readonly().optional()
|
|
68508
68526
|
}), record(string(), record(string(), unknown().nullable())));
|
|
68509
|
-
|
|
68510
|
-
|
|
68511
|
-
* name (same pattern as `snapshot`):
|
|
68512
|
-
*
|
|
68513
|
-
* - **Native** providers: registered per-device by device-driver
|
|
68514
|
-
* addons via `ctx.registerNativeCap` — either on a
|
|
68515
|
-
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
68516
|
-
* or directly on the camera (Reolink registers at camera level).
|
|
68517
|
-
* Emits an `onPressed` event every time the firmware pushes a
|
|
68518
|
-
* ring; status tracks the last press and a pressCount since start
|
|
68519
|
-
* (diagnostic).
|
|
68520
|
-
*
|
|
68521
|
-
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
68522
|
-
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
68523
|
-
* device (contact / switch / event-emitter …) into a doorbell for
|
|
68524
|
-
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
68525
|
-
* it per camera in the device-bindings UI, then picks the source
|
|
68526
|
-
* device + trigger in the per-device settings.
|
|
68527
|
-
*
|
|
68528
|
-
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
68529
|
-
* — subscribers listening at the camera level receive ring events
|
|
68530
|
-
* with `via[]` populated. No code on the parent needed.
|
|
68531
|
-
*/
|
|
68532
|
-
var DoorbellStatusSchema = object({
|
|
68533
|
-
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
68534
|
-
lastPressedAt: number().nullable(),
|
|
68535
|
-
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
68536
|
-
pressCountSinceStart: number()
|
|
68537
|
-
});
|
|
68538
|
-
var DoorbellPressEventSchema = object({
|
|
68539
|
-
deviceId: number(),
|
|
68540
|
-
timestamp: number()
|
|
68541
|
-
});
|
|
68542
|
-
/**
|
|
68543
|
-
* The `doorbell-source` extension slot's editable value (D648): the camera's
|
|
68544
|
-
* virtual-doorbell trigger devices, exactly what the wrapper's
|
|
68545
|
-
* `doorbellSources` persists (as `{ deviceId }` records).
|
|
68546
|
-
*/
|
|
68547
|
-
var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
|
|
68548
|
-
/**
|
|
68549
|
-
* The `doorbell-source` slot — which devices ring this camera's VIRTUAL
|
|
68550
|
-
* doorbell, owned by the `virtual-doorbell` wrapper over its
|
|
68551
|
-
* `doorbellSources` store (D648). A source rings when one of its
|
|
68552
|
-
* `SOURCE_CAPS` rises. Whether the wrapper is bound to the camera at all is a
|
|
68553
|
-
* different authority (`deviceManager.setWrapperActive`, D62) — the slot
|
|
68554
|
-
* reports it, it never writes it.
|
|
68555
|
-
*/
|
|
68556
|
-
var DOORBELL_SOURCE_SLOT = {
|
|
68557
|
-
id: "doorbell-source",
|
|
68558
|
-
label: "Doorbell trigger devices",
|
|
68559
|
-
description: "Any of these becoming active rings this camera's virtual doorbell: a binary sensor when it goes active, a switch when it turns on.",
|
|
68560
|
-
shape: "association",
|
|
68561
|
-
hostDeviceTypes: [DeviceType.Camera],
|
|
68562
|
-
sourceCaps: SOURCE_CAPS,
|
|
68563
|
-
cardinality: "many",
|
|
68564
|
-
value: DoorbellSourceSlotValueSchema
|
|
68565
|
-
};
|
|
68566
|
-
var doorbellCapability = {
|
|
68567
|
-
name: "doorbell",
|
|
68568
|
-
scope: "device",
|
|
68569
|
-
deviceNative: true,
|
|
68570
|
-
mode: "singleton",
|
|
68571
|
-
kind: "wrapper",
|
|
68572
|
-
defaultActive: false,
|
|
68573
|
-
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
68574
|
-
extensionSlots: [DOORBELL_SOURCE_SLOT],
|
|
68575
|
-
methods: {},
|
|
68576
|
-
events: {
|
|
68577
|
-
/**
|
|
68578
|
-
* Fires once per physical press. Reolink delivers via Baichuan
|
|
68579
|
-
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
68580
|
-
* release/duration — it's a pulse.
|
|
68581
|
-
*/
|
|
68582
|
-
onPressed: {
|
|
68583
|
-
data: DoorbellPressEventSchema,
|
|
68584
|
-
fromState: {
|
|
68585
|
-
field: "lastPressedAt",
|
|
68586
|
-
on: "advance"
|
|
68587
|
-
}
|
|
68588
|
-
} },
|
|
68589
|
-
status: {
|
|
68590
|
-
schema: DoorbellStatusSchema,
|
|
68591
|
-
kind: "push"
|
|
68592
|
-
},
|
|
68593
|
-
/**
|
|
68594
|
-
* Runtime-state slice — last press timestamp + lifetime press count.
|
|
68595
|
-
* Mirrored by the kernel and readable via
|
|
68596
|
-
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
68597
|
-
* without subscribing.
|
|
68598
|
-
*/
|
|
68599
|
-
runtimeState: DoorbellStatusSchema,
|
|
68600
|
-
/**
|
|
68601
|
-
* Runtime-state durability: **restored** — a monotonic accumulator: the slice IS the record. `lastPressedAt` is content here, not a clock, so it is deliberately NOT volatile.
|
|
68602
|
-
*
|
|
68603
|
-
* See `RuntimeStateDurability`. Enforced by
|
|
68604
|
-
* `scripts/check-runtime-state-durability.ts`.
|
|
68605
|
-
*/
|
|
68606
|
-
durability: "restored"
|
|
68607
|
-
};
|
|
68608
|
-
var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
|
|
68609
|
-
DeviceType.Camera, DeviceType.Camera;
|
|
68527
|
+
var ExtensionSlotIdSchema = _enum(["linked-devices"]);
|
|
68528
|
+
DeviceType.Camera;
|
|
68610
68529
|
/** A slot's editable value, discriminated on `slot`. */
|
|
68611
|
-
var ExtensionSlotValueSchema = discriminatedUnion("slot", [
|
|
68530
|
+
var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
|
|
68612
68531
|
DeviceType.Camera;
|
|
68613
68532
|
var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
|
|
68614
68533
|
state: literal("unreachable"),
|
|
@@ -68645,10 +68564,11 @@ var ExtensionSlotSourceSchema = object({
|
|
|
68645
68564
|
});
|
|
68646
68565
|
/**
|
|
68647
68566
|
* A DIFFERENT authority that gates whether the slot's sources do anything —
|
|
68648
|
-
* reported read-only, named, never written through this contract (D62).
|
|
68649
|
-
*
|
|
68650
|
-
*
|
|
68651
|
-
* `unknown` means the gate could
|
|
68567
|
+
* reported read-only, named, never written through this contract (D62) — e.g.
|
|
68568
|
+
* a slot whose sources act only while a wrapper is bound to the host, a
|
|
68569
|
+
* binding that belongs to `deviceManager.setWrapperActive`. No slot reports
|
|
68570
|
+
* one today (`linked-devices` answers `null`). `unknown` means the gate could
|
|
68571
|
+
* not be read; it is not "inactive" (D315).
|
|
68652
68572
|
*/
|
|
68653
68573
|
var ExtensionSlotActivationSchema = object({
|
|
68654
68574
|
state: _enum([
|
|
@@ -68664,7 +68584,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
|
|
|
68664
68584
|
/** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
|
|
68665
68585
|
slotRef: string(),
|
|
68666
68586
|
slot: ExtensionSlotIdSchema,
|
|
68667
|
-
/** Names the store written (D62), e.g. `
|
|
68587
|
+
/** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
|
|
68668
68588
|
authority: string(),
|
|
68669
68589
|
activation: ExtensionSlotActivationSchema.nullable(),
|
|
68670
68590
|
value: ExtensionSlotValueSchema,
|
|
@@ -68942,7 +68862,7 @@ method(object({
|
|
|
68942
68862
|
* per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
|
|
68943
68863
|
* ends in a log line, and a log line is the thing the operator asked to stop
|
|
68944
68864
|
* needing: *"possiamo armare questi errori intanto? Così al prossimo giro
|
|
68945
|
-
* ricontrolliamo tutti questi punti"
|
|
68865
|
+
* 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
|
|
68946
68866
|
* hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
|
|
68947
68867
|
* media blackout were both diagnosed. The counters stay; this is where they can
|
|
68948
68868
|
* be READ.
|
|
@@ -70318,7 +70238,7 @@ var BrokerStatusSchema$1 = _enum([
|
|
|
70318
70238
|
"unreachable",
|
|
70319
70239
|
"tls-error"
|
|
70320
70240
|
]);
|
|
70321
|
-
var BrokerInfoSchema = object({
|
|
70241
|
+
var BrokerInfoSchema$1 = object({
|
|
70322
70242
|
id: string(),
|
|
70323
70243
|
name: string(),
|
|
70324
70244
|
url: string(),
|
|
@@ -70381,7 +70301,7 @@ var StatusSchema = object({
|
|
|
70381
70301
|
brokerCount: number(),
|
|
70382
70302
|
embeddedRunning: boolean()
|
|
70383
70303
|
});
|
|
70384
|
-
method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
|
|
70304
|
+
method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
|
|
70385
70305
|
kind: "mutation",
|
|
70386
70306
|
auth: "admin"
|
|
70387
70307
|
}), method(IdInputSchema, _void(), {
|
|
@@ -72595,78 +72515,16 @@ var NcRuleInputSchema = object({
|
|
|
72595
72515
|
*/
|
|
72596
72516
|
confirm: NcConfirmSchema.optional(),
|
|
72597
72517
|
/**
|
|
72598
|
-
*
|
|
72599
|
-
*
|
|
72600
|
-
*
|
|
72601
|
-
*
|
|
72602
|
-
*
|
|
72603
|
-
*
|
|
72604
|
-
*
|
|
72605
|
-
*
|
|
72606
|
-
*
|
|
72607
|
-
* Only two honest answers exist, and this flag picks between them. It has
|
|
72608
|
-
* effect ONLY on a rule that declares a recognition scope
|
|
72609
|
-
* ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
|
|
72610
|
-
* other rule there is nothing to wait for and the flag is inert.
|
|
72611
|
-
*
|
|
72612
|
-
* | value | what happens |
|
|
72613
|
-
* | --- | --- |
|
|
72614
|
-
* | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
|
|
72615
|
-
* | 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) |
|
|
72616
|
-
*
|
|
72617
|
-
* `.optional()` and deliberately NOT `.default()`: a Zod default does not run
|
|
72618
|
-
* on the addon cap path, and absent has to keep meaning exactly what every
|
|
72619
|
-
* rule authored before this field meant.
|
|
72620
|
-
*
|
|
72621
|
-
* The cost of `true` is stated here because the editor states it too: a rule
|
|
72622
|
-
* that waits also inherits track-close SEMANTICS — its `zones` condition
|
|
72623
|
-
* tests every zone the track visited and a `crossing` condition can no longer
|
|
72624
|
-
* be satisfied, because a closed track carries no crossing.
|
|
72518
|
+
* IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
|
|
72519
|
+
* seconds; the rule sends ONE message when the window closes — early, once every
|
|
72520
|
+
* subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
|
|
72521
|
+
* the rule matched, with one mosaic tile per subject.
|
|
72522
|
+
* Absent = plain immediate (one message per track, at the first match).
|
|
72523
|
+
* Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
|
|
72524
|
+
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
72525
|
+
* path does not run Zod defaults.
|
|
72625
72526
|
*/
|
|
72626
|
-
|
|
72627
|
-
/**
|
|
72628
|
-
* GROUP a burst of subjects into ONE notification that grows.
|
|
72629
|
-
*
|
|
72630
|
-
* Seconds of quiet after the last matching subject before the burst is
|
|
72631
|
-
* considered over. While it is open, the first subject enqueues immediately —
|
|
72632
|
-
* **exactly as today, with no added latency** — and every real growth (a new
|
|
72633
|
-
* subject, or a name confirmed on one already in it) REPLACES that
|
|
72634
|
-
* notification with an updated one naming everybody. The push carries the
|
|
72635
|
-
* group's own coalescing tag, so the phone replaces rather than stacks.
|
|
72636
|
-
*
|
|
72637
|
-
* `0` / absent = off, and off is today's behaviour byte for byte.
|
|
72638
|
-
*
|
|
72639
|
-
* ### Why an idle cutoff and not a window
|
|
72640
|
-
*
|
|
72641
|
-
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
72642
|
-
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
72643
|
-
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
72644
|
-
* 30 s is a widely shipped value for the same decision.
|
|
72645
|
-
*
|
|
72646
|
-
* ### What it replaces
|
|
72647
|
-
*
|
|
72648
|
-
* The blind cooldown, which collapses a burst by DISCARDING it. Measured on
|
|
72649
|
-
* device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
|
|
72650
|
-
* notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
|
|
72651
|
-
* track that did fire and 7 carrying a confirmed identity nobody heard about.
|
|
72652
|
-
* A group collapses the same volume by MERGING, so the cooldown becomes a
|
|
72653
|
-
* budget over GROUPS — which is what it always meant — and a growth is never
|
|
72654
|
-
* throttled by the window its own first member spent.
|
|
72655
|
-
*
|
|
72656
|
-
* ### Interaction with {@link waitForEnhancement}
|
|
72657
|
-
*
|
|
72658
|
-
* They compose, and the order matters. `waitForEnhancement` defers the rule to
|
|
72659
|
-
* TRACK CLOSE, so with both set the group is opened by the first member to
|
|
72660
|
-
* CLOSE — already carrying its name — and grows as later members close. That
|
|
72661
|
-
* is later, and complete. With grouping alone the group opens on the first
|
|
72662
|
-
* object event and picks up names as they are confirmed, through the growth
|
|
72663
|
-
* path. Neither combination fires twice for one subject.
|
|
72664
|
-
*
|
|
72665
|
-
* `.optional()` and deliberately NOT `.default()`: a Zod default does not run
|
|
72666
|
-
* on the addon cap path, so absent must keep meaning what it meant before this
|
|
72667
|
-
* field existed.
|
|
72668
|
-
*/
|
|
72669
|
-
groupIdleSec: number().int().min(0).max(600).optional()
|
|
72527
|
+
groupingSec: number().int().min(5).max(60).optional()
|
|
72670
72528
|
});
|
|
72671
72529
|
/**
|
|
72672
72530
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -72714,9 +72572,10 @@ var NcRuleClearableKeySchema = _enum([
|
|
|
72714
72572
|
"targetUsers",
|
|
72715
72573
|
"snoozeOptions",
|
|
72716
72574
|
"snoozeAllowGlobal",
|
|
72717
|
-
"waitForEnhancement",
|
|
72718
72575
|
"actions",
|
|
72719
72576
|
"confirm",
|
|
72577
|
+
"groupingSec",
|
|
72578
|
+
"waitForEnhancement",
|
|
72720
72579
|
"groupIdleSec"
|
|
72721
72580
|
]);
|
|
72722
72581
|
var NcRuleUpdateInputSchema = object({
|
|
@@ -72738,9 +72597,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
72738
72597
|
*/
|
|
72739
72598
|
disabledTargetIds: array(string()).default([])
|
|
72740
72599
|
});
|
|
72600
|
+
/**
|
|
72601
|
+
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
|
|
72602
|
+
* still-true state. `backups-exports` and `alarm` are not sections — a completed
|
|
72603
|
+
* job is not an open state, and the alarm stays instant.
|
|
72604
|
+
*/
|
|
72605
|
+
var NcStateSummarySectionIdSchema = _enum([
|
|
72606
|
+
"device-state",
|
|
72607
|
+
"streams",
|
|
72608
|
+
"battery",
|
|
72609
|
+
"consumables",
|
|
72610
|
+
"tanks",
|
|
72611
|
+
"detection-blind",
|
|
72612
|
+
"nodes",
|
|
72613
|
+
"addons",
|
|
72614
|
+
"updates"
|
|
72615
|
+
]);
|
|
72741
72616
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
72742
72617
|
var NcStateSummaryPreviewSectionSchema = object({
|
|
72743
|
-
id:
|
|
72618
|
+
id: NcStateSummarySectionIdSchema,
|
|
72744
72619
|
status: _enum(["read", "unavailable"]),
|
|
72745
72620
|
items: number().int().nonnegative(),
|
|
72746
72621
|
reason: string().optional()
|
|
@@ -72750,7 +72625,7 @@ var NcStateSummaryPreviewSectionSchema = object({
|
|
|
72750
72625
|
* a `rule` split (no `section`), one section's on a `section` split.
|
|
72751
72626
|
*/
|
|
72752
72627
|
var NcStateSummaryPreviewRowSchema = object({
|
|
72753
|
-
section:
|
|
72628
|
+
section: NcStateSummarySectionIdSchema.optional(),
|
|
72754
72629
|
/** The section's name on a per-section row; every reported section's, joined, on a combined one. */
|
|
72755
72630
|
title: string(),
|
|
72756
72631
|
text: string(),
|
|
@@ -73187,6 +73062,29 @@ object({
|
|
|
73187
73062
|
firstAt: number(),
|
|
73188
73063
|
lastAt: number()
|
|
73189
73064
|
});
|
|
73065
|
+
var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
|
|
73066
|
+
var NcAlarmDelaySecSchema = number().int().min(0).max(600);
|
|
73067
|
+
var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
|
|
73068
|
+
var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
|
|
73069
|
+
var NcAlarmModeDelaysListSchema = array(object({
|
|
73070
|
+
mode: AlarmArmModeSchema,
|
|
73071
|
+
exitDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
73072
|
+
entryDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
73073
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
|
|
73074
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
73075
|
+
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
73076
|
+
mode: AlarmArmModeSchema,
|
|
73077
|
+
exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
73078
|
+
entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
73079
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
|
|
73080
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
73081
|
+
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
73082
|
+
var NcAlarmNonBlockingEditSchema = object({
|
|
73083
|
+
mode: AlarmArmModeSchema,
|
|
73084
|
+
deviceId: number().int().positive(),
|
|
73085
|
+
/** true = on the list (may be open, does not block); false = off the list (blocks). */
|
|
73086
|
+
nonBlocking: boolean()
|
|
73087
|
+
});
|
|
73190
73088
|
/**
|
|
73191
73089
|
* The per-mode lists, at most one per mode. Two lists for one mode have no
|
|
73192
73090
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
@@ -73195,10 +73093,10 @@ object({
|
|
|
73195
73093
|
var NcAlarmNonBlockingListSchema = array(object({
|
|
73196
73094
|
mode: AlarmArmModeSchema,
|
|
73197
73095
|
deviceIds: array(number().int()).max(200)
|
|
73198
|
-
})).max(8).refine(
|
|
73096
|
+
})).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
73199
73097
|
/**
|
|
73200
|
-
* The three durations
|
|
73201
|
-
* transitions, and which openings each mode tolerates.
|
|
73098
|
+
* The three durations — global, and per mode since D697 — the panel's state
|
|
73099
|
+
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
73202
73100
|
*
|
|
73203
73101
|
* They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
|
|
73204
73102
|
* `alarm-panel` is `deviceNative` and its other provider mirrors somebody
|
|
@@ -73208,15 +73106,15 @@ var NcAlarmNonBlockingListSchema = array(object({
|
|
|
73208
73106
|
*/
|
|
73209
73107
|
var NcAlarmSettingsSchema = object({
|
|
73210
73108
|
/** Grace period between arming and the mode taking effect. 0 = immediate. */
|
|
73211
|
-
exitDelaySec:
|
|
73109
|
+
exitDelaySec: NcAlarmDelaySecSchema,
|
|
73212
73110
|
/** Grace period between a trigger and the alarm firing. 0 = immediate. */
|
|
73213
|
-
entryDelaySec:
|
|
73111
|
+
entryDelaySec: NcAlarmDelaySecSchema,
|
|
73214
73112
|
/**
|
|
73215
73113
|
* How long `triggered` lasts before the panel re-arms itself.
|
|
73216
73114
|
* **0 = until an operator disarms it** — the behaviour before this field
|
|
73217
73115
|
* existed, and therefore what an untouched install keeps doing.
|
|
73218
73116
|
*/
|
|
73219
|
-
triggeredDurationSec:
|
|
73117
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema,
|
|
73220
73118
|
/**
|
|
73221
73119
|
* Deprecated by D630 — every transition is announced. Parsed, never read;
|
|
73222
73120
|
* remove after one release. Optional so an older admin's patch (which still
|
|
@@ -73239,17 +73137,30 @@ var NcAlarmSettingsSchema = object({
|
|
|
73239
73137
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
73240
73138
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
73241
73139
|
*/
|
|
73242
|
-
nonBlocking: NcAlarmNonBlockingListSchema.default([])
|
|
73140
|
+
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
73141
|
+
/**
|
|
73142
|
+
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
73143
|
+
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
73144
|
+
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
73145
|
+
*/
|
|
73146
|
+
modeDelays: NcAlarmModeDelaysListSchema.default([])
|
|
73243
73147
|
});
|
|
73244
73148
|
/**
|
|
73245
73149
|
* Every field optional — a tab edits one control at a time.
|
|
73246
73150
|
*
|
|
73247
|
-
* `nonBlocking`
|
|
73248
|
-
* remove an inner `.default()`, so a patch that never
|
|
73249
|
-
* parse to `
|
|
73250
|
-
* (the same trap {@link NcRulePatchSchema} documents).
|
|
73151
|
+
* `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
|
|
73152
|
+
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
73153
|
+
* named the field would parse to `[]` and wipe every mode's list on an
|
|
73154
|
+
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
73155
|
+
* `modeDelays` means EDITS, not the stored overrides.
|
|
73251
73156
|
*/
|
|
73252
|
-
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
73157
|
+
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
73158
|
+
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
73159
|
+
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
73160
|
+
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
73161
|
+
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
73162
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
73163
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
|
|
73253
73164
|
/**
|
|
73254
73165
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
73255
73166
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -73349,6 +73260,28 @@ var NcAlarmConfigSchema = object({
|
|
|
73349
73260
|
*/
|
|
73350
73261
|
live: NcAlarmLiveSchema.optional()
|
|
73351
73262
|
});
|
|
73263
|
+
var NcAlarmSensorReadingSchema = _enum([
|
|
73264
|
+
"open",
|
|
73265
|
+
"closed",
|
|
73266
|
+
"unknown",
|
|
73267
|
+
"not-opening"
|
|
73268
|
+
]);
|
|
73269
|
+
/** One device's state as the alarm reads it — the classifier the arm check uses. */
|
|
73270
|
+
var NcAlarmSensorStateSchema = object({
|
|
73271
|
+
deviceId: number().int().positive(),
|
|
73272
|
+
reading: NcAlarmSensorReadingSchema,
|
|
73273
|
+
/** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
|
|
73274
|
+
state: string().nullable(),
|
|
73275
|
+
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
73276
|
+
unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
|
|
73277
|
+
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
73278
|
+
online: boolean().nullable()
|
|
73279
|
+
});
|
|
73280
|
+
var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
|
|
73281
|
+
var NcAlarmSensorsSchema = object({
|
|
73282
|
+
sensors: array(NcAlarmSensorStateSchema),
|
|
73283
|
+
readAt: number().int().nonnegative()
|
|
73284
|
+
});
|
|
73352
73285
|
/**
|
|
73353
73286
|
* ONE rule's demand on ONE camera's clip ring.
|
|
73354
73287
|
*
|
|
@@ -73439,7 +73372,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
73439
73372
|
}), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
|
|
73440
73373
|
kind: "mutation",
|
|
73441
73374
|
auth: "admin"
|
|
73442
|
-
});
|
|
73375
|
+
}), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
|
|
73443
73376
|
/**
|
|
73444
73377
|
* Zod schemas for persisted record types.
|
|
73445
73378
|
*
|
|
@@ -73786,12 +73719,26 @@ var CameraSensorRefSchema = object({
|
|
|
73786
73719
|
function cameraSensorRefKey(ref) {
|
|
73787
73720
|
return `${ref.addonId}/${ref.stableId}`;
|
|
73788
73721
|
}
|
|
73789
|
-
/**
|
|
73790
|
-
|
|
73791
|
-
|
|
73792
|
-
|
|
73793
|
-
|
|
73794
|
-
|
|
73722
|
+
/**
|
|
73723
|
+
* A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
|
|
73724
|
+
* `replace`: its motion is the camera's, and while one is READY the camera's
|
|
73725
|
+
* own motion no longer counts on its own. `confirm`: while one is READY the
|
|
73726
|
+
* camera's own motion counts only while a confirm sensor is active — with or
|
|
73727
|
+
* without a replace sensor (spec C2, the controller's ruling on Q1).
|
|
73728
|
+
*/
|
|
73729
|
+
var CameraSensorModeSchema = _enum([
|
|
73730
|
+
"in-addition",
|
|
73731
|
+
"confirm",
|
|
73732
|
+
"replace"
|
|
73733
|
+
]);
|
|
73734
|
+
/** A stored sensor with no mode — every CS-1 row — is in addition. */
|
|
73735
|
+
var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
|
|
73736
|
+
/**
|
|
73737
|
+
* A camera's attached sensors. A CS-1 row carried an envelope
|
|
73738
|
+
* `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
|
|
73739
|
+
* what the write stores (D672 rule 3), so it is never written again.
|
|
73740
|
+
*/
|
|
73741
|
+
var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
|
|
73795
73742
|
const seen = /* @__PURE__ */ new Set();
|
|
73796
73743
|
value.sensors.forEach((ref, index) => {
|
|
73797
73744
|
const key = cameraSensorRefKey(ref);
|
|
@@ -73803,39 +73750,41 @@ var CameraSensorsConfigSchema = object({
|
|
|
73803
73750
|
seen.add(key);
|
|
73804
73751
|
});
|
|
73805
73752
|
});
|
|
73806
|
-
|
|
73753
|
+
/** Every attachment names its mode; an older orchestrator that does not is in addition. */
|
|
73754
|
+
var AttachmentFields = {
|
|
73807
73755
|
addonId: string(),
|
|
73808
|
-
stableId: string()
|
|
73756
|
+
stableId: string(),
|
|
73757
|
+
mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
|
|
73809
73758
|
};
|
|
73810
73759
|
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
73811
73760
|
object({
|
|
73812
|
-
...
|
|
73761
|
+
...AttachmentFields,
|
|
73813
73762
|
state: literal("ready"),
|
|
73814
73763
|
deviceId: number(),
|
|
73815
73764
|
name: string(),
|
|
73816
73765
|
caps: array(string()).readonly()
|
|
73817
73766
|
}),
|
|
73818
73767
|
object({
|
|
73819
|
-
...
|
|
73768
|
+
...AttachmentFields,
|
|
73820
73769
|
state: literal("offline"),
|
|
73821
73770
|
deviceId: number(),
|
|
73822
73771
|
name: string(),
|
|
73823
73772
|
reason: _enum(["offline", "disabled"])
|
|
73824
73773
|
}),
|
|
73825
73774
|
object({
|
|
73826
|
-
...
|
|
73775
|
+
...AttachmentFields,
|
|
73827
73776
|
state: literal("missing"),
|
|
73828
73777
|
reason: string()
|
|
73829
73778
|
}),
|
|
73830
73779
|
object({
|
|
73831
|
-
...
|
|
73780
|
+
...AttachmentFields,
|
|
73832
73781
|
state: literal("unsupported"),
|
|
73833
73782
|
deviceId: number(),
|
|
73834
73783
|
name: string(),
|
|
73835
73784
|
reason: string()
|
|
73836
73785
|
}),
|
|
73837
73786
|
object({
|
|
73838
|
-
...
|
|
73787
|
+
...AttachmentFields,
|
|
73839
73788
|
state: literal("unreadable"),
|
|
73840
73789
|
reason: string()
|
|
73841
73790
|
})
|
|
@@ -73848,17 +73797,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
|
73848
73797
|
* say.
|
|
73849
73798
|
*/
|
|
73850
73799
|
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
73800
|
+
/** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
|
|
73801
|
+
var CameraOwnMotionSchema = _enum([
|
|
73802
|
+
"always",
|
|
73803
|
+
"when-confirmed",
|
|
73804
|
+
"never"
|
|
73805
|
+
]);
|
|
73806
|
+
/** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
|
|
73807
|
+
var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
|
|
73808
|
+
/**
|
|
73809
|
+
* The camera's OWN onboard motion (D696): the raw input the bridge combines,
|
|
73810
|
+
* never the effective value. The camera's `motion` slice is the effective one,
|
|
73811
|
+
* so a view of the camera's own row reads this.
|
|
73812
|
+
* - `atMs`: when the bridge received the camera's last own edge.
|
|
73813
|
+
* - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
|
|
73814
|
+
* AND it is younger than the window the bridge counts the camera's own motion
|
|
73815
|
+
* for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
|
|
73816
|
+
* sends a clear (heartbeats only) therefore reads `false` once no push came
|
|
73817
|
+
* within the window; a status read is a snapshot, so a live view re-asks.
|
|
73818
|
+
* Absent = this orchestrator has not received the camera's own motion since it
|
|
73819
|
+
* started (unknown, never "quiet"), or an orchestrator older than D696.
|
|
73820
|
+
*/
|
|
73821
|
+
var CameraRawLevelSchema = object({
|
|
73822
|
+
detected: boolean(),
|
|
73823
|
+
atMs: number()
|
|
73824
|
+
});
|
|
73851
73825
|
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
73852
|
-
object({
|
|
73826
|
+
object({
|
|
73827
|
+
state: literal("not-configured"),
|
|
73828
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
73829
|
+
}),
|
|
73853
73830
|
object({
|
|
73854
73831
|
state: literal("unreadable"),
|
|
73855
|
-
reason: string()
|
|
73832
|
+
reason: string(),
|
|
73833
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
73856
73834
|
}),
|
|
73857
73835
|
object({
|
|
73858
73836
|
state: literal("configured"),
|
|
73859
|
-
|
|
73837
|
+
cameraLevel: CameraRawLevelSchema.optional(),
|
|
73860
73838
|
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
73861
|
-
|
|
73839
|
+
/** Absent = an orchestrator older than CS-2: it does not say (D315). */
|
|
73840
|
+
cameraMotion: CameraOwnMotionSchema.optional(),
|
|
73841
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional(),
|
|
73842
|
+
notEnforced: CameraSensorsNotEnforcedSchema.optional()
|
|
73862
73843
|
})
|
|
73863
73844
|
]);
|
|
73864
73845
|
Object.freeze({
|
|
@@ -74543,14 +74524,14 @@ var TrackSchema = object({
|
|
|
74543
74524
|
* `derive-returned-null tile=standin`,
|
|
74544
74525
|
* `native-tile tile=native no-key-frame-at-close`, …) written at close and
|
|
74545
74526
|
* CLEARED by the late-keyFrame upgrade when a native tile lands after all.
|
|
74546
|
-
* The operator-facing answer to "perché manca l'immagine?" on a track whose
|
|
74527
|
+
* The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
|
|
74547
74528
|
* tile is a face/plate stand-in, a raster crop, or an icon.
|
|
74548
74529
|
*
|
|
74549
74530
|
* **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
|
|
74550
74531
|
* the TILE ranked below native, so a track whose thumbnail landed natively
|
|
74551
74532
|
* while its key frame missed carried no reason at all — three of the four
|
|
74552
74533
|
* `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
|
|
74553
|
-
* that shape, and their "niente ultimo" had no cause anywhere on the row.
|
|
74534
|
+
* that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
|
|
74554
74535
|
* The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
|
|
74555
74536
|
* lastFrame copy source`), so its absence is now on this line whatever the
|
|
74556
74537
|
* tile ended up being.
|
|
@@ -74637,7 +74618,7 @@ var MotionEventSchema = object({
|
|
|
74637
74618
|
/**
|
|
74638
74619
|
* Ms offsets from `timestamp` (the episode's own first rising edge, so the
|
|
74639
74620
|
* first entry is always `0`) of every genuine off→on transition the
|
|
74640
|
-
* episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
|
|
74621
|
+
* episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
|
|
74641
74622
|
* push: a firmware source that keepalives at ~1 Hz for the whole burst
|
|
74642
74623
|
* (Reolink, Hikvision) produces exactly one edge; a source that reports an
|
|
74643
74624
|
* explicit `false` mid-episode and then resumes before the quiet window
|
|
@@ -75161,6 +75142,7 @@ var KeyEventSchema = object({
|
|
|
75161
75142
|
bestEventId: string(),
|
|
75162
75143
|
/** Track lifetime in ms (lastSeen - firstSeen). */
|
|
75163
75144
|
windowMs: number().optional(),
|
|
75145
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
75164
75146
|
...TrackFlagFields,
|
|
75165
75147
|
...TrackRetrainFields
|
|
75166
75148
|
});
|
|
@@ -77089,8 +77071,10 @@ var RunnerCameraConfigSchema = object({
|
|
|
77089
77071
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
77090
77072
|
* analyzer providers) running on decoded frames in this runner.
|
|
77091
77073
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
77092
|
-
* analytics). The provider emits ProviderMotion
|
|
77093
|
-
*
|
|
77074
|
+
* analytics). The provider emits its raw push as `ProviderMotion`
|
|
77075
|
+
* (D673); the orchestrator's camera-sensors bridge re-emits the camera's
|
|
77076
|
+
* effective motion as `MotionOnMotionChanged`, which is what reaches
|
|
77077
|
+
* `reportMotion`.
|
|
77094
77078
|
*/
|
|
77095
77079
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
77096
77080
|
/**
|
|
@@ -77267,7 +77251,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
77267
77251
|
hasGpu: boolean(),
|
|
77268
77252
|
inferenceBackend: string().optional(),
|
|
77269
77253
|
cpuCores: number().optional()
|
|
77270
|
-
})
|
|
77254
|
+
}),
|
|
77255
|
+
/**
|
|
77256
|
+
* Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
|
|
77257
|
+
* runner never writes it. ABSENT = a runner older than D696, which still
|
|
77258
|
+
* writes the slice from its phase machine; the orchestrator does not write
|
|
77259
|
+
* while any runner node is absent-or-unanswered, so one slice never has two
|
|
77260
|
+
* writers.
|
|
77261
|
+
*/
|
|
77262
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
77271
77263
|
});
|
|
77272
77264
|
/**
|
|
77273
77265
|
* Aggregate runtime metrics for the runner's whole local pool. Mirrors the
|
|
@@ -79932,7 +79924,7 @@ var ClipPlaybackSchema = object({
|
|
|
79932
79924
|
* **One authorised yes is one wake.** `next-natural` — take the clip the next
|
|
79933
79925
|
* time the camera is awake for its own reasons — is deliberately not a member:
|
|
79934
79926
|
* it was proposed, it is free on the battery, and the operator declined it on
|
|
79935
|
-
* 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."
|
|
79927
|
+
* 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
|
|
79936
79928
|
* D558 "Considered and not taken").
|
|
79937
79929
|
*/
|
|
79938
79930
|
var ClipWakeSchema = _enum(["authorised"]);
|
|
@@ -80193,7 +80185,7 @@ DeviceType.Camera, method(object({
|
|
|
80193
80185
|
* It replaced `sources?: string[]`, a VIEW filter over source ids that
|
|
80194
80186
|
* assumed the answer was a fan-out over everything a camera has. The
|
|
80195
80187
|
* operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
|
|
80196
|
-
* solo"* — so the list is asked of one provider at a time and there is
|
|
80188
|
+
* solo"* [there is only one user] — so the list is asked of one provider at a time and there is
|
|
80197
80189
|
* nothing to filter out of it.
|
|
80198
80190
|
*/
|
|
80199
80191
|
provider: string().min(1)
|
|
@@ -82813,6 +82805,70 @@ onStatusChanged: { data: object({
|
|
|
82813
82805
|
* whether persisting is worth a SQLite commit. */
|
|
82814
82806
|
volatileStateFields: ["lastChangedAt"]
|
|
82815
82807
|
};
|
|
82808
|
+
var DoorbellStatusSchema = object({
|
|
82809
|
+
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
82810
|
+
lastPressedAt: number().nullable(),
|
|
82811
|
+
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
82812
|
+
pressCountSinceStart: number()
|
|
82813
|
+
});
|
|
82814
|
+
var DoorbellPressEventSchema = object({
|
|
82815
|
+
deviceId: number(),
|
|
82816
|
+
timestamp: number()
|
|
82817
|
+
});
|
|
82818
|
+
/**
|
|
82819
|
+
* Doorbell button cap. Two kinds of provider serve it, and to every consumer
|
|
82820
|
+
* they are the same cap:
|
|
82821
|
+
*
|
|
82822
|
+
* - **Native** providers, registered per device by a driver addon through
|
|
82823
|
+
* `ctx.registerNativeCap` — a `DeviceType.Button` accessory with
|
|
82824
|
+
* `role: DeviceRole.Doorbell`, or the camera itself (Reolink registers at
|
|
82825
|
+
* camera level). They emit `onPressed` on every firmware ring.
|
|
82826
|
+
* - **A composed doorbell** (D670, D671): a camera's customization gives it
|
|
82827
|
+
* the cap, its `lastPressedAt` rising from the sources the operator
|
|
82828
|
+
* assigned in Customize → Doorbell, and the composer emits `onPressed`
|
|
82829
|
+
* from that field's advance (`fromState`).
|
|
82830
|
+
*
|
|
82831
|
+
* The DeviceEventPropagator re-emits `onPressed` on the camera parent.
|
|
82832
|
+
*/
|
|
82833
|
+
var doorbellCapability = {
|
|
82834
|
+
name: "doorbell",
|
|
82835
|
+
scope: "device",
|
|
82836
|
+
deviceNative: true,
|
|
82837
|
+
mode: "singleton",
|
|
82838
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
82839
|
+
methods: {},
|
|
82840
|
+
events: {
|
|
82841
|
+
/**
|
|
82842
|
+
* Fires once per physical press. Reolink delivers via Baichuan
|
|
82843
|
+
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
82844
|
+
* release/duration — it's a pulse.
|
|
82845
|
+
*/
|
|
82846
|
+
onPressed: {
|
|
82847
|
+
data: DoorbellPressEventSchema,
|
|
82848
|
+
fromState: {
|
|
82849
|
+
field: "lastPressedAt",
|
|
82850
|
+
on: "advance"
|
|
82851
|
+
}
|
|
82852
|
+
} },
|
|
82853
|
+
status: {
|
|
82854
|
+
schema: DoorbellStatusSchema,
|
|
82855
|
+
kind: "push"
|
|
82856
|
+
},
|
|
82857
|
+
/**
|
|
82858
|
+
* Runtime-state slice — last press timestamp + lifetime press count.
|
|
82859
|
+
* Mirrored by the kernel and readable via
|
|
82860
|
+
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
82861
|
+
* without subscribing.
|
|
82862
|
+
*/
|
|
82863
|
+
runtimeState: DoorbellStatusSchema,
|
|
82864
|
+
/**
|
|
82865
|
+
* Runtime-state durability: **restored** — a monotonic accumulator: the slice IS the record. `lastPressedAt` is content here, not a clock, so it is deliberately NOT volatile.
|
|
82866
|
+
*
|
|
82867
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
82868
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
82869
|
+
*/
|
|
82870
|
+
durability: "restored"
|
|
82871
|
+
};
|
|
82816
82872
|
/**
|
|
82817
82873
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
82818
82874
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -84957,9 +85013,9 @@ var MotionStatusSchema = object({
|
|
|
84957
85013
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
84958
85014
|
lastDetectedAt: number().nullable(),
|
|
84959
85015
|
/**
|
|
84960
|
-
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device
|
|
84961
|
-
* `null` while false and on every `Sensor`
|
|
84962
|
-
* constant's doc for the one-authority rule.
|
|
85016
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
|
|
85017
|
+
* orchestrator writes it, D696), `null` while false and on every `Sensor`
|
|
85018
|
+
* device (D475) — see that constant's doc for the one-authority rule.
|
|
84963
85019
|
*
|
|
84964
85020
|
* ## Reading this field still arms nothing
|
|
84965
85021
|
*
|
|
@@ -84977,34 +85033,31 @@ var MotionStatusSchema = object({
|
|
|
84977
85033
|
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
84978
85034
|
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
84979
85035
|
*
|
|
84980
|
-
* ## Who writes it
|
|
84981
|
-
*
|
|
84982
|
-
* - **Cameras** — the
|
|
84983
|
-
*
|
|
84984
|
-
* `
|
|
84985
|
-
* `
|
|
84986
|
-
*
|
|
84987
|
-
*
|
|
84988
|
-
* a
|
|
84989
|
-
*
|
|
84990
|
-
*
|
|
84991
|
-
*
|
|
84992
|
-
*
|
|
84993
|
-
*
|
|
84994
|
-
*
|
|
84995
|
-
*
|
|
84996
|
-
*
|
|
84997
|
-
*
|
|
84998
|
-
* `
|
|
84999
|
-
*
|
|
85000
|
-
*
|
|
85001
|
-
*
|
|
85002
|
-
*
|
|
85003
|
-
*
|
|
85004
|
-
*
|
|
85005
|
-
* This predates D475 and is not fixed there: the fix touches every
|
|
85006
|
-
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
85007
|
-
* "sole writer" wording without also removing the other writers.
|
|
85036
|
+
* ## Who writes it (D696)
|
|
85037
|
+
*
|
|
85038
|
+
* - **Cameras** — the orchestrator, and nothing else. It writes the camera's
|
|
85039
|
+
* EFFECTIVE motion (`addon-pipeline-orchestrator`
|
|
85040
|
+
* `camera-sensors/motion-slice.ts`), alongside the effective
|
|
85041
|
+
* `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
|
|
85042
|
+
* for a split camera, an unsplit emitter's direct event, the analyzer and
|
|
85043
|
+
* device activity, as the camera's `motionSources` counts them. A source
|
|
85044
|
+
* that never sends a clear falls one window after its last `true`.
|
|
85045
|
+
* `lastDetectedAt` moves only on an effective rise. No camera provider
|
|
85046
|
+
* writes this slice (not even a boot seed), and neither does the runner's
|
|
85047
|
+
* phase machine: its phase is "a session is attached" for every on-motion
|
|
85048
|
+
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
85049
|
+
* A provider's `isDetected` answers from the hub's slice.
|
|
85050
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
85051
|
+
* imports) — the provider pushes both edges itself, from the upstream
|
|
85052
|
+
* system's own state change. That is the sensor's own fact.
|
|
85053
|
+
*
|
|
85054
|
+
* `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
|
|
85055
|
+
* `motion` slice; each sensor writer is a named exemption.
|
|
85056
|
+
*
|
|
85057
|
+
* This replaces the D475 §4 rule ("the phase machine is the sole writer").
|
|
85058
|
+
* That rule was never true: Hikvision and Amcrest wrote the slice raw beside
|
|
85059
|
+
* it, every provider seeded it at boot, and every session left it
|
|
85060
|
+
* `detected: true` after its detach.
|
|
85008
85061
|
*/
|
|
85009
85062
|
autoClearAfterMs: number().nullable()
|
|
85010
85063
|
});
|
|
@@ -85076,11 +85129,12 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
85076
85129
|
*/
|
|
85077
85130
|
runtimeState: MotionStatusSchema,
|
|
85078
85131
|
/**
|
|
85079
|
-
* Runtime-state durability: **session** —
|
|
85132
|
+
* Runtime-state durability: **session** — the writer of this slice
|
|
85080
85133
|
* writes only on an EDGE, so a restored `detected: true` would stay
|
|
85081
85134
|
* frozen until the next one instead of being corrected. The next edge
|
|
85082
|
-
* re-publishes the real state
|
|
85083
|
-
*
|
|
85135
|
+
* re-publishes the real state, and the orchestrator re-publishes every
|
|
85136
|
+
* camera when it starts writing (D696; on who writes it, see
|
|
85137
|
+
* `autoClearAfterMs` above).
|
|
85084
85138
|
*
|
|
85085
85139
|
* See `RuntimeStateDurability`. Enforced by
|
|
85086
85140
|
* `scripts/check-runtime-state-durability.ts`.
|
|
@@ -87611,8 +87665,7 @@ var ptzAutotrackCapability = {
|
|
|
87611
87665
|
deviceNative: true,
|
|
87612
87666
|
mode: "singleton",
|
|
87613
87667
|
/**
|
|
87614
|
-
* Two kinds of provider behind one name, the same shape `snapshot`
|
|
87615
|
-
* `doorbell` use:
|
|
87668
|
+
* Two kinds of provider behind one name, the same shape `snapshot` uses:
|
|
87616
87669
|
*
|
|
87617
87670
|
* - **Native**: the camera's own firmware autotrack, registered per device by
|
|
87618
87671
|
* the driver when the probe says it exists (Reolink: yes; Hikvision:
|
|
@@ -87620,7 +87673,7 @@ var ptzAutotrackCapability = {
|
|
|
87620
87673
|
* - **Wrapper**: the emulated implementation (`@camstack/system`'s `autotrack` builtin),
|
|
87621
87674
|
* which follows a subject with `ptz.move` pulses driven by the detection
|
|
87622
87675
|
* pipeline. `defaultActive: false` — the operator binds it per camera in
|
|
87623
|
-
* the bindings UI
|
|
87676
|
+
* the bindings UI.
|
|
87624
87677
|
*
|
|
87625
87678
|
* The binding chooses WHICH implementation answers; `setEnabled` stays the
|
|
87626
87679
|
* one switch for the function either way. A camera never has both driving its
|
|
@@ -88295,7 +88348,7 @@ var ReadGopBytesResultSchema = object({
|
|
|
88295
88348
|
/**
|
|
88296
88349
|
* A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
|
|
88297
88350
|
* twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
|
|
88298
|
-
* replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-
|
|
88351
|
+
* replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
|
|
88299
88352
|
* a replay needs several seconds of native pixels, not one frame.
|
|
88300
88353
|
*
|
|
88301
88354
|
* `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
|
|
@@ -91659,6 +91712,7 @@ var zoneRulesCapability = {
|
|
|
91659
91712
|
*/
|
|
91660
91713
|
durability: "restored"
|
|
91661
91714
|
};
|
|
91715
|
+
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
91662
91716
|
/**
|
|
91663
91717
|
* Accessory device helpers — shared across drivers.
|
|
91664
91718
|
*
|
|
@@ -92718,13 +92772,14 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
92718
92772
|
async getStatus() {
|
|
92719
92773
|
const all = await this.ctx.kernel.devices?.getAll() ?? [];
|
|
92720
92774
|
const summary = this.restoreFailureSummary();
|
|
92721
|
-
|
|
92775
|
+
const base = {
|
|
92722
92776
|
connected: true,
|
|
92723
|
-
deviceCount: all.length
|
|
92777
|
+
deviceCount: all.length,
|
|
92778
|
+
motionSliceWriter: "orchestrator"
|
|
92724
92779
|
};
|
|
92780
|
+
if (summary === null) return base;
|
|
92725
92781
|
return {
|
|
92726
|
-
|
|
92727
|
-
deviceCount: all.length,
|
|
92782
|
+
...base,
|
|
92728
92783
|
error: summary
|
|
92729
92784
|
};
|
|
92730
92785
|
}
|
|
@@ -98160,6 +98215,12 @@ Object.freeze({
|
|
|
98160
98215
|
addonId: null,
|
|
98161
98216
|
access: "view"
|
|
98162
98217
|
},
|
|
98218
|
+
"notificationRules.getAlarmSensors": {
|
|
98219
|
+
capName: "notification-rules",
|
|
98220
|
+
capScope: "system",
|
|
98221
|
+
addonId: null,
|
|
98222
|
+
access: "view"
|
|
98223
|
+
},
|
|
98163
98224
|
"notificationRules.getClipRetentionAsks": {
|
|
98164
98225
|
capName: "notification-rules",
|
|
98165
98226
|
capScope: "system",
|
|
@@ -101738,6 +101799,11 @@ Object.freeze({
|
|
|
101738
101799
|
}
|
|
101739
101800
|
});
|
|
101740
101801
|
Object.freeze({
|
|
101802
|
+
"accessories.getStatus": [{
|
|
101803
|
+
name: "deviceId",
|
|
101804
|
+
form: "single",
|
|
101805
|
+
optional: false
|
|
101806
|
+
}],
|
|
101741
101807
|
"accessories.setChildHidden": [{
|
|
101742
101808
|
name: "childDeviceId",
|
|
101743
101809
|
form: "single",
|
|
@@ -101757,6 +101823,11 @@ Object.freeze({
|
|
|
101757
101823
|
form: "single",
|
|
101758
101824
|
optional: false
|
|
101759
101825
|
}],
|
|
101826
|
+
"airQualitySensor.getStatus": [{
|
|
101827
|
+
name: "deviceId",
|
|
101828
|
+
form: "single",
|
|
101829
|
+
optional: false
|
|
101830
|
+
}],
|
|
101760
101831
|
"alarmPanel.arm": [{
|
|
101761
101832
|
name: "deviceId",
|
|
101762
101833
|
form: "single",
|
|
@@ -101767,11 +101838,36 @@ Object.freeze({
|
|
|
101767
101838
|
form: "single",
|
|
101768
101839
|
optional: false
|
|
101769
101840
|
}],
|
|
101841
|
+
"alarmPanel.getStatus": [{
|
|
101842
|
+
name: "deviceId",
|
|
101843
|
+
form: "single",
|
|
101844
|
+
optional: false
|
|
101845
|
+
}],
|
|
101770
101846
|
"alarmPanel.trigger": [{
|
|
101771
101847
|
name: "deviceId",
|
|
101772
101848
|
form: "single",
|
|
101773
101849
|
optional: false
|
|
101774
101850
|
}],
|
|
101851
|
+
"ambientLightSensor.getStatus": [{
|
|
101852
|
+
name: "deviceId",
|
|
101853
|
+
form: "single",
|
|
101854
|
+
optional: false
|
|
101855
|
+
}],
|
|
101856
|
+
"audioAnalysis.applyDeviceSettingsPatch": [{
|
|
101857
|
+
name: "deviceId",
|
|
101858
|
+
form: "single",
|
|
101859
|
+
optional: false
|
|
101860
|
+
}],
|
|
101861
|
+
"audioAnalysis.getDeviceLiveContribution": [{
|
|
101862
|
+
name: "deviceId",
|
|
101863
|
+
form: "single",
|
|
101864
|
+
optional: false
|
|
101865
|
+
}],
|
|
101866
|
+
"audioAnalysis.getDeviceSettingsContribution": [{
|
|
101867
|
+
name: "deviceId",
|
|
101868
|
+
form: "single",
|
|
101869
|
+
optional: false
|
|
101870
|
+
}],
|
|
101775
101871
|
"audioAnalysis.resolveDeviceSettings": [{
|
|
101776
101872
|
name: "deviceId",
|
|
101777
101873
|
form: "single",
|
|
@@ -101812,16 +101908,36 @@ Object.freeze({
|
|
|
101812
101908
|
form: "single",
|
|
101813
101909
|
optional: false
|
|
101814
101910
|
}],
|
|
101911
|
+
"automationControl.getStatus": [{
|
|
101912
|
+
name: "deviceId",
|
|
101913
|
+
form: "single",
|
|
101914
|
+
optional: false
|
|
101915
|
+
}],
|
|
101815
101916
|
"automationControl.trigger": [{
|
|
101816
101917
|
name: "deviceId",
|
|
101817
101918
|
form: "single",
|
|
101818
101919
|
optional: false
|
|
101819
101920
|
}],
|
|
101921
|
+
"battery.getStatus": [{
|
|
101922
|
+
name: "deviceId",
|
|
101923
|
+
form: "single",
|
|
101924
|
+
optional: false
|
|
101925
|
+
}],
|
|
101820
101926
|
"battery.wakeForStream": [{
|
|
101821
101927
|
name: "deviceId",
|
|
101822
101928
|
form: "single",
|
|
101823
101929
|
optional: false
|
|
101824
101930
|
}],
|
|
101931
|
+
"binary.getStatus": [{
|
|
101932
|
+
name: "deviceId",
|
|
101933
|
+
form: "single",
|
|
101934
|
+
optional: false
|
|
101935
|
+
}],
|
|
101936
|
+
"brightness.getStatus": [{
|
|
101937
|
+
name: "deviceId",
|
|
101938
|
+
form: "single",
|
|
101939
|
+
optional: false
|
|
101940
|
+
}],
|
|
101825
101941
|
"brightness.setBrightness": [{
|
|
101826
101942
|
name: "deviceId",
|
|
101827
101943
|
form: "single",
|
|
@@ -101837,6 +101953,26 @@ Object.freeze({
|
|
|
101837
101953
|
form: "single",
|
|
101838
101954
|
optional: false
|
|
101839
101955
|
}],
|
|
101956
|
+
"cameraCredentials.getStatus": [{
|
|
101957
|
+
name: "deviceId",
|
|
101958
|
+
form: "single",
|
|
101959
|
+
optional: false
|
|
101960
|
+
}],
|
|
101961
|
+
"cameraGridLayout.applyDeviceSettingsPatch": [{
|
|
101962
|
+
name: "deviceId",
|
|
101963
|
+
form: "single",
|
|
101964
|
+
optional: false
|
|
101965
|
+
}],
|
|
101966
|
+
"cameraGridLayout.getDeviceLiveContribution": [{
|
|
101967
|
+
name: "deviceId",
|
|
101968
|
+
form: "single",
|
|
101969
|
+
optional: false
|
|
101970
|
+
}],
|
|
101971
|
+
"cameraGridLayout.getDeviceSettingsContribution": [{
|
|
101972
|
+
name: "deviceId",
|
|
101973
|
+
form: "single",
|
|
101974
|
+
optional: false
|
|
101975
|
+
}],
|
|
101840
101976
|
"cameraGridLayout.getLayout": [{
|
|
101841
101977
|
name: "deviceId",
|
|
101842
101978
|
form: "single",
|
|
@@ -101852,6 +101988,21 @@ Object.freeze({
|
|
|
101852
101988
|
form: "single",
|
|
101853
101989
|
optional: false
|
|
101854
101990
|
}],
|
|
101991
|
+
"cameraPipelineConfig.applyDeviceSettingsPatch": [{
|
|
101992
|
+
name: "deviceId",
|
|
101993
|
+
form: "single",
|
|
101994
|
+
optional: false
|
|
101995
|
+
}],
|
|
101996
|
+
"cameraPipelineConfig.getDeviceLiveContribution": [{
|
|
101997
|
+
name: "deviceId",
|
|
101998
|
+
form: "single",
|
|
101999
|
+
optional: false
|
|
102000
|
+
}],
|
|
102001
|
+
"cameraPipelineConfig.getDeviceSettingsContribution": [{
|
|
102002
|
+
name: "deviceId",
|
|
102003
|
+
form: "single",
|
|
102004
|
+
optional: false
|
|
102005
|
+
}],
|
|
101855
102006
|
"cameraStreams.getBrokerStreams": [{
|
|
101856
102007
|
name: "deviceId",
|
|
101857
102008
|
form: "single",
|
|
@@ -101877,6 +102028,16 @@ Object.freeze({
|
|
|
101877
102028
|
form: "single",
|
|
101878
102029
|
optional: false
|
|
101879
102030
|
}],
|
|
102031
|
+
"carbonMonoxide.getStatus": [{
|
|
102032
|
+
name: "deviceId",
|
|
102033
|
+
form: "single",
|
|
102034
|
+
optional: false
|
|
102035
|
+
}],
|
|
102036
|
+
"climateControl.getStatus": [{
|
|
102037
|
+
name: "deviceId",
|
|
102038
|
+
form: "single",
|
|
102039
|
+
optional: false
|
|
102040
|
+
}],
|
|
101880
102041
|
"climateControl.setFanMode": [{
|
|
101881
102042
|
name: "deviceId",
|
|
101882
102043
|
form: "single",
|
|
@@ -101917,16 +102078,41 @@ Object.freeze({
|
|
|
101917
102078
|
form: "single",
|
|
101918
102079
|
optional: false
|
|
101919
102080
|
}],
|
|
102081
|
+
"color.getStatus": [{
|
|
102082
|
+
name: "deviceId",
|
|
102083
|
+
form: "single",
|
|
102084
|
+
optional: false
|
|
102085
|
+
}],
|
|
101920
102086
|
"color.setColor": [{
|
|
101921
102087
|
name: "deviceId",
|
|
101922
102088
|
form: "single",
|
|
101923
102089
|
optional: false
|
|
101924
102090
|
}],
|
|
102091
|
+
"connectivity.getStatus": [{
|
|
102092
|
+
name: "deviceId",
|
|
102093
|
+
form: "single",
|
|
102094
|
+
optional: false
|
|
102095
|
+
}],
|
|
102096
|
+
"consumables.getStatus": [{
|
|
102097
|
+
name: "deviceId",
|
|
102098
|
+
form: "single",
|
|
102099
|
+
optional: false
|
|
102100
|
+
}],
|
|
101925
102101
|
"consumables.reset": [{
|
|
101926
102102
|
name: "deviceId",
|
|
101927
102103
|
form: "single",
|
|
101928
102104
|
optional: false
|
|
101929
102105
|
}],
|
|
102106
|
+
"contact.getStatus": [{
|
|
102107
|
+
name: "deviceId",
|
|
102108
|
+
form: "single",
|
|
102109
|
+
optional: false
|
|
102110
|
+
}],
|
|
102111
|
+
"control.getStatus": [{
|
|
102112
|
+
name: "deviceId",
|
|
102113
|
+
form: "single",
|
|
102114
|
+
optional: false
|
|
102115
|
+
}],
|
|
101930
102116
|
"control.setValue": [{
|
|
101931
102117
|
name: "deviceId",
|
|
101932
102118
|
form: "single",
|
|
@@ -101937,6 +102123,11 @@ Object.freeze({
|
|
|
101937
102123
|
form: "single",
|
|
101938
102124
|
optional: false
|
|
101939
102125
|
}],
|
|
102126
|
+
"cover.getStatus": [{
|
|
102127
|
+
name: "deviceId",
|
|
102128
|
+
form: "single",
|
|
102129
|
+
optional: false
|
|
102130
|
+
}],
|
|
101940
102131
|
"cover.open": [{
|
|
101941
102132
|
name: "deviceId",
|
|
101942
102133
|
form: "single",
|
|
@@ -101962,6 +102153,11 @@ Object.freeze({
|
|
|
101962
102153
|
form: "single",
|
|
101963
102154
|
optional: false
|
|
101964
102155
|
}],
|
|
102156
|
+
"dayNight.getStatus": [{
|
|
102157
|
+
name: "deviceId",
|
|
102158
|
+
form: "single",
|
|
102159
|
+
optional: false
|
|
102160
|
+
}],
|
|
101965
102161
|
"dayNight.setSettings": [{
|
|
101966
102162
|
name: "deviceId",
|
|
101967
102163
|
form: "single",
|
|
@@ -101972,11 +102168,31 @@ Object.freeze({
|
|
|
101972
102168
|
form: "single",
|
|
101973
102169
|
optional: true
|
|
101974
102170
|
}],
|
|
102171
|
+
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
102172
|
+
name: "deviceId",
|
|
102173
|
+
form: "single",
|
|
102174
|
+
optional: false
|
|
102175
|
+
}],
|
|
102176
|
+
"detectionPipeline.getDeviceLiveContribution": [{
|
|
102177
|
+
name: "deviceId",
|
|
102178
|
+
form: "single",
|
|
102179
|
+
optional: false
|
|
102180
|
+
}],
|
|
102181
|
+
"detectionPipeline.getDeviceSettingsContribution": [{
|
|
102182
|
+
name: "deviceId",
|
|
102183
|
+
form: "single",
|
|
102184
|
+
optional: false
|
|
102185
|
+
}],
|
|
101975
102186
|
"deviceAdminLink.getAdminLink": [{
|
|
101976
102187
|
name: "deviceId",
|
|
101977
102188
|
form: "single",
|
|
101978
102189
|
optional: false
|
|
101979
102190
|
}],
|
|
102191
|
+
"deviceAdoption.getStatus": [{
|
|
102192
|
+
name: "deviceId",
|
|
102193
|
+
form: "single",
|
|
102194
|
+
optional: false
|
|
102195
|
+
}],
|
|
101980
102196
|
"deviceAdoption.release": [{
|
|
101981
102197
|
name: "camDeviceId",
|
|
101982
102198
|
form: "single",
|
|
@@ -101992,6 +102208,11 @@ Object.freeze({
|
|
|
101992
102208
|
form: "single",
|
|
101993
102209
|
optional: false
|
|
101994
102210
|
}],
|
|
102211
|
+
"deviceDiscovery.getStatus": [{
|
|
102212
|
+
name: "deviceId",
|
|
102213
|
+
form: "single",
|
|
102214
|
+
optional: false
|
|
102215
|
+
}],
|
|
101995
102216
|
"deviceDiscovery.listDiscovered": [{
|
|
101996
102217
|
name: "deviceId",
|
|
101997
102218
|
form: "single",
|
|
@@ -102011,6 +102232,21 @@ Object.freeze({
|
|
|
102011
102232
|
form: "single",
|
|
102012
102233
|
optional: false
|
|
102013
102234
|
}],
|
|
102235
|
+
"deviceExport.applyDeviceSettingsPatch": [{
|
|
102236
|
+
name: "deviceId",
|
|
102237
|
+
form: "single",
|
|
102238
|
+
optional: false
|
|
102239
|
+
}],
|
|
102240
|
+
"deviceExport.getDeviceLiveContribution": [{
|
|
102241
|
+
name: "deviceId",
|
|
102242
|
+
form: "single",
|
|
102243
|
+
optional: false
|
|
102244
|
+
}],
|
|
102245
|
+
"deviceExport.getDeviceSettingsContribution": [{
|
|
102246
|
+
name: "deviceId",
|
|
102247
|
+
form: "single",
|
|
102248
|
+
optional: false
|
|
102249
|
+
}],
|
|
102014
102250
|
"deviceExtension.listCandidates": [{
|
|
102015
102251
|
name: "deviceId",
|
|
102016
102252
|
form: "single",
|
|
@@ -102359,6 +102595,26 @@ Object.freeze({
|
|
|
102359
102595
|
form: "single",
|
|
102360
102596
|
optional: false
|
|
102361
102597
|
}],
|
|
102598
|
+
"deviceStatus.getStatus": [{
|
|
102599
|
+
name: "deviceId",
|
|
102600
|
+
form: "single",
|
|
102601
|
+
optional: false
|
|
102602
|
+
}],
|
|
102603
|
+
"doorbell.getStatus": [{
|
|
102604
|
+
name: "deviceId",
|
|
102605
|
+
form: "single",
|
|
102606
|
+
optional: false
|
|
102607
|
+
}],
|
|
102608
|
+
"enumSensor.getStatus": [{
|
|
102609
|
+
name: "deviceId",
|
|
102610
|
+
form: "single",
|
|
102611
|
+
optional: false
|
|
102612
|
+
}],
|
|
102613
|
+
"eventEmitter.getStatus": [{
|
|
102614
|
+
name: "deviceId",
|
|
102615
|
+
form: "single",
|
|
102616
|
+
optional: false
|
|
102617
|
+
}],
|
|
102362
102618
|
"faceGallery.getFaceByTrack": [{
|
|
102363
102619
|
name: "deviceId",
|
|
102364
102620
|
form: "single",
|
|
@@ -102373,6 +102629,11 @@ Object.freeze({
|
|
|
102373
102629
|
form: "array",
|
|
102374
102630
|
optional: true
|
|
102375
102631
|
}],
|
|
102632
|
+
"fanControl.getStatus": [{
|
|
102633
|
+
name: "deviceId",
|
|
102634
|
+
form: "single",
|
|
102635
|
+
optional: false
|
|
102636
|
+
}],
|
|
102376
102637
|
"fanControl.setDirection": [{
|
|
102377
102638
|
name: "deviceId",
|
|
102378
102639
|
form: "single",
|
|
@@ -102393,6 +102654,26 @@ Object.freeze({
|
|
|
102393
102654
|
form: "single",
|
|
102394
102655
|
optional: false
|
|
102395
102656
|
}],
|
|
102657
|
+
"featureProbe.getStatus": [{
|
|
102658
|
+
name: "deviceId",
|
|
102659
|
+
form: "single",
|
|
102660
|
+
optional: false
|
|
102661
|
+
}],
|
|
102662
|
+
"flood.getStatus": [{
|
|
102663
|
+
name: "deviceId",
|
|
102664
|
+
form: "single",
|
|
102665
|
+
optional: false
|
|
102666
|
+
}],
|
|
102667
|
+
"gas.getStatus": [{
|
|
102668
|
+
name: "deviceId",
|
|
102669
|
+
form: "single",
|
|
102670
|
+
optional: false
|
|
102671
|
+
}],
|
|
102672
|
+
"humidifier.getStatus": [{
|
|
102673
|
+
name: "deviceId",
|
|
102674
|
+
form: "single",
|
|
102675
|
+
optional: false
|
|
102676
|
+
}],
|
|
102396
102677
|
"humidifier.setMode": [{
|
|
102397
102678
|
name: "deviceId",
|
|
102398
102679
|
form: "single",
|
|
@@ -102408,11 +102689,26 @@ Object.freeze({
|
|
|
102408
102689
|
form: "single",
|
|
102409
102690
|
optional: false
|
|
102410
102691
|
}],
|
|
102692
|
+
"humiditySensor.getStatus": [{
|
|
102693
|
+
name: "deviceId",
|
|
102694
|
+
form: "single",
|
|
102695
|
+
optional: false
|
|
102696
|
+
}],
|
|
102697
|
+
"image.getStatus": [{
|
|
102698
|
+
name: "deviceId",
|
|
102699
|
+
form: "single",
|
|
102700
|
+
optional: false
|
|
102701
|
+
}],
|
|
102411
102702
|
"imageSettings.getOptions": [{
|
|
102412
102703
|
name: "deviceId",
|
|
102413
102704
|
form: "single",
|
|
102414
102705
|
optional: false
|
|
102415
102706
|
}],
|
|
102707
|
+
"imageSettings.getStatus": [{
|
|
102708
|
+
name: "deviceId",
|
|
102709
|
+
form: "single",
|
|
102710
|
+
optional: false
|
|
102711
|
+
}],
|
|
102416
102712
|
"imageSettings.setSettings": [{
|
|
102417
102713
|
name: "deviceId",
|
|
102418
102714
|
form: "single",
|
|
@@ -102423,6 +102719,11 @@ Object.freeze({
|
|
|
102423
102719
|
form: "single",
|
|
102424
102720
|
optional: false
|
|
102425
102721
|
}],
|
|
102722
|
+
"intercom.getStatus": [{
|
|
102723
|
+
name: "deviceId",
|
|
102724
|
+
form: "single",
|
|
102725
|
+
optional: false
|
|
102726
|
+
}],
|
|
102426
102727
|
"intercom.handleAnswer": [{
|
|
102427
102728
|
name: "deviceId",
|
|
102428
102729
|
form: "single",
|
|
@@ -102453,6 +102754,11 @@ Object.freeze({
|
|
|
102453
102754
|
form: "single",
|
|
102454
102755
|
optional: false
|
|
102455
102756
|
}],
|
|
102757
|
+
"lawnMowerControl.getStatus": [{
|
|
102758
|
+
name: "deviceId",
|
|
102759
|
+
form: "single",
|
|
102760
|
+
optional: false
|
|
102761
|
+
}],
|
|
102456
102762
|
"lawnMowerControl.pause": [{
|
|
102457
102763
|
name: "deviceId",
|
|
102458
102764
|
form: "single",
|
|
@@ -102463,6 +102769,11 @@ Object.freeze({
|
|
|
102463
102769
|
form: "single",
|
|
102464
102770
|
optional: false
|
|
102465
102771
|
}],
|
|
102772
|
+
"lockControl.getStatus": [{
|
|
102773
|
+
name: "deviceId",
|
|
102774
|
+
form: "single",
|
|
102775
|
+
optional: false
|
|
102776
|
+
}],
|
|
102466
102777
|
"lockControl.lock": [{
|
|
102467
102778
|
name: "deviceId",
|
|
102468
102779
|
form: "single",
|
|
@@ -102478,6 +102789,11 @@ Object.freeze({
|
|
|
102478
102789
|
form: "single",
|
|
102479
102790
|
optional: false
|
|
102480
102791
|
}],
|
|
102792
|
+
"mediaPlayer.getStatus": [{
|
|
102793
|
+
name: "deviceId",
|
|
102794
|
+
form: "single",
|
|
102795
|
+
optional: false
|
|
102796
|
+
}],
|
|
102481
102797
|
"mediaPlayer.next": [{
|
|
102482
102798
|
name: "deviceId",
|
|
102483
102799
|
form: "single",
|
|
@@ -102538,6 +102854,11 @@ Object.freeze({
|
|
|
102538
102854
|
form: "single",
|
|
102539
102855
|
optional: false
|
|
102540
102856
|
}],
|
|
102857
|
+
"motion.getStatus": [{
|
|
102858
|
+
name: "deviceId",
|
|
102859
|
+
form: "single",
|
|
102860
|
+
optional: false
|
|
102861
|
+
}],
|
|
102541
102862
|
"motion.isDetected": [{
|
|
102542
102863
|
name: "deviceId",
|
|
102543
102864
|
form: "single",
|
|
@@ -102548,11 +102869,31 @@ Object.freeze({
|
|
|
102548
102869
|
form: "single",
|
|
102549
102870
|
optional: false
|
|
102550
102871
|
}],
|
|
102872
|
+
"motionDetection.applyDeviceSettingsPatch": [{
|
|
102873
|
+
name: "deviceId",
|
|
102874
|
+
form: "single",
|
|
102875
|
+
optional: false
|
|
102876
|
+
}],
|
|
102877
|
+
"motionDetection.getDeviceLiveContribution": [{
|
|
102878
|
+
name: "deviceId",
|
|
102879
|
+
form: "single",
|
|
102880
|
+
optional: false
|
|
102881
|
+
}],
|
|
102882
|
+
"motionDetection.getDeviceSettingsContribution": [{
|
|
102883
|
+
name: "deviceId",
|
|
102884
|
+
form: "single",
|
|
102885
|
+
optional: false
|
|
102886
|
+
}],
|
|
102551
102887
|
"motionDetection.removeCamera": [{
|
|
102552
102888
|
name: "deviceId",
|
|
102553
102889
|
form: "single",
|
|
102554
102890
|
optional: false
|
|
102555
102891
|
}],
|
|
102892
|
+
"motionTrigger.getStatus": [{
|
|
102893
|
+
name: "deviceId",
|
|
102894
|
+
form: "single",
|
|
102895
|
+
optional: false
|
|
102896
|
+
}],
|
|
102556
102897
|
"motionTrigger.setMotionTrigger": [{
|
|
102557
102898
|
name: "deviceId",
|
|
102558
102899
|
form: "single",
|
|
@@ -102563,6 +102904,11 @@ Object.freeze({
|
|
|
102563
102904
|
form: "single",
|
|
102564
102905
|
optional: false
|
|
102565
102906
|
}],
|
|
102907
|
+
"motionZones.getStatus": [{
|
|
102908
|
+
name: "deviceId",
|
|
102909
|
+
form: "single",
|
|
102910
|
+
optional: false
|
|
102911
|
+
}],
|
|
102566
102912
|
"motionZones.setZone": [{
|
|
102567
102913
|
name: "deviceId",
|
|
102568
102914
|
form: "single",
|
|
@@ -102573,6 +102919,11 @@ Object.freeze({
|
|
|
102573
102919
|
form: "single",
|
|
102574
102920
|
optional: false
|
|
102575
102921
|
}],
|
|
102922
|
+
"nativeObjectDetection.getStatus": [{
|
|
102923
|
+
name: "deviceId",
|
|
102924
|
+
form: "single",
|
|
102925
|
+
optional: false
|
|
102926
|
+
}],
|
|
102576
102927
|
"nativeObjectDetection.setEnabled": [{
|
|
102577
102928
|
name: "deviceId",
|
|
102578
102929
|
form: "single",
|
|
@@ -102588,6 +102939,11 @@ Object.freeze({
|
|
|
102588
102939
|
form: "single",
|
|
102589
102940
|
optional: false
|
|
102590
102941
|
}],
|
|
102942
|
+
"navigation.getStatus": [{
|
|
102943
|
+
name: "deviceId",
|
|
102944
|
+
form: "single",
|
|
102945
|
+
optional: false
|
|
102946
|
+
}],
|
|
102591
102947
|
"navigation.goToPoint": [{
|
|
102592
102948
|
name: "deviceId",
|
|
102593
102949
|
form: "single",
|
|
@@ -102633,6 +102989,11 @@ Object.freeze({
|
|
|
102633
102989
|
form: "single",
|
|
102634
102990
|
optional: false
|
|
102635
102991
|
}],
|
|
102992
|
+
"networkLink.getStatus": [{
|
|
102993
|
+
name: "deviceId",
|
|
102994
|
+
form: "single",
|
|
102995
|
+
optional: false
|
|
102996
|
+
}],
|
|
102636
102997
|
"networkQuality.getDeviceStats": [{
|
|
102637
102998
|
name: "deviceId",
|
|
102638
102999
|
form: "single",
|
|
@@ -102643,6 +103004,11 @@ Object.freeze({
|
|
|
102643
103004
|
form: "single",
|
|
102644
103005
|
optional: false
|
|
102645
103006
|
}],
|
|
103007
|
+
"notificationRules.getAlarmSensors": [{
|
|
103008
|
+
name: "deviceIds",
|
|
103009
|
+
form: "array",
|
|
103010
|
+
optional: false
|
|
103011
|
+
}],
|
|
102646
103012
|
"notificationRules.setDeviceMuted": [{
|
|
102647
103013
|
name: "deviceId",
|
|
102648
103014
|
form: "single",
|
|
@@ -102653,11 +103019,26 @@ Object.freeze({
|
|
|
102653
103019
|
form: "single",
|
|
102654
103020
|
optional: false
|
|
102655
103021
|
}],
|
|
103022
|
+
"notifier.getStatus": [{
|
|
103023
|
+
name: "deviceId",
|
|
103024
|
+
form: "single",
|
|
103025
|
+
optional: false
|
|
103026
|
+
}],
|
|
102656
103027
|
"notifier.send": [{
|
|
102657
103028
|
name: "deviceId",
|
|
102658
103029
|
form: "single",
|
|
102659
103030
|
optional: false
|
|
102660
103031
|
}],
|
|
103032
|
+
"numericSensor.getStatus": [{
|
|
103033
|
+
name: "deviceId",
|
|
103034
|
+
form: "single",
|
|
103035
|
+
optional: false
|
|
103036
|
+
}],
|
|
103037
|
+
"osd.getStatus": [{
|
|
103038
|
+
name: "deviceId",
|
|
103039
|
+
form: "single",
|
|
103040
|
+
optional: false
|
|
103041
|
+
}],
|
|
102661
103042
|
"osd.setOverlay": [{
|
|
102662
103043
|
name: "deviceId",
|
|
102663
103044
|
form: "single",
|
|
@@ -102717,6 +103098,11 @@ Object.freeze({
|
|
|
102717
103098
|
form: "single",
|
|
102718
103099
|
optional: false
|
|
102719
103100
|
}],
|
|
103101
|
+
"petFeeder.getStatus": [{
|
|
103102
|
+
name: "deviceId",
|
|
103103
|
+
form: "single",
|
|
103104
|
+
optional: false
|
|
103105
|
+
}],
|
|
102720
103106
|
"petFeeder.markFoodReplenished": [{
|
|
102721
103107
|
name: "deviceId",
|
|
102722
103108
|
form: "single",
|
|
@@ -102752,6 +103138,11 @@ Object.freeze({
|
|
|
102752
103138
|
form: "single",
|
|
102753
103139
|
optional: false
|
|
102754
103140
|
}],
|
|
103141
|
+
"pipelineAnalytics.applyDeviceSettingsPatch": [{
|
|
103142
|
+
name: "deviceId",
|
|
103143
|
+
form: "single",
|
|
103144
|
+
optional: false
|
|
103145
|
+
}],
|
|
102755
103146
|
"pipelineAnalytics.clearTrackRelation": [{
|
|
102756
103147
|
name: "deviceId",
|
|
102757
103148
|
form: "single",
|
|
@@ -102792,6 +103183,16 @@ Object.freeze({
|
|
|
102792
103183
|
form: "single",
|
|
102793
103184
|
optional: false
|
|
102794
103185
|
}],
|
|
103186
|
+
"pipelineAnalytics.getDeviceLiveContribution": [{
|
|
103187
|
+
name: "deviceId",
|
|
103188
|
+
form: "single",
|
|
103189
|
+
optional: false
|
|
103190
|
+
}],
|
|
103191
|
+
"pipelineAnalytics.getDeviceSettingsContribution": [{
|
|
103192
|
+
name: "deviceId",
|
|
103193
|
+
form: "single",
|
|
103194
|
+
optional: false
|
|
103195
|
+
}],
|
|
102795
103196
|
"pipelineAnalytics.getEventDensity": [{
|
|
102796
103197
|
name: "deviceId",
|
|
102797
103198
|
form: "single",
|
|
@@ -103007,6 +103408,11 @@ Object.freeze({
|
|
|
103007
103408
|
form: "single",
|
|
103008
103409
|
optional: true
|
|
103009
103410
|
}],
|
|
103411
|
+
"pipelineOrchestrator.applyDeviceSettingsPatch": [{
|
|
103412
|
+
name: "deviceId",
|
|
103413
|
+
form: "single",
|
|
103414
|
+
optional: false
|
|
103415
|
+
}],
|
|
103010
103416
|
"pipelineOrchestrator.assignAudio": [{
|
|
103011
103417
|
name: "deviceId",
|
|
103012
103418
|
form: "single",
|
|
@@ -103052,6 +103458,16 @@ Object.freeze({
|
|
|
103052
103458
|
form: "single",
|
|
103053
103459
|
optional: false
|
|
103054
103460
|
}],
|
|
103461
|
+
"pipelineOrchestrator.getDeviceLiveContribution": [{
|
|
103462
|
+
name: "deviceId",
|
|
103463
|
+
form: "single",
|
|
103464
|
+
optional: false
|
|
103465
|
+
}],
|
|
103466
|
+
"pipelineOrchestrator.getDeviceSettingsContribution": [{
|
|
103467
|
+
name: "deviceId",
|
|
103468
|
+
form: "single",
|
|
103469
|
+
optional: false
|
|
103470
|
+
}],
|
|
103055
103471
|
"pipelineOrchestrator.getPipelineAssignment": [{
|
|
103056
103472
|
name: "deviceId",
|
|
103057
103473
|
form: "single",
|
|
@@ -103172,11 +103588,31 @@ Object.freeze({
|
|
|
103172
103588
|
form: "single",
|
|
103173
103589
|
optional: true
|
|
103174
103590
|
}],
|
|
103591
|
+
"powerMeter.getStatus": [{
|
|
103592
|
+
name: "deviceId",
|
|
103593
|
+
form: "single",
|
|
103594
|
+
optional: false
|
|
103595
|
+
}],
|
|
103596
|
+
"presence.getStatus": [{
|
|
103597
|
+
name: "deviceId",
|
|
103598
|
+
form: "single",
|
|
103599
|
+
optional: false
|
|
103600
|
+
}],
|
|
103601
|
+
"pressureSensor.getStatus": [{
|
|
103602
|
+
name: "deviceId",
|
|
103603
|
+
form: "single",
|
|
103604
|
+
optional: false
|
|
103605
|
+
}],
|
|
103175
103606
|
"privacyMask.getOptions": [{
|
|
103176
103607
|
name: "deviceId",
|
|
103177
103608
|
form: "single",
|
|
103178
103609
|
optional: false
|
|
103179
103610
|
}],
|
|
103611
|
+
"privacyMask.getStatus": [{
|
|
103612
|
+
name: "deviceId",
|
|
103613
|
+
form: "single",
|
|
103614
|
+
optional: false
|
|
103615
|
+
}],
|
|
103180
103616
|
"privacyMask.setAudioEnabled": [{
|
|
103181
103617
|
name: "deviceId",
|
|
103182
103618
|
form: "single",
|
|
@@ -103227,6 +103663,11 @@ Object.freeze({
|
|
|
103227
103663
|
form: "single",
|
|
103228
103664
|
optional: false
|
|
103229
103665
|
}],
|
|
103666
|
+
"ptz.getStatus": [{
|
|
103667
|
+
name: "deviceId",
|
|
103668
|
+
form: "single",
|
|
103669
|
+
optional: false
|
|
103670
|
+
}],
|
|
103230
103671
|
"ptz.goHome": [{
|
|
103231
103672
|
name: "deviceId",
|
|
103232
103673
|
form: "single",
|
|
@@ -103317,6 +103758,11 @@ Object.freeze({
|
|
|
103317
103758
|
form: "single",
|
|
103318
103759
|
optional: false
|
|
103319
103760
|
}],
|
|
103761
|
+
"recordingArchive.applyDeviceSettingsPatch": [{
|
|
103762
|
+
name: "deviceId",
|
|
103763
|
+
form: "single",
|
|
103764
|
+
optional: false
|
|
103765
|
+
}],
|
|
103320
103766
|
"recordingArchive.deleteFootprint": [{
|
|
103321
103767
|
name: "deviceId",
|
|
103322
103768
|
form: "single",
|
|
@@ -103337,6 +103783,21 @@ Object.freeze({
|
|
|
103337
103783
|
form: "single",
|
|
103338
103784
|
optional: false
|
|
103339
103785
|
}],
|
|
103786
|
+
"recordingArchive.getDeviceLiveContribution": [{
|
|
103787
|
+
name: "deviceId",
|
|
103788
|
+
form: "single",
|
|
103789
|
+
optional: false
|
|
103790
|
+
}],
|
|
103791
|
+
"recordingArchive.getDeviceSettingsContribution": [{
|
|
103792
|
+
name: "deviceId",
|
|
103793
|
+
form: "single",
|
|
103794
|
+
optional: false
|
|
103795
|
+
}],
|
|
103796
|
+
"recordingArchive.getStatus": [{
|
|
103797
|
+
name: "deviceId",
|
|
103798
|
+
form: "single",
|
|
103799
|
+
optional: false
|
|
103800
|
+
}],
|
|
103340
103801
|
"recordingArchive.listOpsLog": [{
|
|
103341
103802
|
name: "deviceId",
|
|
103342
103803
|
form: "single",
|
|
@@ -103422,6 +103883,11 @@ Object.freeze({
|
|
|
103422
103883
|
form: "single",
|
|
103423
103884
|
optional: false
|
|
103424
103885
|
}],
|
|
103886
|
+
"recordingOnboard.getStatus": [{
|
|
103887
|
+
name: "deviceId",
|
|
103888
|
+
form: "single",
|
|
103889
|
+
optional: false
|
|
103890
|
+
}],
|
|
103425
103891
|
"recordingOnboard.setSettings": [{
|
|
103426
103892
|
name: "deviceId",
|
|
103427
103893
|
form: "single",
|
|
@@ -103452,6 +103918,11 @@ Object.freeze({
|
|
|
103452
103918
|
form: "single",
|
|
103453
103919
|
optional: false
|
|
103454
103920
|
}],
|
|
103921
|
+
"sceneMonitor.getStatus": [{
|
|
103922
|
+
name: "deviceId",
|
|
103923
|
+
form: "single",
|
|
103924
|
+
optional: false
|
|
103925
|
+
}],
|
|
103455
103926
|
"sceneMonitor.listScenes": [{
|
|
103456
103927
|
name: "deviceId",
|
|
103457
103928
|
form: "single",
|
|
@@ -103477,6 +103948,11 @@ Object.freeze({
|
|
|
103477
103948
|
form: "single",
|
|
103478
103949
|
optional: false
|
|
103479
103950
|
}],
|
|
103951
|
+
"scriptRunner.getStatus": [{
|
|
103952
|
+
name: "deviceId",
|
|
103953
|
+
form: "single",
|
|
103954
|
+
optional: false
|
|
103955
|
+
}],
|
|
103480
103956
|
"scriptRunner.run": [{
|
|
103481
103957
|
name: "deviceId",
|
|
103482
103958
|
form: "single",
|
|
@@ -103487,11 +103963,31 @@ Object.freeze({
|
|
|
103487
103963
|
form: "single",
|
|
103488
103964
|
optional: false
|
|
103489
103965
|
}],
|
|
103966
|
+
"smoke.getStatus": [{
|
|
103967
|
+
name: "deviceId",
|
|
103968
|
+
form: "single",
|
|
103969
|
+
optional: false
|
|
103970
|
+
}],
|
|
103971
|
+
"snapshot.applyDeviceSettingsPatch": [{
|
|
103972
|
+
name: "deviceId",
|
|
103973
|
+
form: "single",
|
|
103974
|
+
optional: false
|
|
103975
|
+
}],
|
|
103490
103976
|
"snapshot.getDebugState": [{
|
|
103491
103977
|
name: "deviceId",
|
|
103492
103978
|
form: "single",
|
|
103493
103979
|
optional: false
|
|
103494
103980
|
}],
|
|
103981
|
+
"snapshot.getDeviceLiveContribution": [{
|
|
103982
|
+
name: "deviceId",
|
|
103983
|
+
form: "single",
|
|
103984
|
+
optional: false
|
|
103985
|
+
}],
|
|
103986
|
+
"snapshot.getDeviceSettingsContribution": [{
|
|
103987
|
+
name: "deviceId",
|
|
103988
|
+
form: "single",
|
|
103989
|
+
optional: false
|
|
103990
|
+
}],
|
|
103495
103991
|
"snapshot.getSnapshot": [{
|
|
103496
103992
|
name: "deviceId",
|
|
103497
103993
|
form: "single",
|
|
@@ -103508,6 +104004,11 @@ Object.freeze({
|
|
|
103508
104004
|
form: "array",
|
|
103509
104005
|
optional: false
|
|
103510
104006
|
}],
|
|
104007
|
+
"snapshot.getStatus": [{
|
|
104008
|
+
name: "deviceId",
|
|
104009
|
+
form: "single",
|
|
104010
|
+
optional: false
|
|
104011
|
+
}],
|
|
103511
104012
|
"snapshot.invalidateCache": [{
|
|
103512
104013
|
name: "deviceId",
|
|
103513
104014
|
form: "single",
|
|
@@ -103518,6 +104019,11 @@ Object.freeze({
|
|
|
103518
104019
|
form: "single",
|
|
103519
104020
|
optional: false
|
|
103520
104021
|
}],
|
|
104022
|
+
"streamBroker.applyDeviceSettingsPatch": [{
|
|
104023
|
+
name: "deviceId",
|
|
104024
|
+
form: "single",
|
|
104025
|
+
optional: false
|
|
104026
|
+
}],
|
|
103521
104027
|
"streamBroker.assignProfile": [{
|
|
103522
104028
|
name: "deviceId",
|
|
103523
104029
|
form: "single",
|
|
@@ -103533,6 +104039,16 @@ Object.freeze({
|
|
|
103533
104039
|
form: "single",
|
|
103534
104040
|
optional: false
|
|
103535
104041
|
}],
|
|
104042
|
+
"streamBroker.getDeviceLiveContribution": [{
|
|
104043
|
+
name: "deviceId",
|
|
104044
|
+
form: "single",
|
|
104045
|
+
optional: false
|
|
104046
|
+
}],
|
|
104047
|
+
"streamBroker.getDeviceSettingsContribution": [{
|
|
104048
|
+
name: "deviceId",
|
|
104049
|
+
form: "single",
|
|
104050
|
+
optional: false
|
|
104051
|
+
}],
|
|
103536
104052
|
"streamBroker.getStreamWithCodec": [{
|
|
103537
104053
|
name: "deviceId",
|
|
103538
104054
|
form: "single",
|
|
@@ -103593,16 +104109,46 @@ Object.freeze({
|
|
|
103593
104109
|
form: "single",
|
|
103594
104110
|
optional: false
|
|
103595
104111
|
}],
|
|
104112
|
+
"streamParams.getStatus": [{
|
|
104113
|
+
name: "deviceId",
|
|
104114
|
+
form: "single",
|
|
104115
|
+
optional: false
|
|
104116
|
+
}],
|
|
103596
104117
|
"streamParams.setProfile": [{
|
|
103597
104118
|
name: "deviceId",
|
|
103598
104119
|
form: "single",
|
|
103599
104120
|
optional: false
|
|
103600
104121
|
}],
|
|
104122
|
+
"switch.getStatus": [{
|
|
104123
|
+
name: "deviceId",
|
|
104124
|
+
form: "single",
|
|
104125
|
+
optional: false
|
|
104126
|
+
}],
|
|
103601
104127
|
"switch.setState": [{
|
|
103602
104128
|
name: "deviceId",
|
|
103603
104129
|
form: "single",
|
|
103604
104130
|
optional: false
|
|
103605
104131
|
}],
|
|
104132
|
+
"tamper.getStatus": [{
|
|
104133
|
+
name: "deviceId",
|
|
104134
|
+
form: "single",
|
|
104135
|
+
optional: false
|
|
104136
|
+
}],
|
|
104137
|
+
"temperatureSensor.getStatus": [{
|
|
104138
|
+
name: "deviceId",
|
|
104139
|
+
form: "single",
|
|
104140
|
+
optional: false
|
|
104141
|
+
}],
|
|
104142
|
+
"update.getStatus": [{
|
|
104143
|
+
name: "deviceId",
|
|
104144
|
+
form: "single",
|
|
104145
|
+
optional: false
|
|
104146
|
+
}],
|
|
104147
|
+
"vacuumControl.getStatus": [{
|
|
104148
|
+
name: "deviceId",
|
|
104149
|
+
form: "single",
|
|
104150
|
+
optional: false
|
|
104151
|
+
}],
|
|
103606
104152
|
"vacuumControl.locate": [{
|
|
103607
104153
|
name: "deviceId",
|
|
103608
104154
|
form: "single",
|
|
@@ -103638,6 +104184,11 @@ Object.freeze({
|
|
|
103638
104184
|
form: "single",
|
|
103639
104185
|
optional: false
|
|
103640
104186
|
}],
|
|
104187
|
+
"valve.getStatus": [{
|
|
104188
|
+
name: "deviceId",
|
|
104189
|
+
form: "single",
|
|
104190
|
+
optional: false
|
|
104191
|
+
}],
|
|
103641
104192
|
"valve.open": [{
|
|
103642
104193
|
name: "deviceId",
|
|
103643
104194
|
form: "single",
|
|
@@ -103653,6 +104204,11 @@ Object.freeze({
|
|
|
103653
104204
|
form: "single",
|
|
103654
104205
|
optional: false
|
|
103655
104206
|
}],
|
|
104207
|
+
"vibration.getStatus": [{
|
|
104208
|
+
name: "deviceId",
|
|
104209
|
+
form: "single",
|
|
104210
|
+
optional: false
|
|
104211
|
+
}],
|
|
103656
104212
|
"videoclips.dialClipStream": [{
|
|
103657
104213
|
name: "deviceId",
|
|
103658
104214
|
form: "single",
|
|
@@ -103688,6 +104244,11 @@ Object.freeze({
|
|
|
103688
104244
|
form: "single",
|
|
103689
104245
|
optional: false
|
|
103690
104246
|
}],
|
|
104247
|
+
"waterHeater.getStatus": [{
|
|
104248
|
+
name: "deviceId",
|
|
104249
|
+
form: "single",
|
|
104250
|
+
optional: false
|
|
104251
|
+
}],
|
|
103691
104252
|
"waterHeater.setAway": [{
|
|
103692
104253
|
name: "deviceId",
|
|
103693
104254
|
form: "single",
|
|
@@ -103703,6 +104264,11 @@ Object.freeze({
|
|
|
103703
104264
|
form: "single",
|
|
103704
104265
|
optional: false
|
|
103705
104266
|
}],
|
|
104267
|
+
"weather.getStatus": [{
|
|
104268
|
+
name: "deviceId",
|
|
104269
|
+
form: "single",
|
|
104270
|
+
optional: false
|
|
104271
|
+
}],
|
|
103706
104272
|
"webrtcSession.addIceCandidate": [{
|
|
103707
104273
|
name: "deviceId",
|
|
103708
104274
|
form: "single",
|
|
@@ -104440,7 +105006,7 @@ var PreviewTextField = string().max(200);
|
|
|
104440
105006
|
* Whether the notification's preview is a STILL or a short animation.
|
|
104441
105007
|
*
|
|
104442
105008
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
104443
|
-
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
105009
|
+
* rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
|
|
104444
105010
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
104445
105011
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
104446
105012
|
* simply applies it to a dozen frames sampled across the render and assembles
|
|
@@ -104578,6 +105144,7 @@ TimelapseRuleInputSchema.extend({
|
|
|
104578
105144
|
createdAt: number(),
|
|
104579
105145
|
updatedAt: number()
|
|
104580
105146
|
});
|
|
105147
|
+
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
104581
105148
|
object({
|
|
104582
105149
|
/**
|
|
104583
105150
|
* Fraction of the box's own size added on EACH side before cutting.
|