@camstack/addon-matter-broker 0.2.116 → 0.2.117
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 +893 -326
- package/dist/addon.mjs +893 -326
- package/package.json +1 -3
package/dist/addon.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { networkInterfaces, tmpdir, uptime } from "node:os";
|
|
|
11
11
|
import { finished } from "node:stream/promises";
|
|
12
12
|
import { createConnection, createServer as createServer$2 } from "node:net";
|
|
13
13
|
import * as dgram from "node:dgram";
|
|
14
|
-
//#region ../types/dist/event-category-
|
|
14
|
+
//#region ../types/dist/event-category-BGmz_oxW.mjs
|
|
15
15
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
16
16
|
EventCategory["SystemBoot"] = "system.boot";
|
|
17
17
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -544,6 +544,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
544
544
|
*/
|
|
545
545
|
EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
|
|
546
546
|
EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
|
|
547
|
+
/**
|
|
548
|
+
* A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
|
|
549
|
+
* data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
|
|
550
|
+
* consumer is the orchestrator's camera-sensors bridge, which re-emits the
|
|
551
|
+
* camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
|
|
552
|
+
* for a camera with no attached sensor). Providers must not emit
|
|
553
|
+
* `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
|
|
554
|
+
* keeps it so (camera-grid is a named, deferred exception).
|
|
555
|
+
*/
|
|
547
556
|
EventCategory["ProviderMotion"] = "provider.motion";
|
|
548
557
|
EventCategory["ProviderDetection"] = "provider.detection";
|
|
549
558
|
EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
|
|
@@ -5382,7 +5391,7 @@ var ZodIssueCode = {
|
|
|
5382
5391
|
var ZodFirstPartyTypeKind;
|
|
5383
5392
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5384
5393
|
//#endregion
|
|
5385
|
-
//#region ../types/dist/sleep-
|
|
5394
|
+
//#region ../types/dist/sleep-CDCONfkt.mjs
|
|
5386
5395
|
/**
|
|
5387
5396
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5388
5397
|
* window to float samples (D455).
|
|
@@ -7425,7 +7434,7 @@ function errMsg(err) {
|
|
|
7425
7434
|
return String(err);
|
|
7426
7435
|
}
|
|
7427
7436
|
//#endregion
|
|
7428
|
-
//#region ../types/dist/composition-
|
|
7437
|
+
//#region ../types/dist/composition-Bzr7GwgP.mjs
|
|
7429
7438
|
/**
|
|
7430
7439
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
7431
7440
|
*
|
|
@@ -7479,21 +7488,20 @@ function portable(target) {
|
|
|
7479
7488
|
}
|
|
7480
7489
|
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
7481
7490
|
/**
|
|
7482
|
-
*
|
|
7483
|
-
*
|
|
7491
|
+
* THE table "which boolean of this device type counts as HIGH", and the
|
|
7492
|
+
* pure evaluator of its EDGE.
|
|
7484
7493
|
*
|
|
7485
|
-
*
|
|
7486
|
-
*
|
|
7487
|
-
*
|
|
7488
|
-
*
|
|
7489
|
-
*
|
|
7490
|
-
*
|
|
7491
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
7494
|
+
* ONE table for everyone who asks "is this device HIGH?": the
|
|
7495
|
+
* recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
|
|
7496
|
+
* sensor markers, the orchestrator's camera-sensors bridge and
|
|
7497
|
+
* the sources of a composite doorbell (`doorbellFeatureSources`, D671).
|
|
7498
|
+
* A second copy would diverge at the first cap added, and the symptom — "the
|
|
7499
|
+
* sensor rings the doorbell but does not record" — is exactly D62.
|
|
7492
7500
|
*
|
|
7493
|
-
* ⚠
|
|
7494
|
-
*
|
|
7495
|
-
*
|
|
7496
|
-
*
|
|
7501
|
+
* ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
|
|
7502
|
+
* two must not be unified: that one answers "what is the state WORD for a
|
|
7503
|
+
* rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
|
|
7504
|
+
* boolean's EDGE counts". Deliberately different vocabularies.
|
|
7497
7505
|
*/
|
|
7498
7506
|
/**
|
|
7499
7507
|
* Known binary / switch source caps → the boolean slice field whose
|
|
@@ -9102,22 +9110,22 @@ var CLASS_MAP_MACRO_TARGETS = [
|
|
|
9102
9110
|
"package"
|
|
9103
9111
|
];
|
|
9104
9112
|
/**
|
|
9105
|
-
*
|
|
9106
|
-
*
|
|
9113
|
+
* The FIRST-LEVEL macro classes: those an object detector emits and that
|
|
9114
|
+
* an operator can select.
|
|
9107
9115
|
*
|
|
9108
|
-
*
|
|
9116
|
+
* They are the three offered by the `object-detection` step
|
|
9109
9117
|
* (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
|
|
9110
|
-
* `enabledMacroClasses`). `package`
|
|
9111
|
-
* `MACRO_LABELS` —
|
|
9112
|
-
* `package-detection`,
|
|
9113
|
-
*
|
|
9118
|
+
* `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
|
|
9119
|
+
* `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
|
|
9120
|
+
* `package-detection`, whose enablement is driven by zones, and offering the
|
|
9121
|
+
* same word twice has already made an operator turn on the COCO proxy
|
|
9114
9122
|
* (suitcase/backpack/handbag) lasciando spento il detector dedicato.
|
|
9115
9123
|
*
|
|
9116
|
-
*
|
|
9117
|
-
*
|
|
9118
|
-
* (`types/detection.ts`);
|
|
9119
|
-
* (`RecordingTriggers.objectClasses`)
|
|
9120
|
-
*
|
|
9124
|
+
* ONE list. Before today the same three were hand-written in the step's offer
|
|
9125
|
+
* and a second time as the union `FirstLevelMacro`
|
|
9126
|
+
* (`types/detection.ts`); a third copy for the recording trigger
|
|
9127
|
+
* (`RecordingTriggers.objectClasses`) would have made the later divergence
|
|
9128
|
+
* invisible.
|
|
9121
9129
|
*/
|
|
9122
9130
|
var FIRST_LEVEL_MACRO_CLASSES = [
|
|
9123
9131
|
"person",
|
|
@@ -9182,17 +9190,17 @@ var RecordingStorageModeSchema = _enum([
|
|
|
9182
9190
|
"on-device-decision"
|
|
9183
9191
|
]);
|
|
9184
9192
|
/**
|
|
9185
|
-
*
|
|
9186
|
-
*
|
|
9193
|
+
* The macro classes that can open a recording window — the same
|
|
9194
|
+
* three offered by the `object-detection` step, from ONE list
|
|
9187
9195
|
* ({@link FIRST_LEVEL_MACRO_CLASSES}).
|
|
9188
9196
|
*/
|
|
9189
9197
|
var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
|
|
9190
9198
|
/**
|
|
9191
|
-
* True
|
|
9199
|
+
* True when `values` does not repeat an element.
|
|
9192
9200
|
*
|
|
9193
|
-
*
|
|
9194
|
-
*
|
|
9195
|
-
*
|
|
9201
|
+
* A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
|
|
9202
|
+
* becomes a SOURCE in `bandTriggerSources`, and the same source twice
|
|
9203
|
+
* would count its windows twice in `segmentMissedByMs`.
|
|
9196
9204
|
*/
|
|
9197
9205
|
var noDuplicates = (values) => new Set(values).size === values.length;
|
|
9198
9206
|
/** Which detectors trigger an `events`-mode band. */
|
|
@@ -9200,34 +9208,34 @@ var RecordingTriggersSchema = object({
|
|
|
9200
9208
|
motion: boolean().optional(),
|
|
9201
9209
|
audioThresholdDbfs: number().optional(),
|
|
9202
9210
|
/**
|
|
9203
|
-
*
|
|
9204
|
-
*
|
|
9205
|
-
*
|
|
9206
|
-
*
|
|
9211
|
+
* The macro classes whose detection opens a window. ABSENT = the source
|
|
9212
|
+
* is not listened to; an EMPTY array is rejected, because "events band, object
|
|
9213
|
+
* trigger on, no class" is the same shape "enabled and records
|
|
9214
|
+
* nothing, forever" that `eventsBandCanEverDemand` is written against.
|
|
9207
9215
|
*
|
|
9208
|
-
*
|
|
9209
|
-
*
|
|
9210
|
-
* `minConfidence<Macro>`
|
|
9211
|
-
* (`source: 'onboard'`)
|
|
9212
|
-
*
|
|
9216
|
+
* The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
|
|
9217
|
+
* those that went through `enabledMacroClasses`, the
|
|
9218
|
+
* `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
|
|
9219
|
+
* (`source: 'onboard'`) goes through none of those gates and does NOT open
|
|
9220
|
+
* windows — see `recorder/object-trigger.ts`.
|
|
9213
9221
|
*/
|
|
9214
9222
|
objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
|
|
9215
9223
|
/**
|
|
9216
|
-
*
|
|
9217
|
-
*
|
|
9224
|
+
* The LINKED devices whose RISING EDGE opens a window. Absent = the source
|
|
9225
|
+
* is not listened to; an empty array is rejected for the same reason as
|
|
9218
9226
|
* `objectClasses`.
|
|
9219
9227
|
*
|
|
9220
|
-
*
|
|
9221
|
-
*
|
|
9222
|
-
*
|
|
9223
|
-
*
|
|
9224
|
-
* device (D12) —
|
|
9228
|
+
* These are SOURCE device ids, not cameras: the band names them, so the
|
|
9229
|
+
* hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
|
|
9230
|
+
* does no RPC. The OFFER from which the operator picks them is another question, and
|
|
9231
|
+
* is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
|
|
9232
|
+
* device (D12) — never a global list of caps.
|
|
9225
9233
|
*
|
|
9226
|
-
*
|
|
9227
|
-
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`)
|
|
9228
|
-
*
|
|
9229
|
-
*
|
|
9230
|
-
*
|
|
9234
|
+
* What "high" means depends on the device TYPE and is not decided here:
|
|
9235
|
+
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
|
|
9236
|
+
* the same one as the composite doorbell (D671). And it is the EDGE, not
|
|
9237
|
+
* the level: a contact found already open at runner restart does not
|
|
9238
|
+
* record.
|
|
9231
9239
|
*/
|
|
9232
9240
|
sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
|
|
9233
9241
|
});
|
|
@@ -10304,7 +10312,7 @@ var DecoderSessionConfigSchema = object({
|
|
|
10304
10312
|
* - **VALUE** — at which level, for which scope, until when. That stays ONE
|
|
10305
10313
|
* thing: the logging settings document on the `system` cap. Two authorities
|
|
10306
10314
|
* over the values is the exact defect
|
|
10307
|
-
* `docs/design/plans/2026-08-26-
|
|
10315
|
+
* `docs/design/plans/2026-08-26-per-component-logging.md` was written to
|
|
10308
10316
|
* remove; re-introducing it from the cure side would be grotesque.
|
|
10309
10317
|
*
|
|
10310
10318
|
* Nothing in this file reads a clock, an env var or a store. The registry is
|
|
@@ -12015,7 +12023,7 @@ var BrokerStatusEnum = _enum([
|
|
|
12015
12023
|
"unreachable",
|
|
12016
12024
|
"error"
|
|
12017
12025
|
]);
|
|
12018
|
-
var BrokerInfoSchema
|
|
12026
|
+
var BrokerInfoSchema = object({
|
|
12019
12027
|
/** Stable broker id. Persisted; survives addon restarts. */
|
|
12020
12028
|
id: string$2(),
|
|
12021
12029
|
/** Addon id of the provider that OWNS this broker.
|
|
@@ -12158,8 +12166,8 @@ var brokerCapability = {
|
|
|
12158
12166
|
kind: "poll"
|
|
12159
12167
|
},
|
|
12160
12168
|
methods: {
|
|
12161
|
-
list: method(ListInputSchema, array(BrokerInfoSchema
|
|
12162
|
-
get: method(GetInputSchema, BrokerInfoSchema
|
|
12169
|
+
list: method(ListInputSchema, array(BrokerInfoSchema)),
|
|
12170
|
+
get: method(GetInputSchema, BrokerInfoSchema.nullable()),
|
|
12163
12171
|
/** Enumerate which addon provides which broker kind(s) for the
|
|
12164
12172
|
* unified create picker. The auto-mount fans this array across
|
|
12165
12173
|
* every registered `broker` provider (array-output method), so the
|
|
@@ -13908,7 +13916,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
13908
13916
|
*
|
|
13909
13917
|
* ⚠ An earlier version of this comment blamed Zod stripping, and that
|
|
13910
13918
|
* was wrong — corrected 2026-08-26 after the hop map
|
|
13911
|
-
* (`docs/design/2026-08-26-
|
|
13919
|
+
* (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
|
|
13912
13920
|
* There is **no Zod parse at all** between the door and the engine: the
|
|
13913
13921
|
* dispatcher forwards the payload verbatim and UDS carries it whole. A
|
|
13914
13922
|
* field declared here reaches `SqliteSettingsBackend` either way.
|
|
@@ -14788,7 +14796,17 @@ var SiteZoneSchema = object({
|
|
|
14788
14796
|
var ProviderStatusSchema = object({
|
|
14789
14797
|
connected: boolean(),
|
|
14790
14798
|
deviceCount: number(),
|
|
14791
|
-
error: string$2().optional()
|
|
14799
|
+
error: string$2().optional(),
|
|
14800
|
+
/**
|
|
14801
|
+
* `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
|
|
14802
|
+
* — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
|
|
14803
|
+
* which every provider bundles, so only a provider BUILT from D696-amended
|
|
14804
|
+
* code says it. ABSENT means an older provider that may still write it (raw
|
|
14805
|
+
* VMD writes, a boot seed), and the orchestrator's provider gate keeps that
|
|
14806
|
+
* provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
|
|
14807
|
+
* — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
|
|
14808
|
+
*/
|
|
14809
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
14792
14810
|
});
|
|
14793
14811
|
object({
|
|
14794
14812
|
externalId: string$2(),
|
|
@@ -15667,109 +15685,10 @@ method(object({
|
|
|
15667
15685
|
deviceIds: array(number()).readonly(),
|
|
15668
15686
|
caps: array(string$2()).readonly().optional()
|
|
15669
15687
|
}), record(string$2(), record(string$2(), unknown().nullable())));
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
* name (same pattern as `snapshot`):
|
|
15673
|
-
*
|
|
15674
|
-
* - **Native** providers: registered per-device by device-driver
|
|
15675
|
-
* addons via `ctx.registerNativeCap` — either on a
|
|
15676
|
-
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
15677
|
-
* or directly on the camera (Reolink registers at camera level).
|
|
15678
|
-
* Emits an `onPressed` event every time the firmware pushes a
|
|
15679
|
-
* ring; status tracks the last press and a pressCount since start
|
|
15680
|
-
* (diagnostic).
|
|
15681
|
-
*
|
|
15682
|
-
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
15683
|
-
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
15684
|
-
* device (contact / switch / event-emitter …) into a doorbell for
|
|
15685
|
-
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
15686
|
-
* it per camera in the device-bindings UI, then picks the source
|
|
15687
|
-
* device + trigger in the per-device settings.
|
|
15688
|
-
*
|
|
15689
|
-
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
15690
|
-
* — subscribers listening at the camera level receive ring events
|
|
15691
|
-
* with `via[]` populated. No code on the parent needed.
|
|
15692
|
-
*/
|
|
15693
|
-
var DoorbellStatusSchema = object({
|
|
15694
|
-
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
15695
|
-
lastPressedAt: number().nullable(),
|
|
15696
|
-
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
15697
|
-
pressCountSinceStart: number()
|
|
15698
|
-
});
|
|
15699
|
-
var DoorbellPressEventSchema = object({
|
|
15700
|
-
deviceId: number(),
|
|
15701
|
-
timestamp: number()
|
|
15702
|
-
});
|
|
15703
|
-
/**
|
|
15704
|
-
* The `doorbell-source` extension slot's editable value (D648): the camera's
|
|
15705
|
-
* virtual-doorbell trigger devices, exactly what the wrapper's
|
|
15706
|
-
* `doorbellSources` persists (as `{ deviceId }` records).
|
|
15707
|
-
*/
|
|
15708
|
-
var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
|
|
15709
|
-
/**
|
|
15710
|
-
* The `doorbell-source` slot — which devices ring this camera's VIRTUAL
|
|
15711
|
-
* doorbell, owned by the `virtual-doorbell` wrapper over its
|
|
15712
|
-
* `doorbellSources` store (D648). A source rings when one of its
|
|
15713
|
-
* `SOURCE_CAPS` rises. Whether the wrapper is bound to the camera at all is a
|
|
15714
|
-
* different authority (`deviceManager.setWrapperActive`, D62) — the slot
|
|
15715
|
-
* reports it, it never writes it.
|
|
15716
|
-
*/
|
|
15717
|
-
var DOORBELL_SOURCE_SLOT = {
|
|
15718
|
-
id: "doorbell-source",
|
|
15719
|
-
label: "Doorbell trigger devices",
|
|
15720
|
-
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.",
|
|
15721
|
-
shape: "association",
|
|
15722
|
-
hostDeviceTypes: [DeviceType.Camera],
|
|
15723
|
-
sourceCaps: SOURCE_CAPS,
|
|
15724
|
-
cardinality: "many",
|
|
15725
|
-
value: DoorbellSourceSlotValueSchema
|
|
15726
|
-
};
|
|
15727
|
-
var doorbellCapability = {
|
|
15728
|
-
name: "doorbell",
|
|
15729
|
-
scope: "device",
|
|
15730
|
-
deviceNative: true,
|
|
15731
|
-
mode: "singleton",
|
|
15732
|
-
kind: "wrapper",
|
|
15733
|
-
defaultActive: false,
|
|
15734
|
-
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
15735
|
-
extensionSlots: [DOORBELL_SOURCE_SLOT],
|
|
15736
|
-
methods: {},
|
|
15737
|
-
events: {
|
|
15738
|
-
/**
|
|
15739
|
-
* Fires once per physical press. Reolink delivers via Baichuan
|
|
15740
|
-
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
15741
|
-
* release/duration — it's a pulse.
|
|
15742
|
-
*/
|
|
15743
|
-
onPressed: {
|
|
15744
|
-
data: DoorbellPressEventSchema,
|
|
15745
|
-
fromState: {
|
|
15746
|
-
field: "lastPressedAt",
|
|
15747
|
-
on: "advance"
|
|
15748
|
-
}
|
|
15749
|
-
} },
|
|
15750
|
-
status: {
|
|
15751
|
-
schema: DoorbellStatusSchema,
|
|
15752
|
-
kind: "push"
|
|
15753
|
-
},
|
|
15754
|
-
/**
|
|
15755
|
-
* Runtime-state slice — last press timestamp + lifetime press count.
|
|
15756
|
-
* Mirrored by the kernel and readable via
|
|
15757
|
-
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
15758
|
-
* without subscribing.
|
|
15759
|
-
*/
|
|
15760
|
-
runtimeState: DoorbellStatusSchema,
|
|
15761
|
-
/**
|
|
15762
|
-
* 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.
|
|
15763
|
-
*
|
|
15764
|
-
* See `RuntimeStateDurability`. Enforced by
|
|
15765
|
-
* `scripts/check-runtime-state-durability.ts`.
|
|
15766
|
-
*/
|
|
15767
|
-
durability: "restored"
|
|
15768
|
-
};
|
|
15769
|
-
var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
|
|
15770
|
-
DeviceType.Camera, DeviceType.Camera;
|
|
15688
|
+
var ExtensionSlotIdSchema = _enum(["linked-devices"]);
|
|
15689
|
+
DeviceType.Camera;
|
|
15771
15690
|
/** A slot's editable value, discriminated on `slot`. */
|
|
15772
|
-
var ExtensionSlotValueSchema = discriminatedUnion("slot", [
|
|
15691
|
+
var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
|
|
15773
15692
|
DeviceType.Camera;
|
|
15774
15693
|
var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
|
|
15775
15694
|
state: literal("unreachable"),
|
|
@@ -15806,10 +15725,11 @@ var ExtensionSlotSourceSchema = object({
|
|
|
15806
15725
|
});
|
|
15807
15726
|
/**
|
|
15808
15727
|
* A DIFFERENT authority that gates whether the slot's sources do anything —
|
|
15809
|
-
* reported read-only, named, never written through this contract (D62).
|
|
15810
|
-
*
|
|
15811
|
-
*
|
|
15812
|
-
* `unknown` means the gate could
|
|
15728
|
+
* reported read-only, named, never written through this contract (D62) — e.g.
|
|
15729
|
+
* a slot whose sources act only while a wrapper is bound to the host, a
|
|
15730
|
+
* binding that belongs to `deviceManager.setWrapperActive`. No slot reports
|
|
15731
|
+
* one today (`linked-devices` answers `null`). `unknown` means the gate could
|
|
15732
|
+
* not be read; it is not "inactive" (D315).
|
|
15813
15733
|
*/
|
|
15814
15734
|
var ExtensionSlotActivationSchema = object({
|
|
15815
15735
|
state: _enum([
|
|
@@ -15825,7 +15745,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
|
|
|
15825
15745
|
/** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
|
|
15826
15746
|
slotRef: string$2(),
|
|
15827
15747
|
slot: ExtensionSlotIdSchema,
|
|
15828
|
-
/** Names the store written (D62), e.g. `
|
|
15748
|
+
/** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
|
|
15829
15749
|
authority: string$2(),
|
|
15830
15750
|
activation: ExtensionSlotActivationSchema.nullable(),
|
|
15831
15751
|
value: ExtensionSlotValueSchema,
|
|
@@ -16103,7 +16023,7 @@ method(object({
|
|
|
16103
16023
|
* per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
|
|
16104
16024
|
* ends in a log line, and a log line is the thing the operator asked to stop
|
|
16105
16025
|
* needing: *"possiamo armare questi errori intanto? Così al prossimo giro
|
|
16106
|
-
* ricontrolliamo tutti questi punti"
|
|
16026
|
+
* 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
|
|
16107
16027
|
* hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
|
|
16108
16028
|
* media blackout were both diagnosed. The counters stay; this is where they can
|
|
16109
16029
|
* be READ.
|
|
@@ -17479,7 +17399,7 @@ var BrokerStatusSchema$1 = _enum([
|
|
|
17479
17399
|
"unreachable",
|
|
17480
17400
|
"tls-error"
|
|
17481
17401
|
]);
|
|
17482
|
-
var BrokerInfoSchema = object({
|
|
17402
|
+
var BrokerInfoSchema$1 = object({
|
|
17483
17403
|
id: string$2(),
|
|
17484
17404
|
name: string$2(),
|
|
17485
17405
|
url: string$2(),
|
|
@@ -17542,7 +17462,7 @@ var StatusSchema = object({
|
|
|
17542
17462
|
brokerCount: number(),
|
|
17543
17463
|
embeddedRunning: boolean()
|
|
17544
17464
|
});
|
|
17545
|
-
method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
|
|
17465
|
+
method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
|
|
17546
17466
|
kind: "mutation",
|
|
17547
17467
|
auth: "admin"
|
|
17548
17468
|
}), method(IdInputSchema, _void(), {
|
|
@@ -19756,78 +19676,16 @@ var NcRuleInputSchema = object({
|
|
|
19756
19676
|
*/
|
|
19757
19677
|
confirm: NcConfirmSchema.optional(),
|
|
19758
19678
|
/**
|
|
19759
|
-
*
|
|
19760
|
-
*
|
|
19761
|
-
*
|
|
19762
|
-
*
|
|
19763
|
-
*
|
|
19764
|
-
*
|
|
19765
|
-
*
|
|
19766
|
-
*
|
|
19767
|
-
*
|
|
19768
|
-
* Only two honest answers exist, and this flag picks between them. It has
|
|
19769
|
-
* effect ONLY on a rule that declares a recognition scope
|
|
19770
|
-
* ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
|
|
19771
|
-
* other rule there is nothing to wait for and the flag is inert.
|
|
19772
|
-
*
|
|
19773
|
-
* | value | what happens |
|
|
19774
|
-
* | --- | --- |
|
|
19775
|
-
* | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
|
|
19776
|
-
* | 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) |
|
|
19777
|
-
*
|
|
19778
|
-
* `.optional()` and deliberately NOT `.default()`: a Zod default does not run
|
|
19779
|
-
* on the addon cap path, and absent has to keep meaning exactly what every
|
|
19780
|
-
* rule authored before this field meant.
|
|
19781
|
-
*
|
|
19782
|
-
* The cost of `true` is stated here because the editor states it too: a rule
|
|
19783
|
-
* that waits also inherits track-close SEMANTICS — its `zones` condition
|
|
19784
|
-
* tests every zone the track visited and a `crossing` condition can no longer
|
|
19785
|
-
* be satisfied, because a closed track carries no crossing.
|
|
19786
|
-
*/
|
|
19787
|
-
waitForEnhancement: boolean().optional(),
|
|
19788
|
-
/**
|
|
19789
|
-
* GROUP a burst of subjects into ONE notification that grows.
|
|
19790
|
-
*
|
|
19791
|
-
* Seconds of quiet after the last matching subject before the burst is
|
|
19792
|
-
* considered over. While it is open, the first subject enqueues immediately —
|
|
19793
|
-
* **exactly as today, with no added latency** — and every real growth (a new
|
|
19794
|
-
* subject, or a name confirmed on one already in it) REPLACES that
|
|
19795
|
-
* notification with an updated one naming everybody. The push carries the
|
|
19796
|
-
* group's own coalescing tag, so the phone replaces rather than stacks.
|
|
19797
|
-
*
|
|
19798
|
-
* `0` / absent = off, and off is today's behaviour byte for byte.
|
|
19799
|
-
*
|
|
19800
|
-
* ### Why an idle cutoff and not a window
|
|
19801
|
-
*
|
|
19802
|
-
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
19803
|
-
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
19804
|
-
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
19805
|
-
* 30 s is a widely shipped value for the same decision.
|
|
19806
|
-
*
|
|
19807
|
-
* ### What it replaces
|
|
19808
|
-
*
|
|
19809
|
-
* The blind cooldown, which collapses a burst by DISCARDING it. Measured on
|
|
19810
|
-
* device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
|
|
19811
|
-
* notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
|
|
19812
|
-
* track that did fire and 7 carrying a confirmed identity nobody heard about.
|
|
19813
|
-
* A group collapses the same volume by MERGING, so the cooldown becomes a
|
|
19814
|
-
* budget over GROUPS — which is what it always meant — and a growth is never
|
|
19815
|
-
* throttled by the window its own first member spent.
|
|
19816
|
-
*
|
|
19817
|
-
* ### Interaction with {@link waitForEnhancement}
|
|
19818
|
-
*
|
|
19819
|
-
* They compose, and the order matters. `waitForEnhancement` defers the rule to
|
|
19820
|
-
* TRACK CLOSE, so with both set the group is opened by the first member to
|
|
19821
|
-
* CLOSE — already carrying its name — and grows as later members close. That
|
|
19822
|
-
* is later, and complete. With grouping alone the group opens on the first
|
|
19823
|
-
* object event and picks up names as they are confirmed, through the growth
|
|
19824
|
-
* path. Neither combination fires twice for one subject.
|
|
19825
|
-
*
|
|
19826
|
-
* `.optional()` and deliberately NOT `.default()`: a Zod default does not run
|
|
19827
|
-
* on the addon cap path, so absent must keep meaning what it meant before this
|
|
19828
|
-
* field existed.
|
|
19679
|
+
* IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
|
|
19680
|
+
* seconds; the rule sends ONE message when the window closes — early, once every
|
|
19681
|
+
* subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
|
|
19682
|
+
* the rule matched, with one mosaic tile per subject.
|
|
19683
|
+
* Absent = plain immediate (one message per track, at the first match).
|
|
19684
|
+
* Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
|
|
19685
|
+
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
19686
|
+
* path does not run Zod defaults.
|
|
19829
19687
|
*/
|
|
19830
|
-
|
|
19688
|
+
groupingSec: number().int().min(5).max(60).optional()
|
|
19831
19689
|
});
|
|
19832
19690
|
/**
|
|
19833
19691
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -19875,9 +19733,10 @@ var NcRuleClearableKeySchema = _enum([
|
|
|
19875
19733
|
"targetUsers",
|
|
19876
19734
|
"snoozeOptions",
|
|
19877
19735
|
"snoozeAllowGlobal",
|
|
19878
|
-
"waitForEnhancement",
|
|
19879
19736
|
"actions",
|
|
19880
19737
|
"confirm",
|
|
19738
|
+
"groupingSec",
|
|
19739
|
+
"waitForEnhancement",
|
|
19881
19740
|
"groupIdleSec"
|
|
19882
19741
|
]);
|
|
19883
19742
|
var NcRuleUpdateInputSchema = object({
|
|
@@ -19899,9 +19758,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
19899
19758
|
*/
|
|
19900
19759
|
disabledTargetIds: array(string$2()).default([])
|
|
19901
19760
|
});
|
|
19761
|
+
/**
|
|
19762
|
+
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
|
|
19763
|
+
* still-true state. `backups-exports` and `alarm` are not sections — a completed
|
|
19764
|
+
* job is not an open state, and the alarm stays instant.
|
|
19765
|
+
*/
|
|
19766
|
+
var NcStateSummarySectionIdSchema = _enum([
|
|
19767
|
+
"device-state",
|
|
19768
|
+
"streams",
|
|
19769
|
+
"battery",
|
|
19770
|
+
"consumables",
|
|
19771
|
+
"tanks",
|
|
19772
|
+
"detection-blind",
|
|
19773
|
+
"nodes",
|
|
19774
|
+
"addons",
|
|
19775
|
+
"updates"
|
|
19776
|
+
]);
|
|
19902
19777
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
19903
19778
|
var NcStateSummaryPreviewSectionSchema = object({
|
|
19904
|
-
id:
|
|
19779
|
+
id: NcStateSummarySectionIdSchema,
|
|
19905
19780
|
status: _enum(["read", "unavailable"]),
|
|
19906
19781
|
items: number().int().nonnegative(),
|
|
19907
19782
|
reason: string$2().optional()
|
|
@@ -19911,7 +19786,7 @@ var NcStateSummaryPreviewSectionSchema = object({
|
|
|
19911
19786
|
* a `rule` split (no `section`), one section's on a `section` split.
|
|
19912
19787
|
*/
|
|
19913
19788
|
var NcStateSummaryPreviewRowSchema = object({
|
|
19914
|
-
section:
|
|
19789
|
+
section: NcStateSummarySectionIdSchema.optional(),
|
|
19915
19790
|
/** The section's name on a per-section row; every reported section's, joined, on a combined one. */
|
|
19916
19791
|
title: string$2(),
|
|
19917
19792
|
text: string$2(),
|
|
@@ -20348,6 +20223,29 @@ object({
|
|
|
20348
20223
|
firstAt: number(),
|
|
20349
20224
|
lastAt: number()
|
|
20350
20225
|
});
|
|
20226
|
+
var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
|
|
20227
|
+
var NcAlarmDelaySecSchema = number().int().min(0).max(600);
|
|
20228
|
+
var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
|
|
20229
|
+
var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
|
|
20230
|
+
var NcAlarmModeDelaysListSchema = array(object({
|
|
20231
|
+
mode: AlarmArmModeSchema,
|
|
20232
|
+
exitDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
20233
|
+
entryDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
20234
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
|
|
20235
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20236
|
+
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20237
|
+
mode: AlarmArmModeSchema,
|
|
20238
|
+
exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
20239
|
+
entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
20240
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
|
|
20241
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20242
|
+
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20243
|
+
var NcAlarmNonBlockingEditSchema = object({
|
|
20244
|
+
mode: AlarmArmModeSchema,
|
|
20245
|
+
deviceId: number().int().positive(),
|
|
20246
|
+
/** true = on the list (may be open, does not block); false = off the list (blocks). */
|
|
20247
|
+
nonBlocking: boolean()
|
|
20248
|
+
});
|
|
20351
20249
|
/**
|
|
20352
20250
|
* The per-mode lists, at most one per mode. Two lists for one mode have no
|
|
20353
20251
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
@@ -20356,10 +20254,10 @@ object({
|
|
|
20356
20254
|
var NcAlarmNonBlockingListSchema = array(object({
|
|
20357
20255
|
mode: AlarmArmModeSchema,
|
|
20358
20256
|
deviceIds: array(number().int()).max(200)
|
|
20359
|
-
})).max(8).refine(
|
|
20257
|
+
})).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20360
20258
|
/**
|
|
20361
|
-
* The three durations
|
|
20362
|
-
* transitions, and which openings each mode tolerates.
|
|
20259
|
+
* The three durations — global, and per mode since D697 — the panel's state
|
|
20260
|
+
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
20363
20261
|
*
|
|
20364
20262
|
* They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
|
|
20365
20263
|
* `alarm-panel` is `deviceNative` and its other provider mirrors somebody
|
|
@@ -20369,15 +20267,15 @@ var NcAlarmNonBlockingListSchema = array(object({
|
|
|
20369
20267
|
*/
|
|
20370
20268
|
var NcAlarmSettingsSchema = object({
|
|
20371
20269
|
/** Grace period between arming and the mode taking effect. 0 = immediate. */
|
|
20372
|
-
exitDelaySec:
|
|
20270
|
+
exitDelaySec: NcAlarmDelaySecSchema,
|
|
20373
20271
|
/** Grace period between a trigger and the alarm firing. 0 = immediate. */
|
|
20374
|
-
entryDelaySec:
|
|
20272
|
+
entryDelaySec: NcAlarmDelaySecSchema,
|
|
20375
20273
|
/**
|
|
20376
20274
|
* How long `triggered` lasts before the panel re-arms itself.
|
|
20377
20275
|
* **0 = until an operator disarms it** — the behaviour before this field
|
|
20378
20276
|
* existed, and therefore what an untouched install keeps doing.
|
|
20379
20277
|
*/
|
|
20380
|
-
triggeredDurationSec:
|
|
20278
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema,
|
|
20381
20279
|
/**
|
|
20382
20280
|
* Deprecated by D630 — every transition is announced. Parsed, never read;
|
|
20383
20281
|
* remove after one release. Optional so an older admin's patch (which still
|
|
@@ -20400,17 +20298,30 @@ var NcAlarmSettingsSchema = object({
|
|
|
20400
20298
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
20401
20299
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
20402
20300
|
*/
|
|
20403
|
-
nonBlocking: NcAlarmNonBlockingListSchema.default([])
|
|
20301
|
+
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
20302
|
+
/**
|
|
20303
|
+
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
20304
|
+
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
20305
|
+
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
20306
|
+
*/
|
|
20307
|
+
modeDelays: NcAlarmModeDelaysListSchema.default([])
|
|
20404
20308
|
});
|
|
20405
20309
|
/**
|
|
20406
20310
|
* Every field optional — a tab edits one control at a time.
|
|
20407
20311
|
*
|
|
20408
|
-
* `nonBlocking`
|
|
20409
|
-
* remove an inner `.default()`, so a patch that never
|
|
20410
|
-
* parse to `
|
|
20411
|
-
* (the same trap {@link NcRulePatchSchema} documents).
|
|
20312
|
+
* `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
|
|
20313
|
+
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
20314
|
+
* named the field would parse to `[]` and wipe every mode's list on an
|
|
20315
|
+
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
20316
|
+
* `modeDelays` means EDITS, not the stored overrides.
|
|
20412
20317
|
*/
|
|
20413
|
-
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20318
|
+
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20319
|
+
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
20320
|
+
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
20321
|
+
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
20322
|
+
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
20323
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
20324
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
|
|
20414
20325
|
/**
|
|
20415
20326
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
20416
20327
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -20510,6 +20421,28 @@ var NcAlarmConfigSchema = object({
|
|
|
20510
20421
|
*/
|
|
20511
20422
|
live: NcAlarmLiveSchema.optional()
|
|
20512
20423
|
});
|
|
20424
|
+
var NcAlarmSensorReadingSchema = _enum([
|
|
20425
|
+
"open",
|
|
20426
|
+
"closed",
|
|
20427
|
+
"unknown",
|
|
20428
|
+
"not-opening"
|
|
20429
|
+
]);
|
|
20430
|
+
/** One device's state as the alarm reads it — the classifier the arm check uses. */
|
|
20431
|
+
var NcAlarmSensorStateSchema = object({
|
|
20432
|
+
deviceId: number().int().positive(),
|
|
20433
|
+
reading: NcAlarmSensorReadingSchema,
|
|
20434
|
+
/** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
|
|
20435
|
+
state: string$2().nullable(),
|
|
20436
|
+
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
20437
|
+
unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
|
|
20438
|
+
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
20439
|
+
online: boolean().nullable()
|
|
20440
|
+
});
|
|
20441
|
+
var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
|
|
20442
|
+
var NcAlarmSensorsSchema = object({
|
|
20443
|
+
sensors: array(NcAlarmSensorStateSchema),
|
|
20444
|
+
readAt: number().int().nonnegative()
|
|
20445
|
+
});
|
|
20513
20446
|
/**
|
|
20514
20447
|
* ONE rule's demand on ONE camera's clip ring.
|
|
20515
20448
|
*
|
|
@@ -20600,7 +20533,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
20600
20533
|
}), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
|
|
20601
20534
|
kind: "mutation",
|
|
20602
20535
|
auth: "admin"
|
|
20603
|
-
});
|
|
20536
|
+
}), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
|
|
20604
20537
|
/**
|
|
20605
20538
|
* Zod schemas for persisted record types.
|
|
20606
20539
|
*
|
|
@@ -20947,12 +20880,26 @@ var CameraSensorRefSchema = object({
|
|
|
20947
20880
|
function cameraSensorRefKey(ref) {
|
|
20948
20881
|
return `${ref.addonId}/${ref.stableId}`;
|
|
20949
20882
|
}
|
|
20950
|
-
/**
|
|
20951
|
-
|
|
20952
|
-
|
|
20953
|
-
|
|
20954
|
-
|
|
20955
|
-
|
|
20883
|
+
/**
|
|
20884
|
+
* A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
|
|
20885
|
+
* `replace`: its motion is the camera's, and while one is READY the camera's
|
|
20886
|
+
* own motion no longer counts on its own. `confirm`: while one is READY the
|
|
20887
|
+
* camera's own motion counts only while a confirm sensor is active — with or
|
|
20888
|
+
* without a replace sensor (spec C2, the controller's ruling on Q1).
|
|
20889
|
+
*/
|
|
20890
|
+
var CameraSensorModeSchema = _enum([
|
|
20891
|
+
"in-addition",
|
|
20892
|
+
"confirm",
|
|
20893
|
+
"replace"
|
|
20894
|
+
]);
|
|
20895
|
+
/** A stored sensor with no mode — every CS-1 row — is in addition. */
|
|
20896
|
+
var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
|
|
20897
|
+
/**
|
|
20898
|
+
* A camera's attached sensors. A CS-1 row carried an envelope
|
|
20899
|
+
* `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
|
|
20900
|
+
* what the write stores (D672 rule 3), so it is never written again.
|
|
20901
|
+
*/
|
|
20902
|
+
var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
|
|
20956
20903
|
const seen = /* @__PURE__ */ new Set();
|
|
20957
20904
|
value.sensors.forEach((ref, index) => {
|
|
20958
20905
|
const key = cameraSensorRefKey(ref);
|
|
@@ -20964,39 +20911,41 @@ var CameraSensorsConfigSchema = object({
|
|
|
20964
20911
|
seen.add(key);
|
|
20965
20912
|
});
|
|
20966
20913
|
});
|
|
20967
|
-
|
|
20914
|
+
/** Every attachment names its mode; an older orchestrator that does not is in addition. */
|
|
20915
|
+
var AttachmentFields = {
|
|
20968
20916
|
addonId: string$2(),
|
|
20969
|
-
stableId: string$2()
|
|
20917
|
+
stableId: string$2(),
|
|
20918
|
+
mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
|
|
20970
20919
|
};
|
|
20971
20920
|
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20972
20921
|
object({
|
|
20973
|
-
...
|
|
20922
|
+
...AttachmentFields,
|
|
20974
20923
|
state: literal("ready"),
|
|
20975
20924
|
deviceId: number(),
|
|
20976
20925
|
name: string$2(),
|
|
20977
20926
|
caps: array(string$2()).readonly()
|
|
20978
20927
|
}),
|
|
20979
20928
|
object({
|
|
20980
|
-
...
|
|
20929
|
+
...AttachmentFields,
|
|
20981
20930
|
state: literal("offline"),
|
|
20982
20931
|
deviceId: number(),
|
|
20983
20932
|
name: string$2(),
|
|
20984
20933
|
reason: _enum(["offline", "disabled"])
|
|
20985
20934
|
}),
|
|
20986
20935
|
object({
|
|
20987
|
-
...
|
|
20936
|
+
...AttachmentFields,
|
|
20988
20937
|
state: literal("missing"),
|
|
20989
20938
|
reason: string$2()
|
|
20990
20939
|
}),
|
|
20991
20940
|
object({
|
|
20992
|
-
...
|
|
20941
|
+
...AttachmentFields,
|
|
20993
20942
|
state: literal("unsupported"),
|
|
20994
20943
|
deviceId: number(),
|
|
20995
20944
|
name: string$2(),
|
|
20996
20945
|
reason: string$2()
|
|
20997
20946
|
}),
|
|
20998
20947
|
object({
|
|
20999
|
-
...
|
|
20948
|
+
...AttachmentFields,
|
|
21000
20949
|
state: literal("unreadable"),
|
|
21001
20950
|
reason: string$2()
|
|
21002
20951
|
})
|
|
@@ -21009,17 +20958,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
|
21009
20958
|
* say.
|
|
21010
20959
|
*/
|
|
21011
20960
|
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20961
|
+
/** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
|
|
20962
|
+
var CameraOwnMotionSchema = _enum([
|
|
20963
|
+
"always",
|
|
20964
|
+
"when-confirmed",
|
|
20965
|
+
"never"
|
|
20966
|
+
]);
|
|
20967
|
+
/** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
|
|
20968
|
+
var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
|
|
20969
|
+
/**
|
|
20970
|
+
* The camera's OWN onboard motion (D696): the raw input the bridge combines,
|
|
20971
|
+
* never the effective value. The camera's `motion` slice is the effective one,
|
|
20972
|
+
* so a view of the camera's own row reads this.
|
|
20973
|
+
* - `atMs`: when the bridge received the camera's last own edge.
|
|
20974
|
+
* - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
|
|
20975
|
+
* AND it is younger than the window the bridge counts the camera's own motion
|
|
20976
|
+
* for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
|
|
20977
|
+
* sends a clear (heartbeats only) therefore reads `false` once no push came
|
|
20978
|
+
* within the window; a status read is a snapshot, so a live view re-asks.
|
|
20979
|
+
* Absent = this orchestrator has not received the camera's own motion since it
|
|
20980
|
+
* started (unknown, never "quiet"), or an orchestrator older than D696.
|
|
20981
|
+
*/
|
|
20982
|
+
var CameraRawLevelSchema = object({
|
|
20983
|
+
detected: boolean(),
|
|
20984
|
+
atMs: number()
|
|
20985
|
+
});
|
|
21012
20986
|
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
21013
|
-
object({
|
|
20987
|
+
object({
|
|
20988
|
+
state: literal("not-configured"),
|
|
20989
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
20990
|
+
}),
|
|
21014
20991
|
object({
|
|
21015
20992
|
state: literal("unreadable"),
|
|
21016
|
-
reason: string$2()
|
|
20993
|
+
reason: string$2(),
|
|
20994
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
21017
20995
|
}),
|
|
21018
20996
|
object({
|
|
21019
20997
|
state: literal("configured"),
|
|
21020
|
-
|
|
20998
|
+
cameraLevel: CameraRawLevelSchema.optional(),
|
|
21021
20999
|
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
21022
|
-
|
|
21000
|
+
/** Absent = an orchestrator older than CS-2: it does not say (D315). */
|
|
21001
|
+
cameraMotion: CameraOwnMotionSchema.optional(),
|
|
21002
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional(),
|
|
21003
|
+
notEnforced: CameraSensorsNotEnforcedSchema.optional()
|
|
21023
21004
|
})
|
|
21024
21005
|
]);
|
|
21025
21006
|
Object.freeze({
|
|
@@ -21704,14 +21685,14 @@ var TrackSchema = object({
|
|
|
21704
21685
|
* `derive-returned-null tile=standin`,
|
|
21705
21686
|
* `native-tile tile=native no-key-frame-at-close`, …) written at close and
|
|
21706
21687
|
* CLEARED by the late-keyFrame upgrade when a native tile lands after all.
|
|
21707
|
-
* The operator-facing answer to "perché manca l'immagine?" on a track whose
|
|
21688
|
+
* The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
|
|
21708
21689
|
* tile is a face/plate stand-in, a raster crop, or an icon.
|
|
21709
21690
|
*
|
|
21710
21691
|
* **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
|
|
21711
21692
|
* the TILE ranked below native, so a track whose thumbnail landed natively
|
|
21712
21693
|
* while its key frame missed carried no reason at all — three of the four
|
|
21713
21694
|
* `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
|
|
21714
|
-
* that shape, and their "niente ultimo" had no cause anywhere on the row.
|
|
21695
|
+
* that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
|
|
21715
21696
|
* The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
|
|
21716
21697
|
* lastFrame copy source`), so its absence is now on this line whatever the
|
|
21717
21698
|
* tile ended up being.
|
|
@@ -21798,7 +21779,7 @@ var MotionEventSchema = object({
|
|
|
21798
21779
|
/**
|
|
21799
21780
|
* Ms offsets from `timestamp` (the episode's own first rising edge, so the
|
|
21800
21781
|
* first entry is always `0`) of every genuine off→on transition the
|
|
21801
|
-
* episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
|
|
21782
|
+
* episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
|
|
21802
21783
|
* push: a firmware source that keepalives at ~1 Hz for the whole burst
|
|
21803
21784
|
* (Reolink, Hikvision) produces exactly one edge; a source that reports an
|
|
21804
21785
|
* explicit `false` mid-episode and then resumes before the quiet window
|
|
@@ -22322,6 +22303,7 @@ var KeyEventSchema = object({
|
|
|
22322
22303
|
bestEventId: string$2(),
|
|
22323
22304
|
/** Track lifetime in ms (lastSeen - firstSeen). */
|
|
22324
22305
|
windowMs: number().optional(),
|
|
22306
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
22325
22307
|
...TrackFlagFields,
|
|
22326
22308
|
...TrackRetrainFields
|
|
22327
22309
|
});
|
|
@@ -24250,8 +24232,10 @@ var RunnerCameraConfigSchema = object({
|
|
|
24250
24232
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
24251
24233
|
* analyzer providers) running on decoded frames in this runner.
|
|
24252
24234
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
24253
|
-
* analytics). The provider emits ProviderMotion
|
|
24254
|
-
*
|
|
24235
|
+
* analytics). The provider emits its raw push as `ProviderMotion`
|
|
24236
|
+
* (D673); the orchestrator's camera-sensors bridge re-emits the camera's
|
|
24237
|
+
* effective motion as `MotionOnMotionChanged`, which is what reaches
|
|
24238
|
+
* `reportMotion`.
|
|
24255
24239
|
*/
|
|
24256
24240
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24257
24241
|
/**
|
|
@@ -24428,7 +24412,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
24428
24412
|
hasGpu: boolean(),
|
|
24429
24413
|
inferenceBackend: string$2().optional(),
|
|
24430
24414
|
cpuCores: number().optional()
|
|
24431
|
-
})
|
|
24415
|
+
}),
|
|
24416
|
+
/**
|
|
24417
|
+
* Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
|
|
24418
|
+
* runner never writes it. ABSENT = a runner older than D696, which still
|
|
24419
|
+
* writes the slice from its phase machine; the orchestrator does not write
|
|
24420
|
+
* while any runner node is absent-or-unanswered, so one slice never has two
|
|
24421
|
+
* writers.
|
|
24422
|
+
*/
|
|
24423
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
24432
24424
|
});
|
|
24433
24425
|
/**
|
|
24434
24426
|
* Aggregate runtime metrics for the runner's whole local pool. Mirrors the
|
|
@@ -27093,7 +27085,7 @@ var ClipPlaybackSchema = object({
|
|
|
27093
27085
|
* **One authorised yes is one wake.** `next-natural` — take the clip the next
|
|
27094
27086
|
* time the camera is awake for its own reasons — is deliberately not a member:
|
|
27095
27087
|
* it was proposed, it is free on the battery, and the operator declined it on
|
|
27096
|
-
* 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."
|
|
27088
|
+
* 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
|
|
27097
27089
|
* D558 "Considered and not taken").
|
|
27098
27090
|
*/
|
|
27099
27091
|
var ClipWakeSchema = _enum(["authorised"]);
|
|
@@ -27354,7 +27346,7 @@ DeviceType.Camera, method(object({
|
|
|
27354
27346
|
* It replaced `sources?: string[]`, a VIEW filter over source ids that
|
|
27355
27347
|
* assumed the answer was a fan-out over everything a camera has. The
|
|
27356
27348
|
* operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
|
|
27357
|
-
* solo"* — so the list is asked of one provider at a time and there is
|
|
27349
|
+
* solo"* [there is only one user] — so the list is asked of one provider at a time and there is
|
|
27358
27350
|
* nothing to filter out of it.
|
|
27359
27351
|
*/
|
|
27360
27352
|
provider: string$2().min(1)
|
|
@@ -29966,6 +29958,70 @@ onStatusChanged: { data: object({
|
|
|
29966
29958
|
* whether persisting is worth a SQLite commit. */
|
|
29967
29959
|
volatileStateFields: ["lastChangedAt"]
|
|
29968
29960
|
};
|
|
29961
|
+
var DoorbellStatusSchema = object({
|
|
29962
|
+
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
29963
|
+
lastPressedAt: number().nullable(),
|
|
29964
|
+
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
29965
|
+
pressCountSinceStart: number()
|
|
29966
|
+
});
|
|
29967
|
+
var DoorbellPressEventSchema = object({
|
|
29968
|
+
deviceId: number(),
|
|
29969
|
+
timestamp: number()
|
|
29970
|
+
});
|
|
29971
|
+
/**
|
|
29972
|
+
* Doorbell button cap. Two kinds of provider serve it, and to every consumer
|
|
29973
|
+
* they are the same cap:
|
|
29974
|
+
*
|
|
29975
|
+
* - **Native** providers, registered per device by a driver addon through
|
|
29976
|
+
* `ctx.registerNativeCap` — a `DeviceType.Button` accessory with
|
|
29977
|
+
* `role: DeviceRole.Doorbell`, or the camera itself (Reolink registers at
|
|
29978
|
+
* camera level). They emit `onPressed` on every firmware ring.
|
|
29979
|
+
* - **A composed doorbell** (D670, D671): a camera's customization gives it
|
|
29980
|
+
* the cap, its `lastPressedAt` rising from the sources the operator
|
|
29981
|
+
* assigned in Customize → Doorbell, and the composer emits `onPressed`
|
|
29982
|
+
* from that field's advance (`fromState`).
|
|
29983
|
+
*
|
|
29984
|
+
* The DeviceEventPropagator re-emits `onPressed` on the camera parent.
|
|
29985
|
+
*/
|
|
29986
|
+
var doorbellCapability = {
|
|
29987
|
+
name: "doorbell",
|
|
29988
|
+
scope: "device",
|
|
29989
|
+
deviceNative: true,
|
|
29990
|
+
mode: "singleton",
|
|
29991
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
29992
|
+
methods: {},
|
|
29993
|
+
events: {
|
|
29994
|
+
/**
|
|
29995
|
+
* Fires once per physical press. Reolink delivers via Baichuan
|
|
29996
|
+
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
29997
|
+
* release/duration — it's a pulse.
|
|
29998
|
+
*/
|
|
29999
|
+
onPressed: {
|
|
30000
|
+
data: DoorbellPressEventSchema,
|
|
30001
|
+
fromState: {
|
|
30002
|
+
field: "lastPressedAt",
|
|
30003
|
+
on: "advance"
|
|
30004
|
+
}
|
|
30005
|
+
} },
|
|
30006
|
+
status: {
|
|
30007
|
+
schema: DoorbellStatusSchema,
|
|
30008
|
+
kind: "push"
|
|
30009
|
+
},
|
|
30010
|
+
/**
|
|
30011
|
+
* Runtime-state slice — last press timestamp + lifetime press count.
|
|
30012
|
+
* Mirrored by the kernel and readable via
|
|
30013
|
+
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
30014
|
+
* without subscribing.
|
|
30015
|
+
*/
|
|
30016
|
+
runtimeState: DoorbellStatusSchema,
|
|
30017
|
+
/**
|
|
30018
|
+
* 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.
|
|
30019
|
+
*
|
|
30020
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
30021
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
30022
|
+
*/
|
|
30023
|
+
durability: "restored"
|
|
30024
|
+
};
|
|
29969
30025
|
/**
|
|
29970
30026
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
29971
30027
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -32110,9 +32166,9 @@ var MotionStatusSchema = object({
|
|
|
32110
32166
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
32111
32167
|
lastDetectedAt: number().nullable(),
|
|
32112
32168
|
/**
|
|
32113
|
-
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device
|
|
32114
|
-
* `null` while false and on every `Sensor`
|
|
32115
|
-
* constant's doc for the one-authority rule.
|
|
32169
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
|
|
32170
|
+
* orchestrator writes it, D696), `null` while false and on every `Sensor`
|
|
32171
|
+
* device (D475) — see that constant's doc for the one-authority rule.
|
|
32116
32172
|
*
|
|
32117
32173
|
* ## Reading this field still arms nothing
|
|
32118
32174
|
*
|
|
@@ -32130,34 +32186,31 @@ var MotionStatusSchema = object({
|
|
|
32130
32186
|
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
32131
32187
|
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
32132
32188
|
*
|
|
32133
|
-
* ## Who writes it
|
|
32134
|
-
*
|
|
32135
|
-
* - **Cameras** — the
|
|
32136
|
-
*
|
|
32137
|
-
* `
|
|
32138
|
-
* `
|
|
32139
|
-
*
|
|
32140
|
-
*
|
|
32141
|
-
* a
|
|
32142
|
-
*
|
|
32143
|
-
*
|
|
32144
|
-
*
|
|
32145
|
-
*
|
|
32146
|
-
*
|
|
32147
|
-
*
|
|
32148
|
-
*
|
|
32149
|
-
*
|
|
32150
|
-
*
|
|
32151
|
-
* `
|
|
32152
|
-
*
|
|
32153
|
-
*
|
|
32154
|
-
*
|
|
32155
|
-
*
|
|
32156
|
-
*
|
|
32157
|
-
*
|
|
32158
|
-
* This predates D475 and is not fixed there: the fix touches every
|
|
32159
|
-
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
32160
|
-
* "sole writer" wording without also removing the other writers.
|
|
32189
|
+
* ## Who writes it (D696)
|
|
32190
|
+
*
|
|
32191
|
+
* - **Cameras** — the orchestrator, and nothing else. It writes the camera's
|
|
32192
|
+
* EFFECTIVE motion (`addon-pipeline-orchestrator`
|
|
32193
|
+
* `camera-sensors/motion-slice.ts`), alongside the effective
|
|
32194
|
+
* `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
|
|
32195
|
+
* for a split camera, an unsplit emitter's direct event, the analyzer and
|
|
32196
|
+
* device activity, as the camera's `motionSources` counts them. A source
|
|
32197
|
+
* that never sends a clear falls one window after its last `true`.
|
|
32198
|
+
* `lastDetectedAt` moves only on an effective rise. No camera provider
|
|
32199
|
+
* writes this slice (not even a boot seed), and neither does the runner's
|
|
32200
|
+
* phase machine: its phase is "a session is attached" for every on-motion
|
|
32201
|
+
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
32202
|
+
* A provider's `isDetected` answers from the hub's slice.
|
|
32203
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
32204
|
+
* imports) — the provider pushes both edges itself, from the upstream
|
|
32205
|
+
* system's own state change. That is the sensor's own fact.
|
|
32206
|
+
*
|
|
32207
|
+
* `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
|
|
32208
|
+
* `motion` slice; each sensor writer is a named exemption.
|
|
32209
|
+
*
|
|
32210
|
+
* This replaces the D475 §4 rule ("the phase machine is the sole writer").
|
|
32211
|
+
* That rule was never true: Hikvision and Amcrest wrote the slice raw beside
|
|
32212
|
+
* it, every provider seeded it at boot, and every session left it
|
|
32213
|
+
* `detected: true` after its detach.
|
|
32161
32214
|
*/
|
|
32162
32215
|
autoClearAfterMs: number().nullable()
|
|
32163
32216
|
});
|
|
@@ -32229,11 +32282,12 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
32229
32282
|
*/
|
|
32230
32283
|
runtimeState: MotionStatusSchema,
|
|
32231
32284
|
/**
|
|
32232
|
-
* Runtime-state durability: **session** —
|
|
32285
|
+
* Runtime-state durability: **session** — the writer of this slice
|
|
32233
32286
|
* writes only on an EDGE, so a restored `detected: true` would stay
|
|
32234
32287
|
* frozen until the next one instead of being corrected. The next edge
|
|
32235
|
-
* re-publishes the real state
|
|
32236
|
-
*
|
|
32288
|
+
* re-publishes the real state, and the orchestrator re-publishes every
|
|
32289
|
+
* camera when it starts writing (D696; on who writes it, see
|
|
32290
|
+
* `autoClearAfterMs` above).
|
|
32237
32291
|
*
|
|
32238
32292
|
* See `RuntimeStateDurability`. Enforced by
|
|
32239
32293
|
* `scripts/check-runtime-state-durability.ts`.
|
|
@@ -34616,8 +34670,7 @@ var ptzAutotrackCapability = {
|
|
|
34616
34670
|
deviceNative: true,
|
|
34617
34671
|
mode: "singleton",
|
|
34618
34672
|
/**
|
|
34619
|
-
* Two kinds of provider behind one name, the same shape `snapshot`
|
|
34620
|
-
* `doorbell` use:
|
|
34673
|
+
* Two kinds of provider behind one name, the same shape `snapshot` uses:
|
|
34621
34674
|
*
|
|
34622
34675
|
* - **Native**: the camera's own firmware autotrack, registered per device by
|
|
34623
34676
|
* the driver when the probe says it exists (Reolink: yes; Hikvision:
|
|
@@ -34625,7 +34678,7 @@ var ptzAutotrackCapability = {
|
|
|
34625
34678
|
* - **Wrapper**: the emulated implementation (`@camstack/system`'s `autotrack` builtin),
|
|
34626
34679
|
* which follows a subject with `ptz.move` pulses driven by the detection
|
|
34627
34680
|
* pipeline. `defaultActive: false` — the operator binds it per camera in
|
|
34628
|
-
* the bindings UI
|
|
34681
|
+
* the bindings UI.
|
|
34629
34682
|
*
|
|
34630
34683
|
* The binding chooses WHICH implementation answers; `setEnabled` stays the
|
|
34631
34684
|
* one switch for the function either way. A camera never has both driving its
|
|
@@ -35300,7 +35353,7 @@ var ReadGopBytesResultSchema = object({
|
|
|
35300
35353
|
/**
|
|
35301
35354
|
* A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
|
|
35302
35355
|
* twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
|
|
35303
|
-
* replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-
|
|
35356
|
+
* replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
|
|
35304
35357
|
* a replay needs several seconds of native pixels, not one frame.
|
|
35305
35358
|
*
|
|
35306
35359
|
* `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
|
|
@@ -38664,6 +38717,7 @@ var zoneRulesCapability = {
|
|
|
38664
38717
|
*/
|
|
38665
38718
|
durability: "restored"
|
|
38666
38719
|
};
|
|
38720
|
+
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
38667
38721
|
/**
|
|
38668
38722
|
* Accessory device helpers — shared across drivers.
|
|
38669
38723
|
*
|
|
@@ -39723,13 +39777,14 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
39723
39777
|
async getStatus() {
|
|
39724
39778
|
const all = await this.ctx.kernel.devices?.getAll() ?? [];
|
|
39725
39779
|
const summary = this.restoreFailureSummary();
|
|
39726
|
-
|
|
39780
|
+
const base = {
|
|
39727
39781
|
connected: true,
|
|
39728
|
-
deviceCount: all.length
|
|
39782
|
+
deviceCount: all.length,
|
|
39783
|
+
motionSliceWriter: "orchestrator"
|
|
39729
39784
|
};
|
|
39785
|
+
if (summary === null) return base;
|
|
39730
39786
|
return {
|
|
39731
|
-
|
|
39732
|
-
deviceCount: all.length,
|
|
39787
|
+
...base,
|
|
39733
39788
|
error: summary
|
|
39734
39789
|
};
|
|
39735
39790
|
}
|
|
@@ -45165,6 +45220,12 @@ Object.freeze({
|
|
|
45165
45220
|
addonId: null,
|
|
45166
45221
|
access: "view"
|
|
45167
45222
|
},
|
|
45223
|
+
"notificationRules.getAlarmSensors": {
|
|
45224
|
+
capName: "notification-rules",
|
|
45225
|
+
capScope: "system",
|
|
45226
|
+
addonId: null,
|
|
45227
|
+
access: "view"
|
|
45228
|
+
},
|
|
45168
45229
|
"notificationRules.getClipRetentionAsks": {
|
|
45169
45230
|
capName: "notification-rules",
|
|
45170
45231
|
capScope: "system",
|
|
@@ -48743,6 +48804,11 @@ Object.freeze({
|
|
|
48743
48804
|
}
|
|
48744
48805
|
});
|
|
48745
48806
|
Object.freeze({
|
|
48807
|
+
"accessories.getStatus": [{
|
|
48808
|
+
name: "deviceId",
|
|
48809
|
+
form: "single",
|
|
48810
|
+
optional: false
|
|
48811
|
+
}],
|
|
48746
48812
|
"accessories.setChildHidden": [{
|
|
48747
48813
|
name: "childDeviceId",
|
|
48748
48814
|
form: "single",
|
|
@@ -48762,6 +48828,11 @@ Object.freeze({
|
|
|
48762
48828
|
form: "single",
|
|
48763
48829
|
optional: false
|
|
48764
48830
|
}],
|
|
48831
|
+
"airQualitySensor.getStatus": [{
|
|
48832
|
+
name: "deviceId",
|
|
48833
|
+
form: "single",
|
|
48834
|
+
optional: false
|
|
48835
|
+
}],
|
|
48765
48836
|
"alarmPanel.arm": [{
|
|
48766
48837
|
name: "deviceId",
|
|
48767
48838
|
form: "single",
|
|
@@ -48772,11 +48843,36 @@ Object.freeze({
|
|
|
48772
48843
|
form: "single",
|
|
48773
48844
|
optional: false
|
|
48774
48845
|
}],
|
|
48846
|
+
"alarmPanel.getStatus": [{
|
|
48847
|
+
name: "deviceId",
|
|
48848
|
+
form: "single",
|
|
48849
|
+
optional: false
|
|
48850
|
+
}],
|
|
48775
48851
|
"alarmPanel.trigger": [{
|
|
48776
48852
|
name: "deviceId",
|
|
48777
48853
|
form: "single",
|
|
48778
48854
|
optional: false
|
|
48779
48855
|
}],
|
|
48856
|
+
"ambientLightSensor.getStatus": [{
|
|
48857
|
+
name: "deviceId",
|
|
48858
|
+
form: "single",
|
|
48859
|
+
optional: false
|
|
48860
|
+
}],
|
|
48861
|
+
"audioAnalysis.applyDeviceSettingsPatch": [{
|
|
48862
|
+
name: "deviceId",
|
|
48863
|
+
form: "single",
|
|
48864
|
+
optional: false
|
|
48865
|
+
}],
|
|
48866
|
+
"audioAnalysis.getDeviceLiveContribution": [{
|
|
48867
|
+
name: "deviceId",
|
|
48868
|
+
form: "single",
|
|
48869
|
+
optional: false
|
|
48870
|
+
}],
|
|
48871
|
+
"audioAnalysis.getDeviceSettingsContribution": [{
|
|
48872
|
+
name: "deviceId",
|
|
48873
|
+
form: "single",
|
|
48874
|
+
optional: false
|
|
48875
|
+
}],
|
|
48780
48876
|
"audioAnalysis.resolveDeviceSettings": [{
|
|
48781
48877
|
name: "deviceId",
|
|
48782
48878
|
form: "single",
|
|
@@ -48817,16 +48913,36 @@ Object.freeze({
|
|
|
48817
48913
|
form: "single",
|
|
48818
48914
|
optional: false
|
|
48819
48915
|
}],
|
|
48916
|
+
"automationControl.getStatus": [{
|
|
48917
|
+
name: "deviceId",
|
|
48918
|
+
form: "single",
|
|
48919
|
+
optional: false
|
|
48920
|
+
}],
|
|
48820
48921
|
"automationControl.trigger": [{
|
|
48821
48922
|
name: "deviceId",
|
|
48822
48923
|
form: "single",
|
|
48823
48924
|
optional: false
|
|
48824
48925
|
}],
|
|
48926
|
+
"battery.getStatus": [{
|
|
48927
|
+
name: "deviceId",
|
|
48928
|
+
form: "single",
|
|
48929
|
+
optional: false
|
|
48930
|
+
}],
|
|
48825
48931
|
"battery.wakeForStream": [{
|
|
48826
48932
|
name: "deviceId",
|
|
48827
48933
|
form: "single",
|
|
48828
48934
|
optional: false
|
|
48829
48935
|
}],
|
|
48936
|
+
"binary.getStatus": [{
|
|
48937
|
+
name: "deviceId",
|
|
48938
|
+
form: "single",
|
|
48939
|
+
optional: false
|
|
48940
|
+
}],
|
|
48941
|
+
"brightness.getStatus": [{
|
|
48942
|
+
name: "deviceId",
|
|
48943
|
+
form: "single",
|
|
48944
|
+
optional: false
|
|
48945
|
+
}],
|
|
48830
48946
|
"brightness.setBrightness": [{
|
|
48831
48947
|
name: "deviceId",
|
|
48832
48948
|
form: "single",
|
|
@@ -48842,6 +48958,26 @@ Object.freeze({
|
|
|
48842
48958
|
form: "single",
|
|
48843
48959
|
optional: false
|
|
48844
48960
|
}],
|
|
48961
|
+
"cameraCredentials.getStatus": [{
|
|
48962
|
+
name: "deviceId",
|
|
48963
|
+
form: "single",
|
|
48964
|
+
optional: false
|
|
48965
|
+
}],
|
|
48966
|
+
"cameraGridLayout.applyDeviceSettingsPatch": [{
|
|
48967
|
+
name: "deviceId",
|
|
48968
|
+
form: "single",
|
|
48969
|
+
optional: false
|
|
48970
|
+
}],
|
|
48971
|
+
"cameraGridLayout.getDeviceLiveContribution": [{
|
|
48972
|
+
name: "deviceId",
|
|
48973
|
+
form: "single",
|
|
48974
|
+
optional: false
|
|
48975
|
+
}],
|
|
48976
|
+
"cameraGridLayout.getDeviceSettingsContribution": [{
|
|
48977
|
+
name: "deviceId",
|
|
48978
|
+
form: "single",
|
|
48979
|
+
optional: false
|
|
48980
|
+
}],
|
|
48845
48981
|
"cameraGridLayout.getLayout": [{
|
|
48846
48982
|
name: "deviceId",
|
|
48847
48983
|
form: "single",
|
|
@@ -48857,6 +48993,21 @@ Object.freeze({
|
|
|
48857
48993
|
form: "single",
|
|
48858
48994
|
optional: false
|
|
48859
48995
|
}],
|
|
48996
|
+
"cameraPipelineConfig.applyDeviceSettingsPatch": [{
|
|
48997
|
+
name: "deviceId",
|
|
48998
|
+
form: "single",
|
|
48999
|
+
optional: false
|
|
49000
|
+
}],
|
|
49001
|
+
"cameraPipelineConfig.getDeviceLiveContribution": [{
|
|
49002
|
+
name: "deviceId",
|
|
49003
|
+
form: "single",
|
|
49004
|
+
optional: false
|
|
49005
|
+
}],
|
|
49006
|
+
"cameraPipelineConfig.getDeviceSettingsContribution": [{
|
|
49007
|
+
name: "deviceId",
|
|
49008
|
+
form: "single",
|
|
49009
|
+
optional: false
|
|
49010
|
+
}],
|
|
48860
49011
|
"cameraStreams.getBrokerStreams": [{
|
|
48861
49012
|
name: "deviceId",
|
|
48862
49013
|
form: "single",
|
|
@@ -48882,6 +49033,16 @@ Object.freeze({
|
|
|
48882
49033
|
form: "single",
|
|
48883
49034
|
optional: false
|
|
48884
49035
|
}],
|
|
49036
|
+
"carbonMonoxide.getStatus": [{
|
|
49037
|
+
name: "deviceId",
|
|
49038
|
+
form: "single",
|
|
49039
|
+
optional: false
|
|
49040
|
+
}],
|
|
49041
|
+
"climateControl.getStatus": [{
|
|
49042
|
+
name: "deviceId",
|
|
49043
|
+
form: "single",
|
|
49044
|
+
optional: false
|
|
49045
|
+
}],
|
|
48885
49046
|
"climateControl.setFanMode": [{
|
|
48886
49047
|
name: "deviceId",
|
|
48887
49048
|
form: "single",
|
|
@@ -48922,16 +49083,41 @@ Object.freeze({
|
|
|
48922
49083
|
form: "single",
|
|
48923
49084
|
optional: false
|
|
48924
49085
|
}],
|
|
49086
|
+
"color.getStatus": [{
|
|
49087
|
+
name: "deviceId",
|
|
49088
|
+
form: "single",
|
|
49089
|
+
optional: false
|
|
49090
|
+
}],
|
|
48925
49091
|
"color.setColor": [{
|
|
48926
49092
|
name: "deviceId",
|
|
48927
49093
|
form: "single",
|
|
48928
49094
|
optional: false
|
|
48929
49095
|
}],
|
|
49096
|
+
"connectivity.getStatus": [{
|
|
49097
|
+
name: "deviceId",
|
|
49098
|
+
form: "single",
|
|
49099
|
+
optional: false
|
|
49100
|
+
}],
|
|
49101
|
+
"consumables.getStatus": [{
|
|
49102
|
+
name: "deviceId",
|
|
49103
|
+
form: "single",
|
|
49104
|
+
optional: false
|
|
49105
|
+
}],
|
|
48930
49106
|
"consumables.reset": [{
|
|
48931
49107
|
name: "deviceId",
|
|
48932
49108
|
form: "single",
|
|
48933
49109
|
optional: false
|
|
48934
49110
|
}],
|
|
49111
|
+
"contact.getStatus": [{
|
|
49112
|
+
name: "deviceId",
|
|
49113
|
+
form: "single",
|
|
49114
|
+
optional: false
|
|
49115
|
+
}],
|
|
49116
|
+
"control.getStatus": [{
|
|
49117
|
+
name: "deviceId",
|
|
49118
|
+
form: "single",
|
|
49119
|
+
optional: false
|
|
49120
|
+
}],
|
|
48935
49121
|
"control.setValue": [{
|
|
48936
49122
|
name: "deviceId",
|
|
48937
49123
|
form: "single",
|
|
@@ -48942,6 +49128,11 @@ Object.freeze({
|
|
|
48942
49128
|
form: "single",
|
|
48943
49129
|
optional: false
|
|
48944
49130
|
}],
|
|
49131
|
+
"cover.getStatus": [{
|
|
49132
|
+
name: "deviceId",
|
|
49133
|
+
form: "single",
|
|
49134
|
+
optional: false
|
|
49135
|
+
}],
|
|
48945
49136
|
"cover.open": [{
|
|
48946
49137
|
name: "deviceId",
|
|
48947
49138
|
form: "single",
|
|
@@ -48967,6 +49158,11 @@ Object.freeze({
|
|
|
48967
49158
|
form: "single",
|
|
48968
49159
|
optional: false
|
|
48969
49160
|
}],
|
|
49161
|
+
"dayNight.getStatus": [{
|
|
49162
|
+
name: "deviceId",
|
|
49163
|
+
form: "single",
|
|
49164
|
+
optional: false
|
|
49165
|
+
}],
|
|
48970
49166
|
"dayNight.setSettings": [{
|
|
48971
49167
|
name: "deviceId",
|
|
48972
49168
|
form: "single",
|
|
@@ -48977,11 +49173,31 @@ Object.freeze({
|
|
|
48977
49173
|
form: "single",
|
|
48978
49174
|
optional: true
|
|
48979
49175
|
}],
|
|
49176
|
+
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
49177
|
+
name: "deviceId",
|
|
49178
|
+
form: "single",
|
|
49179
|
+
optional: false
|
|
49180
|
+
}],
|
|
49181
|
+
"detectionPipeline.getDeviceLiveContribution": [{
|
|
49182
|
+
name: "deviceId",
|
|
49183
|
+
form: "single",
|
|
49184
|
+
optional: false
|
|
49185
|
+
}],
|
|
49186
|
+
"detectionPipeline.getDeviceSettingsContribution": [{
|
|
49187
|
+
name: "deviceId",
|
|
49188
|
+
form: "single",
|
|
49189
|
+
optional: false
|
|
49190
|
+
}],
|
|
48980
49191
|
"deviceAdminLink.getAdminLink": [{
|
|
48981
49192
|
name: "deviceId",
|
|
48982
49193
|
form: "single",
|
|
48983
49194
|
optional: false
|
|
48984
49195
|
}],
|
|
49196
|
+
"deviceAdoption.getStatus": [{
|
|
49197
|
+
name: "deviceId",
|
|
49198
|
+
form: "single",
|
|
49199
|
+
optional: false
|
|
49200
|
+
}],
|
|
48985
49201
|
"deviceAdoption.release": [{
|
|
48986
49202
|
name: "camDeviceId",
|
|
48987
49203
|
form: "single",
|
|
@@ -48997,6 +49213,11 @@ Object.freeze({
|
|
|
48997
49213
|
form: "single",
|
|
48998
49214
|
optional: false
|
|
48999
49215
|
}],
|
|
49216
|
+
"deviceDiscovery.getStatus": [{
|
|
49217
|
+
name: "deviceId",
|
|
49218
|
+
form: "single",
|
|
49219
|
+
optional: false
|
|
49220
|
+
}],
|
|
49000
49221
|
"deviceDiscovery.listDiscovered": [{
|
|
49001
49222
|
name: "deviceId",
|
|
49002
49223
|
form: "single",
|
|
@@ -49016,6 +49237,21 @@ Object.freeze({
|
|
|
49016
49237
|
form: "single",
|
|
49017
49238
|
optional: false
|
|
49018
49239
|
}],
|
|
49240
|
+
"deviceExport.applyDeviceSettingsPatch": [{
|
|
49241
|
+
name: "deviceId",
|
|
49242
|
+
form: "single",
|
|
49243
|
+
optional: false
|
|
49244
|
+
}],
|
|
49245
|
+
"deviceExport.getDeviceLiveContribution": [{
|
|
49246
|
+
name: "deviceId",
|
|
49247
|
+
form: "single",
|
|
49248
|
+
optional: false
|
|
49249
|
+
}],
|
|
49250
|
+
"deviceExport.getDeviceSettingsContribution": [{
|
|
49251
|
+
name: "deviceId",
|
|
49252
|
+
form: "single",
|
|
49253
|
+
optional: false
|
|
49254
|
+
}],
|
|
49019
49255
|
"deviceExtension.listCandidates": [{
|
|
49020
49256
|
name: "deviceId",
|
|
49021
49257
|
form: "single",
|
|
@@ -49364,6 +49600,26 @@ Object.freeze({
|
|
|
49364
49600
|
form: "single",
|
|
49365
49601
|
optional: false
|
|
49366
49602
|
}],
|
|
49603
|
+
"deviceStatus.getStatus": [{
|
|
49604
|
+
name: "deviceId",
|
|
49605
|
+
form: "single",
|
|
49606
|
+
optional: false
|
|
49607
|
+
}],
|
|
49608
|
+
"doorbell.getStatus": [{
|
|
49609
|
+
name: "deviceId",
|
|
49610
|
+
form: "single",
|
|
49611
|
+
optional: false
|
|
49612
|
+
}],
|
|
49613
|
+
"enumSensor.getStatus": [{
|
|
49614
|
+
name: "deviceId",
|
|
49615
|
+
form: "single",
|
|
49616
|
+
optional: false
|
|
49617
|
+
}],
|
|
49618
|
+
"eventEmitter.getStatus": [{
|
|
49619
|
+
name: "deviceId",
|
|
49620
|
+
form: "single",
|
|
49621
|
+
optional: false
|
|
49622
|
+
}],
|
|
49367
49623
|
"faceGallery.getFaceByTrack": [{
|
|
49368
49624
|
name: "deviceId",
|
|
49369
49625
|
form: "single",
|
|
@@ -49378,6 +49634,11 @@ Object.freeze({
|
|
|
49378
49634
|
form: "array",
|
|
49379
49635
|
optional: true
|
|
49380
49636
|
}],
|
|
49637
|
+
"fanControl.getStatus": [{
|
|
49638
|
+
name: "deviceId",
|
|
49639
|
+
form: "single",
|
|
49640
|
+
optional: false
|
|
49641
|
+
}],
|
|
49381
49642
|
"fanControl.setDirection": [{
|
|
49382
49643
|
name: "deviceId",
|
|
49383
49644
|
form: "single",
|
|
@@ -49398,6 +49659,26 @@ Object.freeze({
|
|
|
49398
49659
|
form: "single",
|
|
49399
49660
|
optional: false
|
|
49400
49661
|
}],
|
|
49662
|
+
"featureProbe.getStatus": [{
|
|
49663
|
+
name: "deviceId",
|
|
49664
|
+
form: "single",
|
|
49665
|
+
optional: false
|
|
49666
|
+
}],
|
|
49667
|
+
"flood.getStatus": [{
|
|
49668
|
+
name: "deviceId",
|
|
49669
|
+
form: "single",
|
|
49670
|
+
optional: false
|
|
49671
|
+
}],
|
|
49672
|
+
"gas.getStatus": [{
|
|
49673
|
+
name: "deviceId",
|
|
49674
|
+
form: "single",
|
|
49675
|
+
optional: false
|
|
49676
|
+
}],
|
|
49677
|
+
"humidifier.getStatus": [{
|
|
49678
|
+
name: "deviceId",
|
|
49679
|
+
form: "single",
|
|
49680
|
+
optional: false
|
|
49681
|
+
}],
|
|
49401
49682
|
"humidifier.setMode": [{
|
|
49402
49683
|
name: "deviceId",
|
|
49403
49684
|
form: "single",
|
|
@@ -49413,11 +49694,26 @@ Object.freeze({
|
|
|
49413
49694
|
form: "single",
|
|
49414
49695
|
optional: false
|
|
49415
49696
|
}],
|
|
49697
|
+
"humiditySensor.getStatus": [{
|
|
49698
|
+
name: "deviceId",
|
|
49699
|
+
form: "single",
|
|
49700
|
+
optional: false
|
|
49701
|
+
}],
|
|
49702
|
+
"image.getStatus": [{
|
|
49703
|
+
name: "deviceId",
|
|
49704
|
+
form: "single",
|
|
49705
|
+
optional: false
|
|
49706
|
+
}],
|
|
49416
49707
|
"imageSettings.getOptions": [{
|
|
49417
49708
|
name: "deviceId",
|
|
49418
49709
|
form: "single",
|
|
49419
49710
|
optional: false
|
|
49420
49711
|
}],
|
|
49712
|
+
"imageSettings.getStatus": [{
|
|
49713
|
+
name: "deviceId",
|
|
49714
|
+
form: "single",
|
|
49715
|
+
optional: false
|
|
49716
|
+
}],
|
|
49421
49717
|
"imageSettings.setSettings": [{
|
|
49422
49718
|
name: "deviceId",
|
|
49423
49719
|
form: "single",
|
|
@@ -49428,6 +49724,11 @@ Object.freeze({
|
|
|
49428
49724
|
form: "single",
|
|
49429
49725
|
optional: false
|
|
49430
49726
|
}],
|
|
49727
|
+
"intercom.getStatus": [{
|
|
49728
|
+
name: "deviceId",
|
|
49729
|
+
form: "single",
|
|
49730
|
+
optional: false
|
|
49731
|
+
}],
|
|
49431
49732
|
"intercom.handleAnswer": [{
|
|
49432
49733
|
name: "deviceId",
|
|
49433
49734
|
form: "single",
|
|
@@ -49458,6 +49759,11 @@ Object.freeze({
|
|
|
49458
49759
|
form: "single",
|
|
49459
49760
|
optional: false
|
|
49460
49761
|
}],
|
|
49762
|
+
"lawnMowerControl.getStatus": [{
|
|
49763
|
+
name: "deviceId",
|
|
49764
|
+
form: "single",
|
|
49765
|
+
optional: false
|
|
49766
|
+
}],
|
|
49461
49767
|
"lawnMowerControl.pause": [{
|
|
49462
49768
|
name: "deviceId",
|
|
49463
49769
|
form: "single",
|
|
@@ -49468,6 +49774,11 @@ Object.freeze({
|
|
|
49468
49774
|
form: "single",
|
|
49469
49775
|
optional: false
|
|
49470
49776
|
}],
|
|
49777
|
+
"lockControl.getStatus": [{
|
|
49778
|
+
name: "deviceId",
|
|
49779
|
+
form: "single",
|
|
49780
|
+
optional: false
|
|
49781
|
+
}],
|
|
49471
49782
|
"lockControl.lock": [{
|
|
49472
49783
|
name: "deviceId",
|
|
49473
49784
|
form: "single",
|
|
@@ -49483,6 +49794,11 @@ Object.freeze({
|
|
|
49483
49794
|
form: "single",
|
|
49484
49795
|
optional: false
|
|
49485
49796
|
}],
|
|
49797
|
+
"mediaPlayer.getStatus": [{
|
|
49798
|
+
name: "deviceId",
|
|
49799
|
+
form: "single",
|
|
49800
|
+
optional: false
|
|
49801
|
+
}],
|
|
49486
49802
|
"mediaPlayer.next": [{
|
|
49487
49803
|
name: "deviceId",
|
|
49488
49804
|
form: "single",
|
|
@@ -49543,6 +49859,11 @@ Object.freeze({
|
|
|
49543
49859
|
form: "single",
|
|
49544
49860
|
optional: false
|
|
49545
49861
|
}],
|
|
49862
|
+
"motion.getStatus": [{
|
|
49863
|
+
name: "deviceId",
|
|
49864
|
+
form: "single",
|
|
49865
|
+
optional: false
|
|
49866
|
+
}],
|
|
49546
49867
|
"motion.isDetected": [{
|
|
49547
49868
|
name: "deviceId",
|
|
49548
49869
|
form: "single",
|
|
@@ -49553,11 +49874,31 @@ Object.freeze({
|
|
|
49553
49874
|
form: "single",
|
|
49554
49875
|
optional: false
|
|
49555
49876
|
}],
|
|
49877
|
+
"motionDetection.applyDeviceSettingsPatch": [{
|
|
49878
|
+
name: "deviceId",
|
|
49879
|
+
form: "single",
|
|
49880
|
+
optional: false
|
|
49881
|
+
}],
|
|
49882
|
+
"motionDetection.getDeviceLiveContribution": [{
|
|
49883
|
+
name: "deviceId",
|
|
49884
|
+
form: "single",
|
|
49885
|
+
optional: false
|
|
49886
|
+
}],
|
|
49887
|
+
"motionDetection.getDeviceSettingsContribution": [{
|
|
49888
|
+
name: "deviceId",
|
|
49889
|
+
form: "single",
|
|
49890
|
+
optional: false
|
|
49891
|
+
}],
|
|
49556
49892
|
"motionDetection.removeCamera": [{
|
|
49557
49893
|
name: "deviceId",
|
|
49558
49894
|
form: "single",
|
|
49559
49895
|
optional: false
|
|
49560
49896
|
}],
|
|
49897
|
+
"motionTrigger.getStatus": [{
|
|
49898
|
+
name: "deviceId",
|
|
49899
|
+
form: "single",
|
|
49900
|
+
optional: false
|
|
49901
|
+
}],
|
|
49561
49902
|
"motionTrigger.setMotionTrigger": [{
|
|
49562
49903
|
name: "deviceId",
|
|
49563
49904
|
form: "single",
|
|
@@ -49568,6 +49909,11 @@ Object.freeze({
|
|
|
49568
49909
|
form: "single",
|
|
49569
49910
|
optional: false
|
|
49570
49911
|
}],
|
|
49912
|
+
"motionZones.getStatus": [{
|
|
49913
|
+
name: "deviceId",
|
|
49914
|
+
form: "single",
|
|
49915
|
+
optional: false
|
|
49916
|
+
}],
|
|
49571
49917
|
"motionZones.setZone": [{
|
|
49572
49918
|
name: "deviceId",
|
|
49573
49919
|
form: "single",
|
|
@@ -49578,6 +49924,11 @@ Object.freeze({
|
|
|
49578
49924
|
form: "single",
|
|
49579
49925
|
optional: false
|
|
49580
49926
|
}],
|
|
49927
|
+
"nativeObjectDetection.getStatus": [{
|
|
49928
|
+
name: "deviceId",
|
|
49929
|
+
form: "single",
|
|
49930
|
+
optional: false
|
|
49931
|
+
}],
|
|
49581
49932
|
"nativeObjectDetection.setEnabled": [{
|
|
49582
49933
|
name: "deviceId",
|
|
49583
49934
|
form: "single",
|
|
@@ -49593,6 +49944,11 @@ Object.freeze({
|
|
|
49593
49944
|
form: "single",
|
|
49594
49945
|
optional: false
|
|
49595
49946
|
}],
|
|
49947
|
+
"navigation.getStatus": [{
|
|
49948
|
+
name: "deviceId",
|
|
49949
|
+
form: "single",
|
|
49950
|
+
optional: false
|
|
49951
|
+
}],
|
|
49596
49952
|
"navigation.goToPoint": [{
|
|
49597
49953
|
name: "deviceId",
|
|
49598
49954
|
form: "single",
|
|
@@ -49638,6 +49994,11 @@ Object.freeze({
|
|
|
49638
49994
|
form: "single",
|
|
49639
49995
|
optional: false
|
|
49640
49996
|
}],
|
|
49997
|
+
"networkLink.getStatus": [{
|
|
49998
|
+
name: "deviceId",
|
|
49999
|
+
form: "single",
|
|
50000
|
+
optional: false
|
|
50001
|
+
}],
|
|
49641
50002
|
"networkQuality.getDeviceStats": [{
|
|
49642
50003
|
name: "deviceId",
|
|
49643
50004
|
form: "single",
|
|
@@ -49648,6 +50009,11 @@ Object.freeze({
|
|
|
49648
50009
|
form: "single",
|
|
49649
50010
|
optional: false
|
|
49650
50011
|
}],
|
|
50012
|
+
"notificationRules.getAlarmSensors": [{
|
|
50013
|
+
name: "deviceIds",
|
|
50014
|
+
form: "array",
|
|
50015
|
+
optional: false
|
|
50016
|
+
}],
|
|
49651
50017
|
"notificationRules.setDeviceMuted": [{
|
|
49652
50018
|
name: "deviceId",
|
|
49653
50019
|
form: "single",
|
|
@@ -49658,11 +50024,26 @@ Object.freeze({
|
|
|
49658
50024
|
form: "single",
|
|
49659
50025
|
optional: false
|
|
49660
50026
|
}],
|
|
50027
|
+
"notifier.getStatus": [{
|
|
50028
|
+
name: "deviceId",
|
|
50029
|
+
form: "single",
|
|
50030
|
+
optional: false
|
|
50031
|
+
}],
|
|
49661
50032
|
"notifier.send": [{
|
|
49662
50033
|
name: "deviceId",
|
|
49663
50034
|
form: "single",
|
|
49664
50035
|
optional: false
|
|
49665
50036
|
}],
|
|
50037
|
+
"numericSensor.getStatus": [{
|
|
50038
|
+
name: "deviceId",
|
|
50039
|
+
form: "single",
|
|
50040
|
+
optional: false
|
|
50041
|
+
}],
|
|
50042
|
+
"osd.getStatus": [{
|
|
50043
|
+
name: "deviceId",
|
|
50044
|
+
form: "single",
|
|
50045
|
+
optional: false
|
|
50046
|
+
}],
|
|
49666
50047
|
"osd.setOverlay": [{
|
|
49667
50048
|
name: "deviceId",
|
|
49668
50049
|
form: "single",
|
|
@@ -49722,6 +50103,11 @@ Object.freeze({
|
|
|
49722
50103
|
form: "single",
|
|
49723
50104
|
optional: false
|
|
49724
50105
|
}],
|
|
50106
|
+
"petFeeder.getStatus": [{
|
|
50107
|
+
name: "deviceId",
|
|
50108
|
+
form: "single",
|
|
50109
|
+
optional: false
|
|
50110
|
+
}],
|
|
49725
50111
|
"petFeeder.markFoodReplenished": [{
|
|
49726
50112
|
name: "deviceId",
|
|
49727
50113
|
form: "single",
|
|
@@ -49757,6 +50143,11 @@ Object.freeze({
|
|
|
49757
50143
|
form: "single",
|
|
49758
50144
|
optional: false
|
|
49759
50145
|
}],
|
|
50146
|
+
"pipelineAnalytics.applyDeviceSettingsPatch": [{
|
|
50147
|
+
name: "deviceId",
|
|
50148
|
+
form: "single",
|
|
50149
|
+
optional: false
|
|
50150
|
+
}],
|
|
49760
50151
|
"pipelineAnalytics.clearTrackRelation": [{
|
|
49761
50152
|
name: "deviceId",
|
|
49762
50153
|
form: "single",
|
|
@@ -49797,6 +50188,16 @@ Object.freeze({
|
|
|
49797
50188
|
form: "single",
|
|
49798
50189
|
optional: false
|
|
49799
50190
|
}],
|
|
50191
|
+
"pipelineAnalytics.getDeviceLiveContribution": [{
|
|
50192
|
+
name: "deviceId",
|
|
50193
|
+
form: "single",
|
|
50194
|
+
optional: false
|
|
50195
|
+
}],
|
|
50196
|
+
"pipelineAnalytics.getDeviceSettingsContribution": [{
|
|
50197
|
+
name: "deviceId",
|
|
50198
|
+
form: "single",
|
|
50199
|
+
optional: false
|
|
50200
|
+
}],
|
|
49800
50201
|
"pipelineAnalytics.getEventDensity": [{
|
|
49801
50202
|
name: "deviceId",
|
|
49802
50203
|
form: "single",
|
|
@@ -50012,6 +50413,11 @@ Object.freeze({
|
|
|
50012
50413
|
form: "single",
|
|
50013
50414
|
optional: true
|
|
50014
50415
|
}],
|
|
50416
|
+
"pipelineOrchestrator.applyDeviceSettingsPatch": [{
|
|
50417
|
+
name: "deviceId",
|
|
50418
|
+
form: "single",
|
|
50419
|
+
optional: false
|
|
50420
|
+
}],
|
|
50015
50421
|
"pipelineOrchestrator.assignAudio": [{
|
|
50016
50422
|
name: "deviceId",
|
|
50017
50423
|
form: "single",
|
|
@@ -50057,6 +50463,16 @@ Object.freeze({
|
|
|
50057
50463
|
form: "single",
|
|
50058
50464
|
optional: false
|
|
50059
50465
|
}],
|
|
50466
|
+
"pipelineOrchestrator.getDeviceLiveContribution": [{
|
|
50467
|
+
name: "deviceId",
|
|
50468
|
+
form: "single",
|
|
50469
|
+
optional: false
|
|
50470
|
+
}],
|
|
50471
|
+
"pipelineOrchestrator.getDeviceSettingsContribution": [{
|
|
50472
|
+
name: "deviceId",
|
|
50473
|
+
form: "single",
|
|
50474
|
+
optional: false
|
|
50475
|
+
}],
|
|
50060
50476
|
"pipelineOrchestrator.getPipelineAssignment": [{
|
|
50061
50477
|
name: "deviceId",
|
|
50062
50478
|
form: "single",
|
|
@@ -50177,11 +50593,31 @@ Object.freeze({
|
|
|
50177
50593
|
form: "single",
|
|
50178
50594
|
optional: true
|
|
50179
50595
|
}],
|
|
50596
|
+
"powerMeter.getStatus": [{
|
|
50597
|
+
name: "deviceId",
|
|
50598
|
+
form: "single",
|
|
50599
|
+
optional: false
|
|
50600
|
+
}],
|
|
50601
|
+
"presence.getStatus": [{
|
|
50602
|
+
name: "deviceId",
|
|
50603
|
+
form: "single",
|
|
50604
|
+
optional: false
|
|
50605
|
+
}],
|
|
50606
|
+
"pressureSensor.getStatus": [{
|
|
50607
|
+
name: "deviceId",
|
|
50608
|
+
form: "single",
|
|
50609
|
+
optional: false
|
|
50610
|
+
}],
|
|
50180
50611
|
"privacyMask.getOptions": [{
|
|
50181
50612
|
name: "deviceId",
|
|
50182
50613
|
form: "single",
|
|
50183
50614
|
optional: false
|
|
50184
50615
|
}],
|
|
50616
|
+
"privacyMask.getStatus": [{
|
|
50617
|
+
name: "deviceId",
|
|
50618
|
+
form: "single",
|
|
50619
|
+
optional: false
|
|
50620
|
+
}],
|
|
50185
50621
|
"privacyMask.setAudioEnabled": [{
|
|
50186
50622
|
name: "deviceId",
|
|
50187
50623
|
form: "single",
|
|
@@ -50232,6 +50668,11 @@ Object.freeze({
|
|
|
50232
50668
|
form: "single",
|
|
50233
50669
|
optional: false
|
|
50234
50670
|
}],
|
|
50671
|
+
"ptz.getStatus": [{
|
|
50672
|
+
name: "deviceId",
|
|
50673
|
+
form: "single",
|
|
50674
|
+
optional: false
|
|
50675
|
+
}],
|
|
50235
50676
|
"ptz.goHome": [{
|
|
50236
50677
|
name: "deviceId",
|
|
50237
50678
|
form: "single",
|
|
@@ -50322,6 +50763,11 @@ Object.freeze({
|
|
|
50322
50763
|
form: "single",
|
|
50323
50764
|
optional: false
|
|
50324
50765
|
}],
|
|
50766
|
+
"recordingArchive.applyDeviceSettingsPatch": [{
|
|
50767
|
+
name: "deviceId",
|
|
50768
|
+
form: "single",
|
|
50769
|
+
optional: false
|
|
50770
|
+
}],
|
|
50325
50771
|
"recordingArchive.deleteFootprint": [{
|
|
50326
50772
|
name: "deviceId",
|
|
50327
50773
|
form: "single",
|
|
@@ -50342,6 +50788,21 @@ Object.freeze({
|
|
|
50342
50788
|
form: "single",
|
|
50343
50789
|
optional: false
|
|
50344
50790
|
}],
|
|
50791
|
+
"recordingArchive.getDeviceLiveContribution": [{
|
|
50792
|
+
name: "deviceId",
|
|
50793
|
+
form: "single",
|
|
50794
|
+
optional: false
|
|
50795
|
+
}],
|
|
50796
|
+
"recordingArchive.getDeviceSettingsContribution": [{
|
|
50797
|
+
name: "deviceId",
|
|
50798
|
+
form: "single",
|
|
50799
|
+
optional: false
|
|
50800
|
+
}],
|
|
50801
|
+
"recordingArchive.getStatus": [{
|
|
50802
|
+
name: "deviceId",
|
|
50803
|
+
form: "single",
|
|
50804
|
+
optional: false
|
|
50805
|
+
}],
|
|
50345
50806
|
"recordingArchive.listOpsLog": [{
|
|
50346
50807
|
name: "deviceId",
|
|
50347
50808
|
form: "single",
|
|
@@ -50427,6 +50888,11 @@ Object.freeze({
|
|
|
50427
50888
|
form: "single",
|
|
50428
50889
|
optional: false
|
|
50429
50890
|
}],
|
|
50891
|
+
"recordingOnboard.getStatus": [{
|
|
50892
|
+
name: "deviceId",
|
|
50893
|
+
form: "single",
|
|
50894
|
+
optional: false
|
|
50895
|
+
}],
|
|
50430
50896
|
"recordingOnboard.setSettings": [{
|
|
50431
50897
|
name: "deviceId",
|
|
50432
50898
|
form: "single",
|
|
@@ -50457,6 +50923,11 @@ Object.freeze({
|
|
|
50457
50923
|
form: "single",
|
|
50458
50924
|
optional: false
|
|
50459
50925
|
}],
|
|
50926
|
+
"sceneMonitor.getStatus": [{
|
|
50927
|
+
name: "deviceId",
|
|
50928
|
+
form: "single",
|
|
50929
|
+
optional: false
|
|
50930
|
+
}],
|
|
50460
50931
|
"sceneMonitor.listScenes": [{
|
|
50461
50932
|
name: "deviceId",
|
|
50462
50933
|
form: "single",
|
|
@@ -50482,6 +50953,11 @@ Object.freeze({
|
|
|
50482
50953
|
form: "single",
|
|
50483
50954
|
optional: false
|
|
50484
50955
|
}],
|
|
50956
|
+
"scriptRunner.getStatus": [{
|
|
50957
|
+
name: "deviceId",
|
|
50958
|
+
form: "single",
|
|
50959
|
+
optional: false
|
|
50960
|
+
}],
|
|
50485
50961
|
"scriptRunner.run": [{
|
|
50486
50962
|
name: "deviceId",
|
|
50487
50963
|
form: "single",
|
|
@@ -50492,11 +50968,31 @@ Object.freeze({
|
|
|
50492
50968
|
form: "single",
|
|
50493
50969
|
optional: false
|
|
50494
50970
|
}],
|
|
50971
|
+
"smoke.getStatus": [{
|
|
50972
|
+
name: "deviceId",
|
|
50973
|
+
form: "single",
|
|
50974
|
+
optional: false
|
|
50975
|
+
}],
|
|
50976
|
+
"snapshot.applyDeviceSettingsPatch": [{
|
|
50977
|
+
name: "deviceId",
|
|
50978
|
+
form: "single",
|
|
50979
|
+
optional: false
|
|
50980
|
+
}],
|
|
50495
50981
|
"snapshot.getDebugState": [{
|
|
50496
50982
|
name: "deviceId",
|
|
50497
50983
|
form: "single",
|
|
50498
50984
|
optional: false
|
|
50499
50985
|
}],
|
|
50986
|
+
"snapshot.getDeviceLiveContribution": [{
|
|
50987
|
+
name: "deviceId",
|
|
50988
|
+
form: "single",
|
|
50989
|
+
optional: false
|
|
50990
|
+
}],
|
|
50991
|
+
"snapshot.getDeviceSettingsContribution": [{
|
|
50992
|
+
name: "deviceId",
|
|
50993
|
+
form: "single",
|
|
50994
|
+
optional: false
|
|
50995
|
+
}],
|
|
50500
50996
|
"snapshot.getSnapshot": [{
|
|
50501
50997
|
name: "deviceId",
|
|
50502
50998
|
form: "single",
|
|
@@ -50513,6 +51009,11 @@ Object.freeze({
|
|
|
50513
51009
|
form: "array",
|
|
50514
51010
|
optional: false
|
|
50515
51011
|
}],
|
|
51012
|
+
"snapshot.getStatus": [{
|
|
51013
|
+
name: "deviceId",
|
|
51014
|
+
form: "single",
|
|
51015
|
+
optional: false
|
|
51016
|
+
}],
|
|
50516
51017
|
"snapshot.invalidateCache": [{
|
|
50517
51018
|
name: "deviceId",
|
|
50518
51019
|
form: "single",
|
|
@@ -50523,6 +51024,11 @@ Object.freeze({
|
|
|
50523
51024
|
form: "single",
|
|
50524
51025
|
optional: false
|
|
50525
51026
|
}],
|
|
51027
|
+
"streamBroker.applyDeviceSettingsPatch": [{
|
|
51028
|
+
name: "deviceId",
|
|
51029
|
+
form: "single",
|
|
51030
|
+
optional: false
|
|
51031
|
+
}],
|
|
50526
51032
|
"streamBroker.assignProfile": [{
|
|
50527
51033
|
name: "deviceId",
|
|
50528
51034
|
form: "single",
|
|
@@ -50538,6 +51044,16 @@ Object.freeze({
|
|
|
50538
51044
|
form: "single",
|
|
50539
51045
|
optional: false
|
|
50540
51046
|
}],
|
|
51047
|
+
"streamBroker.getDeviceLiveContribution": [{
|
|
51048
|
+
name: "deviceId",
|
|
51049
|
+
form: "single",
|
|
51050
|
+
optional: false
|
|
51051
|
+
}],
|
|
51052
|
+
"streamBroker.getDeviceSettingsContribution": [{
|
|
51053
|
+
name: "deviceId",
|
|
51054
|
+
form: "single",
|
|
51055
|
+
optional: false
|
|
51056
|
+
}],
|
|
50541
51057
|
"streamBroker.getStreamWithCodec": [{
|
|
50542
51058
|
name: "deviceId",
|
|
50543
51059
|
form: "single",
|
|
@@ -50598,16 +51114,46 @@ Object.freeze({
|
|
|
50598
51114
|
form: "single",
|
|
50599
51115
|
optional: false
|
|
50600
51116
|
}],
|
|
51117
|
+
"streamParams.getStatus": [{
|
|
51118
|
+
name: "deviceId",
|
|
51119
|
+
form: "single",
|
|
51120
|
+
optional: false
|
|
51121
|
+
}],
|
|
50601
51122
|
"streamParams.setProfile": [{
|
|
50602
51123
|
name: "deviceId",
|
|
50603
51124
|
form: "single",
|
|
50604
51125
|
optional: false
|
|
50605
51126
|
}],
|
|
51127
|
+
"switch.getStatus": [{
|
|
51128
|
+
name: "deviceId",
|
|
51129
|
+
form: "single",
|
|
51130
|
+
optional: false
|
|
51131
|
+
}],
|
|
50606
51132
|
"switch.setState": [{
|
|
50607
51133
|
name: "deviceId",
|
|
50608
51134
|
form: "single",
|
|
50609
51135
|
optional: false
|
|
50610
51136
|
}],
|
|
51137
|
+
"tamper.getStatus": [{
|
|
51138
|
+
name: "deviceId",
|
|
51139
|
+
form: "single",
|
|
51140
|
+
optional: false
|
|
51141
|
+
}],
|
|
51142
|
+
"temperatureSensor.getStatus": [{
|
|
51143
|
+
name: "deviceId",
|
|
51144
|
+
form: "single",
|
|
51145
|
+
optional: false
|
|
51146
|
+
}],
|
|
51147
|
+
"update.getStatus": [{
|
|
51148
|
+
name: "deviceId",
|
|
51149
|
+
form: "single",
|
|
51150
|
+
optional: false
|
|
51151
|
+
}],
|
|
51152
|
+
"vacuumControl.getStatus": [{
|
|
51153
|
+
name: "deviceId",
|
|
51154
|
+
form: "single",
|
|
51155
|
+
optional: false
|
|
51156
|
+
}],
|
|
50611
51157
|
"vacuumControl.locate": [{
|
|
50612
51158
|
name: "deviceId",
|
|
50613
51159
|
form: "single",
|
|
@@ -50643,6 +51189,11 @@ Object.freeze({
|
|
|
50643
51189
|
form: "single",
|
|
50644
51190
|
optional: false
|
|
50645
51191
|
}],
|
|
51192
|
+
"valve.getStatus": [{
|
|
51193
|
+
name: "deviceId",
|
|
51194
|
+
form: "single",
|
|
51195
|
+
optional: false
|
|
51196
|
+
}],
|
|
50646
51197
|
"valve.open": [{
|
|
50647
51198
|
name: "deviceId",
|
|
50648
51199
|
form: "single",
|
|
@@ -50658,6 +51209,11 @@ Object.freeze({
|
|
|
50658
51209
|
form: "single",
|
|
50659
51210
|
optional: false
|
|
50660
51211
|
}],
|
|
51212
|
+
"vibration.getStatus": [{
|
|
51213
|
+
name: "deviceId",
|
|
51214
|
+
form: "single",
|
|
51215
|
+
optional: false
|
|
51216
|
+
}],
|
|
50661
51217
|
"videoclips.dialClipStream": [{
|
|
50662
51218
|
name: "deviceId",
|
|
50663
51219
|
form: "single",
|
|
@@ -50693,6 +51249,11 @@ Object.freeze({
|
|
|
50693
51249
|
form: "single",
|
|
50694
51250
|
optional: false
|
|
50695
51251
|
}],
|
|
51252
|
+
"waterHeater.getStatus": [{
|
|
51253
|
+
name: "deviceId",
|
|
51254
|
+
form: "single",
|
|
51255
|
+
optional: false
|
|
51256
|
+
}],
|
|
50696
51257
|
"waterHeater.setAway": [{
|
|
50697
51258
|
name: "deviceId",
|
|
50698
51259
|
form: "single",
|
|
@@ -50708,6 +51269,11 @@ Object.freeze({
|
|
|
50708
51269
|
form: "single",
|
|
50709
51270
|
optional: false
|
|
50710
51271
|
}],
|
|
51272
|
+
"weather.getStatus": [{
|
|
51273
|
+
name: "deviceId",
|
|
51274
|
+
form: "single",
|
|
51275
|
+
optional: false
|
|
51276
|
+
}],
|
|
50711
51277
|
"webrtcSession.addIceCandidate": [{
|
|
50712
51278
|
name: "deviceId",
|
|
50713
51279
|
form: "single",
|
|
@@ -51445,7 +52011,7 @@ var PreviewTextField = string$2().max(200);
|
|
|
51445
52011
|
* Whether the notification's preview is a STILL or a short animation.
|
|
51446
52012
|
*
|
|
51447
52013
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
51448
|
-
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
52014
|
+
* rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
|
|
51449
52015
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
51450
52016
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
51451
52017
|
* simply applies it to a dozen frames sampled across the render and assembles
|
|
@@ -51583,6 +52149,7 @@ TimelapseRuleInputSchema.extend({
|
|
|
51583
52149
|
createdAt: number(),
|
|
51584
52150
|
updatedAt: number()
|
|
51585
52151
|
});
|
|
52152
|
+
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
51586
52153
|
object({
|
|
51587
52154
|
/**
|
|
51588
52155
|
* Fraction of the box's own size added on EACH side before cutting.
|