@camstack/addon-provider-velux 0.2.146 → 0.2.147
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 +18 -0
- package/dist/addon.js +959 -509
- package/dist/addon.mjs +959 -509
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
//#region ../types/dist/event-category-
|
|
2
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
3
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
5
5
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -325,6 +325,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
325
325
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
326
326
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
327
327
|
/**
|
|
328
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
329
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
330
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
331
|
+
*/
|
|
332
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
333
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
334
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
335
|
+
/**
|
|
328
336
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
329
337
|
* (a settings change via `setAgentInferenceDevices` /
|
|
330
338
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5434,7 +5442,7 @@ var ZodIssueCode = {
|
|
|
5434
5442
|
var ZodFirstPartyTypeKind;
|
|
5435
5443
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5436
5444
|
//#endregion
|
|
5437
|
-
//#region ../types/dist/sleep-
|
|
5445
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5438
5446
|
/**
|
|
5439
5447
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5440
5448
|
* window to float samples (D455).
|
|
@@ -7988,6 +7996,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
7988
7996
|
}).strict();
|
|
7989
7997
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
7990
7998
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
7999
|
+
var READING_QUANTITIES = [
|
|
8000
|
+
"temperature",
|
|
8001
|
+
"pressure",
|
|
8002
|
+
"speed",
|
|
8003
|
+
"precipitation",
|
|
8004
|
+
"precipitation-rate",
|
|
8005
|
+
"length",
|
|
8006
|
+
"area",
|
|
8007
|
+
"illuminance",
|
|
8008
|
+
"irradiance",
|
|
8009
|
+
"power",
|
|
8010
|
+
"energy",
|
|
8011
|
+
"voltage",
|
|
8012
|
+
"current",
|
|
8013
|
+
"apparent-power",
|
|
8014
|
+
"humidity",
|
|
8015
|
+
"percentage",
|
|
8016
|
+
"concentration-volume",
|
|
8017
|
+
"concentration-mass",
|
|
8018
|
+
"concentration-ppb",
|
|
8019
|
+
"volume",
|
|
8020
|
+
"duration",
|
|
8021
|
+
"duration-ms",
|
|
8022
|
+
"information",
|
|
8023
|
+
"sound-level",
|
|
8024
|
+
"signal-level",
|
|
8025
|
+
"colour-temperature",
|
|
8026
|
+
"angle",
|
|
8027
|
+
"bitrate",
|
|
8028
|
+
"rate",
|
|
8029
|
+
"mass",
|
|
8030
|
+
"index",
|
|
8031
|
+
"ratio",
|
|
8032
|
+
"count",
|
|
8033
|
+
"none",
|
|
8034
|
+
"device"
|
|
8035
|
+
];
|
|
8036
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8037
|
+
new Set(READING_QUANTITIES);
|
|
8038
|
+
/**
|
|
8039
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8040
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8041
|
+
*/
|
|
8042
|
+
var QUANTITY_BASE = {
|
|
8043
|
+
temperature: "°C",
|
|
8044
|
+
pressure: "hPa",
|
|
8045
|
+
speed: "m/s",
|
|
8046
|
+
precipitation: "mm",
|
|
8047
|
+
"precipitation-rate": "mm/h",
|
|
8048
|
+
length: "m",
|
|
8049
|
+
area: "m²",
|
|
8050
|
+
illuminance: "lx",
|
|
8051
|
+
irradiance: "W/m²",
|
|
8052
|
+
power: "W",
|
|
8053
|
+
energy: "kWh",
|
|
8054
|
+
voltage: "V",
|
|
8055
|
+
current: "A",
|
|
8056
|
+
"apparent-power": "VA",
|
|
8057
|
+
humidity: "%",
|
|
8058
|
+
percentage: "%",
|
|
8059
|
+
"concentration-volume": "ppm",
|
|
8060
|
+
"concentration-mass": "µg/m³",
|
|
8061
|
+
"concentration-ppb": "ppb",
|
|
8062
|
+
volume: "L",
|
|
8063
|
+
duration: "s",
|
|
8064
|
+
"duration-ms": "ms",
|
|
8065
|
+
information: "B",
|
|
8066
|
+
"sound-level": "dBFS",
|
|
8067
|
+
"signal-level": "dBm",
|
|
8068
|
+
"colour-temperature": "mired",
|
|
8069
|
+
angle: "°",
|
|
8070
|
+
bitrate: "kbps",
|
|
8071
|
+
rate: "fps",
|
|
8072
|
+
mass: "kg",
|
|
8073
|
+
index: "none",
|
|
8074
|
+
ratio: "none",
|
|
8075
|
+
count: "none",
|
|
8076
|
+
none: "none",
|
|
8077
|
+
device: "device"
|
|
8078
|
+
};
|
|
8079
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8080
|
+
function baseUnitOf(quantity) {
|
|
8081
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8082
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8083
|
+
return symbol;
|
|
8084
|
+
}
|
|
8085
|
+
function readingMeta(quantity, extras) {
|
|
8086
|
+
return {
|
|
8087
|
+
quantity,
|
|
8088
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8089
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8090
|
+
};
|
|
8091
|
+
}
|
|
7991
8092
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
7992
8093
|
var CamProfileSchema = _enum([
|
|
7993
8094
|
"high",
|
|
@@ -8015,8 +8116,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8015
8116
|
"derived"
|
|
8016
8117
|
]);
|
|
8017
8118
|
var CamStreamResolutionSchema = object({
|
|
8018
|
-
width: number().int().positive(),
|
|
8019
|
-
height: number().int().positive()
|
|
8119
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8120
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8020
8121
|
});
|
|
8021
8122
|
var CameraStreamSchema = object({
|
|
8022
8123
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8534,6 +8635,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8534
8635
|
"filesystem-browse",
|
|
8535
8636
|
"flood",
|
|
8536
8637
|
"gas",
|
|
8638
|
+
"group-commands",
|
|
8639
|
+
"group-status",
|
|
8537
8640
|
"heating-valve",
|
|
8538
8641
|
"humidifier",
|
|
8539
8642
|
"humidity-sensor",
|
|
@@ -8663,14 +8766,6 @@ Object.freeze({
|
|
|
8663
8766
|
{
|
|
8664
8767
|
"path": "aqi",
|
|
8665
8768
|
"valueType": "number"
|
|
8666
|
-
},
|
|
8667
|
-
{
|
|
8668
|
-
"path": "unit",
|
|
8669
|
-
"valueType": "string"
|
|
8670
|
-
},
|
|
8671
|
-
{
|
|
8672
|
-
"path": "precision",
|
|
8673
|
-
"valueType": "number"
|
|
8674
8769
|
}
|
|
8675
8770
|
],
|
|
8676
8771
|
"alarm-panel": [
|
|
@@ -8706,20 +8801,10 @@ Object.freeze({
|
|
|
8706
8801
|
"valueType": "boolean"
|
|
8707
8802
|
}
|
|
8708
8803
|
],
|
|
8709
|
-
"ambient-light-sensor": [
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
},
|
|
8714
|
-
{
|
|
8715
|
-
"path": "unit",
|
|
8716
|
-
"valueType": "string"
|
|
8717
|
-
},
|
|
8718
|
-
{
|
|
8719
|
-
"path": "precision",
|
|
8720
|
-
"valueType": "number"
|
|
8721
|
-
}
|
|
8722
|
-
],
|
|
8804
|
+
"ambient-light-sensor": [{
|
|
8805
|
+
"path": "lux",
|
|
8806
|
+
"valueType": "number"
|
|
8807
|
+
}],
|
|
8723
8808
|
"audio-metrics": [
|
|
8724
8809
|
{
|
|
8725
8810
|
"path": "ts",
|
|
@@ -8799,6 +8884,10 @@ Object.freeze({
|
|
|
8799
8884
|
"path": "lastUpdated",
|
|
8800
8885
|
"valueType": "number"
|
|
8801
8886
|
},
|
|
8887
|
+
{
|
|
8888
|
+
"path": "volts",
|
|
8889
|
+
"valueType": "number"
|
|
8890
|
+
},
|
|
8802
8891
|
{
|
|
8803
8892
|
"path": "lastContactAt",
|
|
8804
8893
|
"valueType": "number"
|
|
@@ -9041,10 +9130,6 @@ Object.freeze({
|
|
|
9041
9130
|
"datetime"
|
|
9042
9131
|
]
|
|
9043
9132
|
},
|
|
9044
|
-
{
|
|
9045
|
-
"path": "unit",
|
|
9046
|
-
"valueType": "string"
|
|
9047
|
-
},
|
|
9048
9133
|
{
|
|
9049
9134
|
"path": "min",
|
|
9050
9135
|
"valueType": "number"
|
|
@@ -9056,19 +9141,6 @@ Object.freeze({
|
|
|
9056
9141
|
{
|
|
9057
9142
|
"path": "step",
|
|
9058
9143
|
"valueType": "number"
|
|
9059
|
-
},
|
|
9060
|
-
{
|
|
9061
|
-
"path": "precision",
|
|
9062
|
-
"valueType": "number"
|
|
9063
|
-
},
|
|
9064
|
-
{
|
|
9065
|
-
"path": "format",
|
|
9066
|
-
"valueType": "enum",
|
|
9067
|
-
"enumValues": [
|
|
9068
|
-
"date",
|
|
9069
|
-
"time",
|
|
9070
|
-
"datetime"
|
|
9071
|
-
]
|
|
9072
9144
|
}
|
|
9073
9145
|
],
|
|
9074
9146
|
"cover": [
|
|
@@ -9309,13 +9381,8 @@ Object.freeze({
|
|
|
9309
9381
|
"path": "value",
|
|
9310
9382
|
"valueType": "string"
|
|
9311
9383
|
}, {
|
|
9312
|
-
"path": "
|
|
9313
|
-
"valueType": "
|
|
9314
|
-
"enumValues": [
|
|
9315
|
-
"date",
|
|
9316
|
-
"time",
|
|
9317
|
-
"datetime"
|
|
9318
|
-
]
|
|
9384
|
+
"path": "timestamp",
|
|
9385
|
+
"valueType": "boolean"
|
|
9319
9386
|
}],
|
|
9320
9387
|
"event-emitter": [
|
|
9321
9388
|
{
|
|
@@ -9388,6 +9455,20 @@ Object.freeze({
|
|
|
9388
9455
|
"path": "detected",
|
|
9389
9456
|
"valueType": "boolean"
|
|
9390
9457
|
}],
|
|
9458
|
+
"group-status": [
|
|
9459
|
+
{
|
|
9460
|
+
"path": "included",
|
|
9461
|
+
"valueType": "number"
|
|
9462
|
+
},
|
|
9463
|
+
{
|
|
9464
|
+
"path": "excluded",
|
|
9465
|
+
"valueType": "number"
|
|
9466
|
+
},
|
|
9467
|
+
{
|
|
9468
|
+
"path": "total",
|
|
9469
|
+
"valueType": "number"
|
|
9470
|
+
}
|
|
9471
|
+
],
|
|
9391
9472
|
"heating-valve": [{
|
|
9392
9473
|
"path": "position",
|
|
9393
9474
|
"valueType": "number"
|
|
@@ -9422,20 +9503,10 @@ Object.freeze({
|
|
|
9422
9503
|
"valueType": "number"
|
|
9423
9504
|
}
|
|
9424
9505
|
],
|
|
9425
|
-
"humidity-sensor": [
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
},
|
|
9430
|
-
{
|
|
9431
|
-
"path": "unit",
|
|
9432
|
-
"valueType": "string"
|
|
9433
|
-
},
|
|
9434
|
-
{
|
|
9435
|
-
"path": "precision",
|
|
9436
|
-
"valueType": "number"
|
|
9437
|
-
}
|
|
9438
|
-
],
|
|
9506
|
+
"humidity-sensor": [{
|
|
9507
|
+
"path": "percent",
|
|
9508
|
+
"valueType": "number"
|
|
9509
|
+
}],
|
|
9439
9510
|
"image": [{
|
|
9440
9511
|
"path": "url",
|
|
9441
9512
|
"valueType": "string"
|
|
@@ -9774,20 +9845,10 @@ Object.freeze({
|
|
|
9774
9845
|
"valueType": "boolean"
|
|
9775
9846
|
}
|
|
9776
9847
|
],
|
|
9777
|
-
"numeric-sensor": [
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
},
|
|
9782
|
-
{
|
|
9783
|
-
"path": "unit",
|
|
9784
|
-
"valueType": "string"
|
|
9785
|
-
},
|
|
9786
|
-
{
|
|
9787
|
-
"path": "precision",
|
|
9788
|
-
"valueType": "number"
|
|
9789
|
-
}
|
|
9790
|
-
],
|
|
9848
|
+
"numeric-sensor": [{
|
|
9849
|
+
"path": "value",
|
|
9850
|
+
"valueType": "number"
|
|
9851
|
+
}],
|
|
9791
9852
|
"pet-feeder": [
|
|
9792
9853
|
{
|
|
9793
9854
|
"path": "foodLevel",
|
|
@@ -9879,14 +9940,6 @@ Object.freeze({
|
|
|
9879
9940
|
{
|
|
9880
9941
|
"path": "powerFactor",
|
|
9881
9942
|
"valueType": "number"
|
|
9882
|
-
},
|
|
9883
|
-
{
|
|
9884
|
-
"path": "unit",
|
|
9885
|
-
"valueType": "string"
|
|
9886
|
-
},
|
|
9887
|
-
{
|
|
9888
|
-
"path": "precision",
|
|
9889
|
-
"valueType": "number"
|
|
9890
9943
|
}
|
|
9891
9944
|
],
|
|
9892
9945
|
"presence": [
|
|
@@ -9915,20 +9968,10 @@ Object.freeze({
|
|
|
9915
9968
|
"valueType": "number"
|
|
9916
9969
|
}
|
|
9917
9970
|
],
|
|
9918
|
-
"pressure-sensor": [
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
|
|
9922
|
-
},
|
|
9923
|
-
{
|
|
9924
|
-
"path": "unit",
|
|
9925
|
-
"valueType": "string"
|
|
9926
|
-
},
|
|
9927
|
-
{
|
|
9928
|
-
"path": "precision",
|
|
9929
|
-
"valueType": "number"
|
|
9930
|
-
}
|
|
9931
|
-
],
|
|
9971
|
+
"pressure-sensor": [{
|
|
9972
|
+
"path": "hpa",
|
|
9973
|
+
"valueType": "number"
|
|
9974
|
+
}],
|
|
9932
9975
|
"privacy-mask": [{
|
|
9933
9976
|
"path": "enabled",
|
|
9934
9977
|
"valueType": "boolean"
|
|
@@ -10239,20 +10282,10 @@ Object.freeze({
|
|
|
10239
10282
|
"path": "tampered",
|
|
10240
10283
|
"valueType": "boolean"
|
|
10241
10284
|
}],
|
|
10242
|
-
"temperature-sensor": [
|
|
10243
|
-
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
},
|
|
10247
|
-
{
|
|
10248
|
-
"path": "unit",
|
|
10249
|
-
"valueType": "string"
|
|
10250
|
-
},
|
|
10251
|
-
{
|
|
10252
|
-
"path": "precision",
|
|
10253
|
-
"valueType": "number"
|
|
10254
|
-
}
|
|
10255
|
-
],
|
|
10285
|
+
"temperature-sensor": [{
|
|
10286
|
+
"path": "celsius",
|
|
10287
|
+
"valueType": "number"
|
|
10288
|
+
}],
|
|
10256
10289
|
"update": [
|
|
10257
10290
|
{
|
|
10258
10291
|
"path": "currentVersion",
|
|
@@ -10363,10 +10396,6 @@ Object.freeze({
|
|
|
10363
10396
|
"path": "temperature",
|
|
10364
10397
|
"valueType": "number"
|
|
10365
10398
|
},
|
|
10366
|
-
{
|
|
10367
|
-
"path": "temperatureUnit",
|
|
10368
|
-
"valueType": "string"
|
|
10369
|
-
},
|
|
10370
10399
|
{
|
|
10371
10400
|
"path": "humidity",
|
|
10372
10401
|
"valueType": "number"
|
|
@@ -10375,18 +10404,10 @@ Object.freeze({
|
|
|
10375
10404
|
"path": "pressure",
|
|
10376
10405
|
"valueType": "number"
|
|
10377
10406
|
},
|
|
10378
|
-
{
|
|
10379
|
-
"path": "pressureUnit",
|
|
10380
|
-
"valueType": "string"
|
|
10381
|
-
},
|
|
10382
10407
|
{
|
|
10383
10408
|
"path": "windSpeed",
|
|
10384
10409
|
"valueType": "number"
|
|
10385
10410
|
},
|
|
10386
|
-
{
|
|
10387
|
-
"path": "windSpeedUnit",
|
|
10388
|
-
"valueType": "string"
|
|
10389
|
-
},
|
|
10390
10411
|
{
|
|
10391
10412
|
"path": "windBearing",
|
|
10392
10413
|
"valueType": "number"
|
|
@@ -10803,7 +10824,7 @@ function errMsg(err) {
|
|
|
10803
10824
|
return String(err);
|
|
10804
10825
|
}
|
|
10805
10826
|
//#endregion
|
|
10806
|
-
//#region ../types/dist/composition-
|
|
10827
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10807
10828
|
/**
|
|
10808
10829
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10809
10830
|
*
|
|
@@ -11558,15 +11579,74 @@ function validateExpressionSource(src) {
|
|
|
11558
11579
|
}
|
|
11559
11580
|
return null;
|
|
11560
11581
|
}
|
|
11561
|
-
/**
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11582
|
+
/**
|
|
11583
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11584
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11585
|
+
* `composition.ts` (D659).
|
|
11586
|
+
*/
|
|
11565
11587
|
var CompositionSourceRefSchema = object({
|
|
11566
11588
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11567
11589
|
addonId: string().min(1),
|
|
11568
11590
|
stableId: string().min(1)
|
|
11569
11591
|
});
|
|
11592
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11593
|
+
"temperature",
|
|
11594
|
+
"humidity",
|
|
11595
|
+
"pressure",
|
|
11596
|
+
"illuminance",
|
|
11597
|
+
"power",
|
|
11598
|
+
"energy",
|
|
11599
|
+
"battery",
|
|
11600
|
+
"numeric",
|
|
11601
|
+
"motion",
|
|
11602
|
+
"contact",
|
|
11603
|
+
"leak",
|
|
11604
|
+
"smoke",
|
|
11605
|
+
"occupancy",
|
|
11606
|
+
"binary",
|
|
11607
|
+
"switch",
|
|
11608
|
+
"light"
|
|
11609
|
+
];
|
|
11610
|
+
var NUMERIC_AGGREGATES = [
|
|
11611
|
+
"mean",
|
|
11612
|
+
"median",
|
|
11613
|
+
"min",
|
|
11614
|
+
"max",
|
|
11615
|
+
"sum"
|
|
11616
|
+
];
|
|
11617
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11618
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11619
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11620
|
+
var AGGREGATE_REDUCERS = [
|
|
11621
|
+
"mean",
|
|
11622
|
+
"median",
|
|
11623
|
+
"min",
|
|
11624
|
+
"max",
|
|
11625
|
+
"sum",
|
|
11626
|
+
"any",
|
|
11627
|
+
"all"
|
|
11628
|
+
];
|
|
11629
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11630
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11631
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11632
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11633
|
+
var HelperMemberSchema = object({
|
|
11634
|
+
source: CompositionSourceRefSchema,
|
|
11635
|
+
cap: string().min(1),
|
|
11636
|
+
fieldPath: string().min(1)
|
|
11637
|
+
});
|
|
11638
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11639
|
+
kind: literal("group"),
|
|
11640
|
+
templateId: GroupTemplateIdSchema,
|
|
11641
|
+
aggregate: AggregateReducerSchema,
|
|
11642
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11643
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11644
|
+
active: ActiveCriterionSchema.optional()
|
|
11645
|
+
})]);
|
|
11646
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11647
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11648
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11649
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11570
11650
|
/** One field of one capability of one source device. */
|
|
11571
11651
|
var CompositionFieldReadSchema = object({
|
|
11572
11652
|
source: CompositionSourceRefSchema,
|
|
@@ -11610,7 +11690,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11610
11690
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11611
11691
|
CompositionFromSourceSchema,
|
|
11612
11692
|
CompositionExpressionSourceSchema,
|
|
11613
|
-
CompositionCodeSourceSchema
|
|
11693
|
+
CompositionCodeSourceSchema,
|
|
11694
|
+
object({
|
|
11695
|
+
kind: literal("aggregate"),
|
|
11696
|
+
reducer: _enum([
|
|
11697
|
+
"mean",
|
|
11698
|
+
"median",
|
|
11699
|
+
"min",
|
|
11700
|
+
"max",
|
|
11701
|
+
"sum",
|
|
11702
|
+
"any",
|
|
11703
|
+
"all"
|
|
11704
|
+
]),
|
|
11705
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11706
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11707
|
+
publish: _enum([
|
|
11708
|
+
"value",
|
|
11709
|
+
"included",
|
|
11710
|
+
"excluded",
|
|
11711
|
+
"total"
|
|
11712
|
+
]),
|
|
11713
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11714
|
+
empty: _enum([
|
|
11715
|
+
"null",
|
|
11716
|
+
"omit",
|
|
11717
|
+
"offline"
|
|
11718
|
+
])
|
|
11719
|
+
})
|
|
11614
11720
|
]);
|
|
11615
11721
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11616
11722
|
kind: literal("forward"),
|
|
@@ -11656,7 +11762,13 @@ var CompositionSchema = object({
|
|
|
11656
11762
|
kind: literal("existing"),
|
|
11657
11763
|
device: CompositionSourceRefSchema
|
|
11658
11764
|
})]),
|
|
11659
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11765
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11766
|
+
/**
|
|
11767
|
+
* Present when the block is a helper template. Absent on a free
|
|
11768
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11769
|
+
* never the compiled features.
|
|
11770
|
+
*/
|
|
11771
|
+
helper: HelperSpecSchema.optional()
|
|
11660
11772
|
}).superRefine((composition, ctx) => {
|
|
11661
11773
|
const seen = /* @__PURE__ */ new Set();
|
|
11662
11774
|
composition.features.forEach((feature, index) => {
|
|
@@ -17864,7 +17976,11 @@ var CompositionProblemSchema = object({
|
|
|
17864
17976
|
"item-field-reserved",
|
|
17865
17977
|
"target-missing",
|
|
17866
17978
|
"target-unreadable",
|
|
17867
|
-
"not-replaceable"
|
|
17979
|
+
"not-replaceable",
|
|
17980
|
+
"native-capability-replace",
|
|
17981
|
+
"mixed-quantity",
|
|
17982
|
+
"helper-mismatch",
|
|
17983
|
+
"member-constraint"
|
|
17868
17984
|
]),
|
|
17869
17985
|
path: string(),
|
|
17870
17986
|
message: string()
|
|
@@ -17885,7 +18001,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17885
18001
|
"null",
|
|
17886
18002
|
"offline",
|
|
17887
18003
|
"unknown",
|
|
17888
|
-
"release"
|
|
18004
|
+
"release",
|
|
18005
|
+
"omit"
|
|
17889
18006
|
]);
|
|
17890
18007
|
/**
|
|
17891
18008
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -17922,9 +18039,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17922
18039
|
reads: array(CompositionFieldReadSchema)
|
|
17923
18040
|
});
|
|
17924
18041
|
/**
|
|
17925
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17926
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17927
|
-
*
|
|
18042
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18043
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18044
|
+
* Replacing a capability the device already serves is refused
|
|
18045
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18046
|
+
* wire for a claim the hub already holds.
|
|
17928
18047
|
*/
|
|
17929
18048
|
var CompositionFeatureModeSchema = _enum([
|
|
17930
18049
|
"new",
|
|
@@ -18097,6 +18216,275 @@ Object.freeze({
|
|
|
18097
18216
|
result: ["number", "null"]
|
|
18098
18217
|
}
|
|
18099
18218
|
});
|
|
18219
|
+
/**
|
|
18220
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18221
|
+
* Data, not a form default written into the block.
|
|
18222
|
+
*/
|
|
18223
|
+
var NOW = {
|
|
18224
|
+
fieldPath: "lastFetchedAt",
|
|
18225
|
+
expr: "now"
|
|
18226
|
+
};
|
|
18227
|
+
var CHANGED = {
|
|
18228
|
+
fieldPath: "lastChangedAt",
|
|
18229
|
+
expr: "now"
|
|
18230
|
+
};
|
|
18231
|
+
function numeric(input) {
|
|
18232
|
+
return {
|
|
18233
|
+
...input,
|
|
18234
|
+
family: "numeric",
|
|
18235
|
+
deviceType: DeviceType.Sensor,
|
|
18236
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18237
|
+
commandCaps: [],
|
|
18238
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18239
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18240
|
+
accept: [{
|
|
18241
|
+
cap: input.outputCap,
|
|
18242
|
+
fieldPath: input.outputField
|
|
18243
|
+
}]
|
|
18244
|
+
};
|
|
18245
|
+
}
|
|
18246
|
+
function binary(input) {
|
|
18247
|
+
return {
|
|
18248
|
+
...input,
|
|
18249
|
+
family: "binary",
|
|
18250
|
+
deviceType: DeviceType.Sensor,
|
|
18251
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18252
|
+
commandCaps: [],
|
|
18253
|
+
quantity: "none",
|
|
18254
|
+
baseUnit: void 0,
|
|
18255
|
+
aggregates: BINARY_AGGREGATES,
|
|
18256
|
+
empty: "offline"
|
|
18257
|
+
};
|
|
18258
|
+
}
|
|
18259
|
+
var GROUP_TEMPLATES = [
|
|
18260
|
+
numeric({
|
|
18261
|
+
id: "temperature",
|
|
18262
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18263
|
+
role: DeviceRole.TemperatureSensor,
|
|
18264
|
+
outputCap: "temperature-sensor",
|
|
18265
|
+
outputField: "celsius",
|
|
18266
|
+
quantity: "temperature",
|
|
18267
|
+
defaultAggregate: "mean",
|
|
18268
|
+
empty: "null",
|
|
18269
|
+
companions: [NOW]
|
|
18270
|
+
}),
|
|
18271
|
+
numeric({
|
|
18272
|
+
id: "humidity",
|
|
18273
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18274
|
+
role: DeviceRole.HumiditySensor,
|
|
18275
|
+
outputCap: "humidity-sensor",
|
|
18276
|
+
outputField: "percent",
|
|
18277
|
+
quantity: "humidity",
|
|
18278
|
+
defaultAggregate: "mean",
|
|
18279
|
+
empty: "null",
|
|
18280
|
+
companions: [NOW]
|
|
18281
|
+
}),
|
|
18282
|
+
numeric({
|
|
18283
|
+
id: "pressure",
|
|
18284
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18285
|
+
role: DeviceRole.PressureSensor,
|
|
18286
|
+
outputCap: "pressure-sensor",
|
|
18287
|
+
outputField: "hpa",
|
|
18288
|
+
quantity: "pressure",
|
|
18289
|
+
defaultAggregate: "mean",
|
|
18290
|
+
empty: "null",
|
|
18291
|
+
companions: [NOW]
|
|
18292
|
+
}),
|
|
18293
|
+
numeric({
|
|
18294
|
+
id: "illuminance",
|
|
18295
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18296
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18297
|
+
outputCap: "ambient-light-sensor",
|
|
18298
|
+
outputField: "lux",
|
|
18299
|
+
quantity: "illuminance",
|
|
18300
|
+
defaultAggregate: "mean",
|
|
18301
|
+
empty: "null",
|
|
18302
|
+
companions: [NOW]
|
|
18303
|
+
}),
|
|
18304
|
+
numeric({
|
|
18305
|
+
id: "power",
|
|
18306
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18307
|
+
role: DeviceRole.PowerSensor,
|
|
18308
|
+
outputCap: "power-meter",
|
|
18309
|
+
outputField: "watts",
|
|
18310
|
+
quantity: "power",
|
|
18311
|
+
defaultAggregate: "sum",
|
|
18312
|
+
empty: "omit",
|
|
18313
|
+
companions: [NOW]
|
|
18314
|
+
}),
|
|
18315
|
+
numeric({
|
|
18316
|
+
id: "energy",
|
|
18317
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18318
|
+
role: DeviceRole.EnergySensor,
|
|
18319
|
+
outputCap: "power-meter",
|
|
18320
|
+
outputField: "kwhTotal",
|
|
18321
|
+
quantity: "energy",
|
|
18322
|
+
defaultAggregate: "sum",
|
|
18323
|
+
empty: "omit",
|
|
18324
|
+
companions: [NOW]
|
|
18325
|
+
}),
|
|
18326
|
+
numeric({
|
|
18327
|
+
id: "battery",
|
|
18328
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18329
|
+
role: DeviceRole.BatterySensor,
|
|
18330
|
+
outputCap: "battery",
|
|
18331
|
+
outputField: "percentage",
|
|
18332
|
+
quantity: "percentage",
|
|
18333
|
+
defaultAggregate: "mean",
|
|
18334
|
+
empty: "null",
|
|
18335
|
+
companions: [
|
|
18336
|
+
{
|
|
18337
|
+
fieldPath: "charging",
|
|
18338
|
+
expr: "\"unknown\""
|
|
18339
|
+
},
|
|
18340
|
+
{
|
|
18341
|
+
fieldPath: "sleeping",
|
|
18342
|
+
expr: "false"
|
|
18343
|
+
},
|
|
18344
|
+
{
|
|
18345
|
+
fieldPath: "lastUpdated",
|
|
18346
|
+
expr: "now"
|
|
18347
|
+
}
|
|
18348
|
+
]
|
|
18349
|
+
}),
|
|
18350
|
+
numeric({
|
|
18351
|
+
id: "numeric",
|
|
18352
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18353
|
+
role: DeviceRole.NumericSensor,
|
|
18354
|
+
outputCap: "numeric-sensor",
|
|
18355
|
+
outputField: "value",
|
|
18356
|
+
quantity: "device",
|
|
18357
|
+
defaultAggregate: "mean",
|
|
18358
|
+
empty: "null",
|
|
18359
|
+
companions: [NOW]
|
|
18360
|
+
}),
|
|
18361
|
+
binary({
|
|
18362
|
+
id: "motion",
|
|
18363
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18364
|
+
role: DeviceRole.MotionSensor,
|
|
18365
|
+
outputCap: "motion",
|
|
18366
|
+
outputField: "detected",
|
|
18367
|
+
defaultAggregate: "any",
|
|
18368
|
+
accept: [{
|
|
18369
|
+
cap: "motion",
|
|
18370
|
+
fieldPath: "detected"
|
|
18371
|
+
}],
|
|
18372
|
+
companions: [{
|
|
18373
|
+
fieldPath: "lastDetectedAt",
|
|
18374
|
+
expr: "null"
|
|
18375
|
+
}, {
|
|
18376
|
+
fieldPath: "autoClearAfterMs",
|
|
18377
|
+
expr: "null"
|
|
18378
|
+
}]
|
|
18379
|
+
}),
|
|
18380
|
+
binary({
|
|
18381
|
+
id: "contact",
|
|
18382
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18383
|
+
role: DeviceRole.ContactSensor,
|
|
18384
|
+
outputCap: "contact",
|
|
18385
|
+
outputField: "entryOpen",
|
|
18386
|
+
defaultAggregate: "any",
|
|
18387
|
+
accept: [{
|
|
18388
|
+
cap: "contact",
|
|
18389
|
+
fieldPath: "entryOpen"
|
|
18390
|
+
}],
|
|
18391
|
+
companions: [CHANGED]
|
|
18392
|
+
}),
|
|
18393
|
+
binary({
|
|
18394
|
+
id: "leak",
|
|
18395
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18396
|
+
role: DeviceRole.LeakSensor,
|
|
18397
|
+
outputCap: "flood",
|
|
18398
|
+
outputField: "flooded",
|
|
18399
|
+
defaultAggregate: "any",
|
|
18400
|
+
accept: [{
|
|
18401
|
+
cap: "flood",
|
|
18402
|
+
fieldPath: "flooded"
|
|
18403
|
+
}],
|
|
18404
|
+
companions: [CHANGED]
|
|
18405
|
+
}),
|
|
18406
|
+
binary({
|
|
18407
|
+
id: "smoke",
|
|
18408
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18409
|
+
role: DeviceRole.SmokeSensor,
|
|
18410
|
+
outputCap: "smoke",
|
|
18411
|
+
outputField: "detected",
|
|
18412
|
+
defaultAggregate: "any",
|
|
18413
|
+
accept: [{
|
|
18414
|
+
cap: "smoke",
|
|
18415
|
+
fieldPath: "detected"
|
|
18416
|
+
}],
|
|
18417
|
+
companions: [CHANGED]
|
|
18418
|
+
}),
|
|
18419
|
+
binary({
|
|
18420
|
+
id: "occupancy",
|
|
18421
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18422
|
+
role: DeviceRole.BinarySensor,
|
|
18423
|
+
outputCap: "binary",
|
|
18424
|
+
outputField: "on",
|
|
18425
|
+
defaultAggregate: "any",
|
|
18426
|
+
accept: [{
|
|
18427
|
+
cap: "motion",
|
|
18428
|
+
fieldPath: "detected"
|
|
18429
|
+
}, {
|
|
18430
|
+
cap: "binary",
|
|
18431
|
+
fieldPath: "on"
|
|
18432
|
+
}],
|
|
18433
|
+
companions: [CHANGED]
|
|
18434
|
+
}),
|
|
18435
|
+
binary({
|
|
18436
|
+
id: "binary",
|
|
18437
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18438
|
+
role: DeviceRole.BinarySensor,
|
|
18439
|
+
outputCap: "binary",
|
|
18440
|
+
outputField: "on",
|
|
18441
|
+
defaultAggregate: "any",
|
|
18442
|
+
accept: [{
|
|
18443
|
+
cap: "binary",
|
|
18444
|
+
fieldPath: "on"
|
|
18445
|
+
}],
|
|
18446
|
+
companions: [CHANGED]
|
|
18447
|
+
}),
|
|
18448
|
+
actuator({
|
|
18449
|
+
id: "switch",
|
|
18450
|
+
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.",
|
|
18451
|
+
deviceType: DeviceType.Switch,
|
|
18452
|
+
outputCap: "switch",
|
|
18453
|
+
commandCaps: ["switch"]
|
|
18454
|
+
}),
|
|
18455
|
+
actuator({
|
|
18456
|
+
id: "light",
|
|
18457
|
+
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.",
|
|
18458
|
+
deviceType: DeviceType.Light,
|
|
18459
|
+
outputCap: "switch",
|
|
18460
|
+
commandCaps: [
|
|
18461
|
+
"switch",
|
|
18462
|
+
"brightness",
|
|
18463
|
+
"color"
|
|
18464
|
+
]
|
|
18465
|
+
})
|
|
18466
|
+
];
|
|
18467
|
+
function actuator(input) {
|
|
18468
|
+
return {
|
|
18469
|
+
...input,
|
|
18470
|
+
family: "actuator",
|
|
18471
|
+
role: void 0,
|
|
18472
|
+
memberDeviceType: input.deviceType,
|
|
18473
|
+
outputField: "on",
|
|
18474
|
+
quantity: "none",
|
|
18475
|
+
baseUnit: void 0,
|
|
18476
|
+
aggregates: BINARY_AGGREGATES,
|
|
18477
|
+
defaultAggregate: "any",
|
|
18478
|
+
empty: "offline",
|
|
18479
|
+
accept: [{
|
|
18480
|
+
cap: "switch",
|
|
18481
|
+
fieldPath: "on"
|
|
18482
|
+
}],
|
|
18483
|
+
companions: [CHANGED]
|
|
18484
|
+
};
|
|
18485
|
+
}
|
|
18486
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18487
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18100
18488
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18101
18489
|
/**
|
|
18102
18490
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19923,12 +20311,12 @@ function buildDeviceAdminUrl(parts) {
|
|
|
19923
20311
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19924
20312
|
* in-place so dispatch keeps working.
|
|
19925
20313
|
*
|
|
19926
|
-
* **
|
|
19927
|
-
*
|
|
19928
|
-
*
|
|
19929
|
-
*
|
|
19930
|
-
* (`ha-domain-mapping`)
|
|
19931
|
-
* stored after that point.
|
|
20314
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20315
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20316
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20317
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20318
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20319
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19932
20320
|
*
|
|
19933
20321
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19934
20322
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19942,6 +20330,14 @@ var SourceInfoSchema = object({
|
|
|
19942
20330
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19943
20331
|
* Used to detect rename when `id` changes. */
|
|
19944
20332
|
uniqueId: string().optional(),
|
|
20333
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20334
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20335
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20336
|
+
dateTimeShape: _enum([
|
|
20337
|
+
"date",
|
|
20338
|
+
"time",
|
|
20339
|
+
"datetime"
|
|
20340
|
+
]).optional(),
|
|
19945
20341
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19946
20342
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19947
20343
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41046,7 +41442,8 @@ method(object({
|
|
|
41046
41442
|
"enum"
|
|
41047
41443
|
]),
|
|
41048
41444
|
enumValues: array(string()).optional(),
|
|
41049
|
-
item: boolean().optional()
|
|
41445
|
+
item: boolean().optional(),
|
|
41446
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41050
41447
|
})).readonly(),
|
|
41051
41448
|
itemArray: object({
|
|
41052
41449
|
path: string(),
|
|
@@ -44890,8 +45287,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44890
45287
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44891
45288
|
var MaskGridShapeSchema = object({
|
|
44892
45289
|
kind: literal("grid"),
|
|
44893
|
-
gridWidth: number(),
|
|
44894
|
-
gridHeight: number(),
|
|
45290
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45291
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44895
45292
|
cells: array(boolean())
|
|
44896
45293
|
});
|
|
44897
45294
|
discriminatedUnion("kind", [
|
|
@@ -45003,6 +45400,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45003
45400
|
"detection-blind",
|
|
45004
45401
|
"motion-noisy",
|
|
45005
45402
|
"motion-calm",
|
|
45403
|
+
"package-llm-silent",
|
|
45404
|
+
"package-llm-answered",
|
|
45006
45405
|
"recording-stalled",
|
|
45007
45406
|
"recording-healthy",
|
|
45008
45407
|
"recording-degraded",
|
|
@@ -56094,6 +56493,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56094
56493
|
deprecated: string().optional(),
|
|
56095
56494
|
distTags: array(string()).readonly()
|
|
56096
56495
|
});
|
|
56496
|
+
/**
|
|
56497
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56498
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56499
|
+
* tarball failure — never an empty string standing in for either.
|
|
56500
|
+
*/
|
|
56501
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56502
|
+
object({
|
|
56503
|
+
status: literal("ok"),
|
|
56504
|
+
markdown: string()
|
|
56505
|
+
}),
|
|
56506
|
+
object({ status: literal("missing") }),
|
|
56507
|
+
object({
|
|
56508
|
+
status: literal("error"),
|
|
56509
|
+
message: string()
|
|
56510
|
+
})
|
|
56511
|
+
]);
|
|
56512
|
+
var PackageDocsSchema = object({
|
|
56513
|
+
name: string(),
|
|
56514
|
+
version: string(),
|
|
56515
|
+
readme: PackageDocBodySchema,
|
|
56516
|
+
changelog: PackageDocBodySchema
|
|
56517
|
+
});
|
|
56097
56518
|
var SearchResultSchema = object({
|
|
56098
56519
|
name: string(),
|
|
56099
56520
|
version: string(),
|
|
@@ -56312,7 +56733,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56312
56733
|
}), object({ success: literal(true) }), {
|
|
56313
56734
|
kind: "mutation",
|
|
56314
56735
|
auth: "admin"
|
|
56315
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56736
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56737
|
+
name: string().min(1),
|
|
56738
|
+
version: string().min(1).optional()
|
|
56739
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56316
56740
|
kind: "mutation",
|
|
56317
56741
|
auth: "admin"
|
|
56318
56742
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56371,27 +56795,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56371
56795
|
*/
|
|
56372
56796
|
var AirQualitySensorStatusSchema = object({
|
|
56373
56797
|
/** Carbon dioxide concentration in ppm. */
|
|
56374
|
-
co2Ppm: number().min(0).optional(),
|
|
56798
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56375
56799
|
/** Total volatile organic compounds in ppb. */
|
|
56376
|
-
vocPpb: number().min(0).optional(),
|
|
56800
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56377
56801
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56378
|
-
pm25: number().min(0).optional(),
|
|
56802
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56379
56803
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56380
|
-
pm10: number().min(0).optional(),
|
|
56804
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56381
56805
|
/** Composite AQI value (typically 0..500). */
|
|
56382
|
-
aqi: number().optional(),
|
|
56806
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56383
56807
|
/** Ms epoch when the slice was last updated. */
|
|
56384
|
-
lastFetchedAt: number()
|
|
56385
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56386
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56387
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56388
|
-
* per slice is unambiguous. */
|
|
56389
|
-
unit: string().optional(),
|
|
56390
|
-
/** Suggested decimal places for numeric display.
|
|
56391
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56392
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56393
|
-
* auto-formatting when absent. */
|
|
56394
|
-
precision: number().int().min(0).max(10).optional()
|
|
56808
|
+
lastFetchedAt: number()
|
|
56395
56809
|
});
|
|
56396
56810
|
var airQualitySensorCapability = {
|
|
56397
56811
|
name: "air-quality-sensor",
|
|
@@ -56428,12 +56842,12 @@ var airQualitySensorCapability = {
|
|
|
56428
56842
|
},
|
|
56429
56843
|
pm25: {
|
|
56430
56844
|
kind: "gauge",
|
|
56431
|
-
unit: "
|
|
56845
|
+
unit: "µg/m³",
|
|
56432
56846
|
deadband: 1
|
|
56433
56847
|
},
|
|
56434
56848
|
pm10: {
|
|
56435
56849
|
kind: "gauge",
|
|
56436
|
-
unit: "
|
|
56850
|
+
unit: "µg/m³",
|
|
56437
56851
|
deadband: 1
|
|
56438
56852
|
},
|
|
56439
56853
|
aqi: {
|
|
@@ -56451,22 +56865,13 @@ var airQualitySensorCapability = {
|
|
|
56451
56865
|
* entries with `device_class: illuminance`.
|
|
56452
56866
|
*/
|
|
56453
56867
|
var AmbientLightSensorStatusSchema = object({
|
|
56454
|
-
/** Current illuminance in lux (lx). */
|
|
56455
|
-
lux: number().min(0).meta({
|
|
56456
|
-
|
|
56868
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56869
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56870
|
+
precision: 0,
|
|
56457
56871
|
label: "Illuminance"
|
|
56458
|
-
}),
|
|
56872
|
+
})),
|
|
56459
56873
|
/** Ms epoch when the slice was last updated. */
|
|
56460
|
-
lastFetchedAt: number()
|
|
56461
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56462
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56463
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56464
|
-
unit: string().optional(),
|
|
56465
|
-
/** Suggested decimal places for numeric display.
|
|
56466
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56467
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56468
|
-
* auto-formatting when absent. */
|
|
56469
|
-
precision: number().int().min(0).max(10).optional()
|
|
56874
|
+
lastFetchedAt: number()
|
|
56470
56875
|
});
|
|
56471
56876
|
var ambientLightSensorCapability = {
|
|
56472
56877
|
name: "ambient-light-sensor",
|
|
@@ -56498,12 +56903,7 @@ var ambientLightSensorCapability = {
|
|
|
56498
56903
|
} } },
|
|
56499
56904
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56500
56905
|
* whether persisting is worth a SQLite commit. */
|
|
56501
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56502
|
-
customize: {
|
|
56503
|
-
version: 1,
|
|
56504
|
-
advanced: "derive",
|
|
56505
|
-
targets: []
|
|
56506
|
-
}
|
|
56906
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56507
56907
|
};
|
|
56508
56908
|
/**
|
|
56509
56909
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -56730,10 +57130,7 @@ var BatteryStatusSchema = object({
|
|
|
56730
57130
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56731
57131
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56732
57132
|
*/
|
|
56733
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56734
|
-
unit: "%",
|
|
56735
|
-
label: "Charge"
|
|
56736
|
-
}),
|
|
57133
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56737
57134
|
/**
|
|
56738
57135
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56739
57136
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56760,7 +57157,14 @@ var BatteryStatusSchema = object({
|
|
|
56760
57157
|
*/
|
|
56761
57158
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56762
57159
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56763
|
-
lastUpdated: number(),
|
|
57160
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57161
|
+
/**
|
|
57162
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57163
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57164
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57165
|
+
* `numeric-sensor` on the same device.
|
|
57166
|
+
*/
|
|
57167
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56764
57168
|
/**
|
|
56765
57169
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56766
57170
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56812,7 +57216,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
56812
57216
|
/** Generic Customize target for the percentage reading (D936). */
|
|
56813
57217
|
var batteryCustomize = {
|
|
56814
57218
|
version: 1,
|
|
56815
|
-
advanced: "derive",
|
|
56816
57219
|
targets: [{
|
|
56817
57220
|
id: "percentage",
|
|
56818
57221
|
cardinality: "scalar",
|
|
@@ -56821,7 +57224,7 @@ var batteryCustomize = {
|
|
|
56821
57224
|
stateField: "percentage"
|
|
56822
57225
|
},
|
|
56823
57226
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
56824
|
-
apply: "add
|
|
57227
|
+
apply: "add",
|
|
56825
57228
|
path: "percentage",
|
|
56826
57229
|
sources: [{
|
|
56827
57230
|
kind: "field",
|
|
@@ -56942,10 +57345,16 @@ onStatusChanged: { data: object({
|
|
|
56942
57345
|
/**
|
|
56943
57346
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
56944
57347
|
*/
|
|
56945
|
-
history: { fields: {
|
|
56946
|
-
|
|
56947
|
-
|
|
56948
|
-
|
|
57348
|
+
history: { fields: {
|
|
57349
|
+
percentage: {
|
|
57350
|
+
kind: "gauge",
|
|
57351
|
+
unit: "%"
|
|
57352
|
+
},
|
|
57353
|
+
volts: {
|
|
57354
|
+
kind: "gauge",
|
|
57355
|
+
unit: "V"
|
|
57356
|
+
}
|
|
57357
|
+
} },
|
|
56949
57358
|
customize: batteryCustomize,
|
|
56950
57359
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56951
57360
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -56992,12 +57401,7 @@ var binaryCapability = {
|
|
|
56992
57401
|
history: { fields: { on: { kind: "boolean" } } },
|
|
56993
57402
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56994
57403
|
* whether persisting is worth a SQLite commit. */
|
|
56995
|
-
volatileStateFields: ["lastChangedAt"]
|
|
56996
|
-
customize: {
|
|
56997
|
-
version: 1,
|
|
56998
|
-
advanced: "derive",
|
|
56999
|
-
targets: []
|
|
57000
|
-
}
|
|
57404
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57001
57405
|
};
|
|
57002
57406
|
/**
|
|
57003
57407
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57013,7 +57417,7 @@ var binaryCapability = {
|
|
|
57013
57417
|
*/
|
|
57014
57418
|
var BrightnessStatusSchema = object({
|
|
57015
57419
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57016
|
-
percentage: number().min(0).max(100),
|
|
57420
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57017
57421
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57018
57422
|
lastChangedAt: number()
|
|
57019
57423
|
});
|
|
@@ -57467,21 +57871,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57467
57871
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57468
57872
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57469
57873
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57470
|
-
target: number().nullable(),
|
|
57874
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57471
57875
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57472
57876
|
* in `heat_cool` mode. */
|
|
57473
|
-
targetHigh: number().nullable(),
|
|
57877
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57474
57878
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57475
57879
|
* in `heat_cool` mode. */
|
|
57476
|
-
targetLow: number().nullable(),
|
|
57880
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57477
57881
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57478
57882
|
* humidity control. */
|
|
57479
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57883
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57480
57884
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57481
57885
|
* the device's internal sensor. */
|
|
57482
|
-
currentTemp: number().nullable(),
|
|
57886
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57483
57887
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57484
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57888
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57485
57889
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57486
57890
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57487
57891
|
swingVertical: boolean().nullable(),
|
|
@@ -57489,11 +57893,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57489
57893
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57490
57894
|
swingHorizontal: boolean().nullable(),
|
|
57491
57895
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57492
|
-
minTemp: number().nullable().optional(),
|
|
57896
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57493
57897
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57494
|
-
maxTemp: number().nullable().optional(),
|
|
57898
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57495
57899
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57496
|
-
tempStep: number().positive().nullable().optional(),
|
|
57900
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57497
57901
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57498
57902
|
lastFetchedAt: number()
|
|
57499
57903
|
});
|
|
@@ -57635,17 +58039,17 @@ var climateControlCapability = {
|
|
|
57635
58039
|
* modes to expose in the picker without a slice fetch.
|
|
57636
58040
|
*/
|
|
57637
58041
|
var RgbTripletSchema = object({
|
|
57638
|
-
r: number().int().min(0).max(255),
|
|
57639
|
-
g: number().int().min(0).max(255),
|
|
57640
|
-
b: number().int().min(0).max(255)
|
|
58042
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58043
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58044
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57641
58045
|
});
|
|
57642
58046
|
var HsvTripletSchema = object({
|
|
57643
58047
|
/** Hue in degrees, 0..360. */
|
|
57644
|
-
h: number().min(0).max(360),
|
|
58048
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57645
58049
|
/** Saturation as 0..100 inclusive. */
|
|
57646
|
-
s: number().min(0).max(100),
|
|
58050
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57647
58051
|
/** Value/brightness as 0..100 inclusive. */
|
|
57648
|
-
v: number().min(0).max(100)
|
|
58052
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57649
58053
|
});
|
|
57650
58054
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57651
58055
|
object({
|
|
@@ -57674,7 +58078,7 @@ var ColorStatusSchema = object({
|
|
|
57674
58078
|
/** Populated when `mode === 'hsv'`. */
|
|
57675
58079
|
hsv: HsvTripletSchema.optional(),
|
|
57676
58080
|
/** Populated when `mode === 'mired'`. */
|
|
57677
|
-
mireds: number().int().optional(),
|
|
58081
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57678
58082
|
/** Ms epoch of the last operator-driven change. */
|
|
57679
58083
|
lastChangedAt: number()
|
|
57680
58084
|
});
|
|
@@ -57869,18 +58273,12 @@ _enum([
|
|
|
57869
58273
|
"empty",
|
|
57870
58274
|
"full"
|
|
57871
58275
|
]);
|
|
57872
|
-
/**
|
|
57873
|
-
|
|
57874
|
-
|
|
57875
|
-
"days",
|
|
57876
|
-
"hours",
|
|
57877
|
-
"cycles"
|
|
57878
|
-
]);
|
|
57879
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57880
|
-
* days). `value` null = unknown (D393). */
|
|
58276
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58277
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58278
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57881
58279
|
var ConsumableRemainingSchema = object({
|
|
57882
|
-
value: number().min(0).nullable(),
|
|
57883
|
-
|
|
58280
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58281
|
+
kind: ConsumableRemainingKindSchema
|
|
57884
58282
|
});
|
|
57885
58283
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
57886
58284
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -57893,7 +58291,7 @@ var ConsumableItemSchema = object({
|
|
|
57893
58291
|
/** Display name. */
|
|
57894
58292
|
label: string().min(1),
|
|
57895
58293
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57896
|
-
level: number().min(0).max(100).nullable(),
|
|
58294
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57897
58295
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57898
58296
|
status: ConsumableStatusSchema.nullable(),
|
|
57899
58297
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57975,8 +58373,8 @@ var consumablesCustomize = {
|
|
|
57975
58373
|
transforms: [{ kind: "identity" }]
|
|
57976
58374
|
}],
|
|
57977
58375
|
literals: [{
|
|
57978
|
-
path: "remaining.
|
|
57979
|
-
values: [...
|
|
58376
|
+
path: "remaining.kind",
|
|
58377
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
57980
58378
|
}]
|
|
57981
58379
|
},
|
|
57982
58380
|
{
|
|
@@ -58105,7 +58503,6 @@ reset: method(object({
|
|
|
58105
58503
|
},
|
|
58106
58504
|
"remaining.value": {
|
|
58107
58505
|
kind: "gauge",
|
|
58108
|
-
unitFrom: "remaining.unit",
|
|
58109
58506
|
deadband: 1,
|
|
58110
58507
|
displayName: "Remaining"
|
|
58111
58508
|
}
|
|
@@ -58175,10 +58572,9 @@ var contactCapability = {
|
|
|
58175
58572
|
* (empty array for the other kinds). It lives in the slice because
|
|
58176
58573
|
* HA `select.*` entities may update their options at runtime.
|
|
58177
58574
|
*
|
|
58178
|
-
*
|
|
58179
|
-
*
|
|
58180
|
-
*
|
|
58181
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58575
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58576
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58577
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58182
58578
|
*/
|
|
58183
58579
|
var ControlStatusSchema = object({
|
|
58184
58580
|
kind: _enum([
|
|
@@ -58190,39 +58586,17 @@ var ControlStatusSchema = object({
|
|
|
58190
58586
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58191
58587
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58192
58588
|
* or time-only — HA accepts all three forms). */
|
|
58193
|
-
value: union([number(), string()]),
|
|
58589
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58194
58590
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58195
58591
|
options: array(string()),
|
|
58196
58592
|
/** Ms epoch when the slice was last updated. */
|
|
58197
58593
|
lastChangedAt: number(),
|
|
58198
|
-
/**
|
|
58199
|
-
|
|
58200
|
-
|
|
58201
|
-
|
|
58202
|
-
/**
|
|
58203
|
-
|
|
58204
|
-
min: number().optional(),
|
|
58205
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58206
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58207
|
-
max: number().optional(),
|
|
58208
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58209
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58210
|
-
step: number().optional(),
|
|
58211
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58212
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58213
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58214
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58215
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58216
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58217
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58218
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58219
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58220
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58221
|
-
format: _enum([
|
|
58222
|
-
"date",
|
|
58223
|
-
"time",
|
|
58224
|
-
"datetime"
|
|
58225
|
-
]).optional()
|
|
58594
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58595
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58596
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58597
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58598
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58599
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58226
58600
|
});
|
|
58227
58601
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58228
58602
|
object({
|
|
@@ -58288,9 +58662,9 @@ var CoverStatusSchema = object({
|
|
|
58288
58662
|
]),
|
|
58289
58663
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58290
58664
|
* no intermediate position surface. */
|
|
58291
|
-
position: number().min(0).max(100).nullable(),
|
|
58665
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58292
58666
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58293
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58667
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58294
58668
|
/** Ms epoch when the slice was last updated. */
|
|
58295
58669
|
lastChangedAt: number()
|
|
58296
58670
|
});
|
|
@@ -58393,9 +58767,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58393
58767
|
var DayNightStatusSchema = object({
|
|
58394
58768
|
mode: DayNightModeSchema,
|
|
58395
58769
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58396
|
-
sensitivity: number().optional(),
|
|
58770
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58397
58771
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58398
|
-
switchDelaySec: number().optional(),
|
|
58772
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58399
58773
|
lastFetchedAt: number()
|
|
58400
58774
|
});
|
|
58401
58775
|
/**
|
|
@@ -58613,11 +58987,11 @@ var DishwasherStatusSchema = object({
|
|
|
58613
58987
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58614
58988
|
availablePrograms: array(string()),
|
|
58615
58989
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58616
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
58990
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58617
58991
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58618
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
58992
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58619
58993
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58620
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58994
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58621
58995
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58622
58996
|
doorOpen: boolean().nullable(),
|
|
58623
58997
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58641,7 +59015,7 @@ var DishwasherStatusSchema = object({
|
|
|
58641
59015
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58642
59016
|
machineCareDue: boolean().nullable(),
|
|
58643
59017
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58644
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59018
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58645
59019
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58646
59020
|
halfLoad: boolean().nullable(),
|
|
58647
59021
|
hygienePlus: boolean().nullable(),
|
|
@@ -58656,7 +59030,7 @@ var DishwasherStatusSchema = object({
|
|
|
58656
59030
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58657
59031
|
activeEvents: array(string()),
|
|
58658
59032
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58659
|
-
errorCode: number().nullable(),
|
|
59033
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58660
59034
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58661
59035
|
errorLabel: string().nullable(),
|
|
58662
59036
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -58887,7 +59261,7 @@ var DoorbellStatusSchema = object({
|
|
|
58887
59261
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
58888
59262
|
lastPressedAt: number().nullable(),
|
|
58889
59263
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
58890
|
-
pressCountSinceStart: number()
|
|
59264
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
58891
59265
|
});
|
|
58892
59266
|
var DoorbellPressEventSchema = object({
|
|
58893
59267
|
deviceId: number(),
|
|
@@ -58952,17 +59326,7 @@ onPressed: {
|
|
|
58952
59326
|
history: "none",
|
|
58953
59327
|
customize: doorbellCustomize
|
|
58954
59328
|
};
|
|
58955
|
-
|
|
58956
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
58957
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
58958
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
58959
|
-
* The option set is stable across observations; it is persisted in the
|
|
58960
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
58961
|
-
* stored in `sourceInfo`.
|
|
58962
|
-
*/
|
|
58963
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
58964
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
58965
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59329
|
+
_enum([
|
|
58966
59330
|
"date",
|
|
58967
59331
|
"time",
|
|
58968
59332
|
"datetime"
|
|
@@ -58970,12 +59334,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
58970
59334
|
var EnumSensorStatusSchema = object({
|
|
58971
59335
|
value: string(),
|
|
58972
59336
|
/**
|
|
58973
|
-
* Set
|
|
58974
|
-
* as
|
|
58975
|
-
*
|
|
58976
|
-
* a time-only sensor → `'time'`.
|
|
59337
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59338
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59339
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
58977
59340
|
*/
|
|
58978
|
-
|
|
59341
|
+
timestamp: boolean().optional(),
|
|
58979
59342
|
/** Ms epoch when the slice was last updated. */
|
|
58980
59343
|
lastFetchedAt: number()
|
|
58981
59344
|
});
|
|
@@ -59002,11 +59365,11 @@ var enumSensorCapability = {
|
|
|
59002
59365
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59003
59366
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59004
59367
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59005
|
-
* `
|
|
59368
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59006
59369
|
*/
|
|
59007
59370
|
history: { fields: { value: {
|
|
59008
59371
|
kind: "enum",
|
|
59009
|
-
skipWhenSet: "
|
|
59372
|
+
skipWhenSet: "timestamp"
|
|
59010
59373
|
} } },
|
|
59011
59374
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59012
59375
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59026,13 +59389,13 @@ var EventFireSchema = object({
|
|
|
59026
59389
|
deviceId: number(),
|
|
59027
59390
|
eventType: string(),
|
|
59028
59391
|
data: record(string(), unknown()).nullable(),
|
|
59029
|
-
timestamp: number(),
|
|
59030
|
-
seq: number()
|
|
59392
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59393
|
+
seq: number().meta(readingMeta("count"))
|
|
59031
59394
|
});
|
|
59032
59395
|
var EventEmitterStatusSchema = object({
|
|
59033
59396
|
eventTypes: array(string()),
|
|
59034
59397
|
lastEvent: EventFireSchema.nullable(),
|
|
59035
|
-
eventCountSinceStart: number()
|
|
59398
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59036
59399
|
});
|
|
59037
59400
|
var eventEmitterCapability = {
|
|
59038
59401
|
name: "event-emitter",
|
|
@@ -59445,10 +59808,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59445
59808
|
var FanControlStatusSchema = object({
|
|
59446
59809
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59447
59810
|
* speed surface (single-speed fan). */
|
|
59448
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59811
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59449
59812
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59450
59813
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59451
|
-
percentageStep: number().positive().optional(),
|
|
59814
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59452
59815
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59453
59816
|
* — empty string when no preset is active or supported. */
|
|
59454
59817
|
preset: string(),
|
|
@@ -59569,7 +59932,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59569
59932
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59570
59933
|
model: string().nullable(),
|
|
59571
59934
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59572
|
-
channelCount: number().nullable(),
|
|
59935
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59573
59936
|
/**
|
|
59574
59937
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59575
59938
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59692,9 +60055,91 @@ var gasCapability = {
|
|
|
59692
60055
|
* whether persisting is worth a SQLite commit. */
|
|
59693
60056
|
volatileStateFields: ["lastChangedAt"]
|
|
59694
60057
|
};
|
|
60058
|
+
var GroupCommandsSchema = object({
|
|
60059
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60060
|
+
results: array(object({
|
|
60061
|
+
deviceId: number().int().nonnegative(),
|
|
60062
|
+
cap: string().min(1),
|
|
60063
|
+
method: string().min(1),
|
|
60064
|
+
ok: boolean(),
|
|
60065
|
+
error: string().optional(),
|
|
60066
|
+
/** Ms epoch of the attempt. */
|
|
60067
|
+
at: number()
|
|
60068
|
+
})) });
|
|
60069
|
+
var groupCommandsCapability = {
|
|
60070
|
+
name: "group-commands",
|
|
60071
|
+
scope: "device",
|
|
60072
|
+
deviceNative: true,
|
|
60073
|
+
mode: "singleton",
|
|
60074
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60075
|
+
methods: {},
|
|
60076
|
+
status: {
|
|
60077
|
+
schema: GroupCommandsSchema,
|
|
60078
|
+
kind: "push"
|
|
60079
|
+
},
|
|
60080
|
+
runtimeState: GroupCommandsSchema,
|
|
60081
|
+
/**
|
|
60082
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60083
|
+
* failure would outlive the command that caused it.
|
|
60084
|
+
*
|
|
60085
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60086
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60087
|
+
*/
|
|
60088
|
+
durability: "session",
|
|
60089
|
+
history: "none"
|
|
60090
|
+
};
|
|
60091
|
+
/**
|
|
60092
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60093
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60094
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60095
|
+
* series that later statistics read is the output cap's own history block.
|
|
60096
|
+
*/
|
|
60097
|
+
var GroupStatusSchema = object({
|
|
60098
|
+
/** Members whose current value entered the aggregate. */
|
|
60099
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60100
|
+
precision: 0,
|
|
60101
|
+
label: "Reporting"
|
|
60102
|
+
})),
|
|
60103
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60104
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60105
|
+
precision: 0,
|
|
60106
|
+
label: "Excluded"
|
|
60107
|
+
})),
|
|
60108
|
+
/** `included` + `excluded`. */
|
|
60109
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60110
|
+
precision: 0,
|
|
60111
|
+
label: "Members"
|
|
60112
|
+
}))
|
|
60113
|
+
});
|
|
60114
|
+
var groupStatusCapability = {
|
|
60115
|
+
name: "group-status",
|
|
60116
|
+
scope: "device",
|
|
60117
|
+
deviceNative: true,
|
|
60118
|
+
mode: "singleton",
|
|
60119
|
+
deviceTypes: [
|
|
60120
|
+
DeviceType.Sensor,
|
|
60121
|
+
DeviceType.Switch,
|
|
60122
|
+
DeviceType.Light
|
|
60123
|
+
],
|
|
60124
|
+
methods: {},
|
|
60125
|
+
status: {
|
|
60126
|
+
schema: GroupStatusSchema,
|
|
60127
|
+
kind: "push"
|
|
60128
|
+
},
|
|
60129
|
+
runtimeState: GroupStatusSchema,
|
|
60130
|
+
/**
|
|
60131
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60132
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60133
|
+
*
|
|
60134
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60135
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60136
|
+
*/
|
|
60137
|
+
durability: "session",
|
|
60138
|
+
history: "none"
|
|
60139
|
+
};
|
|
59695
60140
|
var HeatingValveStatusSchema = object({
|
|
59696
60141
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59697
|
-
position: number().min(0).max(100).nullable(),
|
|
60142
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59698
60143
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59699
60144
|
lastFetchedAt: number()
|
|
59700
60145
|
});
|
|
@@ -59737,9 +60182,9 @@ var HumidifierStatusSchema = object({
|
|
|
59737
60182
|
/** Whether the humidifier is currently on. */
|
|
59738
60183
|
on: boolean(),
|
|
59739
60184
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59740
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60185
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59741
60186
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59742
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60187
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59743
60188
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59744
60189
|
* device has no mode surface. */
|
|
59745
60190
|
mode: string().nullable(),
|
|
@@ -59749,9 +60194,9 @@ var HumidifierStatusSchema = object({
|
|
|
59749
60194
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59750
60195
|
action: string().nullable(),
|
|
59751
60196
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59752
|
-
minHumidity: number().nullable(),
|
|
60197
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59753
60198
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59754
|
-
maxHumidity: number().nullable(),
|
|
60199
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59755
60200
|
/** Ms epoch when the slice was last updated. */
|
|
59756
60201
|
lastChangedAt: number()
|
|
59757
60202
|
});
|
|
@@ -59821,22 +60266,13 @@ var humidifierCapability = {
|
|
|
59821
60266
|
* `sourceInfo`.
|
|
59822
60267
|
*/
|
|
59823
60268
|
var HumiditySensorStatusSchema = object({
|
|
59824
|
-
/** Current relative humidity, 0..100. */
|
|
59825
|
-
percent: number().min(0).max(100).meta({
|
|
59826
|
-
|
|
60269
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60270
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60271
|
+
precision: 0,
|
|
59827
60272
|
label: "Humidity"
|
|
59828
|
-
}),
|
|
60273
|
+
})),
|
|
59829
60274
|
/** Ms epoch when the slice was last updated. */
|
|
59830
|
-
lastFetchedAt: number()
|
|
59831
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59832
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59833
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59834
|
-
unit: string().optional(),
|
|
59835
|
-
/** Suggested decimal places for numeric display.
|
|
59836
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59837
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59838
|
-
* auto-formatting when absent. */
|
|
59839
|
-
precision: number().int().min(0).max(10).optional()
|
|
60275
|
+
lastFetchedAt: number()
|
|
59840
60276
|
});
|
|
59841
60277
|
var humiditySensorCapability = {
|
|
59842
60278
|
name: "humidity-sensor",
|
|
@@ -59867,12 +60303,7 @@ var humiditySensorCapability = {
|
|
|
59867
60303
|
} } },
|
|
59868
60304
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59869
60305
|
* whether persisting is worth a SQLite commit. */
|
|
59870
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59871
|
-
customize: {
|
|
59872
|
-
version: 1,
|
|
59873
|
-
advanced: "derive",
|
|
59874
|
-
targets: []
|
|
59875
|
-
}
|
|
60306
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59876
60307
|
};
|
|
59877
60308
|
/**
|
|
59878
60309
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -59893,7 +60324,7 @@ var ImageStatusSchema = object({
|
|
|
59893
60324
|
* entity exposes no `entity_picture` (yet). */
|
|
59894
60325
|
url: string().nullable(),
|
|
59895
60326
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
59896
|
-
lastUpdated: number().nullable()
|
|
60327
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
59897
60328
|
});
|
|
59898
60329
|
var imageCapability = {
|
|
59899
60330
|
name: "image",
|
|
@@ -59981,19 +60412,19 @@ var NormalizedRangeSchema = object({
|
|
|
59981
60412
|
*/
|
|
59982
60413
|
var ImageSettingsStatusSchema = object({
|
|
59983
60414
|
/** Normalized 0–100. */
|
|
59984
|
-
brightness: number().optional(),
|
|
60415
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
59985
60416
|
/** Normalized 0–100. */
|
|
59986
|
-
contrast: number().optional(),
|
|
60417
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
59987
60418
|
/** Normalized 0–100. */
|
|
59988
|
-
saturation: number().optional(),
|
|
60419
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
59989
60420
|
/** Normalized 0–100. */
|
|
59990
|
-
sharpness: number().optional(),
|
|
60421
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
59991
60422
|
mirror: boolean().optional(),
|
|
59992
60423
|
flip: boolean().optional(),
|
|
59993
60424
|
rotate: ImageRotateSchema.optional(),
|
|
59994
60425
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
59995
60426
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
59996
|
-
warmth: number().optional(),
|
|
60427
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
59997
60428
|
exposureMode: ExposureModeSchema.optional(),
|
|
59998
60429
|
backlightMode: BacklightModeSchema.optional(),
|
|
59999
60430
|
lastFetchedAt: number()
|
|
@@ -60272,10 +60703,10 @@ var IntercomAbilitySchema = object({
|
|
|
60272
60703
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60273
60704
|
codecs: array(string()),
|
|
60274
60705
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60275
|
-
sampleRate: number(),
|
|
60706
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60276
60707
|
duplex: _enum(["half", "full"]),
|
|
60277
60708
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60278
|
-
maxBacklogMs: number()
|
|
60709
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60279
60710
|
});
|
|
60280
60711
|
var IntercomStatusSchema = object({
|
|
60281
60712
|
/** True while a talk session is open. */
|
|
@@ -60502,13 +60933,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60502
60933
|
activity: LawnMowerActivitySchema,
|
|
60503
60934
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60504
60935
|
* reading. */
|
|
60505
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60936
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60506
60937
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60507
60938
|
* task is active / progress is unavailable. */
|
|
60508
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60939
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60509
60940
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60510
60941
|
* or null when unknown. */
|
|
60511
|
-
currentCode: number().nullable(),
|
|
60942
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60512
60943
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60513
60944
|
currentCodeLabel: string().nullable(),
|
|
60514
60945
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61041,7 +61472,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61041
61472
|
state: MediaPlayerStateSchema,
|
|
61042
61473
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61043
61474
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61044
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61475
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61045
61476
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61046
61477
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61047
61478
|
isMuted: boolean().nullable(),
|
|
@@ -61054,10 +61485,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61054
61485
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61055
61486
|
/** Current playback position in ms. Null when not seekable or
|
|
61056
61487
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61057
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61488
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61058
61489
|
/** Total duration of the current media in ms. Null when unknown
|
|
61059
61490
|
* (live stream) or nothing is playing. */
|
|
61060
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61491
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61061
61492
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61062
61493
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61063
61494
|
shuffle: boolean().nullable(),
|
|
@@ -61366,7 +61797,7 @@ var motionCustomize = {
|
|
|
61366
61797
|
eventName: "onMotionChanged"
|
|
61367
61798
|
},
|
|
61368
61799
|
deviceTypes: [DeviceType.Camera],
|
|
61369
|
-
apply: "
|
|
61800
|
+
apply: "add",
|
|
61370
61801
|
applyAuthority: {
|
|
61371
61802
|
kind: "camera-sensors",
|
|
61372
61803
|
timeoutField: "motionCooldownMs"
|
|
@@ -61438,7 +61869,7 @@ var MotionStatusSchema = object({
|
|
|
61438
61869
|
* it, every provider seeded it at boot, and every session left it
|
|
61439
61870
|
* `detected: true` after its detach.
|
|
61440
61871
|
*/
|
|
61441
|
-
autoClearAfterMs: number().nullable()
|
|
61872
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61442
61873
|
});
|
|
61443
61874
|
/**
|
|
61444
61875
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61475,12 +61906,18 @@ var motionCapability = {
|
|
|
61475
61906
|
methods: {
|
|
61476
61907
|
/**
|
|
61477
61908
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61478
|
-
* for consumers that don't need the full status object
|
|
61479
|
-
*
|
|
61480
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61481
|
-
* consumer.
|
|
61909
|
+
* for consumers that don't need the full status object. A composed
|
|
61910
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61482
61911
|
*/
|
|
61483
61912
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
61913
|
+
/**
|
|
61914
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
61915
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
61916
|
+
*/
|
|
61917
|
+
composedMethods: { isDetected: {
|
|
61918
|
+
kind: "slice",
|
|
61919
|
+
field: "detected"
|
|
61920
|
+
} },
|
|
61484
61921
|
events: {
|
|
61485
61922
|
/**
|
|
61486
61923
|
* Fires every time the runner transitions a camera between
|
|
@@ -61620,7 +62057,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61620
62057
|
* the grid region(s). */
|
|
61621
62058
|
var MotionZoneStatusSchema = object({
|
|
61622
62059
|
enabled: boolean(),
|
|
61623
|
-
sensitivity: number(),
|
|
62060
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61624
62061
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61625
62062
|
regions: array(MotionZoneRegionSchema),
|
|
61626
62063
|
lastFetchedAt: number()
|
|
@@ -61990,7 +62427,7 @@ var NavigationStatusSchema = object({
|
|
|
61990
62427
|
following: boolean(),
|
|
61991
62428
|
flash: boolean(),
|
|
61992
62429
|
lightMode: NavigationLightModeSchema,
|
|
61993
|
-
lightLevel: number().min(40).max(100),
|
|
62430
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
61994
62431
|
/** Ms epoch when the slice was last updated. */
|
|
61995
62432
|
lastChangedAt: number()
|
|
61996
62433
|
});
|
|
@@ -62124,13 +62561,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62124
62561
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62125
62562
|
* SKIP a null rather than coerce it.
|
|
62126
62563
|
*/
|
|
62127
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62564
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62128
62565
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62129
|
-
rssiDbm: number().optional(),
|
|
62566
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62130
62567
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62131
62568
|
ssid: string().optional(),
|
|
62132
62569
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62133
|
-
lastUpdated: number()
|
|
62570
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62134
62571
|
});
|
|
62135
62572
|
var networkLinkCapability = {
|
|
62136
62573
|
name: "network-link",
|
|
@@ -62515,7 +62952,7 @@ var NotifierStatusSchema = object({
|
|
|
62515
62952
|
lastError: string().nullable(),
|
|
62516
62953
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62517
62954
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62518
|
-
queueDepth: number().int().nonnegative(),
|
|
62955
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62519
62956
|
/** Per-feature capability matrix — authoritative source for the
|
|
62520
62957
|
* compose-form field gating. */
|
|
62521
62958
|
supports: NotifierSupportsSchema
|
|
@@ -62607,11 +63044,9 @@ onSent: { data: object({
|
|
|
62607
63044
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62608
63045
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62609
63046
|
*
|
|
62610
|
-
* The
|
|
62611
|
-
*
|
|
62612
|
-
*
|
|
62613
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62614
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63047
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63048
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63049
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62615
63050
|
*
|
|
62616
63051
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62617
63052
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62620,15 +63055,8 @@ onSent: { data: object({
|
|
|
62620
63055
|
* numeric values land here.
|
|
62621
63056
|
*/
|
|
62622
63057
|
var NumericSensorStatusSchema = object({
|
|
62623
|
-
|
|
62624
|
-
|
|
62625
|
-
* Populated live from the upstream source on each state push.
|
|
62626
|
-
* Absent for unitless sensors. */
|
|
62627
|
-
unit: string().optional(),
|
|
62628
|
-
/** Suggested decimal places for numeric display.
|
|
62629
|
-
* Populated live from the upstream source when provided.
|
|
62630
|
-
* Falls back to auto-formatting when absent. */
|
|
62631
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63058
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63059
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62632
63060
|
/** Ms epoch when the slice was last updated. */
|
|
62633
63061
|
lastFetchedAt: number()
|
|
62634
63062
|
});
|
|
@@ -62652,11 +63080,11 @@ var numericSensorCapability = {
|
|
|
62652
63080
|
*/
|
|
62653
63081
|
durability: "restored",
|
|
62654
63082
|
/**
|
|
62655
|
-
* History (D850): recorded series. The unit is
|
|
63083
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63084
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62656
63085
|
*/
|
|
62657
63086
|
history: { fields: { value: {
|
|
62658
63087
|
kind: "gauge",
|
|
62659
|
-
unitFrom: "unit",
|
|
62660
63088
|
minIntervalMs: 3e4
|
|
62661
63089
|
} } },
|
|
62662
63090
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -62948,23 +63376,26 @@ var PetFeederStatusSchema = object({
|
|
|
62948
63376
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
62949
63377
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
62950
63378
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
62951
|
-
foodLevel: number().nullable(),
|
|
63379
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
62952
63380
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
62953
63381
|
* single-hopper models. */
|
|
62954
|
-
food1: number().nullable(),
|
|
63382
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
62955
63383
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
62956
63384
|
* single-hopper models. */
|
|
62957
|
-
food2: number().nullable(),
|
|
63385
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
62958
63386
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
62959
63387
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
62960
63388
|
* below the feeder's low threshold. */
|
|
62961
63389
|
lowFood: boolean(),
|
|
62962
63390
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
62963
63391
|
* device has no battery reading. */
|
|
62964
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
62965
|
-
/**
|
|
62966
|
-
*
|
|
62967
|
-
|
|
63392
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63393
|
+
/**
|
|
63394
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63395
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63396
|
+
* model has no desiccant sensor.
|
|
63397
|
+
*/
|
|
63398
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
62968
63399
|
/** True while a feed is in progress. */
|
|
62969
63400
|
feeding: boolean(),
|
|
62970
63401
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -62975,7 +63406,7 @@ var PetFeederStatusSchema = object({
|
|
|
62975
63406
|
* with `errorCode` for consumers that want the raw integer. */
|
|
62976
63407
|
error: string().nullable(),
|
|
62977
63408
|
/** Raw device error code (0 / null = no error). */
|
|
62978
|
-
errorCode: number().nullable(),
|
|
63409
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
62979
63410
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
62980
63411
|
isDualHopper: boolean(),
|
|
62981
63412
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -62985,7 +63416,7 @@ var PetFeederStatusSchema = object({
|
|
|
62985
63416
|
/** Play a chime when dispensing. */
|
|
62986
63417
|
feedSound: boolean(),
|
|
62987
63418
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
62988
|
-
volume: number(),
|
|
63419
|
+
volume: number().meta(readingMeta("none")),
|
|
62989
63420
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
62990
63421
|
lastFetchedAt: number()
|
|
62991
63422
|
});
|
|
@@ -63104,7 +63535,7 @@ var petFeederCapability = {
|
|
|
63104
63535
|
},
|
|
63105
63536
|
desiccantLeftDays: {
|
|
63106
63537
|
kind: "gauge",
|
|
63107
|
-
unit: "
|
|
63538
|
+
unit: "s"
|
|
63108
63539
|
}
|
|
63109
63540
|
} }
|
|
63110
63541
|
};
|
|
@@ -63505,36 +63936,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63505
63936
|
*/
|
|
63506
63937
|
var PowerMeterStatusSchema = object({
|
|
63507
63938
|
/** Instantaneous power draw in watts. */
|
|
63508
|
-
watts: number().optional().meta({
|
|
63509
|
-
unit: "W",
|
|
63510
|
-
label: "Power"
|
|
63511
|
-
}),
|
|
63939
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63512
63940
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63513
|
-
kwhTotal: number().optional().meta({
|
|
63514
|
-
unit: "kWh",
|
|
63515
|
-
label: "Energy"
|
|
63516
|
-
}),
|
|
63941
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63517
63942
|
/** Voltage in volts. */
|
|
63518
|
-
volts: number().optional(),
|
|
63943
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63519
63944
|
/** Current in amperes. */
|
|
63520
|
-
amps: number().optional(),
|
|
63521
|
-
/** Apparent power in volt-amperes
|
|
63522
|
-
va: number().optional(),
|
|
63945
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
63946
|
+
/** Apparent power in volt-amperes. */
|
|
63947
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63523
63948
|
/** Power factor (0..1) if reported. */
|
|
63524
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
63949
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63525
63950
|
/** Ms epoch when the slice was last updated. */
|
|
63526
|
-
lastFetchedAt: number()
|
|
63527
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63528
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63529
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63530
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63531
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63532
|
-
unit: string().optional(),
|
|
63533
|
-
/** Suggested decimal places for numeric display.
|
|
63534
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63535
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63536
|
-
* auto-formatting when absent. */
|
|
63537
|
-
precision: number().int().min(0).max(10).optional()
|
|
63951
|
+
lastFetchedAt: number()
|
|
63538
63952
|
});
|
|
63539
63953
|
var powerMeterCapability = {
|
|
63540
63954
|
name: "power-meter",
|
|
@@ -63598,12 +64012,7 @@ var powerMeterCapability = {
|
|
|
63598
64012
|
} },
|
|
63599
64013
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63600
64014
|
* whether persisting is worth a SQLite commit. */
|
|
63601
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63602
|
-
customize: {
|
|
63603
|
-
version: 1,
|
|
63604
|
-
advanced: "derive",
|
|
63605
|
-
targets: []
|
|
63606
|
-
}
|
|
64015
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63607
64016
|
};
|
|
63608
64017
|
/**
|
|
63609
64018
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63623,11 +64032,11 @@ var powerMeterCapability = {
|
|
|
63623
64032
|
*/
|
|
63624
64033
|
var GpsLocationSchema = object({
|
|
63625
64034
|
/** Latitude in decimal degrees, -90..90. */
|
|
63626
|
-
latitude: number().min(-90).max(90),
|
|
64035
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63627
64036
|
/** Longitude in decimal degrees, -180..180. */
|
|
63628
|
-
longitude: number().min(-180).max(180),
|
|
64037
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63629
64038
|
/** Reported accuracy in meters (lower = better). */
|
|
63630
|
-
accuracyMeters: number().nonnegative()
|
|
64039
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63631
64040
|
});
|
|
63632
64041
|
var PresenceStatusSchema = object({
|
|
63633
64042
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63639,7 +64048,7 @@ var PresenceStatusSchema = object({
|
|
|
63639
64048
|
gps: GpsLocationSchema.nullable(),
|
|
63640
64049
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63641
64050
|
* when not reported. */
|
|
63642
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64051
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63643
64052
|
/** Ms epoch when the slice was last updated. */
|
|
63644
64053
|
lastChangedAt: number()
|
|
63645
64054
|
});
|
|
@@ -63689,19 +64098,10 @@ var presenceCapability = {
|
|
|
63689
64098
|
* `sourceInfo`.
|
|
63690
64099
|
*/
|
|
63691
64100
|
var PressureSensorStatusSchema = object({
|
|
63692
|
-
/** Current pressure in hPa. */
|
|
63693
|
-
hpa: number(),
|
|
64101
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64102
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63694
64103
|
/** Ms epoch when the slice was last updated. */
|
|
63695
|
-
lastFetchedAt: number()
|
|
63696
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63697
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63698
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63699
|
-
unit: string().optional(),
|
|
63700
|
-
/** Suggested decimal places for numeric display.
|
|
63701
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63702
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63703
|
-
* auto-formatting when absent. */
|
|
63704
|
-
precision: number().int().min(0).max(10).optional()
|
|
64104
|
+
lastFetchedAt: number()
|
|
63705
64105
|
});
|
|
63706
64106
|
var pressureSensorCapability = {
|
|
63707
64107
|
name: "pressure-sensor",
|
|
@@ -64115,8 +64515,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64115
64515
|
}), _void(), { kind: "mutation" });
|
|
64116
64516
|
var PtzAutotrackSettingsSchema = object({
|
|
64117
64517
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64118
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64119
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64518
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64519
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64120
64520
|
});
|
|
64121
64521
|
/**
|
|
64122
64522
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64270,7 +64670,7 @@ var RunningStateStatusSchema = object({
|
|
|
64270
64670
|
/** null = unknown — never coerced to false (D393). */
|
|
64271
64671
|
running: boolean().nullable(),
|
|
64272
64672
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64273
|
-
since: number().nullable(),
|
|
64673
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64274
64674
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64275
64675
|
phase: string().nullable(),
|
|
64276
64676
|
/** null until a reading has been published (D393). */
|
|
@@ -64285,7 +64685,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64285
64685
|
/** Generic Customize target for the running boolean (D936). */
|
|
64286
64686
|
var runningCustomize = {
|
|
64287
64687
|
version: 1,
|
|
64288
|
-
advanced: "derive",
|
|
64289
64688
|
targets: [{
|
|
64290
64689
|
id: "running",
|
|
64291
64690
|
cardinality: "scalar",
|
|
@@ -64305,7 +64704,7 @@ var runningCustomize = {
|
|
|
64305
64704
|
DeviceType.Thermostat,
|
|
64306
64705
|
DeviceType.PetFeeder
|
|
64307
64706
|
],
|
|
64308
|
-
apply: "add
|
|
64707
|
+
apply: "add",
|
|
64309
64708
|
path: "running",
|
|
64310
64709
|
sources: [
|
|
64311
64710
|
{
|
|
@@ -65569,9 +65968,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65569
65968
|
*/
|
|
65570
65969
|
var RecordWindowSchema = object({
|
|
65571
65970
|
trigger: RecordTriggerSchema,
|
|
65572
|
-
day: number().int().min(0).max(6),
|
|
65573
|
-
startMinute: number().int().min(0).max(1439),
|
|
65574
|
-
endMinute: number().int().min(1).max(1440)
|
|
65971
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
65972
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
65973
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65575
65974
|
});
|
|
65576
65975
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65577
65976
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65647,10 +66046,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65647
66046
|
/** Master "record to the card at all" switch. */
|
|
65648
66047
|
enabled: boolean().nullable(),
|
|
65649
66048
|
overwriteWhenFull: boolean().nullable(),
|
|
65650
|
-
preRecordSec: number().nullable(),
|
|
65651
|
-
postRecordSec: number().nullable(),
|
|
66049
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66050
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65652
66051
|
/** Length of one recorded file, in minutes. */
|
|
65653
|
-
segmentMinutes: number().nullable(),
|
|
66052
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65654
66053
|
/** The primary track's weekly windows, flattened. */
|
|
65655
66054
|
windows: array(RecordWindowSchema),
|
|
65656
66055
|
/**
|
|
@@ -65666,7 +66065,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65666
66065
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65667
66066
|
* writable.
|
|
65668
66067
|
*/
|
|
65669
|
-
unreadableWindows: number(),
|
|
66068
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65670
66069
|
/**
|
|
65671
66070
|
* The camera is scheduled to record and has NO usable storage.
|
|
65672
66071
|
*
|
|
@@ -66511,7 +66910,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66511
66910
|
url: string().optional(),
|
|
66512
66911
|
codec: string().optional(),
|
|
66513
66912
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66514
|
-
fps: number().positive().optional(),
|
|
66913
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66515
66914
|
label: string().optional(),
|
|
66516
66915
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66517
66916
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66598,18 +66997,18 @@ var StreamProfileSchema = _enum([
|
|
|
66598
66997
|
]);
|
|
66599
66998
|
/** The current encoding config of one stream profile. */
|
|
66600
66999
|
var StreamProfileConfigSchema = object({
|
|
66601
|
-
width: number(),
|
|
66602
|
-
height: number(),
|
|
67000
|
+
width: number().meta(readingMeta("none")),
|
|
67001
|
+
height: number().meta(readingMeta("none")),
|
|
66603
67002
|
codec: _enum(["h264", "h265"]),
|
|
66604
|
-
framerate: number(),
|
|
66605
|
-
bitrate: number(),
|
|
67003
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67004
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66606
67005
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66607
67006
|
encoderProfile: _enum([
|
|
66608
67007
|
"high",
|
|
66609
67008
|
"main",
|
|
66610
67009
|
"baseline"
|
|
66611
67010
|
]).optional(),
|
|
66612
|
-
gop: number().optional(),
|
|
67011
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66613
67012
|
/**
|
|
66614
67013
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66615
67014
|
*
|
|
@@ -66830,12 +67229,7 @@ var switchCapability = {
|
|
|
66830
67229
|
label: "On",
|
|
66831
67230
|
kind: "boolean"
|
|
66832
67231
|
}
|
|
66833
|
-
}] }
|
|
66834
|
-
customize: {
|
|
66835
|
-
version: 1,
|
|
66836
|
-
advanced: "derive",
|
|
66837
|
-
targets: []
|
|
66838
|
-
}
|
|
67232
|
+
}] }
|
|
66839
67233
|
};
|
|
66840
67234
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66841
67235
|
function hasControlCharacter(value) {
|
|
@@ -67418,35 +67812,21 @@ var tamperCapability = {
|
|
|
67418
67812
|
* entries with `device_class: temperature` and any future native
|
|
67419
67813
|
* thermometer.
|
|
67420
67814
|
*
|
|
67421
|
-
*
|
|
67422
|
-
*
|
|
67423
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67424
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67425
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67426
|
-
* `sourceInfo`.
|
|
67815
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67816
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67427
67817
|
*
|
|
67428
67818
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67429
67819
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67430
67820
|
* changed" steady state.
|
|
67431
67821
|
*/
|
|
67432
67822
|
var TemperatureSensorStatusSchema = object({
|
|
67433
|
-
/** Current temperature in Celsius. */
|
|
67434
|
-
celsius: number().meta({
|
|
67435
|
-
|
|
67823
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67824
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67825
|
+
precision: 1,
|
|
67436
67826
|
label: "Temperature"
|
|
67437
|
-
}),
|
|
67827
|
+
})),
|
|
67438
67828
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67439
|
-
lastFetchedAt: number()
|
|
67440
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67441
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67442
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67443
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67444
|
-
unit: string().optional(),
|
|
67445
|
-
/** Suggested decimal places for numeric display.
|
|
67446
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67447
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67448
|
-
* auto-formatting when absent. */
|
|
67449
|
-
precision: number().int().min(0).max(10).optional()
|
|
67829
|
+
lastFetchedAt: number()
|
|
67450
67830
|
});
|
|
67451
67831
|
var temperatureSensorCapability = {
|
|
67452
67832
|
name: "temperature-sensor",
|
|
@@ -67477,12 +67857,7 @@ var temperatureSensorCapability = {
|
|
|
67477
67857
|
} } },
|
|
67478
67858
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67479
67859
|
* whether persisting is worth a SQLite commit. */
|
|
67480
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67481
|
-
customize: {
|
|
67482
|
-
version: 1,
|
|
67483
|
-
advanced: "derive",
|
|
67484
|
-
targets: []
|
|
67485
|
-
}
|
|
67860
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67486
67861
|
};
|
|
67487
67862
|
/**
|
|
67488
67863
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67765,16 +68140,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67765
68140
|
]),
|
|
67766
68141
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67767
68142
|
* reading. */
|
|
67768
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68143
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67769
68144
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67770
68145
|
* the vacuum has no speed control. */
|
|
67771
68146
|
fanSpeed: string().nullable(),
|
|
67772
68147
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67773
68148
|
availableFanSpeeds: array(string()),
|
|
67774
68149
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67775
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68150
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67776
68151
|
/** Current error code (0 / null = no error). */
|
|
67777
|
-
errorCode: number().nullable(),
|
|
68152
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67778
68153
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67779
68154
|
errorLabel: string().nullable(),
|
|
67780
68155
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67852,7 +68227,7 @@ var ValveStatusSchema = object({
|
|
|
67852
68227
|
]),
|
|
67853
68228
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67854
68229
|
* intermediate position surface. */
|
|
67855
|
-
position: number().min(0).max(100).nullable(),
|
|
68230
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67856
68231
|
/** Ms epoch when the slice was last updated. */
|
|
67857
68232
|
lastChangedAt: number()
|
|
67858
68233
|
});
|
|
@@ -67960,9 +68335,9 @@ var vibrationCapability = {
|
|
|
67960
68335
|
*/
|
|
67961
68336
|
var WaterHeaterStatusSchema = object({
|
|
67962
68337
|
/** Current measured temperature. Null when not reported. */
|
|
67963
|
-
currentTemp: number().nullable(),
|
|
68338
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67964
68339
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
67965
|
-
targetTemp: number().nullable(),
|
|
68340
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67966
68341
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
67967
68342
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
67968
68343
|
* device reports an unknown state. */
|
|
@@ -67973,9 +68348,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
67973
68348
|
* has no away surface. */
|
|
67974
68349
|
away: boolean().nullable(),
|
|
67975
68350
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
67976
|
-
minTemp: number().nullable(),
|
|
68351
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67977
68352
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
67978
|
-
maxTemp: number().nullable(),
|
|
68353
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67979
68354
|
/** Ms epoch when the slice was last updated. */
|
|
67980
68355
|
lastChangedAt: number()
|
|
67981
68356
|
});
|
|
@@ -68060,25 +68435,18 @@ var waterHeaterCapability = {
|
|
|
68060
68435
|
* Forecast deferred — current conditions only for v1.
|
|
68061
68436
|
*/
|
|
68062
68437
|
var WeatherStatusSchema = object({
|
|
68063
|
-
/** Verbatim
|
|
68064
|
-
* when no condition has been reported yet. */
|
|
68438
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68065
68439
|
condition: string().nullable(),
|
|
68066
|
-
/** Current temperature in
|
|
68067
|
-
temperature: number().nullable(),
|
|
68068
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68069
|
-
temperatureUnit: string().nullable(),
|
|
68440
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68441
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68070
68442
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68071
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68072
|
-
/** Barometric pressure in
|
|
68073
|
-
pressure: number().nullable(),
|
|
68074
|
-
/**
|
|
68075
|
-
|
|
68076
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68077
|
-
windSpeed: number().nullable(),
|
|
68078
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68079
|
-
windSpeedUnit: string().nullable(),
|
|
68443
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68444
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68445
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68446
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68447
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68080
68448
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68081
|
-
windBearing: number().nullable(),
|
|
68449
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68082
68450
|
/** Ms epoch when the slice was last updated. */
|
|
68083
68451
|
lastFetchedAt: number()
|
|
68084
68452
|
});
|
|
@@ -68106,12 +68474,12 @@ var weatherCapability = {
|
|
|
68106
68474
|
*/
|
|
68107
68475
|
durability: "session",
|
|
68108
68476
|
/**
|
|
68109
|
-
* History (D850): recorded series.
|
|
68477
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68110
68478
|
*/
|
|
68111
68479
|
history: { fields: {
|
|
68112
68480
|
temperature: {
|
|
68113
68481
|
kind: "gauge",
|
|
68114
|
-
|
|
68482
|
+
unit: "°C",
|
|
68115
68483
|
deadband: .2
|
|
68116
68484
|
},
|
|
68117
68485
|
humidity: {
|
|
@@ -68121,12 +68489,12 @@ var weatherCapability = {
|
|
|
68121
68489
|
},
|
|
68122
68490
|
pressure: {
|
|
68123
68491
|
kind: "gauge",
|
|
68124
|
-
|
|
68492
|
+
unit: "hPa",
|
|
68125
68493
|
deadband: .5
|
|
68126
68494
|
},
|
|
68127
68495
|
windSpeed: {
|
|
68128
68496
|
kind: "gauge",
|
|
68129
|
-
|
|
68497
|
+
unit: "m/s",
|
|
68130
68498
|
deadband: .5
|
|
68131
68499
|
}
|
|
68132
68500
|
} }
|
|
@@ -69357,6 +69725,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69357
69725
|
featureProbe: featureProbeCapability,
|
|
69358
69726
|
flood: floodCapability,
|
|
69359
69727
|
gas: gasCapability,
|
|
69728
|
+
groupCommands: groupCommandsCapability,
|
|
69729
|
+
groupStatus: groupStatusCapability,
|
|
69360
69730
|
heatingValve: heatingValveCapability,
|
|
69361
69731
|
humidifier: humidifierCapability,
|
|
69362
69732
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70733,6 +71103,13 @@ Object.freeze({
|
|
|
70733
71103
|
access: "view",
|
|
70734
71104
|
role: "admin"
|
|
70735
71105
|
},
|
|
71106
|
+
"addons.getPackageDocs": {
|
|
71107
|
+
capName: "addons",
|
|
71108
|
+
capScope: "system",
|
|
71109
|
+
addonId: null,
|
|
71110
|
+
access: "view",
|
|
71111
|
+
role: "admin"
|
|
71112
|
+
},
|
|
70736
71113
|
"addons.getVersions": {
|
|
70737
71114
|
capName: "addons",
|
|
70738
71115
|
capScope: "system",
|
|
@@ -73841,6 +74218,20 @@ Object.freeze({
|
|
|
73841
74218
|
access: "view",
|
|
73842
74219
|
role: "viewer"
|
|
73843
74220
|
},
|
|
74221
|
+
"groupCommands.getStatus": {
|
|
74222
|
+
capName: "group-commands",
|
|
74223
|
+
capScope: "device",
|
|
74224
|
+
addonId: null,
|
|
74225
|
+
access: "view",
|
|
74226
|
+
role: "viewer"
|
|
74227
|
+
},
|
|
74228
|
+
"groupStatus.getStatus": {
|
|
74229
|
+
capName: "group-status",
|
|
74230
|
+
capScope: "device",
|
|
74231
|
+
addonId: null,
|
|
74232
|
+
access: "view",
|
|
74233
|
+
role: "viewer"
|
|
74234
|
+
},
|
|
73844
74235
|
"heatingValve.getStatus": {
|
|
73845
74236
|
capName: "heating-valve",
|
|
73846
74237
|
capScope: "device",
|
|
@@ -83663,6 +84054,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83663
84054
|
icon: "flame"
|
|
83664
84055
|
}]
|
|
83665
84056
|
},
|
|
84057
|
+
"group-commands": {
|
|
84058
|
+
scope: "device",
|
|
84059
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84060
|
+
},
|
|
84061
|
+
"group-status": {
|
|
84062
|
+
scope: "device",
|
|
84063
|
+
noun: t("Group", "Gruppo"),
|
|
84064
|
+
state: [
|
|
84065
|
+
{
|
|
84066
|
+
kind: "numeric",
|
|
84067
|
+
field: "included",
|
|
84068
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84069
|
+
label: t("Reporting", "Rispondono"),
|
|
84070
|
+
icon: "users"
|
|
84071
|
+
},
|
|
84072
|
+
{
|
|
84073
|
+
kind: "numeric",
|
|
84074
|
+
field: "excluded",
|
|
84075
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84076
|
+
label: t("Excluded", "Esclusi"),
|
|
84077
|
+
icon: "users"
|
|
84078
|
+
},
|
|
84079
|
+
{
|
|
84080
|
+
kind: "numeric",
|
|
84081
|
+
field: "total",
|
|
84082
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84083
|
+
label: t("Members", "Membri"),
|
|
84084
|
+
icon: "sigma"
|
|
84085
|
+
}
|
|
84086
|
+
]
|
|
84087
|
+
},
|
|
83666
84088
|
"humidity-sensor": {
|
|
83667
84089
|
scope: "device",
|
|
83668
84090
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83696,7 +84118,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83696
84118
|
field: "value",
|
|
83697
84119
|
quantity: t("the reading", "il valore"),
|
|
83698
84120
|
label: t("Reading", "Valore"),
|
|
83699
|
-
unitField: "unit",
|
|
83700
84121
|
icon: "gauge"
|
|
83701
84122
|
}]
|
|
83702
84123
|
},
|
|
@@ -83832,7 +84253,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83832
84253
|
field: "temperature",
|
|
83833
84254
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83834
84255
|
label: t("Temperature", "Temperatura"),
|
|
83835
|
-
|
|
84256
|
+
unit: "°C",
|
|
83836
84257
|
icon: "thermometer"
|
|
83837
84258
|
},
|
|
83838
84259
|
{
|
|
@@ -83848,7 +84269,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83848
84269
|
field: "windSpeed",
|
|
83849
84270
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83850
84271
|
label: t("Wind", "Vento"),
|
|
83851
|
-
|
|
84272
|
+
unit: "m/s",
|
|
83852
84273
|
icon: "wind"
|
|
83853
84274
|
},
|
|
83854
84275
|
{
|
|
@@ -83856,7 +84277,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83856
84277
|
field: "pressure",
|
|
83857
84278
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83858
84279
|
label: t("Pressure", "Pressione"),
|
|
83859
|
-
|
|
84280
|
+
unit: "hPa",
|
|
83860
84281
|
icon: "gauge"
|
|
83861
84282
|
}
|
|
83862
84283
|
]
|
|
@@ -85129,6 +85550,16 @@ Object.freeze({
|
|
|
85129
85550
|
form: "single",
|
|
85130
85551
|
optional: false
|
|
85131
85552
|
}],
|
|
85553
|
+
"groupCommands.getStatus": [{
|
|
85554
|
+
name: "deviceId",
|
|
85555
|
+
form: "single",
|
|
85556
|
+
optional: false
|
|
85557
|
+
}],
|
|
85558
|
+
"groupStatus.getStatus": [{
|
|
85559
|
+
name: "deviceId",
|
|
85560
|
+
form: "single",
|
|
85561
|
+
optional: false
|
|
85562
|
+
}],
|
|
85132
85563
|
"heatingValve.getStatus": [{
|
|
85133
85564
|
name: "deviceId",
|
|
85134
85565
|
form: "single",
|
|
@@ -87113,6 +87544,8 @@ new Map(Object.entries({
|
|
|
87113
87544
|
"detection-blind": "device-events",
|
|
87114
87545
|
"motion-noisy": "device-events",
|
|
87115
87546
|
"motion-calm": "device-events",
|
|
87547
|
+
"package-llm-silent": "device-events",
|
|
87548
|
+
"package-llm-answered": "device-events",
|
|
87116
87549
|
"recording-stalled": "device-events",
|
|
87117
87550
|
"recording-healthy": "device-events",
|
|
87118
87551
|
"recording-degraded": "device-events",
|
|
@@ -87196,6 +87629,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87196
87629
|
label: "Motion without a subject",
|
|
87197
87630
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87198
87631
|
},
|
|
87632
|
+
{
|
|
87633
|
+
id: "package-llm",
|
|
87634
|
+
family: "device-events",
|
|
87635
|
+
label: "Package confirm",
|
|
87636
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87637
|
+
},
|
|
87199
87638
|
{
|
|
87200
87639
|
id: "recording",
|
|
87201
87640
|
family: "device-events",
|
|
@@ -87377,6 +87816,8 @@ var DEVICE_EVENTS = [
|
|
|
87377
87816
|
"detection-blind",
|
|
87378
87817
|
"motion-noisy",
|
|
87379
87818
|
"motion-calm",
|
|
87819
|
+
"package-llm-silent",
|
|
87820
|
+
"package-llm-answered",
|
|
87380
87821
|
"recording-stalled",
|
|
87381
87822
|
"recording-healthy",
|
|
87382
87823
|
"recording-degraded",
|
|
@@ -87645,6 +88086,15 @@ new Map([
|
|
|
87645
88086
|
snapshotLabel: "Cameras with constant motion now",
|
|
87646
88087
|
snapshotSection: null
|
|
87647
88088
|
},
|
|
88089
|
+
{
|
|
88090
|
+
id: "package-llm-confirm",
|
|
88091
|
+
family: "device-events",
|
|
88092
|
+
label: "Package confirm (not answering / answering again)",
|
|
88093
|
+
bad: ["package-llm-silent"],
|
|
88094
|
+
recovery: ["package-llm-answered"],
|
|
88095
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88096
|
+
snapshotSection: null
|
|
88097
|
+
},
|
|
87648
88098
|
{
|
|
87649
88099
|
id: "recording-health",
|
|
87650
88100
|
family: "device-events",
|