@camstack/addon-provider-unifi 0.2.146 → 0.2.148
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 +966 -509
- package/dist/addon.mjs +966 -509
- package/package.json +10 -3
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
|
});
|
|
@@ -57484,21 +57888,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57484
57888
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57485
57889
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57486
57890
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57487
|
-
target: number().nullable(),
|
|
57891
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57488
57892
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57489
57893
|
* in `heat_cool` mode. */
|
|
57490
|
-
targetHigh: number().nullable(),
|
|
57894
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57491
57895
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57492
57896
|
* in `heat_cool` mode. */
|
|
57493
|
-
targetLow: number().nullable(),
|
|
57897
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57494
57898
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57495
57899
|
* humidity control. */
|
|
57496
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57900
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57497
57901
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57498
57902
|
* the device's internal sensor. */
|
|
57499
|
-
currentTemp: number().nullable(),
|
|
57903
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57500
57904
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57501
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57905
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57502
57906
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57503
57907
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57504
57908
|
swingVertical: boolean().nullable(),
|
|
@@ -57506,11 +57910,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57506
57910
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57507
57911
|
swingHorizontal: boolean().nullable(),
|
|
57508
57912
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57509
|
-
minTemp: number().nullable().optional(),
|
|
57913
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57510
57914
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57511
|
-
maxTemp: number().nullable().optional(),
|
|
57915
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57512
57916
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57513
|
-
tempStep: number().positive().nullable().optional(),
|
|
57917
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57514
57918
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57515
57919
|
lastFetchedAt: number()
|
|
57516
57920
|
});
|
|
@@ -57652,17 +58056,17 @@ var climateControlCapability = {
|
|
|
57652
58056
|
* modes to expose in the picker without a slice fetch.
|
|
57653
58057
|
*/
|
|
57654
58058
|
var RgbTripletSchema = object({
|
|
57655
|
-
r: number().int().min(0).max(255),
|
|
57656
|
-
g: number().int().min(0).max(255),
|
|
57657
|
-
b: number().int().min(0).max(255)
|
|
58059
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58060
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58061
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57658
58062
|
});
|
|
57659
58063
|
var HsvTripletSchema = object({
|
|
57660
58064
|
/** Hue in degrees, 0..360. */
|
|
57661
|
-
h: number().min(0).max(360),
|
|
58065
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57662
58066
|
/** Saturation as 0..100 inclusive. */
|
|
57663
|
-
s: number().min(0).max(100),
|
|
58067
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57664
58068
|
/** Value/brightness as 0..100 inclusive. */
|
|
57665
|
-
v: number().min(0).max(100)
|
|
58069
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57666
58070
|
});
|
|
57667
58071
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57668
58072
|
object({
|
|
@@ -57691,7 +58095,7 @@ var ColorStatusSchema = object({
|
|
|
57691
58095
|
/** Populated when `mode === 'hsv'`. */
|
|
57692
58096
|
hsv: HsvTripletSchema.optional(),
|
|
57693
58097
|
/** Populated when `mode === 'mired'`. */
|
|
57694
|
-
mireds: number().int().optional(),
|
|
58098
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57695
58099
|
/** Ms epoch of the last operator-driven change. */
|
|
57696
58100
|
lastChangedAt: number()
|
|
57697
58101
|
});
|
|
@@ -57886,18 +58290,12 @@ _enum([
|
|
|
57886
58290
|
"empty",
|
|
57887
58291
|
"full"
|
|
57888
58292
|
]);
|
|
57889
|
-
/**
|
|
57890
|
-
|
|
57891
|
-
|
|
57892
|
-
"days",
|
|
57893
|
-
"hours",
|
|
57894
|
-
"cycles"
|
|
57895
|
-
]);
|
|
57896
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57897
|
-
* days). `value` null = unknown (D393). */
|
|
58293
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58294
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58295
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57898
58296
|
var ConsumableRemainingSchema = object({
|
|
57899
|
-
value: number().min(0).nullable(),
|
|
57900
|
-
|
|
58297
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58298
|
+
kind: ConsumableRemainingKindSchema
|
|
57901
58299
|
});
|
|
57902
58300
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
57903
58301
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -57910,7 +58308,7 @@ var ConsumableItemSchema = object({
|
|
|
57910
58308
|
/** Display name. */
|
|
57911
58309
|
label: string().min(1),
|
|
57912
58310
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57913
|
-
level: number().min(0).max(100).nullable(),
|
|
58311
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57914
58312
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57915
58313
|
status: ConsumableStatusSchema.nullable(),
|
|
57916
58314
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57992,8 +58390,8 @@ var consumablesCustomize = {
|
|
|
57992
58390
|
transforms: [{ kind: "identity" }]
|
|
57993
58391
|
}],
|
|
57994
58392
|
literals: [{
|
|
57995
|
-
path: "remaining.
|
|
57996
|
-
values: [...
|
|
58393
|
+
path: "remaining.kind",
|
|
58394
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
57997
58395
|
}]
|
|
57998
58396
|
},
|
|
57999
58397
|
{
|
|
@@ -58122,7 +58520,6 @@ reset: method(object({
|
|
|
58122
58520
|
},
|
|
58123
58521
|
"remaining.value": {
|
|
58124
58522
|
kind: "gauge",
|
|
58125
|
-
unitFrom: "remaining.unit",
|
|
58126
58523
|
deadband: 1,
|
|
58127
58524
|
displayName: "Remaining"
|
|
58128
58525
|
}
|
|
@@ -58192,10 +58589,9 @@ var contactCapability = {
|
|
|
58192
58589
|
* (empty array for the other kinds). It lives in the slice because
|
|
58193
58590
|
* HA `select.*` entities may update their options at runtime.
|
|
58194
58591
|
*
|
|
58195
|
-
*
|
|
58196
|
-
*
|
|
58197
|
-
*
|
|
58198
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58592
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58593
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58594
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58199
58595
|
*/
|
|
58200
58596
|
var ControlStatusSchema = object({
|
|
58201
58597
|
kind: _enum([
|
|
@@ -58207,39 +58603,17 @@ var ControlStatusSchema = object({
|
|
|
58207
58603
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58208
58604
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58209
58605
|
* or time-only — HA accepts all three forms). */
|
|
58210
|
-
value: union([number(), string()]),
|
|
58606
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58211
58607
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58212
58608
|
options: array(string()),
|
|
58213
58609
|
/** Ms epoch when the slice was last updated. */
|
|
58214
58610
|
lastChangedAt: number(),
|
|
58215
|
-
/**
|
|
58216
|
-
|
|
58217
|
-
|
|
58218
|
-
|
|
58219
|
-
/**
|
|
58220
|
-
|
|
58221
|
-
min: number().optional(),
|
|
58222
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58223
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58224
|
-
max: number().optional(),
|
|
58225
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58226
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58227
|
-
step: number().optional(),
|
|
58228
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58229
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58230
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58231
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58232
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58233
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58234
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58235
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58236
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58237
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58238
|
-
format: _enum([
|
|
58239
|
-
"date",
|
|
58240
|
-
"time",
|
|
58241
|
-
"datetime"
|
|
58242
|
-
]).optional()
|
|
58611
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58612
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58613
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58614
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58615
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58616
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58243
58617
|
});
|
|
58244
58618
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58245
58619
|
object({
|
|
@@ -58305,9 +58679,9 @@ var CoverStatusSchema = object({
|
|
|
58305
58679
|
]),
|
|
58306
58680
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58307
58681
|
* no intermediate position surface. */
|
|
58308
|
-
position: number().min(0).max(100).nullable(),
|
|
58682
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58309
58683
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58310
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58684
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58311
58685
|
/** Ms epoch when the slice was last updated. */
|
|
58312
58686
|
lastChangedAt: number()
|
|
58313
58687
|
});
|
|
@@ -58410,9 +58784,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58410
58784
|
var DayNightStatusSchema = object({
|
|
58411
58785
|
mode: DayNightModeSchema,
|
|
58412
58786
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58413
|
-
sensitivity: number().optional(),
|
|
58787
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58414
58788
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58415
|
-
switchDelaySec: number().optional(),
|
|
58789
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58416
58790
|
lastFetchedAt: number()
|
|
58417
58791
|
});
|
|
58418
58792
|
/**
|
|
@@ -58630,11 +59004,11 @@ var DishwasherStatusSchema = object({
|
|
|
58630
59004
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58631
59005
|
availablePrograms: array(string()),
|
|
58632
59006
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58633
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59007
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58634
59008
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58635
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59009
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58636
59010
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58637
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59011
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58638
59012
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58639
59013
|
doorOpen: boolean().nullable(),
|
|
58640
59014
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58658,7 +59032,7 @@ var DishwasherStatusSchema = object({
|
|
|
58658
59032
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58659
59033
|
machineCareDue: boolean().nullable(),
|
|
58660
59034
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58661
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59035
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58662
59036
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58663
59037
|
halfLoad: boolean().nullable(),
|
|
58664
59038
|
hygienePlus: boolean().nullable(),
|
|
@@ -58673,7 +59047,7 @@ var DishwasherStatusSchema = object({
|
|
|
58673
59047
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58674
59048
|
activeEvents: array(string()),
|
|
58675
59049
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58676
|
-
errorCode: number().nullable(),
|
|
59050
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58677
59051
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58678
59052
|
errorLabel: string().nullable(),
|
|
58679
59053
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -58885,6 +59259,7 @@ var doorbellCustomize = {
|
|
|
58885
59259
|
applyAuthority: { kind: "composition-claim" },
|
|
58886
59260
|
eventName: "onPressed",
|
|
58887
59261
|
edges: ["rising"],
|
|
59262
|
+
defaultEdge: "rising",
|
|
58888
59263
|
timestampPath: "lastPressedAt",
|
|
58889
59264
|
counterPath: "pressCountSinceStart",
|
|
58890
59265
|
highWater: "composer-advance",
|
|
@@ -58903,7 +59278,7 @@ var DoorbellStatusSchema = object({
|
|
|
58903
59278
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
58904
59279
|
lastPressedAt: number().nullable(),
|
|
58905
59280
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
58906
|
-
pressCountSinceStart: number()
|
|
59281
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
58907
59282
|
});
|
|
58908
59283
|
var DoorbellPressEventSchema = object({
|
|
58909
59284
|
deviceId: number(),
|
|
@@ -58968,17 +59343,7 @@ onPressed: {
|
|
|
58968
59343
|
history: "none",
|
|
58969
59344
|
customize: doorbellCustomize
|
|
58970
59345
|
};
|
|
58971
|
-
|
|
58972
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
58973
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
58974
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
58975
|
-
* The option set is stable across observations; it is persisted in the
|
|
58976
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
58977
|
-
* stored in `sourceInfo`.
|
|
58978
|
-
*/
|
|
58979
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
58980
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
58981
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59346
|
+
_enum([
|
|
58982
59347
|
"date",
|
|
58983
59348
|
"time",
|
|
58984
59349
|
"datetime"
|
|
@@ -58986,12 +59351,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
58986
59351
|
var EnumSensorStatusSchema = object({
|
|
58987
59352
|
value: string(),
|
|
58988
59353
|
/**
|
|
58989
|
-
* Set
|
|
58990
|
-
* as
|
|
58991
|
-
*
|
|
58992
|
-
* a time-only sensor → `'time'`.
|
|
59354
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59355
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59356
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
58993
59357
|
*/
|
|
58994
|
-
|
|
59358
|
+
timestamp: boolean().optional(),
|
|
58995
59359
|
/** Ms epoch when the slice was last updated. */
|
|
58996
59360
|
lastFetchedAt: number()
|
|
58997
59361
|
});
|
|
@@ -59018,11 +59382,11 @@ var enumSensorCapability = {
|
|
|
59018
59382
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59019
59383
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59020
59384
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59021
|
-
* `
|
|
59385
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59022
59386
|
*/
|
|
59023
59387
|
history: { fields: { value: {
|
|
59024
59388
|
kind: "enum",
|
|
59025
|
-
skipWhenSet: "
|
|
59389
|
+
skipWhenSet: "timestamp"
|
|
59026
59390
|
} } },
|
|
59027
59391
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59028
59392
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59042,13 +59406,13 @@ var EventFireSchema = object({
|
|
|
59042
59406
|
deviceId: number(),
|
|
59043
59407
|
eventType: string(),
|
|
59044
59408
|
data: record(string(), unknown()).nullable(),
|
|
59045
|
-
timestamp: number(),
|
|
59046
|
-
seq: number()
|
|
59409
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59410
|
+
seq: number().meta(readingMeta("count"))
|
|
59047
59411
|
});
|
|
59048
59412
|
var EventEmitterStatusSchema = object({
|
|
59049
59413
|
eventTypes: array(string()),
|
|
59050
59414
|
lastEvent: EventFireSchema.nullable(),
|
|
59051
|
-
eventCountSinceStart: number()
|
|
59415
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59052
59416
|
});
|
|
59053
59417
|
var eventEmitterCapability = {
|
|
59054
59418
|
name: "event-emitter",
|
|
@@ -59461,10 +59825,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59461
59825
|
var FanControlStatusSchema = object({
|
|
59462
59826
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59463
59827
|
* speed surface (single-speed fan). */
|
|
59464
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59828
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59465
59829
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59466
59830
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59467
|
-
percentageStep: number().positive().optional(),
|
|
59831
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59468
59832
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59469
59833
|
* — empty string when no preset is active or supported. */
|
|
59470
59834
|
preset: string(),
|
|
@@ -59585,7 +59949,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59585
59949
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59586
59950
|
model: string().nullable(),
|
|
59587
59951
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59588
|
-
channelCount: number().nullable(),
|
|
59952
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59589
59953
|
/**
|
|
59590
59954
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59591
59955
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59708,9 +60072,91 @@ var gasCapability = {
|
|
|
59708
60072
|
* whether persisting is worth a SQLite commit. */
|
|
59709
60073
|
volatileStateFields: ["lastChangedAt"]
|
|
59710
60074
|
};
|
|
60075
|
+
var GroupCommandsSchema = object({
|
|
60076
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60077
|
+
results: array(object({
|
|
60078
|
+
deviceId: number().int().nonnegative(),
|
|
60079
|
+
cap: string().min(1),
|
|
60080
|
+
method: string().min(1),
|
|
60081
|
+
ok: boolean(),
|
|
60082
|
+
error: string().optional(),
|
|
60083
|
+
/** Ms epoch of the attempt. */
|
|
60084
|
+
at: number()
|
|
60085
|
+
})) });
|
|
60086
|
+
var groupCommandsCapability = {
|
|
60087
|
+
name: "group-commands",
|
|
60088
|
+
scope: "device",
|
|
60089
|
+
deviceNative: true,
|
|
60090
|
+
mode: "singleton",
|
|
60091
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60092
|
+
methods: {},
|
|
60093
|
+
status: {
|
|
60094
|
+
schema: GroupCommandsSchema,
|
|
60095
|
+
kind: "push"
|
|
60096
|
+
},
|
|
60097
|
+
runtimeState: GroupCommandsSchema,
|
|
60098
|
+
/**
|
|
60099
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60100
|
+
* failure would outlive the command that caused it.
|
|
60101
|
+
*
|
|
60102
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60103
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60104
|
+
*/
|
|
60105
|
+
durability: "session",
|
|
60106
|
+
history: "none"
|
|
60107
|
+
};
|
|
60108
|
+
/**
|
|
60109
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60110
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60111
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60112
|
+
* series that later statistics read is the output cap's own history block.
|
|
60113
|
+
*/
|
|
60114
|
+
var GroupStatusSchema = object({
|
|
60115
|
+
/** Members whose current value entered the aggregate. */
|
|
60116
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60117
|
+
precision: 0,
|
|
60118
|
+
label: "Reporting"
|
|
60119
|
+
})),
|
|
60120
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60121
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60122
|
+
precision: 0,
|
|
60123
|
+
label: "Excluded"
|
|
60124
|
+
})),
|
|
60125
|
+
/** `included` + `excluded`. */
|
|
60126
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60127
|
+
precision: 0,
|
|
60128
|
+
label: "Members"
|
|
60129
|
+
}))
|
|
60130
|
+
});
|
|
60131
|
+
var groupStatusCapability = {
|
|
60132
|
+
name: "group-status",
|
|
60133
|
+
scope: "device",
|
|
60134
|
+
deviceNative: true,
|
|
60135
|
+
mode: "singleton",
|
|
60136
|
+
deviceTypes: [
|
|
60137
|
+
DeviceType.Sensor,
|
|
60138
|
+
DeviceType.Switch,
|
|
60139
|
+
DeviceType.Light
|
|
60140
|
+
],
|
|
60141
|
+
methods: {},
|
|
60142
|
+
status: {
|
|
60143
|
+
schema: GroupStatusSchema,
|
|
60144
|
+
kind: "push"
|
|
60145
|
+
},
|
|
60146
|
+
runtimeState: GroupStatusSchema,
|
|
60147
|
+
/**
|
|
60148
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60149
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60150
|
+
*
|
|
60151
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60152
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60153
|
+
*/
|
|
60154
|
+
durability: "session",
|
|
60155
|
+
history: "none"
|
|
60156
|
+
};
|
|
59711
60157
|
var HeatingValveStatusSchema = object({
|
|
59712
60158
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59713
|
-
position: number().min(0).max(100).nullable(),
|
|
60159
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59714
60160
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59715
60161
|
lastFetchedAt: number()
|
|
59716
60162
|
});
|
|
@@ -59753,9 +60199,9 @@ var HumidifierStatusSchema = object({
|
|
|
59753
60199
|
/** Whether the humidifier is currently on. */
|
|
59754
60200
|
on: boolean(),
|
|
59755
60201
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59756
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60202
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59757
60203
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59758
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60204
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59759
60205
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59760
60206
|
* device has no mode surface. */
|
|
59761
60207
|
mode: string().nullable(),
|
|
@@ -59765,9 +60211,9 @@ var HumidifierStatusSchema = object({
|
|
|
59765
60211
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59766
60212
|
action: string().nullable(),
|
|
59767
60213
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59768
|
-
minHumidity: number().nullable(),
|
|
60214
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59769
60215
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59770
|
-
maxHumidity: number().nullable(),
|
|
60216
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59771
60217
|
/** Ms epoch when the slice was last updated. */
|
|
59772
60218
|
lastChangedAt: number()
|
|
59773
60219
|
});
|
|
@@ -59837,22 +60283,13 @@ var humidifierCapability = {
|
|
|
59837
60283
|
* `sourceInfo`.
|
|
59838
60284
|
*/
|
|
59839
60285
|
var HumiditySensorStatusSchema = object({
|
|
59840
|
-
/** Current relative humidity, 0..100. */
|
|
59841
|
-
percent: number().min(0).max(100).meta({
|
|
59842
|
-
|
|
60286
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60287
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60288
|
+
precision: 0,
|
|
59843
60289
|
label: "Humidity"
|
|
59844
|
-
}),
|
|
60290
|
+
})),
|
|
59845
60291
|
/** Ms epoch when the slice was last updated. */
|
|
59846
|
-
lastFetchedAt: number()
|
|
59847
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59848
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59849
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59850
|
-
unit: string().optional(),
|
|
59851
|
-
/** Suggested decimal places for numeric display.
|
|
59852
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59853
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59854
|
-
* auto-formatting when absent. */
|
|
59855
|
-
precision: number().int().min(0).max(10).optional()
|
|
60292
|
+
lastFetchedAt: number()
|
|
59856
60293
|
});
|
|
59857
60294
|
var humiditySensorCapability = {
|
|
59858
60295
|
name: "humidity-sensor",
|
|
@@ -59883,12 +60320,7 @@ var humiditySensorCapability = {
|
|
|
59883
60320
|
} } },
|
|
59884
60321
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59885
60322
|
* whether persisting is worth a SQLite commit. */
|
|
59886
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59887
|
-
customize: {
|
|
59888
|
-
version: 1,
|
|
59889
|
-
advanced: "derive",
|
|
59890
|
-
targets: []
|
|
59891
|
-
}
|
|
60323
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59892
60324
|
};
|
|
59893
60325
|
/**
|
|
59894
60326
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -59909,7 +60341,7 @@ var ImageStatusSchema = object({
|
|
|
59909
60341
|
* entity exposes no `entity_picture` (yet). */
|
|
59910
60342
|
url: string().nullable(),
|
|
59911
60343
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
59912
|
-
lastUpdated: number().nullable()
|
|
60344
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
59913
60345
|
});
|
|
59914
60346
|
var imageCapability = {
|
|
59915
60347
|
name: "image",
|
|
@@ -59997,19 +60429,19 @@ var NormalizedRangeSchema = object({
|
|
|
59997
60429
|
*/
|
|
59998
60430
|
var ImageSettingsStatusSchema = object({
|
|
59999
60431
|
/** Normalized 0–100. */
|
|
60000
|
-
brightness: number().optional(),
|
|
60432
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60001
60433
|
/** Normalized 0–100. */
|
|
60002
|
-
contrast: number().optional(),
|
|
60434
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60003
60435
|
/** Normalized 0–100. */
|
|
60004
|
-
saturation: number().optional(),
|
|
60436
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60005
60437
|
/** Normalized 0–100. */
|
|
60006
|
-
sharpness: number().optional(),
|
|
60438
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60007
60439
|
mirror: boolean().optional(),
|
|
60008
60440
|
flip: boolean().optional(),
|
|
60009
60441
|
rotate: ImageRotateSchema.optional(),
|
|
60010
60442
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60011
60443
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60012
|
-
warmth: number().optional(),
|
|
60444
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60013
60445
|
exposureMode: ExposureModeSchema.optional(),
|
|
60014
60446
|
backlightMode: BacklightModeSchema.optional(),
|
|
60015
60447
|
lastFetchedAt: number()
|
|
@@ -60288,10 +60720,10 @@ var IntercomAbilitySchema = object({
|
|
|
60288
60720
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60289
60721
|
codecs: array(string()),
|
|
60290
60722
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60291
|
-
sampleRate: number(),
|
|
60723
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60292
60724
|
duplex: _enum(["half", "full"]),
|
|
60293
60725
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60294
|
-
maxBacklogMs: number()
|
|
60726
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60295
60727
|
});
|
|
60296
60728
|
var IntercomStatusSchema = object({
|
|
60297
60729
|
/** True while a talk session is open. */
|
|
@@ -60518,13 +60950,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60518
60950
|
activity: LawnMowerActivitySchema,
|
|
60519
60951
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60520
60952
|
* reading. */
|
|
60521
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60953
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60522
60954
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60523
60955
|
* task is active / progress is unavailable. */
|
|
60524
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60956
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60525
60957
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60526
60958
|
* or null when unknown. */
|
|
60527
|
-
currentCode: number().nullable(),
|
|
60959
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60528
60960
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60529
60961
|
currentCodeLabel: string().nullable(),
|
|
60530
60962
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61057,7 +61489,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61057
61489
|
state: MediaPlayerStateSchema,
|
|
61058
61490
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61059
61491
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61060
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61492
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61061
61493
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61062
61494
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61063
61495
|
isMuted: boolean().nullable(),
|
|
@@ -61070,10 +61502,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61070
61502
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61071
61503
|
/** Current playback position in ms. Null when not seekable or
|
|
61072
61504
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61073
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61505
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61074
61506
|
/** Total duration of the current media in ms. Null when unknown
|
|
61075
61507
|
* (live stream) or nothing is playing. */
|
|
61076
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61508
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61077
61509
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61078
61510
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61079
61511
|
shuffle: boolean().nullable(),
|
|
@@ -61382,7 +61814,7 @@ var motionCustomize = {
|
|
|
61382
61814
|
eventName: "onMotionChanged"
|
|
61383
61815
|
},
|
|
61384
61816
|
deviceTypes: [DeviceType.Camera],
|
|
61385
|
-
apply: "
|
|
61817
|
+
apply: "add",
|
|
61386
61818
|
applyAuthority: {
|
|
61387
61819
|
kind: "camera-sensors",
|
|
61388
61820
|
timeoutField: "motionCooldownMs"
|
|
@@ -61454,7 +61886,7 @@ var MotionStatusSchema = object({
|
|
|
61454
61886
|
* it, every provider seeded it at boot, and every session left it
|
|
61455
61887
|
* `detected: true` after its detach.
|
|
61456
61888
|
*/
|
|
61457
|
-
autoClearAfterMs: number().nullable()
|
|
61889
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61458
61890
|
});
|
|
61459
61891
|
/**
|
|
61460
61892
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61491,12 +61923,18 @@ var motionCapability = {
|
|
|
61491
61923
|
methods: {
|
|
61492
61924
|
/**
|
|
61493
61925
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61494
|
-
* for consumers that don't need the full status object
|
|
61495
|
-
*
|
|
61496
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61497
|
-
* consumer.
|
|
61926
|
+
* for consumers that don't need the full status object. A composed
|
|
61927
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61498
61928
|
*/
|
|
61499
61929
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
61930
|
+
/**
|
|
61931
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
61932
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
61933
|
+
*/
|
|
61934
|
+
composedMethods: { isDetected: {
|
|
61935
|
+
kind: "slice",
|
|
61936
|
+
field: "detected"
|
|
61937
|
+
} },
|
|
61500
61938
|
events: {
|
|
61501
61939
|
/**
|
|
61502
61940
|
* Fires every time the runner transitions a camera between
|
|
@@ -61636,7 +62074,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61636
62074
|
* the grid region(s). */
|
|
61637
62075
|
var MotionZoneStatusSchema = object({
|
|
61638
62076
|
enabled: boolean(),
|
|
61639
|
-
sensitivity: number(),
|
|
62077
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61640
62078
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61641
62079
|
regions: array(MotionZoneRegionSchema),
|
|
61642
62080
|
lastFetchedAt: number()
|
|
@@ -62006,7 +62444,7 @@ var NavigationStatusSchema = object({
|
|
|
62006
62444
|
following: boolean(),
|
|
62007
62445
|
flash: boolean(),
|
|
62008
62446
|
lightMode: NavigationLightModeSchema,
|
|
62009
|
-
lightLevel: number().min(40).max(100),
|
|
62447
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62010
62448
|
/** Ms epoch when the slice was last updated. */
|
|
62011
62449
|
lastChangedAt: number()
|
|
62012
62450
|
});
|
|
@@ -62140,13 +62578,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62140
62578
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62141
62579
|
* SKIP a null rather than coerce it.
|
|
62142
62580
|
*/
|
|
62143
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62581
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62144
62582
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62145
|
-
rssiDbm: number().optional(),
|
|
62583
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62146
62584
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62147
62585
|
ssid: string().optional(),
|
|
62148
62586
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62149
|
-
lastUpdated: number()
|
|
62587
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62150
62588
|
});
|
|
62151
62589
|
var networkLinkCapability = {
|
|
62152
62590
|
name: "network-link",
|
|
@@ -62531,7 +62969,7 @@ var NotifierStatusSchema = object({
|
|
|
62531
62969
|
lastError: string().nullable(),
|
|
62532
62970
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62533
62971
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62534
|
-
queueDepth: number().int().nonnegative(),
|
|
62972
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62535
62973
|
/** Per-feature capability matrix — authoritative source for the
|
|
62536
62974
|
* compose-form field gating. */
|
|
62537
62975
|
supports: NotifierSupportsSchema
|
|
@@ -62623,11 +63061,9 @@ onSent: { data: object({
|
|
|
62623
63061
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62624
63062
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62625
63063
|
*
|
|
62626
|
-
* The
|
|
62627
|
-
*
|
|
62628
|
-
*
|
|
62629
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62630
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63064
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63065
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63066
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62631
63067
|
*
|
|
62632
63068
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62633
63069
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62636,15 +63072,8 @@ onSent: { data: object({
|
|
|
62636
63072
|
* numeric values land here.
|
|
62637
63073
|
*/
|
|
62638
63074
|
var NumericSensorStatusSchema = object({
|
|
62639
|
-
|
|
62640
|
-
|
|
62641
|
-
* Populated live from the upstream source on each state push.
|
|
62642
|
-
* Absent for unitless sensors. */
|
|
62643
|
-
unit: string().optional(),
|
|
62644
|
-
/** Suggested decimal places for numeric display.
|
|
62645
|
-
* Populated live from the upstream source when provided.
|
|
62646
|
-
* Falls back to auto-formatting when absent. */
|
|
62647
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63075
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63076
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62648
63077
|
/** Ms epoch when the slice was last updated. */
|
|
62649
63078
|
lastFetchedAt: number()
|
|
62650
63079
|
});
|
|
@@ -62668,11 +63097,11 @@ var numericSensorCapability = {
|
|
|
62668
63097
|
*/
|
|
62669
63098
|
durability: "restored",
|
|
62670
63099
|
/**
|
|
62671
|
-
* History (D850): recorded series. The unit is
|
|
63100
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63101
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62672
63102
|
*/
|
|
62673
63103
|
history: { fields: { value: {
|
|
62674
63104
|
kind: "gauge",
|
|
62675
|
-
unitFrom: "unit",
|
|
62676
63105
|
minIntervalMs: 3e4
|
|
62677
63106
|
} } },
|
|
62678
63107
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -62964,23 +63393,26 @@ var PetFeederStatusSchema = object({
|
|
|
62964
63393
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
62965
63394
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
62966
63395
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
62967
|
-
foodLevel: number().nullable(),
|
|
63396
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
62968
63397
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
62969
63398
|
* single-hopper models. */
|
|
62970
|
-
food1: number().nullable(),
|
|
63399
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
62971
63400
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
62972
63401
|
* single-hopper models. */
|
|
62973
|
-
food2: number().nullable(),
|
|
63402
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
62974
63403
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
62975
63404
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
62976
63405
|
* below the feeder's low threshold. */
|
|
62977
63406
|
lowFood: boolean(),
|
|
62978
63407
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
62979
63408
|
* device has no battery reading. */
|
|
62980
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
62981
|
-
/**
|
|
62982
|
-
*
|
|
62983
|
-
|
|
63409
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63410
|
+
/**
|
|
63411
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63412
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63413
|
+
* model has no desiccant sensor.
|
|
63414
|
+
*/
|
|
63415
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
62984
63416
|
/** True while a feed is in progress. */
|
|
62985
63417
|
feeding: boolean(),
|
|
62986
63418
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -62991,7 +63423,7 @@ var PetFeederStatusSchema = object({
|
|
|
62991
63423
|
* with `errorCode` for consumers that want the raw integer. */
|
|
62992
63424
|
error: string().nullable(),
|
|
62993
63425
|
/** Raw device error code (0 / null = no error). */
|
|
62994
|
-
errorCode: number().nullable(),
|
|
63426
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
62995
63427
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
62996
63428
|
isDualHopper: boolean(),
|
|
62997
63429
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63001,7 +63433,7 @@ var PetFeederStatusSchema = object({
|
|
|
63001
63433
|
/** Play a chime when dispensing. */
|
|
63002
63434
|
feedSound: boolean(),
|
|
63003
63435
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63004
|
-
volume: number(),
|
|
63436
|
+
volume: number().meta(readingMeta("none")),
|
|
63005
63437
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63006
63438
|
lastFetchedAt: number()
|
|
63007
63439
|
});
|
|
@@ -63120,7 +63552,7 @@ var petFeederCapability = {
|
|
|
63120
63552
|
},
|
|
63121
63553
|
desiccantLeftDays: {
|
|
63122
63554
|
kind: "gauge",
|
|
63123
|
-
unit: "
|
|
63555
|
+
unit: "s"
|
|
63124
63556
|
}
|
|
63125
63557
|
} }
|
|
63126
63558
|
};
|
|
@@ -63521,36 +63953,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63521
63953
|
*/
|
|
63522
63954
|
var PowerMeterStatusSchema = object({
|
|
63523
63955
|
/** Instantaneous power draw in watts. */
|
|
63524
|
-
watts: number().optional().meta({
|
|
63525
|
-
unit: "W",
|
|
63526
|
-
label: "Power"
|
|
63527
|
-
}),
|
|
63956
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63528
63957
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63529
|
-
kwhTotal: number().optional().meta({
|
|
63530
|
-
unit: "kWh",
|
|
63531
|
-
label: "Energy"
|
|
63532
|
-
}),
|
|
63958
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63533
63959
|
/** Voltage in volts. */
|
|
63534
|
-
volts: number().optional(),
|
|
63960
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63535
63961
|
/** Current in amperes. */
|
|
63536
|
-
amps: number().optional(),
|
|
63537
|
-
/** Apparent power in volt-amperes
|
|
63538
|
-
va: number().optional(),
|
|
63962
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
63963
|
+
/** Apparent power in volt-amperes. */
|
|
63964
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63539
63965
|
/** Power factor (0..1) if reported. */
|
|
63540
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
63966
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63541
63967
|
/** Ms epoch when the slice was last updated. */
|
|
63542
|
-
lastFetchedAt: number()
|
|
63543
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63544
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63545
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63546
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63547
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63548
|
-
unit: string().optional(),
|
|
63549
|
-
/** Suggested decimal places for numeric display.
|
|
63550
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63551
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63552
|
-
* auto-formatting when absent. */
|
|
63553
|
-
precision: number().int().min(0).max(10).optional()
|
|
63968
|
+
lastFetchedAt: number()
|
|
63554
63969
|
});
|
|
63555
63970
|
var powerMeterCapability = {
|
|
63556
63971
|
name: "power-meter",
|
|
@@ -63614,12 +64029,7 @@ var powerMeterCapability = {
|
|
|
63614
64029
|
} },
|
|
63615
64030
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63616
64031
|
* whether persisting is worth a SQLite commit. */
|
|
63617
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63618
|
-
customize: {
|
|
63619
|
-
version: 1,
|
|
63620
|
-
advanced: "derive",
|
|
63621
|
-
targets: []
|
|
63622
|
-
}
|
|
64032
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63623
64033
|
};
|
|
63624
64034
|
/**
|
|
63625
64035
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63639,11 +64049,11 @@ var powerMeterCapability = {
|
|
|
63639
64049
|
*/
|
|
63640
64050
|
var GpsLocationSchema = object({
|
|
63641
64051
|
/** Latitude in decimal degrees, -90..90. */
|
|
63642
|
-
latitude: number().min(-90).max(90),
|
|
64052
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63643
64053
|
/** Longitude in decimal degrees, -180..180. */
|
|
63644
|
-
longitude: number().min(-180).max(180),
|
|
64054
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63645
64055
|
/** Reported accuracy in meters (lower = better). */
|
|
63646
|
-
accuracyMeters: number().nonnegative()
|
|
64056
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63647
64057
|
});
|
|
63648
64058
|
var PresenceStatusSchema = object({
|
|
63649
64059
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63655,7 +64065,7 @@ var PresenceStatusSchema = object({
|
|
|
63655
64065
|
gps: GpsLocationSchema.nullable(),
|
|
63656
64066
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63657
64067
|
* when not reported. */
|
|
63658
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64068
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63659
64069
|
/** Ms epoch when the slice was last updated. */
|
|
63660
64070
|
lastChangedAt: number()
|
|
63661
64071
|
});
|
|
@@ -63705,19 +64115,10 @@ var presenceCapability = {
|
|
|
63705
64115
|
* `sourceInfo`.
|
|
63706
64116
|
*/
|
|
63707
64117
|
var PressureSensorStatusSchema = object({
|
|
63708
|
-
/** Current pressure in hPa. */
|
|
63709
|
-
hpa: number(),
|
|
64118
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64119
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63710
64120
|
/** Ms epoch when the slice was last updated. */
|
|
63711
|
-
lastFetchedAt: number()
|
|
63712
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63713
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63714
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63715
|
-
unit: string().optional(),
|
|
63716
|
-
/** Suggested decimal places for numeric display.
|
|
63717
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63718
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63719
|
-
* auto-formatting when absent. */
|
|
63720
|
-
precision: number().int().min(0).max(10).optional()
|
|
64121
|
+
lastFetchedAt: number()
|
|
63721
64122
|
});
|
|
63722
64123
|
var pressureSensorCapability = {
|
|
63723
64124
|
name: "pressure-sensor",
|
|
@@ -64131,8 +64532,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64131
64532
|
}), _void(), { kind: "mutation" });
|
|
64132
64533
|
var PtzAutotrackSettingsSchema = object({
|
|
64133
64534
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64134
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64135
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64535
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64536
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64136
64537
|
});
|
|
64137
64538
|
/**
|
|
64138
64539
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64286,7 +64687,7 @@ var RunningStateStatusSchema = object({
|
|
|
64286
64687
|
/** null = unknown — never coerced to false (D393). */
|
|
64287
64688
|
running: boolean().nullable(),
|
|
64288
64689
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64289
|
-
since: number().nullable(),
|
|
64690
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64290
64691
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64291
64692
|
phase: string().nullable(),
|
|
64292
64693
|
/** null until a reading has been published (D393). */
|
|
@@ -64301,7 +64702,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64301
64702
|
/** Generic Customize target for the running boolean (D936). */
|
|
64302
64703
|
var runningCustomize = {
|
|
64303
64704
|
version: 1,
|
|
64304
|
-
advanced: "derive",
|
|
64305
64705
|
targets: [{
|
|
64306
64706
|
id: "running",
|
|
64307
64707
|
cardinality: "scalar",
|
|
@@ -64321,7 +64721,7 @@ var runningCustomize = {
|
|
|
64321
64721
|
DeviceType.Thermostat,
|
|
64322
64722
|
DeviceType.PetFeeder
|
|
64323
64723
|
],
|
|
64324
|
-
apply: "add
|
|
64724
|
+
apply: "add",
|
|
64325
64725
|
path: "running",
|
|
64326
64726
|
sources: [
|
|
64327
64727
|
{
|
|
@@ -64337,6 +64737,7 @@ var runningCustomize = {
|
|
|
64337
64737
|
requiredUnit: "W",
|
|
64338
64738
|
transforms: [{
|
|
64339
64739
|
kind: "threshold",
|
|
64740
|
+
comparisons: ["gte", "lte"],
|
|
64340
64741
|
comparison: "gte",
|
|
64341
64742
|
defaultThreshold: 5,
|
|
64342
64743
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -65584,9 +65985,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65584
65985
|
*/
|
|
65585
65986
|
var RecordWindowSchema = object({
|
|
65586
65987
|
trigger: RecordTriggerSchema,
|
|
65587
|
-
day: number().int().min(0).max(6),
|
|
65588
|
-
startMinute: number().int().min(0).max(1439),
|
|
65589
|
-
endMinute: number().int().min(1).max(1440)
|
|
65988
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
65989
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
65990
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65590
65991
|
});
|
|
65591
65992
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65592
65993
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65662,10 +66063,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65662
66063
|
/** Master "record to the card at all" switch. */
|
|
65663
66064
|
enabled: boolean().nullable(),
|
|
65664
66065
|
overwriteWhenFull: boolean().nullable(),
|
|
65665
|
-
preRecordSec: number().nullable(),
|
|
65666
|
-
postRecordSec: number().nullable(),
|
|
66066
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66067
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65667
66068
|
/** Length of one recorded file, in minutes. */
|
|
65668
|
-
segmentMinutes: number().nullable(),
|
|
66069
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65669
66070
|
/** The primary track's weekly windows, flattened. */
|
|
65670
66071
|
windows: array(RecordWindowSchema),
|
|
65671
66072
|
/**
|
|
@@ -65681,7 +66082,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65681
66082
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65682
66083
|
* writable.
|
|
65683
66084
|
*/
|
|
65684
|
-
unreadableWindows: number(),
|
|
66085
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65685
66086
|
/**
|
|
65686
66087
|
* The camera is scheduled to record and has NO usable storage.
|
|
65687
66088
|
*
|
|
@@ -66526,7 +66927,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66526
66927
|
url: string().optional(),
|
|
66527
66928
|
codec: string().optional(),
|
|
66528
66929
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66529
|
-
fps: number().positive().optional(),
|
|
66930
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66530
66931
|
label: string().optional(),
|
|
66531
66932
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66532
66933
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66613,18 +67014,18 @@ var StreamProfileSchema = _enum([
|
|
|
66613
67014
|
]);
|
|
66614
67015
|
/** The current encoding config of one stream profile. */
|
|
66615
67016
|
var StreamProfileConfigSchema = object({
|
|
66616
|
-
width: number(),
|
|
66617
|
-
height: number(),
|
|
67017
|
+
width: number().meta(readingMeta("none")),
|
|
67018
|
+
height: number().meta(readingMeta("none")),
|
|
66618
67019
|
codec: _enum(["h264", "h265"]),
|
|
66619
|
-
framerate: number(),
|
|
66620
|
-
bitrate: number(),
|
|
67020
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67021
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66621
67022
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66622
67023
|
encoderProfile: _enum([
|
|
66623
67024
|
"high",
|
|
66624
67025
|
"main",
|
|
66625
67026
|
"baseline"
|
|
66626
67027
|
]).optional(),
|
|
66627
|
-
gop: number().optional(),
|
|
67028
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66628
67029
|
/**
|
|
66629
67030
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66630
67031
|
*
|
|
@@ -66845,12 +67246,7 @@ var switchCapability = {
|
|
|
66845
67246
|
label: "On",
|
|
66846
67247
|
kind: "boolean"
|
|
66847
67248
|
}
|
|
66848
|
-
}] }
|
|
66849
|
-
customize: {
|
|
66850
|
-
version: 1,
|
|
66851
|
-
advanced: "derive",
|
|
66852
|
-
targets: []
|
|
66853
|
-
}
|
|
67249
|
+
}] }
|
|
66854
67250
|
};
|
|
66855
67251
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66856
67252
|
function hasControlCharacter(value) {
|
|
@@ -67433,35 +67829,21 @@ var tamperCapability = {
|
|
|
67433
67829
|
* entries with `device_class: temperature` and any future native
|
|
67434
67830
|
* thermometer.
|
|
67435
67831
|
*
|
|
67436
|
-
*
|
|
67437
|
-
*
|
|
67438
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67439
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67440
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67441
|
-
* `sourceInfo`.
|
|
67832
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67833
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67442
67834
|
*
|
|
67443
67835
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67444
67836
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67445
67837
|
* changed" steady state.
|
|
67446
67838
|
*/
|
|
67447
67839
|
var TemperatureSensorStatusSchema = object({
|
|
67448
|
-
/** Current temperature in Celsius. */
|
|
67449
|
-
celsius: number().meta({
|
|
67450
|
-
|
|
67840
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67841
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67842
|
+
precision: 1,
|
|
67451
67843
|
label: "Temperature"
|
|
67452
|
-
}),
|
|
67844
|
+
})),
|
|
67453
67845
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67454
|
-
lastFetchedAt: number()
|
|
67455
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67456
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67457
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67458
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67459
|
-
unit: string().optional(),
|
|
67460
|
-
/** Suggested decimal places for numeric display.
|
|
67461
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67462
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67463
|
-
* auto-formatting when absent. */
|
|
67464
|
-
precision: number().int().min(0).max(10).optional()
|
|
67846
|
+
lastFetchedAt: number()
|
|
67465
67847
|
});
|
|
67466
67848
|
var temperatureSensorCapability = {
|
|
67467
67849
|
name: "temperature-sensor",
|
|
@@ -67492,12 +67874,7 @@ var temperatureSensorCapability = {
|
|
|
67492
67874
|
} } },
|
|
67493
67875
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67494
67876
|
* whether persisting is worth a SQLite commit. */
|
|
67495
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67496
|
-
customize: {
|
|
67497
|
-
version: 1,
|
|
67498
|
-
advanced: "derive",
|
|
67499
|
-
targets: []
|
|
67500
|
-
}
|
|
67877
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67501
67878
|
};
|
|
67502
67879
|
/**
|
|
67503
67880
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67780,16 +68157,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67780
68157
|
]),
|
|
67781
68158
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67782
68159
|
* reading. */
|
|
67783
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68160
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67784
68161
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67785
68162
|
* the vacuum has no speed control. */
|
|
67786
68163
|
fanSpeed: string().nullable(),
|
|
67787
68164
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67788
68165
|
availableFanSpeeds: array(string()),
|
|
67789
68166
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67790
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68167
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67791
68168
|
/** Current error code (0 / null = no error). */
|
|
67792
|
-
errorCode: number().nullable(),
|
|
68169
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67793
68170
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67794
68171
|
errorLabel: string().nullable(),
|
|
67795
68172
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67867,7 +68244,7 @@ var ValveStatusSchema = object({
|
|
|
67867
68244
|
]),
|
|
67868
68245
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67869
68246
|
* intermediate position surface. */
|
|
67870
|
-
position: number().min(0).max(100).nullable(),
|
|
68247
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67871
68248
|
/** Ms epoch when the slice was last updated. */
|
|
67872
68249
|
lastChangedAt: number()
|
|
67873
68250
|
});
|
|
@@ -67975,9 +68352,9 @@ var vibrationCapability = {
|
|
|
67975
68352
|
*/
|
|
67976
68353
|
var WaterHeaterStatusSchema = object({
|
|
67977
68354
|
/** Current measured temperature. Null when not reported. */
|
|
67978
|
-
currentTemp: number().nullable(),
|
|
68355
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67979
68356
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
67980
|
-
targetTemp: number().nullable(),
|
|
68357
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67981
68358
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
67982
68359
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
67983
68360
|
* device reports an unknown state. */
|
|
@@ -67988,9 +68365,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
67988
68365
|
* has no away surface. */
|
|
67989
68366
|
away: boolean().nullable(),
|
|
67990
68367
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
67991
|
-
minTemp: number().nullable(),
|
|
68368
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67992
68369
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
67993
|
-
maxTemp: number().nullable(),
|
|
68370
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67994
68371
|
/** Ms epoch when the slice was last updated. */
|
|
67995
68372
|
lastChangedAt: number()
|
|
67996
68373
|
});
|
|
@@ -68075,25 +68452,18 @@ var waterHeaterCapability = {
|
|
|
68075
68452
|
* Forecast deferred — current conditions only for v1.
|
|
68076
68453
|
*/
|
|
68077
68454
|
var WeatherStatusSchema = object({
|
|
68078
|
-
/** Verbatim
|
|
68079
|
-
* when no condition has been reported yet. */
|
|
68455
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68080
68456
|
condition: string().nullable(),
|
|
68081
|
-
/** Current temperature in
|
|
68082
|
-
temperature: number().nullable(),
|
|
68083
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68084
|
-
temperatureUnit: string().nullable(),
|
|
68457
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68458
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68085
68459
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68086
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68087
|
-
/** Barometric pressure in
|
|
68088
|
-
pressure: number().nullable(),
|
|
68089
|
-
/**
|
|
68090
|
-
|
|
68091
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68092
|
-
windSpeed: number().nullable(),
|
|
68093
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68094
|
-
windSpeedUnit: string().nullable(),
|
|
68460
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68461
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68462
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68463
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68464
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68095
68465
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68096
|
-
windBearing: number().nullable(),
|
|
68466
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68097
68467
|
/** Ms epoch when the slice was last updated. */
|
|
68098
68468
|
lastFetchedAt: number()
|
|
68099
68469
|
});
|
|
@@ -68121,12 +68491,12 @@ var weatherCapability = {
|
|
|
68121
68491
|
*/
|
|
68122
68492
|
durability: "session",
|
|
68123
68493
|
/**
|
|
68124
|
-
* History (D850): recorded series.
|
|
68494
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68125
68495
|
*/
|
|
68126
68496
|
history: { fields: {
|
|
68127
68497
|
temperature: {
|
|
68128
68498
|
kind: "gauge",
|
|
68129
|
-
|
|
68499
|
+
unit: "°C",
|
|
68130
68500
|
deadband: .2
|
|
68131
68501
|
},
|
|
68132
68502
|
humidity: {
|
|
@@ -68136,12 +68506,12 @@ var weatherCapability = {
|
|
|
68136
68506
|
},
|
|
68137
68507
|
pressure: {
|
|
68138
68508
|
kind: "gauge",
|
|
68139
|
-
|
|
68509
|
+
unit: "hPa",
|
|
68140
68510
|
deadband: .5
|
|
68141
68511
|
},
|
|
68142
68512
|
windSpeed: {
|
|
68143
68513
|
kind: "gauge",
|
|
68144
|
-
|
|
68514
|
+
unit: "m/s",
|
|
68145
68515
|
deadband: .5
|
|
68146
68516
|
}
|
|
68147
68517
|
} }
|
|
@@ -69372,6 +69742,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69372
69742
|
featureProbe: featureProbeCapability,
|
|
69373
69743
|
flood: floodCapability,
|
|
69374
69744
|
gas: gasCapability,
|
|
69745
|
+
groupCommands: groupCommandsCapability,
|
|
69746
|
+
groupStatus: groupStatusCapability,
|
|
69375
69747
|
heatingValve: heatingValveCapability,
|
|
69376
69748
|
humidifier: humidifierCapability,
|
|
69377
69749
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70748,6 +71120,13 @@ Object.freeze({
|
|
|
70748
71120
|
access: "view",
|
|
70749
71121
|
role: "admin"
|
|
70750
71122
|
},
|
|
71123
|
+
"addons.getPackageDocs": {
|
|
71124
|
+
capName: "addons",
|
|
71125
|
+
capScope: "system",
|
|
71126
|
+
addonId: null,
|
|
71127
|
+
access: "view",
|
|
71128
|
+
role: "admin"
|
|
71129
|
+
},
|
|
70751
71130
|
"addons.getVersions": {
|
|
70752
71131
|
capName: "addons",
|
|
70753
71132
|
capScope: "system",
|
|
@@ -73856,6 +74235,20 @@ Object.freeze({
|
|
|
73856
74235
|
access: "view",
|
|
73857
74236
|
role: "viewer"
|
|
73858
74237
|
},
|
|
74238
|
+
"groupCommands.getStatus": {
|
|
74239
|
+
capName: "group-commands",
|
|
74240
|
+
capScope: "device",
|
|
74241
|
+
addonId: null,
|
|
74242
|
+
access: "view",
|
|
74243
|
+
role: "viewer"
|
|
74244
|
+
},
|
|
74245
|
+
"groupStatus.getStatus": {
|
|
74246
|
+
capName: "group-status",
|
|
74247
|
+
capScope: "device",
|
|
74248
|
+
addonId: null,
|
|
74249
|
+
access: "view",
|
|
74250
|
+
role: "viewer"
|
|
74251
|
+
},
|
|
73859
74252
|
"heatingValve.getStatus": {
|
|
73860
74253
|
capName: "heating-valve",
|
|
73861
74254
|
capScope: "device",
|
|
@@ -83678,6 +84071,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83678
84071
|
icon: "flame"
|
|
83679
84072
|
}]
|
|
83680
84073
|
},
|
|
84074
|
+
"group-commands": {
|
|
84075
|
+
scope: "device",
|
|
84076
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84077
|
+
},
|
|
84078
|
+
"group-status": {
|
|
84079
|
+
scope: "device",
|
|
84080
|
+
noun: t("Group", "Gruppo"),
|
|
84081
|
+
state: [
|
|
84082
|
+
{
|
|
84083
|
+
kind: "numeric",
|
|
84084
|
+
field: "included",
|
|
84085
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84086
|
+
label: t("Reporting", "Rispondono"),
|
|
84087
|
+
icon: "users"
|
|
84088
|
+
},
|
|
84089
|
+
{
|
|
84090
|
+
kind: "numeric",
|
|
84091
|
+
field: "excluded",
|
|
84092
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84093
|
+
label: t("Excluded", "Esclusi"),
|
|
84094
|
+
icon: "users"
|
|
84095
|
+
},
|
|
84096
|
+
{
|
|
84097
|
+
kind: "numeric",
|
|
84098
|
+
field: "total",
|
|
84099
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84100
|
+
label: t("Members", "Membri"),
|
|
84101
|
+
icon: "sigma"
|
|
84102
|
+
}
|
|
84103
|
+
]
|
|
84104
|
+
},
|
|
83681
84105
|
"humidity-sensor": {
|
|
83682
84106
|
scope: "device",
|
|
83683
84107
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83711,7 +84135,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83711
84135
|
field: "value",
|
|
83712
84136
|
quantity: t("the reading", "il valore"),
|
|
83713
84137
|
label: t("Reading", "Valore"),
|
|
83714
|
-
unitField: "unit",
|
|
83715
84138
|
icon: "gauge"
|
|
83716
84139
|
}]
|
|
83717
84140
|
},
|
|
@@ -83847,7 +84270,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83847
84270
|
field: "temperature",
|
|
83848
84271
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83849
84272
|
label: t("Temperature", "Temperatura"),
|
|
83850
|
-
|
|
84273
|
+
unit: "°C",
|
|
83851
84274
|
icon: "thermometer"
|
|
83852
84275
|
},
|
|
83853
84276
|
{
|
|
@@ -83863,7 +84286,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83863
84286
|
field: "windSpeed",
|
|
83864
84287
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83865
84288
|
label: t("Wind", "Vento"),
|
|
83866
|
-
|
|
84289
|
+
unit: "m/s",
|
|
83867
84290
|
icon: "wind"
|
|
83868
84291
|
},
|
|
83869
84292
|
{
|
|
@@ -83871,7 +84294,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83871
84294
|
field: "pressure",
|
|
83872
84295
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83873
84296
|
label: t("Pressure", "Pressione"),
|
|
83874
|
-
|
|
84297
|
+
unit: "hPa",
|
|
83875
84298
|
icon: "gauge"
|
|
83876
84299
|
}
|
|
83877
84300
|
]
|
|
@@ -85144,6 +85567,16 @@ Object.freeze({
|
|
|
85144
85567
|
form: "single",
|
|
85145
85568
|
optional: false
|
|
85146
85569
|
}],
|
|
85570
|
+
"groupCommands.getStatus": [{
|
|
85571
|
+
name: "deviceId",
|
|
85572
|
+
form: "single",
|
|
85573
|
+
optional: false
|
|
85574
|
+
}],
|
|
85575
|
+
"groupStatus.getStatus": [{
|
|
85576
|
+
name: "deviceId",
|
|
85577
|
+
form: "single",
|
|
85578
|
+
optional: false
|
|
85579
|
+
}],
|
|
85147
85580
|
"heatingValve.getStatus": [{
|
|
85148
85581
|
name: "deviceId",
|
|
85149
85582
|
form: "single",
|
|
@@ -87008,6 +87441,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
87008
87441
|
targetId: string().min(1),
|
|
87009
87442
|
enabled: boolean(),
|
|
87010
87443
|
debounceMs: number().nonnegative(),
|
|
87444
|
+
edges: array(_enum([
|
|
87445
|
+
"rising",
|
|
87446
|
+
"button",
|
|
87447
|
+
"native-event"
|
|
87448
|
+
])).min(1).optional(),
|
|
87011
87449
|
sources: array(OverrideSourceSchema).min(1)
|
|
87012
87450
|
});
|
|
87013
87451
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -87123,6 +87561,8 @@ new Map(Object.entries({
|
|
|
87123
87561
|
"detection-blind": "device-events",
|
|
87124
87562
|
"motion-noisy": "device-events",
|
|
87125
87563
|
"motion-calm": "device-events",
|
|
87564
|
+
"package-llm-silent": "device-events",
|
|
87565
|
+
"package-llm-answered": "device-events",
|
|
87126
87566
|
"recording-stalled": "device-events",
|
|
87127
87567
|
"recording-healthy": "device-events",
|
|
87128
87568
|
"recording-degraded": "device-events",
|
|
@@ -87206,6 +87646,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87206
87646
|
label: "Motion without a subject",
|
|
87207
87647
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87208
87648
|
},
|
|
87649
|
+
{
|
|
87650
|
+
id: "package-llm",
|
|
87651
|
+
family: "device-events",
|
|
87652
|
+
label: "Package confirm",
|
|
87653
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87654
|
+
},
|
|
87209
87655
|
{
|
|
87210
87656
|
id: "recording",
|
|
87211
87657
|
family: "device-events",
|
|
@@ -87387,6 +87833,8 @@ var DEVICE_EVENTS = [
|
|
|
87387
87833
|
"detection-blind",
|
|
87388
87834
|
"motion-noisy",
|
|
87389
87835
|
"motion-calm",
|
|
87836
|
+
"package-llm-silent",
|
|
87837
|
+
"package-llm-answered",
|
|
87390
87838
|
"recording-stalled",
|
|
87391
87839
|
"recording-healthy",
|
|
87392
87840
|
"recording-degraded",
|
|
@@ -87655,6 +88103,15 @@ new Map([
|
|
|
87655
88103
|
snapshotLabel: "Cameras with constant motion now",
|
|
87656
88104
|
snapshotSection: null
|
|
87657
88105
|
},
|
|
88106
|
+
{
|
|
88107
|
+
id: "package-llm-confirm",
|
|
88108
|
+
family: "device-events",
|
|
88109
|
+
label: "Package confirm (not answering / answering again)",
|
|
88110
|
+
bad: ["package-llm-silent"],
|
|
88111
|
+
recovery: ["package-llm-answered"],
|
|
88112
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88113
|
+
snapshotSection: null
|
|
88114
|
+
},
|
|
87658
88115
|
{
|
|
87659
88116
|
id: "recording-health",
|
|
87660
88117
|
family: "device-events",
|