@camstack/addon-matter-broker 0.2.147 → 0.2.149
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 +18 -0
- package/dist/addon.js +959 -510
- package/dist/addon.mjs +959 -510
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -13,7 +13,7 @@ let node_stream_promises = require("node:stream/promises");
|
|
|
13
13
|
let node_net = require("node:net");
|
|
14
14
|
let node_dgram = require("node:dgram");
|
|
15
15
|
node_dgram = require_esm.__toESM(node_dgram, 1);
|
|
16
|
-
//#region ../types/dist/event-category-
|
|
16
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
17
17
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
18
18
|
EventCategory["SystemBoot"] = "system.boot";
|
|
19
19
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -339,6 +339,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
339
339
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
340
340
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
341
341
|
/**
|
|
342
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
343
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
344
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
345
|
+
*/
|
|
346
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
347
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
348
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
349
|
+
/**
|
|
342
350
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
343
351
|
* (a settings change via `setAgentInferenceDevices` /
|
|
344
352
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5581,7 +5589,7 @@ var ZodIssueCode = {
|
|
|
5581
5589
|
var ZodFirstPartyTypeKind;
|
|
5582
5590
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5583
5591
|
//#endregion
|
|
5584
|
-
//#region ../types/dist/sleep-
|
|
5592
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5585
5593
|
/**
|
|
5586
5594
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5587
5595
|
* window to float samples (D455).
|
|
@@ -8323,6 +8331,99 @@ function defineEntryKind(name, spec) {
|
|
|
8323
8331
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8324
8332
|
return defined;
|
|
8325
8333
|
}
|
|
8334
|
+
var READING_QUANTITIES = [
|
|
8335
|
+
"temperature",
|
|
8336
|
+
"pressure",
|
|
8337
|
+
"speed",
|
|
8338
|
+
"precipitation",
|
|
8339
|
+
"precipitation-rate",
|
|
8340
|
+
"length",
|
|
8341
|
+
"area",
|
|
8342
|
+
"illuminance",
|
|
8343
|
+
"irradiance",
|
|
8344
|
+
"power",
|
|
8345
|
+
"energy",
|
|
8346
|
+
"voltage",
|
|
8347
|
+
"current",
|
|
8348
|
+
"apparent-power",
|
|
8349
|
+
"humidity",
|
|
8350
|
+
"percentage",
|
|
8351
|
+
"concentration-volume",
|
|
8352
|
+
"concentration-mass",
|
|
8353
|
+
"concentration-ppb",
|
|
8354
|
+
"volume",
|
|
8355
|
+
"duration",
|
|
8356
|
+
"duration-ms",
|
|
8357
|
+
"information",
|
|
8358
|
+
"sound-level",
|
|
8359
|
+
"signal-level",
|
|
8360
|
+
"colour-temperature",
|
|
8361
|
+
"angle",
|
|
8362
|
+
"bitrate",
|
|
8363
|
+
"rate",
|
|
8364
|
+
"mass",
|
|
8365
|
+
"index",
|
|
8366
|
+
"ratio",
|
|
8367
|
+
"count",
|
|
8368
|
+
"none",
|
|
8369
|
+
"device"
|
|
8370
|
+
];
|
|
8371
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8372
|
+
new Set(READING_QUANTITIES);
|
|
8373
|
+
/**
|
|
8374
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8375
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8376
|
+
*/
|
|
8377
|
+
var QUANTITY_BASE = {
|
|
8378
|
+
temperature: "°C",
|
|
8379
|
+
pressure: "hPa",
|
|
8380
|
+
speed: "m/s",
|
|
8381
|
+
precipitation: "mm",
|
|
8382
|
+
"precipitation-rate": "mm/h",
|
|
8383
|
+
length: "m",
|
|
8384
|
+
area: "m²",
|
|
8385
|
+
illuminance: "lx",
|
|
8386
|
+
irradiance: "W/m²",
|
|
8387
|
+
power: "W",
|
|
8388
|
+
energy: "kWh",
|
|
8389
|
+
voltage: "V",
|
|
8390
|
+
current: "A",
|
|
8391
|
+
"apparent-power": "VA",
|
|
8392
|
+
humidity: "%",
|
|
8393
|
+
percentage: "%",
|
|
8394
|
+
"concentration-volume": "ppm",
|
|
8395
|
+
"concentration-mass": "µg/m³",
|
|
8396
|
+
"concentration-ppb": "ppb",
|
|
8397
|
+
volume: "L",
|
|
8398
|
+
duration: "s",
|
|
8399
|
+
"duration-ms": "ms",
|
|
8400
|
+
information: "B",
|
|
8401
|
+
"sound-level": "dBFS",
|
|
8402
|
+
"signal-level": "dBm",
|
|
8403
|
+
"colour-temperature": "mired",
|
|
8404
|
+
angle: "°",
|
|
8405
|
+
bitrate: "kbps",
|
|
8406
|
+
rate: "fps",
|
|
8407
|
+
mass: "kg",
|
|
8408
|
+
index: "none",
|
|
8409
|
+
ratio: "none",
|
|
8410
|
+
count: "none",
|
|
8411
|
+
none: "none",
|
|
8412
|
+
device: "device"
|
|
8413
|
+
};
|
|
8414
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8415
|
+
function baseUnitOf(quantity) {
|
|
8416
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8417
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8418
|
+
return symbol;
|
|
8419
|
+
}
|
|
8420
|
+
function readingMeta(quantity, extras) {
|
|
8421
|
+
return {
|
|
8422
|
+
quantity,
|
|
8423
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8424
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8425
|
+
};
|
|
8426
|
+
}
|
|
8326
8427
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8327
8428
|
var CamProfileSchema = _enum([
|
|
8328
8429
|
"high",
|
|
@@ -8350,8 +8451,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8350
8451
|
"derived"
|
|
8351
8452
|
]);
|
|
8352
8453
|
var CamStreamResolutionSchema = object({
|
|
8353
|
-
width: number().int().positive(),
|
|
8354
|
-
height: number().int().positive()
|
|
8454
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8455
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8355
8456
|
});
|
|
8356
8457
|
var CameraStreamSchema = object({
|
|
8357
8458
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8869,6 +8970,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8869
8970
|
"filesystem-browse",
|
|
8870
8971
|
"flood",
|
|
8871
8972
|
"gas",
|
|
8973
|
+
"group-commands",
|
|
8974
|
+
"group-status",
|
|
8872
8975
|
"heating-valve",
|
|
8873
8976
|
"humidifier",
|
|
8874
8977
|
"humidity-sensor",
|
|
@@ -8998,14 +9101,6 @@ Object.freeze({
|
|
|
8998
9101
|
{
|
|
8999
9102
|
"path": "aqi",
|
|
9000
9103
|
"valueType": "number"
|
|
9001
|
-
},
|
|
9002
|
-
{
|
|
9003
|
-
"path": "unit",
|
|
9004
|
-
"valueType": "string"
|
|
9005
|
-
},
|
|
9006
|
-
{
|
|
9007
|
-
"path": "precision",
|
|
9008
|
-
"valueType": "number"
|
|
9009
9104
|
}
|
|
9010
9105
|
],
|
|
9011
9106
|
"alarm-panel": [
|
|
@@ -9041,20 +9136,10 @@ Object.freeze({
|
|
|
9041
9136
|
"valueType": "boolean"
|
|
9042
9137
|
}
|
|
9043
9138
|
],
|
|
9044
|
-
"ambient-light-sensor": [
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
},
|
|
9049
|
-
{
|
|
9050
|
-
"path": "unit",
|
|
9051
|
-
"valueType": "string"
|
|
9052
|
-
},
|
|
9053
|
-
{
|
|
9054
|
-
"path": "precision",
|
|
9055
|
-
"valueType": "number"
|
|
9056
|
-
}
|
|
9057
|
-
],
|
|
9139
|
+
"ambient-light-sensor": [{
|
|
9140
|
+
"path": "lux",
|
|
9141
|
+
"valueType": "number"
|
|
9142
|
+
}],
|
|
9058
9143
|
"audio-metrics": [
|
|
9059
9144
|
{
|
|
9060
9145
|
"path": "ts",
|
|
@@ -9134,6 +9219,10 @@ Object.freeze({
|
|
|
9134
9219
|
"path": "lastUpdated",
|
|
9135
9220
|
"valueType": "number"
|
|
9136
9221
|
},
|
|
9222
|
+
{
|
|
9223
|
+
"path": "volts",
|
|
9224
|
+
"valueType": "number"
|
|
9225
|
+
},
|
|
9137
9226
|
{
|
|
9138
9227
|
"path": "lastContactAt",
|
|
9139
9228
|
"valueType": "number"
|
|
@@ -9376,10 +9465,6 @@ Object.freeze({
|
|
|
9376
9465
|
"datetime"
|
|
9377
9466
|
]
|
|
9378
9467
|
},
|
|
9379
|
-
{
|
|
9380
|
-
"path": "unit",
|
|
9381
|
-
"valueType": "string"
|
|
9382
|
-
},
|
|
9383
9468
|
{
|
|
9384
9469
|
"path": "min",
|
|
9385
9470
|
"valueType": "number"
|
|
@@ -9391,19 +9476,6 @@ Object.freeze({
|
|
|
9391
9476
|
{
|
|
9392
9477
|
"path": "step",
|
|
9393
9478
|
"valueType": "number"
|
|
9394
|
-
},
|
|
9395
|
-
{
|
|
9396
|
-
"path": "precision",
|
|
9397
|
-
"valueType": "number"
|
|
9398
|
-
},
|
|
9399
|
-
{
|
|
9400
|
-
"path": "format",
|
|
9401
|
-
"valueType": "enum",
|
|
9402
|
-
"enumValues": [
|
|
9403
|
-
"date",
|
|
9404
|
-
"time",
|
|
9405
|
-
"datetime"
|
|
9406
|
-
]
|
|
9407
9479
|
}
|
|
9408
9480
|
],
|
|
9409
9481
|
"cover": [
|
|
@@ -9644,13 +9716,8 @@ Object.freeze({
|
|
|
9644
9716
|
"path": "value",
|
|
9645
9717
|
"valueType": "string"
|
|
9646
9718
|
}, {
|
|
9647
|
-
"path": "
|
|
9648
|
-
"valueType": "
|
|
9649
|
-
"enumValues": [
|
|
9650
|
-
"date",
|
|
9651
|
-
"time",
|
|
9652
|
-
"datetime"
|
|
9653
|
-
]
|
|
9719
|
+
"path": "timestamp",
|
|
9720
|
+
"valueType": "boolean"
|
|
9654
9721
|
}],
|
|
9655
9722
|
"event-emitter": [
|
|
9656
9723
|
{
|
|
@@ -9723,6 +9790,20 @@ Object.freeze({
|
|
|
9723
9790
|
"path": "detected",
|
|
9724
9791
|
"valueType": "boolean"
|
|
9725
9792
|
}],
|
|
9793
|
+
"group-status": [
|
|
9794
|
+
{
|
|
9795
|
+
"path": "included",
|
|
9796
|
+
"valueType": "number"
|
|
9797
|
+
},
|
|
9798
|
+
{
|
|
9799
|
+
"path": "excluded",
|
|
9800
|
+
"valueType": "number"
|
|
9801
|
+
},
|
|
9802
|
+
{
|
|
9803
|
+
"path": "total",
|
|
9804
|
+
"valueType": "number"
|
|
9805
|
+
}
|
|
9806
|
+
],
|
|
9726
9807
|
"heating-valve": [{
|
|
9727
9808
|
"path": "position",
|
|
9728
9809
|
"valueType": "number"
|
|
@@ -9757,20 +9838,10 @@ Object.freeze({
|
|
|
9757
9838
|
"valueType": "number"
|
|
9758
9839
|
}
|
|
9759
9840
|
],
|
|
9760
|
-
"humidity-sensor": [
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
},
|
|
9765
|
-
{
|
|
9766
|
-
"path": "unit",
|
|
9767
|
-
"valueType": "string"
|
|
9768
|
-
},
|
|
9769
|
-
{
|
|
9770
|
-
"path": "precision",
|
|
9771
|
-
"valueType": "number"
|
|
9772
|
-
}
|
|
9773
|
-
],
|
|
9841
|
+
"humidity-sensor": [{
|
|
9842
|
+
"path": "percent",
|
|
9843
|
+
"valueType": "number"
|
|
9844
|
+
}],
|
|
9774
9845
|
"image": [{
|
|
9775
9846
|
"path": "url",
|
|
9776
9847
|
"valueType": "string"
|
|
@@ -10109,20 +10180,10 @@ Object.freeze({
|
|
|
10109
10180
|
"valueType": "boolean"
|
|
10110
10181
|
}
|
|
10111
10182
|
],
|
|
10112
|
-
"numeric-sensor": [
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
},
|
|
10117
|
-
{
|
|
10118
|
-
"path": "unit",
|
|
10119
|
-
"valueType": "string"
|
|
10120
|
-
},
|
|
10121
|
-
{
|
|
10122
|
-
"path": "precision",
|
|
10123
|
-
"valueType": "number"
|
|
10124
|
-
}
|
|
10125
|
-
],
|
|
10183
|
+
"numeric-sensor": [{
|
|
10184
|
+
"path": "value",
|
|
10185
|
+
"valueType": "number"
|
|
10186
|
+
}],
|
|
10126
10187
|
"pet-feeder": [
|
|
10127
10188
|
{
|
|
10128
10189
|
"path": "foodLevel",
|
|
@@ -10214,14 +10275,6 @@ Object.freeze({
|
|
|
10214
10275
|
{
|
|
10215
10276
|
"path": "powerFactor",
|
|
10216
10277
|
"valueType": "number"
|
|
10217
|
-
},
|
|
10218
|
-
{
|
|
10219
|
-
"path": "unit",
|
|
10220
|
-
"valueType": "string"
|
|
10221
|
-
},
|
|
10222
|
-
{
|
|
10223
|
-
"path": "precision",
|
|
10224
|
-
"valueType": "number"
|
|
10225
10278
|
}
|
|
10226
10279
|
],
|
|
10227
10280
|
"presence": [
|
|
@@ -10250,20 +10303,10 @@ Object.freeze({
|
|
|
10250
10303
|
"valueType": "number"
|
|
10251
10304
|
}
|
|
10252
10305
|
],
|
|
10253
|
-
"pressure-sensor": [
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
},
|
|
10258
|
-
{
|
|
10259
|
-
"path": "unit",
|
|
10260
|
-
"valueType": "string"
|
|
10261
|
-
},
|
|
10262
|
-
{
|
|
10263
|
-
"path": "precision",
|
|
10264
|
-
"valueType": "number"
|
|
10265
|
-
}
|
|
10266
|
-
],
|
|
10306
|
+
"pressure-sensor": [{
|
|
10307
|
+
"path": "hpa",
|
|
10308
|
+
"valueType": "number"
|
|
10309
|
+
}],
|
|
10267
10310
|
"privacy-mask": [{
|
|
10268
10311
|
"path": "enabled",
|
|
10269
10312
|
"valueType": "boolean"
|
|
@@ -10574,20 +10617,10 @@ Object.freeze({
|
|
|
10574
10617
|
"path": "tampered",
|
|
10575
10618
|
"valueType": "boolean"
|
|
10576
10619
|
}],
|
|
10577
|
-
"temperature-sensor": [
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
},
|
|
10582
|
-
{
|
|
10583
|
-
"path": "unit",
|
|
10584
|
-
"valueType": "string"
|
|
10585
|
-
},
|
|
10586
|
-
{
|
|
10587
|
-
"path": "precision",
|
|
10588
|
-
"valueType": "number"
|
|
10589
|
-
}
|
|
10590
|
-
],
|
|
10620
|
+
"temperature-sensor": [{
|
|
10621
|
+
"path": "celsius",
|
|
10622
|
+
"valueType": "number"
|
|
10623
|
+
}],
|
|
10591
10624
|
"update": [
|
|
10592
10625
|
{
|
|
10593
10626
|
"path": "currentVersion",
|
|
@@ -10698,10 +10731,6 @@ Object.freeze({
|
|
|
10698
10731
|
"path": "temperature",
|
|
10699
10732
|
"valueType": "number"
|
|
10700
10733
|
},
|
|
10701
|
-
{
|
|
10702
|
-
"path": "temperatureUnit",
|
|
10703
|
-
"valueType": "string"
|
|
10704
|
-
},
|
|
10705
10734
|
{
|
|
10706
10735
|
"path": "humidity",
|
|
10707
10736
|
"valueType": "number"
|
|
@@ -10710,18 +10739,10 @@ Object.freeze({
|
|
|
10710
10739
|
"path": "pressure",
|
|
10711
10740
|
"valueType": "number"
|
|
10712
10741
|
},
|
|
10713
|
-
{
|
|
10714
|
-
"path": "pressureUnit",
|
|
10715
|
-
"valueType": "string"
|
|
10716
|
-
},
|
|
10717
10742
|
{
|
|
10718
10743
|
"path": "windSpeed",
|
|
10719
10744
|
"valueType": "number"
|
|
10720
10745
|
},
|
|
10721
|
-
{
|
|
10722
|
-
"path": "windSpeedUnit",
|
|
10723
|
-
"valueType": "string"
|
|
10724
|
-
},
|
|
10725
10746
|
{
|
|
10726
10747
|
"path": "windBearing",
|
|
10727
10748
|
"valueType": "number"
|
|
@@ -11124,7 +11145,7 @@ function errMsg(err) {
|
|
|
11124
11145
|
return String(err);
|
|
11125
11146
|
}
|
|
11126
11147
|
//#endregion
|
|
11127
|
-
//#region ../types/dist/composition-
|
|
11148
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11128
11149
|
/**
|
|
11129
11150
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11130
11151
|
*
|
|
@@ -11879,15 +11900,74 @@ function validateExpressionSource(src) {
|
|
|
11879
11900
|
}
|
|
11880
11901
|
return null;
|
|
11881
11902
|
}
|
|
11882
|
-
/**
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11903
|
+
/**
|
|
11904
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11905
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11906
|
+
* `composition.ts` (D659).
|
|
11907
|
+
*/
|
|
11886
11908
|
var CompositionSourceRefSchema = object({
|
|
11887
11909
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11888
11910
|
addonId: string$2().min(1),
|
|
11889
11911
|
stableId: string$2().min(1)
|
|
11890
11912
|
});
|
|
11913
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11914
|
+
"temperature",
|
|
11915
|
+
"humidity",
|
|
11916
|
+
"pressure",
|
|
11917
|
+
"illuminance",
|
|
11918
|
+
"power",
|
|
11919
|
+
"energy",
|
|
11920
|
+
"battery",
|
|
11921
|
+
"numeric",
|
|
11922
|
+
"motion",
|
|
11923
|
+
"contact",
|
|
11924
|
+
"leak",
|
|
11925
|
+
"smoke",
|
|
11926
|
+
"occupancy",
|
|
11927
|
+
"binary",
|
|
11928
|
+
"switch",
|
|
11929
|
+
"light"
|
|
11930
|
+
];
|
|
11931
|
+
var NUMERIC_AGGREGATES = [
|
|
11932
|
+
"mean",
|
|
11933
|
+
"median",
|
|
11934
|
+
"min",
|
|
11935
|
+
"max",
|
|
11936
|
+
"sum"
|
|
11937
|
+
];
|
|
11938
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11939
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11940
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11941
|
+
var AGGREGATE_REDUCERS = [
|
|
11942
|
+
"mean",
|
|
11943
|
+
"median",
|
|
11944
|
+
"min",
|
|
11945
|
+
"max",
|
|
11946
|
+
"sum",
|
|
11947
|
+
"any",
|
|
11948
|
+
"all"
|
|
11949
|
+
];
|
|
11950
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11951
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11952
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11953
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11954
|
+
var HelperMemberSchema = object({
|
|
11955
|
+
source: CompositionSourceRefSchema,
|
|
11956
|
+
cap: string$2().min(1),
|
|
11957
|
+
fieldPath: string$2().min(1)
|
|
11958
|
+
});
|
|
11959
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11960
|
+
kind: literal("group"),
|
|
11961
|
+
templateId: GroupTemplateIdSchema,
|
|
11962
|
+
aggregate: AggregateReducerSchema,
|
|
11963
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11964
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11965
|
+
active: ActiveCriterionSchema.optional()
|
|
11966
|
+
})]);
|
|
11967
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11968
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11969
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11970
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11891
11971
|
/** One field of one capability of one source device. */
|
|
11892
11972
|
var CompositionFieldReadSchema = object({
|
|
11893
11973
|
source: CompositionSourceRefSchema,
|
|
@@ -11931,7 +12011,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11931
12011
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11932
12012
|
CompositionFromSourceSchema,
|
|
11933
12013
|
CompositionExpressionSourceSchema,
|
|
11934
|
-
CompositionCodeSourceSchema
|
|
12014
|
+
CompositionCodeSourceSchema,
|
|
12015
|
+
object({
|
|
12016
|
+
kind: literal("aggregate"),
|
|
12017
|
+
reducer: _enum([
|
|
12018
|
+
"mean",
|
|
12019
|
+
"median",
|
|
12020
|
+
"min",
|
|
12021
|
+
"max",
|
|
12022
|
+
"sum",
|
|
12023
|
+
"any",
|
|
12024
|
+
"all"
|
|
12025
|
+
]),
|
|
12026
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12027
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12028
|
+
publish: _enum([
|
|
12029
|
+
"value",
|
|
12030
|
+
"included",
|
|
12031
|
+
"excluded",
|
|
12032
|
+
"total"
|
|
12033
|
+
]),
|
|
12034
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12035
|
+
empty: _enum([
|
|
12036
|
+
"null",
|
|
12037
|
+
"omit",
|
|
12038
|
+
"offline"
|
|
12039
|
+
])
|
|
12040
|
+
})
|
|
11935
12041
|
]);
|
|
11936
12042
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11937
12043
|
kind: literal("forward"),
|
|
@@ -11977,7 +12083,13 @@ var CompositionSchema = object({
|
|
|
11977
12083
|
kind: literal("existing"),
|
|
11978
12084
|
device: CompositionSourceRefSchema
|
|
11979
12085
|
})]),
|
|
11980
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12086
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12087
|
+
/**
|
|
12088
|
+
* Present when the block is a helper template. Absent on a free
|
|
12089
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12090
|
+
* never the compiled features.
|
|
12091
|
+
*/
|
|
12092
|
+
helper: HelperSpecSchema.optional()
|
|
11981
12093
|
}).superRefine((composition, ctx) => {
|
|
11982
12094
|
const seen = /* @__PURE__ */ new Set();
|
|
11983
12095
|
composition.features.forEach((feature, index) => {
|
|
@@ -18234,7 +18346,11 @@ var CompositionProblemSchema = object({
|
|
|
18234
18346
|
"item-field-reserved",
|
|
18235
18347
|
"target-missing",
|
|
18236
18348
|
"target-unreadable",
|
|
18237
|
-
"not-replaceable"
|
|
18349
|
+
"not-replaceable",
|
|
18350
|
+
"native-capability-replace",
|
|
18351
|
+
"mixed-quantity",
|
|
18352
|
+
"helper-mismatch",
|
|
18353
|
+
"member-constraint"
|
|
18238
18354
|
]),
|
|
18239
18355
|
path: string$2(),
|
|
18240
18356
|
message: string$2()
|
|
@@ -18255,7 +18371,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18255
18371
|
"null",
|
|
18256
18372
|
"offline",
|
|
18257
18373
|
"unknown",
|
|
18258
|
-
"release"
|
|
18374
|
+
"release",
|
|
18375
|
+
"omit"
|
|
18259
18376
|
]);
|
|
18260
18377
|
/**
|
|
18261
18378
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18292,9 +18409,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18292
18409
|
reads: array(CompositionFieldReadSchema)
|
|
18293
18410
|
});
|
|
18294
18411
|
/**
|
|
18295
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18296
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18297
|
-
*
|
|
18412
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18413
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18414
|
+
* Replacing a capability the device already serves is refused
|
|
18415
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18416
|
+
* wire for a claim the hub already holds.
|
|
18298
18417
|
*/
|
|
18299
18418
|
var CompositionFeatureModeSchema = _enum([
|
|
18300
18419
|
"new",
|
|
@@ -18467,6 +18586,275 @@ Object.freeze({
|
|
|
18467
18586
|
result: ["number", "null"]
|
|
18468
18587
|
}
|
|
18469
18588
|
});
|
|
18589
|
+
/**
|
|
18590
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18591
|
+
* Data, not a form default written into the block.
|
|
18592
|
+
*/
|
|
18593
|
+
var NOW = {
|
|
18594
|
+
fieldPath: "lastFetchedAt",
|
|
18595
|
+
expr: "now"
|
|
18596
|
+
};
|
|
18597
|
+
var CHANGED = {
|
|
18598
|
+
fieldPath: "lastChangedAt",
|
|
18599
|
+
expr: "now"
|
|
18600
|
+
};
|
|
18601
|
+
function numeric(input) {
|
|
18602
|
+
return {
|
|
18603
|
+
...input,
|
|
18604
|
+
family: "numeric",
|
|
18605
|
+
deviceType: DeviceType.Sensor,
|
|
18606
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18607
|
+
commandCaps: [],
|
|
18608
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18609
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18610
|
+
accept: [{
|
|
18611
|
+
cap: input.outputCap,
|
|
18612
|
+
fieldPath: input.outputField
|
|
18613
|
+
}]
|
|
18614
|
+
};
|
|
18615
|
+
}
|
|
18616
|
+
function binary(input) {
|
|
18617
|
+
return {
|
|
18618
|
+
...input,
|
|
18619
|
+
family: "binary",
|
|
18620
|
+
deviceType: DeviceType.Sensor,
|
|
18621
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18622
|
+
commandCaps: [],
|
|
18623
|
+
quantity: "none",
|
|
18624
|
+
baseUnit: void 0,
|
|
18625
|
+
aggregates: BINARY_AGGREGATES,
|
|
18626
|
+
empty: "offline"
|
|
18627
|
+
};
|
|
18628
|
+
}
|
|
18629
|
+
var GROUP_TEMPLATES = [
|
|
18630
|
+
numeric({
|
|
18631
|
+
id: "temperature",
|
|
18632
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18633
|
+
role: DeviceRole.TemperatureSensor,
|
|
18634
|
+
outputCap: "temperature-sensor",
|
|
18635
|
+
outputField: "celsius",
|
|
18636
|
+
quantity: "temperature",
|
|
18637
|
+
defaultAggregate: "mean",
|
|
18638
|
+
empty: "null",
|
|
18639
|
+
companions: [NOW]
|
|
18640
|
+
}),
|
|
18641
|
+
numeric({
|
|
18642
|
+
id: "humidity",
|
|
18643
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18644
|
+
role: DeviceRole.HumiditySensor,
|
|
18645
|
+
outputCap: "humidity-sensor",
|
|
18646
|
+
outputField: "percent",
|
|
18647
|
+
quantity: "humidity",
|
|
18648
|
+
defaultAggregate: "mean",
|
|
18649
|
+
empty: "null",
|
|
18650
|
+
companions: [NOW]
|
|
18651
|
+
}),
|
|
18652
|
+
numeric({
|
|
18653
|
+
id: "pressure",
|
|
18654
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18655
|
+
role: DeviceRole.PressureSensor,
|
|
18656
|
+
outputCap: "pressure-sensor",
|
|
18657
|
+
outputField: "hpa",
|
|
18658
|
+
quantity: "pressure",
|
|
18659
|
+
defaultAggregate: "mean",
|
|
18660
|
+
empty: "null",
|
|
18661
|
+
companions: [NOW]
|
|
18662
|
+
}),
|
|
18663
|
+
numeric({
|
|
18664
|
+
id: "illuminance",
|
|
18665
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18666
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18667
|
+
outputCap: "ambient-light-sensor",
|
|
18668
|
+
outputField: "lux",
|
|
18669
|
+
quantity: "illuminance",
|
|
18670
|
+
defaultAggregate: "mean",
|
|
18671
|
+
empty: "null",
|
|
18672
|
+
companions: [NOW]
|
|
18673
|
+
}),
|
|
18674
|
+
numeric({
|
|
18675
|
+
id: "power",
|
|
18676
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18677
|
+
role: DeviceRole.PowerSensor,
|
|
18678
|
+
outputCap: "power-meter",
|
|
18679
|
+
outputField: "watts",
|
|
18680
|
+
quantity: "power",
|
|
18681
|
+
defaultAggregate: "sum",
|
|
18682
|
+
empty: "omit",
|
|
18683
|
+
companions: [NOW]
|
|
18684
|
+
}),
|
|
18685
|
+
numeric({
|
|
18686
|
+
id: "energy",
|
|
18687
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18688
|
+
role: DeviceRole.EnergySensor,
|
|
18689
|
+
outputCap: "power-meter",
|
|
18690
|
+
outputField: "kwhTotal",
|
|
18691
|
+
quantity: "energy",
|
|
18692
|
+
defaultAggregate: "sum",
|
|
18693
|
+
empty: "omit",
|
|
18694
|
+
companions: [NOW]
|
|
18695
|
+
}),
|
|
18696
|
+
numeric({
|
|
18697
|
+
id: "battery",
|
|
18698
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18699
|
+
role: DeviceRole.BatterySensor,
|
|
18700
|
+
outputCap: "battery",
|
|
18701
|
+
outputField: "percentage",
|
|
18702
|
+
quantity: "percentage",
|
|
18703
|
+
defaultAggregate: "mean",
|
|
18704
|
+
empty: "null",
|
|
18705
|
+
companions: [
|
|
18706
|
+
{
|
|
18707
|
+
fieldPath: "charging",
|
|
18708
|
+
expr: "\"unknown\""
|
|
18709
|
+
},
|
|
18710
|
+
{
|
|
18711
|
+
fieldPath: "sleeping",
|
|
18712
|
+
expr: "false"
|
|
18713
|
+
},
|
|
18714
|
+
{
|
|
18715
|
+
fieldPath: "lastUpdated",
|
|
18716
|
+
expr: "now"
|
|
18717
|
+
}
|
|
18718
|
+
]
|
|
18719
|
+
}),
|
|
18720
|
+
numeric({
|
|
18721
|
+
id: "numeric",
|
|
18722
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18723
|
+
role: DeviceRole.NumericSensor,
|
|
18724
|
+
outputCap: "numeric-sensor",
|
|
18725
|
+
outputField: "value",
|
|
18726
|
+
quantity: "device",
|
|
18727
|
+
defaultAggregate: "mean",
|
|
18728
|
+
empty: "null",
|
|
18729
|
+
companions: [NOW]
|
|
18730
|
+
}),
|
|
18731
|
+
binary({
|
|
18732
|
+
id: "motion",
|
|
18733
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18734
|
+
role: DeviceRole.MotionSensor,
|
|
18735
|
+
outputCap: "motion",
|
|
18736
|
+
outputField: "detected",
|
|
18737
|
+
defaultAggregate: "any",
|
|
18738
|
+
accept: [{
|
|
18739
|
+
cap: "motion",
|
|
18740
|
+
fieldPath: "detected"
|
|
18741
|
+
}],
|
|
18742
|
+
companions: [{
|
|
18743
|
+
fieldPath: "lastDetectedAt",
|
|
18744
|
+
expr: "null"
|
|
18745
|
+
}, {
|
|
18746
|
+
fieldPath: "autoClearAfterMs",
|
|
18747
|
+
expr: "null"
|
|
18748
|
+
}]
|
|
18749
|
+
}),
|
|
18750
|
+
binary({
|
|
18751
|
+
id: "contact",
|
|
18752
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18753
|
+
role: DeviceRole.ContactSensor,
|
|
18754
|
+
outputCap: "contact",
|
|
18755
|
+
outputField: "entryOpen",
|
|
18756
|
+
defaultAggregate: "any",
|
|
18757
|
+
accept: [{
|
|
18758
|
+
cap: "contact",
|
|
18759
|
+
fieldPath: "entryOpen"
|
|
18760
|
+
}],
|
|
18761
|
+
companions: [CHANGED]
|
|
18762
|
+
}),
|
|
18763
|
+
binary({
|
|
18764
|
+
id: "leak",
|
|
18765
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18766
|
+
role: DeviceRole.LeakSensor,
|
|
18767
|
+
outputCap: "flood",
|
|
18768
|
+
outputField: "flooded",
|
|
18769
|
+
defaultAggregate: "any",
|
|
18770
|
+
accept: [{
|
|
18771
|
+
cap: "flood",
|
|
18772
|
+
fieldPath: "flooded"
|
|
18773
|
+
}],
|
|
18774
|
+
companions: [CHANGED]
|
|
18775
|
+
}),
|
|
18776
|
+
binary({
|
|
18777
|
+
id: "smoke",
|
|
18778
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18779
|
+
role: DeviceRole.SmokeSensor,
|
|
18780
|
+
outputCap: "smoke",
|
|
18781
|
+
outputField: "detected",
|
|
18782
|
+
defaultAggregate: "any",
|
|
18783
|
+
accept: [{
|
|
18784
|
+
cap: "smoke",
|
|
18785
|
+
fieldPath: "detected"
|
|
18786
|
+
}],
|
|
18787
|
+
companions: [CHANGED]
|
|
18788
|
+
}),
|
|
18789
|
+
binary({
|
|
18790
|
+
id: "occupancy",
|
|
18791
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18792
|
+
role: DeviceRole.BinarySensor,
|
|
18793
|
+
outputCap: "binary",
|
|
18794
|
+
outputField: "on",
|
|
18795
|
+
defaultAggregate: "any",
|
|
18796
|
+
accept: [{
|
|
18797
|
+
cap: "motion",
|
|
18798
|
+
fieldPath: "detected"
|
|
18799
|
+
}, {
|
|
18800
|
+
cap: "binary",
|
|
18801
|
+
fieldPath: "on"
|
|
18802
|
+
}],
|
|
18803
|
+
companions: [CHANGED]
|
|
18804
|
+
}),
|
|
18805
|
+
binary({
|
|
18806
|
+
id: "binary",
|
|
18807
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18808
|
+
role: DeviceRole.BinarySensor,
|
|
18809
|
+
outputCap: "binary",
|
|
18810
|
+
outputField: "on",
|
|
18811
|
+
defaultAggregate: "any",
|
|
18812
|
+
accept: [{
|
|
18813
|
+
cap: "binary",
|
|
18814
|
+
fieldPath: "on"
|
|
18815
|
+
}],
|
|
18816
|
+
companions: [CHANGED]
|
|
18817
|
+
}),
|
|
18818
|
+
actuator({
|
|
18819
|
+
id: "switch",
|
|
18820
|
+
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.",
|
|
18821
|
+
deviceType: DeviceType.Switch,
|
|
18822
|
+
outputCap: "switch",
|
|
18823
|
+
commandCaps: ["switch"]
|
|
18824
|
+
}),
|
|
18825
|
+
actuator({
|
|
18826
|
+
id: "light",
|
|
18827
|
+
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.",
|
|
18828
|
+
deviceType: DeviceType.Light,
|
|
18829
|
+
outputCap: "switch",
|
|
18830
|
+
commandCaps: [
|
|
18831
|
+
"switch",
|
|
18832
|
+
"brightness",
|
|
18833
|
+
"color"
|
|
18834
|
+
]
|
|
18835
|
+
})
|
|
18836
|
+
];
|
|
18837
|
+
function actuator(input) {
|
|
18838
|
+
return {
|
|
18839
|
+
...input,
|
|
18840
|
+
family: "actuator",
|
|
18841
|
+
role: void 0,
|
|
18842
|
+
memberDeviceType: input.deviceType,
|
|
18843
|
+
outputField: "on",
|
|
18844
|
+
quantity: "none",
|
|
18845
|
+
baseUnit: void 0,
|
|
18846
|
+
aggregates: BINARY_AGGREGATES,
|
|
18847
|
+
defaultAggregate: "any",
|
|
18848
|
+
empty: "offline",
|
|
18849
|
+
accept: [{
|
|
18850
|
+
cap: "switch",
|
|
18851
|
+
fieldPath: "on"
|
|
18852
|
+
}],
|
|
18853
|
+
companions: [CHANGED]
|
|
18854
|
+
};
|
|
18855
|
+
}
|
|
18856
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18857
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18470
18858
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18471
18859
|
/**
|
|
18472
18860
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20180,12 +20568,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20180
20568
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20181
20569
|
* in-place so dispatch keeps working.
|
|
20182
20570
|
*
|
|
20183
|
-
* **
|
|
20184
|
-
*
|
|
20185
|
-
*
|
|
20186
|
-
*
|
|
20187
|
-
* (`ha-domain-mapping`)
|
|
20188
|
-
* stored after that point.
|
|
20571
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20572
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20573
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20574
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20575
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20576
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20189
20577
|
*
|
|
20190
20578
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20191
20579
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20199,6 +20587,14 @@ var SourceInfoSchema = object({
|
|
|
20199
20587
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20200
20588
|
* Used to detect rename when `id` changes. */
|
|
20201
20589
|
uniqueId: string$2().optional(),
|
|
20590
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20591
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20592
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20593
|
+
dateTimeShape: _enum([
|
|
20594
|
+
"date",
|
|
20595
|
+
"time",
|
|
20596
|
+
"datetime"
|
|
20597
|
+
]).optional(),
|
|
20202
20598
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20203
20599
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20204
20600
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41320,7 +41716,8 @@ method(object({
|
|
|
41320
41716
|
"enum"
|
|
41321
41717
|
]),
|
|
41322
41718
|
enumValues: array(string$2()).optional(),
|
|
41323
|
-
item: boolean().optional()
|
|
41719
|
+
item: boolean().optional(),
|
|
41720
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41324
41721
|
})).readonly(),
|
|
41325
41722
|
itemArray: object({
|
|
41326
41723
|
path: string$2(),
|
|
@@ -45164,8 +45561,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
45164
45561
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
45165
45562
|
var MaskGridShapeSchema = object({
|
|
45166
45563
|
kind: literal("grid"),
|
|
45167
|
-
gridWidth: number(),
|
|
45168
|
-
gridHeight: number(),
|
|
45564
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45565
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
45169
45566
|
cells: array(boolean())
|
|
45170
45567
|
});
|
|
45171
45568
|
discriminatedUnion("kind", [
|
|
@@ -45277,6 +45674,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45277
45674
|
"detection-blind",
|
|
45278
45675
|
"motion-noisy",
|
|
45279
45676
|
"motion-calm",
|
|
45677
|
+
"package-llm-silent",
|
|
45678
|
+
"package-llm-answered",
|
|
45280
45679
|
"recording-stalled",
|
|
45281
45680
|
"recording-healthy",
|
|
45282
45681
|
"recording-degraded",
|
|
@@ -56368,6 +56767,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56368
56767
|
deprecated: string$2().optional(),
|
|
56369
56768
|
distTags: array(string$2()).readonly()
|
|
56370
56769
|
});
|
|
56770
|
+
/**
|
|
56771
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56772
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56773
|
+
* tarball failure — never an empty string standing in for either.
|
|
56774
|
+
*/
|
|
56775
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56776
|
+
object({
|
|
56777
|
+
status: literal("ok"),
|
|
56778
|
+
markdown: string$2()
|
|
56779
|
+
}),
|
|
56780
|
+
object({ status: literal("missing") }),
|
|
56781
|
+
object({
|
|
56782
|
+
status: literal("error"),
|
|
56783
|
+
message: string$2()
|
|
56784
|
+
})
|
|
56785
|
+
]);
|
|
56786
|
+
var PackageDocsSchema = object({
|
|
56787
|
+
name: string$2(),
|
|
56788
|
+
version: string$2(),
|
|
56789
|
+
readme: PackageDocBodySchema,
|
|
56790
|
+
changelog: PackageDocBodySchema
|
|
56791
|
+
});
|
|
56371
56792
|
var SearchResultSchema = object({
|
|
56372
56793
|
name: string$2(),
|
|
56373
56794
|
version: string$2(),
|
|
@@ -56586,7 +57007,10 @@ method(object({ nodeId: string$2().optional() }).optional(), array(AddonListItem
|
|
|
56586
57007
|
}), object({ success: literal(true) }), {
|
|
56587
57008
|
kind: "mutation",
|
|
56588
57009
|
auth: "admin"
|
|
56589
|
-
}), method(object({ name: string$2() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57010
|
+
}), method(object({ name: string$2() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57011
|
+
name: string$2().min(1),
|
|
57012
|
+
version: string$2().min(1).optional()
|
|
57013
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string$2() }), RestartAddonResultSchema, {
|
|
56590
57014
|
kind: "mutation",
|
|
56591
57015
|
auth: "admin"
|
|
56592
57016
|
}), method(object({ packageName: string$2() }), object({ success: literal(true) }), {
|
|
@@ -56645,27 +57069,17 @@ method(object({ nodeId: string$2().optional() }).optional(), array(AddonListItem
|
|
|
56645
57069
|
*/
|
|
56646
57070
|
var AirQualitySensorStatusSchema = object({
|
|
56647
57071
|
/** Carbon dioxide concentration in ppm. */
|
|
56648
|
-
co2Ppm: number().min(0).optional(),
|
|
57072
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56649
57073
|
/** Total volatile organic compounds in ppb. */
|
|
56650
|
-
vocPpb: number().min(0).optional(),
|
|
57074
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56651
57075
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56652
|
-
pm25: number().min(0).optional(),
|
|
57076
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56653
57077
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56654
|
-
pm10: number().min(0).optional(),
|
|
57078
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56655
57079
|
/** Composite AQI value (typically 0..500). */
|
|
56656
|
-
aqi: number().optional(),
|
|
57080
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56657
57081
|
/** Ms epoch when the slice was last updated. */
|
|
56658
|
-
lastFetchedAt: number()
|
|
56659
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56660
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56661
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56662
|
-
* per slice is unambiguous. */
|
|
56663
|
-
unit: string$2().optional(),
|
|
56664
|
-
/** Suggested decimal places for numeric display.
|
|
56665
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56666
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56667
|
-
* auto-formatting when absent. */
|
|
56668
|
-
precision: number().int().min(0).max(10).optional()
|
|
57082
|
+
lastFetchedAt: number()
|
|
56669
57083
|
});
|
|
56670
57084
|
var airQualitySensorCapability = {
|
|
56671
57085
|
name: "air-quality-sensor",
|
|
@@ -56702,12 +57116,12 @@ var airQualitySensorCapability = {
|
|
|
56702
57116
|
},
|
|
56703
57117
|
pm25: {
|
|
56704
57118
|
kind: "gauge",
|
|
56705
|
-
unit: "
|
|
57119
|
+
unit: "µg/m³",
|
|
56706
57120
|
deadband: 1
|
|
56707
57121
|
},
|
|
56708
57122
|
pm10: {
|
|
56709
57123
|
kind: "gauge",
|
|
56710
|
-
unit: "
|
|
57124
|
+
unit: "µg/m³",
|
|
56711
57125
|
deadband: 1
|
|
56712
57126
|
},
|
|
56713
57127
|
aqi: {
|
|
@@ -56725,22 +57139,13 @@ var airQualitySensorCapability = {
|
|
|
56725
57139
|
* entries with `device_class: illuminance`.
|
|
56726
57140
|
*/
|
|
56727
57141
|
var AmbientLightSensorStatusSchema = object({
|
|
56728
|
-
/** Current illuminance in lux (lx). */
|
|
56729
|
-
lux: number().min(0).meta({
|
|
56730
|
-
|
|
57142
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57143
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57144
|
+
precision: 0,
|
|
56731
57145
|
label: "Illuminance"
|
|
56732
|
-
}),
|
|
57146
|
+
})),
|
|
56733
57147
|
/** Ms epoch when the slice was last updated. */
|
|
56734
|
-
lastFetchedAt: number()
|
|
56735
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56736
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56737
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56738
|
-
unit: string$2().optional(),
|
|
56739
|
-
/** Suggested decimal places for numeric display.
|
|
56740
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56741
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56742
|
-
* auto-formatting when absent. */
|
|
56743
|
-
precision: number().int().min(0).max(10).optional()
|
|
57148
|
+
lastFetchedAt: number()
|
|
56744
57149
|
});
|
|
56745
57150
|
var ambientLightSensorCapability = {
|
|
56746
57151
|
name: "ambient-light-sensor",
|
|
@@ -56772,12 +57177,7 @@ var ambientLightSensorCapability = {
|
|
|
56772
57177
|
} } },
|
|
56773
57178
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56774
57179
|
* whether persisting is worth a SQLite commit. */
|
|
56775
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56776
|
-
customize: {
|
|
56777
|
-
version: 1,
|
|
56778
|
-
advanced: "derive",
|
|
56779
|
-
targets: []
|
|
56780
|
-
}
|
|
57180
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56781
57181
|
};
|
|
56782
57182
|
/**
|
|
56783
57183
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57004,10 +57404,7 @@ var BatteryStatusSchema = object({
|
|
|
57004
57404
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57005
57405
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57006
57406
|
*/
|
|
57007
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57008
|
-
unit: "%",
|
|
57009
|
-
label: "Charge"
|
|
57010
|
-
}),
|
|
57407
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57011
57408
|
/**
|
|
57012
57409
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57013
57410
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57034,7 +57431,14 @@ var BatteryStatusSchema = object({
|
|
|
57034
57431
|
*/
|
|
57035
57432
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57036
57433
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57037
|
-
lastUpdated: number(),
|
|
57434
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57435
|
+
/**
|
|
57436
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57437
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57438
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57439
|
+
* `numeric-sensor` on the same device.
|
|
57440
|
+
*/
|
|
57441
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57038
57442
|
/**
|
|
57039
57443
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57040
57444
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57086,7 +57490,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57086
57490
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57087
57491
|
var batteryCustomize = {
|
|
57088
57492
|
version: 1,
|
|
57089
|
-
advanced: "derive",
|
|
57090
57493
|
targets: [{
|
|
57091
57494
|
id: "percentage",
|
|
57092
57495
|
cardinality: "scalar",
|
|
@@ -57095,7 +57498,7 @@ var batteryCustomize = {
|
|
|
57095
57498
|
stateField: "percentage"
|
|
57096
57499
|
},
|
|
57097
57500
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57098
|
-
apply: "add
|
|
57501
|
+
apply: "add",
|
|
57099
57502
|
path: "percentage",
|
|
57100
57503
|
sources: [{
|
|
57101
57504
|
kind: "field",
|
|
@@ -57216,10 +57619,16 @@ onStatusChanged: { data: object({
|
|
|
57216
57619
|
/**
|
|
57217
57620
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57218
57621
|
*/
|
|
57219
|
-
history: { fields: {
|
|
57220
|
-
|
|
57221
|
-
|
|
57222
|
-
|
|
57622
|
+
history: { fields: {
|
|
57623
|
+
percentage: {
|
|
57624
|
+
kind: "gauge",
|
|
57625
|
+
unit: "%"
|
|
57626
|
+
},
|
|
57627
|
+
volts: {
|
|
57628
|
+
kind: "gauge",
|
|
57629
|
+
unit: "V"
|
|
57630
|
+
}
|
|
57631
|
+
} },
|
|
57223
57632
|
customize: batteryCustomize,
|
|
57224
57633
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57225
57634
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57266,12 +57675,7 @@ var binaryCapability = {
|
|
|
57266
57675
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57267
57676
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57268
57677
|
* whether persisting is worth a SQLite commit. */
|
|
57269
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57270
|
-
customize: {
|
|
57271
|
-
version: 1,
|
|
57272
|
-
advanced: "derive",
|
|
57273
|
-
targets: []
|
|
57274
|
-
}
|
|
57678
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57275
57679
|
};
|
|
57276
57680
|
/**
|
|
57277
57681
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57287,7 +57691,7 @@ var binaryCapability = {
|
|
|
57287
57691
|
*/
|
|
57288
57692
|
var BrightnessStatusSchema = object({
|
|
57289
57693
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57290
|
-
percentage: number().min(0).max(100),
|
|
57694
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57291
57695
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57292
57696
|
lastChangedAt: number()
|
|
57293
57697
|
});
|
|
@@ -57758,21 +58162,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57758
58162
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57759
58163
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57760
58164
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57761
|
-
target: number().nullable(),
|
|
58165
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57762
58166
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57763
58167
|
* in `heat_cool` mode. */
|
|
57764
|
-
targetHigh: number().nullable(),
|
|
58168
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57765
58169
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57766
58170
|
* in `heat_cool` mode. */
|
|
57767
|
-
targetLow: number().nullable(),
|
|
58171
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57768
58172
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57769
58173
|
* humidity control. */
|
|
57770
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58174
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57771
58175
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57772
58176
|
* the device's internal sensor. */
|
|
57773
|
-
currentTemp: number().nullable(),
|
|
58177
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57774
58178
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57775
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58179
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57776
58180
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57777
58181
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57778
58182
|
swingVertical: boolean().nullable(),
|
|
@@ -57780,11 +58184,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57780
58184
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57781
58185
|
swingHorizontal: boolean().nullable(),
|
|
57782
58186
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57783
|
-
minTemp: number().nullable().optional(),
|
|
58187
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57784
58188
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57785
|
-
maxTemp: number().nullable().optional(),
|
|
58189
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57786
58190
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57787
|
-
tempStep: number().positive().nullable().optional(),
|
|
58191
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57788
58192
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57789
58193
|
lastFetchedAt: number()
|
|
57790
58194
|
});
|
|
@@ -57926,17 +58330,17 @@ var climateControlCapability = {
|
|
|
57926
58330
|
* modes to expose in the picker without a slice fetch.
|
|
57927
58331
|
*/
|
|
57928
58332
|
var RgbTripletSchema = object({
|
|
57929
|
-
r: number().int().min(0).max(255),
|
|
57930
|
-
g: number().int().min(0).max(255),
|
|
57931
|
-
b: number().int().min(0).max(255)
|
|
58333
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58334
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58335
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57932
58336
|
});
|
|
57933
58337
|
var HsvTripletSchema = object({
|
|
57934
58338
|
/** Hue in degrees, 0..360. */
|
|
57935
|
-
h: number().min(0).max(360),
|
|
58339
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57936
58340
|
/** Saturation as 0..100 inclusive. */
|
|
57937
|
-
s: number().min(0).max(100),
|
|
58341
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57938
58342
|
/** Value/brightness as 0..100 inclusive. */
|
|
57939
|
-
v: number().min(0).max(100)
|
|
58343
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57940
58344
|
});
|
|
57941
58345
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57942
58346
|
object({
|
|
@@ -57965,7 +58369,7 @@ var ColorStatusSchema = object({
|
|
|
57965
58369
|
/** Populated when `mode === 'hsv'`. */
|
|
57966
58370
|
hsv: HsvTripletSchema.optional(),
|
|
57967
58371
|
/** Populated when `mode === 'mired'`. */
|
|
57968
|
-
mireds: number().int().optional(),
|
|
58372
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57969
58373
|
/** Ms epoch of the last operator-driven change. */
|
|
57970
58374
|
lastChangedAt: number()
|
|
57971
58375
|
});
|
|
@@ -58160,18 +58564,12 @@ _enum([
|
|
|
58160
58564
|
"empty",
|
|
58161
58565
|
"full"
|
|
58162
58566
|
]);
|
|
58163
|
-
/**
|
|
58164
|
-
|
|
58165
|
-
|
|
58166
|
-
"days",
|
|
58167
|
-
"hours",
|
|
58168
|
-
"cycles"
|
|
58169
|
-
]);
|
|
58170
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
58171
|
-
* days). `value` null = unknown (D393). */
|
|
58567
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58568
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58569
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
58172
58570
|
var ConsumableRemainingSchema = object({
|
|
58173
|
-
value: number().min(0).nullable(),
|
|
58174
|
-
|
|
58571
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58572
|
+
kind: ConsumableRemainingKindSchema
|
|
58175
58573
|
});
|
|
58176
58574
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
58177
58575
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -58184,7 +58582,7 @@ var ConsumableItemSchema = object({
|
|
|
58184
58582
|
/** Display name. */
|
|
58185
58583
|
label: string$2().min(1),
|
|
58186
58584
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
58187
|
-
level: number().min(0).max(100).nullable(),
|
|
58585
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58188
58586
|
/** The provider's discrete verdict when known (binary mode). */
|
|
58189
58587
|
status: ConsumableStatusSchema.nullable(),
|
|
58190
58588
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58266,8 +58664,8 @@ var consumablesCustomize = {
|
|
|
58266
58664
|
transforms: [{ kind: "identity" }]
|
|
58267
58665
|
}],
|
|
58268
58666
|
literals: [{
|
|
58269
|
-
path: "remaining.
|
|
58270
|
-
values: [...
|
|
58667
|
+
path: "remaining.kind",
|
|
58668
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58271
58669
|
}]
|
|
58272
58670
|
},
|
|
58273
58671
|
{
|
|
@@ -58396,7 +58794,6 @@ reset: method(object({
|
|
|
58396
58794
|
},
|
|
58397
58795
|
"remaining.value": {
|
|
58398
58796
|
kind: "gauge",
|
|
58399
|
-
unitFrom: "remaining.unit",
|
|
58400
58797
|
deadband: 1,
|
|
58401
58798
|
displayName: "Remaining"
|
|
58402
58799
|
}
|
|
@@ -58466,10 +58863,9 @@ var contactCapability = {
|
|
|
58466
58863
|
* (empty array for the other kinds). It lives in the slice because
|
|
58467
58864
|
* HA `select.*` entities may update their options at runtime.
|
|
58468
58865
|
*
|
|
58469
|
-
*
|
|
58470
|
-
*
|
|
58471
|
-
*
|
|
58472
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58866
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58867
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58868
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58473
58869
|
*/
|
|
58474
58870
|
var ControlStatusSchema = object({
|
|
58475
58871
|
kind: _enum([
|
|
@@ -58481,39 +58877,17 @@ var ControlStatusSchema = object({
|
|
|
58481
58877
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58482
58878
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58483
58879
|
* or time-only — HA accepts all three forms). */
|
|
58484
|
-
value: union([number(), string$2()]),
|
|
58880
|
+
value: union([number().meta(readingMeta("device")), string$2()]),
|
|
58485
58881
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58486
58882
|
options: array(string$2()),
|
|
58487
58883
|
/** Ms epoch when the slice was last updated. */
|
|
58488
58884
|
lastChangedAt: number(),
|
|
58489
|
-
/**
|
|
58490
|
-
|
|
58491
|
-
|
|
58492
|
-
|
|
58493
|
-
/**
|
|
58494
|
-
|
|
58495
|
-
min: number().optional(),
|
|
58496
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58497
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58498
|
-
max: number().optional(),
|
|
58499
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58500
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58501
|
-
step: number().optional(),
|
|
58502
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58503
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58504
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58505
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58506
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58507
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58508
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58509
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58510
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58511
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58512
|
-
format: _enum([
|
|
58513
|
-
"date",
|
|
58514
|
-
"time",
|
|
58515
|
-
"datetime"
|
|
58516
|
-
]).optional()
|
|
58885
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58886
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58887
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58888
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58889
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58890
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58517
58891
|
});
|
|
58518
58892
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58519
58893
|
object({
|
|
@@ -58579,9 +58953,9 @@ var CoverStatusSchema = object({
|
|
|
58579
58953
|
]),
|
|
58580
58954
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58581
58955
|
* no intermediate position surface. */
|
|
58582
|
-
position: number().min(0).max(100).nullable(),
|
|
58956
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58583
58957
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58584
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58958
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58585
58959
|
/** Ms epoch when the slice was last updated. */
|
|
58586
58960
|
lastChangedAt: number()
|
|
58587
58961
|
});
|
|
@@ -58684,9 +59058,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58684
59058
|
var DayNightStatusSchema = object({
|
|
58685
59059
|
mode: DayNightModeSchema,
|
|
58686
59060
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58687
|
-
sensitivity: number().optional(),
|
|
59061
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58688
59062
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58689
|
-
switchDelaySec: number().optional(),
|
|
59063
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58690
59064
|
lastFetchedAt: number()
|
|
58691
59065
|
});
|
|
58692
59066
|
/**
|
|
@@ -58904,11 +59278,11 @@ var DishwasherStatusSchema = object({
|
|
|
58904
59278
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58905
59279
|
availablePrograms: array(string$2()),
|
|
58906
59280
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58907
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59281
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58908
59282
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58909
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59283
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58910
59284
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58911
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59285
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58912
59286
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58913
59287
|
doorOpen: boolean().nullable(),
|
|
58914
59288
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58932,7 +59306,7 @@ var DishwasherStatusSchema = object({
|
|
|
58932
59306
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58933
59307
|
machineCareDue: boolean().nullable(),
|
|
58934
59308
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58935
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59309
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58936
59310
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58937
59311
|
halfLoad: boolean().nullable(),
|
|
58938
59312
|
hygienePlus: boolean().nullable(),
|
|
@@ -58947,7 +59321,7 @@ var DishwasherStatusSchema = object({
|
|
|
58947
59321
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58948
59322
|
activeEvents: array(string$2()),
|
|
58949
59323
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58950
|
-
errorCode: number().nullable(),
|
|
59324
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58951
59325
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58952
59326
|
errorLabel: string$2().nullable(),
|
|
58953
59327
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -59178,7 +59552,7 @@ var DoorbellStatusSchema = object({
|
|
|
59178
59552
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
59179
59553
|
lastPressedAt: number().nullable(),
|
|
59180
59554
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
59181
|
-
pressCountSinceStart: number()
|
|
59555
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
59182
59556
|
});
|
|
59183
59557
|
var DoorbellPressEventSchema = object({
|
|
59184
59558
|
deviceId: number(),
|
|
@@ -59243,17 +59617,7 @@ onPressed: {
|
|
|
59243
59617
|
history: "none",
|
|
59244
59618
|
customize: doorbellCustomize
|
|
59245
59619
|
};
|
|
59246
|
-
|
|
59247
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59248
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59249
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59250
|
-
* The option set is stable across observations; it is persisted in the
|
|
59251
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59252
|
-
* stored in `sourceInfo`.
|
|
59253
|
-
*/
|
|
59254
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59255
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59256
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59620
|
+
_enum([
|
|
59257
59621
|
"date",
|
|
59258
59622
|
"time",
|
|
59259
59623
|
"datetime"
|
|
@@ -59261,12 +59625,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59261
59625
|
var EnumSensorStatusSchema = object({
|
|
59262
59626
|
value: string$2(),
|
|
59263
59627
|
/**
|
|
59264
|
-
* Set
|
|
59265
|
-
* as
|
|
59266
|
-
*
|
|
59267
|
-
* a time-only sensor → `'time'`.
|
|
59628
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59629
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59630
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59268
59631
|
*/
|
|
59269
|
-
|
|
59632
|
+
timestamp: boolean().optional(),
|
|
59270
59633
|
/** Ms epoch when the slice was last updated. */
|
|
59271
59634
|
lastFetchedAt: number()
|
|
59272
59635
|
});
|
|
@@ -59293,11 +59656,11 @@ var enumSensorCapability = {
|
|
|
59293
59656
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59294
59657
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59295
59658
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59296
|
-
* `
|
|
59659
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59297
59660
|
*/
|
|
59298
59661
|
history: { fields: { value: {
|
|
59299
59662
|
kind: "enum",
|
|
59300
|
-
skipWhenSet: "
|
|
59663
|
+
skipWhenSet: "timestamp"
|
|
59301
59664
|
} } },
|
|
59302
59665
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59303
59666
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59317,13 +59680,13 @@ var EventFireSchema = object({
|
|
|
59317
59680
|
deviceId: number(),
|
|
59318
59681
|
eventType: string$2(),
|
|
59319
59682
|
data: record(string$2(), unknown()).nullable(),
|
|
59320
|
-
timestamp: number(),
|
|
59321
|
-
seq: number()
|
|
59683
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59684
|
+
seq: number().meta(readingMeta("count"))
|
|
59322
59685
|
});
|
|
59323
59686
|
var EventEmitterStatusSchema = object({
|
|
59324
59687
|
eventTypes: array(string$2()),
|
|
59325
59688
|
lastEvent: EventFireSchema.nullable(),
|
|
59326
|
-
eventCountSinceStart: number()
|
|
59689
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59327
59690
|
});
|
|
59328
59691
|
var eventEmitterCapability = {
|
|
59329
59692
|
name: "event-emitter",
|
|
@@ -59736,10 +60099,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59736
60099
|
var FanControlStatusSchema = object({
|
|
59737
60100
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59738
60101
|
* speed surface (single-speed fan). */
|
|
59739
|
-
percentage: number().min(0).max(100).nullable(),
|
|
60102
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59740
60103
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59741
60104
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59742
|
-
percentageStep: number().positive().optional(),
|
|
60105
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59743
60106
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59744
60107
|
* — empty string when no preset is active or supported. */
|
|
59745
60108
|
preset: string$2(),
|
|
@@ -59860,7 +60223,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59860
60223
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59861
60224
|
model: string$2().nullable(),
|
|
59862
60225
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59863
|
-
channelCount: number().nullable(),
|
|
60226
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59864
60227
|
/**
|
|
59865
60228
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59866
60229
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59983,9 +60346,91 @@ var gasCapability = {
|
|
|
59983
60346
|
* whether persisting is worth a SQLite commit. */
|
|
59984
60347
|
volatileStateFields: ["lastChangedAt"]
|
|
59985
60348
|
};
|
|
60349
|
+
var GroupCommandsSchema = object({
|
|
60350
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60351
|
+
results: array(object({
|
|
60352
|
+
deviceId: number().int().nonnegative(),
|
|
60353
|
+
cap: string$2().min(1),
|
|
60354
|
+
method: string$2().min(1),
|
|
60355
|
+
ok: boolean(),
|
|
60356
|
+
error: string$2().optional(),
|
|
60357
|
+
/** Ms epoch of the attempt. */
|
|
60358
|
+
at: number()
|
|
60359
|
+
})) });
|
|
60360
|
+
var groupCommandsCapability = {
|
|
60361
|
+
name: "group-commands",
|
|
60362
|
+
scope: "device",
|
|
60363
|
+
deviceNative: true,
|
|
60364
|
+
mode: "singleton",
|
|
60365
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60366
|
+
methods: {},
|
|
60367
|
+
status: {
|
|
60368
|
+
schema: GroupCommandsSchema,
|
|
60369
|
+
kind: "push"
|
|
60370
|
+
},
|
|
60371
|
+
runtimeState: GroupCommandsSchema,
|
|
60372
|
+
/**
|
|
60373
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60374
|
+
* failure would outlive the command that caused it.
|
|
60375
|
+
*
|
|
60376
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60377
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60378
|
+
*/
|
|
60379
|
+
durability: "session",
|
|
60380
|
+
history: "none"
|
|
60381
|
+
};
|
|
60382
|
+
/**
|
|
60383
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60384
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60385
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60386
|
+
* series that later statistics read is the output cap's own history block.
|
|
60387
|
+
*/
|
|
60388
|
+
var GroupStatusSchema = object({
|
|
60389
|
+
/** Members whose current value entered the aggregate. */
|
|
60390
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60391
|
+
precision: 0,
|
|
60392
|
+
label: "Reporting"
|
|
60393
|
+
})),
|
|
60394
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60395
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60396
|
+
precision: 0,
|
|
60397
|
+
label: "Excluded"
|
|
60398
|
+
})),
|
|
60399
|
+
/** `included` + `excluded`. */
|
|
60400
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60401
|
+
precision: 0,
|
|
60402
|
+
label: "Members"
|
|
60403
|
+
}))
|
|
60404
|
+
});
|
|
60405
|
+
var groupStatusCapability = {
|
|
60406
|
+
name: "group-status",
|
|
60407
|
+
scope: "device",
|
|
60408
|
+
deviceNative: true,
|
|
60409
|
+
mode: "singleton",
|
|
60410
|
+
deviceTypes: [
|
|
60411
|
+
DeviceType.Sensor,
|
|
60412
|
+
DeviceType.Switch,
|
|
60413
|
+
DeviceType.Light
|
|
60414
|
+
],
|
|
60415
|
+
methods: {},
|
|
60416
|
+
status: {
|
|
60417
|
+
schema: GroupStatusSchema,
|
|
60418
|
+
kind: "push"
|
|
60419
|
+
},
|
|
60420
|
+
runtimeState: GroupStatusSchema,
|
|
60421
|
+
/**
|
|
60422
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60423
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60424
|
+
*
|
|
60425
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60426
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60427
|
+
*/
|
|
60428
|
+
durability: "session",
|
|
60429
|
+
history: "none"
|
|
60430
|
+
};
|
|
59986
60431
|
var HeatingValveStatusSchema = object({
|
|
59987
60432
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59988
|
-
position: number().min(0).max(100).nullable(),
|
|
60433
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59989
60434
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59990
60435
|
lastFetchedAt: number()
|
|
59991
60436
|
});
|
|
@@ -60028,9 +60473,9 @@ var HumidifierStatusSchema = object({
|
|
|
60028
60473
|
/** Whether the humidifier is currently on. */
|
|
60029
60474
|
on: boolean(),
|
|
60030
60475
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60031
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60476
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60032
60477
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60033
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60478
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60034
60479
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60035
60480
|
* device has no mode surface. */
|
|
60036
60481
|
mode: string$2().nullable(),
|
|
@@ -60040,9 +60485,9 @@ var HumidifierStatusSchema = object({
|
|
|
60040
60485
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60041
60486
|
action: string$2().nullable(),
|
|
60042
60487
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60043
|
-
minHumidity: number().nullable(),
|
|
60488
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60044
60489
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60045
|
-
maxHumidity: number().nullable(),
|
|
60490
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60046
60491
|
/** Ms epoch when the slice was last updated. */
|
|
60047
60492
|
lastChangedAt: number()
|
|
60048
60493
|
});
|
|
@@ -60112,22 +60557,13 @@ var humidifierCapability = {
|
|
|
60112
60557
|
* `sourceInfo`.
|
|
60113
60558
|
*/
|
|
60114
60559
|
var HumiditySensorStatusSchema = object({
|
|
60115
|
-
/** Current relative humidity, 0..100. */
|
|
60116
|
-
percent: number().min(0).max(100).meta({
|
|
60117
|
-
|
|
60560
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60561
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60562
|
+
precision: 0,
|
|
60118
60563
|
label: "Humidity"
|
|
60119
|
-
}),
|
|
60564
|
+
})),
|
|
60120
60565
|
/** Ms epoch when the slice was last updated. */
|
|
60121
|
-
lastFetchedAt: number()
|
|
60122
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60123
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60124
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60125
|
-
unit: string$2().optional(),
|
|
60126
|
-
/** Suggested decimal places for numeric display.
|
|
60127
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60128
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60129
|
-
* auto-formatting when absent. */
|
|
60130
|
-
precision: number().int().min(0).max(10).optional()
|
|
60566
|
+
lastFetchedAt: number()
|
|
60131
60567
|
});
|
|
60132
60568
|
var humiditySensorCapability = {
|
|
60133
60569
|
name: "humidity-sensor",
|
|
@@ -60158,12 +60594,7 @@ var humiditySensorCapability = {
|
|
|
60158
60594
|
} } },
|
|
60159
60595
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60160
60596
|
* whether persisting is worth a SQLite commit. */
|
|
60161
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60162
|
-
customize: {
|
|
60163
|
-
version: 1,
|
|
60164
|
-
advanced: "derive",
|
|
60165
|
-
targets: []
|
|
60166
|
-
}
|
|
60597
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60167
60598
|
};
|
|
60168
60599
|
/**
|
|
60169
60600
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -60184,7 +60615,7 @@ var ImageStatusSchema = object({
|
|
|
60184
60615
|
* entity exposes no `entity_picture` (yet). */
|
|
60185
60616
|
url: string$2().nullable(),
|
|
60186
60617
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
60187
|
-
lastUpdated: number().nullable()
|
|
60618
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
60188
60619
|
});
|
|
60189
60620
|
var imageCapability = {
|
|
60190
60621
|
name: "image",
|
|
@@ -60272,19 +60703,19 @@ var NormalizedRangeSchema = object({
|
|
|
60272
60703
|
*/
|
|
60273
60704
|
var ImageSettingsStatusSchema = object({
|
|
60274
60705
|
/** Normalized 0–100. */
|
|
60275
|
-
brightness: number().optional(),
|
|
60706
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60276
60707
|
/** Normalized 0–100. */
|
|
60277
|
-
contrast: number().optional(),
|
|
60708
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60278
60709
|
/** Normalized 0–100. */
|
|
60279
|
-
saturation: number().optional(),
|
|
60710
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60280
60711
|
/** Normalized 0–100. */
|
|
60281
|
-
sharpness: number().optional(),
|
|
60712
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60282
60713
|
mirror: boolean().optional(),
|
|
60283
60714
|
flip: boolean().optional(),
|
|
60284
60715
|
rotate: ImageRotateSchema.optional(),
|
|
60285
60716
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60286
60717
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60287
|
-
warmth: number().optional(),
|
|
60718
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60288
60719
|
exposureMode: ExposureModeSchema.optional(),
|
|
60289
60720
|
backlightMode: BacklightModeSchema.optional(),
|
|
60290
60721
|
lastFetchedAt: number()
|
|
@@ -60563,10 +60994,10 @@ var IntercomAbilitySchema = object({
|
|
|
60563
60994
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60564
60995
|
codecs: array(string$2()),
|
|
60565
60996
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60566
|
-
sampleRate: number(),
|
|
60997
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60567
60998
|
duplex: _enum(["half", "full"]),
|
|
60568
60999
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60569
|
-
maxBacklogMs: number()
|
|
61000
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60570
61001
|
});
|
|
60571
61002
|
var IntercomStatusSchema = object({
|
|
60572
61003
|
/** True while a talk session is open. */
|
|
@@ -60793,13 +61224,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60793
61224
|
activity: LawnMowerActivitySchema,
|
|
60794
61225
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60795
61226
|
* reading. */
|
|
60796
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
61227
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60797
61228
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60798
61229
|
* task is active / progress is unavailable. */
|
|
60799
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61230
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60800
61231
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60801
61232
|
* or null when unknown. */
|
|
60802
|
-
currentCode: number().nullable(),
|
|
61233
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60803
61234
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60804
61235
|
currentCodeLabel: string$2().nullable(),
|
|
60805
61236
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61332,7 +61763,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61332
61763
|
state: MediaPlayerStateSchema,
|
|
61333
61764
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61334
61765
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61335
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61766
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61336
61767
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61337
61768
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61338
61769
|
isMuted: boolean().nullable(),
|
|
@@ -61345,10 +61776,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61345
61776
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61346
61777
|
/** Current playback position in ms. Null when not seekable or
|
|
61347
61778
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61348
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61779
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61349
61780
|
/** Total duration of the current media in ms. Null when unknown
|
|
61350
61781
|
* (live stream) or nothing is playing. */
|
|
61351
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61782
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61352
61783
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61353
61784
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61354
61785
|
shuffle: boolean().nullable(),
|
|
@@ -61657,7 +62088,7 @@ var motionCustomize = {
|
|
|
61657
62088
|
eventName: "onMotionChanged"
|
|
61658
62089
|
},
|
|
61659
62090
|
deviceTypes: [DeviceType.Camera],
|
|
61660
|
-
apply: "
|
|
62091
|
+
apply: "add",
|
|
61661
62092
|
applyAuthority: {
|
|
61662
62093
|
kind: "camera-sensors",
|
|
61663
62094
|
timeoutField: "motionCooldownMs"
|
|
@@ -61729,7 +62160,7 @@ var MotionStatusSchema = object({
|
|
|
61729
62160
|
* it, every provider seeded it at boot, and every session left it
|
|
61730
62161
|
* `detected: true` after its detach.
|
|
61731
62162
|
*/
|
|
61732
|
-
autoClearAfterMs: number().nullable()
|
|
62163
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61733
62164
|
});
|
|
61734
62165
|
/**
|
|
61735
62166
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61766,12 +62197,18 @@ var motionCapability = {
|
|
|
61766
62197
|
methods: {
|
|
61767
62198
|
/**
|
|
61768
62199
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61769
|
-
* for consumers that don't need the full status object
|
|
61770
|
-
*
|
|
61771
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61772
|
-
* consumer.
|
|
62200
|
+
* for consumers that don't need the full status object. A composed
|
|
62201
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61773
62202
|
*/
|
|
61774
62203
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62204
|
+
/**
|
|
62205
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62206
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62207
|
+
*/
|
|
62208
|
+
composedMethods: { isDetected: {
|
|
62209
|
+
kind: "slice",
|
|
62210
|
+
field: "detected"
|
|
62211
|
+
} },
|
|
61775
62212
|
events: {
|
|
61776
62213
|
/**
|
|
61777
62214
|
* Fires every time the runner transitions a camera between
|
|
@@ -61911,7 +62348,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61911
62348
|
* the grid region(s). */
|
|
61912
62349
|
var MotionZoneStatusSchema = object({
|
|
61913
62350
|
enabled: boolean(),
|
|
61914
|
-
sensitivity: number(),
|
|
62351
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61915
62352
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61916
62353
|
regions: array(MotionZoneRegionSchema),
|
|
61917
62354
|
lastFetchedAt: number()
|
|
@@ -62281,7 +62718,7 @@ var NavigationStatusSchema = object({
|
|
|
62281
62718
|
following: boolean(),
|
|
62282
62719
|
flash: boolean(),
|
|
62283
62720
|
lightMode: NavigationLightModeSchema,
|
|
62284
|
-
lightLevel: number().min(40).max(100),
|
|
62721
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62285
62722
|
/** Ms epoch when the slice was last updated. */
|
|
62286
62723
|
lastChangedAt: number()
|
|
62287
62724
|
});
|
|
@@ -62415,13 +62852,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62415
62852
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62416
62853
|
* SKIP a null rather than coerce it.
|
|
62417
62854
|
*/
|
|
62418
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62855
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62419
62856
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62420
|
-
rssiDbm: number().optional(),
|
|
62857
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62421
62858
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62422
62859
|
ssid: string$2().optional(),
|
|
62423
62860
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62424
|
-
lastUpdated: number()
|
|
62861
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62425
62862
|
});
|
|
62426
62863
|
var networkLinkCapability = {
|
|
62427
62864
|
name: "network-link",
|
|
@@ -62806,7 +63243,7 @@ var NotifierStatusSchema = object({
|
|
|
62806
63243
|
lastError: string$2().nullable(),
|
|
62807
63244
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62808
63245
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62809
|
-
queueDepth: number().int().nonnegative(),
|
|
63246
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62810
63247
|
/** Per-feature capability matrix — authoritative source for the
|
|
62811
63248
|
* compose-form field gating. */
|
|
62812
63249
|
supports: NotifierSupportsSchema
|
|
@@ -62898,11 +63335,9 @@ onSent: { data: object({
|
|
|
62898
63335
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62899
63336
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62900
63337
|
*
|
|
62901
|
-
* The
|
|
62902
|
-
*
|
|
62903
|
-
*
|
|
62904
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62905
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63338
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63339
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63340
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62906
63341
|
*
|
|
62907
63342
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62908
63343
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62911,15 +63346,8 @@ onSent: { data: object({
|
|
|
62911
63346
|
* numeric values land here.
|
|
62912
63347
|
*/
|
|
62913
63348
|
var NumericSensorStatusSchema = object({
|
|
62914
|
-
|
|
62915
|
-
|
|
62916
|
-
* Populated live from the upstream source on each state push.
|
|
62917
|
-
* Absent for unitless sensors. */
|
|
62918
|
-
unit: string$2().optional(),
|
|
62919
|
-
/** Suggested decimal places for numeric display.
|
|
62920
|
-
* Populated live from the upstream source when provided.
|
|
62921
|
-
* Falls back to auto-formatting when absent. */
|
|
62922
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63349
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63350
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62923
63351
|
/** Ms epoch when the slice was last updated. */
|
|
62924
63352
|
lastFetchedAt: number()
|
|
62925
63353
|
});
|
|
@@ -62943,11 +63371,11 @@ var numericSensorCapability = {
|
|
|
62943
63371
|
*/
|
|
62944
63372
|
durability: "restored",
|
|
62945
63373
|
/**
|
|
62946
|
-
* History (D850): recorded series. The unit is
|
|
63374
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63375
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62947
63376
|
*/
|
|
62948
63377
|
history: { fields: { value: {
|
|
62949
63378
|
kind: "gauge",
|
|
62950
|
-
unitFrom: "unit",
|
|
62951
63379
|
minIntervalMs: 3e4
|
|
62952
63380
|
} } },
|
|
62953
63381
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63239,23 +63667,26 @@ var PetFeederStatusSchema = object({
|
|
|
63239
63667
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63240
63668
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63241
63669
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63242
|
-
foodLevel: number().nullable(),
|
|
63670
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63243
63671
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63244
63672
|
* single-hopper models. */
|
|
63245
|
-
food1: number().nullable(),
|
|
63673
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63246
63674
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63247
63675
|
* single-hopper models. */
|
|
63248
|
-
food2: number().nullable(),
|
|
63676
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63249
63677
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63250
63678
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63251
63679
|
* below the feeder's low threshold. */
|
|
63252
63680
|
lowFood: boolean(),
|
|
63253
63681
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63254
63682
|
* device has no battery reading. */
|
|
63255
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63256
|
-
/**
|
|
63257
|
-
*
|
|
63258
|
-
|
|
63683
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63684
|
+
/**
|
|
63685
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63686
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63687
|
+
* model has no desiccant sensor.
|
|
63688
|
+
*/
|
|
63689
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63259
63690
|
/** True while a feed is in progress. */
|
|
63260
63691
|
feeding: boolean(),
|
|
63261
63692
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63266,7 +63697,7 @@ var PetFeederStatusSchema = object({
|
|
|
63266
63697
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63267
63698
|
error: string$2().nullable(),
|
|
63268
63699
|
/** Raw device error code (0 / null = no error). */
|
|
63269
|
-
errorCode: number().nullable(),
|
|
63700
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63270
63701
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63271
63702
|
isDualHopper: boolean(),
|
|
63272
63703
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63276,7 +63707,7 @@ var PetFeederStatusSchema = object({
|
|
|
63276
63707
|
/** Play a chime when dispensing. */
|
|
63277
63708
|
feedSound: boolean(),
|
|
63278
63709
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63279
|
-
volume: number(),
|
|
63710
|
+
volume: number().meta(readingMeta("none")),
|
|
63280
63711
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63281
63712
|
lastFetchedAt: number()
|
|
63282
63713
|
});
|
|
@@ -63395,7 +63826,7 @@ var petFeederCapability = {
|
|
|
63395
63826
|
},
|
|
63396
63827
|
desiccantLeftDays: {
|
|
63397
63828
|
kind: "gauge",
|
|
63398
|
-
unit: "
|
|
63829
|
+
unit: "s"
|
|
63399
63830
|
}
|
|
63400
63831
|
} }
|
|
63401
63832
|
};
|
|
@@ -63796,36 +64227,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63796
64227
|
*/
|
|
63797
64228
|
var PowerMeterStatusSchema = object({
|
|
63798
64229
|
/** Instantaneous power draw in watts. */
|
|
63799
|
-
watts: number().optional().meta({
|
|
63800
|
-
unit: "W",
|
|
63801
|
-
label: "Power"
|
|
63802
|
-
}),
|
|
64230
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63803
64231
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63804
|
-
kwhTotal: number().optional().meta({
|
|
63805
|
-
unit: "kWh",
|
|
63806
|
-
label: "Energy"
|
|
63807
|
-
}),
|
|
64232
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63808
64233
|
/** Voltage in volts. */
|
|
63809
|
-
volts: number().optional(),
|
|
64234
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63810
64235
|
/** Current in amperes. */
|
|
63811
|
-
amps: number().optional(),
|
|
63812
|
-
/** Apparent power in volt-amperes
|
|
63813
|
-
va: number().optional(),
|
|
64236
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
64237
|
+
/** Apparent power in volt-amperes. */
|
|
64238
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63814
64239
|
/** Power factor (0..1) if reported. */
|
|
63815
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
64240
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63816
64241
|
/** Ms epoch when the slice was last updated. */
|
|
63817
|
-
lastFetchedAt: number()
|
|
63818
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63819
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63820
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63821
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63822
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63823
|
-
unit: string$2().optional(),
|
|
63824
|
-
/** Suggested decimal places for numeric display.
|
|
63825
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63826
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63827
|
-
* auto-formatting when absent. */
|
|
63828
|
-
precision: number().int().min(0).max(10).optional()
|
|
64242
|
+
lastFetchedAt: number()
|
|
63829
64243
|
});
|
|
63830
64244
|
var powerMeterCapability = {
|
|
63831
64245
|
name: "power-meter",
|
|
@@ -63889,12 +64303,7 @@ var powerMeterCapability = {
|
|
|
63889
64303
|
} },
|
|
63890
64304
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63891
64305
|
* whether persisting is worth a SQLite commit. */
|
|
63892
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63893
|
-
customize: {
|
|
63894
|
-
version: 1,
|
|
63895
|
-
advanced: "derive",
|
|
63896
|
-
targets: []
|
|
63897
|
-
}
|
|
64306
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63898
64307
|
};
|
|
63899
64308
|
/**
|
|
63900
64309
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63914,11 +64323,11 @@ var powerMeterCapability = {
|
|
|
63914
64323
|
*/
|
|
63915
64324
|
var GpsLocationSchema = object({
|
|
63916
64325
|
/** Latitude in decimal degrees, -90..90. */
|
|
63917
|
-
latitude: number().min(-90).max(90),
|
|
64326
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63918
64327
|
/** Longitude in decimal degrees, -180..180. */
|
|
63919
|
-
longitude: number().min(-180).max(180),
|
|
64328
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63920
64329
|
/** Reported accuracy in meters (lower = better). */
|
|
63921
|
-
accuracyMeters: number().nonnegative()
|
|
64330
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63922
64331
|
});
|
|
63923
64332
|
var PresenceStatusSchema = object({
|
|
63924
64333
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63930,7 +64339,7 @@ var PresenceStatusSchema = object({
|
|
|
63930
64339
|
gps: GpsLocationSchema.nullable(),
|
|
63931
64340
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63932
64341
|
* when not reported. */
|
|
63933
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64342
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63934
64343
|
/** Ms epoch when the slice was last updated. */
|
|
63935
64344
|
lastChangedAt: number()
|
|
63936
64345
|
});
|
|
@@ -63980,19 +64389,10 @@ var presenceCapability = {
|
|
|
63980
64389
|
* `sourceInfo`.
|
|
63981
64390
|
*/
|
|
63982
64391
|
var PressureSensorStatusSchema = object({
|
|
63983
|
-
/** Current pressure in hPa. */
|
|
63984
|
-
hpa: number(),
|
|
64392
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64393
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63985
64394
|
/** Ms epoch when the slice was last updated. */
|
|
63986
|
-
lastFetchedAt: number()
|
|
63987
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63988
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63989
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63990
|
-
unit: string$2().optional(),
|
|
63991
|
-
/** Suggested decimal places for numeric display.
|
|
63992
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63993
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63994
|
-
* auto-formatting when absent. */
|
|
63995
|
-
precision: number().int().min(0).max(10).optional()
|
|
64395
|
+
lastFetchedAt: number()
|
|
63996
64396
|
});
|
|
63997
64397
|
var pressureSensorCapability = {
|
|
63998
64398
|
name: "pressure-sensor",
|
|
@@ -64406,8 +64806,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64406
64806
|
}), _void(), { kind: "mutation" });
|
|
64407
64807
|
var PtzAutotrackSettingsSchema = object({
|
|
64408
64808
|
targetType: string$2().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64409
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64410
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64809
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64810
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64411
64811
|
});
|
|
64412
64812
|
/**
|
|
64413
64813
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64561,7 +64961,7 @@ var RunningStateStatusSchema = object({
|
|
|
64561
64961
|
/** null = unknown — never coerced to false (D393). */
|
|
64562
64962
|
running: boolean().nullable(),
|
|
64563
64963
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64564
|
-
since: number().nullable(),
|
|
64964
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64565
64965
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64566
64966
|
phase: string$2().nullable(),
|
|
64567
64967
|
/** null until a reading has been published (D393). */
|
|
@@ -64576,7 +64976,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64576
64976
|
/** Generic Customize target for the running boolean (D936). */
|
|
64577
64977
|
var runningCustomize = {
|
|
64578
64978
|
version: 1,
|
|
64579
|
-
advanced: "derive",
|
|
64580
64979
|
targets: [{
|
|
64581
64980
|
id: "running",
|
|
64582
64981
|
cardinality: "scalar",
|
|
@@ -64596,7 +64995,7 @@ var runningCustomize = {
|
|
|
64596
64995
|
DeviceType.Thermostat,
|
|
64597
64996
|
DeviceType.PetFeeder
|
|
64598
64997
|
],
|
|
64599
|
-
apply: "add
|
|
64998
|
+
apply: "add",
|
|
64600
64999
|
path: "running",
|
|
64601
65000
|
sources: [
|
|
64602
65001
|
{
|
|
@@ -65860,9 +66259,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65860
66259
|
*/
|
|
65861
66260
|
var RecordWindowSchema = object({
|
|
65862
66261
|
trigger: RecordTriggerSchema,
|
|
65863
|
-
day: number().int().min(0).max(6),
|
|
65864
|
-
startMinute: number().int().min(0).max(1439),
|
|
65865
|
-
endMinute: number().int().min(1).max(1440)
|
|
66262
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66263
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66264
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65866
66265
|
});
|
|
65867
66266
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65868
66267
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65938,10 +66337,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65938
66337
|
/** Master "record to the card at all" switch. */
|
|
65939
66338
|
enabled: boolean().nullable(),
|
|
65940
66339
|
overwriteWhenFull: boolean().nullable(),
|
|
65941
|
-
preRecordSec: number().nullable(),
|
|
65942
|
-
postRecordSec: number().nullable(),
|
|
66340
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66341
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65943
66342
|
/** Length of one recorded file, in minutes. */
|
|
65944
|
-
segmentMinutes: number().nullable(),
|
|
66343
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65945
66344
|
/** The primary track's weekly windows, flattened. */
|
|
65946
66345
|
windows: array(RecordWindowSchema),
|
|
65947
66346
|
/**
|
|
@@ -65957,7 +66356,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65957
66356
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65958
66357
|
* writable.
|
|
65959
66358
|
*/
|
|
65960
|
-
unreadableWindows: number(),
|
|
66359
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65961
66360
|
/**
|
|
65962
66361
|
* The camera is scheduled to record and has NO usable storage.
|
|
65963
66362
|
*
|
|
@@ -66802,7 +67201,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66802
67201
|
url: string$2().optional(),
|
|
66803
67202
|
codec: string$2().optional(),
|
|
66804
67203
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66805
|
-
fps: number().positive().optional(),
|
|
67204
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66806
67205
|
label: string$2().optional(),
|
|
66807
67206
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66808
67207
|
deviceFeatures: array(string$2()).optional(),
|
|
@@ -66889,18 +67288,18 @@ var StreamProfileSchema = _enum([
|
|
|
66889
67288
|
]);
|
|
66890
67289
|
/** The current encoding config of one stream profile. */
|
|
66891
67290
|
var StreamProfileConfigSchema = object({
|
|
66892
|
-
width: number(),
|
|
66893
|
-
height: number(),
|
|
67291
|
+
width: number().meta(readingMeta("none")),
|
|
67292
|
+
height: number().meta(readingMeta("none")),
|
|
66894
67293
|
codec: _enum(["h264", "h265"]),
|
|
66895
|
-
framerate: number(),
|
|
66896
|
-
bitrate: number(),
|
|
67294
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67295
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66897
67296
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66898
67297
|
encoderProfile: _enum([
|
|
66899
67298
|
"high",
|
|
66900
67299
|
"main",
|
|
66901
67300
|
"baseline"
|
|
66902
67301
|
]).optional(),
|
|
66903
|
-
gop: number().optional(),
|
|
67302
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66904
67303
|
/**
|
|
66905
67304
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66906
67305
|
*
|
|
@@ -67121,12 +67520,7 @@ var switchCapability = {
|
|
|
67121
67520
|
label: "On",
|
|
67122
67521
|
kind: "boolean"
|
|
67123
67522
|
}
|
|
67124
|
-
}] }
|
|
67125
|
-
customize: {
|
|
67126
|
-
version: 1,
|
|
67127
|
-
advanced: "derive",
|
|
67128
|
-
targets: []
|
|
67129
|
-
}
|
|
67523
|
+
}] }
|
|
67130
67524
|
};
|
|
67131
67525
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
67132
67526
|
function hasControlCharacter(value) {
|
|
@@ -67709,35 +68103,21 @@ var tamperCapability = {
|
|
|
67709
68103
|
* entries with `device_class: temperature` and any future native
|
|
67710
68104
|
* thermometer.
|
|
67711
68105
|
*
|
|
67712
|
-
*
|
|
67713
|
-
*
|
|
67714
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67715
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67716
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67717
|
-
* `sourceInfo`.
|
|
68106
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
68107
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67718
68108
|
*
|
|
67719
68109
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67720
68110
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67721
68111
|
* changed" steady state.
|
|
67722
68112
|
*/
|
|
67723
68113
|
var TemperatureSensorStatusSchema = object({
|
|
67724
|
-
/** Current temperature in Celsius. */
|
|
67725
|
-
celsius: number().meta({
|
|
67726
|
-
|
|
68114
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68115
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
68116
|
+
precision: 1,
|
|
67727
68117
|
label: "Temperature"
|
|
67728
|
-
}),
|
|
68118
|
+
})),
|
|
67729
68119
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67730
|
-
lastFetchedAt: number()
|
|
67731
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67732
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67733
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67734
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67735
|
-
unit: string$2().optional(),
|
|
67736
|
-
/** Suggested decimal places for numeric display.
|
|
67737
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67738
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67739
|
-
* auto-formatting when absent. */
|
|
67740
|
-
precision: number().int().min(0).max(10).optional()
|
|
68120
|
+
lastFetchedAt: number()
|
|
67741
68121
|
});
|
|
67742
68122
|
var temperatureSensorCapability = {
|
|
67743
68123
|
name: "temperature-sensor",
|
|
@@ -67768,12 +68148,7 @@ var temperatureSensorCapability = {
|
|
|
67768
68148
|
} } },
|
|
67769
68149
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67770
68150
|
* whether persisting is worth a SQLite commit. */
|
|
67771
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67772
|
-
customize: {
|
|
67773
|
-
version: 1,
|
|
67774
|
-
advanced: "derive",
|
|
67775
|
-
targets: []
|
|
67776
|
-
}
|
|
68151
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67777
68152
|
};
|
|
67778
68153
|
/**
|
|
67779
68154
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -68056,16 +68431,16 @@ var VacuumControlStatusSchema = object({
|
|
|
68056
68431
|
]),
|
|
68057
68432
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
68058
68433
|
* reading. */
|
|
68059
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68434
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68060
68435
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
68061
68436
|
* the vacuum has no speed control. */
|
|
68062
68437
|
fanSpeed: string$2().nullable(),
|
|
68063
68438
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68064
68439
|
availableFanSpeeds: array(string$2()),
|
|
68065
68440
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68066
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68441
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68067
68442
|
/** Current error code (0 / null = no error). */
|
|
68068
|
-
errorCode: number().nullable(),
|
|
68443
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68069
68444
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
68070
68445
|
errorLabel: string$2().nullable(),
|
|
68071
68446
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -68143,7 +68518,7 @@ var ValveStatusSchema = object({
|
|
|
68143
68518
|
]),
|
|
68144
68519
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
68145
68520
|
* intermediate position surface. */
|
|
68146
|
-
position: number().min(0).max(100).nullable(),
|
|
68521
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68147
68522
|
/** Ms epoch when the slice was last updated. */
|
|
68148
68523
|
lastChangedAt: number()
|
|
68149
68524
|
});
|
|
@@ -68251,9 +68626,9 @@ var vibrationCapability = {
|
|
|
68251
68626
|
*/
|
|
68252
68627
|
var WaterHeaterStatusSchema = object({
|
|
68253
68628
|
/** Current measured temperature. Null when not reported. */
|
|
68254
|
-
currentTemp: number().nullable(),
|
|
68629
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68255
68630
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68256
|
-
targetTemp: number().nullable(),
|
|
68631
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68257
68632
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68258
68633
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68259
68634
|
* device reports an unknown state. */
|
|
@@ -68264,9 +68639,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68264
68639
|
* has no away surface. */
|
|
68265
68640
|
away: boolean().nullable(),
|
|
68266
68641
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68267
|
-
minTemp: number().nullable(),
|
|
68642
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68268
68643
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68269
|
-
maxTemp: number().nullable(),
|
|
68644
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68270
68645
|
/** Ms epoch when the slice was last updated. */
|
|
68271
68646
|
lastChangedAt: number()
|
|
68272
68647
|
});
|
|
@@ -68351,25 +68726,18 @@ var waterHeaterCapability = {
|
|
|
68351
68726
|
* Forecast deferred — current conditions only for v1.
|
|
68352
68727
|
*/
|
|
68353
68728
|
var WeatherStatusSchema = object({
|
|
68354
|
-
/** Verbatim
|
|
68355
|
-
* when no condition has been reported yet. */
|
|
68729
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68356
68730
|
condition: string$2().nullable(),
|
|
68357
|
-
/** Current temperature in
|
|
68358
|
-
temperature: number().nullable(),
|
|
68359
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68360
|
-
temperatureUnit: string$2().nullable(),
|
|
68731
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68732
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68361
68733
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68362
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68363
|
-
/** Barometric pressure in
|
|
68364
|
-
pressure: number().nullable(),
|
|
68365
|
-
/**
|
|
68366
|
-
|
|
68367
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68368
|
-
windSpeed: number().nullable(),
|
|
68369
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68370
|
-
windSpeedUnit: string$2().nullable(),
|
|
68734
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68735
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68736
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68737
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68738
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68371
68739
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68372
|
-
windBearing: number().nullable(),
|
|
68740
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68373
68741
|
/** Ms epoch when the slice was last updated. */
|
|
68374
68742
|
lastFetchedAt: number()
|
|
68375
68743
|
});
|
|
@@ -68397,12 +68765,12 @@ var weatherCapability = {
|
|
|
68397
68765
|
*/
|
|
68398
68766
|
durability: "session",
|
|
68399
68767
|
/**
|
|
68400
|
-
* History (D850): recorded series.
|
|
68768
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68401
68769
|
*/
|
|
68402
68770
|
history: { fields: {
|
|
68403
68771
|
temperature: {
|
|
68404
68772
|
kind: "gauge",
|
|
68405
|
-
|
|
68773
|
+
unit: "°C",
|
|
68406
68774
|
deadband: .2
|
|
68407
68775
|
},
|
|
68408
68776
|
humidity: {
|
|
@@ -68412,12 +68780,12 @@ var weatherCapability = {
|
|
|
68412
68780
|
},
|
|
68413
68781
|
pressure: {
|
|
68414
68782
|
kind: "gauge",
|
|
68415
|
-
|
|
68783
|
+
unit: "hPa",
|
|
68416
68784
|
deadband: .5
|
|
68417
68785
|
},
|
|
68418
68786
|
windSpeed: {
|
|
68419
68787
|
kind: "gauge",
|
|
68420
|
-
|
|
68788
|
+
unit: "m/s",
|
|
68421
68789
|
deadband: .5
|
|
68422
68790
|
}
|
|
68423
68791
|
} }
|
|
@@ -69648,6 +70016,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69648
70016
|
featureProbe: featureProbeCapability,
|
|
69649
70017
|
flood: floodCapability,
|
|
69650
70018
|
gas: gasCapability,
|
|
70019
|
+
groupCommands: groupCommandsCapability,
|
|
70020
|
+
groupStatus: groupStatusCapability,
|
|
69651
70021
|
heatingValve: heatingValveCapability,
|
|
69652
70022
|
humidifier: humidifierCapability,
|
|
69653
70023
|
humiditySensor: humiditySensorCapability,
|
|
@@ -71024,6 +71394,13 @@ Object.freeze({
|
|
|
71024
71394
|
access: "view",
|
|
71025
71395
|
role: "admin"
|
|
71026
71396
|
},
|
|
71397
|
+
"addons.getPackageDocs": {
|
|
71398
|
+
capName: "addons",
|
|
71399
|
+
capScope: "system",
|
|
71400
|
+
addonId: null,
|
|
71401
|
+
access: "view",
|
|
71402
|
+
role: "admin"
|
|
71403
|
+
},
|
|
71027
71404
|
"addons.getVersions": {
|
|
71028
71405
|
capName: "addons",
|
|
71029
71406
|
capScope: "system",
|
|
@@ -74132,6 +74509,20 @@ Object.freeze({
|
|
|
74132
74509
|
access: "view",
|
|
74133
74510
|
role: "viewer"
|
|
74134
74511
|
},
|
|
74512
|
+
"groupCommands.getStatus": {
|
|
74513
|
+
capName: "group-commands",
|
|
74514
|
+
capScope: "device",
|
|
74515
|
+
addonId: null,
|
|
74516
|
+
access: "view",
|
|
74517
|
+
role: "viewer"
|
|
74518
|
+
},
|
|
74519
|
+
"groupStatus.getStatus": {
|
|
74520
|
+
capName: "group-status",
|
|
74521
|
+
capScope: "device",
|
|
74522
|
+
addonId: null,
|
|
74523
|
+
access: "view",
|
|
74524
|
+
role: "viewer"
|
|
74525
|
+
},
|
|
74135
74526
|
"heatingValve.getStatus": {
|
|
74136
74527
|
capName: "heating-valve",
|
|
74137
74528
|
capScope: "device",
|
|
@@ -83954,6 +84345,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83954
84345
|
icon: "flame"
|
|
83955
84346
|
}]
|
|
83956
84347
|
},
|
|
84348
|
+
"group-commands": {
|
|
84349
|
+
scope: "device",
|
|
84350
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84351
|
+
},
|
|
84352
|
+
"group-status": {
|
|
84353
|
+
scope: "device",
|
|
84354
|
+
noun: t("Group", "Gruppo"),
|
|
84355
|
+
state: [
|
|
84356
|
+
{
|
|
84357
|
+
kind: "numeric",
|
|
84358
|
+
field: "included",
|
|
84359
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84360
|
+
label: t("Reporting", "Rispondono"),
|
|
84361
|
+
icon: "users"
|
|
84362
|
+
},
|
|
84363
|
+
{
|
|
84364
|
+
kind: "numeric",
|
|
84365
|
+
field: "excluded",
|
|
84366
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84367
|
+
label: t("Excluded", "Esclusi"),
|
|
84368
|
+
icon: "users"
|
|
84369
|
+
},
|
|
84370
|
+
{
|
|
84371
|
+
kind: "numeric",
|
|
84372
|
+
field: "total",
|
|
84373
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84374
|
+
label: t("Members", "Membri"),
|
|
84375
|
+
icon: "sigma"
|
|
84376
|
+
}
|
|
84377
|
+
]
|
|
84378
|
+
},
|
|
83957
84379
|
"humidity-sensor": {
|
|
83958
84380
|
scope: "device",
|
|
83959
84381
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83987,7 +84409,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83987
84409
|
field: "value",
|
|
83988
84410
|
quantity: t("the reading", "il valore"),
|
|
83989
84411
|
label: t("Reading", "Valore"),
|
|
83990
|
-
unitField: "unit",
|
|
83991
84412
|
icon: "gauge"
|
|
83992
84413
|
}]
|
|
83993
84414
|
},
|
|
@@ -84123,7 +84544,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84123
84544
|
field: "temperature",
|
|
84124
84545
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
84125
84546
|
label: t("Temperature", "Temperatura"),
|
|
84126
|
-
|
|
84547
|
+
unit: "°C",
|
|
84127
84548
|
icon: "thermometer"
|
|
84128
84549
|
},
|
|
84129
84550
|
{
|
|
@@ -84139,7 +84560,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84139
84560
|
field: "windSpeed",
|
|
84140
84561
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
84141
84562
|
label: t("Wind", "Vento"),
|
|
84142
|
-
|
|
84563
|
+
unit: "m/s",
|
|
84143
84564
|
icon: "wind"
|
|
84144
84565
|
},
|
|
84145
84566
|
{
|
|
@@ -84147,7 +84568,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84147
84568
|
field: "pressure",
|
|
84148
84569
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
84149
84570
|
label: t("Pressure", "Pressione"),
|
|
84150
|
-
|
|
84571
|
+
unit: "hPa",
|
|
84151
84572
|
icon: "gauge"
|
|
84152
84573
|
}
|
|
84153
84574
|
]
|
|
@@ -85420,6 +85841,16 @@ Object.freeze({
|
|
|
85420
85841
|
form: "single",
|
|
85421
85842
|
optional: false
|
|
85422
85843
|
}],
|
|
85844
|
+
"groupCommands.getStatus": [{
|
|
85845
|
+
name: "deviceId",
|
|
85846
|
+
form: "single",
|
|
85847
|
+
optional: false
|
|
85848
|
+
}],
|
|
85849
|
+
"groupStatus.getStatus": [{
|
|
85850
|
+
name: "deviceId",
|
|
85851
|
+
form: "single",
|
|
85852
|
+
optional: false
|
|
85853
|
+
}],
|
|
85423
85854
|
"heatingValve.getStatus": [{
|
|
85424
85855
|
name: "deviceId",
|
|
85425
85856
|
form: "single",
|
|
@@ -87404,6 +87835,8 @@ new Map(Object.entries({
|
|
|
87404
87835
|
"detection-blind": "device-events",
|
|
87405
87836
|
"motion-noisy": "device-events",
|
|
87406
87837
|
"motion-calm": "device-events",
|
|
87838
|
+
"package-llm-silent": "device-events",
|
|
87839
|
+
"package-llm-answered": "device-events",
|
|
87407
87840
|
"recording-stalled": "device-events",
|
|
87408
87841
|
"recording-healthy": "device-events",
|
|
87409
87842
|
"recording-degraded": "device-events",
|
|
@@ -87487,6 +87920,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87487
87920
|
label: "Motion without a subject",
|
|
87488
87921
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87489
87922
|
},
|
|
87923
|
+
{
|
|
87924
|
+
id: "package-llm",
|
|
87925
|
+
family: "device-events",
|
|
87926
|
+
label: "Package confirm",
|
|
87927
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87928
|
+
},
|
|
87490
87929
|
{
|
|
87491
87930
|
id: "recording",
|
|
87492
87931
|
family: "device-events",
|
|
@@ -87668,6 +88107,8 @@ var DEVICE_EVENTS = [
|
|
|
87668
88107
|
"detection-blind",
|
|
87669
88108
|
"motion-noisy",
|
|
87670
88109
|
"motion-calm",
|
|
88110
|
+
"package-llm-silent",
|
|
88111
|
+
"package-llm-answered",
|
|
87671
88112
|
"recording-stalled",
|
|
87672
88113
|
"recording-healthy",
|
|
87673
88114
|
"recording-degraded",
|
|
@@ -87936,6 +88377,15 @@ new Map([
|
|
|
87936
88377
|
snapshotLabel: "Cameras with constant motion now",
|
|
87937
88378
|
snapshotSection: null
|
|
87938
88379
|
},
|
|
88380
|
+
{
|
|
88381
|
+
id: "package-llm-confirm",
|
|
88382
|
+
family: "device-events",
|
|
88383
|
+
label: "Package confirm (not answering / answering again)",
|
|
88384
|
+
bad: ["package-llm-silent"],
|
|
88385
|
+
recovery: ["package-llm-answered"],
|
|
88386
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88387
|
+
snapshotSection: null
|
|
88388
|
+
},
|
|
87939
88389
|
{
|
|
87940
88390
|
id: "recording-health",
|
|
87941
88391
|
family: "device-events",
|
|
@@ -197439,7 +197889,6 @@ function decodeElectricalPower(attributeId, value) {
|
|
|
197439
197889
|
cap: "power-meter",
|
|
197440
197890
|
patch: {
|
|
197441
197891
|
watts: mw / 1e3,
|
|
197442
|
-
unit: "W",
|
|
197443
197892
|
lastFetchedAt: Date.now()
|
|
197444
197893
|
}
|
|
197445
197894
|
};
|