@camstack/addon-terminal 0.1.152 → 0.1.154
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/CHANGELOG.md +12 -0
- package/README.md +19 -0
- package/dist/addon.js +966 -509
- package/dist/addon.mjs +966 -509
- package/package.json +10 -3
package/dist/addon.js
CHANGED
|
@@ -31,7 +31,7 @@ let node_module = require("node:module");
|
|
|
31
31
|
let sharp = require("sharp");
|
|
32
32
|
sharp = __toESM(sharp);
|
|
33
33
|
let node_http = require("node:http");
|
|
34
|
-
//#region ../types/dist/event-category-
|
|
34
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
35
35
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
36
36
|
EventCategory["SystemBoot"] = "system.boot";
|
|
37
37
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -357,6 +357,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
357
357
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
358
358
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
359
359
|
/**
|
|
360
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
361
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
362
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
363
|
+
*/
|
|
364
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
365
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
366
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
367
|
+
/**
|
|
360
368
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
361
369
|
* (a settings change via `setAgentInferenceDevices` /
|
|
362
370
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5466,7 +5474,7 @@ var ZodIssueCode = {
|
|
|
5466
5474
|
var ZodFirstPartyTypeKind;
|
|
5467
5475
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5468
5476
|
//#endregion
|
|
5469
|
-
//#region ../types/dist/sleep-
|
|
5477
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5470
5478
|
/**
|
|
5471
5479
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5472
5480
|
* window to float samples (D455).
|
|
@@ -8020,6 +8028,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
8020
8028
|
}).strict();
|
|
8021
8029
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8022
8030
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8031
|
+
var READING_QUANTITIES = [
|
|
8032
|
+
"temperature",
|
|
8033
|
+
"pressure",
|
|
8034
|
+
"speed",
|
|
8035
|
+
"precipitation",
|
|
8036
|
+
"precipitation-rate",
|
|
8037
|
+
"length",
|
|
8038
|
+
"area",
|
|
8039
|
+
"illuminance",
|
|
8040
|
+
"irradiance",
|
|
8041
|
+
"power",
|
|
8042
|
+
"energy",
|
|
8043
|
+
"voltage",
|
|
8044
|
+
"current",
|
|
8045
|
+
"apparent-power",
|
|
8046
|
+
"humidity",
|
|
8047
|
+
"percentage",
|
|
8048
|
+
"concentration-volume",
|
|
8049
|
+
"concentration-mass",
|
|
8050
|
+
"concentration-ppb",
|
|
8051
|
+
"volume",
|
|
8052
|
+
"duration",
|
|
8053
|
+
"duration-ms",
|
|
8054
|
+
"information",
|
|
8055
|
+
"sound-level",
|
|
8056
|
+
"signal-level",
|
|
8057
|
+
"colour-temperature",
|
|
8058
|
+
"angle",
|
|
8059
|
+
"bitrate",
|
|
8060
|
+
"rate",
|
|
8061
|
+
"mass",
|
|
8062
|
+
"index",
|
|
8063
|
+
"ratio",
|
|
8064
|
+
"count",
|
|
8065
|
+
"none",
|
|
8066
|
+
"device"
|
|
8067
|
+
];
|
|
8068
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8069
|
+
new Set(READING_QUANTITIES);
|
|
8070
|
+
/**
|
|
8071
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8072
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8073
|
+
*/
|
|
8074
|
+
var QUANTITY_BASE = {
|
|
8075
|
+
temperature: "°C",
|
|
8076
|
+
pressure: "hPa",
|
|
8077
|
+
speed: "m/s",
|
|
8078
|
+
precipitation: "mm",
|
|
8079
|
+
"precipitation-rate": "mm/h",
|
|
8080
|
+
length: "m",
|
|
8081
|
+
area: "m²",
|
|
8082
|
+
illuminance: "lx",
|
|
8083
|
+
irradiance: "W/m²",
|
|
8084
|
+
power: "W",
|
|
8085
|
+
energy: "kWh",
|
|
8086
|
+
voltage: "V",
|
|
8087
|
+
current: "A",
|
|
8088
|
+
"apparent-power": "VA",
|
|
8089
|
+
humidity: "%",
|
|
8090
|
+
percentage: "%",
|
|
8091
|
+
"concentration-volume": "ppm",
|
|
8092
|
+
"concentration-mass": "µg/m³",
|
|
8093
|
+
"concentration-ppb": "ppb",
|
|
8094
|
+
volume: "L",
|
|
8095
|
+
duration: "s",
|
|
8096
|
+
"duration-ms": "ms",
|
|
8097
|
+
information: "B",
|
|
8098
|
+
"sound-level": "dBFS",
|
|
8099
|
+
"signal-level": "dBm",
|
|
8100
|
+
"colour-temperature": "mired",
|
|
8101
|
+
angle: "°",
|
|
8102
|
+
bitrate: "kbps",
|
|
8103
|
+
rate: "fps",
|
|
8104
|
+
mass: "kg",
|
|
8105
|
+
index: "none",
|
|
8106
|
+
ratio: "none",
|
|
8107
|
+
count: "none",
|
|
8108
|
+
none: "none",
|
|
8109
|
+
device: "device"
|
|
8110
|
+
};
|
|
8111
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8112
|
+
function baseUnitOf(quantity) {
|
|
8113
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8114
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8115
|
+
return symbol;
|
|
8116
|
+
}
|
|
8117
|
+
function readingMeta(quantity, extras) {
|
|
8118
|
+
return {
|
|
8119
|
+
quantity,
|
|
8120
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8121
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8122
|
+
};
|
|
8123
|
+
}
|
|
8023
8124
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8024
8125
|
var CamProfileSchema = _enum([
|
|
8025
8126
|
"high",
|
|
@@ -8047,8 +8148,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8047
8148
|
"derived"
|
|
8048
8149
|
]);
|
|
8049
8150
|
var CamStreamResolutionSchema = object({
|
|
8050
|
-
width: number().int().positive(),
|
|
8051
|
-
height: number().int().positive()
|
|
8151
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8152
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8052
8153
|
});
|
|
8053
8154
|
var CameraStreamSchema = object({
|
|
8054
8155
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8625,6 +8726,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8625
8726
|
"filesystem-browse",
|
|
8626
8727
|
"flood",
|
|
8627
8728
|
"gas",
|
|
8729
|
+
"group-commands",
|
|
8730
|
+
"group-status",
|
|
8628
8731
|
"heating-valve",
|
|
8629
8732
|
"humidifier",
|
|
8630
8733
|
"humidity-sensor",
|
|
@@ -8754,14 +8857,6 @@ Object.freeze({
|
|
|
8754
8857
|
{
|
|
8755
8858
|
"path": "aqi",
|
|
8756
8859
|
"valueType": "number"
|
|
8757
|
-
},
|
|
8758
|
-
{
|
|
8759
|
-
"path": "unit",
|
|
8760
|
-
"valueType": "string"
|
|
8761
|
-
},
|
|
8762
|
-
{
|
|
8763
|
-
"path": "precision",
|
|
8764
|
-
"valueType": "number"
|
|
8765
8860
|
}
|
|
8766
8861
|
],
|
|
8767
8862
|
"alarm-panel": [
|
|
@@ -8797,20 +8892,10 @@ Object.freeze({
|
|
|
8797
8892
|
"valueType": "boolean"
|
|
8798
8893
|
}
|
|
8799
8894
|
],
|
|
8800
|
-
"ambient-light-sensor": [
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
},
|
|
8805
|
-
{
|
|
8806
|
-
"path": "unit",
|
|
8807
|
-
"valueType": "string"
|
|
8808
|
-
},
|
|
8809
|
-
{
|
|
8810
|
-
"path": "precision",
|
|
8811
|
-
"valueType": "number"
|
|
8812
|
-
}
|
|
8813
|
-
],
|
|
8895
|
+
"ambient-light-sensor": [{
|
|
8896
|
+
"path": "lux",
|
|
8897
|
+
"valueType": "number"
|
|
8898
|
+
}],
|
|
8814
8899
|
"audio-metrics": [
|
|
8815
8900
|
{
|
|
8816
8901
|
"path": "ts",
|
|
@@ -8890,6 +8975,10 @@ Object.freeze({
|
|
|
8890
8975
|
"path": "lastUpdated",
|
|
8891
8976
|
"valueType": "number"
|
|
8892
8977
|
},
|
|
8978
|
+
{
|
|
8979
|
+
"path": "volts",
|
|
8980
|
+
"valueType": "number"
|
|
8981
|
+
},
|
|
8893
8982
|
{
|
|
8894
8983
|
"path": "lastContactAt",
|
|
8895
8984
|
"valueType": "number"
|
|
@@ -9132,10 +9221,6 @@ Object.freeze({
|
|
|
9132
9221
|
"datetime"
|
|
9133
9222
|
]
|
|
9134
9223
|
},
|
|
9135
|
-
{
|
|
9136
|
-
"path": "unit",
|
|
9137
|
-
"valueType": "string"
|
|
9138
|
-
},
|
|
9139
9224
|
{
|
|
9140
9225
|
"path": "min",
|
|
9141
9226
|
"valueType": "number"
|
|
@@ -9147,19 +9232,6 @@ Object.freeze({
|
|
|
9147
9232
|
{
|
|
9148
9233
|
"path": "step",
|
|
9149
9234
|
"valueType": "number"
|
|
9150
|
-
},
|
|
9151
|
-
{
|
|
9152
|
-
"path": "precision",
|
|
9153
|
-
"valueType": "number"
|
|
9154
|
-
},
|
|
9155
|
-
{
|
|
9156
|
-
"path": "format",
|
|
9157
|
-
"valueType": "enum",
|
|
9158
|
-
"enumValues": [
|
|
9159
|
-
"date",
|
|
9160
|
-
"time",
|
|
9161
|
-
"datetime"
|
|
9162
|
-
]
|
|
9163
9235
|
}
|
|
9164
9236
|
],
|
|
9165
9237
|
"cover": [
|
|
@@ -9400,13 +9472,8 @@ Object.freeze({
|
|
|
9400
9472
|
"path": "value",
|
|
9401
9473
|
"valueType": "string"
|
|
9402
9474
|
}, {
|
|
9403
|
-
"path": "
|
|
9404
|
-
"valueType": "
|
|
9405
|
-
"enumValues": [
|
|
9406
|
-
"date",
|
|
9407
|
-
"time",
|
|
9408
|
-
"datetime"
|
|
9409
|
-
]
|
|
9475
|
+
"path": "timestamp",
|
|
9476
|
+
"valueType": "boolean"
|
|
9410
9477
|
}],
|
|
9411
9478
|
"event-emitter": [
|
|
9412
9479
|
{
|
|
@@ -9479,6 +9546,20 @@ Object.freeze({
|
|
|
9479
9546
|
"path": "detected",
|
|
9480
9547
|
"valueType": "boolean"
|
|
9481
9548
|
}],
|
|
9549
|
+
"group-status": [
|
|
9550
|
+
{
|
|
9551
|
+
"path": "included",
|
|
9552
|
+
"valueType": "number"
|
|
9553
|
+
},
|
|
9554
|
+
{
|
|
9555
|
+
"path": "excluded",
|
|
9556
|
+
"valueType": "number"
|
|
9557
|
+
},
|
|
9558
|
+
{
|
|
9559
|
+
"path": "total",
|
|
9560
|
+
"valueType": "number"
|
|
9561
|
+
}
|
|
9562
|
+
],
|
|
9482
9563
|
"heating-valve": [{
|
|
9483
9564
|
"path": "position",
|
|
9484
9565
|
"valueType": "number"
|
|
@@ -9513,20 +9594,10 @@ Object.freeze({
|
|
|
9513
9594
|
"valueType": "number"
|
|
9514
9595
|
}
|
|
9515
9596
|
],
|
|
9516
|
-
"humidity-sensor": [
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
},
|
|
9521
|
-
{
|
|
9522
|
-
"path": "unit",
|
|
9523
|
-
"valueType": "string"
|
|
9524
|
-
},
|
|
9525
|
-
{
|
|
9526
|
-
"path": "precision",
|
|
9527
|
-
"valueType": "number"
|
|
9528
|
-
}
|
|
9529
|
-
],
|
|
9597
|
+
"humidity-sensor": [{
|
|
9598
|
+
"path": "percent",
|
|
9599
|
+
"valueType": "number"
|
|
9600
|
+
}],
|
|
9530
9601
|
"image": [{
|
|
9531
9602
|
"path": "url",
|
|
9532
9603
|
"valueType": "string"
|
|
@@ -9865,20 +9936,10 @@ Object.freeze({
|
|
|
9865
9936
|
"valueType": "boolean"
|
|
9866
9937
|
}
|
|
9867
9938
|
],
|
|
9868
|
-
"numeric-sensor": [
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
},
|
|
9873
|
-
{
|
|
9874
|
-
"path": "unit",
|
|
9875
|
-
"valueType": "string"
|
|
9876
|
-
},
|
|
9877
|
-
{
|
|
9878
|
-
"path": "precision",
|
|
9879
|
-
"valueType": "number"
|
|
9880
|
-
}
|
|
9881
|
-
],
|
|
9939
|
+
"numeric-sensor": [{
|
|
9940
|
+
"path": "value",
|
|
9941
|
+
"valueType": "number"
|
|
9942
|
+
}],
|
|
9882
9943
|
"pet-feeder": [
|
|
9883
9944
|
{
|
|
9884
9945
|
"path": "foodLevel",
|
|
@@ -9970,14 +10031,6 @@ Object.freeze({
|
|
|
9970
10031
|
{
|
|
9971
10032
|
"path": "powerFactor",
|
|
9972
10033
|
"valueType": "number"
|
|
9973
|
-
},
|
|
9974
|
-
{
|
|
9975
|
-
"path": "unit",
|
|
9976
|
-
"valueType": "string"
|
|
9977
|
-
},
|
|
9978
|
-
{
|
|
9979
|
-
"path": "precision",
|
|
9980
|
-
"valueType": "number"
|
|
9981
10034
|
}
|
|
9982
10035
|
],
|
|
9983
10036
|
"presence": [
|
|
@@ -10006,20 +10059,10 @@ Object.freeze({
|
|
|
10006
10059
|
"valueType": "number"
|
|
10007
10060
|
}
|
|
10008
10061
|
],
|
|
10009
|
-
"pressure-sensor": [
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
},
|
|
10014
|
-
{
|
|
10015
|
-
"path": "unit",
|
|
10016
|
-
"valueType": "string"
|
|
10017
|
-
},
|
|
10018
|
-
{
|
|
10019
|
-
"path": "precision",
|
|
10020
|
-
"valueType": "number"
|
|
10021
|
-
}
|
|
10022
|
-
],
|
|
10062
|
+
"pressure-sensor": [{
|
|
10063
|
+
"path": "hpa",
|
|
10064
|
+
"valueType": "number"
|
|
10065
|
+
}],
|
|
10023
10066
|
"privacy-mask": [{
|
|
10024
10067
|
"path": "enabled",
|
|
10025
10068
|
"valueType": "boolean"
|
|
@@ -10330,20 +10373,10 @@ Object.freeze({
|
|
|
10330
10373
|
"path": "tampered",
|
|
10331
10374
|
"valueType": "boolean"
|
|
10332
10375
|
}],
|
|
10333
|
-
"temperature-sensor": [
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
},
|
|
10338
|
-
{
|
|
10339
|
-
"path": "unit",
|
|
10340
|
-
"valueType": "string"
|
|
10341
|
-
},
|
|
10342
|
-
{
|
|
10343
|
-
"path": "precision",
|
|
10344
|
-
"valueType": "number"
|
|
10345
|
-
}
|
|
10346
|
-
],
|
|
10376
|
+
"temperature-sensor": [{
|
|
10377
|
+
"path": "celsius",
|
|
10378
|
+
"valueType": "number"
|
|
10379
|
+
}],
|
|
10347
10380
|
"update": [
|
|
10348
10381
|
{
|
|
10349
10382
|
"path": "currentVersion",
|
|
@@ -10454,10 +10487,6 @@ Object.freeze({
|
|
|
10454
10487
|
"path": "temperature",
|
|
10455
10488
|
"valueType": "number"
|
|
10456
10489
|
},
|
|
10457
|
-
{
|
|
10458
|
-
"path": "temperatureUnit",
|
|
10459
|
-
"valueType": "string"
|
|
10460
|
-
},
|
|
10461
10490
|
{
|
|
10462
10491
|
"path": "humidity",
|
|
10463
10492
|
"valueType": "number"
|
|
@@ -10466,18 +10495,10 @@ Object.freeze({
|
|
|
10466
10495
|
"path": "pressure",
|
|
10467
10496
|
"valueType": "number"
|
|
10468
10497
|
},
|
|
10469
|
-
{
|
|
10470
|
-
"path": "pressureUnit",
|
|
10471
|
-
"valueType": "string"
|
|
10472
|
-
},
|
|
10473
10498
|
{
|
|
10474
10499
|
"path": "windSpeed",
|
|
10475
10500
|
"valueType": "number"
|
|
10476
10501
|
},
|
|
10477
|
-
{
|
|
10478
|
-
"path": "windSpeedUnit",
|
|
10479
|
-
"valueType": "string"
|
|
10480
|
-
},
|
|
10481
10502
|
{
|
|
10482
10503
|
"path": "windBearing",
|
|
10483
10504
|
"valueType": "number"
|
|
@@ -10880,7 +10901,7 @@ function errMsg(err) {
|
|
|
10880
10901
|
return String(err);
|
|
10881
10902
|
}
|
|
10882
10903
|
//#endregion
|
|
10883
|
-
//#region ../types/dist/composition-
|
|
10904
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10884
10905
|
/**
|
|
10885
10906
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10886
10907
|
*
|
|
@@ -11635,15 +11656,74 @@ function validateExpressionSource(src) {
|
|
|
11635
11656
|
}
|
|
11636
11657
|
return null;
|
|
11637
11658
|
}
|
|
11638
|
-
/**
|
|
11639
|
-
|
|
11640
|
-
|
|
11641
|
-
|
|
11659
|
+
/**
|
|
11660
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11661
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11662
|
+
* `composition.ts` (D659).
|
|
11663
|
+
*/
|
|
11642
11664
|
var CompositionSourceRefSchema = object({
|
|
11643
11665
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11644
11666
|
addonId: string().min(1),
|
|
11645
11667
|
stableId: string().min(1)
|
|
11646
11668
|
});
|
|
11669
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11670
|
+
"temperature",
|
|
11671
|
+
"humidity",
|
|
11672
|
+
"pressure",
|
|
11673
|
+
"illuminance",
|
|
11674
|
+
"power",
|
|
11675
|
+
"energy",
|
|
11676
|
+
"battery",
|
|
11677
|
+
"numeric",
|
|
11678
|
+
"motion",
|
|
11679
|
+
"contact",
|
|
11680
|
+
"leak",
|
|
11681
|
+
"smoke",
|
|
11682
|
+
"occupancy",
|
|
11683
|
+
"binary",
|
|
11684
|
+
"switch",
|
|
11685
|
+
"light"
|
|
11686
|
+
];
|
|
11687
|
+
var NUMERIC_AGGREGATES = [
|
|
11688
|
+
"mean",
|
|
11689
|
+
"median",
|
|
11690
|
+
"min",
|
|
11691
|
+
"max",
|
|
11692
|
+
"sum"
|
|
11693
|
+
];
|
|
11694
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11695
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11696
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11697
|
+
var AGGREGATE_REDUCERS = [
|
|
11698
|
+
"mean",
|
|
11699
|
+
"median",
|
|
11700
|
+
"min",
|
|
11701
|
+
"max",
|
|
11702
|
+
"sum",
|
|
11703
|
+
"any",
|
|
11704
|
+
"all"
|
|
11705
|
+
];
|
|
11706
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11707
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11708
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11709
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11710
|
+
var HelperMemberSchema = object({
|
|
11711
|
+
source: CompositionSourceRefSchema,
|
|
11712
|
+
cap: string().min(1),
|
|
11713
|
+
fieldPath: string().min(1)
|
|
11714
|
+
});
|
|
11715
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11716
|
+
kind: literal("group"),
|
|
11717
|
+
templateId: GroupTemplateIdSchema,
|
|
11718
|
+
aggregate: AggregateReducerSchema,
|
|
11719
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11720
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11721
|
+
active: ActiveCriterionSchema.optional()
|
|
11722
|
+
})]);
|
|
11723
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11724
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11725
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11726
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11647
11727
|
/** One field of one capability of one source device. */
|
|
11648
11728
|
var CompositionFieldReadSchema = object({
|
|
11649
11729
|
source: CompositionSourceRefSchema,
|
|
@@ -11687,7 +11767,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11687
11767
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11688
11768
|
CompositionFromSourceSchema,
|
|
11689
11769
|
CompositionExpressionSourceSchema,
|
|
11690
|
-
CompositionCodeSourceSchema
|
|
11770
|
+
CompositionCodeSourceSchema,
|
|
11771
|
+
object({
|
|
11772
|
+
kind: literal("aggregate"),
|
|
11773
|
+
reducer: _enum([
|
|
11774
|
+
"mean",
|
|
11775
|
+
"median",
|
|
11776
|
+
"min",
|
|
11777
|
+
"max",
|
|
11778
|
+
"sum",
|
|
11779
|
+
"any",
|
|
11780
|
+
"all"
|
|
11781
|
+
]),
|
|
11782
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11783
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11784
|
+
publish: _enum([
|
|
11785
|
+
"value",
|
|
11786
|
+
"included",
|
|
11787
|
+
"excluded",
|
|
11788
|
+
"total"
|
|
11789
|
+
]),
|
|
11790
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11791
|
+
empty: _enum([
|
|
11792
|
+
"null",
|
|
11793
|
+
"omit",
|
|
11794
|
+
"offline"
|
|
11795
|
+
])
|
|
11796
|
+
})
|
|
11691
11797
|
]);
|
|
11692
11798
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11693
11799
|
kind: literal("forward"),
|
|
@@ -11733,7 +11839,13 @@ var CompositionSchema = object({
|
|
|
11733
11839
|
kind: literal("existing"),
|
|
11734
11840
|
device: CompositionSourceRefSchema
|
|
11735
11841
|
})]),
|
|
11736
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11842
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11843
|
+
/**
|
|
11844
|
+
* Present when the block is a helper template. Absent on a free
|
|
11845
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11846
|
+
* never the compiled features.
|
|
11847
|
+
*/
|
|
11848
|
+
helper: HelperSpecSchema.optional()
|
|
11737
11849
|
}).superRefine((composition, ctx) => {
|
|
11738
11850
|
const seen = /* @__PURE__ */ new Set();
|
|
11739
11851
|
composition.features.forEach((feature, index) => {
|
|
@@ -17973,7 +18085,11 @@ var CompositionProblemSchema = object({
|
|
|
17973
18085
|
"item-field-reserved",
|
|
17974
18086
|
"target-missing",
|
|
17975
18087
|
"target-unreadable",
|
|
17976
|
-
"not-replaceable"
|
|
18088
|
+
"not-replaceable",
|
|
18089
|
+
"native-capability-replace",
|
|
18090
|
+
"mixed-quantity",
|
|
18091
|
+
"helper-mismatch",
|
|
18092
|
+
"member-constraint"
|
|
17977
18093
|
]),
|
|
17978
18094
|
path: string(),
|
|
17979
18095
|
message: string()
|
|
@@ -17994,7 +18110,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17994
18110
|
"null",
|
|
17995
18111
|
"offline",
|
|
17996
18112
|
"unknown",
|
|
17997
|
-
"release"
|
|
18113
|
+
"release",
|
|
18114
|
+
"omit"
|
|
17998
18115
|
]);
|
|
17999
18116
|
/**
|
|
18000
18117
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18031,9 +18148,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18031
18148
|
reads: array(CompositionFieldReadSchema)
|
|
18032
18149
|
});
|
|
18033
18150
|
/**
|
|
18034
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18035
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18036
|
-
*
|
|
18151
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18152
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18153
|
+
* Replacing a capability the device already serves is refused
|
|
18154
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18155
|
+
* wire for a claim the hub already holds.
|
|
18037
18156
|
*/
|
|
18038
18157
|
var CompositionFeatureModeSchema = _enum([
|
|
18039
18158
|
"new",
|
|
@@ -18206,6 +18325,275 @@ Object.freeze({
|
|
|
18206
18325
|
result: ["number", "null"]
|
|
18207
18326
|
}
|
|
18208
18327
|
});
|
|
18328
|
+
/**
|
|
18329
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18330
|
+
* Data, not a form default written into the block.
|
|
18331
|
+
*/
|
|
18332
|
+
var NOW = {
|
|
18333
|
+
fieldPath: "lastFetchedAt",
|
|
18334
|
+
expr: "now"
|
|
18335
|
+
};
|
|
18336
|
+
var CHANGED = {
|
|
18337
|
+
fieldPath: "lastChangedAt",
|
|
18338
|
+
expr: "now"
|
|
18339
|
+
};
|
|
18340
|
+
function numeric(input) {
|
|
18341
|
+
return {
|
|
18342
|
+
...input,
|
|
18343
|
+
family: "numeric",
|
|
18344
|
+
deviceType: DeviceType.Sensor,
|
|
18345
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18346
|
+
commandCaps: [],
|
|
18347
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18348
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18349
|
+
accept: [{
|
|
18350
|
+
cap: input.outputCap,
|
|
18351
|
+
fieldPath: input.outputField
|
|
18352
|
+
}]
|
|
18353
|
+
};
|
|
18354
|
+
}
|
|
18355
|
+
function binary(input) {
|
|
18356
|
+
return {
|
|
18357
|
+
...input,
|
|
18358
|
+
family: "binary",
|
|
18359
|
+
deviceType: DeviceType.Sensor,
|
|
18360
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18361
|
+
commandCaps: [],
|
|
18362
|
+
quantity: "none",
|
|
18363
|
+
baseUnit: void 0,
|
|
18364
|
+
aggregates: BINARY_AGGREGATES,
|
|
18365
|
+
empty: "offline"
|
|
18366
|
+
};
|
|
18367
|
+
}
|
|
18368
|
+
var GROUP_TEMPLATES = [
|
|
18369
|
+
numeric({
|
|
18370
|
+
id: "temperature",
|
|
18371
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18372
|
+
role: DeviceRole.TemperatureSensor,
|
|
18373
|
+
outputCap: "temperature-sensor",
|
|
18374
|
+
outputField: "celsius",
|
|
18375
|
+
quantity: "temperature",
|
|
18376
|
+
defaultAggregate: "mean",
|
|
18377
|
+
empty: "null",
|
|
18378
|
+
companions: [NOW]
|
|
18379
|
+
}),
|
|
18380
|
+
numeric({
|
|
18381
|
+
id: "humidity",
|
|
18382
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18383
|
+
role: DeviceRole.HumiditySensor,
|
|
18384
|
+
outputCap: "humidity-sensor",
|
|
18385
|
+
outputField: "percent",
|
|
18386
|
+
quantity: "humidity",
|
|
18387
|
+
defaultAggregate: "mean",
|
|
18388
|
+
empty: "null",
|
|
18389
|
+
companions: [NOW]
|
|
18390
|
+
}),
|
|
18391
|
+
numeric({
|
|
18392
|
+
id: "pressure",
|
|
18393
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18394
|
+
role: DeviceRole.PressureSensor,
|
|
18395
|
+
outputCap: "pressure-sensor",
|
|
18396
|
+
outputField: "hpa",
|
|
18397
|
+
quantity: "pressure",
|
|
18398
|
+
defaultAggregate: "mean",
|
|
18399
|
+
empty: "null",
|
|
18400
|
+
companions: [NOW]
|
|
18401
|
+
}),
|
|
18402
|
+
numeric({
|
|
18403
|
+
id: "illuminance",
|
|
18404
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18405
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18406
|
+
outputCap: "ambient-light-sensor",
|
|
18407
|
+
outputField: "lux",
|
|
18408
|
+
quantity: "illuminance",
|
|
18409
|
+
defaultAggregate: "mean",
|
|
18410
|
+
empty: "null",
|
|
18411
|
+
companions: [NOW]
|
|
18412
|
+
}),
|
|
18413
|
+
numeric({
|
|
18414
|
+
id: "power",
|
|
18415
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18416
|
+
role: DeviceRole.PowerSensor,
|
|
18417
|
+
outputCap: "power-meter",
|
|
18418
|
+
outputField: "watts",
|
|
18419
|
+
quantity: "power",
|
|
18420
|
+
defaultAggregate: "sum",
|
|
18421
|
+
empty: "omit",
|
|
18422
|
+
companions: [NOW]
|
|
18423
|
+
}),
|
|
18424
|
+
numeric({
|
|
18425
|
+
id: "energy",
|
|
18426
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18427
|
+
role: DeviceRole.EnergySensor,
|
|
18428
|
+
outputCap: "power-meter",
|
|
18429
|
+
outputField: "kwhTotal",
|
|
18430
|
+
quantity: "energy",
|
|
18431
|
+
defaultAggregate: "sum",
|
|
18432
|
+
empty: "omit",
|
|
18433
|
+
companions: [NOW]
|
|
18434
|
+
}),
|
|
18435
|
+
numeric({
|
|
18436
|
+
id: "battery",
|
|
18437
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18438
|
+
role: DeviceRole.BatterySensor,
|
|
18439
|
+
outputCap: "battery",
|
|
18440
|
+
outputField: "percentage",
|
|
18441
|
+
quantity: "percentage",
|
|
18442
|
+
defaultAggregate: "mean",
|
|
18443
|
+
empty: "null",
|
|
18444
|
+
companions: [
|
|
18445
|
+
{
|
|
18446
|
+
fieldPath: "charging",
|
|
18447
|
+
expr: "\"unknown\""
|
|
18448
|
+
},
|
|
18449
|
+
{
|
|
18450
|
+
fieldPath: "sleeping",
|
|
18451
|
+
expr: "false"
|
|
18452
|
+
},
|
|
18453
|
+
{
|
|
18454
|
+
fieldPath: "lastUpdated",
|
|
18455
|
+
expr: "now"
|
|
18456
|
+
}
|
|
18457
|
+
]
|
|
18458
|
+
}),
|
|
18459
|
+
numeric({
|
|
18460
|
+
id: "numeric",
|
|
18461
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18462
|
+
role: DeviceRole.NumericSensor,
|
|
18463
|
+
outputCap: "numeric-sensor",
|
|
18464
|
+
outputField: "value",
|
|
18465
|
+
quantity: "device",
|
|
18466
|
+
defaultAggregate: "mean",
|
|
18467
|
+
empty: "null",
|
|
18468
|
+
companions: [NOW]
|
|
18469
|
+
}),
|
|
18470
|
+
binary({
|
|
18471
|
+
id: "motion",
|
|
18472
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18473
|
+
role: DeviceRole.MotionSensor,
|
|
18474
|
+
outputCap: "motion",
|
|
18475
|
+
outputField: "detected",
|
|
18476
|
+
defaultAggregate: "any",
|
|
18477
|
+
accept: [{
|
|
18478
|
+
cap: "motion",
|
|
18479
|
+
fieldPath: "detected"
|
|
18480
|
+
}],
|
|
18481
|
+
companions: [{
|
|
18482
|
+
fieldPath: "lastDetectedAt",
|
|
18483
|
+
expr: "null"
|
|
18484
|
+
}, {
|
|
18485
|
+
fieldPath: "autoClearAfterMs",
|
|
18486
|
+
expr: "null"
|
|
18487
|
+
}]
|
|
18488
|
+
}),
|
|
18489
|
+
binary({
|
|
18490
|
+
id: "contact",
|
|
18491
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18492
|
+
role: DeviceRole.ContactSensor,
|
|
18493
|
+
outputCap: "contact",
|
|
18494
|
+
outputField: "entryOpen",
|
|
18495
|
+
defaultAggregate: "any",
|
|
18496
|
+
accept: [{
|
|
18497
|
+
cap: "contact",
|
|
18498
|
+
fieldPath: "entryOpen"
|
|
18499
|
+
}],
|
|
18500
|
+
companions: [CHANGED]
|
|
18501
|
+
}),
|
|
18502
|
+
binary({
|
|
18503
|
+
id: "leak",
|
|
18504
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18505
|
+
role: DeviceRole.LeakSensor,
|
|
18506
|
+
outputCap: "flood",
|
|
18507
|
+
outputField: "flooded",
|
|
18508
|
+
defaultAggregate: "any",
|
|
18509
|
+
accept: [{
|
|
18510
|
+
cap: "flood",
|
|
18511
|
+
fieldPath: "flooded"
|
|
18512
|
+
}],
|
|
18513
|
+
companions: [CHANGED]
|
|
18514
|
+
}),
|
|
18515
|
+
binary({
|
|
18516
|
+
id: "smoke",
|
|
18517
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18518
|
+
role: DeviceRole.SmokeSensor,
|
|
18519
|
+
outputCap: "smoke",
|
|
18520
|
+
outputField: "detected",
|
|
18521
|
+
defaultAggregate: "any",
|
|
18522
|
+
accept: [{
|
|
18523
|
+
cap: "smoke",
|
|
18524
|
+
fieldPath: "detected"
|
|
18525
|
+
}],
|
|
18526
|
+
companions: [CHANGED]
|
|
18527
|
+
}),
|
|
18528
|
+
binary({
|
|
18529
|
+
id: "occupancy",
|
|
18530
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18531
|
+
role: DeviceRole.BinarySensor,
|
|
18532
|
+
outputCap: "binary",
|
|
18533
|
+
outputField: "on",
|
|
18534
|
+
defaultAggregate: "any",
|
|
18535
|
+
accept: [{
|
|
18536
|
+
cap: "motion",
|
|
18537
|
+
fieldPath: "detected"
|
|
18538
|
+
}, {
|
|
18539
|
+
cap: "binary",
|
|
18540
|
+
fieldPath: "on"
|
|
18541
|
+
}],
|
|
18542
|
+
companions: [CHANGED]
|
|
18543
|
+
}),
|
|
18544
|
+
binary({
|
|
18545
|
+
id: "binary",
|
|
18546
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18547
|
+
role: DeviceRole.BinarySensor,
|
|
18548
|
+
outputCap: "binary",
|
|
18549
|
+
outputField: "on",
|
|
18550
|
+
defaultAggregate: "any",
|
|
18551
|
+
accept: [{
|
|
18552
|
+
cap: "binary",
|
|
18553
|
+
fieldPath: "on"
|
|
18554
|
+
}],
|
|
18555
|
+
companions: [CHANGED]
|
|
18556
|
+
}),
|
|
18557
|
+
actuator({
|
|
18558
|
+
id: "switch",
|
|
18559
|
+
summary: "On when at least one switch is on, or when all of them are. Offline and unknown members are left out of that decision, never read as off, and still receive the command.",
|
|
18560
|
+
deviceType: DeviceType.Switch,
|
|
18561
|
+
outputCap: "switch",
|
|
18562
|
+
commandCaps: ["switch"]
|
|
18563
|
+
}),
|
|
18564
|
+
actuator({
|
|
18565
|
+
id: "light",
|
|
18566
|
+
summary: "On when at least one light is on, or when all of them are. Brightness and colour are offered only when every member has them. A command is not sent to a member that lacks it.",
|
|
18567
|
+
deviceType: DeviceType.Light,
|
|
18568
|
+
outputCap: "switch",
|
|
18569
|
+
commandCaps: [
|
|
18570
|
+
"switch",
|
|
18571
|
+
"brightness",
|
|
18572
|
+
"color"
|
|
18573
|
+
]
|
|
18574
|
+
})
|
|
18575
|
+
];
|
|
18576
|
+
function actuator(input) {
|
|
18577
|
+
return {
|
|
18578
|
+
...input,
|
|
18579
|
+
family: "actuator",
|
|
18580
|
+
role: void 0,
|
|
18581
|
+
memberDeviceType: input.deviceType,
|
|
18582
|
+
outputField: "on",
|
|
18583
|
+
quantity: "none",
|
|
18584
|
+
baseUnit: void 0,
|
|
18585
|
+
aggregates: BINARY_AGGREGATES,
|
|
18586
|
+
defaultAggregate: "any",
|
|
18587
|
+
empty: "offline",
|
|
18588
|
+
accept: [{
|
|
18589
|
+
cap: "switch",
|
|
18590
|
+
fieldPath: "on"
|
|
18591
|
+
}],
|
|
18592
|
+
companions: [CHANGED]
|
|
18593
|
+
};
|
|
18594
|
+
}
|
|
18595
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18596
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18209
18597
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18210
18598
|
/**
|
|
18211
18599
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19919,12 +20307,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
19919
20307
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19920
20308
|
* in-place so dispatch keeps working.
|
|
19921
20309
|
*
|
|
19922
|
-
* **
|
|
19923
|
-
*
|
|
19924
|
-
*
|
|
19925
|
-
*
|
|
19926
|
-
* (`ha-domain-mapping`)
|
|
19927
|
-
* stored after that point.
|
|
20310
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20311
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20312
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20313
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20314
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20315
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19928
20316
|
*
|
|
19929
20317
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19930
20318
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19938,6 +20326,14 @@ var SourceInfoSchema = object({
|
|
|
19938
20326
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19939
20327
|
* Used to detect rename when `id` changes. */
|
|
19940
20328
|
uniqueId: string().optional(),
|
|
20329
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20330
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20331
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20332
|
+
dateTimeShape: _enum([
|
|
20333
|
+
"date",
|
|
20334
|
+
"time",
|
|
20335
|
+
"datetime"
|
|
20336
|
+
]).optional(),
|
|
19941
20337
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19942
20338
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19943
20339
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40961,7 +41357,8 @@ method(object({
|
|
|
40961
41357
|
"enum"
|
|
40962
41358
|
]),
|
|
40963
41359
|
enumValues: array(string()).optional(),
|
|
40964
|
-
item: boolean().optional()
|
|
41360
|
+
item: boolean().optional(),
|
|
41361
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40965
41362
|
})).readonly(),
|
|
40966
41363
|
itemArray: object({
|
|
40967
41364
|
path: string(),
|
|
@@ -44805,8 +45202,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44805
45202
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44806
45203
|
var MaskGridShapeSchema = object({
|
|
44807
45204
|
kind: literal("grid"),
|
|
44808
|
-
gridWidth: number(),
|
|
44809
|
-
gridHeight: number(),
|
|
45205
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45206
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44810
45207
|
cells: array(boolean())
|
|
44811
45208
|
});
|
|
44812
45209
|
discriminatedUnion("kind", [
|
|
@@ -44918,6 +45315,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44918
45315
|
"detection-blind",
|
|
44919
45316
|
"motion-noisy",
|
|
44920
45317
|
"motion-calm",
|
|
45318
|
+
"package-llm-silent",
|
|
45319
|
+
"package-llm-answered",
|
|
44921
45320
|
"recording-stalled",
|
|
44922
45321
|
"recording-healthy",
|
|
44923
45322
|
"recording-degraded",
|
|
@@ -56157,6 +56556,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56157
56556
|
deprecated: string().optional(),
|
|
56158
56557
|
distTags: array(string()).readonly()
|
|
56159
56558
|
});
|
|
56559
|
+
/**
|
|
56560
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56561
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56562
|
+
* tarball failure — never an empty string standing in for either.
|
|
56563
|
+
*/
|
|
56564
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56565
|
+
object({
|
|
56566
|
+
status: literal("ok"),
|
|
56567
|
+
markdown: string()
|
|
56568
|
+
}),
|
|
56569
|
+
object({ status: literal("missing") }),
|
|
56570
|
+
object({
|
|
56571
|
+
status: literal("error"),
|
|
56572
|
+
message: string()
|
|
56573
|
+
})
|
|
56574
|
+
]);
|
|
56575
|
+
var PackageDocsSchema = object({
|
|
56576
|
+
name: string(),
|
|
56577
|
+
version: string(),
|
|
56578
|
+
readme: PackageDocBodySchema,
|
|
56579
|
+
changelog: PackageDocBodySchema
|
|
56580
|
+
});
|
|
56160
56581
|
var SearchResultSchema = object({
|
|
56161
56582
|
name: string(),
|
|
56162
56583
|
version: string(),
|
|
@@ -56375,7 +56796,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56375
56796
|
}), object({ success: literal(true) }), {
|
|
56376
56797
|
kind: "mutation",
|
|
56377
56798
|
auth: "admin"
|
|
56378
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56799
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56800
|
+
name: string().min(1),
|
|
56801
|
+
version: string().min(1).optional()
|
|
56802
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56379
56803
|
kind: "mutation",
|
|
56380
56804
|
auth: "admin"
|
|
56381
56805
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56434,27 +56858,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56434
56858
|
*/
|
|
56435
56859
|
var AirQualitySensorStatusSchema = object({
|
|
56436
56860
|
/** Carbon dioxide concentration in ppm. */
|
|
56437
|
-
co2Ppm: number().min(0).optional(),
|
|
56861
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56438
56862
|
/** Total volatile organic compounds in ppb. */
|
|
56439
|
-
vocPpb: number().min(0).optional(),
|
|
56863
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56440
56864
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56441
|
-
pm25: number().min(0).optional(),
|
|
56865
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56442
56866
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56443
|
-
pm10: number().min(0).optional(),
|
|
56867
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56444
56868
|
/** Composite AQI value (typically 0..500). */
|
|
56445
|
-
aqi: number().optional(),
|
|
56869
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56446
56870
|
/** Ms epoch when the slice was last updated. */
|
|
56447
|
-
lastFetchedAt: number()
|
|
56448
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56449
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56450
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56451
|
-
* per slice is unambiguous. */
|
|
56452
|
-
unit: string().optional(),
|
|
56453
|
-
/** Suggested decimal places for numeric display.
|
|
56454
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56455
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56456
|
-
* auto-formatting when absent. */
|
|
56457
|
-
precision: number().int().min(0).max(10).optional()
|
|
56871
|
+
lastFetchedAt: number()
|
|
56458
56872
|
});
|
|
56459
56873
|
var airQualitySensorCapability = {
|
|
56460
56874
|
name: "air-quality-sensor",
|
|
@@ -56491,12 +56905,12 @@ var airQualitySensorCapability = {
|
|
|
56491
56905
|
},
|
|
56492
56906
|
pm25: {
|
|
56493
56907
|
kind: "gauge",
|
|
56494
|
-
unit: "
|
|
56908
|
+
unit: "µg/m³",
|
|
56495
56909
|
deadband: 1
|
|
56496
56910
|
},
|
|
56497
56911
|
pm10: {
|
|
56498
56912
|
kind: "gauge",
|
|
56499
|
-
unit: "
|
|
56913
|
+
unit: "µg/m³",
|
|
56500
56914
|
deadband: 1
|
|
56501
56915
|
},
|
|
56502
56916
|
aqi: {
|
|
@@ -56514,22 +56928,13 @@ var airQualitySensorCapability = {
|
|
|
56514
56928
|
* entries with `device_class: illuminance`.
|
|
56515
56929
|
*/
|
|
56516
56930
|
var AmbientLightSensorStatusSchema = object({
|
|
56517
|
-
/** Current illuminance in lux (lx). */
|
|
56518
|
-
lux: number().min(0).meta({
|
|
56519
|
-
|
|
56931
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56932
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56933
|
+
precision: 0,
|
|
56520
56934
|
label: "Illuminance"
|
|
56521
|
-
}),
|
|
56935
|
+
})),
|
|
56522
56936
|
/** Ms epoch when the slice was last updated. */
|
|
56523
|
-
lastFetchedAt: number()
|
|
56524
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56525
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56526
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56527
|
-
unit: string().optional(),
|
|
56528
|
-
/** Suggested decimal places for numeric display.
|
|
56529
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56530
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56531
|
-
* auto-formatting when absent. */
|
|
56532
|
-
precision: number().int().min(0).max(10).optional()
|
|
56937
|
+
lastFetchedAt: number()
|
|
56533
56938
|
});
|
|
56534
56939
|
var ambientLightSensorCapability = {
|
|
56535
56940
|
name: "ambient-light-sensor",
|
|
@@ -56561,12 +56966,7 @@ var ambientLightSensorCapability = {
|
|
|
56561
56966
|
} } },
|
|
56562
56967
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56563
56968
|
* whether persisting is worth a SQLite commit. */
|
|
56564
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56565
|
-
customize: {
|
|
56566
|
-
version: 1,
|
|
56567
|
-
advanced: "derive",
|
|
56568
|
-
targets: []
|
|
56569
|
-
}
|
|
56969
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56570
56970
|
};
|
|
56571
56971
|
/**
|
|
56572
56972
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -56793,10 +57193,7 @@ var BatteryStatusSchema = object({
|
|
|
56793
57193
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56794
57194
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56795
57195
|
*/
|
|
56796
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56797
|
-
unit: "%",
|
|
56798
|
-
label: "Charge"
|
|
56799
|
-
}),
|
|
57196
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56800
57197
|
/**
|
|
56801
57198
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56802
57199
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56823,7 +57220,14 @@ var BatteryStatusSchema = object({
|
|
|
56823
57220
|
*/
|
|
56824
57221
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56825
57222
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56826
|
-
lastUpdated: number(),
|
|
57223
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57224
|
+
/**
|
|
57225
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57226
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57227
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57228
|
+
* `numeric-sensor` on the same device.
|
|
57229
|
+
*/
|
|
57230
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56827
57231
|
/**
|
|
56828
57232
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56829
57233
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56875,7 +57279,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
56875
57279
|
/** Generic Customize target for the percentage reading (D936). */
|
|
56876
57280
|
var batteryCustomize = {
|
|
56877
57281
|
version: 1,
|
|
56878
|
-
advanced: "derive",
|
|
56879
57282
|
targets: [{
|
|
56880
57283
|
id: "percentage",
|
|
56881
57284
|
cardinality: "scalar",
|
|
@@ -56884,7 +57287,7 @@ var batteryCustomize = {
|
|
|
56884
57287
|
stateField: "percentage"
|
|
56885
57288
|
},
|
|
56886
57289
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
56887
|
-
apply: "add
|
|
57290
|
+
apply: "add",
|
|
56888
57291
|
path: "percentage",
|
|
56889
57292
|
sources: [{
|
|
56890
57293
|
kind: "field",
|
|
@@ -57005,10 +57408,16 @@ onStatusChanged: { data: object({
|
|
|
57005
57408
|
/**
|
|
57006
57409
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57007
57410
|
*/
|
|
57008
|
-
history: { fields: {
|
|
57009
|
-
|
|
57010
|
-
|
|
57011
|
-
|
|
57411
|
+
history: { fields: {
|
|
57412
|
+
percentage: {
|
|
57413
|
+
kind: "gauge",
|
|
57414
|
+
unit: "%"
|
|
57415
|
+
},
|
|
57416
|
+
volts: {
|
|
57417
|
+
kind: "gauge",
|
|
57418
|
+
unit: "V"
|
|
57419
|
+
}
|
|
57420
|
+
} },
|
|
57012
57421
|
customize: batteryCustomize,
|
|
57013
57422
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57014
57423
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57055,12 +57464,7 @@ var binaryCapability = {
|
|
|
57055
57464
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57056
57465
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57057
57466
|
* whether persisting is worth a SQLite commit. */
|
|
57058
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57059
|
-
customize: {
|
|
57060
|
-
version: 1,
|
|
57061
|
-
advanced: "derive",
|
|
57062
|
-
targets: []
|
|
57063
|
-
}
|
|
57467
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57064
57468
|
};
|
|
57065
57469
|
/**
|
|
57066
57470
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57076,7 +57480,7 @@ var binaryCapability = {
|
|
|
57076
57480
|
*/
|
|
57077
57481
|
var BrightnessStatusSchema = object({
|
|
57078
57482
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57079
|
-
percentage: number().min(0).max(100),
|
|
57483
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57080
57484
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57081
57485
|
lastChangedAt: number()
|
|
57082
57486
|
});
|
|
@@ -57530,21 +57934,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57530
57934
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57531
57935
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57532
57936
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57533
|
-
target: number().nullable(),
|
|
57937
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57534
57938
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57535
57939
|
* in `heat_cool` mode. */
|
|
57536
|
-
targetHigh: number().nullable(),
|
|
57940
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57537
57941
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57538
57942
|
* in `heat_cool` mode. */
|
|
57539
|
-
targetLow: number().nullable(),
|
|
57943
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57540
57944
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57541
57945
|
* humidity control. */
|
|
57542
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57946
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57543
57947
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57544
57948
|
* the device's internal sensor. */
|
|
57545
|
-
currentTemp: number().nullable(),
|
|
57949
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57546
57950
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57547
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57951
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57548
57952
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57549
57953
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57550
57954
|
swingVertical: boolean().nullable(),
|
|
@@ -57552,11 +57956,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57552
57956
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57553
57957
|
swingHorizontal: boolean().nullable(),
|
|
57554
57958
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57555
|
-
minTemp: number().nullable().optional(),
|
|
57959
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57556
57960
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57557
|
-
maxTemp: number().nullable().optional(),
|
|
57961
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57558
57962
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57559
|
-
tempStep: number().positive().nullable().optional(),
|
|
57963
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57560
57964
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57561
57965
|
lastFetchedAt: number()
|
|
57562
57966
|
});
|
|
@@ -57698,17 +58102,17 @@ var climateControlCapability = {
|
|
|
57698
58102
|
* modes to expose in the picker without a slice fetch.
|
|
57699
58103
|
*/
|
|
57700
58104
|
var RgbTripletSchema = object({
|
|
57701
|
-
r: number().int().min(0).max(255),
|
|
57702
|
-
g: number().int().min(0).max(255),
|
|
57703
|
-
b: number().int().min(0).max(255)
|
|
58105
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58106
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58107
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57704
58108
|
});
|
|
57705
58109
|
var HsvTripletSchema = object({
|
|
57706
58110
|
/** Hue in degrees, 0..360. */
|
|
57707
|
-
h: number().min(0).max(360),
|
|
58111
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57708
58112
|
/** Saturation as 0..100 inclusive. */
|
|
57709
|
-
s: number().min(0).max(100),
|
|
58113
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57710
58114
|
/** Value/brightness as 0..100 inclusive. */
|
|
57711
|
-
v: number().min(0).max(100)
|
|
58115
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57712
58116
|
});
|
|
57713
58117
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57714
58118
|
object({
|
|
@@ -57737,7 +58141,7 @@ var ColorStatusSchema = object({
|
|
|
57737
58141
|
/** Populated when `mode === 'hsv'`. */
|
|
57738
58142
|
hsv: HsvTripletSchema.optional(),
|
|
57739
58143
|
/** Populated when `mode === 'mired'`. */
|
|
57740
|
-
mireds: number().int().optional(),
|
|
58144
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57741
58145
|
/** Ms epoch of the last operator-driven change. */
|
|
57742
58146
|
lastChangedAt: number()
|
|
57743
58147
|
});
|
|
@@ -57932,18 +58336,12 @@ _enum([
|
|
|
57932
58336
|
"empty",
|
|
57933
58337
|
"full"
|
|
57934
58338
|
]);
|
|
57935
|
-
/**
|
|
57936
|
-
|
|
57937
|
-
|
|
57938
|
-
"days",
|
|
57939
|
-
"hours",
|
|
57940
|
-
"cycles"
|
|
57941
|
-
]);
|
|
57942
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57943
|
-
* days). `value` null = unknown (D393). */
|
|
58339
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58340
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58341
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57944
58342
|
var ConsumableRemainingSchema = object({
|
|
57945
|
-
value: number().min(0).nullable(),
|
|
57946
|
-
|
|
58343
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58344
|
+
kind: ConsumableRemainingKindSchema
|
|
57947
58345
|
});
|
|
57948
58346
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
57949
58347
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -57956,7 +58354,7 @@ var ConsumableItemSchema = object({
|
|
|
57956
58354
|
/** Display name. */
|
|
57957
58355
|
label: string().min(1),
|
|
57958
58356
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57959
|
-
level: number().min(0).max(100).nullable(),
|
|
58357
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57960
58358
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57961
58359
|
status: ConsumableStatusSchema.nullable(),
|
|
57962
58360
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58038,8 +58436,8 @@ var consumablesCustomize = {
|
|
|
58038
58436
|
transforms: [{ kind: "identity" }]
|
|
58039
58437
|
}],
|
|
58040
58438
|
literals: [{
|
|
58041
|
-
path: "remaining.
|
|
58042
|
-
values: [...
|
|
58439
|
+
path: "remaining.kind",
|
|
58440
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58043
58441
|
}]
|
|
58044
58442
|
},
|
|
58045
58443
|
{
|
|
@@ -58168,7 +58566,6 @@ reset: method(object({
|
|
|
58168
58566
|
},
|
|
58169
58567
|
"remaining.value": {
|
|
58170
58568
|
kind: "gauge",
|
|
58171
|
-
unitFrom: "remaining.unit",
|
|
58172
58569
|
deadband: 1,
|
|
58173
58570
|
displayName: "Remaining"
|
|
58174
58571
|
}
|
|
@@ -58238,10 +58635,9 @@ var contactCapability = {
|
|
|
58238
58635
|
* (empty array for the other kinds). It lives in the slice because
|
|
58239
58636
|
* HA `select.*` entities may update their options at runtime.
|
|
58240
58637
|
*
|
|
58241
|
-
*
|
|
58242
|
-
*
|
|
58243
|
-
*
|
|
58244
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58638
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58639
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58640
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58245
58641
|
*/
|
|
58246
58642
|
var ControlStatusSchema = object({
|
|
58247
58643
|
kind: _enum([
|
|
@@ -58253,39 +58649,17 @@ var ControlStatusSchema = object({
|
|
|
58253
58649
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58254
58650
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58255
58651
|
* or time-only — HA accepts all three forms). */
|
|
58256
|
-
value: union([number(), string()]),
|
|
58652
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58257
58653
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58258
58654
|
options: array(string()),
|
|
58259
58655
|
/** Ms epoch when the slice was last updated. */
|
|
58260
58656
|
lastChangedAt: number(),
|
|
58261
|
-
/**
|
|
58262
|
-
|
|
58263
|
-
|
|
58264
|
-
|
|
58265
|
-
/**
|
|
58266
|
-
|
|
58267
|
-
min: number().optional(),
|
|
58268
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58269
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58270
|
-
max: number().optional(),
|
|
58271
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58272
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58273
|
-
step: number().optional(),
|
|
58274
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58275
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58276
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58277
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58278
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58279
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58280
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58281
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58282
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58283
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58284
|
-
format: _enum([
|
|
58285
|
-
"date",
|
|
58286
|
-
"time",
|
|
58287
|
-
"datetime"
|
|
58288
|
-
]).optional()
|
|
58657
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58658
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58659
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58660
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58661
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58662
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58289
58663
|
});
|
|
58290
58664
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58291
58665
|
object({
|
|
@@ -58351,9 +58725,9 @@ var CoverStatusSchema = object({
|
|
|
58351
58725
|
]),
|
|
58352
58726
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58353
58727
|
* no intermediate position surface. */
|
|
58354
|
-
position: number().min(0).max(100).nullable(),
|
|
58728
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58355
58729
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58356
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58730
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58357
58731
|
/** Ms epoch when the slice was last updated. */
|
|
58358
58732
|
lastChangedAt: number()
|
|
58359
58733
|
});
|
|
@@ -58456,9 +58830,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58456
58830
|
var DayNightStatusSchema = object({
|
|
58457
58831
|
mode: DayNightModeSchema,
|
|
58458
58832
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58459
|
-
sensitivity: number().optional(),
|
|
58833
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58460
58834
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58461
|
-
switchDelaySec: number().optional(),
|
|
58835
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58462
58836
|
lastFetchedAt: number()
|
|
58463
58837
|
});
|
|
58464
58838
|
/**
|
|
@@ -58676,11 +59050,11 @@ var DishwasherStatusSchema = object({
|
|
|
58676
59050
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58677
59051
|
availablePrograms: array(string()),
|
|
58678
59052
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58679
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59053
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58680
59054
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58681
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59055
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58682
59056
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58683
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59057
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58684
59058
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58685
59059
|
doorOpen: boolean().nullable(),
|
|
58686
59060
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58704,7 +59078,7 @@ var DishwasherStatusSchema = object({
|
|
|
58704
59078
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58705
59079
|
machineCareDue: boolean().nullable(),
|
|
58706
59080
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58707
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59081
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58708
59082
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58709
59083
|
halfLoad: boolean().nullable(),
|
|
58710
59084
|
hygienePlus: boolean().nullable(),
|
|
@@ -58719,7 +59093,7 @@ var DishwasherStatusSchema = object({
|
|
|
58719
59093
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58720
59094
|
activeEvents: array(string()),
|
|
58721
59095
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58722
|
-
errorCode: number().nullable(),
|
|
59096
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58723
59097
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58724
59098
|
errorLabel: string().nullable(),
|
|
58725
59099
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -58931,6 +59305,7 @@ var doorbellCustomize = {
|
|
|
58931
59305
|
applyAuthority: { kind: "composition-claim" },
|
|
58932
59306
|
eventName: "onPressed",
|
|
58933
59307
|
edges: ["rising"],
|
|
59308
|
+
defaultEdge: "rising",
|
|
58934
59309
|
timestampPath: "lastPressedAt",
|
|
58935
59310
|
counterPath: "pressCountSinceStart",
|
|
58936
59311
|
highWater: "composer-advance",
|
|
@@ -58949,7 +59324,7 @@ var DoorbellStatusSchema = object({
|
|
|
58949
59324
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
58950
59325
|
lastPressedAt: number().nullable(),
|
|
58951
59326
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
58952
|
-
pressCountSinceStart: number()
|
|
59327
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
58953
59328
|
});
|
|
58954
59329
|
var DoorbellPressEventSchema = object({
|
|
58955
59330
|
deviceId: number(),
|
|
@@ -59014,17 +59389,7 @@ onPressed: {
|
|
|
59014
59389
|
history: "none",
|
|
59015
59390
|
customize: doorbellCustomize
|
|
59016
59391
|
};
|
|
59017
|
-
|
|
59018
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59019
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59020
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59021
|
-
* The option set is stable across observations; it is persisted in the
|
|
59022
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59023
|
-
* stored in `sourceInfo`.
|
|
59024
|
-
*/
|
|
59025
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59026
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59027
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59392
|
+
_enum([
|
|
59028
59393
|
"date",
|
|
59029
59394
|
"time",
|
|
59030
59395
|
"datetime"
|
|
@@ -59032,12 +59397,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59032
59397
|
var EnumSensorStatusSchema = object({
|
|
59033
59398
|
value: string(),
|
|
59034
59399
|
/**
|
|
59035
|
-
* Set
|
|
59036
|
-
* as
|
|
59037
|
-
*
|
|
59038
|
-
* a time-only sensor → `'time'`.
|
|
59400
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59401
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59402
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59039
59403
|
*/
|
|
59040
|
-
|
|
59404
|
+
timestamp: boolean().optional(),
|
|
59041
59405
|
/** Ms epoch when the slice was last updated. */
|
|
59042
59406
|
lastFetchedAt: number()
|
|
59043
59407
|
});
|
|
@@ -59064,11 +59428,11 @@ var enumSensorCapability = {
|
|
|
59064
59428
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59065
59429
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59066
59430
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59067
|
-
* `
|
|
59431
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59068
59432
|
*/
|
|
59069
59433
|
history: { fields: { value: {
|
|
59070
59434
|
kind: "enum",
|
|
59071
|
-
skipWhenSet: "
|
|
59435
|
+
skipWhenSet: "timestamp"
|
|
59072
59436
|
} } },
|
|
59073
59437
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59074
59438
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59088,13 +59452,13 @@ var EventFireSchema = object({
|
|
|
59088
59452
|
deviceId: number(),
|
|
59089
59453
|
eventType: string(),
|
|
59090
59454
|
data: record(string(), unknown()).nullable(),
|
|
59091
|
-
timestamp: number(),
|
|
59092
|
-
seq: number()
|
|
59455
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59456
|
+
seq: number().meta(readingMeta("count"))
|
|
59093
59457
|
});
|
|
59094
59458
|
var EventEmitterStatusSchema = object({
|
|
59095
59459
|
eventTypes: array(string()),
|
|
59096
59460
|
lastEvent: EventFireSchema.nullable(),
|
|
59097
|
-
eventCountSinceStart: number()
|
|
59461
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59098
59462
|
});
|
|
59099
59463
|
var eventEmitterCapability = {
|
|
59100
59464
|
name: "event-emitter",
|
|
@@ -59507,10 +59871,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59507
59871
|
var FanControlStatusSchema = object({
|
|
59508
59872
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59509
59873
|
* speed surface (single-speed fan). */
|
|
59510
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59874
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59511
59875
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59512
59876
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59513
|
-
percentageStep: number().positive().optional(),
|
|
59877
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59514
59878
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59515
59879
|
* — empty string when no preset is active or supported. */
|
|
59516
59880
|
preset: string(),
|
|
@@ -59631,7 +59995,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59631
59995
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59632
59996
|
model: string().nullable(),
|
|
59633
59997
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59634
|
-
channelCount: number().nullable(),
|
|
59998
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59635
59999
|
/**
|
|
59636
60000
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59637
60001
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59754,9 +60118,91 @@ var gasCapability = {
|
|
|
59754
60118
|
* whether persisting is worth a SQLite commit. */
|
|
59755
60119
|
volatileStateFields: ["lastChangedAt"]
|
|
59756
60120
|
};
|
|
60121
|
+
var GroupCommandsSchema = object({
|
|
60122
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60123
|
+
results: array(object({
|
|
60124
|
+
deviceId: number().int().nonnegative(),
|
|
60125
|
+
cap: string().min(1),
|
|
60126
|
+
method: string().min(1),
|
|
60127
|
+
ok: boolean(),
|
|
60128
|
+
error: string().optional(),
|
|
60129
|
+
/** Ms epoch of the attempt. */
|
|
60130
|
+
at: number()
|
|
60131
|
+
})) });
|
|
60132
|
+
var groupCommandsCapability = {
|
|
60133
|
+
name: "group-commands",
|
|
60134
|
+
scope: "device",
|
|
60135
|
+
deviceNative: true,
|
|
60136
|
+
mode: "singleton",
|
|
60137
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60138
|
+
methods: {},
|
|
60139
|
+
status: {
|
|
60140
|
+
schema: GroupCommandsSchema,
|
|
60141
|
+
kind: "push"
|
|
60142
|
+
},
|
|
60143
|
+
runtimeState: GroupCommandsSchema,
|
|
60144
|
+
/**
|
|
60145
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60146
|
+
* failure would outlive the command that caused it.
|
|
60147
|
+
*
|
|
60148
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60149
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60150
|
+
*/
|
|
60151
|
+
durability: "session",
|
|
60152
|
+
history: "none"
|
|
60153
|
+
};
|
|
60154
|
+
/**
|
|
60155
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60156
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60157
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60158
|
+
* series that later statistics read is the output cap's own history block.
|
|
60159
|
+
*/
|
|
60160
|
+
var GroupStatusSchema = object({
|
|
60161
|
+
/** Members whose current value entered the aggregate. */
|
|
60162
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60163
|
+
precision: 0,
|
|
60164
|
+
label: "Reporting"
|
|
60165
|
+
})),
|
|
60166
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60167
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60168
|
+
precision: 0,
|
|
60169
|
+
label: "Excluded"
|
|
60170
|
+
})),
|
|
60171
|
+
/** `included` + `excluded`. */
|
|
60172
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60173
|
+
precision: 0,
|
|
60174
|
+
label: "Members"
|
|
60175
|
+
}))
|
|
60176
|
+
});
|
|
60177
|
+
var groupStatusCapability = {
|
|
60178
|
+
name: "group-status",
|
|
60179
|
+
scope: "device",
|
|
60180
|
+
deviceNative: true,
|
|
60181
|
+
mode: "singleton",
|
|
60182
|
+
deviceTypes: [
|
|
60183
|
+
DeviceType.Sensor,
|
|
60184
|
+
DeviceType.Switch,
|
|
60185
|
+
DeviceType.Light
|
|
60186
|
+
],
|
|
60187
|
+
methods: {},
|
|
60188
|
+
status: {
|
|
60189
|
+
schema: GroupStatusSchema,
|
|
60190
|
+
kind: "push"
|
|
60191
|
+
},
|
|
60192
|
+
runtimeState: GroupStatusSchema,
|
|
60193
|
+
/**
|
|
60194
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60195
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60196
|
+
*
|
|
60197
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60198
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60199
|
+
*/
|
|
60200
|
+
durability: "session",
|
|
60201
|
+
history: "none"
|
|
60202
|
+
};
|
|
59757
60203
|
var HeatingValveStatusSchema = object({
|
|
59758
60204
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59759
|
-
position: number().min(0).max(100).nullable(),
|
|
60205
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59760
60206
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59761
60207
|
lastFetchedAt: number()
|
|
59762
60208
|
});
|
|
@@ -59799,9 +60245,9 @@ var HumidifierStatusSchema = object({
|
|
|
59799
60245
|
/** Whether the humidifier is currently on. */
|
|
59800
60246
|
on: boolean(),
|
|
59801
60247
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59802
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60248
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59803
60249
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59804
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60250
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59805
60251
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59806
60252
|
* device has no mode surface. */
|
|
59807
60253
|
mode: string().nullable(),
|
|
@@ -59811,9 +60257,9 @@ var HumidifierStatusSchema = object({
|
|
|
59811
60257
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59812
60258
|
action: string().nullable(),
|
|
59813
60259
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59814
|
-
minHumidity: number().nullable(),
|
|
60260
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59815
60261
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59816
|
-
maxHumidity: number().nullable(),
|
|
60262
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59817
60263
|
/** Ms epoch when the slice was last updated. */
|
|
59818
60264
|
lastChangedAt: number()
|
|
59819
60265
|
});
|
|
@@ -59883,22 +60329,13 @@ var humidifierCapability = {
|
|
|
59883
60329
|
* `sourceInfo`.
|
|
59884
60330
|
*/
|
|
59885
60331
|
var HumiditySensorStatusSchema = object({
|
|
59886
|
-
/** Current relative humidity, 0..100. */
|
|
59887
|
-
percent: number().min(0).max(100).meta({
|
|
59888
|
-
|
|
60332
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60333
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60334
|
+
precision: 0,
|
|
59889
60335
|
label: "Humidity"
|
|
59890
|
-
}),
|
|
60336
|
+
})),
|
|
59891
60337
|
/** Ms epoch when the slice was last updated. */
|
|
59892
|
-
lastFetchedAt: number()
|
|
59893
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59894
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59895
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59896
|
-
unit: string().optional(),
|
|
59897
|
-
/** Suggested decimal places for numeric display.
|
|
59898
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59899
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59900
|
-
* auto-formatting when absent. */
|
|
59901
|
-
precision: number().int().min(0).max(10).optional()
|
|
60338
|
+
lastFetchedAt: number()
|
|
59902
60339
|
});
|
|
59903
60340
|
var humiditySensorCapability = {
|
|
59904
60341
|
name: "humidity-sensor",
|
|
@@ -59929,12 +60366,7 @@ var humiditySensorCapability = {
|
|
|
59929
60366
|
} } },
|
|
59930
60367
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59931
60368
|
* whether persisting is worth a SQLite commit. */
|
|
59932
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59933
|
-
customize: {
|
|
59934
|
-
version: 1,
|
|
59935
|
-
advanced: "derive",
|
|
59936
|
-
targets: []
|
|
59937
|
-
}
|
|
60369
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59938
60370
|
};
|
|
59939
60371
|
/**
|
|
59940
60372
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -59955,7 +60387,7 @@ var ImageStatusSchema = object({
|
|
|
59955
60387
|
* entity exposes no `entity_picture` (yet). */
|
|
59956
60388
|
url: string().nullable(),
|
|
59957
60389
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
59958
|
-
lastUpdated: number().nullable()
|
|
60390
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
59959
60391
|
});
|
|
59960
60392
|
var imageCapability = {
|
|
59961
60393
|
name: "image",
|
|
@@ -60043,19 +60475,19 @@ var NormalizedRangeSchema = object({
|
|
|
60043
60475
|
*/
|
|
60044
60476
|
var ImageSettingsStatusSchema = object({
|
|
60045
60477
|
/** Normalized 0–100. */
|
|
60046
|
-
brightness: number().optional(),
|
|
60478
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60047
60479
|
/** Normalized 0–100. */
|
|
60048
|
-
contrast: number().optional(),
|
|
60480
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60049
60481
|
/** Normalized 0–100. */
|
|
60050
|
-
saturation: number().optional(),
|
|
60482
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60051
60483
|
/** Normalized 0–100. */
|
|
60052
|
-
sharpness: number().optional(),
|
|
60484
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60053
60485
|
mirror: boolean().optional(),
|
|
60054
60486
|
flip: boolean().optional(),
|
|
60055
60487
|
rotate: ImageRotateSchema.optional(),
|
|
60056
60488
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60057
60489
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60058
|
-
warmth: number().optional(),
|
|
60490
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60059
60491
|
exposureMode: ExposureModeSchema.optional(),
|
|
60060
60492
|
backlightMode: BacklightModeSchema.optional(),
|
|
60061
60493
|
lastFetchedAt: number()
|
|
@@ -60334,10 +60766,10 @@ var IntercomAbilitySchema = object({
|
|
|
60334
60766
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60335
60767
|
codecs: array(string()),
|
|
60336
60768
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60337
|
-
sampleRate: number(),
|
|
60769
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60338
60770
|
duplex: _enum(["half", "full"]),
|
|
60339
60771
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60340
|
-
maxBacklogMs: number()
|
|
60772
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60341
60773
|
});
|
|
60342
60774
|
var IntercomStatusSchema = object({
|
|
60343
60775
|
/** True while a talk session is open. */
|
|
@@ -60564,13 +60996,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60564
60996
|
activity: LawnMowerActivitySchema,
|
|
60565
60997
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60566
60998
|
* reading. */
|
|
60567
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60999
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60568
61000
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60569
61001
|
* task is active / progress is unavailable. */
|
|
60570
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61002
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60571
61003
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60572
61004
|
* or null when unknown. */
|
|
60573
|
-
currentCode: number().nullable(),
|
|
61005
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60574
61006
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60575
61007
|
currentCodeLabel: string().nullable(),
|
|
60576
61008
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61103,7 +61535,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61103
61535
|
state: MediaPlayerStateSchema,
|
|
61104
61536
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61105
61537
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61106
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61538
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61107
61539
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61108
61540
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61109
61541
|
isMuted: boolean().nullable(),
|
|
@@ -61116,10 +61548,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61116
61548
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61117
61549
|
/** Current playback position in ms. Null when not seekable or
|
|
61118
61550
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61119
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61551
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61120
61552
|
/** Total duration of the current media in ms. Null when unknown
|
|
61121
61553
|
* (live stream) or nothing is playing. */
|
|
61122
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61554
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61123
61555
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61124
61556
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61125
61557
|
shuffle: boolean().nullable(),
|
|
@@ -61428,7 +61860,7 @@ var motionCustomize = {
|
|
|
61428
61860
|
eventName: "onMotionChanged"
|
|
61429
61861
|
},
|
|
61430
61862
|
deviceTypes: [DeviceType.Camera],
|
|
61431
|
-
apply: "
|
|
61863
|
+
apply: "add",
|
|
61432
61864
|
applyAuthority: {
|
|
61433
61865
|
kind: "camera-sensors",
|
|
61434
61866
|
timeoutField: "motionCooldownMs"
|
|
@@ -61500,7 +61932,7 @@ var MotionStatusSchema = object({
|
|
|
61500
61932
|
* it, every provider seeded it at boot, and every session left it
|
|
61501
61933
|
* `detected: true` after its detach.
|
|
61502
61934
|
*/
|
|
61503
|
-
autoClearAfterMs: number().nullable()
|
|
61935
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61504
61936
|
});
|
|
61505
61937
|
/**
|
|
61506
61938
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61537,12 +61969,18 @@ var motionCapability = {
|
|
|
61537
61969
|
methods: {
|
|
61538
61970
|
/**
|
|
61539
61971
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61540
|
-
* for consumers that don't need the full status object
|
|
61541
|
-
*
|
|
61542
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61543
|
-
* consumer.
|
|
61972
|
+
* for consumers that don't need the full status object. A composed
|
|
61973
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61544
61974
|
*/
|
|
61545
61975
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
61976
|
+
/**
|
|
61977
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
61978
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
61979
|
+
*/
|
|
61980
|
+
composedMethods: { isDetected: {
|
|
61981
|
+
kind: "slice",
|
|
61982
|
+
field: "detected"
|
|
61983
|
+
} },
|
|
61546
61984
|
events: {
|
|
61547
61985
|
/**
|
|
61548
61986
|
* Fires every time the runner transitions a camera between
|
|
@@ -61682,7 +62120,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61682
62120
|
* the grid region(s). */
|
|
61683
62121
|
var MotionZoneStatusSchema = object({
|
|
61684
62122
|
enabled: boolean(),
|
|
61685
|
-
sensitivity: number(),
|
|
62123
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61686
62124
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61687
62125
|
regions: array(MotionZoneRegionSchema),
|
|
61688
62126
|
lastFetchedAt: number()
|
|
@@ -62052,7 +62490,7 @@ var NavigationStatusSchema = object({
|
|
|
62052
62490
|
following: boolean(),
|
|
62053
62491
|
flash: boolean(),
|
|
62054
62492
|
lightMode: NavigationLightModeSchema,
|
|
62055
|
-
lightLevel: number().min(40).max(100),
|
|
62493
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62056
62494
|
/** Ms epoch when the slice was last updated. */
|
|
62057
62495
|
lastChangedAt: number()
|
|
62058
62496
|
});
|
|
@@ -62186,13 +62624,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62186
62624
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62187
62625
|
* SKIP a null rather than coerce it.
|
|
62188
62626
|
*/
|
|
62189
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62627
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62190
62628
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62191
|
-
rssiDbm: number().optional(),
|
|
62629
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62192
62630
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62193
62631
|
ssid: string().optional(),
|
|
62194
62632
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62195
|
-
lastUpdated: number()
|
|
62633
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62196
62634
|
});
|
|
62197
62635
|
var networkLinkCapability = {
|
|
62198
62636
|
name: "network-link",
|
|
@@ -62577,7 +63015,7 @@ var NotifierStatusSchema = object({
|
|
|
62577
63015
|
lastError: string().nullable(),
|
|
62578
63016
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62579
63017
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62580
|
-
queueDepth: number().int().nonnegative(),
|
|
63018
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62581
63019
|
/** Per-feature capability matrix — authoritative source for the
|
|
62582
63020
|
* compose-form field gating. */
|
|
62583
63021
|
supports: NotifierSupportsSchema
|
|
@@ -62669,11 +63107,9 @@ onSent: { data: object({
|
|
|
62669
63107
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62670
63108
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62671
63109
|
*
|
|
62672
|
-
* The
|
|
62673
|
-
*
|
|
62674
|
-
*
|
|
62675
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62676
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63110
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63111
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63112
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62677
63113
|
*
|
|
62678
63114
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62679
63115
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62682,15 +63118,8 @@ onSent: { data: object({
|
|
|
62682
63118
|
* numeric values land here.
|
|
62683
63119
|
*/
|
|
62684
63120
|
var NumericSensorStatusSchema = object({
|
|
62685
|
-
|
|
62686
|
-
|
|
62687
|
-
* Populated live from the upstream source on each state push.
|
|
62688
|
-
* Absent for unitless sensors. */
|
|
62689
|
-
unit: string().optional(),
|
|
62690
|
-
/** Suggested decimal places for numeric display.
|
|
62691
|
-
* Populated live from the upstream source when provided.
|
|
62692
|
-
* Falls back to auto-formatting when absent. */
|
|
62693
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63121
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63122
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62694
63123
|
/** Ms epoch when the slice was last updated. */
|
|
62695
63124
|
lastFetchedAt: number()
|
|
62696
63125
|
});
|
|
@@ -62714,11 +63143,11 @@ var numericSensorCapability = {
|
|
|
62714
63143
|
*/
|
|
62715
63144
|
durability: "restored",
|
|
62716
63145
|
/**
|
|
62717
|
-
* History (D850): recorded series. The unit is
|
|
63146
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63147
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62718
63148
|
*/
|
|
62719
63149
|
history: { fields: { value: {
|
|
62720
63150
|
kind: "gauge",
|
|
62721
|
-
unitFrom: "unit",
|
|
62722
63151
|
minIntervalMs: 3e4
|
|
62723
63152
|
} } },
|
|
62724
63153
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63010,23 +63439,26 @@ var PetFeederStatusSchema = object({
|
|
|
63010
63439
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63011
63440
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63012
63441
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63013
|
-
foodLevel: number().nullable(),
|
|
63442
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63014
63443
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63015
63444
|
* single-hopper models. */
|
|
63016
|
-
food1: number().nullable(),
|
|
63445
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63017
63446
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63018
63447
|
* single-hopper models. */
|
|
63019
|
-
food2: number().nullable(),
|
|
63448
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63020
63449
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63021
63450
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63022
63451
|
* below the feeder's low threshold. */
|
|
63023
63452
|
lowFood: boolean(),
|
|
63024
63453
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63025
63454
|
* device has no battery reading. */
|
|
63026
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63027
|
-
/**
|
|
63028
|
-
*
|
|
63029
|
-
|
|
63455
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63456
|
+
/**
|
|
63457
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63458
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63459
|
+
* model has no desiccant sensor.
|
|
63460
|
+
*/
|
|
63461
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63030
63462
|
/** True while a feed is in progress. */
|
|
63031
63463
|
feeding: boolean(),
|
|
63032
63464
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63037,7 +63469,7 @@ var PetFeederStatusSchema = object({
|
|
|
63037
63469
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63038
63470
|
error: string().nullable(),
|
|
63039
63471
|
/** Raw device error code (0 / null = no error). */
|
|
63040
|
-
errorCode: number().nullable(),
|
|
63472
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63041
63473
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63042
63474
|
isDualHopper: boolean(),
|
|
63043
63475
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63047,7 +63479,7 @@ var PetFeederStatusSchema = object({
|
|
|
63047
63479
|
/** Play a chime when dispensing. */
|
|
63048
63480
|
feedSound: boolean(),
|
|
63049
63481
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63050
|
-
volume: number(),
|
|
63482
|
+
volume: number().meta(readingMeta("none")),
|
|
63051
63483
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63052
63484
|
lastFetchedAt: number()
|
|
63053
63485
|
});
|
|
@@ -63166,7 +63598,7 @@ var petFeederCapability = {
|
|
|
63166
63598
|
},
|
|
63167
63599
|
desiccantLeftDays: {
|
|
63168
63600
|
kind: "gauge",
|
|
63169
|
-
unit: "
|
|
63601
|
+
unit: "s"
|
|
63170
63602
|
}
|
|
63171
63603
|
} }
|
|
63172
63604
|
};
|
|
@@ -63567,36 +63999,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63567
63999
|
*/
|
|
63568
64000
|
var PowerMeterStatusSchema = object({
|
|
63569
64001
|
/** Instantaneous power draw in watts. */
|
|
63570
|
-
watts: number().optional().meta({
|
|
63571
|
-
unit: "W",
|
|
63572
|
-
label: "Power"
|
|
63573
|
-
}),
|
|
64002
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63574
64003
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63575
|
-
kwhTotal: number().optional().meta({
|
|
63576
|
-
unit: "kWh",
|
|
63577
|
-
label: "Energy"
|
|
63578
|
-
}),
|
|
64004
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63579
64005
|
/** Voltage in volts. */
|
|
63580
|
-
volts: number().optional(),
|
|
64006
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63581
64007
|
/** Current in amperes. */
|
|
63582
|
-
amps: number().optional(),
|
|
63583
|
-
/** Apparent power in volt-amperes
|
|
63584
|
-
va: number().optional(),
|
|
64008
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
64009
|
+
/** Apparent power in volt-amperes. */
|
|
64010
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63585
64011
|
/** Power factor (0..1) if reported. */
|
|
63586
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
64012
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63587
64013
|
/** Ms epoch when the slice was last updated. */
|
|
63588
|
-
lastFetchedAt: number()
|
|
63589
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63590
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63591
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63592
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63593
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63594
|
-
unit: string().optional(),
|
|
63595
|
-
/** Suggested decimal places for numeric display.
|
|
63596
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63597
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63598
|
-
* auto-formatting when absent. */
|
|
63599
|
-
precision: number().int().min(0).max(10).optional()
|
|
64014
|
+
lastFetchedAt: number()
|
|
63600
64015
|
});
|
|
63601
64016
|
var powerMeterCapability = {
|
|
63602
64017
|
name: "power-meter",
|
|
@@ -63660,12 +64075,7 @@ var powerMeterCapability = {
|
|
|
63660
64075
|
} },
|
|
63661
64076
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63662
64077
|
* whether persisting is worth a SQLite commit. */
|
|
63663
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63664
|
-
customize: {
|
|
63665
|
-
version: 1,
|
|
63666
|
-
advanced: "derive",
|
|
63667
|
-
targets: []
|
|
63668
|
-
}
|
|
64078
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63669
64079
|
};
|
|
63670
64080
|
/**
|
|
63671
64081
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63685,11 +64095,11 @@ var powerMeterCapability = {
|
|
|
63685
64095
|
*/
|
|
63686
64096
|
var GpsLocationSchema = object({
|
|
63687
64097
|
/** Latitude in decimal degrees, -90..90. */
|
|
63688
|
-
latitude: number().min(-90).max(90),
|
|
64098
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63689
64099
|
/** Longitude in decimal degrees, -180..180. */
|
|
63690
|
-
longitude: number().min(-180).max(180),
|
|
64100
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63691
64101
|
/** Reported accuracy in meters (lower = better). */
|
|
63692
|
-
accuracyMeters: number().nonnegative()
|
|
64102
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63693
64103
|
});
|
|
63694
64104
|
var PresenceStatusSchema = object({
|
|
63695
64105
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63701,7 +64111,7 @@ var PresenceStatusSchema = object({
|
|
|
63701
64111
|
gps: GpsLocationSchema.nullable(),
|
|
63702
64112
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63703
64113
|
* when not reported. */
|
|
63704
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64114
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63705
64115
|
/** Ms epoch when the slice was last updated. */
|
|
63706
64116
|
lastChangedAt: number()
|
|
63707
64117
|
});
|
|
@@ -63751,19 +64161,10 @@ var presenceCapability = {
|
|
|
63751
64161
|
* `sourceInfo`.
|
|
63752
64162
|
*/
|
|
63753
64163
|
var PressureSensorStatusSchema = object({
|
|
63754
|
-
/** Current pressure in hPa. */
|
|
63755
|
-
hpa: number(),
|
|
64164
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64165
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63756
64166
|
/** Ms epoch when the slice was last updated. */
|
|
63757
|
-
lastFetchedAt: number()
|
|
63758
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63759
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63760
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63761
|
-
unit: string().optional(),
|
|
63762
|
-
/** Suggested decimal places for numeric display.
|
|
63763
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63764
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63765
|
-
* auto-formatting when absent. */
|
|
63766
|
-
precision: number().int().min(0).max(10).optional()
|
|
64167
|
+
lastFetchedAt: number()
|
|
63767
64168
|
});
|
|
63768
64169
|
var pressureSensorCapability = {
|
|
63769
64170
|
name: "pressure-sensor",
|
|
@@ -64177,8 +64578,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64177
64578
|
}), _void(), { kind: "mutation" });
|
|
64178
64579
|
var PtzAutotrackSettingsSchema = object({
|
|
64179
64580
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64180
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64181
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64581
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64582
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64182
64583
|
});
|
|
64183
64584
|
/**
|
|
64184
64585
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64332,7 +64733,7 @@ var RunningStateStatusSchema = object({
|
|
|
64332
64733
|
/** null = unknown — never coerced to false (D393). */
|
|
64333
64734
|
running: boolean().nullable(),
|
|
64334
64735
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64335
|
-
since: number().nullable(),
|
|
64736
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64336
64737
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64337
64738
|
phase: string().nullable(),
|
|
64338
64739
|
/** null until a reading has been published (D393). */
|
|
@@ -64347,7 +64748,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64347
64748
|
/** Generic Customize target for the running boolean (D936). */
|
|
64348
64749
|
var runningCustomize = {
|
|
64349
64750
|
version: 1,
|
|
64350
|
-
advanced: "derive",
|
|
64351
64751
|
targets: [{
|
|
64352
64752
|
id: "running",
|
|
64353
64753
|
cardinality: "scalar",
|
|
@@ -64367,7 +64767,7 @@ var runningCustomize = {
|
|
|
64367
64767
|
DeviceType.Thermostat,
|
|
64368
64768
|
DeviceType.PetFeeder
|
|
64369
64769
|
],
|
|
64370
|
-
apply: "add
|
|
64770
|
+
apply: "add",
|
|
64371
64771
|
path: "running",
|
|
64372
64772
|
sources: [
|
|
64373
64773
|
{
|
|
@@ -64383,6 +64783,7 @@ var runningCustomize = {
|
|
|
64383
64783
|
requiredUnit: "W",
|
|
64384
64784
|
transforms: [{
|
|
64385
64785
|
kind: "threshold",
|
|
64786
|
+
comparisons: ["gte", "lte"],
|
|
64386
64787
|
comparison: "gte",
|
|
64387
64788
|
defaultThreshold: 5,
|
|
64388
64789
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -65630,9 +66031,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65630
66031
|
*/
|
|
65631
66032
|
var RecordWindowSchema = object({
|
|
65632
66033
|
trigger: RecordTriggerSchema,
|
|
65633
|
-
day: number().int().min(0).max(6),
|
|
65634
|
-
startMinute: number().int().min(0).max(1439),
|
|
65635
|
-
endMinute: number().int().min(1).max(1440)
|
|
66034
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66035
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66036
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65636
66037
|
});
|
|
65637
66038
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65638
66039
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65708,10 +66109,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65708
66109
|
/** Master "record to the card at all" switch. */
|
|
65709
66110
|
enabled: boolean().nullable(),
|
|
65710
66111
|
overwriteWhenFull: boolean().nullable(),
|
|
65711
|
-
preRecordSec: number().nullable(),
|
|
65712
|
-
postRecordSec: number().nullable(),
|
|
66112
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66113
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65713
66114
|
/** Length of one recorded file, in minutes. */
|
|
65714
|
-
segmentMinutes: number().nullable(),
|
|
66115
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65715
66116
|
/** The primary track's weekly windows, flattened. */
|
|
65716
66117
|
windows: array(RecordWindowSchema),
|
|
65717
66118
|
/**
|
|
@@ -65727,7 +66128,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65727
66128
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65728
66129
|
* writable.
|
|
65729
66130
|
*/
|
|
65730
|
-
unreadableWindows: number(),
|
|
66131
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65731
66132
|
/**
|
|
65732
66133
|
* The camera is scheduled to record and has NO usable storage.
|
|
65733
66134
|
*
|
|
@@ -66572,7 +66973,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66572
66973
|
url: string().optional(),
|
|
66573
66974
|
codec: string().optional(),
|
|
66574
66975
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66575
|
-
fps: number().positive().optional(),
|
|
66976
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66576
66977
|
label: string().optional(),
|
|
66577
66978
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66578
66979
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66659,18 +67060,18 @@ var StreamProfileSchema = _enum([
|
|
|
66659
67060
|
]);
|
|
66660
67061
|
/** The current encoding config of one stream profile. */
|
|
66661
67062
|
var StreamProfileConfigSchema = object({
|
|
66662
|
-
width: number(),
|
|
66663
|
-
height: number(),
|
|
67063
|
+
width: number().meta(readingMeta("none")),
|
|
67064
|
+
height: number().meta(readingMeta("none")),
|
|
66664
67065
|
codec: _enum(["h264", "h265"]),
|
|
66665
|
-
framerate: number(),
|
|
66666
|
-
bitrate: number(),
|
|
67066
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67067
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66667
67068
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66668
67069
|
encoderProfile: _enum([
|
|
66669
67070
|
"high",
|
|
66670
67071
|
"main",
|
|
66671
67072
|
"baseline"
|
|
66672
67073
|
]).optional(),
|
|
66673
|
-
gop: number().optional(),
|
|
67074
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66674
67075
|
/**
|
|
66675
67076
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66676
67077
|
*
|
|
@@ -66891,12 +67292,7 @@ var switchCapability = {
|
|
|
66891
67292
|
label: "On",
|
|
66892
67293
|
kind: "boolean"
|
|
66893
67294
|
}
|
|
66894
|
-
}] }
|
|
66895
|
-
customize: {
|
|
66896
|
-
version: 1,
|
|
66897
|
-
advanced: "derive",
|
|
66898
|
-
targets: []
|
|
66899
|
-
}
|
|
67295
|
+
}] }
|
|
66900
67296
|
};
|
|
66901
67297
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66902
67298
|
function hasControlCharacter(value) {
|
|
@@ -67479,35 +67875,21 @@ var tamperCapability = {
|
|
|
67479
67875
|
* entries with `device_class: temperature` and any future native
|
|
67480
67876
|
* thermometer.
|
|
67481
67877
|
*
|
|
67482
|
-
*
|
|
67483
|
-
*
|
|
67484
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67485
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67486
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67487
|
-
* `sourceInfo`.
|
|
67878
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67879
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67488
67880
|
*
|
|
67489
67881
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67490
67882
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67491
67883
|
* changed" steady state.
|
|
67492
67884
|
*/
|
|
67493
67885
|
var TemperatureSensorStatusSchema = object({
|
|
67494
|
-
/** Current temperature in Celsius. */
|
|
67495
|
-
celsius: number().meta({
|
|
67496
|
-
|
|
67886
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67887
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67888
|
+
precision: 1,
|
|
67497
67889
|
label: "Temperature"
|
|
67498
|
-
}),
|
|
67890
|
+
})),
|
|
67499
67891
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67500
|
-
lastFetchedAt: number()
|
|
67501
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67502
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67503
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67504
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67505
|
-
unit: string().optional(),
|
|
67506
|
-
/** Suggested decimal places for numeric display.
|
|
67507
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67508
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67509
|
-
* auto-formatting when absent. */
|
|
67510
|
-
precision: number().int().min(0).max(10).optional()
|
|
67892
|
+
lastFetchedAt: number()
|
|
67511
67893
|
});
|
|
67512
67894
|
var temperatureSensorCapability = {
|
|
67513
67895
|
name: "temperature-sensor",
|
|
@@ -67538,12 +67920,7 @@ var temperatureSensorCapability = {
|
|
|
67538
67920
|
} } },
|
|
67539
67921
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67540
67922
|
* whether persisting is worth a SQLite commit. */
|
|
67541
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67542
|
-
customize: {
|
|
67543
|
-
version: 1,
|
|
67544
|
-
advanced: "derive",
|
|
67545
|
-
targets: []
|
|
67546
|
-
}
|
|
67923
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67547
67924
|
};
|
|
67548
67925
|
/**
|
|
67549
67926
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67826,16 +68203,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67826
68203
|
]),
|
|
67827
68204
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67828
68205
|
* reading. */
|
|
67829
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68206
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67830
68207
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67831
68208
|
* the vacuum has no speed control. */
|
|
67832
68209
|
fanSpeed: string().nullable(),
|
|
67833
68210
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67834
68211
|
availableFanSpeeds: array(string()),
|
|
67835
68212
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67836
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68213
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67837
68214
|
/** Current error code (0 / null = no error). */
|
|
67838
|
-
errorCode: number().nullable(),
|
|
68215
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67839
68216
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67840
68217
|
errorLabel: string().nullable(),
|
|
67841
68218
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67913,7 +68290,7 @@ var ValveStatusSchema = object({
|
|
|
67913
68290
|
]),
|
|
67914
68291
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67915
68292
|
* intermediate position surface. */
|
|
67916
|
-
position: number().min(0).max(100).nullable(),
|
|
68293
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67917
68294
|
/** Ms epoch when the slice was last updated. */
|
|
67918
68295
|
lastChangedAt: number()
|
|
67919
68296
|
});
|
|
@@ -68021,9 +68398,9 @@ var vibrationCapability = {
|
|
|
68021
68398
|
*/
|
|
68022
68399
|
var WaterHeaterStatusSchema = object({
|
|
68023
68400
|
/** Current measured temperature. Null when not reported. */
|
|
68024
|
-
currentTemp: number().nullable(),
|
|
68401
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68025
68402
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68026
|
-
targetTemp: number().nullable(),
|
|
68403
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68027
68404
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68028
68405
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68029
68406
|
* device reports an unknown state. */
|
|
@@ -68034,9 +68411,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68034
68411
|
* has no away surface. */
|
|
68035
68412
|
away: boolean().nullable(),
|
|
68036
68413
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68037
|
-
minTemp: number().nullable(),
|
|
68414
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68038
68415
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68039
|
-
maxTemp: number().nullable(),
|
|
68416
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68040
68417
|
/** Ms epoch when the slice was last updated. */
|
|
68041
68418
|
lastChangedAt: number()
|
|
68042
68419
|
});
|
|
@@ -68121,25 +68498,18 @@ var waterHeaterCapability = {
|
|
|
68121
68498
|
* Forecast deferred — current conditions only for v1.
|
|
68122
68499
|
*/
|
|
68123
68500
|
var WeatherStatusSchema = object({
|
|
68124
|
-
/** Verbatim
|
|
68125
|
-
* when no condition has been reported yet. */
|
|
68501
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68126
68502
|
condition: string().nullable(),
|
|
68127
|
-
/** Current temperature in
|
|
68128
|
-
temperature: number().nullable(),
|
|
68129
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68130
|
-
temperatureUnit: string().nullable(),
|
|
68503
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68504
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68131
68505
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68132
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68133
|
-
/** Barometric pressure in
|
|
68134
|
-
pressure: number().nullable(),
|
|
68135
|
-
/**
|
|
68136
|
-
|
|
68137
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68138
|
-
windSpeed: number().nullable(),
|
|
68139
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68140
|
-
windSpeedUnit: string().nullable(),
|
|
68506
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68507
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68508
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68509
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68510
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68141
68511
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68142
|
-
windBearing: number().nullable(),
|
|
68512
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68143
68513
|
/** Ms epoch when the slice was last updated. */
|
|
68144
68514
|
lastFetchedAt: number()
|
|
68145
68515
|
});
|
|
@@ -68167,12 +68537,12 @@ var weatherCapability = {
|
|
|
68167
68537
|
*/
|
|
68168
68538
|
durability: "session",
|
|
68169
68539
|
/**
|
|
68170
|
-
* History (D850): recorded series.
|
|
68540
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68171
68541
|
*/
|
|
68172
68542
|
history: { fields: {
|
|
68173
68543
|
temperature: {
|
|
68174
68544
|
kind: "gauge",
|
|
68175
|
-
|
|
68545
|
+
unit: "°C",
|
|
68176
68546
|
deadband: .2
|
|
68177
68547
|
},
|
|
68178
68548
|
humidity: {
|
|
@@ -68182,12 +68552,12 @@ var weatherCapability = {
|
|
|
68182
68552
|
},
|
|
68183
68553
|
pressure: {
|
|
68184
68554
|
kind: "gauge",
|
|
68185
|
-
|
|
68555
|
+
unit: "hPa",
|
|
68186
68556
|
deadband: .5
|
|
68187
68557
|
},
|
|
68188
68558
|
windSpeed: {
|
|
68189
68559
|
kind: "gauge",
|
|
68190
|
-
|
|
68560
|
+
unit: "m/s",
|
|
68191
68561
|
deadband: .5
|
|
68192
68562
|
}
|
|
68193
68563
|
} }
|
|
@@ -69418,6 +69788,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69418
69788
|
featureProbe: featureProbeCapability,
|
|
69419
69789
|
flood: floodCapability,
|
|
69420
69790
|
gas: gasCapability,
|
|
69791
|
+
groupCommands: groupCommandsCapability,
|
|
69792
|
+
groupStatus: groupStatusCapability,
|
|
69421
69793
|
heatingValve: heatingValveCapability,
|
|
69422
69794
|
humidifier: humidifierCapability,
|
|
69423
69795
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70311,6 +70683,13 @@ Object.freeze({
|
|
|
70311
70683
|
access: "view",
|
|
70312
70684
|
role: "admin"
|
|
70313
70685
|
},
|
|
70686
|
+
"addons.getPackageDocs": {
|
|
70687
|
+
capName: "addons",
|
|
70688
|
+
capScope: "system",
|
|
70689
|
+
addonId: null,
|
|
70690
|
+
access: "view",
|
|
70691
|
+
role: "admin"
|
|
70692
|
+
},
|
|
70314
70693
|
"addons.getVersions": {
|
|
70315
70694
|
capName: "addons",
|
|
70316
70695
|
capScope: "system",
|
|
@@ -73419,6 +73798,20 @@ Object.freeze({
|
|
|
73419
73798
|
access: "view",
|
|
73420
73799
|
role: "viewer"
|
|
73421
73800
|
},
|
|
73801
|
+
"groupCommands.getStatus": {
|
|
73802
|
+
capName: "group-commands",
|
|
73803
|
+
capScope: "device",
|
|
73804
|
+
addonId: null,
|
|
73805
|
+
access: "view",
|
|
73806
|
+
role: "viewer"
|
|
73807
|
+
},
|
|
73808
|
+
"groupStatus.getStatus": {
|
|
73809
|
+
capName: "group-status",
|
|
73810
|
+
capScope: "device",
|
|
73811
|
+
addonId: null,
|
|
73812
|
+
access: "view",
|
|
73813
|
+
role: "viewer"
|
|
73814
|
+
},
|
|
73422
73815
|
"heatingValve.getStatus": {
|
|
73423
73816
|
capName: "heating-valve",
|
|
73424
73817
|
capScope: "device",
|
|
@@ -83241,6 +83634,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83241
83634
|
icon: "flame"
|
|
83242
83635
|
}]
|
|
83243
83636
|
},
|
|
83637
|
+
"group-commands": {
|
|
83638
|
+
scope: "device",
|
|
83639
|
+
noun: t("Group command", "Comando di gruppo")
|
|
83640
|
+
},
|
|
83641
|
+
"group-status": {
|
|
83642
|
+
scope: "device",
|
|
83643
|
+
noun: t("Group", "Gruppo"),
|
|
83644
|
+
state: [
|
|
83645
|
+
{
|
|
83646
|
+
kind: "numeric",
|
|
83647
|
+
field: "included",
|
|
83648
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
83649
|
+
label: t("Reporting", "Rispondono"),
|
|
83650
|
+
icon: "users"
|
|
83651
|
+
},
|
|
83652
|
+
{
|
|
83653
|
+
kind: "numeric",
|
|
83654
|
+
field: "excluded",
|
|
83655
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
83656
|
+
label: t("Excluded", "Esclusi"),
|
|
83657
|
+
icon: "users"
|
|
83658
|
+
},
|
|
83659
|
+
{
|
|
83660
|
+
kind: "numeric",
|
|
83661
|
+
field: "total",
|
|
83662
|
+
quantity: t("the member count", "il numero di membri"),
|
|
83663
|
+
label: t("Members", "Membri"),
|
|
83664
|
+
icon: "sigma"
|
|
83665
|
+
}
|
|
83666
|
+
]
|
|
83667
|
+
},
|
|
83244
83668
|
"humidity-sensor": {
|
|
83245
83669
|
scope: "device",
|
|
83246
83670
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83274,7 +83698,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83274
83698
|
field: "value",
|
|
83275
83699
|
quantity: t("the reading", "il valore"),
|
|
83276
83700
|
label: t("Reading", "Valore"),
|
|
83277
|
-
unitField: "unit",
|
|
83278
83701
|
icon: "gauge"
|
|
83279
83702
|
}]
|
|
83280
83703
|
},
|
|
@@ -83410,7 +83833,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83410
83833
|
field: "temperature",
|
|
83411
83834
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83412
83835
|
label: t("Temperature", "Temperatura"),
|
|
83413
|
-
|
|
83836
|
+
unit: "°C",
|
|
83414
83837
|
icon: "thermometer"
|
|
83415
83838
|
},
|
|
83416
83839
|
{
|
|
@@ -83426,7 +83849,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83426
83849
|
field: "windSpeed",
|
|
83427
83850
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83428
83851
|
label: t("Wind", "Vento"),
|
|
83429
|
-
|
|
83852
|
+
unit: "m/s",
|
|
83430
83853
|
icon: "wind"
|
|
83431
83854
|
},
|
|
83432
83855
|
{
|
|
@@ -83434,7 +83857,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83434
83857
|
field: "pressure",
|
|
83435
83858
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83436
83859
|
label: t("Pressure", "Pressione"),
|
|
83437
|
-
|
|
83860
|
+
unit: "hPa",
|
|
83438
83861
|
icon: "gauge"
|
|
83439
83862
|
}
|
|
83440
83863
|
]
|
|
@@ -84707,6 +85130,16 @@ Object.freeze({
|
|
|
84707
85130
|
form: "single",
|
|
84708
85131
|
optional: false
|
|
84709
85132
|
}],
|
|
85133
|
+
"groupCommands.getStatus": [{
|
|
85134
|
+
name: "deviceId",
|
|
85135
|
+
form: "single",
|
|
85136
|
+
optional: false
|
|
85137
|
+
}],
|
|
85138
|
+
"groupStatus.getStatus": [{
|
|
85139
|
+
name: "deviceId",
|
|
85140
|
+
form: "single",
|
|
85141
|
+
optional: false
|
|
85142
|
+
}],
|
|
84710
85143
|
"heatingValve.getStatus": [{
|
|
84711
85144
|
name: "deviceId",
|
|
84712
85145
|
form: "single",
|
|
@@ -86571,6 +87004,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
86571
87004
|
targetId: string().min(1),
|
|
86572
87005
|
enabled: boolean(),
|
|
86573
87006
|
debounceMs: number().nonnegative(),
|
|
87007
|
+
edges: array(_enum([
|
|
87008
|
+
"rising",
|
|
87009
|
+
"button",
|
|
87010
|
+
"native-event"
|
|
87011
|
+
])).min(1).optional(),
|
|
86574
87012
|
sources: array(OverrideSourceSchema).min(1)
|
|
86575
87013
|
});
|
|
86576
87014
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -86686,6 +87124,8 @@ new Map(Object.entries({
|
|
|
86686
87124
|
"detection-blind": "device-events",
|
|
86687
87125
|
"motion-noisy": "device-events",
|
|
86688
87126
|
"motion-calm": "device-events",
|
|
87127
|
+
"package-llm-silent": "device-events",
|
|
87128
|
+
"package-llm-answered": "device-events",
|
|
86689
87129
|
"recording-stalled": "device-events",
|
|
86690
87130
|
"recording-healthy": "device-events",
|
|
86691
87131
|
"recording-degraded": "device-events",
|
|
@@ -86769,6 +87209,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
86769
87209
|
label: "Motion without a subject",
|
|
86770
87210
|
kinds: ["motion-noisy", "motion-calm"]
|
|
86771
87211
|
},
|
|
87212
|
+
{
|
|
87213
|
+
id: "package-llm",
|
|
87214
|
+
family: "device-events",
|
|
87215
|
+
label: "Package confirm",
|
|
87216
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87217
|
+
},
|
|
86772
87218
|
{
|
|
86773
87219
|
id: "recording",
|
|
86774
87220
|
family: "device-events",
|
|
@@ -86950,6 +87396,8 @@ var DEVICE_EVENTS = [
|
|
|
86950
87396
|
"detection-blind",
|
|
86951
87397
|
"motion-noisy",
|
|
86952
87398
|
"motion-calm",
|
|
87399
|
+
"package-llm-silent",
|
|
87400
|
+
"package-llm-answered",
|
|
86953
87401
|
"recording-stalled",
|
|
86954
87402
|
"recording-healthy",
|
|
86955
87403
|
"recording-degraded",
|
|
@@ -87218,6 +87666,15 @@ new Map([
|
|
|
87218
87666
|
snapshotLabel: "Cameras with constant motion now",
|
|
87219
87667
|
snapshotSection: null
|
|
87220
87668
|
},
|
|
87669
|
+
{
|
|
87670
|
+
id: "package-llm-confirm",
|
|
87671
|
+
family: "device-events",
|
|
87672
|
+
label: "Package confirm (not answering / answering again)",
|
|
87673
|
+
bad: ["package-llm-silent"],
|
|
87674
|
+
recovery: ["package-llm-answered"],
|
|
87675
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
87676
|
+
snapshotSection: null
|
|
87677
|
+
},
|
|
87221
87678
|
{
|
|
87222
87679
|
id: "recording-health",
|
|
87223
87680
|
family: "device-events",
|