@camstack/types 1.2.416 → 1.2.418
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 +11 -6
- package/dist/capabilities/composer.cap.d.ts +198 -0
- 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 +1421 -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/group-status.cap.d.ts +46 -0
- package/dist/capabilities/humidity-sensor.cap.d.ts +3 -14
- package/dist/capabilities/index.d.ts +4 -2
- package/dist/capabilities/motion.cap.d.ts +13 -5
- 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 +57 -5
- package/dist/client.mjs +55 -6
- package/dist/composition/composition-report.d.ts +80 -3
- package/dist/composition/composition.d.ts +285 -5
- package/dist/composition/helpers/aggregate.d.ts +41 -0
- package/dist/composition/helpers/catalog.d.ts +42 -0
- package/dist/composition/helpers/compile.d.ts +22 -0
- package/dist/composition/helpers/index.d.ts +6 -0
- package/dist/composition/helpers/save.d.ts +18 -0
- package/dist/composition/helpers/source-pick.d.ts +40 -0
- package/dist/composition/helpers/spec.d.ts +38 -0
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/source-ref.d.ts +11 -0
- package/dist/composition/state-fields.d.ts +1 -1
- package/dist/composition/validate-composition.d.ts +8 -2
- package/dist/{composition-kEl9mevu.mjs → composition-B85l9j1M.mjs} +114 -8
- package/dist/{composition-DsmkwP9-.js → composition-OJKOJJD-.js} +179 -7
- package/dist/device/cap-vocabulary/entries/sensors.d.ts +1 -1
- 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-api.d.ts +14 -0
- package/dist/generated/addon-cap-facts.d.ts +1 -1
- package/dist/generated/cap-status-types.d.ts +3 -1
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/customize-catalog.d.ts +11 -87
- package/dist/generated/device-local-state.d.ts +3 -0
- package/dist/generated/device-proxy.d.ts +3 -0
- package/dist/generated/history-catalog.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +1 -1
- package/dist/generated/runtime-state-durability.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1458 -499
- package/dist/index.mjs +1420 -499
- package/dist/node.js +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{sleep-BPQ2ZyaI.js → sleep-7Gw3GJ4n.js} +232 -127
- package/dist/{sleep-BErAxhul.mjs → sleep-B81gwQuR.mjs} +179 -128
- 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,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-7Gw3GJ4n.js");
|
|
3
3
|
const require_event_category = require("./event-category-DXZ3f9Q5.js");
|
|
4
|
-
const require_composition = require("./composition-
|
|
4
|
+
const require_composition = require("./composition-OJKOJJD-.js");
|
|
5
5
|
const require_node_color = require("./node-color.js");
|
|
6
6
|
const require_err_msg = require("./err-msg-BhVbr0NX.js");
|
|
7
7
|
const require_enums = require("./enums.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,11 @@ 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",
|
|
12628
|
+
"mixed-quantity",
|
|
12629
|
+
"helper-mismatch",
|
|
12630
|
+
"member-constraint"
|
|
12612
12631
|
]);
|
|
12613
12632
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
12614
12633
|
var CompositionProblemSchema = zod.z.object({
|
|
@@ -12632,7 +12651,8 @@ var CompositionUnavailableModeSchema = zod.z.enum([
|
|
|
12632
12651
|
"null",
|
|
12633
12652
|
"offline",
|
|
12634
12653
|
"unknown",
|
|
12635
|
-
"release"
|
|
12654
|
+
"release",
|
|
12655
|
+
"omit"
|
|
12636
12656
|
]);
|
|
12637
12657
|
/**
|
|
12638
12658
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -12674,9 +12694,11 @@ function compositionFieldKey(plan) {
|
|
|
12674
12694
|
return `${plan.cap}.${path}`;
|
|
12675
12695
|
}
|
|
12676
12696
|
/**
|
|
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
|
-
*
|
|
12697
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
12698
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
12699
|
+
* Replacing a capability the device already serves is refused
|
|
12700
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
12701
|
+
* wire for a claim the hub already holds.
|
|
12680
12702
|
*/
|
|
12681
12703
|
var CompositionFeatureModeSchema = zod.z.enum([
|
|
12682
12704
|
"new",
|
|
@@ -13001,6 +13023,24 @@ function inferExpressionKinds(input) {
|
|
|
13001
13023
|
* planner (`composition-items.ts`). Internal to the composition module — NOT
|
|
13002
13024
|
* in the barrel: these are planner internals, not a published contract.
|
|
13003
13025
|
*/
|
|
13026
|
+
function aggregateKinds(source) {
|
|
13027
|
+
if (source.publish !== "value") return {
|
|
13028
|
+
ok: true,
|
|
13029
|
+
kinds: new Set(["number"])
|
|
13030
|
+
};
|
|
13031
|
+
if (source.reducer === "any" || source.reducer === "all") return {
|
|
13032
|
+
ok: true,
|
|
13033
|
+
kinds: new Set(["boolean"])
|
|
13034
|
+
};
|
|
13035
|
+
if (source.empty === "null") return {
|
|
13036
|
+
ok: true,
|
|
13037
|
+
kinds: new Set(["number", "null"])
|
|
13038
|
+
};
|
|
13039
|
+
return {
|
|
13040
|
+
ok: true,
|
|
13041
|
+
kinds: new Set(["number"])
|
|
13042
|
+
};
|
|
13043
|
+
}
|
|
13004
13044
|
function readKinds(read, lookupCap) {
|
|
13005
13045
|
const def = lookupCap(read.cap);
|
|
13006
13046
|
const schema = def?.runtimeState ?? def?.status?.schema;
|
|
@@ -13028,6 +13068,7 @@ function sourceKinds(source, lookupCap) {
|
|
|
13028
13068
|
code: "reserved-variant",
|
|
13029
13069
|
message: "code fields arrive in slice 4"
|
|
13030
13070
|
};
|
|
13071
|
+
if (source.kind === "aggregate") return aggregateKinds(source);
|
|
13031
13072
|
const bindingKinds = /* @__PURE__ */ new Map();
|
|
13032
13073
|
for (const [name, binding] of Object.entries(source.bindings)) {
|
|
13033
13074
|
if (binding.kind === "literal") {
|
|
@@ -13224,6 +13265,388 @@ function planItems(def, feature, featureIndex, lookupCap, mode = "new") {
|
|
|
13224
13265
|
};
|
|
13225
13266
|
}
|
|
13226
13267
|
//#endregion
|
|
13268
|
+
//#region src/composition/helpers/catalog.ts
|
|
13269
|
+
/**
|
|
13270
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
13271
|
+
* Data, not a form default written into the block.
|
|
13272
|
+
*/
|
|
13273
|
+
var NOW = {
|
|
13274
|
+
fieldPath: "lastFetchedAt",
|
|
13275
|
+
expr: "now"
|
|
13276
|
+
};
|
|
13277
|
+
var CHANGED = {
|
|
13278
|
+
fieldPath: "lastChangedAt",
|
|
13279
|
+
expr: "now"
|
|
13280
|
+
};
|
|
13281
|
+
function numeric(input) {
|
|
13282
|
+
return {
|
|
13283
|
+
...input,
|
|
13284
|
+
family: "numeric",
|
|
13285
|
+
deviceType: require_err_msg.DeviceType.Sensor,
|
|
13286
|
+
memberDeviceType: require_err_msg.DeviceType.Sensor,
|
|
13287
|
+
baseUnit: require_sleep.baseUnitOf(input.quantity),
|
|
13288
|
+
aggregates: require_composition.NUMERIC_AGGREGATES,
|
|
13289
|
+
accept: [{
|
|
13290
|
+
cap: input.outputCap,
|
|
13291
|
+
fieldPath: input.outputField
|
|
13292
|
+
}]
|
|
13293
|
+
};
|
|
13294
|
+
}
|
|
13295
|
+
function binary(input) {
|
|
13296
|
+
return {
|
|
13297
|
+
...input,
|
|
13298
|
+
family: "binary",
|
|
13299
|
+
deviceType: require_err_msg.DeviceType.Sensor,
|
|
13300
|
+
memberDeviceType: require_err_msg.DeviceType.Sensor,
|
|
13301
|
+
quantity: "none",
|
|
13302
|
+
baseUnit: void 0,
|
|
13303
|
+
aggregates: require_composition.BINARY_AGGREGATES,
|
|
13304
|
+
empty: "offline"
|
|
13305
|
+
};
|
|
13306
|
+
}
|
|
13307
|
+
var GROUP_TEMPLATES = [
|
|
13308
|
+
numeric({
|
|
13309
|
+
id: "temperature",
|
|
13310
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
13311
|
+
role: require_err_msg.DeviceRole.TemperatureSensor,
|
|
13312
|
+
outputCap: "temperature-sensor",
|
|
13313
|
+
outputField: "celsius",
|
|
13314
|
+
quantity: "temperature",
|
|
13315
|
+
defaultAggregate: "mean",
|
|
13316
|
+
empty: "null",
|
|
13317
|
+
companions: [NOW]
|
|
13318
|
+
}),
|
|
13319
|
+
numeric({
|
|
13320
|
+
id: "humidity",
|
|
13321
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
13322
|
+
role: require_err_msg.DeviceRole.HumiditySensor,
|
|
13323
|
+
outputCap: "humidity-sensor",
|
|
13324
|
+
outputField: "percent",
|
|
13325
|
+
quantity: "humidity",
|
|
13326
|
+
defaultAggregate: "mean",
|
|
13327
|
+
empty: "null",
|
|
13328
|
+
companions: [NOW]
|
|
13329
|
+
}),
|
|
13330
|
+
numeric({
|
|
13331
|
+
id: "pressure",
|
|
13332
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
13333
|
+
role: require_err_msg.DeviceRole.PressureSensor,
|
|
13334
|
+
outputCap: "pressure-sensor",
|
|
13335
|
+
outputField: "hpa",
|
|
13336
|
+
quantity: "pressure",
|
|
13337
|
+
defaultAggregate: "mean",
|
|
13338
|
+
empty: "null",
|
|
13339
|
+
companions: [NOW]
|
|
13340
|
+
}),
|
|
13341
|
+
numeric({
|
|
13342
|
+
id: "illuminance",
|
|
13343
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
13344
|
+
role: require_err_msg.DeviceRole.AmbientLightSensor,
|
|
13345
|
+
outputCap: "ambient-light-sensor",
|
|
13346
|
+
outputField: "lux",
|
|
13347
|
+
quantity: "illuminance",
|
|
13348
|
+
defaultAggregate: "mean",
|
|
13349
|
+
empty: "null",
|
|
13350
|
+
companions: [NOW]
|
|
13351
|
+
}),
|
|
13352
|
+
numeric({
|
|
13353
|
+
id: "power",
|
|
13354
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
13355
|
+
role: require_err_msg.DeviceRole.PowerSensor,
|
|
13356
|
+
outputCap: "power-meter",
|
|
13357
|
+
outputField: "watts",
|
|
13358
|
+
quantity: "power",
|
|
13359
|
+
defaultAggregate: "sum",
|
|
13360
|
+
empty: "omit",
|
|
13361
|
+
companions: [NOW]
|
|
13362
|
+
}),
|
|
13363
|
+
numeric({
|
|
13364
|
+
id: "energy",
|
|
13365
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
13366
|
+
role: require_err_msg.DeviceRole.EnergySensor,
|
|
13367
|
+
outputCap: "power-meter",
|
|
13368
|
+
outputField: "kwhTotal",
|
|
13369
|
+
quantity: "energy",
|
|
13370
|
+
defaultAggregate: "sum",
|
|
13371
|
+
empty: "omit",
|
|
13372
|
+
companions: [NOW]
|
|
13373
|
+
}),
|
|
13374
|
+
numeric({
|
|
13375
|
+
id: "battery",
|
|
13376
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
13377
|
+
role: require_err_msg.DeviceRole.BatterySensor,
|
|
13378
|
+
outputCap: "battery",
|
|
13379
|
+
outputField: "percentage",
|
|
13380
|
+
quantity: "percentage",
|
|
13381
|
+
defaultAggregate: "mean",
|
|
13382
|
+
empty: "null",
|
|
13383
|
+
companions: [
|
|
13384
|
+
{
|
|
13385
|
+
fieldPath: "charging",
|
|
13386
|
+
expr: "\"unknown\""
|
|
13387
|
+
},
|
|
13388
|
+
{
|
|
13389
|
+
fieldPath: "sleeping",
|
|
13390
|
+
expr: "false"
|
|
13391
|
+
},
|
|
13392
|
+
{
|
|
13393
|
+
fieldPath: "lastUpdated",
|
|
13394
|
+
expr: "now"
|
|
13395
|
+
}
|
|
13396
|
+
]
|
|
13397
|
+
}),
|
|
13398
|
+
numeric({
|
|
13399
|
+
id: "numeric",
|
|
13400
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
13401
|
+
role: require_err_msg.DeviceRole.NumericSensor,
|
|
13402
|
+
outputCap: "numeric-sensor",
|
|
13403
|
+
outputField: "value",
|
|
13404
|
+
quantity: "device",
|
|
13405
|
+
defaultAggregate: "mean",
|
|
13406
|
+
empty: "null",
|
|
13407
|
+
companions: [NOW]
|
|
13408
|
+
}),
|
|
13409
|
+
binary({
|
|
13410
|
+
id: "motion",
|
|
13411
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
13412
|
+
role: require_err_msg.DeviceRole.MotionSensor,
|
|
13413
|
+
outputCap: "motion",
|
|
13414
|
+
outputField: "detected",
|
|
13415
|
+
defaultAggregate: "any",
|
|
13416
|
+
accept: [{
|
|
13417
|
+
cap: "motion",
|
|
13418
|
+
fieldPath: "detected"
|
|
13419
|
+
}],
|
|
13420
|
+
companions: [{
|
|
13421
|
+
fieldPath: "lastDetectedAt",
|
|
13422
|
+
expr: "null"
|
|
13423
|
+
}, {
|
|
13424
|
+
fieldPath: "autoClearAfterMs",
|
|
13425
|
+
expr: "null"
|
|
13426
|
+
}]
|
|
13427
|
+
}),
|
|
13428
|
+
binary({
|
|
13429
|
+
id: "contact",
|
|
13430
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
13431
|
+
role: require_err_msg.DeviceRole.ContactSensor,
|
|
13432
|
+
outputCap: "contact",
|
|
13433
|
+
outputField: "entryOpen",
|
|
13434
|
+
defaultAggregate: "any",
|
|
13435
|
+
accept: [{
|
|
13436
|
+
cap: "contact",
|
|
13437
|
+
fieldPath: "entryOpen"
|
|
13438
|
+
}],
|
|
13439
|
+
companions: [CHANGED]
|
|
13440
|
+
}),
|
|
13441
|
+
binary({
|
|
13442
|
+
id: "leak",
|
|
13443
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
13444
|
+
role: require_err_msg.DeviceRole.LeakSensor,
|
|
13445
|
+
outputCap: "flood",
|
|
13446
|
+
outputField: "flooded",
|
|
13447
|
+
defaultAggregate: "any",
|
|
13448
|
+
accept: [{
|
|
13449
|
+
cap: "flood",
|
|
13450
|
+
fieldPath: "flooded"
|
|
13451
|
+
}],
|
|
13452
|
+
companions: [CHANGED]
|
|
13453
|
+
}),
|
|
13454
|
+
binary({
|
|
13455
|
+
id: "smoke",
|
|
13456
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
13457
|
+
role: require_err_msg.DeviceRole.SmokeSensor,
|
|
13458
|
+
outputCap: "smoke",
|
|
13459
|
+
outputField: "detected",
|
|
13460
|
+
defaultAggregate: "any",
|
|
13461
|
+
accept: [{
|
|
13462
|
+
cap: "smoke",
|
|
13463
|
+
fieldPath: "detected"
|
|
13464
|
+
}],
|
|
13465
|
+
companions: [CHANGED]
|
|
13466
|
+
}),
|
|
13467
|
+
binary({
|
|
13468
|
+
id: "occupancy",
|
|
13469
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
13470
|
+
role: require_err_msg.DeviceRole.BinarySensor,
|
|
13471
|
+
outputCap: "binary",
|
|
13472
|
+
outputField: "on",
|
|
13473
|
+
defaultAggregate: "any",
|
|
13474
|
+
accept: [{
|
|
13475
|
+
cap: "motion",
|
|
13476
|
+
fieldPath: "detected"
|
|
13477
|
+
}, {
|
|
13478
|
+
cap: "binary",
|
|
13479
|
+
fieldPath: "on"
|
|
13480
|
+
}],
|
|
13481
|
+
companions: [CHANGED]
|
|
13482
|
+
}),
|
|
13483
|
+
binary({
|
|
13484
|
+
id: "binary",
|
|
13485
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
13486
|
+
role: require_err_msg.DeviceRole.BinarySensor,
|
|
13487
|
+
outputCap: "binary",
|
|
13488
|
+
outputField: "on",
|
|
13489
|
+
defaultAggregate: "any",
|
|
13490
|
+
accept: [{
|
|
13491
|
+
cap: "binary",
|
|
13492
|
+
fieldPath: "on"
|
|
13493
|
+
}],
|
|
13494
|
+
companions: [CHANGED]
|
|
13495
|
+
})
|
|
13496
|
+
];
|
|
13497
|
+
var BY_ID = new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
13498
|
+
function groupTemplate(id) {
|
|
13499
|
+
return BY_ID.get(id) ?? null;
|
|
13500
|
+
}
|
|
13501
|
+
//#endregion
|
|
13502
|
+
//#region src/composition/helpers/compile.ts
|
|
13503
|
+
function sameSource(a, b) {
|
|
13504
|
+
return a.addonId === b.addonId && a.stableId === b.stableId;
|
|
13505
|
+
}
|
|
13506
|
+
function sameMember(a, b) {
|
|
13507
|
+
return sameSource(a.source, b.source) && a.cap === b.cap && a.fieldPath === b.fieldPath;
|
|
13508
|
+
}
|
|
13509
|
+
function accepted(template, member) {
|
|
13510
|
+
return template.accept.some((field) => field.cap === member.cap && field.fieldPath === member.fieldPath);
|
|
13511
|
+
}
|
|
13512
|
+
function memberProblems(template, spec) {
|
|
13513
|
+
return spec.members.flatMap((member, index) => {
|
|
13514
|
+
const at = `helper.members[${index}]`;
|
|
13515
|
+
const problems = [];
|
|
13516
|
+
if (!accepted(template, member)) {
|
|
13517
|
+
const allowed = template.accept.map((field) => `${field.cap}.${field.fieldPath}`).join(" or ");
|
|
13518
|
+
problems.push(problem("member-constraint", at, `a ${template.id} group reads ${allowed}; this member is ${member.cap}.${member.fieldPath}`));
|
|
13519
|
+
}
|
|
13520
|
+
if (spec.members.slice(0, index).some((other) => sameMember(other, member))) problems.push(problem("member-constraint", at, "this member is already in the group"));
|
|
13521
|
+
return problems;
|
|
13522
|
+
});
|
|
13523
|
+
}
|
|
13524
|
+
function aggregateSource(template, spec, reads, publish) {
|
|
13525
|
+
return {
|
|
13526
|
+
kind: "aggregate",
|
|
13527
|
+
reducer: spec.aggregate,
|
|
13528
|
+
reads: [...reads],
|
|
13529
|
+
publish,
|
|
13530
|
+
empty: template.empty
|
|
13531
|
+
};
|
|
13532
|
+
}
|
|
13533
|
+
function expressionSource(expr) {
|
|
13534
|
+
return {
|
|
13535
|
+
kind: "expression",
|
|
13536
|
+
expr,
|
|
13537
|
+
bindings: {}
|
|
13538
|
+
};
|
|
13539
|
+
}
|
|
13540
|
+
function draftOf$1(template, spec) {
|
|
13541
|
+
const reads = spec.members.map((member) => ({
|
|
13542
|
+
source: member.source,
|
|
13543
|
+
cap: member.cap,
|
|
13544
|
+
fieldPath: member.fieldPath
|
|
13545
|
+
}));
|
|
13546
|
+
const companions = Object.fromEntries(template.companions.map((companion) => [companion.fieldPath, expressionSource(companion.expr)]));
|
|
13547
|
+
return {
|
|
13548
|
+
target: {
|
|
13549
|
+
kind: "new",
|
|
13550
|
+
type: template.deviceType,
|
|
13551
|
+
role: template.role
|
|
13552
|
+
},
|
|
13553
|
+
helper: spec,
|
|
13554
|
+
features: [{
|
|
13555
|
+
kind: "fields",
|
|
13556
|
+
cap: template.outputCap,
|
|
13557
|
+
fields: {
|
|
13558
|
+
[template.outputField]: aggregateSource(template, spec, reads, "value"),
|
|
13559
|
+
...companions
|
|
13560
|
+
}
|
|
13561
|
+
}, {
|
|
13562
|
+
kind: "fields",
|
|
13563
|
+
cap: "group-status",
|
|
13564
|
+
fields: {
|
|
13565
|
+
included: aggregateSource(template, spec, reads, "included"),
|
|
13566
|
+
excluded: aggregateSource(template, spec, reads, "excluded"),
|
|
13567
|
+
total: aggregateSource(template, spec, reads, "total")
|
|
13568
|
+
}
|
|
13569
|
+
}]
|
|
13570
|
+
};
|
|
13571
|
+
}
|
|
13572
|
+
function parseDraft(draft) {
|
|
13573
|
+
const parsed = require_composition.CompositionSchema.safeParse(draft);
|
|
13574
|
+
if (parsed.success) return {
|
|
13575
|
+
ok: true,
|
|
13576
|
+
composition: parsed.data
|
|
13577
|
+
};
|
|
13578
|
+
return {
|
|
13579
|
+
ok: false,
|
|
13580
|
+
problems: [problem("helper-mismatch", "helper", `the template did not compile: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`)]
|
|
13581
|
+
};
|
|
13582
|
+
}
|
|
13583
|
+
/** Compile a group template to a new-device composition. Refusals are named. */
|
|
13584
|
+
function compileHelper(spec) {
|
|
13585
|
+
const template = groupTemplate(spec.templateId);
|
|
13586
|
+
if (template === null) return {
|
|
13587
|
+
ok: false,
|
|
13588
|
+
problems: [problem("member-constraint", "helper.templateId", `unknown template \`${spec.templateId}\``)]
|
|
13589
|
+
};
|
|
13590
|
+
if (!template.aggregates.includes(spec.aggregate)) {
|
|
13591
|
+
const allowed = template.aggregates.join(", ");
|
|
13592
|
+
return {
|
|
13593
|
+
ok: false,
|
|
13594
|
+
problems: [problem("kind-mismatch", "helper.aggregate", `a ${template.id} group aggregates by ${allowed}, not \`${spec.aggregate}\``)]
|
|
13595
|
+
};
|
|
13596
|
+
}
|
|
13597
|
+
const members = memberProblems(template, spec);
|
|
13598
|
+
if (members.length > 0) return {
|
|
13599
|
+
ok: false,
|
|
13600
|
+
problems: members
|
|
13601
|
+
};
|
|
13602
|
+
return parseDraft(draftOf$1(template, spec));
|
|
13603
|
+
}
|
|
13604
|
+
/** The built body, ignoring `helper`, so a save can demand one writer. */
|
|
13605
|
+
function sameHelperBody(stored, compiled) {
|
|
13606
|
+
return JSON.stringify(stored.target) === JSON.stringify(compiled.target) && JSON.stringify(stored.features) === JSON.stringify(compiled.features);
|
|
13607
|
+
}
|
|
13608
|
+
function templateDeviceType(spec) {
|
|
13609
|
+
return groupTemplate(spec.templateId)?.memberDeviceType ?? null;
|
|
13610
|
+
}
|
|
13611
|
+
//#endregion
|
|
13612
|
+
//#region src/composition/helpers/save.ts
|
|
13613
|
+
function quantityProblems(spec, facts) {
|
|
13614
|
+
const template = groupTemplate(spec.templateId);
|
|
13615
|
+
if (template === null || template.family !== "numeric") return [];
|
|
13616
|
+
const known = spec.members.flatMap((member, index) => {
|
|
13617
|
+
const quantity = facts.get(require_composition.compositionSourceKey(member.source))?.quantity;
|
|
13618
|
+
return quantity === void 0 ? [] : [{
|
|
13619
|
+
index,
|
|
13620
|
+
quantity
|
|
13621
|
+
}];
|
|
13622
|
+
});
|
|
13623
|
+
if (template.quantity !== "device") return known.flatMap((member) => member.quantity === template.quantity ? [] : [problem("mixed-quantity", `helper.members[${member.index}]`, `a ${template.id} group is ${template.quantity}${template.baseUnit === void 0 ? "" : ` (${template.baseUnit})`}; this member is ${member.quantity}`)]);
|
|
13624
|
+
const distinct = [...new Set(known.map((member) => member.quantity))];
|
|
13625
|
+
if (distinct.length <= 1) return [];
|
|
13626
|
+
return [problem("mixed-quantity", "helper.members", `a numeric group requires one quantity; members report ${distinct.join(" and ")}`)];
|
|
13627
|
+
}
|
|
13628
|
+
function deviceTypeProblems(spec, facts) {
|
|
13629
|
+
const template = groupTemplate(spec.templateId);
|
|
13630
|
+
if (template === null) return [];
|
|
13631
|
+
return spec.members.flatMap((member, index) => {
|
|
13632
|
+
const deviceType = facts.get(require_composition.compositionSourceKey(member.source))?.deviceType;
|
|
13633
|
+
if (deviceType === void 0 || deviceType === template.memberDeviceType) return [];
|
|
13634
|
+
return [problem("member-constraint", `helper.members[${index}]`, `a ${template.id} group takes ${template.memberDeviceType} devices; this member is a ${deviceType}`)];
|
|
13635
|
+
});
|
|
13636
|
+
}
|
|
13637
|
+
/**
|
|
13638
|
+
* Problems that refuse a save. No `helper` key means a free composition: this
|
|
13639
|
+
* returns nothing, and expression semantics stay as they are.
|
|
13640
|
+
*/
|
|
13641
|
+
function helperSaveProblems(composition, facts) {
|
|
13642
|
+
const spec = composition.helper;
|
|
13643
|
+
if (spec === void 0) return [];
|
|
13644
|
+
const compiled = compileHelper(spec);
|
|
13645
|
+
if (!compiled.ok) return compiled.problems;
|
|
13646
|
+
if (!sameHelperBody(composition, compiled.composition)) return [problem("helper-mismatch", "helper", "the stored features are not this template — the helper spec is the only writer")];
|
|
13647
|
+
return [...quantityProblems(spec, facts), ...deviceTypeProblems(spec, facts)];
|
|
13648
|
+
}
|
|
13649
|
+
//#endregion
|
|
13227
13650
|
//#region src/composition/composition-graph.ts
|
|
13228
13651
|
/**
|
|
13229
13652
|
* The field graph across every composition, and the cycles in it (D659).
|
|
@@ -13454,6 +13877,7 @@ function planTopLevelField({ def, fields }, field, mode, lookupCap) {
|
|
|
13454
13877
|
const role = roleOf(source);
|
|
13455
13878
|
const unavailable = unavailableFor(tf, role, mode, def.name, fieldAt);
|
|
13456
13879
|
if (!unavailable.ok) return refused(unavailable.problem);
|
|
13880
|
+
const omitEmpty = source.kind === "aggregate" && source.publish === "value" && source.empty === "omit";
|
|
13457
13881
|
const plan = {
|
|
13458
13882
|
cap: def.name,
|
|
13459
13883
|
path,
|
|
@@ -13461,7 +13885,7 @@ function planTopLevelField({ def, fields }, field, mode, lookupCap) {
|
|
|
13461
13885
|
kind: tf.kind,
|
|
13462
13886
|
nullable: tf.nullable,
|
|
13463
13887
|
required: tf.required,
|
|
13464
|
-
unavailable: unavailable.unavailable,
|
|
13888
|
+
unavailable: omitEmpty ? "omit" : unavailable.unavailable,
|
|
13465
13889
|
role,
|
|
13466
13890
|
source,
|
|
13467
13891
|
reads: [...require_composition.fieldReads(source)]
|
|
@@ -13510,6 +13934,9 @@ function isNativeCap(target, cap) {
|
|
|
13510
13934
|
const owner = target.nativeCaps.get(cap);
|
|
13511
13935
|
return owner !== void 0 && owner !== "composer";
|
|
13512
13936
|
}
|
|
13937
|
+
function isPlanProblem(value) {
|
|
13938
|
+
return "code" in value;
|
|
13939
|
+
}
|
|
13513
13940
|
/** The target read, or the refusal that replaces the whole plan when it could not be (D391). */
|
|
13514
13941
|
function planTargetOf(composition, target) {
|
|
13515
13942
|
if (composition.target.kind === "new") return {
|
|
@@ -13525,26 +13952,59 @@ function planTargetOf(composition, target) {
|
|
|
13525
13952
|
found: target
|
|
13526
13953
|
};
|
|
13527
13954
|
}
|
|
13528
|
-
|
|
13955
|
+
var NATIVE_REPLACE_KEPT = new Set([
|
|
13956
|
+
"not-composable",
|
|
13957
|
+
"unknown-capability",
|
|
13958
|
+
"reserved-variant"
|
|
13959
|
+
]);
|
|
13960
|
+
/** A native override is refused, unless the cap cannot be composed at all — that reason stays. */
|
|
13961
|
+
function nativeReplaceOrBlock(refusal, probed) {
|
|
13962
|
+
const kept = probed.problems.filter((item) => NATIVE_REPLACE_KEPT.has(item.code));
|
|
13963
|
+
if (kept.length > 0) return {
|
|
13964
|
+
problems: kept,
|
|
13965
|
+
fields: [],
|
|
13966
|
+
features: [],
|
|
13967
|
+
events: []
|
|
13968
|
+
};
|
|
13969
|
+
return refused(refusal);
|
|
13970
|
+
}
|
|
13971
|
+
function featureTargetOf(target, cap, at) {
|
|
13529
13972
|
if (target.kind === "new") return {
|
|
13530
13973
|
mode: "new",
|
|
13531
13974
|
deviceType: target.type
|
|
13532
13975
|
};
|
|
13976
|
+
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
13977
|
return {
|
|
13534
|
-
mode:
|
|
13978
|
+
mode: "add",
|
|
13535
13979
|
deviceType: target.found.type
|
|
13536
13980
|
};
|
|
13537
13981
|
}
|
|
13538
13982
|
/**
|
|
13539
13983
|
* 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
|
-
*
|
|
13984
|
+
* it is ignored for a new one. On an existing target each feature ADDS a cap
|
|
13985
|
+
* the device lacks. A feature that would replace a native capability is
|
|
13986
|
+
* refused by name (D944). A new device is unchanged.
|
|
13542
13987
|
*/
|
|
13543
13988
|
function planComposition(composition, lookupCap, target) {
|
|
13544
13989
|
const planTarget = planTargetOf(composition, target);
|
|
13545
13990
|
if ("code" in planTarget) return refused(planTarget);
|
|
13546
13991
|
const results = composition.features.map((feature, index) => {
|
|
13547
|
-
const
|
|
13992
|
+
const at = `features[${index}]`;
|
|
13993
|
+
if (feature.kind === "passthrough") return refused(problem("reserved-variant", at, `whole-capability passthrough of \`${feature.cap}\` arrives in slice 3`));
|
|
13994
|
+
const featureTarget = featureTargetOf(planTarget, feature.cap, at);
|
|
13995
|
+
if (isPlanProblem(featureTarget)) {
|
|
13996
|
+
if (!require_composition.compositionFeatureEnabled(feature) || planTarget.kind !== "existing") return {
|
|
13997
|
+
problems: [],
|
|
13998
|
+
fields: [],
|
|
13999
|
+
features: [],
|
|
14000
|
+
events: []
|
|
14001
|
+
};
|
|
14002
|
+
return nativeReplaceOrBlock(featureTarget, planFeature(feature, index, {
|
|
14003
|
+
mode: "add",
|
|
14004
|
+
deviceType: planTarget.found.type
|
|
14005
|
+
}, lookupCap));
|
|
14006
|
+
}
|
|
14007
|
+
const result = planFeature(feature, index, featureTarget, lookupCap);
|
|
13548
14008
|
return require_composition.compositionFeatureEnabled(feature) ? result : {
|
|
13549
14009
|
problems: result.problems,
|
|
13550
14010
|
fields: [],
|
|
@@ -13685,11 +14145,20 @@ function cycleProblems(composition, ctx, fields, self) {
|
|
|
13685
14145
|
function validateComposition(composition, ctx) {
|
|
13686
14146
|
const plan = planComposition(composition, ctx.lookupCap, ctx.target ?? void 0);
|
|
13687
14147
|
const self = candidateSelf(composition, ctx, plan);
|
|
13688
|
-
const
|
|
14148
|
+
const refusedFeatures = plan.problems.filter((item) => item.code === "native-capability-replace").map((item) => item.path);
|
|
14149
|
+
const cycles = cycleProblems(composition, ctx, plan.fields, self).filter((item) => {
|
|
14150
|
+
if (refusedFeatures.some((at) => item.path === at || item.path.startsWith(`${at}.`))) return false;
|
|
14151
|
+
return refusedFeatures.length === 0 || item.path !== "features";
|
|
14152
|
+
});
|
|
14153
|
+
const facts = new Map([...ctx.sources].flatMap(([key, source]) => source.kind === "found" ? [[key, {
|
|
14154
|
+
deviceType: source.deviceType,
|
|
14155
|
+
quantity: source.quantity
|
|
14156
|
+
}]] : []));
|
|
13689
14157
|
const problems = [
|
|
13690
14158
|
...plan.problems,
|
|
13691
14159
|
...sourceProblems(plan.fields, ctx, self),
|
|
13692
|
-
...cycles
|
|
14160
|
+
...cycles,
|
|
14161
|
+
...helperSaveProblems(composition, facts)
|
|
13693
14162
|
];
|
|
13694
14163
|
return {
|
|
13695
14164
|
ok: problems.length === 0,
|
|
@@ -16432,12 +16901,12 @@ function parseAdminBase(baseUrl) {
|
|
|
16432
16901
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
16433
16902
|
* in-place so dispatch keeps working.
|
|
16434
16903
|
*
|
|
16435
|
-
* **
|
|
16436
|
-
*
|
|
16437
|
-
*
|
|
16438
|
-
*
|
|
16439
|
-
* (`ha-domain-mapping`)
|
|
16440
|
-
* stored after that point.
|
|
16904
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
16905
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
16906
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
16907
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
16908
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
16909
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
16441
16910
|
*
|
|
16442
16911
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
16443
16912
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -16451,6 +16920,14 @@ var SourceInfoSchema = zod.z.object({
|
|
|
16451
16920
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
16452
16921
|
* Used to detect rename when `id` changes. */
|
|
16453
16922
|
uniqueId: zod.z.string().optional(),
|
|
16923
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
16924
|
+
quantity: require_sleep.ReadingQuantitySchema.optional(),
|
|
16925
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
16926
|
+
dateTimeShape: zod.z.enum([
|
|
16927
|
+
"date",
|
|
16928
|
+
"time",
|
|
16929
|
+
"datetime"
|
|
16930
|
+
]).optional(),
|
|
16454
16931
|
/** Provider-specific extras that don't fit the structured slots.
|
|
16455
16932
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
16456
16933
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -16535,9 +17012,38 @@ function normalizeUnit(raw) {
|
|
|
16535
17012
|
if (lower === "mph") return "mph";
|
|
16536
17013
|
if (lower === "m/s") return "m/s";
|
|
16537
17014
|
if (lower === "m") return "m";
|
|
17015
|
+
if (lower === "m²" || lower === "m2") return "m²";
|
|
17016
|
+
if (lower === "mm") return "mm";
|
|
17017
|
+
if (lower === "cm") return "cm";
|
|
16538
17018
|
if (lower === "km") return "km";
|
|
17019
|
+
if (lower === "in" || lower === "inch" || lower === "inches") return "in";
|
|
17020
|
+
if (lower === "ft" || lower === "foot" || lower === "feet") return "ft";
|
|
16539
17021
|
if (lower === "kg") return "kg";
|
|
16540
17022
|
if (lower === "g") return "g";
|
|
17023
|
+
if (lower === "l" || lower === "liter" || lower === "litre" || lower === "liters" || lower === "litres") return "L";
|
|
17024
|
+
if (lower === "ml") return "mL";
|
|
17025
|
+
if (lower === "gal" || lower === "gallon" || lower === "gallons") return "gal";
|
|
17026
|
+
if (lower === "s" || lower === "sec" || lower === "second" || lower === "seconds") return "s";
|
|
17027
|
+
if (lower === "ms") return "ms";
|
|
17028
|
+
if (lower === "min" || lower === "minute" || lower === "minutes") return "min";
|
|
17029
|
+
if (lower === "h" || lower === "hr" || lower === "hour" || lower === "hours") return "h";
|
|
17030
|
+
if (lower === "d" || lower === "day" || lower === "days") return "d";
|
|
17031
|
+
if (lower === "b" || lower === "byte" || lower === "bytes") return "B";
|
|
17032
|
+
if (lower === "kib") return "KiB";
|
|
17033
|
+
if (lower === "mib") return "MiB";
|
|
17034
|
+
if (lower === "gib") return "GiB";
|
|
17035
|
+
if (lower === "tib") return "TiB";
|
|
17036
|
+
if (lower === "kb") return "kB";
|
|
17037
|
+
if (lower === "mb") return "MB";
|
|
17038
|
+
if (lower === "gb") return "GB";
|
|
17039
|
+
if (lower === "dbm") return "dBm";
|
|
17040
|
+
if (lower === "dbfs") return "dBFS";
|
|
17041
|
+
if (lower === "inhg") return "inHg";
|
|
17042
|
+
if (lower === "mm/h") return "mm/h";
|
|
17043
|
+
if (lower === "w/m²" || lower === "w/m2") return "W/m²";
|
|
17044
|
+
if (lower === "°" || lower === "deg" || lower === "degree" || lower === "degrees") return "°";
|
|
17045
|
+
if (lower === "kbps") return "kbps";
|
|
17046
|
+
if (lower === "fps") return "fps";
|
|
16541
17047
|
return trimmed;
|
|
16542
17048
|
}
|
|
16543
17049
|
/**
|
|
@@ -37969,7 +38475,8 @@ var deviceManagerCapability = {
|
|
|
37969
38475
|
"enum"
|
|
37970
38476
|
]),
|
|
37971
38477
|
enumValues: zod.z.array(zod.z.string()).optional(),
|
|
37972
|
-
item: zod.z.boolean().optional()
|
|
38478
|
+
item: zod.z.boolean().optional(),
|
|
38479
|
+
quantity: require_sleep.ReadingQuantitySchema.optional()
|
|
37973
38480
|
})).readonly(),
|
|
37974
38481
|
itemArray: zod.z.object({
|
|
37975
38482
|
path: zod.z.string(),
|
|
@@ -44293,8 +44800,8 @@ var MaskPolygonShapeSchema = zod.z.object({
|
|
|
44293
44800
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44294
44801
|
var MaskGridShapeSchema = zod.z.object({
|
|
44295
44802
|
kind: zod.z.literal("grid"),
|
|
44296
|
-
gridWidth: zod.z.number(),
|
|
44297
|
-
gridHeight: zod.z.number(),
|
|
44803
|
+
gridWidth: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
44804
|
+
gridHeight: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
44298
44805
|
cells: zod.z.array(zod.z.boolean())
|
|
44299
44806
|
});
|
|
44300
44807
|
/** Directed line / tripwire — an ordered list of normalized points (≥2). */
|
|
@@ -60558,27 +61065,17 @@ var addonsCapability = {
|
|
|
60558
61065
|
*/
|
|
60559
61066
|
var AirQualitySensorStatusSchema = zod.z.object({
|
|
60560
61067
|
/** Carbon dioxide concentration in ppm. */
|
|
60561
|
-
co2Ppm: zod.z.number().min(0).optional(),
|
|
61068
|
+
co2Ppm: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-volume")),
|
|
60562
61069
|
/** Total volatile organic compounds in ppb. */
|
|
60563
|
-
vocPpb: zod.z.number().min(0).optional(),
|
|
61070
|
+
vocPpb: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-ppb")),
|
|
60564
61071
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
60565
|
-
pm25: zod.z.number().min(0).optional(),
|
|
61072
|
+
pm25: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-mass")),
|
|
60566
61073
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
60567
|
-
pm10: zod.z.number().min(0).optional(),
|
|
61074
|
+
pm10: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-mass")),
|
|
60568
61075
|
/** Composite AQI value (typically 0..500). */
|
|
60569
|
-
aqi: zod.z.number().optional(),
|
|
61076
|
+
aqi: zod.z.number().optional().meta(require_sleep.readingMeta("index")),
|
|
60570
61077
|
/** 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()
|
|
61078
|
+
lastFetchedAt: zod.z.number()
|
|
60582
61079
|
});
|
|
60583
61080
|
var airQualitySensorCapability = {
|
|
60584
61081
|
name: "air-quality-sensor",
|
|
@@ -60615,12 +61112,12 @@ var airQualitySensorCapability = {
|
|
|
60615
61112
|
},
|
|
60616
61113
|
pm25: {
|
|
60617
61114
|
kind: "gauge",
|
|
60618
|
-
unit: "
|
|
61115
|
+
unit: "µg/m³",
|
|
60619
61116
|
deadband: 1
|
|
60620
61117
|
},
|
|
60621
61118
|
pm10: {
|
|
60622
61119
|
kind: "gauge",
|
|
60623
|
-
unit: "
|
|
61120
|
+
unit: "µg/m³",
|
|
60624
61121
|
deadband: 1
|
|
60625
61122
|
},
|
|
60626
61123
|
aqi: {
|
|
@@ -60640,22 +61137,13 @@ var airQualitySensorCapability = {
|
|
|
60640
61137
|
* entries with `device_class: illuminance`.
|
|
60641
61138
|
*/
|
|
60642
61139
|
var AmbientLightSensorStatusSchema = zod.z.object({
|
|
60643
|
-
/** Current illuminance in lux (lx). */
|
|
60644
|
-
lux: zod.z.number().min(0).meta({
|
|
60645
|
-
|
|
61140
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
61141
|
+
lux: zod.z.number().min(0).nullable().meta(require_sleep.readingMeta("illuminance", {
|
|
61142
|
+
precision: 0,
|
|
60646
61143
|
label: "Illuminance"
|
|
60647
|
-
}),
|
|
61144
|
+
})),
|
|
60648
61145
|
/** 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()
|
|
61146
|
+
lastFetchedAt: zod.z.number()
|
|
60659
61147
|
});
|
|
60660
61148
|
var ambientLightSensorCapability = {
|
|
60661
61149
|
name: "ambient-light-sensor",
|
|
@@ -60687,12 +61175,7 @@ var ambientLightSensorCapability = {
|
|
|
60687
61175
|
} } },
|
|
60688
61176
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60689
61177
|
* whether persisting is worth a SQLite commit. */
|
|
60690
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60691
|
-
customize: {
|
|
60692
|
-
version: 1,
|
|
60693
|
-
advanced: "derive",
|
|
60694
|
-
targets: []
|
|
60695
|
-
}
|
|
61178
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60696
61179
|
};
|
|
60697
61180
|
//#endregion
|
|
60698
61181
|
//#region src/capabilities/audio-metrics.cap.ts
|
|
@@ -60934,10 +61417,7 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
60934
61417
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
60935
61418
|
* declines to band a non-finite reading, which is the correct shape.
|
|
60936
61419
|
*/
|
|
60937
|
-
percentage: zod.z.number().min(0).max(100).nullable().meta({
|
|
60938
|
-
unit: "%",
|
|
60939
|
-
label: "Charge"
|
|
60940
|
-
}),
|
|
61420
|
+
percentage: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage", { label: "Charge" })),
|
|
60941
61421
|
/**
|
|
60942
61422
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
60943
61423
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -60964,7 +61444,14 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
60964
61444
|
*/
|
|
60965
61445
|
sleeping: zod.z.boolean().meta({ label: "Sleeping" }),
|
|
60966
61446
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60967
|
-
lastUpdated: zod.z.number(),
|
|
61447
|
+
lastUpdated: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
61448
|
+
/**
|
|
61449
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
61450
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
61451
|
+
* that only report charge. A second reading on this cap, not a second
|
|
61452
|
+
* `numeric-sensor` on the same device.
|
|
61453
|
+
*/
|
|
61454
|
+
volts: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("voltage", { label: "Voltage" })),
|
|
60968
61455
|
/**
|
|
60969
61456
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
60970
61457
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -61016,7 +61503,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
61016
61503
|
/** Generic Customize target for the percentage reading (D936). */
|
|
61017
61504
|
var batteryCustomize = {
|
|
61018
61505
|
version: 1,
|
|
61019
|
-
advanced: "derive",
|
|
61020
61506
|
targets: [{
|
|
61021
61507
|
id: "percentage",
|
|
61022
61508
|
cardinality: "scalar",
|
|
@@ -61025,7 +61511,7 @@ var batteryCustomize = {
|
|
|
61025
61511
|
stateField: "percentage"
|
|
61026
61512
|
},
|
|
61027
61513
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
61028
|
-
apply: "add
|
|
61514
|
+
apply: "add",
|
|
61029
61515
|
path: "percentage",
|
|
61030
61516
|
sources: [{
|
|
61031
61517
|
kind: "field",
|
|
@@ -61146,10 +61632,16 @@ onStatusChanged: { data: zod.z.object({
|
|
|
61146
61632
|
/**
|
|
61147
61633
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
61148
61634
|
*/
|
|
61149
|
-
history: { fields: {
|
|
61150
|
-
|
|
61151
|
-
|
|
61152
|
-
|
|
61635
|
+
history: { fields: {
|
|
61636
|
+
percentage: {
|
|
61637
|
+
kind: "gauge",
|
|
61638
|
+
unit: "%"
|
|
61639
|
+
},
|
|
61640
|
+
volts: {
|
|
61641
|
+
kind: "gauge",
|
|
61642
|
+
unit: "V"
|
|
61643
|
+
}
|
|
61644
|
+
} },
|
|
61153
61645
|
customize: batteryCustomize,
|
|
61154
61646
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61155
61647
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -61198,12 +61690,7 @@ var binaryCapability = {
|
|
|
61198
61690
|
history: { fields: { on: { kind: "boolean" } } },
|
|
61199
61691
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61200
61692
|
* whether persisting is worth a SQLite commit. */
|
|
61201
|
-
volatileStateFields: ["lastChangedAt"]
|
|
61202
|
-
customize: {
|
|
61203
|
-
version: 1,
|
|
61204
|
-
advanced: "derive",
|
|
61205
|
-
targets: []
|
|
61206
|
-
}
|
|
61693
|
+
volatileStateFields: ["lastChangedAt"]
|
|
61207
61694
|
};
|
|
61208
61695
|
//#endregion
|
|
61209
61696
|
//#region src/capabilities/brightness.cap.ts
|
|
@@ -61221,7 +61708,7 @@ var binaryCapability = {
|
|
|
61221
61708
|
*/
|
|
61222
61709
|
var BrightnessStatusSchema = zod.z.object({
|
|
61223
61710
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
61224
|
-
percentage: zod.z.number().min(0).max(100),
|
|
61711
|
+
percentage: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("percentage")),
|
|
61225
61712
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
61226
61713
|
lastChangedAt: zod.z.number()
|
|
61227
61714
|
});
|
|
@@ -61820,21 +62307,21 @@ var ClimateControlStatusSchema = zod.z.object({
|
|
|
61820
62307
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
61821
62308
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
61822
62309
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
61823
|
-
target: zod.z.number().nullable(),
|
|
62310
|
+
target: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61824
62311
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
61825
62312
|
* in `heat_cool` mode. */
|
|
61826
|
-
targetHigh: zod.z.number().nullable(),
|
|
62313
|
+
targetHigh: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61827
62314
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
61828
62315
|
* in `heat_cool` mode. */
|
|
61829
|
-
targetLow: zod.z.number().nullable(),
|
|
62316
|
+
targetLow: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61830
62317
|
/** Target relative humidity (0..100). Null when the device has no
|
|
61831
62318
|
* humidity control. */
|
|
61832
|
-
targetHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
62319
|
+
targetHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
61833
62320
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
61834
62321
|
* the device's internal sensor. */
|
|
61835
|
-
currentTemp: zod.z.number().nullable(),
|
|
62322
|
+
currentTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
61836
62323
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
61837
|
-
currentHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
62324
|
+
currentHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
61838
62325
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
61839
62326
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
61840
62327
|
swingVertical: zod.z.boolean().nullable(),
|
|
@@ -61842,11 +62329,11 @@ var ClimateControlStatusSchema = zod.z.object({
|
|
|
61842
62329
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
61843
62330
|
swingHorizontal: zod.z.boolean().nullable(),
|
|
61844
62331
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
61845
|
-
minTemp: zod.z.number().nullable().optional(),
|
|
62332
|
+
minTemp: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("temperature")),
|
|
61846
62333
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
61847
|
-
maxTemp: zod.z.number().nullable().optional(),
|
|
62334
|
+
maxTemp: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("temperature")),
|
|
61848
62335
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
61849
|
-
tempStep: zod.z.number().positive().nullable().optional(),
|
|
62336
|
+
tempStep: zod.z.number().positive().nullable().optional().meta(require_sleep.readingMeta("temperature")),
|
|
61850
62337
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
61851
62338
|
lastFetchedAt: zod.z.number()
|
|
61852
62339
|
});
|
|
@@ -61990,17 +62477,17 @@ var climateControlCapability = {
|
|
|
61990
62477
|
* modes to expose in the picker without a slice fetch.
|
|
61991
62478
|
*/
|
|
61992
62479
|
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)
|
|
62480
|
+
r: zod.z.number().int().min(0).max(255).meta(require_sleep.readingMeta("none")),
|
|
62481
|
+
g: zod.z.number().int().min(0).max(255).meta(require_sleep.readingMeta("none")),
|
|
62482
|
+
b: zod.z.number().int().min(0).max(255).meta(require_sleep.readingMeta("none"))
|
|
61996
62483
|
});
|
|
61997
62484
|
var HsvTripletSchema = zod.z.object({
|
|
61998
62485
|
/** Hue in degrees, 0..360. */
|
|
61999
|
-
h: zod.z.number().min(0).max(360),
|
|
62486
|
+
h: zod.z.number().min(0).max(360).meta(require_sleep.readingMeta("none")),
|
|
62000
62487
|
/** Saturation as 0..100 inclusive. */
|
|
62001
|
-
s: zod.z.number().min(0).max(100),
|
|
62488
|
+
s: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("none")),
|
|
62002
62489
|
/** Value/brightness as 0..100 inclusive. */
|
|
62003
|
-
v: zod.z.number().min(0).max(100)
|
|
62490
|
+
v: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("none"))
|
|
62004
62491
|
});
|
|
62005
62492
|
var ColorInputSchema = zod.z.discriminatedUnion("mode", [
|
|
62006
62493
|
zod.z.object({
|
|
@@ -62029,7 +62516,7 @@ var ColorStatusSchema = zod.z.object({
|
|
|
62029
62516
|
/** Populated when `mode === 'hsv'`. */
|
|
62030
62517
|
hsv: HsvTripletSchema.optional(),
|
|
62031
62518
|
/** Populated when `mode === 'mired'`. */
|
|
62032
|
-
mireds: zod.z.number().int().optional(),
|
|
62519
|
+
mireds: zod.z.number().int().optional().meta(require_sleep.readingMeta("colour-temperature")),
|
|
62033
62520
|
/** Ms epoch of the last operator-driven change. */
|
|
62034
62521
|
lastChangedAt: zod.z.number()
|
|
62035
62522
|
});
|
|
@@ -62311,18 +62798,12 @@ var FORM_OF_KIND = {
|
|
|
62311
62798
|
function consumableFormOf(item) {
|
|
62312
62799
|
return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
|
|
62313
62800
|
}
|
|
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). */
|
|
62801
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
62802
|
+
var ConsumableRemainingKindSchema = zod.z.enum(["duration", "count"]);
|
|
62803
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
62323
62804
|
var ConsumableRemainingSchema = zod.z.object({
|
|
62324
|
-
value: zod.z.number().min(0).nullable(),
|
|
62325
|
-
|
|
62805
|
+
value: zod.z.number().min(0).nullable().meta(require_sleep.readingMeta("device")),
|
|
62806
|
+
kind: ConsumableRemainingKindSchema
|
|
62326
62807
|
});
|
|
62327
62808
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
62328
62809
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -62335,7 +62816,7 @@ var ConsumableItemSchema = zod.z.object({
|
|
|
62335
62816
|
/** Display name. */
|
|
62336
62817
|
label: zod.z.string().min(1),
|
|
62337
62818
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
62338
|
-
level: zod.z.number().min(0).max(100).nullable(),
|
|
62819
|
+
level: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
62339
62820
|
/** The provider's discrete verdict when known (binary mode). */
|
|
62340
62821
|
status: ConsumableStatusSchema.nullable(),
|
|
62341
62822
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -62417,8 +62898,8 @@ var consumablesCustomize = {
|
|
|
62417
62898
|
transforms: [{ kind: "identity" }]
|
|
62418
62899
|
}],
|
|
62419
62900
|
literals: [{
|
|
62420
|
-
path: "remaining.
|
|
62421
|
-
values: [...
|
|
62901
|
+
path: "remaining.kind",
|
|
62902
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
62422
62903
|
}]
|
|
62423
62904
|
},
|
|
62424
62905
|
{
|
|
@@ -62547,7 +63028,6 @@ reset: require_sleep.method(zod.z.object({
|
|
|
62547
63028
|
},
|
|
62548
63029
|
"remaining.value": {
|
|
62549
63030
|
kind: "gauge",
|
|
62550
|
-
unitFrom: "remaining.unit",
|
|
62551
63031
|
deadband: 1,
|
|
62552
63032
|
displayName: "Remaining"
|
|
62553
63033
|
}
|
|
@@ -62650,49 +63130,26 @@ var ControlKindSchema = zod.z.enum([
|
|
|
62650
63130
|
* (empty array for the other kinds). It lives in the slice because
|
|
62651
63131
|
* HA `select.*` entities may update their options at runtime.
|
|
62652
63132
|
*
|
|
62653
|
-
*
|
|
62654
|
-
*
|
|
62655
|
-
*
|
|
62656
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
63133
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
63134
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
63135
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
62657
63136
|
*/
|
|
62658
63137
|
var ControlStatusSchema = zod.z.object({
|
|
62659
63138
|
kind: ControlKindSchema,
|
|
62660
63139
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
62661
63140
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
62662
63141
|
* or time-only — HA accepts all three forms). */
|
|
62663
|
-
value: zod.z.union([zod.z.number(), zod.z.string()]),
|
|
63142
|
+
value: zod.z.union([zod.z.number().meta(require_sleep.readingMeta("device")), zod.z.string()]),
|
|
62664
63143
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
62665
63144
|
options: zod.z.array(zod.z.string()),
|
|
62666
63145
|
/** Ms epoch when the slice was last updated. */
|
|
62667
63146
|
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()
|
|
63147
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
63148
|
+
min: zod.z.number().optional().meta(require_sleep.readingMeta("device")),
|
|
63149
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
63150
|
+
max: zod.z.number().optional().meta(require_sleep.readingMeta("device")),
|
|
63151
|
+
/** Step increment, in the device quantity's base unit. */
|
|
63152
|
+
step: zod.z.number().optional().meta(require_sleep.readingMeta("device"))
|
|
62696
63153
|
});
|
|
62697
63154
|
var ControlSetValueInputSchema = zod.z.discriminatedUnion("kind", [
|
|
62698
63155
|
zod.z.object({
|
|
@@ -62782,9 +63239,9 @@ var CoverStatusSchema = zod.z.object({
|
|
|
62782
63239
|
state: CoverStateSchema,
|
|
62783
63240
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
62784
63241
|
* no intermediate position surface. */
|
|
62785
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
63242
|
+
position: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
62786
63243
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
62787
|
-
tiltPosition: zod.z.number().min(0).max(100).nullable(),
|
|
63244
|
+
tiltPosition: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
62788
63245
|
/** Ms epoch when the slice was last updated. */
|
|
62789
63246
|
lastChangedAt: zod.z.number()
|
|
62790
63247
|
});
|
|
@@ -62889,9 +63346,9 @@ var NormalizedRangeSchema$1 = zod.z.object({
|
|
|
62889
63346
|
var DayNightStatusSchema = zod.z.object({
|
|
62890
63347
|
mode: DayNightModeSchema,
|
|
62891
63348
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
62892
|
-
sensitivity: zod.z.number().optional(),
|
|
63349
|
+
sensitivity: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
62893
63350
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
62894
|
-
switchDelaySec: zod.z.number().optional(),
|
|
63351
|
+
switchDelaySec: zod.z.number().optional().meta(require_sleep.readingMeta("duration")),
|
|
62895
63352
|
lastFetchedAt: zod.z.number()
|
|
62896
63353
|
});
|
|
62897
63354
|
/**
|
|
@@ -63124,11 +63581,11 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
63124
63581
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
63125
63582
|
availablePrograms: zod.z.array(zod.z.string()),
|
|
63126
63583
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
63127
|
-
remainingSeconds: zod.z.number().int().nonnegative().nullable(),
|
|
63584
|
+
remainingSeconds: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
|
|
63128
63585
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
63129
|
-
delayedStartSeconds: zod.z.number().int().nonnegative().nullable(),
|
|
63586
|
+
delayedStartSeconds: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
|
|
63130
63587
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
63131
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
63588
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
63132
63589
|
/** True when the door is reported open; null when the door state is not known. */
|
|
63133
63590
|
doorOpen: zod.z.boolean().nullable(),
|
|
63134
63591
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -63152,7 +63609,7 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
63152
63609
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
63153
63610
|
machineCareDue: zod.z.boolean().nullable(),
|
|
63154
63611
|
/** 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(),
|
|
63612
|
+
machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("count")),
|
|
63156
63613
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
63157
63614
|
halfLoad: zod.z.boolean().nullable(),
|
|
63158
63615
|
hygienePlus: zod.z.boolean().nullable(),
|
|
@@ -63167,7 +63624,7 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
63167
63624
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
63168
63625
|
activeEvents: zod.z.array(zod.z.string()),
|
|
63169
63626
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
63170
|
-
errorCode: zod.z.number().nullable(),
|
|
63627
|
+
errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
63171
63628
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
63172
63629
|
errorLabel: zod.z.string().nullable(),
|
|
63173
63630
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -63402,7 +63859,7 @@ var DoorbellStatusSchema = zod.z.object({
|
|
|
63402
63859
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
63403
63860
|
lastPressedAt: zod.z.number().nullable(),
|
|
63404
63861
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
63405
|
-
pressCountSinceStart: zod.z.number()
|
|
63862
|
+
pressCountSinceStart: zod.z.number().meta(require_sleep.readingMeta("count"))
|
|
63406
63863
|
});
|
|
63407
63864
|
var DoorbellPressEventSchema = zod.z.object({
|
|
63408
63865
|
deviceId: zod.z.number(),
|
|
@@ -63487,12 +63944,11 @@ var EnumSensorDateTimeFormatSchema = zod.z.enum([
|
|
|
63487
63944
|
var EnumSensorStatusSchema = zod.z.object({
|
|
63488
63945
|
value: zod.z.string(),
|
|
63489
63946
|
/**
|
|
63490
|
-
* Set
|
|
63491
|
-
* as
|
|
63492
|
-
*
|
|
63493
|
-
* a time-only sensor → `'time'`.
|
|
63947
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
63948
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
63949
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
63494
63950
|
*/
|
|
63495
|
-
|
|
63951
|
+
timestamp: zod.z.boolean().optional(),
|
|
63496
63952
|
/** Ms epoch when the slice was last updated. */
|
|
63497
63953
|
lastFetchedAt: zod.z.number()
|
|
63498
63954
|
});
|
|
@@ -63519,11 +63975,11 @@ var enumSensorCapability = {
|
|
|
63519
63975
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
63520
63976
|
* operation state, an HVAC action). The option set is per device, so the
|
|
63521
63977
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
63522
|
-
* `
|
|
63978
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
63523
63979
|
*/
|
|
63524
63980
|
history: { fields: { value: {
|
|
63525
63981
|
kind: "enum",
|
|
63526
|
-
skipWhenSet: "
|
|
63982
|
+
skipWhenSet: "timestamp"
|
|
63527
63983
|
} } },
|
|
63528
63984
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63529
63985
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -63545,13 +64001,13 @@ var EventFireSchema = zod.z.object({
|
|
|
63545
64001
|
deviceId: zod.z.number(),
|
|
63546
64002
|
eventType: zod.z.string(),
|
|
63547
64003
|
data: zod.z.record(zod.z.string(), zod.z.unknown()).nullable(),
|
|
63548
|
-
timestamp: zod.z.number(),
|
|
63549
|
-
seq: zod.z.number()
|
|
64004
|
+
timestamp: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
64005
|
+
seq: zod.z.number().meta(require_sleep.readingMeta("count"))
|
|
63550
64006
|
});
|
|
63551
64007
|
var EventEmitterStatusSchema = zod.z.object({
|
|
63552
64008
|
eventTypes: zod.z.array(zod.z.string()),
|
|
63553
64009
|
lastEvent: EventFireSchema.nullable(),
|
|
63554
|
-
eventCountSinceStart: zod.z.number()
|
|
64010
|
+
eventCountSinceStart: zod.z.number().meta(require_sleep.readingMeta("count"))
|
|
63555
64011
|
});
|
|
63556
64012
|
var eventEmitterCapability = {
|
|
63557
64013
|
name: "event-emitter",
|
|
@@ -64008,10 +64464,10 @@ var FanDirectionSchema = zod.z.enum(["forward", "reverse"]);
|
|
|
64008
64464
|
var FanControlStatusSchema = zod.z.object({
|
|
64009
64465
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
64010
64466
|
* speed surface (single-speed fan). */
|
|
64011
|
-
percentage: zod.z.number().min(0).max(100).nullable(),
|
|
64467
|
+
percentage: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
64012
64468
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
64013
64469
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
64014
|
-
percentageStep: zod.z.number().positive().optional(),
|
|
64470
|
+
percentageStep: zod.z.number().positive().optional().meta(require_sleep.readingMeta("percentage")),
|
|
64015
64471
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
64016
64472
|
* — empty string when no preset is active or supported. */
|
|
64017
64473
|
preset: zod.z.string(),
|
|
@@ -64134,7 +64590,7 @@ var FeatureProbeStatusSchema = zod.z.object({
|
|
|
64134
64590
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
64135
64591
|
model: zod.z.string().nullable(),
|
|
64136
64592
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
64137
|
-
channelCount: zod.z.number().nullable(),
|
|
64593
|
+
channelCount: zod.z.number().nullable().meta(require_sleep.readingMeta("count")),
|
|
64138
64594
|
/**
|
|
64139
64595
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
64140
64596
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -64262,10 +64718,57 @@ var gasCapability = {
|
|
|
64262
64718
|
volatileStateFields: ["lastChangedAt"]
|
|
64263
64719
|
};
|
|
64264
64720
|
//#endregion
|
|
64721
|
+
//#region src/capabilities/group-status.cap.ts
|
|
64722
|
+
/**
|
|
64723
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
64724
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
64725
|
+
* The reading itself stays on the output capability. History is none — the
|
|
64726
|
+
* series that later statistics read is the output cap's own history block.
|
|
64727
|
+
*/
|
|
64728
|
+
var GroupStatusSchema = zod.z.object({
|
|
64729
|
+
/** Members whose current value entered the aggregate. */
|
|
64730
|
+
included: zod.z.number().int().nonnegative().meta(require_sleep.readingMeta("count", {
|
|
64731
|
+
precision: 0,
|
|
64732
|
+
label: "Reporting"
|
|
64733
|
+
})),
|
|
64734
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
64735
|
+
excluded: zod.z.number().int().nonnegative().meta(require_sleep.readingMeta("count", {
|
|
64736
|
+
precision: 0,
|
|
64737
|
+
label: "Excluded"
|
|
64738
|
+
})),
|
|
64739
|
+
/** `included` + `excluded`. */
|
|
64740
|
+
total: zod.z.number().int().nonnegative().meta(require_sleep.readingMeta("count", {
|
|
64741
|
+
precision: 0,
|
|
64742
|
+
label: "Members"
|
|
64743
|
+
}))
|
|
64744
|
+
});
|
|
64745
|
+
var groupStatusCapability = {
|
|
64746
|
+
name: "group-status",
|
|
64747
|
+
scope: "device",
|
|
64748
|
+
deviceNative: true,
|
|
64749
|
+
mode: "singleton",
|
|
64750
|
+
deviceTypes: [require_err_msg.DeviceType.Sensor],
|
|
64751
|
+
methods: {},
|
|
64752
|
+
status: {
|
|
64753
|
+
schema: GroupStatusSchema,
|
|
64754
|
+
kind: "push"
|
|
64755
|
+
},
|
|
64756
|
+
runtimeState: GroupStatusSchema,
|
|
64757
|
+
/**
|
|
64758
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
64759
|
+
* next source event; a restored count would outlive the readings it named.
|
|
64760
|
+
*
|
|
64761
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
64762
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
64763
|
+
*/
|
|
64764
|
+
durability: "session",
|
|
64765
|
+
history: "none"
|
|
64766
|
+
};
|
|
64767
|
+
//#endregion
|
|
64265
64768
|
//#region src/capabilities/heating-valve.cap.ts
|
|
64266
64769
|
var HeatingValveStatusSchema = zod.z.object({
|
|
64267
64770
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
64268
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
64771
|
+
position: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
64269
64772
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64270
64773
|
lastFetchedAt: zod.z.number()
|
|
64271
64774
|
});
|
|
@@ -64310,9 +64813,9 @@ var HumidifierStatusSchema = zod.z.object({
|
|
|
64310
64813
|
/** Whether the humidifier is currently on. */
|
|
64311
64814
|
on: zod.z.boolean(),
|
|
64312
64815
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
64313
|
-
currentHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
64816
|
+
currentHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64314
64817
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
64315
|
-
targetHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
64818
|
+
targetHumidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64316
64819
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
64317
64820
|
* device has no mode surface. */
|
|
64318
64821
|
mode: zod.z.string().nullable(),
|
|
@@ -64322,9 +64825,9 @@ var HumidifierStatusSchema = zod.z.object({
|
|
|
64322
64825
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
64323
64826
|
action: zod.z.string().nullable(),
|
|
64324
64827
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
64325
|
-
minHumidity: zod.z.number().nullable(),
|
|
64828
|
+
minHumidity: zod.z.number().nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64326
64829
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
64327
|
-
maxHumidity: zod.z.number().nullable(),
|
|
64830
|
+
maxHumidity: zod.z.number().nullable().meta(require_sleep.readingMeta("humidity")),
|
|
64328
64831
|
/** Ms epoch when the slice was last updated. */
|
|
64329
64832
|
lastChangedAt: zod.z.number()
|
|
64330
64833
|
});
|
|
@@ -64396,22 +64899,13 @@ var humidifierCapability = {
|
|
|
64396
64899
|
* `sourceInfo`.
|
|
64397
64900
|
*/
|
|
64398
64901
|
var HumiditySensorStatusSchema = zod.z.object({
|
|
64399
|
-
/** Current relative humidity, 0..100. */
|
|
64400
|
-
percent: zod.z.number().min(0).max(100).meta({
|
|
64401
|
-
|
|
64902
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
64903
|
+
percent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity", {
|
|
64904
|
+
precision: 0,
|
|
64402
64905
|
label: "Humidity"
|
|
64403
|
-
}),
|
|
64906
|
+
})),
|
|
64404
64907
|
/** 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()
|
|
64908
|
+
lastFetchedAt: zod.z.number()
|
|
64415
64909
|
});
|
|
64416
64910
|
var humiditySensorCapability = {
|
|
64417
64911
|
name: "humidity-sensor",
|
|
@@ -64442,12 +64936,7 @@ var humiditySensorCapability = {
|
|
|
64442
64936
|
} } },
|
|
64443
64937
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64444
64938
|
* whether persisting is worth a SQLite commit. */
|
|
64445
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64446
|
-
customize: {
|
|
64447
|
-
version: 1,
|
|
64448
|
-
advanced: "derive",
|
|
64449
|
-
targets: []
|
|
64450
|
-
}
|
|
64939
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64451
64940
|
};
|
|
64452
64941
|
//#endregion
|
|
64453
64942
|
//#region src/capabilities/image.cap.ts
|
|
@@ -64470,7 +64959,7 @@ var ImageStatusSchema = zod.z.object({
|
|
|
64470
64959
|
* entity exposes no `entity_picture` (yet). */
|
|
64471
64960
|
url: zod.z.string().nullable(),
|
|
64472
64961
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
64473
|
-
lastUpdated: zod.z.number().nullable()
|
|
64962
|
+
lastUpdated: zod.z.number().nullable().meta(require_sleep.readingMeta("none"))
|
|
64474
64963
|
});
|
|
64475
64964
|
var imageCapability = {
|
|
64476
64965
|
name: "image",
|
|
@@ -64560,19 +65049,19 @@ var NormalizedRangeSchema = zod.z.object({
|
|
|
64560
65049
|
*/
|
|
64561
65050
|
var ImageSettingsStatusSchema = zod.z.object({
|
|
64562
65051
|
/** Normalized 0–100. */
|
|
64563
|
-
brightness: zod.z.number().optional(),
|
|
65052
|
+
brightness: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64564
65053
|
/** Normalized 0–100. */
|
|
64565
|
-
contrast: zod.z.number().optional(),
|
|
65054
|
+
contrast: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64566
65055
|
/** Normalized 0–100. */
|
|
64567
|
-
saturation: zod.z.number().optional(),
|
|
65056
|
+
saturation: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64568
65057
|
/** Normalized 0–100. */
|
|
64569
|
-
sharpness: zod.z.number().optional(),
|
|
65058
|
+
sharpness: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64570
65059
|
mirror: zod.z.boolean().optional(),
|
|
64571
65060
|
flip: zod.z.boolean().optional(),
|
|
64572
65061
|
rotate: ImageRotateSchema.optional(),
|
|
64573
65062
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
64574
65063
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
64575
|
-
warmth: zod.z.number().optional(),
|
|
65064
|
+
warmth: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
64576
65065
|
exposureMode: ExposureModeSchema.optional(),
|
|
64577
65066
|
backlightMode: BacklightModeSchema.optional(),
|
|
64578
65067
|
lastFetchedAt: zod.z.number()
|
|
@@ -64873,10 +65362,10 @@ var IntercomAbilitySchema = zod.z.object({
|
|
|
64873
65362
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
64874
65363
|
codecs: zod.z.array(zod.z.string()),
|
|
64875
65364
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
64876
|
-
sampleRate: zod.z.number(),
|
|
65365
|
+
sampleRate: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
64877
65366
|
duplex: zod.z.enum(["half", "full"]),
|
|
64878
65367
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
64879
|
-
maxBacklogMs: zod.z.number()
|
|
65368
|
+
maxBacklogMs: zod.z.number().meta(require_sleep.readingMeta("duration-ms"))
|
|
64880
65369
|
});
|
|
64881
65370
|
var IntercomStatusSchema = zod.z.object({
|
|
64882
65371
|
/** True while a talk session is open. */
|
|
@@ -65105,13 +65594,13 @@ var LawnMowerControlStatusSchema = zod.z.object({
|
|
|
65105
65594
|
activity: LawnMowerActivitySchema,
|
|
65106
65595
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
65107
65596
|
* reading. */
|
|
65108
|
-
batteryLevel: zod.z.number().min(0).max(100).nullable(),
|
|
65597
|
+
batteryLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
65109
65598
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
65110
65599
|
* task is active / progress is unavailable. */
|
|
65111
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
65600
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
65112
65601
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
65113
65602
|
* or null when unknown. */
|
|
65114
|
-
currentCode: zod.z.number().nullable(),
|
|
65603
|
+
currentCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
65115
65604
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
65116
65605
|
currentCodeLabel: zod.z.string().nullable(),
|
|
65117
65606
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -65841,7 +66330,7 @@ var MediaPlayerStatusSchema = zod.z.object({
|
|
|
65841
66330
|
state: MediaPlayerStateSchema,
|
|
65842
66331
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
65843
66332
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
65844
|
-
volumeLevel: zod.z.number().min(0).max(100).nullable(),
|
|
66333
|
+
volumeLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
65845
66334
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
65846
66335
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
65847
66336
|
isMuted: zod.z.boolean().nullable(),
|
|
@@ -65854,10 +66343,10 @@ var MediaPlayerStatusSchema = zod.z.object({
|
|
|
65854
66343
|
currentMedia: MediaInfoSchema.nullable(),
|
|
65855
66344
|
/** Current playback position in ms. Null when not seekable or
|
|
65856
66345
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
65857
|
-
positionMs: zod.z.number().int().nonnegative().nullable(),
|
|
66346
|
+
positionMs: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
|
|
65858
66347
|
/** Total duration of the current media in ms. Null when unknown
|
|
65859
66348
|
* (live stream) or nothing is playing. */
|
|
65860
|
-
durationMs: zod.z.number().int().nonnegative().nullable(),
|
|
66349
|
+
durationMs: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
|
|
65861
66350
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
65862
66351
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
65863
66352
|
shuffle: zod.z.boolean().nullable(),
|
|
@@ -66237,7 +66726,7 @@ var motionCustomize = {
|
|
|
66237
66726
|
eventName: "onMotionChanged"
|
|
66238
66727
|
},
|
|
66239
66728
|
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
66240
|
-
apply: "
|
|
66729
|
+
apply: "add",
|
|
66241
66730
|
applyAuthority: {
|
|
66242
66731
|
kind: "camera-sensors",
|
|
66243
66732
|
timeoutField: "motionCooldownMs"
|
|
@@ -66334,7 +66823,7 @@ var MotionStatusSchema = zod.z.object({
|
|
|
66334
66823
|
* it, every provider seeded it at boot, and every session left it
|
|
66335
66824
|
* `detected: true` after its detach.
|
|
66336
66825
|
*/
|
|
66337
|
-
autoClearAfterMs: zod.z.number().nullable()
|
|
66826
|
+
autoClearAfterMs: zod.z.number().nullable().meta(require_sleep.readingMeta("duration-ms"))
|
|
66338
66827
|
});
|
|
66339
66828
|
/**
|
|
66340
66829
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -66371,12 +66860,18 @@ var motionCapability = {
|
|
|
66371
66860
|
methods: {
|
|
66372
66861
|
/**
|
|
66373
66862
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
66374
|
-
* for consumers that don't need the full status object
|
|
66375
|
-
*
|
|
66376
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
66377
|
-
* consumer.
|
|
66863
|
+
* for consumers that don't need the full status object. A composed
|
|
66864
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
66378
66865
|
*/
|
|
66379
66866
|
isDetected: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.boolean()) },
|
|
66867
|
+
/**
|
|
66868
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
66869
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
66870
|
+
*/
|
|
66871
|
+
composedMethods: { isDetected: {
|
|
66872
|
+
kind: "slice",
|
|
66873
|
+
field: "detected"
|
|
66874
|
+
} },
|
|
66380
66875
|
events: {
|
|
66381
66876
|
/**
|
|
66382
66877
|
* Fires every time the runner transitions a camera between
|
|
@@ -66520,7 +67015,7 @@ var MotionZoneRegionSchema = zod.z.object({
|
|
|
66520
67015
|
* the grid region(s). */
|
|
66521
67016
|
var MotionZoneStatusSchema = zod.z.object({
|
|
66522
67017
|
enabled: zod.z.boolean(),
|
|
66523
|
-
sensitivity: zod.z.number(),
|
|
67018
|
+
sensitivity: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
66524
67019
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
66525
67020
|
regions: zod.z.array(MotionZoneRegionSchema),
|
|
66526
67021
|
lastFetchedAt: zod.z.number()
|
|
@@ -67036,7 +67531,7 @@ var NavigationStatusSchema = zod.z.object({
|
|
|
67036
67531
|
following: zod.z.boolean(),
|
|
67037
67532
|
flash: zod.z.boolean(),
|
|
67038
67533
|
lightMode: NavigationLightModeSchema,
|
|
67039
|
-
lightLevel: zod.z.number().min(40).max(100),
|
|
67534
|
+
lightLevel: zod.z.number().min(40).max(100).meta(require_sleep.readingMeta("none")),
|
|
67040
67535
|
/** Ms epoch when the slice was last updated. */
|
|
67041
67536
|
lastChangedAt: zod.z.number()
|
|
67042
67537
|
});
|
|
@@ -67187,13 +67682,13 @@ var NetworkLinkStatusSchema = zod.z.object({
|
|
|
67187
67682
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
67188
67683
|
* SKIP a null rather than coerce it.
|
|
67189
67684
|
*/
|
|
67190
|
-
signalPercent: zod.z.number().min(0).max(100).nullable(),
|
|
67685
|
+
signalPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
67191
67686
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
67192
|
-
rssiDbm: zod.z.number().optional(),
|
|
67687
|
+
rssiDbm: zod.z.number().optional().meta(require_sleep.readingMeta("signal-level")),
|
|
67193
67688
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
67194
67689
|
ssid: zod.z.string().optional(),
|
|
67195
67690
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
67196
|
-
lastUpdated: zod.z.number()
|
|
67691
|
+
lastUpdated: zod.z.number().meta(require_sleep.readingMeta("none"))
|
|
67197
67692
|
});
|
|
67198
67693
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
67199
67694
|
var NETWORK_LINK_UNKNOWN = {
|
|
@@ -67669,7 +68164,7 @@ var NotifierStatusSchema = zod.z.object({
|
|
|
67669
68164
|
lastError: zod.z.string().nullable(),
|
|
67670
68165
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
67671
68166
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
67672
|
-
queueDepth: zod.z.number().int().nonnegative(),
|
|
68167
|
+
queueDepth: zod.z.number().int().nonnegative().meta(require_sleep.readingMeta("count")),
|
|
67673
68168
|
/** Per-feature capability matrix — authoritative source for the
|
|
67674
68169
|
* compose-form field gating. */
|
|
67675
68170
|
supports: NotifierSupportsSchema
|
|
@@ -67763,11 +68258,9 @@ onSent: { data: zod.z.object({
|
|
|
67763
68258
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
67764
68259
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
67765
68260
|
*
|
|
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`.
|
|
68261
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
68262
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
68263
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
67771
68264
|
*
|
|
67772
68265
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
67773
68266
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -67776,15 +68269,8 @@ onSent: { data: zod.z.object({
|
|
|
67776
68269
|
* numeric values land here.
|
|
67777
68270
|
*/
|
|
67778
68271
|
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(),
|
|
68272
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
68273
|
+
value: zod.z.number().nullable().meta(require_sleep.readingMeta("device")),
|
|
67788
68274
|
/** Ms epoch when the slice was last updated. */
|
|
67789
68275
|
lastFetchedAt: zod.z.number()
|
|
67790
68276
|
});
|
|
@@ -67808,11 +68294,11 @@ var numericSensorCapability = {
|
|
|
67808
68294
|
*/
|
|
67809
68295
|
durability: "restored",
|
|
67810
68296
|
/**
|
|
67811
|
-
* History (D850): recorded series. The unit is
|
|
68297
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
68298
|
+
* resolved when the series is read — the cap has no single unit.
|
|
67812
68299
|
*/
|
|
67813
68300
|
history: { fields: { value: {
|
|
67814
68301
|
kind: "gauge",
|
|
67815
|
-
unitFrom: "unit",
|
|
67816
68302
|
minIntervalMs: 3e4
|
|
67817
68303
|
} } },
|
|
67818
68304
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -68269,23 +68755,26 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
68269
68755
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
68270
68756
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
68271
68757
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
68272
|
-
foodLevel: zod.z.number().nullable(),
|
|
68758
|
+
foodLevel: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68273
68759
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
68274
68760
|
* single-hopper models. */
|
|
68275
|
-
food1: zod.z.number().nullable(),
|
|
68761
|
+
food1: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68276
68762
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
68277
68763
|
* single-hopper models. */
|
|
68278
|
-
food2: zod.z.number().nullable(),
|
|
68764
|
+
food2: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68279
68765
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
68280
68766
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
68281
68767
|
* below the feeder's low threshold. */
|
|
68282
68768
|
lowFood: zod.z.boolean(),
|
|
68283
68769
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
68284
68770
|
* device has no battery reading. */
|
|
68285
|
-
batteryPower: zod.z.number().min(0).max(100).nullable(),
|
|
68286
|
-
/**
|
|
68287
|
-
*
|
|
68288
|
-
|
|
68771
|
+
batteryPower: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
68772
|
+
/**
|
|
68773
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
68774
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
68775
|
+
* model has no desiccant sensor.
|
|
68776
|
+
*/
|
|
68777
|
+
desiccantLeftDays: zod.z.number().nullable().meta(require_sleep.readingMeta("duration")),
|
|
68289
68778
|
/** True while a feed is in progress. */
|
|
68290
68779
|
feeding: zod.z.boolean(),
|
|
68291
68780
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -68296,7 +68785,7 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
68296
68785
|
* with `errorCode` for consumers that want the raw integer. */
|
|
68297
68786
|
error: zod.z.string().nullable(),
|
|
68298
68787
|
/** Raw device error code (0 / null = no error). */
|
|
68299
|
-
errorCode: zod.z.number().nullable(),
|
|
68788
|
+
errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
68300
68789
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
68301
68790
|
isDualHopper: zod.z.boolean(),
|
|
68302
68791
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -68306,7 +68795,7 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
68306
68795
|
/** Play a chime when dispensing. */
|
|
68307
68796
|
feedSound: zod.z.boolean(),
|
|
68308
68797
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
68309
|
-
volume: zod.z.number(),
|
|
68798
|
+
volume: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
68310
68799
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
68311
68800
|
lastFetchedAt: zod.z.number()
|
|
68312
68801
|
});
|
|
@@ -68425,7 +68914,7 @@ var petFeederCapability = {
|
|
|
68425
68914
|
},
|
|
68426
68915
|
desiccantLeftDays: {
|
|
68427
68916
|
kind: "gauge",
|
|
68428
|
-
unit: "
|
|
68917
|
+
unit: "s"
|
|
68429
68918
|
}
|
|
68430
68919
|
} }
|
|
68431
68920
|
};
|
|
@@ -69631,36 +70120,19 @@ var platformProbeCapability = {
|
|
|
69631
70120
|
*/
|
|
69632
70121
|
var PowerMeterStatusSchema = zod.z.object({
|
|
69633
70122
|
/** Instantaneous power draw in watts. */
|
|
69634
|
-
watts: zod.z.number().optional().meta({
|
|
69635
|
-
unit: "W",
|
|
69636
|
-
label: "Power"
|
|
69637
|
-
}),
|
|
70123
|
+
watts: zod.z.number().optional().meta(require_sleep.readingMeta("power", { label: "Power" })),
|
|
69638
70124
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
69639
|
-
kwhTotal: zod.z.number().optional().meta({
|
|
69640
|
-
unit: "kWh",
|
|
69641
|
-
label: "Energy"
|
|
69642
|
-
}),
|
|
70125
|
+
kwhTotal: zod.z.number().optional().meta(require_sleep.readingMeta("energy", { label: "Energy" })),
|
|
69643
70126
|
/** Voltage in volts. */
|
|
69644
|
-
volts: zod.z.number().optional(),
|
|
70127
|
+
volts: zod.z.number().optional().meta(require_sleep.readingMeta("voltage")),
|
|
69645
70128
|
/** Current in amperes. */
|
|
69646
|
-
amps: zod.z.number().optional(),
|
|
69647
|
-
/** Apparent power in volt-amperes
|
|
69648
|
-
va: zod.z.number().optional(),
|
|
70129
|
+
amps: zod.z.number().optional().meta(require_sleep.readingMeta("current")),
|
|
70130
|
+
/** Apparent power in volt-amperes. */
|
|
70131
|
+
va: zod.z.number().optional().meta(require_sleep.readingMeta("apparent-power")),
|
|
69649
70132
|
/** Power factor (0..1) if reported. */
|
|
69650
|
-
powerFactor: zod.z.number().min(0).max(1).optional(),
|
|
70133
|
+
powerFactor: zod.z.number().min(0).max(1).optional().meta(require_sleep.readingMeta("ratio")),
|
|
69651
70134
|
/** 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()
|
|
70135
|
+
lastFetchedAt: zod.z.number()
|
|
69664
70136
|
});
|
|
69665
70137
|
var powerMeterCapability = {
|
|
69666
70138
|
name: "power-meter",
|
|
@@ -69724,12 +70196,7 @@ var powerMeterCapability = {
|
|
|
69724
70196
|
} },
|
|
69725
70197
|
/** Clock fields: written, but excluded from the compare that decides
|
|
69726
70198
|
* whether persisting is worth a SQLite commit. */
|
|
69727
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
69728
|
-
customize: {
|
|
69729
|
-
version: 1,
|
|
69730
|
-
advanced: "derive",
|
|
69731
|
-
targets: []
|
|
69732
|
-
}
|
|
70199
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
69733
70200
|
};
|
|
69734
70201
|
//#endregion
|
|
69735
70202
|
//#region src/capabilities/presence.cap.ts
|
|
@@ -69751,11 +70218,11 @@ var powerMeterCapability = {
|
|
|
69751
70218
|
*/
|
|
69752
70219
|
var GpsLocationSchema = zod.z.object({
|
|
69753
70220
|
/** Latitude in decimal degrees, -90..90. */
|
|
69754
|
-
latitude: zod.z.number().min(-90).max(90),
|
|
70221
|
+
latitude: zod.z.number().min(-90).max(90).meta(require_sleep.readingMeta("angle")),
|
|
69755
70222
|
/** Longitude in decimal degrees, -180..180. */
|
|
69756
|
-
longitude: zod.z.number().min(-180).max(180),
|
|
70223
|
+
longitude: zod.z.number().min(-180).max(180).meta(require_sleep.readingMeta("angle")),
|
|
69757
70224
|
/** Reported accuracy in meters (lower = better). */
|
|
69758
|
-
accuracyMeters: zod.z.number().nonnegative()
|
|
70225
|
+
accuracyMeters: zod.z.number().nonnegative().meta(require_sleep.readingMeta("length"))
|
|
69759
70226
|
});
|
|
69760
70227
|
var PresenceStatusSchema = zod.z.object({
|
|
69761
70228
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -69767,7 +70234,7 @@ var PresenceStatusSchema = zod.z.object({
|
|
|
69767
70234
|
gps: GpsLocationSchema.nullable(),
|
|
69768
70235
|
/** Optional battery level of the tracking device (0..100). Null
|
|
69769
70236
|
* when not reported. */
|
|
69770
|
-
batteryPercent: zod.z.number().min(0).max(100).nullable(),
|
|
70237
|
+
batteryPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
69771
70238
|
/** Ms epoch when the slice was last updated. */
|
|
69772
70239
|
lastChangedAt: zod.z.number()
|
|
69773
70240
|
});
|
|
@@ -69819,19 +70286,10 @@ var presenceCapability = {
|
|
|
69819
70286
|
* `sourceInfo`.
|
|
69820
70287
|
*/
|
|
69821
70288
|
var PressureSensorStatusSchema = zod.z.object({
|
|
69822
|
-
/** Current pressure in hPa. */
|
|
69823
|
-
hpa: zod.z.number(),
|
|
70289
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
70290
|
+
hpa: zod.z.number().nullable().meta(require_sleep.readingMeta("pressure", { precision: 0 })),
|
|
69824
70291
|
/** 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()
|
|
70292
|
+
lastFetchedAt: zod.z.number()
|
|
69835
70293
|
});
|
|
69836
70294
|
var pressureSensorCapability = {
|
|
69837
70295
|
name: "pressure-sensor",
|
|
@@ -70398,8 +70856,8 @@ var ptzCapability = {
|
|
|
70398
70856
|
var AutotrackTargetTypeSchema = zod.z.string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
70399
70857
|
var PtzAutotrackSettingsSchema = zod.z.object({
|
|
70400
70858
|
targetType: AutotrackTargetTypeSchema,
|
|
70401
|
-
stopDelaySeconds: zod.z.number().int().min(0).max(300),
|
|
70402
|
-
disappearDelaySeconds: zod.z.number().int().min(0).max(300)
|
|
70859
|
+
stopDelaySeconds: zod.z.number().int().min(0).max(300).meta(require_sleep.readingMeta("duration")),
|
|
70860
|
+
disappearDelaySeconds: zod.z.number().int().min(0).max(300).meta(require_sleep.readingMeta("duration"))
|
|
70403
70861
|
});
|
|
70404
70862
|
/**
|
|
70405
70863
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -70566,7 +71024,7 @@ var RunningStateStatusSchema = zod.z.object({
|
|
|
70566
71024
|
/** null = unknown — never coerced to false (D393). */
|
|
70567
71025
|
running: zod.z.boolean().nullable(),
|
|
70568
71026
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
70569
|
-
since: zod.z.number().nullable(),
|
|
71027
|
+
since: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
70570
71028
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
70571
71029
|
phase: zod.z.string().nullable(),
|
|
70572
71030
|
/** null until a reading has been published (D393). */
|
|
@@ -70581,7 +71039,6 @@ var RUNNING_DEVICE_TYPES = Object.values(require_err_msg.DeviceType);
|
|
|
70581
71039
|
/** Generic Customize target for the running boolean (D936). */
|
|
70582
71040
|
var runningCustomize = {
|
|
70583
71041
|
version: 1,
|
|
70584
|
-
advanced: "derive",
|
|
70585
71042
|
targets: [{
|
|
70586
71043
|
id: "running",
|
|
70587
71044
|
cardinality: "scalar",
|
|
@@ -70601,7 +71058,7 @@ var runningCustomize = {
|
|
|
70601
71058
|
require_err_msg.DeviceType.Thermostat,
|
|
70602
71059
|
require_err_msg.DeviceType.PetFeeder
|
|
70603
71060
|
],
|
|
70604
|
-
apply: "add
|
|
71061
|
+
apply: "add",
|
|
70605
71062
|
path: "running",
|
|
70606
71063
|
sources: [
|
|
70607
71064
|
{
|
|
@@ -72449,9 +72906,9 @@ var RecordTriggerSchema = zod.z.enum([
|
|
|
72449
72906
|
*/
|
|
72450
72907
|
var RecordWindowSchema = zod.z.object({
|
|
72451
72908
|
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)
|
|
72909
|
+
day: zod.z.number().int().min(0).max(6).meta(require_sleep.readingMeta("none")),
|
|
72910
|
+
startMinute: zod.z.number().int().min(0).max(1439).meta(require_sleep.readingMeta("none")),
|
|
72911
|
+
endMinute: zod.z.number().int().min(1).max(1440).meta(require_sleep.readingMeta("none"))
|
|
72455
72912
|
});
|
|
72456
72913
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
72457
72914
|
var OnboardStorageVolumeSchema = zod.z.object({
|
|
@@ -72550,10 +73007,10 @@ var RecordingOnboardStatusSchema = zod.z.object({
|
|
|
72550
73007
|
/** Master "record to the card at all" switch. */
|
|
72551
73008
|
enabled: zod.z.boolean().nullable(),
|
|
72552
73009
|
overwriteWhenFull: zod.z.boolean().nullable(),
|
|
72553
|
-
preRecordSec: zod.z.number().nullable(),
|
|
72554
|
-
postRecordSec: zod.z.number().nullable(),
|
|
73010
|
+
preRecordSec: zod.z.number().nullable().meta(require_sleep.readingMeta("duration")),
|
|
73011
|
+
postRecordSec: zod.z.number().nullable().meta(require_sleep.readingMeta("duration")),
|
|
72555
73012
|
/** Length of one recorded file, in minutes. */
|
|
72556
|
-
segmentMinutes: zod.z.number().nullable(),
|
|
73013
|
+
segmentMinutes: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
72557
73014
|
/** The primary track's weekly windows, flattened. */
|
|
72558
73015
|
windows: zod.z.array(RecordWindowSchema),
|
|
72559
73016
|
/**
|
|
@@ -72569,7 +73026,7 @@ var RecordingOnboardStatusSchema = zod.z.object({
|
|
|
72569
73026
|
* provider reporting a non-zero count also reports the schedule as not
|
|
72570
73027
|
* writable.
|
|
72571
73028
|
*/
|
|
72572
|
-
unreadableWindows: zod.z.number(),
|
|
73029
|
+
unreadableWindows: zod.z.number().meta(require_sleep.readingMeta("count")),
|
|
72573
73030
|
/**
|
|
72574
73031
|
* The camera is scheduled to record and has NO usable storage.
|
|
72575
73032
|
*
|
|
@@ -73741,7 +74198,7 @@ var CamStreamDescriptorSchema = zod.z.object({
|
|
|
73741
74198
|
url: zod.z.string().optional(),
|
|
73742
74199
|
codec: zod.z.string().optional(),
|
|
73743
74200
|
resolution: require_sleep.CamStreamResolutionSchema.optional(),
|
|
73744
|
-
fps: zod.z.number().positive().optional(),
|
|
74201
|
+
fps: zod.z.number().positive().optional().meta(require_sleep.readingMeta("rate")),
|
|
73745
74202
|
label: zod.z.string().optional(),
|
|
73746
74203
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
73747
74204
|
deviceFeatures: zod.z.array(zod.z.string()).optional(),
|
|
@@ -73830,18 +74287,18 @@ var StreamProfileSchema = zod.z.enum([
|
|
|
73830
74287
|
]);
|
|
73831
74288
|
/** The current encoding config of one stream profile. */
|
|
73832
74289
|
var StreamProfileConfigSchema = zod.z.object({
|
|
73833
|
-
width: zod.z.number(),
|
|
73834
|
-
height: zod.z.number(),
|
|
74290
|
+
width: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
74291
|
+
height: zod.z.number().meta(require_sleep.readingMeta("none")),
|
|
73835
74292
|
codec: zod.z.enum(["h264", "h265"]),
|
|
73836
|
-
framerate: zod.z.number(),
|
|
73837
|
-
bitrate: zod.z.number(),
|
|
74293
|
+
framerate: zod.z.number().meta(require_sleep.readingMeta("rate")),
|
|
74294
|
+
bitrate: zod.z.number().meta(require_sleep.readingMeta("bitrate")),
|
|
73838
74295
|
bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
|
|
73839
74296
|
encoderProfile: zod.z.enum([
|
|
73840
74297
|
"high",
|
|
73841
74298
|
"main",
|
|
73842
74299
|
"baseline"
|
|
73843
74300
|
]).optional(),
|
|
73844
|
-
gop: zod.z.number().optional(),
|
|
74301
|
+
gop: zod.z.number().optional().meta(require_sleep.readingMeta("none")),
|
|
73845
74302
|
/**
|
|
73846
74303
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
73847
74304
|
*
|
|
@@ -74323,12 +74780,7 @@ var switchCapability = {
|
|
|
74323
74780
|
label: "On",
|
|
74324
74781
|
kind: "boolean"
|
|
74325
74782
|
}
|
|
74326
|
-
}] }
|
|
74327
|
-
customize: {
|
|
74328
|
-
version: 1,
|
|
74329
|
-
advanced: "derive",
|
|
74330
|
-
targets: []
|
|
74331
|
-
}
|
|
74783
|
+
}] }
|
|
74332
74784
|
};
|
|
74333
74785
|
//#endregion
|
|
74334
74786
|
//#region src/system/server-name.ts
|
|
@@ -75076,35 +75528,21 @@ var tamperCapability = {
|
|
|
75076
75528
|
* entries with `device_class: temperature` and any future native
|
|
75077
75529
|
* thermometer.
|
|
75078
75530
|
*
|
|
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`.
|
|
75531
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
75532
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
75085
75533
|
*
|
|
75086
75534
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
75087
75535
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
75088
75536
|
* changed" steady state.
|
|
75089
75537
|
*/
|
|
75090
75538
|
var TemperatureSensorStatusSchema = zod.z.object({
|
|
75091
|
-
/** Current temperature in Celsius. */
|
|
75092
|
-
celsius: zod.z.number().meta({
|
|
75093
|
-
|
|
75539
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
75540
|
+
celsius: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature", {
|
|
75541
|
+
precision: 1,
|
|
75094
75542
|
label: "Temperature"
|
|
75095
|
-
}),
|
|
75543
|
+
})),
|
|
75096
75544
|
/** 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()
|
|
75545
|
+
lastFetchedAt: zod.z.number()
|
|
75108
75546
|
});
|
|
75109
75547
|
var temperatureSensorCapability = {
|
|
75110
75548
|
name: "temperature-sensor",
|
|
@@ -75135,12 +75573,7 @@ var temperatureSensorCapability = {
|
|
|
75135
75573
|
} } },
|
|
75136
75574
|
/** Clock fields: written, but excluded from the compare that decides
|
|
75137
75575
|
* whether persisting is worth a SQLite commit. */
|
|
75138
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
75139
|
-
customize: {
|
|
75140
|
-
version: 1,
|
|
75141
|
-
advanced: "derive",
|
|
75142
|
-
targets: []
|
|
75143
|
-
}
|
|
75576
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
75144
75577
|
};
|
|
75145
75578
|
//#endregion
|
|
75146
75579
|
//#region src/capabilities/toast.cap.ts
|
|
@@ -75494,16 +75927,16 @@ var VacuumControlStatusSchema = zod.z.object({
|
|
|
75494
75927
|
state: VacuumStateSchema,
|
|
75495
75928
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
75496
75929
|
* reading. */
|
|
75497
|
-
batteryLevel: zod.z.number().min(0).max(100).nullable(),
|
|
75930
|
+
batteryLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
75498
75931
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
75499
75932
|
* the vacuum has no speed control. */
|
|
75500
75933
|
fanSpeed: zod.z.string().nullable(),
|
|
75501
75934
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
75502
75935
|
availableFanSpeeds: zod.z.array(zod.z.string()),
|
|
75503
75936
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
75504
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
75937
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
75505
75938
|
/** Current error code (0 / null = no error). */
|
|
75506
|
-
errorCode: zod.z.number().nullable(),
|
|
75939
|
+
errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
|
|
75507
75940
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
75508
75941
|
errorLabel: zod.z.string().nullable(),
|
|
75509
75942
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -75601,7 +76034,7 @@ var ValveStatusSchema = zod.z.object({
|
|
|
75601
76034
|
state: ValveStateSchema,
|
|
75602
76035
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
75603
76036
|
* intermediate position surface. */
|
|
75604
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
76037
|
+
position: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
|
|
75605
76038
|
/** Ms epoch when the slice was last updated. */
|
|
75606
76039
|
lastChangedAt: zod.z.number()
|
|
75607
76040
|
});
|
|
@@ -75713,9 +76146,9 @@ var vibrationCapability = {
|
|
|
75713
76146
|
*/
|
|
75714
76147
|
var WaterHeaterStatusSchema = zod.z.object({
|
|
75715
76148
|
/** Current measured temperature. Null when not reported. */
|
|
75716
|
-
currentTemp: zod.z.number().nullable(),
|
|
76149
|
+
currentTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75717
76150
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
75718
|
-
targetTemp: zod.z.number().nullable(),
|
|
76151
|
+
targetTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75719
76152
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
75720
76153
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
75721
76154
|
* device reports an unknown state. */
|
|
@@ -75726,9 +76159,9 @@ var WaterHeaterStatusSchema = zod.z.object({
|
|
|
75726
76159
|
* has no away surface. */
|
|
75727
76160
|
away: zod.z.boolean().nullable(),
|
|
75728
76161
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
75729
|
-
minTemp: zod.z.number().nullable(),
|
|
76162
|
+
minTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75730
76163
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
75731
|
-
maxTemp: zod.z.number().nullable(),
|
|
76164
|
+
maxTemp: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature")),
|
|
75732
76165
|
/** Ms epoch when the slice was last updated. */
|
|
75733
76166
|
lastChangedAt: zod.z.number()
|
|
75734
76167
|
});
|
|
@@ -75815,25 +76248,18 @@ var waterHeaterCapability = {
|
|
|
75815
76248
|
* Forecast deferred — current conditions only for v1.
|
|
75816
76249
|
*/
|
|
75817
76250
|
var WeatherStatusSchema = zod.z.object({
|
|
75818
|
-
/** Verbatim
|
|
75819
|
-
* when no condition has been reported yet. */
|
|
76251
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
75820
76252
|
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(),
|
|
76253
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
76254
|
+
temperature: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature", { precision: 1 })),
|
|
75825
76255
|
/** 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(),
|
|
76256
|
+
humidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity")),
|
|
76257
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
76258
|
+
pressure: zod.z.number().nullable().meta(require_sleep.readingMeta("pressure")),
|
|
76259
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
76260
|
+
windSpeed: zod.z.number().nullable().meta(require_sleep.readingMeta("speed")),
|
|
75835
76261
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
75836
|
-
windBearing: zod.z.number().nullable(),
|
|
76262
|
+
windBearing: zod.z.number().nullable().meta(require_sleep.readingMeta("angle")),
|
|
75837
76263
|
/** Ms epoch when the slice was last updated. */
|
|
75838
76264
|
lastFetchedAt: zod.z.number()
|
|
75839
76265
|
});
|
|
@@ -75861,12 +76287,12 @@ var weatherCapability = {
|
|
|
75861
76287
|
*/
|
|
75862
76288
|
durability: "session",
|
|
75863
76289
|
/**
|
|
75864
|
-
* History (D850): recorded series.
|
|
76290
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
75865
76291
|
*/
|
|
75866
76292
|
history: { fields: {
|
|
75867
76293
|
temperature: {
|
|
75868
76294
|
kind: "gauge",
|
|
75869
|
-
|
|
76295
|
+
unit: "°C",
|
|
75870
76296
|
deadband: .2
|
|
75871
76297
|
},
|
|
75872
76298
|
humidity: {
|
|
@@ -75876,12 +76302,12 @@ var weatherCapability = {
|
|
|
75876
76302
|
},
|
|
75877
76303
|
pressure: {
|
|
75878
76304
|
kind: "gauge",
|
|
75879
|
-
|
|
76305
|
+
unit: "hPa",
|
|
75880
76306
|
deadband: .5
|
|
75881
76307
|
},
|
|
75882
76308
|
windSpeed: {
|
|
75883
76309
|
kind: "gauge",
|
|
75884
|
-
|
|
76310
|
+
unit: "m/s",
|
|
75885
76311
|
deadband: .5
|
|
75886
76312
|
}
|
|
75887
76313
|
} }
|
|
@@ -77192,6 +77618,127 @@ function createDeviceExtensionProvider(options) {
|
|
|
77192
77618
|
};
|
|
77193
77619
|
}
|
|
77194
77620
|
//#endregion
|
|
77621
|
+
//#region src/composition/helpers/aggregate.ts
|
|
77622
|
+
function isBinaryReducer(reducer) {
|
|
77623
|
+
return reducer === "any" || reducer === "all";
|
|
77624
|
+
}
|
|
77625
|
+
function includedValue(reducer, member) {
|
|
77626
|
+
if (member.state !== "fresh") return null;
|
|
77627
|
+
if (isBinaryReducer(reducer)) return typeof member.value === "boolean" ? member.value : null;
|
|
77628
|
+
return typeof member.value === "number" && Number.isFinite(member.value) ? member.value : null;
|
|
77629
|
+
}
|
|
77630
|
+
function median$1(values) {
|
|
77631
|
+
const sorted = [...values].toSorted((a, b) => a - b);
|
|
77632
|
+
const mid = Math.floor(sorted.length / 2);
|
|
77633
|
+
const right = sorted[mid];
|
|
77634
|
+
const left = sorted[mid - 1];
|
|
77635
|
+
if (right === void 0) throw new Error("median requires at least one finite number");
|
|
77636
|
+
if (sorted.length % 2 === 1) return right;
|
|
77637
|
+
if (left === void 0) throw new Error("median requires at least one finite number");
|
|
77638
|
+
return (left + right) / 2;
|
|
77639
|
+
}
|
|
77640
|
+
function reduceNumbers(reducer, values) {
|
|
77641
|
+
if (reducer === "min") return Math.min(...values);
|
|
77642
|
+
if (reducer === "max") return Math.max(...values);
|
|
77643
|
+
if (reducer === "sum") return values.reduce((sum, value) => sum + value, 0);
|
|
77644
|
+
if (reducer === "median") return median$1(values);
|
|
77645
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
77646
|
+
}
|
|
77647
|
+
function reduceBooleans(reducer, values) {
|
|
77648
|
+
return reducer === "all" ? values.every((value) => value) : values.some((value) => value);
|
|
77649
|
+
}
|
|
77650
|
+
function countsOf(included, total) {
|
|
77651
|
+
return {
|
|
77652
|
+
included,
|
|
77653
|
+
excluded: total - included,
|
|
77654
|
+
total
|
|
77655
|
+
};
|
|
77656
|
+
}
|
|
77657
|
+
function fatalReason(members) {
|
|
77658
|
+
const reasons = members.flatMap((member) => member.state === "unavailable" && member.fatal === true ? [member.reason ?? "source gone"] : []);
|
|
77659
|
+
return reasons.length === 0 ? null : reasons.join("; ");
|
|
77660
|
+
}
|
|
77661
|
+
function emptyOutcome(empty, counts) {
|
|
77662
|
+
if (empty === "null") return {
|
|
77663
|
+
kind: "value",
|
|
77664
|
+
value: null,
|
|
77665
|
+
counts
|
|
77666
|
+
};
|
|
77667
|
+
return {
|
|
77668
|
+
kind: "unavailable",
|
|
77669
|
+
fatal: false,
|
|
77670
|
+
reason: "no member included — unknown is not 0 or off",
|
|
77671
|
+
counts
|
|
77672
|
+
};
|
|
77673
|
+
}
|
|
77674
|
+
/** Pure. `members` is not mutated. An empty included set is null or unavailable, never 0 or false. */
|
|
77675
|
+
function evaluateAggregate(input) {
|
|
77676
|
+
const included = input.members.flatMap((member) => {
|
|
77677
|
+
const value = includedValue(input.reducer, member);
|
|
77678
|
+
return value === null ? [] : [value];
|
|
77679
|
+
});
|
|
77680
|
+
const counts = countsOf(included.length, input.members.length);
|
|
77681
|
+
const gone = fatalReason(input.members);
|
|
77682
|
+
if (gone !== null) return {
|
|
77683
|
+
kind: "unavailable",
|
|
77684
|
+
fatal: true,
|
|
77685
|
+
reason: gone,
|
|
77686
|
+
counts
|
|
77687
|
+
};
|
|
77688
|
+
if (input.publish === "included") return {
|
|
77689
|
+
kind: "value",
|
|
77690
|
+
value: counts.included,
|
|
77691
|
+
counts
|
|
77692
|
+
};
|
|
77693
|
+
if (input.publish === "excluded") return {
|
|
77694
|
+
kind: "value",
|
|
77695
|
+
value: counts.excluded,
|
|
77696
|
+
counts
|
|
77697
|
+
};
|
|
77698
|
+
if (input.publish === "total") return {
|
|
77699
|
+
kind: "value",
|
|
77700
|
+
value: counts.total,
|
|
77701
|
+
counts
|
|
77702
|
+
};
|
|
77703
|
+
if (included.length === 0) return emptyOutcome(input.empty, counts);
|
|
77704
|
+
if (isBinaryReducer(input.reducer)) {
|
|
77705
|
+
const flags = included.filter((value) => typeof value === "boolean");
|
|
77706
|
+
return {
|
|
77707
|
+
kind: "value",
|
|
77708
|
+
value: reduceBooleans(input.reducer, flags),
|
|
77709
|
+
counts
|
|
77710
|
+
};
|
|
77711
|
+
}
|
|
77712
|
+
const numbers = included.filter((value) => typeof value === "number");
|
|
77713
|
+
return {
|
|
77714
|
+
kind: "value",
|
|
77715
|
+
value: reduceNumbers(input.reducer, numbers),
|
|
77716
|
+
counts
|
|
77717
|
+
};
|
|
77718
|
+
}
|
|
77719
|
+
//#endregion
|
|
77720
|
+
//#region src/composition/helpers/source-pick.ts
|
|
77721
|
+
/** What the member step asks the selector for this template. */
|
|
77722
|
+
function sourcePickForTemplate(template) {
|
|
77723
|
+
const valueKind = template.family === "numeric" ? "number" : "boolean";
|
|
77724
|
+
return {
|
|
77725
|
+
purpose: "member",
|
|
77726
|
+
multiple: true,
|
|
77727
|
+
max: 64,
|
|
77728
|
+
deviceTypes: [template.memberDeviceType],
|
|
77729
|
+
accept: template.accept.map((field) => ({
|
|
77730
|
+
...field,
|
|
77731
|
+
valueKind
|
|
77732
|
+
})),
|
|
77733
|
+
history: {
|
|
77734
|
+
required: false,
|
|
77735
|
+
minRetentionMs: null
|
|
77736
|
+
},
|
|
77737
|
+
mustBindCaps: [],
|
|
77738
|
+
exclude: []
|
|
77739
|
+
};
|
|
77740
|
+
}
|
|
77741
|
+
//#endregion
|
|
77195
77742
|
//#region src/units/unit-table.ts
|
|
77196
77743
|
/**
|
|
77197
77744
|
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
@@ -77320,6 +77867,11 @@ var UNIT_TABLE = {
|
|
|
77320
77867
|
factor: 1609.344,
|
|
77321
77868
|
offset: 0
|
|
77322
77869
|
},
|
|
77870
|
+
"m²": {
|
|
77871
|
+
dimension: "area",
|
|
77872
|
+
factor: 1,
|
|
77873
|
+
offset: 0
|
|
77874
|
+
},
|
|
77323
77875
|
lx: {
|
|
77324
77876
|
dimension: "illuminance",
|
|
77325
77877
|
factor: 1,
|
|
@@ -77424,6 +77976,121 @@ var UNIT_TABLE = {
|
|
|
77424
77976
|
dimension: "percentage",
|
|
77425
77977
|
factor: 1,
|
|
77426
77978
|
offset: 0
|
|
77979
|
+
},
|
|
77980
|
+
L: {
|
|
77981
|
+
dimension: "volume",
|
|
77982
|
+
factor: 1,
|
|
77983
|
+
offset: 0
|
|
77984
|
+
},
|
|
77985
|
+
mL: {
|
|
77986
|
+
dimension: "volume",
|
|
77987
|
+
factor: .001,
|
|
77988
|
+
offset: 0
|
|
77989
|
+
},
|
|
77990
|
+
gal: {
|
|
77991
|
+
dimension: "volume",
|
|
77992
|
+
factor: 3.785411784,
|
|
77993
|
+
offset: 0
|
|
77994
|
+
},
|
|
77995
|
+
s: {
|
|
77996
|
+
dimension: "duration",
|
|
77997
|
+
factor: 1,
|
|
77998
|
+
offset: 0
|
|
77999
|
+
},
|
|
78000
|
+
ms: {
|
|
78001
|
+
dimension: "duration",
|
|
78002
|
+
factor: .001,
|
|
78003
|
+
offset: 0
|
|
78004
|
+
},
|
|
78005
|
+
min: {
|
|
78006
|
+
dimension: "duration",
|
|
78007
|
+
factor: 60,
|
|
78008
|
+
offset: 0
|
|
78009
|
+
},
|
|
78010
|
+
h: {
|
|
78011
|
+
dimension: "duration",
|
|
78012
|
+
factor: 3600,
|
|
78013
|
+
offset: 0
|
|
78014
|
+
},
|
|
78015
|
+
d: {
|
|
78016
|
+
dimension: "duration",
|
|
78017
|
+
factor: 86400,
|
|
78018
|
+
offset: 0
|
|
78019
|
+
},
|
|
78020
|
+
B: {
|
|
78021
|
+
dimension: "information",
|
|
78022
|
+
factor: 1,
|
|
78023
|
+
offset: 0
|
|
78024
|
+
},
|
|
78025
|
+
KiB: {
|
|
78026
|
+
dimension: "information",
|
|
78027
|
+
factor: 1024,
|
|
78028
|
+
offset: 0
|
|
78029
|
+
},
|
|
78030
|
+
MiB: {
|
|
78031
|
+
dimension: "information",
|
|
78032
|
+
factor: 1024 ** 2,
|
|
78033
|
+
offset: 0
|
|
78034
|
+
},
|
|
78035
|
+
GiB: {
|
|
78036
|
+
dimension: "information",
|
|
78037
|
+
factor: 1024 ** 3,
|
|
78038
|
+
offset: 0
|
|
78039
|
+
},
|
|
78040
|
+
TiB: {
|
|
78041
|
+
dimension: "information",
|
|
78042
|
+
factor: 1024 ** 4,
|
|
78043
|
+
offset: 0
|
|
78044
|
+
},
|
|
78045
|
+
kB: {
|
|
78046
|
+
dimension: "information",
|
|
78047
|
+
factor: 1e3,
|
|
78048
|
+
offset: 0
|
|
78049
|
+
},
|
|
78050
|
+
MB: {
|
|
78051
|
+
dimension: "information",
|
|
78052
|
+
factor: 1e6,
|
|
78053
|
+
offset: 0
|
|
78054
|
+
},
|
|
78055
|
+
GB: {
|
|
78056
|
+
dimension: "information",
|
|
78057
|
+
factor: 1e9,
|
|
78058
|
+
offset: 0
|
|
78059
|
+
},
|
|
78060
|
+
"°": {
|
|
78061
|
+
dimension: "angle",
|
|
78062
|
+
factor: 1,
|
|
78063
|
+
offset: 0
|
|
78064
|
+
},
|
|
78065
|
+
dBFS: {
|
|
78066
|
+
dimension: "sound-level",
|
|
78067
|
+
factor: 1,
|
|
78068
|
+
offset: 0
|
|
78069
|
+
},
|
|
78070
|
+
dBm: {
|
|
78071
|
+
dimension: "signal-level",
|
|
78072
|
+
factor: 1,
|
|
78073
|
+
offset: 0
|
|
78074
|
+
},
|
|
78075
|
+
mired: {
|
|
78076
|
+
dimension: "colour-temperature",
|
|
78077
|
+
factor: 1,
|
|
78078
|
+
offset: 0
|
|
78079
|
+
},
|
|
78080
|
+
kbps: {
|
|
78081
|
+
dimension: "bitrate",
|
|
78082
|
+
factor: 1,
|
|
78083
|
+
offset: 0
|
|
78084
|
+
},
|
|
78085
|
+
Mbps: {
|
|
78086
|
+
dimension: "bitrate",
|
|
78087
|
+
factor: 1e3,
|
|
78088
|
+
offset: 0
|
|
78089
|
+
},
|
|
78090
|
+
fps: {
|
|
78091
|
+
dimension: "rate",
|
|
78092
|
+
factor: 1,
|
|
78093
|
+
offset: 0
|
|
77427
78094
|
}
|
|
77428
78095
|
};
|
|
77429
78096
|
//#endregion
|
|
@@ -77514,6 +78181,17 @@ function canConvertUnit(from, to) {
|
|
|
77514
78181
|
* Every known unit spelling in a dimension (table insertion order — canonical
|
|
77515
78182
|
* unit first). Powers the UI's same-dimension unit picker.
|
|
77516
78183
|
*/
|
|
78184
|
+
/**
|
|
78185
|
+
* Convert a difference, not a reading. Affine units (°F) shift an absolute
|
|
78186
|
+
* value by their offset; a step of 1°F is 5/9°C, so the offset is cancelled.
|
|
78187
|
+
*/
|
|
78188
|
+
function tryConvertDelta(value, from, to) {
|
|
78189
|
+
if (from === to) return value;
|
|
78190
|
+
const origin = tryConvertUnit(0, from, to);
|
|
78191
|
+
const shifted = tryConvertUnit(value, from, to);
|
|
78192
|
+
if (origin === void 0 || shifted === void 0) return void 0;
|
|
78193
|
+
return shifted - origin;
|
|
78194
|
+
}
|
|
77517
78195
|
function unitsForDimension(dimension) {
|
|
77518
78196
|
const out = [];
|
|
77519
78197
|
for (const [unit, spec] of Object.entries(UNIT_TABLE)) if (spec.dimension === dimension) out.push(unit);
|
|
@@ -77647,11 +78325,45 @@ function expressionOutcome(source, read, now, stateful) {
|
|
|
77647
78325
|
deadline: deadlines.length > 0 ? Math.min(...deadlines) : null
|
|
77648
78326
|
};
|
|
77649
78327
|
}
|
|
78328
|
+
function aggregateRead(reading) {
|
|
78329
|
+
if (reading.state === "unavailable") return {
|
|
78330
|
+
state: "unavailable",
|
|
78331
|
+
fatal: reading.fatal,
|
|
78332
|
+
reason: reading.reason
|
|
78333
|
+
};
|
|
78334
|
+
return {
|
|
78335
|
+
state: reading.state,
|
|
78336
|
+
value: reading.value,
|
|
78337
|
+
...reading.state === "stale" ? { reason: reading.reason } : {}
|
|
78338
|
+
};
|
|
78339
|
+
}
|
|
78340
|
+
function aggregateField(source, read) {
|
|
78341
|
+
const outcome = evaluateAggregate({
|
|
78342
|
+
reducer: source.reducer,
|
|
78343
|
+
members: source.reads.map((item) => aggregateRead(read(item))),
|
|
78344
|
+
publish: source.publish,
|
|
78345
|
+
empty: source.empty
|
|
78346
|
+
});
|
|
78347
|
+
if (outcome.kind === "value") return {
|
|
78348
|
+
state: "fresh",
|
|
78349
|
+
value: outcome.value,
|
|
78350
|
+
reason: null,
|
|
78351
|
+
deadline: null
|
|
78352
|
+
};
|
|
78353
|
+
return {
|
|
78354
|
+
state: "unavailable",
|
|
78355
|
+
value: null,
|
|
78356
|
+
reason: outcome.reason,
|
|
78357
|
+
fatal: outcome.fatal,
|
|
78358
|
+
confirmed: true
|
|
78359
|
+
};
|
|
78360
|
+
}
|
|
77650
78361
|
function evaluateCompositionField(input) {
|
|
77651
78362
|
const { source } = input;
|
|
77652
78363
|
switch (source.kind) {
|
|
77653
78364
|
case "from": return fromReading(input.read(source), source);
|
|
77654
78365
|
case "expression": return expressionOutcome(source, input.read, input.now, input.stateful);
|
|
78366
|
+
case "aggregate": return aggregateField(source, input.read);
|
|
77655
78367
|
case "code": return {
|
|
77656
78368
|
state: "unavailable",
|
|
77657
78369
|
value: null,
|
|
@@ -77817,9 +78529,9 @@ function feederCustomizationExample(sources) {
|
|
|
77817
78529
|
expr: "number(d)",
|
|
77818
78530
|
bindings: days
|
|
77819
78531
|
},
|
|
77820
|
-
"remaining.
|
|
78532
|
+
"remaining.kind": {
|
|
77821
78533
|
kind: "expression",
|
|
77822
|
-
expr: "\"
|
|
78534
|
+
expr: "\"duration\"",
|
|
77823
78535
|
bindings: {}
|
|
77824
78536
|
},
|
|
77825
78537
|
status: {
|
|
@@ -78085,19 +78797,9 @@ function convertUnitTargets(from) {
|
|
|
78085
78797
|
//#region src/generated/customize-catalog.ts
|
|
78086
78798
|
/**
|
|
78087
78799
|
* Customize catalog, projected from every `*.cap.ts` `customize` block.
|
|
78088
|
-
*
|
|
78800
|
+
* 5 caps. Field keys are `runtimeState` paths. No Zod.
|
|
78089
78801
|
*/
|
|
78090
78802
|
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
78803
|
"battery": {
|
|
78102
78804
|
version: 1,
|
|
78103
78805
|
targets: [{
|
|
@@ -78112,7 +78814,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78112
78814
|
require_err_msg.DeviceType.Container,
|
|
78113
78815
|
require_err_msg.DeviceType.Thermostat
|
|
78114
78816
|
],
|
|
78115
|
-
apply: "add
|
|
78817
|
+
apply: "add",
|
|
78116
78818
|
vocabularyCap: "battery",
|
|
78117
78819
|
vocabularyStateField: "percentage",
|
|
78118
78820
|
sources: [{
|
|
@@ -78151,38 +78853,6 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78151
78853
|
when: "add"
|
|
78152
78854
|
}
|
|
78153
78855
|
]
|
|
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
78856
|
}]
|
|
78187
78857
|
},
|
|
78188
78858
|
"consumables": {
|
|
@@ -78260,12 +78930,8 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78260
78930
|
transforms: [{ kind: "identity" }]
|
|
78261
78931
|
}],
|
|
78262
78932
|
literals: [{
|
|
78263
|
-
path: "remaining.
|
|
78264
|
-
values: [
|
|
78265
|
-
"days",
|
|
78266
|
-
"hours",
|
|
78267
|
-
"cycles"
|
|
78268
|
-
]
|
|
78933
|
+
path: "remaining.kind",
|
|
78934
|
+
values: ["duration", "count"]
|
|
78269
78935
|
}]
|
|
78270
78936
|
},
|
|
78271
78937
|
{
|
|
@@ -78323,8 +78989,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78323
78989
|
path: "lastFetchedAt",
|
|
78324
78990
|
when: "add"
|
|
78325
78991
|
}]
|
|
78326
|
-
}]
|
|
78327
|
-
advancedParameters: []
|
|
78992
|
+
}]
|
|
78328
78993
|
},
|
|
78329
78994
|
"doorbell": {
|
|
78330
78995
|
version: 1,
|
|
@@ -78356,17 +79021,6 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78356
79021
|
counterPath: "pressCountSinceStart",
|
|
78357
79022
|
highWater: "composer-advance",
|
|
78358
79023
|
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
79024
|
}]
|
|
78371
79025
|
},
|
|
78372
79026
|
"motion": {
|
|
@@ -78375,7 +79029,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78375
79029
|
id: "detected",
|
|
78376
79030
|
cardinality: "event",
|
|
78377
79031
|
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
78378
|
-
apply: "
|
|
79032
|
+
apply: "add",
|
|
78379
79033
|
vocabularyCap: "motion",
|
|
78380
79034
|
vocabularyEvent: "onMotionChanged",
|
|
78381
79035
|
sources: [{
|
|
@@ -78404,22 +79058,6 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78404
79058
|
"confirm",
|
|
78405
79059
|
"replace"
|
|
78406
79060
|
]
|
|
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
79061
|
}]
|
|
78424
79062
|
},
|
|
78425
79063
|
"running-state": {
|
|
@@ -78439,7 +79077,7 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78439
79077
|
require_err_msg.DeviceType.Thermostat,
|
|
78440
79078
|
require_err_msg.DeviceType.PetFeeder
|
|
78441
79079
|
],
|
|
78442
|
-
apply: "add
|
|
79080
|
+
apply: "add",
|
|
78443
79081
|
vocabularyCap: "running-state",
|
|
78444
79082
|
vocabularyStateField: "running",
|
|
78445
79083
|
sources: [
|
|
@@ -78502,29 +79140,26 @@ var CAP_CUSTOMIZE_CATALOG = {
|
|
|
78502
79140
|
sourceChangedAt: "prefer"
|
|
78503
79141
|
}
|
|
78504
79142
|
]
|
|
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
79143
|
}]
|
|
78526
79144
|
}
|
|
78527
79145
|
};
|
|
79146
|
+
/**
|
|
79147
|
+
* Unit meta on runtime-state fields. The composed-device row reads this;
|
|
79148
|
+
* it is not an override list (D944).
|
|
79149
|
+
*/
|
|
79150
|
+
var CAP_RUNTIME_FIELD_UNITS = {
|
|
79151
|
+
"ambient-light-sensor": { lux: "lx" },
|
|
79152
|
+
"battery": {
|
|
79153
|
+
percentage: "%",
|
|
79154
|
+
volts: "V"
|
|
79155
|
+
},
|
|
79156
|
+
"humidity-sensor": { percent: "%" },
|
|
79157
|
+
"power-meter": {
|
|
79158
|
+
watts: "W",
|
|
79159
|
+
kwhTotal: "kWh"
|
|
79160
|
+
},
|
|
79161
|
+
"temperature-sensor": { celsius: "°C" }
|
|
79162
|
+
};
|
|
78528
79163
|
//#endregion
|
|
78529
79164
|
//#region src/composition/customize/field-source.ts
|
|
78530
79165
|
function fromRead(source, cap, fieldPath) {
|
|
@@ -80584,6 +81219,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
80584
81219
|
featureProbe: featureProbeCapability,
|
|
80585
81220
|
flood: floodCapability,
|
|
80586
81221
|
gas: gasCapability,
|
|
81222
|
+
groupStatus: groupStatusCapability,
|
|
80587
81223
|
heatingValve: heatingValveCapability,
|
|
80588
81224
|
humidifier: humidifierCapability,
|
|
80589
81225
|
humiditySensor: humiditySensorCapability,
|
|
@@ -85909,6 +86545,13 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
85909
86545
|
access: "view",
|
|
85910
86546
|
role: "viewer"
|
|
85911
86547
|
},
|
|
86548
|
+
"groupStatus.getStatus": {
|
|
86549
|
+
capName: "group-status",
|
|
86550
|
+
capScope: "device",
|
|
86551
|
+
addonId: null,
|
|
86552
|
+
access: "view",
|
|
86553
|
+
role: "viewer"
|
|
86554
|
+
},
|
|
85912
86555
|
"heatingValve.getStatus": {
|
|
85913
86556
|
capName: "heating-valve",
|
|
85914
86557
|
capScope: "device",
|
|
@@ -92447,6 +93090,7 @@ var KNOWN_CAP_NAMES = [
|
|
|
92447
93090
|
"filesystem-browse",
|
|
92448
93091
|
"flood",
|
|
92449
93092
|
"gas",
|
|
93093
|
+
"group-status",
|
|
92450
93094
|
"heating-valve",
|
|
92451
93095
|
"humidifier",
|
|
92452
93096
|
"humidity-sensor",
|
|
@@ -92595,6 +93239,7 @@ var DEVICE_CAP_NAMES = [
|
|
|
92595
93239
|
"feature-probe",
|
|
92596
93240
|
"flood",
|
|
92597
93241
|
"gas",
|
|
93242
|
+
"group-status",
|
|
92598
93243
|
"heating-valve",
|
|
92599
93244
|
"humidifier",
|
|
92600
93245
|
"humidity-sensor",
|
|
@@ -96112,6 +96757,33 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96112
96757
|
icon: "flame"
|
|
96113
96758
|
}]
|
|
96114
96759
|
},
|
|
96760
|
+
"group-status": {
|
|
96761
|
+
scope: "device",
|
|
96762
|
+
noun: t("Group", "Gruppo"),
|
|
96763
|
+
state: [
|
|
96764
|
+
{
|
|
96765
|
+
kind: "numeric",
|
|
96766
|
+
field: "included",
|
|
96767
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
96768
|
+
label: t("Reporting", "Rispondono"),
|
|
96769
|
+
icon: "users"
|
|
96770
|
+
},
|
|
96771
|
+
{
|
|
96772
|
+
kind: "numeric",
|
|
96773
|
+
field: "excluded",
|
|
96774
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
96775
|
+
label: t("Excluded", "Esclusi"),
|
|
96776
|
+
icon: "users"
|
|
96777
|
+
},
|
|
96778
|
+
{
|
|
96779
|
+
kind: "numeric",
|
|
96780
|
+
field: "total",
|
|
96781
|
+
quantity: t("the member count", "il numero di membri"),
|
|
96782
|
+
label: t("Members", "Membri"),
|
|
96783
|
+
icon: "sigma"
|
|
96784
|
+
}
|
|
96785
|
+
]
|
|
96786
|
+
},
|
|
96115
96787
|
"humidity-sensor": {
|
|
96116
96788
|
scope: "device",
|
|
96117
96789
|
noun: t("Humidity", "Umidità"),
|
|
@@ -96145,7 +96817,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96145
96817
|
field: "value",
|
|
96146
96818
|
quantity: t("the reading", "il valore"),
|
|
96147
96819
|
label: t("Reading", "Valore"),
|
|
96148
|
-
unitField: "unit",
|
|
96149
96820
|
icon: "gauge"
|
|
96150
96821
|
}]
|
|
96151
96822
|
},
|
|
@@ -96281,7 +96952,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96281
96952
|
field: "temperature",
|
|
96282
96953
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
96283
96954
|
label: t("Temperature", "Temperatura"),
|
|
96284
|
-
|
|
96955
|
+
unit: "°C",
|
|
96285
96956
|
icon: "thermometer"
|
|
96286
96957
|
},
|
|
96287
96958
|
{
|
|
@@ -96297,7 +96968,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96297
96968
|
field: "windSpeed",
|
|
96298
96969
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
96299
96970
|
label: t("Wind", "Vento"),
|
|
96300
|
-
|
|
96971
|
+
unit: "m/s",
|
|
96301
96972
|
icon: "wind"
|
|
96302
96973
|
},
|
|
96303
96974
|
{
|
|
@@ -96305,7 +96976,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
96305
96976
|
field: "pressure",
|
|
96306
96977
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
96307
96978
|
label: t("Pressure", "Pressione"),
|
|
96308
|
-
|
|
96979
|
+
unit: "hPa",
|
|
96309
96980
|
icon: "gauge"
|
|
96310
96981
|
}
|
|
96311
96982
|
]
|
|
@@ -98250,6 +98921,7 @@ var CAP_NAMES_WITH_STATUS = [
|
|
|
98250
98921
|
"feature-probe",
|
|
98251
98922
|
"flood",
|
|
98252
98923
|
"gas",
|
|
98924
|
+
"group-status",
|
|
98253
98925
|
"heating-valve",
|
|
98254
98926
|
"humidifier",
|
|
98255
98927
|
"humidity-sensor",
|
|
@@ -98372,6 +99044,7 @@ var CAPABILITY_NAMES = {
|
|
|
98372
99044
|
filesystemBrowse: "filesystem-browse",
|
|
98373
99045
|
flood: "flood",
|
|
98374
99046
|
gas: "gas",
|
|
99047
|
+
groupStatus: "group-status",
|
|
98375
99048
|
heatingValve: "heating-valve",
|
|
98376
99049
|
humidifier: "humidifier",
|
|
98377
99050
|
humiditySensor: "humidity-sensor",
|
|
@@ -98778,6 +99451,10 @@ var CAPABILITY_ROUTER_KEYS = [
|
|
|
98778
99451
|
key: "gas",
|
|
98779
99452
|
name: "gas"
|
|
98780
99453
|
},
|
|
99454
|
+
{
|
|
99455
|
+
key: "groupStatus",
|
|
99456
|
+
name: "group-status"
|
|
99457
|
+
},
|
|
98781
99458
|
{
|
|
98782
99459
|
key: "heatingValve",
|
|
98783
99460
|
name: "heating-valve"
|
|
@@ -99291,6 +99968,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
99291
99968
|
filesystemBrowseCapability,
|
|
99292
99969
|
floodCapability,
|
|
99293
99970
|
gasCapability,
|
|
99971
|
+
groupStatusCapability,
|
|
99294
99972
|
heatingValveCapability,
|
|
99295
99973
|
humidifierCapability,
|
|
99296
99974
|
humiditySensorCapability,
|
|
@@ -100367,6 +101045,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
100367
101045
|
form: "single",
|
|
100368
101046
|
optional: false
|
|
100369
101047
|
}],
|
|
101048
|
+
"groupStatus.getStatus": [{
|
|
101049
|
+
name: "deviceId",
|
|
101050
|
+
form: "single",
|
|
101051
|
+
optional: false
|
|
101052
|
+
}],
|
|
100370
101053
|
"heatingValve.getStatus": [{
|
|
100371
101054
|
name: "deviceId",
|
|
100372
101055
|
form: "single",
|
|
@@ -102378,7 +103061,7 @@ function getCapsByProviderKind(kind) {
|
|
|
102378
103061
|
//#region src/generated/runtime-state-durability.ts
|
|
102379
103062
|
/**
|
|
102380
103063
|
* Per-cap runtime-state policy, projected from every `*.cap.ts` that declares
|
|
102381
|
-
* `runtimeState`.
|
|
103064
|
+
* `runtimeState`. 73 caps: 38 `restored`, 35 `session`.
|
|
102382
103065
|
*
|
|
102383
103066
|
* A cap absent from this map has no runtime-state slice at all. A cap PRESENT
|
|
102384
103067
|
* with `durability: 'session'` has one and has decided not to keep it.
|
|
@@ -102496,6 +103179,10 @@ var RUNTIME_STATE_POLICY = {
|
|
|
102496
103179
|
durability: "restored",
|
|
102497
103180
|
volatileFields: ["lastChangedAt"]
|
|
102498
103181
|
},
|
|
103182
|
+
"group-status": {
|
|
103183
|
+
durability: "session",
|
|
103184
|
+
volatileFields: []
|
|
103185
|
+
},
|
|
102499
103186
|
"heating-valve": {
|
|
102500
103187
|
durability: "session",
|
|
102501
103188
|
volatileFields: ["lastFetchedAt"]
|
|
@@ -102838,7 +103525,7 @@ var BucketAccumulator = class {
|
|
|
102838
103525
|
//#region src/generated/history-catalog.ts
|
|
102839
103526
|
/**
|
|
102840
103527
|
* Cap history catalog, projected from every `*.cap.ts` `history` block.
|
|
102841
|
-
* 41 caps with series (
|
|
103528
|
+
* 41 caps with series (75 series), 31 caps answered `'none'`.
|
|
102842
103529
|
* Field keys are `runtimeState` paths (`a.b` into fixed objects only).
|
|
102843
103530
|
*/
|
|
102844
103531
|
var HISTORY_CATALOG = {
|
|
@@ -102855,12 +103542,12 @@ var HISTORY_CATALOG = {
|
|
|
102855
103542
|
},
|
|
102856
103543
|
"pm25": {
|
|
102857
103544
|
kind: "gauge",
|
|
102858
|
-
unit: "
|
|
103545
|
+
unit: "µg/m³",
|
|
102859
103546
|
deadband: 1
|
|
102860
103547
|
},
|
|
102861
103548
|
"pm10": {
|
|
102862
103549
|
kind: "gauge",
|
|
102863
|
-
unit: "
|
|
103550
|
+
unit: "µg/m³",
|
|
102864
103551
|
deadband: 1
|
|
102865
103552
|
},
|
|
102866
103553
|
"aqi": {
|
|
@@ -102890,10 +103577,16 @@ var HISTORY_CATALOG = {
|
|
|
102890
103577
|
deadbandPct: 10,
|
|
102891
103578
|
minIntervalMs: 6e4
|
|
102892
103579
|
} },
|
|
102893
|
-
"battery": {
|
|
102894
|
-
|
|
102895
|
-
|
|
102896
|
-
|
|
103580
|
+
"battery": {
|
|
103581
|
+
"percentage": {
|
|
103582
|
+
kind: "gauge",
|
|
103583
|
+
unit: "%"
|
|
103584
|
+
},
|
|
103585
|
+
"volts": {
|
|
103586
|
+
kind: "gauge",
|
|
103587
|
+
unit: "V"
|
|
103588
|
+
}
|
|
103589
|
+
},
|
|
102897
103590
|
"binary": { "on": { kind: "boolean" } },
|
|
102898
103591
|
"brightness": { "percentage": {
|
|
102899
103592
|
kind: "gauge",
|
|
@@ -102977,7 +103670,7 @@ var HISTORY_CATALOG = {
|
|
|
102977
103670
|
},
|
|
102978
103671
|
"enum-sensor": { "value": {
|
|
102979
103672
|
kind: "enum",
|
|
102980
|
-
skipWhenSet: "
|
|
103673
|
+
skipWhenSet: "timestamp"
|
|
102981
103674
|
} },
|
|
102982
103675
|
"fan-control": {
|
|
102983
103676
|
"percentage": {
|
|
@@ -103050,7 +103743,6 @@ var HISTORY_CATALOG = {
|
|
|
103050
103743
|
},
|
|
103051
103744
|
"numeric-sensor": { "value": {
|
|
103052
103745
|
kind: "gauge",
|
|
103053
|
-
unitFrom: "unit",
|
|
103054
103746
|
minIntervalMs: 3e4
|
|
103055
103747
|
} },
|
|
103056
103748
|
"pet-feeder": {
|
|
@@ -103064,7 +103756,7 @@ var HISTORY_CATALOG = {
|
|
|
103064
103756
|
},
|
|
103065
103757
|
"desiccantLeftDays": {
|
|
103066
103758
|
kind: "gauge",
|
|
103067
|
-
unit: "
|
|
103759
|
+
unit: "s"
|
|
103068
103760
|
}
|
|
103069
103761
|
},
|
|
103070
103762
|
"power-meter": {
|
|
@@ -103168,7 +103860,7 @@ var HISTORY_CATALOG = {
|
|
|
103168
103860
|
"weather": {
|
|
103169
103861
|
"temperature": {
|
|
103170
103862
|
kind: "gauge",
|
|
103171
|
-
|
|
103863
|
+
unit: "°C",
|
|
103172
103864
|
deadband: .2
|
|
103173
103865
|
},
|
|
103174
103866
|
"humidity": {
|
|
@@ -103178,12 +103870,12 @@ var HISTORY_CATALOG = {
|
|
|
103178
103870
|
},
|
|
103179
103871
|
"pressure": {
|
|
103180
103872
|
kind: "gauge",
|
|
103181
|
-
|
|
103873
|
+
unit: "hPa",
|
|
103182
103874
|
deadband: .5
|
|
103183
103875
|
},
|
|
103184
103876
|
"windSpeed": {
|
|
103185
103877
|
kind: "gauge",
|
|
103186
|
-
|
|
103878
|
+
unit: "m/s",
|
|
103187
103879
|
deadband: .5
|
|
103188
103880
|
}
|
|
103189
103881
|
}
|
|
@@ -103217,7 +103909,6 @@ var HISTORY_ITEM_CATALOG = { "consumables": {
|
|
|
103217
103909
|
},
|
|
103218
103910
|
"remaining.value": {
|
|
103219
103911
|
kind: "gauge",
|
|
103220
|
-
unitFrom: "remaining.unit",
|
|
103221
103912
|
deadband: 1,
|
|
103222
103913
|
displayName: "Remaining"
|
|
103223
103914
|
}
|
|
@@ -103235,6 +103926,7 @@ var HISTORY_NONE_CAPS = [
|
|
|
103235
103926
|
"doorbell",
|
|
103236
103927
|
"event-emitter",
|
|
103237
103928
|
"feature-probe",
|
|
103929
|
+
"group-status",
|
|
103238
103930
|
"image",
|
|
103239
103931
|
"image-settings",
|
|
103240
103932
|
"intercom",
|
|
@@ -103261,6 +103953,14 @@ function historyFieldsFor(capName) {
|
|
|
103261
103953
|
return HISTORY_CATALOG[capName] ?? {};
|
|
103262
103954
|
}
|
|
103263
103955
|
//#endregion
|
|
103956
|
+
//#region src/capabilities/runtime-field-unit.ts
|
|
103957
|
+
/**
|
|
103958
|
+
* The unit a composed-device field row offers convert-unit from (D941, D944).
|
|
103959
|
+
*/
|
|
103960
|
+
function runtimeFieldUnit(cap, path) {
|
|
103961
|
+
return CAP_RUNTIME_FIELD_UNITS[cap]?.[path];
|
|
103962
|
+
}
|
|
103963
|
+
//#endregion
|
|
103264
103964
|
//#region src/composition/customize/override-draft.ts
|
|
103265
103965
|
/**
|
|
103266
103966
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
@@ -112817,6 +113517,227 @@ var DEVICE_TYPE_INFO = { ["camera"]: {
|
|
|
112817
113517
|
icon: "camera"
|
|
112818
113518
|
} };
|
|
112819
113519
|
//#endregion
|
|
113520
|
+
//#region src/units/threshold.ts
|
|
113521
|
+
/**
|
|
113522
|
+
* Move a threshold between the unit the operator sees and the stored base.
|
|
113523
|
+
* A failed conversion leaves the number unchanged — the recipe stays serialisable.
|
|
113524
|
+
*/
|
|
113525
|
+
function thresholdToBase(value, displayUnit, baseUnit) {
|
|
113526
|
+
if (!Number.isFinite(value) || displayUnit === baseUnit) return value;
|
|
113527
|
+
return tryConvertUnit(value, displayUnit, baseUnit) ?? value;
|
|
113528
|
+
}
|
|
113529
|
+
function thresholdToDisplay(value, baseUnit, displayUnit) {
|
|
113530
|
+
if (!Number.isFinite(value) || baseUnit === displayUnit) return value;
|
|
113531
|
+
return tryConvertUnit(value, baseUnit, displayUnit) ?? value;
|
|
113532
|
+
}
|
|
113533
|
+
//#endregion
|
|
113534
|
+
//#region src/units/format-reading.ts
|
|
113535
|
+
/**
|
|
113536
|
+
* Render a stored base-unit reading (D944 §4). The preference defaults to
|
|
113537
|
+
* metric. An operator override is applied by the caller via `convertUnit`
|
|
113538
|
+
* before this, or by passing the already-chosen display unit through
|
|
113539
|
+
* `resolveSensorDisplay` — this function is the quantity → string step.
|
|
113540
|
+
*/
|
|
113541
|
+
var DURATION_STEPS = [
|
|
113542
|
+
{
|
|
113543
|
+
value: 86400,
|
|
113544
|
+
unit: "d"
|
|
113545
|
+
},
|
|
113546
|
+
{
|
|
113547
|
+
value: 3600,
|
|
113548
|
+
unit: "h"
|
|
113549
|
+
},
|
|
113550
|
+
{
|
|
113551
|
+
value: 60,
|
|
113552
|
+
unit: "min"
|
|
113553
|
+
}
|
|
113554
|
+
];
|
|
113555
|
+
var INFO_STEPS = [
|
|
113556
|
+
{
|
|
113557
|
+
factor: 1024 ** 4,
|
|
113558
|
+
unit: "TiB"
|
|
113559
|
+
},
|
|
113560
|
+
{
|
|
113561
|
+
factor: 1024 ** 3,
|
|
113562
|
+
unit: "GiB"
|
|
113563
|
+
},
|
|
113564
|
+
{
|
|
113565
|
+
factor: 1024 ** 2,
|
|
113566
|
+
unit: "MiB"
|
|
113567
|
+
},
|
|
113568
|
+
{
|
|
113569
|
+
factor: 1024,
|
|
113570
|
+
unit: "KiB"
|
|
113571
|
+
}
|
|
113572
|
+
];
|
|
113573
|
+
function formatMagnitude(value, precision) {
|
|
113574
|
+
if (!Number.isFinite(value)) return "";
|
|
113575
|
+
if (precision !== void 0) return value.toFixed(precision);
|
|
113576
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(1);
|
|
113577
|
+
}
|
|
113578
|
+
function scaleDuration(seconds) {
|
|
113579
|
+
const abs = Math.abs(seconds);
|
|
113580
|
+
for (const step of DURATION_STEPS) if (abs >= step.value) return {
|
|
113581
|
+
value: seconds / step.value,
|
|
113582
|
+
unit: step.unit
|
|
113583
|
+
};
|
|
113584
|
+
return {
|
|
113585
|
+
value: seconds,
|
|
113586
|
+
unit: "s"
|
|
113587
|
+
};
|
|
113588
|
+
}
|
|
113589
|
+
function scaleInformation(bytes) {
|
|
113590
|
+
const abs = Math.abs(bytes);
|
|
113591
|
+
for (const step of INFO_STEPS) if (abs >= step.factor) return {
|
|
113592
|
+
value: bytes / step.factor,
|
|
113593
|
+
unit: step.unit
|
|
113594
|
+
};
|
|
113595
|
+
return {
|
|
113596
|
+
value: bytes,
|
|
113597
|
+
unit: "B"
|
|
113598
|
+
};
|
|
113599
|
+
}
|
|
113600
|
+
function resolvedQuantity(input) {
|
|
113601
|
+
if (input.quantity === "device") return input.deviceQuantity ?? "none";
|
|
113602
|
+
return input.quantity;
|
|
113603
|
+
}
|
|
113604
|
+
function formatReading(input) {
|
|
113605
|
+
const quantity = resolvedQuantity(input);
|
|
113606
|
+
const precision = input.precision;
|
|
113607
|
+
if (!Number.isFinite(input.value)) return {
|
|
113608
|
+
text: "",
|
|
113609
|
+
unit: "",
|
|
113610
|
+
value: input.value
|
|
113611
|
+
};
|
|
113612
|
+
if (quantity === "duration" || quantity === "duration-ms") {
|
|
113613
|
+
const scaled = scaleDuration(quantity === "duration-ms" ? input.value / 1e3 : input.value);
|
|
113614
|
+
return {
|
|
113615
|
+
text: formatMagnitude(scaled.value, precision),
|
|
113616
|
+
unit: scaled.unit,
|
|
113617
|
+
value: scaled.value
|
|
113618
|
+
};
|
|
113619
|
+
}
|
|
113620
|
+
if (quantity === "information") {
|
|
113621
|
+
const scaled = scaleInformation(input.value);
|
|
113622
|
+
return {
|
|
113623
|
+
text: formatMagnitude(scaled.value, precision),
|
|
113624
|
+
unit: scaled.unit,
|
|
113625
|
+
value: scaled.value
|
|
113626
|
+
};
|
|
113627
|
+
}
|
|
113628
|
+
const preference = input.preference ?? "metric";
|
|
113629
|
+
const base = require_sleep.baseUnitOf(quantity);
|
|
113630
|
+
const display = require_sleep.displayUnitFor(quantity, preference);
|
|
113631
|
+
if (base === void 0 || display === void 0) return {
|
|
113632
|
+
text: formatMagnitude(input.value, precision),
|
|
113633
|
+
unit: "",
|
|
113634
|
+
value: input.value
|
|
113635
|
+
};
|
|
113636
|
+
const converted = tryConvertUnit(input.value, base, display);
|
|
113637
|
+
if (converted === void 0) return {
|
|
113638
|
+
text: formatMagnitude(input.value, precision),
|
|
113639
|
+
unit: base,
|
|
113640
|
+
value: input.value
|
|
113641
|
+
};
|
|
113642
|
+
return {
|
|
113643
|
+
text: formatMagnitude(converted, precision),
|
|
113644
|
+
unit: display,
|
|
113645
|
+
value: converted
|
|
113646
|
+
};
|
|
113647
|
+
}
|
|
113648
|
+
//#endregion
|
|
113649
|
+
//#region src/units/ingest-reading.ts
|
|
113650
|
+
/**
|
|
113651
|
+
* Convert an upstream number into the stored base of its quantity (D944 §4).
|
|
113652
|
+
* An unknown unit or a unit from another dimension is a refusal: the caller
|
|
113653
|
+
* logs it and publishes null (D393). This function never guesses.
|
|
113654
|
+
*/
|
|
113655
|
+
var DIMENSION_QUANTITY = {
|
|
113656
|
+
temperature: "temperature",
|
|
113657
|
+
pressure: "pressure",
|
|
113658
|
+
speed: "speed",
|
|
113659
|
+
"precipitation-rate": "precipitation-rate",
|
|
113660
|
+
length: "length",
|
|
113661
|
+
area: "area",
|
|
113662
|
+
illuminance: "illuminance",
|
|
113663
|
+
irradiance: "irradiance",
|
|
113664
|
+
power: "power",
|
|
113665
|
+
"apparent-power": "apparent-power",
|
|
113666
|
+
energy: "energy",
|
|
113667
|
+
voltage: "voltage",
|
|
113668
|
+
current: "current",
|
|
113669
|
+
"concentration-volume": "concentration-volume",
|
|
113670
|
+
"concentration-mass": "concentration-mass",
|
|
113671
|
+
mass: "mass",
|
|
113672
|
+
percentage: "percentage",
|
|
113673
|
+
volume: "volume",
|
|
113674
|
+
duration: "duration",
|
|
113675
|
+
information: "information",
|
|
113676
|
+
angle: "angle",
|
|
113677
|
+
"sound-level": "sound-level",
|
|
113678
|
+
"signal-level": "signal-level",
|
|
113679
|
+
"colour-temperature": "colour-temperature",
|
|
113680
|
+
bitrate: "bitrate",
|
|
113681
|
+
rate: "rate"
|
|
113682
|
+
};
|
|
113683
|
+
/**
|
|
113684
|
+
* Quantity implied by a unit symbol. `ppb` and `ms` are the two symbols
|
|
113685
|
+
* whose stored base is not the dimension's canonical unit. `mm` is length;
|
|
113686
|
+
* precipitation is chosen by the caller (a device class), not by the symbol.
|
|
113687
|
+
*/
|
|
113688
|
+
function quantityFromUnit(rawUnit) {
|
|
113689
|
+
const unit = normalizeUnit(rawUnit);
|
|
113690
|
+
if (unit === void 0) return void 0;
|
|
113691
|
+
if (unit === "ppb") return "concentration-ppb";
|
|
113692
|
+
if (unit === "ms") return "duration-ms";
|
|
113693
|
+
const dimension = unitDimension(unit);
|
|
113694
|
+
if (dimension === void 0) return void 0;
|
|
113695
|
+
return DIMENSION_QUANTITY[dimension];
|
|
113696
|
+
}
|
|
113697
|
+
function ingestReading(input) {
|
|
113698
|
+
if (!Number.isFinite(input.value)) return {
|
|
113699
|
+
ok: false,
|
|
113700
|
+
reason: "non-finite"
|
|
113701
|
+
};
|
|
113702
|
+
if (input.quantity === "device") return {
|
|
113703
|
+
ok: false,
|
|
113704
|
+
reason: "unknown-unit"
|
|
113705
|
+
};
|
|
113706
|
+
const raw = input.rawUnit?.trim();
|
|
113707
|
+
if (raw === void 0 || raw.length === 0) return {
|
|
113708
|
+
ok: true,
|
|
113709
|
+
value: input.value
|
|
113710
|
+
};
|
|
113711
|
+
const unit = normalizeUnit(raw);
|
|
113712
|
+
if (unit === void 0) return {
|
|
113713
|
+
ok: false,
|
|
113714
|
+
reason: "unknown-unit"
|
|
113715
|
+
};
|
|
113716
|
+
const base = require_sleep.baseUnitOf(input.quantity);
|
|
113717
|
+
if (base === void 0) {
|
|
113718
|
+
if (unitDimension(unit) !== void 0) return {
|
|
113719
|
+
ok: false,
|
|
113720
|
+
reason: "cross-dimension"
|
|
113721
|
+
};
|
|
113722
|
+
return {
|
|
113723
|
+
ok: false,
|
|
113724
|
+
reason: "unknown-unit"
|
|
113725
|
+
};
|
|
113726
|
+
}
|
|
113727
|
+
const converted = tryConvertUnit(input.value, unit, base);
|
|
113728
|
+
if (converted === void 0) return unitDimension(unit) === void 0 ? {
|
|
113729
|
+
ok: false,
|
|
113730
|
+
reason: "unknown-unit"
|
|
113731
|
+
} : {
|
|
113732
|
+
ok: false,
|
|
113733
|
+
reason: "cross-dimension"
|
|
113734
|
+
};
|
|
113735
|
+
return {
|
|
113736
|
+
ok: true,
|
|
113737
|
+
value: converted
|
|
113738
|
+
};
|
|
113739
|
+
}
|
|
113740
|
+
//#endregion
|
|
112820
113741
|
//#region src/util/location-match.ts
|
|
112821
113742
|
/**
|
|
112822
113743
|
* Pure fuzzy matcher for adoption location import. Normalized
|
|
@@ -114261,6 +115182,7 @@ exports.ADMIN_SCOPE = ADMIN_SCOPE;
|
|
|
114261
115182
|
exports.AGENT_MDNS_QUERY_NAME = AGENT_MDNS_QUERY_NAME;
|
|
114262
115183
|
exports.AGENT_MDNS_SERVICE_TYPE = AGENT_MDNS_SERVICE_TYPE;
|
|
114263
115184
|
exports.AGENT_MDNS_TXT_KEYS = AGENT_MDNS_TXT_KEYS;
|
|
115185
|
+
exports.AGGREGATE_REDUCERS = require_composition.AGGREGATE_REDUCERS;
|
|
114264
115186
|
exports.AGGREGATE_THROUGHPUT_BY_KIND = AGGREGATE_THROUGHPUT_BY_KIND;
|
|
114265
115187
|
exports.ALEXA_EGRESS_PROFILE = ALEXA_EGRESS_PROFILE;
|
|
114266
115188
|
exports.ALL_CAPABILITY_DEFINITIONS = ALL_CAPABILITY_DEFINITIONS;
|
|
@@ -114315,6 +115237,7 @@ exports.AdoptionOutcomeSchema = AdoptionOutcomeSchema;
|
|
|
114315
115237
|
exports.AdoptionReleaseInputSchema = ReleaseInputSchema;
|
|
114316
115238
|
exports.AdoptionStatusSchema = AdoptionStatusSchema;
|
|
114317
115239
|
exports.AgentLoadSummarySchema = AgentLoadSummarySchema;
|
|
115240
|
+
exports.AggregateReducerSchema = require_composition.AggregateReducerSchema;
|
|
114318
115241
|
exports.AirQualitySensorStatusSchema = AirQualitySensorStatusSchema;
|
|
114319
115242
|
exports.AlarmArmModeSchema = AlarmArmModeSchema;
|
|
114320
115243
|
exports.AlarmPanelStatusSchema = AlarmPanelStatusSchema;
|
|
@@ -114381,6 +115304,7 @@ exports.BASE_LIVE_EGRESS_PROFILE = BASE_LIVE_EGRESS_PROFILE;
|
|
|
114381
115304
|
exports.BATTERY_DEVICE_PROFILE = BATTERY_DEVICE_PROFILE;
|
|
114382
115305
|
exports.BATTERY_UNREACHABLE_AFTER_MS = BATTERY_UNREACHABLE_AFTER_MS;
|
|
114383
115306
|
exports.BENCH_ROOT_STEP_ID = BENCH_ROOT_STEP_ID;
|
|
115307
|
+
exports.BINARY_AGGREGATES = require_composition.BINARY_AGGREGATES;
|
|
114384
115308
|
exports.BIRTH_DECISION_DEFAULT_LIMIT = BIRTH_DECISION_DEFAULT_LIMIT;
|
|
114385
115309
|
exports.BOOT_RECOVERY_BACKOFF_MS = require_sleep.BOOT_RECOVERY_BACKOFF_MS;
|
|
114386
115310
|
exports.BUILTIN_RESULT_KINDS = BUILTIN_RESULT_KINDS;
|
|
@@ -114443,6 +115367,7 @@ exports.CAP_CUSTOMIZE_CATALOG = CAP_CUSTOMIZE_CATALOG;
|
|
|
114443
115367
|
exports.CAP_NAMES_WITH_STATUS = CAP_NAMES_WITH_STATUS;
|
|
114444
115368
|
exports.CAP_NODE_PIN_CONTEXT_KEY = require_sleep.CAP_NODE_PIN_CONTEXT_KEY;
|
|
114445
115369
|
exports.CAP_PROVIDER_KIND_MAP = CAP_PROVIDER_KIND_MAP;
|
|
115370
|
+
exports.CAP_RUNTIME_FIELD_UNITS = CAP_RUNTIME_FIELD_UNITS;
|
|
114446
115371
|
exports.CAP_VOCABULARY = CAP_VOCABULARY;
|
|
114447
115372
|
exports.CAP_VOCABULARY_BY_NAME = CAP_VOCABULARY_BY_NAME;
|
|
114448
115373
|
exports.CATALOG_LANGS = CATALOG_LANGS;
|
|
@@ -114590,6 +115515,7 @@ exports.ComposerApplyResultSchema = ComposerApplyResultSchema;
|
|
|
114590
115515
|
exports.ComposerBlockSchema = ComposerBlockSchema;
|
|
114591
115516
|
exports.ComposerBlockVerdictSchema = ComposerBlockVerdictSchema;
|
|
114592
115517
|
exports.ComposerUnreadableBlockSchema = ComposerUnreadableBlockSchema;
|
|
115518
|
+
exports.CompositionAggregateSourceSchema = require_composition.CompositionAggregateSourceSchema;
|
|
114593
115519
|
exports.CompositionBindingSchema = require_composition.CompositionBindingSchema;
|
|
114594
115520
|
exports.CompositionBlockInputSchema = CompositionBlockInputSchema;
|
|
114595
115521
|
exports.CompositionBlockStateSchema = CompositionBlockStateSchema;
|
|
@@ -114641,8 +115567,8 @@ exports.ConsumableFormSchema = ConsumableFormSchema;
|
|
|
114641
115567
|
exports.ConsumableItemSchema = ConsumableItemSchema;
|
|
114642
115568
|
exports.ConsumableKindSchema = ConsumableKindSchema;
|
|
114643
115569
|
exports.ConsumableLevelSchema = ConsumableLevelSchema;
|
|
115570
|
+
exports.ConsumableRemainingKindSchema = ConsumableRemainingKindSchema;
|
|
114644
115571
|
exports.ConsumableRemainingSchema = ConsumableRemainingSchema;
|
|
114645
|
-
exports.ConsumableRemainingUnitSchema = ConsumableRemainingUnitSchema;
|
|
114646
115572
|
exports.ConsumableStatusSchema = ConsumableStatusSchema;
|
|
114647
115573
|
exports.ConsumablesStatusSchema = ConsumablesStatusSchema;
|
|
114648
115574
|
exports.ContactStatusSchema = ContactStatusSchema;
|
|
@@ -114688,6 +115614,7 @@ exports.DEFAULT_CLUSTER_STEP_SETTINGS = DEFAULT_CLUSTER_STEP_SETTINGS;
|
|
|
114688
115614
|
exports.DEFAULT_CORE_BLOCK_ENTRY = DEFAULT_CORE_BLOCK_ENTRY;
|
|
114689
115615
|
exports.DEFAULT_DECODER_HWACCEL_CONFIG = DEFAULT_DECODER_HWACCEL_CONFIG;
|
|
114690
115616
|
exports.DEFAULT_DETAIL_CROP_CONVENTION = DEFAULT_DETAIL_CROP_CONVENTION;
|
|
115617
|
+
exports.DEFAULT_DISPLAY_PREFERENCE = require_sleep.DEFAULT_DISPLAY_PREFERENCE;
|
|
114691
115618
|
exports.DEFAULT_EVENTS_BAND_BUFFER_SEC = DEFAULT_EVENTS_BAND_BUFFER_SEC;
|
|
114692
115619
|
exports.DEFAULT_EVENT_COLOR = DEFAULT_EVENT_COLOR;
|
|
114693
115620
|
exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
|
|
@@ -114746,6 +115673,7 @@ exports.DEVICE_TOMBSTONE_RETENTION_MS = DEVICE_TOMBSTONE_RETENTION_MS;
|
|
|
114746
115673
|
exports.DEVICE_TYPE_CONTROL_KIND = DEVICE_TYPE_CONTROL_KIND;
|
|
114747
115674
|
exports.DEVICE_TYPE_DO_CAPS = DEVICE_TYPE_DO_CAPS;
|
|
114748
115675
|
exports.DEVICE_TYPE_INFO = DEVICE_TYPE_INFO;
|
|
115676
|
+
exports.DISPLAY_PREFERENCES = require_sleep.DISPLAY_PREFERENCES;
|
|
114749
115677
|
exports.DISPLAY_PRESETS = DISPLAY_PRESETS;
|
|
114750
115678
|
exports.DOORBELL_RISE_DEBOUNCE_MS = DOORBELL_RISE_DEBOUNCE_MS;
|
|
114751
115679
|
exports.DataStoreDatabaseSchema = DataStoreDatabaseSchema;
|
|
@@ -114964,12 +115892,17 @@ exports.FrameInputSchema = FrameInputSchema;
|
|
|
114964
115892
|
exports.FrameLazyCountersSchema = FrameLazyCountersSchema;
|
|
114965
115893
|
exports.FrameLazyMetricsSchema = FrameLazyMetricsSchema;
|
|
114966
115894
|
exports.G711_SCALE_CORRECTION_DB = G711_SCALE_CORRECTION_DB;
|
|
115895
|
+
exports.GROUP_TEMPLATES = GROUP_TEMPLATES;
|
|
115896
|
+
exports.GROUP_TEMPLATE_IDS = require_composition.GROUP_TEMPLATE_IDS;
|
|
114967
115897
|
exports.GasStatusSchema = GasStatusSchema;
|
|
114968
115898
|
exports.GetLoggingSettingsInputSchema = GetLoggingSettingsInputSchema;
|
|
114969
115899
|
exports.GetStreamWithCodecInputSchema = GetStreamWithCodecInputSchema;
|
|
114970
115900
|
exports.GlobalMetricsSchema = GlobalMetricsSchema;
|
|
114971
115901
|
exports.GridLayoutPatchSchema = GridLayoutPatchSchema;
|
|
114972
115902
|
exports.GridLayoutViewSchema = GridLayoutViewSchema;
|
|
115903
|
+
exports.GroupHelperSpecSchema = require_composition.GroupHelperSpecSchema;
|
|
115904
|
+
exports.GroupStatusSchema = GroupStatusSchema;
|
|
115905
|
+
exports.GroupTemplateIdSchema = require_composition.GroupTemplateIdSchema;
|
|
114973
115906
|
exports.HAP_AUDIO_BASE = HAP_AUDIO_BASE;
|
|
114974
115907
|
exports.HAP_AUDIO_BITRATE_KBPS = HAP_AUDIO_BITRATE_KBPS;
|
|
114975
115908
|
exports.HAP_AUDIO_VBV_KBITS = HAP_AUDIO_VBV_KBITS;
|
|
@@ -114993,6 +115926,8 @@ exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
|
|
|
114993
115926
|
exports.HardwareClassIdSchema = HardwareClassIdSchema;
|
|
114994
115927
|
exports.HealthStatusSchema = HealthStatusSchema;
|
|
114995
115928
|
exports.HeatingValveStatusSchema = HeatingValveStatusSchema;
|
|
115929
|
+
exports.HelperMemberSchema = require_composition.HelperMemberSchema;
|
|
115930
|
+
exports.HelperSpecSchema = require_composition.HelperSpecSchema;
|
|
114996
115931
|
exports.HfModelResolutionSchema = HfModelResolutionSchema;
|
|
114997
115932
|
exports.HistoryPointSchema = HistoryPointSchema;
|
|
114998
115933
|
exports.HistoryResolutionEnum = HistoryResolutionEnum;
|
|
@@ -115167,6 +116102,7 @@ exports.MAX_EXPRESSION_BINDINGS = require_composition.MAX_EXPRESSION_BINDINGS;
|
|
|
115167
116102
|
exports.MAX_EXPRESSION_CALL_ARGS = require_composition.MAX_EXPRESSION_CALL_ARGS;
|
|
115168
116103
|
exports.MAX_EXPRESSION_EVAL_STEPS = require_composition.MAX_EXPRESSION_EVAL_STEPS;
|
|
115169
116104
|
exports.MAX_EXPRESSION_SOURCE_LENGTH = require_composition.MAX_EXPRESSION_SOURCE_LENGTH;
|
|
116105
|
+
exports.MAX_HELPER_MEMBERS = require_composition.MAX_HELPER_MEMBERS;
|
|
115170
116106
|
exports.MAX_KEYS = MAX_KEYS;
|
|
115171
116107
|
exports.MAX_REASONS_PER_KEY = MAX_REASONS_PER_KEY;
|
|
115172
116108
|
exports.MAX_REQUEUED_BUCKETS_PER_SERIES = MAX_REQUEUED_BUCKETS_PER_SERIES;
|
|
@@ -115358,6 +116294,7 @@ exports.NETWORK_LINK_UNKNOWN = NETWORK_LINK_UNKNOWN;
|
|
|
115358
116294
|
exports.NODE_BENCHMARK_DEFAULTS = NODE_BENCHMARK_DEFAULTS;
|
|
115359
116295
|
exports.NODE_COLOR_IDS = require_node_color.NODE_COLOR_IDS;
|
|
115360
116296
|
exports.NO_MEASURED_CAPACITY = NO_MEASURED_CAPACITY;
|
|
116297
|
+
exports.NUMERIC_AGGREGATES = require_composition.NUMERIC_AGGREGATES;
|
|
115361
116298
|
exports.NativeCropBboxSchema = NativeCropBboxSchema;
|
|
115362
116299
|
exports.NativeCropRefSchema = NativeCropRefSchema;
|
|
115363
116300
|
exports.NativeCropResultSchema = NativeCropResultSchema;
|
|
@@ -115676,6 +116613,7 @@ exports.PtzPositionSchema = PtzPositionSchema;
|
|
|
115676
116613
|
exports.PtzPresetFunctionSchema = PtzPresetFunctionSchema;
|
|
115677
116614
|
exports.PtzPresetSchema = PtzPresetSchema;
|
|
115678
116615
|
exports.PtzStatusSchema = PtzStatusSchema;
|
|
116616
|
+
exports.QUANTITY_BASE = require_sleep.QUANTITY_BASE;
|
|
115679
116617
|
exports.QueryFilterSchema = QueryFilterSchema;
|
|
115680
116618
|
exports.RATE_CONTROL_RELAXED = RATE_CONTROL_RELAXED;
|
|
115681
116619
|
exports.RATE_CONTROL_TIGHT = RATE_CONTROL_TIGHT;
|
|
@@ -115754,6 +116692,7 @@ exports.ReadSegmentBytesResultSchema = ReadSegmentBytesResultSchema;
|
|
|
115754
116692
|
exports.ReadWindowBytesResultSchema = ReadWindowBytesResultSchema;
|
|
115755
116693
|
exports.ReadinessRegistry = require_sleep.ReadinessRegistry;
|
|
115756
116694
|
exports.ReadinessTimeoutError = require_sleep.ReadinessTimeoutError;
|
|
116695
|
+
exports.ReadingQuantitySchema = require_sleep.ReadingQuantitySchema;
|
|
115757
116696
|
exports.RebuildObjectEmbeddingsRefusalSchema = RebuildObjectEmbeddingsRefusalSchema;
|
|
115758
116697
|
exports.RecentTracksPageSchema = RecentTracksPageSchema;
|
|
115759
116698
|
exports.RecentTracksQueryInput = RecentTracksQueryInput;
|
|
@@ -116320,6 +117259,7 @@ exports.autoAssignProfiles = autoAssignProfiles;
|
|
|
116320
117259
|
exports.automationControlCapability = automationControlCapability;
|
|
116321
117260
|
exports.backupCapability = backupCapability;
|
|
116322
117261
|
exports.bareAddonId = bareAddonId;
|
|
117262
|
+
exports.baseUnitOf = require_sleep.baseUnitOf;
|
|
116323
117263
|
exports.batteryCapability = batteryCapability;
|
|
116324
117264
|
exports.bestLocationMatch = bestLocationMatch;
|
|
116325
117265
|
exports.binaryCapability = binaryCapability;
|
|
@@ -116409,6 +117349,7 @@ exports.commitWatchdogRestart = commitWatchdogRestart;
|
|
|
116409
117349
|
exports.compareToTarget = compareToTarget;
|
|
116410
117350
|
exports.compileExpression = require_composition.compileExpression;
|
|
116411
117351
|
exports.compileExpressionSafe = require_composition.compileExpressionSafe;
|
|
117352
|
+
exports.compileHelper = compileHelper;
|
|
116412
117353
|
exports.compileKeyedArrayOverride = compileKeyedArrayOverride;
|
|
116413
117354
|
exports.compilePulseOverride = compilePulseOverride;
|
|
116414
117355
|
exports.compileScalarOverride = compileScalarOverride;
|
|
@@ -116539,6 +117480,7 @@ exports.diffStepSettings = diffStepSettings;
|
|
|
116539
117480
|
exports.disarmRoseMemory = require_composition.disarmRoseMemory;
|
|
116540
117481
|
exports.dishwasherCapability = dishwasherCapability;
|
|
116541
117482
|
exports.displayPaletteCapability = displayPaletteCapability;
|
|
117483
|
+
exports.displayUnitFor = require_sleep.displayUnitFor;
|
|
116542
117484
|
exports.doActionSelectValue = doActionSelectValue;
|
|
116543
117485
|
exports.dominantClipLabels = dominantClipLabels;
|
|
116544
117486
|
exports.doorbellCapability = doorbellCapability;
|
|
@@ -116570,6 +117512,7 @@ exports.enumerateItemArrayFields = enumerateItemArrayFields;
|
|
|
116570
117512
|
exports.enumerateSchemaFields = enumerateSchemaFields;
|
|
116571
117513
|
exports.errMsg = require_err_msg.errMsg;
|
|
116572
117514
|
exports.estimateNodeBenchmarkDurationMs = estimateNodeBenchmarkDurationMs;
|
|
117515
|
+
exports.evaluateAggregate = evaluateAggregate;
|
|
116573
117516
|
exports.evaluateAst = require_composition.evaluateAst;
|
|
116574
117517
|
exports.evaluateCompositionField = evaluateCompositionField;
|
|
116575
117518
|
exports.evaluateCount = require_composition.evaluateCount;
|
|
@@ -116625,6 +117568,7 @@ exports.formatMediaOwnerKey = formatMediaOwnerKey;
|
|
|
116625
117568
|
exports.formatMinutes = formatMinutes;
|
|
116626
117569
|
exports.formatPaletteViolations = formatPaletteViolations;
|
|
116627
117570
|
exports.formatParkedFor = formatParkedFor;
|
|
117571
|
+
exports.formatReading = formatReading;
|
|
116628
117572
|
exports.formatSecretScope = require_sleep.formatSecretScope;
|
|
116629
117573
|
exports.formulaProblem = formulaProblem;
|
|
116630
117574
|
exports.freshResults = freshResults;
|
|
@@ -116642,13 +117586,17 @@ exports.gifFilterComplex = gifFilterComplex;
|
|
|
116642
117586
|
exports.gifFromMp4Args = gifFromMp4Args;
|
|
116643
117587
|
exports.globalSecretScope = require_sleep.globalSecretScope;
|
|
116644
117588
|
exports.grantRowsOf = grantRowsOf;
|
|
117589
|
+
exports.groupStatusCapability = groupStatusCapability;
|
|
117590
|
+
exports.groupTemplate = groupTemplate;
|
|
116645
117591
|
exports.hasModelBoundOverrides = hasModelBoundOverrides;
|
|
116646
117592
|
exports.hasMotionTrigger = hasMotionTrigger;
|
|
116647
117593
|
exports.hasUrlScheme = hasUrlScheme;
|
|
116648
117594
|
exports.heatingValveCapability = heatingValveCapability;
|
|
117595
|
+
exports.helperSaveProblems = helperSaveProblems;
|
|
116649
117596
|
exports.hfModelUrl = require_sleep.hfModelUrl;
|
|
116650
117597
|
exports.historyFieldsFor = historyFieldsFor;
|
|
116651
117598
|
exports.historyItemFieldPath = require_sleep.historyItemFieldPath;
|
|
117599
|
+
exports.historyUnitFor = require_sleep.historyUnitFor;
|
|
116652
117600
|
exports.htmlToText = htmlToText;
|
|
116653
117601
|
exports.hubAddressHostname = hubAddressHostname;
|
|
116654
117602
|
exports.hubMotionNativeProvider = hubMotionNativeProvider;
|
|
@@ -116663,6 +117611,7 @@ exports.imageModesForKind = imageModesForKind;
|
|
|
116663
117611
|
exports.imageSettingsCapability = imageSettingsCapability;
|
|
116664
117612
|
exports.inferExpressionKinds = inferExpressionKinds;
|
|
116665
117613
|
exports.inferModelProvider = inferModelProvider;
|
|
117614
|
+
exports.ingestReading = ingestReading;
|
|
116666
117615
|
exports.initialPoolMemoryState = initialPoolMemoryState;
|
|
116667
117616
|
exports.integrationsCapability = integrationsCapability;
|
|
116668
117617
|
exports.intercomCapability = intercomCapability;
|
|
@@ -116717,6 +117666,7 @@ exports.isOauthLandingReason = isOauthLandingReason;
|
|
|
116717
117666
|
exports.isObjectInput = isObjectInput;
|
|
116718
117667
|
exports.isOccupancyRule = isOccupancyRule;
|
|
116719
117668
|
exports.isOwnerOnlyEventCategory = require_event_category.isOwnerOnlyEventCategory;
|
|
117669
|
+
exports.isReadingQuantity = require_sleep.isReadingQuantity;
|
|
116720
117670
|
exports.isRemovedModelId = isRemovedModelId;
|
|
116721
117671
|
exports.isRestoredCap = isRestoredCap;
|
|
116722
117672
|
exports.isRetiredClearKey = isRetiredClearKey;
|
|
@@ -116947,6 +117897,7 @@ exports.ptzAutotrackCapability = ptzAutotrackCapability;
|
|
|
116947
117897
|
exports.ptzCapability = ptzCapability;
|
|
116948
117898
|
exports.publicEventCategories = require_event_category.publicEventCategories;
|
|
116949
117899
|
exports.pythonScriptForBackend = pythonScriptForBackend;
|
|
117900
|
+
exports.quantityFromUnit = quantityFromUnit;
|
|
116950
117901
|
exports.rankStreams = rankStreams;
|
|
116951
117902
|
exports.readClusterStepModels = readClusterStepModels;
|
|
116952
117903
|
exports.readClusterStepSettings = readClusterStepSettings;
|
|
@@ -116965,6 +117916,7 @@ exports.readRecoveryRecipeForSteps = readRecoveryRecipeForSteps;
|
|
|
116965
117916
|
exports.readTimelapseGeneratedAt = readTimelapseGeneratedAt;
|
|
116966
117917
|
exports.readUseRootModel = readUseRootModel;
|
|
116967
117918
|
exports.readinessKey = require_sleep.readinessKey;
|
|
117919
|
+
exports.readingMeta = require_sleep.readingMeta;
|
|
116968
117920
|
exports.rebootCapability = rebootCapability;
|
|
116969
117921
|
exports.recommendNode = recommendNode;
|
|
116970
117922
|
exports.reconcileBlockDevices = reconcileBlockDevices;
|
|
@@ -117065,8 +118017,10 @@ exports.runningFromMediaPlayer = runningFromMediaPlayer;
|
|
|
117065
118017
|
exports.runningFromVacuumState = runningFromVacuumState;
|
|
117066
118018
|
exports.runningStateCapability = runningStateCapability;
|
|
117067
118019
|
exports.runtimeDevices = runtimeDevices;
|
|
118020
|
+
exports.runtimeFieldUnit = runtimeFieldUnit;
|
|
117068
118021
|
exports.runtimeStatePolicyFor = runtimeStatePolicyFor;
|
|
117069
118022
|
exports.sameDoFamily = sameDoFamily;
|
|
118023
|
+
exports.sameHelperBody = sameHelperBody;
|
|
117070
118024
|
exports.sameRead = sameRead;
|
|
117071
118025
|
exports.sceneMonitorCapability = sceneMonitorCapability;
|
|
117072
118026
|
exports.scheduleForSendTimes = scheduleForSendTimes;
|
|
@@ -117116,6 +118070,7 @@ exports.sliceChangedAt = require_composition.sliceChangedAt;
|
|
|
117116
118070
|
exports.smokeCapability = smokeCapability;
|
|
117117
118071
|
exports.smtpProviderCapability = smtpProviderCapability;
|
|
117118
118072
|
exports.snapshotCapability = snapshotCapability;
|
|
118073
|
+
exports.sourcePickForTemplate = sourcePickForTemplate;
|
|
117119
118074
|
exports.splitTranslationRef = splitTranslationRef;
|
|
117120
118075
|
exports.squareAround = squareAround;
|
|
117121
118076
|
exports.ssoBridgeCapability = ssoBridgeCapability;
|
|
@@ -117178,12 +118133,15 @@ exports.taskPhaseSchema = taskPhaseSchema;
|
|
|
117178
118133
|
exports.taskTargetSchema = taskTargetSchema;
|
|
117179
118134
|
exports.temperatureSensorCapability = temperatureSensorCapability;
|
|
117180
118135
|
exports.templateCarriesSummary = templateCarriesSummary;
|
|
118136
|
+
exports.templateDeviceType = templateDeviceType;
|
|
117181
118137
|
exports.templateVarDeliveryApplies = templateVarDeliveryApplies;
|
|
117182
118138
|
exports.templateVarKindApplies = templateVarKindApplies;
|
|
117183
118139
|
exports.templateVarSystemEventApplies = templateVarSystemEventApplies;
|
|
117184
118140
|
exports.templateVarsFor = templateVarsFor;
|
|
117185
118141
|
exports.terminalSessionCapability = terminalSessionCapability;
|
|
117186
118142
|
exports.textToHtml = textToHtml;
|
|
118143
|
+
exports.thresholdToBase = thresholdToBase;
|
|
118144
|
+
exports.thresholdToDisplay = thresholdToDisplay;
|
|
117187
118145
|
exports.timeOfDayToMinutes = timeOfDayToMinutes;
|
|
117188
118146
|
exports.toAppLinkHubOrigin = toAppLinkHubOrigin;
|
|
117189
118147
|
exports.toDeviceSummary = toDeviceSummary;
|
|
@@ -117199,6 +118157,7 @@ exports.trainingCapability = trainingCapability;
|
|
|
117199
118157
|
exports.trainingProviderCapability = trainingProviderCapability;
|
|
117200
118158
|
exports.transcodeBody = transcodeBody;
|
|
117201
118159
|
exports.transformSecretWrite = require_sleep.transformSecretWrite;
|
|
118160
|
+
exports.tryConvertDelta = tryConvertDelta;
|
|
117202
118161
|
exports.tryConvertUnit = tryConvertUnit;
|
|
117203
118162
|
exports.turnProviderCapability = turnProviderCapability;
|
|
117204
118163
|
exports.unitCompanionField = unitCompanionField;
|