@camstack/addon-provider-amcrest 0.2.159 → 0.2.161
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 +20 -0
- package/dist/addon.js +966 -509
- package/dist/addon.mjs +966 -509
- package/package.json +10 -3
package/dist/addon.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import { networkInterfaces } from "node:os";
|
|
|
14
14
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
15
15
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
16
16
|
//#endregion
|
|
17
|
-
//#region ../types/dist/event-category-
|
|
17
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
18
18
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
19
19
|
EventCategory["SystemBoot"] = "system.boot";
|
|
20
20
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -340,6 +340,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
340
340
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
341
341
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
342
342
|
/**
|
|
343
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
344
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
345
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
346
|
+
*/
|
|
347
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
348
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
349
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
350
|
+
/**
|
|
343
351
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
344
352
|
* (a settings change via `setAgentInferenceDevices` /
|
|
345
353
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5449,7 +5457,7 @@ var ZodIssueCode = {
|
|
|
5449
5457
|
var ZodFirstPartyTypeKind;
|
|
5450
5458
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5451
5459
|
//#endregion
|
|
5452
|
-
//#region ../types/dist/sleep-
|
|
5460
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5453
5461
|
/**
|
|
5454
5462
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5455
5463
|
* window to float samples (D455).
|
|
@@ -8003,6 +8011,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
8003
8011
|
}).strict();
|
|
8004
8012
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8005
8013
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8014
|
+
var READING_QUANTITIES = [
|
|
8015
|
+
"temperature",
|
|
8016
|
+
"pressure",
|
|
8017
|
+
"speed",
|
|
8018
|
+
"precipitation",
|
|
8019
|
+
"precipitation-rate",
|
|
8020
|
+
"length",
|
|
8021
|
+
"area",
|
|
8022
|
+
"illuminance",
|
|
8023
|
+
"irradiance",
|
|
8024
|
+
"power",
|
|
8025
|
+
"energy",
|
|
8026
|
+
"voltage",
|
|
8027
|
+
"current",
|
|
8028
|
+
"apparent-power",
|
|
8029
|
+
"humidity",
|
|
8030
|
+
"percentage",
|
|
8031
|
+
"concentration-volume",
|
|
8032
|
+
"concentration-mass",
|
|
8033
|
+
"concentration-ppb",
|
|
8034
|
+
"volume",
|
|
8035
|
+
"duration",
|
|
8036
|
+
"duration-ms",
|
|
8037
|
+
"information",
|
|
8038
|
+
"sound-level",
|
|
8039
|
+
"signal-level",
|
|
8040
|
+
"colour-temperature",
|
|
8041
|
+
"angle",
|
|
8042
|
+
"bitrate",
|
|
8043
|
+
"rate",
|
|
8044
|
+
"mass",
|
|
8045
|
+
"index",
|
|
8046
|
+
"ratio",
|
|
8047
|
+
"count",
|
|
8048
|
+
"none",
|
|
8049
|
+
"device"
|
|
8050
|
+
];
|
|
8051
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8052
|
+
new Set(READING_QUANTITIES);
|
|
8053
|
+
/**
|
|
8054
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8055
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8056
|
+
*/
|
|
8057
|
+
var QUANTITY_BASE = {
|
|
8058
|
+
temperature: "°C",
|
|
8059
|
+
pressure: "hPa",
|
|
8060
|
+
speed: "m/s",
|
|
8061
|
+
precipitation: "mm",
|
|
8062
|
+
"precipitation-rate": "mm/h",
|
|
8063
|
+
length: "m",
|
|
8064
|
+
area: "m²",
|
|
8065
|
+
illuminance: "lx",
|
|
8066
|
+
irradiance: "W/m²",
|
|
8067
|
+
power: "W",
|
|
8068
|
+
energy: "kWh",
|
|
8069
|
+
voltage: "V",
|
|
8070
|
+
current: "A",
|
|
8071
|
+
"apparent-power": "VA",
|
|
8072
|
+
humidity: "%",
|
|
8073
|
+
percentage: "%",
|
|
8074
|
+
"concentration-volume": "ppm",
|
|
8075
|
+
"concentration-mass": "µg/m³",
|
|
8076
|
+
"concentration-ppb": "ppb",
|
|
8077
|
+
volume: "L",
|
|
8078
|
+
duration: "s",
|
|
8079
|
+
"duration-ms": "ms",
|
|
8080
|
+
information: "B",
|
|
8081
|
+
"sound-level": "dBFS",
|
|
8082
|
+
"signal-level": "dBm",
|
|
8083
|
+
"colour-temperature": "mired",
|
|
8084
|
+
angle: "°",
|
|
8085
|
+
bitrate: "kbps",
|
|
8086
|
+
rate: "fps",
|
|
8087
|
+
mass: "kg",
|
|
8088
|
+
index: "none",
|
|
8089
|
+
ratio: "none",
|
|
8090
|
+
count: "none",
|
|
8091
|
+
none: "none",
|
|
8092
|
+
device: "device"
|
|
8093
|
+
};
|
|
8094
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8095
|
+
function baseUnitOf(quantity) {
|
|
8096
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8097
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8098
|
+
return symbol;
|
|
8099
|
+
}
|
|
8100
|
+
function readingMeta(quantity, extras) {
|
|
8101
|
+
return {
|
|
8102
|
+
quantity,
|
|
8103
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8104
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8105
|
+
};
|
|
8106
|
+
}
|
|
8006
8107
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8007
8108
|
var CamProfileSchema = _enum([
|
|
8008
8109
|
"high",
|
|
@@ -8030,8 +8131,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8030
8131
|
"derived"
|
|
8031
8132
|
]);
|
|
8032
8133
|
var CamStreamResolutionSchema = object({
|
|
8033
|
-
width: number().int().positive(),
|
|
8034
|
-
height: number().int().positive()
|
|
8134
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8135
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8035
8136
|
});
|
|
8036
8137
|
var CameraStreamSchema = object({
|
|
8037
8138
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8549,6 +8650,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8549
8650
|
"filesystem-browse",
|
|
8550
8651
|
"flood",
|
|
8551
8652
|
"gas",
|
|
8653
|
+
"group-commands",
|
|
8654
|
+
"group-status",
|
|
8552
8655
|
"heating-valve",
|
|
8553
8656
|
"humidifier",
|
|
8554
8657
|
"humidity-sensor",
|
|
@@ -8678,14 +8781,6 @@ Object.freeze({
|
|
|
8678
8781
|
{
|
|
8679
8782
|
"path": "aqi",
|
|
8680
8783
|
"valueType": "number"
|
|
8681
|
-
},
|
|
8682
|
-
{
|
|
8683
|
-
"path": "unit",
|
|
8684
|
-
"valueType": "string"
|
|
8685
|
-
},
|
|
8686
|
-
{
|
|
8687
|
-
"path": "precision",
|
|
8688
|
-
"valueType": "number"
|
|
8689
8784
|
}
|
|
8690
8785
|
],
|
|
8691
8786
|
"alarm-panel": [
|
|
@@ -8721,20 +8816,10 @@ Object.freeze({
|
|
|
8721
8816
|
"valueType": "boolean"
|
|
8722
8817
|
}
|
|
8723
8818
|
],
|
|
8724
|
-
"ambient-light-sensor": [
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
},
|
|
8729
|
-
{
|
|
8730
|
-
"path": "unit",
|
|
8731
|
-
"valueType": "string"
|
|
8732
|
-
},
|
|
8733
|
-
{
|
|
8734
|
-
"path": "precision",
|
|
8735
|
-
"valueType": "number"
|
|
8736
|
-
}
|
|
8737
|
-
],
|
|
8819
|
+
"ambient-light-sensor": [{
|
|
8820
|
+
"path": "lux",
|
|
8821
|
+
"valueType": "number"
|
|
8822
|
+
}],
|
|
8738
8823
|
"audio-metrics": [
|
|
8739
8824
|
{
|
|
8740
8825
|
"path": "ts",
|
|
@@ -8814,6 +8899,10 @@ Object.freeze({
|
|
|
8814
8899
|
"path": "lastUpdated",
|
|
8815
8900
|
"valueType": "number"
|
|
8816
8901
|
},
|
|
8902
|
+
{
|
|
8903
|
+
"path": "volts",
|
|
8904
|
+
"valueType": "number"
|
|
8905
|
+
},
|
|
8817
8906
|
{
|
|
8818
8907
|
"path": "lastContactAt",
|
|
8819
8908
|
"valueType": "number"
|
|
@@ -9056,10 +9145,6 @@ Object.freeze({
|
|
|
9056
9145
|
"datetime"
|
|
9057
9146
|
]
|
|
9058
9147
|
},
|
|
9059
|
-
{
|
|
9060
|
-
"path": "unit",
|
|
9061
|
-
"valueType": "string"
|
|
9062
|
-
},
|
|
9063
9148
|
{
|
|
9064
9149
|
"path": "min",
|
|
9065
9150
|
"valueType": "number"
|
|
@@ -9071,19 +9156,6 @@ Object.freeze({
|
|
|
9071
9156
|
{
|
|
9072
9157
|
"path": "step",
|
|
9073
9158
|
"valueType": "number"
|
|
9074
|
-
},
|
|
9075
|
-
{
|
|
9076
|
-
"path": "precision",
|
|
9077
|
-
"valueType": "number"
|
|
9078
|
-
},
|
|
9079
|
-
{
|
|
9080
|
-
"path": "format",
|
|
9081
|
-
"valueType": "enum",
|
|
9082
|
-
"enumValues": [
|
|
9083
|
-
"date",
|
|
9084
|
-
"time",
|
|
9085
|
-
"datetime"
|
|
9086
|
-
]
|
|
9087
9159
|
}
|
|
9088
9160
|
],
|
|
9089
9161
|
"cover": [
|
|
@@ -9324,13 +9396,8 @@ Object.freeze({
|
|
|
9324
9396
|
"path": "value",
|
|
9325
9397
|
"valueType": "string"
|
|
9326
9398
|
}, {
|
|
9327
|
-
"path": "
|
|
9328
|
-
"valueType": "
|
|
9329
|
-
"enumValues": [
|
|
9330
|
-
"date",
|
|
9331
|
-
"time",
|
|
9332
|
-
"datetime"
|
|
9333
|
-
]
|
|
9399
|
+
"path": "timestamp",
|
|
9400
|
+
"valueType": "boolean"
|
|
9334
9401
|
}],
|
|
9335
9402
|
"event-emitter": [
|
|
9336
9403
|
{
|
|
@@ -9403,6 +9470,20 @@ Object.freeze({
|
|
|
9403
9470
|
"path": "detected",
|
|
9404
9471
|
"valueType": "boolean"
|
|
9405
9472
|
}],
|
|
9473
|
+
"group-status": [
|
|
9474
|
+
{
|
|
9475
|
+
"path": "included",
|
|
9476
|
+
"valueType": "number"
|
|
9477
|
+
},
|
|
9478
|
+
{
|
|
9479
|
+
"path": "excluded",
|
|
9480
|
+
"valueType": "number"
|
|
9481
|
+
},
|
|
9482
|
+
{
|
|
9483
|
+
"path": "total",
|
|
9484
|
+
"valueType": "number"
|
|
9485
|
+
}
|
|
9486
|
+
],
|
|
9406
9487
|
"heating-valve": [{
|
|
9407
9488
|
"path": "position",
|
|
9408
9489
|
"valueType": "number"
|
|
@@ -9437,20 +9518,10 @@ Object.freeze({
|
|
|
9437
9518
|
"valueType": "number"
|
|
9438
9519
|
}
|
|
9439
9520
|
],
|
|
9440
|
-
"humidity-sensor": [
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
},
|
|
9445
|
-
{
|
|
9446
|
-
"path": "unit",
|
|
9447
|
-
"valueType": "string"
|
|
9448
|
-
},
|
|
9449
|
-
{
|
|
9450
|
-
"path": "precision",
|
|
9451
|
-
"valueType": "number"
|
|
9452
|
-
}
|
|
9453
|
-
],
|
|
9521
|
+
"humidity-sensor": [{
|
|
9522
|
+
"path": "percent",
|
|
9523
|
+
"valueType": "number"
|
|
9524
|
+
}],
|
|
9454
9525
|
"image": [{
|
|
9455
9526
|
"path": "url",
|
|
9456
9527
|
"valueType": "string"
|
|
@@ -9789,20 +9860,10 @@ Object.freeze({
|
|
|
9789
9860
|
"valueType": "boolean"
|
|
9790
9861
|
}
|
|
9791
9862
|
],
|
|
9792
|
-
"numeric-sensor": [
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
},
|
|
9797
|
-
{
|
|
9798
|
-
"path": "unit",
|
|
9799
|
-
"valueType": "string"
|
|
9800
|
-
},
|
|
9801
|
-
{
|
|
9802
|
-
"path": "precision",
|
|
9803
|
-
"valueType": "number"
|
|
9804
|
-
}
|
|
9805
|
-
],
|
|
9863
|
+
"numeric-sensor": [{
|
|
9864
|
+
"path": "value",
|
|
9865
|
+
"valueType": "number"
|
|
9866
|
+
}],
|
|
9806
9867
|
"pet-feeder": [
|
|
9807
9868
|
{
|
|
9808
9869
|
"path": "foodLevel",
|
|
@@ -9894,14 +9955,6 @@ Object.freeze({
|
|
|
9894
9955
|
{
|
|
9895
9956
|
"path": "powerFactor",
|
|
9896
9957
|
"valueType": "number"
|
|
9897
|
-
},
|
|
9898
|
-
{
|
|
9899
|
-
"path": "unit",
|
|
9900
|
-
"valueType": "string"
|
|
9901
|
-
},
|
|
9902
|
-
{
|
|
9903
|
-
"path": "precision",
|
|
9904
|
-
"valueType": "number"
|
|
9905
9958
|
}
|
|
9906
9959
|
],
|
|
9907
9960
|
"presence": [
|
|
@@ -9930,20 +9983,10 @@ Object.freeze({
|
|
|
9930
9983
|
"valueType": "number"
|
|
9931
9984
|
}
|
|
9932
9985
|
],
|
|
9933
|
-
"pressure-sensor": [
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
},
|
|
9938
|
-
{
|
|
9939
|
-
"path": "unit",
|
|
9940
|
-
"valueType": "string"
|
|
9941
|
-
},
|
|
9942
|
-
{
|
|
9943
|
-
"path": "precision",
|
|
9944
|
-
"valueType": "number"
|
|
9945
|
-
}
|
|
9946
|
-
],
|
|
9986
|
+
"pressure-sensor": [{
|
|
9987
|
+
"path": "hpa",
|
|
9988
|
+
"valueType": "number"
|
|
9989
|
+
}],
|
|
9947
9990
|
"privacy-mask": [{
|
|
9948
9991
|
"path": "enabled",
|
|
9949
9992
|
"valueType": "boolean"
|
|
@@ -10254,20 +10297,10 @@ Object.freeze({
|
|
|
10254
10297
|
"path": "tampered",
|
|
10255
10298
|
"valueType": "boolean"
|
|
10256
10299
|
}],
|
|
10257
|
-
"temperature-sensor": [
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
},
|
|
10262
|
-
{
|
|
10263
|
-
"path": "unit",
|
|
10264
|
-
"valueType": "string"
|
|
10265
|
-
},
|
|
10266
|
-
{
|
|
10267
|
-
"path": "precision",
|
|
10268
|
-
"valueType": "number"
|
|
10269
|
-
}
|
|
10270
|
-
],
|
|
10300
|
+
"temperature-sensor": [{
|
|
10301
|
+
"path": "celsius",
|
|
10302
|
+
"valueType": "number"
|
|
10303
|
+
}],
|
|
10271
10304
|
"update": [
|
|
10272
10305
|
{
|
|
10273
10306
|
"path": "currentVersion",
|
|
@@ -10378,10 +10411,6 @@ Object.freeze({
|
|
|
10378
10411
|
"path": "temperature",
|
|
10379
10412
|
"valueType": "number"
|
|
10380
10413
|
},
|
|
10381
|
-
{
|
|
10382
|
-
"path": "temperatureUnit",
|
|
10383
|
-
"valueType": "string"
|
|
10384
|
-
},
|
|
10385
10414
|
{
|
|
10386
10415
|
"path": "humidity",
|
|
10387
10416
|
"valueType": "number"
|
|
@@ -10390,18 +10419,10 @@ Object.freeze({
|
|
|
10390
10419
|
"path": "pressure",
|
|
10391
10420
|
"valueType": "number"
|
|
10392
10421
|
},
|
|
10393
|
-
{
|
|
10394
|
-
"path": "pressureUnit",
|
|
10395
|
-
"valueType": "string"
|
|
10396
|
-
},
|
|
10397
10422
|
{
|
|
10398
10423
|
"path": "windSpeed",
|
|
10399
10424
|
"valueType": "number"
|
|
10400
10425
|
},
|
|
10401
|
-
{
|
|
10402
|
-
"path": "windSpeedUnit",
|
|
10403
|
-
"valueType": "string"
|
|
10404
|
-
},
|
|
10405
10426
|
{
|
|
10406
10427
|
"path": "windBearing",
|
|
10407
10428
|
"valueType": "number"
|
|
@@ -10808,7 +10829,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10808
10829
|
return DeviceRole;
|
|
10809
10830
|
}({});
|
|
10810
10831
|
//#endregion
|
|
10811
|
-
//#region ../types/dist/composition-
|
|
10832
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10812
10833
|
/**
|
|
10813
10834
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10814
10835
|
*
|
|
@@ -11563,15 +11584,74 @@ function validateExpressionSource(src) {
|
|
|
11563
11584
|
}
|
|
11564
11585
|
return null;
|
|
11565
11586
|
}
|
|
11566
|
-
/**
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11587
|
+
/**
|
|
11588
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11589
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11590
|
+
* `composition.ts` (D659).
|
|
11591
|
+
*/
|
|
11570
11592
|
var CompositionSourceRefSchema = object({
|
|
11571
11593
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11572
11594
|
addonId: string().min(1),
|
|
11573
11595
|
stableId: string().min(1)
|
|
11574
11596
|
});
|
|
11597
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11598
|
+
"temperature",
|
|
11599
|
+
"humidity",
|
|
11600
|
+
"pressure",
|
|
11601
|
+
"illuminance",
|
|
11602
|
+
"power",
|
|
11603
|
+
"energy",
|
|
11604
|
+
"battery",
|
|
11605
|
+
"numeric",
|
|
11606
|
+
"motion",
|
|
11607
|
+
"contact",
|
|
11608
|
+
"leak",
|
|
11609
|
+
"smoke",
|
|
11610
|
+
"occupancy",
|
|
11611
|
+
"binary",
|
|
11612
|
+
"switch",
|
|
11613
|
+
"light"
|
|
11614
|
+
];
|
|
11615
|
+
var NUMERIC_AGGREGATES = [
|
|
11616
|
+
"mean",
|
|
11617
|
+
"median",
|
|
11618
|
+
"min",
|
|
11619
|
+
"max",
|
|
11620
|
+
"sum"
|
|
11621
|
+
];
|
|
11622
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11623
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11624
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11625
|
+
var AGGREGATE_REDUCERS = [
|
|
11626
|
+
"mean",
|
|
11627
|
+
"median",
|
|
11628
|
+
"min",
|
|
11629
|
+
"max",
|
|
11630
|
+
"sum",
|
|
11631
|
+
"any",
|
|
11632
|
+
"all"
|
|
11633
|
+
];
|
|
11634
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11635
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11636
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11637
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11638
|
+
var HelperMemberSchema = object({
|
|
11639
|
+
source: CompositionSourceRefSchema,
|
|
11640
|
+
cap: string().min(1),
|
|
11641
|
+
fieldPath: string().min(1)
|
|
11642
|
+
});
|
|
11643
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11644
|
+
kind: literal("group"),
|
|
11645
|
+
templateId: GroupTemplateIdSchema,
|
|
11646
|
+
aggregate: AggregateReducerSchema,
|
|
11647
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11648
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11649
|
+
active: ActiveCriterionSchema.optional()
|
|
11650
|
+
})]);
|
|
11651
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11652
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11653
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11654
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11575
11655
|
/** One field of one capability of one source device. */
|
|
11576
11656
|
var CompositionFieldReadSchema = object({
|
|
11577
11657
|
source: CompositionSourceRefSchema,
|
|
@@ -11615,7 +11695,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11615
11695
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11616
11696
|
CompositionFromSourceSchema,
|
|
11617
11697
|
CompositionExpressionSourceSchema,
|
|
11618
|
-
CompositionCodeSourceSchema
|
|
11698
|
+
CompositionCodeSourceSchema,
|
|
11699
|
+
object({
|
|
11700
|
+
kind: literal("aggregate"),
|
|
11701
|
+
reducer: _enum([
|
|
11702
|
+
"mean",
|
|
11703
|
+
"median",
|
|
11704
|
+
"min",
|
|
11705
|
+
"max",
|
|
11706
|
+
"sum",
|
|
11707
|
+
"any",
|
|
11708
|
+
"all"
|
|
11709
|
+
]),
|
|
11710
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11711
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11712
|
+
publish: _enum([
|
|
11713
|
+
"value",
|
|
11714
|
+
"included",
|
|
11715
|
+
"excluded",
|
|
11716
|
+
"total"
|
|
11717
|
+
]),
|
|
11718
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11719
|
+
empty: _enum([
|
|
11720
|
+
"null",
|
|
11721
|
+
"omit",
|
|
11722
|
+
"offline"
|
|
11723
|
+
])
|
|
11724
|
+
})
|
|
11619
11725
|
]);
|
|
11620
11726
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11621
11727
|
kind: literal("forward"),
|
|
@@ -11661,7 +11767,13 @@ var CompositionSchema = object({
|
|
|
11661
11767
|
kind: literal("existing"),
|
|
11662
11768
|
device: CompositionSourceRefSchema
|
|
11663
11769
|
})]),
|
|
11664
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11770
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11771
|
+
/**
|
|
11772
|
+
* Present when the block is a helper template. Absent on a free
|
|
11773
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11774
|
+
* never the compiled features.
|
|
11775
|
+
*/
|
|
11776
|
+
helper: HelperSpecSchema.optional()
|
|
11665
11777
|
}).superRefine((composition, ctx) => {
|
|
11666
11778
|
const seen = /* @__PURE__ */ new Set();
|
|
11667
11779
|
composition.features.forEach((feature, index) => {
|
|
@@ -17907,7 +18019,11 @@ var CompositionProblemSchema = object({
|
|
|
17907
18019
|
"item-field-reserved",
|
|
17908
18020
|
"target-missing",
|
|
17909
18021
|
"target-unreadable",
|
|
17910
|
-
"not-replaceable"
|
|
18022
|
+
"not-replaceable",
|
|
18023
|
+
"native-capability-replace",
|
|
18024
|
+
"mixed-quantity",
|
|
18025
|
+
"helper-mismatch",
|
|
18026
|
+
"member-constraint"
|
|
17911
18027
|
]),
|
|
17912
18028
|
path: string(),
|
|
17913
18029
|
message: string()
|
|
@@ -17928,7 +18044,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17928
18044
|
"null",
|
|
17929
18045
|
"offline",
|
|
17930
18046
|
"unknown",
|
|
17931
|
-
"release"
|
|
18047
|
+
"release",
|
|
18048
|
+
"omit"
|
|
17932
18049
|
]);
|
|
17933
18050
|
/**
|
|
17934
18051
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -17965,9 +18082,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17965
18082
|
reads: array(CompositionFieldReadSchema)
|
|
17966
18083
|
});
|
|
17967
18084
|
/**
|
|
17968
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17969
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17970
|
-
*
|
|
18085
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18086
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18087
|
+
* Replacing a capability the device already serves is refused
|
|
18088
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18089
|
+
* wire for a claim the hub already holds.
|
|
17971
18090
|
*/
|
|
17972
18091
|
var CompositionFeatureModeSchema = _enum([
|
|
17973
18092
|
"new",
|
|
@@ -18140,6 +18259,275 @@ Object.freeze({
|
|
|
18140
18259
|
result: ["number", "null"]
|
|
18141
18260
|
}
|
|
18142
18261
|
});
|
|
18262
|
+
/**
|
|
18263
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18264
|
+
* Data, not a form default written into the block.
|
|
18265
|
+
*/
|
|
18266
|
+
var NOW = {
|
|
18267
|
+
fieldPath: "lastFetchedAt",
|
|
18268
|
+
expr: "now"
|
|
18269
|
+
};
|
|
18270
|
+
var CHANGED = {
|
|
18271
|
+
fieldPath: "lastChangedAt",
|
|
18272
|
+
expr: "now"
|
|
18273
|
+
};
|
|
18274
|
+
function numeric(input) {
|
|
18275
|
+
return {
|
|
18276
|
+
...input,
|
|
18277
|
+
family: "numeric",
|
|
18278
|
+
deviceType: DeviceType.Sensor,
|
|
18279
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18280
|
+
commandCaps: [],
|
|
18281
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18282
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18283
|
+
accept: [{
|
|
18284
|
+
cap: input.outputCap,
|
|
18285
|
+
fieldPath: input.outputField
|
|
18286
|
+
}]
|
|
18287
|
+
};
|
|
18288
|
+
}
|
|
18289
|
+
function binary(input) {
|
|
18290
|
+
return {
|
|
18291
|
+
...input,
|
|
18292
|
+
family: "binary",
|
|
18293
|
+
deviceType: DeviceType.Sensor,
|
|
18294
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18295
|
+
commandCaps: [],
|
|
18296
|
+
quantity: "none",
|
|
18297
|
+
baseUnit: void 0,
|
|
18298
|
+
aggregates: BINARY_AGGREGATES,
|
|
18299
|
+
empty: "offline"
|
|
18300
|
+
};
|
|
18301
|
+
}
|
|
18302
|
+
var GROUP_TEMPLATES = [
|
|
18303
|
+
numeric({
|
|
18304
|
+
id: "temperature",
|
|
18305
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18306
|
+
role: DeviceRole.TemperatureSensor,
|
|
18307
|
+
outputCap: "temperature-sensor",
|
|
18308
|
+
outputField: "celsius",
|
|
18309
|
+
quantity: "temperature",
|
|
18310
|
+
defaultAggregate: "mean",
|
|
18311
|
+
empty: "null",
|
|
18312
|
+
companions: [NOW]
|
|
18313
|
+
}),
|
|
18314
|
+
numeric({
|
|
18315
|
+
id: "humidity",
|
|
18316
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18317
|
+
role: DeviceRole.HumiditySensor,
|
|
18318
|
+
outputCap: "humidity-sensor",
|
|
18319
|
+
outputField: "percent",
|
|
18320
|
+
quantity: "humidity",
|
|
18321
|
+
defaultAggregate: "mean",
|
|
18322
|
+
empty: "null",
|
|
18323
|
+
companions: [NOW]
|
|
18324
|
+
}),
|
|
18325
|
+
numeric({
|
|
18326
|
+
id: "pressure",
|
|
18327
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18328
|
+
role: DeviceRole.PressureSensor,
|
|
18329
|
+
outputCap: "pressure-sensor",
|
|
18330
|
+
outputField: "hpa",
|
|
18331
|
+
quantity: "pressure",
|
|
18332
|
+
defaultAggregate: "mean",
|
|
18333
|
+
empty: "null",
|
|
18334
|
+
companions: [NOW]
|
|
18335
|
+
}),
|
|
18336
|
+
numeric({
|
|
18337
|
+
id: "illuminance",
|
|
18338
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18339
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18340
|
+
outputCap: "ambient-light-sensor",
|
|
18341
|
+
outputField: "lux",
|
|
18342
|
+
quantity: "illuminance",
|
|
18343
|
+
defaultAggregate: "mean",
|
|
18344
|
+
empty: "null",
|
|
18345
|
+
companions: [NOW]
|
|
18346
|
+
}),
|
|
18347
|
+
numeric({
|
|
18348
|
+
id: "power",
|
|
18349
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18350
|
+
role: DeviceRole.PowerSensor,
|
|
18351
|
+
outputCap: "power-meter",
|
|
18352
|
+
outputField: "watts",
|
|
18353
|
+
quantity: "power",
|
|
18354
|
+
defaultAggregate: "sum",
|
|
18355
|
+
empty: "omit",
|
|
18356
|
+
companions: [NOW]
|
|
18357
|
+
}),
|
|
18358
|
+
numeric({
|
|
18359
|
+
id: "energy",
|
|
18360
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18361
|
+
role: DeviceRole.EnergySensor,
|
|
18362
|
+
outputCap: "power-meter",
|
|
18363
|
+
outputField: "kwhTotal",
|
|
18364
|
+
quantity: "energy",
|
|
18365
|
+
defaultAggregate: "sum",
|
|
18366
|
+
empty: "omit",
|
|
18367
|
+
companions: [NOW]
|
|
18368
|
+
}),
|
|
18369
|
+
numeric({
|
|
18370
|
+
id: "battery",
|
|
18371
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18372
|
+
role: DeviceRole.BatterySensor,
|
|
18373
|
+
outputCap: "battery",
|
|
18374
|
+
outputField: "percentage",
|
|
18375
|
+
quantity: "percentage",
|
|
18376
|
+
defaultAggregate: "mean",
|
|
18377
|
+
empty: "null",
|
|
18378
|
+
companions: [
|
|
18379
|
+
{
|
|
18380
|
+
fieldPath: "charging",
|
|
18381
|
+
expr: "\"unknown\""
|
|
18382
|
+
},
|
|
18383
|
+
{
|
|
18384
|
+
fieldPath: "sleeping",
|
|
18385
|
+
expr: "false"
|
|
18386
|
+
},
|
|
18387
|
+
{
|
|
18388
|
+
fieldPath: "lastUpdated",
|
|
18389
|
+
expr: "now"
|
|
18390
|
+
}
|
|
18391
|
+
]
|
|
18392
|
+
}),
|
|
18393
|
+
numeric({
|
|
18394
|
+
id: "numeric",
|
|
18395
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18396
|
+
role: DeviceRole.NumericSensor,
|
|
18397
|
+
outputCap: "numeric-sensor",
|
|
18398
|
+
outputField: "value",
|
|
18399
|
+
quantity: "device",
|
|
18400
|
+
defaultAggregate: "mean",
|
|
18401
|
+
empty: "null",
|
|
18402
|
+
companions: [NOW]
|
|
18403
|
+
}),
|
|
18404
|
+
binary({
|
|
18405
|
+
id: "motion",
|
|
18406
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18407
|
+
role: DeviceRole.MotionSensor,
|
|
18408
|
+
outputCap: "motion",
|
|
18409
|
+
outputField: "detected",
|
|
18410
|
+
defaultAggregate: "any",
|
|
18411
|
+
accept: [{
|
|
18412
|
+
cap: "motion",
|
|
18413
|
+
fieldPath: "detected"
|
|
18414
|
+
}],
|
|
18415
|
+
companions: [{
|
|
18416
|
+
fieldPath: "lastDetectedAt",
|
|
18417
|
+
expr: "null"
|
|
18418
|
+
}, {
|
|
18419
|
+
fieldPath: "autoClearAfterMs",
|
|
18420
|
+
expr: "null"
|
|
18421
|
+
}]
|
|
18422
|
+
}),
|
|
18423
|
+
binary({
|
|
18424
|
+
id: "contact",
|
|
18425
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18426
|
+
role: DeviceRole.ContactSensor,
|
|
18427
|
+
outputCap: "contact",
|
|
18428
|
+
outputField: "entryOpen",
|
|
18429
|
+
defaultAggregate: "any",
|
|
18430
|
+
accept: [{
|
|
18431
|
+
cap: "contact",
|
|
18432
|
+
fieldPath: "entryOpen"
|
|
18433
|
+
}],
|
|
18434
|
+
companions: [CHANGED]
|
|
18435
|
+
}),
|
|
18436
|
+
binary({
|
|
18437
|
+
id: "leak",
|
|
18438
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18439
|
+
role: DeviceRole.LeakSensor,
|
|
18440
|
+
outputCap: "flood",
|
|
18441
|
+
outputField: "flooded",
|
|
18442
|
+
defaultAggregate: "any",
|
|
18443
|
+
accept: [{
|
|
18444
|
+
cap: "flood",
|
|
18445
|
+
fieldPath: "flooded"
|
|
18446
|
+
}],
|
|
18447
|
+
companions: [CHANGED]
|
|
18448
|
+
}),
|
|
18449
|
+
binary({
|
|
18450
|
+
id: "smoke",
|
|
18451
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18452
|
+
role: DeviceRole.SmokeSensor,
|
|
18453
|
+
outputCap: "smoke",
|
|
18454
|
+
outputField: "detected",
|
|
18455
|
+
defaultAggregate: "any",
|
|
18456
|
+
accept: [{
|
|
18457
|
+
cap: "smoke",
|
|
18458
|
+
fieldPath: "detected"
|
|
18459
|
+
}],
|
|
18460
|
+
companions: [CHANGED]
|
|
18461
|
+
}),
|
|
18462
|
+
binary({
|
|
18463
|
+
id: "occupancy",
|
|
18464
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18465
|
+
role: DeviceRole.BinarySensor,
|
|
18466
|
+
outputCap: "binary",
|
|
18467
|
+
outputField: "on",
|
|
18468
|
+
defaultAggregate: "any",
|
|
18469
|
+
accept: [{
|
|
18470
|
+
cap: "motion",
|
|
18471
|
+
fieldPath: "detected"
|
|
18472
|
+
}, {
|
|
18473
|
+
cap: "binary",
|
|
18474
|
+
fieldPath: "on"
|
|
18475
|
+
}],
|
|
18476
|
+
companions: [CHANGED]
|
|
18477
|
+
}),
|
|
18478
|
+
binary({
|
|
18479
|
+
id: "binary",
|
|
18480
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18481
|
+
role: DeviceRole.BinarySensor,
|
|
18482
|
+
outputCap: "binary",
|
|
18483
|
+
outputField: "on",
|
|
18484
|
+
defaultAggregate: "any",
|
|
18485
|
+
accept: [{
|
|
18486
|
+
cap: "binary",
|
|
18487
|
+
fieldPath: "on"
|
|
18488
|
+
}],
|
|
18489
|
+
companions: [CHANGED]
|
|
18490
|
+
}),
|
|
18491
|
+
actuator({
|
|
18492
|
+
id: "switch",
|
|
18493
|
+
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.",
|
|
18494
|
+
deviceType: DeviceType.Switch,
|
|
18495
|
+
outputCap: "switch",
|
|
18496
|
+
commandCaps: ["switch"]
|
|
18497
|
+
}),
|
|
18498
|
+
actuator({
|
|
18499
|
+
id: "light",
|
|
18500
|
+
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.",
|
|
18501
|
+
deviceType: DeviceType.Light,
|
|
18502
|
+
outputCap: "switch",
|
|
18503
|
+
commandCaps: [
|
|
18504
|
+
"switch",
|
|
18505
|
+
"brightness",
|
|
18506
|
+
"color"
|
|
18507
|
+
]
|
|
18508
|
+
})
|
|
18509
|
+
];
|
|
18510
|
+
function actuator(input) {
|
|
18511
|
+
return {
|
|
18512
|
+
...input,
|
|
18513
|
+
family: "actuator",
|
|
18514
|
+
role: void 0,
|
|
18515
|
+
memberDeviceType: input.deviceType,
|
|
18516
|
+
outputField: "on",
|
|
18517
|
+
quantity: "none",
|
|
18518
|
+
baseUnit: void 0,
|
|
18519
|
+
aggregates: BINARY_AGGREGATES,
|
|
18520
|
+
defaultAggregate: "any",
|
|
18521
|
+
empty: "offline",
|
|
18522
|
+
accept: [{
|
|
18523
|
+
cap: "switch",
|
|
18524
|
+
fieldPath: "on"
|
|
18525
|
+
}],
|
|
18526
|
+
companions: [CHANGED]
|
|
18527
|
+
};
|
|
18528
|
+
}
|
|
18529
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18530
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18143
18531
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18144
18532
|
/**
|
|
18145
18533
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19966,12 +20354,12 @@ function buildDeviceAdminUrl(parts) {
|
|
|
19966
20354
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19967
20355
|
* in-place so dispatch keeps working.
|
|
19968
20356
|
*
|
|
19969
|
-
* **
|
|
19970
|
-
*
|
|
19971
|
-
*
|
|
19972
|
-
*
|
|
19973
|
-
* (`ha-domain-mapping`)
|
|
19974
|
-
* stored after that point.
|
|
20357
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20358
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20359
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20360
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20361
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20362
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19975
20363
|
*
|
|
19976
20364
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19977
20365
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19985,6 +20373,14 @@ var SourceInfoSchema = object({
|
|
|
19985
20373
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19986
20374
|
* Used to detect rename when `id` changes. */
|
|
19987
20375
|
uniqueId: string().optional(),
|
|
20376
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20377
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20378
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20379
|
+
dateTimeShape: _enum([
|
|
20380
|
+
"date",
|
|
20381
|
+
"time",
|
|
20382
|
+
"datetime"
|
|
20383
|
+
]).optional(),
|
|
19988
20384
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19989
20385
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19990
20386
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41089,7 +41485,8 @@ method(object({
|
|
|
41089
41485
|
"enum"
|
|
41090
41486
|
]),
|
|
41091
41487
|
enumValues: array(string()).optional(),
|
|
41092
|
-
item: boolean().optional()
|
|
41488
|
+
item: boolean().optional(),
|
|
41489
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41093
41490
|
})).readonly(),
|
|
41094
41491
|
itemArray: object({
|
|
41095
41492
|
path: string(),
|
|
@@ -44933,8 +45330,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44933
45330
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44934
45331
|
var MaskGridShapeSchema = object({
|
|
44935
45332
|
kind: literal("grid"),
|
|
44936
|
-
gridWidth: number(),
|
|
44937
|
-
gridHeight: number(),
|
|
45333
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45334
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44938
45335
|
cells: array(boolean())
|
|
44939
45336
|
});
|
|
44940
45337
|
discriminatedUnion("kind", [
|
|
@@ -45046,6 +45443,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45046
45443
|
"detection-blind",
|
|
45047
45444
|
"motion-noisy",
|
|
45048
45445
|
"motion-calm",
|
|
45446
|
+
"package-llm-silent",
|
|
45447
|
+
"package-llm-answered",
|
|
45049
45448
|
"recording-stalled",
|
|
45050
45449
|
"recording-healthy",
|
|
45051
45450
|
"recording-degraded",
|
|
@@ -56650,6 +57049,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56650
57049
|
deprecated: string().optional(),
|
|
56651
57050
|
distTags: array(string()).readonly()
|
|
56652
57051
|
});
|
|
57052
|
+
/**
|
|
57053
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
57054
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
57055
|
+
* tarball failure — never an empty string standing in for either.
|
|
57056
|
+
*/
|
|
57057
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
57058
|
+
object({
|
|
57059
|
+
status: literal("ok"),
|
|
57060
|
+
markdown: string()
|
|
57061
|
+
}),
|
|
57062
|
+
object({ status: literal("missing") }),
|
|
57063
|
+
object({
|
|
57064
|
+
status: literal("error"),
|
|
57065
|
+
message: string()
|
|
57066
|
+
})
|
|
57067
|
+
]);
|
|
57068
|
+
var PackageDocsSchema = object({
|
|
57069
|
+
name: string(),
|
|
57070
|
+
version: string(),
|
|
57071
|
+
readme: PackageDocBodySchema,
|
|
57072
|
+
changelog: PackageDocBodySchema
|
|
57073
|
+
});
|
|
56653
57074
|
var SearchResultSchema = object({
|
|
56654
57075
|
name: string(),
|
|
56655
57076
|
version: string(),
|
|
@@ -56868,7 +57289,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56868
57289
|
}), object({ success: literal(true) }), {
|
|
56869
57290
|
kind: "mutation",
|
|
56870
57291
|
auth: "admin"
|
|
56871
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57292
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57293
|
+
name: string().min(1),
|
|
57294
|
+
version: string().min(1).optional()
|
|
57295
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56872
57296
|
kind: "mutation",
|
|
56873
57297
|
auth: "admin"
|
|
56874
57298
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56927,27 +57351,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56927
57351
|
*/
|
|
56928
57352
|
var AirQualitySensorStatusSchema = object({
|
|
56929
57353
|
/** Carbon dioxide concentration in ppm. */
|
|
56930
|
-
co2Ppm: number().min(0).optional(),
|
|
57354
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56931
57355
|
/** Total volatile organic compounds in ppb. */
|
|
56932
|
-
vocPpb: number().min(0).optional(),
|
|
57356
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56933
57357
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56934
|
-
pm25: number().min(0).optional(),
|
|
57358
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56935
57359
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56936
|
-
pm10: number().min(0).optional(),
|
|
57360
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56937
57361
|
/** Composite AQI value (typically 0..500). */
|
|
56938
|
-
aqi: number().optional(),
|
|
57362
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56939
57363
|
/** Ms epoch when the slice was last updated. */
|
|
56940
|
-
lastFetchedAt: number()
|
|
56941
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56942
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56943
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56944
|
-
* per slice is unambiguous. */
|
|
56945
|
-
unit: string().optional(),
|
|
56946
|
-
/** Suggested decimal places for numeric display.
|
|
56947
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56948
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56949
|
-
* auto-formatting when absent. */
|
|
56950
|
-
precision: number().int().min(0).max(10).optional()
|
|
57364
|
+
lastFetchedAt: number()
|
|
56951
57365
|
});
|
|
56952
57366
|
var airQualitySensorCapability = {
|
|
56953
57367
|
name: "air-quality-sensor",
|
|
@@ -56984,12 +57398,12 @@ var airQualitySensorCapability = {
|
|
|
56984
57398
|
},
|
|
56985
57399
|
pm25: {
|
|
56986
57400
|
kind: "gauge",
|
|
56987
|
-
unit: "
|
|
57401
|
+
unit: "µg/m³",
|
|
56988
57402
|
deadband: 1
|
|
56989
57403
|
},
|
|
56990
57404
|
pm10: {
|
|
56991
57405
|
kind: "gauge",
|
|
56992
|
-
unit: "
|
|
57406
|
+
unit: "µg/m³",
|
|
56993
57407
|
deadband: 1
|
|
56994
57408
|
},
|
|
56995
57409
|
aqi: {
|
|
@@ -57007,22 +57421,13 @@ var airQualitySensorCapability = {
|
|
|
57007
57421
|
* entries with `device_class: illuminance`.
|
|
57008
57422
|
*/
|
|
57009
57423
|
var AmbientLightSensorStatusSchema = object({
|
|
57010
|
-
/** Current illuminance in lux (lx). */
|
|
57011
|
-
lux: number().min(0).meta({
|
|
57012
|
-
|
|
57424
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57425
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57426
|
+
precision: 0,
|
|
57013
57427
|
label: "Illuminance"
|
|
57014
|
-
}),
|
|
57428
|
+
})),
|
|
57015
57429
|
/** Ms epoch when the slice was last updated. */
|
|
57016
|
-
lastFetchedAt: number()
|
|
57017
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
57018
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
57019
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
57020
|
-
unit: string().optional(),
|
|
57021
|
-
/** Suggested decimal places for numeric display.
|
|
57022
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57023
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57024
|
-
* auto-formatting when absent. */
|
|
57025
|
-
precision: number().int().min(0).max(10).optional()
|
|
57430
|
+
lastFetchedAt: number()
|
|
57026
57431
|
});
|
|
57027
57432
|
var ambientLightSensorCapability = {
|
|
57028
57433
|
name: "ambient-light-sensor",
|
|
@@ -57054,12 +57459,7 @@ var ambientLightSensorCapability = {
|
|
|
57054
57459
|
} } },
|
|
57055
57460
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57056
57461
|
* whether persisting is worth a SQLite commit. */
|
|
57057
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
57058
|
-
customize: {
|
|
57059
|
-
version: 1,
|
|
57060
|
-
advanced: "derive",
|
|
57061
|
-
targets: []
|
|
57062
|
-
}
|
|
57462
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
57063
57463
|
};
|
|
57064
57464
|
/**
|
|
57065
57465
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57286,10 +57686,7 @@ var BatteryStatusSchema = object({
|
|
|
57286
57686
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57287
57687
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57288
57688
|
*/
|
|
57289
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57290
|
-
unit: "%",
|
|
57291
|
-
label: "Charge"
|
|
57292
|
-
}),
|
|
57689
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57293
57690
|
/**
|
|
57294
57691
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57295
57692
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57316,7 +57713,14 @@ var BatteryStatusSchema = object({
|
|
|
57316
57713
|
*/
|
|
57317
57714
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57318
57715
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57319
|
-
lastUpdated: number(),
|
|
57716
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57717
|
+
/**
|
|
57718
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57719
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57720
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57721
|
+
* `numeric-sensor` on the same device.
|
|
57722
|
+
*/
|
|
57723
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57320
57724
|
/**
|
|
57321
57725
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57322
57726
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57368,7 +57772,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57368
57772
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57369
57773
|
var batteryCustomize = {
|
|
57370
57774
|
version: 1,
|
|
57371
|
-
advanced: "derive",
|
|
57372
57775
|
targets: [{
|
|
57373
57776
|
id: "percentage",
|
|
57374
57777
|
cardinality: "scalar",
|
|
@@ -57377,7 +57780,7 @@ var batteryCustomize = {
|
|
|
57377
57780
|
stateField: "percentage"
|
|
57378
57781
|
},
|
|
57379
57782
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57380
|
-
apply: "add
|
|
57783
|
+
apply: "add",
|
|
57381
57784
|
path: "percentage",
|
|
57382
57785
|
sources: [{
|
|
57383
57786
|
kind: "field",
|
|
@@ -57498,10 +57901,16 @@ onStatusChanged: { data: object({
|
|
|
57498
57901
|
/**
|
|
57499
57902
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57500
57903
|
*/
|
|
57501
|
-
history: { fields: {
|
|
57502
|
-
|
|
57503
|
-
|
|
57504
|
-
|
|
57904
|
+
history: { fields: {
|
|
57905
|
+
percentage: {
|
|
57906
|
+
kind: "gauge",
|
|
57907
|
+
unit: "%"
|
|
57908
|
+
},
|
|
57909
|
+
volts: {
|
|
57910
|
+
kind: "gauge",
|
|
57911
|
+
unit: "V"
|
|
57912
|
+
}
|
|
57913
|
+
} },
|
|
57505
57914
|
customize: batteryCustomize,
|
|
57506
57915
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57507
57916
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57548,12 +57957,7 @@ var binaryCapability = {
|
|
|
57548
57957
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57549
57958
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57550
57959
|
* whether persisting is worth a SQLite commit. */
|
|
57551
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57552
|
-
customize: {
|
|
57553
|
-
version: 1,
|
|
57554
|
-
advanced: "derive",
|
|
57555
|
-
targets: []
|
|
57556
|
-
}
|
|
57960
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57557
57961
|
};
|
|
57558
57962
|
/**
|
|
57559
57963
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57569,7 +57973,7 @@ var binaryCapability = {
|
|
|
57569
57973
|
*/
|
|
57570
57974
|
var BrightnessStatusSchema = object({
|
|
57571
57975
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57572
|
-
percentage: number().min(0).max(100),
|
|
57976
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57573
57977
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57574
57978
|
lastChangedAt: number()
|
|
57575
57979
|
});
|
|
@@ -58023,21 +58427,21 @@ var ClimateControlStatusSchema = object({
|
|
|
58023
58427
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
58024
58428
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
58025
58429
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
58026
|
-
target: number().nullable(),
|
|
58430
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
58027
58431
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
58028
58432
|
* in `heat_cool` mode. */
|
|
58029
|
-
targetHigh: number().nullable(),
|
|
58433
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
58030
58434
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
58031
58435
|
* in `heat_cool` mode. */
|
|
58032
|
-
targetLow: number().nullable(),
|
|
58436
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
58033
58437
|
/** Target relative humidity (0..100). Null when the device has no
|
|
58034
58438
|
* humidity control. */
|
|
58035
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58439
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58036
58440
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
58037
58441
|
* the device's internal sensor. */
|
|
58038
|
-
currentTemp: number().nullable(),
|
|
58442
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
58039
58443
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
58040
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58444
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58041
58445
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
58042
58446
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
58043
58447
|
swingVertical: boolean().nullable(),
|
|
@@ -58045,11 +58449,11 @@ var ClimateControlStatusSchema = object({
|
|
|
58045
58449
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
58046
58450
|
swingHorizontal: boolean().nullable(),
|
|
58047
58451
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58048
|
-
minTemp: number().nullable().optional(),
|
|
58452
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58049
58453
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58050
|
-
maxTemp: number().nullable().optional(),
|
|
58454
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58051
58455
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
58052
|
-
tempStep: number().positive().nullable().optional(),
|
|
58456
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
58053
58457
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
58054
58458
|
lastFetchedAt: number()
|
|
58055
58459
|
});
|
|
@@ -58191,17 +58595,17 @@ var climateControlCapability = {
|
|
|
58191
58595
|
* modes to expose in the picker without a slice fetch.
|
|
58192
58596
|
*/
|
|
58193
58597
|
var RgbTripletSchema = object({
|
|
58194
|
-
r: number().int().min(0).max(255),
|
|
58195
|
-
g: number().int().min(0).max(255),
|
|
58196
|
-
b: number().int().min(0).max(255)
|
|
58598
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58599
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58600
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
58197
58601
|
});
|
|
58198
58602
|
var HsvTripletSchema = object({
|
|
58199
58603
|
/** Hue in degrees, 0..360. */
|
|
58200
|
-
h: number().min(0).max(360),
|
|
58604
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
58201
58605
|
/** Saturation as 0..100 inclusive. */
|
|
58202
|
-
s: number().min(0).max(100),
|
|
58606
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
58203
58607
|
/** Value/brightness as 0..100 inclusive. */
|
|
58204
|
-
v: number().min(0).max(100)
|
|
58608
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
58205
58609
|
});
|
|
58206
58610
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
58207
58611
|
object({
|
|
@@ -58230,7 +58634,7 @@ var ColorStatusSchema = object({
|
|
|
58230
58634
|
/** Populated when `mode === 'hsv'`. */
|
|
58231
58635
|
hsv: HsvTripletSchema.optional(),
|
|
58232
58636
|
/** Populated when `mode === 'mired'`. */
|
|
58233
|
-
mireds: number().int().optional(),
|
|
58637
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58234
58638
|
/** Ms epoch of the last operator-driven change. */
|
|
58235
58639
|
lastChangedAt: number()
|
|
58236
58640
|
});
|
|
@@ -58425,18 +58829,12 @@ _enum([
|
|
|
58425
58829
|
"empty",
|
|
58426
58830
|
"full"
|
|
58427
58831
|
]);
|
|
58428
|
-
/**
|
|
58429
|
-
|
|
58430
|
-
|
|
58431
|
-
"days",
|
|
58432
|
-
"hours",
|
|
58433
|
-
"cycles"
|
|
58434
|
-
]);
|
|
58435
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
58436
|
-
* days). `value` null = unknown (D393). */
|
|
58832
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58833
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58834
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
58437
58835
|
var ConsumableRemainingSchema = object({
|
|
58438
|
-
value: number().min(0).nullable(),
|
|
58439
|
-
|
|
58836
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58837
|
+
kind: ConsumableRemainingKindSchema
|
|
58440
58838
|
});
|
|
58441
58839
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
58442
58840
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -58449,7 +58847,7 @@ var ConsumableItemSchema = object({
|
|
|
58449
58847
|
/** Display name. */
|
|
58450
58848
|
label: string().min(1),
|
|
58451
58849
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
58452
|
-
level: number().min(0).max(100).nullable(),
|
|
58850
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58453
58851
|
/** The provider's discrete verdict when known (binary mode). */
|
|
58454
58852
|
status: ConsumableStatusSchema.nullable(),
|
|
58455
58853
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58531,8 +58929,8 @@ var consumablesCustomize = {
|
|
|
58531
58929
|
transforms: [{ kind: "identity" }]
|
|
58532
58930
|
}],
|
|
58533
58931
|
literals: [{
|
|
58534
|
-
path: "remaining.
|
|
58535
|
-
values: [...
|
|
58932
|
+
path: "remaining.kind",
|
|
58933
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58536
58934
|
}]
|
|
58537
58935
|
},
|
|
58538
58936
|
{
|
|
@@ -58661,7 +59059,6 @@ reset: method(object({
|
|
|
58661
59059
|
},
|
|
58662
59060
|
"remaining.value": {
|
|
58663
59061
|
kind: "gauge",
|
|
58664
|
-
unitFrom: "remaining.unit",
|
|
58665
59062
|
deadband: 1,
|
|
58666
59063
|
displayName: "Remaining"
|
|
58667
59064
|
}
|
|
@@ -58731,10 +59128,9 @@ var contactCapability = {
|
|
|
58731
59128
|
* (empty array for the other kinds). It lives in the slice because
|
|
58732
59129
|
* HA `select.*` entities may update their options at runtime.
|
|
58733
59130
|
*
|
|
58734
|
-
*
|
|
58735
|
-
*
|
|
58736
|
-
*
|
|
58737
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
59131
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
59132
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
59133
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58738
59134
|
*/
|
|
58739
59135
|
var ControlStatusSchema = object({
|
|
58740
59136
|
kind: _enum([
|
|
@@ -58746,39 +59142,17 @@ var ControlStatusSchema = object({
|
|
|
58746
59142
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58747
59143
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58748
59144
|
* or time-only — HA accepts all three forms). */
|
|
58749
|
-
value: union([number(), string()]),
|
|
59145
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58750
59146
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58751
59147
|
options: array(string()),
|
|
58752
59148
|
/** Ms epoch when the slice was last updated. */
|
|
58753
59149
|
lastChangedAt: number(),
|
|
58754
|
-
/**
|
|
58755
|
-
|
|
58756
|
-
|
|
58757
|
-
|
|
58758
|
-
/**
|
|
58759
|
-
|
|
58760
|
-
min: number().optional(),
|
|
58761
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58762
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58763
|
-
max: number().optional(),
|
|
58764
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58765
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58766
|
-
step: number().optional(),
|
|
58767
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58768
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58769
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58770
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58771
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58772
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58773
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58774
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58775
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58776
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58777
|
-
format: _enum([
|
|
58778
|
-
"date",
|
|
58779
|
-
"time",
|
|
58780
|
-
"datetime"
|
|
58781
|
-
]).optional()
|
|
59150
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
59151
|
+
min: number().optional().meta(readingMeta("device")),
|
|
59152
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
59153
|
+
max: number().optional().meta(readingMeta("device")),
|
|
59154
|
+
/** Step increment, in the device quantity's base unit. */
|
|
59155
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58782
59156
|
});
|
|
58783
59157
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58784
59158
|
object({
|
|
@@ -58844,9 +59218,9 @@ var CoverStatusSchema = object({
|
|
|
58844
59218
|
]),
|
|
58845
59219
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58846
59220
|
* no intermediate position surface. */
|
|
58847
|
-
position: number().min(0).max(100).nullable(),
|
|
59221
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58848
59222
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58849
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
59223
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58850
59224
|
/** Ms epoch when the slice was last updated. */
|
|
58851
59225
|
lastChangedAt: number()
|
|
58852
59226
|
});
|
|
@@ -58949,9 +59323,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58949
59323
|
var DayNightStatusSchema = object({
|
|
58950
59324
|
mode: DayNightModeSchema,
|
|
58951
59325
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58952
|
-
sensitivity: number().optional(),
|
|
59326
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58953
59327
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58954
|
-
switchDelaySec: number().optional(),
|
|
59328
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58955
59329
|
lastFetchedAt: number()
|
|
58956
59330
|
});
|
|
58957
59331
|
/**
|
|
@@ -59169,11 +59543,11 @@ var DishwasherStatusSchema = object({
|
|
|
59169
59543
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59170
59544
|
availablePrograms: array(string()),
|
|
59171
59545
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59172
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59546
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59173
59547
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59174
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59548
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59175
59549
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59176
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59550
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59177
59551
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59178
59552
|
doorOpen: boolean().nullable(),
|
|
59179
59553
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59197,7 +59571,7 @@ var DishwasherStatusSchema = object({
|
|
|
59197
59571
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
59198
59572
|
machineCareDue: boolean().nullable(),
|
|
59199
59573
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
59200
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59574
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
59201
59575
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
59202
59576
|
halfLoad: boolean().nullable(),
|
|
59203
59577
|
hygienePlus: boolean().nullable(),
|
|
@@ -59212,7 +59586,7 @@ var DishwasherStatusSchema = object({
|
|
|
59212
59586
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
59213
59587
|
activeEvents: array(string()),
|
|
59214
59588
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
59215
|
-
errorCode: number().nullable(),
|
|
59589
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
59216
59590
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
59217
59591
|
errorLabel: string().nullable(),
|
|
59218
59592
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -59424,6 +59798,7 @@ var doorbellCustomize = {
|
|
|
59424
59798
|
applyAuthority: { kind: "composition-claim" },
|
|
59425
59799
|
eventName: "onPressed",
|
|
59426
59800
|
edges: ["rising"],
|
|
59801
|
+
defaultEdge: "rising",
|
|
59427
59802
|
timestampPath: "lastPressedAt",
|
|
59428
59803
|
counterPath: "pressCountSinceStart",
|
|
59429
59804
|
highWater: "composer-advance",
|
|
@@ -59442,7 +59817,7 @@ var DoorbellStatusSchema = object({
|
|
|
59442
59817
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
59443
59818
|
lastPressedAt: number().nullable(),
|
|
59444
59819
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
59445
|
-
pressCountSinceStart: number()
|
|
59820
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
59446
59821
|
});
|
|
59447
59822
|
var DoorbellPressEventSchema = object({
|
|
59448
59823
|
deviceId: number(),
|
|
@@ -59507,17 +59882,7 @@ onPressed: {
|
|
|
59507
59882
|
history: "none",
|
|
59508
59883
|
customize: doorbellCustomize
|
|
59509
59884
|
};
|
|
59510
|
-
|
|
59511
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59512
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59513
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59514
|
-
* The option set is stable across observations; it is persisted in the
|
|
59515
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59516
|
-
* stored in `sourceInfo`.
|
|
59517
|
-
*/
|
|
59518
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59519
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59520
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59885
|
+
_enum([
|
|
59521
59886
|
"date",
|
|
59522
59887
|
"time",
|
|
59523
59888
|
"datetime"
|
|
@@ -59525,12 +59890,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59525
59890
|
var EnumSensorStatusSchema = object({
|
|
59526
59891
|
value: string(),
|
|
59527
59892
|
/**
|
|
59528
|
-
* Set
|
|
59529
|
-
* as
|
|
59530
|
-
*
|
|
59531
|
-
* a time-only sensor → `'time'`.
|
|
59893
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59894
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59895
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59532
59896
|
*/
|
|
59533
|
-
|
|
59897
|
+
timestamp: boolean().optional(),
|
|
59534
59898
|
/** Ms epoch when the slice was last updated. */
|
|
59535
59899
|
lastFetchedAt: number()
|
|
59536
59900
|
});
|
|
@@ -59557,11 +59921,11 @@ var enumSensorCapability = {
|
|
|
59557
59921
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59558
59922
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59559
59923
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59560
|
-
* `
|
|
59924
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59561
59925
|
*/
|
|
59562
59926
|
history: { fields: { value: {
|
|
59563
59927
|
kind: "enum",
|
|
59564
|
-
skipWhenSet: "
|
|
59928
|
+
skipWhenSet: "timestamp"
|
|
59565
59929
|
} } },
|
|
59566
59930
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59567
59931
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59581,13 +59945,13 @@ var EventFireSchema = object({
|
|
|
59581
59945
|
deviceId: number(),
|
|
59582
59946
|
eventType: string(),
|
|
59583
59947
|
data: record(string(), unknown()).nullable(),
|
|
59584
|
-
timestamp: number(),
|
|
59585
|
-
seq: number()
|
|
59948
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59949
|
+
seq: number().meta(readingMeta("count"))
|
|
59586
59950
|
});
|
|
59587
59951
|
var EventEmitterStatusSchema = object({
|
|
59588
59952
|
eventTypes: array(string()),
|
|
59589
59953
|
lastEvent: EventFireSchema.nullable(),
|
|
59590
|
-
eventCountSinceStart: number()
|
|
59954
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59591
59955
|
});
|
|
59592
59956
|
var eventEmitterCapability = {
|
|
59593
59957
|
name: "event-emitter",
|
|
@@ -60000,10 +60364,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60000
60364
|
var FanControlStatusSchema = object({
|
|
60001
60365
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60002
60366
|
* speed surface (single-speed fan). */
|
|
60003
|
-
percentage: number().min(0).max(100).nullable(),
|
|
60367
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60004
60368
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60005
60369
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60006
|
-
percentageStep: number().positive().optional(),
|
|
60370
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
60007
60371
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
60008
60372
|
* — empty string when no preset is active or supported. */
|
|
60009
60373
|
preset: string(),
|
|
@@ -60124,7 +60488,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
60124
60488
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
60125
60489
|
model: string().nullable(),
|
|
60126
60490
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
60127
|
-
channelCount: number().nullable(),
|
|
60491
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
60128
60492
|
/**
|
|
60129
60493
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
60130
60494
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -60247,9 +60611,91 @@ var gasCapability = {
|
|
|
60247
60611
|
* whether persisting is worth a SQLite commit. */
|
|
60248
60612
|
volatileStateFields: ["lastChangedAt"]
|
|
60249
60613
|
};
|
|
60614
|
+
var GroupCommandsSchema = object({
|
|
60615
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60616
|
+
results: array(object({
|
|
60617
|
+
deviceId: number().int().nonnegative(),
|
|
60618
|
+
cap: string().min(1),
|
|
60619
|
+
method: string().min(1),
|
|
60620
|
+
ok: boolean(),
|
|
60621
|
+
error: string().optional(),
|
|
60622
|
+
/** Ms epoch of the attempt. */
|
|
60623
|
+
at: number()
|
|
60624
|
+
})) });
|
|
60625
|
+
var groupCommandsCapability = {
|
|
60626
|
+
name: "group-commands",
|
|
60627
|
+
scope: "device",
|
|
60628
|
+
deviceNative: true,
|
|
60629
|
+
mode: "singleton",
|
|
60630
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60631
|
+
methods: {},
|
|
60632
|
+
status: {
|
|
60633
|
+
schema: GroupCommandsSchema,
|
|
60634
|
+
kind: "push"
|
|
60635
|
+
},
|
|
60636
|
+
runtimeState: GroupCommandsSchema,
|
|
60637
|
+
/**
|
|
60638
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60639
|
+
* failure would outlive the command that caused it.
|
|
60640
|
+
*
|
|
60641
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60642
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60643
|
+
*/
|
|
60644
|
+
durability: "session",
|
|
60645
|
+
history: "none"
|
|
60646
|
+
};
|
|
60647
|
+
/**
|
|
60648
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60649
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60650
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60651
|
+
* series that later statistics read is the output cap's own history block.
|
|
60652
|
+
*/
|
|
60653
|
+
var GroupStatusSchema = object({
|
|
60654
|
+
/** Members whose current value entered the aggregate. */
|
|
60655
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60656
|
+
precision: 0,
|
|
60657
|
+
label: "Reporting"
|
|
60658
|
+
})),
|
|
60659
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60660
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60661
|
+
precision: 0,
|
|
60662
|
+
label: "Excluded"
|
|
60663
|
+
})),
|
|
60664
|
+
/** `included` + `excluded`. */
|
|
60665
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60666
|
+
precision: 0,
|
|
60667
|
+
label: "Members"
|
|
60668
|
+
}))
|
|
60669
|
+
});
|
|
60670
|
+
var groupStatusCapability = {
|
|
60671
|
+
name: "group-status",
|
|
60672
|
+
scope: "device",
|
|
60673
|
+
deviceNative: true,
|
|
60674
|
+
mode: "singleton",
|
|
60675
|
+
deviceTypes: [
|
|
60676
|
+
DeviceType.Sensor,
|
|
60677
|
+
DeviceType.Switch,
|
|
60678
|
+
DeviceType.Light
|
|
60679
|
+
],
|
|
60680
|
+
methods: {},
|
|
60681
|
+
status: {
|
|
60682
|
+
schema: GroupStatusSchema,
|
|
60683
|
+
kind: "push"
|
|
60684
|
+
},
|
|
60685
|
+
runtimeState: GroupStatusSchema,
|
|
60686
|
+
/**
|
|
60687
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60688
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60689
|
+
*
|
|
60690
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60691
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60692
|
+
*/
|
|
60693
|
+
durability: "session",
|
|
60694
|
+
history: "none"
|
|
60695
|
+
};
|
|
60250
60696
|
var HeatingValveStatusSchema = object({
|
|
60251
60697
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60252
|
-
position: number().min(0).max(100).nullable(),
|
|
60698
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60253
60699
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
60254
60700
|
lastFetchedAt: number()
|
|
60255
60701
|
});
|
|
@@ -60292,9 +60738,9 @@ var HumidifierStatusSchema = object({
|
|
|
60292
60738
|
/** Whether the humidifier is currently on. */
|
|
60293
60739
|
on: boolean(),
|
|
60294
60740
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60295
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60741
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60296
60742
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60297
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60743
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60298
60744
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60299
60745
|
* device has no mode surface. */
|
|
60300
60746
|
mode: string().nullable(),
|
|
@@ -60304,9 +60750,9 @@ var HumidifierStatusSchema = object({
|
|
|
60304
60750
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60305
60751
|
action: string().nullable(),
|
|
60306
60752
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60307
|
-
minHumidity: number().nullable(),
|
|
60753
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60308
60754
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60309
|
-
maxHumidity: number().nullable(),
|
|
60755
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60310
60756
|
/** Ms epoch when the slice was last updated. */
|
|
60311
60757
|
lastChangedAt: number()
|
|
60312
60758
|
});
|
|
@@ -60376,22 +60822,13 @@ var humidifierCapability = {
|
|
|
60376
60822
|
* `sourceInfo`.
|
|
60377
60823
|
*/
|
|
60378
60824
|
var HumiditySensorStatusSchema = object({
|
|
60379
|
-
/** Current relative humidity, 0..100. */
|
|
60380
|
-
percent: number().min(0).max(100).meta({
|
|
60381
|
-
|
|
60825
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60826
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60827
|
+
precision: 0,
|
|
60382
60828
|
label: "Humidity"
|
|
60383
|
-
}),
|
|
60829
|
+
})),
|
|
60384
60830
|
/** Ms epoch when the slice was last updated. */
|
|
60385
|
-
lastFetchedAt: number()
|
|
60386
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60387
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60388
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60389
|
-
unit: string().optional(),
|
|
60390
|
-
/** Suggested decimal places for numeric display.
|
|
60391
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60392
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60393
|
-
* auto-formatting when absent. */
|
|
60394
|
-
precision: number().int().min(0).max(10).optional()
|
|
60831
|
+
lastFetchedAt: number()
|
|
60395
60832
|
});
|
|
60396
60833
|
var humiditySensorCapability = {
|
|
60397
60834
|
name: "humidity-sensor",
|
|
@@ -60422,12 +60859,7 @@ var humiditySensorCapability = {
|
|
|
60422
60859
|
} } },
|
|
60423
60860
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60424
60861
|
* whether persisting is worth a SQLite commit. */
|
|
60425
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60426
|
-
customize: {
|
|
60427
|
-
version: 1,
|
|
60428
|
-
advanced: "derive",
|
|
60429
|
-
targets: []
|
|
60430
|
-
}
|
|
60862
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60431
60863
|
};
|
|
60432
60864
|
/**
|
|
60433
60865
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -60448,7 +60880,7 @@ var ImageStatusSchema = object({
|
|
|
60448
60880
|
* entity exposes no `entity_picture` (yet). */
|
|
60449
60881
|
url: string().nullable(),
|
|
60450
60882
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
60451
|
-
lastUpdated: number().nullable()
|
|
60883
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
60452
60884
|
});
|
|
60453
60885
|
var imageCapability = {
|
|
60454
60886
|
name: "image",
|
|
@@ -60536,19 +60968,19 @@ var NormalizedRangeSchema = object({
|
|
|
60536
60968
|
*/
|
|
60537
60969
|
var ImageSettingsStatusSchema = object({
|
|
60538
60970
|
/** Normalized 0–100. */
|
|
60539
|
-
brightness: number().optional(),
|
|
60971
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60540
60972
|
/** Normalized 0–100. */
|
|
60541
|
-
contrast: number().optional(),
|
|
60973
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60542
60974
|
/** Normalized 0–100. */
|
|
60543
|
-
saturation: number().optional(),
|
|
60975
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60544
60976
|
/** Normalized 0–100. */
|
|
60545
|
-
sharpness: number().optional(),
|
|
60977
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60546
60978
|
mirror: boolean().optional(),
|
|
60547
60979
|
flip: boolean().optional(),
|
|
60548
60980
|
rotate: ImageRotateSchema.optional(),
|
|
60549
60981
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60550
60982
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60551
|
-
warmth: number().optional(),
|
|
60983
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60552
60984
|
exposureMode: ExposureModeSchema.optional(),
|
|
60553
60985
|
backlightMode: BacklightModeSchema.optional(),
|
|
60554
60986
|
lastFetchedAt: number()
|
|
@@ -60827,10 +61259,10 @@ var IntercomAbilitySchema = object({
|
|
|
60827
61259
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60828
61260
|
codecs: array(string()),
|
|
60829
61261
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60830
|
-
sampleRate: number(),
|
|
61262
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60831
61263
|
duplex: _enum(["half", "full"]),
|
|
60832
61264
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60833
|
-
maxBacklogMs: number()
|
|
61265
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60834
61266
|
});
|
|
60835
61267
|
var IntercomStatusSchema = object({
|
|
60836
61268
|
/** True while a talk session is open. */
|
|
@@ -61057,13 +61489,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61057
61489
|
activity: LawnMowerActivitySchema,
|
|
61058
61490
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
61059
61491
|
* reading. */
|
|
61060
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
61492
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61061
61493
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61062
61494
|
* task is active / progress is unavailable. */
|
|
61063
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61495
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61064
61496
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61065
61497
|
* or null when unknown. */
|
|
61066
|
-
currentCode: number().nullable(),
|
|
61498
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
61067
61499
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
61068
61500
|
currentCodeLabel: string().nullable(),
|
|
61069
61501
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61596,7 +62028,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61596
62028
|
state: MediaPlayerStateSchema,
|
|
61597
62029
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61598
62030
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61599
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
62031
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61600
62032
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61601
62033
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61602
62034
|
isMuted: boolean().nullable(),
|
|
@@ -61609,10 +62041,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61609
62041
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61610
62042
|
/** Current playback position in ms. Null when not seekable or
|
|
61611
62043
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61612
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
62044
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61613
62045
|
/** Total duration of the current media in ms. Null when unknown
|
|
61614
62046
|
* (live stream) or nothing is playing. */
|
|
61615
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
62047
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61616
62048
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61617
62049
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61618
62050
|
shuffle: boolean().nullable(),
|
|
@@ -61921,7 +62353,7 @@ var motionCustomize = {
|
|
|
61921
62353
|
eventName: "onMotionChanged"
|
|
61922
62354
|
},
|
|
61923
62355
|
deviceTypes: [DeviceType.Camera],
|
|
61924
|
-
apply: "
|
|
62356
|
+
apply: "add",
|
|
61925
62357
|
applyAuthority: {
|
|
61926
62358
|
kind: "camera-sensors",
|
|
61927
62359
|
timeoutField: "motionCooldownMs"
|
|
@@ -61993,7 +62425,7 @@ var MotionStatusSchema = object({
|
|
|
61993
62425
|
* it, every provider seeded it at boot, and every session left it
|
|
61994
62426
|
* `detected: true` after its detach.
|
|
61995
62427
|
*/
|
|
61996
|
-
autoClearAfterMs: number().nullable()
|
|
62428
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61997
62429
|
});
|
|
61998
62430
|
/**
|
|
61999
62431
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -62030,12 +62462,18 @@ var motionCapability = {
|
|
|
62030
62462
|
methods: {
|
|
62031
62463
|
/**
|
|
62032
62464
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62033
|
-
* for consumers that don't need the full status object
|
|
62034
|
-
*
|
|
62035
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62036
|
-
* consumer.
|
|
62465
|
+
* for consumers that don't need the full status object. A composed
|
|
62466
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
62037
62467
|
*/
|
|
62038
62468
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62469
|
+
/**
|
|
62470
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62471
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62472
|
+
*/
|
|
62473
|
+
composedMethods: { isDetected: {
|
|
62474
|
+
kind: "slice",
|
|
62475
|
+
field: "detected"
|
|
62476
|
+
} },
|
|
62039
62477
|
events: {
|
|
62040
62478
|
/**
|
|
62041
62479
|
* Fires every time the runner transitions a camera between
|
|
@@ -62175,7 +62613,7 @@ var MotionZoneRegionSchema = object({
|
|
|
62175
62613
|
* the grid region(s). */
|
|
62176
62614
|
var MotionZoneStatusSchema = object({
|
|
62177
62615
|
enabled: boolean(),
|
|
62178
|
-
sensitivity: number(),
|
|
62616
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
62179
62617
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
62180
62618
|
regions: array(MotionZoneRegionSchema),
|
|
62181
62619
|
lastFetchedAt: number()
|
|
@@ -62545,7 +62983,7 @@ var NavigationStatusSchema = object({
|
|
|
62545
62983
|
following: boolean(),
|
|
62546
62984
|
flash: boolean(),
|
|
62547
62985
|
lightMode: NavigationLightModeSchema,
|
|
62548
|
-
lightLevel: number().min(40).max(100),
|
|
62986
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62549
62987
|
/** Ms epoch when the slice was last updated. */
|
|
62550
62988
|
lastChangedAt: number()
|
|
62551
62989
|
});
|
|
@@ -62679,13 +63117,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62679
63117
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62680
63118
|
* SKIP a null rather than coerce it.
|
|
62681
63119
|
*/
|
|
62682
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
63120
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62683
63121
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62684
|
-
rssiDbm: number().optional(),
|
|
63122
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62685
63123
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62686
63124
|
ssid: string().optional(),
|
|
62687
63125
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62688
|
-
lastUpdated: number()
|
|
63126
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62689
63127
|
});
|
|
62690
63128
|
var networkLinkCapability = {
|
|
62691
63129
|
name: "network-link",
|
|
@@ -63070,7 +63508,7 @@ var NotifierStatusSchema = object({
|
|
|
63070
63508
|
lastError: string().nullable(),
|
|
63071
63509
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
63072
63510
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
63073
|
-
queueDepth: number().int().nonnegative(),
|
|
63511
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
63074
63512
|
/** Per-feature capability matrix — authoritative source for the
|
|
63075
63513
|
* compose-form field gating. */
|
|
63076
63514
|
supports: NotifierSupportsSchema
|
|
@@ -63162,11 +63600,9 @@ onSent: { data: object({
|
|
|
63162
63600
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
63163
63601
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
63164
63602
|
*
|
|
63165
|
-
* The
|
|
63166
|
-
*
|
|
63167
|
-
*
|
|
63168
|
-
* The UI reads them directly from the slice — they are the single source
|
|
63169
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63603
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63604
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63605
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
63170
63606
|
*
|
|
63171
63607
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
63172
63608
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -63175,15 +63611,8 @@ onSent: { data: object({
|
|
|
63175
63611
|
* numeric values land here.
|
|
63176
63612
|
*/
|
|
63177
63613
|
var NumericSensorStatusSchema = object({
|
|
63178
|
-
|
|
63179
|
-
|
|
63180
|
-
* Populated live from the upstream source on each state push.
|
|
63181
|
-
* Absent for unitless sensors. */
|
|
63182
|
-
unit: string().optional(),
|
|
63183
|
-
/** Suggested decimal places for numeric display.
|
|
63184
|
-
* Populated live from the upstream source when provided.
|
|
63185
|
-
* Falls back to auto-formatting when absent. */
|
|
63186
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63614
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63615
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
63187
63616
|
/** Ms epoch when the slice was last updated. */
|
|
63188
63617
|
lastFetchedAt: number()
|
|
63189
63618
|
});
|
|
@@ -63207,11 +63636,11 @@ var numericSensorCapability = {
|
|
|
63207
63636
|
*/
|
|
63208
63637
|
durability: "restored",
|
|
63209
63638
|
/**
|
|
63210
|
-
* History (D850): recorded series. The unit is
|
|
63639
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63640
|
+
* resolved when the series is read — the cap has no single unit.
|
|
63211
63641
|
*/
|
|
63212
63642
|
history: { fields: { value: {
|
|
63213
63643
|
kind: "gauge",
|
|
63214
|
-
unitFrom: "unit",
|
|
63215
63644
|
minIntervalMs: 3e4
|
|
63216
63645
|
} } },
|
|
63217
63646
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63549,23 +63978,26 @@ var PetFeederStatusSchema = object({
|
|
|
63549
63978
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63550
63979
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63551
63980
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63552
|
-
foodLevel: number().nullable(),
|
|
63981
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63553
63982
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63554
63983
|
* single-hopper models. */
|
|
63555
|
-
food1: number().nullable(),
|
|
63984
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63556
63985
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63557
63986
|
* single-hopper models. */
|
|
63558
|
-
food2: number().nullable(),
|
|
63987
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63559
63988
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63560
63989
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63561
63990
|
* below the feeder's low threshold. */
|
|
63562
63991
|
lowFood: boolean(),
|
|
63563
63992
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63564
63993
|
* device has no battery reading. */
|
|
63565
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63566
|
-
/**
|
|
63567
|
-
*
|
|
63568
|
-
|
|
63994
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63995
|
+
/**
|
|
63996
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63997
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63998
|
+
* model has no desiccant sensor.
|
|
63999
|
+
*/
|
|
64000
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63569
64001
|
/** True while a feed is in progress. */
|
|
63570
64002
|
feeding: boolean(),
|
|
63571
64003
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63576,7 +64008,7 @@ var PetFeederStatusSchema = object({
|
|
|
63576
64008
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63577
64009
|
error: string().nullable(),
|
|
63578
64010
|
/** Raw device error code (0 / null = no error). */
|
|
63579
|
-
errorCode: number().nullable(),
|
|
64011
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63580
64012
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63581
64013
|
isDualHopper: boolean(),
|
|
63582
64014
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63586,7 +64018,7 @@ var PetFeederStatusSchema = object({
|
|
|
63586
64018
|
/** Play a chime when dispensing. */
|
|
63587
64019
|
feedSound: boolean(),
|
|
63588
64020
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63589
|
-
volume: number(),
|
|
64021
|
+
volume: number().meta(readingMeta("none")),
|
|
63590
64022
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63591
64023
|
lastFetchedAt: number()
|
|
63592
64024
|
});
|
|
@@ -63705,7 +64137,7 @@ var petFeederCapability = {
|
|
|
63705
64137
|
},
|
|
63706
64138
|
desiccantLeftDays: {
|
|
63707
64139
|
kind: "gauge",
|
|
63708
|
-
unit: "
|
|
64140
|
+
unit: "s"
|
|
63709
64141
|
}
|
|
63710
64142
|
} }
|
|
63711
64143
|
};
|
|
@@ -64106,36 +64538,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64106
64538
|
*/
|
|
64107
64539
|
var PowerMeterStatusSchema = object({
|
|
64108
64540
|
/** Instantaneous power draw in watts. */
|
|
64109
|
-
watts: number().optional().meta({
|
|
64110
|
-
unit: "W",
|
|
64111
|
-
label: "Power"
|
|
64112
|
-
}),
|
|
64541
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64113
64542
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64114
|
-
kwhTotal: number().optional().meta({
|
|
64115
|
-
unit: "kWh",
|
|
64116
|
-
label: "Energy"
|
|
64117
|
-
}),
|
|
64543
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64118
64544
|
/** Voltage in volts. */
|
|
64119
|
-
volts: number().optional(),
|
|
64545
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
64120
64546
|
/** Current in amperes. */
|
|
64121
|
-
amps: number().optional(),
|
|
64122
|
-
/** Apparent power in volt-amperes
|
|
64123
|
-
va: number().optional(),
|
|
64547
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
64548
|
+
/** Apparent power in volt-amperes. */
|
|
64549
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64124
64550
|
/** Power factor (0..1) if reported. */
|
|
64125
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
64551
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64126
64552
|
/** Ms epoch when the slice was last updated. */
|
|
64127
|
-
lastFetchedAt: number()
|
|
64128
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
64129
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
64130
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
64131
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
64132
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
64133
|
-
unit: string().optional(),
|
|
64134
|
-
/** Suggested decimal places for numeric display.
|
|
64135
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64136
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64137
|
-
* auto-formatting when absent. */
|
|
64138
|
-
precision: number().int().min(0).max(10).optional()
|
|
64553
|
+
lastFetchedAt: number()
|
|
64139
64554
|
});
|
|
64140
64555
|
var powerMeterCapability = {
|
|
64141
64556
|
name: "power-meter",
|
|
@@ -64199,12 +64614,7 @@ var powerMeterCapability = {
|
|
|
64199
64614
|
} },
|
|
64200
64615
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64201
64616
|
* whether persisting is worth a SQLite commit. */
|
|
64202
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64203
|
-
customize: {
|
|
64204
|
-
version: 1,
|
|
64205
|
-
advanced: "derive",
|
|
64206
|
-
targets: []
|
|
64207
|
-
}
|
|
64617
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64208
64618
|
};
|
|
64209
64619
|
/**
|
|
64210
64620
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64224,11 +64634,11 @@ var powerMeterCapability = {
|
|
|
64224
64634
|
*/
|
|
64225
64635
|
var GpsLocationSchema = object({
|
|
64226
64636
|
/** Latitude in decimal degrees, -90..90. */
|
|
64227
|
-
latitude: number().min(-90).max(90),
|
|
64637
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
64228
64638
|
/** Longitude in decimal degrees, -180..180. */
|
|
64229
|
-
longitude: number().min(-180).max(180),
|
|
64639
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
64230
64640
|
/** Reported accuracy in meters (lower = better). */
|
|
64231
|
-
accuracyMeters: number().nonnegative()
|
|
64641
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
64232
64642
|
});
|
|
64233
64643
|
var PresenceStatusSchema = object({
|
|
64234
64644
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -64240,7 +64650,7 @@ var PresenceStatusSchema = object({
|
|
|
64240
64650
|
gps: GpsLocationSchema.nullable(),
|
|
64241
64651
|
/** Optional battery level of the tracking device (0..100). Null
|
|
64242
64652
|
* when not reported. */
|
|
64243
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64653
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64244
64654
|
/** Ms epoch when the slice was last updated. */
|
|
64245
64655
|
lastChangedAt: number()
|
|
64246
64656
|
});
|
|
@@ -64290,19 +64700,10 @@ var presenceCapability = {
|
|
|
64290
64700
|
* `sourceInfo`.
|
|
64291
64701
|
*/
|
|
64292
64702
|
var PressureSensorStatusSchema = object({
|
|
64293
|
-
/** Current pressure in hPa. */
|
|
64294
|
-
hpa: number(),
|
|
64703
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64704
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64295
64705
|
/** Ms epoch when the slice was last updated. */
|
|
64296
|
-
lastFetchedAt: number()
|
|
64297
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64298
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64299
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64300
|
-
unit: string().optional(),
|
|
64301
|
-
/** Suggested decimal places for numeric display.
|
|
64302
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64303
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64304
|
-
* auto-formatting when absent. */
|
|
64305
|
-
precision: number().int().min(0).max(10).optional()
|
|
64706
|
+
lastFetchedAt: number()
|
|
64306
64707
|
});
|
|
64307
64708
|
var pressureSensorCapability = {
|
|
64308
64709
|
name: "pressure-sensor",
|
|
@@ -64828,8 +65229,8 @@ var ptzCapability = {
|
|
|
64828
65229
|
};
|
|
64829
65230
|
var PtzAutotrackSettingsSchema = object({
|
|
64830
65231
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64831
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64832
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
65232
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
65233
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64833
65234
|
});
|
|
64834
65235
|
/**
|
|
64835
65236
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64983,7 +65384,7 @@ var RunningStateStatusSchema = object({
|
|
|
64983
65384
|
/** null = unknown — never coerced to false (D393). */
|
|
64984
65385
|
running: boolean().nullable(),
|
|
64985
65386
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64986
|
-
since: number().nullable(),
|
|
65387
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64987
65388
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64988
65389
|
phase: string().nullable(),
|
|
64989
65390
|
/** null until a reading has been published (D393). */
|
|
@@ -64998,7 +65399,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64998
65399
|
/** Generic Customize target for the running boolean (D936). */
|
|
64999
65400
|
var runningCustomize = {
|
|
65000
65401
|
version: 1,
|
|
65001
|
-
advanced: "derive",
|
|
65002
65402
|
targets: [{
|
|
65003
65403
|
id: "running",
|
|
65004
65404
|
cardinality: "scalar",
|
|
@@ -65018,7 +65418,7 @@ var runningCustomize = {
|
|
|
65018
65418
|
DeviceType.Thermostat,
|
|
65019
65419
|
DeviceType.PetFeeder
|
|
65020
65420
|
],
|
|
65021
|
-
apply: "add
|
|
65421
|
+
apply: "add",
|
|
65022
65422
|
path: "running",
|
|
65023
65423
|
sources: [
|
|
65024
65424
|
{
|
|
@@ -65034,6 +65434,7 @@ var runningCustomize = {
|
|
|
65034
65434
|
requiredUnit: "W",
|
|
65035
65435
|
transforms: [{
|
|
65036
65436
|
kind: "threshold",
|
|
65437
|
+
comparisons: ["gte", "lte"],
|
|
65037
65438
|
comparison: "gte",
|
|
65038
65439
|
defaultThreshold: 5,
|
|
65039
65440
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -66285,9 +66686,9 @@ var RecordTriggerSchema = _enum([
|
|
|
66285
66686
|
*/
|
|
66286
66687
|
var RecordWindowSchema = object({
|
|
66287
66688
|
trigger: RecordTriggerSchema,
|
|
66288
|
-
day: number().int().min(0).max(6),
|
|
66289
|
-
startMinute: number().int().min(0).max(1439),
|
|
66290
|
-
endMinute: number().int().min(1).max(1440)
|
|
66689
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66690
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66691
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
66291
66692
|
});
|
|
66292
66693
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
66293
66694
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -66363,10 +66764,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
66363
66764
|
/** Master "record to the card at all" switch. */
|
|
66364
66765
|
enabled: boolean().nullable(),
|
|
66365
66766
|
overwriteWhenFull: boolean().nullable(),
|
|
66366
|
-
preRecordSec: number().nullable(),
|
|
66367
|
-
postRecordSec: number().nullable(),
|
|
66767
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66768
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66368
66769
|
/** Length of one recorded file, in minutes. */
|
|
66369
|
-
segmentMinutes: number().nullable(),
|
|
66770
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
66370
66771
|
/** The primary track's weekly windows, flattened. */
|
|
66371
66772
|
windows: array(RecordWindowSchema),
|
|
66372
66773
|
/**
|
|
@@ -66382,7 +66783,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
66382
66783
|
* provider reporting a non-zero count also reports the schedule as not
|
|
66383
66784
|
* writable.
|
|
66384
66785
|
*/
|
|
66385
|
-
unreadableWindows: number(),
|
|
66786
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
66386
66787
|
/**
|
|
66387
66788
|
* The camera is scheduled to record and has NO usable storage.
|
|
66388
66789
|
*
|
|
@@ -67329,7 +67730,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
67329
67730
|
url: string().optional(),
|
|
67330
67731
|
codec: string().optional(),
|
|
67331
67732
|
resolution: CamStreamResolutionSchema.optional(),
|
|
67332
|
-
fps: number().positive().optional(),
|
|
67733
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
67333
67734
|
label: string().optional(),
|
|
67334
67735
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
67335
67736
|
deviceFeatures: array(string()).optional(),
|
|
@@ -67416,18 +67817,18 @@ var StreamProfileSchema = _enum([
|
|
|
67416
67817
|
]);
|
|
67417
67818
|
/** The current encoding config of one stream profile. */
|
|
67418
67819
|
var StreamProfileConfigSchema = object({
|
|
67419
|
-
width: number(),
|
|
67420
|
-
height: number(),
|
|
67820
|
+
width: number().meta(readingMeta("none")),
|
|
67821
|
+
height: number().meta(readingMeta("none")),
|
|
67421
67822
|
codec: _enum(["h264", "h265"]),
|
|
67422
|
-
framerate: number(),
|
|
67423
|
-
bitrate: number(),
|
|
67823
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67824
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
67424
67825
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
67425
67826
|
encoderProfile: _enum([
|
|
67426
67827
|
"high",
|
|
67427
67828
|
"main",
|
|
67428
67829
|
"baseline"
|
|
67429
67830
|
]).optional(),
|
|
67430
|
-
gop: number().optional(),
|
|
67831
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
67431
67832
|
/**
|
|
67432
67833
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
67433
67834
|
*
|
|
@@ -67846,12 +68247,7 @@ var switchCapability = {
|
|
|
67846
68247
|
label: "On",
|
|
67847
68248
|
kind: "boolean"
|
|
67848
68249
|
}
|
|
67849
|
-
}] }
|
|
67850
|
-
customize: {
|
|
67851
|
-
version: 1,
|
|
67852
|
-
advanced: "derive",
|
|
67853
|
-
targets: []
|
|
67854
|
-
}
|
|
68250
|
+
}] }
|
|
67855
68251
|
};
|
|
67856
68252
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
67857
68253
|
function hasControlCharacter(value) {
|
|
@@ -68434,35 +68830,21 @@ var tamperCapability = {
|
|
|
68434
68830
|
* entries with `device_class: temperature` and any future native
|
|
68435
68831
|
* thermometer.
|
|
68436
68832
|
*
|
|
68437
|
-
*
|
|
68438
|
-
*
|
|
68439
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
68440
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
68441
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
68442
|
-
* `sourceInfo`.
|
|
68833
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
68834
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
68443
68835
|
*
|
|
68444
68836
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
68445
68837
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
68446
68838
|
* changed" steady state.
|
|
68447
68839
|
*/
|
|
68448
68840
|
var TemperatureSensorStatusSchema = object({
|
|
68449
|
-
/** Current temperature in Celsius. */
|
|
68450
|
-
celsius: number().meta({
|
|
68451
|
-
|
|
68841
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68842
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
68843
|
+
precision: 1,
|
|
68452
68844
|
label: "Temperature"
|
|
68453
|
-
}),
|
|
68845
|
+
})),
|
|
68454
68846
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
68455
|
-
lastFetchedAt: number()
|
|
68456
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
68457
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
68458
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
68459
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
68460
|
-
unit: string().optional(),
|
|
68461
|
-
/** Suggested decimal places for numeric display.
|
|
68462
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
68463
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
68464
|
-
* auto-formatting when absent. */
|
|
68465
|
-
precision: number().int().min(0).max(10).optional()
|
|
68847
|
+
lastFetchedAt: number()
|
|
68466
68848
|
});
|
|
68467
68849
|
var temperatureSensorCapability = {
|
|
68468
68850
|
name: "temperature-sensor",
|
|
@@ -68493,12 +68875,7 @@ var temperatureSensorCapability = {
|
|
|
68493
68875
|
} } },
|
|
68494
68876
|
/** Clock fields: written, but excluded from the compare that decides
|
|
68495
68877
|
* whether persisting is worth a SQLite commit. */
|
|
68496
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
68497
|
-
customize: {
|
|
68498
|
-
version: 1,
|
|
68499
|
-
advanced: "derive",
|
|
68500
|
-
targets: []
|
|
68501
|
-
}
|
|
68878
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
68502
68879
|
};
|
|
68503
68880
|
/**
|
|
68504
68881
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -68781,16 +69158,16 @@ var VacuumControlStatusSchema = object({
|
|
|
68781
69158
|
]),
|
|
68782
69159
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
68783
69160
|
* reading. */
|
|
68784
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
69161
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68785
69162
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
68786
69163
|
* the vacuum has no speed control. */
|
|
68787
69164
|
fanSpeed: string().nullable(),
|
|
68788
69165
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68789
69166
|
availableFanSpeeds: array(string()),
|
|
68790
69167
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68791
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
69168
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68792
69169
|
/** Current error code (0 / null = no error). */
|
|
68793
|
-
errorCode: number().nullable(),
|
|
69170
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68794
69171
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
68795
69172
|
errorLabel: string().nullable(),
|
|
68796
69173
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -68868,7 +69245,7 @@ var ValveStatusSchema = object({
|
|
|
68868
69245
|
]),
|
|
68869
69246
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
68870
69247
|
* intermediate position surface. */
|
|
68871
|
-
position: number().min(0).max(100).nullable(),
|
|
69248
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68872
69249
|
/** Ms epoch when the slice was last updated. */
|
|
68873
69250
|
lastChangedAt: number()
|
|
68874
69251
|
});
|
|
@@ -68976,9 +69353,9 @@ var vibrationCapability = {
|
|
|
68976
69353
|
*/
|
|
68977
69354
|
var WaterHeaterStatusSchema = object({
|
|
68978
69355
|
/** Current measured temperature. Null when not reported. */
|
|
68979
|
-
currentTemp: number().nullable(),
|
|
69356
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68980
69357
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68981
|
-
targetTemp: number().nullable(),
|
|
69358
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68982
69359
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68983
69360
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68984
69361
|
* device reports an unknown state. */
|
|
@@ -68989,9 +69366,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68989
69366
|
* has no away surface. */
|
|
68990
69367
|
away: boolean().nullable(),
|
|
68991
69368
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68992
|
-
minTemp: number().nullable(),
|
|
69369
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68993
69370
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68994
|
-
maxTemp: number().nullable(),
|
|
69371
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68995
69372
|
/** Ms epoch when the slice was last updated. */
|
|
68996
69373
|
lastChangedAt: number()
|
|
68997
69374
|
});
|
|
@@ -69076,25 +69453,18 @@ var waterHeaterCapability = {
|
|
|
69076
69453
|
* Forecast deferred — current conditions only for v1.
|
|
69077
69454
|
*/
|
|
69078
69455
|
var WeatherStatusSchema = object({
|
|
69079
|
-
/** Verbatim
|
|
69080
|
-
* when no condition has been reported yet. */
|
|
69456
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
69081
69457
|
condition: string().nullable(),
|
|
69082
|
-
/** Current temperature in
|
|
69083
|
-
temperature: number().nullable(),
|
|
69084
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
69085
|
-
temperatureUnit: string().nullable(),
|
|
69458
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
69459
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
69086
69460
|
/** Relative humidity (0..100). Null when not provided. */
|
|
69087
|
-
humidity: number().min(0).max(100).nullable(),
|
|
69088
|
-
/** Barometric pressure in
|
|
69089
|
-
pressure: number().nullable(),
|
|
69090
|
-
/**
|
|
69091
|
-
|
|
69092
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
69093
|
-
windSpeed: number().nullable(),
|
|
69094
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
69095
|
-
windSpeedUnit: string().nullable(),
|
|
69461
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
69462
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
69463
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
69464
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
69465
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
69096
69466
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
69097
|
-
windBearing: number().nullable(),
|
|
69467
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
69098
69468
|
/** Ms epoch when the slice was last updated. */
|
|
69099
69469
|
lastFetchedAt: number()
|
|
69100
69470
|
});
|
|
@@ -69122,12 +69492,12 @@ var weatherCapability = {
|
|
|
69122
69492
|
*/
|
|
69123
69493
|
durability: "session",
|
|
69124
69494
|
/**
|
|
69125
|
-
* History (D850): recorded series.
|
|
69495
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
69126
69496
|
*/
|
|
69127
69497
|
history: { fields: {
|
|
69128
69498
|
temperature: {
|
|
69129
69499
|
kind: "gauge",
|
|
69130
|
-
|
|
69500
|
+
unit: "°C",
|
|
69131
69501
|
deadband: .2
|
|
69132
69502
|
},
|
|
69133
69503
|
humidity: {
|
|
@@ -69137,12 +69507,12 @@ var weatherCapability = {
|
|
|
69137
69507
|
},
|
|
69138
69508
|
pressure: {
|
|
69139
69509
|
kind: "gauge",
|
|
69140
|
-
|
|
69510
|
+
unit: "hPa",
|
|
69141
69511
|
deadband: .5
|
|
69142
69512
|
},
|
|
69143
69513
|
windSpeed: {
|
|
69144
69514
|
kind: "gauge",
|
|
69145
|
-
|
|
69515
|
+
unit: "m/s",
|
|
69146
69516
|
deadband: .5
|
|
69147
69517
|
}
|
|
69148
69518
|
} }
|
|
@@ -70506,6 +70876,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70506
70876
|
featureProbe: featureProbeCapability,
|
|
70507
70877
|
flood: floodCapability,
|
|
70508
70878
|
gas: gasCapability,
|
|
70879
|
+
groupCommands: groupCommandsCapability,
|
|
70880
|
+
groupStatus: groupStatusCapability,
|
|
70509
70881
|
heatingValve: heatingValveCapability,
|
|
70510
70882
|
humidifier: humidifierCapability,
|
|
70511
70883
|
humiditySensor: humiditySensorCapability,
|
|
@@ -71886,6 +72258,13 @@ Object.freeze({
|
|
|
71886
72258
|
access: "view",
|
|
71887
72259
|
role: "admin"
|
|
71888
72260
|
},
|
|
72261
|
+
"addons.getPackageDocs": {
|
|
72262
|
+
capName: "addons",
|
|
72263
|
+
capScope: "system",
|
|
72264
|
+
addonId: null,
|
|
72265
|
+
access: "view",
|
|
72266
|
+
role: "admin"
|
|
72267
|
+
},
|
|
71889
72268
|
"addons.getVersions": {
|
|
71890
72269
|
capName: "addons",
|
|
71891
72270
|
capScope: "system",
|
|
@@ -74994,6 +75373,20 @@ Object.freeze({
|
|
|
74994
75373
|
access: "view",
|
|
74995
75374
|
role: "viewer"
|
|
74996
75375
|
},
|
|
75376
|
+
"groupCommands.getStatus": {
|
|
75377
|
+
capName: "group-commands",
|
|
75378
|
+
capScope: "device",
|
|
75379
|
+
addonId: null,
|
|
75380
|
+
access: "view",
|
|
75381
|
+
role: "viewer"
|
|
75382
|
+
},
|
|
75383
|
+
"groupStatus.getStatus": {
|
|
75384
|
+
capName: "group-status",
|
|
75385
|
+
capScope: "device",
|
|
75386
|
+
addonId: null,
|
|
75387
|
+
access: "view",
|
|
75388
|
+
role: "viewer"
|
|
75389
|
+
},
|
|
74997
75390
|
"heatingValve.getStatus": {
|
|
74998
75391
|
capName: "heating-valve",
|
|
74999
75392
|
capScope: "device",
|
|
@@ -84816,6 +85209,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84816
85209
|
icon: "flame"
|
|
84817
85210
|
}]
|
|
84818
85211
|
},
|
|
85212
|
+
"group-commands": {
|
|
85213
|
+
scope: "device",
|
|
85214
|
+
noun: t("Group command", "Comando di gruppo")
|
|
85215
|
+
},
|
|
85216
|
+
"group-status": {
|
|
85217
|
+
scope: "device",
|
|
85218
|
+
noun: t("Group", "Gruppo"),
|
|
85219
|
+
state: [
|
|
85220
|
+
{
|
|
85221
|
+
kind: "numeric",
|
|
85222
|
+
field: "included",
|
|
85223
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
85224
|
+
label: t("Reporting", "Rispondono"),
|
|
85225
|
+
icon: "users"
|
|
85226
|
+
},
|
|
85227
|
+
{
|
|
85228
|
+
kind: "numeric",
|
|
85229
|
+
field: "excluded",
|
|
85230
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
85231
|
+
label: t("Excluded", "Esclusi"),
|
|
85232
|
+
icon: "users"
|
|
85233
|
+
},
|
|
85234
|
+
{
|
|
85235
|
+
kind: "numeric",
|
|
85236
|
+
field: "total",
|
|
85237
|
+
quantity: t("the member count", "il numero di membri"),
|
|
85238
|
+
label: t("Members", "Membri"),
|
|
85239
|
+
icon: "sigma"
|
|
85240
|
+
}
|
|
85241
|
+
]
|
|
85242
|
+
},
|
|
84819
85243
|
"humidity-sensor": {
|
|
84820
85244
|
scope: "device",
|
|
84821
85245
|
noun: t("Humidity", "Umidità"),
|
|
@@ -84849,7 +85273,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84849
85273
|
field: "value",
|
|
84850
85274
|
quantity: t("the reading", "il valore"),
|
|
84851
85275
|
label: t("Reading", "Valore"),
|
|
84852
|
-
unitField: "unit",
|
|
84853
85276
|
icon: "gauge"
|
|
84854
85277
|
}]
|
|
84855
85278
|
},
|
|
@@ -84985,7 +85408,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84985
85408
|
field: "temperature",
|
|
84986
85409
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
84987
85410
|
label: t("Temperature", "Temperatura"),
|
|
84988
|
-
|
|
85411
|
+
unit: "°C",
|
|
84989
85412
|
icon: "thermometer"
|
|
84990
85413
|
},
|
|
84991
85414
|
{
|
|
@@ -85001,7 +85424,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85001
85424
|
field: "windSpeed",
|
|
85002
85425
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
85003
85426
|
label: t("Wind", "Vento"),
|
|
85004
|
-
|
|
85427
|
+
unit: "m/s",
|
|
85005
85428
|
icon: "wind"
|
|
85006
85429
|
},
|
|
85007
85430
|
{
|
|
@@ -85009,7 +85432,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85009
85432
|
field: "pressure",
|
|
85010
85433
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
85011
85434
|
label: t("Pressure", "Pressione"),
|
|
85012
|
-
|
|
85435
|
+
unit: "hPa",
|
|
85013
85436
|
icon: "gauge"
|
|
85014
85437
|
}
|
|
85015
85438
|
]
|
|
@@ -86488,6 +86911,16 @@ Object.freeze({
|
|
|
86488
86911
|
form: "single",
|
|
86489
86912
|
optional: false
|
|
86490
86913
|
}],
|
|
86914
|
+
"groupCommands.getStatus": [{
|
|
86915
|
+
name: "deviceId",
|
|
86916
|
+
form: "single",
|
|
86917
|
+
optional: false
|
|
86918
|
+
}],
|
|
86919
|
+
"groupStatus.getStatus": [{
|
|
86920
|
+
name: "deviceId",
|
|
86921
|
+
form: "single",
|
|
86922
|
+
optional: false
|
|
86923
|
+
}],
|
|
86491
86924
|
"heatingValve.getStatus": [{
|
|
86492
86925
|
name: "deviceId",
|
|
86493
86926
|
form: "single",
|
|
@@ -88352,6 +88785,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
88352
88785
|
targetId: string().min(1),
|
|
88353
88786
|
enabled: boolean(),
|
|
88354
88787
|
debounceMs: number().nonnegative(),
|
|
88788
|
+
edges: array(_enum([
|
|
88789
|
+
"rising",
|
|
88790
|
+
"button",
|
|
88791
|
+
"native-event"
|
|
88792
|
+
])).min(1).optional(),
|
|
88355
88793
|
sources: array(OverrideSourceSchema).min(1)
|
|
88356
88794
|
});
|
|
88357
88795
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -88467,6 +88905,8 @@ new Map(Object.entries({
|
|
|
88467
88905
|
"detection-blind": "device-events",
|
|
88468
88906
|
"motion-noisy": "device-events",
|
|
88469
88907
|
"motion-calm": "device-events",
|
|
88908
|
+
"package-llm-silent": "device-events",
|
|
88909
|
+
"package-llm-answered": "device-events",
|
|
88470
88910
|
"recording-stalled": "device-events",
|
|
88471
88911
|
"recording-healthy": "device-events",
|
|
88472
88912
|
"recording-degraded": "device-events",
|
|
@@ -88550,6 +88990,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
88550
88990
|
label: "Motion without a subject",
|
|
88551
88991
|
kinds: ["motion-noisy", "motion-calm"]
|
|
88552
88992
|
},
|
|
88993
|
+
{
|
|
88994
|
+
id: "package-llm",
|
|
88995
|
+
family: "device-events",
|
|
88996
|
+
label: "Package confirm",
|
|
88997
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
88998
|
+
},
|
|
88553
88999
|
{
|
|
88554
89000
|
id: "recording",
|
|
88555
89001
|
family: "device-events",
|
|
@@ -88731,6 +89177,8 @@ var DEVICE_EVENTS = [
|
|
|
88731
89177
|
"detection-blind",
|
|
88732
89178
|
"motion-noisy",
|
|
88733
89179
|
"motion-calm",
|
|
89180
|
+
"package-llm-silent",
|
|
89181
|
+
"package-llm-answered",
|
|
88734
89182
|
"recording-stalled",
|
|
88735
89183
|
"recording-healthy",
|
|
88736
89184
|
"recording-degraded",
|
|
@@ -88999,6 +89447,15 @@ new Map([
|
|
|
88999
89447
|
snapshotLabel: "Cameras with constant motion now",
|
|
89000
89448
|
snapshotSection: null
|
|
89001
89449
|
},
|
|
89450
|
+
{
|
|
89451
|
+
id: "package-llm-confirm",
|
|
89452
|
+
family: "device-events",
|
|
89453
|
+
label: "Package confirm (not answering / answering again)",
|
|
89454
|
+
bad: ["package-llm-silent"],
|
|
89455
|
+
recovery: ["package-llm-answered"],
|
|
89456
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
89457
|
+
snapshotSection: null
|
|
89458
|
+
},
|
|
89002
89459
|
{
|
|
89003
89460
|
id: "recording-health",
|
|
89004
89461
|
family: "device-events",
|