@camstack/addon-provider-reolink 1.2.210 → 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 +959 -509
- package/dist/addon.mjs +959 -509
- package/package.json +4 -2
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. */
|
|
@@ -60108,7 +60482,7 @@ var DoorbellStatusSchema = object({
|
|
|
60108
60482
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
60109
60483
|
lastPressedAt: number().nullable(),
|
|
60110
60484
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
60111
|
-
pressCountSinceStart: number()
|
|
60485
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
60112
60486
|
});
|
|
60113
60487
|
var DoorbellPressEventSchema = object({
|
|
60114
60488
|
deviceId: number(),
|
|
@@ -60173,17 +60547,7 @@ onPressed: {
|
|
|
60173
60547
|
history: "none",
|
|
60174
60548
|
customize: doorbellCustomize
|
|
60175
60549
|
};
|
|
60176
|
-
|
|
60177
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
60178
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
60179
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
60180
|
-
* The option set is stable across observations; it is persisted in the
|
|
60181
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
60182
|
-
* stored in `sourceInfo`.
|
|
60183
|
-
*/
|
|
60184
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
60185
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
60186
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
60550
|
+
_enum([
|
|
60187
60551
|
"date",
|
|
60188
60552
|
"time",
|
|
60189
60553
|
"datetime"
|
|
@@ -60191,12 +60555,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
60191
60555
|
var EnumSensorStatusSchema = object({
|
|
60192
60556
|
value: string(),
|
|
60193
60557
|
/**
|
|
60194
|
-
* Set
|
|
60195
|
-
* as
|
|
60196
|
-
*
|
|
60197
|
-
* 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.
|
|
60198
60561
|
*/
|
|
60199
|
-
|
|
60562
|
+
timestamp: boolean().optional(),
|
|
60200
60563
|
/** Ms epoch when the slice was last updated. */
|
|
60201
60564
|
lastFetchedAt: number()
|
|
60202
60565
|
});
|
|
@@ -60223,11 +60586,11 @@ var enumSensorCapability = {
|
|
|
60223
60586
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
60224
60587
|
* operation state, an HVAC action). The option set is per device, so the
|
|
60225
60588
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
60226
|
-
* `
|
|
60589
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
60227
60590
|
*/
|
|
60228
60591
|
history: { fields: { value: {
|
|
60229
60592
|
kind: "enum",
|
|
60230
|
-
skipWhenSet: "
|
|
60593
|
+
skipWhenSet: "timestamp"
|
|
60231
60594
|
} } },
|
|
60232
60595
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60233
60596
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -60247,13 +60610,13 @@ var EventFireSchema = object({
|
|
|
60247
60610
|
deviceId: number(),
|
|
60248
60611
|
eventType: string(),
|
|
60249
60612
|
data: record(string(), unknown()).nullable(),
|
|
60250
|
-
timestamp: number(),
|
|
60251
|
-
seq: number()
|
|
60613
|
+
timestamp: number().meta(readingMeta("none")),
|
|
60614
|
+
seq: number().meta(readingMeta("count"))
|
|
60252
60615
|
});
|
|
60253
60616
|
var EventEmitterStatusSchema = object({
|
|
60254
60617
|
eventTypes: array(string()),
|
|
60255
60618
|
lastEvent: EventFireSchema.nullable(),
|
|
60256
|
-
eventCountSinceStart: number()
|
|
60619
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
60257
60620
|
});
|
|
60258
60621
|
var eventEmitterCapability = {
|
|
60259
60622
|
name: "event-emitter",
|
|
@@ -60666,10 +61029,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60666
61029
|
var FanControlStatusSchema = object({
|
|
60667
61030
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60668
61031
|
* speed surface (single-speed fan). */
|
|
60669
|
-
percentage: number().min(0).max(100).nullable(),
|
|
61032
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60670
61033
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60671
61034
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60672
|
-
percentageStep: number().positive().optional(),
|
|
61035
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
60673
61036
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
60674
61037
|
* — empty string when no preset is active or supported. */
|
|
60675
61038
|
preset: string(),
|
|
@@ -60790,7 +61153,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
60790
61153
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
60791
61154
|
model: string().nullable(),
|
|
60792
61155
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
60793
|
-
channelCount: number().nullable(),
|
|
61156
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
60794
61157
|
/**
|
|
60795
61158
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
60796
61159
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -60913,9 +61276,91 @@ var gasCapability = {
|
|
|
60913
61276
|
* whether persisting is worth a SQLite commit. */
|
|
60914
61277
|
volatileStateFields: ["lastChangedAt"]
|
|
60915
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
|
+
};
|
|
60916
61361
|
var HeatingValveStatusSchema = object({
|
|
60917
61362
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60918
|
-
position: number().min(0).max(100).nullable(),
|
|
61363
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60919
61364
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
60920
61365
|
lastFetchedAt: number()
|
|
60921
61366
|
});
|
|
@@ -60958,9 +61403,9 @@ var HumidifierStatusSchema = object({
|
|
|
60958
61403
|
/** Whether the humidifier is currently on. */
|
|
60959
61404
|
on: boolean(),
|
|
60960
61405
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60961
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
61406
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60962
61407
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60963
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
61408
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60964
61409
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60965
61410
|
* device has no mode surface. */
|
|
60966
61411
|
mode: string().nullable(),
|
|
@@ -60970,9 +61415,9 @@ var HumidifierStatusSchema = object({
|
|
|
60970
61415
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60971
61416
|
action: string().nullable(),
|
|
60972
61417
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60973
|
-
minHumidity: number().nullable(),
|
|
61418
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60974
61419
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60975
|
-
maxHumidity: number().nullable(),
|
|
61420
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60976
61421
|
/** Ms epoch when the slice was last updated. */
|
|
60977
61422
|
lastChangedAt: number()
|
|
60978
61423
|
});
|
|
@@ -61042,22 +61487,13 @@ var humidifierCapability = {
|
|
|
61042
61487
|
* `sourceInfo`.
|
|
61043
61488
|
*/
|
|
61044
61489
|
var HumiditySensorStatusSchema = object({
|
|
61045
|
-
/** Current relative humidity, 0..100. */
|
|
61046
|
-
percent: number().min(0).max(100).meta({
|
|
61047
|
-
|
|
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,
|
|
61048
61493
|
label: "Humidity"
|
|
61049
|
-
}),
|
|
61494
|
+
})),
|
|
61050
61495
|
/** Ms epoch when the slice was last updated. */
|
|
61051
|
-
lastFetchedAt: number()
|
|
61052
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61053
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61054
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61055
|
-
unit: string().optional(),
|
|
61056
|
-
/** Suggested decimal places for numeric display.
|
|
61057
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61058
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61059
|
-
* auto-formatting when absent. */
|
|
61060
|
-
precision: number().int().min(0).max(10).optional()
|
|
61496
|
+
lastFetchedAt: number()
|
|
61061
61497
|
});
|
|
61062
61498
|
var humiditySensorCapability = {
|
|
61063
61499
|
name: "humidity-sensor",
|
|
@@ -61088,12 +61524,7 @@ var humiditySensorCapability = {
|
|
|
61088
61524
|
} } },
|
|
61089
61525
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61090
61526
|
* whether persisting is worth a SQLite commit. */
|
|
61091
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
61092
|
-
customize: {
|
|
61093
|
-
version: 1,
|
|
61094
|
-
advanced: "derive",
|
|
61095
|
-
targets: []
|
|
61096
|
-
}
|
|
61527
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
61097
61528
|
};
|
|
61098
61529
|
/**
|
|
61099
61530
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -61114,7 +61545,7 @@ var ImageStatusSchema = object({
|
|
|
61114
61545
|
* entity exposes no `entity_picture` (yet). */
|
|
61115
61546
|
url: string().nullable(),
|
|
61116
61547
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
61117
|
-
lastUpdated: number().nullable()
|
|
61548
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
61118
61549
|
});
|
|
61119
61550
|
var imageCapability = {
|
|
61120
61551
|
name: "image",
|
|
@@ -61202,19 +61633,19 @@ var NormalizedRangeSchema = object({
|
|
|
61202
61633
|
*/
|
|
61203
61634
|
var ImageSettingsStatusSchema = object({
|
|
61204
61635
|
/** Normalized 0–100. */
|
|
61205
|
-
brightness: number().optional(),
|
|
61636
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
61206
61637
|
/** Normalized 0–100. */
|
|
61207
|
-
contrast: number().optional(),
|
|
61638
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
61208
61639
|
/** Normalized 0–100. */
|
|
61209
|
-
saturation: number().optional(),
|
|
61640
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
61210
61641
|
/** Normalized 0–100. */
|
|
61211
|
-
sharpness: number().optional(),
|
|
61642
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
61212
61643
|
mirror: boolean().optional(),
|
|
61213
61644
|
flip: boolean().optional(),
|
|
61214
61645
|
rotate: ImageRotateSchema.optional(),
|
|
61215
61646
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
61216
61647
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
61217
|
-
warmth: number().optional(),
|
|
61648
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
61218
61649
|
exposureMode: ExposureModeSchema.optional(),
|
|
61219
61650
|
backlightMode: BacklightModeSchema.optional(),
|
|
61220
61651
|
lastFetchedAt: number()
|
|
@@ -61493,10 +61924,10 @@ var IntercomAbilitySchema = object({
|
|
|
61493
61924
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
61494
61925
|
codecs: array(string()),
|
|
61495
61926
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
61496
|
-
sampleRate: number(),
|
|
61927
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
61497
61928
|
duplex: _enum(["half", "full"]),
|
|
61498
61929
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
61499
|
-
maxBacklogMs: number()
|
|
61930
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
61500
61931
|
});
|
|
61501
61932
|
var IntercomStatusSchema = object({
|
|
61502
61933
|
/** True while a talk session is open. */
|
|
@@ -61723,13 +62154,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61723
62154
|
activity: LawnMowerActivitySchema,
|
|
61724
62155
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
61725
62156
|
* reading. */
|
|
61726
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
62157
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61727
62158
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61728
62159
|
* task is active / progress is unavailable. */
|
|
61729
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
62160
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61730
62161
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61731
62162
|
* or null when unknown. */
|
|
61732
|
-
currentCode: number().nullable(),
|
|
62163
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
61733
62164
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
61734
62165
|
currentCodeLabel: string().nullable(),
|
|
61735
62166
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -62262,7 +62693,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
62262
62693
|
state: MediaPlayerStateSchema,
|
|
62263
62694
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
62264
62695
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
62265
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
62696
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62266
62697
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
62267
62698
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
62268
62699
|
isMuted: boolean().nullable(),
|
|
@@ -62275,10 +62706,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62275
62706
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62276
62707
|
/** Current playback position in ms. Null when not seekable or
|
|
62277
62708
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62278
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
62709
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62279
62710
|
/** Total duration of the current media in ms. Null when unknown
|
|
62280
62711
|
* (live stream) or nothing is playing. */
|
|
62281
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
62712
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62282
62713
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62283
62714
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62284
62715
|
shuffle: boolean().nullable(),
|
|
@@ -62587,7 +63018,7 @@ var motionCustomize = {
|
|
|
62587
63018
|
eventName: "onMotionChanged"
|
|
62588
63019
|
},
|
|
62589
63020
|
deviceTypes: [DeviceType.Camera],
|
|
62590
|
-
apply: "
|
|
63021
|
+
apply: "add",
|
|
62591
63022
|
applyAuthority: {
|
|
62592
63023
|
kind: "camera-sensors",
|
|
62593
63024
|
timeoutField: "motionCooldownMs"
|
|
@@ -62659,7 +63090,7 @@ var MotionStatusSchema = object({
|
|
|
62659
63090
|
* it, every provider seeded it at boot, and every session left it
|
|
62660
63091
|
* `detected: true` after its detach.
|
|
62661
63092
|
*/
|
|
62662
|
-
autoClearAfterMs: number().nullable()
|
|
63093
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
62663
63094
|
});
|
|
62664
63095
|
/**
|
|
62665
63096
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -62696,12 +63127,18 @@ var motionCapability = {
|
|
|
62696
63127
|
methods: {
|
|
62697
63128
|
/**
|
|
62698
63129
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62699
|
-
* for consumers that don't need the full status object
|
|
62700
|
-
*
|
|
62701
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62702
|
-
* 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.
|
|
62703
63132
|
*/
|
|
62704
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
|
+
} },
|
|
62705
63142
|
events: {
|
|
62706
63143
|
/**
|
|
62707
63144
|
* Fires every time the runner transitions a camera between
|
|
@@ -62841,7 +63278,7 @@ var MotionZoneRegionSchema = object({
|
|
|
62841
63278
|
* the grid region(s). */
|
|
62842
63279
|
var MotionZoneStatusSchema = object({
|
|
62843
63280
|
enabled: boolean(),
|
|
62844
|
-
sensitivity: number(),
|
|
63281
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
62845
63282
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
62846
63283
|
regions: array(MotionZoneRegionSchema),
|
|
62847
63284
|
lastFetchedAt: number()
|
|
@@ -63211,7 +63648,7 @@ var NavigationStatusSchema = object({
|
|
|
63211
63648
|
following: boolean(),
|
|
63212
63649
|
flash: boolean(),
|
|
63213
63650
|
lightMode: NavigationLightModeSchema,
|
|
63214
|
-
lightLevel: number().min(40).max(100),
|
|
63651
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
63215
63652
|
/** Ms epoch when the slice was last updated. */
|
|
63216
63653
|
lastChangedAt: number()
|
|
63217
63654
|
});
|
|
@@ -63345,13 +63782,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
63345
63782
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63346
63783
|
* SKIP a null rather than coerce it.
|
|
63347
63784
|
*/
|
|
63348
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
63785
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63349
63786
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63350
|
-
rssiDbm: number().optional(),
|
|
63787
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
63351
63788
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63352
63789
|
ssid: string().optional(),
|
|
63353
63790
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
63354
|
-
lastUpdated: number()
|
|
63791
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
63355
63792
|
});
|
|
63356
63793
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
63357
63794
|
var NETWORK_LINK_UNKNOWN = {
|
|
@@ -63756,7 +64193,7 @@ var NotifierStatusSchema = object({
|
|
|
63756
64193
|
lastError: string().nullable(),
|
|
63757
64194
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
63758
64195
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
63759
|
-
queueDepth: number().int().nonnegative(),
|
|
64196
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
63760
64197
|
/** Per-feature capability matrix — authoritative source for the
|
|
63761
64198
|
* compose-form field gating. */
|
|
63762
64199
|
supports: NotifierSupportsSchema
|
|
@@ -63848,11 +64285,9 @@ onSent: { data: object({
|
|
|
63848
64285
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
63849
64286
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
63850
64287
|
*
|
|
63851
|
-
* The
|
|
63852
|
-
*
|
|
63853
|
-
*
|
|
63854
|
-
* The UI reads them directly from the slice — they are the single source
|
|
63855
|
-
* 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).
|
|
63856
64291
|
*
|
|
63857
64292
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
63858
64293
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -63861,15 +64296,8 @@ onSent: { data: object({
|
|
|
63861
64296
|
* numeric values land here.
|
|
63862
64297
|
*/
|
|
63863
64298
|
var NumericSensorStatusSchema = object({
|
|
63864
|
-
|
|
63865
|
-
|
|
63866
|
-
* Populated live from the upstream source on each state push.
|
|
63867
|
-
* Absent for unitless sensors. */
|
|
63868
|
-
unit: string().optional(),
|
|
63869
|
-
/** Suggested decimal places for numeric display.
|
|
63870
|
-
* Populated live from the upstream source when provided.
|
|
63871
|
-
* Falls back to auto-formatting when absent. */
|
|
63872
|
-
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")),
|
|
63873
64301
|
/** Ms epoch when the slice was last updated. */
|
|
63874
64302
|
lastFetchedAt: number()
|
|
63875
64303
|
});
|
|
@@ -63893,11 +64321,11 @@ var numericSensorCapability = {
|
|
|
63893
64321
|
*/
|
|
63894
64322
|
durability: "restored",
|
|
63895
64323
|
/**
|
|
63896
|
-
* 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.
|
|
63897
64326
|
*/
|
|
63898
64327
|
history: { fields: { value: {
|
|
63899
64328
|
kind: "gauge",
|
|
63900
|
-
unitFrom: "unit",
|
|
63901
64329
|
minIntervalMs: 3e4
|
|
63902
64330
|
} } },
|
|
63903
64331
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -64235,23 +64663,26 @@ var PetFeederStatusSchema = object({
|
|
|
64235
64663
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
64236
64664
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
64237
64665
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
64238
|
-
foodLevel: number().nullable(),
|
|
64666
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64239
64667
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64240
64668
|
* single-hopper models. */
|
|
64241
|
-
food1: number().nullable(),
|
|
64669
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
64242
64670
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
64243
64671
|
* single-hopper models. */
|
|
64244
|
-
food2: number().nullable(),
|
|
64672
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
64245
64673
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64246
64674
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
64247
64675
|
* below the feeder's low threshold. */
|
|
64248
64676
|
lowFood: boolean(),
|
|
64249
64677
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
64250
64678
|
* device has no battery reading. */
|
|
64251
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
64252
|
-
/**
|
|
64253
|
-
*
|
|
64254
|
-
|
|
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")),
|
|
64255
64686
|
/** True while a feed is in progress. */
|
|
64256
64687
|
feeding: boolean(),
|
|
64257
64688
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -64262,7 +64693,7 @@ var PetFeederStatusSchema = object({
|
|
|
64262
64693
|
* with `errorCode` for consumers that want the raw integer. */
|
|
64263
64694
|
error: string().nullable(),
|
|
64264
64695
|
/** Raw device error code (0 / null = no error). */
|
|
64265
|
-
errorCode: number().nullable(),
|
|
64696
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64266
64697
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
64267
64698
|
isDualHopper: boolean(),
|
|
64268
64699
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -64272,7 +64703,7 @@ var PetFeederStatusSchema = object({
|
|
|
64272
64703
|
/** Play a chime when dispensing. */
|
|
64273
64704
|
feedSound: boolean(),
|
|
64274
64705
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
64275
|
-
volume: number(),
|
|
64706
|
+
volume: number().meta(readingMeta("none")),
|
|
64276
64707
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
64277
64708
|
lastFetchedAt: number()
|
|
64278
64709
|
});
|
|
@@ -64391,7 +64822,7 @@ var petFeederCapability = {
|
|
|
64391
64822
|
},
|
|
64392
64823
|
desiccantLeftDays: {
|
|
64393
64824
|
kind: "gauge",
|
|
64394
|
-
unit: "
|
|
64825
|
+
unit: "s"
|
|
64395
64826
|
}
|
|
64396
64827
|
} }
|
|
64397
64828
|
};
|
|
@@ -64792,36 +65223,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64792
65223
|
*/
|
|
64793
65224
|
var PowerMeterStatusSchema = object({
|
|
64794
65225
|
/** Instantaneous power draw in watts. */
|
|
64795
|
-
watts: number().optional().meta({
|
|
64796
|
-
unit: "W",
|
|
64797
|
-
label: "Power"
|
|
64798
|
-
}),
|
|
65226
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64799
65227
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64800
|
-
kwhTotal: number().optional().meta({
|
|
64801
|
-
unit: "kWh",
|
|
64802
|
-
label: "Energy"
|
|
64803
|
-
}),
|
|
65228
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64804
65229
|
/** Voltage in volts. */
|
|
64805
|
-
volts: number().optional(),
|
|
65230
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
64806
65231
|
/** Current in amperes. */
|
|
64807
|
-
amps: number().optional(),
|
|
64808
|
-
/** Apparent power in volt-amperes
|
|
64809
|
-
va: number().optional(),
|
|
65232
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
65233
|
+
/** Apparent power in volt-amperes. */
|
|
65234
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64810
65235
|
/** Power factor (0..1) if reported. */
|
|
64811
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
65236
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64812
65237
|
/** Ms epoch when the slice was last updated. */
|
|
64813
|
-
lastFetchedAt: number()
|
|
64814
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
64815
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
64816
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
64817
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
64818
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
64819
|
-
unit: string().optional(),
|
|
64820
|
-
/** Suggested decimal places for numeric display.
|
|
64821
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64822
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64823
|
-
* auto-formatting when absent. */
|
|
64824
|
-
precision: number().int().min(0).max(10).optional()
|
|
65238
|
+
lastFetchedAt: number()
|
|
64825
65239
|
});
|
|
64826
65240
|
var powerMeterCapability = {
|
|
64827
65241
|
name: "power-meter",
|
|
@@ -64885,12 +65299,7 @@ var powerMeterCapability = {
|
|
|
64885
65299
|
} },
|
|
64886
65300
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64887
65301
|
* whether persisting is worth a SQLite commit. */
|
|
64888
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64889
|
-
customize: {
|
|
64890
|
-
version: 1,
|
|
64891
|
-
advanced: "derive",
|
|
64892
|
-
targets: []
|
|
64893
|
-
}
|
|
65302
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64894
65303
|
};
|
|
64895
65304
|
/**
|
|
64896
65305
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64910,11 +65319,11 @@ var powerMeterCapability = {
|
|
|
64910
65319
|
*/
|
|
64911
65320
|
var GpsLocationSchema = object({
|
|
64912
65321
|
/** Latitude in decimal degrees, -90..90. */
|
|
64913
|
-
latitude: number().min(-90).max(90),
|
|
65322
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
64914
65323
|
/** Longitude in decimal degrees, -180..180. */
|
|
64915
|
-
longitude: number().min(-180).max(180),
|
|
65324
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
64916
65325
|
/** Reported accuracy in meters (lower = better). */
|
|
64917
|
-
accuracyMeters: number().nonnegative()
|
|
65326
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
64918
65327
|
});
|
|
64919
65328
|
var PresenceStatusSchema = object({
|
|
64920
65329
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -64926,7 +65335,7 @@ var PresenceStatusSchema = object({
|
|
|
64926
65335
|
gps: GpsLocationSchema.nullable(),
|
|
64927
65336
|
/** Optional battery level of the tracking device (0..100). Null
|
|
64928
65337
|
* when not reported. */
|
|
64929
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
65338
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64930
65339
|
/** Ms epoch when the slice was last updated. */
|
|
64931
65340
|
lastChangedAt: number()
|
|
64932
65341
|
});
|
|
@@ -64976,19 +65385,10 @@ var presenceCapability = {
|
|
|
64976
65385
|
* `sourceInfo`.
|
|
64977
65386
|
*/
|
|
64978
65387
|
var PressureSensorStatusSchema = object({
|
|
64979
|
-
/** Current pressure in hPa. */
|
|
64980
|
-
hpa: number(),
|
|
65388
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65389
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64981
65390
|
/** Ms epoch when the slice was last updated. */
|
|
64982
|
-
lastFetchedAt: number()
|
|
64983
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64984
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64985
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64986
|
-
unit: string().optional(),
|
|
64987
|
-
/** Suggested decimal places for numeric display.
|
|
64988
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64989
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64990
|
-
* auto-formatting when absent. */
|
|
64991
|
-
precision: number().int().min(0).max(10).optional()
|
|
65391
|
+
lastFetchedAt: number()
|
|
64992
65392
|
});
|
|
64993
65393
|
var pressureSensorCapability = {
|
|
64994
65394
|
name: "pressure-sensor",
|
|
@@ -65514,8 +65914,8 @@ var ptzCapability = {
|
|
|
65514
65914
|
};
|
|
65515
65915
|
var PtzAutotrackSettingsSchema = object({
|
|
65516
65916
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
65517
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
65518
|
-
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"))
|
|
65519
65919
|
});
|
|
65520
65920
|
/**
|
|
65521
65921
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -65669,7 +66069,7 @@ var RunningStateStatusSchema = object({
|
|
|
65669
66069
|
/** null = unknown — never coerced to false (D393). */
|
|
65670
66070
|
running: boolean().nullable(),
|
|
65671
66071
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
65672
|
-
since: number().nullable(),
|
|
66072
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
65673
66073
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
65674
66074
|
phase: string().nullable(),
|
|
65675
66075
|
/** null until a reading has been published (D393). */
|
|
@@ -65684,7 +66084,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
65684
66084
|
/** Generic Customize target for the running boolean (D936). */
|
|
65685
66085
|
var runningCustomize = {
|
|
65686
66086
|
version: 1,
|
|
65687
|
-
advanced: "derive",
|
|
65688
66087
|
targets: [{
|
|
65689
66088
|
id: "running",
|
|
65690
66089
|
cardinality: "scalar",
|
|
@@ -65704,7 +66103,7 @@ var runningCustomize = {
|
|
|
65704
66103
|
DeviceType.Thermostat,
|
|
65705
66104
|
DeviceType.PetFeeder
|
|
65706
66105
|
],
|
|
65707
|
-
apply: "add
|
|
66106
|
+
apply: "add",
|
|
65708
66107
|
path: "running",
|
|
65709
66108
|
sources: [
|
|
65710
66109
|
{
|
|
@@ -66997,9 +67396,9 @@ var RecordTriggerSchema = _enum([
|
|
|
66997
67396
|
*/
|
|
66998
67397
|
var RecordWindowSchema = object({
|
|
66999
67398
|
trigger: RecordTriggerSchema,
|
|
67000
|
-
day: number().int().min(0).max(6),
|
|
67001
|
-
startMinute: number().int().min(0).max(1439),
|
|
67002
|
-
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"))
|
|
67003
67402
|
});
|
|
67004
67403
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
67005
67404
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -67075,10 +67474,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
67075
67474
|
/** Master "record to the card at all" switch. */
|
|
67076
67475
|
enabled: boolean().nullable(),
|
|
67077
67476
|
overwriteWhenFull: boolean().nullable(),
|
|
67078
|
-
preRecordSec: number().nullable(),
|
|
67079
|
-
postRecordSec: number().nullable(),
|
|
67477
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
67478
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
67080
67479
|
/** Length of one recorded file, in minutes. */
|
|
67081
|
-
segmentMinutes: number().nullable(),
|
|
67480
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
67082
67481
|
/** The primary track's weekly windows, flattened. */
|
|
67083
67482
|
windows: array(RecordWindowSchema),
|
|
67084
67483
|
/**
|
|
@@ -67094,7 +67493,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
67094
67493
|
* provider reporting a non-zero count also reports the schedule as not
|
|
67095
67494
|
* writable.
|
|
67096
67495
|
*/
|
|
67097
|
-
unreadableWindows: number(),
|
|
67496
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
67098
67497
|
/**
|
|
67099
67498
|
* The camera is scheduled to record and has NO usable storage.
|
|
67100
67499
|
*
|
|
@@ -68104,7 +68503,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
68104
68503
|
url: string().optional(),
|
|
68105
68504
|
codec: string().optional(),
|
|
68106
68505
|
resolution: CamStreamResolutionSchema.optional(),
|
|
68107
|
-
fps: number().positive().optional(),
|
|
68506
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
68108
68507
|
label: string().optional(),
|
|
68109
68508
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
68110
68509
|
deviceFeatures: array(string()).optional(),
|
|
@@ -68191,18 +68590,18 @@ var StreamProfileSchema = _enum([
|
|
|
68191
68590
|
]);
|
|
68192
68591
|
/** The current encoding config of one stream profile. */
|
|
68193
68592
|
var StreamProfileConfigSchema = object({
|
|
68194
|
-
width: number(),
|
|
68195
|
-
height: number(),
|
|
68593
|
+
width: number().meta(readingMeta("none")),
|
|
68594
|
+
height: number().meta(readingMeta("none")),
|
|
68196
68595
|
codec: _enum(["h264", "h265"]),
|
|
68197
|
-
framerate: number(),
|
|
68198
|
-
bitrate: number(),
|
|
68596
|
+
framerate: number().meta(readingMeta("rate")),
|
|
68597
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
68199
68598
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
68200
68599
|
encoderProfile: _enum([
|
|
68201
68600
|
"high",
|
|
68202
68601
|
"main",
|
|
68203
68602
|
"baseline"
|
|
68204
68603
|
]).optional(),
|
|
68205
|
-
gop: number().optional(),
|
|
68604
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
68206
68605
|
/**
|
|
68207
68606
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
68208
68607
|
*
|
|
@@ -68621,12 +69020,7 @@ var switchCapability = {
|
|
|
68621
69020
|
label: "On",
|
|
68622
69021
|
kind: "boolean"
|
|
68623
69022
|
}
|
|
68624
|
-
}] }
|
|
68625
|
-
customize: {
|
|
68626
|
-
version: 1,
|
|
68627
|
-
advanced: "derive",
|
|
68628
|
-
targets: []
|
|
68629
|
-
}
|
|
69023
|
+
}] }
|
|
68630
69024
|
};
|
|
68631
69025
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
68632
69026
|
function hasControlCharacter(value) {
|
|
@@ -69209,35 +69603,21 @@ var tamperCapability = {
|
|
|
69209
69603
|
* entries with `device_class: temperature` and any future native
|
|
69210
69604
|
* thermometer.
|
|
69211
69605
|
*
|
|
69212
|
-
*
|
|
69213
|
-
*
|
|
69214
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
69215
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
69216
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
69217
|
-
* `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.
|
|
69218
69608
|
*
|
|
69219
69609
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
69220
69610
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
69221
69611
|
* changed" steady state.
|
|
69222
69612
|
*/
|
|
69223
69613
|
var TemperatureSensorStatusSchema = object({
|
|
69224
|
-
/** Current temperature in Celsius. */
|
|
69225
|
-
celsius: number().meta({
|
|
69226
|
-
|
|
69614
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69615
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
69616
|
+
precision: 1,
|
|
69227
69617
|
label: "Temperature"
|
|
69228
|
-
}),
|
|
69618
|
+
})),
|
|
69229
69619
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
69230
|
-
lastFetchedAt: number()
|
|
69231
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
69232
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
69233
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
69234
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
69235
|
-
unit: string().optional(),
|
|
69236
|
-
/** Suggested decimal places for numeric display.
|
|
69237
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
69238
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
69239
|
-
* auto-formatting when absent. */
|
|
69240
|
-
precision: number().int().min(0).max(10).optional()
|
|
69620
|
+
lastFetchedAt: number()
|
|
69241
69621
|
});
|
|
69242
69622
|
var temperatureSensorCapability = {
|
|
69243
69623
|
name: "temperature-sensor",
|
|
@@ -69268,12 +69648,7 @@ var temperatureSensorCapability = {
|
|
|
69268
69648
|
} } },
|
|
69269
69649
|
/** Clock fields: written, but excluded from the compare that decides
|
|
69270
69650
|
* whether persisting is worth a SQLite commit. */
|
|
69271
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
69272
|
-
customize: {
|
|
69273
|
-
version: 1,
|
|
69274
|
-
advanced: "derive",
|
|
69275
|
-
targets: []
|
|
69276
|
-
}
|
|
69651
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
69277
69652
|
};
|
|
69278
69653
|
/**
|
|
69279
69654
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -69556,16 +69931,16 @@ var VacuumControlStatusSchema = object({
|
|
|
69556
69931
|
]),
|
|
69557
69932
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
69558
69933
|
* reading. */
|
|
69559
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
69934
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69560
69935
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
69561
69936
|
* the vacuum has no speed control. */
|
|
69562
69937
|
fanSpeed: string().nullable(),
|
|
69563
69938
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69564
69939
|
availableFanSpeeds: array(string()),
|
|
69565
69940
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69566
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
69941
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69567
69942
|
/** Current error code (0 / null = no error). */
|
|
69568
|
-
errorCode: number().nullable(),
|
|
69943
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69569
69944
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
69570
69945
|
errorLabel: string().nullable(),
|
|
69571
69946
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -69643,7 +70018,7 @@ var ValveStatusSchema = object({
|
|
|
69643
70018
|
]),
|
|
69644
70019
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
69645
70020
|
* intermediate position surface. */
|
|
69646
|
-
position: number().min(0).max(100).nullable(),
|
|
70021
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69647
70022
|
/** Ms epoch when the slice was last updated. */
|
|
69648
70023
|
lastChangedAt: number()
|
|
69649
70024
|
});
|
|
@@ -69751,9 +70126,9 @@ var vibrationCapability = {
|
|
|
69751
70126
|
*/
|
|
69752
70127
|
var WaterHeaterStatusSchema = object({
|
|
69753
70128
|
/** Current measured temperature. Null when not reported. */
|
|
69754
|
-
currentTemp: number().nullable(),
|
|
70129
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69755
70130
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
69756
|
-
targetTemp: number().nullable(),
|
|
70131
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69757
70132
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
69758
70133
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
69759
70134
|
* device reports an unknown state. */
|
|
@@ -69764,9 +70139,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
69764
70139
|
* has no away surface. */
|
|
69765
70140
|
away: boolean().nullable(),
|
|
69766
70141
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
69767
|
-
minTemp: number().nullable(),
|
|
70142
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69768
70143
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
69769
|
-
maxTemp: number().nullable(),
|
|
70144
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69770
70145
|
/** Ms epoch when the slice was last updated. */
|
|
69771
70146
|
lastChangedAt: number()
|
|
69772
70147
|
});
|
|
@@ -69851,25 +70226,18 @@ var waterHeaterCapability = {
|
|
|
69851
70226
|
* Forecast deferred — current conditions only for v1.
|
|
69852
70227
|
*/
|
|
69853
70228
|
var WeatherStatusSchema = object({
|
|
69854
|
-
/** Verbatim
|
|
69855
|
-
* when no condition has been reported yet. */
|
|
70229
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
69856
70230
|
condition: string().nullable(),
|
|
69857
|
-
/** Current temperature in
|
|
69858
|
-
temperature: number().nullable(),
|
|
69859
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
69860
|
-
temperatureUnit: string().nullable(),
|
|
70231
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
70232
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
69861
70233
|
/** Relative humidity (0..100). Null when not provided. */
|
|
69862
|
-
humidity: number().min(0).max(100).nullable(),
|
|
69863
|
-
/** Barometric pressure in
|
|
69864
|
-
pressure: number().nullable(),
|
|
69865
|
-
/**
|
|
69866
|
-
|
|
69867
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
69868
|
-
windSpeed: number().nullable(),
|
|
69869
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
69870
|
-
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")),
|
|
69871
70239
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
69872
|
-
windBearing: number().nullable(),
|
|
70240
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
69873
70241
|
/** Ms epoch when the slice was last updated. */
|
|
69874
70242
|
lastFetchedAt: number()
|
|
69875
70243
|
});
|
|
@@ -69897,12 +70265,12 @@ var weatherCapability = {
|
|
|
69897
70265
|
*/
|
|
69898
70266
|
durability: "session",
|
|
69899
70267
|
/**
|
|
69900
|
-
* History (D850): recorded series.
|
|
70268
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
69901
70269
|
*/
|
|
69902
70270
|
history: { fields: {
|
|
69903
70271
|
temperature: {
|
|
69904
70272
|
kind: "gauge",
|
|
69905
|
-
|
|
70273
|
+
unit: "°C",
|
|
69906
70274
|
deadband: .2
|
|
69907
70275
|
},
|
|
69908
70276
|
humidity: {
|
|
@@ -69912,12 +70280,12 @@ var weatherCapability = {
|
|
|
69912
70280
|
},
|
|
69913
70281
|
pressure: {
|
|
69914
70282
|
kind: "gauge",
|
|
69915
|
-
|
|
70283
|
+
unit: "hPa",
|
|
69916
70284
|
deadband: .5
|
|
69917
70285
|
},
|
|
69918
70286
|
windSpeed: {
|
|
69919
70287
|
kind: "gauge",
|
|
69920
|
-
|
|
70288
|
+
unit: "m/s",
|
|
69921
70289
|
deadband: .5
|
|
69922
70290
|
}
|
|
69923
70291
|
} }
|
|
@@ -71296,6 +71664,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
71296
71664
|
featureProbe: featureProbeCapability,
|
|
71297
71665
|
flood: floodCapability,
|
|
71298
71666
|
gas: gasCapability,
|
|
71667
|
+
groupCommands: groupCommandsCapability,
|
|
71668
|
+
groupStatus: groupStatusCapability,
|
|
71299
71669
|
heatingValve: heatingValveCapability,
|
|
71300
71670
|
humidifier: humidifierCapability,
|
|
71301
71671
|
humiditySensor: humiditySensorCapability,
|
|
@@ -72672,6 +73042,13 @@ Object.freeze({
|
|
|
72672
73042
|
access: "view",
|
|
72673
73043
|
role: "admin"
|
|
72674
73044
|
},
|
|
73045
|
+
"addons.getPackageDocs": {
|
|
73046
|
+
capName: "addons",
|
|
73047
|
+
capScope: "system",
|
|
73048
|
+
addonId: null,
|
|
73049
|
+
access: "view",
|
|
73050
|
+
role: "admin"
|
|
73051
|
+
},
|
|
72675
73052
|
"addons.getVersions": {
|
|
72676
73053
|
capName: "addons",
|
|
72677
73054
|
capScope: "system",
|
|
@@ -75780,6 +76157,20 @@ Object.freeze({
|
|
|
75780
76157
|
access: "view",
|
|
75781
76158
|
role: "viewer"
|
|
75782
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
|
+
},
|
|
75783
76174
|
"heatingValve.getStatus": {
|
|
75784
76175
|
capName: "heating-valve",
|
|
75785
76176
|
capScope: "device",
|
|
@@ -85602,6 +85993,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85602
85993
|
icon: "flame"
|
|
85603
85994
|
}]
|
|
85604
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
|
+
},
|
|
85605
86027
|
"humidity-sensor": {
|
|
85606
86028
|
scope: "device",
|
|
85607
86029
|
noun: t("Humidity", "Umidità"),
|
|
@@ -85635,7 +86057,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85635
86057
|
field: "value",
|
|
85636
86058
|
quantity: t("the reading", "il valore"),
|
|
85637
86059
|
label: t("Reading", "Valore"),
|
|
85638
|
-
unitField: "unit",
|
|
85639
86060
|
icon: "gauge"
|
|
85640
86061
|
}]
|
|
85641
86062
|
},
|
|
@@ -85771,7 +86192,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85771
86192
|
field: "temperature",
|
|
85772
86193
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
85773
86194
|
label: t("Temperature", "Temperatura"),
|
|
85774
|
-
|
|
86195
|
+
unit: "°C",
|
|
85775
86196
|
icon: "thermometer"
|
|
85776
86197
|
},
|
|
85777
86198
|
{
|
|
@@ -85787,7 +86208,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85787
86208
|
field: "windSpeed",
|
|
85788
86209
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
85789
86210
|
label: t("Wind", "Vento"),
|
|
85790
|
-
|
|
86211
|
+
unit: "m/s",
|
|
85791
86212
|
icon: "wind"
|
|
85792
86213
|
},
|
|
85793
86214
|
{
|
|
@@ -85795,7 +86216,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85795
86216
|
field: "pressure",
|
|
85796
86217
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
85797
86218
|
label: t("Pressure", "Pressione"),
|
|
85798
|
-
|
|
86219
|
+
unit: "hPa",
|
|
85799
86220
|
icon: "gauge"
|
|
85800
86221
|
}
|
|
85801
86222
|
]
|
|
@@ -87220,6 +87641,16 @@ Object.freeze({
|
|
|
87220
87641
|
form: "single",
|
|
87221
87642
|
optional: false
|
|
87222
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
|
+
}],
|
|
87223
87654
|
"heatingValve.getStatus": [{
|
|
87224
87655
|
name: "deviceId",
|
|
87225
87656
|
form: "single",
|
|
@@ -89204,6 +89635,8 @@ new Map(Object.entries({
|
|
|
89204
89635
|
"detection-blind": "device-events",
|
|
89205
89636
|
"motion-noisy": "device-events",
|
|
89206
89637
|
"motion-calm": "device-events",
|
|
89638
|
+
"package-llm-silent": "device-events",
|
|
89639
|
+
"package-llm-answered": "device-events",
|
|
89207
89640
|
"recording-stalled": "device-events",
|
|
89208
89641
|
"recording-healthy": "device-events",
|
|
89209
89642
|
"recording-degraded": "device-events",
|
|
@@ -89287,6 +89720,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
89287
89720
|
label: "Motion without a subject",
|
|
89288
89721
|
kinds: ["motion-noisy", "motion-calm"]
|
|
89289
89722
|
},
|
|
89723
|
+
{
|
|
89724
|
+
id: "package-llm",
|
|
89725
|
+
family: "device-events",
|
|
89726
|
+
label: "Package confirm",
|
|
89727
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
89728
|
+
},
|
|
89290
89729
|
{
|
|
89291
89730
|
id: "recording",
|
|
89292
89731
|
family: "device-events",
|
|
@@ -89468,6 +89907,8 @@ var DEVICE_EVENTS = [
|
|
|
89468
89907
|
"detection-blind",
|
|
89469
89908
|
"motion-noisy",
|
|
89470
89909
|
"motion-calm",
|
|
89910
|
+
"package-llm-silent",
|
|
89911
|
+
"package-llm-answered",
|
|
89471
89912
|
"recording-stalled",
|
|
89472
89913
|
"recording-healthy",
|
|
89473
89914
|
"recording-degraded",
|
|
@@ -89736,6 +90177,15 @@ new Map([
|
|
|
89736
90177
|
snapshotLabel: "Cameras with constant motion now",
|
|
89737
90178
|
snapshotSection: null
|
|
89738
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
|
+
},
|
|
89739
90189
|
{
|
|
89740
90190
|
id: "recording-health",
|
|
89741
90191
|
family: "device-events",
|