@camstack/addon-provider-ecowitt 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 +892 -325
- package/dist/addon.mjs +892 -325
- package/package.json +1 -3
package/dist/addon.js
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
let http = require("http");
|
|
3
3
|
let events = require("events");
|
|
4
4
|
let dgram = require("dgram");
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-BGmz_oxW.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -535,6 +535,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
535
535
|
*/
|
|
536
536
|
EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
|
|
537
537
|
EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
|
|
538
|
+
/**
|
|
539
|
+
* A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
|
|
540
|
+
* data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
|
|
541
|
+
* consumer is the orchestrator's camera-sensors bridge, which re-emits the
|
|
542
|
+
* camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
|
|
543
|
+
* for a camera with no attached sensor). Providers must not emit
|
|
544
|
+
* `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
|
|
545
|
+
* keeps it so (camera-grid is a named, deferred exception).
|
|
546
|
+
*/
|
|
538
547
|
EventCategory["ProviderMotion"] = "provider.motion";
|
|
539
548
|
EventCategory["ProviderDetection"] = "provider.detection";
|
|
540
549
|
EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
|
|
@@ -5373,7 +5382,7 @@ var ZodIssueCode$1 = {
|
|
|
5373
5382
|
var ZodFirstPartyTypeKind$1;
|
|
5374
5383
|
ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
|
|
5375
5384
|
//#endregion
|
|
5376
|
-
//#region ../types/dist/sleep-
|
|
5385
|
+
//#region ../types/dist/sleep-CDCONfkt.mjs
|
|
5377
5386
|
/**
|
|
5378
5387
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5379
5388
|
* window to float samples (D455).
|
|
@@ -7416,7 +7425,7 @@ function errMsg(err) {
|
|
|
7416
7425
|
return String(err);
|
|
7417
7426
|
}
|
|
7418
7427
|
//#endregion
|
|
7419
|
-
//#region ../types/dist/composition-
|
|
7428
|
+
//#region ../types/dist/composition-Bzr7GwgP.mjs
|
|
7420
7429
|
/**
|
|
7421
7430
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
7422
7431
|
*
|
|
@@ -7470,21 +7479,20 @@ function portable(target) {
|
|
|
7470
7479
|
}
|
|
7471
7480
|
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
7472
7481
|
/**
|
|
7473
|
-
*
|
|
7474
|
-
*
|
|
7482
|
+
* THE table "which boolean of this device type counts as HIGH", and the
|
|
7483
|
+
* pure evaluator of its EDGE.
|
|
7475
7484
|
*
|
|
7476
|
-
*
|
|
7477
|
-
*
|
|
7478
|
-
*
|
|
7479
|
-
*
|
|
7480
|
-
*
|
|
7481
|
-
*
|
|
7482
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
7485
|
+
* ONE table for everyone who asks "is this device HIGH?": the
|
|
7486
|
+
* recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
|
|
7487
|
+
* sensor markers, the orchestrator's camera-sensors bridge and
|
|
7488
|
+
* the sources of a composite doorbell (`doorbellFeatureSources`, D671).
|
|
7489
|
+
* A second copy would diverge at the first cap added, and the symptom — "the
|
|
7490
|
+
* sensor rings the doorbell but does not record" — is exactly D62.
|
|
7483
7491
|
*
|
|
7484
|
-
* ⚠
|
|
7485
|
-
*
|
|
7486
|
-
*
|
|
7487
|
-
*
|
|
7492
|
+
* ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
|
|
7493
|
+
* two must not be unified: that one answers "what is the state WORD for a
|
|
7494
|
+
* rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
|
|
7495
|
+
* boolean's EDGE counts". Deliberately different vocabularies.
|
|
7488
7496
|
*/
|
|
7489
7497
|
/**
|
|
7490
7498
|
* Known binary / switch source caps → the boolean slice field whose
|
|
@@ -9093,22 +9101,22 @@ var CLASS_MAP_MACRO_TARGETS = [
|
|
|
9093
9101
|
"package"
|
|
9094
9102
|
];
|
|
9095
9103
|
/**
|
|
9096
|
-
*
|
|
9097
|
-
*
|
|
9104
|
+
* The FIRST-LEVEL macro classes: those an object detector emits and that
|
|
9105
|
+
* an operator can select.
|
|
9098
9106
|
*
|
|
9099
|
-
*
|
|
9107
|
+
* They are the three offered by the `object-detection` step
|
|
9100
9108
|
* (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
|
|
9101
|
-
* `enabledMacroClasses`). `package`
|
|
9102
|
-
* `MACRO_LABELS` —
|
|
9103
|
-
* `package-detection`,
|
|
9104
|
-
*
|
|
9109
|
+
* `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
|
|
9110
|
+
* `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
|
|
9111
|
+
* `package-detection`, whose enablement is driven by zones, and offering the
|
|
9112
|
+
* same word twice has already made an operator turn on the COCO proxy
|
|
9105
9113
|
* (suitcase/backpack/handbag) lasciando spento il detector dedicato.
|
|
9106
9114
|
*
|
|
9107
|
-
*
|
|
9108
|
-
*
|
|
9109
|
-
* (`types/detection.ts`);
|
|
9110
|
-
* (`RecordingTriggers.objectClasses`)
|
|
9111
|
-
*
|
|
9115
|
+
* ONE list. Before today the same three were hand-written in the step's offer
|
|
9116
|
+
* and a second time as the union `FirstLevelMacro`
|
|
9117
|
+
* (`types/detection.ts`); a third copy for the recording trigger
|
|
9118
|
+
* (`RecordingTriggers.objectClasses`) would have made the later divergence
|
|
9119
|
+
* invisible.
|
|
9112
9120
|
*/
|
|
9113
9121
|
var FIRST_LEVEL_MACRO_CLASSES = [
|
|
9114
9122
|
"person",
|
|
@@ -9173,17 +9181,17 @@ var RecordingStorageModeSchema = _enum([
|
|
|
9173
9181
|
"on-device-decision"
|
|
9174
9182
|
]);
|
|
9175
9183
|
/**
|
|
9176
|
-
*
|
|
9177
|
-
*
|
|
9184
|
+
* The macro classes that can open a recording window — the same
|
|
9185
|
+
* three offered by the `object-detection` step, from ONE list
|
|
9178
9186
|
* ({@link FIRST_LEVEL_MACRO_CLASSES}).
|
|
9179
9187
|
*/
|
|
9180
9188
|
var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
|
|
9181
9189
|
/**
|
|
9182
|
-
* True
|
|
9190
|
+
* True when `values` does not repeat an element.
|
|
9183
9191
|
*
|
|
9184
|
-
*
|
|
9185
|
-
*
|
|
9186
|
-
*
|
|
9192
|
+
* A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
|
|
9193
|
+
* becomes a SOURCE in `bandTriggerSources`, and the same source twice
|
|
9194
|
+
* would count its windows twice in `segmentMissedByMs`.
|
|
9187
9195
|
*/
|
|
9188
9196
|
var noDuplicates = (values) => new Set(values).size === values.length;
|
|
9189
9197
|
/** Which detectors trigger an `events`-mode band. */
|
|
@@ -9191,34 +9199,34 @@ var RecordingTriggersSchema = object({
|
|
|
9191
9199
|
motion: boolean().optional(),
|
|
9192
9200
|
audioThresholdDbfs: number().optional(),
|
|
9193
9201
|
/**
|
|
9194
|
-
*
|
|
9195
|
-
*
|
|
9196
|
-
*
|
|
9197
|
-
*
|
|
9202
|
+
* The macro classes whose detection opens a window. ABSENT = the source
|
|
9203
|
+
* is not listened to; an EMPTY array is rejected, because "events band, object
|
|
9204
|
+
* trigger on, no class" is the same shape "enabled and records
|
|
9205
|
+
* nothing, forever" that `eventsBandCanEverDemand` is written against.
|
|
9198
9206
|
*
|
|
9199
|
-
*
|
|
9200
|
-
*
|
|
9201
|
-
* `minConfidence<Macro>`
|
|
9202
|
-
* (`source: 'onboard'`)
|
|
9203
|
-
*
|
|
9207
|
+
* The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
|
|
9208
|
+
* those that went through `enabledMacroClasses`, the
|
|
9209
|
+
* `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
|
|
9210
|
+
* (`source: 'onboard'`) goes through none of those gates and does NOT open
|
|
9211
|
+
* windows — see `recorder/object-trigger.ts`.
|
|
9204
9212
|
*/
|
|
9205
9213
|
objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
|
|
9206
9214
|
/**
|
|
9207
|
-
*
|
|
9208
|
-
*
|
|
9215
|
+
* The LINKED devices whose RISING EDGE opens a window. Absent = the source
|
|
9216
|
+
* is not listened to; an empty array is rejected for the same reason as
|
|
9209
9217
|
* `objectClasses`.
|
|
9210
9218
|
*
|
|
9211
|
-
*
|
|
9212
|
-
*
|
|
9213
|
-
*
|
|
9214
|
-
*
|
|
9215
|
-
* device (D12) —
|
|
9219
|
+
* These are SOURCE device ids, not cameras: the band names them, so the
|
|
9220
|
+
* hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
|
|
9221
|
+
* does no RPC. The OFFER from which the operator picks them is another question, and
|
|
9222
|
+
* is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
|
|
9223
|
+
* device (D12) — never a global list of caps.
|
|
9216
9224
|
*
|
|
9217
|
-
*
|
|
9218
|
-
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`)
|
|
9219
|
-
*
|
|
9220
|
-
*
|
|
9221
|
-
*
|
|
9225
|
+
* What "high" means depends on the device TYPE and is not decided here:
|
|
9226
|
+
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
|
|
9227
|
+
* the same one as the composite doorbell (D671). And it is the EDGE, not
|
|
9228
|
+
* the level: a contact found already open at runner restart does not
|
|
9229
|
+
* record.
|
|
9222
9230
|
*/
|
|
9223
9231
|
sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
|
|
9224
9232
|
});
|
|
@@ -10295,7 +10303,7 @@ var DecoderSessionConfigSchema = object({
|
|
|
10295
10303
|
* - **VALUE** — at which level, for which scope, until when. That stays ONE
|
|
10296
10304
|
* thing: the logging settings document on the `system` cap. Two authorities
|
|
10297
10305
|
* over the values is the exact defect
|
|
10298
|
-
* `docs/design/plans/2026-08-26-
|
|
10306
|
+
* `docs/design/plans/2026-08-26-per-component-logging.md` was written to
|
|
10299
10307
|
* remove; re-introducing it from the cure side would be grotesque.
|
|
10300
10308
|
*
|
|
10301
10309
|
* Nothing in this file reads a clock, an env var or a store. The registry is
|
|
@@ -12006,7 +12014,7 @@ var BrokerStatusEnum = _enum([
|
|
|
12006
12014
|
"unreachable",
|
|
12007
12015
|
"error"
|
|
12008
12016
|
]);
|
|
12009
|
-
var BrokerInfoSchema
|
|
12017
|
+
var BrokerInfoSchema = object({
|
|
12010
12018
|
/** Stable broker id. Persisted; survives addon restarts. */
|
|
12011
12019
|
id: string(),
|
|
12012
12020
|
/** Addon id of the provider that OWNS this broker.
|
|
@@ -12139,7 +12147,7 @@ var GetStateInputSchema = object({
|
|
|
12139
12147
|
* HA: entity_id (returns the cached entity state). */
|
|
12140
12148
|
key: string()
|
|
12141
12149
|
});
|
|
12142
|
-
method(ListInputSchema, array(BrokerInfoSchema
|
|
12150
|
+
method(ListInputSchema, array(BrokerInfoSchema)), method(GetInputSchema, BrokerInfoSchema.nullable()), method(_void(), array(BrokerProviderInfoSchema), { auth: "admin" }), method(AddInputSchema, AddResultSchema, {
|
|
12143
12151
|
kind: "mutation",
|
|
12144
12152
|
auth: "admin"
|
|
12145
12153
|
}), method(RemoveInputSchema, _void(), {
|
|
@@ -13850,7 +13858,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
13850
13858
|
*
|
|
13851
13859
|
* ⚠ An earlier version of this comment blamed Zod stripping, and that
|
|
13852
13860
|
* was wrong — corrected 2026-08-26 after the hop map
|
|
13853
|
-
* (`docs/design/2026-08-26-
|
|
13861
|
+
* (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
|
|
13854
13862
|
* There is **no Zod parse at all** between the door and the engine: the
|
|
13855
13863
|
* dispatcher forwards the payload verbatim and UDS carries it whole. A
|
|
13856
13864
|
* field declared here reaches `SqliteSettingsBackend` either way.
|
|
@@ -14826,7 +14834,17 @@ var SiteZoneSchema = object({
|
|
|
14826
14834
|
var ProviderStatusSchema = object({
|
|
14827
14835
|
connected: boolean(),
|
|
14828
14836
|
deviceCount: number(),
|
|
14829
|
-
error: string().optional()
|
|
14837
|
+
error: string().optional(),
|
|
14838
|
+
/**
|
|
14839
|
+
* `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
|
|
14840
|
+
* — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
|
|
14841
|
+
* which every provider bundles, so only a provider BUILT from D696-amended
|
|
14842
|
+
* code says it. ABSENT means an older provider that may still write it (raw
|
|
14843
|
+
* VMD writes, a boot seed), and the orchestrator's provider gate keeps that
|
|
14844
|
+
* provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
|
|
14845
|
+
* — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
|
|
14846
|
+
*/
|
|
14847
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
14830
14848
|
});
|
|
14831
14849
|
object({
|
|
14832
14850
|
externalId: string(),
|
|
@@ -15705,109 +15723,10 @@ method(object({
|
|
|
15705
15723
|
deviceIds: array(number()).readonly(),
|
|
15706
15724
|
caps: array(string()).readonly().optional()
|
|
15707
15725
|
}), record(string(), record(string(), unknown().nullable())));
|
|
15708
|
-
|
|
15709
|
-
|
|
15710
|
-
* name (same pattern as `snapshot`):
|
|
15711
|
-
*
|
|
15712
|
-
* - **Native** providers: registered per-device by device-driver
|
|
15713
|
-
* addons via `ctx.registerNativeCap` — either on a
|
|
15714
|
-
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
15715
|
-
* or directly on the camera (Reolink registers at camera level).
|
|
15716
|
-
* Emits an `onPressed` event every time the firmware pushes a
|
|
15717
|
-
* ring; status tracks the last press and a pressCount since start
|
|
15718
|
-
* (diagnostic).
|
|
15719
|
-
*
|
|
15720
|
-
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
15721
|
-
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
15722
|
-
* device (contact / switch / event-emitter …) into a doorbell for
|
|
15723
|
-
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
15724
|
-
* it per camera in the device-bindings UI, then picks the source
|
|
15725
|
-
* device + trigger in the per-device settings.
|
|
15726
|
-
*
|
|
15727
|
-
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
15728
|
-
* — subscribers listening at the camera level receive ring events
|
|
15729
|
-
* with `via[]` populated. No code on the parent needed.
|
|
15730
|
-
*/
|
|
15731
|
-
var DoorbellStatusSchema = object({
|
|
15732
|
-
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
15733
|
-
lastPressedAt: number().nullable(),
|
|
15734
|
-
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
15735
|
-
pressCountSinceStart: number()
|
|
15736
|
-
});
|
|
15737
|
-
var DoorbellPressEventSchema = object({
|
|
15738
|
-
deviceId: number(),
|
|
15739
|
-
timestamp: number()
|
|
15740
|
-
});
|
|
15741
|
-
/**
|
|
15742
|
-
* The `doorbell-source` extension slot's editable value (D648): the camera's
|
|
15743
|
-
* virtual-doorbell trigger devices, exactly what the wrapper's
|
|
15744
|
-
* `doorbellSources` persists (as `{ deviceId }` records).
|
|
15745
|
-
*/
|
|
15746
|
-
var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
|
|
15747
|
-
/**
|
|
15748
|
-
* The `doorbell-source` slot — which devices ring this camera's VIRTUAL
|
|
15749
|
-
* doorbell, owned by the `virtual-doorbell` wrapper over its
|
|
15750
|
-
* `doorbellSources` store (D648). A source rings when one of its
|
|
15751
|
-
* `SOURCE_CAPS` rises. Whether the wrapper is bound to the camera at all is a
|
|
15752
|
-
* different authority (`deviceManager.setWrapperActive`, D62) — the slot
|
|
15753
|
-
* reports it, it never writes it.
|
|
15754
|
-
*/
|
|
15755
|
-
var DOORBELL_SOURCE_SLOT = {
|
|
15756
|
-
id: "doorbell-source",
|
|
15757
|
-
label: "Doorbell trigger devices",
|
|
15758
|
-
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.",
|
|
15759
|
-
shape: "association",
|
|
15760
|
-
hostDeviceTypes: [DeviceType.Camera],
|
|
15761
|
-
sourceCaps: SOURCE_CAPS,
|
|
15762
|
-
cardinality: "many",
|
|
15763
|
-
value: DoorbellSourceSlotValueSchema
|
|
15764
|
-
};
|
|
15765
|
-
var doorbellCapability = {
|
|
15766
|
-
name: "doorbell",
|
|
15767
|
-
scope: "device",
|
|
15768
|
-
deviceNative: true,
|
|
15769
|
-
mode: "singleton",
|
|
15770
|
-
kind: "wrapper",
|
|
15771
|
-
defaultActive: false,
|
|
15772
|
-
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
15773
|
-
extensionSlots: [DOORBELL_SOURCE_SLOT],
|
|
15774
|
-
methods: {},
|
|
15775
|
-
events: {
|
|
15776
|
-
/**
|
|
15777
|
-
* Fires once per physical press. Reolink delivers via Baichuan
|
|
15778
|
-
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
15779
|
-
* release/duration — it's a pulse.
|
|
15780
|
-
*/
|
|
15781
|
-
onPressed: {
|
|
15782
|
-
data: DoorbellPressEventSchema,
|
|
15783
|
-
fromState: {
|
|
15784
|
-
field: "lastPressedAt",
|
|
15785
|
-
on: "advance"
|
|
15786
|
-
}
|
|
15787
|
-
} },
|
|
15788
|
-
status: {
|
|
15789
|
-
schema: DoorbellStatusSchema,
|
|
15790
|
-
kind: "push"
|
|
15791
|
-
},
|
|
15792
|
-
/**
|
|
15793
|
-
* Runtime-state slice — last press timestamp + lifetime press count.
|
|
15794
|
-
* Mirrored by the kernel and readable via
|
|
15795
|
-
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
15796
|
-
* without subscribing.
|
|
15797
|
-
*/
|
|
15798
|
-
runtimeState: DoorbellStatusSchema,
|
|
15799
|
-
/**
|
|
15800
|
-
* 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.
|
|
15801
|
-
*
|
|
15802
|
-
* See `RuntimeStateDurability`. Enforced by
|
|
15803
|
-
* `scripts/check-runtime-state-durability.ts`.
|
|
15804
|
-
*/
|
|
15805
|
-
durability: "restored"
|
|
15806
|
-
};
|
|
15807
|
-
var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
|
|
15808
|
-
DeviceType.Camera, DeviceType.Camera;
|
|
15726
|
+
var ExtensionSlotIdSchema = _enum(["linked-devices"]);
|
|
15727
|
+
DeviceType.Camera;
|
|
15809
15728
|
/** A slot's editable value, discriminated on `slot`. */
|
|
15810
|
-
var ExtensionSlotValueSchema = discriminatedUnion("slot", [
|
|
15729
|
+
var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
|
|
15811
15730
|
DeviceType.Camera;
|
|
15812
15731
|
var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
|
|
15813
15732
|
state: literal("unreachable"),
|
|
@@ -15844,10 +15763,11 @@ var ExtensionSlotSourceSchema = object({
|
|
|
15844
15763
|
});
|
|
15845
15764
|
/**
|
|
15846
15765
|
* A DIFFERENT authority that gates whether the slot's sources do anything —
|
|
15847
|
-
* reported read-only, named, never written through this contract (D62).
|
|
15848
|
-
*
|
|
15849
|
-
*
|
|
15850
|
-
* `unknown` means the gate could
|
|
15766
|
+
* reported read-only, named, never written through this contract (D62) — e.g.
|
|
15767
|
+
* a slot whose sources act only while a wrapper is bound to the host, a
|
|
15768
|
+
* binding that belongs to `deviceManager.setWrapperActive`. No slot reports
|
|
15769
|
+
* one today (`linked-devices` answers `null`). `unknown` means the gate could
|
|
15770
|
+
* not be read; it is not "inactive" (D315).
|
|
15851
15771
|
*/
|
|
15852
15772
|
var ExtensionSlotActivationSchema = object({
|
|
15853
15773
|
state: _enum([
|
|
@@ -15863,7 +15783,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
|
|
|
15863
15783
|
/** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
|
|
15864
15784
|
slotRef: string(),
|
|
15865
15785
|
slot: ExtensionSlotIdSchema,
|
|
15866
|
-
/** Names the store written (D62), e.g. `
|
|
15786
|
+
/** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
|
|
15867
15787
|
authority: string(),
|
|
15868
15788
|
activation: ExtensionSlotActivationSchema.nullable(),
|
|
15869
15789
|
value: ExtensionSlotValueSchema,
|
|
@@ -16141,7 +16061,7 @@ method(object({
|
|
|
16141
16061
|
* per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
|
|
16142
16062
|
* ends in a log line, and a log line is the thing the operator asked to stop
|
|
16143
16063
|
* needing: *"possiamo armare questi errori intanto? Così al prossimo giro
|
|
16144
|
-
* ricontrolliamo tutti questi punti"
|
|
16064
|
+
* 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
|
|
16145
16065
|
* hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
|
|
16146
16066
|
* media blackout were both diagnosed. The counters stay; this is where they can
|
|
16147
16067
|
* be READ.
|
|
@@ -17517,7 +17437,7 @@ var BrokerStatusSchema$1 = _enum([
|
|
|
17517
17437
|
"unreachable",
|
|
17518
17438
|
"tls-error"
|
|
17519
17439
|
]);
|
|
17520
|
-
var BrokerInfoSchema = object({
|
|
17440
|
+
var BrokerInfoSchema$1 = object({
|
|
17521
17441
|
id: string(),
|
|
17522
17442
|
name: string(),
|
|
17523
17443
|
url: string(),
|
|
@@ -17580,7 +17500,7 @@ var StatusSchema = object({
|
|
|
17580
17500
|
brokerCount: number(),
|
|
17581
17501
|
embeddedRunning: boolean()
|
|
17582
17502
|
});
|
|
17583
|
-
method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
|
|
17503
|
+
method(_void(), array(BrokerInfoSchema$1)), method(IdInputSchema, BrokerConnectionDetailsSchema, { auth: "admin" }), method(AddBrokerInputSchema, AddBrokerResultSchema, {
|
|
17584
17504
|
kind: "mutation",
|
|
17585
17505
|
auth: "admin"
|
|
17586
17506
|
}), method(IdInputSchema, _void(), {
|
|
@@ -19794,78 +19714,16 @@ var NcRuleInputSchema = object({
|
|
|
19794
19714
|
*/
|
|
19795
19715
|
confirm: NcConfirmSchema.optional(),
|
|
19796
19716
|
/**
|
|
19797
|
-
*
|
|
19798
|
-
*
|
|
19799
|
-
*
|
|
19800
|
-
*
|
|
19801
|
-
*
|
|
19802
|
-
*
|
|
19803
|
-
*
|
|
19804
|
-
*
|
|
19805
|
-
*
|
|
19806
|
-
* Only two honest answers exist, and this flag picks between them. It has
|
|
19807
|
-
* effect ONLY on a rule that declares a recognition scope
|
|
19808
|
-
* ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
|
|
19809
|
-
* other rule there is nothing to wait for and the flag is inert.
|
|
19810
|
-
*
|
|
19811
|
-
* | value | what happens |
|
|
19812
|
-
* | --- | --- |
|
|
19813
|
-
* | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
|
|
19814
|
-
* | 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) |
|
|
19815
|
-
*
|
|
19816
|
-
* `.optional()` and deliberately NOT `.default()`: a Zod default does not run
|
|
19817
|
-
* on the addon cap path, and absent has to keep meaning exactly what every
|
|
19818
|
-
* rule authored before this field meant.
|
|
19819
|
-
*
|
|
19820
|
-
* The cost of `true` is stated here because the editor states it too: a rule
|
|
19821
|
-
* that waits also inherits track-close SEMANTICS — its `zones` condition
|
|
19822
|
-
* tests every zone the track visited and a `crossing` condition can no longer
|
|
19823
|
-
* be satisfied, because a closed track carries no crossing.
|
|
19824
|
-
*/
|
|
19825
|
-
waitForEnhancement: boolean().optional(),
|
|
19826
|
-
/**
|
|
19827
|
-
* GROUP a burst of subjects into ONE notification that grows.
|
|
19828
|
-
*
|
|
19829
|
-
* Seconds of quiet after the last matching subject before the burst is
|
|
19830
|
-
* considered over. While it is open, the first subject enqueues immediately —
|
|
19831
|
-
* **exactly as today, with no added latency** — and every real growth (a new
|
|
19832
|
-
* subject, or a name confirmed on one already in it) REPLACES that
|
|
19833
|
-
* notification with an updated one naming everybody. The push carries the
|
|
19834
|
-
* group's own coalescing tag, so the phone replaces rather than stacks.
|
|
19835
|
-
*
|
|
19836
|
-
* `0` / absent = off, and off is today's behaviour byte for byte.
|
|
19837
|
-
*
|
|
19838
|
-
* ### Why an idle cutoff and not a window
|
|
19839
|
-
*
|
|
19840
|
-
* The measured seven-person arrival on device 590 spans 110 s with every
|
|
19841
|
-
* internal gap under 30 s. A 12 s fixed window cuts it into three groups; an
|
|
19842
|
-
* idle cutoff holds it as one and ends it when the arrival actually ends.
|
|
19843
|
-
* 30 s is a widely shipped value for the same decision.
|
|
19844
|
-
*
|
|
19845
|
-
* ### What it replaces
|
|
19846
|
-
*
|
|
19847
|
-
* The blind cooldown, which collapses a burst by DISCARDING it. Measured on
|
|
19848
|
-
* device 615 / *Persona su Uscio* over six days: 116 qualifying tracks → 74
|
|
19849
|
-
* notifications, **44 (37.9%) suppressed outright**, 23 of them overlapping a
|
|
19850
|
-
* track that did fire and 7 carrying a confirmed identity nobody heard about.
|
|
19851
|
-
* A group collapses the same volume by MERGING, so the cooldown becomes a
|
|
19852
|
-
* budget over GROUPS — which is what it always meant — and a growth is never
|
|
19853
|
-
* throttled by the window its own first member spent.
|
|
19854
|
-
*
|
|
19855
|
-
* ### Interaction with {@link waitForEnhancement}
|
|
19856
|
-
*
|
|
19857
|
-
* They compose, and the order matters. `waitForEnhancement` defers the rule to
|
|
19858
|
-
* TRACK CLOSE, so with both set the group is opened by the first member to
|
|
19859
|
-
* CLOSE — already carrying its name — and grows as later members close. That
|
|
19860
|
-
* is later, and complete. With grouping alone the group opens on the first
|
|
19861
|
-
* object event and picks up names as they are confirmed, through the growth
|
|
19862
|
-
* path. Neither combination fires twice for one subject.
|
|
19863
|
-
*
|
|
19864
|
-
* `.optional()` and deliberately NOT `.default()`: a Zod default does not run
|
|
19865
|
-
* on the addon cap path, so absent must keep meaning what it meant before this
|
|
19866
|
-
* field existed.
|
|
19717
|
+
* IMMEDIATE GROUPED (D692): the first matching subject opens a window of this many
|
|
19718
|
+
* seconds; the rule sends ONE message when the window closes — early, once every
|
|
19719
|
+
* subject in it is final, never before {@link NC_GROUPING_MIN_SEC} — naming everybody
|
|
19720
|
+
* the rule matched, with one mosaic tile per subject.
|
|
19721
|
+
* Absent = plain immediate (one message per track, at the first match).
|
|
19722
|
+
* Only an `immediate` DETECTION rule may carry it (`ruleGroupingApplies`, enforced on
|
|
19723
|
+
* save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
|
|
19724
|
+
* path does not run Zod defaults.
|
|
19867
19725
|
*/
|
|
19868
|
-
|
|
19726
|
+
groupingSec: number().int().min(5).max(60).optional()
|
|
19869
19727
|
});
|
|
19870
19728
|
/**
|
|
19871
19729
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -19913,9 +19771,10 @@ var NcRuleClearableKeySchema = _enum([
|
|
|
19913
19771
|
"targetUsers",
|
|
19914
19772
|
"snoozeOptions",
|
|
19915
19773
|
"snoozeAllowGlobal",
|
|
19916
|
-
"waitForEnhancement",
|
|
19917
19774
|
"actions",
|
|
19918
19775
|
"confirm",
|
|
19776
|
+
"groupingSec",
|
|
19777
|
+
"waitForEnhancement",
|
|
19919
19778
|
"groupIdleSec"
|
|
19920
19779
|
]);
|
|
19921
19780
|
var NcRuleUpdateInputSchema = object({
|
|
@@ -19937,9 +19796,25 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
19937
19796
|
*/
|
|
19938
19797
|
disabledTargetIds: array(string()).default([])
|
|
19939
19798
|
});
|
|
19799
|
+
/**
|
|
19800
|
+
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
|
|
19801
|
+
* still-true state. `backups-exports` and `alarm` are not sections — a completed
|
|
19802
|
+
* job is not an open state, and the alarm stays instant.
|
|
19803
|
+
*/
|
|
19804
|
+
var NcStateSummarySectionIdSchema = _enum([
|
|
19805
|
+
"device-state",
|
|
19806
|
+
"streams",
|
|
19807
|
+
"battery",
|
|
19808
|
+
"consumables",
|
|
19809
|
+
"tanks",
|
|
19810
|
+
"detection-blind",
|
|
19811
|
+
"nodes",
|
|
19812
|
+
"addons",
|
|
19813
|
+
"updates"
|
|
19814
|
+
]);
|
|
19940
19815
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
19941
19816
|
var NcStateSummaryPreviewSectionSchema = object({
|
|
19942
|
-
id:
|
|
19817
|
+
id: NcStateSummarySectionIdSchema,
|
|
19943
19818
|
status: _enum(["read", "unavailable"]),
|
|
19944
19819
|
items: number().int().nonnegative(),
|
|
19945
19820
|
reason: string().optional()
|
|
@@ -19949,7 +19824,7 @@ var NcStateSummaryPreviewSectionSchema = object({
|
|
|
19949
19824
|
* a `rule` split (no `section`), one section's on a `section` split.
|
|
19950
19825
|
*/
|
|
19951
19826
|
var NcStateSummaryPreviewRowSchema = object({
|
|
19952
|
-
section:
|
|
19827
|
+
section: NcStateSummarySectionIdSchema.optional(),
|
|
19953
19828
|
/** The section's name on a per-section row; every reported section's, joined, on a combined one. */
|
|
19954
19829
|
title: string(),
|
|
19955
19830
|
text: string(),
|
|
@@ -20386,6 +20261,29 @@ object({
|
|
|
20386
20261
|
firstAt: number(),
|
|
20387
20262
|
lastAt: number()
|
|
20388
20263
|
});
|
|
20264
|
+
var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
|
|
20265
|
+
var NcAlarmDelaySecSchema = number().int().min(0).max(600);
|
|
20266
|
+
var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
|
|
20267
|
+
var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
|
|
20268
|
+
var NcAlarmModeDelaysListSchema = array(object({
|
|
20269
|
+
mode: AlarmArmModeSchema,
|
|
20270
|
+
exitDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
20271
|
+
entryDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
20272
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
|
|
20273
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20274
|
+
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20275
|
+
mode: AlarmArmModeSchema,
|
|
20276
|
+
exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
20277
|
+
entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
20278
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
|
|
20279
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20280
|
+
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20281
|
+
var NcAlarmNonBlockingEditSchema = object({
|
|
20282
|
+
mode: AlarmArmModeSchema,
|
|
20283
|
+
deviceId: number().int().positive(),
|
|
20284
|
+
/** true = on the list (may be open, does not block); false = off the list (blocks). */
|
|
20285
|
+
nonBlocking: boolean()
|
|
20286
|
+
});
|
|
20389
20287
|
/**
|
|
20390
20288
|
* The per-mode lists, at most one per mode. Two lists for one mode have no
|
|
20391
20289
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
@@ -20394,10 +20292,10 @@ object({
|
|
|
20394
20292
|
var NcAlarmNonBlockingListSchema = array(object({
|
|
20395
20293
|
mode: AlarmArmModeSchema,
|
|
20396
20294
|
deviceIds: array(number().int()).max(200)
|
|
20397
|
-
})).max(8).refine(
|
|
20295
|
+
})).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20398
20296
|
/**
|
|
20399
|
-
* The three durations
|
|
20400
|
-
* transitions, and which openings each mode tolerates.
|
|
20297
|
+
* The three durations — global, and per mode since D697 — the panel's state
|
|
20298
|
+
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
20401
20299
|
*
|
|
20402
20300
|
* They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
|
|
20403
20301
|
* `alarm-panel` is `deviceNative` and its other provider mirrors somebody
|
|
@@ -20407,15 +20305,15 @@ var NcAlarmNonBlockingListSchema = array(object({
|
|
|
20407
20305
|
*/
|
|
20408
20306
|
var NcAlarmSettingsSchema = object({
|
|
20409
20307
|
/** Grace period between arming and the mode taking effect. 0 = immediate. */
|
|
20410
|
-
exitDelaySec:
|
|
20308
|
+
exitDelaySec: NcAlarmDelaySecSchema,
|
|
20411
20309
|
/** Grace period between a trigger and the alarm firing. 0 = immediate. */
|
|
20412
|
-
entryDelaySec:
|
|
20310
|
+
entryDelaySec: NcAlarmDelaySecSchema,
|
|
20413
20311
|
/**
|
|
20414
20312
|
* How long `triggered` lasts before the panel re-arms itself.
|
|
20415
20313
|
* **0 = until an operator disarms it** — the behaviour before this field
|
|
20416
20314
|
* existed, and therefore what an untouched install keeps doing.
|
|
20417
20315
|
*/
|
|
20418
|
-
triggeredDurationSec:
|
|
20316
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema,
|
|
20419
20317
|
/**
|
|
20420
20318
|
* Deprecated by D630 — every transition is announced. Parsed, never read;
|
|
20421
20319
|
* remove after one release. Optional so an older admin's patch (which still
|
|
@@ -20438,17 +20336,30 @@ var NcAlarmSettingsSchema = object({
|
|
|
20438
20336
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
20439
20337
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
20440
20338
|
*/
|
|
20441
|
-
nonBlocking: NcAlarmNonBlockingListSchema.default([])
|
|
20339
|
+
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
20340
|
+
/**
|
|
20341
|
+
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
20342
|
+
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
20343
|
+
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
20344
|
+
*/
|
|
20345
|
+
modeDelays: NcAlarmModeDelaysListSchema.default([])
|
|
20442
20346
|
});
|
|
20443
20347
|
/**
|
|
20444
20348
|
* Every field optional — a tab edits one control at a time.
|
|
20445
20349
|
*
|
|
20446
|
-
* `nonBlocking`
|
|
20447
|
-
* remove an inner `.default()`, so a patch that never
|
|
20448
|
-
* parse to `
|
|
20449
|
-
* (the same trap {@link NcRulePatchSchema} documents).
|
|
20350
|
+
* `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
|
|
20351
|
+
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
20352
|
+
* named the field would parse to `[]` and wipe every mode's list on an
|
|
20353
|
+
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
20354
|
+
* `modeDelays` means EDITS, not the stored overrides.
|
|
20450
20355
|
*/
|
|
20451
|
-
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20356
|
+
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20357
|
+
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
20358
|
+
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
20359
|
+
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
20360
|
+
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
20361
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
20362
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
|
|
20452
20363
|
/**
|
|
20453
20364
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
20454
20365
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -20548,6 +20459,28 @@ var NcAlarmConfigSchema = object({
|
|
|
20548
20459
|
*/
|
|
20549
20460
|
live: NcAlarmLiveSchema.optional()
|
|
20550
20461
|
});
|
|
20462
|
+
var NcAlarmSensorReadingSchema = _enum([
|
|
20463
|
+
"open",
|
|
20464
|
+
"closed",
|
|
20465
|
+
"unknown",
|
|
20466
|
+
"not-opening"
|
|
20467
|
+
]);
|
|
20468
|
+
/** One device's state as the alarm reads it — the classifier the arm check uses. */
|
|
20469
|
+
var NcAlarmSensorStateSchema = object({
|
|
20470
|
+
deviceId: number().int().positive(),
|
|
20471
|
+
reading: NcAlarmSensorReadingSchema,
|
|
20472
|
+
/** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
|
|
20473
|
+
state: string().nullable(),
|
|
20474
|
+
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
20475
|
+
unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
|
|
20476
|
+
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
20477
|
+
online: boolean().nullable()
|
|
20478
|
+
});
|
|
20479
|
+
var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
|
|
20480
|
+
var NcAlarmSensorsSchema = object({
|
|
20481
|
+
sensors: array(NcAlarmSensorStateSchema),
|
|
20482
|
+
readAt: number().int().nonnegative()
|
|
20483
|
+
});
|
|
20551
20484
|
/**
|
|
20552
20485
|
* ONE rule's demand on ONE camera's clip ring.
|
|
20553
20486
|
*
|
|
@@ -20638,7 +20571,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
20638
20571
|
}), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
|
|
20639
20572
|
kind: "mutation",
|
|
20640
20573
|
auth: "admin"
|
|
20641
|
-
});
|
|
20574
|
+
}), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
|
|
20642
20575
|
/**
|
|
20643
20576
|
* Zod schemas for persisted record types.
|
|
20644
20577
|
*
|
|
@@ -20985,12 +20918,26 @@ var CameraSensorRefSchema = object({
|
|
|
20985
20918
|
function cameraSensorRefKey(ref) {
|
|
20986
20919
|
return `${ref.addonId}/${ref.stableId}`;
|
|
20987
20920
|
}
|
|
20988
|
-
/**
|
|
20989
|
-
|
|
20990
|
-
|
|
20991
|
-
|
|
20992
|
-
|
|
20993
|
-
|
|
20921
|
+
/**
|
|
20922
|
+
* A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
|
|
20923
|
+
* `replace`: its motion is the camera's, and while one is READY the camera's
|
|
20924
|
+
* own motion no longer counts on its own. `confirm`: while one is READY the
|
|
20925
|
+
* camera's own motion counts only while a confirm sensor is active — with or
|
|
20926
|
+
* without a replace sensor (spec C2, the controller's ruling on Q1).
|
|
20927
|
+
*/
|
|
20928
|
+
var CameraSensorModeSchema = _enum([
|
|
20929
|
+
"in-addition",
|
|
20930
|
+
"confirm",
|
|
20931
|
+
"replace"
|
|
20932
|
+
]);
|
|
20933
|
+
/** A stored sensor with no mode — every CS-1 row — is in addition. */
|
|
20934
|
+
var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
|
|
20935
|
+
/**
|
|
20936
|
+
* A camera's attached sensors. A CS-1 row carried an envelope
|
|
20937
|
+
* `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
|
|
20938
|
+
* what the write stores (D672 rule 3), so it is never written again.
|
|
20939
|
+
*/
|
|
20940
|
+
var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
|
|
20994
20941
|
const seen = /* @__PURE__ */ new Set();
|
|
20995
20942
|
value.sensors.forEach((ref, index) => {
|
|
20996
20943
|
const key = cameraSensorRefKey(ref);
|
|
@@ -21002,39 +20949,41 @@ var CameraSensorsConfigSchema = object({
|
|
|
21002
20949
|
seen.add(key);
|
|
21003
20950
|
});
|
|
21004
20951
|
});
|
|
21005
|
-
|
|
20952
|
+
/** Every attachment names its mode; an older orchestrator that does not is in addition. */
|
|
20953
|
+
var AttachmentFields = {
|
|
21006
20954
|
addonId: string(),
|
|
21007
|
-
stableId: string()
|
|
20955
|
+
stableId: string(),
|
|
20956
|
+
mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
|
|
21008
20957
|
};
|
|
21009
20958
|
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
21010
20959
|
object({
|
|
21011
|
-
...
|
|
20960
|
+
...AttachmentFields,
|
|
21012
20961
|
state: literal("ready"),
|
|
21013
20962
|
deviceId: number(),
|
|
21014
20963
|
name: string(),
|
|
21015
20964
|
caps: array(string()).readonly()
|
|
21016
20965
|
}),
|
|
21017
20966
|
object({
|
|
21018
|
-
...
|
|
20967
|
+
...AttachmentFields,
|
|
21019
20968
|
state: literal("offline"),
|
|
21020
20969
|
deviceId: number(),
|
|
21021
20970
|
name: string(),
|
|
21022
20971
|
reason: _enum(["offline", "disabled"])
|
|
21023
20972
|
}),
|
|
21024
20973
|
object({
|
|
21025
|
-
...
|
|
20974
|
+
...AttachmentFields,
|
|
21026
20975
|
state: literal("missing"),
|
|
21027
20976
|
reason: string()
|
|
21028
20977
|
}),
|
|
21029
20978
|
object({
|
|
21030
|
-
...
|
|
20979
|
+
...AttachmentFields,
|
|
21031
20980
|
state: literal("unsupported"),
|
|
21032
20981
|
deviceId: number(),
|
|
21033
20982
|
name: string(),
|
|
21034
20983
|
reason: string()
|
|
21035
20984
|
}),
|
|
21036
20985
|
object({
|
|
21037
|
-
...
|
|
20986
|
+
...AttachmentFields,
|
|
21038
20987
|
state: literal("unreadable"),
|
|
21039
20988
|
reason: string()
|
|
21040
20989
|
})
|
|
@@ -21047,17 +20996,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
|
21047
20996
|
* say.
|
|
21048
20997
|
*/
|
|
21049
20998
|
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20999
|
+
/** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
|
|
21000
|
+
var CameraOwnMotionSchema = _enum([
|
|
21001
|
+
"always",
|
|
21002
|
+
"when-confirmed",
|
|
21003
|
+
"never"
|
|
21004
|
+
]);
|
|
21005
|
+
/** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
|
|
21006
|
+
var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
|
|
21007
|
+
/**
|
|
21008
|
+
* The camera's OWN onboard motion (D696): the raw input the bridge combines,
|
|
21009
|
+
* never the effective value. The camera's `motion` slice is the effective one,
|
|
21010
|
+
* so a view of the camera's own row reads this.
|
|
21011
|
+
* - `atMs`: when the bridge received the camera's last own edge.
|
|
21012
|
+
* - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
|
|
21013
|
+
* AND it is younger than the window the bridge counts the camera's own motion
|
|
21014
|
+
* for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
|
|
21015
|
+
* sends a clear (heartbeats only) therefore reads `false` once no push came
|
|
21016
|
+
* within the window; a status read is a snapshot, so a live view re-asks.
|
|
21017
|
+
* Absent = this orchestrator has not received the camera's own motion since it
|
|
21018
|
+
* started (unknown, never "quiet"), or an orchestrator older than D696.
|
|
21019
|
+
*/
|
|
21020
|
+
var CameraRawLevelSchema = object({
|
|
21021
|
+
detected: boolean(),
|
|
21022
|
+
atMs: number()
|
|
21023
|
+
});
|
|
21050
21024
|
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
21051
|
-
object({
|
|
21025
|
+
object({
|
|
21026
|
+
state: literal("not-configured"),
|
|
21027
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
21028
|
+
}),
|
|
21052
21029
|
object({
|
|
21053
21030
|
state: literal("unreadable"),
|
|
21054
|
-
reason: string()
|
|
21031
|
+
reason: string(),
|
|
21032
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
21055
21033
|
}),
|
|
21056
21034
|
object({
|
|
21057
21035
|
state: literal("configured"),
|
|
21058
|
-
|
|
21036
|
+
cameraLevel: CameraRawLevelSchema.optional(),
|
|
21059
21037
|
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
21060
|
-
|
|
21038
|
+
/** Absent = an orchestrator older than CS-2: it does not say (D315). */
|
|
21039
|
+
cameraMotion: CameraOwnMotionSchema.optional(),
|
|
21040
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional(),
|
|
21041
|
+
notEnforced: CameraSensorsNotEnforcedSchema.optional()
|
|
21061
21042
|
})
|
|
21062
21043
|
]);
|
|
21063
21044
|
Object.freeze({
|
|
@@ -21742,14 +21723,14 @@ var TrackSchema = object({
|
|
|
21742
21723
|
* `derive-returned-null tile=standin`,
|
|
21743
21724
|
* `native-tile tile=native no-key-frame-at-close`, …) written at close and
|
|
21744
21725
|
* CLEARED by the late-keyFrame upgrade when a native tile lands after all.
|
|
21745
|
-
* The operator-facing answer to "perché manca l'immagine?" on a track whose
|
|
21726
|
+
* The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
|
|
21746
21727
|
* tile is a face/plate stand-in, a raster crop, or an icon.
|
|
21747
21728
|
*
|
|
21748
21729
|
* **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
|
|
21749
21730
|
* the TILE ranked below native, so a track whose thumbnail landed natively
|
|
21750
21731
|
* while its key frame missed carried no reason at all — three of the four
|
|
21751
21732
|
* `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
|
|
21752
|
-
* that shape, and their "niente ultimo" had no cause anywhere on the row.
|
|
21733
|
+
* that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
|
|
21753
21734
|
* The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
|
|
21754
21735
|
* lastFrame copy source`), so its absence is now on this line whatever the
|
|
21755
21736
|
* tile ended up being.
|
|
@@ -21836,7 +21817,7 @@ var MotionEventSchema = object({
|
|
|
21836
21817
|
/**
|
|
21837
21818
|
* Ms offsets from `timestamp` (the episode's own first rising edge, so the
|
|
21838
21819
|
* first entry is always `0`) of every genuine off→on transition the
|
|
21839
|
-
* episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
|
|
21820
|
+
* episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
|
|
21840
21821
|
* push: a firmware source that keepalives at ~1 Hz for the whole burst
|
|
21841
21822
|
* (Reolink, Hikvision) produces exactly one edge; a source that reports an
|
|
21842
21823
|
* explicit `false` mid-episode and then resumes before the quiet window
|
|
@@ -22360,6 +22341,7 @@ var KeyEventSchema = object({
|
|
|
22360
22341
|
bestEventId: string(),
|
|
22361
22342
|
/** Track lifetime in ms (lastSeen - firstSeen). */
|
|
22362
22343
|
windowMs: number().optional(),
|
|
22344
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
22363
22345
|
...TrackFlagFields,
|
|
22364
22346
|
...TrackRetrainFields
|
|
22365
22347
|
});
|
|
@@ -24288,8 +24270,10 @@ var RunnerCameraConfigSchema = object({
|
|
|
24288
24270
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
24289
24271
|
* analyzer providers) running on decoded frames in this runner.
|
|
24290
24272
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
24291
|
-
* analytics). The provider emits ProviderMotion
|
|
24292
|
-
*
|
|
24273
|
+
* analytics). The provider emits its raw push as `ProviderMotion`
|
|
24274
|
+
* (D673); the orchestrator's camera-sensors bridge re-emits the camera's
|
|
24275
|
+
* effective motion as `MotionOnMotionChanged`, which is what reaches
|
|
24276
|
+
* `reportMotion`.
|
|
24293
24277
|
*/
|
|
24294
24278
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24295
24279
|
/**
|
|
@@ -24466,7 +24450,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
24466
24450
|
hasGpu: boolean(),
|
|
24467
24451
|
inferenceBackend: string().optional(),
|
|
24468
24452
|
cpuCores: number().optional()
|
|
24469
|
-
})
|
|
24453
|
+
}),
|
|
24454
|
+
/**
|
|
24455
|
+
* Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
|
|
24456
|
+
* runner never writes it. ABSENT = a runner older than D696, which still
|
|
24457
|
+
* writes the slice from its phase machine; the orchestrator does not write
|
|
24458
|
+
* while any runner node is absent-or-unanswered, so one slice never has two
|
|
24459
|
+
* writers.
|
|
24460
|
+
*/
|
|
24461
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
24470
24462
|
});
|
|
24471
24463
|
/**
|
|
24472
24464
|
* Aggregate runtime metrics for the runner's whole local pool. Mirrors the
|
|
@@ -27131,7 +27123,7 @@ var ClipPlaybackSchema = object({
|
|
|
27131
27123
|
* **One authorised yes is one wake.** `next-natural` — take the clip the next
|
|
27132
27124
|
* time the camera is awake for its own reasons — is deliberately not a member:
|
|
27133
27125
|
* it was proposed, it is free on the battery, and the operator declined it on
|
|
27134
|
-
* 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."
|
|
27126
|
+
* 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
|
|
27135
27127
|
* D558 "Considered and not taken").
|
|
27136
27128
|
*/
|
|
27137
27129
|
var ClipWakeSchema = _enum(["authorised"]);
|
|
@@ -27392,7 +27384,7 @@ DeviceType.Camera, method(object({
|
|
|
27392
27384
|
* It replaced `sources?: string[]`, a VIEW filter over source ids that
|
|
27393
27385
|
* assumed the answer was a fan-out over everything a camera has. The
|
|
27394
27386
|
* operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
|
|
27395
|
-
* solo"* — so the list is asked of one provider at a time and there is
|
|
27387
|
+
* solo"* [there is only one user] — so the list is asked of one provider at a time and there is
|
|
27396
27388
|
* nothing to filter out of it.
|
|
27397
27389
|
*/
|
|
27398
27390
|
provider: string().min(1)
|
|
@@ -29987,6 +29979,70 @@ onStatusChanged: { data: object({
|
|
|
29987
29979
|
* whether persisting is worth a SQLite commit. */
|
|
29988
29980
|
volatileStateFields: ["lastChangedAt"]
|
|
29989
29981
|
};
|
|
29982
|
+
var DoorbellStatusSchema = object({
|
|
29983
|
+
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
29984
|
+
lastPressedAt: number().nullable(),
|
|
29985
|
+
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
29986
|
+
pressCountSinceStart: number()
|
|
29987
|
+
});
|
|
29988
|
+
var DoorbellPressEventSchema = object({
|
|
29989
|
+
deviceId: number(),
|
|
29990
|
+
timestamp: number()
|
|
29991
|
+
});
|
|
29992
|
+
/**
|
|
29993
|
+
* Doorbell button cap. Two kinds of provider serve it, and to every consumer
|
|
29994
|
+
* they are the same cap:
|
|
29995
|
+
*
|
|
29996
|
+
* - **Native** providers, registered per device by a driver addon through
|
|
29997
|
+
* `ctx.registerNativeCap` — a `DeviceType.Button` accessory with
|
|
29998
|
+
* `role: DeviceRole.Doorbell`, or the camera itself (Reolink registers at
|
|
29999
|
+
* camera level). They emit `onPressed` on every firmware ring.
|
|
30000
|
+
* - **A composed doorbell** (D670, D671): a camera's customization gives it
|
|
30001
|
+
* the cap, its `lastPressedAt` rising from the sources the operator
|
|
30002
|
+
* assigned in Customize → Doorbell, and the composer emits `onPressed`
|
|
30003
|
+
* from that field's advance (`fromState`).
|
|
30004
|
+
*
|
|
30005
|
+
* The DeviceEventPropagator re-emits `onPressed` on the camera parent.
|
|
30006
|
+
*/
|
|
30007
|
+
var doorbellCapability = {
|
|
30008
|
+
name: "doorbell",
|
|
30009
|
+
scope: "device",
|
|
30010
|
+
deviceNative: true,
|
|
30011
|
+
mode: "singleton",
|
|
30012
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
30013
|
+
methods: {},
|
|
30014
|
+
events: {
|
|
30015
|
+
/**
|
|
30016
|
+
* Fires once per physical press. Reolink delivers via Baichuan
|
|
30017
|
+
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
30018
|
+
* release/duration — it's a pulse.
|
|
30019
|
+
*/
|
|
30020
|
+
onPressed: {
|
|
30021
|
+
data: DoorbellPressEventSchema,
|
|
30022
|
+
fromState: {
|
|
30023
|
+
field: "lastPressedAt",
|
|
30024
|
+
on: "advance"
|
|
30025
|
+
}
|
|
30026
|
+
} },
|
|
30027
|
+
status: {
|
|
30028
|
+
schema: DoorbellStatusSchema,
|
|
30029
|
+
kind: "push"
|
|
30030
|
+
},
|
|
30031
|
+
/**
|
|
30032
|
+
* Runtime-state slice — last press timestamp + lifetime press count.
|
|
30033
|
+
* Mirrored by the kernel and readable via
|
|
30034
|
+
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
30035
|
+
* without subscribing.
|
|
30036
|
+
*/
|
|
30037
|
+
runtimeState: DoorbellStatusSchema,
|
|
30038
|
+
/**
|
|
30039
|
+
* 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.
|
|
30040
|
+
*
|
|
30041
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
30042
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
30043
|
+
*/
|
|
30044
|
+
durability: "restored"
|
|
30045
|
+
};
|
|
29990
30046
|
/**
|
|
29991
30047
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
29992
30048
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -32131,9 +32187,9 @@ var MotionStatusSchema = object({
|
|
|
32131
32187
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
32132
32188
|
lastDetectedAt: number().nullable(),
|
|
32133
32189
|
/**
|
|
32134
|
-
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device
|
|
32135
|
-
* `null` while false and on every `Sensor`
|
|
32136
|
-
* constant's doc for the one-authority rule.
|
|
32190
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
|
|
32191
|
+
* orchestrator writes it, D696), `null` while false and on every `Sensor`
|
|
32192
|
+
* device (D475) — see that constant's doc for the one-authority rule.
|
|
32137
32193
|
*
|
|
32138
32194
|
* ## Reading this field still arms nothing
|
|
32139
32195
|
*
|
|
@@ -32151,34 +32207,31 @@ var MotionStatusSchema = object({
|
|
|
32151
32207
|
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
32152
32208
|
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
32153
32209
|
*
|
|
32154
|
-
* ## Who writes it
|
|
32155
|
-
*
|
|
32156
|
-
* - **Cameras** — the
|
|
32157
|
-
*
|
|
32158
|
-
* `
|
|
32159
|
-
* `
|
|
32160
|
-
*
|
|
32161
|
-
*
|
|
32162
|
-
* a
|
|
32163
|
-
*
|
|
32164
|
-
*
|
|
32165
|
-
*
|
|
32166
|
-
*
|
|
32167
|
-
*
|
|
32168
|
-
*
|
|
32169
|
-
*
|
|
32170
|
-
*
|
|
32171
|
-
*
|
|
32172
|
-
* `
|
|
32173
|
-
*
|
|
32174
|
-
*
|
|
32175
|
-
*
|
|
32176
|
-
*
|
|
32177
|
-
*
|
|
32178
|
-
*
|
|
32179
|
-
* This predates D475 and is not fixed there: the fix touches every
|
|
32180
|
-
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
32181
|
-
* "sole writer" wording without also removing the other writers.
|
|
32210
|
+
* ## Who writes it (D696)
|
|
32211
|
+
*
|
|
32212
|
+
* - **Cameras** — the orchestrator, and nothing else. It writes the camera's
|
|
32213
|
+
* EFFECTIVE motion (`addon-pipeline-orchestrator`
|
|
32214
|
+
* `camera-sensors/motion-slice.ts`), alongside the effective
|
|
32215
|
+
* `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
|
|
32216
|
+
* for a split camera, an unsplit emitter's direct event, the analyzer and
|
|
32217
|
+
* device activity, as the camera's `motionSources` counts them. A source
|
|
32218
|
+
* that never sends a clear falls one window after its last `true`.
|
|
32219
|
+
* `lastDetectedAt` moves only on an effective rise. No camera provider
|
|
32220
|
+
* writes this slice (not even a boot seed), and neither does the runner's
|
|
32221
|
+
* phase machine: its phase is "a session is attached" for every on-motion
|
|
32222
|
+
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
32223
|
+
* A provider's `isDetected` answers from the hub's slice.
|
|
32224
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
32225
|
+
* imports) — the provider pushes both edges itself, from the upstream
|
|
32226
|
+
* system's own state change. That is the sensor's own fact.
|
|
32227
|
+
*
|
|
32228
|
+
* `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
|
|
32229
|
+
* `motion` slice; each sensor writer is a named exemption.
|
|
32230
|
+
*
|
|
32231
|
+
* This replaces the D475 §4 rule ("the phase machine is the sole writer").
|
|
32232
|
+
* That rule was never true: Hikvision and Amcrest wrote the slice raw beside
|
|
32233
|
+
* it, every provider seeded it at boot, and every session left it
|
|
32234
|
+
* `detected: true` after its detach.
|
|
32182
32235
|
*/
|
|
32183
32236
|
autoClearAfterMs: number().nullable()
|
|
32184
32237
|
});
|
|
@@ -32250,11 +32303,12 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
32250
32303
|
*/
|
|
32251
32304
|
runtimeState: MotionStatusSchema,
|
|
32252
32305
|
/**
|
|
32253
|
-
* Runtime-state durability: **session** —
|
|
32306
|
+
* Runtime-state durability: **session** — the writer of this slice
|
|
32254
32307
|
* writes only on an EDGE, so a restored `detected: true` would stay
|
|
32255
32308
|
* frozen until the next one instead of being corrected. The next edge
|
|
32256
|
-
* re-publishes the real state
|
|
32257
|
-
*
|
|
32309
|
+
* re-publishes the real state, and the orchestrator re-publishes every
|
|
32310
|
+
* camera when it starts writing (D696; on who writes it, see
|
|
32311
|
+
* `autoClearAfterMs` above).
|
|
32258
32312
|
*
|
|
32259
32313
|
* See `RuntimeStateDurability`. Enforced by
|
|
32260
32314
|
* `scripts/check-runtime-state-durability.ts`.
|
|
@@ -34637,8 +34691,7 @@ var ptzAutotrackCapability = {
|
|
|
34637
34691
|
deviceNative: true,
|
|
34638
34692
|
mode: "singleton",
|
|
34639
34693
|
/**
|
|
34640
|
-
* Two kinds of provider behind one name, the same shape `snapshot`
|
|
34641
|
-
* `doorbell` use:
|
|
34694
|
+
* Two kinds of provider behind one name, the same shape `snapshot` uses:
|
|
34642
34695
|
*
|
|
34643
34696
|
* - **Native**: the camera's own firmware autotrack, registered per device by
|
|
34644
34697
|
* the driver when the probe says it exists (Reolink: yes; Hikvision:
|
|
@@ -34646,7 +34699,7 @@ var ptzAutotrackCapability = {
|
|
|
34646
34699
|
* - **Wrapper**: the emulated implementation (`@camstack/system`'s `autotrack` builtin),
|
|
34647
34700
|
* which follows a subject with `ptz.move` pulses driven by the detection
|
|
34648
34701
|
* pipeline. `defaultActive: false` — the operator binds it per camera in
|
|
34649
|
-
* the bindings UI
|
|
34702
|
+
* the bindings UI.
|
|
34650
34703
|
*
|
|
34651
34704
|
* The binding chooses WHICH implementation answers; `setEnabled` stays the
|
|
34652
34705
|
* one switch for the function either way. A camera never has both driving its
|
|
@@ -35321,7 +35374,7 @@ var ReadGopBytesResultSchema = object({
|
|
|
35321
35374
|
/**
|
|
35322
35375
|
* A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
|
|
35323
35376
|
* twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
|
|
35324
|
-
* replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-
|
|
35377
|
+
* replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
|
|
35325
35378
|
* a replay needs several seconds of native pixels, not one frame.
|
|
35326
35379
|
*
|
|
35327
35380
|
* `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
|
|
@@ -38685,6 +38738,7 @@ var zoneRulesCapability = {
|
|
|
38685
38738
|
*/
|
|
38686
38739
|
durability: "restored"
|
|
38687
38740
|
};
|
|
38741
|
+
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
38688
38742
|
/**
|
|
38689
38743
|
* Accessory device helpers — shared across drivers.
|
|
38690
38744
|
*
|
|
@@ -39744,13 +39798,14 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
39744
39798
|
async getStatus() {
|
|
39745
39799
|
const all = await this.ctx.kernel.devices?.getAll() ?? [];
|
|
39746
39800
|
const summary = this.restoreFailureSummary();
|
|
39747
|
-
|
|
39801
|
+
const base = {
|
|
39748
39802
|
connected: true,
|
|
39749
|
-
deviceCount: all.length
|
|
39803
|
+
deviceCount: all.length,
|
|
39804
|
+
motionSliceWriter: "orchestrator"
|
|
39750
39805
|
};
|
|
39806
|
+
if (summary === null) return base;
|
|
39751
39807
|
return {
|
|
39752
|
-
|
|
39753
|
-
deviceCount: all.length,
|
|
39808
|
+
...base,
|
|
39754
39809
|
error: summary
|
|
39755
39810
|
};
|
|
39756
39811
|
}
|
|
@@ -45186,6 +45241,12 @@ Object.freeze({
|
|
|
45186
45241
|
addonId: null,
|
|
45187
45242
|
access: "view"
|
|
45188
45243
|
},
|
|
45244
|
+
"notificationRules.getAlarmSensors": {
|
|
45245
|
+
capName: "notification-rules",
|
|
45246
|
+
capScope: "system",
|
|
45247
|
+
addonId: null,
|
|
45248
|
+
access: "view"
|
|
45249
|
+
},
|
|
45189
45250
|
"notificationRules.getClipRetentionAsks": {
|
|
45190
45251
|
capName: "notification-rules",
|
|
45191
45252
|
capScope: "system",
|
|
@@ -48764,6 +48825,11 @@ Object.freeze({
|
|
|
48764
48825
|
}
|
|
48765
48826
|
});
|
|
48766
48827
|
Object.freeze({
|
|
48828
|
+
"accessories.getStatus": [{
|
|
48829
|
+
name: "deviceId",
|
|
48830
|
+
form: "single",
|
|
48831
|
+
optional: false
|
|
48832
|
+
}],
|
|
48767
48833
|
"accessories.setChildHidden": [{
|
|
48768
48834
|
name: "childDeviceId",
|
|
48769
48835
|
form: "single",
|
|
@@ -48783,6 +48849,11 @@ Object.freeze({
|
|
|
48783
48849
|
form: "single",
|
|
48784
48850
|
optional: false
|
|
48785
48851
|
}],
|
|
48852
|
+
"airQualitySensor.getStatus": [{
|
|
48853
|
+
name: "deviceId",
|
|
48854
|
+
form: "single",
|
|
48855
|
+
optional: false
|
|
48856
|
+
}],
|
|
48786
48857
|
"alarmPanel.arm": [{
|
|
48787
48858
|
name: "deviceId",
|
|
48788
48859
|
form: "single",
|
|
@@ -48793,11 +48864,36 @@ Object.freeze({
|
|
|
48793
48864
|
form: "single",
|
|
48794
48865
|
optional: false
|
|
48795
48866
|
}],
|
|
48867
|
+
"alarmPanel.getStatus": [{
|
|
48868
|
+
name: "deviceId",
|
|
48869
|
+
form: "single",
|
|
48870
|
+
optional: false
|
|
48871
|
+
}],
|
|
48796
48872
|
"alarmPanel.trigger": [{
|
|
48797
48873
|
name: "deviceId",
|
|
48798
48874
|
form: "single",
|
|
48799
48875
|
optional: false
|
|
48800
48876
|
}],
|
|
48877
|
+
"ambientLightSensor.getStatus": [{
|
|
48878
|
+
name: "deviceId",
|
|
48879
|
+
form: "single",
|
|
48880
|
+
optional: false
|
|
48881
|
+
}],
|
|
48882
|
+
"audioAnalysis.applyDeviceSettingsPatch": [{
|
|
48883
|
+
name: "deviceId",
|
|
48884
|
+
form: "single",
|
|
48885
|
+
optional: false
|
|
48886
|
+
}],
|
|
48887
|
+
"audioAnalysis.getDeviceLiveContribution": [{
|
|
48888
|
+
name: "deviceId",
|
|
48889
|
+
form: "single",
|
|
48890
|
+
optional: false
|
|
48891
|
+
}],
|
|
48892
|
+
"audioAnalysis.getDeviceSettingsContribution": [{
|
|
48893
|
+
name: "deviceId",
|
|
48894
|
+
form: "single",
|
|
48895
|
+
optional: false
|
|
48896
|
+
}],
|
|
48801
48897
|
"audioAnalysis.resolveDeviceSettings": [{
|
|
48802
48898
|
name: "deviceId",
|
|
48803
48899
|
form: "single",
|
|
@@ -48838,16 +48934,36 @@ Object.freeze({
|
|
|
48838
48934
|
form: "single",
|
|
48839
48935
|
optional: false
|
|
48840
48936
|
}],
|
|
48937
|
+
"automationControl.getStatus": [{
|
|
48938
|
+
name: "deviceId",
|
|
48939
|
+
form: "single",
|
|
48940
|
+
optional: false
|
|
48941
|
+
}],
|
|
48841
48942
|
"automationControl.trigger": [{
|
|
48842
48943
|
name: "deviceId",
|
|
48843
48944
|
form: "single",
|
|
48844
48945
|
optional: false
|
|
48845
48946
|
}],
|
|
48947
|
+
"battery.getStatus": [{
|
|
48948
|
+
name: "deviceId",
|
|
48949
|
+
form: "single",
|
|
48950
|
+
optional: false
|
|
48951
|
+
}],
|
|
48846
48952
|
"battery.wakeForStream": [{
|
|
48847
48953
|
name: "deviceId",
|
|
48848
48954
|
form: "single",
|
|
48849
48955
|
optional: false
|
|
48850
48956
|
}],
|
|
48957
|
+
"binary.getStatus": [{
|
|
48958
|
+
name: "deviceId",
|
|
48959
|
+
form: "single",
|
|
48960
|
+
optional: false
|
|
48961
|
+
}],
|
|
48962
|
+
"brightness.getStatus": [{
|
|
48963
|
+
name: "deviceId",
|
|
48964
|
+
form: "single",
|
|
48965
|
+
optional: false
|
|
48966
|
+
}],
|
|
48851
48967
|
"brightness.setBrightness": [{
|
|
48852
48968
|
name: "deviceId",
|
|
48853
48969
|
form: "single",
|
|
@@ -48863,6 +48979,26 @@ Object.freeze({
|
|
|
48863
48979
|
form: "single",
|
|
48864
48980
|
optional: false
|
|
48865
48981
|
}],
|
|
48982
|
+
"cameraCredentials.getStatus": [{
|
|
48983
|
+
name: "deviceId",
|
|
48984
|
+
form: "single",
|
|
48985
|
+
optional: false
|
|
48986
|
+
}],
|
|
48987
|
+
"cameraGridLayout.applyDeviceSettingsPatch": [{
|
|
48988
|
+
name: "deviceId",
|
|
48989
|
+
form: "single",
|
|
48990
|
+
optional: false
|
|
48991
|
+
}],
|
|
48992
|
+
"cameraGridLayout.getDeviceLiveContribution": [{
|
|
48993
|
+
name: "deviceId",
|
|
48994
|
+
form: "single",
|
|
48995
|
+
optional: false
|
|
48996
|
+
}],
|
|
48997
|
+
"cameraGridLayout.getDeviceSettingsContribution": [{
|
|
48998
|
+
name: "deviceId",
|
|
48999
|
+
form: "single",
|
|
49000
|
+
optional: false
|
|
49001
|
+
}],
|
|
48866
49002
|
"cameraGridLayout.getLayout": [{
|
|
48867
49003
|
name: "deviceId",
|
|
48868
49004
|
form: "single",
|
|
@@ -48878,6 +49014,21 @@ Object.freeze({
|
|
|
48878
49014
|
form: "single",
|
|
48879
49015
|
optional: false
|
|
48880
49016
|
}],
|
|
49017
|
+
"cameraPipelineConfig.applyDeviceSettingsPatch": [{
|
|
49018
|
+
name: "deviceId",
|
|
49019
|
+
form: "single",
|
|
49020
|
+
optional: false
|
|
49021
|
+
}],
|
|
49022
|
+
"cameraPipelineConfig.getDeviceLiveContribution": [{
|
|
49023
|
+
name: "deviceId",
|
|
49024
|
+
form: "single",
|
|
49025
|
+
optional: false
|
|
49026
|
+
}],
|
|
49027
|
+
"cameraPipelineConfig.getDeviceSettingsContribution": [{
|
|
49028
|
+
name: "deviceId",
|
|
49029
|
+
form: "single",
|
|
49030
|
+
optional: false
|
|
49031
|
+
}],
|
|
48881
49032
|
"cameraStreams.getBrokerStreams": [{
|
|
48882
49033
|
name: "deviceId",
|
|
48883
49034
|
form: "single",
|
|
@@ -48903,6 +49054,16 @@ Object.freeze({
|
|
|
48903
49054
|
form: "single",
|
|
48904
49055
|
optional: false
|
|
48905
49056
|
}],
|
|
49057
|
+
"carbonMonoxide.getStatus": [{
|
|
49058
|
+
name: "deviceId",
|
|
49059
|
+
form: "single",
|
|
49060
|
+
optional: false
|
|
49061
|
+
}],
|
|
49062
|
+
"climateControl.getStatus": [{
|
|
49063
|
+
name: "deviceId",
|
|
49064
|
+
form: "single",
|
|
49065
|
+
optional: false
|
|
49066
|
+
}],
|
|
48906
49067
|
"climateControl.setFanMode": [{
|
|
48907
49068
|
name: "deviceId",
|
|
48908
49069
|
form: "single",
|
|
@@ -48943,16 +49104,41 @@ Object.freeze({
|
|
|
48943
49104
|
form: "single",
|
|
48944
49105
|
optional: false
|
|
48945
49106
|
}],
|
|
49107
|
+
"color.getStatus": [{
|
|
49108
|
+
name: "deviceId",
|
|
49109
|
+
form: "single",
|
|
49110
|
+
optional: false
|
|
49111
|
+
}],
|
|
48946
49112
|
"color.setColor": [{
|
|
48947
49113
|
name: "deviceId",
|
|
48948
49114
|
form: "single",
|
|
48949
49115
|
optional: false
|
|
48950
49116
|
}],
|
|
49117
|
+
"connectivity.getStatus": [{
|
|
49118
|
+
name: "deviceId",
|
|
49119
|
+
form: "single",
|
|
49120
|
+
optional: false
|
|
49121
|
+
}],
|
|
49122
|
+
"consumables.getStatus": [{
|
|
49123
|
+
name: "deviceId",
|
|
49124
|
+
form: "single",
|
|
49125
|
+
optional: false
|
|
49126
|
+
}],
|
|
48951
49127
|
"consumables.reset": [{
|
|
48952
49128
|
name: "deviceId",
|
|
48953
49129
|
form: "single",
|
|
48954
49130
|
optional: false
|
|
48955
49131
|
}],
|
|
49132
|
+
"contact.getStatus": [{
|
|
49133
|
+
name: "deviceId",
|
|
49134
|
+
form: "single",
|
|
49135
|
+
optional: false
|
|
49136
|
+
}],
|
|
49137
|
+
"control.getStatus": [{
|
|
49138
|
+
name: "deviceId",
|
|
49139
|
+
form: "single",
|
|
49140
|
+
optional: false
|
|
49141
|
+
}],
|
|
48956
49142
|
"control.setValue": [{
|
|
48957
49143
|
name: "deviceId",
|
|
48958
49144
|
form: "single",
|
|
@@ -48963,6 +49149,11 @@ Object.freeze({
|
|
|
48963
49149
|
form: "single",
|
|
48964
49150
|
optional: false
|
|
48965
49151
|
}],
|
|
49152
|
+
"cover.getStatus": [{
|
|
49153
|
+
name: "deviceId",
|
|
49154
|
+
form: "single",
|
|
49155
|
+
optional: false
|
|
49156
|
+
}],
|
|
48966
49157
|
"cover.open": [{
|
|
48967
49158
|
name: "deviceId",
|
|
48968
49159
|
form: "single",
|
|
@@ -48988,6 +49179,11 @@ Object.freeze({
|
|
|
48988
49179
|
form: "single",
|
|
48989
49180
|
optional: false
|
|
48990
49181
|
}],
|
|
49182
|
+
"dayNight.getStatus": [{
|
|
49183
|
+
name: "deviceId",
|
|
49184
|
+
form: "single",
|
|
49185
|
+
optional: false
|
|
49186
|
+
}],
|
|
48991
49187
|
"dayNight.setSettings": [{
|
|
48992
49188
|
name: "deviceId",
|
|
48993
49189
|
form: "single",
|
|
@@ -48998,11 +49194,31 @@ Object.freeze({
|
|
|
48998
49194
|
form: "single",
|
|
48999
49195
|
optional: true
|
|
49000
49196
|
}],
|
|
49197
|
+
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
49198
|
+
name: "deviceId",
|
|
49199
|
+
form: "single",
|
|
49200
|
+
optional: false
|
|
49201
|
+
}],
|
|
49202
|
+
"detectionPipeline.getDeviceLiveContribution": [{
|
|
49203
|
+
name: "deviceId",
|
|
49204
|
+
form: "single",
|
|
49205
|
+
optional: false
|
|
49206
|
+
}],
|
|
49207
|
+
"detectionPipeline.getDeviceSettingsContribution": [{
|
|
49208
|
+
name: "deviceId",
|
|
49209
|
+
form: "single",
|
|
49210
|
+
optional: false
|
|
49211
|
+
}],
|
|
49001
49212
|
"deviceAdminLink.getAdminLink": [{
|
|
49002
49213
|
name: "deviceId",
|
|
49003
49214
|
form: "single",
|
|
49004
49215
|
optional: false
|
|
49005
49216
|
}],
|
|
49217
|
+
"deviceAdoption.getStatus": [{
|
|
49218
|
+
name: "deviceId",
|
|
49219
|
+
form: "single",
|
|
49220
|
+
optional: false
|
|
49221
|
+
}],
|
|
49006
49222
|
"deviceAdoption.release": [{
|
|
49007
49223
|
name: "camDeviceId",
|
|
49008
49224
|
form: "single",
|
|
@@ -49018,6 +49234,11 @@ Object.freeze({
|
|
|
49018
49234
|
form: "single",
|
|
49019
49235
|
optional: false
|
|
49020
49236
|
}],
|
|
49237
|
+
"deviceDiscovery.getStatus": [{
|
|
49238
|
+
name: "deviceId",
|
|
49239
|
+
form: "single",
|
|
49240
|
+
optional: false
|
|
49241
|
+
}],
|
|
49021
49242
|
"deviceDiscovery.listDiscovered": [{
|
|
49022
49243
|
name: "deviceId",
|
|
49023
49244
|
form: "single",
|
|
@@ -49037,6 +49258,21 @@ Object.freeze({
|
|
|
49037
49258
|
form: "single",
|
|
49038
49259
|
optional: false
|
|
49039
49260
|
}],
|
|
49261
|
+
"deviceExport.applyDeviceSettingsPatch": [{
|
|
49262
|
+
name: "deviceId",
|
|
49263
|
+
form: "single",
|
|
49264
|
+
optional: false
|
|
49265
|
+
}],
|
|
49266
|
+
"deviceExport.getDeviceLiveContribution": [{
|
|
49267
|
+
name: "deviceId",
|
|
49268
|
+
form: "single",
|
|
49269
|
+
optional: false
|
|
49270
|
+
}],
|
|
49271
|
+
"deviceExport.getDeviceSettingsContribution": [{
|
|
49272
|
+
name: "deviceId",
|
|
49273
|
+
form: "single",
|
|
49274
|
+
optional: false
|
|
49275
|
+
}],
|
|
49040
49276
|
"deviceExtension.listCandidates": [{
|
|
49041
49277
|
name: "deviceId",
|
|
49042
49278
|
form: "single",
|
|
@@ -49385,6 +49621,26 @@ Object.freeze({
|
|
|
49385
49621
|
form: "single",
|
|
49386
49622
|
optional: false
|
|
49387
49623
|
}],
|
|
49624
|
+
"deviceStatus.getStatus": [{
|
|
49625
|
+
name: "deviceId",
|
|
49626
|
+
form: "single",
|
|
49627
|
+
optional: false
|
|
49628
|
+
}],
|
|
49629
|
+
"doorbell.getStatus": [{
|
|
49630
|
+
name: "deviceId",
|
|
49631
|
+
form: "single",
|
|
49632
|
+
optional: false
|
|
49633
|
+
}],
|
|
49634
|
+
"enumSensor.getStatus": [{
|
|
49635
|
+
name: "deviceId",
|
|
49636
|
+
form: "single",
|
|
49637
|
+
optional: false
|
|
49638
|
+
}],
|
|
49639
|
+
"eventEmitter.getStatus": [{
|
|
49640
|
+
name: "deviceId",
|
|
49641
|
+
form: "single",
|
|
49642
|
+
optional: false
|
|
49643
|
+
}],
|
|
49388
49644
|
"faceGallery.getFaceByTrack": [{
|
|
49389
49645
|
name: "deviceId",
|
|
49390
49646
|
form: "single",
|
|
@@ -49399,6 +49655,11 @@ Object.freeze({
|
|
|
49399
49655
|
form: "array",
|
|
49400
49656
|
optional: true
|
|
49401
49657
|
}],
|
|
49658
|
+
"fanControl.getStatus": [{
|
|
49659
|
+
name: "deviceId",
|
|
49660
|
+
form: "single",
|
|
49661
|
+
optional: false
|
|
49662
|
+
}],
|
|
49402
49663
|
"fanControl.setDirection": [{
|
|
49403
49664
|
name: "deviceId",
|
|
49404
49665
|
form: "single",
|
|
@@ -49419,6 +49680,26 @@ Object.freeze({
|
|
|
49419
49680
|
form: "single",
|
|
49420
49681
|
optional: false
|
|
49421
49682
|
}],
|
|
49683
|
+
"featureProbe.getStatus": [{
|
|
49684
|
+
name: "deviceId",
|
|
49685
|
+
form: "single",
|
|
49686
|
+
optional: false
|
|
49687
|
+
}],
|
|
49688
|
+
"flood.getStatus": [{
|
|
49689
|
+
name: "deviceId",
|
|
49690
|
+
form: "single",
|
|
49691
|
+
optional: false
|
|
49692
|
+
}],
|
|
49693
|
+
"gas.getStatus": [{
|
|
49694
|
+
name: "deviceId",
|
|
49695
|
+
form: "single",
|
|
49696
|
+
optional: false
|
|
49697
|
+
}],
|
|
49698
|
+
"humidifier.getStatus": [{
|
|
49699
|
+
name: "deviceId",
|
|
49700
|
+
form: "single",
|
|
49701
|
+
optional: false
|
|
49702
|
+
}],
|
|
49422
49703
|
"humidifier.setMode": [{
|
|
49423
49704
|
name: "deviceId",
|
|
49424
49705
|
form: "single",
|
|
@@ -49434,11 +49715,26 @@ Object.freeze({
|
|
|
49434
49715
|
form: "single",
|
|
49435
49716
|
optional: false
|
|
49436
49717
|
}],
|
|
49718
|
+
"humiditySensor.getStatus": [{
|
|
49719
|
+
name: "deviceId",
|
|
49720
|
+
form: "single",
|
|
49721
|
+
optional: false
|
|
49722
|
+
}],
|
|
49723
|
+
"image.getStatus": [{
|
|
49724
|
+
name: "deviceId",
|
|
49725
|
+
form: "single",
|
|
49726
|
+
optional: false
|
|
49727
|
+
}],
|
|
49437
49728
|
"imageSettings.getOptions": [{
|
|
49438
49729
|
name: "deviceId",
|
|
49439
49730
|
form: "single",
|
|
49440
49731
|
optional: false
|
|
49441
49732
|
}],
|
|
49733
|
+
"imageSettings.getStatus": [{
|
|
49734
|
+
name: "deviceId",
|
|
49735
|
+
form: "single",
|
|
49736
|
+
optional: false
|
|
49737
|
+
}],
|
|
49442
49738
|
"imageSettings.setSettings": [{
|
|
49443
49739
|
name: "deviceId",
|
|
49444
49740
|
form: "single",
|
|
@@ -49449,6 +49745,11 @@ Object.freeze({
|
|
|
49449
49745
|
form: "single",
|
|
49450
49746
|
optional: false
|
|
49451
49747
|
}],
|
|
49748
|
+
"intercom.getStatus": [{
|
|
49749
|
+
name: "deviceId",
|
|
49750
|
+
form: "single",
|
|
49751
|
+
optional: false
|
|
49752
|
+
}],
|
|
49452
49753
|
"intercom.handleAnswer": [{
|
|
49453
49754
|
name: "deviceId",
|
|
49454
49755
|
form: "single",
|
|
@@ -49479,6 +49780,11 @@ Object.freeze({
|
|
|
49479
49780
|
form: "single",
|
|
49480
49781
|
optional: false
|
|
49481
49782
|
}],
|
|
49783
|
+
"lawnMowerControl.getStatus": [{
|
|
49784
|
+
name: "deviceId",
|
|
49785
|
+
form: "single",
|
|
49786
|
+
optional: false
|
|
49787
|
+
}],
|
|
49482
49788
|
"lawnMowerControl.pause": [{
|
|
49483
49789
|
name: "deviceId",
|
|
49484
49790
|
form: "single",
|
|
@@ -49489,6 +49795,11 @@ Object.freeze({
|
|
|
49489
49795
|
form: "single",
|
|
49490
49796
|
optional: false
|
|
49491
49797
|
}],
|
|
49798
|
+
"lockControl.getStatus": [{
|
|
49799
|
+
name: "deviceId",
|
|
49800
|
+
form: "single",
|
|
49801
|
+
optional: false
|
|
49802
|
+
}],
|
|
49492
49803
|
"lockControl.lock": [{
|
|
49493
49804
|
name: "deviceId",
|
|
49494
49805
|
form: "single",
|
|
@@ -49504,6 +49815,11 @@ Object.freeze({
|
|
|
49504
49815
|
form: "single",
|
|
49505
49816
|
optional: false
|
|
49506
49817
|
}],
|
|
49818
|
+
"mediaPlayer.getStatus": [{
|
|
49819
|
+
name: "deviceId",
|
|
49820
|
+
form: "single",
|
|
49821
|
+
optional: false
|
|
49822
|
+
}],
|
|
49507
49823
|
"mediaPlayer.next": [{
|
|
49508
49824
|
name: "deviceId",
|
|
49509
49825
|
form: "single",
|
|
@@ -49564,6 +49880,11 @@ Object.freeze({
|
|
|
49564
49880
|
form: "single",
|
|
49565
49881
|
optional: false
|
|
49566
49882
|
}],
|
|
49883
|
+
"motion.getStatus": [{
|
|
49884
|
+
name: "deviceId",
|
|
49885
|
+
form: "single",
|
|
49886
|
+
optional: false
|
|
49887
|
+
}],
|
|
49567
49888
|
"motion.isDetected": [{
|
|
49568
49889
|
name: "deviceId",
|
|
49569
49890
|
form: "single",
|
|
@@ -49574,11 +49895,31 @@ Object.freeze({
|
|
|
49574
49895
|
form: "single",
|
|
49575
49896
|
optional: false
|
|
49576
49897
|
}],
|
|
49898
|
+
"motionDetection.applyDeviceSettingsPatch": [{
|
|
49899
|
+
name: "deviceId",
|
|
49900
|
+
form: "single",
|
|
49901
|
+
optional: false
|
|
49902
|
+
}],
|
|
49903
|
+
"motionDetection.getDeviceLiveContribution": [{
|
|
49904
|
+
name: "deviceId",
|
|
49905
|
+
form: "single",
|
|
49906
|
+
optional: false
|
|
49907
|
+
}],
|
|
49908
|
+
"motionDetection.getDeviceSettingsContribution": [{
|
|
49909
|
+
name: "deviceId",
|
|
49910
|
+
form: "single",
|
|
49911
|
+
optional: false
|
|
49912
|
+
}],
|
|
49577
49913
|
"motionDetection.removeCamera": [{
|
|
49578
49914
|
name: "deviceId",
|
|
49579
49915
|
form: "single",
|
|
49580
49916
|
optional: false
|
|
49581
49917
|
}],
|
|
49918
|
+
"motionTrigger.getStatus": [{
|
|
49919
|
+
name: "deviceId",
|
|
49920
|
+
form: "single",
|
|
49921
|
+
optional: false
|
|
49922
|
+
}],
|
|
49582
49923
|
"motionTrigger.setMotionTrigger": [{
|
|
49583
49924
|
name: "deviceId",
|
|
49584
49925
|
form: "single",
|
|
@@ -49589,6 +49930,11 @@ Object.freeze({
|
|
|
49589
49930
|
form: "single",
|
|
49590
49931
|
optional: false
|
|
49591
49932
|
}],
|
|
49933
|
+
"motionZones.getStatus": [{
|
|
49934
|
+
name: "deviceId",
|
|
49935
|
+
form: "single",
|
|
49936
|
+
optional: false
|
|
49937
|
+
}],
|
|
49592
49938
|
"motionZones.setZone": [{
|
|
49593
49939
|
name: "deviceId",
|
|
49594
49940
|
form: "single",
|
|
@@ -49599,6 +49945,11 @@ Object.freeze({
|
|
|
49599
49945
|
form: "single",
|
|
49600
49946
|
optional: false
|
|
49601
49947
|
}],
|
|
49948
|
+
"nativeObjectDetection.getStatus": [{
|
|
49949
|
+
name: "deviceId",
|
|
49950
|
+
form: "single",
|
|
49951
|
+
optional: false
|
|
49952
|
+
}],
|
|
49602
49953
|
"nativeObjectDetection.setEnabled": [{
|
|
49603
49954
|
name: "deviceId",
|
|
49604
49955
|
form: "single",
|
|
@@ -49614,6 +49965,11 @@ Object.freeze({
|
|
|
49614
49965
|
form: "single",
|
|
49615
49966
|
optional: false
|
|
49616
49967
|
}],
|
|
49968
|
+
"navigation.getStatus": [{
|
|
49969
|
+
name: "deviceId",
|
|
49970
|
+
form: "single",
|
|
49971
|
+
optional: false
|
|
49972
|
+
}],
|
|
49617
49973
|
"navigation.goToPoint": [{
|
|
49618
49974
|
name: "deviceId",
|
|
49619
49975
|
form: "single",
|
|
@@ -49659,6 +50015,11 @@ Object.freeze({
|
|
|
49659
50015
|
form: "single",
|
|
49660
50016
|
optional: false
|
|
49661
50017
|
}],
|
|
50018
|
+
"networkLink.getStatus": [{
|
|
50019
|
+
name: "deviceId",
|
|
50020
|
+
form: "single",
|
|
50021
|
+
optional: false
|
|
50022
|
+
}],
|
|
49662
50023
|
"networkQuality.getDeviceStats": [{
|
|
49663
50024
|
name: "deviceId",
|
|
49664
50025
|
form: "single",
|
|
@@ -49669,6 +50030,11 @@ Object.freeze({
|
|
|
49669
50030
|
form: "single",
|
|
49670
50031
|
optional: false
|
|
49671
50032
|
}],
|
|
50033
|
+
"notificationRules.getAlarmSensors": [{
|
|
50034
|
+
name: "deviceIds",
|
|
50035
|
+
form: "array",
|
|
50036
|
+
optional: false
|
|
50037
|
+
}],
|
|
49672
50038
|
"notificationRules.setDeviceMuted": [{
|
|
49673
50039
|
name: "deviceId",
|
|
49674
50040
|
form: "single",
|
|
@@ -49679,11 +50045,26 @@ Object.freeze({
|
|
|
49679
50045
|
form: "single",
|
|
49680
50046
|
optional: false
|
|
49681
50047
|
}],
|
|
50048
|
+
"notifier.getStatus": [{
|
|
50049
|
+
name: "deviceId",
|
|
50050
|
+
form: "single",
|
|
50051
|
+
optional: false
|
|
50052
|
+
}],
|
|
49682
50053
|
"notifier.send": [{
|
|
49683
50054
|
name: "deviceId",
|
|
49684
50055
|
form: "single",
|
|
49685
50056
|
optional: false
|
|
49686
50057
|
}],
|
|
50058
|
+
"numericSensor.getStatus": [{
|
|
50059
|
+
name: "deviceId",
|
|
50060
|
+
form: "single",
|
|
50061
|
+
optional: false
|
|
50062
|
+
}],
|
|
50063
|
+
"osd.getStatus": [{
|
|
50064
|
+
name: "deviceId",
|
|
50065
|
+
form: "single",
|
|
50066
|
+
optional: false
|
|
50067
|
+
}],
|
|
49687
50068
|
"osd.setOverlay": [{
|
|
49688
50069
|
name: "deviceId",
|
|
49689
50070
|
form: "single",
|
|
@@ -49743,6 +50124,11 @@ Object.freeze({
|
|
|
49743
50124
|
form: "single",
|
|
49744
50125
|
optional: false
|
|
49745
50126
|
}],
|
|
50127
|
+
"petFeeder.getStatus": [{
|
|
50128
|
+
name: "deviceId",
|
|
50129
|
+
form: "single",
|
|
50130
|
+
optional: false
|
|
50131
|
+
}],
|
|
49746
50132
|
"petFeeder.markFoodReplenished": [{
|
|
49747
50133
|
name: "deviceId",
|
|
49748
50134
|
form: "single",
|
|
@@ -49778,6 +50164,11 @@ Object.freeze({
|
|
|
49778
50164
|
form: "single",
|
|
49779
50165
|
optional: false
|
|
49780
50166
|
}],
|
|
50167
|
+
"pipelineAnalytics.applyDeviceSettingsPatch": [{
|
|
50168
|
+
name: "deviceId",
|
|
50169
|
+
form: "single",
|
|
50170
|
+
optional: false
|
|
50171
|
+
}],
|
|
49781
50172
|
"pipelineAnalytics.clearTrackRelation": [{
|
|
49782
50173
|
name: "deviceId",
|
|
49783
50174
|
form: "single",
|
|
@@ -49818,6 +50209,16 @@ Object.freeze({
|
|
|
49818
50209
|
form: "single",
|
|
49819
50210
|
optional: false
|
|
49820
50211
|
}],
|
|
50212
|
+
"pipelineAnalytics.getDeviceLiveContribution": [{
|
|
50213
|
+
name: "deviceId",
|
|
50214
|
+
form: "single",
|
|
50215
|
+
optional: false
|
|
50216
|
+
}],
|
|
50217
|
+
"pipelineAnalytics.getDeviceSettingsContribution": [{
|
|
50218
|
+
name: "deviceId",
|
|
50219
|
+
form: "single",
|
|
50220
|
+
optional: false
|
|
50221
|
+
}],
|
|
49821
50222
|
"pipelineAnalytics.getEventDensity": [{
|
|
49822
50223
|
name: "deviceId",
|
|
49823
50224
|
form: "single",
|
|
@@ -50033,6 +50434,11 @@ Object.freeze({
|
|
|
50033
50434
|
form: "single",
|
|
50034
50435
|
optional: true
|
|
50035
50436
|
}],
|
|
50437
|
+
"pipelineOrchestrator.applyDeviceSettingsPatch": [{
|
|
50438
|
+
name: "deviceId",
|
|
50439
|
+
form: "single",
|
|
50440
|
+
optional: false
|
|
50441
|
+
}],
|
|
50036
50442
|
"pipelineOrchestrator.assignAudio": [{
|
|
50037
50443
|
name: "deviceId",
|
|
50038
50444
|
form: "single",
|
|
@@ -50078,6 +50484,16 @@ Object.freeze({
|
|
|
50078
50484
|
form: "single",
|
|
50079
50485
|
optional: false
|
|
50080
50486
|
}],
|
|
50487
|
+
"pipelineOrchestrator.getDeviceLiveContribution": [{
|
|
50488
|
+
name: "deviceId",
|
|
50489
|
+
form: "single",
|
|
50490
|
+
optional: false
|
|
50491
|
+
}],
|
|
50492
|
+
"pipelineOrchestrator.getDeviceSettingsContribution": [{
|
|
50493
|
+
name: "deviceId",
|
|
50494
|
+
form: "single",
|
|
50495
|
+
optional: false
|
|
50496
|
+
}],
|
|
50081
50497
|
"pipelineOrchestrator.getPipelineAssignment": [{
|
|
50082
50498
|
name: "deviceId",
|
|
50083
50499
|
form: "single",
|
|
@@ -50198,11 +50614,31 @@ Object.freeze({
|
|
|
50198
50614
|
form: "single",
|
|
50199
50615
|
optional: true
|
|
50200
50616
|
}],
|
|
50617
|
+
"powerMeter.getStatus": [{
|
|
50618
|
+
name: "deviceId",
|
|
50619
|
+
form: "single",
|
|
50620
|
+
optional: false
|
|
50621
|
+
}],
|
|
50622
|
+
"presence.getStatus": [{
|
|
50623
|
+
name: "deviceId",
|
|
50624
|
+
form: "single",
|
|
50625
|
+
optional: false
|
|
50626
|
+
}],
|
|
50627
|
+
"pressureSensor.getStatus": [{
|
|
50628
|
+
name: "deviceId",
|
|
50629
|
+
form: "single",
|
|
50630
|
+
optional: false
|
|
50631
|
+
}],
|
|
50201
50632
|
"privacyMask.getOptions": [{
|
|
50202
50633
|
name: "deviceId",
|
|
50203
50634
|
form: "single",
|
|
50204
50635
|
optional: false
|
|
50205
50636
|
}],
|
|
50637
|
+
"privacyMask.getStatus": [{
|
|
50638
|
+
name: "deviceId",
|
|
50639
|
+
form: "single",
|
|
50640
|
+
optional: false
|
|
50641
|
+
}],
|
|
50206
50642
|
"privacyMask.setAudioEnabled": [{
|
|
50207
50643
|
name: "deviceId",
|
|
50208
50644
|
form: "single",
|
|
@@ -50253,6 +50689,11 @@ Object.freeze({
|
|
|
50253
50689
|
form: "single",
|
|
50254
50690
|
optional: false
|
|
50255
50691
|
}],
|
|
50692
|
+
"ptz.getStatus": [{
|
|
50693
|
+
name: "deviceId",
|
|
50694
|
+
form: "single",
|
|
50695
|
+
optional: false
|
|
50696
|
+
}],
|
|
50256
50697
|
"ptz.goHome": [{
|
|
50257
50698
|
name: "deviceId",
|
|
50258
50699
|
form: "single",
|
|
@@ -50343,6 +50784,11 @@ Object.freeze({
|
|
|
50343
50784
|
form: "single",
|
|
50344
50785
|
optional: false
|
|
50345
50786
|
}],
|
|
50787
|
+
"recordingArchive.applyDeviceSettingsPatch": [{
|
|
50788
|
+
name: "deviceId",
|
|
50789
|
+
form: "single",
|
|
50790
|
+
optional: false
|
|
50791
|
+
}],
|
|
50346
50792
|
"recordingArchive.deleteFootprint": [{
|
|
50347
50793
|
name: "deviceId",
|
|
50348
50794
|
form: "single",
|
|
@@ -50363,6 +50809,21 @@ Object.freeze({
|
|
|
50363
50809
|
form: "single",
|
|
50364
50810
|
optional: false
|
|
50365
50811
|
}],
|
|
50812
|
+
"recordingArchive.getDeviceLiveContribution": [{
|
|
50813
|
+
name: "deviceId",
|
|
50814
|
+
form: "single",
|
|
50815
|
+
optional: false
|
|
50816
|
+
}],
|
|
50817
|
+
"recordingArchive.getDeviceSettingsContribution": [{
|
|
50818
|
+
name: "deviceId",
|
|
50819
|
+
form: "single",
|
|
50820
|
+
optional: false
|
|
50821
|
+
}],
|
|
50822
|
+
"recordingArchive.getStatus": [{
|
|
50823
|
+
name: "deviceId",
|
|
50824
|
+
form: "single",
|
|
50825
|
+
optional: false
|
|
50826
|
+
}],
|
|
50366
50827
|
"recordingArchive.listOpsLog": [{
|
|
50367
50828
|
name: "deviceId",
|
|
50368
50829
|
form: "single",
|
|
@@ -50448,6 +50909,11 @@ Object.freeze({
|
|
|
50448
50909
|
form: "single",
|
|
50449
50910
|
optional: false
|
|
50450
50911
|
}],
|
|
50912
|
+
"recordingOnboard.getStatus": [{
|
|
50913
|
+
name: "deviceId",
|
|
50914
|
+
form: "single",
|
|
50915
|
+
optional: false
|
|
50916
|
+
}],
|
|
50451
50917
|
"recordingOnboard.setSettings": [{
|
|
50452
50918
|
name: "deviceId",
|
|
50453
50919
|
form: "single",
|
|
@@ -50478,6 +50944,11 @@ Object.freeze({
|
|
|
50478
50944
|
form: "single",
|
|
50479
50945
|
optional: false
|
|
50480
50946
|
}],
|
|
50947
|
+
"sceneMonitor.getStatus": [{
|
|
50948
|
+
name: "deviceId",
|
|
50949
|
+
form: "single",
|
|
50950
|
+
optional: false
|
|
50951
|
+
}],
|
|
50481
50952
|
"sceneMonitor.listScenes": [{
|
|
50482
50953
|
name: "deviceId",
|
|
50483
50954
|
form: "single",
|
|
@@ -50503,6 +50974,11 @@ Object.freeze({
|
|
|
50503
50974
|
form: "single",
|
|
50504
50975
|
optional: false
|
|
50505
50976
|
}],
|
|
50977
|
+
"scriptRunner.getStatus": [{
|
|
50978
|
+
name: "deviceId",
|
|
50979
|
+
form: "single",
|
|
50980
|
+
optional: false
|
|
50981
|
+
}],
|
|
50506
50982
|
"scriptRunner.run": [{
|
|
50507
50983
|
name: "deviceId",
|
|
50508
50984
|
form: "single",
|
|
@@ -50513,11 +50989,31 @@ Object.freeze({
|
|
|
50513
50989
|
form: "single",
|
|
50514
50990
|
optional: false
|
|
50515
50991
|
}],
|
|
50992
|
+
"smoke.getStatus": [{
|
|
50993
|
+
name: "deviceId",
|
|
50994
|
+
form: "single",
|
|
50995
|
+
optional: false
|
|
50996
|
+
}],
|
|
50997
|
+
"snapshot.applyDeviceSettingsPatch": [{
|
|
50998
|
+
name: "deviceId",
|
|
50999
|
+
form: "single",
|
|
51000
|
+
optional: false
|
|
51001
|
+
}],
|
|
50516
51002
|
"snapshot.getDebugState": [{
|
|
50517
51003
|
name: "deviceId",
|
|
50518
51004
|
form: "single",
|
|
50519
51005
|
optional: false
|
|
50520
51006
|
}],
|
|
51007
|
+
"snapshot.getDeviceLiveContribution": [{
|
|
51008
|
+
name: "deviceId",
|
|
51009
|
+
form: "single",
|
|
51010
|
+
optional: false
|
|
51011
|
+
}],
|
|
51012
|
+
"snapshot.getDeviceSettingsContribution": [{
|
|
51013
|
+
name: "deviceId",
|
|
51014
|
+
form: "single",
|
|
51015
|
+
optional: false
|
|
51016
|
+
}],
|
|
50521
51017
|
"snapshot.getSnapshot": [{
|
|
50522
51018
|
name: "deviceId",
|
|
50523
51019
|
form: "single",
|
|
@@ -50534,6 +51030,11 @@ Object.freeze({
|
|
|
50534
51030
|
form: "array",
|
|
50535
51031
|
optional: false
|
|
50536
51032
|
}],
|
|
51033
|
+
"snapshot.getStatus": [{
|
|
51034
|
+
name: "deviceId",
|
|
51035
|
+
form: "single",
|
|
51036
|
+
optional: false
|
|
51037
|
+
}],
|
|
50537
51038
|
"snapshot.invalidateCache": [{
|
|
50538
51039
|
name: "deviceId",
|
|
50539
51040
|
form: "single",
|
|
@@ -50544,6 +51045,11 @@ Object.freeze({
|
|
|
50544
51045
|
form: "single",
|
|
50545
51046
|
optional: false
|
|
50546
51047
|
}],
|
|
51048
|
+
"streamBroker.applyDeviceSettingsPatch": [{
|
|
51049
|
+
name: "deviceId",
|
|
51050
|
+
form: "single",
|
|
51051
|
+
optional: false
|
|
51052
|
+
}],
|
|
50547
51053
|
"streamBroker.assignProfile": [{
|
|
50548
51054
|
name: "deviceId",
|
|
50549
51055
|
form: "single",
|
|
@@ -50559,6 +51065,16 @@ Object.freeze({
|
|
|
50559
51065
|
form: "single",
|
|
50560
51066
|
optional: false
|
|
50561
51067
|
}],
|
|
51068
|
+
"streamBroker.getDeviceLiveContribution": [{
|
|
51069
|
+
name: "deviceId",
|
|
51070
|
+
form: "single",
|
|
51071
|
+
optional: false
|
|
51072
|
+
}],
|
|
51073
|
+
"streamBroker.getDeviceSettingsContribution": [{
|
|
51074
|
+
name: "deviceId",
|
|
51075
|
+
form: "single",
|
|
51076
|
+
optional: false
|
|
51077
|
+
}],
|
|
50562
51078
|
"streamBroker.getStreamWithCodec": [{
|
|
50563
51079
|
name: "deviceId",
|
|
50564
51080
|
form: "single",
|
|
@@ -50619,16 +51135,46 @@ Object.freeze({
|
|
|
50619
51135
|
form: "single",
|
|
50620
51136
|
optional: false
|
|
50621
51137
|
}],
|
|
51138
|
+
"streamParams.getStatus": [{
|
|
51139
|
+
name: "deviceId",
|
|
51140
|
+
form: "single",
|
|
51141
|
+
optional: false
|
|
51142
|
+
}],
|
|
50622
51143
|
"streamParams.setProfile": [{
|
|
50623
51144
|
name: "deviceId",
|
|
50624
51145
|
form: "single",
|
|
50625
51146
|
optional: false
|
|
50626
51147
|
}],
|
|
51148
|
+
"switch.getStatus": [{
|
|
51149
|
+
name: "deviceId",
|
|
51150
|
+
form: "single",
|
|
51151
|
+
optional: false
|
|
51152
|
+
}],
|
|
50627
51153
|
"switch.setState": [{
|
|
50628
51154
|
name: "deviceId",
|
|
50629
51155
|
form: "single",
|
|
50630
51156
|
optional: false
|
|
50631
51157
|
}],
|
|
51158
|
+
"tamper.getStatus": [{
|
|
51159
|
+
name: "deviceId",
|
|
51160
|
+
form: "single",
|
|
51161
|
+
optional: false
|
|
51162
|
+
}],
|
|
51163
|
+
"temperatureSensor.getStatus": [{
|
|
51164
|
+
name: "deviceId",
|
|
51165
|
+
form: "single",
|
|
51166
|
+
optional: false
|
|
51167
|
+
}],
|
|
51168
|
+
"update.getStatus": [{
|
|
51169
|
+
name: "deviceId",
|
|
51170
|
+
form: "single",
|
|
51171
|
+
optional: false
|
|
51172
|
+
}],
|
|
51173
|
+
"vacuumControl.getStatus": [{
|
|
51174
|
+
name: "deviceId",
|
|
51175
|
+
form: "single",
|
|
51176
|
+
optional: false
|
|
51177
|
+
}],
|
|
50632
51178
|
"vacuumControl.locate": [{
|
|
50633
51179
|
name: "deviceId",
|
|
50634
51180
|
form: "single",
|
|
@@ -50664,6 +51210,11 @@ Object.freeze({
|
|
|
50664
51210
|
form: "single",
|
|
50665
51211
|
optional: false
|
|
50666
51212
|
}],
|
|
51213
|
+
"valve.getStatus": [{
|
|
51214
|
+
name: "deviceId",
|
|
51215
|
+
form: "single",
|
|
51216
|
+
optional: false
|
|
51217
|
+
}],
|
|
50667
51218
|
"valve.open": [{
|
|
50668
51219
|
name: "deviceId",
|
|
50669
51220
|
form: "single",
|
|
@@ -50679,6 +51230,11 @@ Object.freeze({
|
|
|
50679
51230
|
form: "single",
|
|
50680
51231
|
optional: false
|
|
50681
51232
|
}],
|
|
51233
|
+
"vibration.getStatus": [{
|
|
51234
|
+
name: "deviceId",
|
|
51235
|
+
form: "single",
|
|
51236
|
+
optional: false
|
|
51237
|
+
}],
|
|
50682
51238
|
"videoclips.dialClipStream": [{
|
|
50683
51239
|
name: "deviceId",
|
|
50684
51240
|
form: "single",
|
|
@@ -50714,6 +51270,11 @@ Object.freeze({
|
|
|
50714
51270
|
form: "single",
|
|
50715
51271
|
optional: false
|
|
50716
51272
|
}],
|
|
51273
|
+
"waterHeater.getStatus": [{
|
|
51274
|
+
name: "deviceId",
|
|
51275
|
+
form: "single",
|
|
51276
|
+
optional: false
|
|
51277
|
+
}],
|
|
50717
51278
|
"waterHeater.setAway": [{
|
|
50718
51279
|
name: "deviceId",
|
|
50719
51280
|
form: "single",
|
|
@@ -50729,6 +51290,11 @@ Object.freeze({
|
|
|
50729
51290
|
form: "single",
|
|
50730
51291
|
optional: false
|
|
50731
51292
|
}],
|
|
51293
|
+
"weather.getStatus": [{
|
|
51294
|
+
name: "deviceId",
|
|
51295
|
+
form: "single",
|
|
51296
|
+
optional: false
|
|
51297
|
+
}],
|
|
50732
51298
|
"webrtcSession.addIceCandidate": [{
|
|
50733
51299
|
name: "deviceId",
|
|
50734
51300
|
form: "single",
|
|
@@ -51466,7 +52032,7 @@ var PreviewTextField = string().max(200);
|
|
|
51466
52032
|
* Whether the notification's preview is a STILL or a short animation.
|
|
51467
52033
|
*
|
|
51468
52034
|
* The operator's ask, verbatim: *"inviato come gif o video (come per le altre
|
|
51469
|
-
* rule)"* — the other rules already offer an animated preview, and a ten-hour
|
|
52035
|
+
* rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
|
|
51470
52036
|
* night reads better as three seconds of motion than as one frame of it. Both
|
|
51471
52037
|
* modes get the SAME treatment (blurred frame, large centred title); `'gif'`
|
|
51472
52038
|
* simply applies it to a dozen frames sampled across the render and assembles
|
|
@@ -51604,6 +52170,7 @@ TimelapseRuleInputSchema.extend({
|
|
|
51604
52170
|
createdAt: number(),
|
|
51605
52171
|
updatedAt: number()
|
|
51606
52172
|
});
|
|
52173
|
+
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
51607
52174
|
object({
|
|
51608
52175
|
/**
|
|
51609
52176
|
* Fraction of the box's own size added on EACH side before cutting.
|