@camstack/addon-post-analysis 1.2.293 → 1.2.295
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/{clip-model-registry-D2zqXamW.mjs → clip-model-registry-BrHhUIfN.mjs} +276 -156
- package/dist/{clip-model-registry-BAuTHS_s.js → clip-model-registry-Dxlc9JV3.js} +275 -155
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DW6-zerK.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-B28yTZRG.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-vs3KH9py.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-KXwf-qxG.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-CAJh3aX8.mjs → hostInit-CLLZtXTH.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +331 -141
- package/dist/pipeline-analytics/index.mjs +331 -141
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +2 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Boh18P08.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bs5QFgmh.mjs +0 -26
|
@@ -5370,7 +5370,7 @@ var ZodIssueCode = {
|
|
|
5370
5370
|
var ZodFirstPartyTypeKind;
|
|
5371
5371
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5372
5372
|
//#endregion
|
|
5373
|
-
//#region ../types/dist/sleep-
|
|
5373
|
+
//#region ../types/dist/sleep-DlrgY4Qb.mjs
|
|
5374
5374
|
/**
|
|
5375
5375
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5376
5376
|
* window to float samples (D455).
|
|
@@ -6985,6 +6985,10 @@ function toNodeId(idOrRunnerId) {
|
|
|
6985
6985
|
const head = idOrRunnerId.split("/")[0];
|
|
6986
6986
|
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
6987
6987
|
}
|
|
6988
|
+
object({
|
|
6989
|
+
field: string().min(1),
|
|
6990
|
+
on: literal("advance")
|
|
6991
|
+
});
|
|
6988
6992
|
/**
|
|
6989
6993
|
* Output schema shared by the contribution + live methods.
|
|
6990
6994
|
*
|
|
@@ -7625,7 +7629,7 @@ function errMsg(err) {
|
|
|
7625
7629
|
return String(err);
|
|
7626
7630
|
}
|
|
7627
7631
|
//#endregion
|
|
7628
|
-
//#region ../types/dist/composition-
|
|
7632
|
+
//#region ../types/dist/composition-BK-GTFYb.mjs
|
|
7629
7633
|
/**
|
|
7630
7634
|
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
7631
7635
|
* canonical form sorts object keys alphabetically at every depth so two
|
|
@@ -7658,6 +7662,173 @@ function replaceWithSortedKeys(_key, value) {
|
|
|
7658
7662
|
return value;
|
|
7659
7663
|
}
|
|
7660
7664
|
/**
|
|
7665
|
+
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
7666
|
+
* valutatore puro del suo FRONTE.
|
|
7667
|
+
*
|
|
7668
|
+
* Viveva dentro il builtin virtual-doorbell
|
|
7669
|
+
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
7670
|
+
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
7671
|
+
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
7672
|
+
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
7673
|
+
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
7674
|
+
* SPOSTA qui e il doorbell la ri-esporta.
|
|
7675
|
+
*
|
|
7676
|
+
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
7677
|
+
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
7678
|
+
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
7679
|
+
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
7680
|
+
*/
|
|
7681
|
+
/**
|
|
7682
|
+
* Known binary / switch source caps → the boolean slice field whose
|
|
7683
|
+
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
7684
|
+
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
7685
|
+
* state, connectivity's connected flag) are deliberately excluded — a
|
|
7686
|
+
* reconnect is not a doorbell press, and it is not a recording either.
|
|
7687
|
+
*/
|
|
7688
|
+
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
7689
|
+
contact: "entryOpen",
|
|
7690
|
+
binary: "on",
|
|
7691
|
+
switch: "on",
|
|
7692
|
+
motion: "detected",
|
|
7693
|
+
flood: "flooded",
|
|
7694
|
+
gas: "detected",
|
|
7695
|
+
smoke: "detected",
|
|
7696
|
+
"carbon-monoxide": "detected",
|
|
7697
|
+
vibration: "detected",
|
|
7698
|
+
tamper: "tampered"
|
|
7699
|
+
};
|
|
7700
|
+
/**
|
|
7701
|
+
* The same caps → the slice field carrying the ms-epoch timestamp of the
|
|
7702
|
+
* last transition. Every source cap MUST appear here (guarded by a spec):
|
|
7703
|
+
* without a transition timestamp the evaluator cannot tell a genuine rise
|
|
7704
|
+
* from a boot-time hydration when the FIRST slice it ever sees is already
|
|
7705
|
+
* active, and errs towards silence — swallowing the rise.
|
|
7706
|
+
*
|
|
7707
|
+
* These timestamps are UPSTREAM ones, not ingest ones: the Home Assistant
|
|
7708
|
+
* provider derives them from `state.last_changed`, so they survive our own
|
|
7709
|
+
* restarts and correctly read as "hours ago" for a state that has been
|
|
7710
|
+
* active for hours. `motion` names its rise timestamp `lastDetectedAt`.
|
|
7711
|
+
*/
|
|
7712
|
+
var SOURCE_CAP_CHANGED_AT_FIELD = {
|
|
7713
|
+
contact: "lastChangedAt",
|
|
7714
|
+
binary: "lastChangedAt",
|
|
7715
|
+
switch: "lastChangedAt",
|
|
7716
|
+
motion: "lastDetectedAt",
|
|
7717
|
+
flood: "lastChangedAt",
|
|
7718
|
+
gas: "lastChangedAt",
|
|
7719
|
+
smoke: "lastChangedAt",
|
|
7720
|
+
"carbon-monoxide": "lastChangedAt",
|
|
7721
|
+
vibration: "lastChangedAt",
|
|
7722
|
+
tamper: "lastChangedAt"
|
|
7723
|
+
};
|
|
7724
|
+
/** Cap names whose presence in a device's bindings qualify it as a source. */
|
|
7725
|
+
var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
|
|
7726
|
+
/** True when a cap is a recognised binary/switch source. */
|
|
7727
|
+
function isSourceCap(capName) {
|
|
7728
|
+
return Object.prototype.hasOwnProperty.call(SOURCE_CAP_ACTIVE_FIELD, capName);
|
|
7729
|
+
}
|
|
7730
|
+
/** Extract the "active" boolean a source cap's slice carries, or null when
|
|
7731
|
+
* the cap is unknown or the field is missing / non-boolean. */
|
|
7732
|
+
function sliceActiveValue(capName, slice) {
|
|
7733
|
+
const field = SOURCE_CAP_ACTIVE_FIELD[capName];
|
|
7734
|
+
if (field === void 0) return null;
|
|
7735
|
+
const raw = slice[field];
|
|
7736
|
+
return typeof raw === "boolean" ? raw : null;
|
|
7737
|
+
}
|
|
7738
|
+
/** Ms-epoch transition timestamp a source cap's slice carries, or null when
|
|
7739
|
+
* it is absent, non-numeric or the zero "never observed" sentinel. */
|
|
7740
|
+
function sliceChangedAt(capName, slice) {
|
|
7741
|
+
const field = SOURCE_CAP_CHANGED_AT_FIELD[capName];
|
|
7742
|
+
if (field === void 0) return null;
|
|
7743
|
+
const raw = slice[field];
|
|
7744
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return null;
|
|
7745
|
+
return raw;
|
|
7746
|
+
}
|
|
7747
|
+
/**
|
|
7748
|
+
* How recent a source's own transition timestamp must be for a FIRST
|
|
7749
|
+
* sighting that is already active to count as a genuine rise rather than a
|
|
7750
|
+
* hydration of long-standing state.
|
|
7751
|
+
*/
|
|
7752
|
+
var DEFAULT_FIRST_SIGHTING_FRESHNESS_MS = 3e4;
|
|
7753
|
+
/**
|
|
7754
|
+
* The source-independent edge rule. The caller supplies an already extracted
|
|
7755
|
+
* boolean level and source timestamp; this function owns first-sighting
|
|
7756
|
+
* freshness and false-to-true detection.
|
|
7757
|
+
*/
|
|
7758
|
+
function evaluateSensorLevelEdge(input) {
|
|
7759
|
+
const timestamp = input.changedAt;
|
|
7760
|
+
const freshFloor = Math.max(input.startedAtMs, input.nowMs - input.firstSightingFreshnessMs);
|
|
7761
|
+
const firstRise = input.priorLevel === void 0 && input.level && timestamp !== null && Number.isFinite(timestamp) && timestamp >= freshFloor;
|
|
7762
|
+
const transitionRise = input.priorLevel === false && input.level && timestamp !== null && Number.isFinite(timestamp);
|
|
7763
|
+
if ((firstRise || transitionRise) && timestamp !== null) return {
|
|
7764
|
+
kind: "rise",
|
|
7765
|
+
timestamp
|
|
7766
|
+
};
|
|
7767
|
+
return {
|
|
7768
|
+
kind: "none",
|
|
7769
|
+
nextPriorLevel: input.level
|
|
7770
|
+
};
|
|
7771
|
+
}
|
|
7772
|
+
/**
|
|
7773
|
+
* IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
|
|
7774
|
+
* porta `prior`, `nowMs` e il proprio `startedAtMs`.
|
|
7775
|
+
*
|
|
7776
|
+
* Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
|
|
7777
|
+
* fronte solo se il timestamp UPSTREAM della transizione è posteriore a
|
|
7778
|
+
* `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
|
|
7779
|
+
* servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
|
|
7780
|
+
* stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
|
|
7781
|
+
* iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
|
|
7782
|
+
* adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
|
|
7783
|
+
* SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
|
|
7784
|
+
*/
|
|
7785
|
+
function evaluateSensorEdge(input) {
|
|
7786
|
+
const value = sliceActiveValue(input.capName, input.slice);
|
|
7787
|
+
if (value === null) return {
|
|
7788
|
+
edge: "none",
|
|
7789
|
+
value: null,
|
|
7790
|
+
reason: isSourceCap(input.capName) ? "non-boolean-value" : "unknown-cap"
|
|
7791
|
+
};
|
|
7792
|
+
if (evaluateSensorLevelEdge({
|
|
7793
|
+
level: value,
|
|
7794
|
+
changedAt: sliceChangedAt(input.capName, input.slice),
|
|
7795
|
+
priorLevel: input.prior,
|
|
7796
|
+
startedAtMs: input.startedAtMs,
|
|
7797
|
+
nowMs: input.nowMs,
|
|
7798
|
+
firstSightingFreshnessMs: input.firstSightingFreshnessMs
|
|
7799
|
+
}).kind === "rise") return {
|
|
7800
|
+
edge: "rising",
|
|
7801
|
+
value: true
|
|
7802
|
+
};
|
|
7803
|
+
if (input.prior === void 0) {
|
|
7804
|
+
if (!value) return {
|
|
7805
|
+
edge: "none",
|
|
7806
|
+
value,
|
|
7807
|
+
reason: "baseline-seeded-inactive"
|
|
7808
|
+
};
|
|
7809
|
+
return {
|
|
7810
|
+
edge: "none",
|
|
7811
|
+
value,
|
|
7812
|
+
reason: "baseline-seeded-stale-active"
|
|
7813
|
+
};
|
|
7814
|
+
}
|
|
7815
|
+
if (input.prior === value) return {
|
|
7816
|
+
edge: "none",
|
|
7817
|
+
value,
|
|
7818
|
+
reason: "no-change"
|
|
7819
|
+
};
|
|
7820
|
+
if (!value) return {
|
|
7821
|
+
edge: "none",
|
|
7822
|
+
value,
|
|
7823
|
+
reason: "falling-edge"
|
|
7824
|
+
};
|
|
7825
|
+
return {
|
|
7826
|
+
edge: "none",
|
|
7827
|
+
value,
|
|
7828
|
+
reason: "missing-timestamp"
|
|
7829
|
+
};
|
|
7830
|
+
}
|
|
7831
|
+
/**
|
|
7661
7832
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
7662
7833
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
7663
7834
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -7854,6 +8025,20 @@ var table = {
|
|
|
7854
8025
|
const present = args.flatMap((a, i) => a === null ? [] : [asFiniteNumber(a, "latest", i)]);
|
|
7855
8026
|
return present.length === 0 ? null : finiteResult(Math.max(...present), "latest");
|
|
7856
8027
|
}
|
|
8028
|
+
},
|
|
8029
|
+
rose: {
|
|
8030
|
+
minArgs: 2,
|
|
8031
|
+
maxArgs: 3,
|
|
8032
|
+
apply: () => {
|
|
8033
|
+
throw new ExpressionEvalError("rose: stateful evaluation context is required");
|
|
8034
|
+
}
|
|
8035
|
+
},
|
|
8036
|
+
count: {
|
|
8037
|
+
minArgs: 1,
|
|
8038
|
+
maxArgs: 1,
|
|
8039
|
+
apply: () => {
|
|
8040
|
+
throw new ExpressionEvalError("count: stateful evaluation context is required");
|
|
8041
|
+
}
|
|
7857
8042
|
}
|
|
7858
8043
|
};
|
|
7859
8044
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -8368,6 +8553,7 @@ var CompositionItemEntrySchema = object({
|
|
|
8368
8553
|
var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
8369
8554
|
kind: literal("fields"),
|
|
8370
8555
|
cap: string().min(1),
|
|
8556
|
+
enabled: boolean().optional(),
|
|
8371
8557
|
fields: record(string().min(1), CompositionFieldSourceSchema).refine((fields) => Object.keys(fields).length <= 32, { message: `at most 32 fields per capability` }),
|
|
8372
8558
|
/**
|
|
8373
8559
|
* Items of the cap's item array, keyed by item key (D663). Naming `items`
|
|
@@ -8379,6 +8565,7 @@ var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
|
8379
8565
|
}), object({
|
|
8380
8566
|
kind: literal("passthrough"),
|
|
8381
8567
|
cap: string().min(1),
|
|
8568
|
+
enabled: boolean().optional(),
|
|
8382
8569
|
source: CompositionSourceRefSchema
|
|
8383
8570
|
})]);
|
|
8384
8571
|
var CompositionSchema = object({
|
|
@@ -13499,6 +13686,15 @@ var cameraStreamsCapability = {
|
|
|
13499
13686
|
function kebabToCamel(s) {
|
|
13500
13687
|
return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
13501
13688
|
}
|
|
13689
|
+
EventCategory.DoorbellOnPressed;
|
|
13690
|
+
var CompositionEventPlanSchema = object({
|
|
13691
|
+
featureIndex: number().int().nonnegative(),
|
|
13692
|
+
cap: string(),
|
|
13693
|
+
eventName: string(),
|
|
13694
|
+
category: _enum(EventCategory),
|
|
13695
|
+
stateField: string(),
|
|
13696
|
+
fieldKey: string()
|
|
13697
|
+
});
|
|
13502
13698
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
13503
13699
|
var CompositionProblemSchema = object({
|
|
13504
13700
|
code: _enum([
|
|
@@ -13548,12 +13744,14 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
13548
13744
|
]);
|
|
13549
13745
|
/**
|
|
13550
13746
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
13551
|
-
* field of its cap changes value · `constant` reads nothing, computed once
|
|
13747
|
+
* field of its cap changes value · `constant` reads nothing, computed once ·
|
|
13748
|
+
* `accumulator` advances from the target's seed/current output.
|
|
13552
13749
|
*/
|
|
13553
13750
|
var CompositionFieldRoleSchema = _enum([
|
|
13554
13751
|
"derived",
|
|
13555
13752
|
"clock",
|
|
13556
|
-
"constant"
|
|
13753
|
+
"constant",
|
|
13754
|
+
"accumulator"
|
|
13557
13755
|
]);
|
|
13558
13756
|
/** The item a planned field belongs to; its `path` is then the dotted path INSIDE the item. */
|
|
13559
13757
|
var CompositionFieldItemSchema = object({
|
|
@@ -13589,6 +13787,7 @@ var CompositionFeatureModeSchema = _enum([
|
|
|
13589
13787
|
"replace"
|
|
13590
13788
|
]);
|
|
13591
13789
|
var CompositionFeaturePlanSchema = object({
|
|
13790
|
+
/** Index in the stored feature array; disabled features are omitted rather than re-indexed. */
|
|
13592
13791
|
featureIndex: number().int().nonnegative(),
|
|
13593
13792
|
cap: string(),
|
|
13594
13793
|
mode: CompositionFeatureModeSchema
|
|
@@ -13597,7 +13796,8 @@ var CompositionValidationSchema = object({
|
|
|
13597
13796
|
ok: boolean(),
|
|
13598
13797
|
problems: array(CompositionProblemSchema),
|
|
13599
13798
|
fields: array(CompositionFieldPlanSchema),
|
|
13600
|
-
features: array(CompositionFeaturePlanSchema)
|
|
13799
|
+
features: array(CompositionFeaturePlanSchema),
|
|
13800
|
+
events: array(CompositionEventPlanSchema)
|
|
13601
13801
|
});
|
|
13602
13802
|
/**
|
|
13603
13803
|
* Mirrors `CoreBlockStatus`, pinned by `core-blocks-source.spec.ts`. `degraded`:
|
|
@@ -15299,6 +15499,34 @@ var DeviceBindingsForDeviceSchema = object({
|
|
|
15299
15499
|
nativeAddonId: string()
|
|
15300
15500
|
}))
|
|
15301
15501
|
});
|
|
15502
|
+
/**
|
|
15503
|
+
* The STORED wrapper activation for one `(device, capability)` pair — the row
|
|
15504
|
+
* `setWrapperActive` writes, read back three-way (D675):
|
|
15505
|
+
*
|
|
15506
|
+
* - `value` — the store answered and holds an activation: the bound wrapper's
|
|
15507
|
+
* addon id, or `null`, the operator's explicit "off" marker (D62);
|
|
15508
|
+
* - `missing` — the store answered, its activation map exists, and it holds
|
|
15509
|
+
* nothing for this pair: the operator never activated or deactivated a
|
|
15510
|
+
* wrapper here;
|
|
15511
|
+
* - `failed` — the store could not be read, holds no activation map at all
|
|
15512
|
+
* (an empty or unready snapshot, D44), or holds something that is not an
|
|
15513
|
+
* activation. It carries NO information: a consumer must never read it as
|
|
15514
|
+
* `missing` (D315, D393).
|
|
15515
|
+
*
|
|
15516
|
+
* This is the persisted INPUT, not the derived `getBindings` view — no registry
|
|
15517
|
+
* resolution, no `defaultActive` auto-binding, no cluster native-cap folding.
|
|
15518
|
+
*/
|
|
15519
|
+
var WrapperActivationReadSchema = discriminatedUnion("kind", [
|
|
15520
|
+
object({
|
|
15521
|
+
kind: literal("value"),
|
|
15522
|
+
wrapperAddonId: string().nullable()
|
|
15523
|
+
}),
|
|
15524
|
+
object({ kind: literal("missing") }),
|
|
15525
|
+
object({
|
|
15526
|
+
kind: literal("failed"),
|
|
15527
|
+
error: string()
|
|
15528
|
+
})
|
|
15529
|
+
]);
|
|
15302
15530
|
var SavedDeviceRowSchema = object({
|
|
15303
15531
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
15304
15532
|
id: number(),
|
|
@@ -15649,7 +15877,10 @@ method(object({
|
|
|
15649
15877
|
}), _void(), {
|
|
15650
15878
|
kind: "mutation",
|
|
15651
15879
|
auth: "admin"
|
|
15652
|
-
}), method(object({
|
|
15880
|
+
}), method(object({
|
|
15881
|
+
deviceId: number(),
|
|
15882
|
+
capName: string().min(1)
|
|
15883
|
+
}), WrapperActivationReadSchema), method(object({ capName: string() }), array(string())), method(object({ deviceType: string() }), array(object({
|
|
15653
15884
|
capName: string(),
|
|
15654
15885
|
wrappers: array(string())
|
|
15655
15886
|
}))), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), object({
|
|
@@ -28918,148 +29149,6 @@ DeviceType.Camera, method(object({
|
|
|
28918
29149
|
auth: "protected"
|
|
28919
29150
|
});
|
|
28920
29151
|
/**
|
|
28921
|
-
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
28922
|
-
* valutatore puro del suo FRONTE.
|
|
28923
|
-
*
|
|
28924
|
-
* Viveva dentro il builtin virtual-doorbell
|
|
28925
|
-
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
28926
|
-
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
28927
|
-
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
28928
|
-
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
28929
|
-
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
28930
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
28931
|
-
*
|
|
28932
|
-
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
28933
|
-
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
28934
|
-
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
28935
|
-
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
28936
|
-
*/
|
|
28937
|
-
/**
|
|
28938
|
-
* Known binary / switch source caps → the boolean slice field whose
|
|
28939
|
-
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
28940
|
-
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
28941
|
-
* state, connectivity's connected flag) are deliberately excluded — a
|
|
28942
|
-
* reconnect is not a doorbell press, and it is not a recording either.
|
|
28943
|
-
*/
|
|
28944
|
-
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
28945
|
-
contact: "entryOpen",
|
|
28946
|
-
binary: "on",
|
|
28947
|
-
switch: "on",
|
|
28948
|
-
motion: "detected",
|
|
28949
|
-
flood: "flooded",
|
|
28950
|
-
gas: "detected",
|
|
28951
|
-
smoke: "detected",
|
|
28952
|
-
"carbon-monoxide": "detected",
|
|
28953
|
-
vibration: "detected",
|
|
28954
|
-
tamper: "tampered"
|
|
28955
|
-
};
|
|
28956
|
-
/**
|
|
28957
|
-
* The same caps → the slice field carrying the ms-epoch timestamp of the
|
|
28958
|
-
* last transition. Every source cap MUST appear here (guarded by a spec):
|
|
28959
|
-
* without a transition timestamp the evaluator cannot tell a genuine rise
|
|
28960
|
-
* from a boot-time hydration when the FIRST slice it ever sees is already
|
|
28961
|
-
* active, and errs towards silence — swallowing the rise.
|
|
28962
|
-
*
|
|
28963
|
-
* These timestamps are UPSTREAM ones, not ingest ones: the Home Assistant
|
|
28964
|
-
* provider derives them from `state.last_changed`, so they survive our own
|
|
28965
|
-
* restarts and correctly read as "hours ago" for a state that has been
|
|
28966
|
-
* active for hours. `motion` names its rise timestamp `lastDetectedAt`.
|
|
28967
|
-
*/
|
|
28968
|
-
var SOURCE_CAP_CHANGED_AT_FIELD = {
|
|
28969
|
-
contact: "lastChangedAt",
|
|
28970
|
-
binary: "lastChangedAt",
|
|
28971
|
-
switch: "lastChangedAt",
|
|
28972
|
-
motion: "lastDetectedAt",
|
|
28973
|
-
flood: "lastChangedAt",
|
|
28974
|
-
gas: "lastChangedAt",
|
|
28975
|
-
smoke: "lastChangedAt",
|
|
28976
|
-
"carbon-monoxide": "lastChangedAt",
|
|
28977
|
-
vibration: "lastChangedAt",
|
|
28978
|
-
tamper: "lastChangedAt"
|
|
28979
|
-
};
|
|
28980
|
-
/** Cap names whose presence in a device's bindings qualify it as a source. */
|
|
28981
|
-
var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
|
|
28982
|
-
/** True when a cap is a recognised binary/switch source. */
|
|
28983
|
-
function isSourceCap(capName) {
|
|
28984
|
-
return Object.prototype.hasOwnProperty.call(SOURCE_CAP_ACTIVE_FIELD, capName);
|
|
28985
|
-
}
|
|
28986
|
-
/** Extract the "active" boolean a source cap's slice carries, or null when
|
|
28987
|
-
* the cap is unknown or the field is missing / non-boolean. */
|
|
28988
|
-
function sliceActiveValue(capName, slice) {
|
|
28989
|
-
const field = SOURCE_CAP_ACTIVE_FIELD[capName];
|
|
28990
|
-
if (field === void 0) return null;
|
|
28991
|
-
const raw = slice[field];
|
|
28992
|
-
return typeof raw === "boolean" ? raw : null;
|
|
28993
|
-
}
|
|
28994
|
-
/** Ms-epoch transition timestamp a source cap's slice carries, or null when
|
|
28995
|
-
* it is absent, non-numeric or the zero "never observed" sentinel. */
|
|
28996
|
-
function sliceChangedAt(capName, slice) {
|
|
28997
|
-
const field = SOURCE_CAP_CHANGED_AT_FIELD[capName];
|
|
28998
|
-
if (field === void 0) return null;
|
|
28999
|
-
const raw = slice[field];
|
|
29000
|
-
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return null;
|
|
29001
|
-
return raw;
|
|
29002
|
-
}
|
|
29003
|
-
/**
|
|
29004
|
-
* How recent a source's own transition timestamp must be for a FIRST
|
|
29005
|
-
* sighting that is already active to count as a genuine rise rather than a
|
|
29006
|
-
* hydration of long-standing state.
|
|
29007
|
-
*/
|
|
29008
|
-
var DEFAULT_FIRST_SIGHTING_FRESHNESS_MS = 3e4;
|
|
29009
|
-
/**
|
|
29010
|
-
* IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
|
|
29011
|
-
* porta `prior`, `nowMs` e il proprio `startedAtMs`.
|
|
29012
|
-
*
|
|
29013
|
-
* Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
|
|
29014
|
-
* fronte solo se il timestamp UPSTREAM della transizione è posteriore a
|
|
29015
|
-
* `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
|
|
29016
|
-
* servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
|
|
29017
|
-
* stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
|
|
29018
|
-
* iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
|
|
29019
|
-
* adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
|
|
29020
|
-
* SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
|
|
29021
|
-
*/
|
|
29022
|
-
function evaluateSensorEdge(input) {
|
|
29023
|
-
const value = sliceActiveValue(input.capName, input.slice);
|
|
29024
|
-
if (value === null) return {
|
|
29025
|
-
edge: "none",
|
|
29026
|
-
value: null,
|
|
29027
|
-
reason: isSourceCap(input.capName) ? "non-boolean-value" : "unknown-cap"
|
|
29028
|
-
};
|
|
29029
|
-
if (input.prior === void 0) {
|
|
29030
|
-
if (!value) return {
|
|
29031
|
-
edge: "none",
|
|
29032
|
-
value,
|
|
29033
|
-
reason: "baseline-seeded-inactive"
|
|
29034
|
-
};
|
|
29035
|
-
const changedAt = sliceChangedAt(input.capName, input.slice);
|
|
29036
|
-
const floor = Math.max(input.startedAtMs, input.nowMs - input.firstSightingFreshnessMs);
|
|
29037
|
-
if (changedAt === null || changedAt < floor) return {
|
|
29038
|
-
edge: "none",
|
|
29039
|
-
value,
|
|
29040
|
-
reason: "baseline-seeded-stale-active"
|
|
29041
|
-
};
|
|
29042
|
-
return {
|
|
29043
|
-
edge: "rising",
|
|
29044
|
-
value: true
|
|
29045
|
-
};
|
|
29046
|
-
}
|
|
29047
|
-
if (input.prior === value) return {
|
|
29048
|
-
edge: "none",
|
|
29049
|
-
value,
|
|
29050
|
-
reason: "no-change"
|
|
29051
|
-
};
|
|
29052
|
-
if (!value) return {
|
|
29053
|
-
edge: "none",
|
|
29054
|
-
value,
|
|
29055
|
-
reason: "falling-edge"
|
|
29056
|
-
};
|
|
29057
|
-
return {
|
|
29058
|
-
edge: "rising",
|
|
29059
|
-
value: true
|
|
29060
|
-
};
|
|
29061
|
-
}
|
|
29062
|
-
/**
|
|
29063
29152
|
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
29064
29153
|
* name (same pattern as `snapshot`):
|
|
29065
29154
|
*
|
|
@@ -29132,7 +29221,13 @@ var doorbellCapability = {
|
|
|
29132
29221
|
* push (`ReolinkSimpleEvent.type === 'doorbell'`). There is no
|
|
29133
29222
|
* release/duration — it's a pulse.
|
|
29134
29223
|
*/
|
|
29135
|
-
onPressed: {
|
|
29224
|
+
onPressed: {
|
|
29225
|
+
data: DoorbellPressEventSchema,
|
|
29226
|
+
fromState: {
|
|
29227
|
+
field: "lastPressedAt",
|
|
29228
|
+
on: "advance"
|
|
29229
|
+
}
|
|
29230
|
+
} },
|
|
29136
29231
|
status: {
|
|
29137
29232
|
schema: DoorbellStatusSchema,
|
|
29138
29233
|
kind: "push"
|
|
@@ -37074,12 +37169,21 @@ var RecordingStorageUsageSchema = object({
|
|
|
37074
37169
|
*/
|
|
37075
37170
|
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
37076
37171
|
/**
|
|
37172
|
+
* Is the `archive` answer WHOLE (D674): the hour ledger loaded without
|
|
37173
|
+
* hitting its row cap, and at least one location resolved? Only then may a
|
|
37174
|
+
* camera ABSENT from `devices[]` be read as "no footage" — and only then is a
|
|
37175
|
+
* row's `oldestMs` the archive's oldest rather than the oldest of a fraction.
|
|
37176
|
+
* OPTIONAL: a recorder predating D674 omits it, and a consumer must read the
|
|
37177
|
+
* absence as `false`. A retention floor is a delete; it never guesses.
|
|
37178
|
+
*/
|
|
37179
|
+
complete: boolean().optional(),
|
|
37180
|
+
/**
|
|
37077
37181
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
37078
|
-
* of the payload without it:
|
|
37079
|
-
*
|
|
37080
|
-
*
|
|
37081
|
-
*
|
|
37082
|
-
*
|
|
37182
|
+
* of the payload without it: a recorder that could not build it omits it. A
|
|
37183
|
+
* UI that dereferences it unconditionally crashes the whole Storage page over
|
|
37184
|
+
* a missing disk bar. (The hub's cap routers pass output through unvalidated
|
|
37185
|
+
* since 2026-07-11 — `cap-router-builder.ts` — so a newer recorder's fields
|
|
37186
|
+
* are not stripped by an older hub.)
|
|
37083
37187
|
*/
|
|
37084
37188
|
locations: array(RecordingLocationUsageSchema).optional()
|
|
37085
37189
|
});
|
|
@@ -40623,7 +40727,12 @@ Object.freeze({
|
|
|
40623
40727
|
number: {
|
|
40624
40728
|
kind: "fixed",
|
|
40625
40729
|
result: ["number", "null"]
|
|
40626
|
-
}
|
|
40730
|
+
},
|
|
40731
|
+
rose: {
|
|
40732
|
+
kind: "fixed",
|
|
40733
|
+
result: ["number", "null"]
|
|
40734
|
+
},
|
|
40735
|
+
count: NUMBER
|
|
40627
40736
|
});
|
|
40628
40737
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
40629
40738
|
/**
|
|
@@ -44838,6 +44947,12 @@ Object.freeze({
|
|
|
44838
44947
|
addonId: null,
|
|
44839
44948
|
access: "view"
|
|
44840
44949
|
},
|
|
44950
|
+
"deviceManager.getWrapperActivation": {
|
|
44951
|
+
capName: "device-manager",
|
|
44952
|
+
capScope: "system",
|
|
44953
|
+
addonId: null,
|
|
44954
|
+
access: "view"
|
|
44955
|
+
},
|
|
44841
44956
|
"deviceManager.listAll": {
|
|
44842
44957
|
capName: "device-manager",
|
|
44843
44958
|
capScope: "system",
|
|
@@ -50647,6 +50762,11 @@ Object.freeze({
|
|
|
50647
50762
|
form: "single",
|
|
50648
50763
|
optional: false
|
|
50649
50764
|
}],
|
|
50765
|
+
"deviceManager.getWrapperActivation": [{
|
|
50766
|
+
name: "deviceId",
|
|
50767
|
+
form: "single",
|
|
50768
|
+
optional: false
|
|
50769
|
+
}],
|
|
50650
50770
|
"deviceManager.listAll": [{
|
|
50651
50771
|
name: "deviceIds",
|
|
50652
50772
|
form: "array",
|
|
@@ -55148,4 +55268,4 @@ function buildClipModelRegistry(entries) {
|
|
|
55148
55268
|
/** The built-in catalog's registry. */
|
|
55149
55269
|
var BUILTIN_CLIP_MODELS = buildClipModelRegistry(CLIP_IMAGE_MODELS);
|
|
55150
55270
|
//#endregion
|
|
55151
|
-
export {
|
|
55271
|
+
export { NcRuleTargetSchema as $, EventCategory as $n, isVectorIndexDimConflict as $t, LockStateSchema as A, DeviceType as An, audioModeOf as At, NC_SENSOR_TRANSITION_KINDS as B, normalizeNodeId as Bn, embeddingRequirementsFailedError as Bt, EMBEDDING_REQUIREMENTS_UNAVAILABLE as C, templateVarsFor as Cn, TimelapseRulePatchSchema as Ct, FULL_IMAGE_BBOX as D, canonicalHash as Dn, alarmPanelCapability as Dt, FIRST_LEVEL_MACRO_CLASSES as E, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as En, addonWidgetsSourceCapability as Et, MediaFileKindEnum as F, customAction as Fn, describeSystemEventDeliveryProblem as Ft, NC_TEMPLATE_VARS as G, discriminatedUnion as Gn, failureContributionCapability as Gt, NC_SYSTEM_EVENT_KIND_GROUP_SPECS as H, _enum as Hn, encodeVectorBase64 as Ht, NC_ALARM_SYSTEM_EVENT_KINDS as I, defineCustomActions as In, describeSystemEventFamilyProblem as It, NcConditionDescriptorSchema as J, object as Jn, isKnownTemplateVar as Jt, NcAlarmConfigSchema as K, literal as Kn, isDetectionMacroClass as Kt, NC_CONDITION_CATALOG as L, hydrateSchema as Ln, embeddingEncoderCapability as Lt, MAX_BIRTH_DECISION_RECORDS as M, BaseAddon as Mn, consumableLowPercentOf as Mt, MAX_BIRTH_LATENCY_PROXY_MS as N, CamProfileSchema as Nn, cosineSimilarity as Nt, FailureCounters as O, evaluateSensorEdge as On, assertTimelapseCadences as Ot, MOTION_CLOSE_AFTER_MS as P, createEvent as Pn, deriveRecordingMode as Pt, NcRuleSchema as Q, unknown as Qn, isSystemEventSummaryRule as Qt, NC_CONSUMABLE_SYSTEM_EVENT_KINDS as R, isDeviceScopedCap as Rn, embeddingModelFailedError as Rt, EMBEDDING_REQUIREMENTS_FAILED as S, templateCarriesSummary as Sn, TimelapseRuleInputSchema as St, EVENT_OWNER_TYPES as T, zoneAnalyticsCapability as Tn, TrackSourceSchema as Tt, NC_TANK_SYSTEM_EVENT_KINDS as U, array as Un, evictionPolicyOfLocation as Ut, NC_SNOOZE_MAX_MINUTES as V, sleep as Vn, embeddingRequirementsUnavailableError as Vt, NC_TAXONOMY as W, boolean as Wn, faceGalleryCapability as Wt, NcRuleInputSchema as X, record as Xn, isScheduleActive as Xt, NcConditionsSchema as Y, partialRecord as Yn, isMediaOwnerType as Yt, NcRulePatchSchema as Z, string as Zn, isSystemDelivery as Zt, DEFAULT_TIMELAPSE_PREVIEW_TEXT as _, subKindsOf as _n, SCENE_DEFAULT_ANCHOR_THRESHOLD as _t, CLIP_EMBEDDING_STEP_ID as a, pipelineAnalyticsCapability as an, NcSystemEventKindSchema as at, DeclaredDevices as b, systemEventFilterApplies as bn, SceneMonitorSchema as bt, resolveClusterModelPin as c, readTimelapseGeneratedAt as cn, NcTemplatePreviewSchema as ct, ArchivedDebugNoteSchema as d, resolvePoolMemoryPolicy as dn, PoolMemoryWatchdog as dt, kebabToCamel as en, NcRuleUpdateInputSchema as et, BaseDevice as f, ruleBelongsToAlarm as fn, RECORDING_EXPORT_MAX_READ_BYTES as ft, DEFAULT_EVENT_COLOR as g, storageOccupancyCapability as gn, SCENE_CONFIRM_DEFAULT_TIMEOUT_MS as gt, CoverStateSchema as h, servedTemplateVars as hn, RetrainStatusSchema as ht, CLIP_TEXT_MODELS as i, parseProcStatus as in, NcSnoozeSuppressedSchema as it, MAX_ARCHIVED_DEBUG_NOTES as j, errMsg as jn, buildEventKindDescriptor as jt, LabelAttributionSchema as k, isSourceCap as kn, audioMetricsCapability as kt, AUDIO_MACRO_LABELS as l, resolveClipSearchMinScore as ln, NcTemplateVarDescriptorSchema as lt, COCO_TO_MACRO as m, sensorRaisedOf as mn, RebuildObjectEmbeddingsRefusalSchema as mt, DEFAULT_CLIP_MODEL as n, notificationRulesCapability as nn, NcSnoozeInputSchema as nt, FACE_EMBEDDING_STEP_ID as o, plateGalleryCapability as on, NcTaxonomySchema as ot, BirthDecisionRecordSchema as p, sceneMonitorCapability as pn, RECORDING_SOURCE_CAMSTACK_ADDON as pt, NcAlarmSettingsPatchSchema as q, number as qn, isEventOwnerType as qt, CLIP_IMAGE_MODELS as r, occupancyScope as rn, NcSnoozeSchema as rt, readClusterModelPinStrict as s, readDeviceStateFrom as sn, NcTemplatePreviewInputSchema as st, BUILTIN_CLIP_MODELS as t, mayWriteToLocation as tn, NcScheduleSchema as tt, AlarmArmModeSchema as u, resolveLocationMode as un, OpsLogEntrySchema as ut, DETECTION_MACRO_CLASSES as v, systemEventDeliveryProblems as vn, SCENE_DEFAULT_UNCOVERED_POLICY as vt, EVENT_KIND_BY_CAP as w, vectorDimFromBase64 as wn, TimelapseRuleSchema as wt, EMBEDDING_MODEL_FAILED as x, systemEventSummaryScheduleOf as xn, TIMELAPSE_DENSE_FLOOR_SEC as xt, DETECTION_PIPELINE_CAP_NAME as y, systemEventFamilyProblems as yn, SCENE_DIVERGED as yt, NC_DEFAULT_SNOOZE_MINUTES as z, nodePin as zn, embeddingRefusalOf as zt };
|