@camstack/types 1.2.65 → 1.2.67
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 +2 -2
- package/dist/addon.mjs +2 -2
- package/dist/capabilities/air-quality-sensor.cap.d.ts +10 -0
- package/dist/capabilities/alarm-panel.cap.d.ts +10 -0
- package/dist/capabilities/ambient-light-sensor.cap.d.ts +10 -0
- package/dist/capabilities/audio-metrics.cap.d.ts +7 -0
- package/dist/capabilities/automation-control.cap.d.ts +7 -0
- package/dist/capabilities/battery.cap.d.ts +10 -0
- package/dist/capabilities/binary.cap.d.ts +10 -0
- package/dist/capabilities/brightness.cap.d.ts +7 -0
- package/dist/capabilities/camera-streams.cap.d.ts +7 -0
- package/dist/capabilities/capability-definition.d.ts +58 -0
- package/dist/capabilities/carbon-monoxide.cap.d.ts +10 -0
- package/dist/capabilities/climate-control.cap.d.ts +7 -0
- package/dist/capabilities/color.cap.d.ts +7 -0
- package/dist/capabilities/connectivity.cap.d.ts +10 -0
- package/dist/capabilities/consumables.cap.d.ts +7 -0
- package/dist/capabilities/contact.cap.d.ts +10 -0
- package/dist/capabilities/control.cap.d.ts +7 -0
- package/dist/capabilities/cover.cap.d.ts +10 -0
- package/dist/capabilities/day-night.cap.d.ts +10 -0
- package/dist/capabilities/device-discovery.cap.d.ts +7 -0
- package/dist/capabilities/device-status.cap.d.ts +10 -0
- package/dist/capabilities/doorbell.cap.d.ts +7 -0
- package/dist/capabilities/enum-sensor.cap.d.ts +10 -0
- package/dist/capabilities/event-emitter.cap.d.ts +7 -0
- package/dist/capabilities/fan-control.cap.d.ts +7 -0
- package/dist/capabilities/feature-probe.cap.d.ts +7 -0
- package/dist/capabilities/flood.cap.d.ts +10 -0
- package/dist/capabilities/gas.cap.d.ts +10 -0
- package/dist/capabilities/humidifier.cap.d.ts +7 -0
- package/dist/capabilities/humidity-sensor.cap.d.ts +10 -0
- package/dist/capabilities/image-settings.cap.d.ts +10 -0
- package/dist/capabilities/image.cap.d.ts +7 -0
- package/dist/capabilities/index.d.ts +3 -3
- package/dist/capabilities/lawn-mower-control.cap.d.ts +7 -0
- package/dist/capabilities/lock-control.cap.d.ts +10 -0
- package/dist/capabilities/media-player.cap.d.ts +7 -0
- package/dist/capabilities/motion-trigger.cap.d.ts +7 -0
- package/dist/capabilities/motion-zones.cap.d.ts +10 -0
- package/dist/capabilities/motion.cap.d.ts +7 -0
- package/dist/capabilities/native-object-detection.cap.d.ts +10 -0
- package/dist/capabilities/notification-output.cap.d.ts +62 -0
- package/dist/capabilities/notification-rules.cap.d.ts +134 -6
- package/dist/capabilities/notifier.cap.d.ts +7 -0
- package/dist/capabilities/numeric-sensor.cap.d.ts +10 -0
- package/dist/capabilities/osd-manager.cap.d.ts +14 -0
- package/dist/capabilities/pet-feeder.cap.d.ts +7 -0
- package/dist/capabilities/power-meter.cap.d.ts +10 -0
- package/dist/capabilities/presence.cap.d.ts +10 -0
- package/dist/capabilities/pressure-sensor.cap.d.ts +10 -0
- package/dist/capabilities/privacy-mask.cap.d.ts +10 -0
- package/dist/capabilities/ptz-autotrack.cap.d.ts +7 -0
- package/dist/capabilities/scene-monitor.cap.d.ts +7 -0
- package/dist/capabilities/script-runner.cap.d.ts +7 -0
- package/dist/capabilities/smoke.cap.d.ts +10 -0
- package/dist/capabilities/stream-params.cap.d.ts +10 -0
- package/dist/capabilities/switch.cap.d.ts +10 -0
- package/dist/capabilities/tamper.cap.d.ts +10 -0
- package/dist/capabilities/temperature-sensor.cap.d.ts +10 -0
- package/dist/capabilities/update.cap.d.ts +7 -0
- package/dist/capabilities/vacuum-control.cap.d.ts +7 -0
- package/dist/capabilities/valve.cap.d.ts +7 -0
- package/dist/capabilities/vibration.cap.d.ts +10 -0
- package/dist/capabilities/water-heater.cap.d.ts +7 -0
- package/dist/capabilities/weather.cap.d.ts +7 -0
- package/dist/capabilities/zone-analytics.cap.d.ts +7 -0
- package/dist/capabilities/zone-rules.cap.d.ts +7 -0
- package/dist/capabilities/zones.cap.d.ts +7 -0
- package/dist/catalogs/coco-classmap.d.ts +21 -0
- package/dist/device/system-mirror.d.ts +37 -0
- package/dist/generated/runtime-state-durability.d.ts +31 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1345 -91
- package/dist/index.mjs +1322 -92
- package/dist/notification/audio-condition.d.ts +118 -0
- package/dist/{sleep-BxjBLp3L.mjs → sleep-CSgK0rNX.mjs} +3 -1
- package/dist/{sleep-BszXLEvP.js → sleep-Dh1EJSqF.js} +8 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-DxZbWydC.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-Dh1EJSqF.js");
|
|
4
4
|
const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
|
|
5
5
|
const require_enums = require("./enums.js");
|
|
6
6
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
@@ -6664,7 +6664,14 @@ var cameraStreamsCapability = {
|
|
|
6664
6664
|
low: zod.z.string().optional()
|
|
6665
6665
|
}),
|
|
6666
6666
|
lastChangedAt: zod.z.number()
|
|
6667
|
-
})
|
|
6667
|
+
}),
|
|
6668
|
+
/**
|
|
6669
|
+
* Runtime-state durability: **session** — a restored `slotStatuses: streaming` for a camera that has been dark for two hours is a lie the UI renders as truth.
|
|
6670
|
+
*
|
|
6671
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
6672
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
6673
|
+
*/
|
|
6674
|
+
durability: "session"
|
|
6668
6675
|
};
|
|
6669
6676
|
//#endregion
|
|
6670
6677
|
//#region src/capabilities/cap-router-predicates.ts
|
|
@@ -7831,6 +7838,13 @@ var deviceDiscoveryCapability = {
|
|
|
7831
7838
|
kind: "poll"
|
|
7832
7839
|
},
|
|
7833
7840
|
runtimeState: DeviceDiscoveryStatusSchema.extend({ lastFetchedAt: zod.z.number().int().nonnegative() }),
|
|
7841
|
+
/**
|
|
7842
|
+
* Runtime-state durability: **session** — 5.7 KB of scan output on the largest device, fully re-derivable by re-scanning.
|
|
7843
|
+
*
|
|
7844
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
7845
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
7846
|
+
*/
|
|
7847
|
+
durability: "session",
|
|
7834
7848
|
methods: {
|
|
7835
7849
|
/**
|
|
7836
7850
|
* Snapshot of the current `discovered` list. Returns the
|
|
@@ -10453,11 +10467,33 @@ var NotificationFormatSchema = zod.z.enum([
|
|
|
10453
10467
|
* Named by INTENT, never by glyph. "check" would tie the vocabulary to one
|
|
10454
10468
|
* renderer's icon set; "acknowledge" survives an adapter that draws it
|
|
10455
10469
|
* differently.
|
|
10470
|
+
*
|
|
10471
|
+
* ── A TOKEN IS NOT A WIRE VALUE ─────────────────────────────────────
|
|
10472
|
+
*
|
|
10473
|
+
* These names are for US. **No adapter may forward one verbatim.** Each maps
|
|
10474
|
+
* the whole set onto its own renderer's vocabulary through a
|
|
10475
|
+
* `Record<NotificationActionIcon, string>` — a Record, never a lookup with a
|
|
10476
|
+
* fallback, so adding a member here fails every adapter's build until someone
|
|
10477
|
+
* decides its glyph, which is the only place that decision can be made
|
|
10478
|
+
* honestly.
|
|
10479
|
+
*
|
|
10480
|
+
* This paragraph is the bug. Zentik declared `actionIcons: true` and passed
|
|
10481
|
+
* `disarm` straight through; iOS feeds that string to
|
|
10482
|
+
* `UNNotificationActionIcon(systemImageName:)`, `disarm` is not an SF Symbol,
|
|
10483
|
+
* and every snooze and alarm button arrived BLANK. A pass-through is not a
|
|
10484
|
+
* mapping, and "the field is documented" is not "the value renders".
|
|
10485
|
+
*
|
|
10486
|
+
* Adding a member is TRAIN-BOUND. The enum lives in the published
|
|
10487
|
+
* `@camstack/server` closure and the cap seam validates against the HUB's copy,
|
|
10488
|
+
* so an addon that emits a token the running hub does not know does not lose an
|
|
10489
|
+
* icon — its whole `send` fails Zod validation and the notification never
|
|
10490
|
+
* arrives. Never emit a new token from an addon before the train carrying it.
|
|
10456
10491
|
*/
|
|
10457
10492
|
var NotificationActionIconSchema = zod.z.enum([
|
|
10458
10493
|
"acknowledge",
|
|
10459
10494
|
"dismiss",
|
|
10460
10495
|
"silence",
|
|
10496
|
+
"snooze",
|
|
10461
10497
|
"view",
|
|
10462
10498
|
"play",
|
|
10463
10499
|
"open",
|
|
@@ -10465,9 +10501,13 @@ var NotificationActionIconSchema = zod.z.enum([
|
|
|
10465
10501
|
"lock",
|
|
10466
10502
|
"unlock",
|
|
10467
10503
|
"arm",
|
|
10504
|
+
"arm-home",
|
|
10505
|
+
"arm-away",
|
|
10506
|
+
"arm-night",
|
|
10468
10507
|
"disarm",
|
|
10469
10508
|
"light",
|
|
10470
|
-
"alert"
|
|
10509
|
+
"alert",
|
|
10510
|
+
"camera"
|
|
10471
10511
|
]);
|
|
10472
10512
|
/** A single tap-through action button. */
|
|
10473
10513
|
var NotificationActionSchema = zod.z.object({
|
|
@@ -10483,7 +10523,23 @@ var NotificationActionSchema = zod.z.object({
|
|
|
10483
10523
|
* else — see `notification-center/action-token.ts` for what that does and
|
|
10484
10524
|
* does not buy.
|
|
10485
10525
|
*/
|
|
10486
|
-
destructive: zod.z.boolean().optional()
|
|
10526
|
+
destructive: zod.z.boolean().optional(),
|
|
10527
|
+
/**
|
|
10528
|
+
* How the tap should REACH the url.
|
|
10529
|
+
*
|
|
10530
|
+
* `navigate` (absent, and every button authored before this field) opens it:
|
|
10531
|
+
* the phone leaves the notification and shows whatever the callback returns.
|
|
10532
|
+
* That is right for a button whose answer the operator wants to read.
|
|
10533
|
+
*
|
|
10534
|
+
* `background` fires it as a POST and stays put. It exists for the buttons
|
|
10535
|
+
* whose whole point is not to interrupt — "silence this for 30 minutes" is
|
|
10536
|
+
* an answer to the notification, and being thrown into a browser tab to
|
|
10537
|
+
* confirm it costs more attention than the notification did. A backend that
|
|
10538
|
+
* cannot do a background call renders it as an ordinary link (the adapters
|
|
10539
|
+
* fall back rather than dropping the button), so this is a preference, never
|
|
10540
|
+
* a requirement.
|
|
10541
|
+
*/
|
|
10542
|
+
mode: zod.z.enum(["navigate", "background"]).optional()
|
|
10487
10543
|
});
|
|
10488
10544
|
/**
|
|
10489
10545
|
* The canonical notification. `body` is the only hard field (Apprise model).
|
|
@@ -11009,6 +11065,29 @@ var MACRO_LABELS = [
|
|
|
11009
11065
|
name: "Package"
|
|
11010
11066
|
}
|
|
11011
11067
|
];
|
|
11068
|
+
/**
|
|
11069
|
+
* The class names a per-class COUNT can ever be keyed on — the macro ids, and
|
|
11070
|
+
* only those.
|
|
11071
|
+
*
|
|
11072
|
+
* `preserveOriginal: false` below is the whole reason this set exists: the
|
|
11073
|
+
* executor maps each raw COCO label onto its macro and DROPS everything else,
|
|
11074
|
+
* so a tracked detection's `className` is always one of {@link MACRO_LABELS}.
|
|
11075
|
+
* Any surface that indexes counts by class name — the ZoneAnalytics occupancy
|
|
11076
|
+
* snapshot's `byClass`, and therefore every occupancy rule — can match nothing
|
|
11077
|
+
* else. Derived from the catalog, never hand-listed, so a new macro joins it by
|
|
11078
|
+
* being declared once.
|
|
11079
|
+
*
|
|
11080
|
+
* Cost of not having it, 2026-08-12: the notification rule editor offered the
|
|
11081
|
+
* full taxonomy for an occupancy class (occupancy is the one condition that
|
|
11082
|
+
* does not go through the engine's macro-expanding `expandClassSelector`), two
|
|
11083
|
+
* live rules were authored on `car`, and both counters read 0 forever.
|
|
11084
|
+
*/
|
|
11085
|
+
var DETECTION_MACRO_CLASSES = new Set(MACRO_LABELS.map((l) => l.id));
|
|
11086
|
+
/** True when `className` is a macro the detector can actually emit (and hence a
|
|
11087
|
+
* class a count can be keyed on) — see {@link DETECTION_MACRO_CLASSES}. */
|
|
11088
|
+
function isDetectionMacroClass(className) {
|
|
11089
|
+
return DETECTION_MACRO_CLASSES.has(className.trim().toLowerCase());
|
|
11090
|
+
}
|
|
11012
11091
|
var COCO_TO_MACRO = {
|
|
11013
11092
|
mapping: {
|
|
11014
11093
|
person: "person",
|
|
@@ -11726,7 +11805,17 @@ var alarmPanelCapability = {
|
|
|
11726
11805
|
* full slice; renders an arm button per `availableModes` entry and
|
|
11727
11806
|
* a PIN field iff `requiresCode === true`.
|
|
11728
11807
|
*/
|
|
11729
|
-
runtimeState: AlarmPanelStatusSchema
|
|
11808
|
+
runtimeState: AlarmPanelStatusSchema,
|
|
11809
|
+
/**
|
|
11810
|
+
* Runtime-state durability: **restored** — armed state is the one thing a panel must not lose across a restart.
|
|
11811
|
+
*
|
|
11812
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
11813
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
11814
|
+
*/
|
|
11815
|
+
durability: "restored",
|
|
11816
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
11817
|
+
* whether persisting is worth a SQLite commit. */
|
|
11818
|
+
volatileStateFields: ["lastChangedAt"]
|
|
11730
11819
|
};
|
|
11731
11820
|
//#endregion
|
|
11732
11821
|
//#region src/capabilities/mask-shape.ts
|
|
@@ -11874,6 +11963,8 @@ var NcSystemEventKindSchema = zod.z.enum([
|
|
|
11874
11963
|
"alarm-triggered",
|
|
11875
11964
|
"alarm-armed",
|
|
11876
11965
|
"alarm-disarmed",
|
|
11966
|
+
"alarm-arming",
|
|
11967
|
+
"alarm-arm-refused",
|
|
11877
11968
|
"camera-online",
|
|
11878
11969
|
"camera-offline",
|
|
11879
11970
|
"camera-disabled",
|
|
@@ -11893,16 +11984,22 @@ var NC_LEGACY_SYSTEM_EVENT_KINDS = new Set([
|
|
|
11893
11984
|
*/
|
|
11894
11985
|
var NC_AUTHORABLE_SYSTEM_EVENT_KINDS = NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KINDS.has(kind));
|
|
11895
11986
|
/**
|
|
11896
|
-
* The panel's
|
|
11987
|
+
* The panel's transitions, as ONE list.
|
|
11897
11988
|
*
|
|
11898
11989
|
* Named here rather than spelled out at each of the four sites that need them
|
|
11899
11990
|
* (the emitter, the intake, the editor group, the combined-notification gate),
|
|
11900
|
-
* because a
|
|
11901
|
-
*
|
|
11991
|
+
* because a transition added to the enum and forgotten at one of them is an
|
|
11992
|
+
* alarm state nobody can be notified about. That is exactly what this list
|
|
11993
|
+
* failed to prevent while it held three: `alarm-arming` was the fourth.
|
|
11994
|
+
*
|
|
11995
|
+
* In LIFECYCLE order, which is the order an editor lists them in and the order
|
|
11996
|
+
* a person experiences them — not the order they were added.
|
|
11902
11997
|
*/
|
|
11903
11998
|
var NC_ALARM_SYSTEM_EVENT_KINDS = [
|
|
11904
|
-
"alarm-
|
|
11999
|
+
"alarm-arm-refused",
|
|
12000
|
+
"alarm-arming",
|
|
11905
12001
|
"alarm-armed",
|
|
12002
|
+
"alarm-triggered",
|
|
11906
12003
|
"alarm-disarmed"
|
|
11907
12004
|
];
|
|
11908
12005
|
/**
|
|
@@ -11934,6 +12031,26 @@ var NcSystemEventConditionSchema = zod.z.object({
|
|
|
11934
12031
|
* unique key `(ruleId, trackId, targetId)`. Not a rule field in P1.
|
|
11935
12032
|
*/
|
|
11936
12033
|
var NC_MAX_PER_TRACK_IMMEDIATE = 1;
|
|
12034
|
+
/** Hard ceiling on a window (24h). A snooze that could not expire would be an
|
|
12035
|
+
* outage the operator asked for once and forgot. */
|
|
12036
|
+
var NC_SNOOZE_MAX_MINUTES = 1440;
|
|
12037
|
+
/**
|
|
12038
|
+
* The durations a notification offers when its rule does not say otherwise.
|
|
12039
|
+
*
|
|
12040
|
+
* MINUTES, and short ones: a snooze button is answered on a lock screen, and
|
|
12041
|
+
* the three choices that fit there are "the next few minutes", "the next half
|
|
12042
|
+
* hour" and "the next hour". Anything longer is a decision somebody sits down
|
|
12043
|
+
* to make, which is what the app's own snooze surface is for.
|
|
12044
|
+
*
|
|
12045
|
+
* Resolved in CODE (`snoozeChoices`), never as a Zod default — see
|
|
12046
|
+
* {@link NcRuleInputSchema.shape.snoozeOptions} for why the distinction is
|
|
12047
|
+
* load-bearing.
|
|
12048
|
+
*/
|
|
12049
|
+
var NC_DEFAULT_SNOOZE_MINUTES = [
|
|
12050
|
+
10,
|
|
12051
|
+
30,
|
|
12052
|
+
60
|
|
12053
|
+
];
|
|
11937
12054
|
/** One weekly activation window. `startMinute > endMinute` crosses midnight. */
|
|
11938
12055
|
var NcScheduleWindowSchema = zod.z.object({
|
|
11939
12056
|
/** Days of week the window STARTS on (0 = Sunday … 6 = Saturday). */
|
|
@@ -12335,15 +12452,15 @@ var NcConditionsSchema = zod.z.object({
|
|
|
12335
12452
|
* (an `immediate` rule naming an `audio-*` class, one notification per
|
|
12336
12453
|
* classified sample) stays exactly as it was for rules that already use it.
|
|
12337
12454
|
*
|
|
12338
|
-
*
|
|
12339
|
-
* rather than an
|
|
12340
|
-
* (`camstack/src/data/notification-center.ts`, guarded by
|
|
12341
|
-
* `scripts/check-viewer-condition-mirror.ts`) and its rule editor
|
|
12455
|
+
* In {@link NC_CONDITION_CATALOG} since P2, and the ORDER it got there is the
|
|
12456
|
+
* rule rather than an accident: the viewer mirrors the descriptor enums BY
|
|
12457
|
+
* HAND (`camstack/src/data/notification-center.ts`, guarded by
|
|
12458
|
+
* `scripts/check-viewer-condition-mirror.ts`) and its rule editor strips the
|
|
12342
12459
|
* condition fields it does not know when a rule is saved from the phone.
|
|
12343
12460
|
* Publishing an editor for a condition the app cannot round-trip is how an
|
|
12344
|
-
* operator loses a rule's conditions by opening it — so the
|
|
12345
|
-
*
|
|
12346
|
-
*
|
|
12461
|
+
* operator loses a rule's conditions by opening it — so the viewer mirror
|
|
12462
|
+
* (P3, shipped) went FIRST, and the descriptor an editor renders from
|
|
12463
|
+
* follows here.
|
|
12347
12464
|
*/
|
|
12348
12465
|
audio: NcAudioConditionSchema.optional()
|
|
12349
12466
|
});
|
|
@@ -12580,6 +12697,30 @@ var NcRuleInputSchema = zod.z.object({
|
|
|
12580
12697
|
*/
|
|
12581
12698
|
snoozeAllowGlobal: zod.z.boolean().optional(),
|
|
12582
12699
|
/**
|
|
12700
|
+
* The snooze durations THIS rule's notification offers as buttons, in
|
|
12701
|
+
* minutes.
|
|
12702
|
+
*
|
|
12703
|
+
* Three states, and all three are distinct — which is exactly why this is
|
|
12704
|
+
* `.optional()` and never `.default()`. A Zod default does not run on the
|
|
12705
|
+
* addon cap path (three production failures in one day), so a schema default
|
|
12706
|
+
* would collapse the first two:
|
|
12707
|
+
*
|
|
12708
|
+
* | value | meaning |
|
|
12709
|
+
* | --- | --- |
|
|
12710
|
+
* | absent | the operator never said ⇒ {@link NC_DEFAULT_SNOOZE_MINUTES} |
|
|
12711
|
+
* | `[]` | **no snooze buttons on this rule** — the explicit override |
|
|
12712
|
+
* | a list | these choices, de-duplicated and sorted, at most four |
|
|
12713
|
+
*
|
|
12714
|
+
* `.max(4)` because the notifier's own action budget is small (ntfy allows
|
|
12715
|
+
* three buttons in total) and a rule that spent it all on snooze choices
|
|
12716
|
+
* would push its own tap-through actions off the notification.
|
|
12717
|
+
*
|
|
12718
|
+
* An empty list is NOT an alarm exemption: a rule the alarm is about, or
|
|
12719
|
+
* that arms the panel, is exempt automatically and cannot be silenced by a
|
|
12720
|
+
* window from anywhere (D133).
|
|
12721
|
+
*/
|
|
12722
|
+
snoozeOptions: zod.z.array(zod.z.number().int().min(1).max(NC_SNOOZE_MAX_MINUTES)).max(4).optional(),
|
|
12723
|
+
/**
|
|
12583
12724
|
* Devices this rule ACTUATES — arm the alarm, open a gate, turn on a light.
|
|
12584
12725
|
*
|
|
12585
12726
|
* This is what makes the rule set the alarm's trigger set without the alarm
|
|
@@ -12679,6 +12820,7 @@ var NcConditionDescriptorSchema = zod.z.object({
|
|
|
12679
12820
|
"device",
|
|
12680
12821
|
"package",
|
|
12681
12822
|
"occupancy",
|
|
12823
|
+
"audio",
|
|
12682
12824
|
"system"
|
|
12683
12825
|
]),
|
|
12684
12826
|
label: zod.z.string(),
|
|
@@ -12697,6 +12839,7 @@ var NcConditionDescriptorSchema = zod.z.object({
|
|
|
12697
12839
|
"crossingSelect",
|
|
12698
12840
|
"polygonDraw",
|
|
12699
12841
|
"occupancy",
|
|
12842
|
+
"audio",
|
|
12700
12843
|
"deviceState",
|
|
12701
12844
|
"systemEvent"
|
|
12702
12845
|
]),
|
|
@@ -12787,13 +12930,17 @@ var NC_CONDITION_CATALOG = [
|
|
|
12787
12930
|
label: "Server update available"
|
|
12788
12931
|
},
|
|
12789
12932
|
{
|
|
12790
|
-
value: "alarm-
|
|
12791
|
-
label: "Alarm
|
|
12933
|
+
value: "alarm-arming",
|
|
12934
|
+
label: "Alarm arming (exit delay)"
|
|
12792
12935
|
},
|
|
12793
12936
|
{
|
|
12794
12937
|
value: "alarm-armed",
|
|
12795
12938
|
label: "Alarm armed"
|
|
12796
12939
|
},
|
|
12940
|
+
{
|
|
12941
|
+
value: "alarm-triggered",
|
|
12942
|
+
label: "Alarm triggered"
|
|
12943
|
+
},
|
|
12797
12944
|
{
|
|
12798
12945
|
value: "alarm-disarmed",
|
|
12799
12946
|
label: "Alarm disarmed"
|
|
@@ -13094,6 +13241,16 @@ var NC_CONDITION_CATALOG = [
|
|
|
13094
13241
|
phase: "P1",
|
|
13095
13242
|
description: "ZoneAnalytics occupancy edge (optionally zone/class-scoped): count crosses the threshold and holds for sustainSeconds. Fail-closed on a missing snapshot."
|
|
13096
13243
|
},
|
|
13244
|
+
{
|
|
13245
|
+
id: "audio",
|
|
13246
|
+
group: "audio",
|
|
13247
|
+
label: "Sound",
|
|
13248
|
+
valueType: "audio",
|
|
13249
|
+
operator: "anyOf",
|
|
13250
|
+
appliesTo: ["immediate"],
|
|
13251
|
+
phase: "P2",
|
|
13252
|
+
description: "Fires when at least hitPercent% of the samples in a samplingSeconds window are hits — a hit clears the dBFS floor AND carries one of the chosen sounds. Both filters are optional and independent, but naming NEITHER never matches: every sample would be a hit, so the engine refuses rather than notifying on silence. dBFS is negative-going (0 = full scale, -96 = silence)."
|
|
13253
|
+
},
|
|
13097
13254
|
{
|
|
13098
13255
|
id: "customZones",
|
|
13099
13256
|
group: "zones",
|
|
@@ -13229,9 +13386,6 @@ var NcSnoozeScopeSchema = zod.z.enum([
|
|
|
13229
13386
|
"device",
|
|
13230
13387
|
"all"
|
|
13231
13388
|
]);
|
|
13232
|
-
/** Hard ceiling on a window (24h). A snooze that could not expire would be an
|
|
13233
|
-
* outage the operator asked for once and forgot. */
|
|
13234
|
-
var NC_SNOOZE_MAX_MINUTES = 1440;
|
|
13235
13389
|
/**
|
|
13236
13390
|
* Client-authored snooze. The server stamps `userId`, `startedAt` and
|
|
13237
13391
|
* `expiresAt` — a DURATION is sent rather than an instant so a client with a
|
|
@@ -13244,6 +13398,19 @@ var NcSnoozeInputSchema = zod.z.object({
|
|
|
13244
13398
|
ruleId: zod.z.string().optional(),
|
|
13245
13399
|
/** Required when `scope: 'device'`. */
|
|
13246
13400
|
deviceId: zod.z.number().int().optional(),
|
|
13401
|
+
/**
|
|
13402
|
+
* Narrow the window to these subject classes — "the cat, not the person".
|
|
13403
|
+
*
|
|
13404
|
+
* ORTHOGONAL to `scope`, deliberately, and absent means EVERY class: that is
|
|
13405
|
+
* what every window authored before this field meant, so no persisted row
|
|
13406
|
+
* changes meaning and no client has to learn anything to keep working.
|
|
13407
|
+
*
|
|
13408
|
+
* It is what makes the window's real key `(deviceId, classes[])` and lets it
|
|
13409
|
+
* cross rules (D133): the operator points at a camera and a kind of thing,
|
|
13410
|
+
* not at whichever of their four rules happened to produce the notification
|
|
13411
|
+
* they are dismissing.
|
|
13412
|
+
*/
|
|
13413
|
+
classes: zod.z.array(zod.z.string().min(1)).min(1).optional(),
|
|
13247
13414
|
durationMinutes: zod.z.number().int().min(1).max(NC_SNOOZE_MAX_MINUTES),
|
|
13248
13415
|
/**
|
|
13249
13416
|
* Silence this for EVERY recipient, not just the caller. Permission is
|
|
@@ -13269,6 +13436,10 @@ var NcSnoozeSchema = zod.z.object({
|
|
|
13269
13436
|
scope: NcSnoozeScopeSchema,
|
|
13270
13437
|
ruleId: zod.z.string().optional(),
|
|
13271
13438
|
deviceId: zod.z.number().int().optional(),
|
|
13439
|
+
/** Subject classes this window covers. ABSENT = every class — see
|
|
13440
|
+
* {@link NcSnoozeInputSchema.shape.classes}. Lives in the JSON blob and has
|
|
13441
|
+
* no SQLite column: nothing queries a window by class. */
|
|
13442
|
+
classes: zod.z.array(zod.z.string().min(1)).min(1).optional(),
|
|
13272
13443
|
startedAt: zod.z.number(),
|
|
13273
13444
|
/** Exclusive: at exactly this instant the snooze is over. Expiry is a
|
|
13274
13445
|
* COMPARISON, not a job — no sweeper can leave the operator silenced. */
|
|
@@ -16061,7 +16232,14 @@ var zonesCapability = {
|
|
|
16061
16232
|
* handle. Slice shape is `{ zones: Zone[] }` so future extensions
|
|
16062
16233
|
* (e.g. zone groupings) can sit alongside the polygon list.
|
|
16063
16234
|
*/
|
|
16064
|
-
runtimeState: zod.z.object({ zones: zod.z.array(ZoneSchema).readonly() })
|
|
16235
|
+
runtimeState: zod.z.object({ zones: zod.z.array(ZoneSchema).readonly() }),
|
|
16236
|
+
/**
|
|
16237
|
+
* Runtime-state durability: **restored** — written only on operator mutation, so a camera that never had one has nothing to re-derive from. This is the slice `zone-mirror-hydration.ts` exists to paper over.
|
|
16238
|
+
*
|
|
16239
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
16240
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
16241
|
+
*/
|
|
16242
|
+
durability: "restored"
|
|
16065
16243
|
};
|
|
16066
16244
|
//#endregion
|
|
16067
16245
|
//#region src/capabilities/pipeline-runner.cap.ts
|
|
@@ -16233,6 +16411,22 @@ var detectionFpsField = {
|
|
|
16233
16411
|
default: 10,
|
|
16234
16412
|
step: 1
|
|
16235
16413
|
};
|
|
16414
|
+
/**
|
|
16415
|
+
* The occupancy re-check interval. DEFAULT 300 s (2026-08-13 — was 30 s).
|
|
16416
|
+
*
|
|
16417
|
+
* The recheck is now on by default (a parked car is invisible to occupancy
|
|
16418
|
+
* rules until the stationary registry has been rebuilt by motion, which after a
|
|
16419
|
+
* restart may be never on a quiet camera). Each cycle re-subscribes a detection
|
|
16420
|
+
* session — an RTSP re-dial — so the switch is only affordable at a WIDE
|
|
16421
|
+
* interval: 300 s is ~12 re-dials an hour per camera, against 120 at the old
|
|
16422
|
+
* 30 s. A parked car is therefore counted within 5 minutes of a restart.
|
|
16423
|
+
*
|
|
16424
|
+
* Why not wider: `max` is 300 and raising it is TRAIN-BOUND, not addon-bound —
|
|
16425
|
+
* the host validates `attachCamera` against ITS copy of this schema, so a
|
|
16426
|
+
* runner asked for 600 would be rejected by the hub until a `@camstack/server`
|
|
16427
|
+
* carrying the wider bound is installed everywhere. 300 is the widest value
|
|
16428
|
+
* that ships with an addon deploy.
|
|
16429
|
+
*/
|
|
16236
16430
|
var occupancyRecheckSecField = {
|
|
16237
16431
|
min: 0,
|
|
16238
16432
|
max: 300,
|
|
@@ -16434,15 +16628,21 @@ var RunnerCameraConfigSchema = zod.z.object({
|
|
|
16434
16628
|
*/
|
|
16435
16629
|
onboardMotionDrivesAnalyzer: zod.z.boolean().default(true),
|
|
16436
16630
|
/**
|
|
16437
|
-
* Master toggle for the occupancy re-check. When `false`
|
|
16438
|
-
*
|
|
16439
|
-
* this is off by default because the recheck re-subscribes a detection session
|
|
16440
|
-
* every N seconds while `watching`, a major source of pull-decoder re-dial
|
|
16441
|
-
* churn (each cycle creates+tears a session → RTSP re-dial → latency). The
|
|
16631
|
+
* Master toggle for the occupancy re-check. When `false` the runner never arms
|
|
16632
|
+
* the periodic recheck timer, regardless of `occupancyRecheckSec`; the
|
|
16442
16633
|
* `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
|
|
16443
16634
|
* (and only render) when this is enabled.
|
|
16444
|
-
|
|
16445
|
-
|
|
16635
|
+
*
|
|
16636
|
+
* DEFAULT `true` since 2026-08-13 (was `false`). It was off because the
|
|
16637
|
+
* recheck re-subscribes a detection session every N seconds while `watching`
|
|
16638
|
+
* — each cycle creates+tears a session ⇒ an RTSP re-dial ⇒ latency, a major
|
|
16639
|
+
* pull-decoder churn source. What that bought was a blind spot: a STATIONARY
|
|
16640
|
+
* object is counted only while the stationary registry holds it, and the
|
|
16641
|
+
* registry rebuilds from motion, so after a restart a parked car was invisible
|
|
16642
|
+
* to every occupancy rule until something moved in front of it. The churn is
|
|
16643
|
+
* now paid on the interval instead — see `occupancyRecheckSecField`.
|
|
16644
|
+
*/
|
|
16645
|
+
occupancyRecheckEnabled: zod.z.boolean().default(true),
|
|
16446
16646
|
occupancyRecheckSec: zod.z.number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
|
|
16447
16647
|
occupancyRecheckFrames: zod.z.number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
|
|
16448
16648
|
/**
|
|
@@ -16575,8 +16775,8 @@ var RunnerCameraDeviceUIFields = [
|
|
|
16575
16775
|
type: "boolean",
|
|
16576
16776
|
style: "checkbox",
|
|
16577
16777
|
label: "Occupancy re-check",
|
|
16578
|
-
description: "Periodically re-sample a few frames during the watching phase
|
|
16579
|
-
default:
|
|
16778
|
+
description: "Periodically re-sample a few frames during the watching phase, so objects that are simply parked are still counted (motion gating alone loses them after a restart). On by default at a wide interval; turn it off on cameras where the extra decoder re-dial is expensive.",
|
|
16779
|
+
default: true
|
|
16580
16780
|
},
|
|
16581
16781
|
{
|
|
16582
16782
|
key: "occupancyRecheckSec",
|
|
@@ -20268,7 +20468,17 @@ var airQualitySensorCapability = {
|
|
|
20268
20468
|
schema: AirQualitySensorStatusSchema,
|
|
20269
20469
|
kind: "push"
|
|
20270
20470
|
},
|
|
20271
|
-
runtimeState: AirQualitySensorStatusSchema
|
|
20471
|
+
runtimeState: AirQualitySensorStatusSchema,
|
|
20472
|
+
/**
|
|
20473
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`.
|
|
20474
|
+
*
|
|
20475
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20476
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20477
|
+
*/
|
|
20478
|
+
durability: "restored",
|
|
20479
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
20480
|
+
* whether persisting is worth a SQLite commit. */
|
|
20481
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
20272
20482
|
};
|
|
20273
20483
|
//#endregion
|
|
20274
20484
|
//#region src/capabilities/ambient-light-sensor.cap.ts
|
|
@@ -20302,7 +20512,17 @@ var ambientLightSensorCapability = {
|
|
|
20302
20512
|
schema: AmbientLightSensorStatusSchema,
|
|
20303
20513
|
kind: "push"
|
|
20304
20514
|
},
|
|
20305
|
-
runtimeState: AmbientLightSensorStatusSchema
|
|
20515
|
+
runtimeState: AmbientLightSensorStatusSchema,
|
|
20516
|
+
/**
|
|
20517
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`.
|
|
20518
|
+
*
|
|
20519
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20520
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20521
|
+
*/
|
|
20522
|
+
durability: "restored",
|
|
20523
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
20524
|
+
* whether persisting is worth a SQLite commit. */
|
|
20525
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
20306
20526
|
};
|
|
20307
20527
|
//#endregion
|
|
20308
20528
|
//#region src/capabilities/audio-metrics.cap.ts
|
|
@@ -20431,7 +20651,14 @@ var audioMetricsCapability = {
|
|
|
20431
20651
|
}), AudioMetricsHistorySchema)
|
|
20432
20652
|
},
|
|
20433
20653
|
/** Reactive runtime-state mirror — live `device.state.audioMetrics.value`. */
|
|
20434
|
-
runtimeState: AudioMetricsSnapshotSchema
|
|
20654
|
+
runtimeState: AudioMetricsSnapshotSchema,
|
|
20655
|
+
/**
|
|
20656
|
+
* Runtime-state durability: **session** — 1 Hz per camera at the mirror and ~63 % of the fleet's whole runtime-state write rate. `avgDbfs` is a rolling 60 s mean that genuinely moves every second, so no equality fix reclaims it — and a two-hour-old dB reading rendered as current is worse than no reading.
|
|
20657
|
+
*
|
|
20658
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20659
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20660
|
+
*/
|
|
20661
|
+
durability: "session"
|
|
20435
20662
|
};
|
|
20436
20663
|
//#endregion
|
|
20437
20664
|
//#region src/capabilities/automation-control.cap.ts
|
|
@@ -20495,7 +20722,14 @@ var automationControlCapability = {
|
|
|
20495
20722
|
* reads `enabled` (toggle) + `isRunning` (spinner) + `lastError`
|
|
20496
20723
|
* (badge) directly.
|
|
20497
20724
|
*/
|
|
20498
|
-
runtimeState: AutomationControlStatusSchema
|
|
20725
|
+
runtimeState: AutomationControlStatusSchema,
|
|
20726
|
+
/**
|
|
20727
|
+
* Runtime-state durability: **session** — the authority for an automation being enabled is the automation store; a restored `isRunning` would be a lie. D62: one authority per switch.
|
|
20728
|
+
*
|
|
20729
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20730
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20731
|
+
*/
|
|
20732
|
+
durability: "session"
|
|
20499
20733
|
};
|
|
20500
20734
|
//#endregion
|
|
20501
20735
|
//#region src/capabilities/battery.cap.ts
|
|
@@ -20603,7 +20837,17 @@ onStatusChanged: { data: zod.z.object({
|
|
|
20603
20837
|
* via `device.runtimeState.getCapState('battery')` regardless of
|
|
20604
20838
|
* the underlying driver.
|
|
20605
20839
|
*/
|
|
20606
|
-
runtimeState: BatteryStatusSchema
|
|
20840
|
+
runtimeState: BatteryStatusSchema,
|
|
20841
|
+
/**
|
|
20842
|
+
* Runtime-state durability: **restored** — a sleeping battery camera may not report for hours; the restored percentage is the only thing the UI and the sleep gate have. Zero churn once `lastUpdated` is excluded — 526 writes, 0 value changes, in 25 minutes.
|
|
20843
|
+
*
|
|
20844
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20845
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20846
|
+
*/
|
|
20847
|
+
durability: "restored",
|
|
20848
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
20849
|
+
* whether persisting is worth a SQLite commit. */
|
|
20850
|
+
volatileStateFields: ["lastUpdated"]
|
|
20607
20851
|
};
|
|
20608
20852
|
//#endregion
|
|
20609
20853
|
//#region src/capabilities/binary.cap.ts
|
|
@@ -20634,7 +20878,17 @@ var binaryCapability = {
|
|
|
20634
20878
|
schema: BinaryStatusSchema,
|
|
20635
20879
|
kind: "push"
|
|
20636
20880
|
},
|
|
20637
|
-
runtimeState: BinaryStatusSchema
|
|
20881
|
+
runtimeState: BinaryStatusSchema,
|
|
20882
|
+
/**
|
|
20883
|
+
* Runtime-state durability: **restored** — transition-driven sensor state; the restored value gives the boot comparison.
|
|
20884
|
+
*
|
|
20885
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20886
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20887
|
+
*/
|
|
20888
|
+
durability: "restored",
|
|
20889
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
20890
|
+
* whether persisting is worth a SQLite commit. */
|
|
20891
|
+
volatileStateFields: ["lastChangedAt"]
|
|
20638
20892
|
};
|
|
20639
20893
|
//#endregion
|
|
20640
20894
|
//#region src/capabilities/brightness.cap.ts
|
|
@@ -20689,7 +20943,14 @@ onBrightnessChanged: { data: zod.z.object({
|
|
|
20689
20943
|
* by the kernel. Read via `device.state.brightness.value` so UI
|
|
20690
20944
|
* sliders surface the current level without polling the provider.
|
|
20691
20945
|
*/
|
|
20692
|
-
runtimeState: BrightnessStatusSchema
|
|
20946
|
+
runtimeState: BrightnessStatusSchema,
|
|
20947
|
+
/**
|
|
20948
|
+
* Runtime-state durability: **session** — live lamp state, re-published by the provider on connect.
|
|
20949
|
+
*
|
|
20950
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
20951
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
20952
|
+
*/
|
|
20953
|
+
durability: "session"
|
|
20693
20954
|
};
|
|
20694
20955
|
//#endregion
|
|
20695
20956
|
//#region src/capabilities/button.cap.ts
|
|
@@ -20824,7 +21085,17 @@ var carbonMonoxideCapability = {
|
|
|
20824
21085
|
schema: CarbonMonoxideStatusSchema,
|
|
20825
21086
|
kind: "push"
|
|
20826
21087
|
},
|
|
20827
|
-
runtimeState: CarbonMonoxideStatusSchema
|
|
21088
|
+
runtimeState: CarbonMonoxideStatusSchema,
|
|
21089
|
+
/**
|
|
21090
|
+
* Runtime-state durability: **restored** — as `smoke`.
|
|
21091
|
+
*
|
|
21092
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21093
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21094
|
+
*/
|
|
21095
|
+
durability: "restored",
|
|
21096
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
21097
|
+
* whether persisting is worth a SQLite commit. */
|
|
21098
|
+
volatileStateFields: ["lastChangedAt"]
|
|
20828
21099
|
};
|
|
20829
21100
|
//#endregion
|
|
20830
21101
|
//#region src/capabilities/climate-control.cap.ts
|
|
@@ -20986,7 +21257,14 @@ var climateControlCapability = {
|
|
|
20986
21257
|
* the full slice via `device.state.climate-control.value` and refresh
|
|
20987
21258
|
* on every push without re-querying the provider.
|
|
20988
21259
|
*/
|
|
20989
|
-
runtimeState: ClimateControlStatusSchema
|
|
21260
|
+
runtimeState: ClimateControlStatusSchema,
|
|
21261
|
+
/**
|
|
21262
|
+
* Runtime-state durability: **session** — as `brightness`; `currentTemp` moves continuously and is re-published on connect.
|
|
21263
|
+
*
|
|
21264
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21265
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21266
|
+
*/
|
|
21267
|
+
durability: "session"
|
|
20990
21268
|
};
|
|
20991
21269
|
//#endregion
|
|
20992
21270
|
//#region src/capabilities/color.cap.ts
|
|
@@ -21098,7 +21376,14 @@ onColorChanged: { data: zod.z.object({
|
|
|
21098
21376
|
* kernel. Read via `device.state.color.value` so UI pickers surface
|
|
21099
21377
|
* the current chromaticity without polling the provider.
|
|
21100
21378
|
*/
|
|
21101
|
-
runtimeState: ColorStatusSchema
|
|
21379
|
+
runtimeState: ColorStatusSchema,
|
|
21380
|
+
/**
|
|
21381
|
+
* Runtime-state durability: **session** — as `brightness`.
|
|
21382
|
+
*
|
|
21383
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21384
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21385
|
+
*/
|
|
21386
|
+
durability: "session"
|
|
21102
21387
|
};
|
|
21103
21388
|
//#endregion
|
|
21104
21389
|
//#region src/capabilities/connection-test.cap.ts
|
|
@@ -21222,7 +21507,17 @@ var connectivityCapability = {
|
|
|
21222
21507
|
schema: ConnectivityStatusSchema,
|
|
21223
21508
|
kind: "push"
|
|
21224
21509
|
},
|
|
21225
|
-
runtimeState: ConnectivityStatusSchema
|
|
21510
|
+
runtimeState: ConnectivityStatusSchema,
|
|
21511
|
+
/**
|
|
21512
|
+
* Runtime-state durability: **restored** — same shape and same argument as `device-status`, for links rather than devices.
|
|
21513
|
+
*
|
|
21514
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21515
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21516
|
+
*/
|
|
21517
|
+
durability: "restored",
|
|
21518
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
21519
|
+
* whether persisting is worth a SQLite commit. */
|
|
21520
|
+
volatileStateFields: ["lastChangedAt"]
|
|
21226
21521
|
};
|
|
21227
21522
|
//#endregion
|
|
21228
21523
|
//#region src/capabilities/consumables.cap.ts
|
|
@@ -21306,7 +21601,14 @@ reset: require_sleep.method(zod.z.object({
|
|
|
21306
21601
|
}
|
|
21307
21602
|
}
|
|
21308
21603
|
},
|
|
21309
|
-
runtimeState: ConsumablesStatusSchema.extend({ lastFetchedAt: zod.z.number() })
|
|
21604
|
+
runtimeState: ConsumablesStatusSchema.extend({ lastFetchedAt: zod.z.number() }),
|
|
21605
|
+
/**
|
|
21606
|
+
* Runtime-state durability: **session** — the authority is the appliance; the provider re-reads the whole item array on connect.
|
|
21607
|
+
*
|
|
21608
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21609
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21610
|
+
*/
|
|
21611
|
+
durability: "session"
|
|
21310
21612
|
};
|
|
21311
21613
|
//#endregion
|
|
21312
21614
|
//#region src/capabilities/contact.cap.ts
|
|
@@ -21339,7 +21641,17 @@ var contactCapability = {
|
|
|
21339
21641
|
schema: ContactStatusSchema,
|
|
21340
21642
|
kind: "push"
|
|
21341
21643
|
},
|
|
21342
|
-
runtimeState: ContactStatusSchema
|
|
21644
|
+
runtimeState: ContactStatusSchema,
|
|
21645
|
+
/**
|
|
21646
|
+
* Runtime-state durability: **restored** — a door left open across a restart must still read open.
|
|
21647
|
+
*
|
|
21648
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21649
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21650
|
+
*/
|
|
21651
|
+
durability: "restored",
|
|
21652
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
21653
|
+
* whether persisting is worth a SQLite commit. */
|
|
21654
|
+
volatileStateFields: ["lastChangedAt"]
|
|
21343
21655
|
};
|
|
21344
21656
|
//#endregion
|
|
21345
21657
|
//#region src/capabilities/control.cap.ts
|
|
@@ -21471,7 +21783,14 @@ var controlCapability = {
|
|
|
21471
21783
|
* dropdown / text field / date picker) read the slice's discriminant
|
|
21472
21784
|
* and value directly without polling the provider.
|
|
21473
21785
|
*/
|
|
21474
|
-
runtimeState: ControlStatusSchema
|
|
21786
|
+
runtimeState: ControlStatusSchema,
|
|
21787
|
+
/**
|
|
21788
|
+
* Runtime-state durability: **session** — a generic control mirrors an external entity that re-publishes on connect; the options array is re-derived with it.
|
|
21789
|
+
*
|
|
21790
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21791
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21792
|
+
*/
|
|
21793
|
+
durability: "session"
|
|
21475
21794
|
};
|
|
21476
21795
|
//#endregion
|
|
21477
21796
|
//#region src/capabilities/cover.cap.ts
|
|
@@ -21556,7 +21875,17 @@ var coverCapability = {
|
|
|
21556
21875
|
* Runtime-state slice — mirrored by the kernel. UI controls watch
|
|
21557
21876
|
* the slice for live position changes during a move.
|
|
21558
21877
|
*/
|
|
21559
|
-
runtimeState: CoverStatusSchema
|
|
21878
|
+
runtimeState: CoverStatusSchema,
|
|
21879
|
+
/**
|
|
21880
|
+
* Runtime-state durability: **restored** — position survives a restart on the device; the mirror should agree at boot rather than read blank.
|
|
21881
|
+
*
|
|
21882
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21883
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21884
|
+
*/
|
|
21885
|
+
durability: "restored",
|
|
21886
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
21887
|
+
* whether persisting is worth a SQLite commit. */
|
|
21888
|
+
volatileStateFields: ["lastChangedAt"]
|
|
21560
21889
|
};
|
|
21561
21890
|
//#endregion
|
|
21562
21891
|
//#region src/capabilities/day-night.cap.ts
|
|
@@ -21652,7 +21981,17 @@ var dayNightCapability = {
|
|
|
21652
21981
|
schema: DayNightStatusSchema,
|
|
21653
21982
|
kind: "poll"
|
|
21654
21983
|
},
|
|
21655
|
-
runtimeState: DayNightStatusSchema
|
|
21984
|
+
runtimeState: DayNightStatusSchema,
|
|
21985
|
+
/**
|
|
21986
|
+
* Runtime-state durability: **restored** — operator-set IR-cut behaviour; mutation-driven.
|
|
21987
|
+
*
|
|
21988
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
21989
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
21990
|
+
*/
|
|
21991
|
+
durability: "restored",
|
|
21992
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
21993
|
+
* whether persisting is worth a SQLite commit. */
|
|
21994
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
21656
21995
|
};
|
|
21657
21996
|
//#endregion
|
|
21658
21997
|
//#region src/capabilities/device-status.cap.ts
|
|
@@ -21701,7 +22040,17 @@ onStatusChanged: { data: zod.z.object({
|
|
|
21701
22040
|
schema: DeviceStatusSchema,
|
|
21702
22041
|
kind: "push"
|
|
21703
22042
|
},
|
|
21704
|
-
runtimeState: DeviceStatusSchema
|
|
22043
|
+
runtimeState: DeviceStatusSchema,
|
|
22044
|
+
/**
|
|
22045
|
+
* Runtime-state durability: **restored** — the previous observation is what makes the first reading after a restart a COMPARISON instead of a phantom transition (D130). 32 real flips across 16 devices in 25 min — the busiest slice in the cold half.
|
|
22046
|
+
*
|
|
22047
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22048
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22049
|
+
*/
|
|
22050
|
+
durability: "restored",
|
|
22051
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
22052
|
+
* whether persisting is worth a SQLite commit. */
|
|
22053
|
+
volatileStateFields: ["lastChangedAt"]
|
|
21705
22054
|
};
|
|
21706
22055
|
//#endregion
|
|
21707
22056
|
//#region src/capabilities/doorbell.cap.ts
|
|
@@ -21765,7 +22114,14 @@ onPressed: { data: DoorbellPressEventSchema } },
|
|
|
21765
22114
|
* `device.state.doorbell.value`. UIs can show "last ring 5m ago"
|
|
21766
22115
|
* without subscribing.
|
|
21767
22116
|
*/
|
|
21768
|
-
runtimeState: DoorbellStatusSchema
|
|
22117
|
+
runtimeState: DoorbellStatusSchema,
|
|
22118
|
+
/**
|
|
22119
|
+
* 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.
|
|
22120
|
+
*
|
|
22121
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22122
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22123
|
+
*/
|
|
22124
|
+
durability: "restored"
|
|
21769
22125
|
};
|
|
21770
22126
|
//#endregion
|
|
21771
22127
|
//#region src/capabilities/enum-sensor.cap.ts
|
|
@@ -21807,7 +22163,17 @@ var enumSensorCapability = {
|
|
|
21807
22163
|
schema: EnumSensorStatusSchema,
|
|
21808
22164
|
kind: "push"
|
|
21809
22165
|
},
|
|
21810
|
-
runtimeState: EnumSensorStatusSchema
|
|
22166
|
+
runtimeState: EnumSensorStatusSchema,
|
|
22167
|
+
/**
|
|
22168
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; 80 devices.
|
|
22169
|
+
*
|
|
22170
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22171
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22172
|
+
*/
|
|
22173
|
+
durability: "restored",
|
|
22174
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
22175
|
+
* whether persisting is worth a SQLite commit. */
|
|
22176
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
21811
22177
|
};
|
|
21812
22178
|
//#endregion
|
|
21813
22179
|
//#region src/capabilities/event-emitter.cap.ts
|
|
@@ -21845,7 +22211,14 @@ var eventEmitterCapability = {
|
|
|
21845
22211
|
schema: EventEmitterStatusSchema,
|
|
21846
22212
|
kind: "push"
|
|
21847
22213
|
},
|
|
21848
|
-
runtimeState: EventEmitterStatusSchema
|
|
22214
|
+
runtimeState: EventEmitterStatusSchema,
|
|
22215
|
+
/**
|
|
22216
|
+
* Runtime-state durability: **session** — `eventCountSinceStart` names its own scope.
|
|
22217
|
+
*
|
|
22218
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22219
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22220
|
+
*/
|
|
22221
|
+
durability: "session"
|
|
21849
22222
|
};
|
|
21850
22223
|
//#endregion
|
|
21851
22224
|
//#region src/capabilities/events.cap.ts
|
|
@@ -22168,7 +22541,14 @@ var fanControlCapability = {
|
|
|
22168
22541
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
22169
22542
|
* sliders read `percentage` for live updates.
|
|
22170
22543
|
*/
|
|
22171
|
-
runtimeState: FanControlStatusSchema
|
|
22544
|
+
runtimeState: FanControlStatusSchema,
|
|
22545
|
+
/**
|
|
22546
|
+
* Runtime-state durability: **session** — as `brightness`.
|
|
22547
|
+
*
|
|
22548
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22549
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22550
|
+
*/
|
|
22551
|
+
durability: "session"
|
|
22172
22552
|
};
|
|
22173
22553
|
//#endregion
|
|
22174
22554
|
//#region src/capabilities/feature-probe.cap.ts
|
|
@@ -22246,7 +22626,14 @@ onProbeChanged: { data: zod.z.object({
|
|
|
22246
22626
|
schema: FeatureProbeStatusSchema,
|
|
22247
22627
|
kind: "push"
|
|
22248
22628
|
},
|
|
22249
|
-
runtimeState: FeatureProbeStatusSchema
|
|
22629
|
+
runtimeState: FeatureProbeStatusSchema,
|
|
22630
|
+
/**
|
|
22631
|
+
* Runtime-state durability: **session** — per-session by definition — `lastProbedAt` means "this worker completed a probe THIS session", which is why the mirror seed already blanks it. Persisting it only creates something to blank.
|
|
22632
|
+
*
|
|
22633
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22634
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22635
|
+
*/
|
|
22636
|
+
durability: "session"
|
|
22250
22637
|
};
|
|
22251
22638
|
//#endregion
|
|
22252
22639
|
//#region src/capabilities/flood.cap.ts
|
|
@@ -22275,7 +22662,17 @@ var floodCapability = {
|
|
|
22275
22662
|
schema: FloodStatusSchema,
|
|
22276
22663
|
kind: "push"
|
|
22277
22664
|
},
|
|
22278
|
-
runtimeState: FloodStatusSchema
|
|
22665
|
+
runtimeState: FloodStatusSchema,
|
|
22666
|
+
/**
|
|
22667
|
+
* Runtime-state durability: **restored** — as `smoke`.
|
|
22668
|
+
*
|
|
22669
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22670
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22671
|
+
*/
|
|
22672
|
+
durability: "restored",
|
|
22673
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
22674
|
+
* whether persisting is worth a SQLite commit. */
|
|
22675
|
+
volatileStateFields: ["lastChangedAt"]
|
|
22279
22676
|
};
|
|
22280
22677
|
//#endregion
|
|
22281
22678
|
//#region src/capabilities/gas.cap.ts
|
|
@@ -22300,7 +22697,17 @@ var gasCapability = {
|
|
|
22300
22697
|
schema: GasStatusSchema,
|
|
22301
22698
|
kind: "push"
|
|
22302
22699
|
},
|
|
22303
|
-
runtimeState: GasStatusSchema
|
|
22700
|
+
runtimeState: GasStatusSchema,
|
|
22701
|
+
/**
|
|
22702
|
+
* Runtime-state durability: **restored** — as `smoke`.
|
|
22703
|
+
*
|
|
22704
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22705
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22706
|
+
*/
|
|
22707
|
+
durability: "restored",
|
|
22708
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
22709
|
+
* whether persisting is worth a SQLite commit. */
|
|
22710
|
+
volatileStateFields: ["lastChangedAt"]
|
|
22304
22711
|
};
|
|
22305
22712
|
//#endregion
|
|
22306
22713
|
//#region src/capabilities/humidifier.cap.ts
|
|
@@ -22378,7 +22785,14 @@ var humidifierCapability = {
|
|
|
22378
22785
|
* Runtime-state slice — mirrored by the kernel. UI controls watch the
|
|
22379
22786
|
* slice for live humidity / mode changes.
|
|
22380
22787
|
*/
|
|
22381
|
-
runtimeState: HumidifierStatusSchema
|
|
22788
|
+
runtimeState: HumidifierStatusSchema,
|
|
22789
|
+
/**
|
|
22790
|
+
* Runtime-state durability: **session** — as `climate-control`.
|
|
22791
|
+
*
|
|
22792
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22793
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22794
|
+
*/
|
|
22795
|
+
durability: "session"
|
|
22382
22796
|
};
|
|
22383
22797
|
//#endregion
|
|
22384
22798
|
//#region src/capabilities/humidity-sensor.cap.ts
|
|
@@ -22416,7 +22830,17 @@ var humiditySensorCapability = {
|
|
|
22416
22830
|
schema: HumiditySensorStatusSchema,
|
|
22417
22831
|
kind: "push"
|
|
22418
22832
|
},
|
|
22419
|
-
runtimeState: HumiditySensorStatusSchema
|
|
22833
|
+
runtimeState: HumiditySensorStatusSchema,
|
|
22834
|
+
/**
|
|
22835
|
+
* Runtime-state durability: **restored** — as `numeric-sensor` (67 of 75 writes were the clock alone).
|
|
22836
|
+
*
|
|
22837
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22838
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22839
|
+
*/
|
|
22840
|
+
durability: "restored",
|
|
22841
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
22842
|
+
* whether persisting is worth a SQLite commit. */
|
|
22843
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
22420
22844
|
};
|
|
22421
22845
|
//#endregion
|
|
22422
22846
|
//#region src/capabilities/image.cap.ts
|
|
@@ -22456,7 +22880,14 @@ var imageCapability = {
|
|
|
22456
22880
|
* Runtime-state slice — mirrored by the kernel. The UI reads `url`
|
|
22457
22881
|
* directly and renders the still image.
|
|
22458
22882
|
*/
|
|
22459
|
-
runtimeState: ImageStatusSchema
|
|
22883
|
+
runtimeState: ImageStatusSchema,
|
|
22884
|
+
/**
|
|
22885
|
+
* Runtime-state durability: **session** — a snapshot URL is a session-scoped handle; a restored one points at nothing.
|
|
22886
|
+
*
|
|
22887
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
22888
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
22889
|
+
*/
|
|
22890
|
+
durability: "session"
|
|
22460
22891
|
};
|
|
22461
22892
|
//#endregion
|
|
22462
22893
|
//#region src/capabilities/image-settings.cap.ts
|
|
@@ -22607,7 +23038,17 @@ var imageSettingsCapability = {
|
|
|
22607
23038
|
schema: ImageSettingsStatusSchema,
|
|
22608
23039
|
kind: "poll"
|
|
22609
23040
|
},
|
|
22610
|
-
runtimeState: ImageSettingsStatusSchema
|
|
23041
|
+
runtimeState: ImageSettingsStatusSchema,
|
|
23042
|
+
/**
|
|
23043
|
+
* Runtime-state durability: **restored** — operator-set camera imaging; mutation-driven.
|
|
23044
|
+
*
|
|
23045
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
23046
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
23047
|
+
*/
|
|
23048
|
+
durability: "restored",
|
|
23049
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
23050
|
+
* whether persisting is worth a SQLite commit. */
|
|
23051
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
22611
23052
|
};
|
|
22612
23053
|
//#endregion
|
|
22613
23054
|
//#region src/capabilities/integrations.cap.ts
|
|
@@ -23022,7 +23463,14 @@ var lawnMowerControlCapability = {
|
|
|
23022
23463
|
* Runtime-state slice — mirrored by the kernel. UI controls watch the
|
|
23023
23464
|
* slice for live activity + battery changes.
|
|
23024
23465
|
*/
|
|
23025
|
-
runtimeState: LawnMowerControlStatusSchema
|
|
23466
|
+
runtimeState: LawnMowerControlStatusSchema,
|
|
23467
|
+
/**
|
|
23468
|
+
* Runtime-state durability: **session** — as `vacuum-control`.
|
|
23469
|
+
*
|
|
23470
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
23471
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
23472
|
+
*/
|
|
23473
|
+
durability: "session"
|
|
23026
23474
|
};
|
|
23027
23475
|
//#endregion
|
|
23028
23476
|
//#region src/capabilities/local-network.cap.ts
|
|
@@ -23329,7 +23777,17 @@ var lockControlCapability = {
|
|
|
23329
23777
|
* read `state` and disable themselves during `locking`/`unlocking`
|
|
23330
23778
|
* transitions.
|
|
23331
23779
|
*/
|
|
23332
|
-
runtimeState: LockControlStatusSchema
|
|
23780
|
+
runtimeState: LockControlStatusSchema,
|
|
23781
|
+
/**
|
|
23782
|
+
* Runtime-state durability: **restored** — a lock left locked must still read locked.
|
|
23783
|
+
*
|
|
23784
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
23785
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
23786
|
+
*/
|
|
23787
|
+
durability: "restored",
|
|
23788
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
23789
|
+
* whether persisting is worth a SQLite commit. */
|
|
23790
|
+
volatileStateFields: ["lastChangedAt"]
|
|
23333
23791
|
};
|
|
23334
23792
|
//#endregion
|
|
23335
23793
|
//#region src/capabilities/media-player.cap.ts
|
|
@@ -23493,7 +23951,14 @@ var mediaPlayerCapability = {
|
|
|
23493
23951
|
* full slice for live now-playing, volume, and progress updates
|
|
23494
23952
|
* without polling.
|
|
23495
23953
|
*/
|
|
23496
|
-
runtimeState: MediaPlayerStatusSchema
|
|
23954
|
+
runtimeState: MediaPlayerStatusSchema,
|
|
23955
|
+
/**
|
|
23956
|
+
* Runtime-state durability: **session** — a restored transport position describes a playback that stopped when the hub did.
|
|
23957
|
+
*
|
|
23958
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
23959
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
23960
|
+
*/
|
|
23961
|
+
durability: "session"
|
|
23497
23962
|
};
|
|
23498
23963
|
//#endregion
|
|
23499
23964
|
//#region src/capabilities/mesh-network.cap.ts
|
|
@@ -23822,7 +24287,14 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
23822
24287
|
* `device.state.motion.value`. Reads never invoke the provider, so
|
|
23823
24288
|
* UIs and other addons can poll the cached state safely.
|
|
23824
24289
|
*/
|
|
23825
|
-
runtimeState: MotionStatusSchema
|
|
24290
|
+
runtimeState: MotionStatusSchema,
|
|
24291
|
+
/**
|
|
24292
|
+
* Runtime-state durability: **session** — self-clearing by construction (`autoClearAfterMs`); a restored `detected: true` is a frozen event, and the next frame re-publishes the real one.
|
|
24293
|
+
*
|
|
24294
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
24295
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
24296
|
+
*/
|
|
24297
|
+
durability: "session"
|
|
23826
24298
|
};
|
|
23827
24299
|
//#endregion
|
|
23828
24300
|
//#region src/capabilities/motion-trigger.cap.ts
|
|
@@ -23889,7 +24361,14 @@ var motionTriggerCapability = {
|
|
|
23889
24361
|
schema: MotionTriggerStatusSchema,
|
|
23890
24362
|
kind: "command-driven"
|
|
23891
24363
|
},
|
|
23892
|
-
runtimeState: MotionTriggerRuntimeStateSchema
|
|
24364
|
+
runtimeState: MotionTriggerRuntimeStateSchema,
|
|
24365
|
+
/**
|
|
24366
|
+
* Runtime-state durability: **session** — the authority for motion-trigger enablement is the provider's own config; the slice is a mirror of it, re-published on connect.
|
|
24367
|
+
*
|
|
24368
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
24369
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
24370
|
+
*/
|
|
24371
|
+
durability: "session"
|
|
23893
24372
|
};
|
|
23894
24373
|
//#endregion
|
|
23895
24374
|
//#region src/capabilities/motion-zones.cap.ts
|
|
@@ -23958,7 +24437,17 @@ var motionZonesCapability = {
|
|
|
23958
24437
|
schema: MotionZoneStatusSchema,
|
|
23959
24438
|
kind: "poll"
|
|
23960
24439
|
},
|
|
23961
|
-
runtimeState: MotionZoneStatusSchema
|
|
24440
|
+
runtimeState: MotionZoneStatusSchema,
|
|
24441
|
+
/**
|
|
24442
|
+
* Runtime-state durability: **restored** — the 14 KB polygon list is the single largest slice on the fleet and has not changed since the operator drew it. Highest value per byte in the table.
|
|
24443
|
+
*
|
|
24444
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
24445
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
24446
|
+
*/
|
|
24447
|
+
durability: "restored",
|
|
24448
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
24449
|
+
* whether persisting is worth a SQLite commit. */
|
|
24450
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
23962
24451
|
};
|
|
23963
24452
|
//#endregion
|
|
23964
24453
|
//#region src/capabilities/native-object-detection.cap.ts
|
|
@@ -24034,7 +24523,17 @@ var nativeObjectDetectionCapability = {
|
|
|
24034
24523
|
schema: NativeObjectDetectionStatusSchema,
|
|
24035
24524
|
kind: "push"
|
|
24036
24525
|
},
|
|
24037
|
-
runtimeState: NativeObjectDetectionRuntimeStateSchema
|
|
24526
|
+
runtimeState: NativeObjectDetectionRuntimeStateSchema,
|
|
24527
|
+
/**
|
|
24528
|
+
* Runtime-state durability: **restored** — `enabled` is an operator toggle on a camera whose refresh is a no-op and whose staleMs is Infinity. There is no hardware value to re-read — losing it loses the setting.
|
|
24529
|
+
*
|
|
24530
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
24531
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
24532
|
+
*/
|
|
24533
|
+
durability: "restored",
|
|
24534
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
24535
|
+
* whether persisting is worth a SQLite commit. */
|
|
24536
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
24038
24537
|
};
|
|
24039
24538
|
//#endregion
|
|
24040
24539
|
//#region src/capabilities/network-quality.cap.ts
|
|
@@ -24427,7 +24926,14 @@ onSent: { data: zod.z.object({
|
|
|
24427
24926
|
* form reads `supports` to gate optional fields; history pane reads
|
|
24428
24927
|
* `lastSentAt` / `lastError` / `queueDepth`.
|
|
24429
24928
|
*/
|
|
24430
|
-
runtimeState: NotifierStatusSchema
|
|
24929
|
+
runtimeState: NotifierStatusSchema,
|
|
24930
|
+
/**
|
|
24931
|
+
* Runtime-state durability: **session** — live queue depth and last-send state; a restored queue depth describes a queue that no longer exists.
|
|
24932
|
+
*
|
|
24933
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
24934
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
24935
|
+
*/
|
|
24936
|
+
durability: "session"
|
|
24431
24937
|
};
|
|
24432
24938
|
//#endregion
|
|
24433
24939
|
//#region src/capabilities/numeric-sensor.cap.ts
|
|
@@ -24472,7 +24978,17 @@ var numericSensorCapability = {
|
|
|
24472
24978
|
schema: NumericSensorStatusSchema,
|
|
24473
24979
|
kind: "push"
|
|
24474
24980
|
},
|
|
24475
|
-
runtimeState: NumericSensorStatusSchema
|
|
24981
|
+
runtimeState: NumericSensorStatusSchema,
|
|
24982
|
+
/**
|
|
24983
|
+
* Runtime-state durability: **restored** — polled value, low churn once the clock is excluded (251 of 669 writes were the clock alone); restoring it removes the cold window before the first poll.
|
|
24984
|
+
*
|
|
24985
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
24986
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
24987
|
+
*/
|
|
24988
|
+
durability: "restored",
|
|
24989
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
24990
|
+
* whether persisting is worth a SQLite commit. */
|
|
24991
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
24476
24992
|
};
|
|
24477
24993
|
//#endregion
|
|
24478
24994
|
//#region src/capabilities/osd.cap.ts
|
|
@@ -24989,7 +25505,14 @@ var petFeederCapability = {
|
|
|
24989
25505
|
* the full slice via `device.state.petFeeder.value` and refresh on
|
|
24990
25506
|
* every poll without re-querying the provider.
|
|
24991
25507
|
*/
|
|
24992
|
-
runtimeState: PetFeederStatusSchema
|
|
25508
|
+
runtimeState: PetFeederStatusSchema,
|
|
25509
|
+
/**
|
|
25510
|
+
* Runtime-state durability: **session** — live appliance state re-published on connect.
|
|
25511
|
+
*
|
|
25512
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
25513
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
25514
|
+
*/
|
|
25515
|
+
durability: "session"
|
|
24993
25516
|
};
|
|
24994
25517
|
//#endregion
|
|
24995
25518
|
//#region src/capabilities/plate-gallery.cap.ts
|
|
@@ -25352,7 +25875,17 @@ var powerMeterCapability = {
|
|
|
25352
25875
|
schema: PowerMeterStatusSchema,
|
|
25353
25876
|
kind: "push"
|
|
25354
25877
|
},
|
|
25355
|
-
runtimeState: PowerMeterStatusSchema
|
|
25878
|
+
runtimeState: PowerMeterStatusSchema,
|
|
25879
|
+
/**
|
|
25880
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `kwhTotal` is an accumulator whose restored value is the baseline.
|
|
25881
|
+
*
|
|
25882
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
25883
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
25884
|
+
*/
|
|
25885
|
+
durability: "restored",
|
|
25886
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
25887
|
+
* whether persisting is worth a SQLite commit. */
|
|
25888
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
25356
25889
|
};
|
|
25357
25890
|
//#endregion
|
|
25358
25891
|
//#region src/capabilities/presence.cap.ts
|
|
@@ -25411,7 +25944,17 @@ var presenceCapability = {
|
|
|
25411
25944
|
* the map pin is rendered (use `DeviceFeature.PresenceGps` for the
|
|
25412
25945
|
* pre-fetch fast-path check).
|
|
25413
25946
|
*/
|
|
25414
|
-
runtimeState: PresenceStatusSchema
|
|
25947
|
+
runtimeState: PresenceStatusSchema,
|
|
25948
|
+
/**
|
|
25949
|
+
* Runtime-state durability: **restored** — occupancy-relevant: the restored state is what an occupancy rule compares the first post-restart observation against.
|
|
25950
|
+
*
|
|
25951
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
25952
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
25953
|
+
*/
|
|
25954
|
+
durability: "restored",
|
|
25955
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
25956
|
+
* whether persisting is worth a SQLite commit. */
|
|
25957
|
+
volatileStateFields: ["lastChangedAt"]
|
|
25415
25958
|
};
|
|
25416
25959
|
//#endregion
|
|
25417
25960
|
//#region src/capabilities/pressure-sensor.cap.ts
|
|
@@ -25449,7 +25992,17 @@ var pressureSensorCapability = {
|
|
|
25449
25992
|
schema: PressureSensorStatusSchema,
|
|
25450
25993
|
kind: "push"
|
|
25451
25994
|
},
|
|
25452
|
-
runtimeState: PressureSensorStatusSchema
|
|
25995
|
+
runtimeState: PressureSensorStatusSchema,
|
|
25996
|
+
/**
|
|
25997
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`.
|
|
25998
|
+
*
|
|
25999
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
26000
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
26001
|
+
*/
|
|
26002
|
+
durability: "restored",
|
|
26003
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
26004
|
+
* whether persisting is worth a SQLite commit. */
|
|
26005
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
25453
26006
|
};
|
|
25454
26007
|
//#endregion
|
|
25455
26008
|
//#region src/capabilities/privacy-mask.cap.ts
|
|
@@ -25581,7 +26134,17 @@ var privacyMaskCapability = {
|
|
|
25581
26134
|
schema: PrivacyMaskStatusSchema,
|
|
25582
26135
|
kind: "poll"
|
|
25583
26136
|
},
|
|
25584
|
-
runtimeState: PrivacyMaskStatusSchema
|
|
26137
|
+
runtimeState: PrivacyMaskStatusSchema,
|
|
26138
|
+
/**
|
|
26139
|
+
* Runtime-state durability: **restored** — operator-drawn regions, zero real churn — 22 writes in 25 minutes, every one of them the clock.
|
|
26140
|
+
*
|
|
26141
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
26142
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
26143
|
+
*/
|
|
26144
|
+
durability: "restored",
|
|
26145
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
26146
|
+
* whether persisting is worth a SQLite commit. */
|
|
26147
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
25585
26148
|
};
|
|
25586
26149
|
/**
|
|
25587
26150
|
* Collapse a camera's PER-PROFILE audio flags into the one answer
|
|
@@ -25848,7 +26411,14 @@ var ptzAutotrackCapability = {
|
|
|
25848
26411
|
* fetch / cache / fallback logic out of the four cap methods —
|
|
25849
26412
|
* they become trampolines over `runtimeState`.
|
|
25850
26413
|
*/
|
|
25851
|
-
runtimeState: PtzAutotrackRuntimeStateSchema
|
|
26414
|
+
runtimeState: PtzAutotrackRuntimeStateSchema,
|
|
26415
|
+
/**
|
|
26416
|
+
* Runtime-state durability: **session** — mirrors the camera's own autotrack config, re-read on connect.
|
|
26417
|
+
*
|
|
26418
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
26419
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
26420
|
+
*/
|
|
26421
|
+
durability: "session"
|
|
25852
26422
|
};
|
|
25853
26423
|
//#endregion
|
|
25854
26424
|
//#region src/capabilities/reboot.cap.ts
|
|
@@ -26693,7 +27263,14 @@ var sceneMonitorCapability = {
|
|
|
26693
27263
|
schema: SceneMonitorStatusSchema,
|
|
26694
27264
|
kind: "push"
|
|
26695
27265
|
},
|
|
26696
|
-
runtimeState: SceneMonitorStatusSchema
|
|
27266
|
+
runtimeState: SceneMonitorStatusSchema,
|
|
27267
|
+
/**
|
|
27268
|
+
* Runtime-state durability: **session** — re-derived from the current scene on the next evaluation.
|
|
27269
|
+
*
|
|
27270
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
27271
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
27272
|
+
*/
|
|
27273
|
+
durability: "session"
|
|
26697
27274
|
};
|
|
26698
27275
|
//#endregion
|
|
26699
27276
|
//#region src/capabilities/schemas/zone-rule.ts
|
|
@@ -26845,7 +27422,14 @@ var scriptRunnerCapability = {
|
|
|
26845
27422
|
* `isRunning` to render a spinner during execution and surfaces
|
|
26846
27423
|
* `lastError` / `lastRunSuccess` in the recent-runs panel.
|
|
26847
27424
|
*/
|
|
26848
|
-
runtimeState: ScriptRunnerStatusSchema
|
|
27425
|
+
runtimeState: ScriptRunnerStatusSchema,
|
|
27426
|
+
/**
|
|
27427
|
+
* Runtime-state durability: **session** — a restored `isRunning: true` describes a process that died with the previous hub.
|
|
27428
|
+
*
|
|
27429
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
27430
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
27431
|
+
*/
|
|
27432
|
+
durability: "session"
|
|
26849
27433
|
};
|
|
26850
27434
|
//#endregion
|
|
26851
27435
|
//#region src/capabilities/smoke.cap.ts
|
|
@@ -26874,7 +27458,17 @@ var smokeCapability = {
|
|
|
26874
27458
|
schema: SmokeStatusSchema,
|
|
26875
27459
|
kind: "push"
|
|
26876
27460
|
},
|
|
26877
|
-
runtimeState: SmokeStatusSchema
|
|
27461
|
+
runtimeState: SmokeStatusSchema,
|
|
27462
|
+
/**
|
|
27463
|
+
* Runtime-state durability: **restored** — a safety sensor must not read "clear" merely because the hub restarted.
|
|
27464
|
+
*
|
|
27465
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
27466
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
27467
|
+
*/
|
|
27468
|
+
durability: "restored",
|
|
27469
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
27470
|
+
* whether persisting is worth a SQLite commit. */
|
|
27471
|
+
volatileStateFields: ["lastChangedAt"]
|
|
26878
27472
|
};
|
|
26879
27473
|
//#endregion
|
|
26880
27474
|
//#region src/capabilities/stream-catalog.cap.ts
|
|
@@ -27064,7 +27658,17 @@ var streamParamsCapability = {
|
|
|
27064
27658
|
schema: StreamParamsStatusSchema,
|
|
27065
27659
|
kind: "poll"
|
|
27066
27660
|
},
|
|
27067
|
-
runtimeState: StreamParamsStatusSchema
|
|
27661
|
+
runtimeState: StreamParamsStatusSchema,
|
|
27662
|
+
/**
|
|
27663
|
+
* Runtime-state durability: **restored** — operator-set encoder profile; mutation-driven.
|
|
27664
|
+
*
|
|
27665
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
27666
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
27667
|
+
*/
|
|
27668
|
+
durability: "restored",
|
|
27669
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
27670
|
+
* whether persisting is worth a SQLite commit. */
|
|
27671
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
27068
27672
|
};
|
|
27069
27673
|
//#endregion
|
|
27070
27674
|
//#region src/capabilities/stream-params-config-schema.ts
|
|
@@ -27371,6 +27975,16 @@ var switchCapability = {
|
|
|
27371
27975
|
* not need to re-query the provider after a setState mutation.
|
|
27372
27976
|
*/
|
|
27373
27977
|
runtimeState: SwitchStatusSchema,
|
|
27978
|
+
/**
|
|
27979
|
+
* Runtime-state durability: **restored** — device state an operator reads as authoritative; 55 devices, transition-driven.
|
|
27980
|
+
*
|
|
27981
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
27982
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
27983
|
+
*/
|
|
27984
|
+
durability: "restored",
|
|
27985
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
27986
|
+
* whether persisting is worth a SQLite commit. */
|
|
27987
|
+
volatileStateFields: ["lastChangedAt"],
|
|
27374
27988
|
settings: { bindings: [{
|
|
27375
27989
|
kind: "scalar",
|
|
27376
27990
|
statusPath: "on",
|
|
@@ -27469,7 +28083,17 @@ var tamperCapability = {
|
|
|
27469
28083
|
schema: TamperStatusSchema,
|
|
27470
28084
|
kind: "push"
|
|
27471
28085
|
},
|
|
27472
|
-
runtimeState: TamperStatusSchema
|
|
28086
|
+
runtimeState: TamperStatusSchema,
|
|
28087
|
+
/**
|
|
28088
|
+
* Runtime-state durability: **restored** — as `smoke`.
|
|
28089
|
+
*
|
|
28090
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28091
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28092
|
+
*/
|
|
28093
|
+
durability: "restored",
|
|
28094
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
28095
|
+
* whether persisting is worth a SQLite commit. */
|
|
28096
|
+
volatileStateFields: ["lastChangedAt"]
|
|
27473
28097
|
};
|
|
27474
28098
|
//#endregion
|
|
27475
28099
|
//#region src/capabilities/temperature-sensor.cap.ts
|
|
@@ -27516,7 +28140,17 @@ var temperatureSensorCapability = {
|
|
|
27516
28140
|
schema: TemperatureSensorStatusSchema,
|
|
27517
28141
|
kind: "push"
|
|
27518
28142
|
},
|
|
27519
|
-
runtimeState: TemperatureSensorStatusSchema
|
|
28143
|
+
runtimeState: TemperatureSensorStatusSchema,
|
|
28144
|
+
/**
|
|
28145
|
+
* Runtime-state durability: **restored** — as `numeric-sensor` (69 of 125 writes were the clock alone).
|
|
28146
|
+
*
|
|
28147
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28148
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28149
|
+
*/
|
|
28150
|
+
durability: "restored",
|
|
28151
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
28152
|
+
* whether persisting is worth a SQLite commit. */
|
|
28153
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
27520
28154
|
};
|
|
27521
28155
|
//#endregion
|
|
27522
28156
|
//#region src/capabilities/toast.cap.ts
|
|
@@ -27596,7 +28230,14 @@ var updateCapability = {
|
|
|
27596
28230
|
schema: UpdateStatusSchema,
|
|
27597
28231
|
kind: "poll"
|
|
27598
28232
|
},
|
|
27599
|
-
runtimeState: UpdateStatusSchema
|
|
28233
|
+
runtimeState: UpdateStatusSchema,
|
|
28234
|
+
/**
|
|
28235
|
+
* Runtime-state durability: **session** — a restored `inProgress: true` describes an update that is no longer running; versions are re-probed at boot.
|
|
28236
|
+
*
|
|
28237
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28238
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28239
|
+
*/
|
|
28240
|
+
durability: "session"
|
|
27600
28241
|
};
|
|
27601
28242
|
//#endregion
|
|
27602
28243
|
//#region src/capabilities/user-management.cap.ts
|
|
@@ -27976,7 +28617,14 @@ var vacuumControlCapability = {
|
|
|
27976
28617
|
* Runtime-state slice — mirrored by the kernel. UI controls watch the
|
|
27977
28618
|
* slice for live state + battery + fan-speed changes.
|
|
27978
28619
|
*/
|
|
27979
|
-
runtimeState: VacuumControlStatusSchema
|
|
28620
|
+
runtimeState: VacuumControlStatusSchema,
|
|
28621
|
+
/**
|
|
28622
|
+
* Runtime-state durability: **session** — as `media-player` — a restored `state: cleaning` is a robot that is not cleaning.
|
|
28623
|
+
*
|
|
28624
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28625
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28626
|
+
*/
|
|
28627
|
+
durability: "session"
|
|
27980
28628
|
};
|
|
27981
28629
|
//#endregion
|
|
27982
28630
|
//#region src/capabilities/valve.cap.ts
|
|
@@ -28048,7 +28696,14 @@ var valveCapability = {
|
|
|
28048
28696
|
* Runtime-state slice — mirrored by the kernel. UI controls watch the
|
|
28049
28697
|
* slice for live position changes during a move.
|
|
28050
28698
|
*/
|
|
28051
|
-
runtimeState: ValveStatusSchema
|
|
28699
|
+
runtimeState: ValveStatusSchema,
|
|
28700
|
+
/**
|
|
28701
|
+
* Runtime-state durability: **session** — as `brightness`.
|
|
28702
|
+
*
|
|
28703
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28704
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28705
|
+
*/
|
|
28706
|
+
durability: "session"
|
|
28052
28707
|
};
|
|
28053
28708
|
//#endregion
|
|
28054
28709
|
//#region src/capabilities/vibration.cap.ts
|
|
@@ -28072,7 +28727,17 @@ var vibrationCapability = {
|
|
|
28072
28727
|
schema: VibrationStatusSchema,
|
|
28073
28728
|
kind: "push"
|
|
28074
28729
|
},
|
|
28075
|
-
runtimeState: VibrationStatusSchema
|
|
28730
|
+
runtimeState: VibrationStatusSchema,
|
|
28731
|
+
/**
|
|
28732
|
+
* Runtime-state durability: **restored** — as `smoke`.
|
|
28733
|
+
*
|
|
28734
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28735
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28736
|
+
*/
|
|
28737
|
+
durability: "restored",
|
|
28738
|
+
/** Clock fields: written, but excluded from the compare that decides
|
|
28739
|
+
* whether persisting is worth a SQLite commit. */
|
|
28740
|
+
volatileStateFields: ["lastChangedAt"]
|
|
28076
28741
|
};
|
|
28077
28742
|
//#endregion
|
|
28078
28743
|
//#region src/capabilities/water-heater.cap.ts
|
|
@@ -28148,7 +28813,14 @@ var waterHeaterCapability = {
|
|
|
28148
28813
|
* Runtime-state slice — mirrored by the kernel. UI controls watch the
|
|
28149
28814
|
* slice for live temperature / mode / away changes.
|
|
28150
28815
|
*/
|
|
28151
|
-
runtimeState: WaterHeaterStatusSchema
|
|
28816
|
+
runtimeState: WaterHeaterStatusSchema,
|
|
28817
|
+
/**
|
|
28818
|
+
* Runtime-state durability: **session** — as `climate-control`.
|
|
28819
|
+
*
|
|
28820
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28821
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28822
|
+
*/
|
|
28823
|
+
durability: "session"
|
|
28152
28824
|
};
|
|
28153
28825
|
//#endregion
|
|
28154
28826
|
//#region src/capabilities/weather.cap.ts
|
|
@@ -28209,7 +28881,14 @@ var weatherCapability = {
|
|
|
28209
28881
|
* Runtime-state slice — mirrored by the kernel. The UI reads the
|
|
28210
28882
|
* current conditions directly from the slice on each weather push.
|
|
28211
28883
|
*/
|
|
28212
|
-
runtimeState: WeatherStatusSchema
|
|
28884
|
+
runtimeState: WeatherStatusSchema,
|
|
28885
|
+
/**
|
|
28886
|
+
* Runtime-state durability: **session** — a forecast is stale the moment the hub is down; the provider re-fetches on connect.
|
|
28887
|
+
*
|
|
28888
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28889
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28890
|
+
*/
|
|
28891
|
+
durability: "session"
|
|
28213
28892
|
};
|
|
28214
28893
|
//#endregion
|
|
28215
28894
|
//#region src/capabilities/zone-analytics.cap.ts
|
|
@@ -28373,7 +29052,14 @@ var zoneAnalyticsCapability = {
|
|
|
28373
29052
|
* automatically; the explicit `getCurrentSnapshot` cap method is
|
|
28374
29053
|
* still useful for one-off polls without a subscription.
|
|
28375
29054
|
*/
|
|
28376
|
-
runtimeState: CameraOccupancySnapshotSchema
|
|
29055
|
+
runtimeState: CameraOccupancySnapshotSchema,
|
|
29056
|
+
/**
|
|
29057
|
+
* Runtime-state durability: **session** — per-frame analytics; with `audio-metrics` it is ~90 % of the offered write rate. Re-derived on the next frame.
|
|
29058
|
+
*
|
|
29059
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
29060
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
29061
|
+
*/
|
|
29062
|
+
durability: "session"
|
|
28377
29063
|
};
|
|
28378
29064
|
//#endregion
|
|
28379
29065
|
//#region src/capabilities/zone-rules.cap.ts
|
|
@@ -28453,7 +29139,14 @@ var zoneRulesCapability = {
|
|
|
28453
29139
|
motion: zod.z.array(ZoneRuleSchema).readonly(),
|
|
28454
29140
|
detection: zod.z.array(ZoneRuleSchema).readonly(),
|
|
28455
29141
|
package: zod.z.array(ZoneRuleSchema).readonly()
|
|
28456
|
-
})
|
|
29142
|
+
}),
|
|
29143
|
+
/**
|
|
29144
|
+
* Runtime-state durability: **restored** — operator intent, mutation-only, same argument as `zones`.
|
|
29145
|
+
*
|
|
29146
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
29147
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
29148
|
+
*/
|
|
29149
|
+
durability: "restored"
|
|
28457
29150
|
};
|
|
28458
29151
|
//#endregion
|
|
28459
29152
|
//#region src/capabilities/index.ts
|
|
@@ -31047,11 +31740,40 @@ var SystemMirror = class {
|
|
|
31047
31740
|
cb(deviceId, lastInfo);
|
|
31048
31741
|
} catch {}
|
|
31049
31742
|
}
|
|
31743
|
+
/**
|
|
31744
|
+
* ONE device's bindings, not the fleet's.
|
|
31745
|
+
*
|
|
31746
|
+
* This runs on every `capability.binding-changed` AND on every
|
|
31747
|
+
* `device.registered`, per mirror. It used to answer that with
|
|
31748
|
+
* `getAllBindings` and `.find()` the one row — measured on the live
|
|
31749
|
+
* hub (524 devices): 903 ms and 373 KB per call, against 21 ms and
|
|
31750
|
+
* 613 bytes for `getBindings({deviceId})`.
|
|
31751
|
+
*
|
|
31752
|
+
* Adopting 20 Home Assistant devices registers 166 devices (parents +
|
|
31753
|
+
* accessories), so an operator with the admin UI open bought 166
|
|
31754
|
+
* full-fleet binding sweeps: ~150 s of hub main-thread time inside a
|
|
31755
|
+
* 219 s adoption, with every other RPC — including the adoption's own —
|
|
31756
|
+
* queued behind them. Same defect, same fix, as `refreshDeviceMetadata`
|
|
31757
|
+
* below (`listAll` → `getDevice`).
|
|
31758
|
+
*
|
|
31759
|
+
* Removal is the destructive direction (every proxy handle a consumer
|
|
31760
|
+
* holds goes inert), and an EMPTY binding list is not a claim that the
|
|
31761
|
+
* device is gone — a device can legitimately bind nothing. So it needs
|
|
31762
|
+
* a second read to agree (D49); `device.unregistered` remains the
|
|
31763
|
+
* primary removal path.
|
|
31764
|
+
*/
|
|
31050
31765
|
async refreshBinding(deviceId) {
|
|
31051
31766
|
try {
|
|
31052
|
-
const fresh =
|
|
31053
|
-
if (fresh
|
|
31054
|
-
|
|
31767
|
+
const fresh = await this.api.deviceManager.getBindings.query({ deviceId });
|
|
31768
|
+
if (fresh.entries.length > 0) {
|
|
31769
|
+
this.bindings.set(deviceId, fresh);
|
|
31770
|
+
return;
|
|
31771
|
+
}
|
|
31772
|
+
if (await this.api.deviceManager.getDevice.query({ deviceId }) === null) {
|
|
31773
|
+
this.applyDeviceRemoval(deviceId);
|
|
31774
|
+
return;
|
|
31775
|
+
}
|
|
31776
|
+
this.bindings.set(deviceId, fresh);
|
|
31055
31777
|
} catch {}
|
|
31056
31778
|
}
|
|
31057
31779
|
async refreshDeviceMetadata(deviceId, kind) {
|
|
@@ -38071,6 +38793,320 @@ function getCapsByProviderKind(kind) {
|
|
|
38071
38793
|
return out;
|
|
38072
38794
|
}
|
|
38073
38795
|
//#endregion
|
|
38796
|
+
//#region src/generated/runtime-state-durability.ts
|
|
38797
|
+
/**
|
|
38798
|
+
* Per-cap runtime-state policy, projected from every `*.cap.ts` that declares
|
|
38799
|
+
* `runtimeState`. 62 caps: 33 `restored`, 29 `session`.
|
|
38800
|
+
*
|
|
38801
|
+
* A cap absent from this map has no runtime-state slice at all. A cap PRESENT
|
|
38802
|
+
* with `durability: 'session'` has one and has decided not to keep it.
|
|
38803
|
+
*/
|
|
38804
|
+
var RUNTIME_STATE_POLICY = {
|
|
38805
|
+
"air-quality-sensor": {
|
|
38806
|
+
durability: "restored",
|
|
38807
|
+
volatileFields: ["lastFetchedAt"]
|
|
38808
|
+
},
|
|
38809
|
+
"alarm-panel": {
|
|
38810
|
+
durability: "restored",
|
|
38811
|
+
volatileFields: ["lastChangedAt"]
|
|
38812
|
+
},
|
|
38813
|
+
"ambient-light-sensor": {
|
|
38814
|
+
durability: "restored",
|
|
38815
|
+
volatileFields: ["lastFetchedAt"]
|
|
38816
|
+
},
|
|
38817
|
+
"audio-metrics": {
|
|
38818
|
+
durability: "session",
|
|
38819
|
+
volatileFields: []
|
|
38820
|
+
},
|
|
38821
|
+
"automation-control": {
|
|
38822
|
+
durability: "session",
|
|
38823
|
+
volatileFields: []
|
|
38824
|
+
},
|
|
38825
|
+
"battery": {
|
|
38826
|
+
durability: "restored",
|
|
38827
|
+
volatileFields: ["lastUpdated"]
|
|
38828
|
+
},
|
|
38829
|
+
"binary": {
|
|
38830
|
+
durability: "restored",
|
|
38831
|
+
volatileFields: ["lastChangedAt"]
|
|
38832
|
+
},
|
|
38833
|
+
"brightness": {
|
|
38834
|
+
durability: "session",
|
|
38835
|
+
volatileFields: []
|
|
38836
|
+
},
|
|
38837
|
+
"camera-streams": {
|
|
38838
|
+
durability: "session",
|
|
38839
|
+
volatileFields: []
|
|
38840
|
+
},
|
|
38841
|
+
"carbon-monoxide": {
|
|
38842
|
+
durability: "restored",
|
|
38843
|
+
volatileFields: ["lastChangedAt"]
|
|
38844
|
+
},
|
|
38845
|
+
"climate-control": {
|
|
38846
|
+
durability: "session",
|
|
38847
|
+
volatileFields: []
|
|
38848
|
+
},
|
|
38849
|
+
"color": {
|
|
38850
|
+
durability: "session",
|
|
38851
|
+
volatileFields: []
|
|
38852
|
+
},
|
|
38853
|
+
"connectivity": {
|
|
38854
|
+
durability: "restored",
|
|
38855
|
+
volatileFields: ["lastChangedAt"]
|
|
38856
|
+
},
|
|
38857
|
+
"consumables": {
|
|
38858
|
+
durability: "session",
|
|
38859
|
+
volatileFields: []
|
|
38860
|
+
},
|
|
38861
|
+
"contact": {
|
|
38862
|
+
durability: "restored",
|
|
38863
|
+
volatileFields: ["lastChangedAt"]
|
|
38864
|
+
},
|
|
38865
|
+
"control": {
|
|
38866
|
+
durability: "session",
|
|
38867
|
+
volatileFields: []
|
|
38868
|
+
},
|
|
38869
|
+
"cover": {
|
|
38870
|
+
durability: "restored",
|
|
38871
|
+
volatileFields: ["lastChangedAt"]
|
|
38872
|
+
},
|
|
38873
|
+
"day-night": {
|
|
38874
|
+
durability: "restored",
|
|
38875
|
+
volatileFields: ["lastFetchedAt"]
|
|
38876
|
+
},
|
|
38877
|
+
"device-discovery": {
|
|
38878
|
+
durability: "session",
|
|
38879
|
+
volatileFields: []
|
|
38880
|
+
},
|
|
38881
|
+
"device-status": {
|
|
38882
|
+
durability: "restored",
|
|
38883
|
+
volatileFields: ["lastChangedAt"]
|
|
38884
|
+
},
|
|
38885
|
+
"doorbell": {
|
|
38886
|
+
durability: "restored",
|
|
38887
|
+
volatileFields: []
|
|
38888
|
+
},
|
|
38889
|
+
"enum-sensor": {
|
|
38890
|
+
durability: "restored",
|
|
38891
|
+
volatileFields: ["lastFetchedAt"]
|
|
38892
|
+
},
|
|
38893
|
+
"event-emitter": {
|
|
38894
|
+
durability: "session",
|
|
38895
|
+
volatileFields: []
|
|
38896
|
+
},
|
|
38897
|
+
"fan-control": {
|
|
38898
|
+
durability: "session",
|
|
38899
|
+
volatileFields: []
|
|
38900
|
+
},
|
|
38901
|
+
"feature-probe": {
|
|
38902
|
+
durability: "session",
|
|
38903
|
+
volatileFields: []
|
|
38904
|
+
},
|
|
38905
|
+
"flood": {
|
|
38906
|
+
durability: "restored",
|
|
38907
|
+
volatileFields: ["lastChangedAt"]
|
|
38908
|
+
},
|
|
38909
|
+
"gas": {
|
|
38910
|
+
durability: "restored",
|
|
38911
|
+
volatileFields: ["lastChangedAt"]
|
|
38912
|
+
},
|
|
38913
|
+
"humidifier": {
|
|
38914
|
+
durability: "session",
|
|
38915
|
+
volatileFields: []
|
|
38916
|
+
},
|
|
38917
|
+
"humidity-sensor": {
|
|
38918
|
+
durability: "restored",
|
|
38919
|
+
volatileFields: ["lastFetchedAt"]
|
|
38920
|
+
},
|
|
38921
|
+
"image": {
|
|
38922
|
+
durability: "session",
|
|
38923
|
+
volatileFields: []
|
|
38924
|
+
},
|
|
38925
|
+
"image-settings": {
|
|
38926
|
+
durability: "restored",
|
|
38927
|
+
volatileFields: ["lastFetchedAt"]
|
|
38928
|
+
},
|
|
38929
|
+
"lawn-mower-control": {
|
|
38930
|
+
durability: "session",
|
|
38931
|
+
volatileFields: []
|
|
38932
|
+
},
|
|
38933
|
+
"lock-control": {
|
|
38934
|
+
durability: "restored",
|
|
38935
|
+
volatileFields: ["lastChangedAt"]
|
|
38936
|
+
},
|
|
38937
|
+
"media-player": {
|
|
38938
|
+
durability: "session",
|
|
38939
|
+
volatileFields: []
|
|
38940
|
+
},
|
|
38941
|
+
"motion": {
|
|
38942
|
+
durability: "session",
|
|
38943
|
+
volatileFields: []
|
|
38944
|
+
},
|
|
38945
|
+
"motion-trigger": {
|
|
38946
|
+
durability: "session",
|
|
38947
|
+
volatileFields: []
|
|
38948
|
+
},
|
|
38949
|
+
"motion-zones": {
|
|
38950
|
+
durability: "restored",
|
|
38951
|
+
volatileFields: ["lastFetchedAt"]
|
|
38952
|
+
},
|
|
38953
|
+
"native-object-detection": {
|
|
38954
|
+
durability: "restored",
|
|
38955
|
+
volatileFields: ["lastFetchedAt"]
|
|
38956
|
+
},
|
|
38957
|
+
"notifier": {
|
|
38958
|
+
durability: "session",
|
|
38959
|
+
volatileFields: []
|
|
38960
|
+
},
|
|
38961
|
+
"numeric-sensor": {
|
|
38962
|
+
durability: "restored",
|
|
38963
|
+
volatileFields: ["lastFetchedAt"]
|
|
38964
|
+
},
|
|
38965
|
+
"pet-feeder": {
|
|
38966
|
+
durability: "session",
|
|
38967
|
+
volatileFields: []
|
|
38968
|
+
},
|
|
38969
|
+
"power-meter": {
|
|
38970
|
+
durability: "restored",
|
|
38971
|
+
volatileFields: ["lastFetchedAt"]
|
|
38972
|
+
},
|
|
38973
|
+
"presence": {
|
|
38974
|
+
durability: "restored",
|
|
38975
|
+
volatileFields: ["lastChangedAt"]
|
|
38976
|
+
},
|
|
38977
|
+
"pressure-sensor": {
|
|
38978
|
+
durability: "restored",
|
|
38979
|
+
volatileFields: ["lastFetchedAt"]
|
|
38980
|
+
},
|
|
38981
|
+
"privacy-mask": {
|
|
38982
|
+
durability: "restored",
|
|
38983
|
+
volatileFields: ["lastFetchedAt"]
|
|
38984
|
+
},
|
|
38985
|
+
"ptz-autotrack": {
|
|
38986
|
+
durability: "session",
|
|
38987
|
+
volatileFields: []
|
|
38988
|
+
},
|
|
38989
|
+
"scene-monitor": {
|
|
38990
|
+
durability: "session",
|
|
38991
|
+
volatileFields: []
|
|
38992
|
+
},
|
|
38993
|
+
"script-runner": {
|
|
38994
|
+
durability: "session",
|
|
38995
|
+
volatileFields: []
|
|
38996
|
+
},
|
|
38997
|
+
"smoke": {
|
|
38998
|
+
durability: "restored",
|
|
38999
|
+
volatileFields: ["lastChangedAt"]
|
|
39000
|
+
},
|
|
39001
|
+
"stream-params": {
|
|
39002
|
+
durability: "restored",
|
|
39003
|
+
volatileFields: ["lastFetchedAt"]
|
|
39004
|
+
},
|
|
39005
|
+
"switch": {
|
|
39006
|
+
durability: "restored",
|
|
39007
|
+
volatileFields: ["lastChangedAt"]
|
|
39008
|
+
},
|
|
39009
|
+
"tamper": {
|
|
39010
|
+
durability: "restored",
|
|
39011
|
+
volatileFields: ["lastChangedAt"]
|
|
39012
|
+
},
|
|
39013
|
+
"temperature-sensor": {
|
|
39014
|
+
durability: "restored",
|
|
39015
|
+
volatileFields: ["lastFetchedAt"]
|
|
39016
|
+
},
|
|
39017
|
+
"update": {
|
|
39018
|
+
durability: "session",
|
|
39019
|
+
volatileFields: []
|
|
39020
|
+
},
|
|
39021
|
+
"vacuum-control": {
|
|
39022
|
+
durability: "session",
|
|
39023
|
+
volatileFields: []
|
|
39024
|
+
},
|
|
39025
|
+
"valve": {
|
|
39026
|
+
durability: "session",
|
|
39027
|
+
volatileFields: []
|
|
39028
|
+
},
|
|
39029
|
+
"vibration": {
|
|
39030
|
+
durability: "restored",
|
|
39031
|
+
volatileFields: ["lastChangedAt"]
|
|
39032
|
+
},
|
|
39033
|
+
"water-heater": {
|
|
39034
|
+
durability: "session",
|
|
39035
|
+
volatileFields: []
|
|
39036
|
+
},
|
|
39037
|
+
"weather": {
|
|
39038
|
+
durability: "session",
|
|
39039
|
+
volatileFields: []
|
|
39040
|
+
},
|
|
39041
|
+
"zone-analytics": {
|
|
39042
|
+
durability: "session",
|
|
39043
|
+
volatileFields: []
|
|
39044
|
+
},
|
|
39045
|
+
"zone-rules": {
|
|
39046
|
+
durability: "restored",
|
|
39047
|
+
volatileFields: []
|
|
39048
|
+
},
|
|
39049
|
+
"zones": {
|
|
39050
|
+
durability: "restored",
|
|
39051
|
+
volatileFields: []
|
|
39052
|
+
}
|
|
39053
|
+
};
|
|
39054
|
+
/**
|
|
39055
|
+
* The policy for `capName`. An UNKNOWN cap resolves to `'session'` — an
|
|
39056
|
+
* addon-private slice the codegen has never seen is not persisted until its
|
|
39057
|
+
* capability says so, which is the safe direction: the cost of a lost session
|
|
39058
|
+
* value is a cold window, the cost of an unasked-for persist is a commit per
|
|
39059
|
+
* second on the fleet's busiest write path.
|
|
39060
|
+
*/
|
|
39061
|
+
function runtimeStatePolicyFor(capName) {
|
|
39062
|
+
return RUNTIME_STATE_POLICY[capName] ?? SESSION_ONLY_POLICY;
|
|
39063
|
+
}
|
|
39064
|
+
/** Shared fallback instance — see {@link runtimeStatePolicyFor}. */
|
|
39065
|
+
var SESSION_ONLY_POLICY = {
|
|
39066
|
+
durability: "session",
|
|
39067
|
+
volatileFields: []
|
|
39068
|
+
};
|
|
39069
|
+
/** True when this cap's slice is written to disk. */
|
|
39070
|
+
function isRestoredCap(capName) {
|
|
39071
|
+
return runtimeStatePolicyFor(capName).durability === "restored";
|
|
39072
|
+
}
|
|
39073
|
+
/** Cap names whose slice survives a restart, sorted. */
|
|
39074
|
+
var RESTORED_CAP_NAMES = [
|
|
39075
|
+
"air-quality-sensor",
|
|
39076
|
+
"alarm-panel",
|
|
39077
|
+
"ambient-light-sensor",
|
|
39078
|
+
"battery",
|
|
39079
|
+
"binary",
|
|
39080
|
+
"carbon-monoxide",
|
|
39081
|
+
"connectivity",
|
|
39082
|
+
"contact",
|
|
39083
|
+
"cover",
|
|
39084
|
+
"day-night",
|
|
39085
|
+
"device-status",
|
|
39086
|
+
"doorbell",
|
|
39087
|
+
"enum-sensor",
|
|
39088
|
+
"flood",
|
|
39089
|
+
"gas",
|
|
39090
|
+
"humidity-sensor",
|
|
39091
|
+
"image-settings",
|
|
39092
|
+
"lock-control",
|
|
39093
|
+
"motion-zones",
|
|
39094
|
+
"native-object-detection",
|
|
39095
|
+
"numeric-sensor",
|
|
39096
|
+
"power-meter",
|
|
39097
|
+
"presence",
|
|
39098
|
+
"pressure-sensor",
|
|
39099
|
+
"privacy-mask",
|
|
39100
|
+
"smoke",
|
|
39101
|
+
"stream-params",
|
|
39102
|
+
"switch",
|
|
39103
|
+
"tamper",
|
|
39104
|
+
"temperature-sensor",
|
|
39105
|
+
"vibration",
|
|
39106
|
+
"zone-rules",
|
|
39107
|
+
"zones"
|
|
39108
|
+
];
|
|
39109
|
+
//#endregion
|
|
38074
39110
|
//#region src/generated/scope-presets.ts
|
|
38075
39111
|
var SCOPE_PRESETS = [
|
|
38076
39112
|
{
|
|
@@ -38733,11 +39769,197 @@ function createSystemProxy(api) {
|
|
|
38733
39769
|
};
|
|
38734
39770
|
}
|
|
38735
39771
|
//#endregion
|
|
39772
|
+
//#region src/notification/audio-condition.ts
|
|
39773
|
+
/**
|
|
39774
|
+
* audio-condition — the authoring logic behind the sustained-sound condition
|
|
39775
|
+
* (`NcConditions.audio`), pure and UI-framework-free.
|
|
39776
|
+
*
|
|
39777
|
+
* WHY IT LIVES HERE
|
|
39778
|
+
* ─────────────────
|
|
39779
|
+
* Same reason as `condition-taxonomy.ts` next door: two editors author this
|
|
39780
|
+
* condition (the admin UI and the viewer), the vocabulary it offers is already
|
|
39781
|
+
* in this package (`AUDIO_MACRO_LABELS`), and a second copy of "what a cleared
|
|
39782
|
+
* threshold writes" is a mirror free to drift. The viewer keeps its own copy
|
|
39783
|
+
* because it is a separate app with its own toolchain; every surface that CAN
|
|
39784
|
+
* import `@camstack/types` uses this one.
|
|
39785
|
+
*
|
|
39786
|
+
* Four behaviours here are not cosmetic:
|
|
39787
|
+
*
|
|
39788
|
+
* 1. **dBFS is negative-going.** `0` is full scale; digital silence reads
|
|
39789
|
+
* {@link NC_AUDIO_DBFS_FLOOR}. A control that let an operator author `60`
|
|
39790
|
+
* meaning "loud" would write a threshold no sample can reach, and the rule
|
|
39791
|
+
* would look broken rather than mis-configured. Every write is clamped.
|
|
39792
|
+
* 2. **Neither filter given = the engine REFUSES.** With no level floor and no
|
|
39793
|
+
* labels every sample is trivially a hit, so the window would fire on
|
|
39794
|
+
* silence. {@link audioIsFailClosed} is how an editor says that BEFORE the
|
|
39795
|
+
* save instead of shipping a rule that never notifies and never says why.
|
|
39796
|
+
* 3. **Both label spellings are the same label.** The hub's taxonomy serves
|
|
39797
|
+
* `audio-dog`; the macro catalog and an operator both say `dog`, and the
|
|
39798
|
+
* matcher normalizes the prefix away on both sides. Selection therefore
|
|
39799
|
+
* compares NORMALIZED ids — a rule authored in the admin UI must not read
|
|
39800
|
+
* as "nothing selected" on the phone.
|
|
39801
|
+
* 4. **A stored label the build does not know stays visible.** It is offered
|
|
39802
|
+
* as an explicitly-unknown, removable choice, never silently dropped:
|
|
39803
|
+
* rewriting the rule the operator is looking at is worse than showing a
|
|
39804
|
+
* stale id.
|
|
39805
|
+
*/
|
|
39806
|
+
/** The `audio-` namespace the NC taxonomy uses for these same macro ids. */
|
|
39807
|
+
var AUDIO_KIND_PREFIX = "audio-";
|
|
39808
|
+
/** Strip the taxonomy's `audio-` namespace: `audio-dog` and `dog` are one label. */
|
|
39809
|
+
function normalizeAudioLabel(value) {
|
|
39810
|
+
return value.startsWith(AUDIO_KIND_PREFIX) ? value.slice(6) : value;
|
|
39811
|
+
}
|
|
39812
|
+
/** Level bounds, in dBFS. Negative-going: the ceiling is full scale. */
|
|
39813
|
+
var NC_AUDIO_DB_MIN = -96;
|
|
39814
|
+
var NC_AUDIO_DB_MAX = 0;
|
|
39815
|
+
/** Step of the level control — 3 dB is one perceptual notch, not one unit. */
|
|
39816
|
+
var NC_AUDIO_DB_STEP = 3;
|
|
39817
|
+
/**
|
|
39818
|
+
* Offered when the operator turns the level filter ON. NOT a schema default:
|
|
39819
|
+
* an absent `dbThreshold` means "any level" and stays absent until asked for,
|
|
39820
|
+
* and a stepper seeded at the -96 floor would need thirty taps to reach a
|
|
39821
|
+
* threshold that can actually fire.
|
|
39822
|
+
*/
|
|
39823
|
+
var NC_AUDIO_DB_OFFERED = -30;
|
|
39824
|
+
var NC_AUDIO_HIT_PERCENT_MIN = 1;
|
|
39825
|
+
var NC_AUDIO_HIT_PERCENT_MAX = 100;
|
|
39826
|
+
var NC_AUDIO_SAMPLING_MIN_SEC = 1;
|
|
39827
|
+
var NC_AUDIO_SAMPLING_MAX_SEC = 300;
|
|
39828
|
+
/** Schema defaults — an untouched sub-field must author exactly these. */
|
|
39829
|
+
var NC_AUDIO_DEFAULTS = {
|
|
39830
|
+
hitPercent: 60,
|
|
39831
|
+
samplingSeconds: 10
|
|
39832
|
+
};
|
|
39833
|
+
/** What an editor SHOWS for an unset condition — without authoring it. */
|
|
39834
|
+
function audioOrDefaults(value) {
|
|
39835
|
+
return value ?? NC_AUDIO_DEFAULTS;
|
|
39836
|
+
}
|
|
39837
|
+
/**
|
|
39838
|
+
* True when the condition names NEITHER a level floor NOR any label. The engine
|
|
39839
|
+
* refuses such a rule (every sample is a hit, so the window fires on silence) —
|
|
39840
|
+
* an editor warns instead of letting the operator ship a rule that never
|
|
39841
|
+
* notifies and says nothing about why.
|
|
39842
|
+
*
|
|
39843
|
+
* An ABSENT condition is not flagged: a rule with no `audio` key is not an
|
|
39844
|
+
* audio rule at all.
|
|
39845
|
+
*/
|
|
39846
|
+
function audioIsFailClosed(value) {
|
|
39847
|
+
if (value === void 0) return false;
|
|
39848
|
+
return value.dbThreshold === void 0 && (value.labels === void 0 || value.labels.length === 0);
|
|
39849
|
+
}
|
|
39850
|
+
function clampInt(value, min, max) {
|
|
39851
|
+
if (!Number.isFinite(value)) return min;
|
|
39852
|
+
return Math.min(max, Math.max(min, Math.round(value)));
|
|
39853
|
+
}
|
|
39854
|
+
function has(patch, key) {
|
|
39855
|
+
return Object.prototype.hasOwnProperty.call(patch, key);
|
|
39856
|
+
}
|
|
39857
|
+
/**
|
|
39858
|
+
* Apply a sub-field edit, seeding from the defaults when nothing is stored yet.
|
|
39859
|
+
* The result is always in-bounds for `NcAudioConditionSchema`, and a cleared
|
|
39860
|
+
* filter is OMITTED rather than written as an explicit `undefined` (which
|
|
39861
|
+
* survives a merge patch as a deliberate erase and reads as authored).
|
|
39862
|
+
*/
|
|
39863
|
+
function patchAudio(current, patch) {
|
|
39864
|
+
const base = audioOrDefaults(current);
|
|
39865
|
+
const labels = has(patch, "labels") ? patch.labels : base.labels;
|
|
39866
|
+
const dbThreshold = has(patch, "dbThreshold") ? patch.dbThreshold : base.dbThreshold;
|
|
39867
|
+
return {
|
|
39868
|
+
...labels !== void 0 && labels.length > 0 ? { labels: [...labels] } : {},
|
|
39869
|
+
...dbThreshold !== void 0 ? { dbThreshold: clampInt(dbThreshold, NC_AUDIO_DB_MIN, 0) } : {},
|
|
39870
|
+
hitPercent: clampInt(patch.hitPercent ?? base.hitPercent, 1, 100),
|
|
39871
|
+
samplingSeconds: clampInt(patch.samplingSeconds ?? base.samplingSeconds, 1, 300)
|
|
39872
|
+
};
|
|
39873
|
+
}
|
|
39874
|
+
/** The icon glyph for a stored label the catalogue does not know. */
|
|
39875
|
+
var UNKNOWN_LABEL_ICON = "🔈";
|
|
39876
|
+
var ICON_BY_ID = new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
|
|
39877
|
+
/**
|
|
39878
|
+
* The label choices: the hub's `audioKinds` when it serves them (its WORDS, the
|
|
39879
|
+
* local EMOJI, keyed by the normalized id), else the local macro catalog — plus
|
|
39880
|
+
* any stored label neither side knows, marked unknown.
|
|
39881
|
+
*
|
|
39882
|
+
* The hub's list wins on membership because it knows which macros this cluster
|
|
39883
|
+
* actually classifies; the icons stay local because the taxonomy carries none.
|
|
39884
|
+
*/
|
|
39885
|
+
function audioLabelChoices(taxonomy, selected) {
|
|
39886
|
+
const fromHub = taxonomy?.audioKinds ?? [];
|
|
39887
|
+
const choices = fromHub.length > 0 ? fromHub.map((entry) => {
|
|
39888
|
+
const id = normalizeAudioLabel(entry.kind);
|
|
39889
|
+
return {
|
|
39890
|
+
value: id,
|
|
39891
|
+
label: entry.label,
|
|
39892
|
+
icon: ICON_BY_ID.get(id) ?? UNKNOWN_LABEL_ICON,
|
|
39893
|
+
unknown: false
|
|
39894
|
+
};
|
|
39895
|
+
}) : AUDIO_MACRO_LABELS.map((macro) => ({
|
|
39896
|
+
value: macro.id,
|
|
39897
|
+
label: macro.name,
|
|
39898
|
+
icon: macro.icon ?? UNKNOWN_LABEL_ICON,
|
|
39899
|
+
unknown: false
|
|
39900
|
+
}));
|
|
39901
|
+
const known = new Set(choices.map((choice) => choice.value));
|
|
39902
|
+
const unknownLabels = [];
|
|
39903
|
+
for (const stored of selected ?? []) {
|
|
39904
|
+
const id = normalizeAudioLabel(stored);
|
|
39905
|
+
if (known.has(id) || unknownLabels.includes(id)) continue;
|
|
39906
|
+
unknownLabels.push(id);
|
|
39907
|
+
choices.push({
|
|
39908
|
+
value: id,
|
|
39909
|
+
label: id,
|
|
39910
|
+
icon: UNKNOWN_LABEL_ICON,
|
|
39911
|
+
unknown: true
|
|
39912
|
+
});
|
|
39913
|
+
}
|
|
39914
|
+
return {
|
|
39915
|
+
choices,
|
|
39916
|
+
unknownLabels
|
|
39917
|
+
};
|
|
39918
|
+
}
|
|
39919
|
+
/**
|
|
39920
|
+
* Is this macro id selected? Compares NORMALIZED ids, so a rule authored with
|
|
39921
|
+
* the taxonomy spelling (`audio-dog`) reads as selected here.
|
|
39922
|
+
*/
|
|
39923
|
+
function isAudioLabelSelected(labels, id) {
|
|
39924
|
+
const wanted = normalizeAudioLabel(id);
|
|
39925
|
+
return (labels ?? []).some((stored) => normalizeAudioLabel(stored) === wanted);
|
|
39926
|
+
}
|
|
39927
|
+
/**
|
|
39928
|
+
* Toggle one macro id. Removing drops EVERY stored spelling of it; adding
|
|
39929
|
+
* appends the bare macro id. Returns `undefined` when the last label goes — the
|
|
39930
|
+
* field is optional and absent means "any sound", never an empty array (which
|
|
39931
|
+
* `NcAudioConditionSchema` rejects outright).
|
|
39932
|
+
*/
|
|
39933
|
+
function toggleAudioLabel(labels, id) {
|
|
39934
|
+
const wanted = normalizeAudioLabel(id);
|
|
39935
|
+
const current = labels ?? [];
|
|
39936
|
+
if (isAudioLabelSelected(current, wanted)) {
|
|
39937
|
+
const next = current.filter((stored) => normalizeAudioLabel(stored) !== wanted);
|
|
39938
|
+
return next.length > 0 ? next : void 0;
|
|
39939
|
+
}
|
|
39940
|
+
return [...current, wanted];
|
|
39941
|
+
}
|
|
39942
|
+
//#endregion
|
|
38736
39943
|
//#region src/notification/condition-taxonomy.ts
|
|
38737
39944
|
/** Condition ids that render the class picker (video macros/subs + audio). */
|
|
38738
39945
|
var CLASS_CONDITION_IDS = new Set(["classes", "classesExclude"]);
|
|
38739
39946
|
/** Condition ids that render the sensor/control label picker. */
|
|
38740
39947
|
var LABEL_CONDITION_IDS = new Set(["sensorKinds"]);
|
|
39948
|
+
/**
|
|
39949
|
+
* Condition ids whose class scope is a COUNT, not a match — they get the
|
|
39950
|
+
* MACRO-ONLY vocabulary.
|
|
39951
|
+
*
|
|
39952
|
+
* Every other class condition goes through the engine's `expandClassSelector`,
|
|
39953
|
+
* which expands a macro to its subs and matches a sub against the detection's
|
|
39954
|
+
* own class. Occupancy does not: it reads `byClass[className]` out of the
|
|
39955
|
+
* ZoneAnalytics snapshot, and that record is keyed on MACROS only (the executor
|
|
39956
|
+
* maps COCO onto the macro and drops the rest). A sub-type therefore names a key
|
|
39957
|
+
* that does not exist — the counter is 0 forever and the rule cannot fire.
|
|
39958
|
+
*
|
|
39959
|
+
* Live cost, 2026-08-12: two rules on device 617 were authored with `car`
|
|
39960
|
+
* because this picker offered the whole taxonomy. They were silent for a day.
|
|
39961
|
+
*/
|
|
39962
|
+
var COUNT_CLASS_CONDITION_IDS = new Set(["occupancy"]);
|
|
38741
39963
|
function toOption(entry) {
|
|
38742
39964
|
return {
|
|
38743
39965
|
value: entry.kind,
|
|
@@ -38815,6 +40037,14 @@ function pickerForCondition(conditionId, taxonomy) {
|
|
|
38815
40037
|
});
|
|
38816
40038
|
return groups.length > 0 ? { groups } : null;
|
|
38817
40039
|
}
|
|
40040
|
+
if (COUNT_CLASS_CONDITION_IDS.has(conditionId)) {
|
|
40041
|
+
const options = taxonomy.videoClasses.filter((e) => e.parentKind === null).map(toOption);
|
|
40042
|
+
return options.length > 0 ? { groups: [{
|
|
40043
|
+
key: "macro",
|
|
40044
|
+
fallbackLabel: "Classes",
|
|
40045
|
+
options
|
|
40046
|
+
}] } : null;
|
|
40047
|
+
}
|
|
38818
40048
|
if (LABEL_CONDITION_IDS.has(conditionId)) {
|
|
38819
40049
|
const groups = groupLabels(taxonomy.labels);
|
|
38820
40050
|
return groups.length > 0 ? { groups } : null;
|
|
@@ -41410,12 +42640,14 @@ exports.DEFAULT_EVENT_COLOR = DEFAULT_EVENT_COLOR;
|
|
|
41410
42640
|
exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
|
|
41411
42641
|
exports.DEFAULT_NATIVE_LEASE_SETTINGS = DEFAULT_NATIVE_LEASE_SETTINGS;
|
|
41412
42642
|
exports.DEFAULT_RETENTION = DEFAULT_RETENTION;
|
|
42643
|
+
exports.DEFAULT_RUNTIME_STATE_DURABILITY = require_sleep.DEFAULT_RUNTIME_STATE_DURABILITY;
|
|
41413
42644
|
exports.DEFAULT_SCRUB_THUMBNAIL_PRESET = DEFAULT_SCRUB_THUMBNAIL_PRESET;
|
|
41414
42645
|
exports.DEFAULT_TIMELAPSE_PREVIEW_TEXT = DEFAULT_TIMELAPSE_PREVIEW_TEXT;
|
|
41415
42646
|
exports.DETAIL_CROP_PADDING_FIELD = DETAIL_CROP_PADDING_FIELD;
|
|
41416
42647
|
exports.DETAIL_CROP_PADDING_KEY = DETAIL_CROP_PADDING_KEY;
|
|
41417
42648
|
exports.DETAIL_CROP_SECTION_ID = DETAIL_CROP_SECTION_ID;
|
|
41418
42649
|
exports.DETAIL_CROP_SQUARE_KEY = DETAIL_CROP_SQUARE_KEY;
|
|
42650
|
+
exports.DETECTION_MACRO_CLASSES = DETECTION_MACRO_CLASSES;
|
|
41419
42651
|
exports.DETECTION_PIPELINE_CAP_NAME = DETECTION_PIPELINE_CAP_NAME;
|
|
41420
42652
|
exports.DEVICE_BACKEND_TO_FORMAT = DEVICE_BACKEND_TO_FORMAT;
|
|
41421
42653
|
exports.DEVICE_CAP_NAMES = DEVICE_CAP_NAMES;
|
|
@@ -41659,6 +42891,15 @@ exports.NATIVE_LEASE_TILE_BUDGET_FIELD = NATIVE_LEASE_TILE_BUDGET_FIELD;
|
|
|
41659
42891
|
exports.NATIVE_LEASE_TILE_BUDGET_KEY = NATIVE_LEASE_TILE_BUDGET_KEY;
|
|
41660
42892
|
exports.NC_ALARM_SYSTEM_EVENT_KINDS = NC_ALARM_SYSTEM_EVENT_KINDS;
|
|
41661
42893
|
exports.NC_AUDIO_DBFS_FLOOR = NC_AUDIO_DBFS_FLOOR;
|
|
42894
|
+
exports.NC_AUDIO_DB_MAX = NC_AUDIO_DB_MAX;
|
|
42895
|
+
exports.NC_AUDIO_DB_MIN = NC_AUDIO_DB_MIN;
|
|
42896
|
+
exports.NC_AUDIO_DB_OFFERED = NC_AUDIO_DB_OFFERED;
|
|
42897
|
+
exports.NC_AUDIO_DB_STEP = NC_AUDIO_DB_STEP;
|
|
42898
|
+
exports.NC_AUDIO_DEFAULTS = NC_AUDIO_DEFAULTS;
|
|
42899
|
+
exports.NC_AUDIO_HIT_PERCENT_MAX = NC_AUDIO_HIT_PERCENT_MAX;
|
|
42900
|
+
exports.NC_AUDIO_HIT_PERCENT_MIN = NC_AUDIO_HIT_PERCENT_MIN;
|
|
42901
|
+
exports.NC_AUDIO_SAMPLING_MAX_SEC = NC_AUDIO_SAMPLING_MAX_SEC;
|
|
42902
|
+
exports.NC_AUDIO_SAMPLING_MIN_SEC = NC_AUDIO_SAMPLING_MIN_SEC;
|
|
41662
42903
|
exports.NC_AUTHORABLE_SYSTEM_EVENT_KINDS = NC_AUTHORABLE_SYSTEM_EVENT_KINDS;
|
|
41663
42904
|
exports.NC_BASE_CONDITION_KEYS = NC_BASE_CONDITION_KEYS;
|
|
41664
42905
|
exports.NC_CONDITION_CATALOG = NC_CONDITION_CATALOG;
|
|
@@ -41666,6 +42907,7 @@ exports.NC_CONFIRM_DEFAULT_MAX_IMAGE_PX = NC_CONFIRM_DEFAULT_MAX_IMAGE_PX;
|
|
|
41666
42907
|
exports.NC_CONFIRM_DEFAULT_TIMEOUT_MS = NC_CONFIRM_DEFAULT_TIMEOUT_MS;
|
|
41667
42908
|
exports.NC_CONFIRM_MAX_TIMEOUT_MS = NC_CONFIRM_MAX_TIMEOUT_MS;
|
|
41668
42909
|
exports.NC_CONFIRM_MIN_TIMEOUT_MS = NC_CONFIRM_MIN_TIMEOUT_MS;
|
|
42910
|
+
exports.NC_DEFAULT_SNOOZE_MINUTES = NC_DEFAULT_SNOOZE_MINUTES;
|
|
41669
42911
|
exports.NC_HISTORY_LIMIT_DEFAULT = NC_HISTORY_LIMIT_DEFAULT;
|
|
41670
42912
|
exports.NC_HISTORY_LIMIT_MAX = NC_HISTORY_LIMIT_MAX;
|
|
41671
42913
|
exports.NC_MAX_PER_TRACK_IMMEDIATE = NC_MAX_PER_TRACK_IMMEDIATE;
|
|
@@ -41812,7 +43054,9 @@ exports.REACHABILITY_PROBE_TIMEOUT_MS = REACHABILITY_PROBE_TIMEOUT_MS;
|
|
|
41812
43054
|
exports.RECOGNITION_TYPES = RECOGNITION_TYPES;
|
|
41813
43055
|
exports.RECORDING_EXPORT_MAX_READ_BYTES = RECORDING_EXPORT_MAX_READ_BYTES;
|
|
41814
43056
|
exports.RESERVED_BINDING_NAMES = RESERVED_BINDING_NAMES;
|
|
43057
|
+
exports.RESTORED_CAP_NAMES = RESTORED_CAP_NAMES;
|
|
41815
43058
|
exports.RUNTIME_DEFAULTS = RUNTIME_DEFAULTS;
|
|
43059
|
+
exports.RUNTIME_STATE_POLICY = RUNTIME_STATE_POLICY;
|
|
41816
43060
|
exports.RUNTIME_TO_FORMAT = RUNTIME_TO_FORMAT;
|
|
41817
43061
|
exports.RawStateResultSchema = require_sleep.RawStateResultSchema;
|
|
41818
43062
|
exports.ReadGopBytesResultSchema = ReadGopBytesResultSchema;
|
|
@@ -42084,7 +43328,10 @@ exports.assertTimelapseCadences = assertTimelapseCadences;
|
|
|
42084
43328
|
exports.audioAnalysisCapability = audioAnalysisCapability;
|
|
42085
43329
|
exports.audioAnalyzerCapability = audioAnalyzerCapability;
|
|
42086
43330
|
exports.audioCodecCapability = audioCodecCapability;
|
|
43331
|
+
exports.audioIsFailClosed = audioIsFailClosed;
|
|
43332
|
+
exports.audioLabelChoices = audioLabelChoices;
|
|
42087
43333
|
exports.audioMetricsCapability = audioMetricsCapability;
|
|
43334
|
+
exports.audioOrDefaults = audioOrDefaults;
|
|
42088
43335
|
exports.audioPlanFromEncodeProfile = require_canonical_hash.audioPlanFromEncodeProfile;
|
|
42089
43336
|
exports.authProviderCapability = authProviderCapability;
|
|
42090
43337
|
exports.autoAssignProfiles = autoAssignProfiles;
|
|
@@ -42222,15 +43469,18 @@ exports.intercomCapability = intercomCapability;
|
|
|
42222
43469
|
exports.invocationFromEncodeProfile = require_canonical_hash.invocationFromEncodeProfile;
|
|
42223
43470
|
exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
|
|
42224
43471
|
exports.isArrayOutputSchema = isArrayOutputSchema;
|
|
43472
|
+
exports.isAudioLabelSelected = isAudioLabelSelected;
|
|
42225
43473
|
exports.isBaseConditionKey = isBaseConditionKey;
|
|
42226
43474
|
exports.isCollectionArrayMethod = isCollectionArrayMethod;
|
|
42227
43475
|
exports.isDeployableToAgent = isDeployableToAgent;
|
|
43476
|
+
exports.isDetectionMacroClass = isDetectionMacroClass;
|
|
42228
43477
|
exports.isDeviceConfigCap = require_sleep.isDeviceConfigCap;
|
|
42229
43478
|
exports.isDeviceScopedCap = require_sleep.isDeviceScopedCap;
|
|
42230
43479
|
exports.isEvent = require_sleep.isEvent;
|
|
42231
43480
|
exports.isIsolatedBuiltin = isIsolatedBuiltin;
|
|
42232
43481
|
exports.isNode = isNode;
|
|
42233
43482
|
exports.isObjectInput = isObjectInput;
|
|
43483
|
+
exports.isRestoredCap = isRestoredCap;
|
|
42234
43484
|
exports.isSameAddonId = isSameAddonId;
|
|
42235
43485
|
exports.isScheduleActive = isScheduleActive;
|
|
42236
43486
|
exports.isSoftwareDecode = require_canonical_hash.isSoftwareDecode;
|
|
@@ -42279,6 +43529,7 @@ exports.networkQualityCapability = networkQualityCapability;
|
|
|
42279
43529
|
exports.nodePin = require_sleep.nodePin;
|
|
42280
43530
|
exports.nodesCapability = nodesCapability;
|
|
42281
43531
|
exports.normalizeAddonInitResult = require_sleep.normalizeAddonInitResult;
|
|
43532
|
+
exports.normalizeAudioLabel = normalizeAudioLabel;
|
|
42282
43533
|
exports.normalizeUnit = normalizeUnit;
|
|
42283
43534
|
exports.notificationOutputCapability = notificationOutputCapability;
|
|
42284
43535
|
exports.notificationRulesCapability = notificationRulesCapability;
|
|
@@ -42295,6 +43546,7 @@ exports.parseJsonObject = require_sleep.parseJsonObject;
|
|
|
42295
43546
|
exports.parseJsonUnknown = require_sleep.parseJsonUnknown;
|
|
42296
43547
|
exports.parseProfileBrokerId = require_sleep.parseProfileBrokerId;
|
|
42297
43548
|
exports.parseStreamParamsFormPatch = parseStreamParamsFormPatch;
|
|
43549
|
+
exports.patchAudio = patchAudio;
|
|
42298
43550
|
exports.petFeederCapability = petFeederCapability;
|
|
42299
43551
|
exports.pickAccessoryControl = pickAccessoryControl;
|
|
42300
43552
|
exports.pickDetailCropConvention = pickDetailCropConvention;
|
|
@@ -42347,6 +43599,7 @@ exports.resolveScrubThumbnailGeometry = resolveScrubThumbnailGeometry;
|
|
|
42347
43599
|
exports.resolveVariantModelId = resolveVariantModelId;
|
|
42348
43600
|
exports.runInferenceStep = runInferenceStep;
|
|
42349
43601
|
exports.runtimeDevices = runtimeDevices;
|
|
43602
|
+
exports.runtimeStatePolicyFor = runtimeStatePolicyFor;
|
|
42350
43603
|
exports.sceneMonitorCapability = sceneMonitorCapability;
|
|
42351
43604
|
exports.scopeKey = require_sleep.scopeKey;
|
|
42352
43605
|
exports.scopesAllowAddon = scopesAllowAddon;
|
|
@@ -42393,6 +43646,7 @@ exports.toExpressionValue = toExpressionValue;
|
|
|
42393
43646
|
exports.toNodeId = require_sleep.toNodeId;
|
|
42394
43647
|
exports.toStreamSourceEntry = toStreamSourceEntry;
|
|
42395
43648
|
exports.toastCapability = toastCapability;
|
|
43649
|
+
exports.toggleAudioLabel = toggleAudioLabel;
|
|
42396
43650
|
exports.tokenize = tokenize;
|
|
42397
43651
|
exports.transcodeBody = transcodeBody;
|
|
42398
43652
|
exports.tryConvertUnit = tryConvertUnit;
|