@camstack/addon-model-studio 1.1.187 → 1.1.189
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/{MotionZonesSettings-Ctu2jUw5.mjs → MotionZonesSettings-FMiMjTOe.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-BklhxSXj.mjs → PrivacyMaskSettings-C54kjXje.mjs} +4 -4
- package/dist/{SceneMonitorEditor-BZRgxah0.mjs → SceneMonitorEditor-D3mHd1Bs.mjs} +3 -3
- package/dist/_stub.js +12 -11
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CVGJSgs1.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DRuIjSMF.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C8mPXBuv.mjs +26 -0
- package/dist/{hostInit-D34VXjYA.mjs → hostInit-CWX7SB3f.mjs} +2 -2
- package/dist/model-studio.addon.js +234 -101
- package/dist/model-studio.addon.mjs +234 -101
- package/dist/{player-overlays-WyG3CO8M.mjs → player-overlays-BR1a0BDm.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-DM13bMuN.mjs → responsive-BoGo5jZn.mjs} +1 -1
- package/dist/{scene-monitor-copy-NEMFgUTn.mjs → scene-monitor-copy-0evm2MrA.mjs} +1 -1
- package/dist/{square-BI5Xsmdj.mjs → square-NiMmxe53.mjs} +1 -1
- package/dist/{trash-2-D1YC9gXH.mjs → trash-2-DD3Sx3hW.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-C_9FXI-l.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DM0hkCAJ.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-a-ZV2LaP.mjs +0 -26
|
@@ -570,7 +570,7 @@ async function importScryptedCatalogModel(input, deps) {
|
|
|
570
570
|
}
|
|
571
571
|
}
|
|
572
572
|
//#endregion
|
|
573
|
-
//#region ../types/dist/event-category-
|
|
573
|
+
//#region ../types/dist/event-category-BGmz_oxW.mjs
|
|
574
574
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
575
575
|
EventCategory["SystemBoot"] = "system.boot";
|
|
576
576
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1103,6 +1103,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1103
1103
|
*/
|
|
1104
1104
|
EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
|
|
1105
1105
|
EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
|
|
1106
|
+
/**
|
|
1107
|
+
* A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
|
|
1108
|
+
* data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
|
|
1109
|
+
* consumer is the orchestrator's camera-sensors bridge, which re-emits the
|
|
1110
|
+
* camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
|
|
1111
|
+
* for a camera with no attached sensor). Providers must not emit
|
|
1112
|
+
* `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
|
|
1113
|
+
* keeps it so (camera-grid is a named, deferred exception).
|
|
1114
|
+
*/
|
|
1106
1115
|
EventCategory["ProviderMotion"] = "provider.motion";
|
|
1107
1116
|
EventCategory["ProviderDetection"] = "provider.detection";
|
|
1108
1117
|
EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
|
|
@@ -5941,7 +5950,7 @@ var ZodIssueCode = {
|
|
|
5941
5950
|
var ZodFirstPartyTypeKind;
|
|
5942
5951
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5943
5952
|
//#endregion
|
|
5944
|
-
//#region ../types/dist/sleep-
|
|
5953
|
+
//#region ../types/dist/sleep-CDCONfkt.mjs
|
|
5945
5954
|
/**
|
|
5946
5955
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5947
5956
|
* window to float samples (D455).
|
|
@@ -8051,7 +8060,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8051
8060
|
return DeviceRole;
|
|
8052
8061
|
}({});
|
|
8053
8062
|
//#endregion
|
|
8054
|
-
//#region ../types/dist/composition-
|
|
8063
|
+
//#region ../types/dist/composition-43aqsZQj.mjs
|
|
8055
8064
|
/**
|
|
8056
8065
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
8057
8066
|
*
|
|
@@ -8108,13 +8117,12 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
|
|
|
8108
8117
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
8109
8118
|
* valutatore puro del suo FRONTE.
|
|
8110
8119
|
*
|
|
8111
|
-
*
|
|
8112
|
-
*
|
|
8113
|
-
*
|
|
8114
|
-
*
|
|
8115
|
-
*
|
|
8116
|
-
* fa suonare il campanello ma non registra" — è esattamente D62.
|
|
8117
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
8120
|
+
* UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
|
|
8121
|
+
* trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
|
|
8122
|
+
* sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
|
|
8123
|
+
* le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
|
|
8124
|
+
* Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
|
|
8125
|
+
* sensore fa suonare il campanello ma non registra" — è esattamente D62.
|
|
8118
8126
|
*
|
|
8119
8127
|
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
8120
8128
|
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
@@ -9849,7 +9857,7 @@ var RecordingTriggersSchema = object({
|
|
|
9849
9857
|
*
|
|
9850
9858
|
* Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
|
|
9851
9859
|
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
|
|
9852
|
-
* la stessa
|
|
9860
|
+
* la stessa del campanello composto (D671). Ed è il FRONTE, non
|
|
9853
9861
|
* il livello: un contatto trovato già aperto al riavvio del runner non fa
|
|
9854
9862
|
* registrare.
|
|
9855
9863
|
*/
|
|
@@ -15969,28 +15977,10 @@ method(object({
|
|
|
15969
15977
|
deviceIds: array(number()).readonly(),
|
|
15970
15978
|
caps: array(string()).readonly().optional()
|
|
15971
15979
|
}), record(string(), record(string(), unknown().nullable())));
|
|
15972
|
-
|
|
15973
|
-
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
15974
|
-
lastPressedAt: number().nullable(),
|
|
15975
|
-
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
15976
|
-
pressCountSinceStart: number()
|
|
15977
|
-
});
|
|
15978
|
-
object({
|
|
15979
|
-
deviceId: number(),
|
|
15980
|
-
timestamp: number()
|
|
15981
|
-
});
|
|
15982
|
-
/**
|
|
15983
|
-
* The `doorbell-source` extension slot's editable value (D648): the camera's
|
|
15984
|
-
* virtual-doorbell trigger devices, exactly what the wrapper's
|
|
15985
|
-
* `doorbellSources` persists (as `{ deviceId }` records).
|
|
15986
|
-
*/
|
|
15987
|
-
var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
|
|
15980
|
+
var ExtensionSlotIdSchema = _enum(["linked-devices"]);
|
|
15988
15981
|
DeviceType.Camera;
|
|
15989
|
-
DeviceType.Button, DeviceType.Camera;
|
|
15990
|
-
var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
|
|
15991
|
-
DeviceType.Camera, DeviceType.Camera;
|
|
15992
15982
|
/** A slot's editable value, discriminated on `slot`. */
|
|
15993
|
-
var ExtensionSlotValueSchema = discriminatedUnion("slot", [
|
|
15983
|
+
var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
|
|
15994
15984
|
DeviceType.Camera;
|
|
15995
15985
|
var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
|
|
15996
15986
|
state: literal("unreachable"),
|
|
@@ -16027,10 +16017,11 @@ var ExtensionSlotSourceSchema = object({
|
|
|
16027
16017
|
});
|
|
16028
16018
|
/**
|
|
16029
16019
|
* A DIFFERENT authority that gates whether the slot's sources do anything —
|
|
16030
|
-
* reported read-only, named, never written through this contract (D62).
|
|
16031
|
-
*
|
|
16032
|
-
*
|
|
16033
|
-
* `unknown` means the gate could
|
|
16020
|
+
* reported read-only, named, never written through this contract (D62) — e.g.
|
|
16021
|
+
* a slot whose sources act only while a wrapper is bound to the host, a
|
|
16022
|
+
* binding that belongs to `deviceManager.setWrapperActive`. No slot reports
|
|
16023
|
+
* one today (`linked-devices` answers `null`). `unknown` means the gate could
|
|
16024
|
+
* not be read; it is not "inactive" (D315).
|
|
16034
16025
|
*/
|
|
16035
16026
|
var ExtensionSlotActivationSchema = object({
|
|
16036
16027
|
state: _enum([
|
|
@@ -16046,7 +16037,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
|
|
|
16046
16037
|
/** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
|
|
16047
16038
|
slotRef: string(),
|
|
16048
16039
|
slot: ExtensionSlotIdSchema,
|
|
16049
|
-
/** Names the store written (D62), e.g. `
|
|
16040
|
+
/** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
|
|
16050
16041
|
authority: string(),
|
|
16051
16042
|
activation: ExtensionSlotActivationSchema.nullable(),
|
|
16052
16043
|
value: ExtensionSlotValueSchema,
|
|
@@ -20537,6 +20528,29 @@ object({
|
|
|
20537
20528
|
firstAt: number(),
|
|
20538
20529
|
lastAt: number()
|
|
20539
20530
|
});
|
|
20531
|
+
var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
|
|
20532
|
+
var NcAlarmDelaySecSchema = number().int().min(0).max(600);
|
|
20533
|
+
var NcAlarmTriggeredSecSchema = number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
|
|
20534
|
+
var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
|
|
20535
|
+
var NcAlarmModeDelaysListSchema = array(object({
|
|
20536
|
+
mode: AlarmArmModeSchema,
|
|
20537
|
+
exitDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
20538
|
+
entryDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
20539
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
|
|
20540
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20541
|
+
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20542
|
+
mode: AlarmArmModeSchema,
|
|
20543
|
+
exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
20544
|
+
entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
20545
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
|
|
20546
|
+
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20547
|
+
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20548
|
+
var NcAlarmNonBlockingEditSchema = object({
|
|
20549
|
+
mode: AlarmArmModeSchema,
|
|
20550
|
+
deviceId: number().int().positive(),
|
|
20551
|
+
/** true = on the list (may be open, does not block); false = off the list (blocks). */
|
|
20552
|
+
nonBlocking: boolean()
|
|
20553
|
+
});
|
|
20540
20554
|
/**
|
|
20541
20555
|
* The per-mode lists, at most one per mode. Two lists for one mode have no
|
|
20542
20556
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
@@ -20545,10 +20559,10 @@ object({
|
|
|
20545
20559
|
var NcAlarmNonBlockingListSchema = array(object({
|
|
20546
20560
|
mode: AlarmArmModeSchema,
|
|
20547
20561
|
deviceIds: array(number().int()).max(200)
|
|
20548
|
-
})).max(8).refine(
|
|
20562
|
+
})).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20549
20563
|
/**
|
|
20550
|
-
* The three durations
|
|
20551
|
-
* transitions, and which openings each mode tolerates.
|
|
20564
|
+
* The three durations — global, and per mode since D697 — the panel's state
|
|
20565
|
+
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
20552
20566
|
*
|
|
20553
20567
|
* They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
|
|
20554
20568
|
* `alarm-panel` is `deviceNative` and its other provider mirrors somebody
|
|
@@ -20558,15 +20572,15 @@ var NcAlarmNonBlockingListSchema = array(object({
|
|
|
20558
20572
|
*/
|
|
20559
20573
|
var NcAlarmSettingsSchema = object({
|
|
20560
20574
|
/** Grace period between arming and the mode taking effect. 0 = immediate. */
|
|
20561
|
-
exitDelaySec:
|
|
20575
|
+
exitDelaySec: NcAlarmDelaySecSchema,
|
|
20562
20576
|
/** Grace period between a trigger and the alarm firing. 0 = immediate. */
|
|
20563
|
-
entryDelaySec:
|
|
20577
|
+
entryDelaySec: NcAlarmDelaySecSchema,
|
|
20564
20578
|
/**
|
|
20565
20579
|
* How long `triggered` lasts before the panel re-arms itself.
|
|
20566
20580
|
* **0 = until an operator disarms it** — the behaviour before this field
|
|
20567
20581
|
* existed, and therefore what an untouched install keeps doing.
|
|
20568
20582
|
*/
|
|
20569
|
-
triggeredDurationSec:
|
|
20583
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema,
|
|
20570
20584
|
/**
|
|
20571
20585
|
* Deprecated by D630 — every transition is announced. Parsed, never read;
|
|
20572
20586
|
* remove after one release. Optional so an older admin's patch (which still
|
|
@@ -20589,17 +20603,30 @@ var NcAlarmSettingsSchema = object({
|
|
|
20589
20603
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
20590
20604
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
20591
20605
|
*/
|
|
20592
|
-
nonBlocking: NcAlarmNonBlockingListSchema.default([])
|
|
20606
|
+
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
20607
|
+
/**
|
|
20608
|
+
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
20609
|
+
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
20610
|
+
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
20611
|
+
*/
|
|
20612
|
+
modeDelays: NcAlarmModeDelaysListSchema.default([])
|
|
20593
20613
|
});
|
|
20594
20614
|
/**
|
|
20595
20615
|
* Every field optional — a tab edits one control at a time.
|
|
20596
20616
|
*
|
|
20597
|
-
* `nonBlocking`
|
|
20598
|
-
* remove an inner `.default()`, so a patch that never
|
|
20599
|
-
* parse to `
|
|
20600
|
-
* (the same trap {@link NcRulePatchSchema} documents).
|
|
20617
|
+
* `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
|
|
20618
|
+
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
20619
|
+
* named the field would parse to `[]` and wipe every mode's list on an
|
|
20620
|
+
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
20621
|
+
* `modeDelays` means EDITS, not the stored overrides.
|
|
20601
20622
|
*/
|
|
20602
|
-
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20623
|
+
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20624
|
+
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
20625
|
+
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
20626
|
+
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
20627
|
+
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
20628
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
20629
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
|
|
20603
20630
|
/**
|
|
20604
20631
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
20605
20632
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -20699,6 +20726,28 @@ var NcAlarmConfigSchema = object({
|
|
|
20699
20726
|
*/
|
|
20700
20727
|
live: NcAlarmLiveSchema.optional()
|
|
20701
20728
|
});
|
|
20729
|
+
var NcAlarmSensorReadingSchema = _enum([
|
|
20730
|
+
"open",
|
|
20731
|
+
"closed",
|
|
20732
|
+
"unknown",
|
|
20733
|
+
"not-opening"
|
|
20734
|
+
]);
|
|
20735
|
+
/** One device's state as the alarm reads it — the classifier the arm check uses. */
|
|
20736
|
+
var NcAlarmSensorStateSchema = object({
|
|
20737
|
+
deviceId: number().int().positive(),
|
|
20738
|
+
reading: NcAlarmSensorReadingSchema,
|
|
20739
|
+
/** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
|
|
20740
|
+
state: string().nullable(),
|
|
20741
|
+
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
20742
|
+
unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
|
|
20743
|
+
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
20744
|
+
online: boolean().nullable()
|
|
20745
|
+
});
|
|
20746
|
+
var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
|
|
20747
|
+
var NcAlarmSensorsSchema = object({
|
|
20748
|
+
sensors: array(NcAlarmSensorStateSchema),
|
|
20749
|
+
readAt: number().int().nonnegative()
|
|
20750
|
+
});
|
|
20702
20751
|
/**
|
|
20703
20752
|
* ONE rule's demand on ONE camera's clip ring.
|
|
20704
20753
|
*
|
|
@@ -20789,7 +20838,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
20789
20838
|
}), method(object({}), NcAlarmConfigSchema, { auth: "admin" }), method(object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
|
|
20790
20839
|
kind: "mutation",
|
|
20791
20840
|
auth: "admin"
|
|
20792
|
-
});
|
|
20841
|
+
}), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
|
|
20793
20842
|
/**
|
|
20794
20843
|
* Zod schemas for persisted record types.
|
|
20795
20844
|
*
|
|
@@ -21136,12 +21185,26 @@ var CameraSensorRefSchema = object({
|
|
|
21136
21185
|
function cameraSensorRefKey(ref) {
|
|
21137
21186
|
return `${ref.addonId}/${ref.stableId}`;
|
|
21138
21187
|
}
|
|
21139
|
-
/**
|
|
21140
|
-
|
|
21141
|
-
|
|
21142
|
-
|
|
21143
|
-
|
|
21144
|
-
|
|
21188
|
+
/**
|
|
21189
|
+
* A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
|
|
21190
|
+
* `replace`: its motion is the camera's, and while one is READY the camera's
|
|
21191
|
+
* own motion no longer counts on its own. `confirm`: while one is READY the
|
|
21192
|
+
* camera's own motion counts only while a confirm sensor is active — with or
|
|
21193
|
+
* without a replace sensor (spec C2, the controller's ruling on Q1).
|
|
21194
|
+
*/
|
|
21195
|
+
var CameraSensorModeSchema = _enum([
|
|
21196
|
+
"in-addition",
|
|
21197
|
+
"confirm",
|
|
21198
|
+
"replace"
|
|
21199
|
+
]);
|
|
21200
|
+
/** A stored sensor with no mode — every CS-1 row — is in addition. */
|
|
21201
|
+
var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
|
|
21202
|
+
/**
|
|
21203
|
+
* A camera's attached sensors. A CS-1 row carried an envelope
|
|
21204
|
+
* `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
|
|
21205
|
+
* what the write stores (D672 rule 3), so it is never written again.
|
|
21206
|
+
*/
|
|
21207
|
+
var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
|
|
21145
21208
|
const seen = /* @__PURE__ */ new Set();
|
|
21146
21209
|
value.sensors.forEach((ref, index) => {
|
|
21147
21210
|
const key = cameraSensorRefKey(ref);
|
|
@@ -21153,39 +21216,41 @@ var CameraSensorsConfigSchema = object({
|
|
|
21153
21216
|
seen.add(key);
|
|
21154
21217
|
});
|
|
21155
21218
|
});
|
|
21156
|
-
|
|
21219
|
+
/** Every attachment names its mode; an older orchestrator that does not is in addition. */
|
|
21220
|
+
var AttachmentFields = {
|
|
21157
21221
|
addonId: string(),
|
|
21158
|
-
stableId: string()
|
|
21222
|
+
stableId: string(),
|
|
21223
|
+
mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
|
|
21159
21224
|
};
|
|
21160
21225
|
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
21161
21226
|
object({
|
|
21162
|
-
...
|
|
21227
|
+
...AttachmentFields,
|
|
21163
21228
|
state: literal("ready"),
|
|
21164
21229
|
deviceId: number(),
|
|
21165
21230
|
name: string(),
|
|
21166
21231
|
caps: array(string()).readonly()
|
|
21167
21232
|
}),
|
|
21168
21233
|
object({
|
|
21169
|
-
...
|
|
21234
|
+
...AttachmentFields,
|
|
21170
21235
|
state: literal("offline"),
|
|
21171
21236
|
deviceId: number(),
|
|
21172
21237
|
name: string(),
|
|
21173
21238
|
reason: _enum(["offline", "disabled"])
|
|
21174
21239
|
}),
|
|
21175
21240
|
object({
|
|
21176
|
-
...
|
|
21241
|
+
...AttachmentFields,
|
|
21177
21242
|
state: literal("missing"),
|
|
21178
21243
|
reason: string()
|
|
21179
21244
|
}),
|
|
21180
21245
|
object({
|
|
21181
|
-
...
|
|
21246
|
+
...AttachmentFields,
|
|
21182
21247
|
state: literal("unsupported"),
|
|
21183
21248
|
deviceId: number(),
|
|
21184
21249
|
name: string(),
|
|
21185
21250
|
reason: string()
|
|
21186
21251
|
}),
|
|
21187
21252
|
object({
|
|
21188
|
-
...
|
|
21253
|
+
...AttachmentFields,
|
|
21189
21254
|
state: literal("unreadable"),
|
|
21190
21255
|
reason: string()
|
|
21191
21256
|
})
|
|
@@ -21198,17 +21263,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
|
21198
21263
|
* say.
|
|
21199
21264
|
*/
|
|
21200
21265
|
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
21266
|
+
/** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
|
|
21267
|
+
var CameraOwnMotionSchema = _enum([
|
|
21268
|
+
"always",
|
|
21269
|
+
"when-confirmed",
|
|
21270
|
+
"never"
|
|
21271
|
+
]);
|
|
21272
|
+
/** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
|
|
21273
|
+
var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
|
|
21274
|
+
/**
|
|
21275
|
+
* The camera's OWN onboard motion (D696): the raw input the bridge combines,
|
|
21276
|
+
* never the effective value. The camera's `motion` slice is the effective one,
|
|
21277
|
+
* so a view of the camera's own row reads this.
|
|
21278
|
+
* - `atMs`: when the bridge received the camera's last own edge.
|
|
21279
|
+
* - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
|
|
21280
|
+
* AND it is younger than the window the bridge counts the camera's own motion
|
|
21281
|
+
* for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
|
|
21282
|
+
* sends a clear (heartbeats only) therefore reads `false` once no push came
|
|
21283
|
+
* within the window; a status read is a snapshot, so a live view re-asks.
|
|
21284
|
+
* Absent = this orchestrator has not received the camera's own motion since it
|
|
21285
|
+
* started (unknown, never "quiet"), or an orchestrator older than D696.
|
|
21286
|
+
*/
|
|
21287
|
+
var CameraRawLevelSchema = object({
|
|
21288
|
+
detected: boolean(),
|
|
21289
|
+
atMs: number()
|
|
21290
|
+
});
|
|
21201
21291
|
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
21202
|
-
object({
|
|
21292
|
+
object({
|
|
21293
|
+
state: literal("not-configured"),
|
|
21294
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
21295
|
+
}),
|
|
21203
21296
|
object({
|
|
21204
21297
|
state: literal("unreadable"),
|
|
21205
|
-
reason: string()
|
|
21298
|
+
reason: string(),
|
|
21299
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
21206
21300
|
}),
|
|
21207
21301
|
object({
|
|
21208
21302
|
state: literal("configured"),
|
|
21209
|
-
|
|
21303
|
+
cameraLevel: CameraRawLevelSchema.optional(),
|
|
21210
21304
|
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
21211
|
-
|
|
21305
|
+
/** Absent = an orchestrator older than CS-2: it does not say (D315). */
|
|
21306
|
+
cameraMotion: CameraOwnMotionSchema.optional(),
|
|
21307
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional(),
|
|
21308
|
+
notEnforced: CameraSensorsNotEnforcedSchema.optional()
|
|
21212
21309
|
})
|
|
21213
21310
|
]);
|
|
21214
21311
|
Object.freeze({
|
|
@@ -24399,8 +24496,10 @@ var RunnerCameraConfigSchema = object({
|
|
|
24399
24496
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
24400
24497
|
* analyzer providers) running on decoded frames in this runner.
|
|
24401
24498
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
24402
|
-
* analytics). The provider emits ProviderMotion
|
|
24403
|
-
*
|
|
24499
|
+
* analytics). The provider emits its raw push as `ProviderMotion`
|
|
24500
|
+
* (D673); the orchestrator's camera-sensors bridge re-emits the camera's
|
|
24501
|
+
* effective motion as `MotionOnMotionChanged`, which is what reaches
|
|
24502
|
+
* `reportMotion`.
|
|
24404
24503
|
*/
|
|
24405
24504
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24406
24505
|
/**
|
|
@@ -24577,7 +24676,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
24577
24676
|
hasGpu: boolean(),
|
|
24578
24677
|
inferenceBackend: string().optional(),
|
|
24579
24678
|
cpuCores: number().optional()
|
|
24580
|
-
})
|
|
24679
|
+
}),
|
|
24680
|
+
/**
|
|
24681
|
+
* Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
|
|
24682
|
+
* runner never writes it. ABSENT = a runner older than D696, which still
|
|
24683
|
+
* writes the slice from its phase machine; the orchestrator does not write
|
|
24684
|
+
* while any runner node is absent-or-unanswered, so one slice never has two
|
|
24685
|
+
* writers.
|
|
24686
|
+
*/
|
|
24687
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
24581
24688
|
});
|
|
24582
24689
|
/**
|
|
24583
24690
|
* Aggregate runtime metrics for the runner's whole local pool. Mirrors the
|
|
@@ -29418,6 +29525,17 @@ object({
|
|
|
29418
29525
|
deviceId: number(),
|
|
29419
29526
|
status: DeviceStatusSchema
|
|
29420
29527
|
});
|
|
29528
|
+
object({
|
|
29529
|
+
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
29530
|
+
lastPressedAt: number().nullable(),
|
|
29531
|
+
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
29532
|
+
pressCountSinceStart: number()
|
|
29533
|
+
});
|
|
29534
|
+
object({
|
|
29535
|
+
deviceId: number(),
|
|
29536
|
+
timestamp: number()
|
|
29537
|
+
});
|
|
29538
|
+
DeviceType.Button, DeviceType.Camera;
|
|
29421
29539
|
/**
|
|
29422
29540
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
29423
29541
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -31062,9 +31180,9 @@ object({
|
|
|
31062
31180
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
31063
31181
|
lastDetectedAt: number().nullable(),
|
|
31064
31182
|
/**
|
|
31065
|
-
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device
|
|
31066
|
-
* `null` while false and on every `Sensor`
|
|
31067
|
-
* constant's doc for the one-authority rule.
|
|
31183
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
|
|
31184
|
+
* orchestrator writes it, D696), `null` while false and on every `Sensor`
|
|
31185
|
+
* device (D475) — see that constant's doc for the one-authority rule.
|
|
31068
31186
|
*
|
|
31069
31187
|
* ## Reading this field still arms nothing
|
|
31070
31188
|
*
|
|
@@ -31082,38 +31200,41 @@ object({
|
|
|
31082
31200
|
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
31083
31201
|
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
31084
31202
|
*
|
|
31085
|
-
* ## Who writes it
|
|
31086
|
-
*
|
|
31087
|
-
* - **Cameras** — the
|
|
31088
|
-
*
|
|
31089
|
-
* `
|
|
31090
|
-
* `
|
|
31091
|
-
*
|
|
31092
|
-
*
|
|
31093
|
-
* a
|
|
31094
|
-
*
|
|
31095
|
-
*
|
|
31096
|
-
*
|
|
31097
|
-
*
|
|
31098
|
-
*
|
|
31099
|
-
*
|
|
31100
|
-
*
|
|
31101
|
-
*
|
|
31102
|
-
*
|
|
31103
|
-
* `
|
|
31104
|
-
*
|
|
31105
|
-
*
|
|
31106
|
-
*
|
|
31107
|
-
*
|
|
31108
|
-
*
|
|
31109
|
-
*
|
|
31110
|
-
* This predates D475 and is not fixed there: the fix touches every
|
|
31111
|
-
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
31112
|
-
* "sole writer" wording without also removing the other writers.
|
|
31203
|
+
* ## Who writes it (D696)
|
|
31204
|
+
*
|
|
31205
|
+
* - **Cameras** — the orchestrator, and nothing else. It writes the camera's
|
|
31206
|
+
* EFFECTIVE motion (`addon-pipeline-orchestrator`
|
|
31207
|
+
* `camera-sensors/motion-slice.ts`), alongside the effective
|
|
31208
|
+
* `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
|
|
31209
|
+
* for a split camera, an unsplit emitter's direct event, the analyzer and
|
|
31210
|
+
* device activity, as the camera's `motionSources` counts them. A source
|
|
31211
|
+
* that never sends a clear falls one window after its last `true`.
|
|
31212
|
+
* `lastDetectedAt` moves only on an effective rise. No camera provider
|
|
31213
|
+
* writes this slice (not even a boot seed), and neither does the runner's
|
|
31214
|
+
* phase machine: its phase is "a session is attached" for every on-motion
|
|
31215
|
+
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
31216
|
+
* A provider's `isDetected` answers from the hub's slice.
|
|
31217
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
31218
|
+
* imports) — the provider pushes both edges itself, from the upstream
|
|
31219
|
+
* system's own state change. That is the sensor's own fact.
|
|
31220
|
+
*
|
|
31221
|
+
* `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
|
|
31222
|
+
* `motion` slice; each sensor writer is a named exemption.
|
|
31223
|
+
*
|
|
31224
|
+
* This replaces the D475 §4 rule ("the phase machine is the sole writer").
|
|
31225
|
+
* That rule was never true: Hikvision and Amcrest wrote the slice raw beside
|
|
31226
|
+
* it, every provider seeded it at boot, and every session left it
|
|
31227
|
+
* `detected: true` after its detach.
|
|
31113
31228
|
*/
|
|
31114
31229
|
autoClearAfterMs: number().nullable()
|
|
31115
31230
|
});
|
|
31116
|
-
|
|
31231
|
+
/**
|
|
31232
|
+
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
31233
|
+
* event `EventCategory.MotionOnMotionChanged`. Single source of truth
|
|
31234
|
+
* — both the cap event surface and the bus payload type alias to this
|
|
31235
|
+
* schema.
|
|
31236
|
+
*/
|
|
31237
|
+
var MotionOnMotionChangedDataSchema = object({
|
|
31117
31238
|
deviceId: number(),
|
|
31118
31239
|
detected: boolean(),
|
|
31119
31240
|
timestamp: number(),
|
|
@@ -41172,6 +41293,12 @@ Object.freeze({
|
|
|
41172
41293
|
addonId: null,
|
|
41173
41294
|
access: "view"
|
|
41174
41295
|
},
|
|
41296
|
+
"notificationRules.getAlarmSensors": {
|
|
41297
|
+
capName: "notification-rules",
|
|
41298
|
+
capScope: "system",
|
|
41299
|
+
addonId: null,
|
|
41300
|
+
access: "view"
|
|
41301
|
+
},
|
|
41175
41302
|
"notificationRules.getClipRetentionAsks": {
|
|
41176
41303
|
capName: "notification-rules",
|
|
41177
41304
|
capScope: "system",
|
|
@@ -45655,6 +45782,11 @@ Object.freeze({
|
|
|
45655
45782
|
form: "single",
|
|
45656
45783
|
optional: false
|
|
45657
45784
|
}],
|
|
45785
|
+
"notificationRules.getAlarmSensors": [{
|
|
45786
|
+
name: "deviceIds",
|
|
45787
|
+
form: "array",
|
|
45788
|
+
optional: false
|
|
45789
|
+
}],
|
|
45658
45790
|
"notificationRules.setDeviceMuted": [{
|
|
45659
45791
|
name: "deviceId",
|
|
45660
45792
|
form: "single",
|
|
@@ -47590,6 +47722,7 @@ TimelapseRuleInputSchema.extend({
|
|
|
47590
47722
|
createdAt: number(),
|
|
47591
47723
|
updatedAt: number()
|
|
47592
47724
|
});
|
|
47725
|
+
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
47593
47726
|
object({
|
|
47594
47727
|
/**
|
|
47595
47728
|
* Fraction of the box's own size added on EACH side before cutting.
|