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