@camstack/addon-provider-wyze 0.2.158 → 0.2.159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +18 -0
- package/dist/addon.js +959 -509
- package/dist/addon.mjs +959 -509
- package/package.json +4 -2
package/dist/addon.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { getCACertificates, setDefaultCACertificates } from "node:tls";
|
|
|
10
10
|
//#region \0rolldown/runtime.js
|
|
11
11
|
var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
|
|
12
12
|
//#endregion
|
|
13
|
-
//#region ../types/dist/event-category-
|
|
13
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
14
14
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
15
15
|
EventCategory["SystemBoot"] = "system.boot";
|
|
16
16
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -336,6 +336,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
336
336
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
337
337
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
338
338
|
/**
|
|
339
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
340
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
341
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
342
|
+
*/
|
|
343
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
344
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
345
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
346
|
+
/**
|
|
339
347
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
340
348
|
* (a settings change via `setAgentInferenceDevices` /
|
|
341
349
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5445,7 +5453,7 @@ var ZodIssueCode = {
|
|
|
5445
5453
|
var ZodFirstPartyTypeKind;
|
|
5446
5454
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5447
5455
|
//#endregion
|
|
5448
|
-
//#region ../types/dist/sleep-
|
|
5456
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5449
5457
|
/**
|
|
5450
5458
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5451
5459
|
* window to float samples (D455).
|
|
@@ -7999,6 +8007,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
7999
8007
|
}).strict();
|
|
8000
8008
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8001
8009
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8010
|
+
var READING_QUANTITIES = [
|
|
8011
|
+
"temperature",
|
|
8012
|
+
"pressure",
|
|
8013
|
+
"speed",
|
|
8014
|
+
"precipitation",
|
|
8015
|
+
"precipitation-rate",
|
|
8016
|
+
"length",
|
|
8017
|
+
"area",
|
|
8018
|
+
"illuminance",
|
|
8019
|
+
"irradiance",
|
|
8020
|
+
"power",
|
|
8021
|
+
"energy",
|
|
8022
|
+
"voltage",
|
|
8023
|
+
"current",
|
|
8024
|
+
"apparent-power",
|
|
8025
|
+
"humidity",
|
|
8026
|
+
"percentage",
|
|
8027
|
+
"concentration-volume",
|
|
8028
|
+
"concentration-mass",
|
|
8029
|
+
"concentration-ppb",
|
|
8030
|
+
"volume",
|
|
8031
|
+
"duration",
|
|
8032
|
+
"duration-ms",
|
|
8033
|
+
"information",
|
|
8034
|
+
"sound-level",
|
|
8035
|
+
"signal-level",
|
|
8036
|
+
"colour-temperature",
|
|
8037
|
+
"angle",
|
|
8038
|
+
"bitrate",
|
|
8039
|
+
"rate",
|
|
8040
|
+
"mass",
|
|
8041
|
+
"index",
|
|
8042
|
+
"ratio",
|
|
8043
|
+
"count",
|
|
8044
|
+
"none",
|
|
8045
|
+
"device"
|
|
8046
|
+
];
|
|
8047
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8048
|
+
new Set(READING_QUANTITIES);
|
|
8049
|
+
/**
|
|
8050
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8051
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8052
|
+
*/
|
|
8053
|
+
var QUANTITY_BASE = {
|
|
8054
|
+
temperature: "°C",
|
|
8055
|
+
pressure: "hPa",
|
|
8056
|
+
speed: "m/s",
|
|
8057
|
+
precipitation: "mm",
|
|
8058
|
+
"precipitation-rate": "mm/h",
|
|
8059
|
+
length: "m",
|
|
8060
|
+
area: "m²",
|
|
8061
|
+
illuminance: "lx",
|
|
8062
|
+
irradiance: "W/m²",
|
|
8063
|
+
power: "W",
|
|
8064
|
+
energy: "kWh",
|
|
8065
|
+
voltage: "V",
|
|
8066
|
+
current: "A",
|
|
8067
|
+
"apparent-power": "VA",
|
|
8068
|
+
humidity: "%",
|
|
8069
|
+
percentage: "%",
|
|
8070
|
+
"concentration-volume": "ppm",
|
|
8071
|
+
"concentration-mass": "µg/m³",
|
|
8072
|
+
"concentration-ppb": "ppb",
|
|
8073
|
+
volume: "L",
|
|
8074
|
+
duration: "s",
|
|
8075
|
+
"duration-ms": "ms",
|
|
8076
|
+
information: "B",
|
|
8077
|
+
"sound-level": "dBFS",
|
|
8078
|
+
"signal-level": "dBm",
|
|
8079
|
+
"colour-temperature": "mired",
|
|
8080
|
+
angle: "°",
|
|
8081
|
+
bitrate: "kbps",
|
|
8082
|
+
rate: "fps",
|
|
8083
|
+
mass: "kg",
|
|
8084
|
+
index: "none",
|
|
8085
|
+
ratio: "none",
|
|
8086
|
+
count: "none",
|
|
8087
|
+
none: "none",
|
|
8088
|
+
device: "device"
|
|
8089
|
+
};
|
|
8090
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8091
|
+
function baseUnitOf(quantity) {
|
|
8092
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8093
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8094
|
+
return symbol;
|
|
8095
|
+
}
|
|
8096
|
+
function readingMeta(quantity, extras) {
|
|
8097
|
+
return {
|
|
8098
|
+
quantity,
|
|
8099
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8100
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8101
|
+
};
|
|
8102
|
+
}
|
|
8002
8103
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8003
8104
|
var CamProfileSchema = _enum([
|
|
8004
8105
|
"high",
|
|
@@ -8026,8 +8127,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8026
8127
|
"derived"
|
|
8027
8128
|
]);
|
|
8028
8129
|
var CamStreamResolutionSchema = object({
|
|
8029
|
-
width: number().int().positive(),
|
|
8030
|
-
height: number().int().positive()
|
|
8130
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8131
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8031
8132
|
});
|
|
8032
8133
|
var CameraStreamSchema = object({
|
|
8033
8134
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8545,6 +8646,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8545
8646
|
"filesystem-browse",
|
|
8546
8647
|
"flood",
|
|
8547
8648
|
"gas",
|
|
8649
|
+
"group-commands",
|
|
8650
|
+
"group-status",
|
|
8548
8651
|
"heating-valve",
|
|
8549
8652
|
"humidifier",
|
|
8550
8653
|
"humidity-sensor",
|
|
@@ -8674,14 +8777,6 @@ Object.freeze({
|
|
|
8674
8777
|
{
|
|
8675
8778
|
"path": "aqi",
|
|
8676
8779
|
"valueType": "number"
|
|
8677
|
-
},
|
|
8678
|
-
{
|
|
8679
|
-
"path": "unit",
|
|
8680
|
-
"valueType": "string"
|
|
8681
|
-
},
|
|
8682
|
-
{
|
|
8683
|
-
"path": "precision",
|
|
8684
|
-
"valueType": "number"
|
|
8685
8780
|
}
|
|
8686
8781
|
],
|
|
8687
8782
|
"alarm-panel": [
|
|
@@ -8717,20 +8812,10 @@ Object.freeze({
|
|
|
8717
8812
|
"valueType": "boolean"
|
|
8718
8813
|
}
|
|
8719
8814
|
],
|
|
8720
|
-
"ambient-light-sensor": [
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
},
|
|
8725
|
-
{
|
|
8726
|
-
"path": "unit",
|
|
8727
|
-
"valueType": "string"
|
|
8728
|
-
},
|
|
8729
|
-
{
|
|
8730
|
-
"path": "precision",
|
|
8731
|
-
"valueType": "number"
|
|
8732
|
-
}
|
|
8733
|
-
],
|
|
8815
|
+
"ambient-light-sensor": [{
|
|
8816
|
+
"path": "lux",
|
|
8817
|
+
"valueType": "number"
|
|
8818
|
+
}],
|
|
8734
8819
|
"audio-metrics": [
|
|
8735
8820
|
{
|
|
8736
8821
|
"path": "ts",
|
|
@@ -8810,6 +8895,10 @@ Object.freeze({
|
|
|
8810
8895
|
"path": "lastUpdated",
|
|
8811
8896
|
"valueType": "number"
|
|
8812
8897
|
},
|
|
8898
|
+
{
|
|
8899
|
+
"path": "volts",
|
|
8900
|
+
"valueType": "number"
|
|
8901
|
+
},
|
|
8813
8902
|
{
|
|
8814
8903
|
"path": "lastContactAt",
|
|
8815
8904
|
"valueType": "number"
|
|
@@ -9052,10 +9141,6 @@ Object.freeze({
|
|
|
9052
9141
|
"datetime"
|
|
9053
9142
|
]
|
|
9054
9143
|
},
|
|
9055
|
-
{
|
|
9056
|
-
"path": "unit",
|
|
9057
|
-
"valueType": "string"
|
|
9058
|
-
},
|
|
9059
9144
|
{
|
|
9060
9145
|
"path": "min",
|
|
9061
9146
|
"valueType": "number"
|
|
@@ -9067,19 +9152,6 @@ Object.freeze({
|
|
|
9067
9152
|
{
|
|
9068
9153
|
"path": "step",
|
|
9069
9154
|
"valueType": "number"
|
|
9070
|
-
},
|
|
9071
|
-
{
|
|
9072
|
-
"path": "precision",
|
|
9073
|
-
"valueType": "number"
|
|
9074
|
-
},
|
|
9075
|
-
{
|
|
9076
|
-
"path": "format",
|
|
9077
|
-
"valueType": "enum",
|
|
9078
|
-
"enumValues": [
|
|
9079
|
-
"date",
|
|
9080
|
-
"time",
|
|
9081
|
-
"datetime"
|
|
9082
|
-
]
|
|
9083
9155
|
}
|
|
9084
9156
|
],
|
|
9085
9157
|
"cover": [
|
|
@@ -9320,13 +9392,8 @@ Object.freeze({
|
|
|
9320
9392
|
"path": "value",
|
|
9321
9393
|
"valueType": "string"
|
|
9322
9394
|
}, {
|
|
9323
|
-
"path": "
|
|
9324
|
-
"valueType": "
|
|
9325
|
-
"enumValues": [
|
|
9326
|
-
"date",
|
|
9327
|
-
"time",
|
|
9328
|
-
"datetime"
|
|
9329
|
-
]
|
|
9395
|
+
"path": "timestamp",
|
|
9396
|
+
"valueType": "boolean"
|
|
9330
9397
|
}],
|
|
9331
9398
|
"event-emitter": [
|
|
9332
9399
|
{
|
|
@@ -9399,6 +9466,20 @@ Object.freeze({
|
|
|
9399
9466
|
"path": "detected",
|
|
9400
9467
|
"valueType": "boolean"
|
|
9401
9468
|
}],
|
|
9469
|
+
"group-status": [
|
|
9470
|
+
{
|
|
9471
|
+
"path": "included",
|
|
9472
|
+
"valueType": "number"
|
|
9473
|
+
},
|
|
9474
|
+
{
|
|
9475
|
+
"path": "excluded",
|
|
9476
|
+
"valueType": "number"
|
|
9477
|
+
},
|
|
9478
|
+
{
|
|
9479
|
+
"path": "total",
|
|
9480
|
+
"valueType": "number"
|
|
9481
|
+
}
|
|
9482
|
+
],
|
|
9402
9483
|
"heating-valve": [{
|
|
9403
9484
|
"path": "position",
|
|
9404
9485
|
"valueType": "number"
|
|
@@ -9433,20 +9514,10 @@ Object.freeze({
|
|
|
9433
9514
|
"valueType": "number"
|
|
9434
9515
|
}
|
|
9435
9516
|
],
|
|
9436
|
-
"humidity-sensor": [
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
},
|
|
9441
|
-
{
|
|
9442
|
-
"path": "unit",
|
|
9443
|
-
"valueType": "string"
|
|
9444
|
-
},
|
|
9445
|
-
{
|
|
9446
|
-
"path": "precision",
|
|
9447
|
-
"valueType": "number"
|
|
9448
|
-
}
|
|
9449
|
-
],
|
|
9517
|
+
"humidity-sensor": [{
|
|
9518
|
+
"path": "percent",
|
|
9519
|
+
"valueType": "number"
|
|
9520
|
+
}],
|
|
9450
9521
|
"image": [{
|
|
9451
9522
|
"path": "url",
|
|
9452
9523
|
"valueType": "string"
|
|
@@ -9785,20 +9856,10 @@ Object.freeze({
|
|
|
9785
9856
|
"valueType": "boolean"
|
|
9786
9857
|
}
|
|
9787
9858
|
],
|
|
9788
|
-
"numeric-sensor": [
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
},
|
|
9793
|
-
{
|
|
9794
|
-
"path": "unit",
|
|
9795
|
-
"valueType": "string"
|
|
9796
|
-
},
|
|
9797
|
-
{
|
|
9798
|
-
"path": "precision",
|
|
9799
|
-
"valueType": "number"
|
|
9800
|
-
}
|
|
9801
|
-
],
|
|
9859
|
+
"numeric-sensor": [{
|
|
9860
|
+
"path": "value",
|
|
9861
|
+
"valueType": "number"
|
|
9862
|
+
}],
|
|
9802
9863
|
"pet-feeder": [
|
|
9803
9864
|
{
|
|
9804
9865
|
"path": "foodLevel",
|
|
@@ -9890,14 +9951,6 @@ Object.freeze({
|
|
|
9890
9951
|
{
|
|
9891
9952
|
"path": "powerFactor",
|
|
9892
9953
|
"valueType": "number"
|
|
9893
|
-
},
|
|
9894
|
-
{
|
|
9895
|
-
"path": "unit",
|
|
9896
|
-
"valueType": "string"
|
|
9897
|
-
},
|
|
9898
|
-
{
|
|
9899
|
-
"path": "precision",
|
|
9900
|
-
"valueType": "number"
|
|
9901
9954
|
}
|
|
9902
9955
|
],
|
|
9903
9956
|
"presence": [
|
|
@@ -9926,20 +9979,10 @@ Object.freeze({
|
|
|
9926
9979
|
"valueType": "number"
|
|
9927
9980
|
}
|
|
9928
9981
|
],
|
|
9929
|
-
"pressure-sensor": [
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
},
|
|
9934
|
-
{
|
|
9935
|
-
"path": "unit",
|
|
9936
|
-
"valueType": "string"
|
|
9937
|
-
},
|
|
9938
|
-
{
|
|
9939
|
-
"path": "precision",
|
|
9940
|
-
"valueType": "number"
|
|
9941
|
-
}
|
|
9942
|
-
],
|
|
9982
|
+
"pressure-sensor": [{
|
|
9983
|
+
"path": "hpa",
|
|
9984
|
+
"valueType": "number"
|
|
9985
|
+
}],
|
|
9943
9986
|
"privacy-mask": [{
|
|
9944
9987
|
"path": "enabled",
|
|
9945
9988
|
"valueType": "boolean"
|
|
@@ -10250,20 +10293,10 @@ Object.freeze({
|
|
|
10250
10293
|
"path": "tampered",
|
|
10251
10294
|
"valueType": "boolean"
|
|
10252
10295
|
}],
|
|
10253
|
-
"temperature-sensor": [
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
},
|
|
10258
|
-
{
|
|
10259
|
-
"path": "unit",
|
|
10260
|
-
"valueType": "string"
|
|
10261
|
-
},
|
|
10262
|
-
{
|
|
10263
|
-
"path": "precision",
|
|
10264
|
-
"valueType": "number"
|
|
10265
|
-
}
|
|
10266
|
-
],
|
|
10296
|
+
"temperature-sensor": [{
|
|
10297
|
+
"path": "celsius",
|
|
10298
|
+
"valueType": "number"
|
|
10299
|
+
}],
|
|
10267
10300
|
"update": [
|
|
10268
10301
|
{
|
|
10269
10302
|
"path": "currentVersion",
|
|
@@ -10374,10 +10407,6 @@ Object.freeze({
|
|
|
10374
10407
|
"path": "temperature",
|
|
10375
10408
|
"valueType": "number"
|
|
10376
10409
|
},
|
|
10377
|
-
{
|
|
10378
|
-
"path": "temperatureUnit",
|
|
10379
|
-
"valueType": "string"
|
|
10380
|
-
},
|
|
10381
10410
|
{
|
|
10382
10411
|
"path": "humidity",
|
|
10383
10412
|
"valueType": "number"
|
|
@@ -10386,18 +10415,10 @@ Object.freeze({
|
|
|
10386
10415
|
"path": "pressure",
|
|
10387
10416
|
"valueType": "number"
|
|
10388
10417
|
},
|
|
10389
|
-
{
|
|
10390
|
-
"path": "pressureUnit",
|
|
10391
|
-
"valueType": "string"
|
|
10392
|
-
},
|
|
10393
10418
|
{
|
|
10394
10419
|
"path": "windSpeed",
|
|
10395
10420
|
"valueType": "number"
|
|
10396
10421
|
},
|
|
10397
|
-
{
|
|
10398
|
-
"path": "windSpeedUnit",
|
|
10399
|
-
"valueType": "string"
|
|
10400
|
-
},
|
|
10401
10422
|
{
|
|
10402
10423
|
"path": "windBearing",
|
|
10403
10424
|
"valueType": "number"
|
|
@@ -10814,7 +10835,7 @@ function errMsg(err) {
|
|
|
10814
10835
|
return String(err);
|
|
10815
10836
|
}
|
|
10816
10837
|
//#endregion
|
|
10817
|
-
//#region ../types/dist/composition-
|
|
10838
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10818
10839
|
/**
|
|
10819
10840
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10820
10841
|
*
|
|
@@ -11569,15 +11590,74 @@ function validateExpressionSource(src) {
|
|
|
11569
11590
|
}
|
|
11570
11591
|
return null;
|
|
11571
11592
|
}
|
|
11572
|
-
/**
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11593
|
+
/**
|
|
11594
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11595
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11596
|
+
* `composition.ts` (D659).
|
|
11597
|
+
*/
|
|
11576
11598
|
var CompositionSourceRefSchema = object({
|
|
11577
11599
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11578
11600
|
addonId: string().min(1),
|
|
11579
11601
|
stableId: string().min(1)
|
|
11580
11602
|
});
|
|
11603
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11604
|
+
"temperature",
|
|
11605
|
+
"humidity",
|
|
11606
|
+
"pressure",
|
|
11607
|
+
"illuminance",
|
|
11608
|
+
"power",
|
|
11609
|
+
"energy",
|
|
11610
|
+
"battery",
|
|
11611
|
+
"numeric",
|
|
11612
|
+
"motion",
|
|
11613
|
+
"contact",
|
|
11614
|
+
"leak",
|
|
11615
|
+
"smoke",
|
|
11616
|
+
"occupancy",
|
|
11617
|
+
"binary",
|
|
11618
|
+
"switch",
|
|
11619
|
+
"light"
|
|
11620
|
+
];
|
|
11621
|
+
var NUMERIC_AGGREGATES = [
|
|
11622
|
+
"mean",
|
|
11623
|
+
"median",
|
|
11624
|
+
"min",
|
|
11625
|
+
"max",
|
|
11626
|
+
"sum"
|
|
11627
|
+
];
|
|
11628
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11629
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11630
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11631
|
+
var AGGREGATE_REDUCERS = [
|
|
11632
|
+
"mean",
|
|
11633
|
+
"median",
|
|
11634
|
+
"min",
|
|
11635
|
+
"max",
|
|
11636
|
+
"sum",
|
|
11637
|
+
"any",
|
|
11638
|
+
"all"
|
|
11639
|
+
];
|
|
11640
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11641
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11642
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11643
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11644
|
+
var HelperMemberSchema = object({
|
|
11645
|
+
source: CompositionSourceRefSchema,
|
|
11646
|
+
cap: string().min(1),
|
|
11647
|
+
fieldPath: string().min(1)
|
|
11648
|
+
});
|
|
11649
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11650
|
+
kind: literal("group"),
|
|
11651
|
+
templateId: GroupTemplateIdSchema,
|
|
11652
|
+
aggregate: AggregateReducerSchema,
|
|
11653
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11654
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11655
|
+
active: ActiveCriterionSchema.optional()
|
|
11656
|
+
})]);
|
|
11657
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11658
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11659
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11660
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11581
11661
|
/** One field of one capability of one source device. */
|
|
11582
11662
|
var CompositionFieldReadSchema = object({
|
|
11583
11663
|
source: CompositionSourceRefSchema,
|
|
@@ -11621,7 +11701,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11621
11701
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11622
11702
|
CompositionFromSourceSchema,
|
|
11623
11703
|
CompositionExpressionSourceSchema,
|
|
11624
|
-
CompositionCodeSourceSchema
|
|
11704
|
+
CompositionCodeSourceSchema,
|
|
11705
|
+
object({
|
|
11706
|
+
kind: literal("aggregate"),
|
|
11707
|
+
reducer: _enum([
|
|
11708
|
+
"mean",
|
|
11709
|
+
"median",
|
|
11710
|
+
"min",
|
|
11711
|
+
"max",
|
|
11712
|
+
"sum",
|
|
11713
|
+
"any",
|
|
11714
|
+
"all"
|
|
11715
|
+
]),
|
|
11716
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11717
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11718
|
+
publish: _enum([
|
|
11719
|
+
"value",
|
|
11720
|
+
"included",
|
|
11721
|
+
"excluded",
|
|
11722
|
+
"total"
|
|
11723
|
+
]),
|
|
11724
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11725
|
+
empty: _enum([
|
|
11726
|
+
"null",
|
|
11727
|
+
"omit",
|
|
11728
|
+
"offline"
|
|
11729
|
+
])
|
|
11730
|
+
})
|
|
11625
11731
|
]);
|
|
11626
11732
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11627
11733
|
kind: literal("forward"),
|
|
@@ -11667,7 +11773,13 @@ var CompositionSchema = object({
|
|
|
11667
11773
|
kind: literal("existing"),
|
|
11668
11774
|
device: CompositionSourceRefSchema
|
|
11669
11775
|
})]),
|
|
11670
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11776
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11777
|
+
/**
|
|
11778
|
+
* Present when the block is a helper template. Absent on a free
|
|
11779
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11780
|
+
* never the compiled features.
|
|
11781
|
+
*/
|
|
11782
|
+
helper: HelperSpecSchema.optional()
|
|
11671
11783
|
}).superRefine((composition, ctx) => {
|
|
11672
11784
|
const seen = /* @__PURE__ */ new Set();
|
|
11673
11785
|
composition.features.forEach((feature, index) => {
|
|
@@ -17895,7 +18007,11 @@ var CompositionProblemSchema = object({
|
|
|
17895
18007
|
"item-field-reserved",
|
|
17896
18008
|
"target-missing",
|
|
17897
18009
|
"target-unreadable",
|
|
17898
|
-
"not-replaceable"
|
|
18010
|
+
"not-replaceable",
|
|
18011
|
+
"native-capability-replace",
|
|
18012
|
+
"mixed-quantity",
|
|
18013
|
+
"helper-mismatch",
|
|
18014
|
+
"member-constraint"
|
|
17899
18015
|
]),
|
|
17900
18016
|
path: string(),
|
|
17901
18017
|
message: string()
|
|
@@ -17916,7 +18032,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17916
18032
|
"null",
|
|
17917
18033
|
"offline",
|
|
17918
18034
|
"unknown",
|
|
17919
|
-
"release"
|
|
18035
|
+
"release",
|
|
18036
|
+
"omit"
|
|
17920
18037
|
]);
|
|
17921
18038
|
/**
|
|
17922
18039
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -17953,9 +18070,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17953
18070
|
reads: array(CompositionFieldReadSchema)
|
|
17954
18071
|
});
|
|
17955
18072
|
/**
|
|
17956
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17957
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17958
|
-
*
|
|
18073
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18074
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18075
|
+
* Replacing a capability the device already serves is refused
|
|
18076
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18077
|
+
* wire for a claim the hub already holds.
|
|
17959
18078
|
*/
|
|
17960
18079
|
var CompositionFeatureModeSchema = _enum([
|
|
17961
18080
|
"new",
|
|
@@ -18128,6 +18247,275 @@ Object.freeze({
|
|
|
18128
18247
|
result: ["number", "null"]
|
|
18129
18248
|
}
|
|
18130
18249
|
});
|
|
18250
|
+
/**
|
|
18251
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18252
|
+
* Data, not a form default written into the block.
|
|
18253
|
+
*/
|
|
18254
|
+
var NOW = {
|
|
18255
|
+
fieldPath: "lastFetchedAt",
|
|
18256
|
+
expr: "now"
|
|
18257
|
+
};
|
|
18258
|
+
var CHANGED = {
|
|
18259
|
+
fieldPath: "lastChangedAt",
|
|
18260
|
+
expr: "now"
|
|
18261
|
+
};
|
|
18262
|
+
function numeric(input) {
|
|
18263
|
+
return {
|
|
18264
|
+
...input,
|
|
18265
|
+
family: "numeric",
|
|
18266
|
+
deviceType: DeviceType.Sensor,
|
|
18267
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18268
|
+
commandCaps: [],
|
|
18269
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18270
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18271
|
+
accept: [{
|
|
18272
|
+
cap: input.outputCap,
|
|
18273
|
+
fieldPath: input.outputField
|
|
18274
|
+
}]
|
|
18275
|
+
};
|
|
18276
|
+
}
|
|
18277
|
+
function binary(input) {
|
|
18278
|
+
return {
|
|
18279
|
+
...input,
|
|
18280
|
+
family: "binary",
|
|
18281
|
+
deviceType: DeviceType.Sensor,
|
|
18282
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18283
|
+
commandCaps: [],
|
|
18284
|
+
quantity: "none",
|
|
18285
|
+
baseUnit: void 0,
|
|
18286
|
+
aggregates: BINARY_AGGREGATES,
|
|
18287
|
+
empty: "offline"
|
|
18288
|
+
};
|
|
18289
|
+
}
|
|
18290
|
+
var GROUP_TEMPLATES = [
|
|
18291
|
+
numeric({
|
|
18292
|
+
id: "temperature",
|
|
18293
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18294
|
+
role: DeviceRole.TemperatureSensor,
|
|
18295
|
+
outputCap: "temperature-sensor",
|
|
18296
|
+
outputField: "celsius",
|
|
18297
|
+
quantity: "temperature",
|
|
18298
|
+
defaultAggregate: "mean",
|
|
18299
|
+
empty: "null",
|
|
18300
|
+
companions: [NOW]
|
|
18301
|
+
}),
|
|
18302
|
+
numeric({
|
|
18303
|
+
id: "humidity",
|
|
18304
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18305
|
+
role: DeviceRole.HumiditySensor,
|
|
18306
|
+
outputCap: "humidity-sensor",
|
|
18307
|
+
outputField: "percent",
|
|
18308
|
+
quantity: "humidity",
|
|
18309
|
+
defaultAggregate: "mean",
|
|
18310
|
+
empty: "null",
|
|
18311
|
+
companions: [NOW]
|
|
18312
|
+
}),
|
|
18313
|
+
numeric({
|
|
18314
|
+
id: "pressure",
|
|
18315
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18316
|
+
role: DeviceRole.PressureSensor,
|
|
18317
|
+
outputCap: "pressure-sensor",
|
|
18318
|
+
outputField: "hpa",
|
|
18319
|
+
quantity: "pressure",
|
|
18320
|
+
defaultAggregate: "mean",
|
|
18321
|
+
empty: "null",
|
|
18322
|
+
companions: [NOW]
|
|
18323
|
+
}),
|
|
18324
|
+
numeric({
|
|
18325
|
+
id: "illuminance",
|
|
18326
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18327
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18328
|
+
outputCap: "ambient-light-sensor",
|
|
18329
|
+
outputField: "lux",
|
|
18330
|
+
quantity: "illuminance",
|
|
18331
|
+
defaultAggregate: "mean",
|
|
18332
|
+
empty: "null",
|
|
18333
|
+
companions: [NOW]
|
|
18334
|
+
}),
|
|
18335
|
+
numeric({
|
|
18336
|
+
id: "power",
|
|
18337
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18338
|
+
role: DeviceRole.PowerSensor,
|
|
18339
|
+
outputCap: "power-meter",
|
|
18340
|
+
outputField: "watts",
|
|
18341
|
+
quantity: "power",
|
|
18342
|
+
defaultAggregate: "sum",
|
|
18343
|
+
empty: "omit",
|
|
18344
|
+
companions: [NOW]
|
|
18345
|
+
}),
|
|
18346
|
+
numeric({
|
|
18347
|
+
id: "energy",
|
|
18348
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18349
|
+
role: DeviceRole.EnergySensor,
|
|
18350
|
+
outputCap: "power-meter",
|
|
18351
|
+
outputField: "kwhTotal",
|
|
18352
|
+
quantity: "energy",
|
|
18353
|
+
defaultAggregate: "sum",
|
|
18354
|
+
empty: "omit",
|
|
18355
|
+
companions: [NOW]
|
|
18356
|
+
}),
|
|
18357
|
+
numeric({
|
|
18358
|
+
id: "battery",
|
|
18359
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18360
|
+
role: DeviceRole.BatterySensor,
|
|
18361
|
+
outputCap: "battery",
|
|
18362
|
+
outputField: "percentage",
|
|
18363
|
+
quantity: "percentage",
|
|
18364
|
+
defaultAggregate: "mean",
|
|
18365
|
+
empty: "null",
|
|
18366
|
+
companions: [
|
|
18367
|
+
{
|
|
18368
|
+
fieldPath: "charging",
|
|
18369
|
+
expr: "\"unknown\""
|
|
18370
|
+
},
|
|
18371
|
+
{
|
|
18372
|
+
fieldPath: "sleeping",
|
|
18373
|
+
expr: "false"
|
|
18374
|
+
},
|
|
18375
|
+
{
|
|
18376
|
+
fieldPath: "lastUpdated",
|
|
18377
|
+
expr: "now"
|
|
18378
|
+
}
|
|
18379
|
+
]
|
|
18380
|
+
}),
|
|
18381
|
+
numeric({
|
|
18382
|
+
id: "numeric",
|
|
18383
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18384
|
+
role: DeviceRole.NumericSensor,
|
|
18385
|
+
outputCap: "numeric-sensor",
|
|
18386
|
+
outputField: "value",
|
|
18387
|
+
quantity: "device",
|
|
18388
|
+
defaultAggregate: "mean",
|
|
18389
|
+
empty: "null",
|
|
18390
|
+
companions: [NOW]
|
|
18391
|
+
}),
|
|
18392
|
+
binary({
|
|
18393
|
+
id: "motion",
|
|
18394
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18395
|
+
role: DeviceRole.MotionSensor,
|
|
18396
|
+
outputCap: "motion",
|
|
18397
|
+
outputField: "detected",
|
|
18398
|
+
defaultAggregate: "any",
|
|
18399
|
+
accept: [{
|
|
18400
|
+
cap: "motion",
|
|
18401
|
+
fieldPath: "detected"
|
|
18402
|
+
}],
|
|
18403
|
+
companions: [{
|
|
18404
|
+
fieldPath: "lastDetectedAt",
|
|
18405
|
+
expr: "null"
|
|
18406
|
+
}, {
|
|
18407
|
+
fieldPath: "autoClearAfterMs",
|
|
18408
|
+
expr: "null"
|
|
18409
|
+
}]
|
|
18410
|
+
}),
|
|
18411
|
+
binary({
|
|
18412
|
+
id: "contact",
|
|
18413
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18414
|
+
role: DeviceRole.ContactSensor,
|
|
18415
|
+
outputCap: "contact",
|
|
18416
|
+
outputField: "entryOpen",
|
|
18417
|
+
defaultAggregate: "any",
|
|
18418
|
+
accept: [{
|
|
18419
|
+
cap: "contact",
|
|
18420
|
+
fieldPath: "entryOpen"
|
|
18421
|
+
}],
|
|
18422
|
+
companions: [CHANGED]
|
|
18423
|
+
}),
|
|
18424
|
+
binary({
|
|
18425
|
+
id: "leak",
|
|
18426
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18427
|
+
role: DeviceRole.LeakSensor,
|
|
18428
|
+
outputCap: "flood",
|
|
18429
|
+
outputField: "flooded",
|
|
18430
|
+
defaultAggregate: "any",
|
|
18431
|
+
accept: [{
|
|
18432
|
+
cap: "flood",
|
|
18433
|
+
fieldPath: "flooded"
|
|
18434
|
+
}],
|
|
18435
|
+
companions: [CHANGED]
|
|
18436
|
+
}),
|
|
18437
|
+
binary({
|
|
18438
|
+
id: "smoke",
|
|
18439
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18440
|
+
role: DeviceRole.SmokeSensor,
|
|
18441
|
+
outputCap: "smoke",
|
|
18442
|
+
outputField: "detected",
|
|
18443
|
+
defaultAggregate: "any",
|
|
18444
|
+
accept: [{
|
|
18445
|
+
cap: "smoke",
|
|
18446
|
+
fieldPath: "detected"
|
|
18447
|
+
}],
|
|
18448
|
+
companions: [CHANGED]
|
|
18449
|
+
}),
|
|
18450
|
+
binary({
|
|
18451
|
+
id: "occupancy",
|
|
18452
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18453
|
+
role: DeviceRole.BinarySensor,
|
|
18454
|
+
outputCap: "binary",
|
|
18455
|
+
outputField: "on",
|
|
18456
|
+
defaultAggregate: "any",
|
|
18457
|
+
accept: [{
|
|
18458
|
+
cap: "motion",
|
|
18459
|
+
fieldPath: "detected"
|
|
18460
|
+
}, {
|
|
18461
|
+
cap: "binary",
|
|
18462
|
+
fieldPath: "on"
|
|
18463
|
+
}],
|
|
18464
|
+
companions: [CHANGED]
|
|
18465
|
+
}),
|
|
18466
|
+
binary({
|
|
18467
|
+
id: "binary",
|
|
18468
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18469
|
+
role: DeviceRole.BinarySensor,
|
|
18470
|
+
outputCap: "binary",
|
|
18471
|
+
outputField: "on",
|
|
18472
|
+
defaultAggregate: "any",
|
|
18473
|
+
accept: [{
|
|
18474
|
+
cap: "binary",
|
|
18475
|
+
fieldPath: "on"
|
|
18476
|
+
}],
|
|
18477
|
+
companions: [CHANGED]
|
|
18478
|
+
}),
|
|
18479
|
+
actuator({
|
|
18480
|
+
id: "switch",
|
|
18481
|
+
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.",
|
|
18482
|
+
deviceType: DeviceType.Switch,
|
|
18483
|
+
outputCap: "switch",
|
|
18484
|
+
commandCaps: ["switch"]
|
|
18485
|
+
}),
|
|
18486
|
+
actuator({
|
|
18487
|
+
id: "light",
|
|
18488
|
+
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.",
|
|
18489
|
+
deviceType: DeviceType.Light,
|
|
18490
|
+
outputCap: "switch",
|
|
18491
|
+
commandCaps: [
|
|
18492
|
+
"switch",
|
|
18493
|
+
"brightness",
|
|
18494
|
+
"color"
|
|
18495
|
+
]
|
|
18496
|
+
})
|
|
18497
|
+
];
|
|
18498
|
+
function actuator(input) {
|
|
18499
|
+
return {
|
|
18500
|
+
...input,
|
|
18501
|
+
family: "actuator",
|
|
18502
|
+
role: void 0,
|
|
18503
|
+
memberDeviceType: input.deviceType,
|
|
18504
|
+
outputField: "on",
|
|
18505
|
+
quantity: "none",
|
|
18506
|
+
baseUnit: void 0,
|
|
18507
|
+
aggregates: BINARY_AGGREGATES,
|
|
18508
|
+
defaultAggregate: "any",
|
|
18509
|
+
empty: "offline",
|
|
18510
|
+
accept: [{
|
|
18511
|
+
cap: "switch",
|
|
18512
|
+
fieldPath: "on"
|
|
18513
|
+
}],
|
|
18514
|
+
companions: [CHANGED]
|
|
18515
|
+
};
|
|
18516
|
+
}
|
|
18517
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18518
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18131
18519
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18132
18520
|
/**
|
|
18133
18521
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19841,12 +20229,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
19841
20229
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19842
20230
|
* in-place so dispatch keeps working.
|
|
19843
20231
|
*
|
|
19844
|
-
* **
|
|
19845
|
-
*
|
|
19846
|
-
*
|
|
19847
|
-
*
|
|
19848
|
-
* (`ha-domain-mapping`)
|
|
19849
|
-
* stored after that point.
|
|
20232
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20233
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20234
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20235
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20236
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20237
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19850
20238
|
*
|
|
19851
20239
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19852
20240
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19860,6 +20248,14 @@ var SourceInfoSchema = object({
|
|
|
19860
20248
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19861
20249
|
* Used to detect rename when `id` changes. */
|
|
19862
20250
|
uniqueId: string().optional(),
|
|
20251
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20252
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20253
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20254
|
+
dateTimeShape: _enum([
|
|
20255
|
+
"date",
|
|
20256
|
+
"time",
|
|
20257
|
+
"datetime"
|
|
20258
|
+
]).optional(),
|
|
19863
20259
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19864
20260
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19865
20261
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40981,7 +41377,8 @@ method(object({
|
|
|
40981
41377
|
"enum"
|
|
40982
41378
|
]),
|
|
40983
41379
|
enumValues: array(string()).optional(),
|
|
40984
|
-
item: boolean().optional()
|
|
41380
|
+
item: boolean().optional(),
|
|
41381
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40985
41382
|
})).readonly(),
|
|
40986
41383
|
itemArray: object({
|
|
40987
41384
|
path: string(),
|
|
@@ -44825,8 +45222,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44825
45222
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44826
45223
|
var MaskGridShapeSchema = object({
|
|
44827
45224
|
kind: literal("grid"),
|
|
44828
|
-
gridWidth: number(),
|
|
44829
|
-
gridHeight: number(),
|
|
45225
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45226
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44830
45227
|
cells: array(boolean())
|
|
44831
45228
|
});
|
|
44832
45229
|
discriminatedUnion("kind", [
|
|
@@ -44938,6 +45335,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44938
45335
|
"detection-blind",
|
|
44939
45336
|
"motion-noisy",
|
|
44940
45337
|
"motion-calm",
|
|
45338
|
+
"package-llm-silent",
|
|
45339
|
+
"package-llm-answered",
|
|
44941
45340
|
"recording-stalled",
|
|
44942
45341
|
"recording-healthy",
|
|
44943
45342
|
"recording-degraded",
|
|
@@ -56133,6 +56532,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56133
56532
|
deprecated: string().optional(),
|
|
56134
56533
|
distTags: array(string()).readonly()
|
|
56135
56534
|
});
|
|
56535
|
+
/**
|
|
56536
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56537
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56538
|
+
* tarball failure — never an empty string standing in for either.
|
|
56539
|
+
*/
|
|
56540
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56541
|
+
object({
|
|
56542
|
+
status: literal("ok"),
|
|
56543
|
+
markdown: string()
|
|
56544
|
+
}),
|
|
56545
|
+
object({ status: literal("missing") }),
|
|
56546
|
+
object({
|
|
56547
|
+
status: literal("error"),
|
|
56548
|
+
message: string()
|
|
56549
|
+
})
|
|
56550
|
+
]);
|
|
56551
|
+
var PackageDocsSchema = object({
|
|
56552
|
+
name: string(),
|
|
56553
|
+
version: string(),
|
|
56554
|
+
readme: PackageDocBodySchema,
|
|
56555
|
+
changelog: PackageDocBodySchema
|
|
56556
|
+
});
|
|
56136
56557
|
var SearchResultSchema = object({
|
|
56137
56558
|
name: string(),
|
|
56138
56559
|
version: string(),
|
|
@@ -56351,7 +56772,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56351
56772
|
}), object({ success: literal(true) }), {
|
|
56352
56773
|
kind: "mutation",
|
|
56353
56774
|
auth: "admin"
|
|
56354
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56775
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56776
|
+
name: string().min(1),
|
|
56777
|
+
version: string().min(1).optional()
|
|
56778
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56355
56779
|
kind: "mutation",
|
|
56356
56780
|
auth: "admin"
|
|
56357
56781
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56410,27 +56834,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56410
56834
|
*/
|
|
56411
56835
|
var AirQualitySensorStatusSchema = object({
|
|
56412
56836
|
/** Carbon dioxide concentration in ppm. */
|
|
56413
|
-
co2Ppm: number().min(0).optional(),
|
|
56837
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56414
56838
|
/** Total volatile organic compounds in ppb. */
|
|
56415
|
-
vocPpb: number().min(0).optional(),
|
|
56839
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56416
56840
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56417
|
-
pm25: number().min(0).optional(),
|
|
56841
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56418
56842
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56419
|
-
pm10: number().min(0).optional(),
|
|
56843
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56420
56844
|
/** Composite AQI value (typically 0..500). */
|
|
56421
|
-
aqi: number().optional(),
|
|
56845
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56422
56846
|
/** Ms epoch when the slice was last updated. */
|
|
56423
|
-
lastFetchedAt: number()
|
|
56424
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56425
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56426
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56427
|
-
* per slice is unambiguous. */
|
|
56428
|
-
unit: string().optional(),
|
|
56429
|
-
/** Suggested decimal places for numeric display.
|
|
56430
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56431
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56432
|
-
* auto-formatting when absent. */
|
|
56433
|
-
precision: number().int().min(0).max(10).optional()
|
|
56847
|
+
lastFetchedAt: number()
|
|
56434
56848
|
});
|
|
56435
56849
|
var airQualitySensorCapability = {
|
|
56436
56850
|
name: "air-quality-sensor",
|
|
@@ -56467,12 +56881,12 @@ var airQualitySensorCapability = {
|
|
|
56467
56881
|
},
|
|
56468
56882
|
pm25: {
|
|
56469
56883
|
kind: "gauge",
|
|
56470
|
-
unit: "
|
|
56884
|
+
unit: "µg/m³",
|
|
56471
56885
|
deadband: 1
|
|
56472
56886
|
},
|
|
56473
56887
|
pm10: {
|
|
56474
56888
|
kind: "gauge",
|
|
56475
|
-
unit: "
|
|
56889
|
+
unit: "µg/m³",
|
|
56476
56890
|
deadband: 1
|
|
56477
56891
|
},
|
|
56478
56892
|
aqi: {
|
|
@@ -56490,22 +56904,13 @@ var airQualitySensorCapability = {
|
|
|
56490
56904
|
* entries with `device_class: illuminance`.
|
|
56491
56905
|
*/
|
|
56492
56906
|
var AmbientLightSensorStatusSchema = object({
|
|
56493
|
-
/** Current illuminance in lux (lx). */
|
|
56494
|
-
lux: number().min(0).meta({
|
|
56495
|
-
|
|
56907
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56908
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56909
|
+
precision: 0,
|
|
56496
56910
|
label: "Illuminance"
|
|
56497
|
-
}),
|
|
56911
|
+
})),
|
|
56498
56912
|
/** Ms epoch when the slice was last updated. */
|
|
56499
|
-
lastFetchedAt: number()
|
|
56500
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56501
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56502
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56503
|
-
unit: string().optional(),
|
|
56504
|
-
/** Suggested decimal places for numeric display.
|
|
56505
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56506
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56507
|
-
* auto-formatting when absent. */
|
|
56508
|
-
precision: number().int().min(0).max(10).optional()
|
|
56913
|
+
lastFetchedAt: number()
|
|
56509
56914
|
});
|
|
56510
56915
|
var ambientLightSensorCapability = {
|
|
56511
56916
|
name: "ambient-light-sensor",
|
|
@@ -56537,12 +56942,7 @@ var ambientLightSensorCapability = {
|
|
|
56537
56942
|
} } },
|
|
56538
56943
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56539
56944
|
* whether persisting is worth a SQLite commit. */
|
|
56540
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56541
|
-
customize: {
|
|
56542
|
-
version: 1,
|
|
56543
|
-
advanced: "derive",
|
|
56544
|
-
targets: []
|
|
56545
|
-
}
|
|
56945
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56546
56946
|
};
|
|
56547
56947
|
/**
|
|
56548
56948
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -56769,10 +57169,7 @@ var BatteryStatusSchema = object({
|
|
|
56769
57169
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56770
57170
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56771
57171
|
*/
|
|
56772
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56773
|
-
unit: "%",
|
|
56774
|
-
label: "Charge"
|
|
56775
|
-
}),
|
|
57172
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56776
57173
|
/**
|
|
56777
57174
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56778
57175
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56799,7 +57196,14 @@ var BatteryStatusSchema = object({
|
|
|
56799
57196
|
*/
|
|
56800
57197
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56801
57198
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56802
|
-
lastUpdated: number(),
|
|
57199
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57200
|
+
/**
|
|
57201
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57202
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57203
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57204
|
+
* `numeric-sensor` on the same device.
|
|
57205
|
+
*/
|
|
57206
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56803
57207
|
/**
|
|
56804
57208
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56805
57209
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56851,7 +57255,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
56851
57255
|
/** Generic Customize target for the percentage reading (D936). */
|
|
56852
57256
|
var batteryCustomize = {
|
|
56853
57257
|
version: 1,
|
|
56854
|
-
advanced: "derive",
|
|
56855
57258
|
targets: [{
|
|
56856
57259
|
id: "percentage",
|
|
56857
57260
|
cardinality: "scalar",
|
|
@@ -56860,7 +57263,7 @@ var batteryCustomize = {
|
|
|
56860
57263
|
stateField: "percentage"
|
|
56861
57264
|
},
|
|
56862
57265
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
56863
|
-
apply: "add
|
|
57266
|
+
apply: "add",
|
|
56864
57267
|
path: "percentage",
|
|
56865
57268
|
sources: [{
|
|
56866
57269
|
kind: "field",
|
|
@@ -56981,10 +57384,16 @@ onStatusChanged: { data: object({
|
|
|
56981
57384
|
/**
|
|
56982
57385
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
56983
57386
|
*/
|
|
56984
|
-
history: { fields: {
|
|
56985
|
-
|
|
56986
|
-
|
|
56987
|
-
|
|
57387
|
+
history: { fields: {
|
|
57388
|
+
percentage: {
|
|
57389
|
+
kind: "gauge",
|
|
57390
|
+
unit: "%"
|
|
57391
|
+
},
|
|
57392
|
+
volts: {
|
|
57393
|
+
kind: "gauge",
|
|
57394
|
+
unit: "V"
|
|
57395
|
+
}
|
|
57396
|
+
} },
|
|
56988
57397
|
customize: batteryCustomize,
|
|
56989
57398
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56990
57399
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57031,12 +57440,7 @@ var binaryCapability = {
|
|
|
57031
57440
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57032
57441
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57033
57442
|
* whether persisting is worth a SQLite commit. */
|
|
57034
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57035
|
-
customize: {
|
|
57036
|
-
version: 1,
|
|
57037
|
-
advanced: "derive",
|
|
57038
|
-
targets: []
|
|
57039
|
-
}
|
|
57443
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57040
57444
|
};
|
|
57041
57445
|
/**
|
|
57042
57446
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57052,7 +57456,7 @@ var binaryCapability = {
|
|
|
57052
57456
|
*/
|
|
57053
57457
|
var BrightnessStatusSchema = object({
|
|
57054
57458
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57055
|
-
percentage: number().min(0).max(100),
|
|
57459
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57056
57460
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57057
57461
|
lastChangedAt: number()
|
|
57058
57462
|
});
|
|
@@ -57506,21 +57910,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57506
57910
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57507
57911
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57508
57912
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57509
|
-
target: number().nullable(),
|
|
57913
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57510
57914
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57511
57915
|
* in `heat_cool` mode. */
|
|
57512
|
-
targetHigh: number().nullable(),
|
|
57916
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57513
57917
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57514
57918
|
* in `heat_cool` mode. */
|
|
57515
|
-
targetLow: number().nullable(),
|
|
57919
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57516
57920
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57517
57921
|
* humidity control. */
|
|
57518
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57922
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57519
57923
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57520
57924
|
* the device's internal sensor. */
|
|
57521
|
-
currentTemp: number().nullable(),
|
|
57925
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57522
57926
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57523
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57927
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57524
57928
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57525
57929
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57526
57930
|
swingVertical: boolean().nullable(),
|
|
@@ -57528,11 +57932,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57528
57932
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57529
57933
|
swingHorizontal: boolean().nullable(),
|
|
57530
57934
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57531
|
-
minTemp: number().nullable().optional(),
|
|
57935
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57532
57936
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57533
|
-
maxTemp: number().nullable().optional(),
|
|
57937
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57534
57938
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57535
|
-
tempStep: number().positive().nullable().optional(),
|
|
57939
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57536
57940
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57537
57941
|
lastFetchedAt: number()
|
|
57538
57942
|
});
|
|
@@ -57674,17 +58078,17 @@ var climateControlCapability = {
|
|
|
57674
58078
|
* modes to expose in the picker without a slice fetch.
|
|
57675
58079
|
*/
|
|
57676
58080
|
var RgbTripletSchema = object({
|
|
57677
|
-
r: number().int().min(0).max(255),
|
|
57678
|
-
g: number().int().min(0).max(255),
|
|
57679
|
-
b: number().int().min(0).max(255)
|
|
58081
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58082
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58083
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57680
58084
|
});
|
|
57681
58085
|
var HsvTripletSchema = object({
|
|
57682
58086
|
/** Hue in degrees, 0..360. */
|
|
57683
|
-
h: number().min(0).max(360),
|
|
58087
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57684
58088
|
/** Saturation as 0..100 inclusive. */
|
|
57685
|
-
s: number().min(0).max(100),
|
|
58089
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57686
58090
|
/** Value/brightness as 0..100 inclusive. */
|
|
57687
|
-
v: number().min(0).max(100)
|
|
58091
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57688
58092
|
});
|
|
57689
58093
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57690
58094
|
object({
|
|
@@ -57713,7 +58117,7 @@ var ColorStatusSchema = object({
|
|
|
57713
58117
|
/** Populated when `mode === 'hsv'`. */
|
|
57714
58118
|
hsv: HsvTripletSchema.optional(),
|
|
57715
58119
|
/** Populated when `mode === 'mired'`. */
|
|
57716
|
-
mireds: number().int().optional(),
|
|
58120
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57717
58121
|
/** Ms epoch of the last operator-driven change. */
|
|
57718
58122
|
lastChangedAt: number()
|
|
57719
58123
|
});
|
|
@@ -57916,18 +58320,12 @@ _enum([
|
|
|
57916
58320
|
"empty",
|
|
57917
58321
|
"full"
|
|
57918
58322
|
]);
|
|
57919
|
-
/**
|
|
57920
|
-
|
|
57921
|
-
|
|
57922
|
-
"days",
|
|
57923
|
-
"hours",
|
|
57924
|
-
"cycles"
|
|
57925
|
-
]);
|
|
57926
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57927
|
-
* days). `value` null = unknown (D393). */
|
|
58323
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58324
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58325
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57928
58326
|
var ConsumableRemainingSchema = object({
|
|
57929
|
-
value: number().min(0).nullable(),
|
|
57930
|
-
|
|
58327
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58328
|
+
kind: ConsumableRemainingKindSchema
|
|
57931
58329
|
});
|
|
57932
58330
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
57933
58331
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -57940,7 +58338,7 @@ var ConsumableItemSchema = object({
|
|
|
57940
58338
|
/** Display name. */
|
|
57941
58339
|
label: string().min(1),
|
|
57942
58340
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57943
|
-
level: number().min(0).max(100).nullable(),
|
|
58341
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57944
58342
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57945
58343
|
status: ConsumableStatusSchema.nullable(),
|
|
57946
58344
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58022,8 +58420,8 @@ var consumablesCustomize = {
|
|
|
58022
58420
|
transforms: [{ kind: "identity" }]
|
|
58023
58421
|
}],
|
|
58024
58422
|
literals: [{
|
|
58025
|
-
path: "remaining.
|
|
58026
|
-
values: [...
|
|
58423
|
+
path: "remaining.kind",
|
|
58424
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58027
58425
|
}]
|
|
58028
58426
|
},
|
|
58029
58427
|
{
|
|
@@ -58152,7 +58550,6 @@ reset: method(object({
|
|
|
58152
58550
|
},
|
|
58153
58551
|
"remaining.value": {
|
|
58154
58552
|
kind: "gauge",
|
|
58155
|
-
unitFrom: "remaining.unit",
|
|
58156
58553
|
deadband: 1,
|
|
58157
58554
|
displayName: "Remaining"
|
|
58158
58555
|
}
|
|
@@ -58222,10 +58619,9 @@ var contactCapability = {
|
|
|
58222
58619
|
* (empty array for the other kinds). It lives in the slice because
|
|
58223
58620
|
* HA `select.*` entities may update their options at runtime.
|
|
58224
58621
|
*
|
|
58225
|
-
*
|
|
58226
|
-
*
|
|
58227
|
-
*
|
|
58228
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58622
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58623
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58624
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58229
58625
|
*/
|
|
58230
58626
|
var ControlStatusSchema = object({
|
|
58231
58627
|
kind: _enum([
|
|
@@ -58237,39 +58633,17 @@ var ControlStatusSchema = object({
|
|
|
58237
58633
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58238
58634
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58239
58635
|
* or time-only — HA accepts all three forms). */
|
|
58240
|
-
value: union([number(), string()]),
|
|
58636
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58241
58637
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58242
58638
|
options: array(string()),
|
|
58243
58639
|
/** Ms epoch when the slice was last updated. */
|
|
58244
58640
|
lastChangedAt: number(),
|
|
58245
|
-
/**
|
|
58246
|
-
|
|
58247
|
-
|
|
58248
|
-
|
|
58249
|
-
/**
|
|
58250
|
-
|
|
58251
|
-
min: number().optional(),
|
|
58252
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58253
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58254
|
-
max: number().optional(),
|
|
58255
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58256
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58257
|
-
step: number().optional(),
|
|
58258
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58259
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58260
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58261
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58262
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58263
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58264
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58265
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58266
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58267
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58268
|
-
format: _enum([
|
|
58269
|
-
"date",
|
|
58270
|
-
"time",
|
|
58271
|
-
"datetime"
|
|
58272
|
-
]).optional()
|
|
58641
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58642
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58643
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58644
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58645
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58646
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58273
58647
|
});
|
|
58274
58648
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58275
58649
|
object({
|
|
@@ -58335,9 +58709,9 @@ var CoverStatusSchema = object({
|
|
|
58335
58709
|
]),
|
|
58336
58710
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58337
58711
|
* no intermediate position surface. */
|
|
58338
|
-
position: number().min(0).max(100).nullable(),
|
|
58712
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58339
58713
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58340
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58714
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58341
58715
|
/** Ms epoch when the slice was last updated. */
|
|
58342
58716
|
lastChangedAt: number()
|
|
58343
58717
|
});
|
|
@@ -58440,9 +58814,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58440
58814
|
var DayNightStatusSchema = object({
|
|
58441
58815
|
mode: DayNightModeSchema,
|
|
58442
58816
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58443
|
-
sensitivity: number().optional(),
|
|
58817
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58444
58818
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58445
|
-
switchDelaySec: number().optional(),
|
|
58819
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58446
58820
|
lastFetchedAt: number()
|
|
58447
58821
|
});
|
|
58448
58822
|
/**
|
|
@@ -58660,11 +59034,11 @@ var DishwasherStatusSchema = object({
|
|
|
58660
59034
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58661
59035
|
availablePrograms: array(string()),
|
|
58662
59036
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58663
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59037
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58664
59038
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58665
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59039
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58666
59040
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58667
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59041
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58668
59042
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58669
59043
|
doorOpen: boolean().nullable(),
|
|
58670
59044
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58688,7 +59062,7 @@ var DishwasherStatusSchema = object({
|
|
|
58688
59062
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58689
59063
|
machineCareDue: boolean().nullable(),
|
|
58690
59064
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58691
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59065
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58692
59066
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58693
59067
|
halfLoad: boolean().nullable(),
|
|
58694
59068
|
hygienePlus: boolean().nullable(),
|
|
@@ -58703,7 +59077,7 @@ var DishwasherStatusSchema = object({
|
|
|
58703
59077
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58704
59078
|
activeEvents: array(string()),
|
|
58705
59079
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58706
|
-
errorCode: number().nullable(),
|
|
59080
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58707
59081
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58708
59082
|
errorLabel: string().nullable(),
|
|
58709
59083
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -58934,7 +59308,7 @@ var DoorbellStatusSchema = object({
|
|
|
58934
59308
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
58935
59309
|
lastPressedAt: number().nullable(),
|
|
58936
59310
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
58937
|
-
pressCountSinceStart: number()
|
|
59311
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
58938
59312
|
});
|
|
58939
59313
|
var DoorbellPressEventSchema = object({
|
|
58940
59314
|
deviceId: number(),
|
|
@@ -58999,17 +59373,7 @@ onPressed: {
|
|
|
58999
59373
|
history: "none",
|
|
59000
59374
|
customize: doorbellCustomize
|
|
59001
59375
|
};
|
|
59002
|
-
|
|
59003
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59004
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59005
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59006
|
-
* The option set is stable across observations; it is persisted in the
|
|
59007
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59008
|
-
* stored in `sourceInfo`.
|
|
59009
|
-
*/
|
|
59010
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59011
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59012
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59376
|
+
_enum([
|
|
59013
59377
|
"date",
|
|
59014
59378
|
"time",
|
|
59015
59379
|
"datetime"
|
|
@@ -59017,12 +59381,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59017
59381
|
var EnumSensorStatusSchema = object({
|
|
59018
59382
|
value: string(),
|
|
59019
59383
|
/**
|
|
59020
|
-
* Set
|
|
59021
|
-
* as
|
|
59022
|
-
*
|
|
59023
|
-
* a time-only sensor → `'time'`.
|
|
59384
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59385
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59386
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59024
59387
|
*/
|
|
59025
|
-
|
|
59388
|
+
timestamp: boolean().optional(),
|
|
59026
59389
|
/** Ms epoch when the slice was last updated. */
|
|
59027
59390
|
lastFetchedAt: number()
|
|
59028
59391
|
});
|
|
@@ -59049,11 +59412,11 @@ var enumSensorCapability = {
|
|
|
59049
59412
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59050
59413
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59051
59414
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59052
|
-
* `
|
|
59415
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59053
59416
|
*/
|
|
59054
59417
|
history: { fields: { value: {
|
|
59055
59418
|
kind: "enum",
|
|
59056
|
-
skipWhenSet: "
|
|
59419
|
+
skipWhenSet: "timestamp"
|
|
59057
59420
|
} } },
|
|
59058
59421
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59059
59422
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59073,13 +59436,13 @@ var EventFireSchema = object({
|
|
|
59073
59436
|
deviceId: number(),
|
|
59074
59437
|
eventType: string(),
|
|
59075
59438
|
data: record(string(), unknown()).nullable(),
|
|
59076
|
-
timestamp: number(),
|
|
59077
|
-
seq: number()
|
|
59439
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59440
|
+
seq: number().meta(readingMeta("count"))
|
|
59078
59441
|
});
|
|
59079
59442
|
var EventEmitterStatusSchema = object({
|
|
59080
59443
|
eventTypes: array(string()),
|
|
59081
59444
|
lastEvent: EventFireSchema.nullable(),
|
|
59082
|
-
eventCountSinceStart: number()
|
|
59445
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59083
59446
|
});
|
|
59084
59447
|
var eventEmitterCapability = {
|
|
59085
59448
|
name: "event-emitter",
|
|
@@ -59492,10 +59855,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59492
59855
|
var FanControlStatusSchema = object({
|
|
59493
59856
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59494
59857
|
* speed surface (single-speed fan). */
|
|
59495
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59858
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59496
59859
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59497
59860
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59498
|
-
percentageStep: number().positive().optional(),
|
|
59861
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59499
59862
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59500
59863
|
* — empty string when no preset is active or supported. */
|
|
59501
59864
|
preset: string(),
|
|
@@ -59616,7 +59979,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59616
59979
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59617
59980
|
model: string().nullable(),
|
|
59618
59981
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59619
|
-
channelCount: number().nullable(),
|
|
59982
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59620
59983
|
/**
|
|
59621
59984
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59622
59985
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59739,9 +60102,91 @@ var gasCapability = {
|
|
|
59739
60102
|
* whether persisting is worth a SQLite commit. */
|
|
59740
60103
|
volatileStateFields: ["lastChangedAt"]
|
|
59741
60104
|
};
|
|
60105
|
+
var GroupCommandsSchema = object({
|
|
60106
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60107
|
+
results: array(object({
|
|
60108
|
+
deviceId: number().int().nonnegative(),
|
|
60109
|
+
cap: string().min(1),
|
|
60110
|
+
method: string().min(1),
|
|
60111
|
+
ok: boolean(),
|
|
60112
|
+
error: string().optional(),
|
|
60113
|
+
/** Ms epoch of the attempt. */
|
|
60114
|
+
at: number()
|
|
60115
|
+
})) });
|
|
60116
|
+
var groupCommandsCapability = {
|
|
60117
|
+
name: "group-commands",
|
|
60118
|
+
scope: "device",
|
|
60119
|
+
deviceNative: true,
|
|
60120
|
+
mode: "singleton",
|
|
60121
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60122
|
+
methods: {},
|
|
60123
|
+
status: {
|
|
60124
|
+
schema: GroupCommandsSchema,
|
|
60125
|
+
kind: "push"
|
|
60126
|
+
},
|
|
60127
|
+
runtimeState: GroupCommandsSchema,
|
|
60128
|
+
/**
|
|
60129
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60130
|
+
* failure would outlive the command that caused it.
|
|
60131
|
+
*
|
|
60132
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60133
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60134
|
+
*/
|
|
60135
|
+
durability: "session",
|
|
60136
|
+
history: "none"
|
|
60137
|
+
};
|
|
60138
|
+
/**
|
|
60139
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60140
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60141
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60142
|
+
* series that later statistics read is the output cap's own history block.
|
|
60143
|
+
*/
|
|
60144
|
+
var GroupStatusSchema = object({
|
|
60145
|
+
/** Members whose current value entered the aggregate. */
|
|
60146
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60147
|
+
precision: 0,
|
|
60148
|
+
label: "Reporting"
|
|
60149
|
+
})),
|
|
60150
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60151
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60152
|
+
precision: 0,
|
|
60153
|
+
label: "Excluded"
|
|
60154
|
+
})),
|
|
60155
|
+
/** `included` + `excluded`. */
|
|
60156
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60157
|
+
precision: 0,
|
|
60158
|
+
label: "Members"
|
|
60159
|
+
}))
|
|
60160
|
+
});
|
|
60161
|
+
var groupStatusCapability = {
|
|
60162
|
+
name: "group-status",
|
|
60163
|
+
scope: "device",
|
|
60164
|
+
deviceNative: true,
|
|
60165
|
+
mode: "singleton",
|
|
60166
|
+
deviceTypes: [
|
|
60167
|
+
DeviceType.Sensor,
|
|
60168
|
+
DeviceType.Switch,
|
|
60169
|
+
DeviceType.Light
|
|
60170
|
+
],
|
|
60171
|
+
methods: {},
|
|
60172
|
+
status: {
|
|
60173
|
+
schema: GroupStatusSchema,
|
|
60174
|
+
kind: "push"
|
|
60175
|
+
},
|
|
60176
|
+
runtimeState: GroupStatusSchema,
|
|
60177
|
+
/**
|
|
60178
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60179
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60180
|
+
*
|
|
60181
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60182
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60183
|
+
*/
|
|
60184
|
+
durability: "session",
|
|
60185
|
+
history: "none"
|
|
60186
|
+
};
|
|
59742
60187
|
var HeatingValveStatusSchema = object({
|
|
59743
60188
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59744
|
-
position: number().min(0).max(100).nullable(),
|
|
60189
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59745
60190
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59746
60191
|
lastFetchedAt: number()
|
|
59747
60192
|
});
|
|
@@ -59784,9 +60229,9 @@ var HumidifierStatusSchema = object({
|
|
|
59784
60229
|
/** Whether the humidifier is currently on. */
|
|
59785
60230
|
on: boolean(),
|
|
59786
60231
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59787
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60232
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59788
60233
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59789
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60234
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59790
60235
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59791
60236
|
* device has no mode surface. */
|
|
59792
60237
|
mode: string().nullable(),
|
|
@@ -59796,9 +60241,9 @@ var HumidifierStatusSchema = object({
|
|
|
59796
60241
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59797
60242
|
action: string().nullable(),
|
|
59798
60243
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59799
|
-
minHumidity: number().nullable(),
|
|
60244
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59800
60245
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59801
|
-
maxHumidity: number().nullable(),
|
|
60246
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59802
60247
|
/** Ms epoch when the slice was last updated. */
|
|
59803
60248
|
lastChangedAt: number()
|
|
59804
60249
|
});
|
|
@@ -59868,22 +60313,13 @@ var humidifierCapability = {
|
|
|
59868
60313
|
* `sourceInfo`.
|
|
59869
60314
|
*/
|
|
59870
60315
|
var HumiditySensorStatusSchema = object({
|
|
59871
|
-
/** Current relative humidity, 0..100. */
|
|
59872
|
-
percent: number().min(0).max(100).meta({
|
|
59873
|
-
|
|
60316
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60317
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60318
|
+
precision: 0,
|
|
59874
60319
|
label: "Humidity"
|
|
59875
|
-
}),
|
|
60320
|
+
})),
|
|
59876
60321
|
/** Ms epoch when the slice was last updated. */
|
|
59877
|
-
lastFetchedAt: number()
|
|
59878
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59879
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59880
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59881
|
-
unit: string().optional(),
|
|
59882
|
-
/** Suggested decimal places for numeric display.
|
|
59883
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59884
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59885
|
-
* auto-formatting when absent. */
|
|
59886
|
-
precision: number().int().min(0).max(10).optional()
|
|
60322
|
+
lastFetchedAt: number()
|
|
59887
60323
|
});
|
|
59888
60324
|
var humiditySensorCapability = {
|
|
59889
60325
|
name: "humidity-sensor",
|
|
@@ -59914,12 +60350,7 @@ var humiditySensorCapability = {
|
|
|
59914
60350
|
} } },
|
|
59915
60351
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59916
60352
|
* whether persisting is worth a SQLite commit. */
|
|
59917
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59918
|
-
customize: {
|
|
59919
|
-
version: 1,
|
|
59920
|
-
advanced: "derive",
|
|
59921
|
-
targets: []
|
|
59922
|
-
}
|
|
60353
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59923
60354
|
};
|
|
59924
60355
|
/**
|
|
59925
60356
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -59940,7 +60371,7 @@ var ImageStatusSchema = object({
|
|
|
59940
60371
|
* entity exposes no `entity_picture` (yet). */
|
|
59941
60372
|
url: string().nullable(),
|
|
59942
60373
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
59943
|
-
lastUpdated: number().nullable()
|
|
60374
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
59944
60375
|
});
|
|
59945
60376
|
var imageCapability = {
|
|
59946
60377
|
name: "image",
|
|
@@ -60028,19 +60459,19 @@ var NormalizedRangeSchema = object({
|
|
|
60028
60459
|
*/
|
|
60029
60460
|
var ImageSettingsStatusSchema = object({
|
|
60030
60461
|
/** Normalized 0–100. */
|
|
60031
|
-
brightness: number().optional(),
|
|
60462
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60032
60463
|
/** Normalized 0–100. */
|
|
60033
|
-
contrast: number().optional(),
|
|
60464
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60034
60465
|
/** Normalized 0–100. */
|
|
60035
|
-
saturation: number().optional(),
|
|
60466
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60036
60467
|
/** Normalized 0–100. */
|
|
60037
|
-
sharpness: number().optional(),
|
|
60468
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60038
60469
|
mirror: boolean().optional(),
|
|
60039
60470
|
flip: boolean().optional(),
|
|
60040
60471
|
rotate: ImageRotateSchema.optional(),
|
|
60041
60472
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60042
60473
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60043
|
-
warmth: number().optional(),
|
|
60474
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60044
60475
|
exposureMode: ExposureModeSchema.optional(),
|
|
60045
60476
|
backlightMode: BacklightModeSchema.optional(),
|
|
60046
60477
|
lastFetchedAt: number()
|
|
@@ -60319,10 +60750,10 @@ var IntercomAbilitySchema = object({
|
|
|
60319
60750
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60320
60751
|
codecs: array(string()),
|
|
60321
60752
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60322
|
-
sampleRate: number(),
|
|
60753
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60323
60754
|
duplex: _enum(["half", "full"]),
|
|
60324
60755
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60325
|
-
maxBacklogMs: number()
|
|
60756
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60326
60757
|
});
|
|
60327
60758
|
var IntercomStatusSchema = object({
|
|
60328
60759
|
/** True while a talk session is open. */
|
|
@@ -60549,13 +60980,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60549
60980
|
activity: LawnMowerActivitySchema,
|
|
60550
60981
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60551
60982
|
* reading. */
|
|
60552
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60983
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60553
60984
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60554
60985
|
* task is active / progress is unavailable. */
|
|
60555
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60986
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60556
60987
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60557
60988
|
* or null when unknown. */
|
|
60558
|
-
currentCode: number().nullable(),
|
|
60989
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60559
60990
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60560
60991
|
currentCodeLabel: string().nullable(),
|
|
60561
60992
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61088,7 +61519,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61088
61519
|
state: MediaPlayerStateSchema,
|
|
61089
61520
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61090
61521
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61091
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61522
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61092
61523
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61093
61524
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61094
61525
|
isMuted: boolean().nullable(),
|
|
@@ -61101,10 +61532,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61101
61532
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61102
61533
|
/** Current playback position in ms. Null when not seekable or
|
|
61103
61534
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61104
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61535
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61105
61536
|
/** Total duration of the current media in ms. Null when unknown
|
|
61106
61537
|
* (live stream) or nothing is playing. */
|
|
61107
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61538
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61108
61539
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61109
61540
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61110
61541
|
shuffle: boolean().nullable(),
|
|
@@ -61413,7 +61844,7 @@ var motionCustomize = {
|
|
|
61413
61844
|
eventName: "onMotionChanged"
|
|
61414
61845
|
},
|
|
61415
61846
|
deviceTypes: [DeviceType.Camera],
|
|
61416
|
-
apply: "
|
|
61847
|
+
apply: "add",
|
|
61417
61848
|
applyAuthority: {
|
|
61418
61849
|
kind: "camera-sensors",
|
|
61419
61850
|
timeoutField: "motionCooldownMs"
|
|
@@ -61485,7 +61916,7 @@ var MotionStatusSchema = object({
|
|
|
61485
61916
|
* it, every provider seeded it at boot, and every session left it
|
|
61486
61917
|
* `detected: true` after its detach.
|
|
61487
61918
|
*/
|
|
61488
|
-
autoClearAfterMs: number().nullable()
|
|
61919
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61489
61920
|
});
|
|
61490
61921
|
/**
|
|
61491
61922
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61522,12 +61953,18 @@ var motionCapability = {
|
|
|
61522
61953
|
methods: {
|
|
61523
61954
|
/**
|
|
61524
61955
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61525
|
-
* for consumers that don't need the full status object
|
|
61526
|
-
*
|
|
61527
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61528
|
-
* consumer.
|
|
61956
|
+
* for consumers that don't need the full status object. A composed
|
|
61957
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61529
61958
|
*/
|
|
61530
61959
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
61960
|
+
/**
|
|
61961
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
61962
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
61963
|
+
*/
|
|
61964
|
+
composedMethods: { isDetected: {
|
|
61965
|
+
kind: "slice",
|
|
61966
|
+
field: "detected"
|
|
61967
|
+
} },
|
|
61531
61968
|
events: {
|
|
61532
61969
|
/**
|
|
61533
61970
|
* Fires every time the runner transitions a camera between
|
|
@@ -61667,7 +62104,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61667
62104
|
* the grid region(s). */
|
|
61668
62105
|
var MotionZoneStatusSchema = object({
|
|
61669
62106
|
enabled: boolean(),
|
|
61670
|
-
sensitivity: number(),
|
|
62107
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61671
62108
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61672
62109
|
regions: array(MotionZoneRegionSchema),
|
|
61673
62110
|
lastFetchedAt: number()
|
|
@@ -62037,7 +62474,7 @@ var NavigationStatusSchema = object({
|
|
|
62037
62474
|
following: boolean(),
|
|
62038
62475
|
flash: boolean(),
|
|
62039
62476
|
lightMode: NavigationLightModeSchema,
|
|
62040
|
-
lightLevel: number().min(40).max(100),
|
|
62477
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62041
62478
|
/** Ms epoch when the slice was last updated. */
|
|
62042
62479
|
lastChangedAt: number()
|
|
62043
62480
|
});
|
|
@@ -62171,13 +62608,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62171
62608
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62172
62609
|
* SKIP a null rather than coerce it.
|
|
62173
62610
|
*/
|
|
62174
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62611
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62175
62612
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62176
|
-
rssiDbm: number().optional(),
|
|
62613
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62177
62614
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62178
62615
|
ssid: string().optional(),
|
|
62179
62616
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62180
|
-
lastUpdated: number()
|
|
62617
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62181
62618
|
});
|
|
62182
62619
|
var networkLinkCapability = {
|
|
62183
62620
|
name: "network-link",
|
|
@@ -62562,7 +62999,7 @@ var NotifierStatusSchema = object({
|
|
|
62562
62999
|
lastError: string().nullable(),
|
|
62563
63000
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62564
63001
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62565
|
-
queueDepth: number().int().nonnegative(),
|
|
63002
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62566
63003
|
/** Per-feature capability matrix — authoritative source for the
|
|
62567
63004
|
* compose-form field gating. */
|
|
62568
63005
|
supports: NotifierSupportsSchema
|
|
@@ -62654,11 +63091,9 @@ onSent: { data: object({
|
|
|
62654
63091
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62655
63092
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62656
63093
|
*
|
|
62657
|
-
* The
|
|
62658
|
-
*
|
|
62659
|
-
*
|
|
62660
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62661
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63094
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63095
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63096
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62662
63097
|
*
|
|
62663
63098
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62664
63099
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62667,15 +63102,8 @@ onSent: { data: object({
|
|
|
62667
63102
|
* numeric values land here.
|
|
62668
63103
|
*/
|
|
62669
63104
|
var NumericSensorStatusSchema = object({
|
|
62670
|
-
|
|
62671
|
-
|
|
62672
|
-
* Populated live from the upstream source on each state push.
|
|
62673
|
-
* Absent for unitless sensors. */
|
|
62674
|
-
unit: string().optional(),
|
|
62675
|
-
/** Suggested decimal places for numeric display.
|
|
62676
|
-
* Populated live from the upstream source when provided.
|
|
62677
|
-
* Falls back to auto-formatting when absent. */
|
|
62678
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63105
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63106
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62679
63107
|
/** Ms epoch when the slice was last updated. */
|
|
62680
63108
|
lastFetchedAt: number()
|
|
62681
63109
|
});
|
|
@@ -62699,11 +63127,11 @@ var numericSensorCapability = {
|
|
|
62699
63127
|
*/
|
|
62700
63128
|
durability: "restored",
|
|
62701
63129
|
/**
|
|
62702
|
-
* History (D850): recorded series. The unit is
|
|
63130
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63131
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62703
63132
|
*/
|
|
62704
63133
|
history: { fields: { value: {
|
|
62705
63134
|
kind: "gauge",
|
|
62706
|
-
unitFrom: "unit",
|
|
62707
63135
|
minIntervalMs: 3e4
|
|
62708
63136
|
} } },
|
|
62709
63137
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -62995,23 +63423,26 @@ var PetFeederStatusSchema = object({
|
|
|
62995
63423
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
62996
63424
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
62997
63425
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
62998
|
-
foodLevel: number().nullable(),
|
|
63426
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
62999
63427
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63000
63428
|
* single-hopper models. */
|
|
63001
|
-
food1: number().nullable(),
|
|
63429
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63002
63430
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63003
63431
|
* single-hopper models. */
|
|
63004
|
-
food2: number().nullable(),
|
|
63432
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63005
63433
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63006
63434
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63007
63435
|
* below the feeder's low threshold. */
|
|
63008
63436
|
lowFood: boolean(),
|
|
63009
63437
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63010
63438
|
* device has no battery reading. */
|
|
63011
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63012
|
-
/**
|
|
63013
|
-
*
|
|
63014
|
-
|
|
63439
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63440
|
+
/**
|
|
63441
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63442
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63443
|
+
* model has no desiccant sensor.
|
|
63444
|
+
*/
|
|
63445
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63015
63446
|
/** True while a feed is in progress. */
|
|
63016
63447
|
feeding: boolean(),
|
|
63017
63448
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63022,7 +63453,7 @@ var PetFeederStatusSchema = object({
|
|
|
63022
63453
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63023
63454
|
error: string().nullable(),
|
|
63024
63455
|
/** Raw device error code (0 / null = no error). */
|
|
63025
|
-
errorCode: number().nullable(),
|
|
63456
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63026
63457
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63027
63458
|
isDualHopper: boolean(),
|
|
63028
63459
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63032,7 +63463,7 @@ var PetFeederStatusSchema = object({
|
|
|
63032
63463
|
/** Play a chime when dispensing. */
|
|
63033
63464
|
feedSound: boolean(),
|
|
63034
63465
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63035
|
-
volume: number(),
|
|
63466
|
+
volume: number().meta(readingMeta("none")),
|
|
63036
63467
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63037
63468
|
lastFetchedAt: number()
|
|
63038
63469
|
});
|
|
@@ -63151,7 +63582,7 @@ var petFeederCapability = {
|
|
|
63151
63582
|
},
|
|
63152
63583
|
desiccantLeftDays: {
|
|
63153
63584
|
kind: "gauge",
|
|
63154
|
-
unit: "
|
|
63585
|
+
unit: "s"
|
|
63155
63586
|
}
|
|
63156
63587
|
} }
|
|
63157
63588
|
};
|
|
@@ -63552,36 +63983,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63552
63983
|
*/
|
|
63553
63984
|
var PowerMeterStatusSchema = object({
|
|
63554
63985
|
/** Instantaneous power draw in watts. */
|
|
63555
|
-
watts: number().optional().meta({
|
|
63556
|
-
unit: "W",
|
|
63557
|
-
label: "Power"
|
|
63558
|
-
}),
|
|
63986
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63559
63987
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63560
|
-
kwhTotal: number().optional().meta({
|
|
63561
|
-
unit: "kWh",
|
|
63562
|
-
label: "Energy"
|
|
63563
|
-
}),
|
|
63988
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63564
63989
|
/** Voltage in volts. */
|
|
63565
|
-
volts: number().optional(),
|
|
63990
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63566
63991
|
/** Current in amperes. */
|
|
63567
|
-
amps: number().optional(),
|
|
63568
|
-
/** Apparent power in volt-amperes
|
|
63569
|
-
va: number().optional(),
|
|
63992
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
63993
|
+
/** Apparent power in volt-amperes. */
|
|
63994
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63570
63995
|
/** Power factor (0..1) if reported. */
|
|
63571
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
63996
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63572
63997
|
/** Ms epoch when the slice was last updated. */
|
|
63573
|
-
lastFetchedAt: number()
|
|
63574
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63575
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63576
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63577
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63578
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63579
|
-
unit: string().optional(),
|
|
63580
|
-
/** Suggested decimal places for numeric display.
|
|
63581
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63582
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63583
|
-
* auto-formatting when absent. */
|
|
63584
|
-
precision: number().int().min(0).max(10).optional()
|
|
63998
|
+
lastFetchedAt: number()
|
|
63585
63999
|
});
|
|
63586
64000
|
var powerMeterCapability = {
|
|
63587
64001
|
name: "power-meter",
|
|
@@ -63645,12 +64059,7 @@ var powerMeterCapability = {
|
|
|
63645
64059
|
} },
|
|
63646
64060
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63647
64061
|
* whether persisting is worth a SQLite commit. */
|
|
63648
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63649
|
-
customize: {
|
|
63650
|
-
version: 1,
|
|
63651
|
-
advanced: "derive",
|
|
63652
|
-
targets: []
|
|
63653
|
-
}
|
|
64062
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63654
64063
|
};
|
|
63655
64064
|
/**
|
|
63656
64065
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63670,11 +64079,11 @@ var powerMeterCapability = {
|
|
|
63670
64079
|
*/
|
|
63671
64080
|
var GpsLocationSchema = object({
|
|
63672
64081
|
/** Latitude in decimal degrees, -90..90. */
|
|
63673
|
-
latitude: number().min(-90).max(90),
|
|
64082
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63674
64083
|
/** Longitude in decimal degrees, -180..180. */
|
|
63675
|
-
longitude: number().min(-180).max(180),
|
|
64084
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63676
64085
|
/** Reported accuracy in meters (lower = better). */
|
|
63677
|
-
accuracyMeters: number().nonnegative()
|
|
64086
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63678
64087
|
});
|
|
63679
64088
|
var PresenceStatusSchema = object({
|
|
63680
64089
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63686,7 +64095,7 @@ var PresenceStatusSchema = object({
|
|
|
63686
64095
|
gps: GpsLocationSchema.nullable(),
|
|
63687
64096
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63688
64097
|
* when not reported. */
|
|
63689
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64098
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63690
64099
|
/** Ms epoch when the slice was last updated. */
|
|
63691
64100
|
lastChangedAt: number()
|
|
63692
64101
|
});
|
|
@@ -63736,19 +64145,10 @@ var presenceCapability = {
|
|
|
63736
64145
|
* `sourceInfo`.
|
|
63737
64146
|
*/
|
|
63738
64147
|
var PressureSensorStatusSchema = object({
|
|
63739
|
-
/** Current pressure in hPa. */
|
|
63740
|
-
hpa: number(),
|
|
64148
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64149
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63741
64150
|
/** Ms epoch when the slice was last updated. */
|
|
63742
|
-
lastFetchedAt: number()
|
|
63743
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63744
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63745
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63746
|
-
unit: string().optional(),
|
|
63747
|
-
/** Suggested decimal places for numeric display.
|
|
63748
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63749
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63750
|
-
* auto-formatting when absent. */
|
|
63751
|
-
precision: number().int().min(0).max(10).optional()
|
|
64151
|
+
lastFetchedAt: number()
|
|
63752
64152
|
});
|
|
63753
64153
|
var pressureSensorCapability = {
|
|
63754
64154
|
name: "pressure-sensor",
|
|
@@ -64162,8 +64562,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64162
64562
|
}), _void(), { kind: "mutation" });
|
|
64163
64563
|
var PtzAutotrackSettingsSchema = object({
|
|
64164
64564
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64165
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64166
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64565
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64566
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64167
64567
|
});
|
|
64168
64568
|
/**
|
|
64169
64569
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64317,7 +64717,7 @@ var RunningStateStatusSchema = object({
|
|
|
64317
64717
|
/** null = unknown — never coerced to false (D393). */
|
|
64318
64718
|
running: boolean().nullable(),
|
|
64319
64719
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64320
|
-
since: number().nullable(),
|
|
64720
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64321
64721
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64322
64722
|
phase: string().nullable(),
|
|
64323
64723
|
/** null until a reading has been published (D393). */
|
|
@@ -64332,7 +64732,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64332
64732
|
/** Generic Customize target for the running boolean (D936). */
|
|
64333
64733
|
var runningCustomize = {
|
|
64334
64734
|
version: 1,
|
|
64335
|
-
advanced: "derive",
|
|
64336
64735
|
targets: [{
|
|
64337
64736
|
id: "running",
|
|
64338
64737
|
cardinality: "scalar",
|
|
@@ -64352,7 +64751,7 @@ var runningCustomize = {
|
|
|
64352
64751
|
DeviceType.Thermostat,
|
|
64353
64752
|
DeviceType.PetFeeder
|
|
64354
64753
|
],
|
|
64355
|
-
apply: "add
|
|
64754
|
+
apply: "add",
|
|
64356
64755
|
path: "running",
|
|
64357
64756
|
sources: [
|
|
64358
64757
|
{
|
|
@@ -65616,9 +66015,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65616
66015
|
*/
|
|
65617
66016
|
var RecordWindowSchema = object({
|
|
65618
66017
|
trigger: RecordTriggerSchema,
|
|
65619
|
-
day: number().int().min(0).max(6),
|
|
65620
|
-
startMinute: number().int().min(0).max(1439),
|
|
65621
|
-
endMinute: number().int().min(1).max(1440)
|
|
66018
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66019
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66020
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65622
66021
|
});
|
|
65623
66022
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65624
66023
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65694,10 +66093,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65694
66093
|
/** Master "record to the card at all" switch. */
|
|
65695
66094
|
enabled: boolean().nullable(),
|
|
65696
66095
|
overwriteWhenFull: boolean().nullable(),
|
|
65697
|
-
preRecordSec: number().nullable(),
|
|
65698
|
-
postRecordSec: number().nullable(),
|
|
66096
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66097
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65699
66098
|
/** Length of one recorded file, in minutes. */
|
|
65700
|
-
segmentMinutes: number().nullable(),
|
|
66099
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65701
66100
|
/** The primary track's weekly windows, flattened. */
|
|
65702
66101
|
windows: array(RecordWindowSchema),
|
|
65703
66102
|
/**
|
|
@@ -65713,7 +66112,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65713
66112
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65714
66113
|
* writable.
|
|
65715
66114
|
*/
|
|
65716
|
-
unreadableWindows: number(),
|
|
66115
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65717
66116
|
/**
|
|
65718
66117
|
* The camera is scheduled to record and has NO usable storage.
|
|
65719
66118
|
*
|
|
@@ -66558,7 +66957,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66558
66957
|
url: string().optional(),
|
|
66559
66958
|
codec: string().optional(),
|
|
66560
66959
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66561
|
-
fps: number().positive().optional(),
|
|
66960
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66562
66961
|
label: string().optional(),
|
|
66563
66962
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66564
66963
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66645,18 +67044,18 @@ var StreamProfileSchema = _enum([
|
|
|
66645
67044
|
]);
|
|
66646
67045
|
/** The current encoding config of one stream profile. */
|
|
66647
67046
|
var StreamProfileConfigSchema = object({
|
|
66648
|
-
width: number(),
|
|
66649
|
-
height: number(),
|
|
67047
|
+
width: number().meta(readingMeta("none")),
|
|
67048
|
+
height: number().meta(readingMeta("none")),
|
|
66650
67049
|
codec: _enum(["h264", "h265"]),
|
|
66651
|
-
framerate: number(),
|
|
66652
|
-
bitrate: number(),
|
|
67050
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67051
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66653
67052
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66654
67053
|
encoderProfile: _enum([
|
|
66655
67054
|
"high",
|
|
66656
67055
|
"main",
|
|
66657
67056
|
"baseline"
|
|
66658
67057
|
]).optional(),
|
|
66659
|
-
gop: number().optional(),
|
|
67058
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66660
67059
|
/**
|
|
66661
67060
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66662
67061
|
*
|
|
@@ -66877,12 +67276,7 @@ var switchCapability = {
|
|
|
66877
67276
|
label: "On",
|
|
66878
67277
|
kind: "boolean"
|
|
66879
67278
|
}
|
|
66880
|
-
}] }
|
|
66881
|
-
customize: {
|
|
66882
|
-
version: 1,
|
|
66883
|
-
advanced: "derive",
|
|
66884
|
-
targets: []
|
|
66885
|
-
}
|
|
67279
|
+
}] }
|
|
66886
67280
|
};
|
|
66887
67281
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66888
67282
|
function hasControlCharacter(value) {
|
|
@@ -67465,35 +67859,21 @@ var tamperCapability = {
|
|
|
67465
67859
|
* entries with `device_class: temperature` and any future native
|
|
67466
67860
|
* thermometer.
|
|
67467
67861
|
*
|
|
67468
|
-
*
|
|
67469
|
-
*
|
|
67470
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67471
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67472
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67473
|
-
* `sourceInfo`.
|
|
67862
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67863
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67474
67864
|
*
|
|
67475
67865
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67476
67866
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67477
67867
|
* changed" steady state.
|
|
67478
67868
|
*/
|
|
67479
67869
|
var TemperatureSensorStatusSchema = object({
|
|
67480
|
-
/** Current temperature in Celsius. */
|
|
67481
|
-
celsius: number().meta({
|
|
67482
|
-
|
|
67870
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67871
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67872
|
+
precision: 1,
|
|
67483
67873
|
label: "Temperature"
|
|
67484
|
-
}),
|
|
67874
|
+
})),
|
|
67485
67875
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67486
|
-
lastFetchedAt: number()
|
|
67487
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67488
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67489
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67490
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67491
|
-
unit: string().optional(),
|
|
67492
|
-
/** Suggested decimal places for numeric display.
|
|
67493
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67494
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67495
|
-
* auto-formatting when absent. */
|
|
67496
|
-
precision: number().int().min(0).max(10).optional()
|
|
67876
|
+
lastFetchedAt: number()
|
|
67497
67877
|
});
|
|
67498
67878
|
var temperatureSensorCapability = {
|
|
67499
67879
|
name: "temperature-sensor",
|
|
@@ -67524,12 +67904,7 @@ var temperatureSensorCapability = {
|
|
|
67524
67904
|
} } },
|
|
67525
67905
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67526
67906
|
* whether persisting is worth a SQLite commit. */
|
|
67527
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67528
|
-
customize: {
|
|
67529
|
-
version: 1,
|
|
67530
|
-
advanced: "derive",
|
|
67531
|
-
targets: []
|
|
67532
|
-
}
|
|
67907
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67533
67908
|
};
|
|
67534
67909
|
/**
|
|
67535
67910
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67812,16 +68187,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67812
68187
|
]),
|
|
67813
68188
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67814
68189
|
* reading. */
|
|
67815
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68190
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67816
68191
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67817
68192
|
* the vacuum has no speed control. */
|
|
67818
68193
|
fanSpeed: string().nullable(),
|
|
67819
68194
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67820
68195
|
availableFanSpeeds: array(string()),
|
|
67821
68196
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67822
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68197
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67823
68198
|
/** Current error code (0 / null = no error). */
|
|
67824
|
-
errorCode: number().nullable(),
|
|
68199
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67825
68200
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67826
68201
|
errorLabel: string().nullable(),
|
|
67827
68202
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67899,7 +68274,7 @@ var ValveStatusSchema = object({
|
|
|
67899
68274
|
]),
|
|
67900
68275
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67901
68276
|
* intermediate position surface. */
|
|
67902
|
-
position: number().min(0).max(100).nullable(),
|
|
68277
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67903
68278
|
/** Ms epoch when the slice was last updated. */
|
|
67904
68279
|
lastChangedAt: number()
|
|
67905
68280
|
});
|
|
@@ -68007,9 +68382,9 @@ var vibrationCapability = {
|
|
|
68007
68382
|
*/
|
|
68008
68383
|
var WaterHeaterStatusSchema = object({
|
|
68009
68384
|
/** Current measured temperature. Null when not reported. */
|
|
68010
|
-
currentTemp: number().nullable(),
|
|
68385
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68011
68386
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68012
|
-
targetTemp: number().nullable(),
|
|
68387
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68013
68388
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68014
68389
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68015
68390
|
* device reports an unknown state. */
|
|
@@ -68020,9 +68395,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68020
68395
|
* has no away surface. */
|
|
68021
68396
|
away: boolean().nullable(),
|
|
68022
68397
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68023
|
-
minTemp: number().nullable(),
|
|
68398
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68024
68399
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68025
|
-
maxTemp: number().nullable(),
|
|
68400
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68026
68401
|
/** Ms epoch when the slice was last updated. */
|
|
68027
68402
|
lastChangedAt: number()
|
|
68028
68403
|
});
|
|
@@ -68107,25 +68482,18 @@ var waterHeaterCapability = {
|
|
|
68107
68482
|
* Forecast deferred — current conditions only for v1.
|
|
68108
68483
|
*/
|
|
68109
68484
|
var WeatherStatusSchema = object({
|
|
68110
|
-
/** Verbatim
|
|
68111
|
-
* when no condition has been reported yet. */
|
|
68485
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68112
68486
|
condition: string().nullable(),
|
|
68113
|
-
/** Current temperature in
|
|
68114
|
-
temperature: number().nullable(),
|
|
68115
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68116
|
-
temperatureUnit: string().nullable(),
|
|
68487
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68488
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68117
68489
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68118
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68119
|
-
/** Barometric pressure in
|
|
68120
|
-
pressure: number().nullable(),
|
|
68121
|
-
/**
|
|
68122
|
-
|
|
68123
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68124
|
-
windSpeed: number().nullable(),
|
|
68125
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68126
|
-
windSpeedUnit: string().nullable(),
|
|
68490
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68491
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68492
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68493
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68494
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68127
68495
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68128
|
-
windBearing: number().nullable(),
|
|
68496
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68129
68497
|
/** Ms epoch when the slice was last updated. */
|
|
68130
68498
|
lastFetchedAt: number()
|
|
68131
68499
|
});
|
|
@@ -68153,12 +68521,12 @@ var weatherCapability = {
|
|
|
68153
68521
|
*/
|
|
68154
68522
|
durability: "session",
|
|
68155
68523
|
/**
|
|
68156
|
-
* History (D850): recorded series.
|
|
68524
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68157
68525
|
*/
|
|
68158
68526
|
history: { fields: {
|
|
68159
68527
|
temperature: {
|
|
68160
68528
|
kind: "gauge",
|
|
68161
|
-
|
|
68529
|
+
unit: "°C",
|
|
68162
68530
|
deadband: .2
|
|
68163
68531
|
},
|
|
68164
68532
|
humidity: {
|
|
@@ -68168,12 +68536,12 @@ var weatherCapability = {
|
|
|
68168
68536
|
},
|
|
68169
68537
|
pressure: {
|
|
68170
68538
|
kind: "gauge",
|
|
68171
|
-
|
|
68539
|
+
unit: "hPa",
|
|
68172
68540
|
deadband: .5
|
|
68173
68541
|
},
|
|
68174
68542
|
windSpeed: {
|
|
68175
68543
|
kind: "gauge",
|
|
68176
|
-
|
|
68544
|
+
unit: "m/s",
|
|
68177
68545
|
deadband: .5
|
|
68178
68546
|
}
|
|
68179
68547
|
} }
|
|
@@ -69404,6 +69772,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69404
69772
|
featureProbe: featureProbeCapability,
|
|
69405
69773
|
flood: floodCapability,
|
|
69406
69774
|
gas: gasCapability,
|
|
69775
|
+
groupCommands: groupCommandsCapability,
|
|
69776
|
+
groupStatus: groupStatusCapability,
|
|
69407
69777
|
heatingValve: heatingValveCapability,
|
|
69408
69778
|
humidifier: humidifierCapability,
|
|
69409
69779
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70780,6 +71150,13 @@ Object.freeze({
|
|
|
70780
71150
|
access: "view",
|
|
70781
71151
|
role: "admin"
|
|
70782
71152
|
},
|
|
71153
|
+
"addons.getPackageDocs": {
|
|
71154
|
+
capName: "addons",
|
|
71155
|
+
capScope: "system",
|
|
71156
|
+
addonId: null,
|
|
71157
|
+
access: "view",
|
|
71158
|
+
role: "admin"
|
|
71159
|
+
},
|
|
70783
71160
|
"addons.getVersions": {
|
|
70784
71161
|
capName: "addons",
|
|
70785
71162
|
capScope: "system",
|
|
@@ -73888,6 +74265,20 @@ Object.freeze({
|
|
|
73888
74265
|
access: "view",
|
|
73889
74266
|
role: "viewer"
|
|
73890
74267
|
},
|
|
74268
|
+
"groupCommands.getStatus": {
|
|
74269
|
+
capName: "group-commands",
|
|
74270
|
+
capScope: "device",
|
|
74271
|
+
addonId: null,
|
|
74272
|
+
access: "view",
|
|
74273
|
+
role: "viewer"
|
|
74274
|
+
},
|
|
74275
|
+
"groupStatus.getStatus": {
|
|
74276
|
+
capName: "group-status",
|
|
74277
|
+
capScope: "device",
|
|
74278
|
+
addonId: null,
|
|
74279
|
+
access: "view",
|
|
74280
|
+
role: "viewer"
|
|
74281
|
+
},
|
|
73891
74282
|
"heatingValve.getStatus": {
|
|
73892
74283
|
capName: "heating-valve",
|
|
73893
74284
|
capScope: "device",
|
|
@@ -83710,6 +84101,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83710
84101
|
icon: "flame"
|
|
83711
84102
|
}]
|
|
83712
84103
|
},
|
|
84104
|
+
"group-commands": {
|
|
84105
|
+
scope: "device",
|
|
84106
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84107
|
+
},
|
|
84108
|
+
"group-status": {
|
|
84109
|
+
scope: "device",
|
|
84110
|
+
noun: t("Group", "Gruppo"),
|
|
84111
|
+
state: [
|
|
84112
|
+
{
|
|
84113
|
+
kind: "numeric",
|
|
84114
|
+
field: "included",
|
|
84115
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84116
|
+
label: t("Reporting", "Rispondono"),
|
|
84117
|
+
icon: "users"
|
|
84118
|
+
},
|
|
84119
|
+
{
|
|
84120
|
+
kind: "numeric",
|
|
84121
|
+
field: "excluded",
|
|
84122
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84123
|
+
label: t("Excluded", "Esclusi"),
|
|
84124
|
+
icon: "users"
|
|
84125
|
+
},
|
|
84126
|
+
{
|
|
84127
|
+
kind: "numeric",
|
|
84128
|
+
field: "total",
|
|
84129
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84130
|
+
label: t("Members", "Membri"),
|
|
84131
|
+
icon: "sigma"
|
|
84132
|
+
}
|
|
84133
|
+
]
|
|
84134
|
+
},
|
|
83713
84135
|
"humidity-sensor": {
|
|
83714
84136
|
scope: "device",
|
|
83715
84137
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83743,7 +84165,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83743
84165
|
field: "value",
|
|
83744
84166
|
quantity: t("the reading", "il valore"),
|
|
83745
84167
|
label: t("Reading", "Valore"),
|
|
83746
|
-
unitField: "unit",
|
|
83747
84168
|
icon: "gauge"
|
|
83748
84169
|
}]
|
|
83749
84170
|
},
|
|
@@ -83879,7 +84300,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83879
84300
|
field: "temperature",
|
|
83880
84301
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83881
84302
|
label: t("Temperature", "Temperatura"),
|
|
83882
|
-
|
|
84303
|
+
unit: "°C",
|
|
83883
84304
|
icon: "thermometer"
|
|
83884
84305
|
},
|
|
83885
84306
|
{
|
|
@@ -83895,7 +84316,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83895
84316
|
field: "windSpeed",
|
|
83896
84317
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83897
84318
|
label: t("Wind", "Vento"),
|
|
83898
|
-
|
|
84319
|
+
unit: "m/s",
|
|
83899
84320
|
icon: "wind"
|
|
83900
84321
|
},
|
|
83901
84322
|
{
|
|
@@ -83903,7 +84324,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83903
84324
|
field: "pressure",
|
|
83904
84325
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83905
84326
|
label: t("Pressure", "Pressione"),
|
|
83906
|
-
|
|
84327
|
+
unit: "hPa",
|
|
83907
84328
|
icon: "gauge"
|
|
83908
84329
|
}
|
|
83909
84330
|
]
|
|
@@ -85176,6 +85597,16 @@ Object.freeze({
|
|
|
85176
85597
|
form: "single",
|
|
85177
85598
|
optional: false
|
|
85178
85599
|
}],
|
|
85600
|
+
"groupCommands.getStatus": [{
|
|
85601
|
+
name: "deviceId",
|
|
85602
|
+
form: "single",
|
|
85603
|
+
optional: false
|
|
85604
|
+
}],
|
|
85605
|
+
"groupStatus.getStatus": [{
|
|
85606
|
+
name: "deviceId",
|
|
85607
|
+
form: "single",
|
|
85608
|
+
optional: false
|
|
85609
|
+
}],
|
|
85179
85610
|
"heatingValve.getStatus": [{
|
|
85180
85611
|
name: "deviceId",
|
|
85181
85612
|
form: "single",
|
|
@@ -87160,6 +87591,8 @@ new Map(Object.entries({
|
|
|
87160
87591
|
"detection-blind": "device-events",
|
|
87161
87592
|
"motion-noisy": "device-events",
|
|
87162
87593
|
"motion-calm": "device-events",
|
|
87594
|
+
"package-llm-silent": "device-events",
|
|
87595
|
+
"package-llm-answered": "device-events",
|
|
87163
87596
|
"recording-stalled": "device-events",
|
|
87164
87597
|
"recording-healthy": "device-events",
|
|
87165
87598
|
"recording-degraded": "device-events",
|
|
@@ -87243,6 +87676,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87243
87676
|
label: "Motion without a subject",
|
|
87244
87677
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87245
87678
|
},
|
|
87679
|
+
{
|
|
87680
|
+
id: "package-llm",
|
|
87681
|
+
family: "device-events",
|
|
87682
|
+
label: "Package confirm",
|
|
87683
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87684
|
+
},
|
|
87246
87685
|
{
|
|
87247
87686
|
id: "recording",
|
|
87248
87687
|
family: "device-events",
|
|
@@ -87424,6 +87863,8 @@ var DEVICE_EVENTS = [
|
|
|
87424
87863
|
"detection-blind",
|
|
87425
87864
|
"motion-noisy",
|
|
87426
87865
|
"motion-calm",
|
|
87866
|
+
"package-llm-silent",
|
|
87867
|
+
"package-llm-answered",
|
|
87427
87868
|
"recording-stalled",
|
|
87428
87869
|
"recording-healthy",
|
|
87429
87870
|
"recording-degraded",
|
|
@@ -87692,6 +88133,15 @@ new Map([
|
|
|
87692
88133
|
snapshotLabel: "Cameras with constant motion now",
|
|
87693
88134
|
snapshotSection: null
|
|
87694
88135
|
},
|
|
88136
|
+
{
|
|
88137
|
+
id: "package-llm-confirm",
|
|
88138
|
+
family: "device-events",
|
|
88139
|
+
label: "Package confirm (not answering / answering again)",
|
|
88140
|
+
bad: ["package-llm-silent"],
|
|
88141
|
+
recovery: ["package-llm-answered"],
|
|
88142
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88143
|
+
snapshotSection: null
|
|
88144
|
+
},
|
|
87695
88145
|
{
|
|
87696
88146
|
id: "recording-health",
|
|
87697
88147
|
family: "device-events",
|