@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.js
CHANGED
|
@@ -36,7 +36,7 @@ let node_os = require("node:os");
|
|
|
36
36
|
node_os = require_chunk.__toESM(node_os, 1);
|
|
37
37
|
let node_fs = require("node:fs");
|
|
38
38
|
node_fs = require_chunk.__toESM(node_fs, 1);
|
|
39
|
-
//#region ../types/dist/event-category-
|
|
39
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
40
40
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
41
41
|
EventCategory["SystemBoot"] = "system.boot";
|
|
42
42
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -362,6 +362,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
362
362
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
363
363
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
364
364
|
/**
|
|
365
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
366
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
367
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
368
|
+
*/
|
|
369
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
370
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
371
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
372
|
+
/**
|
|
365
373
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
366
374
|
* (a settings change via `setAgentInferenceDevices` /
|
|
367
375
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5471,7 +5479,7 @@ var ZodIssueCode = {
|
|
|
5471
5479
|
var ZodFirstPartyTypeKind;
|
|
5472
5480
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5473
5481
|
//#endregion
|
|
5474
|
-
//#region ../types/dist/sleep-
|
|
5482
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5475
5483
|
/**
|
|
5476
5484
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5477
5485
|
* window to float samples (D455).
|
|
@@ -8029,6 +8037,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
8029
8037
|
}).strict();
|
|
8030
8038
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8031
8039
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8040
|
+
var READING_QUANTITIES = [
|
|
8041
|
+
"temperature",
|
|
8042
|
+
"pressure",
|
|
8043
|
+
"speed",
|
|
8044
|
+
"precipitation",
|
|
8045
|
+
"precipitation-rate",
|
|
8046
|
+
"length",
|
|
8047
|
+
"area",
|
|
8048
|
+
"illuminance",
|
|
8049
|
+
"irradiance",
|
|
8050
|
+
"power",
|
|
8051
|
+
"energy",
|
|
8052
|
+
"voltage",
|
|
8053
|
+
"current",
|
|
8054
|
+
"apparent-power",
|
|
8055
|
+
"humidity",
|
|
8056
|
+
"percentage",
|
|
8057
|
+
"concentration-volume",
|
|
8058
|
+
"concentration-mass",
|
|
8059
|
+
"concentration-ppb",
|
|
8060
|
+
"volume",
|
|
8061
|
+
"duration",
|
|
8062
|
+
"duration-ms",
|
|
8063
|
+
"information",
|
|
8064
|
+
"sound-level",
|
|
8065
|
+
"signal-level",
|
|
8066
|
+
"colour-temperature",
|
|
8067
|
+
"angle",
|
|
8068
|
+
"bitrate",
|
|
8069
|
+
"rate",
|
|
8070
|
+
"mass",
|
|
8071
|
+
"index",
|
|
8072
|
+
"ratio",
|
|
8073
|
+
"count",
|
|
8074
|
+
"none",
|
|
8075
|
+
"device"
|
|
8076
|
+
];
|
|
8077
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8078
|
+
new Set(READING_QUANTITIES);
|
|
8079
|
+
/**
|
|
8080
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8081
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8082
|
+
*/
|
|
8083
|
+
var QUANTITY_BASE = {
|
|
8084
|
+
temperature: "°C",
|
|
8085
|
+
pressure: "hPa",
|
|
8086
|
+
speed: "m/s",
|
|
8087
|
+
precipitation: "mm",
|
|
8088
|
+
"precipitation-rate": "mm/h",
|
|
8089
|
+
length: "m",
|
|
8090
|
+
area: "m²",
|
|
8091
|
+
illuminance: "lx",
|
|
8092
|
+
irradiance: "W/m²",
|
|
8093
|
+
power: "W",
|
|
8094
|
+
energy: "kWh",
|
|
8095
|
+
voltage: "V",
|
|
8096
|
+
current: "A",
|
|
8097
|
+
"apparent-power": "VA",
|
|
8098
|
+
humidity: "%",
|
|
8099
|
+
percentage: "%",
|
|
8100
|
+
"concentration-volume": "ppm",
|
|
8101
|
+
"concentration-mass": "µg/m³",
|
|
8102
|
+
"concentration-ppb": "ppb",
|
|
8103
|
+
volume: "L",
|
|
8104
|
+
duration: "s",
|
|
8105
|
+
"duration-ms": "ms",
|
|
8106
|
+
information: "B",
|
|
8107
|
+
"sound-level": "dBFS",
|
|
8108
|
+
"signal-level": "dBm",
|
|
8109
|
+
"colour-temperature": "mired",
|
|
8110
|
+
angle: "°",
|
|
8111
|
+
bitrate: "kbps",
|
|
8112
|
+
rate: "fps",
|
|
8113
|
+
mass: "kg",
|
|
8114
|
+
index: "none",
|
|
8115
|
+
ratio: "none",
|
|
8116
|
+
count: "none",
|
|
8117
|
+
none: "none",
|
|
8118
|
+
device: "device"
|
|
8119
|
+
};
|
|
8120
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8121
|
+
function baseUnitOf(quantity) {
|
|
8122
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8123
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8124
|
+
return symbol;
|
|
8125
|
+
}
|
|
8126
|
+
function readingMeta(quantity, extras) {
|
|
8127
|
+
return {
|
|
8128
|
+
quantity,
|
|
8129
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8130
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8131
|
+
};
|
|
8132
|
+
}
|
|
8032
8133
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8033
8134
|
var CamProfileSchema = _enum([
|
|
8034
8135
|
"high",
|
|
@@ -8056,8 +8157,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8056
8157
|
"derived"
|
|
8057
8158
|
]);
|
|
8058
8159
|
var CamStreamResolutionSchema = object({
|
|
8059
|
-
width: number().int().positive(),
|
|
8060
|
-
height: number().int().positive()
|
|
8160
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8161
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8061
8162
|
});
|
|
8062
8163
|
var CameraStreamSchema = object({
|
|
8063
8164
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8609,6 +8710,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8609
8710
|
"filesystem-browse",
|
|
8610
8711
|
"flood",
|
|
8611
8712
|
"gas",
|
|
8713
|
+
"group-commands",
|
|
8714
|
+
"group-status",
|
|
8612
8715
|
"heating-valve",
|
|
8613
8716
|
"humidifier",
|
|
8614
8717
|
"humidity-sensor",
|
|
@@ -8738,14 +8841,6 @@ Object.freeze({
|
|
|
8738
8841
|
{
|
|
8739
8842
|
"path": "aqi",
|
|
8740
8843
|
"valueType": "number"
|
|
8741
|
-
},
|
|
8742
|
-
{
|
|
8743
|
-
"path": "unit",
|
|
8744
|
-
"valueType": "string"
|
|
8745
|
-
},
|
|
8746
|
-
{
|
|
8747
|
-
"path": "precision",
|
|
8748
|
-
"valueType": "number"
|
|
8749
8844
|
}
|
|
8750
8845
|
],
|
|
8751
8846
|
"alarm-panel": [
|
|
@@ -8781,20 +8876,10 @@ Object.freeze({
|
|
|
8781
8876
|
"valueType": "boolean"
|
|
8782
8877
|
}
|
|
8783
8878
|
],
|
|
8784
|
-
"ambient-light-sensor": [
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
},
|
|
8789
|
-
{
|
|
8790
|
-
"path": "unit",
|
|
8791
|
-
"valueType": "string"
|
|
8792
|
-
},
|
|
8793
|
-
{
|
|
8794
|
-
"path": "precision",
|
|
8795
|
-
"valueType": "number"
|
|
8796
|
-
}
|
|
8797
|
-
],
|
|
8879
|
+
"ambient-light-sensor": [{
|
|
8880
|
+
"path": "lux",
|
|
8881
|
+
"valueType": "number"
|
|
8882
|
+
}],
|
|
8798
8883
|
"audio-metrics": [
|
|
8799
8884
|
{
|
|
8800
8885
|
"path": "ts",
|
|
@@ -8874,6 +8959,10 @@ Object.freeze({
|
|
|
8874
8959
|
"path": "lastUpdated",
|
|
8875
8960
|
"valueType": "number"
|
|
8876
8961
|
},
|
|
8962
|
+
{
|
|
8963
|
+
"path": "volts",
|
|
8964
|
+
"valueType": "number"
|
|
8965
|
+
},
|
|
8877
8966
|
{
|
|
8878
8967
|
"path": "lastContactAt",
|
|
8879
8968
|
"valueType": "number"
|
|
@@ -9116,10 +9205,6 @@ Object.freeze({
|
|
|
9116
9205
|
"datetime"
|
|
9117
9206
|
]
|
|
9118
9207
|
},
|
|
9119
|
-
{
|
|
9120
|
-
"path": "unit",
|
|
9121
|
-
"valueType": "string"
|
|
9122
|
-
},
|
|
9123
9208
|
{
|
|
9124
9209
|
"path": "min",
|
|
9125
9210
|
"valueType": "number"
|
|
@@ -9131,19 +9216,6 @@ Object.freeze({
|
|
|
9131
9216
|
{
|
|
9132
9217
|
"path": "step",
|
|
9133
9218
|
"valueType": "number"
|
|
9134
|
-
},
|
|
9135
|
-
{
|
|
9136
|
-
"path": "precision",
|
|
9137
|
-
"valueType": "number"
|
|
9138
|
-
},
|
|
9139
|
-
{
|
|
9140
|
-
"path": "format",
|
|
9141
|
-
"valueType": "enum",
|
|
9142
|
-
"enumValues": [
|
|
9143
|
-
"date",
|
|
9144
|
-
"time",
|
|
9145
|
-
"datetime"
|
|
9146
|
-
]
|
|
9147
9219
|
}
|
|
9148
9220
|
],
|
|
9149
9221
|
"cover": [
|
|
@@ -9384,13 +9456,8 @@ Object.freeze({
|
|
|
9384
9456
|
"path": "value",
|
|
9385
9457
|
"valueType": "string"
|
|
9386
9458
|
}, {
|
|
9387
|
-
"path": "
|
|
9388
|
-
"valueType": "
|
|
9389
|
-
"enumValues": [
|
|
9390
|
-
"date",
|
|
9391
|
-
"time",
|
|
9392
|
-
"datetime"
|
|
9393
|
-
]
|
|
9459
|
+
"path": "timestamp",
|
|
9460
|
+
"valueType": "boolean"
|
|
9394
9461
|
}],
|
|
9395
9462
|
"event-emitter": [
|
|
9396
9463
|
{
|
|
@@ -9463,6 +9530,20 @@ Object.freeze({
|
|
|
9463
9530
|
"path": "detected",
|
|
9464
9531
|
"valueType": "boolean"
|
|
9465
9532
|
}],
|
|
9533
|
+
"group-status": [
|
|
9534
|
+
{
|
|
9535
|
+
"path": "included",
|
|
9536
|
+
"valueType": "number"
|
|
9537
|
+
},
|
|
9538
|
+
{
|
|
9539
|
+
"path": "excluded",
|
|
9540
|
+
"valueType": "number"
|
|
9541
|
+
},
|
|
9542
|
+
{
|
|
9543
|
+
"path": "total",
|
|
9544
|
+
"valueType": "number"
|
|
9545
|
+
}
|
|
9546
|
+
],
|
|
9466
9547
|
"heating-valve": [{
|
|
9467
9548
|
"path": "position",
|
|
9468
9549
|
"valueType": "number"
|
|
@@ -9497,20 +9578,10 @@ Object.freeze({
|
|
|
9497
9578
|
"valueType": "number"
|
|
9498
9579
|
}
|
|
9499
9580
|
],
|
|
9500
|
-
"humidity-sensor": [
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
},
|
|
9505
|
-
{
|
|
9506
|
-
"path": "unit",
|
|
9507
|
-
"valueType": "string"
|
|
9508
|
-
},
|
|
9509
|
-
{
|
|
9510
|
-
"path": "precision",
|
|
9511
|
-
"valueType": "number"
|
|
9512
|
-
}
|
|
9513
|
-
],
|
|
9581
|
+
"humidity-sensor": [{
|
|
9582
|
+
"path": "percent",
|
|
9583
|
+
"valueType": "number"
|
|
9584
|
+
}],
|
|
9514
9585
|
"image": [{
|
|
9515
9586
|
"path": "url",
|
|
9516
9587
|
"valueType": "string"
|
|
@@ -9849,20 +9920,10 @@ Object.freeze({
|
|
|
9849
9920
|
"valueType": "boolean"
|
|
9850
9921
|
}
|
|
9851
9922
|
],
|
|
9852
|
-
"numeric-sensor": [
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
},
|
|
9857
|
-
{
|
|
9858
|
-
"path": "unit",
|
|
9859
|
-
"valueType": "string"
|
|
9860
|
-
},
|
|
9861
|
-
{
|
|
9862
|
-
"path": "precision",
|
|
9863
|
-
"valueType": "number"
|
|
9864
|
-
}
|
|
9865
|
-
],
|
|
9923
|
+
"numeric-sensor": [{
|
|
9924
|
+
"path": "value",
|
|
9925
|
+
"valueType": "number"
|
|
9926
|
+
}],
|
|
9866
9927
|
"pet-feeder": [
|
|
9867
9928
|
{
|
|
9868
9929
|
"path": "foodLevel",
|
|
@@ -9954,14 +10015,6 @@ Object.freeze({
|
|
|
9954
10015
|
{
|
|
9955
10016
|
"path": "powerFactor",
|
|
9956
10017
|
"valueType": "number"
|
|
9957
|
-
},
|
|
9958
|
-
{
|
|
9959
|
-
"path": "unit",
|
|
9960
|
-
"valueType": "string"
|
|
9961
|
-
},
|
|
9962
|
-
{
|
|
9963
|
-
"path": "precision",
|
|
9964
|
-
"valueType": "number"
|
|
9965
10018
|
}
|
|
9966
10019
|
],
|
|
9967
10020
|
"presence": [
|
|
@@ -9990,20 +10043,10 @@ Object.freeze({
|
|
|
9990
10043
|
"valueType": "number"
|
|
9991
10044
|
}
|
|
9992
10045
|
],
|
|
9993
|
-
"pressure-sensor": [
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
},
|
|
9998
|
-
{
|
|
9999
|
-
"path": "unit",
|
|
10000
|
-
"valueType": "string"
|
|
10001
|
-
},
|
|
10002
|
-
{
|
|
10003
|
-
"path": "precision",
|
|
10004
|
-
"valueType": "number"
|
|
10005
|
-
}
|
|
10006
|
-
],
|
|
10046
|
+
"pressure-sensor": [{
|
|
10047
|
+
"path": "hpa",
|
|
10048
|
+
"valueType": "number"
|
|
10049
|
+
}],
|
|
10007
10050
|
"privacy-mask": [{
|
|
10008
10051
|
"path": "enabled",
|
|
10009
10052
|
"valueType": "boolean"
|
|
@@ -10314,20 +10357,10 @@ Object.freeze({
|
|
|
10314
10357
|
"path": "tampered",
|
|
10315
10358
|
"valueType": "boolean"
|
|
10316
10359
|
}],
|
|
10317
|
-
"temperature-sensor": [
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
},
|
|
10322
|
-
{
|
|
10323
|
-
"path": "unit",
|
|
10324
|
-
"valueType": "string"
|
|
10325
|
-
},
|
|
10326
|
-
{
|
|
10327
|
-
"path": "precision",
|
|
10328
|
-
"valueType": "number"
|
|
10329
|
-
}
|
|
10330
|
-
],
|
|
10360
|
+
"temperature-sensor": [{
|
|
10361
|
+
"path": "celsius",
|
|
10362
|
+
"valueType": "number"
|
|
10363
|
+
}],
|
|
10331
10364
|
"update": [
|
|
10332
10365
|
{
|
|
10333
10366
|
"path": "currentVersion",
|
|
@@ -10438,10 +10471,6 @@ Object.freeze({
|
|
|
10438
10471
|
"path": "temperature",
|
|
10439
10472
|
"valueType": "number"
|
|
10440
10473
|
},
|
|
10441
|
-
{
|
|
10442
|
-
"path": "temperatureUnit",
|
|
10443
|
-
"valueType": "string"
|
|
10444
|
-
},
|
|
10445
10474
|
{
|
|
10446
10475
|
"path": "humidity",
|
|
10447
10476
|
"valueType": "number"
|
|
@@ -10450,18 +10479,10 @@ Object.freeze({
|
|
|
10450
10479
|
"path": "pressure",
|
|
10451
10480
|
"valueType": "number"
|
|
10452
10481
|
},
|
|
10453
|
-
{
|
|
10454
|
-
"path": "pressureUnit",
|
|
10455
|
-
"valueType": "string"
|
|
10456
|
-
},
|
|
10457
10482
|
{
|
|
10458
10483
|
"path": "windSpeed",
|
|
10459
10484
|
"valueType": "number"
|
|
10460
10485
|
},
|
|
10461
|
-
{
|
|
10462
|
-
"path": "windSpeedUnit",
|
|
10463
|
-
"valueType": "string"
|
|
10464
|
-
},
|
|
10465
10486
|
{
|
|
10466
10487
|
"path": "windBearing",
|
|
10467
10488
|
"valueType": "number"
|
|
@@ -10892,7 +10913,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10892
10913
|
return DeviceRole;
|
|
10893
10914
|
}({});
|
|
10894
10915
|
//#endregion
|
|
10895
|
-
//#region ../types/dist/composition-
|
|
10916
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10896
10917
|
/**
|
|
10897
10918
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10898
10919
|
*
|
|
@@ -11647,15 +11668,74 @@ function validateExpressionSource(src) {
|
|
|
11647
11668
|
}
|
|
11648
11669
|
return null;
|
|
11649
11670
|
}
|
|
11650
|
-
/**
|
|
11651
|
-
|
|
11652
|
-
|
|
11653
|
-
|
|
11671
|
+
/**
|
|
11672
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11673
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11674
|
+
* `composition.ts` (D659).
|
|
11675
|
+
*/
|
|
11654
11676
|
var CompositionSourceRefSchema = object({
|
|
11655
11677
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11656
11678
|
addonId: string().min(1),
|
|
11657
11679
|
stableId: string().min(1)
|
|
11658
11680
|
});
|
|
11681
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11682
|
+
"temperature",
|
|
11683
|
+
"humidity",
|
|
11684
|
+
"pressure",
|
|
11685
|
+
"illuminance",
|
|
11686
|
+
"power",
|
|
11687
|
+
"energy",
|
|
11688
|
+
"battery",
|
|
11689
|
+
"numeric",
|
|
11690
|
+
"motion",
|
|
11691
|
+
"contact",
|
|
11692
|
+
"leak",
|
|
11693
|
+
"smoke",
|
|
11694
|
+
"occupancy",
|
|
11695
|
+
"binary",
|
|
11696
|
+
"switch",
|
|
11697
|
+
"light"
|
|
11698
|
+
];
|
|
11699
|
+
var NUMERIC_AGGREGATES = [
|
|
11700
|
+
"mean",
|
|
11701
|
+
"median",
|
|
11702
|
+
"min",
|
|
11703
|
+
"max",
|
|
11704
|
+
"sum"
|
|
11705
|
+
];
|
|
11706
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11707
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11708
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11709
|
+
var AGGREGATE_REDUCERS = [
|
|
11710
|
+
"mean",
|
|
11711
|
+
"median",
|
|
11712
|
+
"min",
|
|
11713
|
+
"max",
|
|
11714
|
+
"sum",
|
|
11715
|
+
"any",
|
|
11716
|
+
"all"
|
|
11717
|
+
];
|
|
11718
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11719
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11720
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11721
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11722
|
+
var HelperMemberSchema = object({
|
|
11723
|
+
source: CompositionSourceRefSchema,
|
|
11724
|
+
cap: string().min(1),
|
|
11725
|
+
fieldPath: string().min(1)
|
|
11726
|
+
});
|
|
11727
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11728
|
+
kind: literal("group"),
|
|
11729
|
+
templateId: GroupTemplateIdSchema,
|
|
11730
|
+
aggregate: AggregateReducerSchema,
|
|
11731
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11732
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11733
|
+
active: ActiveCriterionSchema.optional()
|
|
11734
|
+
})]);
|
|
11735
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11736
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11737
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11738
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11659
11739
|
/** One field of one capability of one source device. */
|
|
11660
11740
|
var CompositionFieldReadSchema = object({
|
|
11661
11741
|
source: CompositionSourceRefSchema,
|
|
@@ -11699,7 +11779,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11699
11779
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11700
11780
|
CompositionFromSourceSchema,
|
|
11701
11781
|
CompositionExpressionSourceSchema,
|
|
11702
|
-
CompositionCodeSourceSchema
|
|
11782
|
+
CompositionCodeSourceSchema,
|
|
11783
|
+
object({
|
|
11784
|
+
kind: literal("aggregate"),
|
|
11785
|
+
reducer: _enum([
|
|
11786
|
+
"mean",
|
|
11787
|
+
"median",
|
|
11788
|
+
"min",
|
|
11789
|
+
"max",
|
|
11790
|
+
"sum",
|
|
11791
|
+
"any",
|
|
11792
|
+
"all"
|
|
11793
|
+
]),
|
|
11794
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11795
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11796
|
+
publish: _enum([
|
|
11797
|
+
"value",
|
|
11798
|
+
"included",
|
|
11799
|
+
"excluded",
|
|
11800
|
+
"total"
|
|
11801
|
+
]),
|
|
11802
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11803
|
+
empty: _enum([
|
|
11804
|
+
"null",
|
|
11805
|
+
"omit",
|
|
11806
|
+
"offline"
|
|
11807
|
+
])
|
|
11808
|
+
})
|
|
11703
11809
|
]);
|
|
11704
11810
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11705
11811
|
kind: literal("forward"),
|
|
@@ -11745,7 +11851,13 @@ var CompositionSchema = object({
|
|
|
11745
11851
|
kind: literal("existing"),
|
|
11746
11852
|
device: CompositionSourceRefSchema
|
|
11747
11853
|
})]),
|
|
11748
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11854
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11855
|
+
/**
|
|
11856
|
+
* Present when the block is a helper template. Absent on a free
|
|
11857
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11858
|
+
* never the compiled features.
|
|
11859
|
+
*/
|
|
11860
|
+
helper: HelperSpecSchema.optional()
|
|
11749
11861
|
}).superRefine((composition, ctx) => {
|
|
11750
11862
|
const seen = /* @__PURE__ */ new Set();
|
|
11751
11863
|
composition.features.forEach((feature, index) => {
|
|
@@ -18523,7 +18635,11 @@ var CompositionProblemSchema = object({
|
|
|
18523
18635
|
"item-field-reserved",
|
|
18524
18636
|
"target-missing",
|
|
18525
18637
|
"target-unreadable",
|
|
18526
|
-
"not-replaceable"
|
|
18638
|
+
"not-replaceable",
|
|
18639
|
+
"native-capability-replace",
|
|
18640
|
+
"mixed-quantity",
|
|
18641
|
+
"helper-mismatch",
|
|
18642
|
+
"member-constraint"
|
|
18527
18643
|
]),
|
|
18528
18644
|
path: string(),
|
|
18529
18645
|
message: string()
|
|
@@ -18544,7 +18660,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18544
18660
|
"null",
|
|
18545
18661
|
"offline",
|
|
18546
18662
|
"unknown",
|
|
18547
|
-
"release"
|
|
18663
|
+
"release",
|
|
18664
|
+
"omit"
|
|
18548
18665
|
]);
|
|
18549
18666
|
/**
|
|
18550
18667
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18581,9 +18698,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18581
18698
|
reads: array(CompositionFieldReadSchema)
|
|
18582
18699
|
});
|
|
18583
18700
|
/**
|
|
18584
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18585
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18586
|
-
*
|
|
18701
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18702
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18703
|
+
* Replacing a capability the device already serves is refused
|
|
18704
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18705
|
+
* wire for a claim the hub already holds.
|
|
18587
18706
|
*/
|
|
18588
18707
|
var CompositionFeatureModeSchema = _enum([
|
|
18589
18708
|
"new",
|
|
@@ -18756,6 +18875,275 @@ Object.freeze({
|
|
|
18756
18875
|
result: ["number", "null"]
|
|
18757
18876
|
}
|
|
18758
18877
|
});
|
|
18878
|
+
/**
|
|
18879
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18880
|
+
* Data, not a form default written into the block.
|
|
18881
|
+
*/
|
|
18882
|
+
var NOW = {
|
|
18883
|
+
fieldPath: "lastFetchedAt",
|
|
18884
|
+
expr: "now"
|
|
18885
|
+
};
|
|
18886
|
+
var CHANGED = {
|
|
18887
|
+
fieldPath: "lastChangedAt",
|
|
18888
|
+
expr: "now"
|
|
18889
|
+
};
|
|
18890
|
+
function numeric(input) {
|
|
18891
|
+
return {
|
|
18892
|
+
...input,
|
|
18893
|
+
family: "numeric",
|
|
18894
|
+
deviceType: DeviceType.Sensor,
|
|
18895
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18896
|
+
commandCaps: [],
|
|
18897
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18898
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18899
|
+
accept: [{
|
|
18900
|
+
cap: input.outputCap,
|
|
18901
|
+
fieldPath: input.outputField
|
|
18902
|
+
}]
|
|
18903
|
+
};
|
|
18904
|
+
}
|
|
18905
|
+
function binary(input) {
|
|
18906
|
+
return {
|
|
18907
|
+
...input,
|
|
18908
|
+
family: "binary",
|
|
18909
|
+
deviceType: DeviceType.Sensor,
|
|
18910
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18911
|
+
commandCaps: [],
|
|
18912
|
+
quantity: "none",
|
|
18913
|
+
baseUnit: void 0,
|
|
18914
|
+
aggregates: BINARY_AGGREGATES,
|
|
18915
|
+
empty: "offline"
|
|
18916
|
+
};
|
|
18917
|
+
}
|
|
18918
|
+
var GROUP_TEMPLATES = [
|
|
18919
|
+
numeric({
|
|
18920
|
+
id: "temperature",
|
|
18921
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18922
|
+
role: DeviceRole.TemperatureSensor,
|
|
18923
|
+
outputCap: "temperature-sensor",
|
|
18924
|
+
outputField: "celsius",
|
|
18925
|
+
quantity: "temperature",
|
|
18926
|
+
defaultAggregate: "mean",
|
|
18927
|
+
empty: "null",
|
|
18928
|
+
companions: [NOW]
|
|
18929
|
+
}),
|
|
18930
|
+
numeric({
|
|
18931
|
+
id: "humidity",
|
|
18932
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18933
|
+
role: DeviceRole.HumiditySensor,
|
|
18934
|
+
outputCap: "humidity-sensor",
|
|
18935
|
+
outputField: "percent",
|
|
18936
|
+
quantity: "humidity",
|
|
18937
|
+
defaultAggregate: "mean",
|
|
18938
|
+
empty: "null",
|
|
18939
|
+
companions: [NOW]
|
|
18940
|
+
}),
|
|
18941
|
+
numeric({
|
|
18942
|
+
id: "pressure",
|
|
18943
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18944
|
+
role: DeviceRole.PressureSensor,
|
|
18945
|
+
outputCap: "pressure-sensor",
|
|
18946
|
+
outputField: "hpa",
|
|
18947
|
+
quantity: "pressure",
|
|
18948
|
+
defaultAggregate: "mean",
|
|
18949
|
+
empty: "null",
|
|
18950
|
+
companions: [NOW]
|
|
18951
|
+
}),
|
|
18952
|
+
numeric({
|
|
18953
|
+
id: "illuminance",
|
|
18954
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18955
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18956
|
+
outputCap: "ambient-light-sensor",
|
|
18957
|
+
outputField: "lux",
|
|
18958
|
+
quantity: "illuminance",
|
|
18959
|
+
defaultAggregate: "mean",
|
|
18960
|
+
empty: "null",
|
|
18961
|
+
companions: [NOW]
|
|
18962
|
+
}),
|
|
18963
|
+
numeric({
|
|
18964
|
+
id: "power",
|
|
18965
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18966
|
+
role: DeviceRole.PowerSensor,
|
|
18967
|
+
outputCap: "power-meter",
|
|
18968
|
+
outputField: "watts",
|
|
18969
|
+
quantity: "power",
|
|
18970
|
+
defaultAggregate: "sum",
|
|
18971
|
+
empty: "omit",
|
|
18972
|
+
companions: [NOW]
|
|
18973
|
+
}),
|
|
18974
|
+
numeric({
|
|
18975
|
+
id: "energy",
|
|
18976
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18977
|
+
role: DeviceRole.EnergySensor,
|
|
18978
|
+
outputCap: "power-meter",
|
|
18979
|
+
outputField: "kwhTotal",
|
|
18980
|
+
quantity: "energy",
|
|
18981
|
+
defaultAggregate: "sum",
|
|
18982
|
+
empty: "omit",
|
|
18983
|
+
companions: [NOW]
|
|
18984
|
+
}),
|
|
18985
|
+
numeric({
|
|
18986
|
+
id: "battery",
|
|
18987
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18988
|
+
role: DeviceRole.BatterySensor,
|
|
18989
|
+
outputCap: "battery",
|
|
18990
|
+
outputField: "percentage",
|
|
18991
|
+
quantity: "percentage",
|
|
18992
|
+
defaultAggregate: "mean",
|
|
18993
|
+
empty: "null",
|
|
18994
|
+
companions: [
|
|
18995
|
+
{
|
|
18996
|
+
fieldPath: "charging",
|
|
18997
|
+
expr: "\"unknown\""
|
|
18998
|
+
},
|
|
18999
|
+
{
|
|
19000
|
+
fieldPath: "sleeping",
|
|
19001
|
+
expr: "false"
|
|
19002
|
+
},
|
|
19003
|
+
{
|
|
19004
|
+
fieldPath: "lastUpdated",
|
|
19005
|
+
expr: "now"
|
|
19006
|
+
}
|
|
19007
|
+
]
|
|
19008
|
+
}),
|
|
19009
|
+
numeric({
|
|
19010
|
+
id: "numeric",
|
|
19011
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
19012
|
+
role: DeviceRole.NumericSensor,
|
|
19013
|
+
outputCap: "numeric-sensor",
|
|
19014
|
+
outputField: "value",
|
|
19015
|
+
quantity: "device",
|
|
19016
|
+
defaultAggregate: "mean",
|
|
19017
|
+
empty: "null",
|
|
19018
|
+
companions: [NOW]
|
|
19019
|
+
}),
|
|
19020
|
+
binary({
|
|
19021
|
+
id: "motion",
|
|
19022
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
19023
|
+
role: DeviceRole.MotionSensor,
|
|
19024
|
+
outputCap: "motion",
|
|
19025
|
+
outputField: "detected",
|
|
19026
|
+
defaultAggregate: "any",
|
|
19027
|
+
accept: [{
|
|
19028
|
+
cap: "motion",
|
|
19029
|
+
fieldPath: "detected"
|
|
19030
|
+
}],
|
|
19031
|
+
companions: [{
|
|
19032
|
+
fieldPath: "lastDetectedAt",
|
|
19033
|
+
expr: "null"
|
|
19034
|
+
}, {
|
|
19035
|
+
fieldPath: "autoClearAfterMs",
|
|
19036
|
+
expr: "null"
|
|
19037
|
+
}]
|
|
19038
|
+
}),
|
|
19039
|
+
binary({
|
|
19040
|
+
id: "contact",
|
|
19041
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
19042
|
+
role: DeviceRole.ContactSensor,
|
|
19043
|
+
outputCap: "contact",
|
|
19044
|
+
outputField: "entryOpen",
|
|
19045
|
+
defaultAggregate: "any",
|
|
19046
|
+
accept: [{
|
|
19047
|
+
cap: "contact",
|
|
19048
|
+
fieldPath: "entryOpen"
|
|
19049
|
+
}],
|
|
19050
|
+
companions: [CHANGED]
|
|
19051
|
+
}),
|
|
19052
|
+
binary({
|
|
19053
|
+
id: "leak",
|
|
19054
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
19055
|
+
role: DeviceRole.LeakSensor,
|
|
19056
|
+
outputCap: "flood",
|
|
19057
|
+
outputField: "flooded",
|
|
19058
|
+
defaultAggregate: "any",
|
|
19059
|
+
accept: [{
|
|
19060
|
+
cap: "flood",
|
|
19061
|
+
fieldPath: "flooded"
|
|
19062
|
+
}],
|
|
19063
|
+
companions: [CHANGED]
|
|
19064
|
+
}),
|
|
19065
|
+
binary({
|
|
19066
|
+
id: "smoke",
|
|
19067
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
19068
|
+
role: DeviceRole.SmokeSensor,
|
|
19069
|
+
outputCap: "smoke",
|
|
19070
|
+
outputField: "detected",
|
|
19071
|
+
defaultAggregate: "any",
|
|
19072
|
+
accept: [{
|
|
19073
|
+
cap: "smoke",
|
|
19074
|
+
fieldPath: "detected"
|
|
19075
|
+
}],
|
|
19076
|
+
companions: [CHANGED]
|
|
19077
|
+
}),
|
|
19078
|
+
binary({
|
|
19079
|
+
id: "occupancy",
|
|
19080
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
19081
|
+
role: DeviceRole.BinarySensor,
|
|
19082
|
+
outputCap: "binary",
|
|
19083
|
+
outputField: "on",
|
|
19084
|
+
defaultAggregate: "any",
|
|
19085
|
+
accept: [{
|
|
19086
|
+
cap: "motion",
|
|
19087
|
+
fieldPath: "detected"
|
|
19088
|
+
}, {
|
|
19089
|
+
cap: "binary",
|
|
19090
|
+
fieldPath: "on"
|
|
19091
|
+
}],
|
|
19092
|
+
companions: [CHANGED]
|
|
19093
|
+
}),
|
|
19094
|
+
binary({
|
|
19095
|
+
id: "binary",
|
|
19096
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
19097
|
+
role: DeviceRole.BinarySensor,
|
|
19098
|
+
outputCap: "binary",
|
|
19099
|
+
outputField: "on",
|
|
19100
|
+
defaultAggregate: "any",
|
|
19101
|
+
accept: [{
|
|
19102
|
+
cap: "binary",
|
|
19103
|
+
fieldPath: "on"
|
|
19104
|
+
}],
|
|
19105
|
+
companions: [CHANGED]
|
|
19106
|
+
}),
|
|
19107
|
+
actuator({
|
|
19108
|
+
id: "switch",
|
|
19109
|
+
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.",
|
|
19110
|
+
deviceType: DeviceType.Switch,
|
|
19111
|
+
outputCap: "switch",
|
|
19112
|
+
commandCaps: ["switch"]
|
|
19113
|
+
}),
|
|
19114
|
+
actuator({
|
|
19115
|
+
id: "light",
|
|
19116
|
+
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.",
|
|
19117
|
+
deviceType: DeviceType.Light,
|
|
19118
|
+
outputCap: "switch",
|
|
19119
|
+
commandCaps: [
|
|
19120
|
+
"switch",
|
|
19121
|
+
"brightness",
|
|
19122
|
+
"color"
|
|
19123
|
+
]
|
|
19124
|
+
})
|
|
19125
|
+
];
|
|
19126
|
+
function actuator(input) {
|
|
19127
|
+
return {
|
|
19128
|
+
...input,
|
|
19129
|
+
family: "actuator",
|
|
19130
|
+
role: void 0,
|
|
19131
|
+
memberDeviceType: input.deviceType,
|
|
19132
|
+
outputField: "on",
|
|
19133
|
+
quantity: "none",
|
|
19134
|
+
baseUnit: void 0,
|
|
19135
|
+
aggregates: BINARY_AGGREGATES,
|
|
19136
|
+
defaultAggregate: "any",
|
|
19137
|
+
empty: "offline",
|
|
19138
|
+
accept: [{
|
|
19139
|
+
cap: "switch",
|
|
19140
|
+
fieldPath: "on"
|
|
19141
|
+
}],
|
|
19142
|
+
companions: [CHANGED]
|
|
19143
|
+
};
|
|
19144
|
+
}
|
|
19145
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19146
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18759
19147
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18760
19148
|
/**
|
|
18761
19149
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20582,12 +20970,12 @@ function buildDeviceAdminUrl(parts) {
|
|
|
20582
20970
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20583
20971
|
* in-place so dispatch keeps working.
|
|
20584
20972
|
*
|
|
20585
|
-
* **
|
|
20586
|
-
*
|
|
20587
|
-
*
|
|
20588
|
-
*
|
|
20589
|
-
* (`ha-domain-mapping`)
|
|
20590
|
-
* stored after that point.
|
|
20973
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20974
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20975
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20976
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20977
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20978
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20591
20979
|
*
|
|
20592
20980
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20593
20981
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20601,6 +20989,14 @@ var SourceInfoSchema = object({
|
|
|
20601
20989
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20602
20990
|
* Used to detect rename when `id` changes. */
|
|
20603
20991
|
uniqueId: string().optional(),
|
|
20992
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20993
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20994
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20995
|
+
dateTimeShape: _enum([
|
|
20996
|
+
"date",
|
|
20997
|
+
"time",
|
|
20998
|
+
"datetime"
|
|
20999
|
+
]).optional(),
|
|
20604
21000
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20605
21001
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20606
21002
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41705,7 +42101,8 @@ method(object({
|
|
|
41705
42101
|
"enum"
|
|
41706
42102
|
]),
|
|
41707
42103
|
enumValues: array(string()).optional(),
|
|
41708
|
-
item: boolean().optional()
|
|
42104
|
+
item: boolean().optional(),
|
|
42105
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41709
42106
|
})).readonly(),
|
|
41710
42107
|
itemArray: object({
|
|
41711
42108
|
path: string(),
|
|
@@ -45589,8 +45986,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
45589
45986
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
45590
45987
|
var MaskGridShapeSchema = object({
|
|
45591
45988
|
kind: literal("grid"),
|
|
45592
|
-
gridWidth: number(),
|
|
45593
|
-
gridHeight: number(),
|
|
45989
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45990
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
45594
45991
|
cells: array(boolean())
|
|
45595
45992
|
});
|
|
45596
45993
|
discriminatedUnion("kind", [
|
|
@@ -45702,6 +46099,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45702
46099
|
"detection-blind",
|
|
45703
46100
|
"motion-noisy",
|
|
45704
46101
|
"motion-calm",
|
|
46102
|
+
"package-llm-silent",
|
|
46103
|
+
"package-llm-answered",
|
|
45705
46104
|
"recording-stalled",
|
|
45706
46105
|
"recording-healthy",
|
|
45707
46106
|
"recording-degraded",
|
|
@@ -57315,6 +57714,28 @@ var PackageVersionInfoSchema = object({
|
|
|
57315
57714
|
deprecated: string().optional(),
|
|
57316
57715
|
distTags: array(string()).readonly()
|
|
57317
57716
|
});
|
|
57717
|
+
/**
|
|
57718
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
57719
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
57720
|
+
* tarball failure — never an empty string standing in for either.
|
|
57721
|
+
*/
|
|
57722
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
57723
|
+
object({
|
|
57724
|
+
status: literal("ok"),
|
|
57725
|
+
markdown: string()
|
|
57726
|
+
}),
|
|
57727
|
+
object({ status: literal("missing") }),
|
|
57728
|
+
object({
|
|
57729
|
+
status: literal("error"),
|
|
57730
|
+
message: string()
|
|
57731
|
+
})
|
|
57732
|
+
]);
|
|
57733
|
+
var PackageDocsSchema = object({
|
|
57734
|
+
name: string(),
|
|
57735
|
+
version: string(),
|
|
57736
|
+
readme: PackageDocBodySchema,
|
|
57737
|
+
changelog: PackageDocBodySchema
|
|
57738
|
+
});
|
|
57318
57739
|
var SearchResultSchema = object({
|
|
57319
57740
|
name: string(),
|
|
57320
57741
|
version: string(),
|
|
@@ -57533,7 +57954,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57533
57954
|
}), object({ success: literal(true) }), {
|
|
57534
57955
|
kind: "mutation",
|
|
57535
57956
|
auth: "admin"
|
|
57536
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57957
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57958
|
+
name: string().min(1),
|
|
57959
|
+
version: string().min(1).optional()
|
|
57960
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
57537
57961
|
kind: "mutation",
|
|
57538
57962
|
auth: "admin"
|
|
57539
57963
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -57592,27 +58016,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57592
58016
|
*/
|
|
57593
58017
|
var AirQualitySensorStatusSchema = object({
|
|
57594
58018
|
/** Carbon dioxide concentration in ppm. */
|
|
57595
|
-
co2Ppm: number().min(0).optional(),
|
|
58019
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57596
58020
|
/** Total volatile organic compounds in ppb. */
|
|
57597
|
-
vocPpb: number().min(0).optional(),
|
|
58021
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57598
58022
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57599
|
-
pm25: number().min(0).optional(),
|
|
58023
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57600
58024
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
57601
|
-
pm10: number().min(0).optional(),
|
|
58025
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57602
58026
|
/** Composite AQI value (typically 0..500). */
|
|
57603
|
-
aqi: number().optional(),
|
|
58027
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
57604
58028
|
/** Ms epoch when the slice was last updated. */
|
|
57605
|
-
lastFetchedAt: number()
|
|
57606
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
57607
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
57608
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
57609
|
-
* per slice is unambiguous. */
|
|
57610
|
-
unit: string().optional(),
|
|
57611
|
-
/** Suggested decimal places for numeric display.
|
|
57612
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57613
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57614
|
-
* auto-formatting when absent. */
|
|
57615
|
-
precision: number().int().min(0).max(10).optional()
|
|
58029
|
+
lastFetchedAt: number()
|
|
57616
58030
|
});
|
|
57617
58031
|
var airQualitySensorCapability = {
|
|
57618
58032
|
name: "air-quality-sensor",
|
|
@@ -57649,12 +58063,12 @@ var airQualitySensorCapability = {
|
|
|
57649
58063
|
},
|
|
57650
58064
|
pm25: {
|
|
57651
58065
|
kind: "gauge",
|
|
57652
|
-
unit: "
|
|
58066
|
+
unit: "µg/m³",
|
|
57653
58067
|
deadband: 1
|
|
57654
58068
|
},
|
|
57655
58069
|
pm10: {
|
|
57656
58070
|
kind: "gauge",
|
|
57657
|
-
unit: "
|
|
58071
|
+
unit: "µg/m³",
|
|
57658
58072
|
deadband: 1
|
|
57659
58073
|
},
|
|
57660
58074
|
aqi: {
|
|
@@ -57672,22 +58086,13 @@ var airQualitySensorCapability = {
|
|
|
57672
58086
|
* entries with `device_class: illuminance`.
|
|
57673
58087
|
*/
|
|
57674
58088
|
var AmbientLightSensorStatusSchema = object({
|
|
57675
|
-
/** Current illuminance in lux (lx). */
|
|
57676
|
-
lux: number().min(0).meta({
|
|
57677
|
-
|
|
58089
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
58090
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
58091
|
+
precision: 0,
|
|
57678
58092
|
label: "Illuminance"
|
|
57679
|
-
}),
|
|
58093
|
+
})),
|
|
57680
58094
|
/** Ms epoch when the slice was last updated. */
|
|
57681
|
-
lastFetchedAt: number()
|
|
57682
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
57683
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
57684
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
57685
|
-
unit: string().optional(),
|
|
57686
|
-
/** Suggested decimal places for numeric display.
|
|
57687
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57688
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57689
|
-
* auto-formatting when absent. */
|
|
57690
|
-
precision: number().int().min(0).max(10).optional()
|
|
58095
|
+
lastFetchedAt: number()
|
|
57691
58096
|
});
|
|
57692
58097
|
var ambientLightSensorCapability = {
|
|
57693
58098
|
name: "ambient-light-sensor",
|
|
@@ -57719,12 +58124,7 @@ var ambientLightSensorCapability = {
|
|
|
57719
58124
|
} } },
|
|
57720
58125
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57721
58126
|
* whether persisting is worth a SQLite commit. */
|
|
57722
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
57723
|
-
customize: {
|
|
57724
|
-
version: 1,
|
|
57725
|
-
advanced: "derive",
|
|
57726
|
-
targets: []
|
|
57727
|
-
}
|
|
58127
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
57728
58128
|
};
|
|
57729
58129
|
/**
|
|
57730
58130
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57951,10 +58351,7 @@ var BatteryStatusSchema = object({
|
|
|
57951
58351
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57952
58352
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57953
58353
|
*/
|
|
57954
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57955
|
-
unit: "%",
|
|
57956
|
-
label: "Charge"
|
|
57957
|
-
}),
|
|
58354
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57958
58355
|
/**
|
|
57959
58356
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57960
58357
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57981,7 +58378,14 @@ var BatteryStatusSchema = object({
|
|
|
57981
58378
|
*/
|
|
57982
58379
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57983
58380
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57984
|
-
lastUpdated: number(),
|
|
58381
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
58382
|
+
/**
|
|
58383
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
58384
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
58385
|
+
* that only report charge. A second reading on this cap, not a second
|
|
58386
|
+
* `numeric-sensor` on the same device.
|
|
58387
|
+
*/
|
|
58388
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57985
58389
|
/**
|
|
57986
58390
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57987
58391
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58033,7 +58437,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58033
58437
|
/** Generic Customize target for the percentage reading (D936). */
|
|
58034
58438
|
var batteryCustomize = {
|
|
58035
58439
|
version: 1,
|
|
58036
|
-
advanced: "derive",
|
|
58037
58440
|
targets: [{
|
|
58038
58441
|
id: "percentage",
|
|
58039
58442
|
cardinality: "scalar",
|
|
@@ -58042,7 +58445,7 @@ var batteryCustomize = {
|
|
|
58042
58445
|
stateField: "percentage"
|
|
58043
58446
|
},
|
|
58044
58447
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58045
|
-
apply: "add
|
|
58448
|
+
apply: "add",
|
|
58046
58449
|
path: "percentage",
|
|
58047
58450
|
sources: [{
|
|
58048
58451
|
kind: "field",
|
|
@@ -58163,10 +58566,16 @@ onStatusChanged: { data: object({
|
|
|
58163
58566
|
/**
|
|
58164
58567
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58165
58568
|
*/
|
|
58166
|
-
history: { fields: {
|
|
58167
|
-
|
|
58168
|
-
|
|
58169
|
-
|
|
58569
|
+
history: { fields: {
|
|
58570
|
+
percentage: {
|
|
58571
|
+
kind: "gauge",
|
|
58572
|
+
unit: "%"
|
|
58573
|
+
},
|
|
58574
|
+
volts: {
|
|
58575
|
+
kind: "gauge",
|
|
58576
|
+
unit: "V"
|
|
58577
|
+
}
|
|
58578
|
+
} },
|
|
58170
58579
|
customize: batteryCustomize,
|
|
58171
58580
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58172
58581
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -58213,12 +58622,7 @@ var binaryCapability = {
|
|
|
58213
58622
|
history: { fields: { on: { kind: "boolean" } } },
|
|
58214
58623
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58215
58624
|
* whether persisting is worth a SQLite commit. */
|
|
58216
|
-
volatileStateFields: ["lastChangedAt"]
|
|
58217
|
-
customize: {
|
|
58218
|
-
version: 1,
|
|
58219
|
-
advanced: "derive",
|
|
58220
|
-
targets: []
|
|
58221
|
-
}
|
|
58625
|
+
volatileStateFields: ["lastChangedAt"]
|
|
58222
58626
|
};
|
|
58223
58627
|
/**
|
|
58224
58628
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -58234,7 +58638,7 @@ var binaryCapability = {
|
|
|
58234
58638
|
*/
|
|
58235
58639
|
var BrightnessStatusSchema = object({
|
|
58236
58640
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58237
|
-
percentage: number().min(0).max(100),
|
|
58641
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58238
58642
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58239
58643
|
lastChangedAt: number()
|
|
58240
58644
|
});
|
|
@@ -58688,21 +59092,21 @@ var ClimateControlStatusSchema = object({
|
|
|
58688
59092
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
58689
59093
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
58690
59094
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
58691
|
-
target: number().nullable(),
|
|
59095
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
58692
59096
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
58693
59097
|
* in `heat_cool` mode. */
|
|
58694
|
-
targetHigh: number().nullable(),
|
|
59098
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
58695
59099
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
58696
59100
|
* in `heat_cool` mode. */
|
|
58697
|
-
targetLow: number().nullable(),
|
|
59101
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
58698
59102
|
/** Target relative humidity (0..100). Null when the device has no
|
|
58699
59103
|
* humidity control. */
|
|
58700
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
59104
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58701
59105
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
58702
59106
|
* the device's internal sensor. */
|
|
58703
|
-
currentTemp: number().nullable(),
|
|
59107
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
58704
59108
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
58705
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
59109
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58706
59110
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
58707
59111
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
58708
59112
|
swingVertical: boolean().nullable(),
|
|
@@ -58710,11 +59114,11 @@ var ClimateControlStatusSchema = object({
|
|
|
58710
59114
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
58711
59115
|
swingHorizontal: boolean().nullable(),
|
|
58712
59116
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58713
|
-
minTemp: number().nullable().optional(),
|
|
59117
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58714
59118
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58715
|
-
maxTemp: number().nullable().optional(),
|
|
59119
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58716
59120
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
58717
|
-
tempStep: number().positive().nullable().optional(),
|
|
59121
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
58718
59122
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
58719
59123
|
lastFetchedAt: number()
|
|
58720
59124
|
});
|
|
@@ -58856,17 +59260,17 @@ var climateControlCapability = {
|
|
|
58856
59260
|
* modes to expose in the picker without a slice fetch.
|
|
58857
59261
|
*/
|
|
58858
59262
|
var RgbTripletSchema = object({
|
|
58859
|
-
r: number().int().min(0).max(255),
|
|
58860
|
-
g: number().int().min(0).max(255),
|
|
58861
|
-
b: number().int().min(0).max(255)
|
|
59263
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
59264
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
59265
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
58862
59266
|
});
|
|
58863
59267
|
var HsvTripletSchema = object({
|
|
58864
59268
|
/** Hue in degrees, 0..360. */
|
|
58865
|
-
h: number().min(0).max(360),
|
|
59269
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
58866
59270
|
/** Saturation as 0..100 inclusive. */
|
|
58867
|
-
s: number().min(0).max(100),
|
|
59271
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
58868
59272
|
/** Value/brightness as 0..100 inclusive. */
|
|
58869
|
-
v: number().min(0).max(100)
|
|
59273
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
58870
59274
|
});
|
|
58871
59275
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
58872
59276
|
object({
|
|
@@ -58895,7 +59299,7 @@ var ColorStatusSchema = object({
|
|
|
58895
59299
|
/** Populated when `mode === 'hsv'`. */
|
|
58896
59300
|
hsv: HsvTripletSchema.optional(),
|
|
58897
59301
|
/** Populated when `mode === 'mired'`. */
|
|
58898
|
-
mireds: number().int().optional(),
|
|
59302
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58899
59303
|
/** Ms epoch of the last operator-driven change. */
|
|
58900
59304
|
lastChangedAt: number()
|
|
58901
59305
|
});
|
|
@@ -59090,18 +59494,12 @@ _enum([
|
|
|
59090
59494
|
"empty",
|
|
59091
59495
|
"full"
|
|
59092
59496
|
]);
|
|
59093
|
-
/**
|
|
59094
|
-
|
|
59095
|
-
|
|
59096
|
-
"days",
|
|
59097
|
-
"hours",
|
|
59098
|
-
"cycles"
|
|
59099
|
-
]);
|
|
59100
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
59101
|
-
* days). `value` null = unknown (D393). */
|
|
59497
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
59498
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
59499
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
59102
59500
|
var ConsumableRemainingSchema = object({
|
|
59103
|
-
value: number().min(0).nullable(),
|
|
59104
|
-
|
|
59501
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
59502
|
+
kind: ConsumableRemainingKindSchema
|
|
59105
59503
|
});
|
|
59106
59504
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
59107
59505
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -59114,7 +59512,7 @@ var ConsumableItemSchema = object({
|
|
|
59114
59512
|
/** Display name. */
|
|
59115
59513
|
label: string().min(1),
|
|
59116
59514
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
59117
|
-
level: number().min(0).max(100).nullable(),
|
|
59515
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59118
59516
|
/** The provider's discrete verdict when known (binary mode). */
|
|
59119
59517
|
status: ConsumableStatusSchema.nullable(),
|
|
59120
59518
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -59196,8 +59594,8 @@ var consumablesCustomize = {
|
|
|
59196
59594
|
transforms: [{ kind: "identity" }]
|
|
59197
59595
|
}],
|
|
59198
59596
|
literals: [{
|
|
59199
|
-
path: "remaining.
|
|
59200
|
-
values: [...
|
|
59597
|
+
path: "remaining.kind",
|
|
59598
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
59201
59599
|
}]
|
|
59202
59600
|
},
|
|
59203
59601
|
{
|
|
@@ -59326,7 +59724,6 @@ reset: method(object({
|
|
|
59326
59724
|
},
|
|
59327
59725
|
"remaining.value": {
|
|
59328
59726
|
kind: "gauge",
|
|
59329
|
-
unitFrom: "remaining.unit",
|
|
59330
59727
|
deadband: 1,
|
|
59331
59728
|
displayName: "Remaining"
|
|
59332
59729
|
}
|
|
@@ -59396,10 +59793,9 @@ var contactCapability = {
|
|
|
59396
59793
|
* (empty array for the other kinds). It lives in the slice because
|
|
59397
59794
|
* HA `select.*` entities may update their options at runtime.
|
|
59398
59795
|
*
|
|
59399
|
-
*
|
|
59400
|
-
*
|
|
59401
|
-
*
|
|
59402
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
59796
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
59797
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
59798
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
59403
59799
|
*/
|
|
59404
59800
|
var ControlStatusSchema = object({
|
|
59405
59801
|
kind: _enum([
|
|
@@ -59411,39 +59807,17 @@ var ControlStatusSchema = object({
|
|
|
59411
59807
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
59412
59808
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
59413
59809
|
* or time-only — HA accepts all three forms). */
|
|
59414
|
-
value: union([number(), string()]),
|
|
59810
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
59415
59811
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
59416
59812
|
options: array(string()),
|
|
59417
59813
|
/** Ms epoch when the slice was last updated. */
|
|
59418
59814
|
lastChangedAt: number(),
|
|
59419
|
-
/**
|
|
59420
|
-
|
|
59421
|
-
|
|
59422
|
-
|
|
59423
|
-
/**
|
|
59424
|
-
|
|
59425
|
-
min: number().optional(),
|
|
59426
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
59427
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
59428
|
-
max: number().optional(),
|
|
59429
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
59430
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
59431
|
-
step: number().optional(),
|
|
59432
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
59433
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
59434
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
59435
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
59436
|
-
precision: number().int().min(0).max(10).optional(),
|
|
59437
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
59438
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
59439
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
59440
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
59441
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
59442
|
-
format: _enum([
|
|
59443
|
-
"date",
|
|
59444
|
-
"time",
|
|
59445
|
-
"datetime"
|
|
59446
|
-
]).optional()
|
|
59815
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
59816
|
+
min: number().optional().meta(readingMeta("device")),
|
|
59817
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
59818
|
+
max: number().optional().meta(readingMeta("device")),
|
|
59819
|
+
/** Step increment, in the device quantity's base unit. */
|
|
59820
|
+
step: number().optional().meta(readingMeta("device"))
|
|
59447
59821
|
});
|
|
59448
59822
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
59449
59823
|
object({
|
|
@@ -59509,9 +59883,9 @@ var CoverStatusSchema = object({
|
|
|
59509
59883
|
]),
|
|
59510
59884
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
59511
59885
|
* no intermediate position surface. */
|
|
59512
|
-
position: number().min(0).max(100).nullable(),
|
|
59886
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59513
59887
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
59514
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
59888
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59515
59889
|
/** Ms epoch when the slice was last updated. */
|
|
59516
59890
|
lastChangedAt: number()
|
|
59517
59891
|
});
|
|
@@ -59614,9 +59988,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
59614
59988
|
var DayNightStatusSchema = object({
|
|
59615
59989
|
mode: DayNightModeSchema,
|
|
59616
59990
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
59617
|
-
sensitivity: number().optional(),
|
|
59991
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
59618
59992
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
59619
|
-
switchDelaySec: number().optional(),
|
|
59993
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
59620
59994
|
lastFetchedAt: number()
|
|
59621
59995
|
});
|
|
59622
59996
|
/**
|
|
@@ -59834,11 +60208,11 @@ var DishwasherStatusSchema = object({
|
|
|
59834
60208
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59835
60209
|
availablePrograms: array(string()),
|
|
59836
60210
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59837
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
60211
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59838
60212
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59839
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
60213
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59840
60214
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59841
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60215
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59842
60216
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59843
60217
|
doorOpen: boolean().nullable(),
|
|
59844
60218
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59862,7 +60236,7 @@ var DishwasherStatusSchema = object({
|
|
|
59862
60236
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
59863
60237
|
machineCareDue: boolean().nullable(),
|
|
59864
60238
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
59865
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
60239
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
59866
60240
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
59867
60241
|
halfLoad: boolean().nullable(),
|
|
59868
60242
|
hygienePlus: boolean().nullable(),
|
|
@@ -59877,7 +60251,7 @@ var DishwasherStatusSchema = object({
|
|
|
59877
60251
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
59878
60252
|
activeEvents: array(string()),
|
|
59879
60253
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
59880
|
-
errorCode: number().nullable(),
|
|
60254
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
59881
60255
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
59882
60256
|
errorLabel: string().nullable(),
|
|
59883
60257
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -60089,6 +60463,7 @@ var doorbellCustomize = {
|
|
|
60089
60463
|
applyAuthority: { kind: "composition-claim" },
|
|
60090
60464
|
eventName: "onPressed",
|
|
60091
60465
|
edges: ["rising"],
|
|
60466
|
+
defaultEdge: "rising",
|
|
60092
60467
|
timestampPath: "lastPressedAt",
|
|
60093
60468
|
counterPath: "pressCountSinceStart",
|
|
60094
60469
|
highWater: "composer-advance",
|
|
@@ -60107,7 +60482,7 @@ var DoorbellStatusSchema = object({
|
|
|
60107
60482
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
60108
60483
|
lastPressedAt: number().nullable(),
|
|
60109
60484
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
60110
|
-
pressCountSinceStart: number()
|
|
60485
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
60111
60486
|
});
|
|
60112
60487
|
var DoorbellPressEventSchema = object({
|
|
60113
60488
|
deviceId: number(),
|
|
@@ -60172,17 +60547,7 @@ onPressed: {
|
|
|
60172
60547
|
history: "none",
|
|
60173
60548
|
customize: doorbellCustomize
|
|
60174
60549
|
};
|
|
60175
|
-
|
|
60176
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
60177
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
60178
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
60179
|
-
* The option set is stable across observations; it is persisted in the
|
|
60180
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
60181
|
-
* stored in `sourceInfo`.
|
|
60182
|
-
*/
|
|
60183
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
60184
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
60185
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
60550
|
+
_enum([
|
|
60186
60551
|
"date",
|
|
60187
60552
|
"time",
|
|
60188
60553
|
"datetime"
|
|
@@ -60190,12 +60555,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
60190
60555
|
var EnumSensorStatusSchema = object({
|
|
60191
60556
|
value: string(),
|
|
60192
60557
|
/**
|
|
60193
|
-
* Set
|
|
60194
|
-
* as
|
|
60195
|
-
*
|
|
60196
|
-
* a time-only sensor → `'time'`.
|
|
60558
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
60559
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
60560
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
60197
60561
|
*/
|
|
60198
|
-
|
|
60562
|
+
timestamp: boolean().optional(),
|
|
60199
60563
|
/** Ms epoch when the slice was last updated. */
|
|
60200
60564
|
lastFetchedAt: number()
|
|
60201
60565
|
});
|
|
@@ -60222,11 +60586,11 @@ var enumSensorCapability = {
|
|
|
60222
60586
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
60223
60587
|
* operation state, an HVAC action). The option set is per device, so the
|
|
60224
60588
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
60225
|
-
* `
|
|
60589
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
60226
60590
|
*/
|
|
60227
60591
|
history: { fields: { value: {
|
|
60228
60592
|
kind: "enum",
|
|
60229
|
-
skipWhenSet: "
|
|
60593
|
+
skipWhenSet: "timestamp"
|
|
60230
60594
|
} } },
|
|
60231
60595
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60232
60596
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -60246,13 +60610,13 @@ var EventFireSchema = object({
|
|
|
60246
60610
|
deviceId: number(),
|
|
60247
60611
|
eventType: string(),
|
|
60248
60612
|
data: record(string(), unknown()).nullable(),
|
|
60249
|
-
timestamp: number(),
|
|
60250
|
-
seq: number()
|
|
60613
|
+
timestamp: number().meta(readingMeta("none")),
|
|
60614
|
+
seq: number().meta(readingMeta("count"))
|
|
60251
60615
|
});
|
|
60252
60616
|
var EventEmitterStatusSchema = object({
|
|
60253
60617
|
eventTypes: array(string()),
|
|
60254
60618
|
lastEvent: EventFireSchema.nullable(),
|
|
60255
|
-
eventCountSinceStart: number()
|
|
60619
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
60256
60620
|
});
|
|
60257
60621
|
var eventEmitterCapability = {
|
|
60258
60622
|
name: "event-emitter",
|
|
@@ -60665,10 +61029,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60665
61029
|
var FanControlStatusSchema = object({
|
|
60666
61030
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60667
61031
|
* speed surface (single-speed fan). */
|
|
60668
|
-
percentage: number().min(0).max(100).nullable(),
|
|
61032
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60669
61033
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60670
61034
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60671
|
-
percentageStep: number().positive().optional(),
|
|
61035
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
60672
61036
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
60673
61037
|
* — empty string when no preset is active or supported. */
|
|
60674
61038
|
preset: string(),
|
|
@@ -60789,7 +61153,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
60789
61153
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
60790
61154
|
model: string().nullable(),
|
|
60791
61155
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
60792
|
-
channelCount: number().nullable(),
|
|
61156
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
60793
61157
|
/**
|
|
60794
61158
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
60795
61159
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -60912,9 +61276,91 @@ var gasCapability = {
|
|
|
60912
61276
|
* whether persisting is worth a SQLite commit. */
|
|
60913
61277
|
volatileStateFields: ["lastChangedAt"]
|
|
60914
61278
|
};
|
|
61279
|
+
var GroupCommandsSchema = object({
|
|
61280
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
61281
|
+
results: array(object({
|
|
61282
|
+
deviceId: number().int().nonnegative(),
|
|
61283
|
+
cap: string().min(1),
|
|
61284
|
+
method: string().min(1),
|
|
61285
|
+
ok: boolean(),
|
|
61286
|
+
error: string().optional(),
|
|
61287
|
+
/** Ms epoch of the attempt. */
|
|
61288
|
+
at: number()
|
|
61289
|
+
})) });
|
|
61290
|
+
var groupCommandsCapability = {
|
|
61291
|
+
name: "group-commands",
|
|
61292
|
+
scope: "device",
|
|
61293
|
+
deviceNative: true,
|
|
61294
|
+
mode: "singleton",
|
|
61295
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
61296
|
+
methods: {},
|
|
61297
|
+
status: {
|
|
61298
|
+
schema: GroupCommandsSchema,
|
|
61299
|
+
kind: "push"
|
|
61300
|
+
},
|
|
61301
|
+
runtimeState: GroupCommandsSchema,
|
|
61302
|
+
/**
|
|
61303
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
61304
|
+
* failure would outlive the command that caused it.
|
|
61305
|
+
*
|
|
61306
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61307
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61308
|
+
*/
|
|
61309
|
+
durability: "session",
|
|
61310
|
+
history: "none"
|
|
61311
|
+
};
|
|
61312
|
+
/**
|
|
61313
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
61314
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
61315
|
+
* The reading itself stays on the output capability. History is none — the
|
|
61316
|
+
* series that later statistics read is the output cap's own history block.
|
|
61317
|
+
*/
|
|
61318
|
+
var GroupStatusSchema = object({
|
|
61319
|
+
/** Members whose current value entered the aggregate. */
|
|
61320
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
61321
|
+
precision: 0,
|
|
61322
|
+
label: "Reporting"
|
|
61323
|
+
})),
|
|
61324
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
61325
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
61326
|
+
precision: 0,
|
|
61327
|
+
label: "Excluded"
|
|
61328
|
+
})),
|
|
61329
|
+
/** `included` + `excluded`. */
|
|
61330
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
61331
|
+
precision: 0,
|
|
61332
|
+
label: "Members"
|
|
61333
|
+
}))
|
|
61334
|
+
});
|
|
61335
|
+
var groupStatusCapability = {
|
|
61336
|
+
name: "group-status",
|
|
61337
|
+
scope: "device",
|
|
61338
|
+
deviceNative: true,
|
|
61339
|
+
mode: "singleton",
|
|
61340
|
+
deviceTypes: [
|
|
61341
|
+
DeviceType.Sensor,
|
|
61342
|
+
DeviceType.Switch,
|
|
61343
|
+
DeviceType.Light
|
|
61344
|
+
],
|
|
61345
|
+
methods: {},
|
|
61346
|
+
status: {
|
|
61347
|
+
schema: GroupStatusSchema,
|
|
61348
|
+
kind: "push"
|
|
61349
|
+
},
|
|
61350
|
+
runtimeState: GroupStatusSchema,
|
|
61351
|
+
/**
|
|
61352
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
61353
|
+
* next source event; a restored count would outlive the readings it named.
|
|
61354
|
+
*
|
|
61355
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
61356
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
61357
|
+
*/
|
|
61358
|
+
durability: "session",
|
|
61359
|
+
history: "none"
|
|
61360
|
+
};
|
|
60915
61361
|
var HeatingValveStatusSchema = object({
|
|
60916
61362
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60917
|
-
position: number().min(0).max(100).nullable(),
|
|
61363
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60918
61364
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
60919
61365
|
lastFetchedAt: number()
|
|
60920
61366
|
});
|
|
@@ -60957,9 +61403,9 @@ var HumidifierStatusSchema = object({
|
|
|
60957
61403
|
/** Whether the humidifier is currently on. */
|
|
60958
61404
|
on: boolean(),
|
|
60959
61405
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60960
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
61406
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60961
61407
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60962
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
61408
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60963
61409
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60964
61410
|
* device has no mode surface. */
|
|
60965
61411
|
mode: string().nullable(),
|
|
@@ -60969,9 +61415,9 @@ var HumidifierStatusSchema = object({
|
|
|
60969
61415
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60970
61416
|
action: string().nullable(),
|
|
60971
61417
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60972
|
-
minHumidity: number().nullable(),
|
|
61418
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60973
61419
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60974
|
-
maxHumidity: number().nullable(),
|
|
61420
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60975
61421
|
/** Ms epoch when the slice was last updated. */
|
|
60976
61422
|
lastChangedAt: number()
|
|
60977
61423
|
});
|
|
@@ -61041,22 +61487,13 @@ var humidifierCapability = {
|
|
|
61041
61487
|
* `sourceInfo`.
|
|
61042
61488
|
*/
|
|
61043
61489
|
var HumiditySensorStatusSchema = object({
|
|
61044
|
-
/** Current relative humidity, 0..100. */
|
|
61045
|
-
percent: number().min(0).max(100).meta({
|
|
61046
|
-
|
|
61490
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61491
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61492
|
+
precision: 0,
|
|
61047
61493
|
label: "Humidity"
|
|
61048
|
-
}),
|
|
61494
|
+
})),
|
|
61049
61495
|
/** Ms epoch when the slice was last updated. */
|
|
61050
|
-
lastFetchedAt: number()
|
|
61051
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61052
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61053
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61054
|
-
unit: string().optional(),
|
|
61055
|
-
/** Suggested decimal places for numeric display.
|
|
61056
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61057
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61058
|
-
* auto-formatting when absent. */
|
|
61059
|
-
precision: number().int().min(0).max(10).optional()
|
|
61496
|
+
lastFetchedAt: number()
|
|
61060
61497
|
});
|
|
61061
61498
|
var humiditySensorCapability = {
|
|
61062
61499
|
name: "humidity-sensor",
|
|
@@ -61087,12 +61524,7 @@ var humiditySensorCapability = {
|
|
|
61087
61524
|
} } },
|
|
61088
61525
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61089
61526
|
* whether persisting is worth a SQLite commit. */
|
|
61090
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
61091
|
-
customize: {
|
|
61092
|
-
version: 1,
|
|
61093
|
-
advanced: "derive",
|
|
61094
|
-
targets: []
|
|
61095
|
-
}
|
|
61527
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
61096
61528
|
};
|
|
61097
61529
|
/**
|
|
61098
61530
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -61113,7 +61545,7 @@ var ImageStatusSchema = object({
|
|
|
61113
61545
|
* entity exposes no `entity_picture` (yet). */
|
|
61114
61546
|
url: string().nullable(),
|
|
61115
61547
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
61116
|
-
lastUpdated: number().nullable()
|
|
61548
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
61117
61549
|
});
|
|
61118
61550
|
var imageCapability = {
|
|
61119
61551
|
name: "image",
|
|
@@ -61201,19 +61633,19 @@ var NormalizedRangeSchema = object({
|
|
|
61201
61633
|
*/
|
|
61202
61634
|
var ImageSettingsStatusSchema = object({
|
|
61203
61635
|
/** Normalized 0–100. */
|
|
61204
|
-
brightness: number().optional(),
|
|
61636
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
61205
61637
|
/** Normalized 0–100. */
|
|
61206
|
-
contrast: number().optional(),
|
|
61638
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
61207
61639
|
/** Normalized 0–100. */
|
|
61208
|
-
saturation: number().optional(),
|
|
61640
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
61209
61641
|
/** Normalized 0–100. */
|
|
61210
|
-
sharpness: number().optional(),
|
|
61642
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
61211
61643
|
mirror: boolean().optional(),
|
|
61212
61644
|
flip: boolean().optional(),
|
|
61213
61645
|
rotate: ImageRotateSchema.optional(),
|
|
61214
61646
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
61215
61647
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
61216
|
-
warmth: number().optional(),
|
|
61648
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
61217
61649
|
exposureMode: ExposureModeSchema.optional(),
|
|
61218
61650
|
backlightMode: BacklightModeSchema.optional(),
|
|
61219
61651
|
lastFetchedAt: number()
|
|
@@ -61492,10 +61924,10 @@ var IntercomAbilitySchema = object({
|
|
|
61492
61924
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
61493
61925
|
codecs: array(string()),
|
|
61494
61926
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
61495
|
-
sampleRate: number(),
|
|
61927
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
61496
61928
|
duplex: _enum(["half", "full"]),
|
|
61497
61929
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
61498
|
-
maxBacklogMs: number()
|
|
61930
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
61499
61931
|
});
|
|
61500
61932
|
var IntercomStatusSchema = object({
|
|
61501
61933
|
/** True while a talk session is open. */
|
|
@@ -61722,13 +62154,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61722
62154
|
activity: LawnMowerActivitySchema,
|
|
61723
62155
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
61724
62156
|
* reading. */
|
|
61725
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
62157
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61726
62158
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61727
62159
|
* task is active / progress is unavailable. */
|
|
61728
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
62160
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61729
62161
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61730
62162
|
* or null when unknown. */
|
|
61731
|
-
currentCode: number().nullable(),
|
|
62163
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
61732
62164
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
61733
62165
|
currentCodeLabel: string().nullable(),
|
|
61734
62166
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -62261,7 +62693,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
62261
62693
|
state: MediaPlayerStateSchema,
|
|
62262
62694
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
62263
62695
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
62264
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
62696
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62265
62697
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
62266
62698
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
62267
62699
|
isMuted: boolean().nullable(),
|
|
@@ -62274,10 +62706,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62274
62706
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62275
62707
|
/** Current playback position in ms. Null when not seekable or
|
|
62276
62708
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62277
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
62709
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62278
62710
|
/** Total duration of the current media in ms. Null when unknown
|
|
62279
62711
|
* (live stream) or nothing is playing. */
|
|
62280
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
62712
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62281
62713
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62282
62714
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62283
62715
|
shuffle: boolean().nullable(),
|
|
@@ -62586,7 +63018,7 @@ var motionCustomize = {
|
|
|
62586
63018
|
eventName: "onMotionChanged"
|
|
62587
63019
|
},
|
|
62588
63020
|
deviceTypes: [DeviceType.Camera],
|
|
62589
|
-
apply: "
|
|
63021
|
+
apply: "add",
|
|
62590
63022
|
applyAuthority: {
|
|
62591
63023
|
kind: "camera-sensors",
|
|
62592
63024
|
timeoutField: "motionCooldownMs"
|
|
@@ -62658,7 +63090,7 @@ var MotionStatusSchema = object({
|
|
|
62658
63090
|
* it, every provider seeded it at boot, and every session left it
|
|
62659
63091
|
* `detected: true` after its detach.
|
|
62660
63092
|
*/
|
|
62661
|
-
autoClearAfterMs: number().nullable()
|
|
63093
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
62662
63094
|
});
|
|
62663
63095
|
/**
|
|
62664
63096
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -62695,12 +63127,18 @@ var motionCapability = {
|
|
|
62695
63127
|
methods: {
|
|
62696
63128
|
/**
|
|
62697
63129
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62698
|
-
* for consumers that don't need the full status object
|
|
62699
|
-
*
|
|
62700
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62701
|
-
* consumer.
|
|
63130
|
+
* for consumers that don't need the full status object. A composed
|
|
63131
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
62702
63132
|
*/
|
|
62703
63133
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
63134
|
+
/**
|
|
63135
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
63136
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
63137
|
+
*/
|
|
63138
|
+
composedMethods: { isDetected: {
|
|
63139
|
+
kind: "slice",
|
|
63140
|
+
field: "detected"
|
|
63141
|
+
} },
|
|
62704
63142
|
events: {
|
|
62705
63143
|
/**
|
|
62706
63144
|
* Fires every time the runner transitions a camera between
|
|
@@ -62840,7 +63278,7 @@ var MotionZoneRegionSchema = object({
|
|
|
62840
63278
|
* the grid region(s). */
|
|
62841
63279
|
var MotionZoneStatusSchema = object({
|
|
62842
63280
|
enabled: boolean(),
|
|
62843
|
-
sensitivity: number(),
|
|
63281
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
62844
63282
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
62845
63283
|
regions: array(MotionZoneRegionSchema),
|
|
62846
63284
|
lastFetchedAt: number()
|
|
@@ -63210,7 +63648,7 @@ var NavigationStatusSchema = object({
|
|
|
63210
63648
|
following: boolean(),
|
|
63211
63649
|
flash: boolean(),
|
|
63212
63650
|
lightMode: NavigationLightModeSchema,
|
|
63213
|
-
lightLevel: number().min(40).max(100),
|
|
63651
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
63214
63652
|
/** Ms epoch when the slice was last updated. */
|
|
63215
63653
|
lastChangedAt: number()
|
|
63216
63654
|
});
|
|
@@ -63344,13 +63782,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
63344
63782
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63345
63783
|
* SKIP a null rather than coerce it.
|
|
63346
63784
|
*/
|
|
63347
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
63785
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63348
63786
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63349
|
-
rssiDbm: number().optional(),
|
|
63787
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
63350
63788
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63351
63789
|
ssid: string().optional(),
|
|
63352
63790
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
63353
|
-
lastUpdated: number()
|
|
63791
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
63354
63792
|
});
|
|
63355
63793
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
63356
63794
|
var NETWORK_LINK_UNKNOWN = {
|
|
@@ -63755,7 +64193,7 @@ var NotifierStatusSchema = object({
|
|
|
63755
64193
|
lastError: string().nullable(),
|
|
63756
64194
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
63757
64195
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
63758
|
-
queueDepth: number().int().nonnegative(),
|
|
64196
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
63759
64197
|
/** Per-feature capability matrix — authoritative source for the
|
|
63760
64198
|
* compose-form field gating. */
|
|
63761
64199
|
supports: NotifierSupportsSchema
|
|
@@ -63847,11 +64285,9 @@ onSent: { data: object({
|
|
|
63847
64285
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
63848
64286
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
63849
64287
|
*
|
|
63850
|
-
* The
|
|
63851
|
-
*
|
|
63852
|
-
*
|
|
63853
|
-
* The UI reads them directly from the slice — they are the single source
|
|
63854
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
64288
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
64289
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
64290
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
63855
64291
|
*
|
|
63856
64292
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
63857
64293
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -63860,15 +64296,8 @@ onSent: { data: object({
|
|
|
63860
64296
|
* numeric values land here.
|
|
63861
64297
|
*/
|
|
63862
64298
|
var NumericSensorStatusSchema = object({
|
|
63863
|
-
|
|
63864
|
-
|
|
63865
|
-
* Populated live from the upstream source on each state push.
|
|
63866
|
-
* Absent for unitless sensors. */
|
|
63867
|
-
unit: string().optional(),
|
|
63868
|
-
/** Suggested decimal places for numeric display.
|
|
63869
|
-
* Populated live from the upstream source when provided.
|
|
63870
|
-
* Falls back to auto-formatting when absent. */
|
|
63871
|
-
precision: number().int().min(0).max(10).optional(),
|
|
64299
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
64300
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
63872
64301
|
/** Ms epoch when the slice was last updated. */
|
|
63873
64302
|
lastFetchedAt: number()
|
|
63874
64303
|
});
|
|
@@ -63892,11 +64321,11 @@ var numericSensorCapability = {
|
|
|
63892
64321
|
*/
|
|
63893
64322
|
durability: "restored",
|
|
63894
64323
|
/**
|
|
63895
|
-
* History (D850): recorded series. The unit is
|
|
64324
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
64325
|
+
* resolved when the series is read — the cap has no single unit.
|
|
63896
64326
|
*/
|
|
63897
64327
|
history: { fields: { value: {
|
|
63898
64328
|
kind: "gauge",
|
|
63899
|
-
unitFrom: "unit",
|
|
63900
64329
|
minIntervalMs: 3e4
|
|
63901
64330
|
} } },
|
|
63902
64331
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -64234,23 +64663,26 @@ var PetFeederStatusSchema = object({
|
|
|
64234
64663
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
64235
64664
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
64236
64665
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
64237
|
-
foodLevel: number().nullable(),
|
|
64666
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64238
64667
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64239
64668
|
* single-hopper models. */
|
|
64240
|
-
food1: number().nullable(),
|
|
64669
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
64241
64670
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
64242
64671
|
* single-hopper models. */
|
|
64243
|
-
food2: number().nullable(),
|
|
64672
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
64244
64673
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64245
64674
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
64246
64675
|
* below the feeder's low threshold. */
|
|
64247
64676
|
lowFood: boolean(),
|
|
64248
64677
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
64249
64678
|
* device has no battery reading. */
|
|
64250
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
64251
|
-
/**
|
|
64252
|
-
*
|
|
64253
|
-
|
|
64679
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64680
|
+
/**
|
|
64681
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
64682
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
64683
|
+
* model has no desiccant sensor.
|
|
64684
|
+
*/
|
|
64685
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
64254
64686
|
/** True while a feed is in progress. */
|
|
64255
64687
|
feeding: boolean(),
|
|
64256
64688
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -64261,7 +64693,7 @@ var PetFeederStatusSchema = object({
|
|
|
64261
64693
|
* with `errorCode` for consumers that want the raw integer. */
|
|
64262
64694
|
error: string().nullable(),
|
|
64263
64695
|
/** Raw device error code (0 / null = no error). */
|
|
64264
|
-
errorCode: number().nullable(),
|
|
64696
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64265
64697
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
64266
64698
|
isDualHopper: boolean(),
|
|
64267
64699
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -64271,7 +64703,7 @@ var PetFeederStatusSchema = object({
|
|
|
64271
64703
|
/** Play a chime when dispensing. */
|
|
64272
64704
|
feedSound: boolean(),
|
|
64273
64705
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
64274
|
-
volume: number(),
|
|
64706
|
+
volume: number().meta(readingMeta("none")),
|
|
64275
64707
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
64276
64708
|
lastFetchedAt: number()
|
|
64277
64709
|
});
|
|
@@ -64390,7 +64822,7 @@ var petFeederCapability = {
|
|
|
64390
64822
|
},
|
|
64391
64823
|
desiccantLeftDays: {
|
|
64392
64824
|
kind: "gauge",
|
|
64393
|
-
unit: "
|
|
64825
|
+
unit: "s"
|
|
64394
64826
|
}
|
|
64395
64827
|
} }
|
|
64396
64828
|
};
|
|
@@ -64791,36 +65223,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64791
65223
|
*/
|
|
64792
65224
|
var PowerMeterStatusSchema = object({
|
|
64793
65225
|
/** Instantaneous power draw in watts. */
|
|
64794
|
-
watts: number().optional().meta({
|
|
64795
|
-
unit: "W",
|
|
64796
|
-
label: "Power"
|
|
64797
|
-
}),
|
|
65226
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64798
65227
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64799
|
-
kwhTotal: number().optional().meta({
|
|
64800
|
-
unit: "kWh",
|
|
64801
|
-
label: "Energy"
|
|
64802
|
-
}),
|
|
65228
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64803
65229
|
/** Voltage in volts. */
|
|
64804
|
-
volts: number().optional(),
|
|
65230
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
64805
65231
|
/** Current in amperes. */
|
|
64806
|
-
amps: number().optional(),
|
|
64807
|
-
/** Apparent power in volt-amperes
|
|
64808
|
-
va: number().optional(),
|
|
65232
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
65233
|
+
/** Apparent power in volt-amperes. */
|
|
65234
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64809
65235
|
/** Power factor (0..1) if reported. */
|
|
64810
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
65236
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64811
65237
|
/** Ms epoch when the slice was last updated. */
|
|
64812
|
-
lastFetchedAt: number()
|
|
64813
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
64814
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
64815
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
64816
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
64817
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
64818
|
-
unit: string().optional(),
|
|
64819
|
-
/** Suggested decimal places for numeric display.
|
|
64820
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64821
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64822
|
-
* auto-formatting when absent. */
|
|
64823
|
-
precision: number().int().min(0).max(10).optional()
|
|
65238
|
+
lastFetchedAt: number()
|
|
64824
65239
|
});
|
|
64825
65240
|
var powerMeterCapability = {
|
|
64826
65241
|
name: "power-meter",
|
|
@@ -64884,12 +65299,7 @@ var powerMeterCapability = {
|
|
|
64884
65299
|
} },
|
|
64885
65300
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64886
65301
|
* whether persisting is worth a SQLite commit. */
|
|
64887
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64888
|
-
customize: {
|
|
64889
|
-
version: 1,
|
|
64890
|
-
advanced: "derive",
|
|
64891
|
-
targets: []
|
|
64892
|
-
}
|
|
65302
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64893
65303
|
};
|
|
64894
65304
|
/**
|
|
64895
65305
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64909,11 +65319,11 @@ var powerMeterCapability = {
|
|
|
64909
65319
|
*/
|
|
64910
65320
|
var GpsLocationSchema = object({
|
|
64911
65321
|
/** Latitude in decimal degrees, -90..90. */
|
|
64912
|
-
latitude: number().min(-90).max(90),
|
|
65322
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
64913
65323
|
/** Longitude in decimal degrees, -180..180. */
|
|
64914
|
-
longitude: number().min(-180).max(180),
|
|
65324
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
64915
65325
|
/** Reported accuracy in meters (lower = better). */
|
|
64916
|
-
accuracyMeters: number().nonnegative()
|
|
65326
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
64917
65327
|
});
|
|
64918
65328
|
var PresenceStatusSchema = object({
|
|
64919
65329
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -64925,7 +65335,7 @@ var PresenceStatusSchema = object({
|
|
|
64925
65335
|
gps: GpsLocationSchema.nullable(),
|
|
64926
65336
|
/** Optional battery level of the tracking device (0..100). Null
|
|
64927
65337
|
* when not reported. */
|
|
64928
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
65338
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64929
65339
|
/** Ms epoch when the slice was last updated. */
|
|
64930
65340
|
lastChangedAt: number()
|
|
64931
65341
|
});
|
|
@@ -64975,19 +65385,10 @@ var presenceCapability = {
|
|
|
64975
65385
|
* `sourceInfo`.
|
|
64976
65386
|
*/
|
|
64977
65387
|
var PressureSensorStatusSchema = object({
|
|
64978
|
-
/** Current pressure in hPa. */
|
|
64979
|
-
hpa: number(),
|
|
65388
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65389
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64980
65390
|
/** Ms epoch when the slice was last updated. */
|
|
64981
|
-
lastFetchedAt: number()
|
|
64982
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64983
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64984
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64985
|
-
unit: string().optional(),
|
|
64986
|
-
/** Suggested decimal places for numeric display.
|
|
64987
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64988
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64989
|
-
* auto-formatting when absent. */
|
|
64990
|
-
precision: number().int().min(0).max(10).optional()
|
|
65391
|
+
lastFetchedAt: number()
|
|
64991
65392
|
});
|
|
64992
65393
|
var pressureSensorCapability = {
|
|
64993
65394
|
name: "pressure-sensor",
|
|
@@ -65513,8 +65914,8 @@ var ptzCapability = {
|
|
|
65513
65914
|
};
|
|
65514
65915
|
var PtzAutotrackSettingsSchema = object({
|
|
65515
65916
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
65516
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
65517
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
65917
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
65918
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
65518
65919
|
});
|
|
65519
65920
|
/**
|
|
65520
65921
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -65668,7 +66069,7 @@ var RunningStateStatusSchema = object({
|
|
|
65668
66069
|
/** null = unknown — never coerced to false (D393). */
|
|
65669
66070
|
running: boolean().nullable(),
|
|
65670
66071
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
65671
|
-
since: number().nullable(),
|
|
66072
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
65672
66073
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
65673
66074
|
phase: string().nullable(),
|
|
65674
66075
|
/** null until a reading has been published (D393). */
|
|
@@ -65683,7 +66084,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
65683
66084
|
/** Generic Customize target for the running boolean (D936). */
|
|
65684
66085
|
var runningCustomize = {
|
|
65685
66086
|
version: 1,
|
|
65686
|
-
advanced: "derive",
|
|
65687
66087
|
targets: [{
|
|
65688
66088
|
id: "running",
|
|
65689
66089
|
cardinality: "scalar",
|
|
@@ -65703,7 +66103,7 @@ var runningCustomize = {
|
|
|
65703
66103
|
DeviceType.Thermostat,
|
|
65704
66104
|
DeviceType.PetFeeder
|
|
65705
66105
|
],
|
|
65706
|
-
apply: "add
|
|
66106
|
+
apply: "add",
|
|
65707
66107
|
path: "running",
|
|
65708
66108
|
sources: [
|
|
65709
66109
|
{
|
|
@@ -65719,6 +66119,7 @@ var runningCustomize = {
|
|
|
65719
66119
|
requiredUnit: "W",
|
|
65720
66120
|
transforms: [{
|
|
65721
66121
|
kind: "threshold",
|
|
66122
|
+
comparisons: ["gte", "lte"],
|
|
65722
66123
|
comparison: "gte",
|
|
65723
66124
|
defaultThreshold: 5,
|
|
65724
66125
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -66995,9 +67396,9 @@ var RecordTriggerSchema = _enum([
|
|
|
66995
67396
|
*/
|
|
66996
67397
|
var RecordWindowSchema = object({
|
|
66997
67398
|
trigger: RecordTriggerSchema,
|
|
66998
|
-
day: number().int().min(0).max(6),
|
|
66999
|
-
startMinute: number().int().min(0).max(1439),
|
|
67000
|
-
endMinute: number().int().min(1).max(1440)
|
|
67399
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
67400
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
67401
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
67001
67402
|
});
|
|
67002
67403
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
67003
67404
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -67073,10 +67474,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
67073
67474
|
/** Master "record to the card at all" switch. */
|
|
67074
67475
|
enabled: boolean().nullable(),
|
|
67075
67476
|
overwriteWhenFull: boolean().nullable(),
|
|
67076
|
-
preRecordSec: number().nullable(),
|
|
67077
|
-
postRecordSec: number().nullable(),
|
|
67477
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
67478
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
67078
67479
|
/** Length of one recorded file, in minutes. */
|
|
67079
|
-
segmentMinutes: number().nullable(),
|
|
67480
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
67080
67481
|
/** The primary track's weekly windows, flattened. */
|
|
67081
67482
|
windows: array(RecordWindowSchema),
|
|
67082
67483
|
/**
|
|
@@ -67092,7 +67493,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
67092
67493
|
* provider reporting a non-zero count also reports the schedule as not
|
|
67093
67494
|
* writable.
|
|
67094
67495
|
*/
|
|
67095
|
-
unreadableWindows: number(),
|
|
67496
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
67096
67497
|
/**
|
|
67097
67498
|
* The camera is scheduled to record and has NO usable storage.
|
|
67098
67499
|
*
|
|
@@ -68102,7 +68503,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
68102
68503
|
url: string().optional(),
|
|
68103
68504
|
codec: string().optional(),
|
|
68104
68505
|
resolution: CamStreamResolutionSchema.optional(),
|
|
68105
|
-
fps: number().positive().optional(),
|
|
68506
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
68106
68507
|
label: string().optional(),
|
|
68107
68508
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
68108
68509
|
deviceFeatures: array(string()).optional(),
|
|
@@ -68189,18 +68590,18 @@ var StreamProfileSchema = _enum([
|
|
|
68189
68590
|
]);
|
|
68190
68591
|
/** The current encoding config of one stream profile. */
|
|
68191
68592
|
var StreamProfileConfigSchema = object({
|
|
68192
|
-
width: number(),
|
|
68193
|
-
height: number(),
|
|
68593
|
+
width: number().meta(readingMeta("none")),
|
|
68594
|
+
height: number().meta(readingMeta("none")),
|
|
68194
68595
|
codec: _enum(["h264", "h265"]),
|
|
68195
|
-
framerate: number(),
|
|
68196
|
-
bitrate: number(),
|
|
68596
|
+
framerate: number().meta(readingMeta("rate")),
|
|
68597
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
68197
68598
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
68198
68599
|
encoderProfile: _enum([
|
|
68199
68600
|
"high",
|
|
68200
68601
|
"main",
|
|
68201
68602
|
"baseline"
|
|
68202
68603
|
]).optional(),
|
|
68203
|
-
gop: number().optional(),
|
|
68604
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
68204
68605
|
/**
|
|
68205
68606
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
68206
68607
|
*
|
|
@@ -68619,12 +69020,7 @@ var switchCapability = {
|
|
|
68619
69020
|
label: "On",
|
|
68620
69021
|
kind: "boolean"
|
|
68621
69022
|
}
|
|
68622
|
-
}] }
|
|
68623
|
-
customize: {
|
|
68624
|
-
version: 1,
|
|
68625
|
-
advanced: "derive",
|
|
68626
|
-
targets: []
|
|
68627
|
-
}
|
|
69023
|
+
}] }
|
|
68628
69024
|
};
|
|
68629
69025
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
68630
69026
|
function hasControlCharacter(value) {
|
|
@@ -69207,35 +69603,21 @@ var tamperCapability = {
|
|
|
69207
69603
|
* entries with `device_class: temperature` and any future native
|
|
69208
69604
|
* thermometer.
|
|
69209
69605
|
*
|
|
69210
|
-
*
|
|
69211
|
-
*
|
|
69212
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
69213
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
69214
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
69215
|
-
* `sourceInfo`.
|
|
69606
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
69607
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
69216
69608
|
*
|
|
69217
69609
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
69218
69610
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
69219
69611
|
* changed" steady state.
|
|
69220
69612
|
*/
|
|
69221
69613
|
var TemperatureSensorStatusSchema = object({
|
|
69222
|
-
/** Current temperature in Celsius. */
|
|
69223
|
-
celsius: number().meta({
|
|
69224
|
-
|
|
69614
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69615
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
69616
|
+
precision: 1,
|
|
69225
69617
|
label: "Temperature"
|
|
69226
|
-
}),
|
|
69618
|
+
})),
|
|
69227
69619
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
69228
|
-
lastFetchedAt: number()
|
|
69229
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
69230
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
69231
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
69232
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
69233
|
-
unit: string().optional(),
|
|
69234
|
-
/** Suggested decimal places for numeric display.
|
|
69235
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
69236
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
69237
|
-
* auto-formatting when absent. */
|
|
69238
|
-
precision: number().int().min(0).max(10).optional()
|
|
69620
|
+
lastFetchedAt: number()
|
|
69239
69621
|
});
|
|
69240
69622
|
var temperatureSensorCapability = {
|
|
69241
69623
|
name: "temperature-sensor",
|
|
@@ -69266,12 +69648,7 @@ var temperatureSensorCapability = {
|
|
|
69266
69648
|
} } },
|
|
69267
69649
|
/** Clock fields: written, but excluded from the compare that decides
|
|
69268
69650
|
* whether persisting is worth a SQLite commit. */
|
|
69269
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
69270
|
-
customize: {
|
|
69271
|
-
version: 1,
|
|
69272
|
-
advanced: "derive",
|
|
69273
|
-
targets: []
|
|
69274
|
-
}
|
|
69651
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
69275
69652
|
};
|
|
69276
69653
|
/**
|
|
69277
69654
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -69554,16 +69931,16 @@ var VacuumControlStatusSchema = object({
|
|
|
69554
69931
|
]),
|
|
69555
69932
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
69556
69933
|
* reading. */
|
|
69557
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
69934
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69558
69935
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
69559
69936
|
* the vacuum has no speed control. */
|
|
69560
69937
|
fanSpeed: string().nullable(),
|
|
69561
69938
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69562
69939
|
availableFanSpeeds: array(string()),
|
|
69563
69940
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69564
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
69941
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69565
69942
|
/** Current error code (0 / null = no error). */
|
|
69566
|
-
errorCode: number().nullable(),
|
|
69943
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69567
69944
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
69568
69945
|
errorLabel: string().nullable(),
|
|
69569
69946
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -69641,7 +70018,7 @@ var ValveStatusSchema = object({
|
|
|
69641
70018
|
]),
|
|
69642
70019
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
69643
70020
|
* intermediate position surface. */
|
|
69644
|
-
position: number().min(0).max(100).nullable(),
|
|
70021
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69645
70022
|
/** Ms epoch when the slice was last updated. */
|
|
69646
70023
|
lastChangedAt: number()
|
|
69647
70024
|
});
|
|
@@ -69749,9 +70126,9 @@ var vibrationCapability = {
|
|
|
69749
70126
|
*/
|
|
69750
70127
|
var WaterHeaterStatusSchema = object({
|
|
69751
70128
|
/** Current measured temperature. Null when not reported. */
|
|
69752
|
-
currentTemp: number().nullable(),
|
|
70129
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69753
70130
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
69754
|
-
targetTemp: number().nullable(),
|
|
70131
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69755
70132
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
69756
70133
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
69757
70134
|
* device reports an unknown state. */
|
|
@@ -69762,9 +70139,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
69762
70139
|
* has no away surface. */
|
|
69763
70140
|
away: boolean().nullable(),
|
|
69764
70141
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
69765
|
-
minTemp: number().nullable(),
|
|
70142
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69766
70143
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
69767
|
-
maxTemp: number().nullable(),
|
|
70144
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69768
70145
|
/** Ms epoch when the slice was last updated. */
|
|
69769
70146
|
lastChangedAt: number()
|
|
69770
70147
|
});
|
|
@@ -69849,25 +70226,18 @@ var waterHeaterCapability = {
|
|
|
69849
70226
|
* Forecast deferred — current conditions only for v1.
|
|
69850
70227
|
*/
|
|
69851
70228
|
var WeatherStatusSchema = object({
|
|
69852
|
-
/** Verbatim
|
|
69853
|
-
* when no condition has been reported yet. */
|
|
70229
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
69854
70230
|
condition: string().nullable(),
|
|
69855
|
-
/** Current temperature in
|
|
69856
|
-
temperature: number().nullable(),
|
|
69857
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
69858
|
-
temperatureUnit: string().nullable(),
|
|
70231
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
70232
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
69859
70233
|
/** Relative humidity (0..100). Null when not provided. */
|
|
69860
|
-
humidity: number().min(0).max(100).nullable(),
|
|
69861
|
-
/** Barometric pressure in
|
|
69862
|
-
pressure: number().nullable(),
|
|
69863
|
-
/**
|
|
69864
|
-
|
|
69865
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
69866
|
-
windSpeed: number().nullable(),
|
|
69867
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
69868
|
-
windSpeedUnit: string().nullable(),
|
|
70234
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
70235
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
70236
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
70237
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
70238
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
69869
70239
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
69870
|
-
windBearing: number().nullable(),
|
|
70240
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
69871
70241
|
/** Ms epoch when the slice was last updated. */
|
|
69872
70242
|
lastFetchedAt: number()
|
|
69873
70243
|
});
|
|
@@ -69895,12 +70265,12 @@ var weatherCapability = {
|
|
|
69895
70265
|
*/
|
|
69896
70266
|
durability: "session",
|
|
69897
70267
|
/**
|
|
69898
|
-
* History (D850): recorded series.
|
|
70268
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
69899
70269
|
*/
|
|
69900
70270
|
history: { fields: {
|
|
69901
70271
|
temperature: {
|
|
69902
70272
|
kind: "gauge",
|
|
69903
|
-
|
|
70273
|
+
unit: "°C",
|
|
69904
70274
|
deadband: .2
|
|
69905
70275
|
},
|
|
69906
70276
|
humidity: {
|
|
@@ -69910,12 +70280,12 @@ var weatherCapability = {
|
|
|
69910
70280
|
},
|
|
69911
70281
|
pressure: {
|
|
69912
70282
|
kind: "gauge",
|
|
69913
|
-
|
|
70283
|
+
unit: "hPa",
|
|
69914
70284
|
deadband: .5
|
|
69915
70285
|
},
|
|
69916
70286
|
windSpeed: {
|
|
69917
70287
|
kind: "gauge",
|
|
69918
|
-
|
|
70288
|
+
unit: "m/s",
|
|
69919
70289
|
deadband: .5
|
|
69920
70290
|
}
|
|
69921
70291
|
} }
|
|
@@ -71294,6 +71664,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71294
71664
|
featureProbe: featureProbeCapability,
|
|
71295
71665
|
flood: floodCapability,
|
|
71296
71666
|
gas: gasCapability,
|
|
71667
|
+
groupCommands: groupCommandsCapability,
|
|
71668
|
+
groupStatus: groupStatusCapability,
|
|
71297
71669
|
heatingValve: heatingValveCapability,
|
|
71298
71670
|
humidifier: humidifierCapability,
|
|
71299
71671
|
humiditySensor: humiditySensorCapability,
|
|
@@ -72670,6 +73042,13 @@ Object.freeze({
|
|
|
72670
73042
|
access: "view",
|
|
72671
73043
|
role: "admin"
|
|
72672
73044
|
},
|
|
73045
|
+
"addons.getPackageDocs": {
|
|
73046
|
+
capName: "addons",
|
|
73047
|
+
capScope: "system",
|
|
73048
|
+
addonId: null,
|
|
73049
|
+
access: "view",
|
|
73050
|
+
role: "admin"
|
|
73051
|
+
},
|
|
72673
73052
|
"addons.getVersions": {
|
|
72674
73053
|
capName: "addons",
|
|
72675
73054
|
capScope: "system",
|
|
@@ -75778,6 +76157,20 @@ Object.freeze({
|
|
|
75778
76157
|
access: "view",
|
|
75779
76158
|
role: "viewer"
|
|
75780
76159
|
},
|
|
76160
|
+
"groupCommands.getStatus": {
|
|
76161
|
+
capName: "group-commands",
|
|
76162
|
+
capScope: "device",
|
|
76163
|
+
addonId: null,
|
|
76164
|
+
access: "view",
|
|
76165
|
+
role: "viewer"
|
|
76166
|
+
},
|
|
76167
|
+
"groupStatus.getStatus": {
|
|
76168
|
+
capName: "group-status",
|
|
76169
|
+
capScope: "device",
|
|
76170
|
+
addonId: null,
|
|
76171
|
+
access: "view",
|
|
76172
|
+
role: "viewer"
|
|
76173
|
+
},
|
|
75781
76174
|
"heatingValve.getStatus": {
|
|
75782
76175
|
capName: "heating-valve",
|
|
75783
76176
|
capScope: "device",
|
|
@@ -85600,6 +85993,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85600
85993
|
icon: "flame"
|
|
85601
85994
|
}]
|
|
85602
85995
|
},
|
|
85996
|
+
"group-commands": {
|
|
85997
|
+
scope: "device",
|
|
85998
|
+
noun: t("Group command", "Comando di gruppo")
|
|
85999
|
+
},
|
|
86000
|
+
"group-status": {
|
|
86001
|
+
scope: "device",
|
|
86002
|
+
noun: t("Group", "Gruppo"),
|
|
86003
|
+
state: [
|
|
86004
|
+
{
|
|
86005
|
+
kind: "numeric",
|
|
86006
|
+
field: "included",
|
|
86007
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
86008
|
+
label: t("Reporting", "Rispondono"),
|
|
86009
|
+
icon: "users"
|
|
86010
|
+
},
|
|
86011
|
+
{
|
|
86012
|
+
kind: "numeric",
|
|
86013
|
+
field: "excluded",
|
|
86014
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
86015
|
+
label: t("Excluded", "Esclusi"),
|
|
86016
|
+
icon: "users"
|
|
86017
|
+
},
|
|
86018
|
+
{
|
|
86019
|
+
kind: "numeric",
|
|
86020
|
+
field: "total",
|
|
86021
|
+
quantity: t("the member count", "il numero di membri"),
|
|
86022
|
+
label: t("Members", "Membri"),
|
|
86023
|
+
icon: "sigma"
|
|
86024
|
+
}
|
|
86025
|
+
]
|
|
86026
|
+
},
|
|
85603
86027
|
"humidity-sensor": {
|
|
85604
86028
|
scope: "device",
|
|
85605
86029
|
noun: t("Humidity", "Umidità"),
|
|
@@ -85633,7 +86057,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85633
86057
|
field: "value",
|
|
85634
86058
|
quantity: t("the reading", "il valore"),
|
|
85635
86059
|
label: t("Reading", "Valore"),
|
|
85636
|
-
unitField: "unit",
|
|
85637
86060
|
icon: "gauge"
|
|
85638
86061
|
}]
|
|
85639
86062
|
},
|
|
@@ -85769,7 +86192,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85769
86192
|
field: "temperature",
|
|
85770
86193
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
85771
86194
|
label: t("Temperature", "Temperatura"),
|
|
85772
|
-
|
|
86195
|
+
unit: "°C",
|
|
85773
86196
|
icon: "thermometer"
|
|
85774
86197
|
},
|
|
85775
86198
|
{
|
|
@@ -85785,7 +86208,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85785
86208
|
field: "windSpeed",
|
|
85786
86209
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
85787
86210
|
label: t("Wind", "Vento"),
|
|
85788
|
-
|
|
86211
|
+
unit: "m/s",
|
|
85789
86212
|
icon: "wind"
|
|
85790
86213
|
},
|
|
85791
86214
|
{
|
|
@@ -85793,7 +86216,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85793
86216
|
field: "pressure",
|
|
85794
86217
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
85795
86218
|
label: t("Pressure", "Pressione"),
|
|
85796
|
-
|
|
86219
|
+
unit: "hPa",
|
|
85797
86220
|
icon: "gauge"
|
|
85798
86221
|
}
|
|
85799
86222
|
]
|
|
@@ -87218,6 +87641,16 @@ Object.freeze({
|
|
|
87218
87641
|
form: "single",
|
|
87219
87642
|
optional: false
|
|
87220
87643
|
}],
|
|
87644
|
+
"groupCommands.getStatus": [{
|
|
87645
|
+
name: "deviceId",
|
|
87646
|
+
form: "single",
|
|
87647
|
+
optional: false
|
|
87648
|
+
}],
|
|
87649
|
+
"groupStatus.getStatus": [{
|
|
87650
|
+
name: "deviceId",
|
|
87651
|
+
form: "single",
|
|
87652
|
+
optional: false
|
|
87653
|
+
}],
|
|
87221
87654
|
"heatingValve.getStatus": [{
|
|
87222
87655
|
name: "deviceId",
|
|
87223
87656
|
form: "single",
|
|
@@ -89082,6 +89515,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
89082
89515
|
targetId: string().min(1),
|
|
89083
89516
|
enabled: boolean(),
|
|
89084
89517
|
debounceMs: number().nonnegative(),
|
|
89518
|
+
edges: array(_enum([
|
|
89519
|
+
"rising",
|
|
89520
|
+
"button",
|
|
89521
|
+
"native-event"
|
|
89522
|
+
])).min(1).optional(),
|
|
89085
89523
|
sources: array(OverrideSourceSchema).min(1)
|
|
89086
89524
|
});
|
|
89087
89525
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -89197,6 +89635,8 @@ new Map(Object.entries({
|
|
|
89197
89635
|
"detection-blind": "device-events",
|
|
89198
89636
|
"motion-noisy": "device-events",
|
|
89199
89637
|
"motion-calm": "device-events",
|
|
89638
|
+
"package-llm-silent": "device-events",
|
|
89639
|
+
"package-llm-answered": "device-events",
|
|
89200
89640
|
"recording-stalled": "device-events",
|
|
89201
89641
|
"recording-healthy": "device-events",
|
|
89202
89642
|
"recording-degraded": "device-events",
|
|
@@ -89280,6 +89720,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
89280
89720
|
label: "Motion without a subject",
|
|
89281
89721
|
kinds: ["motion-noisy", "motion-calm"]
|
|
89282
89722
|
},
|
|
89723
|
+
{
|
|
89724
|
+
id: "package-llm",
|
|
89725
|
+
family: "device-events",
|
|
89726
|
+
label: "Package confirm",
|
|
89727
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
89728
|
+
},
|
|
89283
89729
|
{
|
|
89284
89730
|
id: "recording",
|
|
89285
89731
|
family: "device-events",
|
|
@@ -89461,6 +89907,8 @@ var DEVICE_EVENTS = [
|
|
|
89461
89907
|
"detection-blind",
|
|
89462
89908
|
"motion-noisy",
|
|
89463
89909
|
"motion-calm",
|
|
89910
|
+
"package-llm-silent",
|
|
89911
|
+
"package-llm-answered",
|
|
89464
89912
|
"recording-stalled",
|
|
89465
89913
|
"recording-healthy",
|
|
89466
89914
|
"recording-degraded",
|
|
@@ -89729,6 +90177,15 @@ new Map([
|
|
|
89729
90177
|
snapshotLabel: "Cameras with constant motion now",
|
|
89730
90178
|
snapshotSection: null
|
|
89731
90179
|
},
|
|
90180
|
+
{
|
|
90181
|
+
id: "package-llm-confirm",
|
|
90182
|
+
family: "device-events",
|
|
90183
|
+
label: "Package confirm (not answering / answering again)",
|
|
90184
|
+
bad: ["package-llm-silent"],
|
|
90185
|
+
recovery: ["package-llm-answered"],
|
|
90186
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
90187
|
+
snapshotSection: null
|
|
90188
|
+
},
|
|
89732
90189
|
{
|
|
89733
90190
|
id: "recording-health",
|
|
89734
90191
|
family: "device-events",
|