@camstack/addon-provider-rtsp 1.2.146 → 1.2.147
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 +19 -0
- package/dist/addon.js +959 -509
- package/dist/addon.mjs +959 -509
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
//#endregion
|
|
24
24
|
let node_net = require("node:net");
|
|
25
25
|
node_net = __toESM(node_net);
|
|
26
|
-
//#region ../types/dist/event-category-
|
|
26
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
27
27
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
28
28
|
EventCategory["SystemBoot"] = "system.boot";
|
|
29
29
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -349,6 +349,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
349
349
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
350
350
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
351
351
|
/**
|
|
352
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
353
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
354
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
355
|
+
*/
|
|
356
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
357
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
358
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
359
|
+
/**
|
|
352
360
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
353
361
|
* (a settings change via `setAgentInferenceDevices` /
|
|
354
362
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5458,7 +5466,7 @@ var ZodIssueCode = {
|
|
|
5458
5466
|
var ZodFirstPartyTypeKind;
|
|
5459
5467
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5460
5468
|
//#endregion
|
|
5461
|
-
//#region ../types/dist/sleep-
|
|
5469
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5462
5470
|
/**
|
|
5463
5471
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5464
5472
|
* window to float samples (D455).
|
|
@@ -8012,6 +8020,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
8012
8020
|
}).strict();
|
|
8013
8021
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8014
8022
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8023
|
+
var READING_QUANTITIES = [
|
|
8024
|
+
"temperature",
|
|
8025
|
+
"pressure",
|
|
8026
|
+
"speed",
|
|
8027
|
+
"precipitation",
|
|
8028
|
+
"precipitation-rate",
|
|
8029
|
+
"length",
|
|
8030
|
+
"area",
|
|
8031
|
+
"illuminance",
|
|
8032
|
+
"irradiance",
|
|
8033
|
+
"power",
|
|
8034
|
+
"energy",
|
|
8035
|
+
"voltage",
|
|
8036
|
+
"current",
|
|
8037
|
+
"apparent-power",
|
|
8038
|
+
"humidity",
|
|
8039
|
+
"percentage",
|
|
8040
|
+
"concentration-volume",
|
|
8041
|
+
"concentration-mass",
|
|
8042
|
+
"concentration-ppb",
|
|
8043
|
+
"volume",
|
|
8044
|
+
"duration",
|
|
8045
|
+
"duration-ms",
|
|
8046
|
+
"information",
|
|
8047
|
+
"sound-level",
|
|
8048
|
+
"signal-level",
|
|
8049
|
+
"colour-temperature",
|
|
8050
|
+
"angle",
|
|
8051
|
+
"bitrate",
|
|
8052
|
+
"rate",
|
|
8053
|
+
"mass",
|
|
8054
|
+
"index",
|
|
8055
|
+
"ratio",
|
|
8056
|
+
"count",
|
|
8057
|
+
"none",
|
|
8058
|
+
"device"
|
|
8059
|
+
];
|
|
8060
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8061
|
+
new Set(READING_QUANTITIES);
|
|
8062
|
+
/**
|
|
8063
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8064
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8065
|
+
*/
|
|
8066
|
+
var QUANTITY_BASE = {
|
|
8067
|
+
temperature: "°C",
|
|
8068
|
+
pressure: "hPa",
|
|
8069
|
+
speed: "m/s",
|
|
8070
|
+
precipitation: "mm",
|
|
8071
|
+
"precipitation-rate": "mm/h",
|
|
8072
|
+
length: "m",
|
|
8073
|
+
area: "m²",
|
|
8074
|
+
illuminance: "lx",
|
|
8075
|
+
irradiance: "W/m²",
|
|
8076
|
+
power: "W",
|
|
8077
|
+
energy: "kWh",
|
|
8078
|
+
voltage: "V",
|
|
8079
|
+
current: "A",
|
|
8080
|
+
"apparent-power": "VA",
|
|
8081
|
+
humidity: "%",
|
|
8082
|
+
percentage: "%",
|
|
8083
|
+
"concentration-volume": "ppm",
|
|
8084
|
+
"concentration-mass": "µg/m³",
|
|
8085
|
+
"concentration-ppb": "ppb",
|
|
8086
|
+
volume: "L",
|
|
8087
|
+
duration: "s",
|
|
8088
|
+
"duration-ms": "ms",
|
|
8089
|
+
information: "B",
|
|
8090
|
+
"sound-level": "dBFS",
|
|
8091
|
+
"signal-level": "dBm",
|
|
8092
|
+
"colour-temperature": "mired",
|
|
8093
|
+
angle: "°",
|
|
8094
|
+
bitrate: "kbps",
|
|
8095
|
+
rate: "fps",
|
|
8096
|
+
mass: "kg",
|
|
8097
|
+
index: "none",
|
|
8098
|
+
ratio: "none",
|
|
8099
|
+
count: "none",
|
|
8100
|
+
none: "none",
|
|
8101
|
+
device: "device"
|
|
8102
|
+
};
|
|
8103
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8104
|
+
function baseUnitOf(quantity) {
|
|
8105
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8106
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8107
|
+
return symbol;
|
|
8108
|
+
}
|
|
8109
|
+
function readingMeta(quantity, extras) {
|
|
8110
|
+
return {
|
|
8111
|
+
quantity,
|
|
8112
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8113
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8114
|
+
};
|
|
8115
|
+
}
|
|
8015
8116
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8016
8117
|
var CamProfileSchema = _enum([
|
|
8017
8118
|
"high",
|
|
@@ -8039,8 +8140,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8039
8140
|
"derived"
|
|
8040
8141
|
]);
|
|
8041
8142
|
var CamStreamResolutionSchema = object({
|
|
8042
|
-
width: number().int().positive(),
|
|
8043
|
-
height: number().int().positive()
|
|
8143
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8144
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8044
8145
|
});
|
|
8045
8146
|
var CameraStreamSchema = object({
|
|
8046
8147
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8558,6 +8659,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8558
8659
|
"filesystem-browse",
|
|
8559
8660
|
"flood",
|
|
8560
8661
|
"gas",
|
|
8662
|
+
"group-commands",
|
|
8663
|
+
"group-status",
|
|
8561
8664
|
"heating-valve",
|
|
8562
8665
|
"humidifier",
|
|
8563
8666
|
"humidity-sensor",
|
|
@@ -8687,14 +8790,6 @@ Object.freeze({
|
|
|
8687
8790
|
{
|
|
8688
8791
|
"path": "aqi",
|
|
8689
8792
|
"valueType": "number"
|
|
8690
|
-
},
|
|
8691
|
-
{
|
|
8692
|
-
"path": "unit",
|
|
8693
|
-
"valueType": "string"
|
|
8694
|
-
},
|
|
8695
|
-
{
|
|
8696
|
-
"path": "precision",
|
|
8697
|
-
"valueType": "number"
|
|
8698
8793
|
}
|
|
8699
8794
|
],
|
|
8700
8795
|
"alarm-panel": [
|
|
@@ -8730,20 +8825,10 @@ Object.freeze({
|
|
|
8730
8825
|
"valueType": "boolean"
|
|
8731
8826
|
}
|
|
8732
8827
|
],
|
|
8733
|
-
"ambient-light-sensor": [
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
},
|
|
8738
|
-
{
|
|
8739
|
-
"path": "unit",
|
|
8740
|
-
"valueType": "string"
|
|
8741
|
-
},
|
|
8742
|
-
{
|
|
8743
|
-
"path": "precision",
|
|
8744
|
-
"valueType": "number"
|
|
8745
|
-
}
|
|
8746
|
-
],
|
|
8828
|
+
"ambient-light-sensor": [{
|
|
8829
|
+
"path": "lux",
|
|
8830
|
+
"valueType": "number"
|
|
8831
|
+
}],
|
|
8747
8832
|
"audio-metrics": [
|
|
8748
8833
|
{
|
|
8749
8834
|
"path": "ts",
|
|
@@ -8823,6 +8908,10 @@ Object.freeze({
|
|
|
8823
8908
|
"path": "lastUpdated",
|
|
8824
8909
|
"valueType": "number"
|
|
8825
8910
|
},
|
|
8911
|
+
{
|
|
8912
|
+
"path": "volts",
|
|
8913
|
+
"valueType": "number"
|
|
8914
|
+
},
|
|
8826
8915
|
{
|
|
8827
8916
|
"path": "lastContactAt",
|
|
8828
8917
|
"valueType": "number"
|
|
@@ -9065,10 +9154,6 @@ Object.freeze({
|
|
|
9065
9154
|
"datetime"
|
|
9066
9155
|
]
|
|
9067
9156
|
},
|
|
9068
|
-
{
|
|
9069
|
-
"path": "unit",
|
|
9070
|
-
"valueType": "string"
|
|
9071
|
-
},
|
|
9072
9157
|
{
|
|
9073
9158
|
"path": "min",
|
|
9074
9159
|
"valueType": "number"
|
|
@@ -9080,19 +9165,6 @@ Object.freeze({
|
|
|
9080
9165
|
{
|
|
9081
9166
|
"path": "step",
|
|
9082
9167
|
"valueType": "number"
|
|
9083
|
-
},
|
|
9084
|
-
{
|
|
9085
|
-
"path": "precision",
|
|
9086
|
-
"valueType": "number"
|
|
9087
|
-
},
|
|
9088
|
-
{
|
|
9089
|
-
"path": "format",
|
|
9090
|
-
"valueType": "enum",
|
|
9091
|
-
"enumValues": [
|
|
9092
|
-
"date",
|
|
9093
|
-
"time",
|
|
9094
|
-
"datetime"
|
|
9095
|
-
]
|
|
9096
9168
|
}
|
|
9097
9169
|
],
|
|
9098
9170
|
"cover": [
|
|
@@ -9333,13 +9405,8 @@ Object.freeze({
|
|
|
9333
9405
|
"path": "value",
|
|
9334
9406
|
"valueType": "string"
|
|
9335
9407
|
}, {
|
|
9336
|
-
"path": "
|
|
9337
|
-
"valueType": "
|
|
9338
|
-
"enumValues": [
|
|
9339
|
-
"date",
|
|
9340
|
-
"time",
|
|
9341
|
-
"datetime"
|
|
9342
|
-
]
|
|
9408
|
+
"path": "timestamp",
|
|
9409
|
+
"valueType": "boolean"
|
|
9343
9410
|
}],
|
|
9344
9411
|
"event-emitter": [
|
|
9345
9412
|
{
|
|
@@ -9412,6 +9479,20 @@ Object.freeze({
|
|
|
9412
9479
|
"path": "detected",
|
|
9413
9480
|
"valueType": "boolean"
|
|
9414
9481
|
}],
|
|
9482
|
+
"group-status": [
|
|
9483
|
+
{
|
|
9484
|
+
"path": "included",
|
|
9485
|
+
"valueType": "number"
|
|
9486
|
+
},
|
|
9487
|
+
{
|
|
9488
|
+
"path": "excluded",
|
|
9489
|
+
"valueType": "number"
|
|
9490
|
+
},
|
|
9491
|
+
{
|
|
9492
|
+
"path": "total",
|
|
9493
|
+
"valueType": "number"
|
|
9494
|
+
}
|
|
9495
|
+
],
|
|
9415
9496
|
"heating-valve": [{
|
|
9416
9497
|
"path": "position",
|
|
9417
9498
|
"valueType": "number"
|
|
@@ -9446,20 +9527,10 @@ Object.freeze({
|
|
|
9446
9527
|
"valueType": "number"
|
|
9447
9528
|
}
|
|
9448
9529
|
],
|
|
9449
|
-
"humidity-sensor": [
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
},
|
|
9454
|
-
{
|
|
9455
|
-
"path": "unit",
|
|
9456
|
-
"valueType": "string"
|
|
9457
|
-
},
|
|
9458
|
-
{
|
|
9459
|
-
"path": "precision",
|
|
9460
|
-
"valueType": "number"
|
|
9461
|
-
}
|
|
9462
|
-
],
|
|
9530
|
+
"humidity-sensor": [{
|
|
9531
|
+
"path": "percent",
|
|
9532
|
+
"valueType": "number"
|
|
9533
|
+
}],
|
|
9463
9534
|
"image": [{
|
|
9464
9535
|
"path": "url",
|
|
9465
9536
|
"valueType": "string"
|
|
@@ -9798,20 +9869,10 @@ Object.freeze({
|
|
|
9798
9869
|
"valueType": "boolean"
|
|
9799
9870
|
}
|
|
9800
9871
|
],
|
|
9801
|
-
"numeric-sensor": [
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
},
|
|
9806
|
-
{
|
|
9807
|
-
"path": "unit",
|
|
9808
|
-
"valueType": "string"
|
|
9809
|
-
},
|
|
9810
|
-
{
|
|
9811
|
-
"path": "precision",
|
|
9812
|
-
"valueType": "number"
|
|
9813
|
-
}
|
|
9814
|
-
],
|
|
9872
|
+
"numeric-sensor": [{
|
|
9873
|
+
"path": "value",
|
|
9874
|
+
"valueType": "number"
|
|
9875
|
+
}],
|
|
9815
9876
|
"pet-feeder": [
|
|
9816
9877
|
{
|
|
9817
9878
|
"path": "foodLevel",
|
|
@@ -9903,14 +9964,6 @@ Object.freeze({
|
|
|
9903
9964
|
{
|
|
9904
9965
|
"path": "powerFactor",
|
|
9905
9966
|
"valueType": "number"
|
|
9906
|
-
},
|
|
9907
|
-
{
|
|
9908
|
-
"path": "unit",
|
|
9909
|
-
"valueType": "string"
|
|
9910
|
-
},
|
|
9911
|
-
{
|
|
9912
|
-
"path": "precision",
|
|
9913
|
-
"valueType": "number"
|
|
9914
9967
|
}
|
|
9915
9968
|
],
|
|
9916
9969
|
"presence": [
|
|
@@ -9939,20 +9992,10 @@ Object.freeze({
|
|
|
9939
9992
|
"valueType": "number"
|
|
9940
9993
|
}
|
|
9941
9994
|
],
|
|
9942
|
-
"pressure-sensor": [
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
},
|
|
9947
|
-
{
|
|
9948
|
-
"path": "unit",
|
|
9949
|
-
"valueType": "string"
|
|
9950
|
-
},
|
|
9951
|
-
{
|
|
9952
|
-
"path": "precision",
|
|
9953
|
-
"valueType": "number"
|
|
9954
|
-
}
|
|
9955
|
-
],
|
|
9995
|
+
"pressure-sensor": [{
|
|
9996
|
+
"path": "hpa",
|
|
9997
|
+
"valueType": "number"
|
|
9998
|
+
}],
|
|
9956
9999
|
"privacy-mask": [{
|
|
9957
10000
|
"path": "enabled",
|
|
9958
10001
|
"valueType": "boolean"
|
|
@@ -10263,20 +10306,10 @@ Object.freeze({
|
|
|
10263
10306
|
"path": "tampered",
|
|
10264
10307
|
"valueType": "boolean"
|
|
10265
10308
|
}],
|
|
10266
|
-
"temperature-sensor": [
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
},
|
|
10271
|
-
{
|
|
10272
|
-
"path": "unit",
|
|
10273
|
-
"valueType": "string"
|
|
10274
|
-
},
|
|
10275
|
-
{
|
|
10276
|
-
"path": "precision",
|
|
10277
|
-
"valueType": "number"
|
|
10278
|
-
}
|
|
10279
|
-
],
|
|
10309
|
+
"temperature-sensor": [{
|
|
10310
|
+
"path": "celsius",
|
|
10311
|
+
"valueType": "number"
|
|
10312
|
+
}],
|
|
10280
10313
|
"update": [
|
|
10281
10314
|
{
|
|
10282
10315
|
"path": "currentVersion",
|
|
@@ -10387,10 +10420,6 @@ Object.freeze({
|
|
|
10387
10420
|
"path": "temperature",
|
|
10388
10421
|
"valueType": "number"
|
|
10389
10422
|
},
|
|
10390
|
-
{
|
|
10391
|
-
"path": "temperatureUnit",
|
|
10392
|
-
"valueType": "string"
|
|
10393
|
-
},
|
|
10394
10423
|
{
|
|
10395
10424
|
"path": "humidity",
|
|
10396
10425
|
"valueType": "number"
|
|
@@ -10399,18 +10428,10 @@ Object.freeze({
|
|
|
10399
10428
|
"path": "pressure",
|
|
10400
10429
|
"valueType": "number"
|
|
10401
10430
|
},
|
|
10402
|
-
{
|
|
10403
|
-
"path": "pressureUnit",
|
|
10404
|
-
"valueType": "string"
|
|
10405
|
-
},
|
|
10406
10431
|
{
|
|
10407
10432
|
"path": "windSpeed",
|
|
10408
10433
|
"valueType": "number"
|
|
10409
10434
|
},
|
|
10410
|
-
{
|
|
10411
|
-
"path": "windSpeedUnit",
|
|
10412
|
-
"valueType": "string"
|
|
10413
|
-
},
|
|
10414
10435
|
{
|
|
10415
10436
|
"path": "windBearing",
|
|
10416
10437
|
"valueType": "number"
|
|
@@ -10902,7 +10923,7 @@ function errMsg(err) {
|
|
|
10902
10923
|
return String(err);
|
|
10903
10924
|
}
|
|
10904
10925
|
//#endregion
|
|
10905
|
-
//#region ../types/dist/composition-
|
|
10926
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10906
10927
|
/**
|
|
10907
10928
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10908
10929
|
*
|
|
@@ -11657,15 +11678,74 @@ function validateExpressionSource(src) {
|
|
|
11657
11678
|
}
|
|
11658
11679
|
return null;
|
|
11659
11680
|
}
|
|
11660
|
-
/**
|
|
11661
|
-
|
|
11662
|
-
|
|
11663
|
-
|
|
11681
|
+
/**
|
|
11682
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11683
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11684
|
+
* `composition.ts` (D659).
|
|
11685
|
+
*/
|
|
11664
11686
|
var CompositionSourceRefSchema = object({
|
|
11665
11687
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11666
11688
|
addonId: string().min(1),
|
|
11667
11689
|
stableId: string().min(1)
|
|
11668
11690
|
});
|
|
11691
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11692
|
+
"temperature",
|
|
11693
|
+
"humidity",
|
|
11694
|
+
"pressure",
|
|
11695
|
+
"illuminance",
|
|
11696
|
+
"power",
|
|
11697
|
+
"energy",
|
|
11698
|
+
"battery",
|
|
11699
|
+
"numeric",
|
|
11700
|
+
"motion",
|
|
11701
|
+
"contact",
|
|
11702
|
+
"leak",
|
|
11703
|
+
"smoke",
|
|
11704
|
+
"occupancy",
|
|
11705
|
+
"binary",
|
|
11706
|
+
"switch",
|
|
11707
|
+
"light"
|
|
11708
|
+
];
|
|
11709
|
+
var NUMERIC_AGGREGATES = [
|
|
11710
|
+
"mean",
|
|
11711
|
+
"median",
|
|
11712
|
+
"min",
|
|
11713
|
+
"max",
|
|
11714
|
+
"sum"
|
|
11715
|
+
];
|
|
11716
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11717
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11718
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11719
|
+
var AGGREGATE_REDUCERS = [
|
|
11720
|
+
"mean",
|
|
11721
|
+
"median",
|
|
11722
|
+
"min",
|
|
11723
|
+
"max",
|
|
11724
|
+
"sum",
|
|
11725
|
+
"any",
|
|
11726
|
+
"all"
|
|
11727
|
+
];
|
|
11728
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11729
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11730
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11731
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11732
|
+
var HelperMemberSchema = object({
|
|
11733
|
+
source: CompositionSourceRefSchema,
|
|
11734
|
+
cap: string().min(1),
|
|
11735
|
+
fieldPath: string().min(1)
|
|
11736
|
+
});
|
|
11737
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11738
|
+
kind: literal("group"),
|
|
11739
|
+
templateId: GroupTemplateIdSchema,
|
|
11740
|
+
aggregate: AggregateReducerSchema,
|
|
11741
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11742
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11743
|
+
active: ActiveCriterionSchema.optional()
|
|
11744
|
+
})]);
|
|
11745
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11746
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11747
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11748
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11669
11749
|
/** One field of one capability of one source device. */
|
|
11670
11750
|
var CompositionFieldReadSchema = object({
|
|
11671
11751
|
source: CompositionSourceRefSchema,
|
|
@@ -11709,7 +11789,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11709
11789
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11710
11790
|
CompositionFromSourceSchema,
|
|
11711
11791
|
CompositionExpressionSourceSchema,
|
|
11712
|
-
CompositionCodeSourceSchema
|
|
11792
|
+
CompositionCodeSourceSchema,
|
|
11793
|
+
object({
|
|
11794
|
+
kind: literal("aggregate"),
|
|
11795
|
+
reducer: _enum([
|
|
11796
|
+
"mean",
|
|
11797
|
+
"median",
|
|
11798
|
+
"min",
|
|
11799
|
+
"max",
|
|
11800
|
+
"sum",
|
|
11801
|
+
"any",
|
|
11802
|
+
"all"
|
|
11803
|
+
]),
|
|
11804
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11805
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11806
|
+
publish: _enum([
|
|
11807
|
+
"value",
|
|
11808
|
+
"included",
|
|
11809
|
+
"excluded",
|
|
11810
|
+
"total"
|
|
11811
|
+
]),
|
|
11812
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11813
|
+
empty: _enum([
|
|
11814
|
+
"null",
|
|
11815
|
+
"omit",
|
|
11816
|
+
"offline"
|
|
11817
|
+
])
|
|
11818
|
+
})
|
|
11713
11819
|
]);
|
|
11714
11820
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11715
11821
|
kind: literal("forward"),
|
|
@@ -11755,7 +11861,13 @@ var CompositionSchema = object({
|
|
|
11755
11861
|
kind: literal("existing"),
|
|
11756
11862
|
device: CompositionSourceRefSchema
|
|
11757
11863
|
})]),
|
|
11758
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11864
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11865
|
+
/**
|
|
11866
|
+
* Present when the block is a helper template. Absent on a free
|
|
11867
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11868
|
+
* never the compiled features.
|
|
11869
|
+
*/
|
|
11870
|
+
helper: HelperSpecSchema.optional()
|
|
11759
11871
|
}).superRefine((composition, ctx) => {
|
|
11760
11872
|
const seen = /* @__PURE__ */ new Set();
|
|
11761
11873
|
composition.features.forEach((feature, index) => {
|
|
@@ -17995,7 +18107,11 @@ var CompositionProblemSchema = object({
|
|
|
17995
18107
|
"item-field-reserved",
|
|
17996
18108
|
"target-missing",
|
|
17997
18109
|
"target-unreadable",
|
|
17998
|
-
"not-replaceable"
|
|
18110
|
+
"not-replaceable",
|
|
18111
|
+
"native-capability-replace",
|
|
18112
|
+
"mixed-quantity",
|
|
18113
|
+
"helper-mismatch",
|
|
18114
|
+
"member-constraint"
|
|
17999
18115
|
]),
|
|
18000
18116
|
path: string(),
|
|
18001
18117
|
message: string()
|
|
@@ -18016,7 +18132,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18016
18132
|
"null",
|
|
18017
18133
|
"offline",
|
|
18018
18134
|
"unknown",
|
|
18019
|
-
"release"
|
|
18135
|
+
"release",
|
|
18136
|
+
"omit"
|
|
18020
18137
|
]);
|
|
18021
18138
|
/**
|
|
18022
18139
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18053,9 +18170,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18053
18170
|
reads: array(CompositionFieldReadSchema)
|
|
18054
18171
|
});
|
|
18055
18172
|
/**
|
|
18056
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18057
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18058
|
-
*
|
|
18173
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18174
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18175
|
+
* Replacing a capability the device already serves is refused
|
|
18176
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18177
|
+
* wire for a claim the hub already holds.
|
|
18059
18178
|
*/
|
|
18060
18179
|
var CompositionFeatureModeSchema = _enum([
|
|
18061
18180
|
"new",
|
|
@@ -18228,6 +18347,275 @@ Object.freeze({
|
|
|
18228
18347
|
result: ["number", "null"]
|
|
18229
18348
|
}
|
|
18230
18349
|
});
|
|
18350
|
+
/**
|
|
18351
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18352
|
+
* Data, not a form default written into the block.
|
|
18353
|
+
*/
|
|
18354
|
+
var NOW = {
|
|
18355
|
+
fieldPath: "lastFetchedAt",
|
|
18356
|
+
expr: "now"
|
|
18357
|
+
};
|
|
18358
|
+
var CHANGED = {
|
|
18359
|
+
fieldPath: "lastChangedAt",
|
|
18360
|
+
expr: "now"
|
|
18361
|
+
};
|
|
18362
|
+
function numeric(input) {
|
|
18363
|
+
return {
|
|
18364
|
+
...input,
|
|
18365
|
+
family: "numeric",
|
|
18366
|
+
deviceType: DeviceType.Sensor,
|
|
18367
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18368
|
+
commandCaps: [],
|
|
18369
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18370
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18371
|
+
accept: [{
|
|
18372
|
+
cap: input.outputCap,
|
|
18373
|
+
fieldPath: input.outputField
|
|
18374
|
+
}]
|
|
18375
|
+
};
|
|
18376
|
+
}
|
|
18377
|
+
function binary(input) {
|
|
18378
|
+
return {
|
|
18379
|
+
...input,
|
|
18380
|
+
family: "binary",
|
|
18381
|
+
deviceType: DeviceType.Sensor,
|
|
18382
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18383
|
+
commandCaps: [],
|
|
18384
|
+
quantity: "none",
|
|
18385
|
+
baseUnit: void 0,
|
|
18386
|
+
aggregates: BINARY_AGGREGATES,
|
|
18387
|
+
empty: "offline"
|
|
18388
|
+
};
|
|
18389
|
+
}
|
|
18390
|
+
var GROUP_TEMPLATES = [
|
|
18391
|
+
numeric({
|
|
18392
|
+
id: "temperature",
|
|
18393
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18394
|
+
role: DeviceRole.TemperatureSensor,
|
|
18395
|
+
outputCap: "temperature-sensor",
|
|
18396
|
+
outputField: "celsius",
|
|
18397
|
+
quantity: "temperature",
|
|
18398
|
+
defaultAggregate: "mean",
|
|
18399
|
+
empty: "null",
|
|
18400
|
+
companions: [NOW]
|
|
18401
|
+
}),
|
|
18402
|
+
numeric({
|
|
18403
|
+
id: "humidity",
|
|
18404
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18405
|
+
role: DeviceRole.HumiditySensor,
|
|
18406
|
+
outputCap: "humidity-sensor",
|
|
18407
|
+
outputField: "percent",
|
|
18408
|
+
quantity: "humidity",
|
|
18409
|
+
defaultAggregate: "mean",
|
|
18410
|
+
empty: "null",
|
|
18411
|
+
companions: [NOW]
|
|
18412
|
+
}),
|
|
18413
|
+
numeric({
|
|
18414
|
+
id: "pressure",
|
|
18415
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18416
|
+
role: DeviceRole.PressureSensor,
|
|
18417
|
+
outputCap: "pressure-sensor",
|
|
18418
|
+
outputField: "hpa",
|
|
18419
|
+
quantity: "pressure",
|
|
18420
|
+
defaultAggregate: "mean",
|
|
18421
|
+
empty: "null",
|
|
18422
|
+
companions: [NOW]
|
|
18423
|
+
}),
|
|
18424
|
+
numeric({
|
|
18425
|
+
id: "illuminance",
|
|
18426
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18427
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18428
|
+
outputCap: "ambient-light-sensor",
|
|
18429
|
+
outputField: "lux",
|
|
18430
|
+
quantity: "illuminance",
|
|
18431
|
+
defaultAggregate: "mean",
|
|
18432
|
+
empty: "null",
|
|
18433
|
+
companions: [NOW]
|
|
18434
|
+
}),
|
|
18435
|
+
numeric({
|
|
18436
|
+
id: "power",
|
|
18437
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18438
|
+
role: DeviceRole.PowerSensor,
|
|
18439
|
+
outputCap: "power-meter",
|
|
18440
|
+
outputField: "watts",
|
|
18441
|
+
quantity: "power",
|
|
18442
|
+
defaultAggregate: "sum",
|
|
18443
|
+
empty: "omit",
|
|
18444
|
+
companions: [NOW]
|
|
18445
|
+
}),
|
|
18446
|
+
numeric({
|
|
18447
|
+
id: "energy",
|
|
18448
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18449
|
+
role: DeviceRole.EnergySensor,
|
|
18450
|
+
outputCap: "power-meter",
|
|
18451
|
+
outputField: "kwhTotal",
|
|
18452
|
+
quantity: "energy",
|
|
18453
|
+
defaultAggregate: "sum",
|
|
18454
|
+
empty: "omit",
|
|
18455
|
+
companions: [NOW]
|
|
18456
|
+
}),
|
|
18457
|
+
numeric({
|
|
18458
|
+
id: "battery",
|
|
18459
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18460
|
+
role: DeviceRole.BatterySensor,
|
|
18461
|
+
outputCap: "battery",
|
|
18462
|
+
outputField: "percentage",
|
|
18463
|
+
quantity: "percentage",
|
|
18464
|
+
defaultAggregate: "mean",
|
|
18465
|
+
empty: "null",
|
|
18466
|
+
companions: [
|
|
18467
|
+
{
|
|
18468
|
+
fieldPath: "charging",
|
|
18469
|
+
expr: "\"unknown\""
|
|
18470
|
+
},
|
|
18471
|
+
{
|
|
18472
|
+
fieldPath: "sleeping",
|
|
18473
|
+
expr: "false"
|
|
18474
|
+
},
|
|
18475
|
+
{
|
|
18476
|
+
fieldPath: "lastUpdated",
|
|
18477
|
+
expr: "now"
|
|
18478
|
+
}
|
|
18479
|
+
]
|
|
18480
|
+
}),
|
|
18481
|
+
numeric({
|
|
18482
|
+
id: "numeric",
|
|
18483
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18484
|
+
role: DeviceRole.NumericSensor,
|
|
18485
|
+
outputCap: "numeric-sensor",
|
|
18486
|
+
outputField: "value",
|
|
18487
|
+
quantity: "device",
|
|
18488
|
+
defaultAggregate: "mean",
|
|
18489
|
+
empty: "null",
|
|
18490
|
+
companions: [NOW]
|
|
18491
|
+
}),
|
|
18492
|
+
binary({
|
|
18493
|
+
id: "motion",
|
|
18494
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18495
|
+
role: DeviceRole.MotionSensor,
|
|
18496
|
+
outputCap: "motion",
|
|
18497
|
+
outputField: "detected",
|
|
18498
|
+
defaultAggregate: "any",
|
|
18499
|
+
accept: [{
|
|
18500
|
+
cap: "motion",
|
|
18501
|
+
fieldPath: "detected"
|
|
18502
|
+
}],
|
|
18503
|
+
companions: [{
|
|
18504
|
+
fieldPath: "lastDetectedAt",
|
|
18505
|
+
expr: "null"
|
|
18506
|
+
}, {
|
|
18507
|
+
fieldPath: "autoClearAfterMs",
|
|
18508
|
+
expr: "null"
|
|
18509
|
+
}]
|
|
18510
|
+
}),
|
|
18511
|
+
binary({
|
|
18512
|
+
id: "contact",
|
|
18513
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18514
|
+
role: DeviceRole.ContactSensor,
|
|
18515
|
+
outputCap: "contact",
|
|
18516
|
+
outputField: "entryOpen",
|
|
18517
|
+
defaultAggregate: "any",
|
|
18518
|
+
accept: [{
|
|
18519
|
+
cap: "contact",
|
|
18520
|
+
fieldPath: "entryOpen"
|
|
18521
|
+
}],
|
|
18522
|
+
companions: [CHANGED]
|
|
18523
|
+
}),
|
|
18524
|
+
binary({
|
|
18525
|
+
id: "leak",
|
|
18526
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18527
|
+
role: DeviceRole.LeakSensor,
|
|
18528
|
+
outputCap: "flood",
|
|
18529
|
+
outputField: "flooded",
|
|
18530
|
+
defaultAggregate: "any",
|
|
18531
|
+
accept: [{
|
|
18532
|
+
cap: "flood",
|
|
18533
|
+
fieldPath: "flooded"
|
|
18534
|
+
}],
|
|
18535
|
+
companions: [CHANGED]
|
|
18536
|
+
}),
|
|
18537
|
+
binary({
|
|
18538
|
+
id: "smoke",
|
|
18539
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18540
|
+
role: DeviceRole.SmokeSensor,
|
|
18541
|
+
outputCap: "smoke",
|
|
18542
|
+
outputField: "detected",
|
|
18543
|
+
defaultAggregate: "any",
|
|
18544
|
+
accept: [{
|
|
18545
|
+
cap: "smoke",
|
|
18546
|
+
fieldPath: "detected"
|
|
18547
|
+
}],
|
|
18548
|
+
companions: [CHANGED]
|
|
18549
|
+
}),
|
|
18550
|
+
binary({
|
|
18551
|
+
id: "occupancy",
|
|
18552
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18553
|
+
role: DeviceRole.BinarySensor,
|
|
18554
|
+
outputCap: "binary",
|
|
18555
|
+
outputField: "on",
|
|
18556
|
+
defaultAggregate: "any",
|
|
18557
|
+
accept: [{
|
|
18558
|
+
cap: "motion",
|
|
18559
|
+
fieldPath: "detected"
|
|
18560
|
+
}, {
|
|
18561
|
+
cap: "binary",
|
|
18562
|
+
fieldPath: "on"
|
|
18563
|
+
}],
|
|
18564
|
+
companions: [CHANGED]
|
|
18565
|
+
}),
|
|
18566
|
+
binary({
|
|
18567
|
+
id: "binary",
|
|
18568
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18569
|
+
role: DeviceRole.BinarySensor,
|
|
18570
|
+
outputCap: "binary",
|
|
18571
|
+
outputField: "on",
|
|
18572
|
+
defaultAggregate: "any",
|
|
18573
|
+
accept: [{
|
|
18574
|
+
cap: "binary",
|
|
18575
|
+
fieldPath: "on"
|
|
18576
|
+
}],
|
|
18577
|
+
companions: [CHANGED]
|
|
18578
|
+
}),
|
|
18579
|
+
actuator({
|
|
18580
|
+
id: "switch",
|
|
18581
|
+
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.",
|
|
18582
|
+
deviceType: DeviceType.Switch,
|
|
18583
|
+
outputCap: "switch",
|
|
18584
|
+
commandCaps: ["switch"]
|
|
18585
|
+
}),
|
|
18586
|
+
actuator({
|
|
18587
|
+
id: "light",
|
|
18588
|
+
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.",
|
|
18589
|
+
deviceType: DeviceType.Light,
|
|
18590
|
+
outputCap: "switch",
|
|
18591
|
+
commandCaps: [
|
|
18592
|
+
"switch",
|
|
18593
|
+
"brightness",
|
|
18594
|
+
"color"
|
|
18595
|
+
]
|
|
18596
|
+
})
|
|
18597
|
+
];
|
|
18598
|
+
function actuator(input) {
|
|
18599
|
+
return {
|
|
18600
|
+
...input,
|
|
18601
|
+
family: "actuator",
|
|
18602
|
+
role: void 0,
|
|
18603
|
+
memberDeviceType: input.deviceType,
|
|
18604
|
+
outputField: "on",
|
|
18605
|
+
quantity: "none",
|
|
18606
|
+
baseUnit: void 0,
|
|
18607
|
+
aggregates: BINARY_AGGREGATES,
|
|
18608
|
+
defaultAggregate: "any",
|
|
18609
|
+
empty: "offline",
|
|
18610
|
+
accept: [{
|
|
18611
|
+
cap: "switch",
|
|
18612
|
+
fieldPath: "on"
|
|
18613
|
+
}],
|
|
18614
|
+
companions: [CHANGED]
|
|
18615
|
+
};
|
|
18616
|
+
}
|
|
18617
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18618
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18231
18619
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18232
18620
|
/**
|
|
18233
18621
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19941,12 +20329,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
19941
20329
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19942
20330
|
* in-place so dispatch keeps working.
|
|
19943
20331
|
*
|
|
19944
|
-
* **
|
|
19945
|
-
*
|
|
19946
|
-
*
|
|
19947
|
-
*
|
|
19948
|
-
* (`ha-domain-mapping`)
|
|
19949
|
-
* stored after that point.
|
|
20332
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20333
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20334
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20335
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20336
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20337
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19950
20338
|
*
|
|
19951
20339
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19952
20340
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19960,6 +20348,14 @@ var SourceInfoSchema = object({
|
|
|
19960
20348
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19961
20349
|
* Used to detect rename when `id` changes. */
|
|
19962
20350
|
uniqueId: string().optional(),
|
|
20351
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20352
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20353
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20354
|
+
dateTimeShape: _enum([
|
|
20355
|
+
"date",
|
|
20356
|
+
"time",
|
|
20357
|
+
"datetime"
|
|
20358
|
+
]).optional(),
|
|
19963
20359
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19964
20360
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19965
20361
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41064,7 +41460,8 @@ method(object({
|
|
|
41064
41460
|
"enum"
|
|
41065
41461
|
]),
|
|
41066
41462
|
enumValues: array(string()).optional(),
|
|
41067
|
-
item: boolean().optional()
|
|
41463
|
+
item: boolean().optional(),
|
|
41464
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41068
41465
|
})).readonly(),
|
|
41069
41466
|
itemArray: object({
|
|
41070
41467
|
path: string(),
|
|
@@ -44908,8 +45305,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44908
45305
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44909
45306
|
var MaskGridShapeSchema = object({
|
|
44910
45307
|
kind: literal("grid"),
|
|
44911
|
-
gridWidth: number(),
|
|
44912
|
-
gridHeight: number(),
|
|
45308
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45309
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44913
45310
|
cells: array(boolean())
|
|
44914
45311
|
});
|
|
44915
45312
|
discriminatedUnion("kind", [
|
|
@@ -45021,6 +45418,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45021
45418
|
"detection-blind",
|
|
45022
45419
|
"motion-noisy",
|
|
45023
45420
|
"motion-calm",
|
|
45421
|
+
"package-llm-silent",
|
|
45422
|
+
"package-llm-answered",
|
|
45024
45423
|
"recording-stalled",
|
|
45025
45424
|
"recording-healthy",
|
|
45026
45425
|
"recording-degraded",
|
|
@@ -56216,6 +56615,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56216
56615
|
deprecated: string().optional(),
|
|
56217
56616
|
distTags: array(string()).readonly()
|
|
56218
56617
|
});
|
|
56618
|
+
/**
|
|
56619
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56620
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56621
|
+
* tarball failure — never an empty string standing in for either.
|
|
56622
|
+
*/
|
|
56623
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56624
|
+
object({
|
|
56625
|
+
status: literal("ok"),
|
|
56626
|
+
markdown: string()
|
|
56627
|
+
}),
|
|
56628
|
+
object({ status: literal("missing") }),
|
|
56629
|
+
object({
|
|
56630
|
+
status: literal("error"),
|
|
56631
|
+
message: string()
|
|
56632
|
+
})
|
|
56633
|
+
]);
|
|
56634
|
+
var PackageDocsSchema = object({
|
|
56635
|
+
name: string(),
|
|
56636
|
+
version: string(),
|
|
56637
|
+
readme: PackageDocBodySchema,
|
|
56638
|
+
changelog: PackageDocBodySchema
|
|
56639
|
+
});
|
|
56219
56640
|
var SearchResultSchema = object({
|
|
56220
56641
|
name: string(),
|
|
56221
56642
|
version: string(),
|
|
@@ -56434,7 +56855,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56434
56855
|
}), object({ success: literal(true) }), {
|
|
56435
56856
|
kind: "mutation",
|
|
56436
56857
|
auth: "admin"
|
|
56437
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56858
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56859
|
+
name: string().min(1),
|
|
56860
|
+
version: string().min(1).optional()
|
|
56861
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56438
56862
|
kind: "mutation",
|
|
56439
56863
|
auth: "admin"
|
|
56440
56864
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56493,27 +56917,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56493
56917
|
*/
|
|
56494
56918
|
var AirQualitySensorStatusSchema = object({
|
|
56495
56919
|
/** Carbon dioxide concentration in ppm. */
|
|
56496
|
-
co2Ppm: number().min(0).optional(),
|
|
56920
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56497
56921
|
/** Total volatile organic compounds in ppb. */
|
|
56498
|
-
vocPpb: number().min(0).optional(),
|
|
56922
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56499
56923
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56500
|
-
pm25: number().min(0).optional(),
|
|
56924
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56501
56925
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56502
|
-
pm10: number().min(0).optional(),
|
|
56926
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56503
56927
|
/** Composite AQI value (typically 0..500). */
|
|
56504
|
-
aqi: number().optional(),
|
|
56928
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56505
56929
|
/** Ms epoch when the slice was last updated. */
|
|
56506
|
-
lastFetchedAt: number()
|
|
56507
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56508
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56509
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56510
|
-
* per slice is unambiguous. */
|
|
56511
|
-
unit: string().optional(),
|
|
56512
|
-
/** Suggested decimal places for numeric display.
|
|
56513
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56514
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56515
|
-
* auto-formatting when absent. */
|
|
56516
|
-
precision: number().int().min(0).max(10).optional()
|
|
56930
|
+
lastFetchedAt: number()
|
|
56517
56931
|
});
|
|
56518
56932
|
var airQualitySensorCapability = {
|
|
56519
56933
|
name: "air-quality-sensor",
|
|
@@ -56550,12 +56964,12 @@ var airQualitySensorCapability = {
|
|
|
56550
56964
|
},
|
|
56551
56965
|
pm25: {
|
|
56552
56966
|
kind: "gauge",
|
|
56553
|
-
unit: "
|
|
56967
|
+
unit: "µg/m³",
|
|
56554
56968
|
deadband: 1
|
|
56555
56969
|
},
|
|
56556
56970
|
pm10: {
|
|
56557
56971
|
kind: "gauge",
|
|
56558
|
-
unit: "
|
|
56972
|
+
unit: "µg/m³",
|
|
56559
56973
|
deadband: 1
|
|
56560
56974
|
},
|
|
56561
56975
|
aqi: {
|
|
@@ -56573,22 +56987,13 @@ var airQualitySensorCapability = {
|
|
|
56573
56987
|
* entries with `device_class: illuminance`.
|
|
56574
56988
|
*/
|
|
56575
56989
|
var AmbientLightSensorStatusSchema = object({
|
|
56576
|
-
/** Current illuminance in lux (lx). */
|
|
56577
|
-
lux: number().min(0).meta({
|
|
56578
|
-
|
|
56990
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56991
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56992
|
+
precision: 0,
|
|
56579
56993
|
label: "Illuminance"
|
|
56580
|
-
}),
|
|
56994
|
+
})),
|
|
56581
56995
|
/** Ms epoch when the slice was last updated. */
|
|
56582
|
-
lastFetchedAt: number()
|
|
56583
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56584
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56585
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56586
|
-
unit: string().optional(),
|
|
56587
|
-
/** Suggested decimal places for numeric display.
|
|
56588
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56589
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56590
|
-
* auto-formatting when absent. */
|
|
56591
|
-
precision: number().int().min(0).max(10).optional()
|
|
56996
|
+
lastFetchedAt: number()
|
|
56592
56997
|
});
|
|
56593
56998
|
var ambientLightSensorCapability = {
|
|
56594
56999
|
name: "ambient-light-sensor",
|
|
@@ -56620,12 +57025,7 @@ var ambientLightSensorCapability = {
|
|
|
56620
57025
|
} } },
|
|
56621
57026
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56622
57027
|
* whether persisting is worth a SQLite commit. */
|
|
56623
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56624
|
-
customize: {
|
|
56625
|
-
version: 1,
|
|
56626
|
-
advanced: "derive",
|
|
56627
|
-
targets: []
|
|
56628
|
-
}
|
|
57028
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56629
57029
|
};
|
|
56630
57030
|
/**
|
|
56631
57031
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -56852,10 +57252,7 @@ var BatteryStatusSchema = object({
|
|
|
56852
57252
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56853
57253
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56854
57254
|
*/
|
|
56855
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56856
|
-
unit: "%",
|
|
56857
|
-
label: "Charge"
|
|
56858
|
-
}),
|
|
57255
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56859
57256
|
/**
|
|
56860
57257
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56861
57258
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56882,7 +57279,14 @@ var BatteryStatusSchema = object({
|
|
|
56882
57279
|
*/
|
|
56883
57280
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56884
57281
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56885
|
-
lastUpdated: number(),
|
|
57282
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57283
|
+
/**
|
|
57284
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57285
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57286
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57287
|
+
* `numeric-sensor` on the same device.
|
|
57288
|
+
*/
|
|
57289
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56886
57290
|
/**
|
|
56887
57291
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56888
57292
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56934,7 +57338,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
56934
57338
|
/** Generic Customize target for the percentage reading (D936). */
|
|
56935
57339
|
var batteryCustomize = {
|
|
56936
57340
|
version: 1,
|
|
56937
|
-
advanced: "derive",
|
|
56938
57341
|
targets: [{
|
|
56939
57342
|
id: "percentage",
|
|
56940
57343
|
cardinality: "scalar",
|
|
@@ -56943,7 +57346,7 @@ var batteryCustomize = {
|
|
|
56943
57346
|
stateField: "percentage"
|
|
56944
57347
|
},
|
|
56945
57348
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
56946
|
-
apply: "add
|
|
57349
|
+
apply: "add",
|
|
56947
57350
|
path: "percentage",
|
|
56948
57351
|
sources: [{
|
|
56949
57352
|
kind: "field",
|
|
@@ -57064,10 +57467,16 @@ onStatusChanged: { data: object({
|
|
|
57064
57467
|
/**
|
|
57065
57468
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57066
57469
|
*/
|
|
57067
|
-
history: { fields: {
|
|
57068
|
-
|
|
57069
|
-
|
|
57070
|
-
|
|
57470
|
+
history: { fields: {
|
|
57471
|
+
percentage: {
|
|
57472
|
+
kind: "gauge",
|
|
57473
|
+
unit: "%"
|
|
57474
|
+
},
|
|
57475
|
+
volts: {
|
|
57476
|
+
kind: "gauge",
|
|
57477
|
+
unit: "V"
|
|
57478
|
+
}
|
|
57479
|
+
} },
|
|
57071
57480
|
customize: batteryCustomize,
|
|
57072
57481
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57073
57482
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57114,12 +57523,7 @@ var binaryCapability = {
|
|
|
57114
57523
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57115
57524
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57116
57525
|
* whether persisting is worth a SQLite commit. */
|
|
57117
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57118
|
-
customize: {
|
|
57119
|
-
version: 1,
|
|
57120
|
-
advanced: "derive",
|
|
57121
|
-
targets: []
|
|
57122
|
-
}
|
|
57526
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57123
57527
|
};
|
|
57124
57528
|
/**
|
|
57125
57529
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57135,7 +57539,7 @@ var binaryCapability = {
|
|
|
57135
57539
|
*/
|
|
57136
57540
|
var BrightnessStatusSchema = object({
|
|
57137
57541
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57138
|
-
percentage: number().min(0).max(100),
|
|
57542
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57139
57543
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57140
57544
|
lastChangedAt: number()
|
|
57141
57545
|
});
|
|
@@ -57589,21 +57993,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57589
57993
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57590
57994
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57591
57995
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57592
|
-
target: number().nullable(),
|
|
57996
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57593
57997
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57594
57998
|
* in `heat_cool` mode. */
|
|
57595
|
-
targetHigh: number().nullable(),
|
|
57999
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57596
58000
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57597
58001
|
* in `heat_cool` mode. */
|
|
57598
|
-
targetLow: number().nullable(),
|
|
58002
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57599
58003
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57600
58004
|
* humidity control. */
|
|
57601
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58005
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57602
58006
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57603
58007
|
* the device's internal sensor. */
|
|
57604
|
-
currentTemp: number().nullable(),
|
|
58008
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57605
58009
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57606
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58010
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57607
58011
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57608
58012
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57609
58013
|
swingVertical: boolean().nullable(),
|
|
@@ -57611,11 +58015,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57611
58015
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57612
58016
|
swingHorizontal: boolean().nullable(),
|
|
57613
58017
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57614
|
-
minTemp: number().nullable().optional(),
|
|
58018
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57615
58019
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57616
|
-
maxTemp: number().nullable().optional(),
|
|
58020
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57617
58021
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57618
|
-
tempStep: number().positive().nullable().optional(),
|
|
58022
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57619
58023
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57620
58024
|
lastFetchedAt: number()
|
|
57621
58025
|
});
|
|
@@ -57757,17 +58161,17 @@ var climateControlCapability = {
|
|
|
57757
58161
|
* modes to expose in the picker without a slice fetch.
|
|
57758
58162
|
*/
|
|
57759
58163
|
var RgbTripletSchema = object({
|
|
57760
|
-
r: number().int().min(0).max(255),
|
|
57761
|
-
g: number().int().min(0).max(255),
|
|
57762
|
-
b: number().int().min(0).max(255)
|
|
58164
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58165
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58166
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57763
58167
|
});
|
|
57764
58168
|
var HsvTripletSchema = object({
|
|
57765
58169
|
/** Hue in degrees, 0..360. */
|
|
57766
|
-
h: number().min(0).max(360),
|
|
58170
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57767
58171
|
/** Saturation as 0..100 inclusive. */
|
|
57768
|
-
s: number().min(0).max(100),
|
|
58172
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57769
58173
|
/** Value/brightness as 0..100 inclusive. */
|
|
57770
|
-
v: number().min(0).max(100)
|
|
58174
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57771
58175
|
});
|
|
57772
58176
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57773
58177
|
object({
|
|
@@ -57796,7 +58200,7 @@ var ColorStatusSchema = object({
|
|
|
57796
58200
|
/** Populated when `mode === 'hsv'`. */
|
|
57797
58201
|
hsv: HsvTripletSchema.optional(),
|
|
57798
58202
|
/** Populated when `mode === 'mired'`. */
|
|
57799
|
-
mireds: number().int().optional(),
|
|
58203
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57800
58204
|
/** Ms epoch of the last operator-driven change. */
|
|
57801
58205
|
lastChangedAt: number()
|
|
57802
58206
|
});
|
|
@@ -57999,18 +58403,12 @@ _enum([
|
|
|
57999
58403
|
"empty",
|
|
58000
58404
|
"full"
|
|
58001
58405
|
]);
|
|
58002
|
-
/**
|
|
58003
|
-
|
|
58004
|
-
|
|
58005
|
-
"days",
|
|
58006
|
-
"hours",
|
|
58007
|
-
"cycles"
|
|
58008
|
-
]);
|
|
58009
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
58010
|
-
* days). `value` null = unknown (D393). */
|
|
58406
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58407
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58408
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
58011
58409
|
var ConsumableRemainingSchema = object({
|
|
58012
|
-
value: number().min(0).nullable(),
|
|
58013
|
-
|
|
58410
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58411
|
+
kind: ConsumableRemainingKindSchema
|
|
58014
58412
|
});
|
|
58015
58413
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
58016
58414
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -58023,7 +58421,7 @@ var ConsumableItemSchema = object({
|
|
|
58023
58421
|
/** Display name. */
|
|
58024
58422
|
label: string().min(1),
|
|
58025
58423
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
58026
|
-
level: number().min(0).max(100).nullable(),
|
|
58424
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58027
58425
|
/** The provider's discrete verdict when known (binary mode). */
|
|
58028
58426
|
status: ConsumableStatusSchema.nullable(),
|
|
58029
58427
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58105,8 +58503,8 @@ var consumablesCustomize = {
|
|
|
58105
58503
|
transforms: [{ kind: "identity" }]
|
|
58106
58504
|
}],
|
|
58107
58505
|
literals: [{
|
|
58108
|
-
path: "remaining.
|
|
58109
|
-
values: [...
|
|
58506
|
+
path: "remaining.kind",
|
|
58507
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58110
58508
|
}]
|
|
58111
58509
|
},
|
|
58112
58510
|
{
|
|
@@ -58235,7 +58633,6 @@ reset: method(object({
|
|
|
58235
58633
|
},
|
|
58236
58634
|
"remaining.value": {
|
|
58237
58635
|
kind: "gauge",
|
|
58238
|
-
unitFrom: "remaining.unit",
|
|
58239
58636
|
deadband: 1,
|
|
58240
58637
|
displayName: "Remaining"
|
|
58241
58638
|
}
|
|
@@ -58305,10 +58702,9 @@ var contactCapability = {
|
|
|
58305
58702
|
* (empty array for the other kinds). It lives in the slice because
|
|
58306
58703
|
* HA `select.*` entities may update their options at runtime.
|
|
58307
58704
|
*
|
|
58308
|
-
*
|
|
58309
|
-
*
|
|
58310
|
-
*
|
|
58311
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58705
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58706
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58707
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58312
58708
|
*/
|
|
58313
58709
|
var ControlStatusSchema = object({
|
|
58314
58710
|
kind: _enum([
|
|
@@ -58320,39 +58716,17 @@ var ControlStatusSchema = object({
|
|
|
58320
58716
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58321
58717
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58322
58718
|
* or time-only — HA accepts all three forms). */
|
|
58323
|
-
value: union([number(), string()]),
|
|
58719
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58324
58720
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58325
58721
|
options: array(string()),
|
|
58326
58722
|
/** Ms epoch when the slice was last updated. */
|
|
58327
58723
|
lastChangedAt: number(),
|
|
58328
|
-
/**
|
|
58329
|
-
|
|
58330
|
-
|
|
58331
|
-
|
|
58332
|
-
/**
|
|
58333
|
-
|
|
58334
|
-
min: number().optional(),
|
|
58335
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58336
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58337
|
-
max: number().optional(),
|
|
58338
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58339
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58340
|
-
step: number().optional(),
|
|
58341
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58342
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58343
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58344
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58345
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58346
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58347
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58348
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58349
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58350
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58351
|
-
format: _enum([
|
|
58352
|
-
"date",
|
|
58353
|
-
"time",
|
|
58354
|
-
"datetime"
|
|
58355
|
-
]).optional()
|
|
58724
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58725
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58726
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58727
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58728
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58729
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58356
58730
|
});
|
|
58357
58731
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58358
58732
|
object({
|
|
@@ -58418,9 +58792,9 @@ var CoverStatusSchema = object({
|
|
|
58418
58792
|
]),
|
|
58419
58793
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58420
58794
|
* no intermediate position surface. */
|
|
58421
|
-
position: number().min(0).max(100).nullable(),
|
|
58795
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58422
58796
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58423
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58797
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58424
58798
|
/** Ms epoch when the slice was last updated. */
|
|
58425
58799
|
lastChangedAt: number()
|
|
58426
58800
|
});
|
|
@@ -58523,9 +58897,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58523
58897
|
var DayNightStatusSchema = object({
|
|
58524
58898
|
mode: DayNightModeSchema,
|
|
58525
58899
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58526
|
-
sensitivity: number().optional(),
|
|
58900
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58527
58901
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58528
|
-
switchDelaySec: number().optional(),
|
|
58902
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58529
58903
|
lastFetchedAt: number()
|
|
58530
58904
|
});
|
|
58531
58905
|
/**
|
|
@@ -58743,11 +59117,11 @@ var DishwasherStatusSchema = object({
|
|
|
58743
59117
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58744
59118
|
availablePrograms: array(string()),
|
|
58745
59119
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58746
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59120
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58747
59121
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58748
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59122
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58749
59123
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58750
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59124
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58751
59125
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58752
59126
|
doorOpen: boolean().nullable(),
|
|
58753
59127
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58771,7 +59145,7 @@ var DishwasherStatusSchema = object({
|
|
|
58771
59145
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58772
59146
|
machineCareDue: boolean().nullable(),
|
|
58773
59147
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58774
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59148
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58775
59149
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58776
59150
|
halfLoad: boolean().nullable(),
|
|
58777
59151
|
hygienePlus: boolean().nullable(),
|
|
@@ -58786,7 +59160,7 @@ var DishwasherStatusSchema = object({
|
|
|
58786
59160
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58787
59161
|
activeEvents: array(string()),
|
|
58788
59162
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58789
|
-
errorCode: number().nullable(),
|
|
59163
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58790
59164
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58791
59165
|
errorLabel: string().nullable(),
|
|
58792
59166
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -59017,7 +59391,7 @@ var DoorbellStatusSchema = object({
|
|
|
59017
59391
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
59018
59392
|
lastPressedAt: number().nullable(),
|
|
59019
59393
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
59020
|
-
pressCountSinceStart: number()
|
|
59394
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
59021
59395
|
});
|
|
59022
59396
|
var DoorbellPressEventSchema = object({
|
|
59023
59397
|
deviceId: number(),
|
|
@@ -59082,17 +59456,7 @@ onPressed: {
|
|
|
59082
59456
|
history: "none",
|
|
59083
59457
|
customize: doorbellCustomize
|
|
59084
59458
|
};
|
|
59085
|
-
|
|
59086
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59087
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59088
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59089
|
-
* The option set is stable across observations; it is persisted in the
|
|
59090
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59091
|
-
* stored in `sourceInfo`.
|
|
59092
|
-
*/
|
|
59093
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59094
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59095
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59459
|
+
_enum([
|
|
59096
59460
|
"date",
|
|
59097
59461
|
"time",
|
|
59098
59462
|
"datetime"
|
|
@@ -59100,12 +59464,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59100
59464
|
var EnumSensorStatusSchema = object({
|
|
59101
59465
|
value: string(),
|
|
59102
59466
|
/**
|
|
59103
|
-
* Set
|
|
59104
|
-
* as
|
|
59105
|
-
*
|
|
59106
|
-
* a time-only sensor → `'time'`.
|
|
59467
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59468
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59469
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59107
59470
|
*/
|
|
59108
|
-
|
|
59471
|
+
timestamp: boolean().optional(),
|
|
59109
59472
|
/** Ms epoch when the slice was last updated. */
|
|
59110
59473
|
lastFetchedAt: number()
|
|
59111
59474
|
});
|
|
@@ -59132,11 +59495,11 @@ var enumSensorCapability = {
|
|
|
59132
59495
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59133
59496
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59134
59497
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59135
|
-
* `
|
|
59498
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59136
59499
|
*/
|
|
59137
59500
|
history: { fields: { value: {
|
|
59138
59501
|
kind: "enum",
|
|
59139
|
-
skipWhenSet: "
|
|
59502
|
+
skipWhenSet: "timestamp"
|
|
59140
59503
|
} } },
|
|
59141
59504
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59142
59505
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59156,13 +59519,13 @@ var EventFireSchema = object({
|
|
|
59156
59519
|
deviceId: number(),
|
|
59157
59520
|
eventType: string(),
|
|
59158
59521
|
data: record(string(), unknown()).nullable(),
|
|
59159
|
-
timestamp: number(),
|
|
59160
|
-
seq: number()
|
|
59522
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59523
|
+
seq: number().meta(readingMeta("count"))
|
|
59161
59524
|
});
|
|
59162
59525
|
var EventEmitterStatusSchema = object({
|
|
59163
59526
|
eventTypes: array(string()),
|
|
59164
59527
|
lastEvent: EventFireSchema.nullable(),
|
|
59165
|
-
eventCountSinceStart: number()
|
|
59528
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59166
59529
|
});
|
|
59167
59530
|
var eventEmitterCapability = {
|
|
59168
59531
|
name: "event-emitter",
|
|
@@ -59575,10 +59938,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59575
59938
|
var FanControlStatusSchema = object({
|
|
59576
59939
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59577
59940
|
* speed surface (single-speed fan). */
|
|
59578
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59941
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59579
59942
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59580
59943
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59581
|
-
percentageStep: number().positive().optional(),
|
|
59944
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59582
59945
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59583
59946
|
* — empty string when no preset is active or supported. */
|
|
59584
59947
|
preset: string(),
|
|
@@ -59699,7 +60062,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59699
60062
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59700
60063
|
model: string().nullable(),
|
|
59701
60064
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59702
|
-
channelCount: number().nullable(),
|
|
60065
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59703
60066
|
/**
|
|
59704
60067
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59705
60068
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59822,9 +60185,91 @@ var gasCapability = {
|
|
|
59822
60185
|
* whether persisting is worth a SQLite commit. */
|
|
59823
60186
|
volatileStateFields: ["lastChangedAt"]
|
|
59824
60187
|
};
|
|
60188
|
+
var GroupCommandsSchema = object({
|
|
60189
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60190
|
+
results: array(object({
|
|
60191
|
+
deviceId: number().int().nonnegative(),
|
|
60192
|
+
cap: string().min(1),
|
|
60193
|
+
method: string().min(1),
|
|
60194
|
+
ok: boolean(),
|
|
60195
|
+
error: string().optional(),
|
|
60196
|
+
/** Ms epoch of the attempt. */
|
|
60197
|
+
at: number()
|
|
60198
|
+
})) });
|
|
60199
|
+
var groupCommandsCapability = {
|
|
60200
|
+
name: "group-commands",
|
|
60201
|
+
scope: "device",
|
|
60202
|
+
deviceNative: true,
|
|
60203
|
+
mode: "singleton",
|
|
60204
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60205
|
+
methods: {},
|
|
60206
|
+
status: {
|
|
60207
|
+
schema: GroupCommandsSchema,
|
|
60208
|
+
kind: "push"
|
|
60209
|
+
},
|
|
60210
|
+
runtimeState: GroupCommandsSchema,
|
|
60211
|
+
/**
|
|
60212
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60213
|
+
* failure would outlive the command that caused it.
|
|
60214
|
+
*
|
|
60215
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60216
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60217
|
+
*/
|
|
60218
|
+
durability: "session",
|
|
60219
|
+
history: "none"
|
|
60220
|
+
};
|
|
60221
|
+
/**
|
|
60222
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60223
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60224
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60225
|
+
* series that later statistics read is the output cap's own history block.
|
|
60226
|
+
*/
|
|
60227
|
+
var GroupStatusSchema = object({
|
|
60228
|
+
/** Members whose current value entered the aggregate. */
|
|
60229
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60230
|
+
precision: 0,
|
|
60231
|
+
label: "Reporting"
|
|
60232
|
+
})),
|
|
60233
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60234
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60235
|
+
precision: 0,
|
|
60236
|
+
label: "Excluded"
|
|
60237
|
+
})),
|
|
60238
|
+
/** `included` + `excluded`. */
|
|
60239
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60240
|
+
precision: 0,
|
|
60241
|
+
label: "Members"
|
|
60242
|
+
}))
|
|
60243
|
+
});
|
|
60244
|
+
var groupStatusCapability = {
|
|
60245
|
+
name: "group-status",
|
|
60246
|
+
scope: "device",
|
|
60247
|
+
deviceNative: true,
|
|
60248
|
+
mode: "singleton",
|
|
60249
|
+
deviceTypes: [
|
|
60250
|
+
DeviceType.Sensor,
|
|
60251
|
+
DeviceType.Switch,
|
|
60252
|
+
DeviceType.Light
|
|
60253
|
+
],
|
|
60254
|
+
methods: {},
|
|
60255
|
+
status: {
|
|
60256
|
+
schema: GroupStatusSchema,
|
|
60257
|
+
kind: "push"
|
|
60258
|
+
},
|
|
60259
|
+
runtimeState: GroupStatusSchema,
|
|
60260
|
+
/**
|
|
60261
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60262
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60263
|
+
*
|
|
60264
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60265
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60266
|
+
*/
|
|
60267
|
+
durability: "session",
|
|
60268
|
+
history: "none"
|
|
60269
|
+
};
|
|
59825
60270
|
var HeatingValveStatusSchema = object({
|
|
59826
60271
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59827
|
-
position: number().min(0).max(100).nullable(),
|
|
60272
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59828
60273
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59829
60274
|
lastFetchedAt: number()
|
|
59830
60275
|
});
|
|
@@ -59867,9 +60312,9 @@ var HumidifierStatusSchema = object({
|
|
|
59867
60312
|
/** Whether the humidifier is currently on. */
|
|
59868
60313
|
on: boolean(),
|
|
59869
60314
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59870
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60315
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59871
60316
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59872
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60317
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59873
60318
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59874
60319
|
* device has no mode surface. */
|
|
59875
60320
|
mode: string().nullable(),
|
|
@@ -59879,9 +60324,9 @@ var HumidifierStatusSchema = object({
|
|
|
59879
60324
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59880
60325
|
action: string().nullable(),
|
|
59881
60326
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59882
|
-
minHumidity: number().nullable(),
|
|
60327
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59883
60328
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59884
|
-
maxHumidity: number().nullable(),
|
|
60329
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59885
60330
|
/** Ms epoch when the slice was last updated. */
|
|
59886
60331
|
lastChangedAt: number()
|
|
59887
60332
|
});
|
|
@@ -59951,22 +60396,13 @@ var humidifierCapability = {
|
|
|
59951
60396
|
* `sourceInfo`.
|
|
59952
60397
|
*/
|
|
59953
60398
|
var HumiditySensorStatusSchema = object({
|
|
59954
|
-
/** Current relative humidity, 0..100. */
|
|
59955
|
-
percent: number().min(0).max(100).meta({
|
|
59956
|
-
|
|
60399
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60400
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60401
|
+
precision: 0,
|
|
59957
60402
|
label: "Humidity"
|
|
59958
|
-
}),
|
|
60403
|
+
})),
|
|
59959
60404
|
/** Ms epoch when the slice was last updated. */
|
|
59960
|
-
lastFetchedAt: number()
|
|
59961
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59962
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59963
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59964
|
-
unit: string().optional(),
|
|
59965
|
-
/** Suggested decimal places for numeric display.
|
|
59966
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59967
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59968
|
-
* auto-formatting when absent. */
|
|
59969
|
-
precision: number().int().min(0).max(10).optional()
|
|
60405
|
+
lastFetchedAt: number()
|
|
59970
60406
|
});
|
|
59971
60407
|
var humiditySensorCapability = {
|
|
59972
60408
|
name: "humidity-sensor",
|
|
@@ -59997,12 +60433,7 @@ var humiditySensorCapability = {
|
|
|
59997
60433
|
} } },
|
|
59998
60434
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59999
60435
|
* whether persisting is worth a SQLite commit. */
|
|
60000
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60001
|
-
customize: {
|
|
60002
|
-
version: 1,
|
|
60003
|
-
advanced: "derive",
|
|
60004
|
-
targets: []
|
|
60005
|
-
}
|
|
60436
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60006
60437
|
};
|
|
60007
60438
|
/**
|
|
60008
60439
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -60023,7 +60454,7 @@ var ImageStatusSchema = object({
|
|
|
60023
60454
|
* entity exposes no `entity_picture` (yet). */
|
|
60024
60455
|
url: string().nullable(),
|
|
60025
60456
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
60026
|
-
lastUpdated: number().nullable()
|
|
60457
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
60027
60458
|
});
|
|
60028
60459
|
var imageCapability = {
|
|
60029
60460
|
name: "image",
|
|
@@ -60111,19 +60542,19 @@ var NormalizedRangeSchema = object({
|
|
|
60111
60542
|
*/
|
|
60112
60543
|
var ImageSettingsStatusSchema = object({
|
|
60113
60544
|
/** Normalized 0–100. */
|
|
60114
|
-
brightness: number().optional(),
|
|
60545
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60115
60546
|
/** Normalized 0–100. */
|
|
60116
|
-
contrast: number().optional(),
|
|
60547
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60117
60548
|
/** Normalized 0–100. */
|
|
60118
|
-
saturation: number().optional(),
|
|
60549
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60119
60550
|
/** Normalized 0–100. */
|
|
60120
|
-
sharpness: number().optional(),
|
|
60551
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60121
60552
|
mirror: boolean().optional(),
|
|
60122
60553
|
flip: boolean().optional(),
|
|
60123
60554
|
rotate: ImageRotateSchema.optional(),
|
|
60124
60555
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60125
60556
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60126
|
-
warmth: number().optional(),
|
|
60557
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60127
60558
|
exposureMode: ExposureModeSchema.optional(),
|
|
60128
60559
|
backlightMode: BacklightModeSchema.optional(),
|
|
60129
60560
|
lastFetchedAt: number()
|
|
@@ -60402,10 +60833,10 @@ var IntercomAbilitySchema = object({
|
|
|
60402
60833
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60403
60834
|
codecs: array(string()),
|
|
60404
60835
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60405
|
-
sampleRate: number(),
|
|
60836
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60406
60837
|
duplex: _enum(["half", "full"]),
|
|
60407
60838
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60408
|
-
maxBacklogMs: number()
|
|
60839
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60409
60840
|
});
|
|
60410
60841
|
var IntercomStatusSchema = object({
|
|
60411
60842
|
/** True while a talk session is open. */
|
|
@@ -60632,13 +61063,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60632
61063
|
activity: LawnMowerActivitySchema,
|
|
60633
61064
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60634
61065
|
* reading. */
|
|
60635
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
61066
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60636
61067
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60637
61068
|
* task is active / progress is unavailable. */
|
|
60638
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61069
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60639
61070
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60640
61071
|
* or null when unknown. */
|
|
60641
|
-
currentCode: number().nullable(),
|
|
61072
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60642
61073
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60643
61074
|
currentCodeLabel: string().nullable(),
|
|
60644
61075
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61171,7 +61602,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61171
61602
|
state: MediaPlayerStateSchema,
|
|
61172
61603
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61173
61604
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61174
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61605
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61175
61606
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61176
61607
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61177
61608
|
isMuted: boolean().nullable(),
|
|
@@ -61184,10 +61615,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61184
61615
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61185
61616
|
/** Current playback position in ms. Null when not seekable or
|
|
61186
61617
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61187
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61618
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61188
61619
|
/** Total duration of the current media in ms. Null when unknown
|
|
61189
61620
|
* (live stream) or nothing is playing. */
|
|
61190
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61621
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61191
61622
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61192
61623
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61193
61624
|
shuffle: boolean().nullable(),
|
|
@@ -61496,7 +61927,7 @@ var motionCustomize = {
|
|
|
61496
61927
|
eventName: "onMotionChanged"
|
|
61497
61928
|
},
|
|
61498
61929
|
deviceTypes: [DeviceType.Camera],
|
|
61499
|
-
apply: "
|
|
61930
|
+
apply: "add",
|
|
61500
61931
|
applyAuthority: {
|
|
61501
61932
|
kind: "camera-sensors",
|
|
61502
61933
|
timeoutField: "motionCooldownMs"
|
|
@@ -61568,7 +61999,7 @@ var MotionStatusSchema = object({
|
|
|
61568
61999
|
* it, every provider seeded it at boot, and every session left it
|
|
61569
62000
|
* `detected: true` after its detach.
|
|
61570
62001
|
*/
|
|
61571
|
-
autoClearAfterMs: number().nullable()
|
|
62002
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61572
62003
|
});
|
|
61573
62004
|
/**
|
|
61574
62005
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61605,12 +62036,18 @@ var motionCapability = {
|
|
|
61605
62036
|
methods: {
|
|
61606
62037
|
/**
|
|
61607
62038
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61608
|
-
* for consumers that don't need the full status object
|
|
61609
|
-
*
|
|
61610
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61611
|
-
* consumer.
|
|
62039
|
+
* for consumers that don't need the full status object. A composed
|
|
62040
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61612
62041
|
*/
|
|
61613
62042
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62043
|
+
/**
|
|
62044
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62045
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62046
|
+
*/
|
|
62047
|
+
composedMethods: { isDetected: {
|
|
62048
|
+
kind: "slice",
|
|
62049
|
+
field: "detected"
|
|
62050
|
+
} },
|
|
61614
62051
|
events: {
|
|
61615
62052
|
/**
|
|
61616
62053
|
* Fires every time the runner transitions a camera between
|
|
@@ -61750,7 +62187,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61750
62187
|
* the grid region(s). */
|
|
61751
62188
|
var MotionZoneStatusSchema = object({
|
|
61752
62189
|
enabled: boolean(),
|
|
61753
|
-
sensitivity: number(),
|
|
62190
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61754
62191
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61755
62192
|
regions: array(MotionZoneRegionSchema),
|
|
61756
62193
|
lastFetchedAt: number()
|
|
@@ -62120,7 +62557,7 @@ var NavigationStatusSchema = object({
|
|
|
62120
62557
|
following: boolean(),
|
|
62121
62558
|
flash: boolean(),
|
|
62122
62559
|
lightMode: NavigationLightModeSchema,
|
|
62123
|
-
lightLevel: number().min(40).max(100),
|
|
62560
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62124
62561
|
/** Ms epoch when the slice was last updated. */
|
|
62125
62562
|
lastChangedAt: number()
|
|
62126
62563
|
});
|
|
@@ -62254,13 +62691,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62254
62691
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62255
62692
|
* SKIP a null rather than coerce it.
|
|
62256
62693
|
*/
|
|
62257
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62694
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62258
62695
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62259
|
-
rssiDbm: number().optional(),
|
|
62696
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62260
62697
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62261
62698
|
ssid: string().optional(),
|
|
62262
62699
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62263
|
-
lastUpdated: number()
|
|
62700
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62264
62701
|
});
|
|
62265
62702
|
var networkLinkCapability = {
|
|
62266
62703
|
name: "network-link",
|
|
@@ -62645,7 +63082,7 @@ var NotifierStatusSchema = object({
|
|
|
62645
63082
|
lastError: string().nullable(),
|
|
62646
63083
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62647
63084
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62648
|
-
queueDepth: number().int().nonnegative(),
|
|
63085
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62649
63086
|
/** Per-feature capability matrix — authoritative source for the
|
|
62650
63087
|
* compose-form field gating. */
|
|
62651
63088
|
supports: NotifierSupportsSchema
|
|
@@ -62737,11 +63174,9 @@ onSent: { data: object({
|
|
|
62737
63174
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62738
63175
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62739
63176
|
*
|
|
62740
|
-
* The
|
|
62741
|
-
*
|
|
62742
|
-
*
|
|
62743
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62744
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63177
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63178
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63179
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62745
63180
|
*
|
|
62746
63181
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62747
63182
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62750,15 +63185,8 @@ onSent: { data: object({
|
|
|
62750
63185
|
* numeric values land here.
|
|
62751
63186
|
*/
|
|
62752
63187
|
var NumericSensorStatusSchema = object({
|
|
62753
|
-
|
|
62754
|
-
|
|
62755
|
-
* Populated live from the upstream source on each state push.
|
|
62756
|
-
* Absent for unitless sensors. */
|
|
62757
|
-
unit: string().optional(),
|
|
62758
|
-
/** Suggested decimal places for numeric display.
|
|
62759
|
-
* Populated live from the upstream source when provided.
|
|
62760
|
-
* Falls back to auto-formatting when absent. */
|
|
62761
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63188
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63189
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62762
63190
|
/** Ms epoch when the slice was last updated. */
|
|
62763
63191
|
lastFetchedAt: number()
|
|
62764
63192
|
});
|
|
@@ -62782,11 +63210,11 @@ var numericSensorCapability = {
|
|
|
62782
63210
|
*/
|
|
62783
63211
|
durability: "restored",
|
|
62784
63212
|
/**
|
|
62785
|
-
* History (D850): recorded series. The unit is
|
|
63213
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63214
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62786
63215
|
*/
|
|
62787
63216
|
history: { fields: { value: {
|
|
62788
63217
|
kind: "gauge",
|
|
62789
|
-
unitFrom: "unit",
|
|
62790
63218
|
minIntervalMs: 3e4
|
|
62791
63219
|
} } },
|
|
62792
63220
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63078,23 +63506,26 @@ var PetFeederStatusSchema = object({
|
|
|
63078
63506
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63079
63507
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63080
63508
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63081
|
-
foodLevel: number().nullable(),
|
|
63509
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63082
63510
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63083
63511
|
* single-hopper models. */
|
|
63084
|
-
food1: number().nullable(),
|
|
63512
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63085
63513
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63086
63514
|
* single-hopper models. */
|
|
63087
|
-
food2: number().nullable(),
|
|
63515
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63088
63516
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63089
63517
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63090
63518
|
* below the feeder's low threshold. */
|
|
63091
63519
|
lowFood: boolean(),
|
|
63092
63520
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63093
63521
|
* device has no battery reading. */
|
|
63094
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63095
|
-
/**
|
|
63096
|
-
*
|
|
63097
|
-
|
|
63522
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63523
|
+
/**
|
|
63524
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63525
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63526
|
+
* model has no desiccant sensor.
|
|
63527
|
+
*/
|
|
63528
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63098
63529
|
/** True while a feed is in progress. */
|
|
63099
63530
|
feeding: boolean(),
|
|
63100
63531
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63105,7 +63536,7 @@ var PetFeederStatusSchema = object({
|
|
|
63105
63536
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63106
63537
|
error: string().nullable(),
|
|
63107
63538
|
/** Raw device error code (0 / null = no error). */
|
|
63108
|
-
errorCode: number().nullable(),
|
|
63539
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63109
63540
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63110
63541
|
isDualHopper: boolean(),
|
|
63111
63542
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63115,7 +63546,7 @@ var PetFeederStatusSchema = object({
|
|
|
63115
63546
|
/** Play a chime when dispensing. */
|
|
63116
63547
|
feedSound: boolean(),
|
|
63117
63548
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63118
|
-
volume: number(),
|
|
63549
|
+
volume: number().meta(readingMeta("none")),
|
|
63119
63550
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63120
63551
|
lastFetchedAt: number()
|
|
63121
63552
|
});
|
|
@@ -63234,7 +63665,7 @@ var petFeederCapability = {
|
|
|
63234
63665
|
},
|
|
63235
63666
|
desiccantLeftDays: {
|
|
63236
63667
|
kind: "gauge",
|
|
63237
|
-
unit: "
|
|
63668
|
+
unit: "s"
|
|
63238
63669
|
}
|
|
63239
63670
|
} }
|
|
63240
63671
|
};
|
|
@@ -63635,36 +64066,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63635
64066
|
*/
|
|
63636
64067
|
var PowerMeterStatusSchema = object({
|
|
63637
64068
|
/** Instantaneous power draw in watts. */
|
|
63638
|
-
watts: number().optional().meta({
|
|
63639
|
-
unit: "W",
|
|
63640
|
-
label: "Power"
|
|
63641
|
-
}),
|
|
64069
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63642
64070
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63643
|
-
kwhTotal: number().optional().meta({
|
|
63644
|
-
unit: "kWh",
|
|
63645
|
-
label: "Energy"
|
|
63646
|
-
}),
|
|
64071
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63647
64072
|
/** Voltage in volts. */
|
|
63648
|
-
volts: number().optional(),
|
|
64073
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63649
64074
|
/** Current in amperes. */
|
|
63650
|
-
amps: number().optional(),
|
|
63651
|
-
/** Apparent power in volt-amperes
|
|
63652
|
-
va: number().optional(),
|
|
64075
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
64076
|
+
/** Apparent power in volt-amperes. */
|
|
64077
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63653
64078
|
/** Power factor (0..1) if reported. */
|
|
63654
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
64079
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63655
64080
|
/** Ms epoch when the slice was last updated. */
|
|
63656
|
-
lastFetchedAt: number()
|
|
63657
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63658
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63659
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63660
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63661
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63662
|
-
unit: string().optional(),
|
|
63663
|
-
/** Suggested decimal places for numeric display.
|
|
63664
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63665
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63666
|
-
* auto-formatting when absent. */
|
|
63667
|
-
precision: number().int().min(0).max(10).optional()
|
|
64081
|
+
lastFetchedAt: number()
|
|
63668
64082
|
});
|
|
63669
64083
|
var powerMeterCapability = {
|
|
63670
64084
|
name: "power-meter",
|
|
@@ -63728,12 +64142,7 @@ var powerMeterCapability = {
|
|
|
63728
64142
|
} },
|
|
63729
64143
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63730
64144
|
* whether persisting is worth a SQLite commit. */
|
|
63731
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63732
|
-
customize: {
|
|
63733
|
-
version: 1,
|
|
63734
|
-
advanced: "derive",
|
|
63735
|
-
targets: []
|
|
63736
|
-
}
|
|
64145
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63737
64146
|
};
|
|
63738
64147
|
/**
|
|
63739
64148
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63753,11 +64162,11 @@ var powerMeterCapability = {
|
|
|
63753
64162
|
*/
|
|
63754
64163
|
var GpsLocationSchema = object({
|
|
63755
64164
|
/** Latitude in decimal degrees, -90..90. */
|
|
63756
|
-
latitude: number().min(-90).max(90),
|
|
64165
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63757
64166
|
/** Longitude in decimal degrees, -180..180. */
|
|
63758
|
-
longitude: number().min(-180).max(180),
|
|
64167
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63759
64168
|
/** Reported accuracy in meters (lower = better). */
|
|
63760
|
-
accuracyMeters: number().nonnegative()
|
|
64169
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63761
64170
|
});
|
|
63762
64171
|
var PresenceStatusSchema = object({
|
|
63763
64172
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63769,7 +64178,7 @@ var PresenceStatusSchema = object({
|
|
|
63769
64178
|
gps: GpsLocationSchema.nullable(),
|
|
63770
64179
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63771
64180
|
* when not reported. */
|
|
63772
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64181
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63773
64182
|
/** Ms epoch when the slice was last updated. */
|
|
63774
64183
|
lastChangedAt: number()
|
|
63775
64184
|
});
|
|
@@ -63819,19 +64228,10 @@ var presenceCapability = {
|
|
|
63819
64228
|
* `sourceInfo`.
|
|
63820
64229
|
*/
|
|
63821
64230
|
var PressureSensorStatusSchema = object({
|
|
63822
|
-
/** Current pressure in hPa. */
|
|
63823
|
-
hpa: number(),
|
|
64231
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64232
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63824
64233
|
/** Ms epoch when the slice was last updated. */
|
|
63825
|
-
lastFetchedAt: number()
|
|
63826
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63827
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63828
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63829
|
-
unit: string().optional(),
|
|
63830
|
-
/** Suggested decimal places for numeric display.
|
|
63831
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63832
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63833
|
-
* auto-formatting when absent. */
|
|
63834
|
-
precision: number().int().min(0).max(10).optional()
|
|
64234
|
+
lastFetchedAt: number()
|
|
63835
64235
|
});
|
|
63836
64236
|
var pressureSensorCapability = {
|
|
63837
64237
|
name: "pressure-sensor",
|
|
@@ -64245,8 +64645,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64245
64645
|
}), _void(), { kind: "mutation" });
|
|
64246
64646
|
var PtzAutotrackSettingsSchema = object({
|
|
64247
64647
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64248
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64249
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64648
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64649
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64250
64650
|
});
|
|
64251
64651
|
/**
|
|
64252
64652
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64400,7 +64800,7 @@ var RunningStateStatusSchema = object({
|
|
|
64400
64800
|
/** null = unknown — never coerced to false (D393). */
|
|
64401
64801
|
running: boolean().nullable(),
|
|
64402
64802
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64403
|
-
since: number().nullable(),
|
|
64803
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64404
64804
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64405
64805
|
phase: string().nullable(),
|
|
64406
64806
|
/** null until a reading has been published (D393). */
|
|
@@ -64415,7 +64815,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64415
64815
|
/** Generic Customize target for the running boolean (D936). */
|
|
64416
64816
|
var runningCustomize = {
|
|
64417
64817
|
version: 1,
|
|
64418
|
-
advanced: "derive",
|
|
64419
64818
|
targets: [{
|
|
64420
64819
|
id: "running",
|
|
64421
64820
|
cardinality: "scalar",
|
|
@@ -64435,7 +64834,7 @@ var runningCustomize = {
|
|
|
64435
64834
|
DeviceType.Thermostat,
|
|
64436
64835
|
DeviceType.PetFeeder
|
|
64437
64836
|
],
|
|
64438
|
-
apply: "add
|
|
64837
|
+
apply: "add",
|
|
64439
64838
|
path: "running",
|
|
64440
64839
|
sources: [
|
|
64441
64840
|
{
|
|
@@ -65699,9 +66098,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65699
66098
|
*/
|
|
65700
66099
|
var RecordWindowSchema = object({
|
|
65701
66100
|
trigger: RecordTriggerSchema,
|
|
65702
|
-
day: number().int().min(0).max(6),
|
|
65703
|
-
startMinute: number().int().min(0).max(1439),
|
|
65704
|
-
endMinute: number().int().min(1).max(1440)
|
|
66101
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66102
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66103
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65705
66104
|
});
|
|
65706
66105
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65707
66106
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65777,10 +66176,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65777
66176
|
/** Master "record to the card at all" switch. */
|
|
65778
66177
|
enabled: boolean().nullable(),
|
|
65779
66178
|
overwriteWhenFull: boolean().nullable(),
|
|
65780
|
-
preRecordSec: number().nullable(),
|
|
65781
|
-
postRecordSec: number().nullable(),
|
|
66179
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66180
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65782
66181
|
/** Length of one recorded file, in minutes. */
|
|
65783
|
-
segmentMinutes: number().nullable(),
|
|
66182
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65784
66183
|
/** The primary track's weekly windows, flattened. */
|
|
65785
66184
|
windows: array(RecordWindowSchema),
|
|
65786
66185
|
/**
|
|
@@ -65796,7 +66195,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65796
66195
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65797
66196
|
* writable.
|
|
65798
66197
|
*/
|
|
65799
|
-
unreadableWindows: number(),
|
|
66198
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65800
66199
|
/**
|
|
65801
66200
|
* The camera is scheduled to record and has NO usable storage.
|
|
65802
66201
|
*
|
|
@@ -66641,7 +67040,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66641
67040
|
url: string().optional(),
|
|
66642
67041
|
codec: string().optional(),
|
|
66643
67042
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66644
|
-
fps: number().positive().optional(),
|
|
67043
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66645
67044
|
label: string().optional(),
|
|
66646
67045
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66647
67046
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66728,18 +67127,18 @@ var StreamProfileSchema = _enum([
|
|
|
66728
67127
|
]);
|
|
66729
67128
|
/** The current encoding config of one stream profile. */
|
|
66730
67129
|
var StreamProfileConfigSchema = object({
|
|
66731
|
-
width: number(),
|
|
66732
|
-
height: number(),
|
|
67130
|
+
width: number().meta(readingMeta("none")),
|
|
67131
|
+
height: number().meta(readingMeta("none")),
|
|
66733
67132
|
codec: _enum(["h264", "h265"]),
|
|
66734
|
-
framerate: number(),
|
|
66735
|
-
bitrate: number(),
|
|
67133
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67134
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66736
67135
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66737
67136
|
encoderProfile: _enum([
|
|
66738
67137
|
"high",
|
|
66739
67138
|
"main",
|
|
66740
67139
|
"baseline"
|
|
66741
67140
|
]).optional(),
|
|
66742
|
-
gop: number().optional(),
|
|
67141
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66743
67142
|
/**
|
|
66744
67143
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66745
67144
|
*
|
|
@@ -66960,12 +67359,7 @@ var switchCapability = {
|
|
|
66960
67359
|
label: "On",
|
|
66961
67360
|
kind: "boolean"
|
|
66962
67361
|
}
|
|
66963
|
-
}] }
|
|
66964
|
-
customize: {
|
|
66965
|
-
version: 1,
|
|
66966
|
-
advanced: "derive",
|
|
66967
|
-
targets: []
|
|
66968
|
-
}
|
|
67362
|
+
}] }
|
|
66969
67363
|
};
|
|
66970
67364
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66971
67365
|
function hasControlCharacter(value) {
|
|
@@ -67548,35 +67942,21 @@ var tamperCapability = {
|
|
|
67548
67942
|
* entries with `device_class: temperature` and any future native
|
|
67549
67943
|
* thermometer.
|
|
67550
67944
|
*
|
|
67551
|
-
*
|
|
67552
|
-
*
|
|
67553
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67554
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67555
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67556
|
-
* `sourceInfo`.
|
|
67945
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67946
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67557
67947
|
*
|
|
67558
67948
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67559
67949
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67560
67950
|
* changed" steady state.
|
|
67561
67951
|
*/
|
|
67562
67952
|
var TemperatureSensorStatusSchema = object({
|
|
67563
|
-
/** Current temperature in Celsius. */
|
|
67564
|
-
celsius: number().meta({
|
|
67565
|
-
|
|
67953
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67954
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67955
|
+
precision: 1,
|
|
67566
67956
|
label: "Temperature"
|
|
67567
|
-
}),
|
|
67957
|
+
})),
|
|
67568
67958
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67569
|
-
lastFetchedAt: number()
|
|
67570
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67571
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67572
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67573
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67574
|
-
unit: string().optional(),
|
|
67575
|
-
/** Suggested decimal places for numeric display.
|
|
67576
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67577
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67578
|
-
* auto-formatting when absent. */
|
|
67579
|
-
precision: number().int().min(0).max(10).optional()
|
|
67959
|
+
lastFetchedAt: number()
|
|
67580
67960
|
});
|
|
67581
67961
|
var temperatureSensorCapability = {
|
|
67582
67962
|
name: "temperature-sensor",
|
|
@@ -67607,12 +67987,7 @@ var temperatureSensorCapability = {
|
|
|
67607
67987
|
} } },
|
|
67608
67988
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67609
67989
|
* whether persisting is worth a SQLite commit. */
|
|
67610
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67611
|
-
customize: {
|
|
67612
|
-
version: 1,
|
|
67613
|
-
advanced: "derive",
|
|
67614
|
-
targets: []
|
|
67615
|
-
}
|
|
67990
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67616
67991
|
};
|
|
67617
67992
|
/**
|
|
67618
67993
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67895,16 +68270,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67895
68270
|
]),
|
|
67896
68271
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67897
68272
|
* reading. */
|
|
67898
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68273
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67899
68274
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67900
68275
|
* the vacuum has no speed control. */
|
|
67901
68276
|
fanSpeed: string().nullable(),
|
|
67902
68277
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67903
68278
|
availableFanSpeeds: array(string()),
|
|
67904
68279
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67905
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68280
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67906
68281
|
/** Current error code (0 / null = no error). */
|
|
67907
|
-
errorCode: number().nullable(),
|
|
68282
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67908
68283
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67909
68284
|
errorLabel: string().nullable(),
|
|
67910
68285
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67982,7 +68357,7 @@ var ValveStatusSchema = object({
|
|
|
67982
68357
|
]),
|
|
67983
68358
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67984
68359
|
* intermediate position surface. */
|
|
67985
|
-
position: number().min(0).max(100).nullable(),
|
|
68360
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67986
68361
|
/** Ms epoch when the slice was last updated. */
|
|
67987
68362
|
lastChangedAt: number()
|
|
67988
68363
|
});
|
|
@@ -68090,9 +68465,9 @@ var vibrationCapability = {
|
|
|
68090
68465
|
*/
|
|
68091
68466
|
var WaterHeaterStatusSchema = object({
|
|
68092
68467
|
/** Current measured temperature. Null when not reported. */
|
|
68093
|
-
currentTemp: number().nullable(),
|
|
68468
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68094
68469
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68095
|
-
targetTemp: number().nullable(),
|
|
68470
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68096
68471
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68097
68472
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68098
68473
|
* device reports an unknown state. */
|
|
@@ -68103,9 +68478,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68103
68478
|
* has no away surface. */
|
|
68104
68479
|
away: boolean().nullable(),
|
|
68105
68480
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68106
|
-
minTemp: number().nullable(),
|
|
68481
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68107
68482
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68108
|
-
maxTemp: number().nullable(),
|
|
68483
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68109
68484
|
/** Ms epoch when the slice was last updated. */
|
|
68110
68485
|
lastChangedAt: number()
|
|
68111
68486
|
});
|
|
@@ -68190,25 +68565,18 @@ var waterHeaterCapability = {
|
|
|
68190
68565
|
* Forecast deferred — current conditions only for v1.
|
|
68191
68566
|
*/
|
|
68192
68567
|
var WeatherStatusSchema = object({
|
|
68193
|
-
/** Verbatim
|
|
68194
|
-
* when no condition has been reported yet. */
|
|
68568
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68195
68569
|
condition: string().nullable(),
|
|
68196
|
-
/** Current temperature in
|
|
68197
|
-
temperature: number().nullable(),
|
|
68198
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68199
|
-
temperatureUnit: string().nullable(),
|
|
68570
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68571
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68200
68572
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68201
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68202
|
-
/** Barometric pressure in
|
|
68203
|
-
pressure: number().nullable(),
|
|
68204
|
-
/**
|
|
68205
|
-
|
|
68206
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68207
|
-
windSpeed: number().nullable(),
|
|
68208
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68209
|
-
windSpeedUnit: string().nullable(),
|
|
68573
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68574
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68575
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68576
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68577
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68210
68578
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68211
|
-
windBearing: number().nullable(),
|
|
68579
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68212
68580
|
/** Ms epoch when the slice was last updated. */
|
|
68213
68581
|
lastFetchedAt: number()
|
|
68214
68582
|
});
|
|
@@ -68236,12 +68604,12 @@ var weatherCapability = {
|
|
|
68236
68604
|
*/
|
|
68237
68605
|
durability: "session",
|
|
68238
68606
|
/**
|
|
68239
|
-
* History (D850): recorded series.
|
|
68607
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68240
68608
|
*/
|
|
68241
68609
|
history: { fields: {
|
|
68242
68610
|
temperature: {
|
|
68243
68611
|
kind: "gauge",
|
|
68244
|
-
|
|
68612
|
+
unit: "°C",
|
|
68245
68613
|
deadband: .2
|
|
68246
68614
|
},
|
|
68247
68615
|
humidity: {
|
|
@@ -68251,12 +68619,12 @@ var weatherCapability = {
|
|
|
68251
68619
|
},
|
|
68252
68620
|
pressure: {
|
|
68253
68621
|
kind: "gauge",
|
|
68254
|
-
|
|
68622
|
+
unit: "hPa",
|
|
68255
68623
|
deadband: .5
|
|
68256
68624
|
},
|
|
68257
68625
|
windSpeed: {
|
|
68258
68626
|
kind: "gauge",
|
|
68259
|
-
|
|
68627
|
+
unit: "m/s",
|
|
68260
68628
|
deadband: .5
|
|
68261
68629
|
}
|
|
68262
68630
|
} }
|
|
@@ -69487,6 +69855,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69487
69855
|
featureProbe: featureProbeCapability,
|
|
69488
69856
|
flood: floodCapability,
|
|
69489
69857
|
gas: gasCapability,
|
|
69858
|
+
groupCommands: groupCommandsCapability,
|
|
69859
|
+
groupStatus: groupStatusCapability,
|
|
69490
69860
|
heatingValve: heatingValveCapability,
|
|
69491
69861
|
humidifier: humidifierCapability,
|
|
69492
69862
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70863,6 +71233,13 @@ Object.freeze({
|
|
|
70863
71233
|
access: "view",
|
|
70864
71234
|
role: "admin"
|
|
70865
71235
|
},
|
|
71236
|
+
"addons.getPackageDocs": {
|
|
71237
|
+
capName: "addons",
|
|
71238
|
+
capScope: "system",
|
|
71239
|
+
addonId: null,
|
|
71240
|
+
access: "view",
|
|
71241
|
+
role: "admin"
|
|
71242
|
+
},
|
|
70866
71243
|
"addons.getVersions": {
|
|
70867
71244
|
capName: "addons",
|
|
70868
71245
|
capScope: "system",
|
|
@@ -73971,6 +74348,20 @@ Object.freeze({
|
|
|
73971
74348
|
access: "view",
|
|
73972
74349
|
role: "viewer"
|
|
73973
74350
|
},
|
|
74351
|
+
"groupCommands.getStatus": {
|
|
74352
|
+
capName: "group-commands",
|
|
74353
|
+
capScope: "device",
|
|
74354
|
+
addonId: null,
|
|
74355
|
+
access: "view",
|
|
74356
|
+
role: "viewer"
|
|
74357
|
+
},
|
|
74358
|
+
"groupStatus.getStatus": {
|
|
74359
|
+
capName: "group-status",
|
|
74360
|
+
capScope: "device",
|
|
74361
|
+
addonId: null,
|
|
74362
|
+
access: "view",
|
|
74363
|
+
role: "viewer"
|
|
74364
|
+
},
|
|
73974
74365
|
"heatingValve.getStatus": {
|
|
73975
74366
|
capName: "heating-valve",
|
|
73976
74367
|
capScope: "device",
|
|
@@ -83793,6 +84184,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83793
84184
|
icon: "flame"
|
|
83794
84185
|
}]
|
|
83795
84186
|
},
|
|
84187
|
+
"group-commands": {
|
|
84188
|
+
scope: "device",
|
|
84189
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84190
|
+
},
|
|
84191
|
+
"group-status": {
|
|
84192
|
+
scope: "device",
|
|
84193
|
+
noun: t("Group", "Gruppo"),
|
|
84194
|
+
state: [
|
|
84195
|
+
{
|
|
84196
|
+
kind: "numeric",
|
|
84197
|
+
field: "included",
|
|
84198
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84199
|
+
label: t("Reporting", "Rispondono"),
|
|
84200
|
+
icon: "users"
|
|
84201
|
+
},
|
|
84202
|
+
{
|
|
84203
|
+
kind: "numeric",
|
|
84204
|
+
field: "excluded",
|
|
84205
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84206
|
+
label: t("Excluded", "Esclusi"),
|
|
84207
|
+
icon: "users"
|
|
84208
|
+
},
|
|
84209
|
+
{
|
|
84210
|
+
kind: "numeric",
|
|
84211
|
+
field: "total",
|
|
84212
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84213
|
+
label: t("Members", "Membri"),
|
|
84214
|
+
icon: "sigma"
|
|
84215
|
+
}
|
|
84216
|
+
]
|
|
84217
|
+
},
|
|
83796
84218
|
"humidity-sensor": {
|
|
83797
84219
|
scope: "device",
|
|
83798
84220
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83826,7 +84248,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83826
84248
|
field: "value",
|
|
83827
84249
|
quantity: t("the reading", "il valore"),
|
|
83828
84250
|
label: t("Reading", "Valore"),
|
|
83829
|
-
unitField: "unit",
|
|
83830
84251
|
icon: "gauge"
|
|
83831
84252
|
}]
|
|
83832
84253
|
},
|
|
@@ -83962,7 +84383,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83962
84383
|
field: "temperature",
|
|
83963
84384
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83964
84385
|
label: t("Temperature", "Temperatura"),
|
|
83965
|
-
|
|
84386
|
+
unit: "°C",
|
|
83966
84387
|
icon: "thermometer"
|
|
83967
84388
|
},
|
|
83968
84389
|
{
|
|
@@ -83978,7 +84399,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83978
84399
|
field: "windSpeed",
|
|
83979
84400
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83980
84401
|
label: t("Wind", "Vento"),
|
|
83981
|
-
|
|
84402
|
+
unit: "m/s",
|
|
83982
84403
|
icon: "wind"
|
|
83983
84404
|
},
|
|
83984
84405
|
{
|
|
@@ -83986,7 +84407,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83986
84407
|
field: "pressure",
|
|
83987
84408
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83988
84409
|
label: t("Pressure", "Pressione"),
|
|
83989
|
-
|
|
84410
|
+
unit: "hPa",
|
|
83990
84411
|
icon: "gauge"
|
|
83991
84412
|
}
|
|
83992
84413
|
]
|
|
@@ -85325,6 +85746,16 @@ Object.freeze({
|
|
|
85325
85746
|
form: "single",
|
|
85326
85747
|
optional: false
|
|
85327
85748
|
}],
|
|
85749
|
+
"groupCommands.getStatus": [{
|
|
85750
|
+
name: "deviceId",
|
|
85751
|
+
form: "single",
|
|
85752
|
+
optional: false
|
|
85753
|
+
}],
|
|
85754
|
+
"groupStatus.getStatus": [{
|
|
85755
|
+
name: "deviceId",
|
|
85756
|
+
form: "single",
|
|
85757
|
+
optional: false
|
|
85758
|
+
}],
|
|
85328
85759
|
"heatingValve.getStatus": [{
|
|
85329
85760
|
name: "deviceId",
|
|
85330
85761
|
form: "single",
|
|
@@ -87309,6 +87740,8 @@ new Map(Object.entries({
|
|
|
87309
87740
|
"detection-blind": "device-events",
|
|
87310
87741
|
"motion-noisy": "device-events",
|
|
87311
87742
|
"motion-calm": "device-events",
|
|
87743
|
+
"package-llm-silent": "device-events",
|
|
87744
|
+
"package-llm-answered": "device-events",
|
|
87312
87745
|
"recording-stalled": "device-events",
|
|
87313
87746
|
"recording-healthy": "device-events",
|
|
87314
87747
|
"recording-degraded": "device-events",
|
|
@@ -87392,6 +87825,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87392
87825
|
label: "Motion without a subject",
|
|
87393
87826
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87394
87827
|
},
|
|
87828
|
+
{
|
|
87829
|
+
id: "package-llm",
|
|
87830
|
+
family: "device-events",
|
|
87831
|
+
label: "Package confirm",
|
|
87832
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87833
|
+
},
|
|
87395
87834
|
{
|
|
87396
87835
|
id: "recording",
|
|
87397
87836
|
family: "device-events",
|
|
@@ -87573,6 +88012,8 @@ var DEVICE_EVENTS = [
|
|
|
87573
88012
|
"detection-blind",
|
|
87574
88013
|
"motion-noisy",
|
|
87575
88014
|
"motion-calm",
|
|
88015
|
+
"package-llm-silent",
|
|
88016
|
+
"package-llm-answered",
|
|
87576
88017
|
"recording-stalled",
|
|
87577
88018
|
"recording-healthy",
|
|
87578
88019
|
"recording-degraded",
|
|
@@ -87841,6 +88282,15 @@ new Map([
|
|
|
87841
88282
|
snapshotLabel: "Cameras with constant motion now",
|
|
87842
88283
|
snapshotSection: null
|
|
87843
88284
|
},
|
|
88285
|
+
{
|
|
88286
|
+
id: "package-llm-confirm",
|
|
88287
|
+
family: "device-events",
|
|
88288
|
+
label: "Package confirm (not answering / answering again)",
|
|
88289
|
+
bad: ["package-llm-silent"],
|
|
88290
|
+
recovery: ["package-llm-answered"],
|
|
88291
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88292
|
+
snapshotSection: null
|
|
88293
|
+
},
|
|
87844
88294
|
{
|
|
87845
88295
|
id: "recording-health",
|
|
87846
88296
|
family: "device-events",
|