@camstack/types 1.2.284 → 1.2.285
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/capabilities/index.d.ts +1 -1
- package/dist/capabilities/notification-rules.cap.d.ts +230 -8
- package/dist/generated/addon-api.d.ts +7 -0
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +2 -2
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +296 -16
- package/dist/index.mjs +281 -17
- package/dist/notification/alarm-settings.d.ts +58 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21283,6 +21283,41 @@ var NcSnoozeSuppressedSchema = zod.z.object({
|
|
|
21283
21283
|
firstAt: zod.z.number(),
|
|
21284
21284
|
lastAt: zod.z.number()
|
|
21285
21285
|
});
|
|
21286
|
+
/** The bounds every alarm delay field carries — settings, per-mode overrides, both editors. */
|
|
21287
|
+
var NC_ALARM_DELAY_MAX_SEC = 600;
|
|
21288
|
+
var NC_ALARM_TRIGGERED_MAX_SEC = 3600;
|
|
21289
|
+
/** At most this many ids on one mode's non-blocking list. */
|
|
21290
|
+
var NC_ALARM_NONBLOCKING_MAX = 200;
|
|
21291
|
+
var NcAlarmDelaySecSchema = zod.z.number().int().min(0).max(600);
|
|
21292
|
+
var NcAlarmTriggeredSecSchema = zod.z.number().int().min(0).max(NC_ALARM_TRIGGERED_MAX_SEC);
|
|
21293
|
+
var uniqueModes = (entries) => new Set(entries.map((e) => e.mode)).size === entries.length;
|
|
21294
|
+
/** One mode's OVERRIDES. An absent field inherits the global value (D697). */
|
|
21295
|
+
var NcAlarmModeDelaysSchema = zod.z.object({
|
|
21296
|
+
mode: AlarmArmModeSchema,
|
|
21297
|
+
exitDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
21298
|
+
entryDelaySec: NcAlarmDelaySecSchema.optional(),
|
|
21299
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.optional()
|
|
21300
|
+
});
|
|
21301
|
+
var NcAlarmModeDelaysListSchema = zod.z.array(NcAlarmModeDelaysSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
21302
|
+
/**
|
|
21303
|
+
* One mode's EDIT in a patch: a number sets the override, `null` removes it (the mode inherits
|
|
21304
|
+
* again), an absent field leaves it alone. Per field, so two editors changing two different
|
|
21305
|
+
* delays of one mode never undo each other.
|
|
21306
|
+
*/
|
|
21307
|
+
var NcAlarmModeDelaysEditSchema = zod.z.object({
|
|
21308
|
+
mode: AlarmArmModeSchema,
|
|
21309
|
+
exitDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
21310
|
+
entryDelaySec: NcAlarmDelaySecSchema.nullable().optional(),
|
|
21311
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional()
|
|
21312
|
+
});
|
|
21313
|
+
var NcAlarmModeDelaysEditListSchema = zod.z.array(NcAlarmModeDelaysEditSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
21314
|
+
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
21315
|
+
var NcAlarmNonBlockingEditSchema = zod.z.object({
|
|
21316
|
+
mode: AlarmArmModeSchema,
|
|
21317
|
+
deviceId: zod.z.number().int().positive(),
|
|
21318
|
+
/** true = on the list (may be open, does not block); false = off the list (blocks). */
|
|
21319
|
+
nonBlocking: zod.z.boolean()
|
|
21320
|
+
});
|
|
21286
21321
|
/**
|
|
21287
21322
|
* One arm mode's non-blocking list: devices that may be open when that mode
|
|
21288
21323
|
* arms, without the arm being refused.
|
|
@@ -21296,10 +21331,10 @@ var NcAlarmNonBlockingSchema = zod.z.object({
|
|
|
21296
21331
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
21297
21332
|
* at the boundary rather than interpreted.
|
|
21298
21333
|
*/
|
|
21299
|
-
var NcAlarmNonBlockingListSchema = zod.z.array(NcAlarmNonBlockingSchema).max(8).refine(
|
|
21334
|
+
var NcAlarmNonBlockingListSchema = zod.z.array(NcAlarmNonBlockingSchema).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
21300
21335
|
/**
|
|
21301
|
-
* The three durations
|
|
21302
|
-
* transitions, and which openings each mode tolerates.
|
|
21336
|
+
* The three durations — global, and per mode since D697 — the panel's state
|
|
21337
|
+
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
21303
21338
|
*
|
|
21304
21339
|
* They live on the NOTIFICATION-RULES cap, not on `alarm-panel`, on purpose:
|
|
21305
21340
|
* `alarm-panel` is `deviceNative` and its other provider mirrors somebody
|
|
@@ -21309,15 +21344,15 @@ var NcAlarmNonBlockingListSchema = zod.z.array(NcAlarmNonBlockingSchema).max(8).
|
|
|
21309
21344
|
*/
|
|
21310
21345
|
var NcAlarmSettingsSchema = zod.z.object({
|
|
21311
21346
|
/** Grace period between arming and the mode taking effect. 0 = immediate. */
|
|
21312
|
-
exitDelaySec:
|
|
21347
|
+
exitDelaySec: NcAlarmDelaySecSchema,
|
|
21313
21348
|
/** Grace period between a trigger and the alarm firing. 0 = immediate. */
|
|
21314
|
-
entryDelaySec:
|
|
21349
|
+
entryDelaySec: NcAlarmDelaySecSchema,
|
|
21315
21350
|
/**
|
|
21316
21351
|
* How long `triggered` lasts before the panel re-arms itself.
|
|
21317
21352
|
* **0 = until an operator disarms it** — the behaviour before this field
|
|
21318
21353
|
* existed, and therefore what an untouched install keeps doing.
|
|
21319
21354
|
*/
|
|
21320
|
-
triggeredDurationSec:
|
|
21355
|
+
triggeredDurationSec: NcAlarmTriggeredSecSchema,
|
|
21321
21356
|
/**
|
|
21322
21357
|
* Deprecated by D630 — every transition is announced. Parsed, never read;
|
|
21323
21358
|
* remove after one release. Optional so an older admin's patch (which still
|
|
@@ -21340,17 +21375,30 @@ var NcAlarmSettingsSchema = zod.z.object({
|
|
|
21340
21375
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
21341
21376
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
21342
21377
|
*/
|
|
21343
|
-
nonBlocking: NcAlarmNonBlockingListSchema.default([])
|
|
21378
|
+
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
21379
|
+
/**
|
|
21380
|
+
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
21381
|
+
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
21382
|
+
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
21383
|
+
*/
|
|
21384
|
+
modeDelays: NcAlarmModeDelaysListSchema.default([])
|
|
21344
21385
|
});
|
|
21345
21386
|
/**
|
|
21346
21387
|
* Every field optional — a tab edits one control at a time.
|
|
21347
21388
|
*
|
|
21348
|
-
* `nonBlocking`
|
|
21349
|
-
* remove an inner `.default()`, so a patch that never
|
|
21350
|
-
* parse to `
|
|
21351
|
-
* (the same trap {@link NcRulePatchSchema} documents).
|
|
21389
|
+
* `nonBlocking` and `modeDelays` are re-declared WITHOUT their defaults:
|
|
21390
|
+
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
21391
|
+
* named the field would parse to `[]` and wipe every mode's list on an
|
|
21392
|
+
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
21393
|
+
* `modeDelays` means EDITS, not the stored overrides.
|
|
21352
21394
|
*/
|
|
21353
|
-
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
21395
|
+
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
21396
|
+
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
21397
|
+
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
21398
|
+
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
21399
|
+
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
21400
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
21401
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" });
|
|
21354
21402
|
/**
|
|
21355
21403
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
21356
21404
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -21450,6 +21498,30 @@ var NcAlarmConfigSchema = zod.z.object({
|
|
|
21450
21498
|
*/
|
|
21451
21499
|
live: NcAlarmLiveSchema.optional()
|
|
21452
21500
|
});
|
|
21501
|
+
/** At most this many ids in one `getAlarmSensors` call — a validation bound, not a target. */
|
|
21502
|
+
var NC_ALARM_SENSORS_MAX = 500;
|
|
21503
|
+
var NcAlarmSensorReadingSchema = zod.z.enum([
|
|
21504
|
+
"open",
|
|
21505
|
+
"closed",
|
|
21506
|
+
"unknown",
|
|
21507
|
+
"not-opening"
|
|
21508
|
+
]);
|
|
21509
|
+
/** One device's state as the alarm reads it — the classifier the arm check uses. */
|
|
21510
|
+
var NcAlarmSensorStateSchema = zod.z.object({
|
|
21511
|
+
deviceId: zod.z.number().int().positive(),
|
|
21512
|
+
reading: NcAlarmSensorReadingSchema,
|
|
21513
|
+
/** The word as read (`open`, `closed`, `unlocked`, `stopped`, …); null when unknown / not an opening. */
|
|
21514
|
+
state: zod.z.string().nullable(),
|
|
21515
|
+
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
21516
|
+
unknownWhy: zod.z.enum(["read-failed", "unknown-word"]).nullable(),
|
|
21517
|
+
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
21518
|
+
online: zod.z.boolean().nullable()
|
|
21519
|
+
});
|
|
21520
|
+
var NcAlarmSensorsInputSchema = zod.z.object({ deviceIds: zod.z.array(zod.z.number().int().positive()).max(500) });
|
|
21521
|
+
var NcAlarmSensorsSchema = zod.z.object({
|
|
21522
|
+
sensors: zod.z.array(NcAlarmSensorStateSchema),
|
|
21523
|
+
readAt: zod.z.number().int().nonnegative()
|
|
21524
|
+
});
|
|
21453
21525
|
/**
|
|
21454
21526
|
* The most seconds of footage any notification rule may ask a camera to retain.
|
|
21455
21527
|
*
|
|
@@ -21709,8 +21781,9 @@ var notificationRulesCapability = {
|
|
|
21709
21781
|
*/
|
|
21710
21782
|
getAlarmConfig: require_sleep.method(zod.z.object({}), NcAlarmConfigSchema, { auth: "admin" }),
|
|
21711
21783
|
/**
|
|
21712
|
-
* Patch the settings (durations
|
|
21713
|
-
*
|
|
21784
|
+
* Patch the settings (durations — global and per mode —, recipients,
|
|
21785
|
+
* per-mode non-blocking lists or one membership edit; `announceArm` is
|
|
21786
|
+
* accepted and ignored — D630). Returns the WHOLE config,
|
|
21714
21787
|
* coverage and `live` included, so a
|
|
21715
21788
|
* client never has to guess what the server settled on — the panel clamps
|
|
21716
21789
|
* and normalises, and a form that re-rendered from its own input would
|
|
@@ -21719,7 +21792,15 @@ var notificationRulesCapability = {
|
|
|
21719
21792
|
setAlarmConfig: require_sleep.method(zod.z.object({ patch: NcAlarmSettingsPatchSchema }), NcAlarmConfigSchema, {
|
|
21720
21793
|
kind: "mutation",
|
|
21721
21794
|
auth: "admin"
|
|
21722
|
-
})
|
|
21795
|
+
}),
|
|
21796
|
+
/**
|
|
21797
|
+
* The CURRENT state of each asked device as the alarm reads it (D697) — open, closed,
|
|
21798
|
+
* unknown (why) or not an opening, plus liveness. Classified by the same table the arm
|
|
21799
|
+
* check uses (`alarm-openings.ts`), so the editor and the arm can never disagree. The
|
|
21800
|
+
* caller names the ids (the household openings it already holds); at most
|
|
21801
|
+
* `NC_ALARM_SENSORS_MAX`.
|
|
21802
|
+
*/
|
|
21803
|
+
getAlarmSensors: require_sleep.method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" })
|
|
21723
21804
|
}
|
|
21724
21805
|
};
|
|
21725
21806
|
//#endregion
|
|
@@ -56424,6 +56505,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
56424
56505
|
addonId: null,
|
|
56425
56506
|
access: "view"
|
|
56426
56507
|
},
|
|
56508
|
+
"notificationRules.getAlarmSensors": {
|
|
56509
|
+
capName: "notification-rules",
|
|
56510
|
+
capScope: "system",
|
|
56511
|
+
addonId: null,
|
|
56512
|
+
access: "view"
|
|
56513
|
+
},
|
|
56427
56514
|
"notificationRules.getClipRetentionAsks": {
|
|
56428
56515
|
capName: "notification-rules",
|
|
56429
56516
|
capScope: "system",
|
|
@@ -61244,6 +61331,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
61244
61331
|
form: "single",
|
|
61245
61332
|
optional: false
|
|
61246
61333
|
}],
|
|
61334
|
+
"notificationRules.getAlarmSensors": [{
|
|
61335
|
+
name: "deviceIds",
|
|
61336
|
+
form: "array",
|
|
61337
|
+
optional: false
|
|
61338
|
+
}],
|
|
61247
61339
|
"notificationRules.setDeviceMuted": [{
|
|
61248
61340
|
name: "deviceId",
|
|
61249
61341
|
form: "single",
|
|
@@ -62482,6 +62574,7 @@ var SYSTEM_SCOPE_DEVICE_METHODS = [
|
|
|
62482
62574
|
"faceGallery.listRecentFaces",
|
|
62483
62575
|
"networkQuality.getDeviceStats",
|
|
62484
62576
|
"networkQuality.reportClientStats",
|
|
62577
|
+
"notificationRules.getAlarmSensors",
|
|
62485
62578
|
"notificationRules.setDeviceMuted",
|
|
62486
62579
|
"osdManager.clearSlotBinding",
|
|
62487
62580
|
"osdManager.copyDeviceConfiguration",
|
|
@@ -63422,7 +63515,8 @@ function createSystemProxy(api) {
|
|
|
63422
63515
|
createSnooze: (input) => dispatch("notificationRules", "createSnooze", "mutation", input),
|
|
63423
63516
|
cancelSnooze: (input) => dispatch("notificationRules", "cancelSnooze", "mutation", input),
|
|
63424
63517
|
getAlarmConfig: (input) => dispatch("notificationRules", "getAlarmConfig", "query", input),
|
|
63425
|
-
setAlarmConfig: (input) => dispatch("notificationRules", "setAlarmConfig", "mutation", input)
|
|
63518
|
+
setAlarmConfig: (input) => dispatch("notificationRules", "setAlarmConfig", "mutation", input),
|
|
63519
|
+
getAlarmSensors: (input) => dispatch("notificationRules", "getAlarmSensors", "query", input)
|
|
63426
63520
|
},
|
|
63427
63521
|
osdManager: {
|
|
63428
63522
|
getConditionSupport: (input) => dispatch("osdManager", "getConditionSupport", "query", input),
|
|
@@ -65457,6 +65551,176 @@ function sensorTransitionNeverFires(rule) {
|
|
|
65457
65551
|
/** The warning an editor shows for {@link sensorTransitionNeverFires}. */
|
|
65458
65552
|
var NC_SENSOR_TRANSITION_NEVER_FIRES_WARNING = "This rule belongs to the alarm, and an alarm rule fires only when an opening OPENS. Set to “only when it clears”, it can never fire.";
|
|
65459
65553
|
//#endregion
|
|
65554
|
+
//#region src/notification/alarm-settings.ts
|
|
65555
|
+
var NC_ALARM_DELAY_FIELDS = [
|
|
65556
|
+
"exitDelaySec",
|
|
65557
|
+
"entryDelaySec",
|
|
65558
|
+
"triggeredDurationSec"
|
|
65559
|
+
];
|
|
65560
|
+
/** The mode's value when it overrides the field, else the global one. */
|
|
65561
|
+
function pick(override, global) {
|
|
65562
|
+
return override === void 0 ? {
|
|
65563
|
+
value: global,
|
|
65564
|
+
source: "default"
|
|
65565
|
+
} : {
|
|
65566
|
+
value: override,
|
|
65567
|
+
source: "mode"
|
|
65568
|
+
};
|
|
65569
|
+
}
|
|
65570
|
+
/** What `mode` actually runs on: its own overrides, the global value for every other field. */
|
|
65571
|
+
function resolveModeDelays(settings, mode) {
|
|
65572
|
+
const entry = (settings.modeDelays ?? []).find((e) => e.mode === mode);
|
|
65573
|
+
const exit = pick(entry?.exitDelaySec, settings.exitDelaySec);
|
|
65574
|
+
const entryDelay = pick(entry?.entryDelaySec, settings.entryDelaySec);
|
|
65575
|
+
const triggered = pick(entry?.triggeredDurationSec, settings.triggeredDurationSec);
|
|
65576
|
+
return {
|
|
65577
|
+
exitDelaySec: exit.value,
|
|
65578
|
+
entryDelaySec: entryDelay.value,
|
|
65579
|
+
triggeredDurationSec: triggered.value,
|
|
65580
|
+
source: {
|
|
65581
|
+
exitDelaySec: exit.source,
|
|
65582
|
+
entryDelaySec: entryDelay.source,
|
|
65583
|
+
triggeredDurationSec: triggered.source
|
|
65584
|
+
}
|
|
65585
|
+
};
|
|
65586
|
+
}
|
|
65587
|
+
/** One field of an entry after an edit: number sets, null clears, undefined keeps. */
|
|
65588
|
+
function edited(current, edit) {
|
|
65589
|
+
if (edit === void 0) return current;
|
|
65590
|
+
return edit === null ? void 0 : edit;
|
|
65591
|
+
}
|
|
65592
|
+
/**
|
|
65593
|
+
* Apply per-field edits to the stored overrides. Returns new arrays, never mutates the input;
|
|
65594
|
+
* an entry with no field left is dropped (the mode inherits everything again).
|
|
65595
|
+
*/
|
|
65596
|
+
function applyModeDelaysEdits(current, edits) {
|
|
65597
|
+
const out = current.map((e) => ({ ...e }));
|
|
65598
|
+
for (const edit of edits) {
|
|
65599
|
+
const at = out.findIndex((e) => e.mode === edit.mode);
|
|
65600
|
+
const base = at >= 0 ? out[at] ?? { mode: edit.mode } : { mode: edit.mode };
|
|
65601
|
+
const next = { mode: edit.mode };
|
|
65602
|
+
const exit = edited(base.exitDelaySec, edit.exitDelaySec);
|
|
65603
|
+
const entry = edited(base.entryDelaySec, edit.entryDelaySec);
|
|
65604
|
+
const triggered = edited(base.triggeredDurationSec, edit.triggeredDurationSec);
|
|
65605
|
+
if (exit !== void 0) next.exitDelaySec = exit;
|
|
65606
|
+
if (entry !== void 0) next.entryDelaySec = entry;
|
|
65607
|
+
if (triggered !== void 0) next.triggeredDurationSec = triggered;
|
|
65608
|
+
if (at >= 0) out[at] = next;
|
|
65609
|
+
else out.push(next);
|
|
65610
|
+
}
|
|
65611
|
+
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0);
|
|
65612
|
+
}
|
|
65613
|
+
/**
|
|
65614
|
+
* Put ONE device on, or take it off, ONE mode's list. A no-op answers `changed: false`; an add
|
|
65615
|
+
* to a full list is REFUSED by reason (never silently dropped); an emptied list drops its entry.
|
|
65616
|
+
*/
|
|
65617
|
+
function applyNonBlockingEdit(lists, edit) {
|
|
65618
|
+
const copy = lists.map((l) => ({
|
|
65619
|
+
mode: l.mode,
|
|
65620
|
+
deviceIds: [...l.deviceIds]
|
|
65621
|
+
}));
|
|
65622
|
+
const at = copy.findIndex((l) => l.mode === edit.mode);
|
|
65623
|
+
const held = at >= 0 ? copy[at]?.deviceIds ?? [] : [];
|
|
65624
|
+
const present = held.includes(edit.deviceId);
|
|
65625
|
+
if (edit.nonBlocking === present) return {
|
|
65626
|
+
kind: "applied",
|
|
65627
|
+
lists: copy,
|
|
65628
|
+
changed: false
|
|
65629
|
+
};
|
|
65630
|
+
if (edit.nonBlocking) {
|
|
65631
|
+
if (held.length >= 200) return {
|
|
65632
|
+
kind: "refused",
|
|
65633
|
+
reason: "list-full",
|
|
65634
|
+
mode: edit.mode,
|
|
65635
|
+
max: 200
|
|
65636
|
+
};
|
|
65637
|
+
const next = {
|
|
65638
|
+
mode: edit.mode,
|
|
65639
|
+
deviceIds: [...held, edit.deviceId]
|
|
65640
|
+
};
|
|
65641
|
+
if (at >= 0) copy[at] = next;
|
|
65642
|
+
else copy.push(next);
|
|
65643
|
+
} else {
|
|
65644
|
+
const next = {
|
|
65645
|
+
mode: edit.mode,
|
|
65646
|
+
deviceIds: held.filter((id) => id !== edit.deviceId)
|
|
65647
|
+
};
|
|
65648
|
+
if (at >= 0) copy[at] = next;
|
|
65649
|
+
}
|
|
65650
|
+
return {
|
|
65651
|
+
kind: "applied",
|
|
65652
|
+
lists: copy.filter((l) => l.deviceIds.length > 0),
|
|
65653
|
+
changed: true
|
|
65654
|
+
};
|
|
65655
|
+
}
|
|
65656
|
+
function sameSet(a, b) {
|
|
65657
|
+
const sa = new Set(a);
|
|
65658
|
+
const sb = new Set(b);
|
|
65659
|
+
return sa.size === sb.size && [...sa].every((x) => sb.has(x));
|
|
65660
|
+
}
|
|
65661
|
+
/** Per-mode id sets of a lists value, empty lists ignored. */
|
|
65662
|
+
function listsByMode(lists) {
|
|
65663
|
+
const out = /* @__PURE__ */ new Map();
|
|
65664
|
+
for (const l of lists) if (l.deviceIds.length > 0) out.set(l.mode, new Set(l.deviceIds));
|
|
65665
|
+
return out;
|
|
65666
|
+
}
|
|
65667
|
+
function sameLists(a, b) {
|
|
65668
|
+
const ma = listsByMode(a);
|
|
65669
|
+
const mb = listsByMode(b);
|
|
65670
|
+
if (ma.size !== mb.size) return false;
|
|
65671
|
+
for (const [mode, ids] of ma) {
|
|
65672
|
+
const other = mb.get(mode);
|
|
65673
|
+
if (other === void 0 || !sameSet([...ids], [...other])) return false;
|
|
65674
|
+
}
|
|
65675
|
+
return true;
|
|
65676
|
+
}
|
|
65677
|
+
/** The returned entry's value for one field of a mode-delays edit. */
|
|
65678
|
+
function fieldOf(entry, field) {
|
|
65679
|
+
if (entry === void 0) return void 0;
|
|
65680
|
+
switch (field) {
|
|
65681
|
+
case "exitDelaySec": return entry.exitDelaySec;
|
|
65682
|
+
case "entryDelaySec": return entry.entryDelaySec;
|
|
65683
|
+
case "triggeredDurationSec": return entry.triggeredDurationSec;
|
|
65684
|
+
}
|
|
65685
|
+
}
|
|
65686
|
+
/** The edit's value for one field. */
|
|
65687
|
+
function editFieldOf(edit, field) {
|
|
65688
|
+
switch (field) {
|
|
65689
|
+
case "exitDelaySec": return edit.exitDelaySec;
|
|
65690
|
+
case "entryDelaySec": return edit.entryDelaySec;
|
|
65691
|
+
case "triggeredDurationSec": return edit.triggeredDurationSec;
|
|
65692
|
+
}
|
|
65693
|
+
}
|
|
65694
|
+
/**
|
|
65695
|
+
* True iff every key the patch sent is reflected in what the host returned. A host older than
|
|
65696
|
+
* this build strips the keys it does not know; this is how a client tells "saved" from "parsed
|
|
65697
|
+
* and dropped". `announceArm` is ignored (parsed, never read). A `null` clear "lands" on a host
|
|
65698
|
+
* that stripped the key (it lacks the field) — harmless, because such a host stores no overrides.
|
|
65699
|
+
* A whole-list `nonBlocking` naming a mode the panel does not offer reads as "not landed" (the host
|
|
65700
|
+
* drops it); only older clients and the prune send whole lists, and they do not call this.
|
|
65701
|
+
*/
|
|
65702
|
+
function alarmPatchLanded(patch, returned) {
|
|
65703
|
+
if (patch.exitDelaySec !== void 0 && patch.exitDelaySec !== returned.exitDelaySec) return false;
|
|
65704
|
+
if (patch.entryDelaySec !== void 0 && patch.entryDelaySec !== returned.entryDelaySec) return false;
|
|
65705
|
+
if (patch.triggeredDurationSec !== void 0 && patch.triggeredDurationSec !== returned.triggeredDurationSec) return false;
|
|
65706
|
+
if (patch.announceTargets !== void 0 && !sameSet(patch.announceTargets, returned.announceTargets)) return false;
|
|
65707
|
+
if (patch.nonBlocking !== void 0 && !sameLists(patch.nonBlocking, returned.nonBlocking ?? [])) return false;
|
|
65708
|
+
for (const edit of patch.modeDelays ?? []) {
|
|
65709
|
+
const entry = (returned.modeDelays ?? []).find((e) => e.mode === edit.mode);
|
|
65710
|
+
for (const field of NC_ALARM_DELAY_FIELDS) {
|
|
65711
|
+
const want = editFieldOf(edit, field);
|
|
65712
|
+
if (want === void 0) continue;
|
|
65713
|
+
const got = fieldOf(entry, field);
|
|
65714
|
+
if (want === null ? got !== void 0 : got !== want) return false;
|
|
65715
|
+
}
|
|
65716
|
+
}
|
|
65717
|
+
if (patch.nonBlockingEdit !== void 0) {
|
|
65718
|
+
const e = patch.nonBlockingEdit;
|
|
65719
|
+
if (((returned.nonBlocking ?? []).find((l) => l.mode === e.mode)?.deviceIds.includes(e.deviceId) ?? false) !== e.nonBlocking) return false;
|
|
65720
|
+
}
|
|
65721
|
+
return true;
|
|
65722
|
+
}
|
|
65723
|
+
//#endregion
|
|
65460
65724
|
//#region src/notification/sensor-raised.ts
|
|
65461
65725
|
/**
|
|
65462
65726
|
* WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
|
|
@@ -70084,8 +70348,13 @@ exports.NATIVE_LEASE_TILE_BUDGET_KEY = NATIVE_LEASE_TILE_BUDGET_KEY;
|
|
|
70084
70348
|
exports.NAVIGATION_ACTION_CATALOG = NAVIGATION_ACTION_CATALOG;
|
|
70085
70349
|
exports.NAVIGATION_LIGHT_LEVEL_MAX = NAVIGATION_LIGHT_LEVEL_MAX;
|
|
70086
70350
|
exports.NAVIGATION_LIGHT_LEVEL_MIN = NAVIGATION_LIGHT_LEVEL_MIN;
|
|
70351
|
+
exports.NC_ALARM_DELAY_FIELDS = NC_ALARM_DELAY_FIELDS;
|
|
70352
|
+
exports.NC_ALARM_DELAY_MAX_SEC = NC_ALARM_DELAY_MAX_SEC;
|
|
70353
|
+
exports.NC_ALARM_NONBLOCKING_MAX = NC_ALARM_NONBLOCKING_MAX;
|
|
70087
70354
|
exports.NC_ALARM_OPENING_EVENT_KINDS = NC_ALARM_OPENING_EVENT_KINDS;
|
|
70355
|
+
exports.NC_ALARM_SENSORS_MAX = NC_ALARM_SENSORS_MAX;
|
|
70088
70356
|
exports.NC_ALARM_SYSTEM_EVENT_KINDS = NC_ALARM_SYSTEM_EVENT_KINDS;
|
|
70357
|
+
exports.NC_ALARM_TRIGGERED_MAX_SEC = NC_ALARM_TRIGGERED_MAX_SEC;
|
|
70089
70358
|
exports.NC_AUDIO_CONFIRM_HITS_DEFAULT = NC_AUDIO_CONFIRM_HITS_DEFAULT;
|
|
70090
70359
|
exports.NC_AUDIO_CONFIRM_HITS_MAX = NC_AUDIO_CONFIRM_HITS_MAX;
|
|
70091
70360
|
exports.NC_AUDIO_CONFIRM_HITS_MIN = NC_AUDIO_CONFIRM_HITS_MIN;
|
|
@@ -70173,6 +70442,13 @@ exports.NavigationRuntimeStateSchema = NavigationRuntimeStateSchema;
|
|
|
70173
70442
|
exports.NavigationStatusSchema = NavigationStatusSchema;
|
|
70174
70443
|
exports.NcAlarmConfigSchema = NcAlarmConfigSchema;
|
|
70175
70444
|
exports.NcAlarmModeCoverageSchema = NcAlarmModeCoverageSchema;
|
|
70445
|
+
exports.NcAlarmModeDelaysEditSchema = NcAlarmModeDelaysEditSchema;
|
|
70446
|
+
exports.NcAlarmModeDelaysSchema = NcAlarmModeDelaysSchema;
|
|
70447
|
+
exports.NcAlarmNonBlockingEditSchema = NcAlarmNonBlockingEditSchema;
|
|
70448
|
+
exports.NcAlarmSensorReadingSchema = NcAlarmSensorReadingSchema;
|
|
70449
|
+
exports.NcAlarmSensorStateSchema = NcAlarmSensorStateSchema;
|
|
70450
|
+
exports.NcAlarmSensorsInputSchema = NcAlarmSensorsInputSchema;
|
|
70451
|
+
exports.NcAlarmSensorsSchema = NcAlarmSensorsSchema;
|
|
70176
70452
|
exports.NcAlarmSettingsPatchSchema = NcAlarmSettingsPatchSchema;
|
|
70177
70453
|
exports.NcAlarmSettingsSchema = NcAlarmSettingsSchema;
|
|
70178
70454
|
exports.NcAlarmSkipReasonSchema = NcAlarmSkipReasonSchema;
|
|
@@ -70745,8 +71021,11 @@ exports.addonsCapability = addonsCapability;
|
|
|
70745
71021
|
exports.adminUiCapability = require_sleep.adminUiCapability;
|
|
70746
71022
|
exports.airQualitySensorCapability = airQualitySensorCapability;
|
|
70747
71023
|
exports.alarmPanelCapability = alarmPanelCapability;
|
|
71024
|
+
exports.alarmPatchLanded = alarmPatchLanded;
|
|
70748
71025
|
exports.alertsCapability = alertsCapability;
|
|
70749
71026
|
exports.ambientLightSensorCapability = ambientLightSensorCapability;
|
|
71027
|
+
exports.applyModeDelaysEdits = applyModeDelaysEdits;
|
|
71028
|
+
exports.applyNonBlockingEdit = applyNonBlockingEdit;
|
|
70750
71029
|
exports.asBoolean = require_sleep.asBoolean;
|
|
70751
71030
|
exports.asJsonArray = require_sleep.asJsonArray;
|
|
70752
71031
|
exports.asJsonObject = require_sleep.asJsonObject;
|
|
@@ -71215,6 +71494,7 @@ exports.resolveHydratedFieldValue = require_sleep.resolveHydratedFieldValue;
|
|
|
71215
71494
|
exports.resolveLocationIcon = resolveLocationIcon;
|
|
71216
71495
|
exports.resolveLocationMode = resolveLocationMode;
|
|
71217
71496
|
exports.resolveMethodAuth = resolveMethodAuth;
|
|
71497
|
+
exports.resolveModeDelays = resolveModeDelays;
|
|
71218
71498
|
exports.resolveMutate = resolveMutate;
|
|
71219
71499
|
exports.resolvePoolMemoryPolicy = resolvePoolMemoryPolicy;
|
|
71220
71500
|
exports.resolveRecordingProfiles = resolveRecordingProfiles;
|