@camstack/addon-mqtt-broker 1.2.145 → 1.2.146
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +20 -0
- package/dist/mqtt-broker.addon.js +856 -432
- package/dist/mqtt-broker.addon.mjs +856 -432
- package/package.json +4 -2
|
@@ -39,7 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
39
39
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
40
40
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
41
41
|
//#endregion
|
|
42
|
-
//#region ../types/dist/event-category-
|
|
42
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
43
43
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
44
44
|
EventCategory["SystemBoot"] = "system.boot";
|
|
45
45
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -365,6 +365,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
365
365
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
366
366
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
367
367
|
/**
|
|
368
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
369
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
370
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
371
|
+
*/
|
|
372
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
373
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
374
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
375
|
+
/**
|
|
368
376
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
369
377
|
* (a settings change via `setAgentInferenceDevices` /
|
|
370
378
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5607,7 +5615,7 @@ var ZodIssueCode = {
|
|
|
5607
5615
|
var ZodFirstPartyTypeKind;
|
|
5608
5616
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5609
5617
|
//#endregion
|
|
5610
|
-
//#region ../types/dist/sleep-
|
|
5618
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5611
5619
|
/**
|
|
5612
5620
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5613
5621
|
* window to float samples (D455).
|
|
@@ -8349,6 +8357,99 @@ function defineEntryKind(name, spec) {
|
|
|
8349
8357
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8350
8358
|
return defined;
|
|
8351
8359
|
}
|
|
8360
|
+
var READING_QUANTITIES = [
|
|
8361
|
+
"temperature",
|
|
8362
|
+
"pressure",
|
|
8363
|
+
"speed",
|
|
8364
|
+
"precipitation",
|
|
8365
|
+
"precipitation-rate",
|
|
8366
|
+
"length",
|
|
8367
|
+
"area",
|
|
8368
|
+
"illuminance",
|
|
8369
|
+
"irradiance",
|
|
8370
|
+
"power",
|
|
8371
|
+
"energy",
|
|
8372
|
+
"voltage",
|
|
8373
|
+
"current",
|
|
8374
|
+
"apparent-power",
|
|
8375
|
+
"humidity",
|
|
8376
|
+
"percentage",
|
|
8377
|
+
"concentration-volume",
|
|
8378
|
+
"concentration-mass",
|
|
8379
|
+
"concentration-ppb",
|
|
8380
|
+
"volume",
|
|
8381
|
+
"duration",
|
|
8382
|
+
"duration-ms",
|
|
8383
|
+
"information",
|
|
8384
|
+
"sound-level",
|
|
8385
|
+
"signal-level",
|
|
8386
|
+
"colour-temperature",
|
|
8387
|
+
"angle",
|
|
8388
|
+
"bitrate",
|
|
8389
|
+
"rate",
|
|
8390
|
+
"mass",
|
|
8391
|
+
"index",
|
|
8392
|
+
"ratio",
|
|
8393
|
+
"count",
|
|
8394
|
+
"none",
|
|
8395
|
+
"device"
|
|
8396
|
+
];
|
|
8397
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8398
|
+
new Set(READING_QUANTITIES);
|
|
8399
|
+
/**
|
|
8400
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8401
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8402
|
+
*/
|
|
8403
|
+
var QUANTITY_BASE = {
|
|
8404
|
+
temperature: "°C",
|
|
8405
|
+
pressure: "hPa",
|
|
8406
|
+
speed: "m/s",
|
|
8407
|
+
precipitation: "mm",
|
|
8408
|
+
"precipitation-rate": "mm/h",
|
|
8409
|
+
length: "m",
|
|
8410
|
+
area: "m²",
|
|
8411
|
+
illuminance: "lx",
|
|
8412
|
+
irradiance: "W/m²",
|
|
8413
|
+
power: "W",
|
|
8414
|
+
energy: "kWh",
|
|
8415
|
+
voltage: "V",
|
|
8416
|
+
current: "A",
|
|
8417
|
+
"apparent-power": "VA",
|
|
8418
|
+
humidity: "%",
|
|
8419
|
+
percentage: "%",
|
|
8420
|
+
"concentration-volume": "ppm",
|
|
8421
|
+
"concentration-mass": "µg/m³",
|
|
8422
|
+
"concentration-ppb": "ppb",
|
|
8423
|
+
volume: "L",
|
|
8424
|
+
duration: "s",
|
|
8425
|
+
"duration-ms": "ms",
|
|
8426
|
+
information: "B",
|
|
8427
|
+
"sound-level": "dBFS",
|
|
8428
|
+
"signal-level": "dBm",
|
|
8429
|
+
"colour-temperature": "mired",
|
|
8430
|
+
angle: "°",
|
|
8431
|
+
bitrate: "kbps",
|
|
8432
|
+
rate: "fps",
|
|
8433
|
+
mass: "kg",
|
|
8434
|
+
index: "none",
|
|
8435
|
+
ratio: "none",
|
|
8436
|
+
count: "none",
|
|
8437
|
+
none: "none",
|
|
8438
|
+
device: "device"
|
|
8439
|
+
};
|
|
8440
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8441
|
+
function baseUnitOf(quantity) {
|
|
8442
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8443
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8444
|
+
return symbol;
|
|
8445
|
+
}
|
|
8446
|
+
function readingMeta(quantity, extras) {
|
|
8447
|
+
return {
|
|
8448
|
+
quantity,
|
|
8449
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8450
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8451
|
+
};
|
|
8452
|
+
}
|
|
8352
8453
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8353
8454
|
var CamProfileSchema = _enum([
|
|
8354
8455
|
"high",
|
|
@@ -8376,8 +8477,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8376
8477
|
"derived"
|
|
8377
8478
|
]);
|
|
8378
8479
|
var CamStreamResolutionSchema = object({
|
|
8379
|
-
width: number().int().positive(),
|
|
8380
|
-
height: number().int().positive()
|
|
8480
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8481
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8381
8482
|
});
|
|
8382
8483
|
var CameraStreamSchema = object({
|
|
8383
8484
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8891,6 +8992,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8891
8992
|
"filesystem-browse",
|
|
8892
8993
|
"flood",
|
|
8893
8994
|
"gas",
|
|
8995
|
+
"group-commands",
|
|
8996
|
+
"group-status",
|
|
8894
8997
|
"heating-valve",
|
|
8895
8998
|
"humidifier",
|
|
8896
8999
|
"humidity-sensor",
|
|
@@ -9020,14 +9123,6 @@ Object.freeze({
|
|
|
9020
9123
|
{
|
|
9021
9124
|
"path": "aqi",
|
|
9022
9125
|
"valueType": "number"
|
|
9023
|
-
},
|
|
9024
|
-
{
|
|
9025
|
-
"path": "unit",
|
|
9026
|
-
"valueType": "string"
|
|
9027
|
-
},
|
|
9028
|
-
{
|
|
9029
|
-
"path": "precision",
|
|
9030
|
-
"valueType": "number"
|
|
9031
9126
|
}
|
|
9032
9127
|
],
|
|
9033
9128
|
"alarm-panel": [
|
|
@@ -9063,20 +9158,10 @@ Object.freeze({
|
|
|
9063
9158
|
"valueType": "boolean"
|
|
9064
9159
|
}
|
|
9065
9160
|
],
|
|
9066
|
-
"ambient-light-sensor": [
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
},
|
|
9071
|
-
{
|
|
9072
|
-
"path": "unit",
|
|
9073
|
-
"valueType": "string"
|
|
9074
|
-
},
|
|
9075
|
-
{
|
|
9076
|
-
"path": "precision",
|
|
9077
|
-
"valueType": "number"
|
|
9078
|
-
}
|
|
9079
|
-
],
|
|
9161
|
+
"ambient-light-sensor": [{
|
|
9162
|
+
"path": "lux",
|
|
9163
|
+
"valueType": "number"
|
|
9164
|
+
}],
|
|
9080
9165
|
"audio-metrics": [
|
|
9081
9166
|
{
|
|
9082
9167
|
"path": "ts",
|
|
@@ -9156,6 +9241,10 @@ Object.freeze({
|
|
|
9156
9241
|
"path": "lastUpdated",
|
|
9157
9242
|
"valueType": "number"
|
|
9158
9243
|
},
|
|
9244
|
+
{
|
|
9245
|
+
"path": "volts",
|
|
9246
|
+
"valueType": "number"
|
|
9247
|
+
},
|
|
9159
9248
|
{
|
|
9160
9249
|
"path": "lastContactAt",
|
|
9161
9250
|
"valueType": "number"
|
|
@@ -9398,10 +9487,6 @@ Object.freeze({
|
|
|
9398
9487
|
"datetime"
|
|
9399
9488
|
]
|
|
9400
9489
|
},
|
|
9401
|
-
{
|
|
9402
|
-
"path": "unit",
|
|
9403
|
-
"valueType": "string"
|
|
9404
|
-
},
|
|
9405
9490
|
{
|
|
9406
9491
|
"path": "min",
|
|
9407
9492
|
"valueType": "number"
|
|
@@ -9413,19 +9498,6 @@ Object.freeze({
|
|
|
9413
9498
|
{
|
|
9414
9499
|
"path": "step",
|
|
9415
9500
|
"valueType": "number"
|
|
9416
|
-
},
|
|
9417
|
-
{
|
|
9418
|
-
"path": "precision",
|
|
9419
|
-
"valueType": "number"
|
|
9420
|
-
},
|
|
9421
|
-
{
|
|
9422
|
-
"path": "format",
|
|
9423
|
-
"valueType": "enum",
|
|
9424
|
-
"enumValues": [
|
|
9425
|
-
"date",
|
|
9426
|
-
"time",
|
|
9427
|
-
"datetime"
|
|
9428
|
-
]
|
|
9429
9501
|
}
|
|
9430
9502
|
],
|
|
9431
9503
|
"cover": [
|
|
@@ -9666,13 +9738,8 @@ Object.freeze({
|
|
|
9666
9738
|
"path": "value",
|
|
9667
9739
|
"valueType": "string"
|
|
9668
9740
|
}, {
|
|
9669
|
-
"path": "
|
|
9670
|
-
"valueType": "
|
|
9671
|
-
"enumValues": [
|
|
9672
|
-
"date",
|
|
9673
|
-
"time",
|
|
9674
|
-
"datetime"
|
|
9675
|
-
]
|
|
9741
|
+
"path": "timestamp",
|
|
9742
|
+
"valueType": "boolean"
|
|
9676
9743
|
}],
|
|
9677
9744
|
"event-emitter": [
|
|
9678
9745
|
{
|
|
@@ -9745,6 +9812,20 @@ Object.freeze({
|
|
|
9745
9812
|
"path": "detected",
|
|
9746
9813
|
"valueType": "boolean"
|
|
9747
9814
|
}],
|
|
9815
|
+
"group-status": [
|
|
9816
|
+
{
|
|
9817
|
+
"path": "included",
|
|
9818
|
+
"valueType": "number"
|
|
9819
|
+
},
|
|
9820
|
+
{
|
|
9821
|
+
"path": "excluded",
|
|
9822
|
+
"valueType": "number"
|
|
9823
|
+
},
|
|
9824
|
+
{
|
|
9825
|
+
"path": "total",
|
|
9826
|
+
"valueType": "number"
|
|
9827
|
+
}
|
|
9828
|
+
],
|
|
9748
9829
|
"heating-valve": [{
|
|
9749
9830
|
"path": "position",
|
|
9750
9831
|
"valueType": "number"
|
|
@@ -9779,20 +9860,10 @@ Object.freeze({
|
|
|
9779
9860
|
"valueType": "number"
|
|
9780
9861
|
}
|
|
9781
9862
|
],
|
|
9782
|
-
"humidity-sensor": [
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
},
|
|
9787
|
-
{
|
|
9788
|
-
"path": "unit",
|
|
9789
|
-
"valueType": "string"
|
|
9790
|
-
},
|
|
9791
|
-
{
|
|
9792
|
-
"path": "precision",
|
|
9793
|
-
"valueType": "number"
|
|
9794
|
-
}
|
|
9795
|
-
],
|
|
9863
|
+
"humidity-sensor": [{
|
|
9864
|
+
"path": "percent",
|
|
9865
|
+
"valueType": "number"
|
|
9866
|
+
}],
|
|
9796
9867
|
"image": [{
|
|
9797
9868
|
"path": "url",
|
|
9798
9869
|
"valueType": "string"
|
|
@@ -10131,20 +10202,10 @@ Object.freeze({
|
|
|
10131
10202
|
"valueType": "boolean"
|
|
10132
10203
|
}
|
|
10133
10204
|
],
|
|
10134
|
-
"numeric-sensor": [
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
},
|
|
10139
|
-
{
|
|
10140
|
-
"path": "unit",
|
|
10141
|
-
"valueType": "string"
|
|
10142
|
-
},
|
|
10143
|
-
{
|
|
10144
|
-
"path": "precision",
|
|
10145
|
-
"valueType": "number"
|
|
10146
|
-
}
|
|
10147
|
-
],
|
|
10205
|
+
"numeric-sensor": [{
|
|
10206
|
+
"path": "value",
|
|
10207
|
+
"valueType": "number"
|
|
10208
|
+
}],
|
|
10148
10209
|
"pet-feeder": [
|
|
10149
10210
|
{
|
|
10150
10211
|
"path": "foodLevel",
|
|
@@ -10236,14 +10297,6 @@ Object.freeze({
|
|
|
10236
10297
|
{
|
|
10237
10298
|
"path": "powerFactor",
|
|
10238
10299
|
"valueType": "number"
|
|
10239
|
-
},
|
|
10240
|
-
{
|
|
10241
|
-
"path": "unit",
|
|
10242
|
-
"valueType": "string"
|
|
10243
|
-
},
|
|
10244
|
-
{
|
|
10245
|
-
"path": "precision",
|
|
10246
|
-
"valueType": "number"
|
|
10247
10300
|
}
|
|
10248
10301
|
],
|
|
10249
10302
|
"presence": [
|
|
@@ -10272,20 +10325,10 @@ Object.freeze({
|
|
|
10272
10325
|
"valueType": "number"
|
|
10273
10326
|
}
|
|
10274
10327
|
],
|
|
10275
|
-
"pressure-sensor": [
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
},
|
|
10280
|
-
{
|
|
10281
|
-
"path": "unit",
|
|
10282
|
-
"valueType": "string"
|
|
10283
|
-
},
|
|
10284
|
-
{
|
|
10285
|
-
"path": "precision",
|
|
10286
|
-
"valueType": "number"
|
|
10287
|
-
}
|
|
10288
|
-
],
|
|
10328
|
+
"pressure-sensor": [{
|
|
10329
|
+
"path": "hpa",
|
|
10330
|
+
"valueType": "number"
|
|
10331
|
+
}],
|
|
10289
10332
|
"privacy-mask": [{
|
|
10290
10333
|
"path": "enabled",
|
|
10291
10334
|
"valueType": "boolean"
|
|
@@ -10596,20 +10639,10 @@ Object.freeze({
|
|
|
10596
10639
|
"path": "tampered",
|
|
10597
10640
|
"valueType": "boolean"
|
|
10598
10641
|
}],
|
|
10599
|
-
"temperature-sensor": [
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
},
|
|
10604
|
-
{
|
|
10605
|
-
"path": "unit",
|
|
10606
|
-
"valueType": "string"
|
|
10607
|
-
},
|
|
10608
|
-
{
|
|
10609
|
-
"path": "precision",
|
|
10610
|
-
"valueType": "number"
|
|
10611
|
-
}
|
|
10612
|
-
],
|
|
10642
|
+
"temperature-sensor": [{
|
|
10643
|
+
"path": "celsius",
|
|
10644
|
+
"valueType": "number"
|
|
10645
|
+
}],
|
|
10613
10646
|
"update": [
|
|
10614
10647
|
{
|
|
10615
10648
|
"path": "currentVersion",
|
|
@@ -10720,10 +10753,6 @@ Object.freeze({
|
|
|
10720
10753
|
"path": "temperature",
|
|
10721
10754
|
"valueType": "number"
|
|
10722
10755
|
},
|
|
10723
|
-
{
|
|
10724
|
-
"path": "temperatureUnit",
|
|
10725
|
-
"valueType": "string"
|
|
10726
|
-
},
|
|
10727
10756
|
{
|
|
10728
10757
|
"path": "humidity",
|
|
10729
10758
|
"valueType": "number"
|
|
@@ -10732,18 +10761,10 @@ Object.freeze({
|
|
|
10732
10761
|
"path": "pressure",
|
|
10733
10762
|
"valueType": "number"
|
|
10734
10763
|
},
|
|
10735
|
-
{
|
|
10736
|
-
"path": "pressureUnit",
|
|
10737
|
-
"valueType": "string"
|
|
10738
|
-
},
|
|
10739
10764
|
{
|
|
10740
10765
|
"path": "windSpeed",
|
|
10741
10766
|
"valueType": "number"
|
|
10742
10767
|
},
|
|
10743
|
-
{
|
|
10744
|
-
"path": "windSpeedUnit",
|
|
10745
|
-
"valueType": "string"
|
|
10746
|
-
},
|
|
10747
10768
|
{
|
|
10748
10769
|
"path": "windBearing",
|
|
10749
10770
|
"valueType": "number"
|
|
@@ -11136,7 +11157,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11136
11157
|
return DeviceRole;
|
|
11137
11158
|
}({});
|
|
11138
11159
|
//#endregion
|
|
11139
|
-
//#region ../types/dist/composition-
|
|
11160
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11140
11161
|
/**
|
|
11141
11162
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11142
11163
|
*
|
|
@@ -11891,15 +11912,74 @@ function validateExpressionSource(src) {
|
|
|
11891
11912
|
}
|
|
11892
11913
|
return null;
|
|
11893
11914
|
}
|
|
11894
|
-
/**
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11915
|
+
/**
|
|
11916
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11917
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11918
|
+
* `composition.ts` (D659).
|
|
11919
|
+
*/
|
|
11898
11920
|
var CompositionSourceRefSchema = object({
|
|
11899
11921
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11900
11922
|
addonId: string().min(1),
|
|
11901
11923
|
stableId: string().min(1)
|
|
11902
11924
|
});
|
|
11925
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11926
|
+
"temperature",
|
|
11927
|
+
"humidity",
|
|
11928
|
+
"pressure",
|
|
11929
|
+
"illuminance",
|
|
11930
|
+
"power",
|
|
11931
|
+
"energy",
|
|
11932
|
+
"battery",
|
|
11933
|
+
"numeric",
|
|
11934
|
+
"motion",
|
|
11935
|
+
"contact",
|
|
11936
|
+
"leak",
|
|
11937
|
+
"smoke",
|
|
11938
|
+
"occupancy",
|
|
11939
|
+
"binary",
|
|
11940
|
+
"switch",
|
|
11941
|
+
"light"
|
|
11942
|
+
];
|
|
11943
|
+
var NUMERIC_AGGREGATES = [
|
|
11944
|
+
"mean",
|
|
11945
|
+
"median",
|
|
11946
|
+
"min",
|
|
11947
|
+
"max",
|
|
11948
|
+
"sum"
|
|
11949
|
+
];
|
|
11950
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11951
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11952
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11953
|
+
var AGGREGATE_REDUCERS = [
|
|
11954
|
+
"mean",
|
|
11955
|
+
"median",
|
|
11956
|
+
"min",
|
|
11957
|
+
"max",
|
|
11958
|
+
"sum",
|
|
11959
|
+
"any",
|
|
11960
|
+
"all"
|
|
11961
|
+
];
|
|
11962
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11963
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11964
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11965
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11966
|
+
var HelperMemberSchema = object({
|
|
11967
|
+
source: CompositionSourceRefSchema,
|
|
11968
|
+
cap: string().min(1),
|
|
11969
|
+
fieldPath: string().min(1)
|
|
11970
|
+
});
|
|
11971
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11972
|
+
kind: literal("group"),
|
|
11973
|
+
templateId: GroupTemplateIdSchema,
|
|
11974
|
+
aggregate: AggregateReducerSchema,
|
|
11975
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11976
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11977
|
+
active: ActiveCriterionSchema.optional()
|
|
11978
|
+
})]);
|
|
11979
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11980
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11981
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11982
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11903
11983
|
/** One field of one capability of one source device. */
|
|
11904
11984
|
var CompositionFieldReadSchema = object({
|
|
11905
11985
|
source: CompositionSourceRefSchema,
|
|
@@ -11943,7 +12023,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11943
12023
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11944
12024
|
CompositionFromSourceSchema,
|
|
11945
12025
|
CompositionExpressionSourceSchema,
|
|
11946
|
-
CompositionCodeSourceSchema
|
|
12026
|
+
CompositionCodeSourceSchema,
|
|
12027
|
+
object({
|
|
12028
|
+
kind: literal("aggregate"),
|
|
12029
|
+
reducer: _enum([
|
|
12030
|
+
"mean",
|
|
12031
|
+
"median",
|
|
12032
|
+
"min",
|
|
12033
|
+
"max",
|
|
12034
|
+
"sum",
|
|
12035
|
+
"any",
|
|
12036
|
+
"all"
|
|
12037
|
+
]),
|
|
12038
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12039
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12040
|
+
publish: _enum([
|
|
12041
|
+
"value",
|
|
12042
|
+
"included",
|
|
12043
|
+
"excluded",
|
|
12044
|
+
"total"
|
|
12045
|
+
]),
|
|
12046
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12047
|
+
empty: _enum([
|
|
12048
|
+
"null",
|
|
12049
|
+
"omit",
|
|
12050
|
+
"offline"
|
|
12051
|
+
])
|
|
12052
|
+
})
|
|
11947
12053
|
]);
|
|
11948
12054
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11949
12055
|
kind: literal("forward"),
|
|
@@ -11989,7 +12095,13 @@ var CompositionSchema = object({
|
|
|
11989
12095
|
kind: literal("existing"),
|
|
11990
12096
|
device: CompositionSourceRefSchema
|
|
11991
12097
|
})]),
|
|
11992
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12098
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12099
|
+
/**
|
|
12100
|
+
* Present when the block is a helper template. Absent on a free
|
|
12101
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12102
|
+
* never the compiled features.
|
|
12103
|
+
*/
|
|
12104
|
+
helper: HelperSpecSchema.optional()
|
|
11993
12105
|
}).superRefine((composition, ctx) => {
|
|
11994
12106
|
const seen = /* @__PURE__ */ new Set();
|
|
11995
12107
|
composition.features.forEach((feature, index) => {
|
|
@@ -18140,7 +18252,11 @@ var CompositionProblemSchema = object({
|
|
|
18140
18252
|
"item-field-reserved",
|
|
18141
18253
|
"target-missing",
|
|
18142
18254
|
"target-unreadable",
|
|
18143
|
-
"not-replaceable"
|
|
18255
|
+
"not-replaceable",
|
|
18256
|
+
"native-capability-replace",
|
|
18257
|
+
"mixed-quantity",
|
|
18258
|
+
"helper-mismatch",
|
|
18259
|
+
"member-constraint"
|
|
18144
18260
|
]),
|
|
18145
18261
|
path: string(),
|
|
18146
18262
|
message: string()
|
|
@@ -18161,7 +18277,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18161
18277
|
"null",
|
|
18162
18278
|
"offline",
|
|
18163
18279
|
"unknown",
|
|
18164
|
-
"release"
|
|
18280
|
+
"release",
|
|
18281
|
+
"omit"
|
|
18165
18282
|
]);
|
|
18166
18283
|
/**
|
|
18167
18284
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18198,9 +18315,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18198
18315
|
reads: array(CompositionFieldReadSchema)
|
|
18199
18316
|
});
|
|
18200
18317
|
/**
|
|
18201
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18202
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18203
|
-
*
|
|
18318
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18319
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18320
|
+
* Replacing a capability the device already serves is refused
|
|
18321
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18322
|
+
* wire for a claim the hub already holds.
|
|
18204
18323
|
*/
|
|
18205
18324
|
var CompositionFeatureModeSchema = _enum([
|
|
18206
18325
|
"new",
|
|
@@ -18373,6 +18492,275 @@ Object.freeze({
|
|
|
18373
18492
|
result: ["number", "null"]
|
|
18374
18493
|
}
|
|
18375
18494
|
});
|
|
18495
|
+
/**
|
|
18496
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18497
|
+
* Data, not a form default written into the block.
|
|
18498
|
+
*/
|
|
18499
|
+
var NOW = {
|
|
18500
|
+
fieldPath: "lastFetchedAt",
|
|
18501
|
+
expr: "now"
|
|
18502
|
+
};
|
|
18503
|
+
var CHANGED = {
|
|
18504
|
+
fieldPath: "lastChangedAt",
|
|
18505
|
+
expr: "now"
|
|
18506
|
+
};
|
|
18507
|
+
function numeric(input) {
|
|
18508
|
+
return {
|
|
18509
|
+
...input,
|
|
18510
|
+
family: "numeric",
|
|
18511
|
+
deviceType: DeviceType.Sensor,
|
|
18512
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18513
|
+
commandCaps: [],
|
|
18514
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18515
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18516
|
+
accept: [{
|
|
18517
|
+
cap: input.outputCap,
|
|
18518
|
+
fieldPath: input.outputField
|
|
18519
|
+
}]
|
|
18520
|
+
};
|
|
18521
|
+
}
|
|
18522
|
+
function binary(input) {
|
|
18523
|
+
return {
|
|
18524
|
+
...input,
|
|
18525
|
+
family: "binary",
|
|
18526
|
+
deviceType: DeviceType.Sensor,
|
|
18527
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18528
|
+
commandCaps: [],
|
|
18529
|
+
quantity: "none",
|
|
18530
|
+
baseUnit: void 0,
|
|
18531
|
+
aggregates: BINARY_AGGREGATES,
|
|
18532
|
+
empty: "offline"
|
|
18533
|
+
};
|
|
18534
|
+
}
|
|
18535
|
+
var GROUP_TEMPLATES = [
|
|
18536
|
+
numeric({
|
|
18537
|
+
id: "temperature",
|
|
18538
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18539
|
+
role: DeviceRole.TemperatureSensor,
|
|
18540
|
+
outputCap: "temperature-sensor",
|
|
18541
|
+
outputField: "celsius",
|
|
18542
|
+
quantity: "temperature",
|
|
18543
|
+
defaultAggregate: "mean",
|
|
18544
|
+
empty: "null",
|
|
18545
|
+
companions: [NOW]
|
|
18546
|
+
}),
|
|
18547
|
+
numeric({
|
|
18548
|
+
id: "humidity",
|
|
18549
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18550
|
+
role: DeviceRole.HumiditySensor,
|
|
18551
|
+
outputCap: "humidity-sensor",
|
|
18552
|
+
outputField: "percent",
|
|
18553
|
+
quantity: "humidity",
|
|
18554
|
+
defaultAggregate: "mean",
|
|
18555
|
+
empty: "null",
|
|
18556
|
+
companions: [NOW]
|
|
18557
|
+
}),
|
|
18558
|
+
numeric({
|
|
18559
|
+
id: "pressure",
|
|
18560
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18561
|
+
role: DeviceRole.PressureSensor,
|
|
18562
|
+
outputCap: "pressure-sensor",
|
|
18563
|
+
outputField: "hpa",
|
|
18564
|
+
quantity: "pressure",
|
|
18565
|
+
defaultAggregate: "mean",
|
|
18566
|
+
empty: "null",
|
|
18567
|
+
companions: [NOW]
|
|
18568
|
+
}),
|
|
18569
|
+
numeric({
|
|
18570
|
+
id: "illuminance",
|
|
18571
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18572
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18573
|
+
outputCap: "ambient-light-sensor",
|
|
18574
|
+
outputField: "lux",
|
|
18575
|
+
quantity: "illuminance",
|
|
18576
|
+
defaultAggregate: "mean",
|
|
18577
|
+
empty: "null",
|
|
18578
|
+
companions: [NOW]
|
|
18579
|
+
}),
|
|
18580
|
+
numeric({
|
|
18581
|
+
id: "power",
|
|
18582
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18583
|
+
role: DeviceRole.PowerSensor,
|
|
18584
|
+
outputCap: "power-meter",
|
|
18585
|
+
outputField: "watts",
|
|
18586
|
+
quantity: "power",
|
|
18587
|
+
defaultAggregate: "sum",
|
|
18588
|
+
empty: "omit",
|
|
18589
|
+
companions: [NOW]
|
|
18590
|
+
}),
|
|
18591
|
+
numeric({
|
|
18592
|
+
id: "energy",
|
|
18593
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18594
|
+
role: DeviceRole.EnergySensor,
|
|
18595
|
+
outputCap: "power-meter",
|
|
18596
|
+
outputField: "kwhTotal",
|
|
18597
|
+
quantity: "energy",
|
|
18598
|
+
defaultAggregate: "sum",
|
|
18599
|
+
empty: "omit",
|
|
18600
|
+
companions: [NOW]
|
|
18601
|
+
}),
|
|
18602
|
+
numeric({
|
|
18603
|
+
id: "battery",
|
|
18604
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18605
|
+
role: DeviceRole.BatterySensor,
|
|
18606
|
+
outputCap: "battery",
|
|
18607
|
+
outputField: "percentage",
|
|
18608
|
+
quantity: "percentage",
|
|
18609
|
+
defaultAggregate: "mean",
|
|
18610
|
+
empty: "null",
|
|
18611
|
+
companions: [
|
|
18612
|
+
{
|
|
18613
|
+
fieldPath: "charging",
|
|
18614
|
+
expr: "\"unknown\""
|
|
18615
|
+
},
|
|
18616
|
+
{
|
|
18617
|
+
fieldPath: "sleeping",
|
|
18618
|
+
expr: "false"
|
|
18619
|
+
},
|
|
18620
|
+
{
|
|
18621
|
+
fieldPath: "lastUpdated",
|
|
18622
|
+
expr: "now"
|
|
18623
|
+
}
|
|
18624
|
+
]
|
|
18625
|
+
}),
|
|
18626
|
+
numeric({
|
|
18627
|
+
id: "numeric",
|
|
18628
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18629
|
+
role: DeviceRole.NumericSensor,
|
|
18630
|
+
outputCap: "numeric-sensor",
|
|
18631
|
+
outputField: "value",
|
|
18632
|
+
quantity: "device",
|
|
18633
|
+
defaultAggregate: "mean",
|
|
18634
|
+
empty: "null",
|
|
18635
|
+
companions: [NOW]
|
|
18636
|
+
}),
|
|
18637
|
+
binary({
|
|
18638
|
+
id: "motion",
|
|
18639
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18640
|
+
role: DeviceRole.MotionSensor,
|
|
18641
|
+
outputCap: "motion",
|
|
18642
|
+
outputField: "detected",
|
|
18643
|
+
defaultAggregate: "any",
|
|
18644
|
+
accept: [{
|
|
18645
|
+
cap: "motion",
|
|
18646
|
+
fieldPath: "detected"
|
|
18647
|
+
}],
|
|
18648
|
+
companions: [{
|
|
18649
|
+
fieldPath: "lastDetectedAt",
|
|
18650
|
+
expr: "null"
|
|
18651
|
+
}, {
|
|
18652
|
+
fieldPath: "autoClearAfterMs",
|
|
18653
|
+
expr: "null"
|
|
18654
|
+
}]
|
|
18655
|
+
}),
|
|
18656
|
+
binary({
|
|
18657
|
+
id: "contact",
|
|
18658
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18659
|
+
role: DeviceRole.ContactSensor,
|
|
18660
|
+
outputCap: "contact",
|
|
18661
|
+
outputField: "entryOpen",
|
|
18662
|
+
defaultAggregate: "any",
|
|
18663
|
+
accept: [{
|
|
18664
|
+
cap: "contact",
|
|
18665
|
+
fieldPath: "entryOpen"
|
|
18666
|
+
}],
|
|
18667
|
+
companions: [CHANGED]
|
|
18668
|
+
}),
|
|
18669
|
+
binary({
|
|
18670
|
+
id: "leak",
|
|
18671
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18672
|
+
role: DeviceRole.LeakSensor,
|
|
18673
|
+
outputCap: "flood",
|
|
18674
|
+
outputField: "flooded",
|
|
18675
|
+
defaultAggregate: "any",
|
|
18676
|
+
accept: [{
|
|
18677
|
+
cap: "flood",
|
|
18678
|
+
fieldPath: "flooded"
|
|
18679
|
+
}],
|
|
18680
|
+
companions: [CHANGED]
|
|
18681
|
+
}),
|
|
18682
|
+
binary({
|
|
18683
|
+
id: "smoke",
|
|
18684
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18685
|
+
role: DeviceRole.SmokeSensor,
|
|
18686
|
+
outputCap: "smoke",
|
|
18687
|
+
outputField: "detected",
|
|
18688
|
+
defaultAggregate: "any",
|
|
18689
|
+
accept: [{
|
|
18690
|
+
cap: "smoke",
|
|
18691
|
+
fieldPath: "detected"
|
|
18692
|
+
}],
|
|
18693
|
+
companions: [CHANGED]
|
|
18694
|
+
}),
|
|
18695
|
+
binary({
|
|
18696
|
+
id: "occupancy",
|
|
18697
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18698
|
+
role: DeviceRole.BinarySensor,
|
|
18699
|
+
outputCap: "binary",
|
|
18700
|
+
outputField: "on",
|
|
18701
|
+
defaultAggregate: "any",
|
|
18702
|
+
accept: [{
|
|
18703
|
+
cap: "motion",
|
|
18704
|
+
fieldPath: "detected"
|
|
18705
|
+
}, {
|
|
18706
|
+
cap: "binary",
|
|
18707
|
+
fieldPath: "on"
|
|
18708
|
+
}],
|
|
18709
|
+
companions: [CHANGED]
|
|
18710
|
+
}),
|
|
18711
|
+
binary({
|
|
18712
|
+
id: "binary",
|
|
18713
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18714
|
+
role: DeviceRole.BinarySensor,
|
|
18715
|
+
outputCap: "binary",
|
|
18716
|
+
outputField: "on",
|
|
18717
|
+
defaultAggregate: "any",
|
|
18718
|
+
accept: [{
|
|
18719
|
+
cap: "binary",
|
|
18720
|
+
fieldPath: "on"
|
|
18721
|
+
}],
|
|
18722
|
+
companions: [CHANGED]
|
|
18723
|
+
}),
|
|
18724
|
+
actuator({
|
|
18725
|
+
id: "switch",
|
|
18726
|
+
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.",
|
|
18727
|
+
deviceType: DeviceType.Switch,
|
|
18728
|
+
outputCap: "switch",
|
|
18729
|
+
commandCaps: ["switch"]
|
|
18730
|
+
}),
|
|
18731
|
+
actuator({
|
|
18732
|
+
id: "light",
|
|
18733
|
+
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.",
|
|
18734
|
+
deviceType: DeviceType.Light,
|
|
18735
|
+
outputCap: "switch",
|
|
18736
|
+
commandCaps: [
|
|
18737
|
+
"switch",
|
|
18738
|
+
"brightness",
|
|
18739
|
+
"color"
|
|
18740
|
+
]
|
|
18741
|
+
})
|
|
18742
|
+
];
|
|
18743
|
+
function actuator(input) {
|
|
18744
|
+
return {
|
|
18745
|
+
...input,
|
|
18746
|
+
family: "actuator",
|
|
18747
|
+
role: void 0,
|
|
18748
|
+
memberDeviceType: input.deviceType,
|
|
18749
|
+
outputField: "on",
|
|
18750
|
+
quantity: "none",
|
|
18751
|
+
baseUnit: void 0,
|
|
18752
|
+
aggregates: BINARY_AGGREGATES,
|
|
18753
|
+
defaultAggregate: "any",
|
|
18754
|
+
empty: "offline",
|
|
18755
|
+
accept: [{
|
|
18756
|
+
cap: "switch",
|
|
18757
|
+
fieldPath: "on"
|
|
18758
|
+
}],
|
|
18759
|
+
companions: [CHANGED]
|
|
18760
|
+
};
|
|
18761
|
+
}
|
|
18762
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18763
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18376
18764
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18377
18765
|
/**
|
|
18378
18766
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20086,12 +20474,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20086
20474
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20087
20475
|
* in-place so dispatch keeps working.
|
|
20088
20476
|
*
|
|
20089
|
-
* **
|
|
20090
|
-
*
|
|
20091
|
-
*
|
|
20092
|
-
*
|
|
20093
|
-
* (`ha-domain-mapping`)
|
|
20094
|
-
* stored after that point.
|
|
20477
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20478
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20479
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20480
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20481
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20482
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20095
20483
|
*
|
|
20096
20484
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20097
20485
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20105,6 +20493,14 @@ var SourceInfoSchema = object({
|
|
|
20105
20493
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20106
20494
|
* Used to detect rename when `id` changes. */
|
|
20107
20495
|
uniqueId: string().optional(),
|
|
20496
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20497
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20498
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20499
|
+
dateTimeShape: _enum([
|
|
20500
|
+
"date",
|
|
20501
|
+
"time",
|
|
20502
|
+
"datetime"
|
|
20503
|
+
]).optional(),
|
|
20108
20504
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20109
20505
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20110
20506
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41017,7 +41413,8 @@ method(object({
|
|
|
41017
41413
|
"enum"
|
|
41018
41414
|
]),
|
|
41019
41415
|
enumValues: array(string()).optional(),
|
|
41020
|
-
item: boolean().optional()
|
|
41416
|
+
item: boolean().optional(),
|
|
41417
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41021
41418
|
})).readonly(),
|
|
41022
41419
|
itemArray: object({
|
|
41023
41420
|
path: string(),
|
|
@@ -44836,8 +45233,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44836
45233
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44837
45234
|
var MaskGridShapeSchema = object({
|
|
44838
45235
|
kind: literal("grid"),
|
|
44839
|
-
gridWidth: number(),
|
|
44840
|
-
gridHeight: number(),
|
|
45236
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45237
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44841
45238
|
cells: array(boolean())
|
|
44842
45239
|
});
|
|
44843
45240
|
discriminatedUnion("kind", [
|
|
@@ -44949,6 +45346,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44949
45346
|
"detection-blind",
|
|
44950
45347
|
"motion-noisy",
|
|
44951
45348
|
"motion-calm",
|
|
45349
|
+
"package-llm-silent",
|
|
45350
|
+
"package-llm-answered",
|
|
44952
45351
|
"recording-stalled",
|
|
44953
45352
|
"recording-healthy",
|
|
44954
45353
|
"recording-degraded",
|
|
@@ -55963,6 +56362,28 @@ var PackageVersionInfoSchema = object({
|
|
|
55963
56362
|
deprecated: string().optional(),
|
|
55964
56363
|
distTags: array(string()).readonly()
|
|
55965
56364
|
});
|
|
56365
|
+
/**
|
|
56366
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56367
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56368
|
+
* tarball failure — never an empty string standing in for either.
|
|
56369
|
+
*/
|
|
56370
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56371
|
+
object({
|
|
56372
|
+
status: literal("ok"),
|
|
56373
|
+
markdown: string()
|
|
56374
|
+
}),
|
|
56375
|
+
object({ status: literal("missing") }),
|
|
56376
|
+
object({
|
|
56377
|
+
status: literal("error"),
|
|
56378
|
+
message: string()
|
|
56379
|
+
})
|
|
56380
|
+
]);
|
|
56381
|
+
var PackageDocsSchema = object({
|
|
56382
|
+
name: string(),
|
|
56383
|
+
version: string(),
|
|
56384
|
+
readme: PackageDocBodySchema,
|
|
56385
|
+
changelog: PackageDocBodySchema
|
|
56386
|
+
});
|
|
55966
56387
|
var SearchResultSchema = object({
|
|
55967
56388
|
name: string(),
|
|
55968
56389
|
version: string(),
|
|
@@ -56181,7 +56602,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56181
56602
|
}), object({ success: literal(true) }), {
|
|
56182
56603
|
kind: "mutation",
|
|
56183
56604
|
auth: "admin"
|
|
56184
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56605
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56606
|
+
name: string().min(1),
|
|
56607
|
+
version: string().min(1).optional()
|
|
56608
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56185
56609
|
kind: "mutation",
|
|
56186
56610
|
auth: "admin"
|
|
56187
56611
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56231,46 +56655,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56231
56655
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56232
56656
|
object({
|
|
56233
56657
|
/** Carbon dioxide concentration in ppm. */
|
|
56234
|
-
co2Ppm: number().min(0).optional(),
|
|
56658
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56235
56659
|
/** Total volatile organic compounds in ppb. */
|
|
56236
|
-
vocPpb: number().min(0).optional(),
|
|
56660
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56237
56661
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56238
|
-
pm25: number().min(0).optional(),
|
|
56662
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56239
56663
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56240
|
-
pm10: number().min(0).optional(),
|
|
56664
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56241
56665
|
/** Composite AQI value (typically 0..500). */
|
|
56242
|
-
aqi: number().optional(),
|
|
56666
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56243
56667
|
/** Ms epoch when the slice was last updated. */
|
|
56244
|
-
lastFetchedAt: number()
|
|
56245
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56246
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56247
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56248
|
-
* per slice is unambiguous. */
|
|
56249
|
-
unit: string().optional(),
|
|
56250
|
-
/** Suggested decimal places for numeric display.
|
|
56251
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56252
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56253
|
-
* auto-formatting when absent. */
|
|
56254
|
-
precision: number().int().min(0).max(10).optional()
|
|
56668
|
+
lastFetchedAt: number()
|
|
56255
56669
|
});
|
|
56256
56670
|
DeviceType.Sensor;
|
|
56257
56671
|
object({
|
|
56258
|
-
/** Current illuminance in lux (lx). */
|
|
56259
|
-
lux: number().min(0).meta({
|
|
56260
|
-
|
|
56672
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56673
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56674
|
+
precision: 0,
|
|
56261
56675
|
label: "Illuminance"
|
|
56262
|
-
}),
|
|
56676
|
+
})),
|
|
56263
56677
|
/** Ms epoch when the slice was last updated. */
|
|
56264
|
-
lastFetchedAt: number()
|
|
56265
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56266
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56267
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56268
|
-
unit: string().optional(),
|
|
56269
|
-
/** Suggested decimal places for numeric display.
|
|
56270
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56271
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56272
|
-
* auto-formatting when absent. */
|
|
56273
|
-
precision: number().int().min(0).max(10).optional()
|
|
56678
|
+
lastFetchedAt: number()
|
|
56274
56679
|
});
|
|
56275
56680
|
DeviceType.Sensor;
|
|
56276
56681
|
/**
|
|
@@ -56415,10 +56820,7 @@ var BatteryStatusSchema = object({
|
|
|
56415
56820
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56416
56821
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56417
56822
|
*/
|
|
56418
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56419
|
-
unit: "%",
|
|
56420
|
-
label: "Charge"
|
|
56421
|
-
}),
|
|
56823
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56422
56824
|
/**
|
|
56423
56825
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56424
56826
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56445,7 +56847,14 @@ var BatteryStatusSchema = object({
|
|
|
56445
56847
|
*/
|
|
56446
56848
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56447
56849
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56448
|
-
lastUpdated: number(),
|
|
56850
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56851
|
+
/**
|
|
56852
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56853
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56854
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56855
|
+
* `numeric-sensor` on the same device.
|
|
56856
|
+
*/
|
|
56857
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56449
56858
|
/**
|
|
56450
56859
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56451
56860
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56505,7 +56914,7 @@ object({
|
|
|
56505
56914
|
DeviceType.Sensor;
|
|
56506
56915
|
object({
|
|
56507
56916
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56508
|
-
percentage: number().min(0).max(100),
|
|
56917
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56509
56918
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56510
56919
|
lastChangedAt: number()
|
|
56511
56920
|
});
|
|
@@ -56890,21 +57299,21 @@ object({
|
|
|
56890
57299
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56891
57300
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56892
57301
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56893
|
-
target: number().nullable(),
|
|
57302
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56894
57303
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56895
57304
|
* in `heat_cool` mode. */
|
|
56896
|
-
targetHigh: number().nullable(),
|
|
57305
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56897
57306
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56898
57307
|
* in `heat_cool` mode. */
|
|
56899
|
-
targetLow: number().nullable(),
|
|
57308
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56900
57309
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56901
57310
|
* humidity control. */
|
|
56902
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57311
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56903
57312
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56904
57313
|
* the device's internal sensor. */
|
|
56905
|
-
currentTemp: number().nullable(),
|
|
57314
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56906
57315
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56907
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57316
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56908
57317
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56909
57318
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56910
57319
|
swingVertical: boolean().nullable(),
|
|
@@ -56912,11 +57321,11 @@ object({
|
|
|
56912
57321
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56913
57322
|
swingHorizontal: boolean().nullable(),
|
|
56914
57323
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56915
|
-
minTemp: number().nullable().optional(),
|
|
57324
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56916
57325
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56917
|
-
maxTemp: number().nullable().optional(),
|
|
57326
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56918
57327
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56919
|
-
tempStep: number().positive().nullable().optional(),
|
|
57328
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56920
57329
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56921
57330
|
lastFetchedAt: number()
|
|
56922
57331
|
});
|
|
@@ -56995,17 +57404,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
56995
57404
|
* modes to expose in the picker without a slice fetch.
|
|
56996
57405
|
*/
|
|
56997
57406
|
var RgbTripletSchema = object({
|
|
56998
|
-
r: number().int().min(0).max(255),
|
|
56999
|
-
g: number().int().min(0).max(255),
|
|
57000
|
-
b: number().int().min(0).max(255)
|
|
57407
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57408
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57409
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57001
57410
|
});
|
|
57002
57411
|
var HsvTripletSchema = object({
|
|
57003
57412
|
/** Hue in degrees, 0..360. */
|
|
57004
|
-
h: number().min(0).max(360),
|
|
57413
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57005
57414
|
/** Saturation as 0..100 inclusive. */
|
|
57006
|
-
s: number().min(0).max(100),
|
|
57415
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57007
57416
|
/** Value/brightness as 0..100 inclusive. */
|
|
57008
|
-
v: number().min(0).max(100)
|
|
57417
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57009
57418
|
});
|
|
57010
57419
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57011
57420
|
object({
|
|
@@ -57034,7 +57443,7 @@ object({
|
|
|
57034
57443
|
/** Populated when `mode === 'hsv'`. */
|
|
57035
57444
|
hsv: HsvTripletSchema.optional(),
|
|
57036
57445
|
/** Populated when `mode === 'mired'`. */
|
|
57037
|
-
mireds: number().int().optional(),
|
|
57446
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57038
57447
|
/** Ms epoch of the last operator-driven change. */
|
|
57039
57448
|
lastChangedAt: number()
|
|
57040
57449
|
});
|
|
@@ -57158,18 +57567,12 @@ _enum([
|
|
|
57158
57567
|
"empty",
|
|
57159
57568
|
"full"
|
|
57160
57569
|
]);
|
|
57161
|
-
/**
|
|
57162
|
-
|
|
57163
|
-
|
|
57164
|
-
"days",
|
|
57165
|
-
"hours",
|
|
57166
|
-
"cycles"
|
|
57167
|
-
]);
|
|
57168
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57169
|
-
* days). `value` null = unknown (D393). */
|
|
57570
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57571
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57572
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57170
57573
|
var ConsumableRemainingSchema = object({
|
|
57171
|
-
value: number().min(0).nullable(),
|
|
57172
|
-
|
|
57574
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57575
|
+
kind: ConsumableRemainingKindSchema
|
|
57173
57576
|
});
|
|
57174
57577
|
var ConsumablesStatusSchema = object({
|
|
57175
57578
|
items: array(object({
|
|
@@ -57178,7 +57581,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57178
57581
|
/** Display name. */
|
|
57179
57582
|
label: string().min(1),
|
|
57180
57583
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57181
|
-
level: number().min(0).max(100).nullable(),
|
|
57584
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57182
57585
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57183
57586
|
status: ConsumableStatusSchema.nullable(),
|
|
57184
57587
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57195,7 +57598,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57195
57598
|
})),
|
|
57196
57599
|
lastChangedAt: number()
|
|
57197
57600
|
});
|
|
57198
|
-
Object.values(DeviceType), [...
|
|
57601
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57199
57602
|
Object.values(DeviceType), method(object({
|
|
57200
57603
|
deviceId: number().int().nonnegative(),
|
|
57201
57604
|
key: string().min(1)
|
|
@@ -57220,39 +57623,17 @@ object({
|
|
|
57220
57623
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57221
57624
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57222
57625
|
* or time-only — HA accepts all three forms). */
|
|
57223
|
-
value: union([number(), string()]),
|
|
57626
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57224
57627
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57225
57628
|
options: array(string()),
|
|
57226
57629
|
/** Ms epoch when the slice was last updated. */
|
|
57227
57630
|
lastChangedAt: number(),
|
|
57228
|
-
/**
|
|
57229
|
-
|
|
57230
|
-
|
|
57231
|
-
|
|
57232
|
-
/**
|
|
57233
|
-
|
|
57234
|
-
min: number().optional(),
|
|
57235
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57236
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57237
|
-
max: number().optional(),
|
|
57238
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57239
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57240
|
-
step: number().optional(),
|
|
57241
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57242
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57243
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57244
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57245
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57246
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57247
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57248
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57249
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57250
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57251
|
-
format: _enum([
|
|
57252
|
-
"date",
|
|
57253
|
-
"time",
|
|
57254
|
-
"datetime"
|
|
57255
|
-
]).optional()
|
|
57631
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57632
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57633
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57634
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57635
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57636
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57256
57637
|
});
|
|
57257
57638
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57258
57639
|
object({
|
|
@@ -57290,9 +57671,9 @@ object({
|
|
|
57290
57671
|
]),
|
|
57291
57672
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57292
57673
|
* no intermediate position surface. */
|
|
57293
|
-
position: number().min(0).max(100).nullable(),
|
|
57674
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57294
57675
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57295
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57676
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57296
57677
|
/** Ms epoch when the slice was last updated. */
|
|
57297
57678
|
lastChangedAt: number()
|
|
57298
57679
|
});
|
|
@@ -57350,9 +57731,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57350
57731
|
object({
|
|
57351
57732
|
mode: DayNightModeSchema,
|
|
57352
57733
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57353
|
-
sensitivity: number().optional(),
|
|
57734
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57354
57735
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57355
|
-
switchDelaySec: number().optional(),
|
|
57736
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57356
57737
|
lastFetchedAt: number()
|
|
57357
57738
|
});
|
|
57358
57739
|
/**
|
|
@@ -57507,11 +57888,11 @@ object({
|
|
|
57507
57888
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57508
57889
|
availablePrograms: array(string()),
|
|
57509
57890
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57510
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57891
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57511
57892
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57512
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57893
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57513
57894
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57514
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57895
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57515
57896
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57516
57897
|
doorOpen: boolean().nullable(),
|
|
57517
57898
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57535,7 +57916,7 @@ object({
|
|
|
57535
57916
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57536
57917
|
machineCareDue: boolean().nullable(),
|
|
57537
57918
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57538
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57919
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57539
57920
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57540
57921
|
halfLoad: boolean().nullable(),
|
|
57541
57922
|
hygienePlus: boolean().nullable(),
|
|
@@ -57550,7 +57931,7 @@ object({
|
|
|
57550
57931
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57551
57932
|
activeEvents: array(string()),
|
|
57552
57933
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57553
|
-
errorCode: number().nullable(),
|
|
57934
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57554
57935
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57555
57936
|
errorLabel: string().nullable(),
|
|
57556
57937
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57696,24 +58077,14 @@ object({
|
|
|
57696
58077
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57697
58078
|
lastPressedAt: number().nullable(),
|
|
57698
58079
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57699
|
-
pressCountSinceStart: number()
|
|
58080
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57700
58081
|
});
|
|
57701
58082
|
object({
|
|
57702
58083
|
deviceId: number(),
|
|
57703
58084
|
timestamp: number()
|
|
57704
58085
|
});
|
|
57705
58086
|
DeviceType.Button, DeviceType.Camera;
|
|
57706
|
-
|
|
57707
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57708
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57709
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57710
|
-
* The option set is stable across observations; it is persisted in the
|
|
57711
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57712
|
-
* stored in `sourceInfo`.
|
|
57713
|
-
*/
|
|
57714
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57715
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57716
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
58087
|
+
_enum([
|
|
57717
58088
|
"date",
|
|
57718
58089
|
"time",
|
|
57719
58090
|
"datetime"
|
|
@@ -57721,12 +58092,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57721
58092
|
object({
|
|
57722
58093
|
value: string(),
|
|
57723
58094
|
/**
|
|
57724
|
-
* Set
|
|
57725
|
-
* as
|
|
57726
|
-
*
|
|
57727
|
-
* a time-only sensor → `'time'`.
|
|
58095
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
58096
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
58097
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57728
58098
|
*/
|
|
57729
|
-
|
|
58099
|
+
timestamp: boolean().optional(),
|
|
57730
58100
|
/** Ms epoch when the slice was last updated. */
|
|
57731
58101
|
lastFetchedAt: number()
|
|
57732
58102
|
});
|
|
@@ -57745,13 +58115,13 @@ var EventFireSchema = object({
|
|
|
57745
58115
|
deviceId: number(),
|
|
57746
58116
|
eventType: string(),
|
|
57747
58117
|
data: record(string(), unknown()).nullable(),
|
|
57748
|
-
timestamp: number(),
|
|
57749
|
-
seq: number()
|
|
58118
|
+
timestamp: number().meta(readingMeta("none")),
|
|
58119
|
+
seq: number().meta(readingMeta("count"))
|
|
57750
58120
|
});
|
|
57751
58121
|
object({
|
|
57752
58122
|
eventTypes: array(string()),
|
|
57753
58123
|
lastEvent: EventFireSchema.nullable(),
|
|
57754
|
-
eventCountSinceStart: number()
|
|
58124
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57755
58125
|
});
|
|
57756
58126
|
DeviceType.EventEmitter;
|
|
57757
58127
|
var IdentitySchema = object({
|
|
@@ -58140,10 +58510,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58140
58510
|
object({
|
|
58141
58511
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58142
58512
|
* speed surface (single-speed fan). */
|
|
58143
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58513
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58144
58514
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58145
58515
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58146
|
-
percentageStep: number().positive().optional(),
|
|
58516
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58147
58517
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58148
58518
|
* — empty string when no preset is active or supported. */
|
|
58149
58519
|
preset: string(),
|
|
@@ -58225,7 +58595,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58225
58595
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58226
58596
|
model: string().nullable(),
|
|
58227
58597
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58228
|
-
channelCount: number().nullable(),
|
|
58598
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58229
58599
|
/**
|
|
58230
58600
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58231
58601
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58257,9 +58627,39 @@ object({
|
|
|
58257
58627
|
lastChangedAt: number()
|
|
58258
58628
|
});
|
|
58259
58629
|
DeviceType.Sensor;
|
|
58630
|
+
object({
|
|
58631
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58632
|
+
results: array(object({
|
|
58633
|
+
deviceId: number().int().nonnegative(),
|
|
58634
|
+
cap: string().min(1),
|
|
58635
|
+
method: string().min(1),
|
|
58636
|
+
ok: boolean(),
|
|
58637
|
+
error: string().optional(),
|
|
58638
|
+
/** Ms epoch of the attempt. */
|
|
58639
|
+
at: number()
|
|
58640
|
+
})) });
|
|
58641
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58642
|
+
object({
|
|
58643
|
+
/** Members whose current value entered the aggregate. */
|
|
58644
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58645
|
+
precision: 0,
|
|
58646
|
+
label: "Reporting"
|
|
58647
|
+
})),
|
|
58648
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58649
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58650
|
+
precision: 0,
|
|
58651
|
+
label: "Excluded"
|
|
58652
|
+
})),
|
|
58653
|
+
/** `included` + `excluded`. */
|
|
58654
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58655
|
+
precision: 0,
|
|
58656
|
+
label: "Members"
|
|
58657
|
+
}))
|
|
58658
|
+
});
|
|
58659
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58260
58660
|
object({
|
|
58261
58661
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58262
|
-
position: number().min(0).max(100).nullable(),
|
|
58662
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58263
58663
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58264
58664
|
lastFetchedAt: number()
|
|
58265
58665
|
});
|
|
@@ -58268,9 +58668,9 @@ object({
|
|
|
58268
58668
|
/** Whether the humidifier is currently on. */
|
|
58269
58669
|
on: boolean(),
|
|
58270
58670
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58271
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58671
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58272
58672
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58273
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58673
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58274
58674
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58275
58675
|
* device has no mode surface. */
|
|
58276
58676
|
mode: string().nullable(),
|
|
@@ -58280,9 +58680,9 @@ object({
|
|
|
58280
58680
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58281
58681
|
action: string().nullable(),
|
|
58282
58682
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58283
|
-
minHumidity: number().nullable(),
|
|
58683
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58284
58684
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58285
|
-
maxHumidity: number().nullable(),
|
|
58685
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58286
58686
|
/** Ms epoch when the slice was last updated. */
|
|
58287
58687
|
lastChangedAt: number()
|
|
58288
58688
|
});
|
|
@@ -58306,22 +58706,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58306
58706
|
auth: "protected"
|
|
58307
58707
|
});
|
|
58308
58708
|
object({
|
|
58309
|
-
/** Current relative humidity, 0..100. */
|
|
58310
|
-
percent: number().min(0).max(100).meta({
|
|
58311
|
-
|
|
58709
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58710
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58711
|
+
precision: 0,
|
|
58312
58712
|
label: "Humidity"
|
|
58313
|
-
}),
|
|
58713
|
+
})),
|
|
58314
58714
|
/** Ms epoch when the slice was last updated. */
|
|
58315
|
-
lastFetchedAt: number()
|
|
58316
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58317
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58318
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58319
|
-
unit: string().optional(),
|
|
58320
|
-
/** Suggested decimal places for numeric display.
|
|
58321
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58322
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58323
|
-
* auto-formatting when absent. */
|
|
58324
|
-
precision: number().int().min(0).max(10).optional()
|
|
58715
|
+
lastFetchedAt: number()
|
|
58325
58716
|
});
|
|
58326
58717
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58327
58718
|
object({
|
|
@@ -58329,7 +58720,7 @@ object({
|
|
|
58329
58720
|
* entity exposes no `entity_picture` (yet). */
|
|
58330
58721
|
url: string().nullable(),
|
|
58331
58722
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58332
|
-
lastUpdated: number().nullable()
|
|
58723
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58333
58724
|
});
|
|
58334
58725
|
DeviceType.Image;
|
|
58335
58726
|
/**
|
|
@@ -58385,19 +58776,19 @@ var NormalizedRangeSchema = object({
|
|
|
58385
58776
|
});
|
|
58386
58777
|
object({
|
|
58387
58778
|
/** Normalized 0–100. */
|
|
58388
|
-
brightness: number().optional(),
|
|
58779
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58389
58780
|
/** Normalized 0–100. */
|
|
58390
|
-
contrast: number().optional(),
|
|
58781
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58391
58782
|
/** Normalized 0–100. */
|
|
58392
|
-
saturation: number().optional(),
|
|
58783
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58393
58784
|
/** Normalized 0–100. */
|
|
58394
|
-
sharpness: number().optional(),
|
|
58785
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58395
58786
|
mirror: boolean().optional(),
|
|
58396
58787
|
flip: boolean().optional(),
|
|
58397
58788
|
rotate: ImageRotateSchema.optional(),
|
|
58398
58789
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58399
58790
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58400
|
-
warmth: number().optional(),
|
|
58791
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58401
58792
|
exposureMode: ExposureModeSchema.optional(),
|
|
58402
58793
|
backlightMode: BacklightModeSchema.optional(),
|
|
58403
58794
|
lastFetchedAt: number()
|
|
@@ -58642,10 +59033,10 @@ var IntercomAbilitySchema = object({
|
|
|
58642
59033
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58643
59034
|
codecs: array(string()),
|
|
58644
59035
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58645
|
-
sampleRate: number(),
|
|
59036
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58646
59037
|
duplex: _enum(["half", "full"]),
|
|
58647
59038
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58648
|
-
maxBacklogMs: number()
|
|
59039
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58649
59040
|
});
|
|
58650
59041
|
var IntercomStatusSchema = object({
|
|
58651
59042
|
/** True while a talk session is open. */
|
|
@@ -58756,13 +59147,13 @@ object({
|
|
|
58756
59147
|
activity: LawnMowerActivitySchema,
|
|
58757
59148
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58758
59149
|
* reading. */
|
|
58759
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
59150
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58760
59151
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58761
59152
|
* task is active / progress is unavailable. */
|
|
58762
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59153
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58763
59154
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58764
59155
|
* or null when unknown. */
|
|
58765
|
-
currentCode: number().nullable(),
|
|
59156
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58766
59157
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58767
59158
|
currentCodeLabel: string().nullable(),
|
|
58768
59159
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59224,7 +59615,7 @@ object({
|
|
|
59224
59615
|
state: MediaPlayerStateSchema,
|
|
59225
59616
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59226
59617
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59227
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59618
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59228
59619
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59229
59620
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59230
59621
|
isMuted: boolean().nullable(),
|
|
@@ -59237,10 +59628,10 @@ object({
|
|
|
59237
59628
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59238
59629
|
/** Current playback position in ms. Null when not seekable or
|
|
59239
59630
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59240
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59631
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59241
59632
|
/** Total duration of the current media in ms. Null when unknown
|
|
59242
59633
|
* (live stream) or nothing is playing. */
|
|
59243
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59634
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59244
59635
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59245
59636
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59246
59637
|
shuffle: boolean().nullable(),
|
|
@@ -59540,7 +59931,7 @@ object({
|
|
|
59540
59931
|
* it, every provider seeded it at boot, and every session left it
|
|
59541
59932
|
* `detected: true` after its detach.
|
|
59542
59933
|
*/
|
|
59543
|
-
autoClearAfterMs: number().nullable()
|
|
59934
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59544
59935
|
});
|
|
59545
59936
|
/**
|
|
59546
59937
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59590,7 +59981,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59590
59981
|
});
|
|
59591
59982
|
object({
|
|
59592
59983
|
enabled: boolean(),
|
|
59593
|
-
sensitivity: number(),
|
|
59984
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59594
59985
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59595
59986
|
regions: array(MotionZoneRegionSchema),
|
|
59596
59987
|
lastFetchedAt: number()
|
|
@@ -59894,7 +60285,7 @@ var NavigationStatusSchema = object({
|
|
|
59894
60285
|
following: boolean(),
|
|
59895
60286
|
flash: boolean(),
|
|
59896
60287
|
lightMode: NavigationLightModeSchema,
|
|
59897
|
-
lightLevel: number().min(40).max(100),
|
|
60288
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59898
60289
|
/** Ms epoch when the slice was last updated. */
|
|
59899
60290
|
lastChangedAt: number()
|
|
59900
60291
|
});
|
|
@@ -59940,13 +60331,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59940
60331
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59941
60332
|
* SKIP a null rather than coerce it.
|
|
59942
60333
|
*/
|
|
59943
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
60334
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59944
60335
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59945
|
-
rssiDbm: number().optional(),
|
|
60336
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59946
60337
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59947
60338
|
ssid: string().optional(),
|
|
59948
60339
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59949
|
-
lastUpdated: number()
|
|
60340
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59950
60341
|
});
|
|
59951
60342
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59952
60343
|
deviceId: number(),
|
|
@@ -60265,7 +60656,7 @@ object({
|
|
|
60265
60656
|
lastError: string().nullable(),
|
|
60266
60657
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60267
60658
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60268
|
-
queueDepth: number().int().nonnegative(),
|
|
60659
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60269
60660
|
/** Per-feature capability matrix — authoritative source for the
|
|
60270
60661
|
* compose-form field gating. */
|
|
60271
60662
|
supports: NotifierSupportsSchema
|
|
@@ -60315,15 +60706,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60315
60706
|
acceptedAt: number()
|
|
60316
60707
|
});
|
|
60317
60708
|
object({
|
|
60318
|
-
|
|
60319
|
-
|
|
60320
|
-
* Populated live from the upstream source on each state push.
|
|
60321
|
-
* Absent for unitless sensors. */
|
|
60322
|
-
unit: string().optional(),
|
|
60323
|
-
/** Suggested decimal places for numeric display.
|
|
60324
|
-
* Populated live from the upstream source when provided.
|
|
60325
|
-
* Falls back to auto-formatting when absent. */
|
|
60326
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60709
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60710
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60327
60711
|
/** Ms epoch when the slice was last updated. */
|
|
60328
60712
|
lastFetchedAt: number()
|
|
60329
60713
|
});
|
|
@@ -60613,23 +60997,26 @@ object({
|
|
|
60613
60997
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60614
60998
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60615
60999
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60616
|
-
foodLevel: number().nullable(),
|
|
61000
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60617
61001
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60618
61002
|
* single-hopper models. */
|
|
60619
|
-
food1: number().nullable(),
|
|
61003
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60620
61004
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60621
61005
|
* single-hopper models. */
|
|
60622
|
-
food2: number().nullable(),
|
|
61006
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60623
61007
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60624
61008
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60625
61009
|
* below the feeder's low threshold. */
|
|
60626
61010
|
lowFood: boolean(),
|
|
60627
61011
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60628
61012
|
* device has no battery reading. */
|
|
60629
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60630
|
-
/**
|
|
60631
|
-
*
|
|
60632
|
-
|
|
61013
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61014
|
+
/**
|
|
61015
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
61016
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
61017
|
+
* model has no desiccant sensor.
|
|
61018
|
+
*/
|
|
61019
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60633
61020
|
/** True while a feed is in progress. */
|
|
60634
61021
|
feeding: boolean(),
|
|
60635
61022
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60640,7 +61027,7 @@ object({
|
|
|
60640
61027
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60641
61028
|
error: string().nullable(),
|
|
60642
61029
|
/** Raw device error code (0 / null = no error). */
|
|
60643
|
-
errorCode: number().nullable(),
|
|
61030
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60644
61031
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60645
61032
|
isDualHopper: boolean(),
|
|
60646
61033
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60650,7 +61037,7 @@ object({
|
|
|
60650
61037
|
/** Play a chime when dispensing. */
|
|
60651
61038
|
feedSound: boolean(),
|
|
60652
61039
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60653
|
-
volume: number(),
|
|
61040
|
+
volume: number().meta(readingMeta("none")),
|
|
60654
61041
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60655
61042
|
lastFetchedAt: number()
|
|
60656
61043
|
});
|
|
@@ -61087,36 +61474,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61087
61474
|
});
|
|
61088
61475
|
object({
|
|
61089
61476
|
/** Instantaneous power draw in watts. */
|
|
61090
|
-
watts: number().optional().meta({
|
|
61091
|
-
unit: "W",
|
|
61092
|
-
label: "Power"
|
|
61093
|
-
}),
|
|
61477
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61094
61478
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61095
|
-
kwhTotal: number().optional().meta({
|
|
61096
|
-
unit: "kWh",
|
|
61097
|
-
label: "Energy"
|
|
61098
|
-
}),
|
|
61479
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61099
61480
|
/** Voltage in volts. */
|
|
61100
|
-
volts: number().optional(),
|
|
61481
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61101
61482
|
/** Current in amperes. */
|
|
61102
|
-
amps: number().optional(),
|
|
61103
|
-
/** Apparent power in volt-amperes
|
|
61104
|
-
va: number().optional(),
|
|
61483
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61484
|
+
/** Apparent power in volt-amperes. */
|
|
61485
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61105
61486
|
/** Power factor (0..1) if reported. */
|
|
61106
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61487
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61107
61488
|
/** Ms epoch when the slice was last updated. */
|
|
61108
|
-
lastFetchedAt: number()
|
|
61109
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61110
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61111
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61112
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61113
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61114
|
-
unit: string().optional(),
|
|
61115
|
-
/** Suggested decimal places for numeric display.
|
|
61116
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61117
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61118
|
-
* auto-formatting when absent. */
|
|
61119
|
-
precision: number().int().min(0).max(10).optional()
|
|
61489
|
+
lastFetchedAt: number()
|
|
61120
61490
|
});
|
|
61121
61491
|
DeviceType.Sensor;
|
|
61122
61492
|
/**
|
|
@@ -61137,11 +61507,11 @@ DeviceType.Sensor;
|
|
|
61137
61507
|
*/
|
|
61138
61508
|
var GpsLocationSchema = object({
|
|
61139
61509
|
/** Latitude in decimal degrees, -90..90. */
|
|
61140
|
-
latitude: number().min(-90).max(90),
|
|
61510
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61141
61511
|
/** Longitude in decimal degrees, -180..180. */
|
|
61142
|
-
longitude: number().min(-180).max(180),
|
|
61512
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61143
61513
|
/** Reported accuracy in meters (lower = better). */
|
|
61144
|
-
accuracyMeters: number().nonnegative()
|
|
61514
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61145
61515
|
});
|
|
61146
61516
|
object({
|
|
61147
61517
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61153,25 +61523,16 @@ object({
|
|
|
61153
61523
|
gps: GpsLocationSchema.nullable(),
|
|
61154
61524
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61155
61525
|
* when not reported. */
|
|
61156
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61526
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61157
61527
|
/** Ms epoch when the slice was last updated. */
|
|
61158
61528
|
lastChangedAt: number()
|
|
61159
61529
|
});
|
|
61160
61530
|
DeviceType.Presence;
|
|
61161
61531
|
object({
|
|
61162
|
-
/** Current pressure in hPa. */
|
|
61163
|
-
hpa: number(),
|
|
61532
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61533
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61164
61534
|
/** Ms epoch when the slice was last updated. */
|
|
61165
|
-
lastFetchedAt: number()
|
|
61166
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61167
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61168
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61169
|
-
unit: string().optional(),
|
|
61170
|
-
/** Suggested decimal places for numeric display.
|
|
61171
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61172
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61173
|
-
* auto-formatting when absent. */
|
|
61174
|
-
precision: number().int().min(0).max(10).optional()
|
|
61535
|
+
lastFetchedAt: number()
|
|
61175
61536
|
});
|
|
61176
61537
|
DeviceType.Sensor;
|
|
61177
61538
|
/**
|
|
@@ -61504,8 +61865,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61504
61865
|
}), _void(), { kind: "mutation" });
|
|
61505
61866
|
var PtzAutotrackSettingsSchema = object({
|
|
61506
61867
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61507
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61508
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61868
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61869
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61509
61870
|
});
|
|
61510
61871
|
/**
|
|
61511
61872
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61562,7 +61923,7 @@ object({
|
|
|
61562
61923
|
/** null = unknown — never coerced to false (D393). */
|
|
61563
61924
|
running: boolean().nullable(),
|
|
61564
61925
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61565
|
-
since: number().nullable(),
|
|
61926
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61566
61927
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61567
61928
|
phase: string().nullable(),
|
|
61568
61929
|
/** null until a reading has been published (D393). */
|
|
@@ -62760,9 +63121,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62760
63121
|
*/
|
|
62761
63122
|
var RecordWindowSchema = object({
|
|
62762
63123
|
trigger: RecordTriggerSchema,
|
|
62763
|
-
day: number().int().min(0).max(6),
|
|
62764
|
-
startMinute: number().int().min(0).max(1439),
|
|
62765
|
-
endMinute: number().int().min(1).max(1440)
|
|
63124
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
63125
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
63126
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62766
63127
|
});
|
|
62767
63128
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62768
63129
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62831,10 +63192,10 @@ object({
|
|
|
62831
63192
|
/** Master "record to the card at all" switch. */
|
|
62832
63193
|
enabled: boolean().nullable(),
|
|
62833
63194
|
overwriteWhenFull: boolean().nullable(),
|
|
62834
|
-
preRecordSec: number().nullable(),
|
|
62835
|
-
postRecordSec: number().nullable(),
|
|
63195
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
63196
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62836
63197
|
/** Length of one recorded file, in minutes. */
|
|
62837
|
-
segmentMinutes: number().nullable(),
|
|
63198
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62838
63199
|
/** The primary track's weekly windows, flattened. */
|
|
62839
63200
|
windows: array(RecordWindowSchema),
|
|
62840
63201
|
/**
|
|
@@ -62850,7 +63211,7 @@ object({
|
|
|
62850
63211
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62851
63212
|
* writable.
|
|
62852
63213
|
*/
|
|
62853
|
-
unreadableWindows: number(),
|
|
63214
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62854
63215
|
/**
|
|
62855
63216
|
* The camera is scheduled to record and has NO usable storage.
|
|
62856
63217
|
*
|
|
@@ -63487,7 +63848,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63487
63848
|
url: string().optional(),
|
|
63488
63849
|
codec: string().optional(),
|
|
63489
63850
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63490
|
-
fps: number().positive().optional(),
|
|
63851
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63491
63852
|
label: string().optional(),
|
|
63492
63853
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63493
63854
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63517,18 +63878,18 @@ var StreamProfileSchema = _enum([
|
|
|
63517
63878
|
]);
|
|
63518
63879
|
/** The current encoding config of one stream profile. */
|
|
63519
63880
|
var StreamProfileConfigSchema = object({
|
|
63520
|
-
width: number(),
|
|
63521
|
-
height: number(),
|
|
63881
|
+
width: number().meta(readingMeta("none")),
|
|
63882
|
+
height: number().meta(readingMeta("none")),
|
|
63522
63883
|
codec: _enum(["h264", "h265"]),
|
|
63523
|
-
framerate: number(),
|
|
63524
|
-
bitrate: number(),
|
|
63884
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63885
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63525
63886
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63526
63887
|
encoderProfile: _enum([
|
|
63527
63888
|
"high",
|
|
63528
63889
|
"main",
|
|
63529
63890
|
"baseline"
|
|
63530
63891
|
]).optional(),
|
|
63531
|
-
gop: number().optional(),
|
|
63892
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63532
63893
|
/**
|
|
63533
63894
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63534
63895
|
*
|
|
@@ -64171,23 +64532,13 @@ object({
|
|
|
64171
64532
|
});
|
|
64172
64533
|
DeviceType.Sensor;
|
|
64173
64534
|
object({
|
|
64174
|
-
/** Current temperature in Celsius. */
|
|
64175
|
-
celsius: number().meta({
|
|
64176
|
-
|
|
64535
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64536
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64537
|
+
precision: 1,
|
|
64177
64538
|
label: "Temperature"
|
|
64178
|
-
}),
|
|
64539
|
+
})),
|
|
64179
64540
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64180
|
-
lastFetchedAt: number()
|
|
64181
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64182
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64183
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64184
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64185
|
-
unit: string().optional(),
|
|
64186
|
-
/** Suggested decimal places for numeric display.
|
|
64187
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64188
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64189
|
-
* auto-formatting when absent. */
|
|
64190
|
-
precision: number().int().min(0).max(10).optional()
|
|
64541
|
+
lastFetchedAt: number()
|
|
64191
64542
|
});
|
|
64192
64543
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64193
64544
|
/**
|
|
@@ -64439,16 +64790,16 @@ object({
|
|
|
64439
64790
|
]),
|
|
64440
64791
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64441
64792
|
* reading. */
|
|
64442
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64793
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64443
64794
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64444
64795
|
* the vacuum has no speed control. */
|
|
64445
64796
|
fanSpeed: string().nullable(),
|
|
64446
64797
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64447
64798
|
availableFanSpeeds: array(string()),
|
|
64448
64799
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64449
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64800
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64450
64801
|
/** Current error code (0 / null = no error). */
|
|
64451
|
-
errorCode: number().nullable(),
|
|
64802
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64452
64803
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64453
64804
|
errorLabel: string().nullable(),
|
|
64454
64805
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64487,7 +64838,7 @@ object({
|
|
|
64487
64838
|
]),
|
|
64488
64839
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64489
64840
|
* intermediate position surface. */
|
|
64490
|
-
position: number().min(0).max(100).nullable(),
|
|
64841
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64491
64842
|
/** Ms epoch when the slice was last updated. */
|
|
64492
64843
|
lastChangedAt: number()
|
|
64493
64844
|
});
|
|
@@ -64515,9 +64866,9 @@ object({
|
|
|
64515
64866
|
DeviceType.Sensor;
|
|
64516
64867
|
object({
|
|
64517
64868
|
/** Current measured temperature. Null when not reported. */
|
|
64518
|
-
currentTemp: number().nullable(),
|
|
64869
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64519
64870
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64520
|
-
targetTemp: number().nullable(),
|
|
64871
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64521
64872
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64522
64873
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64523
64874
|
* device reports an unknown state. */
|
|
@@ -64528,9 +64879,9 @@ object({
|
|
|
64528
64879
|
* has no away surface. */
|
|
64529
64880
|
away: boolean().nullable(),
|
|
64530
64881
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64531
|
-
minTemp: number().nullable(),
|
|
64882
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64532
64883
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64533
|
-
maxTemp: number().nullable(),
|
|
64884
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64534
64885
|
/** Ms epoch when the slice was last updated. */
|
|
64535
64886
|
lastChangedAt: number()
|
|
64536
64887
|
});
|
|
@@ -64554,25 +64905,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64554
64905
|
auth: "protected"
|
|
64555
64906
|
});
|
|
64556
64907
|
object({
|
|
64557
|
-
/** Verbatim
|
|
64558
|
-
* when no condition has been reported yet. */
|
|
64908
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64559
64909
|
condition: string().nullable(),
|
|
64560
|
-
/** Current temperature in
|
|
64561
|
-
temperature: number().nullable(),
|
|
64562
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64563
|
-
temperatureUnit: string().nullable(),
|
|
64910
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64911
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64564
64912
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64565
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64566
|
-
/** Barometric pressure in
|
|
64567
|
-
pressure: number().nullable(),
|
|
64568
|
-
/**
|
|
64569
|
-
|
|
64570
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64571
|
-
windSpeed: number().nullable(),
|
|
64572
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64573
|
-
windSpeedUnit: string().nullable(),
|
|
64913
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64914
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64915
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64916
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64917
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64574
64918
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64575
|
-
windBearing: number().nullable(),
|
|
64919
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64576
64920
|
/** Ms epoch when the slice was last updated. */
|
|
64577
64921
|
lastFetchedAt: number()
|
|
64578
64922
|
});
|
|
@@ -65484,6 +65828,13 @@ Object.freeze({
|
|
|
65484
65828
|
access: "view",
|
|
65485
65829
|
role: "admin"
|
|
65486
65830
|
},
|
|
65831
|
+
"addons.getPackageDocs": {
|
|
65832
|
+
capName: "addons",
|
|
65833
|
+
capScope: "system",
|
|
65834
|
+
addonId: null,
|
|
65835
|
+
access: "view",
|
|
65836
|
+
role: "admin"
|
|
65837
|
+
},
|
|
65487
65838
|
"addons.getVersions": {
|
|
65488
65839
|
capName: "addons",
|
|
65489
65840
|
capScope: "system",
|
|
@@ -68592,6 +68943,20 @@ Object.freeze({
|
|
|
68592
68943
|
access: "view",
|
|
68593
68944
|
role: "viewer"
|
|
68594
68945
|
},
|
|
68946
|
+
"groupCommands.getStatus": {
|
|
68947
|
+
capName: "group-commands",
|
|
68948
|
+
capScope: "device",
|
|
68949
|
+
addonId: null,
|
|
68950
|
+
access: "view",
|
|
68951
|
+
role: "viewer"
|
|
68952
|
+
},
|
|
68953
|
+
"groupStatus.getStatus": {
|
|
68954
|
+
capName: "group-status",
|
|
68955
|
+
capScope: "device",
|
|
68956
|
+
addonId: null,
|
|
68957
|
+
access: "view",
|
|
68958
|
+
role: "viewer"
|
|
68959
|
+
},
|
|
68595
68960
|
"heatingValve.getStatus": {
|
|
68596
68961
|
capName: "heating-valve",
|
|
68597
68962
|
capScope: "device",
|
|
@@ -78414,6 +78779,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78414
78779
|
icon: "flame"
|
|
78415
78780
|
}]
|
|
78416
78781
|
},
|
|
78782
|
+
"group-commands": {
|
|
78783
|
+
scope: "device",
|
|
78784
|
+
noun: t("Group command", "Comando di gruppo")
|
|
78785
|
+
},
|
|
78786
|
+
"group-status": {
|
|
78787
|
+
scope: "device",
|
|
78788
|
+
noun: t("Group", "Gruppo"),
|
|
78789
|
+
state: [
|
|
78790
|
+
{
|
|
78791
|
+
kind: "numeric",
|
|
78792
|
+
field: "included",
|
|
78793
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
78794
|
+
label: t("Reporting", "Rispondono"),
|
|
78795
|
+
icon: "users"
|
|
78796
|
+
},
|
|
78797
|
+
{
|
|
78798
|
+
kind: "numeric",
|
|
78799
|
+
field: "excluded",
|
|
78800
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
78801
|
+
label: t("Excluded", "Esclusi"),
|
|
78802
|
+
icon: "users"
|
|
78803
|
+
},
|
|
78804
|
+
{
|
|
78805
|
+
kind: "numeric",
|
|
78806
|
+
field: "total",
|
|
78807
|
+
quantity: t("the member count", "il numero di membri"),
|
|
78808
|
+
label: t("Members", "Membri"),
|
|
78809
|
+
icon: "sigma"
|
|
78810
|
+
}
|
|
78811
|
+
]
|
|
78812
|
+
},
|
|
78417
78813
|
"humidity-sensor": {
|
|
78418
78814
|
scope: "device",
|
|
78419
78815
|
noun: t("Humidity", "Umidità"),
|
|
@@ -78447,7 +78843,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78447
78843
|
field: "value",
|
|
78448
78844
|
quantity: t("the reading", "il valore"),
|
|
78449
78845
|
label: t("Reading", "Valore"),
|
|
78450
|
-
unitField: "unit",
|
|
78451
78846
|
icon: "gauge"
|
|
78452
78847
|
}]
|
|
78453
78848
|
},
|
|
@@ -78583,7 +78978,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78583
78978
|
field: "temperature",
|
|
78584
78979
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78585
78980
|
label: t("Temperature", "Temperatura"),
|
|
78586
|
-
|
|
78981
|
+
unit: "°C",
|
|
78587
78982
|
icon: "thermometer"
|
|
78588
78983
|
},
|
|
78589
78984
|
{
|
|
@@ -78599,7 +78994,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78599
78994
|
field: "windSpeed",
|
|
78600
78995
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78601
78996
|
label: t("Wind", "Vento"),
|
|
78602
|
-
|
|
78997
|
+
unit: "m/s",
|
|
78603
78998
|
icon: "wind"
|
|
78604
78999
|
},
|
|
78605
79000
|
{
|
|
@@ -78607,7 +79002,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78607
79002
|
field: "pressure",
|
|
78608
79003
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78609
79004
|
label: t("Pressure", "Pressione"),
|
|
78610
|
-
|
|
79005
|
+
unit: "hPa",
|
|
78611
79006
|
icon: "gauge"
|
|
78612
79007
|
}
|
|
78613
79008
|
]
|
|
@@ -79880,6 +80275,16 @@ Object.freeze({
|
|
|
79880
80275
|
form: "single",
|
|
79881
80276
|
optional: false
|
|
79882
80277
|
}],
|
|
80278
|
+
"groupCommands.getStatus": [{
|
|
80279
|
+
name: "deviceId",
|
|
80280
|
+
form: "single",
|
|
80281
|
+
optional: false
|
|
80282
|
+
}],
|
|
80283
|
+
"groupStatus.getStatus": [{
|
|
80284
|
+
name: "deviceId",
|
|
80285
|
+
form: "single",
|
|
80286
|
+
optional: false
|
|
80287
|
+
}],
|
|
79883
80288
|
"heatingValve.getStatus": [{
|
|
79884
80289
|
name: "deviceId",
|
|
79885
80290
|
form: "single",
|
|
@@ -81864,6 +82269,8 @@ new Map(Object.entries({
|
|
|
81864
82269
|
"detection-blind": "device-events",
|
|
81865
82270
|
"motion-noisy": "device-events",
|
|
81866
82271
|
"motion-calm": "device-events",
|
|
82272
|
+
"package-llm-silent": "device-events",
|
|
82273
|
+
"package-llm-answered": "device-events",
|
|
81867
82274
|
"recording-stalled": "device-events",
|
|
81868
82275
|
"recording-healthy": "device-events",
|
|
81869
82276
|
"recording-degraded": "device-events",
|
|
@@ -81947,6 +82354,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
81947
82354
|
label: "Motion without a subject",
|
|
81948
82355
|
kinds: ["motion-noisy", "motion-calm"]
|
|
81949
82356
|
},
|
|
82357
|
+
{
|
|
82358
|
+
id: "package-llm",
|
|
82359
|
+
family: "device-events",
|
|
82360
|
+
label: "Package confirm",
|
|
82361
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
82362
|
+
},
|
|
81950
82363
|
{
|
|
81951
82364
|
id: "recording",
|
|
81952
82365
|
family: "device-events",
|
|
@@ -82128,6 +82541,8 @@ var DEVICE_EVENTS = [
|
|
|
82128
82541
|
"detection-blind",
|
|
82129
82542
|
"motion-noisy",
|
|
82130
82543
|
"motion-calm",
|
|
82544
|
+
"package-llm-silent",
|
|
82545
|
+
"package-llm-answered",
|
|
82131
82546
|
"recording-stalled",
|
|
82132
82547
|
"recording-healthy",
|
|
82133
82548
|
"recording-degraded",
|
|
@@ -82396,6 +82811,15 @@ new Map([
|
|
|
82396
82811
|
snapshotLabel: "Cameras with constant motion now",
|
|
82397
82812
|
snapshotSection: null
|
|
82398
82813
|
},
|
|
82814
|
+
{
|
|
82815
|
+
id: "package-llm-confirm",
|
|
82816
|
+
family: "device-events",
|
|
82817
|
+
label: "Package confirm (not answering / answering again)",
|
|
82818
|
+
bad: ["package-llm-silent"],
|
|
82819
|
+
recovery: ["package-llm-answered"],
|
|
82820
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
82821
|
+
snapshotSection: null
|
|
82822
|
+
},
|
|
82399
82823
|
{
|
|
82400
82824
|
id: "recording-health",
|
|
82401
82825
|
family: "device-events",
|