@camstack/addon-provider-reolink 1.2.209 → 1.2.211
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
|
@@ -28,7 +28,7 @@ import { URL as URL$1 } from "url";
|
|
|
28
28
|
import { spawn as spawn$1 } from "node:child_process";
|
|
29
29
|
import os, { tmpdir } from "node:os";
|
|
30
30
|
import { createReadStream } from "node:fs";
|
|
31
|
-
//#region ../types/dist/event-category-
|
|
31
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
32
32
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
33
33
|
EventCategory["SystemBoot"] = "system.boot";
|
|
34
34
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -354,6 +354,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
354
354
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
355
355
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
356
356
|
/**
|
|
357
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
358
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
359
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
360
|
+
*/
|
|
361
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
362
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
363
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
364
|
+
/**
|
|
357
365
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
358
366
|
* (a settings change via `setAgentInferenceDevices` /
|
|
359
367
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5463,7 +5471,7 @@ var ZodIssueCode = {
|
|
|
5463
5471
|
var ZodFirstPartyTypeKind;
|
|
5464
5472
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5465
5473
|
//#endregion
|
|
5466
|
-
//#region ../types/dist/sleep-
|
|
5474
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5467
5475
|
/**
|
|
5468
5476
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5469
5477
|
* window to float samples (D455).
|
|
@@ -8021,6 +8029,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
8021
8029
|
}).strict();
|
|
8022
8030
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8023
8031
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8032
|
+
var READING_QUANTITIES = [
|
|
8033
|
+
"temperature",
|
|
8034
|
+
"pressure",
|
|
8035
|
+
"speed",
|
|
8036
|
+
"precipitation",
|
|
8037
|
+
"precipitation-rate",
|
|
8038
|
+
"length",
|
|
8039
|
+
"area",
|
|
8040
|
+
"illuminance",
|
|
8041
|
+
"irradiance",
|
|
8042
|
+
"power",
|
|
8043
|
+
"energy",
|
|
8044
|
+
"voltage",
|
|
8045
|
+
"current",
|
|
8046
|
+
"apparent-power",
|
|
8047
|
+
"humidity",
|
|
8048
|
+
"percentage",
|
|
8049
|
+
"concentration-volume",
|
|
8050
|
+
"concentration-mass",
|
|
8051
|
+
"concentration-ppb",
|
|
8052
|
+
"volume",
|
|
8053
|
+
"duration",
|
|
8054
|
+
"duration-ms",
|
|
8055
|
+
"information",
|
|
8056
|
+
"sound-level",
|
|
8057
|
+
"signal-level",
|
|
8058
|
+
"colour-temperature",
|
|
8059
|
+
"angle",
|
|
8060
|
+
"bitrate",
|
|
8061
|
+
"rate",
|
|
8062
|
+
"mass",
|
|
8063
|
+
"index",
|
|
8064
|
+
"ratio",
|
|
8065
|
+
"count",
|
|
8066
|
+
"none",
|
|
8067
|
+
"device"
|
|
8068
|
+
];
|
|
8069
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8070
|
+
new Set(READING_QUANTITIES);
|
|
8071
|
+
/**
|
|
8072
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8073
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8074
|
+
*/
|
|
8075
|
+
var QUANTITY_BASE = {
|
|
8076
|
+
temperature: "°C",
|
|
8077
|
+
pressure: "hPa",
|
|
8078
|
+
speed: "m/s",
|
|
8079
|
+
precipitation: "mm",
|
|
8080
|
+
"precipitation-rate": "mm/h",
|
|
8081
|
+
length: "m",
|
|
8082
|
+
area: "m²",
|
|
8083
|
+
illuminance: "lx",
|
|
8084
|
+
irradiance: "W/m²",
|
|
8085
|
+
power: "W",
|
|
8086
|
+
energy: "kWh",
|
|
8087
|
+
voltage: "V",
|
|
8088
|
+
current: "A",
|
|
8089
|
+
"apparent-power": "VA",
|
|
8090
|
+
humidity: "%",
|
|
8091
|
+
percentage: "%",
|
|
8092
|
+
"concentration-volume": "ppm",
|
|
8093
|
+
"concentration-mass": "µg/m³",
|
|
8094
|
+
"concentration-ppb": "ppb",
|
|
8095
|
+
volume: "L",
|
|
8096
|
+
duration: "s",
|
|
8097
|
+
"duration-ms": "ms",
|
|
8098
|
+
information: "B",
|
|
8099
|
+
"sound-level": "dBFS",
|
|
8100
|
+
"signal-level": "dBm",
|
|
8101
|
+
"colour-temperature": "mired",
|
|
8102
|
+
angle: "°",
|
|
8103
|
+
bitrate: "kbps",
|
|
8104
|
+
rate: "fps",
|
|
8105
|
+
mass: "kg",
|
|
8106
|
+
index: "none",
|
|
8107
|
+
ratio: "none",
|
|
8108
|
+
count: "none",
|
|
8109
|
+
none: "none",
|
|
8110
|
+
device: "device"
|
|
8111
|
+
};
|
|
8112
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8113
|
+
function baseUnitOf(quantity) {
|
|
8114
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8115
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8116
|
+
return symbol;
|
|
8117
|
+
}
|
|
8118
|
+
function readingMeta(quantity, extras) {
|
|
8119
|
+
return {
|
|
8120
|
+
quantity,
|
|
8121
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8122
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8123
|
+
};
|
|
8124
|
+
}
|
|
8024
8125
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8025
8126
|
var CamProfileSchema = _enum([
|
|
8026
8127
|
"high",
|
|
@@ -8048,8 +8149,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8048
8149
|
"derived"
|
|
8049
8150
|
]);
|
|
8050
8151
|
var CamStreamResolutionSchema = object({
|
|
8051
|
-
width: number().int().positive(),
|
|
8052
|
-
height: number().int().positive()
|
|
8152
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8153
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8053
8154
|
});
|
|
8054
8155
|
var CameraStreamSchema = object({
|
|
8055
8156
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8601,6 +8702,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8601
8702
|
"filesystem-browse",
|
|
8602
8703
|
"flood",
|
|
8603
8704
|
"gas",
|
|
8705
|
+
"group-commands",
|
|
8706
|
+
"group-status",
|
|
8604
8707
|
"heating-valve",
|
|
8605
8708
|
"humidifier",
|
|
8606
8709
|
"humidity-sensor",
|
|
@@ -8730,14 +8833,6 @@ Object.freeze({
|
|
|
8730
8833
|
{
|
|
8731
8834
|
"path": "aqi",
|
|
8732
8835
|
"valueType": "number"
|
|
8733
|
-
},
|
|
8734
|
-
{
|
|
8735
|
-
"path": "unit",
|
|
8736
|
-
"valueType": "string"
|
|
8737
|
-
},
|
|
8738
|
-
{
|
|
8739
|
-
"path": "precision",
|
|
8740
|
-
"valueType": "number"
|
|
8741
8836
|
}
|
|
8742
8837
|
],
|
|
8743
8838
|
"alarm-panel": [
|
|
@@ -8773,20 +8868,10 @@ Object.freeze({
|
|
|
8773
8868
|
"valueType": "boolean"
|
|
8774
8869
|
}
|
|
8775
8870
|
],
|
|
8776
|
-
"ambient-light-sensor": [
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
},
|
|
8781
|
-
{
|
|
8782
|
-
"path": "unit",
|
|
8783
|
-
"valueType": "string"
|
|
8784
|
-
},
|
|
8785
|
-
{
|
|
8786
|
-
"path": "precision",
|
|
8787
|
-
"valueType": "number"
|
|
8788
|
-
}
|
|
8789
|
-
],
|
|
8871
|
+
"ambient-light-sensor": [{
|
|
8872
|
+
"path": "lux",
|
|
8873
|
+
"valueType": "number"
|
|
8874
|
+
}],
|
|
8790
8875
|
"audio-metrics": [
|
|
8791
8876
|
{
|
|
8792
8877
|
"path": "ts",
|
|
@@ -8866,6 +8951,10 @@ Object.freeze({
|
|
|
8866
8951
|
"path": "lastUpdated",
|
|
8867
8952
|
"valueType": "number"
|
|
8868
8953
|
},
|
|
8954
|
+
{
|
|
8955
|
+
"path": "volts",
|
|
8956
|
+
"valueType": "number"
|
|
8957
|
+
},
|
|
8869
8958
|
{
|
|
8870
8959
|
"path": "lastContactAt",
|
|
8871
8960
|
"valueType": "number"
|
|
@@ -9108,10 +9197,6 @@ Object.freeze({
|
|
|
9108
9197
|
"datetime"
|
|
9109
9198
|
]
|
|
9110
9199
|
},
|
|
9111
|
-
{
|
|
9112
|
-
"path": "unit",
|
|
9113
|
-
"valueType": "string"
|
|
9114
|
-
},
|
|
9115
9200
|
{
|
|
9116
9201
|
"path": "min",
|
|
9117
9202
|
"valueType": "number"
|
|
@@ -9123,19 +9208,6 @@ Object.freeze({
|
|
|
9123
9208
|
{
|
|
9124
9209
|
"path": "step",
|
|
9125
9210
|
"valueType": "number"
|
|
9126
|
-
},
|
|
9127
|
-
{
|
|
9128
|
-
"path": "precision",
|
|
9129
|
-
"valueType": "number"
|
|
9130
|
-
},
|
|
9131
|
-
{
|
|
9132
|
-
"path": "format",
|
|
9133
|
-
"valueType": "enum",
|
|
9134
|
-
"enumValues": [
|
|
9135
|
-
"date",
|
|
9136
|
-
"time",
|
|
9137
|
-
"datetime"
|
|
9138
|
-
]
|
|
9139
9211
|
}
|
|
9140
9212
|
],
|
|
9141
9213
|
"cover": [
|
|
@@ -9376,13 +9448,8 @@ Object.freeze({
|
|
|
9376
9448
|
"path": "value",
|
|
9377
9449
|
"valueType": "string"
|
|
9378
9450
|
}, {
|
|
9379
|
-
"path": "
|
|
9380
|
-
"valueType": "
|
|
9381
|
-
"enumValues": [
|
|
9382
|
-
"date",
|
|
9383
|
-
"time",
|
|
9384
|
-
"datetime"
|
|
9385
|
-
]
|
|
9451
|
+
"path": "timestamp",
|
|
9452
|
+
"valueType": "boolean"
|
|
9386
9453
|
}],
|
|
9387
9454
|
"event-emitter": [
|
|
9388
9455
|
{
|
|
@@ -9455,6 +9522,20 @@ Object.freeze({
|
|
|
9455
9522
|
"path": "detected",
|
|
9456
9523
|
"valueType": "boolean"
|
|
9457
9524
|
}],
|
|
9525
|
+
"group-status": [
|
|
9526
|
+
{
|
|
9527
|
+
"path": "included",
|
|
9528
|
+
"valueType": "number"
|
|
9529
|
+
},
|
|
9530
|
+
{
|
|
9531
|
+
"path": "excluded",
|
|
9532
|
+
"valueType": "number"
|
|
9533
|
+
},
|
|
9534
|
+
{
|
|
9535
|
+
"path": "total",
|
|
9536
|
+
"valueType": "number"
|
|
9537
|
+
}
|
|
9538
|
+
],
|
|
9458
9539
|
"heating-valve": [{
|
|
9459
9540
|
"path": "position",
|
|
9460
9541
|
"valueType": "number"
|
|
@@ -9489,20 +9570,10 @@ Object.freeze({
|
|
|
9489
9570
|
"valueType": "number"
|
|
9490
9571
|
}
|
|
9491
9572
|
],
|
|
9492
|
-
"humidity-sensor": [
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
},
|
|
9497
|
-
{
|
|
9498
|
-
"path": "unit",
|
|
9499
|
-
"valueType": "string"
|
|
9500
|
-
},
|
|
9501
|
-
{
|
|
9502
|
-
"path": "precision",
|
|
9503
|
-
"valueType": "number"
|
|
9504
|
-
}
|
|
9505
|
-
],
|
|
9573
|
+
"humidity-sensor": [{
|
|
9574
|
+
"path": "percent",
|
|
9575
|
+
"valueType": "number"
|
|
9576
|
+
}],
|
|
9506
9577
|
"image": [{
|
|
9507
9578
|
"path": "url",
|
|
9508
9579
|
"valueType": "string"
|
|
@@ -9841,20 +9912,10 @@ Object.freeze({
|
|
|
9841
9912
|
"valueType": "boolean"
|
|
9842
9913
|
}
|
|
9843
9914
|
],
|
|
9844
|
-
"numeric-sensor": [
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
},
|
|
9849
|
-
{
|
|
9850
|
-
"path": "unit",
|
|
9851
|
-
"valueType": "string"
|
|
9852
|
-
},
|
|
9853
|
-
{
|
|
9854
|
-
"path": "precision",
|
|
9855
|
-
"valueType": "number"
|
|
9856
|
-
}
|
|
9857
|
-
],
|
|
9915
|
+
"numeric-sensor": [{
|
|
9916
|
+
"path": "value",
|
|
9917
|
+
"valueType": "number"
|
|
9918
|
+
}],
|
|
9858
9919
|
"pet-feeder": [
|
|
9859
9920
|
{
|
|
9860
9921
|
"path": "foodLevel",
|
|
@@ -9946,14 +10007,6 @@ Object.freeze({
|
|
|
9946
10007
|
{
|
|
9947
10008
|
"path": "powerFactor",
|
|
9948
10009
|
"valueType": "number"
|
|
9949
|
-
},
|
|
9950
|
-
{
|
|
9951
|
-
"path": "unit",
|
|
9952
|
-
"valueType": "string"
|
|
9953
|
-
},
|
|
9954
|
-
{
|
|
9955
|
-
"path": "precision",
|
|
9956
|
-
"valueType": "number"
|
|
9957
10010
|
}
|
|
9958
10011
|
],
|
|
9959
10012
|
"presence": [
|
|
@@ -9982,20 +10035,10 @@ Object.freeze({
|
|
|
9982
10035
|
"valueType": "number"
|
|
9983
10036
|
}
|
|
9984
10037
|
],
|
|
9985
|
-
"pressure-sensor": [
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
},
|
|
9990
|
-
{
|
|
9991
|
-
"path": "unit",
|
|
9992
|
-
"valueType": "string"
|
|
9993
|
-
},
|
|
9994
|
-
{
|
|
9995
|
-
"path": "precision",
|
|
9996
|
-
"valueType": "number"
|
|
9997
|
-
}
|
|
9998
|
-
],
|
|
10038
|
+
"pressure-sensor": [{
|
|
10039
|
+
"path": "hpa",
|
|
10040
|
+
"valueType": "number"
|
|
10041
|
+
}],
|
|
9999
10042
|
"privacy-mask": [{
|
|
10000
10043
|
"path": "enabled",
|
|
10001
10044
|
"valueType": "boolean"
|
|
@@ -10306,20 +10349,10 @@ Object.freeze({
|
|
|
10306
10349
|
"path": "tampered",
|
|
10307
10350
|
"valueType": "boolean"
|
|
10308
10351
|
}],
|
|
10309
|
-
"temperature-sensor": [
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
},
|
|
10314
|
-
{
|
|
10315
|
-
"path": "unit",
|
|
10316
|
-
"valueType": "string"
|
|
10317
|
-
},
|
|
10318
|
-
{
|
|
10319
|
-
"path": "precision",
|
|
10320
|
-
"valueType": "number"
|
|
10321
|
-
}
|
|
10322
|
-
],
|
|
10352
|
+
"temperature-sensor": [{
|
|
10353
|
+
"path": "celsius",
|
|
10354
|
+
"valueType": "number"
|
|
10355
|
+
}],
|
|
10323
10356
|
"update": [
|
|
10324
10357
|
{
|
|
10325
10358
|
"path": "currentVersion",
|
|
@@ -10430,10 +10463,6 @@ Object.freeze({
|
|
|
10430
10463
|
"path": "temperature",
|
|
10431
10464
|
"valueType": "number"
|
|
10432
10465
|
},
|
|
10433
|
-
{
|
|
10434
|
-
"path": "temperatureUnit",
|
|
10435
|
-
"valueType": "string"
|
|
10436
|
-
},
|
|
10437
10466
|
{
|
|
10438
10467
|
"path": "humidity",
|
|
10439
10468
|
"valueType": "number"
|
|
@@ -10442,18 +10471,10 @@ Object.freeze({
|
|
|
10442
10471
|
"path": "pressure",
|
|
10443
10472
|
"valueType": "number"
|
|
10444
10473
|
},
|
|
10445
|
-
{
|
|
10446
|
-
"path": "pressureUnit",
|
|
10447
|
-
"valueType": "string"
|
|
10448
|
-
},
|
|
10449
10474
|
{
|
|
10450
10475
|
"path": "windSpeed",
|
|
10451
10476
|
"valueType": "number"
|
|
10452
10477
|
},
|
|
10453
|
-
{
|
|
10454
|
-
"path": "windSpeedUnit",
|
|
10455
|
-
"valueType": "string"
|
|
10456
|
-
},
|
|
10457
10478
|
{
|
|
10458
10479
|
"path": "windBearing",
|
|
10459
10480
|
"valueType": "number"
|
|
@@ -10884,7 +10905,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10884
10905
|
return DeviceRole;
|
|
10885
10906
|
}({});
|
|
10886
10907
|
//#endregion
|
|
10887
|
-
//#region ../types/dist/composition-
|
|
10908
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10888
10909
|
/**
|
|
10889
10910
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10890
10911
|
*
|
|
@@ -11639,15 +11660,74 @@ function validateExpressionSource(src) {
|
|
|
11639
11660
|
}
|
|
11640
11661
|
return null;
|
|
11641
11662
|
}
|
|
11642
|
-
/**
|
|
11643
|
-
|
|
11644
|
-
|
|
11645
|
-
|
|
11663
|
+
/**
|
|
11664
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11665
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11666
|
+
* `composition.ts` (D659).
|
|
11667
|
+
*/
|
|
11646
11668
|
var CompositionSourceRefSchema = object({
|
|
11647
11669
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11648
11670
|
addonId: string().min(1),
|
|
11649
11671
|
stableId: string().min(1)
|
|
11650
11672
|
});
|
|
11673
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11674
|
+
"temperature",
|
|
11675
|
+
"humidity",
|
|
11676
|
+
"pressure",
|
|
11677
|
+
"illuminance",
|
|
11678
|
+
"power",
|
|
11679
|
+
"energy",
|
|
11680
|
+
"battery",
|
|
11681
|
+
"numeric",
|
|
11682
|
+
"motion",
|
|
11683
|
+
"contact",
|
|
11684
|
+
"leak",
|
|
11685
|
+
"smoke",
|
|
11686
|
+
"occupancy",
|
|
11687
|
+
"binary",
|
|
11688
|
+
"switch",
|
|
11689
|
+
"light"
|
|
11690
|
+
];
|
|
11691
|
+
var NUMERIC_AGGREGATES = [
|
|
11692
|
+
"mean",
|
|
11693
|
+
"median",
|
|
11694
|
+
"min",
|
|
11695
|
+
"max",
|
|
11696
|
+
"sum"
|
|
11697
|
+
];
|
|
11698
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11699
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11700
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11701
|
+
var AGGREGATE_REDUCERS = [
|
|
11702
|
+
"mean",
|
|
11703
|
+
"median",
|
|
11704
|
+
"min",
|
|
11705
|
+
"max",
|
|
11706
|
+
"sum",
|
|
11707
|
+
"any",
|
|
11708
|
+
"all"
|
|
11709
|
+
];
|
|
11710
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11711
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11712
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11713
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11714
|
+
var HelperMemberSchema = object({
|
|
11715
|
+
source: CompositionSourceRefSchema,
|
|
11716
|
+
cap: string().min(1),
|
|
11717
|
+
fieldPath: string().min(1)
|
|
11718
|
+
});
|
|
11719
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11720
|
+
kind: literal("group"),
|
|
11721
|
+
templateId: GroupTemplateIdSchema,
|
|
11722
|
+
aggregate: AggregateReducerSchema,
|
|
11723
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11724
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11725
|
+
active: ActiveCriterionSchema.optional()
|
|
11726
|
+
})]);
|
|
11727
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11728
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11729
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11730
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11651
11731
|
/** One field of one capability of one source device. */
|
|
11652
11732
|
var CompositionFieldReadSchema = object({
|
|
11653
11733
|
source: CompositionSourceRefSchema,
|
|
@@ -11691,7 +11771,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11691
11771
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11692
11772
|
CompositionFromSourceSchema,
|
|
11693
11773
|
CompositionExpressionSourceSchema,
|
|
11694
|
-
CompositionCodeSourceSchema
|
|
11774
|
+
CompositionCodeSourceSchema,
|
|
11775
|
+
object({
|
|
11776
|
+
kind: literal("aggregate"),
|
|
11777
|
+
reducer: _enum([
|
|
11778
|
+
"mean",
|
|
11779
|
+
"median",
|
|
11780
|
+
"min",
|
|
11781
|
+
"max",
|
|
11782
|
+
"sum",
|
|
11783
|
+
"any",
|
|
11784
|
+
"all"
|
|
11785
|
+
]),
|
|
11786
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11787
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11788
|
+
publish: _enum([
|
|
11789
|
+
"value",
|
|
11790
|
+
"included",
|
|
11791
|
+
"excluded",
|
|
11792
|
+
"total"
|
|
11793
|
+
]),
|
|
11794
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11795
|
+
empty: _enum([
|
|
11796
|
+
"null",
|
|
11797
|
+
"omit",
|
|
11798
|
+
"offline"
|
|
11799
|
+
])
|
|
11800
|
+
})
|
|
11695
11801
|
]);
|
|
11696
11802
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11697
11803
|
kind: literal("forward"),
|
|
@@ -11737,7 +11843,13 @@ var CompositionSchema = object({
|
|
|
11737
11843
|
kind: literal("existing"),
|
|
11738
11844
|
device: CompositionSourceRefSchema
|
|
11739
11845
|
})]),
|
|
11740
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11846
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11847
|
+
/**
|
|
11848
|
+
* Present when the block is a helper template. Absent on a free
|
|
11849
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11850
|
+
* never the compiled features.
|
|
11851
|
+
*/
|
|
11852
|
+
helper: HelperSpecSchema.optional()
|
|
11741
11853
|
}).superRefine((composition, ctx) => {
|
|
11742
11854
|
const seen = /* @__PURE__ */ new Set();
|
|
11743
11855
|
composition.features.forEach((feature, index) => {
|
|
@@ -18515,7 +18627,11 @@ var CompositionProblemSchema = object({
|
|
|
18515
18627
|
"item-field-reserved",
|
|
18516
18628
|
"target-missing",
|
|
18517
18629
|
"target-unreadable",
|
|
18518
|
-
"not-replaceable"
|
|
18630
|
+
"not-replaceable",
|
|
18631
|
+
"native-capability-replace",
|
|
18632
|
+
"mixed-quantity",
|
|
18633
|
+
"helper-mismatch",
|
|
18634
|
+
"member-constraint"
|
|
18519
18635
|
]),
|
|
18520
18636
|
path: string(),
|
|
18521
18637
|
message: string()
|
|
@@ -18536,7 +18652,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18536
18652
|
"null",
|
|
18537
18653
|
"offline",
|
|
18538
18654
|
"unknown",
|
|
18539
|
-
"release"
|
|
18655
|
+
"release",
|
|
18656
|
+
"omit"
|
|
18540
18657
|
]);
|
|
18541
18658
|
/**
|
|
18542
18659
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18573,9 +18690,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18573
18690
|
reads: array(CompositionFieldReadSchema)
|
|
18574
18691
|
});
|
|
18575
18692
|
/**
|
|
18576
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18577
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18578
|
-
*
|
|
18693
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18694
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18695
|
+
* Replacing a capability the device already serves is refused
|
|
18696
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18697
|
+
* wire for a claim the hub already holds.
|
|
18579
18698
|
*/
|
|
18580
18699
|
var CompositionFeatureModeSchema = _enum([
|
|
18581
18700
|
"new",
|
|
@@ -18748,6 +18867,275 @@ Object.freeze({
|
|
|
18748
18867
|
result: ["number", "null"]
|
|
18749
18868
|
}
|
|
18750
18869
|
});
|
|
18870
|
+
/**
|
|
18871
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18872
|
+
* Data, not a form default written into the block.
|
|
18873
|
+
*/
|
|
18874
|
+
var NOW = {
|
|
18875
|
+
fieldPath: "lastFetchedAt",
|
|
18876
|
+
expr: "now"
|
|
18877
|
+
};
|
|
18878
|
+
var CHANGED = {
|
|
18879
|
+
fieldPath: "lastChangedAt",
|
|
18880
|
+
expr: "now"
|
|
18881
|
+
};
|
|
18882
|
+
function numeric(input) {
|
|
18883
|
+
return {
|
|
18884
|
+
...input,
|
|
18885
|
+
family: "numeric",
|
|
18886
|
+
deviceType: DeviceType.Sensor,
|
|
18887
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18888
|
+
commandCaps: [],
|
|
18889
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18890
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18891
|
+
accept: [{
|
|
18892
|
+
cap: input.outputCap,
|
|
18893
|
+
fieldPath: input.outputField
|
|
18894
|
+
}]
|
|
18895
|
+
};
|
|
18896
|
+
}
|
|
18897
|
+
function binary(input) {
|
|
18898
|
+
return {
|
|
18899
|
+
...input,
|
|
18900
|
+
family: "binary",
|
|
18901
|
+
deviceType: DeviceType.Sensor,
|
|
18902
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18903
|
+
commandCaps: [],
|
|
18904
|
+
quantity: "none",
|
|
18905
|
+
baseUnit: void 0,
|
|
18906
|
+
aggregates: BINARY_AGGREGATES,
|
|
18907
|
+
empty: "offline"
|
|
18908
|
+
};
|
|
18909
|
+
}
|
|
18910
|
+
var GROUP_TEMPLATES = [
|
|
18911
|
+
numeric({
|
|
18912
|
+
id: "temperature",
|
|
18913
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18914
|
+
role: DeviceRole.TemperatureSensor,
|
|
18915
|
+
outputCap: "temperature-sensor",
|
|
18916
|
+
outputField: "celsius",
|
|
18917
|
+
quantity: "temperature",
|
|
18918
|
+
defaultAggregate: "mean",
|
|
18919
|
+
empty: "null",
|
|
18920
|
+
companions: [NOW]
|
|
18921
|
+
}),
|
|
18922
|
+
numeric({
|
|
18923
|
+
id: "humidity",
|
|
18924
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18925
|
+
role: DeviceRole.HumiditySensor,
|
|
18926
|
+
outputCap: "humidity-sensor",
|
|
18927
|
+
outputField: "percent",
|
|
18928
|
+
quantity: "humidity",
|
|
18929
|
+
defaultAggregate: "mean",
|
|
18930
|
+
empty: "null",
|
|
18931
|
+
companions: [NOW]
|
|
18932
|
+
}),
|
|
18933
|
+
numeric({
|
|
18934
|
+
id: "pressure",
|
|
18935
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18936
|
+
role: DeviceRole.PressureSensor,
|
|
18937
|
+
outputCap: "pressure-sensor",
|
|
18938
|
+
outputField: "hpa",
|
|
18939
|
+
quantity: "pressure",
|
|
18940
|
+
defaultAggregate: "mean",
|
|
18941
|
+
empty: "null",
|
|
18942
|
+
companions: [NOW]
|
|
18943
|
+
}),
|
|
18944
|
+
numeric({
|
|
18945
|
+
id: "illuminance",
|
|
18946
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18947
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18948
|
+
outputCap: "ambient-light-sensor",
|
|
18949
|
+
outputField: "lux",
|
|
18950
|
+
quantity: "illuminance",
|
|
18951
|
+
defaultAggregate: "mean",
|
|
18952
|
+
empty: "null",
|
|
18953
|
+
companions: [NOW]
|
|
18954
|
+
}),
|
|
18955
|
+
numeric({
|
|
18956
|
+
id: "power",
|
|
18957
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18958
|
+
role: DeviceRole.PowerSensor,
|
|
18959
|
+
outputCap: "power-meter",
|
|
18960
|
+
outputField: "watts",
|
|
18961
|
+
quantity: "power",
|
|
18962
|
+
defaultAggregate: "sum",
|
|
18963
|
+
empty: "omit",
|
|
18964
|
+
companions: [NOW]
|
|
18965
|
+
}),
|
|
18966
|
+
numeric({
|
|
18967
|
+
id: "energy",
|
|
18968
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18969
|
+
role: DeviceRole.EnergySensor,
|
|
18970
|
+
outputCap: "power-meter",
|
|
18971
|
+
outputField: "kwhTotal",
|
|
18972
|
+
quantity: "energy",
|
|
18973
|
+
defaultAggregate: "sum",
|
|
18974
|
+
empty: "omit",
|
|
18975
|
+
companions: [NOW]
|
|
18976
|
+
}),
|
|
18977
|
+
numeric({
|
|
18978
|
+
id: "battery",
|
|
18979
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18980
|
+
role: DeviceRole.BatterySensor,
|
|
18981
|
+
outputCap: "battery",
|
|
18982
|
+
outputField: "percentage",
|
|
18983
|
+
quantity: "percentage",
|
|
18984
|
+
defaultAggregate: "mean",
|
|
18985
|
+
empty: "null",
|
|
18986
|
+
companions: [
|
|
18987
|
+
{
|
|
18988
|
+
fieldPath: "charging",
|
|
18989
|
+
expr: "\"unknown\""
|
|
18990
|
+
},
|
|
18991
|
+
{
|
|
18992
|
+
fieldPath: "sleeping",
|
|
18993
|
+
expr: "false"
|
|
18994
|
+
},
|
|
18995
|
+
{
|
|
18996
|
+
fieldPath: "lastUpdated",
|
|
18997
|
+
expr: "now"
|
|
18998
|
+
}
|
|
18999
|
+
]
|
|
19000
|
+
}),
|
|
19001
|
+
numeric({
|
|
19002
|
+
id: "numeric",
|
|
19003
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
19004
|
+
role: DeviceRole.NumericSensor,
|
|
19005
|
+
outputCap: "numeric-sensor",
|
|
19006
|
+
outputField: "value",
|
|
19007
|
+
quantity: "device",
|
|
19008
|
+
defaultAggregate: "mean",
|
|
19009
|
+
empty: "null",
|
|
19010
|
+
companions: [NOW]
|
|
19011
|
+
}),
|
|
19012
|
+
binary({
|
|
19013
|
+
id: "motion",
|
|
19014
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
19015
|
+
role: DeviceRole.MotionSensor,
|
|
19016
|
+
outputCap: "motion",
|
|
19017
|
+
outputField: "detected",
|
|
19018
|
+
defaultAggregate: "any",
|
|
19019
|
+
accept: [{
|
|
19020
|
+
cap: "motion",
|
|
19021
|
+
fieldPath: "detected"
|
|
19022
|
+
}],
|
|
19023
|
+
companions: [{
|
|
19024
|
+
fieldPath: "lastDetectedAt",
|
|
19025
|
+
expr: "null"
|
|
19026
|
+
}, {
|
|
19027
|
+
fieldPath: "autoClearAfterMs",
|
|
19028
|
+
expr: "null"
|
|
19029
|
+
}]
|
|
19030
|
+
}),
|
|
19031
|
+
binary({
|
|
19032
|
+
id: "contact",
|
|
19033
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
19034
|
+
role: DeviceRole.ContactSensor,
|
|
19035
|
+
outputCap: "contact",
|
|
19036
|
+
outputField: "entryOpen",
|
|
19037
|
+
defaultAggregate: "any",
|
|
19038
|
+
accept: [{
|
|
19039
|
+
cap: "contact",
|
|
19040
|
+
fieldPath: "entryOpen"
|
|
19041
|
+
}],
|
|
19042
|
+
companions: [CHANGED]
|
|
19043
|
+
}),
|
|
19044
|
+
binary({
|
|
19045
|
+
id: "leak",
|
|
19046
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
19047
|
+
role: DeviceRole.LeakSensor,
|
|
19048
|
+
outputCap: "flood",
|
|
19049
|
+
outputField: "flooded",
|
|
19050
|
+
defaultAggregate: "any",
|
|
19051
|
+
accept: [{
|
|
19052
|
+
cap: "flood",
|
|
19053
|
+
fieldPath: "flooded"
|
|
19054
|
+
}],
|
|
19055
|
+
companions: [CHANGED]
|
|
19056
|
+
}),
|
|
19057
|
+
binary({
|
|
19058
|
+
id: "smoke",
|
|
19059
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
19060
|
+
role: DeviceRole.SmokeSensor,
|
|
19061
|
+
outputCap: "smoke",
|
|
19062
|
+
outputField: "detected",
|
|
19063
|
+
defaultAggregate: "any",
|
|
19064
|
+
accept: [{
|
|
19065
|
+
cap: "smoke",
|
|
19066
|
+
fieldPath: "detected"
|
|
19067
|
+
}],
|
|
19068
|
+
companions: [CHANGED]
|
|
19069
|
+
}),
|
|
19070
|
+
binary({
|
|
19071
|
+
id: "occupancy",
|
|
19072
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
19073
|
+
role: DeviceRole.BinarySensor,
|
|
19074
|
+
outputCap: "binary",
|
|
19075
|
+
outputField: "on",
|
|
19076
|
+
defaultAggregate: "any",
|
|
19077
|
+
accept: [{
|
|
19078
|
+
cap: "motion",
|
|
19079
|
+
fieldPath: "detected"
|
|
19080
|
+
}, {
|
|
19081
|
+
cap: "binary",
|
|
19082
|
+
fieldPath: "on"
|
|
19083
|
+
}],
|
|
19084
|
+
companions: [CHANGED]
|
|
19085
|
+
}),
|
|
19086
|
+
binary({
|
|
19087
|
+
id: "binary",
|
|
19088
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
19089
|
+
role: DeviceRole.BinarySensor,
|
|
19090
|
+
outputCap: "binary",
|
|
19091
|
+
outputField: "on",
|
|
19092
|
+
defaultAggregate: "any",
|
|
19093
|
+
accept: [{
|
|
19094
|
+
cap: "binary",
|
|
19095
|
+
fieldPath: "on"
|
|
19096
|
+
}],
|
|
19097
|
+
companions: [CHANGED]
|
|
19098
|
+
}),
|
|
19099
|
+
actuator({
|
|
19100
|
+
id: "switch",
|
|
19101
|
+
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.",
|
|
19102
|
+
deviceType: DeviceType.Switch,
|
|
19103
|
+
outputCap: "switch",
|
|
19104
|
+
commandCaps: ["switch"]
|
|
19105
|
+
}),
|
|
19106
|
+
actuator({
|
|
19107
|
+
id: "light",
|
|
19108
|
+
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.",
|
|
19109
|
+
deviceType: DeviceType.Light,
|
|
19110
|
+
outputCap: "switch",
|
|
19111
|
+
commandCaps: [
|
|
19112
|
+
"switch",
|
|
19113
|
+
"brightness",
|
|
19114
|
+
"color"
|
|
19115
|
+
]
|
|
19116
|
+
})
|
|
19117
|
+
];
|
|
19118
|
+
function actuator(input) {
|
|
19119
|
+
return {
|
|
19120
|
+
...input,
|
|
19121
|
+
family: "actuator",
|
|
19122
|
+
role: void 0,
|
|
19123
|
+
memberDeviceType: input.deviceType,
|
|
19124
|
+
outputField: "on",
|
|
19125
|
+
quantity: "none",
|
|
19126
|
+
baseUnit: void 0,
|
|
19127
|
+
aggregates: BINARY_AGGREGATES,
|
|
19128
|
+
defaultAggregate: "any",
|
|
19129
|
+
empty: "offline",
|
|
19130
|
+
accept: [{
|
|
19131
|
+
cap: "switch",
|
|
19132
|
+
fieldPath: "on"
|
|
19133
|
+
}],
|
|
19134
|
+
companions: [CHANGED]
|
|
19135
|
+
};
|
|
19136
|
+
}
|
|
19137
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19138
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18751
19139
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18752
19140
|
/**
|
|
18753
19141
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20574,12 +20962,12 @@ function buildDeviceAdminUrl(parts) {
|
|
|
20574
20962
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20575
20963
|
* in-place so dispatch keeps working.
|
|
20576
20964
|
*
|
|
20577
|
-
* **
|
|
20578
|
-
*
|
|
20579
|
-
*
|
|
20580
|
-
*
|
|
20581
|
-
* (`ha-domain-mapping`)
|
|
20582
|
-
* stored after that point.
|
|
20965
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20966
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20967
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20968
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20969
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20970
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20583
20971
|
*
|
|
20584
20972
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20585
20973
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20593,6 +20981,14 @@ var SourceInfoSchema = object({
|
|
|
20593
20981
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20594
20982
|
* Used to detect rename when `id` changes. */
|
|
20595
20983
|
uniqueId: string().optional(),
|
|
20984
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20985
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20986
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20987
|
+
dateTimeShape: _enum([
|
|
20988
|
+
"date",
|
|
20989
|
+
"time",
|
|
20990
|
+
"datetime"
|
|
20991
|
+
]).optional(),
|
|
20596
20992
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20597
20993
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20598
20994
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41697,7 +42093,8 @@ method(object({
|
|
|
41697
42093
|
"enum"
|
|
41698
42094
|
]),
|
|
41699
42095
|
enumValues: array(string()).optional(),
|
|
41700
|
-
item: boolean().optional()
|
|
42096
|
+
item: boolean().optional(),
|
|
42097
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41701
42098
|
})).readonly(),
|
|
41702
42099
|
itemArray: object({
|
|
41703
42100
|
path: string(),
|
|
@@ -45581,8 +45978,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
45581
45978
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
45582
45979
|
var MaskGridShapeSchema = object({
|
|
45583
45980
|
kind: literal("grid"),
|
|
45584
|
-
gridWidth: number(),
|
|
45585
|
-
gridHeight: number(),
|
|
45981
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45982
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
45586
45983
|
cells: array(boolean())
|
|
45587
45984
|
});
|
|
45588
45985
|
discriminatedUnion("kind", [
|
|
@@ -45694,6 +46091,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45694
46091
|
"detection-blind",
|
|
45695
46092
|
"motion-noisy",
|
|
45696
46093
|
"motion-calm",
|
|
46094
|
+
"package-llm-silent",
|
|
46095
|
+
"package-llm-answered",
|
|
45697
46096
|
"recording-stalled",
|
|
45698
46097
|
"recording-healthy",
|
|
45699
46098
|
"recording-degraded",
|
|
@@ -57307,6 +57706,28 @@ var PackageVersionInfoSchema = object({
|
|
|
57307
57706
|
deprecated: string().optional(),
|
|
57308
57707
|
distTags: array(string()).readonly()
|
|
57309
57708
|
});
|
|
57709
|
+
/**
|
|
57710
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
57711
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
57712
|
+
* tarball failure — never an empty string standing in for either.
|
|
57713
|
+
*/
|
|
57714
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
57715
|
+
object({
|
|
57716
|
+
status: literal("ok"),
|
|
57717
|
+
markdown: string()
|
|
57718
|
+
}),
|
|
57719
|
+
object({ status: literal("missing") }),
|
|
57720
|
+
object({
|
|
57721
|
+
status: literal("error"),
|
|
57722
|
+
message: string()
|
|
57723
|
+
})
|
|
57724
|
+
]);
|
|
57725
|
+
var PackageDocsSchema = object({
|
|
57726
|
+
name: string(),
|
|
57727
|
+
version: string(),
|
|
57728
|
+
readme: PackageDocBodySchema,
|
|
57729
|
+
changelog: PackageDocBodySchema
|
|
57730
|
+
});
|
|
57310
57731
|
var SearchResultSchema = object({
|
|
57311
57732
|
name: string(),
|
|
57312
57733
|
version: string(),
|
|
@@ -57525,7 +57946,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57525
57946
|
}), object({ success: literal(true) }), {
|
|
57526
57947
|
kind: "mutation",
|
|
57527
57948
|
auth: "admin"
|
|
57528
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57949
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57950
|
+
name: string().min(1),
|
|
57951
|
+
version: string().min(1).optional()
|
|
57952
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
57529
57953
|
kind: "mutation",
|
|
57530
57954
|
auth: "admin"
|
|
57531
57955
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -57584,27 +58008,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57584
58008
|
*/
|
|
57585
58009
|
var AirQualitySensorStatusSchema = object({
|
|
57586
58010
|
/** Carbon dioxide concentration in ppm. */
|
|
57587
|
-
co2Ppm: number().min(0).optional(),
|
|
58011
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57588
58012
|
/** Total volatile organic compounds in ppb. */
|
|
57589
|
-
vocPpb: number().min(0).optional(),
|
|
58013
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57590
58014
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57591
|
-
pm25: number().min(0).optional(),
|
|
58015
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57592
58016
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
57593
|
-
pm10: number().min(0).optional(),
|
|
58017
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57594
58018
|
/** Composite AQI value (typically 0..500). */
|
|
57595
|
-
aqi: number().optional(),
|
|
58019
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
57596
58020
|
/** Ms epoch when the slice was last updated. */
|
|
57597
|
-
lastFetchedAt: number()
|
|
57598
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
57599
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
57600
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
57601
|
-
* per slice is unambiguous. */
|
|
57602
|
-
unit: string().optional(),
|
|
57603
|
-
/** Suggested decimal places for numeric display.
|
|
57604
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57605
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57606
|
-
* auto-formatting when absent. */
|
|
57607
|
-
precision: number().int().min(0).max(10).optional()
|
|
58021
|
+
lastFetchedAt: number()
|
|
57608
58022
|
});
|
|
57609
58023
|
var airQualitySensorCapability = {
|
|
57610
58024
|
name: "air-quality-sensor",
|
|
@@ -57641,12 +58055,12 @@ var airQualitySensorCapability = {
|
|
|
57641
58055
|
},
|
|
57642
58056
|
pm25: {
|
|
57643
58057
|
kind: "gauge",
|
|
57644
|
-
unit: "
|
|
58058
|
+
unit: "µg/m³",
|
|
57645
58059
|
deadband: 1
|
|
57646
58060
|
},
|
|
57647
58061
|
pm10: {
|
|
57648
58062
|
kind: "gauge",
|
|
57649
|
-
unit: "
|
|
58063
|
+
unit: "µg/m³",
|
|
57650
58064
|
deadband: 1
|
|
57651
58065
|
},
|
|
57652
58066
|
aqi: {
|
|
@@ -57664,22 +58078,13 @@ var airQualitySensorCapability = {
|
|
|
57664
58078
|
* entries with `device_class: illuminance`.
|
|
57665
58079
|
*/
|
|
57666
58080
|
var AmbientLightSensorStatusSchema = object({
|
|
57667
|
-
/** Current illuminance in lux (lx). */
|
|
57668
|
-
lux: number().min(0).meta({
|
|
57669
|
-
|
|
58081
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
58082
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
58083
|
+
precision: 0,
|
|
57670
58084
|
label: "Illuminance"
|
|
57671
|
-
}),
|
|
58085
|
+
})),
|
|
57672
58086
|
/** Ms epoch when the slice was last updated. */
|
|
57673
|
-
lastFetchedAt: number()
|
|
57674
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
57675
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
57676
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
57677
|
-
unit: string().optional(),
|
|
57678
|
-
/** Suggested decimal places for numeric display.
|
|
57679
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57680
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57681
|
-
* auto-formatting when absent. */
|
|
57682
|
-
precision: number().int().min(0).max(10).optional()
|
|
58087
|
+
lastFetchedAt: number()
|
|
57683
58088
|
});
|
|
57684
58089
|
var ambientLightSensorCapability = {
|
|
57685
58090
|
name: "ambient-light-sensor",
|
|
@@ -57711,12 +58116,7 @@ var ambientLightSensorCapability = {
|
|
|
57711
58116
|
} } },
|
|
57712
58117
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57713
58118
|
* whether persisting is worth a SQLite commit. */
|
|
57714
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
57715
|
-
customize: {
|
|
57716
|
-
version: 1,
|
|
57717
|
-
advanced: "derive",
|
|
57718
|
-
targets: []
|
|
57719
|
-
}
|
|
58119
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
57720
58120
|
};
|
|
57721
58121
|
/**
|
|
57722
58122
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57943,10 +58343,7 @@ var BatteryStatusSchema = object({
|
|
|
57943
58343
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57944
58344
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57945
58345
|
*/
|
|
57946
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57947
|
-
unit: "%",
|
|
57948
|
-
label: "Charge"
|
|
57949
|
-
}),
|
|
58346
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57950
58347
|
/**
|
|
57951
58348
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57952
58349
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57973,7 +58370,14 @@ var BatteryStatusSchema = object({
|
|
|
57973
58370
|
*/
|
|
57974
58371
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57975
58372
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57976
|
-
lastUpdated: number(),
|
|
58373
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
58374
|
+
/**
|
|
58375
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
58376
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
58377
|
+
* that only report charge. A second reading on this cap, not a second
|
|
58378
|
+
* `numeric-sensor` on the same device.
|
|
58379
|
+
*/
|
|
58380
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57977
58381
|
/**
|
|
57978
58382
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57979
58383
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58025,7 +58429,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58025
58429
|
/** Generic Customize target for the percentage reading (D936). */
|
|
58026
58430
|
var batteryCustomize = {
|
|
58027
58431
|
version: 1,
|
|
58028
|
-
advanced: "derive",
|
|
58029
58432
|
targets: [{
|
|
58030
58433
|
id: "percentage",
|
|
58031
58434
|
cardinality: "scalar",
|
|
@@ -58034,7 +58437,7 @@ var batteryCustomize = {
|
|
|
58034
58437
|
stateField: "percentage"
|
|
58035
58438
|
},
|
|
58036
58439
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58037
|
-
apply: "add
|
|
58440
|
+
apply: "add",
|
|
58038
58441
|
path: "percentage",
|
|
58039
58442
|
sources: [{
|
|
58040
58443
|
kind: "field",
|
|
@@ -58155,10 +58558,16 @@ onStatusChanged: { data: object({
|
|
|
58155
58558
|
/**
|
|
58156
58559
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58157
58560
|
*/
|
|
58158
|
-
history: { fields: {
|
|
58159
|
-
|
|
58160
|
-
|
|
58161
|
-
|
|
58561
|
+
history: { fields: {
|
|
58562
|
+
percentage: {
|
|
58563
|
+
kind: "gauge",
|
|
58564
|
+
unit: "%"
|
|
58565
|
+
},
|
|
58566
|
+
volts: {
|
|
58567
|
+
kind: "gauge",
|
|
58568
|
+
unit: "V"
|
|
58569
|
+
}
|
|
58570
|
+
} },
|
|
58162
58571
|
customize: batteryCustomize,
|
|
58163
58572
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58164
58573
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -58205,12 +58614,7 @@ var binaryCapability = {
|
|
|
58205
58614
|
history: { fields: { on: { kind: "boolean" } } },
|
|
58206
58615
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58207
58616
|
* whether persisting is worth a SQLite commit. */
|
|
58208
|
-
volatileStateFields: ["lastChangedAt"]
|
|
58209
|
-
customize: {
|
|
58210
|
-
version: 1,
|
|
58211
|
-
advanced: "derive",
|
|
58212
|
-
targets: []
|
|
58213
|
-
}
|
|
58617
|
+
volatileStateFields: ["lastChangedAt"]
|
|
58214
58618
|
};
|
|
58215
58619
|
/**
|
|
58216
58620
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -58226,7 +58630,7 @@ var binaryCapability = {
|
|
|
58226
58630
|
*/
|
|
58227
58631
|
var BrightnessStatusSchema = object({
|
|
58228
58632
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58229
|
-
percentage: number().min(0).max(100),
|
|
58633
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58230
58634
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58231
58635
|
lastChangedAt: number()
|
|
58232
58636
|
});
|
|
@@ -58680,21 +59084,21 @@ var ClimateControlStatusSchema = object({
|
|
|
58680
59084
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
58681
59085
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
58682
59086
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
58683
|
-
target: number().nullable(),
|
|
59087
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
58684
59088
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
58685
59089
|
* in `heat_cool` mode. */
|
|
58686
|
-
targetHigh: number().nullable(),
|
|
59090
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
58687
59091
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
58688
59092
|
* in `heat_cool` mode. */
|
|
58689
|
-
targetLow: number().nullable(),
|
|
59093
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
58690
59094
|
/** Target relative humidity (0..100). Null when the device has no
|
|
58691
59095
|
* humidity control. */
|
|
58692
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
59096
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58693
59097
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
58694
59098
|
* the device's internal sensor. */
|
|
58695
|
-
currentTemp: number().nullable(),
|
|
59099
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
58696
59100
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
58697
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
59101
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58698
59102
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
58699
59103
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
58700
59104
|
swingVertical: boolean().nullable(),
|
|
@@ -58702,11 +59106,11 @@ var ClimateControlStatusSchema = object({
|
|
|
58702
59106
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
58703
59107
|
swingHorizontal: boolean().nullable(),
|
|
58704
59108
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58705
|
-
minTemp: number().nullable().optional(),
|
|
59109
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58706
59110
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58707
|
-
maxTemp: number().nullable().optional(),
|
|
59111
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58708
59112
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
58709
|
-
tempStep: number().positive().nullable().optional(),
|
|
59113
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
58710
59114
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
58711
59115
|
lastFetchedAt: number()
|
|
58712
59116
|
});
|
|
@@ -58848,17 +59252,17 @@ var climateControlCapability = {
|
|
|
58848
59252
|
* modes to expose in the picker without a slice fetch.
|
|
58849
59253
|
*/
|
|
58850
59254
|
var RgbTripletSchema = object({
|
|
58851
|
-
r: number().int().min(0).max(255),
|
|
58852
|
-
g: number().int().min(0).max(255),
|
|
58853
|
-
b: number().int().min(0).max(255)
|
|
59255
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
59256
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
59257
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
58854
59258
|
});
|
|
58855
59259
|
var HsvTripletSchema = object({
|
|
58856
59260
|
/** Hue in degrees, 0..360. */
|
|
58857
|
-
h: number().min(0).max(360),
|
|
59261
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
58858
59262
|
/** Saturation as 0..100 inclusive. */
|
|
58859
|
-
s: number().min(0).max(100),
|
|
59263
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
58860
59264
|
/** Value/brightness as 0..100 inclusive. */
|
|
58861
|
-
v: number().min(0).max(100)
|
|
59265
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
58862
59266
|
});
|
|
58863
59267
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
58864
59268
|
object({
|
|
@@ -58887,7 +59291,7 @@ var ColorStatusSchema = object({
|
|
|
58887
59291
|
/** Populated when `mode === 'hsv'`. */
|
|
58888
59292
|
hsv: HsvTripletSchema.optional(),
|
|
58889
59293
|
/** Populated when `mode === 'mired'`. */
|
|
58890
|
-
mireds: number().int().optional(),
|
|
59294
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58891
59295
|
/** Ms epoch of the last operator-driven change. */
|
|
58892
59296
|
lastChangedAt: number()
|
|
58893
59297
|
});
|
|
@@ -59082,18 +59486,12 @@ _enum([
|
|
|
59082
59486
|
"empty",
|
|
59083
59487
|
"full"
|
|
59084
59488
|
]);
|
|
59085
|
-
/**
|
|
59086
|
-
|
|
59087
|
-
|
|
59088
|
-
"days",
|
|
59089
|
-
"hours",
|
|
59090
|
-
"cycles"
|
|
59091
|
-
]);
|
|
59092
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
59093
|
-
* days). `value` null = unknown (D393). */
|
|
59489
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
59490
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
59491
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
59094
59492
|
var ConsumableRemainingSchema = object({
|
|
59095
|
-
value: number().min(0).nullable(),
|
|
59096
|
-
|
|
59493
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
59494
|
+
kind: ConsumableRemainingKindSchema
|
|
59097
59495
|
});
|
|
59098
59496
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
59099
59497
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -59106,7 +59504,7 @@ var ConsumableItemSchema = object({
|
|
|
59106
59504
|
/** Display name. */
|
|
59107
59505
|
label: string().min(1),
|
|
59108
59506
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
59109
|
-
level: number().min(0).max(100).nullable(),
|
|
59507
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59110
59508
|
/** The provider's discrete verdict when known (binary mode). */
|
|
59111
59509
|
status: ConsumableStatusSchema.nullable(),
|
|
59112
59510
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -59188,8 +59586,8 @@ var consumablesCustomize = {
|
|
|
59188
59586
|
transforms: [{ kind: "identity" }]
|
|
59189
59587
|
}],
|
|
59190
59588
|
literals: [{
|
|
59191
|
-
path: "remaining.
|
|
59192
|
-
values: [...
|
|
59589
|
+
path: "remaining.kind",
|
|
59590
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
59193
59591
|
}]
|
|
59194
59592
|
},
|
|
59195
59593
|
{
|
|
@@ -59318,7 +59716,6 @@ reset: method(object({
|
|
|
59318
59716
|
},
|
|
59319
59717
|
"remaining.value": {
|
|
59320
59718
|
kind: "gauge",
|
|
59321
|
-
unitFrom: "remaining.unit",
|
|
59322
59719
|
deadband: 1,
|
|
59323
59720
|
displayName: "Remaining"
|
|
59324
59721
|
}
|
|
@@ -59388,10 +59785,9 @@ var contactCapability = {
|
|
|
59388
59785
|
* (empty array for the other kinds). It lives in the slice because
|
|
59389
59786
|
* HA `select.*` entities may update their options at runtime.
|
|
59390
59787
|
*
|
|
59391
|
-
*
|
|
59392
|
-
*
|
|
59393
|
-
*
|
|
59394
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
59788
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
59789
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
59790
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
59395
59791
|
*/
|
|
59396
59792
|
var ControlStatusSchema = object({
|
|
59397
59793
|
kind: _enum([
|
|
@@ -59403,39 +59799,17 @@ var ControlStatusSchema = object({
|
|
|
59403
59799
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
59404
59800
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
59405
59801
|
* or time-only — HA accepts all three forms). */
|
|
59406
|
-
value: union([number(), string()]),
|
|
59802
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
59407
59803
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
59408
59804
|
options: array(string()),
|
|
59409
59805
|
/** Ms epoch when the slice was last updated. */
|
|
59410
59806
|
lastChangedAt: number(),
|
|
59411
|
-
/**
|
|
59412
|
-
|
|
59413
|
-
|
|
59414
|
-
|
|
59415
|
-
/**
|
|
59416
|
-
|
|
59417
|
-
min: number().optional(),
|
|
59418
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
59419
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
59420
|
-
max: number().optional(),
|
|
59421
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
59422
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
59423
|
-
step: number().optional(),
|
|
59424
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
59425
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
59426
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
59427
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
59428
|
-
precision: number().int().min(0).max(10).optional(),
|
|
59429
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
59430
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
59431
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
59432
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
59433
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
59434
|
-
format: _enum([
|
|
59435
|
-
"date",
|
|
59436
|
-
"time",
|
|
59437
|
-
"datetime"
|
|
59438
|
-
]).optional()
|
|
59807
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
59808
|
+
min: number().optional().meta(readingMeta("device")),
|
|
59809
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
59810
|
+
max: number().optional().meta(readingMeta("device")),
|
|
59811
|
+
/** Step increment, in the device quantity's base unit. */
|
|
59812
|
+
step: number().optional().meta(readingMeta("device"))
|
|
59439
59813
|
});
|
|
59440
59814
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
59441
59815
|
object({
|
|
@@ -59501,9 +59875,9 @@ var CoverStatusSchema = object({
|
|
|
59501
59875
|
]),
|
|
59502
59876
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
59503
59877
|
* no intermediate position surface. */
|
|
59504
|
-
position: number().min(0).max(100).nullable(),
|
|
59878
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59505
59879
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
59506
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
59880
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59507
59881
|
/** Ms epoch when the slice was last updated. */
|
|
59508
59882
|
lastChangedAt: number()
|
|
59509
59883
|
});
|
|
@@ -59606,9 +59980,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
59606
59980
|
var DayNightStatusSchema = object({
|
|
59607
59981
|
mode: DayNightModeSchema,
|
|
59608
59982
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
59609
|
-
sensitivity: number().optional(),
|
|
59983
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
59610
59984
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
59611
|
-
switchDelaySec: number().optional(),
|
|
59985
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
59612
59986
|
lastFetchedAt: number()
|
|
59613
59987
|
});
|
|
59614
59988
|
/**
|
|
@@ -59826,11 +60200,11 @@ var DishwasherStatusSchema = object({
|
|
|
59826
60200
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59827
60201
|
availablePrograms: array(string()),
|
|
59828
60202
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59829
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
60203
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59830
60204
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59831
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
60205
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59832
60206
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59833
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60207
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59834
60208
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59835
60209
|
doorOpen: boolean().nullable(),
|
|
59836
60210
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59854,7 +60228,7 @@ var DishwasherStatusSchema = object({
|
|
|
59854
60228
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
59855
60229
|
machineCareDue: boolean().nullable(),
|
|
59856
60230
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
59857
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
60231
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
59858
60232
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
59859
60233
|
halfLoad: boolean().nullable(),
|
|
59860
60234
|
hygienePlus: boolean().nullable(),
|
|
@@ -59869,7 +60243,7 @@ var DishwasherStatusSchema = object({
|
|
|
59869
60243
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
59870
60244
|
activeEvents: array(string()),
|
|
59871
60245
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
59872
|
-
errorCode: number().nullable(),
|
|
60246
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
59873
60247
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
59874
60248
|
errorLabel: string().nullable(),
|
|
59875
60249
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -60081,6 +60455,7 @@ var doorbellCustomize = {
|
|
|
60081
60455
|
applyAuthority: { kind: "composition-claim" },
|
|
60082
60456
|
eventName: "onPressed",
|
|
60083
60457
|
edges: ["rising"],
|
|
60458
|
+
defaultEdge: "rising",
|
|
60084
60459
|
timestampPath: "lastPressedAt",
|
|
60085
60460
|
counterPath: "pressCountSinceStart",
|
|
60086
60461
|
highWater: "composer-advance",
|
|
@@ -60099,7 +60474,7 @@ var DoorbellStatusSchema = object({
|
|
|
60099
60474
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
60100
60475
|
lastPressedAt: number().nullable(),
|
|
60101
60476
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
60102
|
-
pressCountSinceStart: number()
|
|
60477
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
60103
60478
|
});
|
|
60104
60479
|
var DoorbellPressEventSchema = object({
|
|
60105
60480
|
deviceId: number(),
|
|
@@ -60164,17 +60539,7 @@ onPressed: {
|
|
|
60164
60539
|
history: "none",
|
|
60165
60540
|
customize: doorbellCustomize
|
|
60166
60541
|
};
|
|
60167
|
-
|
|
60168
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
60169
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
60170
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
60171
|
-
* The option set is stable across observations; it is persisted in the
|
|
60172
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
60173
|
-
* stored in `sourceInfo`.
|
|
60174
|
-
*/
|
|
60175
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
60176
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
60177
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
60542
|
+
_enum([
|
|
60178
60543
|
"date",
|
|
60179
60544
|
"time",
|
|
60180
60545
|
"datetime"
|
|
@@ -60182,12 +60547,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
60182
60547
|
var EnumSensorStatusSchema = object({
|
|
60183
60548
|
value: string(),
|
|
60184
60549
|
/**
|
|
60185
|
-
* Set
|
|
60186
|
-
* as
|
|
60187
|
-
*
|
|
60188
|
-
* a time-only sensor → `'time'`.
|
|
60550
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
60551
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
60552
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
60189
60553
|
*/
|
|
60190
|
-
|
|
60554
|
+
timestamp: boolean().optional(),
|
|
60191
60555
|
/** Ms epoch when the slice was last updated. */
|
|
60192
60556
|
lastFetchedAt: number()
|
|
60193
60557
|
});
|
|
@@ -60214,11 +60578,11 @@ var enumSensorCapability = {
|
|
|
60214
60578
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
60215
60579
|
* operation state, an HVAC action). The option set is per device, so the
|
|
60216
60580
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
60217
|
-
* `
|
|
60581
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
60218
60582
|
*/
|
|
60219
60583
|
history: { fields: { value: {
|
|
60220
60584
|
kind: "enum",
|
|
60221
|
-
skipWhenSet: "
|
|
60585
|
+
skipWhenSet: "timestamp"
|
|
60222
60586
|
} } },
|
|
60223
60587
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60224
60588
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -60238,13 +60602,13 @@ var EventFireSchema = object({
|
|
|
60238
60602
|
deviceId: number(),
|
|
60239
60603
|
eventType: string(),
|
|
60240
60604
|
data: record(string(), unknown()).nullable(),
|
|
60241
|
-
timestamp: number(),
|
|
60242
|
-
seq: number()
|
|
60605
|
+
timestamp: number().meta(readingMeta("none")),
|
|
60606
|
+
seq: number().meta(readingMeta("count"))
|
|
60243
60607
|
});
|
|
60244
60608
|
var EventEmitterStatusSchema = object({
|
|
60245
60609
|
eventTypes: array(string()),
|
|
60246
60610
|
lastEvent: EventFireSchema.nullable(),
|
|
60247
|
-
eventCountSinceStart: number()
|
|
60611
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
60248
60612
|
});
|
|
60249
60613
|
var eventEmitterCapability = {
|
|
60250
60614
|
name: "event-emitter",
|
|
@@ -60657,10 +61021,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60657
61021
|
var FanControlStatusSchema = object({
|
|
60658
61022
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60659
61023
|
* speed surface (single-speed fan). */
|
|
60660
|
-
percentage: number().min(0).max(100).nullable(),
|
|
61024
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60661
61025
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60662
61026
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60663
|
-
percentageStep: number().positive().optional(),
|
|
61027
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
60664
61028
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
60665
61029
|
* — empty string when no preset is active or supported. */
|
|
60666
61030
|
preset: string(),
|
|
@@ -60781,7 +61145,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
60781
61145
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
60782
61146
|
model: string().nullable(),
|
|
60783
61147
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
60784
|
-
channelCount: number().nullable(),
|
|
61148
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
60785
61149
|
/**
|
|
60786
61150
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
60787
61151
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -60904,9 +61268,91 @@ var gasCapability = {
|
|
|
60904
61268
|
* whether persisting is worth a SQLite commit. */
|
|
60905
61269
|
volatileStateFields: ["lastChangedAt"]
|
|
60906
61270
|
};
|
|
61271
|
+
var GroupCommandsSchema = object({
|
|
61272
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
61273
|
+
results: array(object({
|
|
61274
|
+
deviceId: number().int().nonnegative(),
|
|
61275
|
+
cap: string().min(1),
|
|
61276
|
+
method: string().min(1),
|
|
61277
|
+
ok: boolean(),
|
|
61278
|
+
error: string().optional(),
|
|
61279
|
+
/** Ms epoch of the attempt. */
|
|
61280
|
+
at: number()
|
|
61281
|
+
})) });
|
|
61282
|
+
var groupCommandsCapability = {
|
|
61283
|
+
name: "group-commands",
|
|
61284
|
+
scope: "device",
|
|
61285
|
+
deviceNative: true,
|
|
61286
|
+
mode: "singleton",
|
|
61287
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
61288
|
+
methods: {},
|
|
61289
|
+
status: {
|
|
61290
|
+
schema: GroupCommandsSchema,
|
|
61291
|
+
kind: "push"
|
|
61292
|
+
},
|
|
61293
|
+
runtimeState: GroupCommandsSchema,
|
|
61294
|
+
/**
|
|
61295
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
61296
|
+
* failure would outlive the command that caused it.
|
|
61297
|
+
*
|
|
61298
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61299
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61300
|
+
*/
|
|
61301
|
+
durability: "session",
|
|
61302
|
+
history: "none"
|
|
61303
|
+
};
|
|
61304
|
+
/**
|
|
61305
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
61306
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
61307
|
+
* The reading itself stays on the output capability. History is none — the
|
|
61308
|
+
* series that later statistics read is the output cap's own history block.
|
|
61309
|
+
*/
|
|
61310
|
+
var GroupStatusSchema = object({
|
|
61311
|
+
/** Members whose current value entered the aggregate. */
|
|
61312
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
61313
|
+
precision: 0,
|
|
61314
|
+
label: "Reporting"
|
|
61315
|
+
})),
|
|
61316
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
61317
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
61318
|
+
precision: 0,
|
|
61319
|
+
label: "Excluded"
|
|
61320
|
+
})),
|
|
61321
|
+
/** `included` + `excluded`. */
|
|
61322
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
61323
|
+
precision: 0,
|
|
61324
|
+
label: "Members"
|
|
61325
|
+
}))
|
|
61326
|
+
});
|
|
61327
|
+
var groupStatusCapability = {
|
|
61328
|
+
name: "group-status",
|
|
61329
|
+
scope: "device",
|
|
61330
|
+
deviceNative: true,
|
|
61331
|
+
mode: "singleton",
|
|
61332
|
+
deviceTypes: [
|
|
61333
|
+
DeviceType.Sensor,
|
|
61334
|
+
DeviceType.Switch,
|
|
61335
|
+
DeviceType.Light
|
|
61336
|
+
],
|
|
61337
|
+
methods: {},
|
|
61338
|
+
status: {
|
|
61339
|
+
schema: GroupStatusSchema,
|
|
61340
|
+
kind: "push"
|
|
61341
|
+
},
|
|
61342
|
+
runtimeState: GroupStatusSchema,
|
|
61343
|
+
/**
|
|
61344
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
61345
|
+
* next source event; a restored count would outlive the readings it named.
|
|
61346
|
+
*
|
|
61347
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61348
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61349
|
+
*/
|
|
61350
|
+
durability: "session",
|
|
61351
|
+
history: "none"
|
|
61352
|
+
};
|
|
60907
61353
|
var HeatingValveStatusSchema = object({
|
|
60908
61354
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60909
|
-
position: number().min(0).max(100).nullable(),
|
|
61355
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60910
61356
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
60911
61357
|
lastFetchedAt: number()
|
|
60912
61358
|
});
|
|
@@ -60949,9 +61395,9 @@ var HumidifierStatusSchema = object({
|
|
|
60949
61395
|
/** Whether the humidifier is currently on. */
|
|
60950
61396
|
on: boolean(),
|
|
60951
61397
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60952
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
61398
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60953
61399
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60954
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
61400
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60955
61401
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60956
61402
|
* device has no mode surface. */
|
|
60957
61403
|
mode: string().nullable(),
|
|
@@ -60961,9 +61407,9 @@ var HumidifierStatusSchema = object({
|
|
|
60961
61407
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60962
61408
|
action: string().nullable(),
|
|
60963
61409
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60964
|
-
minHumidity: number().nullable(),
|
|
61410
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60965
61411
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60966
|
-
maxHumidity: number().nullable(),
|
|
61412
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60967
61413
|
/** Ms epoch when the slice was last updated. */
|
|
60968
61414
|
lastChangedAt: number()
|
|
60969
61415
|
});
|
|
@@ -61033,22 +61479,13 @@ var humidifierCapability = {
|
|
|
61033
61479
|
* `sourceInfo`.
|
|
61034
61480
|
*/
|
|
61035
61481
|
var HumiditySensorStatusSchema = object({
|
|
61036
|
-
/** Current relative humidity, 0..100. */
|
|
61037
|
-
percent: number().min(0).max(100).meta({
|
|
61038
|
-
|
|
61482
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61483
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61484
|
+
precision: 0,
|
|
61039
61485
|
label: "Humidity"
|
|
61040
|
-
}),
|
|
61486
|
+
})),
|
|
61041
61487
|
/** Ms epoch when the slice was last updated. */
|
|
61042
|
-
lastFetchedAt: number()
|
|
61043
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61044
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61045
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61046
|
-
unit: string().optional(),
|
|
61047
|
-
/** Suggested decimal places for numeric display.
|
|
61048
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61049
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61050
|
-
* auto-formatting when absent. */
|
|
61051
|
-
precision: number().int().min(0).max(10).optional()
|
|
61488
|
+
lastFetchedAt: number()
|
|
61052
61489
|
});
|
|
61053
61490
|
var humiditySensorCapability = {
|
|
61054
61491
|
name: "humidity-sensor",
|
|
@@ -61079,12 +61516,7 @@ var humiditySensorCapability = {
|
|
|
61079
61516
|
} } },
|
|
61080
61517
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61081
61518
|
* whether persisting is worth a SQLite commit. */
|
|
61082
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
61083
|
-
customize: {
|
|
61084
|
-
version: 1,
|
|
61085
|
-
advanced: "derive",
|
|
61086
|
-
targets: []
|
|
61087
|
-
}
|
|
61519
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
61088
61520
|
};
|
|
61089
61521
|
/**
|
|
61090
61522
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -61105,7 +61537,7 @@ var ImageStatusSchema = object({
|
|
|
61105
61537
|
* entity exposes no `entity_picture` (yet). */
|
|
61106
61538
|
url: string().nullable(),
|
|
61107
61539
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
61108
|
-
lastUpdated: number().nullable()
|
|
61540
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
61109
61541
|
});
|
|
61110
61542
|
var imageCapability = {
|
|
61111
61543
|
name: "image",
|
|
@@ -61193,19 +61625,19 @@ var NormalizedRangeSchema = object({
|
|
|
61193
61625
|
*/
|
|
61194
61626
|
var ImageSettingsStatusSchema = object({
|
|
61195
61627
|
/** Normalized 0–100. */
|
|
61196
|
-
brightness: number().optional(),
|
|
61628
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
61197
61629
|
/** Normalized 0–100. */
|
|
61198
|
-
contrast: number().optional(),
|
|
61630
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
61199
61631
|
/** Normalized 0–100. */
|
|
61200
|
-
saturation: number().optional(),
|
|
61632
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
61201
61633
|
/** Normalized 0–100. */
|
|
61202
|
-
sharpness: number().optional(),
|
|
61634
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
61203
61635
|
mirror: boolean().optional(),
|
|
61204
61636
|
flip: boolean().optional(),
|
|
61205
61637
|
rotate: ImageRotateSchema.optional(),
|
|
61206
61638
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
61207
61639
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
61208
|
-
warmth: number().optional(),
|
|
61640
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
61209
61641
|
exposureMode: ExposureModeSchema.optional(),
|
|
61210
61642
|
backlightMode: BacklightModeSchema.optional(),
|
|
61211
61643
|
lastFetchedAt: number()
|
|
@@ -61484,10 +61916,10 @@ var IntercomAbilitySchema = object({
|
|
|
61484
61916
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
61485
61917
|
codecs: array(string()),
|
|
61486
61918
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
61487
|
-
sampleRate: number(),
|
|
61919
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
61488
61920
|
duplex: _enum(["half", "full"]),
|
|
61489
61921
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
61490
|
-
maxBacklogMs: number()
|
|
61922
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
61491
61923
|
});
|
|
61492
61924
|
var IntercomStatusSchema = object({
|
|
61493
61925
|
/** True while a talk session is open. */
|
|
@@ -61714,13 +62146,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61714
62146
|
activity: LawnMowerActivitySchema,
|
|
61715
62147
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
61716
62148
|
* reading. */
|
|
61717
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
62149
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61718
62150
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61719
62151
|
* task is active / progress is unavailable. */
|
|
61720
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
62152
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61721
62153
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61722
62154
|
* or null when unknown. */
|
|
61723
|
-
currentCode: number().nullable(),
|
|
62155
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
61724
62156
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
61725
62157
|
currentCodeLabel: string().nullable(),
|
|
61726
62158
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -62253,7 +62685,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
62253
62685
|
state: MediaPlayerStateSchema,
|
|
62254
62686
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
62255
62687
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
62256
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
62688
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62257
62689
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
62258
62690
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
62259
62691
|
isMuted: boolean().nullable(),
|
|
@@ -62266,10 +62698,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62266
62698
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62267
62699
|
/** Current playback position in ms. Null when not seekable or
|
|
62268
62700
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62269
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
62701
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62270
62702
|
/** Total duration of the current media in ms. Null when unknown
|
|
62271
62703
|
* (live stream) or nothing is playing. */
|
|
62272
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
62704
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62273
62705
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62274
62706
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62275
62707
|
shuffle: boolean().nullable(),
|
|
@@ -62578,7 +63010,7 @@ var motionCustomize = {
|
|
|
62578
63010
|
eventName: "onMotionChanged"
|
|
62579
63011
|
},
|
|
62580
63012
|
deviceTypes: [DeviceType.Camera],
|
|
62581
|
-
apply: "
|
|
63013
|
+
apply: "add",
|
|
62582
63014
|
applyAuthority: {
|
|
62583
63015
|
kind: "camera-sensors",
|
|
62584
63016
|
timeoutField: "motionCooldownMs"
|
|
@@ -62650,7 +63082,7 @@ var MotionStatusSchema = object({
|
|
|
62650
63082
|
* it, every provider seeded it at boot, and every session left it
|
|
62651
63083
|
* `detected: true` after its detach.
|
|
62652
63084
|
*/
|
|
62653
|
-
autoClearAfterMs: number().nullable()
|
|
63085
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
62654
63086
|
});
|
|
62655
63087
|
/**
|
|
62656
63088
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -62687,12 +63119,18 @@ var motionCapability = {
|
|
|
62687
63119
|
methods: {
|
|
62688
63120
|
/**
|
|
62689
63121
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62690
|
-
* for consumers that don't need the full status object
|
|
62691
|
-
*
|
|
62692
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62693
|
-
* consumer.
|
|
63122
|
+
* for consumers that don't need the full status object. A composed
|
|
63123
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
62694
63124
|
*/
|
|
62695
63125
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
63126
|
+
/**
|
|
63127
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
63128
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
63129
|
+
*/
|
|
63130
|
+
composedMethods: { isDetected: {
|
|
63131
|
+
kind: "slice",
|
|
63132
|
+
field: "detected"
|
|
63133
|
+
} },
|
|
62696
63134
|
events: {
|
|
62697
63135
|
/**
|
|
62698
63136
|
* Fires every time the runner transitions a camera between
|
|
@@ -62832,7 +63270,7 @@ var MotionZoneRegionSchema = object({
|
|
|
62832
63270
|
* the grid region(s). */
|
|
62833
63271
|
var MotionZoneStatusSchema = object({
|
|
62834
63272
|
enabled: boolean(),
|
|
62835
|
-
sensitivity: number(),
|
|
63273
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
62836
63274
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
62837
63275
|
regions: array(MotionZoneRegionSchema),
|
|
62838
63276
|
lastFetchedAt: number()
|
|
@@ -63202,7 +63640,7 @@ var NavigationStatusSchema = object({
|
|
|
63202
63640
|
following: boolean(),
|
|
63203
63641
|
flash: boolean(),
|
|
63204
63642
|
lightMode: NavigationLightModeSchema,
|
|
63205
|
-
lightLevel: number().min(40).max(100),
|
|
63643
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
63206
63644
|
/** Ms epoch when the slice was last updated. */
|
|
63207
63645
|
lastChangedAt: number()
|
|
63208
63646
|
});
|
|
@@ -63336,13 +63774,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
63336
63774
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63337
63775
|
* SKIP a null rather than coerce it.
|
|
63338
63776
|
*/
|
|
63339
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
63777
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63340
63778
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63341
|
-
rssiDbm: number().optional(),
|
|
63779
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
63342
63780
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63343
63781
|
ssid: string().optional(),
|
|
63344
63782
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
63345
|
-
lastUpdated: number()
|
|
63783
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
63346
63784
|
});
|
|
63347
63785
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
63348
63786
|
var NETWORK_LINK_UNKNOWN = {
|
|
@@ -63747,7 +64185,7 @@ var NotifierStatusSchema = object({
|
|
|
63747
64185
|
lastError: string().nullable(),
|
|
63748
64186
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
63749
64187
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
63750
|
-
queueDepth: number().int().nonnegative(),
|
|
64188
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
63751
64189
|
/** Per-feature capability matrix — authoritative source for the
|
|
63752
64190
|
* compose-form field gating. */
|
|
63753
64191
|
supports: NotifierSupportsSchema
|
|
@@ -63839,11 +64277,9 @@ onSent: { data: object({
|
|
|
63839
64277
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
63840
64278
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
63841
64279
|
*
|
|
63842
|
-
* The
|
|
63843
|
-
*
|
|
63844
|
-
*
|
|
63845
|
-
* The UI reads them directly from the slice — they are the single source
|
|
63846
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
64280
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
64281
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
64282
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
63847
64283
|
*
|
|
63848
64284
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
63849
64285
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -63852,15 +64288,8 @@ onSent: { data: object({
|
|
|
63852
64288
|
* numeric values land here.
|
|
63853
64289
|
*/
|
|
63854
64290
|
var NumericSensorStatusSchema = object({
|
|
63855
|
-
|
|
63856
|
-
|
|
63857
|
-
* Populated live from the upstream source on each state push.
|
|
63858
|
-
* Absent for unitless sensors. */
|
|
63859
|
-
unit: string().optional(),
|
|
63860
|
-
/** Suggested decimal places for numeric display.
|
|
63861
|
-
* Populated live from the upstream source when provided.
|
|
63862
|
-
* Falls back to auto-formatting when absent. */
|
|
63863
|
-
precision: number().int().min(0).max(10).optional(),
|
|
64291
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
64292
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
63864
64293
|
/** Ms epoch when the slice was last updated. */
|
|
63865
64294
|
lastFetchedAt: number()
|
|
63866
64295
|
});
|
|
@@ -63884,11 +64313,11 @@ var numericSensorCapability = {
|
|
|
63884
64313
|
*/
|
|
63885
64314
|
durability: "restored",
|
|
63886
64315
|
/**
|
|
63887
|
-
* History (D850): recorded series. The unit is
|
|
64316
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
64317
|
+
* resolved when the series is read — the cap has no single unit.
|
|
63888
64318
|
*/
|
|
63889
64319
|
history: { fields: { value: {
|
|
63890
64320
|
kind: "gauge",
|
|
63891
|
-
unitFrom: "unit",
|
|
63892
64321
|
minIntervalMs: 3e4
|
|
63893
64322
|
} } },
|
|
63894
64323
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -64226,23 +64655,26 @@ var PetFeederStatusSchema = object({
|
|
|
64226
64655
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
64227
64656
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
64228
64657
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
64229
|
-
foodLevel: number().nullable(),
|
|
64658
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64230
64659
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64231
64660
|
* single-hopper models. */
|
|
64232
|
-
food1: number().nullable(),
|
|
64661
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
64233
64662
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
64234
64663
|
* single-hopper models. */
|
|
64235
|
-
food2: number().nullable(),
|
|
64664
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
64236
64665
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64237
64666
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
64238
64667
|
* below the feeder's low threshold. */
|
|
64239
64668
|
lowFood: boolean(),
|
|
64240
64669
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
64241
64670
|
* device has no battery reading. */
|
|
64242
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
64243
|
-
/**
|
|
64244
|
-
*
|
|
64245
|
-
|
|
64671
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64672
|
+
/**
|
|
64673
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
64674
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
64675
|
+
* model has no desiccant sensor.
|
|
64676
|
+
*/
|
|
64677
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
64246
64678
|
/** True while a feed is in progress. */
|
|
64247
64679
|
feeding: boolean(),
|
|
64248
64680
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -64253,7 +64685,7 @@ var PetFeederStatusSchema = object({
|
|
|
64253
64685
|
* with `errorCode` for consumers that want the raw integer. */
|
|
64254
64686
|
error: string().nullable(),
|
|
64255
64687
|
/** Raw device error code (0 / null = no error). */
|
|
64256
|
-
errorCode: number().nullable(),
|
|
64688
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64257
64689
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
64258
64690
|
isDualHopper: boolean(),
|
|
64259
64691
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -64263,7 +64695,7 @@ var PetFeederStatusSchema = object({
|
|
|
64263
64695
|
/** Play a chime when dispensing. */
|
|
64264
64696
|
feedSound: boolean(),
|
|
64265
64697
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
64266
|
-
volume: number(),
|
|
64698
|
+
volume: number().meta(readingMeta("none")),
|
|
64267
64699
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
64268
64700
|
lastFetchedAt: number()
|
|
64269
64701
|
});
|
|
@@ -64382,7 +64814,7 @@ var petFeederCapability = {
|
|
|
64382
64814
|
},
|
|
64383
64815
|
desiccantLeftDays: {
|
|
64384
64816
|
kind: "gauge",
|
|
64385
|
-
unit: "
|
|
64817
|
+
unit: "s"
|
|
64386
64818
|
}
|
|
64387
64819
|
} }
|
|
64388
64820
|
};
|
|
@@ -64783,36 +65215,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64783
65215
|
*/
|
|
64784
65216
|
var PowerMeterStatusSchema = object({
|
|
64785
65217
|
/** Instantaneous power draw in watts. */
|
|
64786
|
-
watts: number().optional().meta({
|
|
64787
|
-
unit: "W",
|
|
64788
|
-
label: "Power"
|
|
64789
|
-
}),
|
|
65218
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64790
65219
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64791
|
-
kwhTotal: number().optional().meta({
|
|
64792
|
-
unit: "kWh",
|
|
64793
|
-
label: "Energy"
|
|
64794
|
-
}),
|
|
65220
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64795
65221
|
/** Voltage in volts. */
|
|
64796
|
-
volts: number().optional(),
|
|
65222
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
64797
65223
|
/** Current in amperes. */
|
|
64798
|
-
amps: number().optional(),
|
|
64799
|
-
/** Apparent power in volt-amperes
|
|
64800
|
-
va: number().optional(),
|
|
65224
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
65225
|
+
/** Apparent power in volt-amperes. */
|
|
65226
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64801
65227
|
/** Power factor (0..1) if reported. */
|
|
64802
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
65228
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64803
65229
|
/** Ms epoch when the slice was last updated. */
|
|
64804
|
-
lastFetchedAt: number()
|
|
64805
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
64806
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
64807
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
64808
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
64809
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
64810
|
-
unit: string().optional(),
|
|
64811
|
-
/** Suggested decimal places for numeric display.
|
|
64812
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64813
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64814
|
-
* auto-formatting when absent. */
|
|
64815
|
-
precision: number().int().min(0).max(10).optional()
|
|
65230
|
+
lastFetchedAt: number()
|
|
64816
65231
|
});
|
|
64817
65232
|
var powerMeterCapability = {
|
|
64818
65233
|
name: "power-meter",
|
|
@@ -64876,12 +65291,7 @@ var powerMeterCapability = {
|
|
|
64876
65291
|
} },
|
|
64877
65292
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64878
65293
|
* whether persisting is worth a SQLite commit. */
|
|
64879
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64880
|
-
customize: {
|
|
64881
|
-
version: 1,
|
|
64882
|
-
advanced: "derive",
|
|
64883
|
-
targets: []
|
|
64884
|
-
}
|
|
65294
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64885
65295
|
};
|
|
64886
65296
|
/**
|
|
64887
65297
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64901,11 +65311,11 @@ var powerMeterCapability = {
|
|
|
64901
65311
|
*/
|
|
64902
65312
|
var GpsLocationSchema = object({
|
|
64903
65313
|
/** Latitude in decimal degrees, -90..90. */
|
|
64904
|
-
latitude: number().min(-90).max(90),
|
|
65314
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
64905
65315
|
/** Longitude in decimal degrees, -180..180. */
|
|
64906
|
-
longitude: number().min(-180).max(180),
|
|
65316
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
64907
65317
|
/** Reported accuracy in meters (lower = better). */
|
|
64908
|
-
accuracyMeters: number().nonnegative()
|
|
65318
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
64909
65319
|
});
|
|
64910
65320
|
var PresenceStatusSchema = object({
|
|
64911
65321
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -64917,7 +65327,7 @@ var PresenceStatusSchema = object({
|
|
|
64917
65327
|
gps: GpsLocationSchema.nullable(),
|
|
64918
65328
|
/** Optional battery level of the tracking device (0..100). Null
|
|
64919
65329
|
* when not reported. */
|
|
64920
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
65330
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64921
65331
|
/** Ms epoch when the slice was last updated. */
|
|
64922
65332
|
lastChangedAt: number()
|
|
64923
65333
|
});
|
|
@@ -64967,19 +65377,10 @@ var presenceCapability = {
|
|
|
64967
65377
|
* `sourceInfo`.
|
|
64968
65378
|
*/
|
|
64969
65379
|
var PressureSensorStatusSchema = object({
|
|
64970
|
-
/** Current pressure in hPa. */
|
|
64971
|
-
hpa: number(),
|
|
65380
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65381
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64972
65382
|
/** Ms epoch when the slice was last updated. */
|
|
64973
|
-
lastFetchedAt: number()
|
|
64974
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64975
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64976
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64977
|
-
unit: string().optional(),
|
|
64978
|
-
/** Suggested decimal places for numeric display.
|
|
64979
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64980
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64981
|
-
* auto-formatting when absent. */
|
|
64982
|
-
precision: number().int().min(0).max(10).optional()
|
|
65383
|
+
lastFetchedAt: number()
|
|
64983
65384
|
});
|
|
64984
65385
|
var pressureSensorCapability = {
|
|
64985
65386
|
name: "pressure-sensor",
|
|
@@ -65505,8 +65906,8 @@ var ptzCapability = {
|
|
|
65505
65906
|
};
|
|
65506
65907
|
var PtzAutotrackSettingsSchema = object({
|
|
65507
65908
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
65508
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
65509
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
65909
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
65910
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
65510
65911
|
});
|
|
65511
65912
|
/**
|
|
65512
65913
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -65660,7 +66061,7 @@ var RunningStateStatusSchema = object({
|
|
|
65660
66061
|
/** null = unknown — never coerced to false (D393). */
|
|
65661
66062
|
running: boolean().nullable(),
|
|
65662
66063
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
65663
|
-
since: number().nullable(),
|
|
66064
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
65664
66065
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
65665
66066
|
phase: string().nullable(),
|
|
65666
66067
|
/** null until a reading has been published (D393). */
|
|
@@ -65675,7 +66076,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
65675
66076
|
/** Generic Customize target for the running boolean (D936). */
|
|
65676
66077
|
var runningCustomize = {
|
|
65677
66078
|
version: 1,
|
|
65678
|
-
advanced: "derive",
|
|
65679
66079
|
targets: [{
|
|
65680
66080
|
id: "running",
|
|
65681
66081
|
cardinality: "scalar",
|
|
@@ -65695,7 +66095,7 @@ var runningCustomize = {
|
|
|
65695
66095
|
DeviceType.Thermostat,
|
|
65696
66096
|
DeviceType.PetFeeder
|
|
65697
66097
|
],
|
|
65698
|
-
apply: "add
|
|
66098
|
+
apply: "add",
|
|
65699
66099
|
path: "running",
|
|
65700
66100
|
sources: [
|
|
65701
66101
|
{
|
|
@@ -65711,6 +66111,7 @@ var runningCustomize = {
|
|
|
65711
66111
|
requiredUnit: "W",
|
|
65712
66112
|
transforms: [{
|
|
65713
66113
|
kind: "threshold",
|
|
66114
|
+
comparisons: ["gte", "lte"],
|
|
65714
66115
|
comparison: "gte",
|
|
65715
66116
|
defaultThreshold: 5,
|
|
65716
66117
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -66987,9 +67388,9 @@ var RecordTriggerSchema = _enum([
|
|
|
66987
67388
|
*/
|
|
66988
67389
|
var RecordWindowSchema = object({
|
|
66989
67390
|
trigger: RecordTriggerSchema,
|
|
66990
|
-
day: number().int().min(0).max(6),
|
|
66991
|
-
startMinute: number().int().min(0).max(1439),
|
|
66992
|
-
endMinute: number().int().min(1).max(1440)
|
|
67391
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
67392
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
67393
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
66993
67394
|
});
|
|
66994
67395
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
66995
67396
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -67065,10 +67466,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
67065
67466
|
/** Master "record to the card at all" switch. */
|
|
67066
67467
|
enabled: boolean().nullable(),
|
|
67067
67468
|
overwriteWhenFull: boolean().nullable(),
|
|
67068
|
-
preRecordSec: number().nullable(),
|
|
67069
|
-
postRecordSec: number().nullable(),
|
|
67469
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
67470
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
67070
67471
|
/** Length of one recorded file, in minutes. */
|
|
67071
|
-
segmentMinutes: number().nullable(),
|
|
67472
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
67072
67473
|
/** The primary track's weekly windows, flattened. */
|
|
67073
67474
|
windows: array(RecordWindowSchema),
|
|
67074
67475
|
/**
|
|
@@ -67084,7 +67485,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
67084
67485
|
* provider reporting a non-zero count also reports the schedule as not
|
|
67085
67486
|
* writable.
|
|
67086
67487
|
*/
|
|
67087
|
-
unreadableWindows: number(),
|
|
67488
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
67088
67489
|
/**
|
|
67089
67490
|
* The camera is scheduled to record and has NO usable storage.
|
|
67090
67491
|
*
|
|
@@ -68094,7 +68495,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
68094
68495
|
url: string().optional(),
|
|
68095
68496
|
codec: string().optional(),
|
|
68096
68497
|
resolution: CamStreamResolutionSchema.optional(),
|
|
68097
|
-
fps: number().positive().optional(),
|
|
68498
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
68098
68499
|
label: string().optional(),
|
|
68099
68500
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
68100
68501
|
deviceFeatures: array(string()).optional(),
|
|
@@ -68181,18 +68582,18 @@ var StreamProfileSchema = _enum([
|
|
|
68181
68582
|
]);
|
|
68182
68583
|
/** The current encoding config of one stream profile. */
|
|
68183
68584
|
var StreamProfileConfigSchema = object({
|
|
68184
|
-
width: number(),
|
|
68185
|
-
height: number(),
|
|
68585
|
+
width: number().meta(readingMeta("none")),
|
|
68586
|
+
height: number().meta(readingMeta("none")),
|
|
68186
68587
|
codec: _enum(["h264", "h265"]),
|
|
68187
|
-
framerate: number(),
|
|
68188
|
-
bitrate: number(),
|
|
68588
|
+
framerate: number().meta(readingMeta("rate")),
|
|
68589
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
68189
68590
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
68190
68591
|
encoderProfile: _enum([
|
|
68191
68592
|
"high",
|
|
68192
68593
|
"main",
|
|
68193
68594
|
"baseline"
|
|
68194
68595
|
]).optional(),
|
|
68195
|
-
gop: number().optional(),
|
|
68596
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
68196
68597
|
/**
|
|
68197
68598
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
68198
68599
|
*
|
|
@@ -68611,12 +69012,7 @@ var switchCapability = {
|
|
|
68611
69012
|
label: "On",
|
|
68612
69013
|
kind: "boolean"
|
|
68613
69014
|
}
|
|
68614
|
-
}] }
|
|
68615
|
-
customize: {
|
|
68616
|
-
version: 1,
|
|
68617
|
-
advanced: "derive",
|
|
68618
|
-
targets: []
|
|
68619
|
-
}
|
|
69015
|
+
}] }
|
|
68620
69016
|
};
|
|
68621
69017
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
68622
69018
|
function hasControlCharacter(value) {
|
|
@@ -69199,35 +69595,21 @@ var tamperCapability = {
|
|
|
69199
69595
|
* entries with `device_class: temperature` and any future native
|
|
69200
69596
|
* thermometer.
|
|
69201
69597
|
*
|
|
69202
|
-
*
|
|
69203
|
-
*
|
|
69204
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
69205
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
69206
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
69207
|
-
* `sourceInfo`.
|
|
69598
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
69599
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
69208
69600
|
*
|
|
69209
69601
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
69210
69602
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
69211
69603
|
* changed" steady state.
|
|
69212
69604
|
*/
|
|
69213
69605
|
var TemperatureSensorStatusSchema = object({
|
|
69214
|
-
/** Current temperature in Celsius. */
|
|
69215
|
-
celsius: number().meta({
|
|
69216
|
-
|
|
69606
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69607
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
69608
|
+
precision: 1,
|
|
69217
69609
|
label: "Temperature"
|
|
69218
|
-
}),
|
|
69610
|
+
})),
|
|
69219
69611
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
69220
|
-
lastFetchedAt: number()
|
|
69221
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
69222
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
69223
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
69224
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
69225
|
-
unit: string().optional(),
|
|
69226
|
-
/** Suggested decimal places for numeric display.
|
|
69227
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
69228
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
69229
|
-
* auto-formatting when absent. */
|
|
69230
|
-
precision: number().int().min(0).max(10).optional()
|
|
69612
|
+
lastFetchedAt: number()
|
|
69231
69613
|
});
|
|
69232
69614
|
var temperatureSensorCapability = {
|
|
69233
69615
|
name: "temperature-sensor",
|
|
@@ -69258,12 +69640,7 @@ var temperatureSensorCapability = {
|
|
|
69258
69640
|
} } },
|
|
69259
69641
|
/** Clock fields: written, but excluded from the compare that decides
|
|
69260
69642
|
* whether persisting is worth a SQLite commit. */
|
|
69261
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
69262
|
-
customize: {
|
|
69263
|
-
version: 1,
|
|
69264
|
-
advanced: "derive",
|
|
69265
|
-
targets: []
|
|
69266
|
-
}
|
|
69643
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
69267
69644
|
};
|
|
69268
69645
|
/**
|
|
69269
69646
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -69546,16 +69923,16 @@ var VacuumControlStatusSchema = object({
|
|
|
69546
69923
|
]),
|
|
69547
69924
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
69548
69925
|
* reading. */
|
|
69549
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
69926
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69550
69927
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
69551
69928
|
* the vacuum has no speed control. */
|
|
69552
69929
|
fanSpeed: string().nullable(),
|
|
69553
69930
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69554
69931
|
availableFanSpeeds: array(string()),
|
|
69555
69932
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69556
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
69933
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69557
69934
|
/** Current error code (0 / null = no error). */
|
|
69558
|
-
errorCode: number().nullable(),
|
|
69935
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69559
69936
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
69560
69937
|
errorLabel: string().nullable(),
|
|
69561
69938
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -69633,7 +70010,7 @@ var ValveStatusSchema = object({
|
|
|
69633
70010
|
]),
|
|
69634
70011
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
69635
70012
|
* intermediate position surface. */
|
|
69636
|
-
position: number().min(0).max(100).nullable(),
|
|
70013
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69637
70014
|
/** Ms epoch when the slice was last updated. */
|
|
69638
70015
|
lastChangedAt: number()
|
|
69639
70016
|
});
|
|
@@ -69741,9 +70118,9 @@ var vibrationCapability = {
|
|
|
69741
70118
|
*/
|
|
69742
70119
|
var WaterHeaterStatusSchema = object({
|
|
69743
70120
|
/** Current measured temperature. Null when not reported. */
|
|
69744
|
-
currentTemp: number().nullable(),
|
|
70121
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69745
70122
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
69746
|
-
targetTemp: number().nullable(),
|
|
70123
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69747
70124
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
69748
70125
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
69749
70126
|
* device reports an unknown state. */
|
|
@@ -69754,9 +70131,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
69754
70131
|
* has no away surface. */
|
|
69755
70132
|
away: boolean().nullable(),
|
|
69756
70133
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
69757
|
-
minTemp: number().nullable(),
|
|
70134
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69758
70135
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
69759
|
-
maxTemp: number().nullable(),
|
|
70136
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69760
70137
|
/** Ms epoch when the slice was last updated. */
|
|
69761
70138
|
lastChangedAt: number()
|
|
69762
70139
|
});
|
|
@@ -69841,25 +70218,18 @@ var waterHeaterCapability = {
|
|
|
69841
70218
|
* Forecast deferred — current conditions only for v1.
|
|
69842
70219
|
*/
|
|
69843
70220
|
var WeatherStatusSchema = object({
|
|
69844
|
-
/** Verbatim
|
|
69845
|
-
* when no condition has been reported yet. */
|
|
70221
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
69846
70222
|
condition: string().nullable(),
|
|
69847
|
-
/** Current temperature in
|
|
69848
|
-
temperature: number().nullable(),
|
|
69849
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
69850
|
-
temperatureUnit: string().nullable(),
|
|
70223
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
70224
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
69851
70225
|
/** Relative humidity (0..100). Null when not provided. */
|
|
69852
|
-
humidity: number().min(0).max(100).nullable(),
|
|
69853
|
-
/** Barometric pressure in
|
|
69854
|
-
pressure: number().nullable(),
|
|
69855
|
-
/**
|
|
69856
|
-
|
|
69857
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
69858
|
-
windSpeed: number().nullable(),
|
|
69859
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
69860
|
-
windSpeedUnit: string().nullable(),
|
|
70226
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
70227
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
70228
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
70229
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
70230
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
69861
70231
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
69862
|
-
windBearing: number().nullable(),
|
|
70232
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
69863
70233
|
/** Ms epoch when the slice was last updated. */
|
|
69864
70234
|
lastFetchedAt: number()
|
|
69865
70235
|
});
|
|
@@ -69887,12 +70257,12 @@ var weatherCapability = {
|
|
|
69887
70257
|
*/
|
|
69888
70258
|
durability: "session",
|
|
69889
70259
|
/**
|
|
69890
|
-
* History (D850): recorded series.
|
|
70260
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
69891
70261
|
*/
|
|
69892
70262
|
history: { fields: {
|
|
69893
70263
|
temperature: {
|
|
69894
70264
|
kind: "gauge",
|
|
69895
|
-
|
|
70265
|
+
unit: "°C",
|
|
69896
70266
|
deadband: .2
|
|
69897
70267
|
},
|
|
69898
70268
|
humidity: {
|
|
@@ -69902,12 +70272,12 @@ var weatherCapability = {
|
|
|
69902
70272
|
},
|
|
69903
70273
|
pressure: {
|
|
69904
70274
|
kind: "gauge",
|
|
69905
|
-
|
|
70275
|
+
unit: "hPa",
|
|
69906
70276
|
deadband: .5
|
|
69907
70277
|
},
|
|
69908
70278
|
windSpeed: {
|
|
69909
70279
|
kind: "gauge",
|
|
69910
|
-
|
|
70280
|
+
unit: "m/s",
|
|
69911
70281
|
deadband: .5
|
|
69912
70282
|
}
|
|
69913
70283
|
} }
|
|
@@ -71286,6 +71656,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71286
71656
|
featureProbe: featureProbeCapability,
|
|
71287
71657
|
flood: floodCapability,
|
|
71288
71658
|
gas: gasCapability,
|
|
71659
|
+
groupCommands: groupCommandsCapability,
|
|
71660
|
+
groupStatus: groupStatusCapability,
|
|
71289
71661
|
heatingValve: heatingValveCapability,
|
|
71290
71662
|
humidifier: humidifierCapability,
|
|
71291
71663
|
humiditySensor: humiditySensorCapability,
|
|
@@ -72662,6 +73034,13 @@ Object.freeze({
|
|
|
72662
73034
|
access: "view",
|
|
72663
73035
|
role: "admin"
|
|
72664
73036
|
},
|
|
73037
|
+
"addons.getPackageDocs": {
|
|
73038
|
+
capName: "addons",
|
|
73039
|
+
capScope: "system",
|
|
73040
|
+
addonId: null,
|
|
73041
|
+
access: "view",
|
|
73042
|
+
role: "admin"
|
|
73043
|
+
},
|
|
72665
73044
|
"addons.getVersions": {
|
|
72666
73045
|
capName: "addons",
|
|
72667
73046
|
capScope: "system",
|
|
@@ -75770,6 +76149,20 @@ Object.freeze({
|
|
|
75770
76149
|
access: "view",
|
|
75771
76150
|
role: "viewer"
|
|
75772
76151
|
},
|
|
76152
|
+
"groupCommands.getStatus": {
|
|
76153
|
+
capName: "group-commands",
|
|
76154
|
+
capScope: "device",
|
|
76155
|
+
addonId: null,
|
|
76156
|
+
access: "view",
|
|
76157
|
+
role: "viewer"
|
|
76158
|
+
},
|
|
76159
|
+
"groupStatus.getStatus": {
|
|
76160
|
+
capName: "group-status",
|
|
76161
|
+
capScope: "device",
|
|
76162
|
+
addonId: null,
|
|
76163
|
+
access: "view",
|
|
76164
|
+
role: "viewer"
|
|
76165
|
+
},
|
|
75773
76166
|
"heatingValve.getStatus": {
|
|
75774
76167
|
capName: "heating-valve",
|
|
75775
76168
|
capScope: "device",
|
|
@@ -85592,6 +85985,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85592
85985
|
icon: "flame"
|
|
85593
85986
|
}]
|
|
85594
85987
|
},
|
|
85988
|
+
"group-commands": {
|
|
85989
|
+
scope: "device",
|
|
85990
|
+
noun: t("Group command", "Comando di gruppo")
|
|
85991
|
+
},
|
|
85992
|
+
"group-status": {
|
|
85993
|
+
scope: "device",
|
|
85994
|
+
noun: t("Group", "Gruppo"),
|
|
85995
|
+
state: [
|
|
85996
|
+
{
|
|
85997
|
+
kind: "numeric",
|
|
85998
|
+
field: "included",
|
|
85999
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
86000
|
+
label: t("Reporting", "Rispondono"),
|
|
86001
|
+
icon: "users"
|
|
86002
|
+
},
|
|
86003
|
+
{
|
|
86004
|
+
kind: "numeric",
|
|
86005
|
+
field: "excluded",
|
|
86006
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
86007
|
+
label: t("Excluded", "Esclusi"),
|
|
86008
|
+
icon: "users"
|
|
86009
|
+
},
|
|
86010
|
+
{
|
|
86011
|
+
kind: "numeric",
|
|
86012
|
+
field: "total",
|
|
86013
|
+
quantity: t("the member count", "il numero di membri"),
|
|
86014
|
+
label: t("Members", "Membri"),
|
|
86015
|
+
icon: "sigma"
|
|
86016
|
+
}
|
|
86017
|
+
]
|
|
86018
|
+
},
|
|
85595
86019
|
"humidity-sensor": {
|
|
85596
86020
|
scope: "device",
|
|
85597
86021
|
noun: t("Humidity", "Umidità"),
|
|
@@ -85625,7 +86049,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85625
86049
|
field: "value",
|
|
85626
86050
|
quantity: t("the reading", "il valore"),
|
|
85627
86051
|
label: t("Reading", "Valore"),
|
|
85628
|
-
unitField: "unit",
|
|
85629
86052
|
icon: "gauge"
|
|
85630
86053
|
}]
|
|
85631
86054
|
},
|
|
@@ -85761,7 +86184,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85761
86184
|
field: "temperature",
|
|
85762
86185
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
85763
86186
|
label: t("Temperature", "Temperatura"),
|
|
85764
|
-
|
|
86187
|
+
unit: "°C",
|
|
85765
86188
|
icon: "thermometer"
|
|
85766
86189
|
},
|
|
85767
86190
|
{
|
|
@@ -85777,7 +86200,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85777
86200
|
field: "windSpeed",
|
|
85778
86201
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
85779
86202
|
label: t("Wind", "Vento"),
|
|
85780
|
-
|
|
86203
|
+
unit: "m/s",
|
|
85781
86204
|
icon: "wind"
|
|
85782
86205
|
},
|
|
85783
86206
|
{
|
|
@@ -85785,7 +86208,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85785
86208
|
field: "pressure",
|
|
85786
86209
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
85787
86210
|
label: t("Pressure", "Pressione"),
|
|
85788
|
-
|
|
86211
|
+
unit: "hPa",
|
|
85789
86212
|
icon: "gauge"
|
|
85790
86213
|
}
|
|
85791
86214
|
]
|
|
@@ -87210,6 +87633,16 @@ Object.freeze({
|
|
|
87210
87633
|
form: "single",
|
|
87211
87634
|
optional: false
|
|
87212
87635
|
}],
|
|
87636
|
+
"groupCommands.getStatus": [{
|
|
87637
|
+
name: "deviceId",
|
|
87638
|
+
form: "single",
|
|
87639
|
+
optional: false
|
|
87640
|
+
}],
|
|
87641
|
+
"groupStatus.getStatus": [{
|
|
87642
|
+
name: "deviceId",
|
|
87643
|
+
form: "single",
|
|
87644
|
+
optional: false
|
|
87645
|
+
}],
|
|
87213
87646
|
"heatingValve.getStatus": [{
|
|
87214
87647
|
name: "deviceId",
|
|
87215
87648
|
form: "single",
|
|
@@ -89074,6 +89507,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
89074
89507
|
targetId: string().min(1),
|
|
89075
89508
|
enabled: boolean(),
|
|
89076
89509
|
debounceMs: number().nonnegative(),
|
|
89510
|
+
edges: array(_enum([
|
|
89511
|
+
"rising",
|
|
89512
|
+
"button",
|
|
89513
|
+
"native-event"
|
|
89514
|
+
])).min(1).optional(),
|
|
89077
89515
|
sources: array(OverrideSourceSchema).min(1)
|
|
89078
89516
|
});
|
|
89079
89517
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -89189,6 +89627,8 @@ new Map(Object.entries({
|
|
|
89189
89627
|
"detection-blind": "device-events",
|
|
89190
89628
|
"motion-noisy": "device-events",
|
|
89191
89629
|
"motion-calm": "device-events",
|
|
89630
|
+
"package-llm-silent": "device-events",
|
|
89631
|
+
"package-llm-answered": "device-events",
|
|
89192
89632
|
"recording-stalled": "device-events",
|
|
89193
89633
|
"recording-healthy": "device-events",
|
|
89194
89634
|
"recording-degraded": "device-events",
|
|
@@ -89272,6 +89712,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
89272
89712
|
label: "Motion without a subject",
|
|
89273
89713
|
kinds: ["motion-noisy", "motion-calm"]
|
|
89274
89714
|
},
|
|
89715
|
+
{
|
|
89716
|
+
id: "package-llm",
|
|
89717
|
+
family: "device-events",
|
|
89718
|
+
label: "Package confirm",
|
|
89719
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
89720
|
+
},
|
|
89275
89721
|
{
|
|
89276
89722
|
id: "recording",
|
|
89277
89723
|
family: "device-events",
|
|
@@ -89453,6 +89899,8 @@ var DEVICE_EVENTS = [
|
|
|
89453
89899
|
"detection-blind",
|
|
89454
89900
|
"motion-noisy",
|
|
89455
89901
|
"motion-calm",
|
|
89902
|
+
"package-llm-silent",
|
|
89903
|
+
"package-llm-answered",
|
|
89456
89904
|
"recording-stalled",
|
|
89457
89905
|
"recording-healthy",
|
|
89458
89906
|
"recording-degraded",
|
|
@@ -89721,6 +90169,15 @@ new Map([
|
|
|
89721
90169
|
snapshotLabel: "Cameras with constant motion now",
|
|
89722
90170
|
snapshotSection: null
|
|
89723
90171
|
},
|
|
90172
|
+
{
|
|
90173
|
+
id: "package-llm-confirm",
|
|
90174
|
+
family: "device-events",
|
|
90175
|
+
label: "Package confirm (not answering / answering again)",
|
|
90176
|
+
bad: ["package-llm-silent"],
|
|
90177
|
+
recovery: ["package-llm-answered"],
|
|
90178
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
90179
|
+
snapshotSection: null
|
|
90180
|
+
},
|
|
89724
90181
|
{
|
|
89725
90182
|
id: "recording-health",
|
|
89726
90183
|
family: "device-events",
|