@camstack/types 1.2.416 → 1.2.417
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 +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/air-quality-sensor.cap.d.ts +2 -8
- package/dist/capabilities/ambient-light-sensor.cap.d.ts +3 -14
- package/dist/capabilities/battery.cap.d.ts +9 -2
- package/dist/capabilities/binary.cap.d.ts +0 -5
- package/dist/capabilities/capability-definition.d.ts +6 -6
- package/dist/capabilities/consumables.cap.d.ts +30 -41
- package/dist/capabilities/control.cap.d.ts +3 -25
- package/dist/capabilities/core-blocks.cap.d.ts +1 -0
- package/dist/capabilities/customize-catalog.d.ts +0 -8
- package/dist/capabilities/customize-spec.d.ts +2 -3
- package/dist/capabilities/device-manager.cap.d.ts +79 -0
- package/dist/capabilities/device-provider.cap.d.ts +36 -0
- package/dist/capabilities/enum-sensor.cap.d.ts +5 -17
- package/dist/capabilities/humidity-sensor.cap.d.ts +3 -14
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/motion.cap.d.ts +1 -1
- package/dist/capabilities/numeric-sensor.cap.d.ts +8 -16
- package/dist/capabilities/pet-feeder.cap.d.ts +1 -1
- package/dist/capabilities/power-meter.cap.d.ts +0 -11
- package/dist/capabilities/pressure-sensor.cap.d.ts +3 -9
- package/dist/capabilities/running-state.cap.d.ts +1 -2
- package/dist/capabilities/runtime-field-unit.d.ts +1 -0
- package/dist/capabilities/runtime-field-units.d.ts +8 -0
- package/dist/capabilities/switch.cap.d.ts +0 -5
- package/dist/capabilities/temperature-sensor.cap.d.ts +5 -20
- package/dist/capabilities/weather.cap.d.ts +4 -13
- package/dist/client.d.ts +2 -1
- package/dist/client.js +54 -5
- package/dist/client.mjs +52 -6
- package/dist/composition/composition-report.d.ts +8 -3
- package/dist/composition/state-fields.d.ts +1 -1
- package/dist/composition/validate-composition.d.ts +3 -2
- package/dist/device/cap-vocabulary/types.d.ts +2 -2
- package/dist/device/schema-fields.d.ts +3 -0
- package/dist/device/source-info.d.ts +12 -6
- package/dist/generated/addon-cap-facts.d.ts +1 -1
- package/dist/generated/customize-catalog.d.ts +11 -87
- package/dist/generated/history-catalog.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +755 -490
- package/dist/index.mjs +738 -490
- package/dist/{sleep-BErAxhul.mjs → sleep-CARd6wZF.mjs} +161 -128
- package/dist/{sleep-BPQ2ZyaI.js → sleep-gtskVoMw.js} +214 -127
- package/dist/units/convert.d.ts +5 -0
- package/dist/units/format-reading.d.ts +15 -0
- package/dist/units/index.d.ts +8 -1
- package/dist/units/ingest-reading.d.ts +21 -0
- package/dist/units/quantity.d.ts +47 -0
- package/dist/units/threshold.d.ts +6 -0
- package/dist/units/unit-table.d.ts +2 -228
- package/package.json +1 -1
- package/dist/capabilities/advanced-parameters.d.ts +0 -17
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-gtskVoMw.js");
|
|
3
3
|
const require_event_category = require("./event-category-DXZ3f9Q5.js");
|
|
4
4
|
const require_composition = require("./composition-DsmkwP9-.js");
|
|
5
5
|
const require_node_color = require("./node-color.js");
|
|
@@ -12398,6 +12398,17 @@ function unwrapSchema(schema) {
|
|
|
12398
12398
|
while (s instanceof zod.z.ZodNullable || s instanceof zod.z.ZodOptional || s instanceof zod.z.ZodDefault) s = s.unwrap();
|
|
12399
12399
|
return s;
|
|
12400
12400
|
}
|
|
12401
|
+
function isMetaBag(value) {
|
|
12402
|
+
return typeof value === "object" && value !== null;
|
|
12403
|
+
}
|
|
12404
|
+
function metaQuantity(schema) {
|
|
12405
|
+
const bag = zod.z.globalRegistry.get(schema);
|
|
12406
|
+
if (isMetaBag(bag) && require_sleep.isReadingQuantity(bag.quantity)) return bag.quantity;
|
|
12407
|
+
}
|
|
12408
|
+
/** Quantity declared with `readingMeta` on the field or on the unwrapped leaf. */
|
|
12409
|
+
function quantityOfField(schema) {
|
|
12410
|
+
return metaQuantity(schema) ?? metaQuantity(unwrapSchema(schema));
|
|
12411
|
+
}
|
|
12401
12412
|
function leafKind(schema) {
|
|
12402
12413
|
const s = unwrapSchema(schema);
|
|
12403
12414
|
if (s instanceof zod.z.ZodEnum) return {
|
|
@@ -12426,11 +12437,15 @@ function enumerateSchemaFields(schema, prefix = "") {
|
|
|
12426
12437
|
continue;
|
|
12427
12438
|
}
|
|
12428
12439
|
const leaf = leafKind(field);
|
|
12429
|
-
if (leaf)
|
|
12430
|
-
|
|
12431
|
-
|
|
12432
|
-
|
|
12433
|
-
|
|
12440
|
+
if (leaf) {
|
|
12441
|
+
const quantity = quantityOfField(field);
|
|
12442
|
+
out.push({
|
|
12443
|
+
path,
|
|
12444
|
+
kind: leaf.kind,
|
|
12445
|
+
...leaf.enumValues ? { enumValues: leaf.enumValues } : {},
|
|
12446
|
+
...quantity !== void 0 ? { quantity } : {}
|
|
12447
|
+
});
|
|
12448
|
+
}
|
|
12434
12449
|
}
|
|
12435
12450
|
return out;
|
|
12436
12451
|
}
|
|
@@ -12491,7 +12506,7 @@ function requiredTopLevelKeys(schema) {
|
|
|
12491
12506
|
/**
|
|
12492
12507
|
* The proper prefixes of `path` whose schema accepts `undefined`: a required
|
|
12493
12508
|
* leaf under one of them is required only once something writes that parent
|
|
12494
|
-
* (`remaining.
|
|
12509
|
+
* (`remaining.kind` is required only when `remaining` is present).
|
|
12495
12510
|
*/
|
|
12496
12511
|
function optionalAncestors(schema, path) {
|
|
12497
12512
|
const segments = path.split(".");
|
|
@@ -12608,7 +12623,8 @@ var CompositionProblemCodeSchema = zod.z.enum([
|
|
|
12608
12623
|
"item-field-reserved",
|
|
12609
12624
|
"target-missing",
|
|
12610
12625
|
"target-unreadable",
|
|
12611
|
-
"not-replaceable"
|
|
12626
|
+
"not-replaceable",
|
|
12627
|
+
"native-capability-replace"
|
|
12612
12628
|
]);
|
|
12613
12629
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
12614
12630
|
var CompositionProblemSchema = zod.z.object({
|
|
@@ -12674,9 +12690,11 @@ function compositionFieldKey(plan) {
|
|
|
12674
12690
|
return `${plan.cap}.${path}`;
|
|
12675
12691
|
}
|
|
12676
12692
|
/**
|
|
12677
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
12678
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
12679
|
-
*
|
|
12693
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
12694
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
12695
|
+
* Replacing a capability the device already serves is refused
|
|
12696
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
12697
|
+
* wire for a claim the hub already holds.
|
|
12680
12698
|
*/
|
|
12681
12699
|
var CompositionFeatureModeSchema = zod.z.enum([
|
|
12682
12700
|
"new",
|
|
@@ -13510,6 +13528,9 @@ function isNativeCap(target, cap) {
|
|
|
13510
13528
|
const owner = target.nativeCaps.get(cap);
|
|
13511
13529
|
return owner !== void 0 && owner !== "composer";
|
|
13512
13530
|
}
|
|
13531
|
+
function isPlanProblem(value) {
|
|
13532
|
+
return "code" in value;
|
|
13533
|
+
}
|
|
13513
13534
|
/** The target read, or the refusal that replaces the whole plan when it could not be (D391). */
|
|
13514
13535
|
function planTargetOf(composition, target) {
|
|
13515
13536
|
if (composition.target.kind === "new") return {
|
|
@@ -13525,26 +13546,59 @@ function planTargetOf(composition, target) {
|
|
|
13525
13546
|
found: target
|
|
13526
13547
|
};
|
|
13527
13548
|
}
|
|
13528
|
-
|
|
13549
|
+
var NATIVE_REPLACE_KEPT = new Set([
|
|
13550
|
+
"not-composable",
|
|
13551
|
+
"unknown-capability",
|
|
13552
|
+
"reserved-variant"
|
|
13553
|
+
]);
|
|
13554
|
+
/** A native override is refused, unless the cap cannot be composed at all — that reason stays. */
|
|
13555
|
+
function nativeReplaceOrBlock(refusal, probed) {
|
|
13556
|
+
const kept = probed.problems.filter((item) => NATIVE_REPLACE_KEPT.has(item.code));
|
|
13557
|
+
if (kept.length > 0) return {
|
|
13558
|
+
problems: kept,
|
|
13559
|
+
fields: [],
|
|
13560
|
+
features: [],
|
|
13561
|
+
events: []
|
|
13562
|
+
};
|
|
13563
|
+
return refused(refusal);
|
|
13564
|
+
}
|
|
13565
|
+
function featureTargetOf(target, cap, at) {
|
|
13529
13566
|
if (target.kind === "new") return {
|
|
13530
13567
|
mode: "new",
|
|
13531
13568
|
deviceType: target.type
|
|
13532
13569
|
};
|
|
13570
|
+
if (isNativeCap(target.found, cap)) return problem("native-capability-replace", at, `native-capability-replace: stored override replaces native capability \`${cap}\` on device ${target.found.deviceId} — refused (D944)`);
|
|
13533
13571
|
return {
|
|
13534
|
-
mode:
|
|
13572
|
+
mode: "add",
|
|
13535
13573
|
deviceType: target.found.type
|
|
13536
13574
|
};
|
|
13537
13575
|
}
|
|
13538
13576
|
/**
|
|
13539
13577
|
* The static plan. `target` describes an EXISTING target device (one read);
|
|
13540
|
-
* it is ignored for a new one. On an existing target each feature
|
|
13541
|
-
*
|
|
13578
|
+
* it is ignored for a new one. On an existing target each feature ADDS a cap
|
|
13579
|
+
* the device lacks. A feature that would replace a native capability is
|
|
13580
|
+
* refused by name (D944). A new device is unchanged.
|
|
13542
13581
|
*/
|
|
13543
13582
|
function planComposition(composition, lookupCap, target) {
|
|
13544
13583
|
const planTarget = planTargetOf(composition, target);
|
|
13545
13584
|
if ("code" in planTarget) return refused(planTarget);
|
|
13546
13585
|
const results = composition.features.map((feature, index) => {
|
|
13547
|
-
const
|
|
13586
|
+
const at = `features[${index}]`;
|
|
13587
|
+
if (feature.kind === "passthrough") return refused(problem("reserved-variant", at, `whole-capability passthrough of \`${feature.cap}\` arrives in slice 3`));
|
|
13588
|
+
const featureTarget = featureTargetOf(planTarget, feature.cap, at);
|
|
13589
|
+
if (isPlanProblem(featureTarget)) {
|
|
13590
|
+
if (!require_composition.compositionFeatureEnabled(feature) || planTarget.kind !== "existing") return {
|
|
13591
|
+
problems: [],
|
|
13592
|
+
fields: [],
|
|
13593
|
+
features: [],
|
|
13594
|
+
events: []
|
|
13595
|
+
};
|
|
13596
|
+
return nativeReplaceOrBlock(featureTarget, planFeature(feature, index, {
|
|
13597
|
+
mode: "add",
|
|
13598
|
+
deviceType: planTarget.found.type
|
|
13599
|
+
}, lookupCap));
|
|
13600
|
+
}
|
|
13601
|
+
const result = planFeature(feature, index, featureTarget, lookupCap);
|
|
13548
13602
|
return require_composition.compositionFeatureEnabled(feature) ? result : {
|
|
13549
13603
|
problems: result.problems,
|
|
13550
13604
|
fields: [],
|
|
@@ -13685,7 +13739,11 @@ function cycleProblems(composition, ctx, fields, self) {
|
|
|
13685
13739
|
function validateComposition(composition, ctx) {
|
|
13686
13740
|
const plan = planComposition(composition, ctx.lookupCap, ctx.target ?? void 0);
|
|
13687
13741
|
const self = candidateSelf(composition, ctx, plan);
|
|
13688
|
-
const
|
|
13742
|
+
const refusedFeatures = plan.problems.filter((item) => item.code === "native-capability-replace").map((item) => item.path);
|
|
13743
|
+
const cycles = cycleProblems(composition, ctx, plan.fields, self).filter((item) => {
|
|
13744
|
+
if (refusedFeatures.some((at) => item.path === at || item.path.startsWith(`${at}.`))) return false;
|
|
13745
|
+
return refusedFeatures.length === 0 || item.path !== "features";
|
|
13746
|
+
});
|
|
13689
13747
|
const problems = [
|
|
13690
13748
|
...plan.problems,
|
|
13691
13749
|
...sourceProblems(plan.fields, ctx, self),
|
|
@@ -16432,12 +16490,12 @@ function parseAdminBase(baseUrl) {
|
|
|
16432
16490
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
16433
16491
|
* in-place so dispatch keeps working.
|
|
16434
16492
|
*
|
|
16435
|
-
* **
|
|
16436
|
-
*
|
|
16437
|
-
*
|
|
16438
|
-
*
|
|
16439
|
-
* (`ha-domain-mapping`)
|
|
16440
|
-
* stored after that point.
|
|
16493
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
16494
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
16495
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
16496
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
16497
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
16498
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
16441
16499
|
*
|
|
16442
16500
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
16443
16501
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -16451,6 +16509,14 @@ var SourceInfoSchema = zod.z.object({
|
|
|
16451
16509
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
16452
16510
|
* Used to detect rename when `id` changes. */
|
|
16453
16511
|
uniqueId: zod.z.string().optional(),
|
|
16512
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
16513
|
+
quantity: require_sleep.ReadingQuantitySchema.optional(),
|
|
16514
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
16515
|
+
dateTimeShape: zod.z.enum([
|
|
16516
|
+
"date",
|
|
16517
|
+
"time",
|
|
16518
|
+
"datetime"
|
|
16519
|
+
]).optional(),
|
|
16454
16520
|
/** Provider-specific extras that don't fit the structured slots.
|
|
16455
16521
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
16456
16522
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -16535,9 +16601,38 @@ function normalizeUnit(raw) {
|
|
|
16535
16601
|
if (lower === "mph") return "mph";
|
|
16536
16602
|
if (lower === "m/s") return "m/s";
|
|
16537
16603
|
if (lower === "m") return "m";
|
|
16604
|
+
if (lower === "m²" || lower === "m2") return "m²";
|
|
16605
|
+
if (lower === "mm") return "mm";
|
|
16606
|
+
if (lower === "cm") return "cm";
|
|
16538
16607
|
if (lower === "km") return "km";
|
|
16608
|
+
if (lower === "in" || lower === "inch" || lower === "inches") return "in";
|
|
16609
|
+
if (lower === "ft" || lower === "foot" || lower === "feet") return "ft";
|
|
16539
16610
|
if (lower === "kg") return "kg";
|
|
16540
16611
|
if (lower === "g") return "g";
|
|
16612
|
+
if (lower === "l" || lower === "liter" || lower === "litre" || lower === "liters" || lower === "litres") return "L";
|
|
16613
|
+
if (lower === "ml") return "mL";
|
|
16614
|
+
if (lower === "gal" || lower === "gallon" || lower === "gallons") return "gal";
|
|
16615
|
+
if (lower === "s" || lower === "sec" || lower === "second" || lower === "seconds") return "s";
|
|
16616
|
+
if (lower === "ms") return "ms";
|
|
16617
|
+
if (lower === "min" || lower === "minute" || lower === "minutes") return "min";
|
|
16618
|
+
if (lower === "h" || lower === "hr" || lower === "hour" || lower === "hours") return "h";
|
|
16619
|
+
if (lower === "d" || lower === "day" || lower === "days") return "d";
|
|
16620
|
+
if (lower === "b" || lower === "byte" || lower === "bytes") return "B";
|
|
16621
|
+
if (lower === "kib") return "KiB";
|
|
16622
|
+
if (lower === "mib") return "MiB";
|
|
16623
|
+
if (lower === "gib") return "GiB";
|
|
16624
|
+
if (lower === "tib") return "TiB";
|
|
16625
|
+
if (lower === "kb") return "kB";
|
|
16626
|
+
if (lower === "mb") return "MB";
|
|
16627
|
+
if (lower === "gb") return "GB";
|
|
16628
|
+
if (lower === "dbm") return "dBm";
|
|
16629
|
+
if (lower === "dbfs") return "dBFS";
|
|
16630
|
+
if (lower === "inhg") return "inHg";
|
|
16631
|
+
if (lower === "mm/h") return "mm/h";
|
|
16632
|
+
if (lower === "w/m²" || lower === "w/m2") return "W/m²";
|
|
16633
|
+
if (lower === "°" || lower === "deg" || lower === "degree" || lower === "degrees") return "°";
|
|
16634
|
+
if (lower === "kbps") return "kbps";
|
|
16635
|
+
if (lower === "fps") return "fps";
|
|
16541
16636
|
return trimmed;
|
|
16542
16637
|
}
|
|
16543
16638
|
/**
|
|
@@ -37969,7 +38064,8 @@ var deviceManagerCapability = {
|
|
|
37969
38064
|
"enum"
|
|
37970
38065
|
]),
|
|
37971
38066
|
enumValues: zod.z.array(zod.z.string()).optional(),
|
|
37972
|
-
item: zod.z.boolean().optional()
|
|
38067
|
+
item: zod.z.boolean().optional(),
|
|
38068
|
+
quantity: require_sleep.ReadingQuantitySchema.optional()
|
|
37973
38069
|
})).readonly(),
|
|
37974
38070
|
itemArray: zod.z.object({
|
|
37975
38071
|
path: zod.z.string(),
|
|
@@ -44293,8 +44389,8 @@ var MaskPolygonShapeSchema = zod.z.object({
|
|
|
44293
44389
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44294
44390
|
var MaskGridShapeSchema = zod.z.object({
|
|
44295
44391
|
kind: zod.z.literal("grid"),
|
|
44296
|
-
gridWidth: zod.z.number(),
|
|
44297
|
-
gridHeight: zod.z.number(),
|
|
44392
|
+
gridWidth: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
44393
|
+
gridHeight: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
44298
44394
|
cells: zod.z.array(zod.z.boolean())
|
|
44299
44395
|
});
|
|
44300
44396
|
/** Directed line / tripwire — an ordered list of normalized points (≥2). */
|
|
@@ -60558,27 +60654,17 @@ var addonsCapability = {
|
|
|
60558
60654
|
*/
|
|
60559
60655
|
var AirQualitySensorStatusSchema = zod.z.object({
|
|
60560
60656
|
/** Carbon dioxide concentration in ppm. */
|
|
60561
|
-
co2Ppm: zod.z.number().min(0).optional(),
|
|
60657
|
+
co2Ppm: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-volume")),
|
|
60562
60658
|
/** Total volatile organic compounds in ppb. */
|
|
60563
|
-
vocPpb: zod.z.number().min(0).optional(),
|
|
60659
|
+
vocPpb: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-ppb")),
|
|
60564
60660
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
60565
|
-
pm25: zod.z.number().min(0).optional(),
|
|
60661
|
+
pm25: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-mass")),
|
|
60566
60662
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
60567
|
-
pm10: zod.z.number().min(0).optional(),
|
|
60663
|
+
pm10: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-mass")),
|
|
60568
60664
|
/** Composite AQI value (typically 0..500). */
|
|
60569
|
-
aqi: zod.z.number().optional(),
|
|
60665
|
+
aqi: zod.z.number().optional().meta(require_sleep.readingMeta("index")),
|
|
60570
60666
|
/** Ms epoch when the slice was last updated. */
|
|
60571
|
-
lastFetchedAt: zod.z.number()
|
|
60572
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
60573
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
60574
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
60575
|
-
* per slice is unambiguous. */
|
|
60576
|
-
unit: zod.z.string().optional(),
|
|
60577
|
-
/** Suggested decimal places for numeric display.
|
|
60578
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60579
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60580
|
-
* auto-formatting when absent. */
|
|
60581
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
60667
|
+
lastFetchedAt: zod.z.number()
|
|
60582
60668
|
});
|
|
60583
60669
|
var airQualitySensorCapability = {
|
|
60584
60670
|
name: "air-quality-sensor",
|
|
@@ -60615,12 +60701,12 @@ var airQualitySensorCapability = {
|
|
|
60615
60701
|
},
|
|
60616
60702
|
pm25: {
|
|
60617
60703
|
kind: "gauge",
|
|
60618
|
-
unit: "
|
|
60704
|
+
unit: "µg/m³",
|
|
60619
60705
|
deadband: 1
|
|
60620
60706
|
},
|
|
60621
60707
|
pm10: {
|
|
60622
60708
|
kind: "gauge",
|
|
60623
|
-
unit: "
|
|
60709
|
+
unit: "µg/m³",
|
|
60624
60710
|
deadband: 1
|
|
60625
60711
|
},
|
|
60626
60712
|
aqi: {
|
|
@@ -60640,22 +60726,13 @@ var airQualitySensorCapability = {
|
|
|
60640
60726
|
* entries with `device_class: illuminance`.
|
|
60641
60727
|
*/
|
|
60642
60728
|
var AmbientLightSensorStatusSchema = zod.z.object({
|
|
60643
|
-
/** Current illuminance in lux (lx). */
|
|
60644
|
-
lux: zod.z.number().min(0).meta({
|
|
60645
|
-
|
|
60729
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
60730
|
+
lux: zod.z.number().min(0).nullable().meta(require_sleep.readingMeta("illuminance", {
|
|
60731
|
+
precision: 0,
|
|
60646
60732
|
label: "Illuminance"
|
|
60647
|
-
}),
|
|
60733
|
+
})),
|
|
60648
60734
|
/** Ms epoch when the slice was last updated. */
|
|
60649
|
-
lastFetchedAt: zod.z.number()
|
|
60650
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60651
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60652
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60653
|
-
unit: zod.z.string().optional(),
|
|
60654
|
-
/** Suggested decimal places for numeric display.
|
|
60655
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60656
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60657
|
-
* auto-formatting when absent. */
|
|
60658
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
60735
|
+
lastFetchedAt: zod.z.number()
|
|
60659
60736
|
});
|
|
60660
60737
|
var ambientLightSensorCapability = {
|
|
60661
60738
|
name: "ambient-light-sensor",
|
|
@@ -60687,12 +60764,7 @@ var ambientLightSensorCapability = {
|
|
|
60687
60764
|
} } },
|
|
60688
60765
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60689
60766
|
* whether persisting is worth a SQLite commit. */
|
|
60690
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60691
|
-
customize: {
|
|
60692
|
-
version: 1,
|
|
60693
|
-
advanced: "derive",
|
|
60694
|
-
targets: []
|
|
60695
|
-
}
|
|
60767
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60696
60768
|
};
|
|
60697
60769
|
//#endregion
|
|
60698
60770
|
//#region src/capabilities/audio-metrics.cap.ts
|
|
@@ -60934,10 +61006,7 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
60934
61006
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
60935
61007
|
* declines to band a non-finite reading, which is the correct shape.
|
|
60936
61008
|
*/
|
|
60937
|
-
percentage: zod.z.number().min(0).max(100).nullable().meta({
|
|
60938
|
-
unit: "%",
|
|
60939
|
-
label: "Charge"
|
|
60940
|
-
}),
|
|
61009
|
+
percentage: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage", { label: "Charge" })),
|
|
60941
61010
|
/**
|
|
60942
61011
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
60943
61012
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -60964,7 +61033,14 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
60964
61033
|
*/
|
|
60965
61034
|
sleeping: zod.z.boolean().meta({ label: "Sleeping" }),
|
|
60966
61035
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60967
|
-
lastUpdated: zod.z.number(),
|
|
61036
|
+
lastUpdated: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
61037
|
+
/**
|
|
61038
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
61039
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
61040
|
+
* that only report charge. A second reading on this cap, not a second
|
|
61041
|
+
* `numeric-sensor` on the same device.
|
|
61042
|
+
*/
|
|
61043
|
+
volts: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("voltage", { label: "Voltage" })),
|
|
60968
61044
|
/**
|
|
60969
61045
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
60970
61046
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -61016,7 +61092,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
61016
61092
|
/** Generic Customize target for the percentage reading (D936). */
|
|
61017
61093
|
var batteryCustomize = {
|
|
61018
61094
|
version: 1,
|
|
61019
|
-
advanced: "derive",
|
|
61020
61095
|
targets: [{
|
|
61021
61096
|
id: "percentage",
|
|
61022
61097
|
cardinality: "scalar",
|
|
@@ -61025,7 +61100,7 @@ var batteryCustomize = {
|
|
|
61025
61100
|
stateField: "percentage"
|
|
61026
61101
|
},
|
|
61027
61102
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
61028
|
-
apply: "add
|
|
61103
|
+
apply: "add",
|
|
61029
61104
|
path: "percentage",
|
|
61030
61105
|
sources: [{
|
|
61031
61106
|
kind: "field",
|
|
@@ -61146,10 +61221,16 @@ onStatusChanged: { data: zod.z.object({
|
|
|
61146
61221
|
/**
|
|
61147
61222
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
61148
61223
|
*/
|
|
61149
|
-
history: { fields: {
|
|
61150
|
-
|
|
61151
|
-
|
|
61152
|
-
|
|
61224
|
+
history: { fields: {
|
|
61225
|
+
percentage: {
|
|
61226
|
+
kind: "gauge",
|
|
61227
|
+
unit: "%"
|
|
61228
|
+
},
|
|
61229
|
+
volts: {
|
|
61230
|
+
kind: "gauge",
|
|
61231
|
+
unit: "V"
|
|
61232
|
+
}
|
|
61233
|
+
} },
|
|
61153
61234
|
customize: batteryCustomize,
|
|
61154
61235
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61155
61236
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -61198,12 +61279,7 @@ var binaryCapability = {
|
|
|
61198
61279
|
history: { fields: { on: { kind: "boolean" } } },
|
|
61199
61280
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61200
61281
|
* whether persisting is worth a SQLite commit. */
|
|
61201
|
-
volatileStateFields: ["lastChangedAt"]
|
|
61202
|
-
customize: {
|
|
61203
|
-
version: 1,
|
|
61204
|
-
advanced: "derive",
|
|
61205
|
-
targets: []
|
|
61206
|
-
}
|
|
61282
|
+
volatileStateFields: ["lastChangedAt"]
|
|
61207
61283
|
};
|
|
61208
61284
|
//#endregion
|
|
61209
61285
|
//#region src/capabilities/brightness.cap.ts
|
|
@@ -61221,7 +61297,7 @@ var binaryCapability = {
|
|
|
61221
61297
|
*/
|
|
61222
61298
|
var BrightnessStatusSchema = zod.z.object({
|
|
61223
61299
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
61224
|
-
percentage: zod.z.number().min(0).max(100),
|
|
61300
|
+
percentage: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("percentage")),
|
|
61225
61301
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
61226
61302
|
lastChangedAt: zod.z.number()
|
|
61227
61303
|
});
|
|
@@ -61820,21 +61896,21 @@ var ClimateControlStatusSchema = zod.z.object({
|
|
|
61820
61896
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
61821
61897
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
61822
61898
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
61823
|
-
target: zod.z.number().nullable(),
|
|
61899
|
+
target: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61824
61900
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
61825
61901
|
* in `heat_cool` mode. */
|
|
61826
|
-
targetHigh: zod.z.number().nullable(),
|
|
61902
|
+
targetHigh: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61827
61903
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
61828
61904
|
* in `heat_cool` mode. */
|
|
61829
|
-
targetLow: zod.z.number().nullable(),
|
|
61905
|
+
targetLow: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61830
61906
|
/** Target relative humidity (0..100). Null when the device has no
|
|
61831
61907
|
* humidity control. */
|
|
61832
|
-
targetHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
61908
|
+
targetHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
61833
61909
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
61834
61910
|
* the device's internal sensor. */
|
|
61835
|
-
currentTemp: zod.z.number().nullable(),
|
|
61911
|
+
currentTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61836
61912
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
61837
|
-
currentHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
61913
|
+
currentHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
61838
61914
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
61839
61915
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
61840
61916
|
swingVertical: zod.z.boolean().nullable(),
|
|
@@ -61842,11 +61918,11 @@ var ClimateControlStatusSchema = zod.z.object({
|
|
|
61842
61918
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
61843
61919
|
swingHorizontal: zod.z.boolean().nullable(),
|
|
61844
61920
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
61845
|
-
minTemp: zod.z.number().nullable().optional(),
|
|
61921
|
+
minTemp: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("temperature")),
|
|
61846
61922
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
61847
|
-
maxTemp: zod.z.number().nullable().optional(),
|
|
61923
|
+
maxTemp: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("temperature")),
|
|
61848
61924
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
61849
|
-
tempStep: zod.z.number().positive().nullable().optional(),
|
|
61925
|
+
tempStep: zod.z.number().positive().nullable().optional().meta(require_sleep.readingMeta("temperature")),
|
|
61850
61926
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
61851
61927
|
lastFetchedAt: zod.z.number()
|
|
61852
61928
|
});
|
|
@@ -61990,17 +62066,17 @@ var climateControlCapability = {
|
|
|
61990
62066
|
* modes to expose in the picker without a slice fetch.
|
|
61991
62067
|
*/
|
|
61992
62068
|
var RgbTripletSchema = zod.z.object({
|
|
61993
|
-
r: zod.z.number().int().min(0).max(255),
|
|
61994
|
-
g: zod.z.number().int().min(0).max(255),
|
|
61995
|
-
b: zod.z.number().int().min(0).max(255)
|
|
62069
|
+
r: zod.z.number().int().min(0).max(255).meta(require_sleep.readingMeta("none")),
|
|
62070
|
+
g: zod.z.number().int().min(0).max(255).meta(require_sleep.readingMeta("none")),
|
|
62071
|
+
b: zod.z.number().int().min(0).max(255).meta(require_sleep.readingMeta("none"))
|
|
61996
62072
|
});
|
|
61997
62073
|
var HsvTripletSchema = zod.z.object({
|
|
61998
62074
|
/** Hue in degrees, 0..360. */
|
|
61999
|
-
h: zod.z.number().min(0).max(360),
|
|
62075
|
+
h: zod.z.number().min(0).max(360).meta(require_sleep.readingMeta("none")),
|
|
62000
62076
|
/** Saturation as 0..100 inclusive. */
|
|
62001
|
-
s: zod.z.number().min(0).max(100),
|
|
62077
|
+
s: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("none")),
|
|
62002
62078
|
/** Value/brightness as 0..100 inclusive. */
|
|
62003
|
-
v: zod.z.number().min(0).max(100)
|
|
62079
|
+
v: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("none"))
|
|
62004
62080
|
});
|
|
62005
62081
|
var ColorInputSchema = zod.z.discriminatedUnion("mode", [
|
|
62006
62082
|
zod.z.object({
|
|
@@ -62029,7 +62105,7 @@ var ColorStatusSchema = zod.z.object({
|
|
|
62029
62105
|
/** Populated when `mode === 'hsv'`. */
|
|
62030
62106
|
hsv: HsvTripletSchema.optional(),
|
|
62031
62107
|
/** Populated when `mode === 'mired'`. */
|
|
62032
|
-
mireds: zod.z.number().int().optional(),
|
|
62108
|
+
mireds: zod.z.number().int().optional().meta(require_sleep.readingMeta("colour-temperature")),
|
|
62033
62109
|
/** Ms epoch of the last operator-driven change. */
|
|
62034
62110
|
lastChangedAt: zod.z.number()
|
|
62035
62111
|
});
|
|
@@ -62311,18 +62387,12 @@ var FORM_OF_KIND = {
|
|
|
62311
62387
|
function consumableFormOf(item) {
|
|
62312
62388
|
return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
|
|
62313
62389
|
}
|
|
62314
|
-
/**
|
|
62315
|
-
|
|
62316
|
-
|
|
62317
|
-
"days",
|
|
62318
|
-
"hours",
|
|
62319
|
-
"cycles"
|
|
62320
|
-
]);
|
|
62321
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
62322
|
-
* days). `value` null = unknown (D393). */
|
|
62390
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
62391
|
+
var ConsumableRemainingKindSchema = zod.z.enum(["duration", "count"]);
|
|
62392
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
62323
62393
|
var ConsumableRemainingSchema = zod.z.object({
|
|
62324
|
-
value: zod.z.number().min(0).nullable(),
|
|
62325
|
-
|
|
62394
|
+
value: zod.z.number().min(0).nullable().meta(require_sleep.readingMeta("device")),
|
|
62395
|
+
kind: ConsumableRemainingKindSchema
|
|
62326
62396
|
});
|
|
62327
62397
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
62328
62398
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -62335,7 +62405,7 @@ var ConsumableItemSchema = zod.z.object({
|
|
|
62335
62405
|
/** Display name. */
|
|
62336
62406
|
label: zod.z.string().min(1),
|
|
62337
62407
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
62338
|
-
level: zod.z.number().min(0).max(100).nullable(),
|
|
62408
|
+
level: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
62339
62409
|
/** The provider's discrete verdict when known (binary mode). */
|
|
62340
62410
|
status: ConsumableStatusSchema.nullable(),
|
|
62341
62411
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -62417,8 +62487,8 @@ var consumablesCustomize = {
|
|
|
62417
62487
|
transforms: [{ kind: "identity" }]
|
|
62418
62488
|
}],
|
|
62419
62489
|
literals: [{
|
|
62420
|
-
path: "remaining.
|
|
62421
|
-
values: [...
|
|
62490
|
+
path: "remaining.kind",
|
|
62491
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
62422
62492
|
}]
|
|
62423
62493
|
},
|
|
62424
62494
|
{
|
|
@@ -62547,7 +62617,6 @@ reset: require_sleep.method(zod.z.object({
|
|
|
62547
62617
|
},
|
|
62548
62618
|
"remaining.value": {
|
|
62549
62619
|
kind: "gauge",
|
|
62550
|
-
unitFrom: "remaining.unit",
|
|
62551
62620
|
deadband: 1,
|
|
62552
62621
|
displayName: "Remaining"
|
|
62553
62622
|
}
|
|
@@ -62650,49 +62719,26 @@ var ControlKindSchema = zod.z.enum([
|
|
|
62650
62719
|
* (empty array for the other kinds). It lives in the slice because
|
|
62651
62720
|
* HA `select.*` entities may update their options at runtime.
|
|
62652
62721
|
*
|
|
62653
|
-
*
|
|
62654
|
-
*
|
|
62655
|
-
*
|
|
62656
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
62722
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
62723
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
62724
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
62657
62725
|
*/
|
|
62658
62726
|
var ControlStatusSchema = zod.z.object({
|
|
62659
62727
|
kind: ControlKindSchema,
|
|
62660
62728
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
62661
62729
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
62662
62730
|
* or time-only — HA accepts all three forms). */
|
|
62663
|
-
value: zod.z.union([zod.z.number(), zod.z.string()]),
|
|
62731
|
+
value: zod.z.union([zod.z.number().meta(require_sleep.readingMeta("device")), zod.z.string()]),
|
|
62664
62732
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
62665
62733
|
options: zod.z.array(zod.z.string()),
|
|
62666
62734
|
/** Ms epoch when the slice was last updated. */
|
|
62667
62735
|
lastChangedAt: zod.z.number(),
|
|
62668
|
-
/**
|
|
62669
|
-
|
|
62670
|
-
|
|
62671
|
-
|
|
62672
|
-
/**
|
|
62673
|
-
|
|
62674
|
-
min: zod.z.number().optional(),
|
|
62675
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
62676
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
62677
|
-
max: zod.z.number().optional(),
|
|
62678
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
62679
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
62680
|
-
step: zod.z.number().optional(),
|
|
62681
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
62682
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
62683
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
62684
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
62685
|
-
precision: zod.z.number().int().min(0).max(10).optional(),
|
|
62686
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
62687
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
62688
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
62689
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
62690
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
62691
|
-
format: zod.z.enum([
|
|
62692
|
-
"date",
|
|
62693
|
-
"time",
|
|
62694
|
-
"datetime"
|
|
62695
|
-
]).optional()
|
|
62736
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
62737
|
+
min: zod.z.number().optional().meta(require_sleep.readingMeta("device")),
|
|
62738
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
62739
|
+
max: zod.z.number().optional().meta(require_sleep.readingMeta("device")),
|
|
62740
|
+
/** Step increment, in the device quantity's base unit. */
|
|
62741
|
+
step: zod.z.number().optional().meta(require_sleep.readingMeta("device"))
|
|
62696
62742
|
});
|
|
62697
62743
|
var ControlSetValueInputSchema = zod.z.discriminatedUnion("kind", [
|
|
62698
62744
|
zod.z.object({
|
|
@@ -62782,9 +62828,9 @@ var CoverStatusSchema = zod.z.object({
|
|
|
62782
62828
|
state: CoverStateSchema,
|
|
62783
62829
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
62784
62830
|
* no intermediate position surface. */
|
|
62785
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
62831
|
+
position: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
62786
62832
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
62787
|
-
tiltPosition: zod.z.number().min(0).max(100).nullable(),
|
|
62833
|
+
tiltPosition: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
62788
62834
|
/** Ms epoch when the slice was last updated. */
|
|
62789
62835
|
lastChangedAt: zod.z.number()
|
|
62790
62836
|
});
|
|
@@ -62889,9 +62935,9 @@ var NormalizedRangeSchema$1 = zod.z.object({
|
|
|
62889
62935
|
var DayNightStatusSchema = zod.z.object({
|
|
62890
62936
|
mode: DayNightModeSchema,
|
|
62891
62937
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
62892
|
-
sensitivity: zod.z.number().optional(),
|
|
62938
|
+
sensitivity: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
62893
62939
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
62894
|
-
switchDelaySec: zod.z.number().optional(),
|
|
62940
|
+
switchDelaySec: zod.z.number().optional().meta(require_sleep.readingMeta("duration")),
|
|
62895
62941
|
lastFetchedAt: zod.z.number()
|
|
62896
62942
|
});
|
|
62897
62943
|
/**
|
|
@@ -63124,11 +63170,11 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
63124
63170
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
63125
63171
|
availablePrograms: zod.z.array(zod.z.string()),
|
|
63126
63172
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
63127
|
-
remainingSeconds: zod.z.number().int().nonnegative().nullable(),
|
|
63173
|
+
remainingSeconds: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
|
|
63128
63174
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
63129
|
-
delayedStartSeconds: zod.z.number().int().nonnegative().nullable(),
|
|
63175
|
+
delayedStartSeconds: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
|
|
63130
63176
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
63131
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
63177
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
63132
63178
|
/** True when the door is reported open; null when the door state is not known. */
|
|
63133
63179
|
doorOpen: zod.z.boolean().nullable(),
|
|
63134
63180
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -63152,7 +63198,7 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
63152
63198
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
63153
63199
|
machineCareDue: zod.z.boolean().nullable(),
|
|
63154
63200
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
63155
|
-
machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable(),
|
|
63201
|
+
machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("count")),
|
|
63156
63202
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
63157
63203
|
halfLoad: zod.z.boolean().nullable(),
|
|
63158
63204
|
hygienePlus: zod.z.boolean().nullable(),
|
|
@@ -63167,7 +63213,7 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
63167
63213
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
63168
63214
|
activeEvents: zod.z.array(zod.z.string()),
|
|
63169
63215
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
63170
|
-
errorCode: zod.z.number().nullable(),
|
|
63216
|
+
errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
63171
63217
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
63172
63218
|
errorLabel: zod.z.string().nullable(),
|
|
63173
63219
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -63402,7 +63448,7 @@ var DoorbellStatusSchema = zod.z.object({
|
|
|
63402
63448
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
63403
63449
|
lastPressedAt: zod.z.number().nullable(),
|
|
63404
63450
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
63405
|
-
pressCountSinceStart: zod.z.number()
|
|
63451
|
+
pressCountSinceStart: zod.z.number().meta(require_sleep.readingMeta("count"))
|
|
63406
63452
|
});
|
|
63407
63453
|
var DoorbellPressEventSchema = zod.z.object({
|
|
63408
63454
|
deviceId: zod.z.number(),
|
|
@@ -63487,12 +63533,11 @@ var EnumSensorDateTimeFormatSchema = zod.z.enum([
|
|
|
63487
63533
|
var EnumSensorStatusSchema = zod.z.object({
|
|
63488
63534
|
value: zod.z.string(),
|
|
63489
63535
|
/**
|
|
63490
|
-
* Set
|
|
63491
|
-
* as
|
|
63492
|
-
*
|
|
63493
|
-
* a time-only sensor → `'time'`.
|
|
63536
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
63537
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
63538
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
63494
63539
|
*/
|
|
63495
|
-
|
|
63540
|
+
timestamp: zod.z.boolean().optional(),
|
|
63496
63541
|
/** Ms epoch when the slice was last updated. */
|
|
63497
63542
|
lastFetchedAt: zod.z.number()
|
|
63498
63543
|
});
|
|
@@ -63519,11 +63564,11 @@ var enumSensorCapability = {
|
|
|
63519
63564
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
63520
63565
|
* operation state, an HVAC action). The option set is per device, so the
|
|
63521
63566
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
63522
|
-
* `
|
|
63567
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
63523
63568
|
*/
|
|
63524
63569
|
history: { fields: { value: {
|
|
63525
63570
|
kind: "enum",
|
|
63526
|
-
skipWhenSet: "
|
|
63571
|
+
skipWhenSet: "timestamp"
|
|
63527
63572
|
} } },
|
|
63528
63573
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63529
63574
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -63545,13 +63590,13 @@ var EventFireSchema = zod.z.object({
|
|
|
63545
63590
|
deviceId: zod.z.number(),
|
|
63546
63591
|
eventType: zod.z.string(),
|
|
63547
63592
|
data: zod.z.record(zod.z.string(), zod.z.unknown()).nullable(),
|
|
63548
|
-
timestamp: zod.z.number(),
|
|
63549
|
-
seq: zod.z.number()
|
|
63593
|
+
timestamp: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
63594
|
+
seq: zod.z.number().meta(require_sleep.readingMeta("count"))
|
|
63550
63595
|
});
|
|
63551
63596
|
var EventEmitterStatusSchema = zod.z.object({
|
|
63552
63597
|
eventTypes: zod.z.array(zod.z.string()),
|
|
63553
63598
|
lastEvent: EventFireSchema.nullable(),
|
|
63554
|
-
eventCountSinceStart: zod.z.number()
|
|
63599
|
+
eventCountSinceStart: zod.z.number().meta(require_sleep.readingMeta("count"))
|
|
63555
63600
|
});
|
|
63556
63601
|
var eventEmitterCapability = {
|
|
63557
63602
|
name: "event-emitter",
|
|
@@ -64008,10 +64053,10 @@ var FanDirectionSchema = zod.z.enum(["forward", "reverse"]);
|
|
|
64008
64053
|
var FanControlStatusSchema = zod.z.object({
|
|
64009
64054
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
64010
64055
|
* speed surface (single-speed fan). */
|
|
64011
|
-
percentage: zod.z.number().min(0).max(100).nullable(),
|
|
64056
|
+
percentage: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
64012
64057
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
64013
64058
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
64014
|
-
percentageStep: zod.z.number().positive().optional(),
|
|
64059
|
+
percentageStep: zod.z.number().positive().optional().meta(require_sleep.readingMeta("percentage")),
|
|
64015
64060
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
64016
64061
|
* — empty string when no preset is active or supported. */
|
|
64017
64062
|
preset: zod.z.string(),
|
|
@@ -64134,7 +64179,7 @@ var FeatureProbeStatusSchema = zod.z.object({
|
|
|
64134
64179
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
64135
64180
|
model: zod.z.string().nullable(),
|
|
64136
64181
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
64137
|
-
channelCount: zod.z.number().nullable(),
|
|
64182
|
+
channelCount: zod.z.number().nullable().meta(require_sleep.readingMeta("count")),
|
|
64138
64183
|
/**
|
|
64139
64184
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
64140
64185
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -64265,7 +64310,7 @@ var gasCapability = {
|
|
|
64265
64310
|
//#region src/capabilities/heating-valve.cap.ts
|
|
64266
64311
|
var HeatingValveStatusSchema = zod.z.object({
|
|
64267
64312
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
64268
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
64313
|
+
position: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
64269
64314
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64270
64315
|
lastFetchedAt: zod.z.number()
|
|
64271
64316
|
});
|
|
@@ -64310,9 +64355,9 @@ var HumidifierStatusSchema = zod.z.object({
|
|
|
64310
64355
|
/** Whether the humidifier is currently on. */
|
|
64311
64356
|
on: zod.z.boolean(),
|
|
64312
64357
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
64313
|
-
currentHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
64358
|
+
currentHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64314
64359
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
64315
|
-
targetHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
64360
|
+
targetHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64316
64361
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
64317
64362
|
* device has no mode surface. */
|
|
64318
64363
|
mode: zod.z.string().nullable(),
|
|
@@ -64322,9 +64367,9 @@ var HumidifierStatusSchema = zod.z.object({
|
|
|
64322
64367
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
64323
64368
|
action: zod.z.string().nullable(),
|
|
64324
64369
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
64325
|
-
minHumidity: zod.z.number().nullable(),
|
|
64370
|
+
minHumidity: zod.z.number().nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64326
64371
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
64327
|
-
maxHumidity: zod.z.number().nullable(),
|
|
64372
|
+
maxHumidity: zod.z.number().nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64328
64373
|
/** Ms epoch when the slice was last updated. */
|
|
64329
64374
|
lastChangedAt: zod.z.number()
|
|
64330
64375
|
});
|
|
@@ -64396,22 +64441,13 @@ var humidifierCapability = {
|
|
|
64396
64441
|
* `sourceInfo`.
|
|
64397
64442
|
*/
|
|
64398
64443
|
var HumiditySensorStatusSchema = zod.z.object({
|
|
64399
|
-
/** Current relative humidity, 0..100. */
|
|
64400
|
-
percent: zod.z.number().min(0).max(100).meta({
|
|
64401
|
-
|
|
64444
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
64445
|
+
percent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity", {
|
|
64446
|
+
precision: 0,
|
|
64402
64447
|
label: "Humidity"
|
|
64403
|
-
}),
|
|
64448
|
+
})),
|
|
64404
64449
|
/** Ms epoch when the slice was last updated. */
|
|
64405
|
-
lastFetchedAt: zod.z.number()
|
|
64406
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64407
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64408
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64409
|
-
unit: zod.z.string().optional(),
|
|
64410
|
-
/** Suggested decimal places for numeric display.
|
|
64411
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64412
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64413
|
-
* auto-formatting when absent. */
|
|
64414
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
64450
|
+
lastFetchedAt: zod.z.number()
|
|
64415
64451
|
});
|
|
64416
64452
|
var humiditySensorCapability = {
|
|
64417
64453
|
name: "humidity-sensor",
|
|
@@ -64442,12 +64478,7 @@ var humiditySensorCapability = {
|
|
|
64442
64478
|
} } },
|
|
64443
64479
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64444
64480
|
* whether persisting is worth a SQLite commit. */
|
|
64445
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64446
|
-
customize: {
|
|
64447
|
-
version: 1,
|
|
64448
|
-
advanced: "derive",
|
|
64449
|
-
targets: []
|
|
64450
|
-
}
|
|
64481
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64451
64482
|
};
|
|
64452
64483
|
//#endregion
|
|
64453
64484
|
//#region src/capabilities/image.cap.ts
|
|
@@ -64470,7 +64501,7 @@ var ImageStatusSchema = zod.z.object({
|
|
|
64470
64501
|
* entity exposes no `entity_picture` (yet). */
|
|
64471
64502
|
url: zod.z.string().nullable(),
|
|
64472
64503
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
64473
|
-
lastUpdated: zod.z.number().nullable()
|
|
64504
|
+
lastUpdated: zod.z.number().nullable().meta(require_sleep.readingMeta("none"))
|
|
64474
64505
|
});
|
|
64475
64506
|
var imageCapability = {
|
|
64476
64507
|
name: "image",
|
|
@@ -64560,19 +64591,19 @@ var NormalizedRangeSchema = zod.z.object({
|
|
|
64560
64591
|
*/
|
|
64561
64592
|
var ImageSettingsStatusSchema = zod.z.object({
|
|
64562
64593
|
/** Normalized 0–100. */
|
|
64563
|
-
brightness: zod.z.number().optional(),
|
|
64594
|
+
brightness: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64564
64595
|
/** Normalized 0–100. */
|
|
64565
|
-
contrast: zod.z.number().optional(),
|
|
64596
|
+
contrast: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64566
64597
|
/** Normalized 0–100. */
|
|
64567
|
-
saturation: zod.z.number().optional(),
|
|
64598
|
+
saturation: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64568
64599
|
/** Normalized 0–100. */
|
|
64569
|
-
sharpness: zod.z.number().optional(),
|
|
64600
|
+
sharpness: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64570
64601
|
mirror: zod.z.boolean().optional(),
|
|
64571
64602
|
flip: zod.z.boolean().optional(),
|
|
64572
64603
|
rotate: ImageRotateSchema.optional(),
|
|
64573
64604
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
64574
64605
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
64575
|
-
warmth: zod.z.number().optional(),
|
|
64606
|
+
warmth: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64576
64607
|
exposureMode: ExposureModeSchema.optional(),
|
|
64577
64608
|
backlightMode: BacklightModeSchema.optional(),
|
|
64578
64609
|
lastFetchedAt: zod.z.number()
|
|
@@ -64873,10 +64904,10 @@ var IntercomAbilitySchema = zod.z.object({
|
|
|
64873
64904
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
64874
64905
|
codecs: zod.z.array(zod.z.string()),
|
|
64875
64906
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
64876
|
-
sampleRate: zod.z.number(),
|
|
64907
|
+
sampleRate: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
64877
64908
|
duplex: zod.z.enum(["half", "full"]),
|
|
64878
64909
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
64879
|
-
maxBacklogMs: zod.z.number()
|
|
64910
|
+
maxBacklogMs: zod.z.number().meta(require_sleep.readingMeta("duration-ms"))
|
|
64880
64911
|
});
|
|
64881
64912
|
var IntercomStatusSchema = zod.z.object({
|
|
64882
64913
|
/** True while a talk session is open. */
|
|
@@ -65105,13 +65136,13 @@ var LawnMowerControlStatusSchema = zod.z.object({
|
|
|
65105
65136
|
activity: LawnMowerActivitySchema,
|
|
65106
65137
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
65107
65138
|
* reading. */
|
|
65108
|
-
batteryLevel: zod.z.number().min(0).max(100).nullable(),
|
|
65139
|
+
batteryLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
65109
65140
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
65110
65141
|
* task is active / progress is unavailable. */
|
|
65111
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
65142
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
65112
65143
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
65113
65144
|
* or null when unknown. */
|
|
65114
|
-
currentCode: zod.z.number().nullable(),
|
|
65145
|
+
currentCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
65115
65146
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
65116
65147
|
currentCodeLabel: zod.z.string().nullable(),
|
|
65117
65148
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -65841,7 +65872,7 @@ var MediaPlayerStatusSchema = zod.z.object({
|
|
|
65841
65872
|
state: MediaPlayerStateSchema,
|
|
65842
65873
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
65843
65874
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
65844
|
-
volumeLevel: zod.z.number().min(0).max(100).nullable(),
|
|
65875
|
+
volumeLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
65845
65876
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
65846
65877
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
65847
65878
|
isMuted: zod.z.boolean().nullable(),
|
|
@@ -65854,10 +65885,10 @@ var MediaPlayerStatusSchema = zod.z.object({
|
|
|
65854
65885
|
currentMedia: MediaInfoSchema.nullable(),
|
|
65855
65886
|
/** Current playback position in ms. Null when not seekable or
|
|
65856
65887
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
65857
|
-
positionMs: zod.z.number().int().nonnegative().nullable(),
|
|
65888
|
+
positionMs: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
|
|
65858
65889
|
/** Total duration of the current media in ms. Null when unknown
|
|
65859
65890
|
* (live stream) or nothing is playing. */
|
|
65860
|
-
durationMs: zod.z.number().int().nonnegative().nullable(),
|
|
65891
|
+
durationMs: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
|
|
65861
65892
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
65862
65893
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
65863
65894
|
shuffle: zod.z.boolean().nullable(),
|
|
@@ -66237,7 +66268,7 @@ var motionCustomize = {
|
|
|
66237
66268
|
eventName: "onMotionChanged"
|
|
66238
66269
|
},
|
|
66239
66270
|
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
66240
|
-
apply: "
|
|
66271
|
+
apply: "add",
|
|
66241
66272
|
applyAuthority: {
|
|
66242
66273
|
kind: "camera-sensors",
|
|
66243
66274
|
timeoutField: "motionCooldownMs"
|
|
@@ -66334,7 +66365,7 @@ var MotionStatusSchema = zod.z.object({
|
|
|
66334
66365
|
* it, every provider seeded it at boot, and every session left it
|
|
66335
66366
|
* `detected: true` after its detach.
|
|
66336
66367
|
*/
|
|
66337
|
-
autoClearAfterMs: zod.z.number().nullable()
|
|
66368
|
+
autoClearAfterMs: zod.z.number().nullable().meta(require_sleep.readingMeta("duration-ms"))
|
|
66338
66369
|
});
|
|
66339
66370
|
/**
|
|
66340
66371
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -66520,7 +66551,7 @@ var MotionZoneRegionSchema = zod.z.object({
|
|
|
66520
66551
|
* the grid region(s). */
|
|
66521
66552
|
var MotionZoneStatusSchema = zod.z.object({
|
|
66522
66553
|
enabled: zod.z.boolean(),
|
|
66523
|
-
sensitivity: zod.z.number(),
|
|
66554
|
+
sensitivity: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
66524
66555
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
66525
66556
|
regions: zod.z.array(MotionZoneRegionSchema),
|
|
66526
66557
|
lastFetchedAt: zod.z.number()
|
|
@@ -67036,7 +67067,7 @@ var NavigationStatusSchema = zod.z.object({
|
|
|
67036
67067
|
following: zod.z.boolean(),
|
|
67037
67068
|
flash: zod.z.boolean(),
|
|
67038
67069
|
lightMode: NavigationLightModeSchema,
|
|
67039
|
-
lightLevel: zod.z.number().min(40).max(100),
|
|
67070
|
+
lightLevel: zod.z.number().min(40).max(100).meta(require_sleep.readingMeta("none")),
|
|
67040
67071
|
/** Ms epoch when the slice was last updated. */
|
|
67041
67072
|
lastChangedAt: zod.z.number()
|
|
67042
67073
|
});
|
|
@@ -67187,13 +67218,13 @@ var NetworkLinkStatusSchema = zod.z.object({
|
|
|
67187
67218
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
67188
67219
|
* SKIP a null rather than coerce it.
|
|
67189
67220
|
*/
|
|
67190
|
-
signalPercent: zod.z.number().min(0).max(100).nullable(),
|
|
67221
|
+
signalPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
67191
67222
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
67192
|
-
rssiDbm: zod.z.number().optional(),
|
|
67223
|
+
rssiDbm: zod.z.number().optional().meta(require_sleep.readingMeta("signal-level")),
|
|
67193
67224
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
67194
67225
|
ssid: zod.z.string().optional(),
|
|
67195
67226
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
67196
|
-
lastUpdated: zod.z.number()
|
|
67227
|
+
lastUpdated: zod.z.number().meta(require_sleep.readingMeta("none"))
|
|
67197
67228
|
});
|
|
67198
67229
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
67199
67230
|
var NETWORK_LINK_UNKNOWN = {
|
|
@@ -67669,7 +67700,7 @@ var NotifierStatusSchema = zod.z.object({
|
|
|
67669
67700
|
lastError: zod.z.string().nullable(),
|
|
67670
67701
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
67671
67702
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
67672
|
-
queueDepth: zod.z.number().int().nonnegative(),
|
|
67703
|
+
queueDepth: zod.z.number().int().nonnegative().meta(require_sleep.readingMeta("count")),
|
|
67673
67704
|
/** Per-feature capability matrix — authoritative source for the
|
|
67674
67705
|
* compose-form field gating. */
|
|
67675
67706
|
supports: NotifierSupportsSchema
|
|
@@ -67763,11 +67794,9 @@ onSent: { data: zod.z.object({
|
|
|
67763
67794
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
67764
67795
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
67765
67796
|
*
|
|
67766
|
-
* The
|
|
67767
|
-
*
|
|
67768
|
-
*
|
|
67769
|
-
* The UI reads them directly from the slice — they are the single source
|
|
67770
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
67797
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
67798
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
67799
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
67771
67800
|
*
|
|
67772
67801
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
67773
67802
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -67776,15 +67805,8 @@ onSent: { data: zod.z.object({
|
|
|
67776
67805
|
* numeric values land here.
|
|
67777
67806
|
*/
|
|
67778
67807
|
var NumericSensorStatusSchema = zod.z.object({
|
|
67779
|
-
|
|
67780
|
-
|
|
67781
|
-
* Populated live from the upstream source on each state push.
|
|
67782
|
-
* Absent for unitless sensors. */
|
|
67783
|
-
unit: zod.z.string().optional(),
|
|
67784
|
-
/** Suggested decimal places for numeric display.
|
|
67785
|
-
* Populated live from the upstream source when provided.
|
|
67786
|
-
* Falls back to auto-formatting when absent. */
|
|
67787
|
-
precision: zod.z.number().int().min(0).max(10).optional(),
|
|
67808
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
67809
|
+
value: zod.z.number().nullable().meta(require_sleep.readingMeta("device")),
|
|
67788
67810
|
/** Ms epoch when the slice was last updated. */
|
|
67789
67811
|
lastFetchedAt: zod.z.number()
|
|
67790
67812
|
});
|
|
@@ -67808,11 +67830,11 @@ var numericSensorCapability = {
|
|
|
67808
67830
|
*/
|
|
67809
67831
|
durability: "restored",
|
|
67810
67832
|
/**
|
|
67811
|
-
* History (D850): recorded series. The unit is
|
|
67833
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
67834
|
+
* resolved when the series is read — the cap has no single unit.
|
|
67812
67835
|
*/
|
|
67813
67836
|
history: { fields: { value: {
|
|
67814
67837
|
kind: "gauge",
|
|
67815
|
-
unitFrom: "unit",
|
|
67816
67838
|
minIntervalMs: 3e4
|
|
67817
67839
|
} } },
|
|
67818
67840
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -68269,23 +68291,26 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
68269
68291
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
68270
68292
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
68271
68293
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
68272
|
-
foodLevel: zod.z.number().nullable(),
|
|
68294
|
+
foodLevel: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68273
68295
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
68274
68296
|
* single-hopper models. */
|
|
68275
|
-
food1: zod.z.number().nullable(),
|
|
68297
|
+
food1: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68276
68298
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
68277
68299
|
* single-hopper models. */
|
|
68278
|
-
food2: zod.z.number().nullable(),
|
|
68300
|
+
food2: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68279
68301
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
68280
68302
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
68281
68303
|
* below the feeder's low threshold. */
|
|
68282
68304
|
lowFood: zod.z.boolean(),
|
|
68283
68305
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
68284
68306
|
* device has no battery reading. */
|
|
68285
|
-
batteryPower: zod.z.number().min(0).max(100).nullable(),
|
|
68286
|
-
/**
|
|
68287
|
-
*
|
|
68288
|
-
|
|
68307
|
+
batteryPower: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
68308
|
+
/**
|
|
68309
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
68310
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
68311
|
+
* model has no desiccant sensor.
|
|
68312
|
+
*/
|
|
68313
|
+
desiccantLeftDays: zod.z.number().nullable().meta(require_sleep.readingMeta("duration")),
|
|
68289
68314
|
/** True while a feed is in progress. */
|
|
68290
68315
|
feeding: zod.z.boolean(),
|
|
68291
68316
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -68296,7 +68321,7 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
68296
68321
|
* with `errorCode` for consumers that want the raw integer. */
|
|
68297
68322
|
error: zod.z.string().nullable(),
|
|
68298
68323
|
/** Raw device error code (0 / null = no error). */
|
|
68299
|
-
errorCode: zod.z.number().nullable(),
|
|
68324
|
+
errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68300
68325
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
68301
68326
|
isDualHopper: zod.z.boolean(),
|
|
68302
68327
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -68306,7 +68331,7 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
68306
68331
|
/** Play a chime when dispensing. */
|
|
68307
68332
|
feedSound: zod.z.boolean(),
|
|
68308
68333
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
68309
|
-
volume: zod.z.number(),
|
|
68334
|
+
volume: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
68310
68335
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
68311
68336
|
lastFetchedAt: zod.z.number()
|
|
68312
68337
|
});
|
|
@@ -68425,7 +68450,7 @@ var petFeederCapability = {
|
|
|
68425
68450
|
},
|
|
68426
68451
|
desiccantLeftDays: {
|
|
68427
68452
|
kind: "gauge",
|
|
68428
|
-
unit: "
|
|
68453
|
+
unit: "s"
|
|
68429
68454
|
}
|
|
68430
68455
|
} }
|
|
68431
68456
|
};
|
|
@@ -69631,36 +69656,19 @@ var platformProbeCapability = {
|
|
|
69631
69656
|
*/
|
|
69632
69657
|
var PowerMeterStatusSchema = zod.z.object({
|
|
69633
69658
|
/** Instantaneous power draw in watts. */
|
|
69634
|
-
watts: zod.z.number().optional().meta({
|
|
69635
|
-
unit: "W",
|
|
69636
|
-
label: "Power"
|
|
69637
|
-
}),
|
|
69659
|
+
watts: zod.z.number().optional().meta(require_sleep.readingMeta("power", { label: "Power" })),
|
|
69638
69660
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
69639
|
-
kwhTotal: zod.z.number().optional().meta({
|
|
69640
|
-
unit: "kWh",
|
|
69641
|
-
label: "Energy"
|
|
69642
|
-
}),
|
|
69661
|
+
kwhTotal: zod.z.number().optional().meta(require_sleep.readingMeta("energy", { label: "Energy" })),
|
|
69643
69662
|
/** Voltage in volts. */
|
|
69644
|
-
volts: zod.z.number().optional(),
|
|
69663
|
+
volts: zod.z.number().optional().meta(require_sleep.readingMeta("voltage")),
|
|
69645
69664
|
/** Current in amperes. */
|
|
69646
|
-
amps: zod.z.number().optional(),
|
|
69647
|
-
/** Apparent power in volt-amperes
|
|
69648
|
-
va: zod.z.number().optional(),
|
|
69665
|
+
amps: zod.z.number().optional().meta(require_sleep.readingMeta("current")),
|
|
69666
|
+
/** Apparent power in volt-amperes. */
|
|
69667
|
+
va: zod.z.number().optional().meta(require_sleep.readingMeta("apparent-power")),
|
|
69649
69668
|
/** Power factor (0..1) if reported. */
|
|
69650
|
-
powerFactor: zod.z.number().min(0).max(1).optional(),
|
|
69669
|
+
powerFactor: zod.z.number().min(0).max(1).optional().meta(require_sleep.readingMeta("ratio")),
|
|
69651
69670
|
/** Ms epoch when the slice was last updated. */
|
|
69652
|
-
lastFetchedAt: zod.z.number()
|
|
69653
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
69654
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
69655
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
69656
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
69657
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
69658
|
-
unit: zod.z.string().optional(),
|
|
69659
|
-
/** Suggested decimal places for numeric display.
|
|
69660
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
69661
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
69662
|
-
* auto-formatting when absent. */
|
|
69663
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
69671
|
+
lastFetchedAt: zod.z.number()
|
|
69664
69672
|
});
|
|
69665
69673
|
var powerMeterCapability = {
|
|
69666
69674
|
name: "power-meter",
|
|
@@ -69724,12 +69732,7 @@ var powerMeterCapability = {
|
|
|
69724
69732
|
} },
|
|
69725
69733
|
/** Clock fields: written, but excluded from the compare that decides
|
|
69726
69734
|
* whether persisting is worth a SQLite commit. */
|
|
69727
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
69728
|
-
customize: {
|
|
69729
|
-
version: 1,
|
|
69730
|
-
advanced: "derive",
|
|
69731
|
-
targets: []
|
|
69732
|
-
}
|
|
69735
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
69733
69736
|
};
|
|
69734
69737
|
//#endregion
|
|
69735
69738
|
//#region src/capabilities/presence.cap.ts
|
|
@@ -69751,11 +69754,11 @@ var powerMeterCapability = {
|
|
|
69751
69754
|
*/
|
|
69752
69755
|
var GpsLocationSchema = zod.z.object({
|
|
69753
69756
|
/** Latitude in decimal degrees, -90..90. */
|
|
69754
|
-
latitude: zod.z.number().min(-90).max(90),
|
|
69757
|
+
latitude: zod.z.number().min(-90).max(90).meta(require_sleep.readingMeta("angle")),
|
|
69755
69758
|
/** Longitude in decimal degrees, -180..180. */
|
|
69756
|
-
longitude: zod.z.number().min(-180).max(180),
|
|
69759
|
+
longitude: zod.z.number().min(-180).max(180).meta(require_sleep.readingMeta("angle")),
|
|
69757
69760
|
/** Reported accuracy in meters (lower = better). */
|
|
69758
|
-
accuracyMeters: zod.z.number().nonnegative()
|
|
69761
|
+
accuracyMeters: zod.z.number().nonnegative().meta(require_sleep.readingMeta("length"))
|
|
69759
69762
|
});
|
|
69760
69763
|
var PresenceStatusSchema = zod.z.object({
|
|
69761
69764
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -69767,7 +69770,7 @@ var PresenceStatusSchema = zod.z.object({
|
|
|
69767
69770
|
gps: GpsLocationSchema.nullable(),
|
|
69768
69771
|
/** Optional battery level of the tracking device (0..100). Null
|
|
69769
69772
|
* when not reported. */
|
|
69770
|
-
batteryPercent: zod.z.number().min(0).max(100).nullable(),
|
|
69773
|
+
batteryPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
69771
69774
|
/** Ms epoch when the slice was last updated. */
|
|
69772
69775
|
lastChangedAt: zod.z.number()
|
|
69773
69776
|
});
|
|
@@ -69819,19 +69822,10 @@ var presenceCapability = {
|
|
|
69819
69822
|
* `sourceInfo`.
|
|
69820
69823
|
*/
|
|
69821
69824
|
var PressureSensorStatusSchema = zod.z.object({
|
|
69822
|
-
/** Current pressure in hPa. */
|
|
69823
|
-
hpa: zod.z.number(),
|
|
69825
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
69826
|
+
hpa: zod.z.number().nullable().meta(require_sleep.readingMeta("pressure", { precision: 0 })),
|
|
69824
69827
|
/** Ms epoch when the slice was last updated. */
|
|
69825
|
-
lastFetchedAt: zod.z.number()
|
|
69826
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
69827
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
69828
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
69829
|
-
unit: zod.z.string().optional(),
|
|
69830
|
-
/** Suggested decimal places for numeric display.
|
|
69831
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
69832
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
69833
|
-
* auto-formatting when absent. */
|
|
69834
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
69828
|
+
lastFetchedAt: zod.z.number()
|
|
69835
69829
|
});
|
|
69836
69830
|
var pressureSensorCapability = {
|
|
69837
69831
|
name: "pressure-sensor",
|
|
@@ -70398,8 +70392,8 @@ var ptzCapability = {
|
|
|
70398
70392
|
var AutotrackTargetTypeSchema = zod.z.string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
70399
70393
|
var PtzAutotrackSettingsSchema = zod.z.object({
|
|
70400
70394
|
targetType: AutotrackTargetTypeSchema,
|
|
70401
|
-
stopDelaySeconds: zod.z.number().int().min(0).max(300),
|
|
70402
|
-
disappearDelaySeconds: zod.z.number().int().min(0).max(300)
|
|
70395
|
+
stopDelaySeconds: zod.z.number().int().min(0).max(300).meta(require_sleep.readingMeta("duration")),
|
|
70396
|
+
disappearDelaySeconds: zod.z.number().int().min(0).max(300).meta(require_sleep.readingMeta("duration"))
|
|
70403
70397
|
});
|
|
70404
70398
|
/**
|
|
70405
70399
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -70566,7 +70560,7 @@ var RunningStateStatusSchema = zod.z.object({
|
|
|
70566
70560
|
/** null = unknown — never coerced to false (D393). */
|
|
70567
70561
|
running: zod.z.boolean().nullable(),
|
|
70568
70562
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
70569
|
-
since: zod.z.number().nullable(),
|
|
70563
|
+
since: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
70570
70564
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
70571
70565
|
phase: zod.z.string().nullable(),
|
|
70572
70566
|
/** null until a reading has been published (D393). */
|
|
@@ -70581,7 +70575,6 @@ var RUNNING_DEVICE_TYPES = Object.values(require_err_msg.DeviceType);
|
|
|
70581
70575
|
/** Generic Customize target for the running boolean (D936). */
|
|
70582
70576
|
var runningCustomize = {
|
|
70583
70577
|
version: 1,
|
|
70584
|
-
advanced: "derive",
|
|
70585
70578
|
targets: [{
|
|
70586
70579
|
id: "running",
|
|
70587
70580
|
cardinality: "scalar",
|
|
@@ -70601,7 +70594,7 @@ var runningCustomize = {
|
|
|
70601
70594
|
require_err_msg.DeviceType.Thermostat,
|
|
70602
70595
|
require_err_msg.DeviceType.PetFeeder
|
|
70603
70596
|
],
|
|
70604
|
-
apply: "add
|
|
70597
|
+
apply: "add",
|
|
70605
70598
|
path: "running",
|
|
70606
70599
|
sources: [
|
|
70607
70600
|
{
|
|
@@ -72449,9 +72442,9 @@ var RecordTriggerSchema = zod.z.enum([
|
|
|
72449
72442
|
*/
|
|
72450
72443
|
var RecordWindowSchema = zod.z.object({
|
|
72451
72444
|
trigger: RecordTriggerSchema,
|
|
72452
|
-
day: zod.z.number().int().min(0).max(6),
|
|
72453
|
-
startMinute: zod.z.number().int().min(0).max(1439),
|
|
72454
|
-
endMinute: zod.z.number().int().min(1).max(1440)
|
|
72445
|
+
day: zod.z.number().int().min(0).max(6).meta(require_sleep.readingMeta("none")),
|
|
72446
|
+
startMinute: zod.z.number().int().min(0).max(1439).meta(require_sleep.readingMeta("none")),
|
|
72447
|
+
endMinute: zod.z.number().int().min(1).max(1440).meta(require_sleep.readingMeta("none"))
|
|
72455
72448
|
});
|
|
72456
72449
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
72457
72450
|
var OnboardStorageVolumeSchema = zod.z.object({
|
|
@@ -72550,10 +72543,10 @@ var RecordingOnboardStatusSchema = zod.z.object({
|
|
|
72550
72543
|
/** Master "record to the card at all" switch. */
|
|
72551
72544
|
enabled: zod.z.boolean().nullable(),
|
|
72552
72545
|
overwriteWhenFull: zod.z.boolean().nullable(),
|
|
72553
|
-
preRecordSec: zod.z.number().nullable(),
|
|
72554
|
-
postRecordSec: zod.z.number().nullable(),
|
|
72546
|
+
preRecordSec: zod.z.number().nullable().meta(require_sleep.readingMeta("duration")),
|
|
72547
|
+
postRecordSec: zod.z.number().nullable().meta(require_sleep.readingMeta("duration")),
|
|
72555
72548
|
/** Length of one recorded file, in minutes. */
|
|
72556
|
-
segmentMinutes: zod.z.number().nullable(),
|
|
72549
|
+
segmentMinutes: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
72557
72550
|
/** The primary track's weekly windows, flattened. */
|
|
72558
72551
|
windows: zod.z.array(RecordWindowSchema),
|
|
72559
72552
|
/**
|
|
@@ -72569,7 +72562,7 @@ var RecordingOnboardStatusSchema = zod.z.object({
|
|
|
72569
72562
|
* provider reporting a non-zero count also reports the schedule as not
|
|
72570
72563
|
* writable.
|
|
72571
72564
|
*/
|
|
72572
|
-
unreadableWindows: zod.z.number(),
|
|
72565
|
+
unreadableWindows: zod.z.number().meta(require_sleep.readingMeta("count")),
|
|
72573
72566
|
/**
|
|
72574
72567
|
* The camera is scheduled to record and has NO usable storage.
|
|
72575
72568
|
*
|
|
@@ -73741,7 +73734,7 @@ var CamStreamDescriptorSchema = zod.z.object({
|
|
|
73741
73734
|
url: zod.z.string().optional(),
|
|
73742
73735
|
codec: zod.z.string().optional(),
|
|
73743
73736
|
resolution: require_sleep.CamStreamResolutionSchema.optional(),
|
|
73744
|
-
fps: zod.z.number().positive().optional(),
|
|
73737
|
+
fps: zod.z.number().positive().optional().meta(require_sleep.readingMeta("rate")),
|
|
73745
73738
|
label: zod.z.string().optional(),
|
|
73746
73739
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
73747
73740
|
deviceFeatures: zod.z.array(zod.z.string()).optional(),
|
|
@@ -73830,18 +73823,18 @@ var StreamProfileSchema = zod.z.enum([
|
|
|
73830
73823
|
]);
|
|
73831
73824
|
/** The current encoding config of one stream profile. */
|
|
73832
73825
|
var StreamProfileConfigSchema = zod.z.object({
|
|
73833
|
-
width: zod.z.number(),
|
|
73834
|
-
height: zod.z.number(),
|
|
73826
|
+
width: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
73827
|
+
height: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
73835
73828
|
codec: zod.z.enum(["h264", "h265"]),
|
|
73836
|
-
framerate: zod.z.number(),
|
|
73837
|
-
bitrate: zod.z.number(),
|
|
73829
|
+
framerate: zod.z.number().meta(require_sleep.readingMeta("rate")),
|
|
73830
|
+
bitrate: zod.z.number().meta(require_sleep.readingMeta("bitrate")),
|
|
73838
73831
|
bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
|
|
73839
73832
|
encoderProfile: zod.z.enum([
|
|
73840
73833
|
"high",
|
|
73841
73834
|
"main",
|
|
73842
73835
|
"baseline"
|
|
73843
73836
|
]).optional(),
|
|
73844
|
-
gop: zod.z.number().optional(),
|
|
73837
|
+
gop: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
73845
73838
|
/**
|
|
73846
73839
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
73847
73840
|
*
|
|
@@ -74323,12 +74316,7 @@ var switchCapability = {
|
|
|
74323
74316
|
label: "On",
|
|
74324
74317
|
kind: "boolean"
|
|
74325
74318
|
}
|
|
74326
|
-
}] }
|
|
74327
|
-
customize: {
|
|
74328
|
-
version: 1,
|
|
74329
|
-
advanced: "derive",
|
|
74330
|
-
targets: []
|
|
74331
|
-
}
|
|
74319
|
+
}] }
|
|
74332
74320
|
};
|
|
74333
74321
|
//#endregion
|
|
74334
74322
|
//#region src/system/server-name.ts
|
|
@@ -75076,35 +75064,21 @@ var tamperCapability = {
|
|
|
75076
75064
|
* entries with `device_class: temperature` and any future native
|
|
75077
75065
|
* thermometer.
|
|
75078
75066
|
*
|
|
75079
|
-
*
|
|
75080
|
-
*
|
|
75081
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
75082
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
75083
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
75084
|
-
* `sourceInfo`.
|
|
75067
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
75068
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
75085
75069
|
*
|
|
75086
75070
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
75087
75071
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
75088
75072
|
* changed" steady state.
|
|
75089
75073
|
*/
|
|
75090
75074
|
var TemperatureSensorStatusSchema = zod.z.object({
|
|
75091
|
-
/** Current temperature in Celsius. */
|
|
75092
|
-
celsius: zod.z.number().meta({
|
|
75093
|
-
|
|
75075
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
75076
|
+
celsius: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature", {
|
|
75077
|
+
precision: 1,
|
|
75094
75078
|
label: "Temperature"
|
|
75095
|
-
}),
|
|
75079
|
+
})),
|
|
75096
75080
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
75097
|
-
lastFetchedAt: zod.z.number()
|
|
75098
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
75099
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
75100
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
75101
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
75102
|
-
unit: zod.z.string().optional(),
|
|
75103
|
-
/** Suggested decimal places for numeric display.
|
|
75104
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
75105
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
75106
|
-
* auto-formatting when absent. */
|
|
75107
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
75081
|
+
lastFetchedAt: zod.z.number()
|
|
75108
75082
|
});
|
|
75109
75083
|
var temperatureSensorCapability = {
|
|
75110
75084
|
name: "temperature-sensor",
|
|
@@ -75135,12 +75109,7 @@ var temperatureSensorCapability = {
|
|
|
75135
75109
|
} } },
|
|
75136
75110
|
/** Clock fields: written, but excluded from the compare that decides
|
|
75137
75111
|
* whether persisting is worth a SQLite commit. */
|
|
75138
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
75139
|
-
customize: {
|
|
75140
|
-
version: 1,
|
|
75141
|
-
advanced: "derive",
|
|
75142
|
-
targets: []
|
|
75143
|
-
}
|
|
75112
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
75144
75113
|
};
|
|
75145
75114
|
//#endregion
|
|
75146
75115
|
//#region src/capabilities/toast.cap.ts
|
|
@@ -75494,16 +75463,16 @@ var VacuumControlStatusSchema = zod.z.object({
|
|
|
75494
75463
|
state: VacuumStateSchema,
|
|
75495
75464
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
75496
75465
|
* reading. */
|
|
75497
|
-
batteryLevel: zod.z.number().min(0).max(100).nullable(),
|
|
75466
|
+
batteryLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
75498
75467
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
75499
75468
|
* the vacuum has no speed control. */
|
|
75500
75469
|
fanSpeed: zod.z.string().nullable(),
|
|
75501
75470
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
75502
75471
|
availableFanSpeeds: zod.z.array(zod.z.string()),
|
|
75503
75472
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
75504
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
75473
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
75505
75474
|
/** Current error code (0 / null = no error). */
|
|
75506
|
-
errorCode: zod.z.number().nullable(),
|
|
75475
|
+
errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
75507
75476
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
75508
75477
|
errorLabel: zod.z.string().nullable(),
|
|
75509
75478
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -75601,7 +75570,7 @@ var ValveStatusSchema = zod.z.object({
|
|
|
75601
75570
|
state: ValveStateSchema,
|
|
75602
75571
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
75603
75572
|
* intermediate position surface. */
|
|
75604
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
75573
|
+
position: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
75605
75574
|
/** Ms epoch when the slice was last updated. */
|
|
75606
75575
|
lastChangedAt: zod.z.number()
|
|
75607
75576
|
});
|
|
@@ -75713,9 +75682,9 @@ var vibrationCapability = {
|
|
|
75713
75682
|
*/
|
|
75714
75683
|
var WaterHeaterStatusSchema = zod.z.object({
|
|
75715
75684
|
/** Current measured temperature. Null when not reported. */
|
|
75716
|
-
currentTemp: zod.z.number().nullable(),
|
|
75685
|
+
currentTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75717
75686
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
75718
|
-
targetTemp: zod.z.number().nullable(),
|
|
75687
|
+
targetTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75719
75688
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
75720
75689
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
75721
75690
|
* device reports an unknown state. */
|
|
@@ -75726,9 +75695,9 @@ var WaterHeaterStatusSchema = zod.z.object({
|
|
|
75726
75695
|
* has no away surface. */
|
|
75727
75696
|
away: zod.z.boolean().nullable(),
|
|
75728
75697
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
75729
|
-
minTemp: zod.z.number().nullable(),
|
|
75698
|
+
minTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75730
75699
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
75731
|
-
maxTemp: zod.z.number().nullable(),
|
|
75700
|
+
maxTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75732
75701
|
/** Ms epoch when the slice was last updated. */
|
|
75733
75702
|
lastChangedAt: zod.z.number()
|
|
75734
75703
|
});
|
|
@@ -75815,25 +75784,18 @@ var waterHeaterCapability = {
|
|
|
75815
75784
|
* Forecast deferred — current conditions only for v1.
|
|
75816
75785
|
*/
|
|
75817
75786
|
var WeatherStatusSchema = zod.z.object({
|
|
75818
|
-
/** Verbatim
|
|
75819
|
-
* when no condition has been reported yet. */
|
|
75787
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
75820
75788
|
condition: zod.z.string().nullable(),
|
|
75821
|
-
/** Current temperature in
|
|
75822
|
-
temperature: zod.z.number().nullable(),
|
|
75823
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
75824
|
-
temperatureUnit: zod.z.string().nullable(),
|
|
75789
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
75790
|
+
temperature: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature", { precision: 1 })),
|
|
75825
75791
|
/** Relative humidity (0..100). Null when not provided. */
|
|
75826
|
-
humidity: zod.z.number().min(0).max(100).nullable(),
|
|
75827
|
-
/** Barometric pressure in
|
|
75828
|
-
pressure: zod.z.number().nullable(),
|
|
75829
|
-
/**
|
|
75830
|
-
|
|
75831
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
75832
|
-
windSpeed: zod.z.number().nullable(),
|
|
75833
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
75834
|
-
windSpeedUnit: zod.z.string().nullable(),
|
|
75792
|
+
humidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
75793
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
75794
|
+
pressure: zod.z.number().nullable().meta(require_sleep.readingMeta("pressure")),
|
|
75795
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
75796
|
+
windSpeed: zod.z.number().nullable().meta(require_sleep.readingMeta("speed")),
|
|
75835
75797
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
75836
|
-
windBearing: zod.z.number().nullable(),
|
|
75798
|
+
windBearing: zod.z.number().nullable().meta(require_sleep.readingMeta("angle")),
|
|
75837
75799
|
/** Ms epoch when the slice was last updated. */
|
|
75838
75800
|
lastFetchedAt: zod.z.number()
|
|
75839
75801
|
});
|
|
@@ -75861,12 +75823,12 @@ var weatherCapability = {
|
|
|
75861
75823
|
*/
|
|
75862
75824
|
durability: "session",
|
|
75863
75825
|
/**
|
|
75864
|
-
* History (D850): recorded series.
|
|
75826
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
75865
75827
|
*/
|
|
75866
75828
|
history: { fields: {
|
|
75867
75829
|
temperature: {
|
|
75868
75830
|
kind: "gauge",
|
|
75869
|
-
|
|
75831
|
+
unit: "°C",
|
|
75870
75832
|
deadband: .2
|
|
75871
75833
|
},
|
|
75872
75834
|
humidity: {
|
|
@@ -75876,12 +75838,12 @@ var weatherCapability = {
|
|
|
75876
75838
|
},
|
|
75877
75839
|
pressure: {
|
|
75878
75840
|
kind: "gauge",
|
|
75879
|
-
|
|
75841
|
+
unit: "hPa",
|
|
75880
75842
|
deadband: .5
|
|
75881
75843
|
},
|
|
75882
75844
|
windSpeed: {
|
|
75883
75845
|
kind: "gauge",
|
|
75884
|
-
|
|
75846
|
+
unit: "m/s",
|
|
75885
75847
|
deadband: .5
|
|
75886
75848
|
}
|
|
75887
75849
|
} }
|
|
@@ -77320,6 +77282,11 @@ var UNIT_TABLE = {
|
|
|
77320
77282
|
factor: 1609.344,
|
|
77321
77283
|
offset: 0
|
|
77322
77284
|
},
|
|
77285
|
+
"m²": {
|
|
77286
|
+
dimension: "area",
|
|
77287
|
+
factor: 1,
|
|
77288
|
+
offset: 0
|
|
77289
|
+
},
|
|
77323
77290
|
lx: {
|
|
77324
77291
|
dimension: "illuminance",
|
|
77325
77292
|
factor: 1,
|
|
@@ -77424,6 +77391,121 @@ var UNIT_TABLE = {
|
|
|
77424
77391
|
dimension: "percentage",
|
|
77425
77392
|
factor: 1,
|
|
77426
77393
|
offset: 0
|
|
77394
|
+
},
|
|
77395
|
+
L: {
|
|
77396
|
+
dimension: "volume",
|
|
77397
|
+
factor: 1,
|
|
77398
|
+
offset: 0
|
|
77399
|
+
},
|
|
77400
|
+
mL: {
|
|
77401
|
+
dimension: "volume",
|
|
77402
|
+
factor: .001,
|
|
77403
|
+
offset: 0
|
|
77404
|
+
},
|
|
77405
|
+
gal: {
|
|
77406
|
+
dimension: "volume",
|
|
77407
|
+
factor: 3.785411784,
|
|
77408
|
+
offset: 0
|
|
77409
|
+
},
|
|
77410
|
+
s: {
|
|
77411
|
+
dimension: "duration",
|
|
77412
|
+
factor: 1,
|
|
77413
|
+
offset: 0
|
|
77414
|
+
},
|
|
77415
|
+
ms: {
|
|
77416
|
+
dimension: "duration",
|
|
77417
|
+
factor: .001,
|
|
77418
|
+
offset: 0
|
|
77419
|
+
},
|
|
77420
|
+
min: {
|
|
77421
|
+
dimension: "duration",
|
|
77422
|
+
factor: 60,
|
|
77423
|
+
offset: 0
|
|
77424
|
+
},
|
|
77425
|
+
h: {
|
|
77426
|
+
dimension: "duration",
|
|
77427
|
+
factor: 3600,
|
|
77428
|
+
offset: 0
|
|
77429
|
+
},
|
|
77430
|
+
d: {
|
|
77431
|
+
dimension: "duration",
|
|
77432
|
+
factor: 86400,
|
|
77433
|
+
offset: 0
|
|
77434
|
+
},
|
|
77435
|
+
B: {
|
|
77436
|
+
dimension: "information",
|
|
77437
|
+
factor: 1,
|
|
77438
|
+
offset: 0
|
|
77439
|
+
},
|
|
77440
|
+
KiB: {
|
|
77441
|
+
dimension: "information",
|
|
77442
|
+
factor: 1024,
|
|
77443
|
+
offset: 0
|
|
77444
|
+
},
|
|
77445
|
+
MiB: {
|
|
77446
|
+
dimension: "information",
|
|
77447
|
+
factor: 1024 ** 2,
|
|
77448
|
+
offset: 0
|
|
77449
|
+
},
|
|
77450
|
+
GiB: {
|
|
77451
|
+
dimension: "information",
|
|
77452
|
+
factor: 1024 ** 3,
|
|
77453
|
+
offset: 0
|
|
77454
|
+
},
|
|
77455
|
+
TiB: {
|
|
77456
|
+
dimension: "information",
|
|
77457
|
+
factor: 1024 ** 4,
|
|
77458
|
+
offset: 0
|
|
77459
|
+
},
|
|
77460
|
+
kB: {
|
|
77461
|
+
dimension: "information",
|
|
77462
|
+
factor: 1e3,
|
|
77463
|
+
offset: 0
|
|
77464
|
+
},
|
|
77465
|
+
MB: {
|
|
77466
|
+
dimension: "information",
|
|
77467
|
+
factor: 1e6,
|
|
77468
|
+
offset: 0
|
|
77469
|
+
},
|
|
77470
|
+
GB: {
|
|
77471
|
+
dimension: "information",
|
|
77472
|
+
factor: 1e9,
|
|
77473
|
+
offset: 0
|
|
77474
|
+
},
|
|
77475
|
+
"°": {
|
|
77476
|
+
dimension: "angle",
|
|
77477
|
+
factor: 1,
|
|
77478
|
+
offset: 0
|
|
77479
|
+
},
|
|
77480
|
+
dBFS: {
|
|
77481
|
+
dimension: "sound-level",
|
|
77482
|
+
factor: 1,
|
|
77483
|
+
offset: 0
|
|
77484
|
+
},
|
|
77485
|
+
dBm: {
|
|
77486
|
+
dimension: "signal-level",
|
|
77487
|
+
factor: 1,
|
|
77488
|
+
offset: 0
|
|
77489
|
+
},
|
|
77490
|
+
mired: {
|
|
77491
|
+
dimension: "colour-temperature",
|
|
77492
|
+
factor: 1,
|
|
77493
|
+
offset: 0
|
|
77494
|
+
},
|
|
77495
|
+
kbps: {
|
|
77496
|
+
dimension: "bitrate",
|
|
77497
|
+
factor: 1,
|
|
77498
|
+
offset: 0
|
|
77499
|
+
},
|
|
77500
|
+
Mbps: {
|
|
77501
|
+
dimension: "bitrate",
|
|
77502
|
+
factor: 1e3,
|
|
77503
|
+
offset: 0
|
|
77504
|
+
},
|
|
77505
|
+
fps: {
|
|
77506
|
+
dimension: "rate",
|
|
77507
|
+
factor: 1,
|
|
77508
|
+
offset: 0
|
|
77427
77509
|
}
|
|
77428
77510
|
};
|
|
77429
77511
|
//#endregion
|
|
@@ -77514,6 +77596,17 @@ function canConvertUnit(from, to) {
|
|
|
77514
77596
|
* Every known unit spelling in a dimension (table insertion order — canonical
|
|
77515
77597
|
* unit first). Powers the UI's same-dimension unit picker.
|
|
77516
77598
|
*/
|
|
77599
|
+
/**
|
|
77600
|
+
* Convert a difference, not a reading. Affine units (°F) shift an absolute
|
|
77601
|
+
* value by their offset; a step of 1°F is 5/9°C, so the offset is cancelled.
|
|
77602
|
+
*/
|
|
77603
|
+
function tryConvertDelta(value, from, to) {
|
|
77604
|
+
if (from === to) return value;
|
|
77605
|
+
const origin = tryConvertUnit(0, from, to);
|
|
77606
|
+
const shifted = tryConvertUnit(value, from, to);
|
|
77607
|
+
if (origin === void 0 || shifted === void 0) return void 0;
|
|
77608
|
+
return shifted - origin;
|
|
77609
|
+
}
|
|
77517
77610
|
function unitsForDimension(dimension) {
|
|
77518
77611
|
const out = [];
|
|
77519
77612
|
for (const [unit, spec] of Object.entries(UNIT_TABLE)) if (spec.dimension === dimension) out.push(unit);
|
|
@@ -77817,9 +77910,9 @@ function feederCustomizationExample(sources) {
|
|
|
77817
77910
|
expr: "number(d)",
|
|
77818
77911
|
bindings: days
|
|
77819
77912
|
},
|
|
77820
|
-
"remaining.
|
|
77913
|
+
"remaining.kind": {
|
|
77821
77914
|
kind: "expression",
|
|
77822
|
-
expr: "\"
|
|
77915
|
+
expr: "\"duration\"",
|
|
77823
77916
|
bindings: {}
|
|
77824
77917
|
},
|
|
77825
77918
|
status: {
|
|
@@ -78085,19 +78178,9 @@ function convertUnitTargets(from) {
|
|
|
78085
78178
|
//#region src/generated/customize-catalog.ts
|
|
78086
78179
|
/**
|
|
78087
78180
|
* Customize catalog, projected from every `*.cap.ts` `customize` block.
|
|
78088
|
-
*
|
|
78181
|
+
* 5 caps. Field keys are `runtimeState` paths. No Zod.
|
|
78089
78182
|
*/
|
|
78090
78183
|
var CAP_CUSTOMIZE_CATALOG = {
|
|
78091
|
-
"ambient-light-sensor": {
|
|
78092
|
-
version: 1,
|
|
78093
|
-
targets: [],
|
|
78094
|
-
advancedParameters: [{
|
|
78095
|
-
path: "lux",
|
|
78096
|
-
kind: "number",
|
|
78097
|
-
label: "Illuminance",
|
|
78098
|
-
unit: "lx"
|
|
78099
|
-
}]
|
|
78100
|
-
},
|
|
78101
78184
|
"battery": {
|
|
78102
78185
|
version: 1,
|
|
78103
78186
|
targets: [{
|
|
@@ -78112,7 +78195,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78112
78195
|
require_err_msg.DeviceType.Container,
|
|
78113
78196
|
require_err_msg.DeviceType.Thermostat
|
|
78114
78197
|
],
|
|
78115
|
-
apply: "add
|
|
78198
|
+
apply: "add",
|
|
78116
78199
|
vocabularyCap: "battery",
|
|
78117
78200
|
vocabularyStateField: "percentage",
|
|
78118
78201
|
sources: [{
|
|
@@ -78151,38 +78234,6 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78151
78234
|
when: "add"
|
|
78152
78235
|
}
|
|
78153
78236
|
]
|
|
78154
|
-
}],
|
|
78155
|
-
advancedParameters: [
|
|
78156
|
-
{
|
|
78157
|
-
path: "binary",
|
|
78158
|
-
kind: "boolean",
|
|
78159
|
-
label: "Binary indicator"
|
|
78160
|
-
},
|
|
78161
|
-
{
|
|
78162
|
-
path: "charging",
|
|
78163
|
-
kind: "enum",
|
|
78164
|
-
label: "Charging source",
|
|
78165
|
-
enumValues: [
|
|
78166
|
-
"dc",
|
|
78167
|
-
"solar",
|
|
78168
|
-
"none",
|
|
78169
|
-
"unknown"
|
|
78170
|
-
]
|
|
78171
|
-
},
|
|
78172
|
-
{
|
|
78173
|
-
path: "sleeping",
|
|
78174
|
-
kind: "boolean",
|
|
78175
|
-
label: "Sleeping"
|
|
78176
|
-
}
|
|
78177
|
-
]
|
|
78178
|
-
},
|
|
78179
|
-
"binary": {
|
|
78180
|
-
version: 1,
|
|
78181
|
-
targets: [],
|
|
78182
|
-
advancedParameters: [{
|
|
78183
|
-
path: "on",
|
|
78184
|
-
kind: "boolean",
|
|
78185
|
-
label: "On"
|
|
78186
78237
|
}]
|
|
78187
78238
|
},
|
|
78188
78239
|
"consumables": {
|
|
@@ -78260,12 +78311,8 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78260
78311
|
transforms: [{ kind: "identity" }]
|
|
78261
78312
|
}],
|
|
78262
78313
|
literals: [{
|
|
78263
|
-
path: "remaining.
|
|
78264
|
-
values: [
|
|
78265
|
-
"days",
|
|
78266
|
-
"hours",
|
|
78267
|
-
"cycles"
|
|
78268
|
-
]
|
|
78314
|
+
path: "remaining.kind",
|
|
78315
|
+
values: ["duration", "count"]
|
|
78269
78316
|
}]
|
|
78270
78317
|
},
|
|
78271
78318
|
{
|
|
@@ -78323,8 +78370,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78323
78370
|
path: "lastFetchedAt",
|
|
78324
78371
|
when: "add"
|
|
78325
78372
|
}]
|
|
78326
|
-
}]
|
|
78327
|
-
advancedParameters: []
|
|
78373
|
+
}]
|
|
78328
78374
|
},
|
|
78329
78375
|
"doorbell": {
|
|
78330
78376
|
version: 1,
|
|
@@ -78356,17 +78402,6 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78356
78402
|
counterPath: "pressCountSinceStart",
|
|
78357
78403
|
highWater: "composer-advance",
|
|
78358
78404
|
debounceMs: 2e3
|
|
78359
|
-
}],
|
|
78360
|
-
advancedParameters: []
|
|
78361
|
-
},
|
|
78362
|
-
"humidity-sensor": {
|
|
78363
|
-
version: 1,
|
|
78364
|
-
targets: [],
|
|
78365
|
-
advancedParameters: [{
|
|
78366
|
-
path: "percent",
|
|
78367
|
-
kind: "number",
|
|
78368
|
-
label: "Humidity",
|
|
78369
|
-
unit: "%"
|
|
78370
78405
|
}]
|
|
78371
78406
|
},
|
|
78372
78407
|
"motion": {
|
|
@@ -78375,7 +78410,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78375
78410
|
id: "detected",
|
|
78376
78411
|
cardinality: "event",
|
|
78377
78412
|
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
78378
|
-
apply: "
|
|
78413
|
+
apply: "add",
|
|
78379
78414
|
vocabularyCap: "motion",
|
|
78380
78415
|
vocabularyEvent: "onMotionChanged",
|
|
78381
78416
|
sources: [{
|
|
@@ -78404,22 +78439,6 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78404
78439
|
"confirm",
|
|
78405
78440
|
"replace"
|
|
78406
78441
|
]
|
|
78407
|
-
}],
|
|
78408
|
-
advancedParameters: []
|
|
78409
|
-
},
|
|
78410
|
-
"power-meter": {
|
|
78411
|
-
version: 1,
|
|
78412
|
-
targets: [],
|
|
78413
|
-
advancedParameters: [{
|
|
78414
|
-
path: "kwhTotal",
|
|
78415
|
-
kind: "number",
|
|
78416
|
-
label: "Energy",
|
|
78417
|
-
unit: "kWh"
|
|
78418
|
-
}, {
|
|
78419
|
-
path: "watts",
|
|
78420
|
-
kind: "number",
|
|
78421
|
-
label: "Power",
|
|
78422
|
-
unit: "W"
|
|
78423
78442
|
}]
|
|
78424
78443
|
},
|
|
78425
78444
|
"running-state": {
|
|
@@ -78439,7 +78458,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78439
78458
|
require_err_msg.DeviceType.Thermostat,
|
|
78440
78459
|
require_err_msg.DeviceType.PetFeeder
|
|
78441
78460
|
],
|
|
78442
|
-
apply: "add
|
|
78461
|
+
apply: "add",
|
|
78443
78462
|
vocabularyCap: "running-state",
|
|
78444
78463
|
vocabularyStateField: "running",
|
|
78445
78464
|
sources: [
|
|
@@ -78502,29 +78521,26 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78502
78521
|
sourceChangedAt: "prefer"
|
|
78503
78522
|
}
|
|
78504
78523
|
]
|
|
78505
|
-
}],
|
|
78506
|
-
advancedParameters: []
|
|
78507
|
-
},
|
|
78508
|
-
"switch": {
|
|
78509
|
-
version: 1,
|
|
78510
|
-
targets: [],
|
|
78511
|
-
advancedParameters: [{
|
|
78512
|
-
path: "on",
|
|
78513
|
-
kind: "boolean",
|
|
78514
|
-
label: "On"
|
|
78515
|
-
}]
|
|
78516
|
-
},
|
|
78517
|
-
"temperature-sensor": {
|
|
78518
|
-
version: 1,
|
|
78519
|
-
targets: [],
|
|
78520
|
-
advancedParameters: [{
|
|
78521
|
-
path: "celsius",
|
|
78522
|
-
kind: "number",
|
|
78523
|
-
label: "Temperature",
|
|
78524
|
-
unit: "°C"
|
|
78525
78524
|
}]
|
|
78526
78525
|
}
|
|
78527
78526
|
};
|
|
78527
|
+
/**
|
|
78528
|
+
* Unit meta on runtime-state fields. The composed-device row reads this;
|
|
78529
|
+
* it is not an override list (D944).
|
|
78530
|
+
*/
|
|
78531
|
+
var CAP_RUNTIME_FIELD_UNITS = {
|
|
78532
|
+
"ambient-light-sensor": { lux: "lx" },
|
|
78533
|
+
"battery": {
|
|
78534
|
+
percentage: "%",
|
|
78535
|
+
volts: "V"
|
|
78536
|
+
},
|
|
78537
|
+
"humidity-sensor": { percent: "%" },
|
|
78538
|
+
"power-meter": {
|
|
78539
|
+
watts: "W",
|
|
78540
|
+
kwhTotal: "kWh"
|
|
78541
|
+
},
|
|
78542
|
+
"temperature-sensor": { celsius: "°C" }
|
|
78543
|
+
};
|
|
78528
78544
|
//#endregion
|
|
78529
78545
|
//#region src/composition/customize/field-source.ts
|
|
78530
78546
|
function fromRead(source, cap, fieldPath) {
|
|
@@ -96145,7 +96161,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96145
96161
|
field: "value",
|
|
96146
96162
|
quantity: t("the reading", "il valore"),
|
|
96147
96163
|
label: t("Reading", "Valore"),
|
|
96148
|
-
unitField: "unit",
|
|
96149
96164
|
icon: "gauge"
|
|
96150
96165
|
}]
|
|
96151
96166
|
},
|
|
@@ -96281,7 +96296,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96281
96296
|
field: "temperature",
|
|
96282
96297
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
96283
96298
|
label: t("Temperature", "Temperatura"),
|
|
96284
|
-
|
|
96299
|
+
unit: "°C",
|
|
96285
96300
|
icon: "thermometer"
|
|
96286
96301
|
},
|
|
96287
96302
|
{
|
|
@@ -96297,7 +96312,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96297
96312
|
field: "windSpeed",
|
|
96298
96313
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
96299
96314
|
label: t("Wind", "Vento"),
|
|
96300
|
-
|
|
96315
|
+
unit: "m/s",
|
|
96301
96316
|
icon: "wind"
|
|
96302
96317
|
},
|
|
96303
96318
|
{
|
|
@@ -96305,7 +96320,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96305
96320
|
field: "pressure",
|
|
96306
96321
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
96307
96322
|
label: t("Pressure", "Pressione"),
|
|
96308
|
-
|
|
96323
|
+
unit: "hPa",
|
|
96309
96324
|
icon: "gauge"
|
|
96310
96325
|
}
|
|
96311
96326
|
]
|
|
@@ -102838,7 +102853,7 @@ var BucketAccumulator = class {
|
|
|
102838
102853
|
//#region src/generated/history-catalog.ts
|
|
102839
102854
|
/**
|
|
102840
102855
|
* Cap history catalog, projected from every `*.cap.ts` `history` block.
|
|
102841
|
-
* 41 caps with series (
|
|
102856
|
+
* 41 caps with series (75 series), 30 caps answered `'none'`.
|
|
102842
102857
|
* Field keys are `runtimeState` paths (`a.b` into fixed objects only).
|
|
102843
102858
|
*/
|
|
102844
102859
|
var HISTORY_CATALOG = {
|
|
@@ -102855,12 +102870,12 @@ var HISTORY_CATALOG = {
|
|
|
102855
102870
|
},
|
|
102856
102871
|
"pm25": {
|
|
102857
102872
|
kind: "gauge",
|
|
102858
|
-
unit: "
|
|
102873
|
+
unit: "µg/m³",
|
|
102859
102874
|
deadband: 1
|
|
102860
102875
|
},
|
|
102861
102876
|
"pm10": {
|
|
102862
102877
|
kind: "gauge",
|
|
102863
|
-
unit: "
|
|
102878
|
+
unit: "µg/m³",
|
|
102864
102879
|
deadband: 1
|
|
102865
102880
|
},
|
|
102866
102881
|
"aqi": {
|
|
@@ -102890,10 +102905,16 @@ var HISTORY_CATALOG = {
|
|
|
102890
102905
|
deadbandPct: 10,
|
|
102891
102906
|
minIntervalMs: 6e4
|
|
102892
102907
|
} },
|
|
102893
|
-
"battery": {
|
|
102894
|
-
|
|
102895
|
-
|
|
102896
|
-
|
|
102908
|
+
"battery": {
|
|
102909
|
+
"percentage": {
|
|
102910
|
+
kind: "gauge",
|
|
102911
|
+
unit: "%"
|
|
102912
|
+
},
|
|
102913
|
+
"volts": {
|
|
102914
|
+
kind: "gauge",
|
|
102915
|
+
unit: "V"
|
|
102916
|
+
}
|
|
102917
|
+
},
|
|
102897
102918
|
"binary": { "on": { kind: "boolean" } },
|
|
102898
102919
|
"brightness": { "percentage": {
|
|
102899
102920
|
kind: "gauge",
|
|
@@ -102977,7 +102998,7 @@ var HISTORY_CATALOG = {
|
|
|
102977
102998
|
},
|
|
102978
102999
|
"enum-sensor": { "value": {
|
|
102979
103000
|
kind: "enum",
|
|
102980
|
-
skipWhenSet: "
|
|
103001
|
+
skipWhenSet: "timestamp"
|
|
102981
103002
|
} },
|
|
102982
103003
|
"fan-control": {
|
|
102983
103004
|
"percentage": {
|
|
@@ -103050,7 +103071,6 @@ var HISTORY_CATALOG = {
|
|
|
103050
103071
|
},
|
|
103051
103072
|
"numeric-sensor": { "value": {
|
|
103052
103073
|
kind: "gauge",
|
|
103053
|
-
unitFrom: "unit",
|
|
103054
103074
|
minIntervalMs: 3e4
|
|
103055
103075
|
} },
|
|
103056
103076
|
"pet-feeder": {
|
|
@@ -103064,7 +103084,7 @@ var HISTORY_CATALOG = {
|
|
|
103064
103084
|
},
|
|
103065
103085
|
"desiccantLeftDays": {
|
|
103066
103086
|
kind: "gauge",
|
|
103067
|
-
unit: "
|
|
103087
|
+
unit: "s"
|
|
103068
103088
|
}
|
|
103069
103089
|
},
|
|
103070
103090
|
"power-meter": {
|
|
@@ -103168,7 +103188,7 @@ var HISTORY_CATALOG = {
|
|
|
103168
103188
|
"weather": {
|
|
103169
103189
|
"temperature": {
|
|
103170
103190
|
kind: "gauge",
|
|
103171
|
-
|
|
103191
|
+
unit: "°C",
|
|
103172
103192
|
deadband: .2
|
|
103173
103193
|
},
|
|
103174
103194
|
"humidity": {
|
|
@@ -103178,12 +103198,12 @@ var HISTORY_CATALOG = {
|
|
|
103178
103198
|
},
|
|
103179
103199
|
"pressure": {
|
|
103180
103200
|
kind: "gauge",
|
|
103181
|
-
|
|
103201
|
+
unit: "hPa",
|
|
103182
103202
|
deadband: .5
|
|
103183
103203
|
},
|
|
103184
103204
|
"windSpeed": {
|
|
103185
103205
|
kind: "gauge",
|
|
103186
|
-
|
|
103206
|
+
unit: "m/s",
|
|
103187
103207
|
deadband: .5
|
|
103188
103208
|
}
|
|
103189
103209
|
}
|
|
@@ -103217,7 +103237,6 @@ var HISTORY_ITEM_CATALOG = { "consumables": {
|
|
|
103217
103237
|
},
|
|
103218
103238
|
"remaining.value": {
|
|
103219
103239
|
kind: "gauge",
|
|
103220
|
-
unitFrom: "remaining.unit",
|
|
103221
103240
|
deadband: 1,
|
|
103222
103241
|
displayName: "Remaining"
|
|
103223
103242
|
}
|
|
@@ -103261,6 +103280,14 @@ function historyFieldsFor(capName) {
|
|
|
103261
103280
|
return HISTORY_CATALOG[capName] ?? {};
|
|
103262
103281
|
}
|
|
103263
103282
|
//#endregion
|
|
103283
|
+
//#region src/capabilities/runtime-field-unit.ts
|
|
103284
|
+
/**
|
|
103285
|
+
* The unit a composed-device field row offers convert-unit from (D941, D944).
|
|
103286
|
+
*/
|
|
103287
|
+
function runtimeFieldUnit(cap, path) {
|
|
103288
|
+
return CAP_RUNTIME_FIELD_UNITS[cap]?.[path];
|
|
103289
|
+
}
|
|
103290
|
+
//#endregion
|
|
103264
103291
|
//#region src/composition/customize/override-draft.ts
|
|
103265
103292
|
/**
|
|
103266
103293
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
@@ -112817,6 +112844,227 @@ var DEVICE_TYPE_INFO = { ["camera"]: {
|
|
|
112817
112844
|
icon: "camera"
|
|
112818
112845
|
} };
|
|
112819
112846
|
//#endregion
|
|
112847
|
+
//#region src/units/threshold.ts
|
|
112848
|
+
/**
|
|
112849
|
+
* Move a threshold between the unit the operator sees and the stored base.
|
|
112850
|
+
* A failed conversion leaves the number unchanged — the recipe stays serialisable.
|
|
112851
|
+
*/
|
|
112852
|
+
function thresholdToBase(value, displayUnit, baseUnit) {
|
|
112853
|
+
if (!Number.isFinite(value) || displayUnit === baseUnit) return value;
|
|
112854
|
+
return tryConvertUnit(value, displayUnit, baseUnit) ?? value;
|
|
112855
|
+
}
|
|
112856
|
+
function thresholdToDisplay(value, baseUnit, displayUnit) {
|
|
112857
|
+
if (!Number.isFinite(value) || baseUnit === displayUnit) return value;
|
|
112858
|
+
return tryConvertUnit(value, baseUnit, displayUnit) ?? value;
|
|
112859
|
+
}
|
|
112860
|
+
//#endregion
|
|
112861
|
+
//#region src/units/format-reading.ts
|
|
112862
|
+
/**
|
|
112863
|
+
* Render a stored base-unit reading (D944 §4). The preference defaults to
|
|
112864
|
+
* metric. An operator override is applied by the caller via `convertUnit`
|
|
112865
|
+
* before this, or by passing the already-chosen display unit through
|
|
112866
|
+
* `resolveSensorDisplay` — this function is the quantity → string step.
|
|
112867
|
+
*/
|
|
112868
|
+
var DURATION_STEPS = [
|
|
112869
|
+
{
|
|
112870
|
+
value: 86400,
|
|
112871
|
+
unit: "d"
|
|
112872
|
+
},
|
|
112873
|
+
{
|
|
112874
|
+
value: 3600,
|
|
112875
|
+
unit: "h"
|
|
112876
|
+
},
|
|
112877
|
+
{
|
|
112878
|
+
value: 60,
|
|
112879
|
+
unit: "min"
|
|
112880
|
+
}
|
|
112881
|
+
];
|
|
112882
|
+
var INFO_STEPS = [
|
|
112883
|
+
{
|
|
112884
|
+
factor: 1024 ** 4,
|
|
112885
|
+
unit: "TiB"
|
|
112886
|
+
},
|
|
112887
|
+
{
|
|
112888
|
+
factor: 1024 ** 3,
|
|
112889
|
+
unit: "GiB"
|
|
112890
|
+
},
|
|
112891
|
+
{
|
|
112892
|
+
factor: 1024 ** 2,
|
|
112893
|
+
unit: "MiB"
|
|
112894
|
+
},
|
|
112895
|
+
{
|
|
112896
|
+
factor: 1024,
|
|
112897
|
+
unit: "KiB"
|
|
112898
|
+
}
|
|
112899
|
+
];
|
|
112900
|
+
function formatMagnitude(value, precision) {
|
|
112901
|
+
if (!Number.isFinite(value)) return "";
|
|
112902
|
+
if (precision !== void 0) return value.toFixed(precision);
|
|
112903
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(1);
|
|
112904
|
+
}
|
|
112905
|
+
function scaleDuration(seconds) {
|
|
112906
|
+
const abs = Math.abs(seconds);
|
|
112907
|
+
for (const step of DURATION_STEPS) if (abs >= step.value) return {
|
|
112908
|
+
value: seconds / step.value,
|
|
112909
|
+
unit: step.unit
|
|
112910
|
+
};
|
|
112911
|
+
return {
|
|
112912
|
+
value: seconds,
|
|
112913
|
+
unit: "s"
|
|
112914
|
+
};
|
|
112915
|
+
}
|
|
112916
|
+
function scaleInformation(bytes) {
|
|
112917
|
+
const abs = Math.abs(bytes);
|
|
112918
|
+
for (const step of INFO_STEPS) if (abs >= step.factor) return {
|
|
112919
|
+
value: bytes / step.factor,
|
|
112920
|
+
unit: step.unit
|
|
112921
|
+
};
|
|
112922
|
+
return {
|
|
112923
|
+
value: bytes,
|
|
112924
|
+
unit: "B"
|
|
112925
|
+
};
|
|
112926
|
+
}
|
|
112927
|
+
function resolvedQuantity(input) {
|
|
112928
|
+
if (input.quantity === "device") return input.deviceQuantity ?? "none";
|
|
112929
|
+
return input.quantity;
|
|
112930
|
+
}
|
|
112931
|
+
function formatReading(input) {
|
|
112932
|
+
const quantity = resolvedQuantity(input);
|
|
112933
|
+
const precision = input.precision;
|
|
112934
|
+
if (!Number.isFinite(input.value)) return {
|
|
112935
|
+
text: "",
|
|
112936
|
+
unit: "",
|
|
112937
|
+
value: input.value
|
|
112938
|
+
};
|
|
112939
|
+
if (quantity === "duration" || quantity === "duration-ms") {
|
|
112940
|
+
const scaled = scaleDuration(quantity === "duration-ms" ? input.value / 1e3 : input.value);
|
|
112941
|
+
return {
|
|
112942
|
+
text: formatMagnitude(scaled.value, precision),
|
|
112943
|
+
unit: scaled.unit,
|
|
112944
|
+
value: scaled.value
|
|
112945
|
+
};
|
|
112946
|
+
}
|
|
112947
|
+
if (quantity === "information") {
|
|
112948
|
+
const scaled = scaleInformation(input.value);
|
|
112949
|
+
return {
|
|
112950
|
+
text: formatMagnitude(scaled.value, precision),
|
|
112951
|
+
unit: scaled.unit,
|
|
112952
|
+
value: scaled.value
|
|
112953
|
+
};
|
|
112954
|
+
}
|
|
112955
|
+
const preference = input.preference ?? "metric";
|
|
112956
|
+
const base = require_sleep.baseUnitOf(quantity);
|
|
112957
|
+
const display = require_sleep.displayUnitFor(quantity, preference);
|
|
112958
|
+
if (base === void 0 || display === void 0) return {
|
|
112959
|
+
text: formatMagnitude(input.value, precision),
|
|
112960
|
+
unit: "",
|
|
112961
|
+
value: input.value
|
|
112962
|
+
};
|
|
112963
|
+
const converted = tryConvertUnit(input.value, base, display);
|
|
112964
|
+
if (converted === void 0) return {
|
|
112965
|
+
text: formatMagnitude(input.value, precision),
|
|
112966
|
+
unit: base,
|
|
112967
|
+
value: input.value
|
|
112968
|
+
};
|
|
112969
|
+
return {
|
|
112970
|
+
text: formatMagnitude(converted, precision),
|
|
112971
|
+
unit: display,
|
|
112972
|
+
value: converted
|
|
112973
|
+
};
|
|
112974
|
+
}
|
|
112975
|
+
//#endregion
|
|
112976
|
+
//#region src/units/ingest-reading.ts
|
|
112977
|
+
/**
|
|
112978
|
+
* Convert an upstream number into the stored base of its quantity (D944 §4).
|
|
112979
|
+
* An unknown unit or a unit from another dimension is a refusal: the caller
|
|
112980
|
+
* logs it and publishes null (D393). This function never guesses.
|
|
112981
|
+
*/
|
|
112982
|
+
var DIMENSION_QUANTITY = {
|
|
112983
|
+
temperature: "temperature",
|
|
112984
|
+
pressure: "pressure",
|
|
112985
|
+
speed: "speed",
|
|
112986
|
+
"precipitation-rate": "precipitation-rate",
|
|
112987
|
+
length: "length",
|
|
112988
|
+
area: "area",
|
|
112989
|
+
illuminance: "illuminance",
|
|
112990
|
+
irradiance: "irradiance",
|
|
112991
|
+
power: "power",
|
|
112992
|
+
"apparent-power": "apparent-power",
|
|
112993
|
+
energy: "energy",
|
|
112994
|
+
voltage: "voltage",
|
|
112995
|
+
current: "current",
|
|
112996
|
+
"concentration-volume": "concentration-volume",
|
|
112997
|
+
"concentration-mass": "concentration-mass",
|
|
112998
|
+
mass: "mass",
|
|
112999
|
+
percentage: "percentage",
|
|
113000
|
+
volume: "volume",
|
|
113001
|
+
duration: "duration",
|
|
113002
|
+
information: "information",
|
|
113003
|
+
angle: "angle",
|
|
113004
|
+
"sound-level": "sound-level",
|
|
113005
|
+
"signal-level": "signal-level",
|
|
113006
|
+
"colour-temperature": "colour-temperature",
|
|
113007
|
+
bitrate: "bitrate",
|
|
113008
|
+
rate: "rate"
|
|
113009
|
+
};
|
|
113010
|
+
/**
|
|
113011
|
+
* Quantity implied by a unit symbol. `ppb` and `ms` are the two symbols
|
|
113012
|
+
* whose stored base is not the dimension's canonical unit. `mm` is length;
|
|
113013
|
+
* precipitation is chosen by the caller (a device class), not by the symbol.
|
|
113014
|
+
*/
|
|
113015
|
+
function quantityFromUnit(rawUnit) {
|
|
113016
|
+
const unit = normalizeUnit(rawUnit);
|
|
113017
|
+
if (unit === void 0) return void 0;
|
|
113018
|
+
if (unit === "ppb") return "concentration-ppb";
|
|
113019
|
+
if (unit === "ms") return "duration-ms";
|
|
113020
|
+
const dimension = unitDimension(unit);
|
|
113021
|
+
if (dimension === void 0) return void 0;
|
|
113022
|
+
return DIMENSION_QUANTITY[dimension];
|
|
113023
|
+
}
|
|
113024
|
+
function ingestReading(input) {
|
|
113025
|
+
if (!Number.isFinite(input.value)) return {
|
|
113026
|
+
ok: false,
|
|
113027
|
+
reason: "non-finite"
|
|
113028
|
+
};
|
|
113029
|
+
if (input.quantity === "device") return {
|
|
113030
|
+
ok: false,
|
|
113031
|
+
reason: "unknown-unit"
|
|
113032
|
+
};
|
|
113033
|
+
const raw = input.rawUnit?.trim();
|
|
113034
|
+
if (raw === void 0 || raw.length === 0) return {
|
|
113035
|
+
ok: true,
|
|
113036
|
+
value: input.value
|
|
113037
|
+
};
|
|
113038
|
+
const unit = normalizeUnit(raw);
|
|
113039
|
+
if (unit === void 0) return {
|
|
113040
|
+
ok: false,
|
|
113041
|
+
reason: "unknown-unit"
|
|
113042
|
+
};
|
|
113043
|
+
const base = require_sleep.baseUnitOf(input.quantity);
|
|
113044
|
+
if (base === void 0) {
|
|
113045
|
+
if (unitDimension(unit) !== void 0) return {
|
|
113046
|
+
ok: false,
|
|
113047
|
+
reason: "cross-dimension"
|
|
113048
|
+
};
|
|
113049
|
+
return {
|
|
113050
|
+
ok: false,
|
|
113051
|
+
reason: "unknown-unit"
|
|
113052
|
+
};
|
|
113053
|
+
}
|
|
113054
|
+
const converted = tryConvertUnit(input.value, unit, base);
|
|
113055
|
+
if (converted === void 0) return unitDimension(unit) === void 0 ? {
|
|
113056
|
+
ok: false,
|
|
113057
|
+
reason: "unknown-unit"
|
|
113058
|
+
} : {
|
|
113059
|
+
ok: false,
|
|
113060
|
+
reason: "cross-dimension"
|
|
113061
|
+
};
|
|
113062
|
+
return {
|
|
113063
|
+
ok: true,
|
|
113064
|
+
value: converted
|
|
113065
|
+
};
|
|
113066
|
+
}
|
|
113067
|
+
//#endregion
|
|
112820
113068
|
//#region src/util/location-match.ts
|
|
112821
113069
|
/**
|
|
112822
113070
|
* Pure fuzzy matcher for adoption location import. Normalized
|
|
@@ -114443,6 +114691,7 @@ exports.CAP_CUSTOMIZE_CATALOG = CAP_CUSTOMIZE_CATALOG;
|
|
|
114443
114691
|
exports.CAP_NAMES_WITH_STATUS = CAP_NAMES_WITH_STATUS;
|
|
114444
114692
|
exports.CAP_NODE_PIN_CONTEXT_KEY = require_sleep.CAP_NODE_PIN_CONTEXT_KEY;
|
|
114445
114693
|
exports.CAP_PROVIDER_KIND_MAP = CAP_PROVIDER_KIND_MAP;
|
|
114694
|
+
exports.CAP_RUNTIME_FIELD_UNITS = CAP_RUNTIME_FIELD_UNITS;
|
|
114446
114695
|
exports.CAP_VOCABULARY = CAP_VOCABULARY;
|
|
114447
114696
|
exports.CAP_VOCABULARY_BY_NAME = CAP_VOCABULARY_BY_NAME;
|
|
114448
114697
|
exports.CATALOG_LANGS = CATALOG_LANGS;
|
|
@@ -114641,8 +114890,8 @@ exports.ConsumableFormSchema = ConsumableFormSchema;
|
|
|
114641
114890
|
exports.ConsumableItemSchema = ConsumableItemSchema;
|
|
114642
114891
|
exports.ConsumableKindSchema = ConsumableKindSchema;
|
|
114643
114892
|
exports.ConsumableLevelSchema = ConsumableLevelSchema;
|
|
114893
|
+
exports.ConsumableRemainingKindSchema = ConsumableRemainingKindSchema;
|
|
114644
114894
|
exports.ConsumableRemainingSchema = ConsumableRemainingSchema;
|
|
114645
|
-
exports.ConsumableRemainingUnitSchema = ConsumableRemainingUnitSchema;
|
|
114646
114895
|
exports.ConsumableStatusSchema = ConsumableStatusSchema;
|
|
114647
114896
|
exports.ConsumablesStatusSchema = ConsumablesStatusSchema;
|
|
114648
114897
|
exports.ContactStatusSchema = ContactStatusSchema;
|
|
@@ -114688,6 +114937,7 @@ exports.DEFAULT_CLUSTER_STEP_SETTINGS = DEFAULT_CLUSTER_STEP_SETTINGS;
|
|
|
114688
114937
|
exports.DEFAULT_CORE_BLOCK_ENTRY = DEFAULT_CORE_BLOCK_ENTRY;
|
|
114689
114938
|
exports.DEFAULT_DECODER_HWACCEL_CONFIG = DEFAULT_DECODER_HWACCEL_CONFIG;
|
|
114690
114939
|
exports.DEFAULT_DETAIL_CROP_CONVENTION = DEFAULT_DETAIL_CROP_CONVENTION;
|
|
114940
|
+
exports.DEFAULT_DISPLAY_PREFERENCE = require_sleep.DEFAULT_DISPLAY_PREFERENCE;
|
|
114691
114941
|
exports.DEFAULT_EVENTS_BAND_BUFFER_SEC = DEFAULT_EVENTS_BAND_BUFFER_SEC;
|
|
114692
114942
|
exports.DEFAULT_EVENT_COLOR = DEFAULT_EVENT_COLOR;
|
|
114693
114943
|
exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
|
|
@@ -114746,6 +114996,7 @@ exports.DEVICE_TOMBSTONE_RETENTION_MS = DEVICE_TOMBSTONE_RETENTION_MS;
|
|
|
114746
114996
|
exports.DEVICE_TYPE_CONTROL_KIND = DEVICE_TYPE_CONTROL_KIND;
|
|
114747
114997
|
exports.DEVICE_TYPE_DO_CAPS = DEVICE_TYPE_DO_CAPS;
|
|
114748
114998
|
exports.DEVICE_TYPE_INFO = DEVICE_TYPE_INFO;
|
|
114999
|
+
exports.DISPLAY_PREFERENCES = require_sleep.DISPLAY_PREFERENCES;
|
|
114749
115000
|
exports.DISPLAY_PRESETS = DISPLAY_PRESETS;
|
|
114750
115001
|
exports.DOORBELL_RISE_DEBOUNCE_MS = DOORBELL_RISE_DEBOUNCE_MS;
|
|
114751
115002
|
exports.DataStoreDatabaseSchema = DataStoreDatabaseSchema;
|
|
@@ -115676,6 +115927,7 @@ exports.PtzPositionSchema = PtzPositionSchema;
|
|
|
115676
115927
|
exports.PtzPresetFunctionSchema = PtzPresetFunctionSchema;
|
|
115677
115928
|
exports.PtzPresetSchema = PtzPresetSchema;
|
|
115678
115929
|
exports.PtzStatusSchema = PtzStatusSchema;
|
|
115930
|
+
exports.QUANTITY_BASE = require_sleep.QUANTITY_BASE;
|
|
115679
115931
|
exports.QueryFilterSchema = QueryFilterSchema;
|
|
115680
115932
|
exports.RATE_CONTROL_RELAXED = RATE_CONTROL_RELAXED;
|
|
115681
115933
|
exports.RATE_CONTROL_TIGHT = RATE_CONTROL_TIGHT;
|
|
@@ -115754,6 +116006,7 @@ exports.ReadSegmentBytesResultSchema = ReadSegmentBytesResultSchema;
|
|
|
115754
116006
|
exports.ReadWindowBytesResultSchema = ReadWindowBytesResultSchema;
|
|
115755
116007
|
exports.ReadinessRegistry = require_sleep.ReadinessRegistry;
|
|
115756
116008
|
exports.ReadinessTimeoutError = require_sleep.ReadinessTimeoutError;
|
|
116009
|
+
exports.ReadingQuantitySchema = require_sleep.ReadingQuantitySchema;
|
|
115757
116010
|
exports.RebuildObjectEmbeddingsRefusalSchema = RebuildObjectEmbeddingsRefusalSchema;
|
|
115758
116011
|
exports.RecentTracksPageSchema = RecentTracksPageSchema;
|
|
115759
116012
|
exports.RecentTracksQueryInput = RecentTracksQueryInput;
|
|
@@ -116320,6 +116573,7 @@ exports.autoAssignProfiles = autoAssignProfiles;
|
|
|
116320
116573
|
exports.automationControlCapability = automationControlCapability;
|
|
116321
116574
|
exports.backupCapability = backupCapability;
|
|
116322
116575
|
exports.bareAddonId = bareAddonId;
|
|
116576
|
+
exports.baseUnitOf = require_sleep.baseUnitOf;
|
|
116323
116577
|
exports.batteryCapability = batteryCapability;
|
|
116324
116578
|
exports.bestLocationMatch = bestLocationMatch;
|
|
116325
116579
|
exports.binaryCapability = binaryCapability;
|
|
@@ -116539,6 +116793,7 @@ exports.diffStepSettings = diffStepSettings;
|
|
|
116539
116793
|
exports.disarmRoseMemory = require_composition.disarmRoseMemory;
|
|
116540
116794
|
exports.dishwasherCapability = dishwasherCapability;
|
|
116541
116795
|
exports.displayPaletteCapability = displayPaletteCapability;
|
|
116796
|
+
exports.displayUnitFor = require_sleep.displayUnitFor;
|
|
116542
116797
|
exports.doActionSelectValue = doActionSelectValue;
|
|
116543
116798
|
exports.dominantClipLabels = dominantClipLabels;
|
|
116544
116799
|
exports.doorbellCapability = doorbellCapability;
|
|
@@ -116625,6 +116880,7 @@ exports.formatMediaOwnerKey = formatMediaOwnerKey;
|
|
|
116625
116880
|
exports.formatMinutes = formatMinutes;
|
|
116626
116881
|
exports.formatPaletteViolations = formatPaletteViolations;
|
|
116627
116882
|
exports.formatParkedFor = formatParkedFor;
|
|
116883
|
+
exports.formatReading = formatReading;
|
|
116628
116884
|
exports.formatSecretScope = require_sleep.formatSecretScope;
|
|
116629
116885
|
exports.formulaProblem = formulaProblem;
|
|
116630
116886
|
exports.freshResults = freshResults;
|
|
@@ -116649,6 +116905,7 @@ exports.heatingValveCapability = heatingValveCapability;
|
|
|
116649
116905
|
exports.hfModelUrl = require_sleep.hfModelUrl;
|
|
116650
116906
|
exports.historyFieldsFor = historyFieldsFor;
|
|
116651
116907
|
exports.historyItemFieldPath = require_sleep.historyItemFieldPath;
|
|
116908
|
+
exports.historyUnitFor = require_sleep.historyUnitFor;
|
|
116652
116909
|
exports.htmlToText = htmlToText;
|
|
116653
116910
|
exports.hubAddressHostname = hubAddressHostname;
|
|
116654
116911
|
exports.hubMotionNativeProvider = hubMotionNativeProvider;
|
|
@@ -116663,6 +116920,7 @@ exports.imageModesForKind = imageModesForKind;
|
|
|
116663
116920
|
exports.imageSettingsCapability = imageSettingsCapability;
|
|
116664
116921
|
exports.inferExpressionKinds = inferExpressionKinds;
|
|
116665
116922
|
exports.inferModelProvider = inferModelProvider;
|
|
116923
|
+
exports.ingestReading = ingestReading;
|
|
116666
116924
|
exports.initialPoolMemoryState = initialPoolMemoryState;
|
|
116667
116925
|
exports.integrationsCapability = integrationsCapability;
|
|
116668
116926
|
exports.intercomCapability = intercomCapability;
|
|
@@ -116717,6 +116975,7 @@ exports.isOauthLandingReason = isOauthLandingReason;
|
|
|
116717
116975
|
exports.isObjectInput = isObjectInput;
|
|
116718
116976
|
exports.isOccupancyRule = isOccupancyRule;
|
|
116719
116977
|
exports.isOwnerOnlyEventCategory = require_event_category.isOwnerOnlyEventCategory;
|
|
116978
|
+
exports.isReadingQuantity = require_sleep.isReadingQuantity;
|
|
116720
116979
|
exports.isRemovedModelId = isRemovedModelId;
|
|
116721
116980
|
exports.isRestoredCap = isRestoredCap;
|
|
116722
116981
|
exports.isRetiredClearKey = isRetiredClearKey;
|
|
@@ -116947,6 +117206,7 @@ exports.ptzAutotrackCapability = ptzAutotrackCapability;
|
|
|
116947
117206
|
exports.ptzCapability = ptzCapability;
|
|
116948
117207
|
exports.publicEventCategories = require_event_category.publicEventCategories;
|
|
116949
117208
|
exports.pythonScriptForBackend = pythonScriptForBackend;
|
|
117209
|
+
exports.quantityFromUnit = quantityFromUnit;
|
|
116950
117210
|
exports.rankStreams = rankStreams;
|
|
116951
117211
|
exports.readClusterStepModels = readClusterStepModels;
|
|
116952
117212
|
exports.readClusterStepSettings = readClusterStepSettings;
|
|
@@ -116965,6 +117225,7 @@ exports.readRecoveryRecipeForSteps = readRecoveryRecipeForSteps;
|
|
|
116965
117225
|
exports.readTimelapseGeneratedAt = readTimelapseGeneratedAt;
|
|
116966
117226
|
exports.readUseRootModel = readUseRootModel;
|
|
116967
117227
|
exports.readinessKey = require_sleep.readinessKey;
|
|
117228
|
+
exports.readingMeta = require_sleep.readingMeta;
|
|
116968
117229
|
exports.rebootCapability = rebootCapability;
|
|
116969
117230
|
exports.recommendNode = recommendNode;
|
|
116970
117231
|
exports.reconcileBlockDevices = reconcileBlockDevices;
|
|
@@ -117065,6 +117326,7 @@ exports.runningFromMediaPlayer = runningFromMediaPlayer;
|
|
|
117065
117326
|
exports.runningFromVacuumState = runningFromVacuumState;
|
|
117066
117327
|
exports.runningStateCapability = runningStateCapability;
|
|
117067
117328
|
exports.runtimeDevices = runtimeDevices;
|
|
117329
|
+
exports.runtimeFieldUnit = runtimeFieldUnit;
|
|
117068
117330
|
exports.runtimeStatePolicyFor = runtimeStatePolicyFor;
|
|
117069
117331
|
exports.sameDoFamily = sameDoFamily;
|
|
117070
117332
|
exports.sameRead = sameRead;
|
|
@@ -117184,6 +117446,8 @@ exports.templateVarSystemEventApplies = templateVarSystemEventApplies;
|
|
|
117184
117446
|
exports.templateVarsFor = templateVarsFor;
|
|
117185
117447
|
exports.terminalSessionCapability = terminalSessionCapability;
|
|
117186
117448
|
exports.textToHtml = textToHtml;
|
|
117449
|
+
exports.thresholdToBase = thresholdToBase;
|
|
117450
|
+
exports.thresholdToDisplay = thresholdToDisplay;
|
|
117187
117451
|
exports.timeOfDayToMinutes = timeOfDayToMinutes;
|
|
117188
117452
|
exports.toAppLinkHubOrigin = toAppLinkHubOrigin;
|
|
117189
117453
|
exports.toDeviceSummary = toDeviceSummary;
|
|
@@ -117199,6 +117463,7 @@ exports.trainingCapability = trainingCapability;
|
|
|
117199
117463
|
exports.trainingProviderCapability = trainingProviderCapability;
|
|
117200
117464
|
exports.transcodeBody = transcodeBody;
|
|
117201
117465
|
exports.transformSecretWrite = require_sleep.transformSecretWrite;
|
|
117466
|
+
exports.tryConvertDelta = tryConvertDelta;
|
|
117202
117467
|
exports.tryConvertUnit = tryConvertUnit;
|
|
117203
117468
|
exports.turnProviderCapability = turnProviderCapability;
|
|
117204
117469
|
exports.unitCompanionField = unitCompanionField;
|