@camstack/addon-waste-collections 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +19 -0
- package/dist/waste-collections.addon.js +861 -432
- package/dist/waste-collections.addon.mjs +861 -432
- package/package.json +13 -2
|
@@ -6,7 +6,7 @@ let node_fs = require("node:fs");
|
|
|
6
6
|
let node_path = require("node:path");
|
|
7
7
|
let node_child_process = require("node:child_process");
|
|
8
8
|
let node_url = require("node:url");
|
|
9
|
-
//#region ../types/dist/event-category-
|
|
9
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
10
10
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
11
11
|
EventCategory["SystemBoot"] = "system.boot";
|
|
12
12
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -332,6 +332,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
332
332
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
333
333
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
334
334
|
/**
|
|
335
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
336
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
337
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
338
|
+
*/
|
|
339
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
340
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
341
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
342
|
+
/**
|
|
335
343
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
336
344
|
* (a settings change via `setAgentInferenceDevices` /
|
|
337
345
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5574,7 +5582,7 @@ var ZodIssueCode = {
|
|
|
5574
5582
|
var ZodFirstPartyTypeKind;
|
|
5575
5583
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5576
5584
|
//#endregion
|
|
5577
|
-
//#region ../types/dist/sleep-
|
|
5585
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5578
5586
|
/**
|
|
5579
5587
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5580
5588
|
* window to float samples (D455).
|
|
@@ -8326,6 +8334,99 @@ function defineEntryKind(name, spec) {
|
|
|
8326
8334
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8327
8335
|
return defined;
|
|
8328
8336
|
}
|
|
8337
|
+
var READING_QUANTITIES = [
|
|
8338
|
+
"temperature",
|
|
8339
|
+
"pressure",
|
|
8340
|
+
"speed",
|
|
8341
|
+
"precipitation",
|
|
8342
|
+
"precipitation-rate",
|
|
8343
|
+
"length",
|
|
8344
|
+
"area",
|
|
8345
|
+
"illuminance",
|
|
8346
|
+
"irradiance",
|
|
8347
|
+
"power",
|
|
8348
|
+
"energy",
|
|
8349
|
+
"voltage",
|
|
8350
|
+
"current",
|
|
8351
|
+
"apparent-power",
|
|
8352
|
+
"humidity",
|
|
8353
|
+
"percentage",
|
|
8354
|
+
"concentration-volume",
|
|
8355
|
+
"concentration-mass",
|
|
8356
|
+
"concentration-ppb",
|
|
8357
|
+
"volume",
|
|
8358
|
+
"duration",
|
|
8359
|
+
"duration-ms",
|
|
8360
|
+
"information",
|
|
8361
|
+
"sound-level",
|
|
8362
|
+
"signal-level",
|
|
8363
|
+
"colour-temperature",
|
|
8364
|
+
"angle",
|
|
8365
|
+
"bitrate",
|
|
8366
|
+
"rate",
|
|
8367
|
+
"mass",
|
|
8368
|
+
"index",
|
|
8369
|
+
"ratio",
|
|
8370
|
+
"count",
|
|
8371
|
+
"none",
|
|
8372
|
+
"device"
|
|
8373
|
+
];
|
|
8374
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8375
|
+
new Set(READING_QUANTITIES);
|
|
8376
|
+
/**
|
|
8377
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8378
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8379
|
+
*/
|
|
8380
|
+
var QUANTITY_BASE = {
|
|
8381
|
+
temperature: "°C",
|
|
8382
|
+
pressure: "hPa",
|
|
8383
|
+
speed: "m/s",
|
|
8384
|
+
precipitation: "mm",
|
|
8385
|
+
"precipitation-rate": "mm/h",
|
|
8386
|
+
length: "m",
|
|
8387
|
+
area: "m²",
|
|
8388
|
+
illuminance: "lx",
|
|
8389
|
+
irradiance: "W/m²",
|
|
8390
|
+
power: "W",
|
|
8391
|
+
energy: "kWh",
|
|
8392
|
+
voltage: "V",
|
|
8393
|
+
current: "A",
|
|
8394
|
+
"apparent-power": "VA",
|
|
8395
|
+
humidity: "%",
|
|
8396
|
+
percentage: "%",
|
|
8397
|
+
"concentration-volume": "ppm",
|
|
8398
|
+
"concentration-mass": "µg/m³",
|
|
8399
|
+
"concentration-ppb": "ppb",
|
|
8400
|
+
volume: "L",
|
|
8401
|
+
duration: "s",
|
|
8402
|
+
"duration-ms": "ms",
|
|
8403
|
+
information: "B",
|
|
8404
|
+
"sound-level": "dBFS",
|
|
8405
|
+
"signal-level": "dBm",
|
|
8406
|
+
"colour-temperature": "mired",
|
|
8407
|
+
angle: "°",
|
|
8408
|
+
bitrate: "kbps",
|
|
8409
|
+
rate: "fps",
|
|
8410
|
+
mass: "kg",
|
|
8411
|
+
index: "none",
|
|
8412
|
+
ratio: "none",
|
|
8413
|
+
count: "none",
|
|
8414
|
+
none: "none",
|
|
8415
|
+
device: "device"
|
|
8416
|
+
};
|
|
8417
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8418
|
+
function baseUnitOf(quantity) {
|
|
8419
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8420
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8421
|
+
return symbol;
|
|
8422
|
+
}
|
|
8423
|
+
function readingMeta(quantity, extras) {
|
|
8424
|
+
return {
|
|
8425
|
+
quantity,
|
|
8426
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8427
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8428
|
+
};
|
|
8429
|
+
}
|
|
8329
8430
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8330
8431
|
var CamProfileSchema = _enum([
|
|
8331
8432
|
"high",
|
|
@@ -8353,8 +8454,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8353
8454
|
"derived"
|
|
8354
8455
|
]);
|
|
8355
8456
|
var CamStreamResolutionSchema = object({
|
|
8356
|
-
width: number().int().positive(),
|
|
8357
|
-
height: number().int().positive()
|
|
8457
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8458
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8358
8459
|
});
|
|
8359
8460
|
var CameraStreamSchema = object({
|
|
8360
8461
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8890,6 +8991,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8890
8991
|
"filesystem-browse",
|
|
8891
8992
|
"flood",
|
|
8892
8993
|
"gas",
|
|
8994
|
+
"group-commands",
|
|
8995
|
+
"group-status",
|
|
8893
8996
|
"heating-valve",
|
|
8894
8997
|
"humidifier",
|
|
8895
8998
|
"humidity-sensor",
|
|
@@ -9019,14 +9122,6 @@ Object.freeze({
|
|
|
9019
9122
|
{
|
|
9020
9123
|
"path": "aqi",
|
|
9021
9124
|
"valueType": "number"
|
|
9022
|
-
},
|
|
9023
|
-
{
|
|
9024
|
-
"path": "unit",
|
|
9025
|
-
"valueType": "string"
|
|
9026
|
-
},
|
|
9027
|
-
{
|
|
9028
|
-
"path": "precision",
|
|
9029
|
-
"valueType": "number"
|
|
9030
9125
|
}
|
|
9031
9126
|
],
|
|
9032
9127
|
"alarm-panel": [
|
|
@@ -9062,20 +9157,10 @@ Object.freeze({
|
|
|
9062
9157
|
"valueType": "boolean"
|
|
9063
9158
|
}
|
|
9064
9159
|
],
|
|
9065
|
-
"ambient-light-sensor": [
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
},
|
|
9070
|
-
{
|
|
9071
|
-
"path": "unit",
|
|
9072
|
-
"valueType": "string"
|
|
9073
|
-
},
|
|
9074
|
-
{
|
|
9075
|
-
"path": "precision",
|
|
9076
|
-
"valueType": "number"
|
|
9077
|
-
}
|
|
9078
|
-
],
|
|
9160
|
+
"ambient-light-sensor": [{
|
|
9161
|
+
"path": "lux",
|
|
9162
|
+
"valueType": "number"
|
|
9163
|
+
}],
|
|
9079
9164
|
"audio-metrics": [
|
|
9080
9165
|
{
|
|
9081
9166
|
"path": "ts",
|
|
@@ -9155,6 +9240,10 @@ Object.freeze({
|
|
|
9155
9240
|
"path": "lastUpdated",
|
|
9156
9241
|
"valueType": "number"
|
|
9157
9242
|
},
|
|
9243
|
+
{
|
|
9244
|
+
"path": "volts",
|
|
9245
|
+
"valueType": "number"
|
|
9246
|
+
},
|
|
9158
9247
|
{
|
|
9159
9248
|
"path": "lastContactAt",
|
|
9160
9249
|
"valueType": "number"
|
|
@@ -9397,10 +9486,6 @@ Object.freeze({
|
|
|
9397
9486
|
"datetime"
|
|
9398
9487
|
]
|
|
9399
9488
|
},
|
|
9400
|
-
{
|
|
9401
|
-
"path": "unit",
|
|
9402
|
-
"valueType": "string"
|
|
9403
|
-
},
|
|
9404
9489
|
{
|
|
9405
9490
|
"path": "min",
|
|
9406
9491
|
"valueType": "number"
|
|
@@ -9412,19 +9497,6 @@ Object.freeze({
|
|
|
9412
9497
|
{
|
|
9413
9498
|
"path": "step",
|
|
9414
9499
|
"valueType": "number"
|
|
9415
|
-
},
|
|
9416
|
-
{
|
|
9417
|
-
"path": "precision",
|
|
9418
|
-
"valueType": "number"
|
|
9419
|
-
},
|
|
9420
|
-
{
|
|
9421
|
-
"path": "format",
|
|
9422
|
-
"valueType": "enum",
|
|
9423
|
-
"enumValues": [
|
|
9424
|
-
"date",
|
|
9425
|
-
"time",
|
|
9426
|
-
"datetime"
|
|
9427
|
-
]
|
|
9428
9500
|
}
|
|
9429
9501
|
],
|
|
9430
9502
|
"cover": [
|
|
@@ -9665,13 +9737,8 @@ Object.freeze({
|
|
|
9665
9737
|
"path": "value",
|
|
9666
9738
|
"valueType": "string"
|
|
9667
9739
|
}, {
|
|
9668
|
-
"path": "
|
|
9669
|
-
"valueType": "
|
|
9670
|
-
"enumValues": [
|
|
9671
|
-
"date",
|
|
9672
|
-
"time",
|
|
9673
|
-
"datetime"
|
|
9674
|
-
]
|
|
9740
|
+
"path": "timestamp",
|
|
9741
|
+
"valueType": "boolean"
|
|
9675
9742
|
}],
|
|
9676
9743
|
"event-emitter": [
|
|
9677
9744
|
{
|
|
@@ -9744,6 +9811,20 @@ Object.freeze({
|
|
|
9744
9811
|
"path": "detected",
|
|
9745
9812
|
"valueType": "boolean"
|
|
9746
9813
|
}],
|
|
9814
|
+
"group-status": [
|
|
9815
|
+
{
|
|
9816
|
+
"path": "included",
|
|
9817
|
+
"valueType": "number"
|
|
9818
|
+
},
|
|
9819
|
+
{
|
|
9820
|
+
"path": "excluded",
|
|
9821
|
+
"valueType": "number"
|
|
9822
|
+
},
|
|
9823
|
+
{
|
|
9824
|
+
"path": "total",
|
|
9825
|
+
"valueType": "number"
|
|
9826
|
+
}
|
|
9827
|
+
],
|
|
9747
9828
|
"heating-valve": [{
|
|
9748
9829
|
"path": "position",
|
|
9749
9830
|
"valueType": "number"
|
|
@@ -9778,20 +9859,10 @@ Object.freeze({
|
|
|
9778
9859
|
"valueType": "number"
|
|
9779
9860
|
}
|
|
9780
9861
|
],
|
|
9781
|
-
"humidity-sensor": [
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
},
|
|
9786
|
-
{
|
|
9787
|
-
"path": "unit",
|
|
9788
|
-
"valueType": "string"
|
|
9789
|
-
},
|
|
9790
|
-
{
|
|
9791
|
-
"path": "precision",
|
|
9792
|
-
"valueType": "number"
|
|
9793
|
-
}
|
|
9794
|
-
],
|
|
9862
|
+
"humidity-sensor": [{
|
|
9863
|
+
"path": "percent",
|
|
9864
|
+
"valueType": "number"
|
|
9865
|
+
}],
|
|
9795
9866
|
"image": [{
|
|
9796
9867
|
"path": "url",
|
|
9797
9868
|
"valueType": "string"
|
|
@@ -10130,20 +10201,10 @@ Object.freeze({
|
|
|
10130
10201
|
"valueType": "boolean"
|
|
10131
10202
|
}
|
|
10132
10203
|
],
|
|
10133
|
-
"numeric-sensor": [
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
},
|
|
10138
|
-
{
|
|
10139
|
-
"path": "unit",
|
|
10140
|
-
"valueType": "string"
|
|
10141
|
-
},
|
|
10142
|
-
{
|
|
10143
|
-
"path": "precision",
|
|
10144
|
-
"valueType": "number"
|
|
10145
|
-
}
|
|
10146
|
-
],
|
|
10204
|
+
"numeric-sensor": [{
|
|
10205
|
+
"path": "value",
|
|
10206
|
+
"valueType": "number"
|
|
10207
|
+
}],
|
|
10147
10208
|
"pet-feeder": [
|
|
10148
10209
|
{
|
|
10149
10210
|
"path": "foodLevel",
|
|
@@ -10235,14 +10296,6 @@ Object.freeze({
|
|
|
10235
10296
|
{
|
|
10236
10297
|
"path": "powerFactor",
|
|
10237
10298
|
"valueType": "number"
|
|
10238
|
-
},
|
|
10239
|
-
{
|
|
10240
|
-
"path": "unit",
|
|
10241
|
-
"valueType": "string"
|
|
10242
|
-
},
|
|
10243
|
-
{
|
|
10244
|
-
"path": "precision",
|
|
10245
|
-
"valueType": "number"
|
|
10246
10299
|
}
|
|
10247
10300
|
],
|
|
10248
10301
|
"presence": [
|
|
@@ -10271,20 +10324,10 @@ Object.freeze({
|
|
|
10271
10324
|
"valueType": "number"
|
|
10272
10325
|
}
|
|
10273
10326
|
],
|
|
10274
|
-
"pressure-sensor": [
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
},
|
|
10279
|
-
{
|
|
10280
|
-
"path": "unit",
|
|
10281
|
-
"valueType": "string"
|
|
10282
|
-
},
|
|
10283
|
-
{
|
|
10284
|
-
"path": "precision",
|
|
10285
|
-
"valueType": "number"
|
|
10286
|
-
}
|
|
10287
|
-
],
|
|
10327
|
+
"pressure-sensor": [{
|
|
10328
|
+
"path": "hpa",
|
|
10329
|
+
"valueType": "number"
|
|
10330
|
+
}],
|
|
10288
10331
|
"privacy-mask": [{
|
|
10289
10332
|
"path": "enabled",
|
|
10290
10333
|
"valueType": "boolean"
|
|
@@ -10595,20 +10638,10 @@ Object.freeze({
|
|
|
10595
10638
|
"path": "tampered",
|
|
10596
10639
|
"valueType": "boolean"
|
|
10597
10640
|
}],
|
|
10598
|
-
"temperature-sensor": [
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
},
|
|
10603
|
-
{
|
|
10604
|
-
"path": "unit",
|
|
10605
|
-
"valueType": "string"
|
|
10606
|
-
},
|
|
10607
|
-
{
|
|
10608
|
-
"path": "precision",
|
|
10609
|
-
"valueType": "number"
|
|
10610
|
-
}
|
|
10611
|
-
],
|
|
10641
|
+
"temperature-sensor": [{
|
|
10642
|
+
"path": "celsius",
|
|
10643
|
+
"valueType": "number"
|
|
10644
|
+
}],
|
|
10612
10645
|
"update": [
|
|
10613
10646
|
{
|
|
10614
10647
|
"path": "currentVersion",
|
|
@@ -10719,10 +10752,6 @@ Object.freeze({
|
|
|
10719
10752
|
"path": "temperature",
|
|
10720
10753
|
"valueType": "number"
|
|
10721
10754
|
},
|
|
10722
|
-
{
|
|
10723
|
-
"path": "temperatureUnit",
|
|
10724
|
-
"valueType": "string"
|
|
10725
|
-
},
|
|
10726
10755
|
{
|
|
10727
10756
|
"path": "humidity",
|
|
10728
10757
|
"valueType": "number"
|
|
@@ -10731,18 +10760,10 @@ Object.freeze({
|
|
|
10731
10760
|
"path": "pressure",
|
|
10732
10761
|
"valueType": "number"
|
|
10733
10762
|
},
|
|
10734
|
-
{
|
|
10735
|
-
"path": "pressureUnit",
|
|
10736
|
-
"valueType": "string"
|
|
10737
|
-
},
|
|
10738
10763
|
{
|
|
10739
10764
|
"path": "windSpeed",
|
|
10740
10765
|
"valueType": "number"
|
|
10741
10766
|
},
|
|
10742
|
-
{
|
|
10743
|
-
"path": "windSpeedUnit",
|
|
10744
|
-
"valueType": "string"
|
|
10745
|
-
},
|
|
10746
10767
|
{
|
|
10747
10768
|
"path": "windBearing",
|
|
10748
10769
|
"valueType": "number"
|
|
@@ -11135,7 +11156,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11135
11156
|
return DeviceRole;
|
|
11136
11157
|
}({});
|
|
11137
11158
|
//#endregion
|
|
11138
|
-
//#region ../types/dist/composition-
|
|
11159
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11139
11160
|
/**
|
|
11140
11161
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11141
11162
|
*
|
|
@@ -11890,15 +11911,74 @@ function validateExpressionSource(src) {
|
|
|
11890
11911
|
}
|
|
11891
11912
|
return null;
|
|
11892
11913
|
}
|
|
11893
|
-
/**
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11914
|
+
/**
|
|
11915
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11916
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11917
|
+
* `composition.ts` (D659).
|
|
11918
|
+
*/
|
|
11897
11919
|
var CompositionSourceRefSchema = object({
|
|
11898
11920
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11899
11921
|
addonId: string().min(1),
|
|
11900
11922
|
stableId: string().min(1)
|
|
11901
11923
|
});
|
|
11924
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11925
|
+
"temperature",
|
|
11926
|
+
"humidity",
|
|
11927
|
+
"pressure",
|
|
11928
|
+
"illuminance",
|
|
11929
|
+
"power",
|
|
11930
|
+
"energy",
|
|
11931
|
+
"battery",
|
|
11932
|
+
"numeric",
|
|
11933
|
+
"motion",
|
|
11934
|
+
"contact",
|
|
11935
|
+
"leak",
|
|
11936
|
+
"smoke",
|
|
11937
|
+
"occupancy",
|
|
11938
|
+
"binary",
|
|
11939
|
+
"switch",
|
|
11940
|
+
"light"
|
|
11941
|
+
];
|
|
11942
|
+
var NUMERIC_AGGREGATES = [
|
|
11943
|
+
"mean",
|
|
11944
|
+
"median",
|
|
11945
|
+
"min",
|
|
11946
|
+
"max",
|
|
11947
|
+
"sum"
|
|
11948
|
+
];
|
|
11949
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11950
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11951
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11952
|
+
var AGGREGATE_REDUCERS = [
|
|
11953
|
+
"mean",
|
|
11954
|
+
"median",
|
|
11955
|
+
"min",
|
|
11956
|
+
"max",
|
|
11957
|
+
"sum",
|
|
11958
|
+
"any",
|
|
11959
|
+
"all"
|
|
11960
|
+
];
|
|
11961
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11962
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11963
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11964
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11965
|
+
var HelperMemberSchema = object({
|
|
11966
|
+
source: CompositionSourceRefSchema,
|
|
11967
|
+
cap: string().min(1),
|
|
11968
|
+
fieldPath: string().min(1)
|
|
11969
|
+
});
|
|
11970
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11971
|
+
kind: literal("group"),
|
|
11972
|
+
templateId: GroupTemplateIdSchema,
|
|
11973
|
+
aggregate: AggregateReducerSchema,
|
|
11974
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11975
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11976
|
+
active: ActiveCriterionSchema.optional()
|
|
11977
|
+
})]);
|
|
11978
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11979
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11980
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11981
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11902
11982
|
/** One field of one capability of one source device. */
|
|
11903
11983
|
var CompositionFieldReadSchema = object({
|
|
11904
11984
|
source: CompositionSourceRefSchema,
|
|
@@ -11942,7 +12022,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11942
12022
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11943
12023
|
CompositionFromSourceSchema,
|
|
11944
12024
|
CompositionExpressionSourceSchema,
|
|
11945
|
-
CompositionCodeSourceSchema
|
|
12025
|
+
CompositionCodeSourceSchema,
|
|
12026
|
+
object({
|
|
12027
|
+
kind: literal("aggregate"),
|
|
12028
|
+
reducer: _enum([
|
|
12029
|
+
"mean",
|
|
12030
|
+
"median",
|
|
12031
|
+
"min",
|
|
12032
|
+
"max",
|
|
12033
|
+
"sum",
|
|
12034
|
+
"any",
|
|
12035
|
+
"all"
|
|
12036
|
+
]),
|
|
12037
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12038
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12039
|
+
publish: _enum([
|
|
12040
|
+
"value",
|
|
12041
|
+
"included",
|
|
12042
|
+
"excluded",
|
|
12043
|
+
"total"
|
|
12044
|
+
]),
|
|
12045
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12046
|
+
empty: _enum([
|
|
12047
|
+
"null",
|
|
12048
|
+
"omit",
|
|
12049
|
+
"offline"
|
|
12050
|
+
])
|
|
12051
|
+
})
|
|
11946
12052
|
]);
|
|
11947
12053
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11948
12054
|
kind: literal("forward"),
|
|
@@ -11988,7 +12094,13 @@ var CompositionSchema = object({
|
|
|
11988
12094
|
kind: literal("existing"),
|
|
11989
12095
|
device: CompositionSourceRefSchema
|
|
11990
12096
|
})]),
|
|
11991
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12097
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12098
|
+
/**
|
|
12099
|
+
* Present when the block is a helper template. Absent on a free
|
|
12100
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12101
|
+
* never the compiled features.
|
|
12102
|
+
*/
|
|
12103
|
+
helper: HelperSpecSchema.optional()
|
|
11992
12104
|
}).superRefine((composition, ctx) => {
|
|
11993
12105
|
const seen = /* @__PURE__ */ new Set();
|
|
11994
12106
|
composition.features.forEach((feature, index) => {
|
|
@@ -18090,7 +18202,11 @@ var CompositionProblemSchema = object({
|
|
|
18090
18202
|
"item-field-reserved",
|
|
18091
18203
|
"target-missing",
|
|
18092
18204
|
"target-unreadable",
|
|
18093
|
-
"not-replaceable"
|
|
18205
|
+
"not-replaceable",
|
|
18206
|
+
"native-capability-replace",
|
|
18207
|
+
"mixed-quantity",
|
|
18208
|
+
"helper-mismatch",
|
|
18209
|
+
"member-constraint"
|
|
18094
18210
|
]),
|
|
18095
18211
|
path: string(),
|
|
18096
18212
|
message: string()
|
|
@@ -18111,7 +18227,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18111
18227
|
"null",
|
|
18112
18228
|
"offline",
|
|
18113
18229
|
"unknown",
|
|
18114
|
-
"release"
|
|
18230
|
+
"release",
|
|
18231
|
+
"omit"
|
|
18115
18232
|
]);
|
|
18116
18233
|
/**
|
|
18117
18234
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18148,9 +18265,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18148
18265
|
reads: array(CompositionFieldReadSchema)
|
|
18149
18266
|
});
|
|
18150
18267
|
/**
|
|
18151
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18152
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18153
|
-
*
|
|
18268
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18269
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18270
|
+
* Replacing a capability the device already serves is refused
|
|
18271
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18272
|
+
* wire for a claim the hub already holds.
|
|
18154
18273
|
*/
|
|
18155
18274
|
var CompositionFeatureModeSchema = _enum([
|
|
18156
18275
|
"new",
|
|
@@ -18323,6 +18442,275 @@ Object.freeze({
|
|
|
18323
18442
|
result: ["number", "null"]
|
|
18324
18443
|
}
|
|
18325
18444
|
});
|
|
18445
|
+
/**
|
|
18446
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18447
|
+
* Data, not a form default written into the block.
|
|
18448
|
+
*/
|
|
18449
|
+
var NOW = {
|
|
18450
|
+
fieldPath: "lastFetchedAt",
|
|
18451
|
+
expr: "now"
|
|
18452
|
+
};
|
|
18453
|
+
var CHANGED = {
|
|
18454
|
+
fieldPath: "lastChangedAt",
|
|
18455
|
+
expr: "now"
|
|
18456
|
+
};
|
|
18457
|
+
function numeric(input) {
|
|
18458
|
+
return {
|
|
18459
|
+
...input,
|
|
18460
|
+
family: "numeric",
|
|
18461
|
+
deviceType: DeviceType.Sensor,
|
|
18462
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18463
|
+
commandCaps: [],
|
|
18464
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18465
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18466
|
+
accept: [{
|
|
18467
|
+
cap: input.outputCap,
|
|
18468
|
+
fieldPath: input.outputField
|
|
18469
|
+
}]
|
|
18470
|
+
};
|
|
18471
|
+
}
|
|
18472
|
+
function binary(input) {
|
|
18473
|
+
return {
|
|
18474
|
+
...input,
|
|
18475
|
+
family: "binary",
|
|
18476
|
+
deviceType: DeviceType.Sensor,
|
|
18477
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18478
|
+
commandCaps: [],
|
|
18479
|
+
quantity: "none",
|
|
18480
|
+
baseUnit: void 0,
|
|
18481
|
+
aggregates: BINARY_AGGREGATES,
|
|
18482
|
+
empty: "offline"
|
|
18483
|
+
};
|
|
18484
|
+
}
|
|
18485
|
+
var GROUP_TEMPLATES = [
|
|
18486
|
+
numeric({
|
|
18487
|
+
id: "temperature",
|
|
18488
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18489
|
+
role: DeviceRole.TemperatureSensor,
|
|
18490
|
+
outputCap: "temperature-sensor",
|
|
18491
|
+
outputField: "celsius",
|
|
18492
|
+
quantity: "temperature",
|
|
18493
|
+
defaultAggregate: "mean",
|
|
18494
|
+
empty: "null",
|
|
18495
|
+
companions: [NOW]
|
|
18496
|
+
}),
|
|
18497
|
+
numeric({
|
|
18498
|
+
id: "humidity",
|
|
18499
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18500
|
+
role: DeviceRole.HumiditySensor,
|
|
18501
|
+
outputCap: "humidity-sensor",
|
|
18502
|
+
outputField: "percent",
|
|
18503
|
+
quantity: "humidity",
|
|
18504
|
+
defaultAggregate: "mean",
|
|
18505
|
+
empty: "null",
|
|
18506
|
+
companions: [NOW]
|
|
18507
|
+
}),
|
|
18508
|
+
numeric({
|
|
18509
|
+
id: "pressure",
|
|
18510
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18511
|
+
role: DeviceRole.PressureSensor,
|
|
18512
|
+
outputCap: "pressure-sensor",
|
|
18513
|
+
outputField: "hpa",
|
|
18514
|
+
quantity: "pressure",
|
|
18515
|
+
defaultAggregate: "mean",
|
|
18516
|
+
empty: "null",
|
|
18517
|
+
companions: [NOW]
|
|
18518
|
+
}),
|
|
18519
|
+
numeric({
|
|
18520
|
+
id: "illuminance",
|
|
18521
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18522
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18523
|
+
outputCap: "ambient-light-sensor",
|
|
18524
|
+
outputField: "lux",
|
|
18525
|
+
quantity: "illuminance",
|
|
18526
|
+
defaultAggregate: "mean",
|
|
18527
|
+
empty: "null",
|
|
18528
|
+
companions: [NOW]
|
|
18529
|
+
}),
|
|
18530
|
+
numeric({
|
|
18531
|
+
id: "power",
|
|
18532
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18533
|
+
role: DeviceRole.PowerSensor,
|
|
18534
|
+
outputCap: "power-meter",
|
|
18535
|
+
outputField: "watts",
|
|
18536
|
+
quantity: "power",
|
|
18537
|
+
defaultAggregate: "sum",
|
|
18538
|
+
empty: "omit",
|
|
18539
|
+
companions: [NOW]
|
|
18540
|
+
}),
|
|
18541
|
+
numeric({
|
|
18542
|
+
id: "energy",
|
|
18543
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18544
|
+
role: DeviceRole.EnergySensor,
|
|
18545
|
+
outputCap: "power-meter",
|
|
18546
|
+
outputField: "kwhTotal",
|
|
18547
|
+
quantity: "energy",
|
|
18548
|
+
defaultAggregate: "sum",
|
|
18549
|
+
empty: "omit",
|
|
18550
|
+
companions: [NOW]
|
|
18551
|
+
}),
|
|
18552
|
+
numeric({
|
|
18553
|
+
id: "battery",
|
|
18554
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18555
|
+
role: DeviceRole.BatterySensor,
|
|
18556
|
+
outputCap: "battery",
|
|
18557
|
+
outputField: "percentage",
|
|
18558
|
+
quantity: "percentage",
|
|
18559
|
+
defaultAggregate: "mean",
|
|
18560
|
+
empty: "null",
|
|
18561
|
+
companions: [
|
|
18562
|
+
{
|
|
18563
|
+
fieldPath: "charging",
|
|
18564
|
+
expr: "\"unknown\""
|
|
18565
|
+
},
|
|
18566
|
+
{
|
|
18567
|
+
fieldPath: "sleeping",
|
|
18568
|
+
expr: "false"
|
|
18569
|
+
},
|
|
18570
|
+
{
|
|
18571
|
+
fieldPath: "lastUpdated",
|
|
18572
|
+
expr: "now"
|
|
18573
|
+
}
|
|
18574
|
+
]
|
|
18575
|
+
}),
|
|
18576
|
+
numeric({
|
|
18577
|
+
id: "numeric",
|
|
18578
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18579
|
+
role: DeviceRole.NumericSensor,
|
|
18580
|
+
outputCap: "numeric-sensor",
|
|
18581
|
+
outputField: "value",
|
|
18582
|
+
quantity: "device",
|
|
18583
|
+
defaultAggregate: "mean",
|
|
18584
|
+
empty: "null",
|
|
18585
|
+
companions: [NOW]
|
|
18586
|
+
}),
|
|
18587
|
+
binary({
|
|
18588
|
+
id: "motion",
|
|
18589
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18590
|
+
role: DeviceRole.MotionSensor,
|
|
18591
|
+
outputCap: "motion",
|
|
18592
|
+
outputField: "detected",
|
|
18593
|
+
defaultAggregate: "any",
|
|
18594
|
+
accept: [{
|
|
18595
|
+
cap: "motion",
|
|
18596
|
+
fieldPath: "detected"
|
|
18597
|
+
}],
|
|
18598
|
+
companions: [{
|
|
18599
|
+
fieldPath: "lastDetectedAt",
|
|
18600
|
+
expr: "null"
|
|
18601
|
+
}, {
|
|
18602
|
+
fieldPath: "autoClearAfterMs",
|
|
18603
|
+
expr: "null"
|
|
18604
|
+
}]
|
|
18605
|
+
}),
|
|
18606
|
+
binary({
|
|
18607
|
+
id: "contact",
|
|
18608
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18609
|
+
role: DeviceRole.ContactSensor,
|
|
18610
|
+
outputCap: "contact",
|
|
18611
|
+
outputField: "entryOpen",
|
|
18612
|
+
defaultAggregate: "any",
|
|
18613
|
+
accept: [{
|
|
18614
|
+
cap: "contact",
|
|
18615
|
+
fieldPath: "entryOpen"
|
|
18616
|
+
}],
|
|
18617
|
+
companions: [CHANGED]
|
|
18618
|
+
}),
|
|
18619
|
+
binary({
|
|
18620
|
+
id: "leak",
|
|
18621
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18622
|
+
role: DeviceRole.LeakSensor,
|
|
18623
|
+
outputCap: "flood",
|
|
18624
|
+
outputField: "flooded",
|
|
18625
|
+
defaultAggregate: "any",
|
|
18626
|
+
accept: [{
|
|
18627
|
+
cap: "flood",
|
|
18628
|
+
fieldPath: "flooded"
|
|
18629
|
+
}],
|
|
18630
|
+
companions: [CHANGED]
|
|
18631
|
+
}),
|
|
18632
|
+
binary({
|
|
18633
|
+
id: "smoke",
|
|
18634
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18635
|
+
role: DeviceRole.SmokeSensor,
|
|
18636
|
+
outputCap: "smoke",
|
|
18637
|
+
outputField: "detected",
|
|
18638
|
+
defaultAggregate: "any",
|
|
18639
|
+
accept: [{
|
|
18640
|
+
cap: "smoke",
|
|
18641
|
+
fieldPath: "detected"
|
|
18642
|
+
}],
|
|
18643
|
+
companions: [CHANGED]
|
|
18644
|
+
}),
|
|
18645
|
+
binary({
|
|
18646
|
+
id: "occupancy",
|
|
18647
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18648
|
+
role: DeviceRole.BinarySensor,
|
|
18649
|
+
outputCap: "binary",
|
|
18650
|
+
outputField: "on",
|
|
18651
|
+
defaultAggregate: "any",
|
|
18652
|
+
accept: [{
|
|
18653
|
+
cap: "motion",
|
|
18654
|
+
fieldPath: "detected"
|
|
18655
|
+
}, {
|
|
18656
|
+
cap: "binary",
|
|
18657
|
+
fieldPath: "on"
|
|
18658
|
+
}],
|
|
18659
|
+
companions: [CHANGED]
|
|
18660
|
+
}),
|
|
18661
|
+
binary({
|
|
18662
|
+
id: "binary",
|
|
18663
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18664
|
+
role: DeviceRole.BinarySensor,
|
|
18665
|
+
outputCap: "binary",
|
|
18666
|
+
outputField: "on",
|
|
18667
|
+
defaultAggregate: "any",
|
|
18668
|
+
accept: [{
|
|
18669
|
+
cap: "binary",
|
|
18670
|
+
fieldPath: "on"
|
|
18671
|
+
}],
|
|
18672
|
+
companions: [CHANGED]
|
|
18673
|
+
}),
|
|
18674
|
+
actuator({
|
|
18675
|
+
id: "switch",
|
|
18676
|
+
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.",
|
|
18677
|
+
deviceType: DeviceType.Switch,
|
|
18678
|
+
outputCap: "switch",
|
|
18679
|
+
commandCaps: ["switch"]
|
|
18680
|
+
}),
|
|
18681
|
+
actuator({
|
|
18682
|
+
id: "light",
|
|
18683
|
+
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.",
|
|
18684
|
+
deviceType: DeviceType.Light,
|
|
18685
|
+
outputCap: "switch",
|
|
18686
|
+
commandCaps: [
|
|
18687
|
+
"switch",
|
|
18688
|
+
"brightness",
|
|
18689
|
+
"color"
|
|
18690
|
+
]
|
|
18691
|
+
})
|
|
18692
|
+
];
|
|
18693
|
+
function actuator(input) {
|
|
18694
|
+
return {
|
|
18695
|
+
...input,
|
|
18696
|
+
family: "actuator",
|
|
18697
|
+
role: void 0,
|
|
18698
|
+
memberDeviceType: input.deviceType,
|
|
18699
|
+
outputField: "on",
|
|
18700
|
+
quantity: "none",
|
|
18701
|
+
baseUnit: void 0,
|
|
18702
|
+
aggregates: BINARY_AGGREGATES,
|
|
18703
|
+
defaultAggregate: "any",
|
|
18704
|
+
empty: "offline",
|
|
18705
|
+
accept: [{
|
|
18706
|
+
cap: "switch",
|
|
18707
|
+
fieldPath: "on"
|
|
18708
|
+
}],
|
|
18709
|
+
companions: [CHANGED]
|
|
18710
|
+
};
|
|
18711
|
+
}
|
|
18712
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18713
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18326
18714
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18327
18715
|
/**
|
|
18328
18716
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20036,12 +20424,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20036
20424
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20037
20425
|
* in-place so dispatch keeps working.
|
|
20038
20426
|
*
|
|
20039
|
-
* **
|
|
20040
|
-
*
|
|
20041
|
-
*
|
|
20042
|
-
*
|
|
20043
|
-
* (`ha-domain-mapping`)
|
|
20044
|
-
* stored after that point.
|
|
20427
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20428
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20429
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20430
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20431
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20432
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20045
20433
|
*
|
|
20046
20434
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20047
20435
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20055,6 +20443,14 @@ var SourceInfoSchema = object({
|
|
|
20055
20443
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20056
20444
|
* Used to detect rename when `id` changes. */
|
|
20057
20445
|
uniqueId: string().optional(),
|
|
20446
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20447
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20448
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20449
|
+
dateTimeShape: _enum([
|
|
20450
|
+
"date",
|
|
20451
|
+
"time",
|
|
20452
|
+
"datetime"
|
|
20453
|
+
]).optional(),
|
|
20058
20454
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20059
20455
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20060
20456
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40967,7 +41363,8 @@ method(object({
|
|
|
40967
41363
|
"enum"
|
|
40968
41364
|
]),
|
|
40969
41365
|
enumValues: array(string()).optional(),
|
|
40970
|
-
item: boolean().optional()
|
|
41366
|
+
item: boolean().optional(),
|
|
41367
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40971
41368
|
})).readonly(),
|
|
40972
41369
|
itemArray: object({
|
|
40973
41370
|
path: string(),
|
|
@@ -44767,8 +45164,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44767
45164
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44768
45165
|
var MaskGridShapeSchema = object({
|
|
44769
45166
|
kind: literal("grid"),
|
|
44770
|
-
gridWidth: number(),
|
|
44771
|
-
gridHeight: number(),
|
|
45167
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45168
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44772
45169
|
cells: array(boolean())
|
|
44773
45170
|
});
|
|
44774
45171
|
discriminatedUnion("kind", [
|
|
@@ -44880,6 +45277,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44880
45277
|
"detection-blind",
|
|
44881
45278
|
"motion-noisy",
|
|
44882
45279
|
"motion-calm",
|
|
45280
|
+
"package-llm-silent",
|
|
45281
|
+
"package-llm-answered",
|
|
44883
45282
|
"recording-stalled",
|
|
44884
45283
|
"recording-healthy",
|
|
44885
45284
|
"recording-degraded",
|
|
@@ -55894,6 +56293,28 @@ var PackageVersionInfoSchema = object({
|
|
|
55894
56293
|
deprecated: string().optional(),
|
|
55895
56294
|
distTags: array(string()).readonly()
|
|
55896
56295
|
});
|
|
56296
|
+
/**
|
|
56297
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56298
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56299
|
+
* tarball failure — never an empty string standing in for either.
|
|
56300
|
+
*/
|
|
56301
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56302
|
+
object({
|
|
56303
|
+
status: literal("ok"),
|
|
56304
|
+
markdown: string()
|
|
56305
|
+
}),
|
|
56306
|
+
object({ status: literal("missing") }),
|
|
56307
|
+
object({
|
|
56308
|
+
status: literal("error"),
|
|
56309
|
+
message: string()
|
|
56310
|
+
})
|
|
56311
|
+
]);
|
|
56312
|
+
var PackageDocsSchema = object({
|
|
56313
|
+
name: string(),
|
|
56314
|
+
version: string(),
|
|
56315
|
+
readme: PackageDocBodySchema,
|
|
56316
|
+
changelog: PackageDocBodySchema
|
|
56317
|
+
});
|
|
55897
56318
|
var SearchResultSchema = object({
|
|
55898
56319
|
name: string(),
|
|
55899
56320
|
version: string(),
|
|
@@ -56112,7 +56533,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56112
56533
|
}), object({ success: literal(true) }), {
|
|
56113
56534
|
kind: "mutation",
|
|
56114
56535
|
auth: "admin"
|
|
56115
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56536
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56537
|
+
name: string().min(1),
|
|
56538
|
+
version: string().min(1).optional()
|
|
56539
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56116
56540
|
kind: "mutation",
|
|
56117
56541
|
auth: "admin"
|
|
56118
56542
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56162,46 +56586,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56162
56586
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56163
56587
|
object({
|
|
56164
56588
|
/** Carbon dioxide concentration in ppm. */
|
|
56165
|
-
co2Ppm: number().min(0).optional(),
|
|
56589
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56166
56590
|
/** Total volatile organic compounds in ppb. */
|
|
56167
|
-
vocPpb: number().min(0).optional(),
|
|
56591
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56168
56592
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56169
|
-
pm25: number().min(0).optional(),
|
|
56593
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56170
56594
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56171
|
-
pm10: number().min(0).optional(),
|
|
56595
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56172
56596
|
/** Composite AQI value (typically 0..500). */
|
|
56173
|
-
aqi: number().optional(),
|
|
56597
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56174
56598
|
/** Ms epoch when the slice was last updated. */
|
|
56175
|
-
lastFetchedAt: number()
|
|
56176
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56177
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56178
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56179
|
-
* per slice is unambiguous. */
|
|
56180
|
-
unit: string().optional(),
|
|
56181
|
-
/** Suggested decimal places for numeric display.
|
|
56182
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56183
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56184
|
-
* auto-formatting when absent. */
|
|
56185
|
-
precision: number().int().min(0).max(10).optional()
|
|
56599
|
+
lastFetchedAt: number()
|
|
56186
56600
|
});
|
|
56187
56601
|
DeviceType.Sensor;
|
|
56188
56602
|
object({
|
|
56189
|
-
/** Current illuminance in lux (lx). */
|
|
56190
|
-
lux: number().min(0).meta({
|
|
56191
|
-
|
|
56603
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56604
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56605
|
+
precision: 0,
|
|
56192
56606
|
label: "Illuminance"
|
|
56193
|
-
}),
|
|
56607
|
+
})),
|
|
56194
56608
|
/** Ms epoch when the slice was last updated. */
|
|
56195
|
-
lastFetchedAt: number()
|
|
56196
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56197
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56198
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56199
|
-
unit: string().optional(),
|
|
56200
|
-
/** Suggested decimal places for numeric display.
|
|
56201
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56202
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56203
|
-
* auto-formatting when absent. */
|
|
56204
|
-
precision: number().int().min(0).max(10).optional()
|
|
56609
|
+
lastFetchedAt: number()
|
|
56205
56610
|
});
|
|
56206
56611
|
DeviceType.Sensor;
|
|
56207
56612
|
/**
|
|
@@ -56346,10 +56751,7 @@ var BatteryStatusSchema = object({
|
|
|
56346
56751
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56347
56752
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56348
56753
|
*/
|
|
56349
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56350
|
-
unit: "%",
|
|
56351
|
-
label: "Charge"
|
|
56352
|
-
}),
|
|
56754
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56353
56755
|
/**
|
|
56354
56756
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56355
56757
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56376,7 +56778,14 @@ var BatteryStatusSchema = object({
|
|
|
56376
56778
|
*/
|
|
56377
56779
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56378
56780
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56379
|
-
lastUpdated: number(),
|
|
56781
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56782
|
+
/**
|
|
56783
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56784
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56785
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56786
|
+
* `numeric-sensor` on the same device.
|
|
56787
|
+
*/
|
|
56788
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56380
56789
|
/**
|
|
56381
56790
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56382
56791
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56436,7 +56845,7 @@ object({
|
|
|
56436
56845
|
DeviceType.Sensor;
|
|
56437
56846
|
object({
|
|
56438
56847
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56439
|
-
percentage: number().min(0).max(100),
|
|
56848
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56440
56849
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56441
56850
|
lastChangedAt: number()
|
|
56442
56851
|
});
|
|
@@ -56831,21 +57240,21 @@ object({
|
|
|
56831
57240
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56832
57241
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56833
57242
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56834
|
-
target: number().nullable(),
|
|
57243
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56835
57244
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56836
57245
|
* in `heat_cool` mode. */
|
|
56837
|
-
targetHigh: number().nullable(),
|
|
57246
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56838
57247
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56839
57248
|
* in `heat_cool` mode. */
|
|
56840
|
-
targetLow: number().nullable(),
|
|
57249
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56841
57250
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56842
57251
|
* humidity control. */
|
|
56843
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57252
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56844
57253
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56845
57254
|
* the device's internal sensor. */
|
|
56846
|
-
currentTemp: number().nullable(),
|
|
57255
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56847
57256
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56848
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57257
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56849
57258
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56850
57259
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56851
57260
|
swingVertical: boolean().nullable(),
|
|
@@ -56853,11 +57262,11 @@ object({
|
|
|
56853
57262
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56854
57263
|
swingHorizontal: boolean().nullable(),
|
|
56855
57264
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56856
|
-
minTemp: number().nullable().optional(),
|
|
57265
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56857
57266
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56858
|
-
maxTemp: number().nullable().optional(),
|
|
57267
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56859
57268
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56860
|
-
tempStep: number().positive().nullable().optional(),
|
|
57269
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56861
57270
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56862
57271
|
lastFetchedAt: number()
|
|
56863
57272
|
});
|
|
@@ -56936,17 +57345,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
56936
57345
|
* modes to expose in the picker without a slice fetch.
|
|
56937
57346
|
*/
|
|
56938
57347
|
var RgbTripletSchema = object({
|
|
56939
|
-
r: number().int().min(0).max(255),
|
|
56940
|
-
g: number().int().min(0).max(255),
|
|
56941
|
-
b: number().int().min(0).max(255)
|
|
57348
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57349
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57350
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
56942
57351
|
});
|
|
56943
57352
|
var HsvTripletSchema = object({
|
|
56944
57353
|
/** Hue in degrees, 0..360. */
|
|
56945
|
-
h: number().min(0).max(360),
|
|
57354
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
56946
57355
|
/** Saturation as 0..100 inclusive. */
|
|
56947
|
-
s: number().min(0).max(100),
|
|
57356
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
56948
57357
|
/** Value/brightness as 0..100 inclusive. */
|
|
56949
|
-
v: number().min(0).max(100)
|
|
57358
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
56950
57359
|
});
|
|
56951
57360
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
56952
57361
|
object({
|
|
@@ -56975,7 +57384,7 @@ object({
|
|
|
56975
57384
|
/** Populated when `mode === 'hsv'`. */
|
|
56976
57385
|
hsv: HsvTripletSchema.optional(),
|
|
56977
57386
|
/** Populated when `mode === 'mired'`. */
|
|
56978
|
-
mireds: number().int().optional(),
|
|
57387
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
56979
57388
|
/** Ms epoch of the last operator-driven change. */
|
|
56980
57389
|
lastChangedAt: number()
|
|
56981
57390
|
});
|
|
@@ -57099,18 +57508,12 @@ _enum([
|
|
|
57099
57508
|
"empty",
|
|
57100
57509
|
"full"
|
|
57101
57510
|
]);
|
|
57102
|
-
/**
|
|
57103
|
-
|
|
57104
|
-
|
|
57105
|
-
"days",
|
|
57106
|
-
"hours",
|
|
57107
|
-
"cycles"
|
|
57108
|
-
]);
|
|
57109
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57110
|
-
* days). `value` null = unknown (D393). */
|
|
57511
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57512
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57513
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57111
57514
|
var ConsumableRemainingSchema = object({
|
|
57112
|
-
value: number().min(0).nullable(),
|
|
57113
|
-
|
|
57515
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57516
|
+
kind: ConsumableRemainingKindSchema
|
|
57114
57517
|
});
|
|
57115
57518
|
var ConsumablesStatusSchema = object({
|
|
57116
57519
|
items: array(object({
|
|
@@ -57119,7 +57522,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57119
57522
|
/** Display name. */
|
|
57120
57523
|
label: string().min(1),
|
|
57121
57524
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57122
|
-
level: number().min(0).max(100).nullable(),
|
|
57525
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57123
57526
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57124
57527
|
status: ConsumableStatusSchema.nullable(),
|
|
57125
57528
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57136,7 +57539,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57136
57539
|
})),
|
|
57137
57540
|
lastChangedAt: number()
|
|
57138
57541
|
});
|
|
57139
|
-
Object.values(DeviceType), [...
|
|
57542
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57140
57543
|
Object.values(DeviceType), method(object({
|
|
57141
57544
|
deviceId: number().int().nonnegative(),
|
|
57142
57545
|
key: string().min(1)
|
|
@@ -57161,39 +57564,17 @@ object({
|
|
|
57161
57564
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57162
57565
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57163
57566
|
* or time-only — HA accepts all three forms). */
|
|
57164
|
-
value: union([number(), string()]),
|
|
57567
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57165
57568
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57166
57569
|
options: array(string()),
|
|
57167
57570
|
/** Ms epoch when the slice was last updated. */
|
|
57168
57571
|
lastChangedAt: number(),
|
|
57169
|
-
/**
|
|
57170
|
-
|
|
57171
|
-
|
|
57172
|
-
|
|
57173
|
-
/**
|
|
57174
|
-
|
|
57175
|
-
min: number().optional(),
|
|
57176
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57177
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57178
|
-
max: number().optional(),
|
|
57179
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57180
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57181
|
-
step: number().optional(),
|
|
57182
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57183
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57184
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57185
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57186
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57187
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57188
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57189
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57190
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57191
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57192
|
-
format: _enum([
|
|
57193
|
-
"date",
|
|
57194
|
-
"time",
|
|
57195
|
-
"datetime"
|
|
57196
|
-
]).optional()
|
|
57572
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57573
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57574
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57575
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57576
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57577
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57197
57578
|
});
|
|
57198
57579
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57199
57580
|
object({
|
|
@@ -57231,9 +57612,9 @@ object({
|
|
|
57231
57612
|
]),
|
|
57232
57613
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57233
57614
|
* no intermediate position surface. */
|
|
57234
|
-
position: number().min(0).max(100).nullable(),
|
|
57615
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57235
57616
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57236
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57617
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57237
57618
|
/** Ms epoch when the slice was last updated. */
|
|
57238
57619
|
lastChangedAt: number()
|
|
57239
57620
|
});
|
|
@@ -57291,9 +57672,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57291
57672
|
object({
|
|
57292
57673
|
mode: DayNightModeSchema,
|
|
57293
57674
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57294
|
-
sensitivity: number().optional(),
|
|
57675
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57295
57676
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57296
|
-
switchDelaySec: number().optional(),
|
|
57677
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57297
57678
|
lastFetchedAt: number()
|
|
57298
57679
|
});
|
|
57299
57680
|
/**
|
|
@@ -57448,11 +57829,11 @@ object({
|
|
|
57448
57829
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57449
57830
|
availablePrograms: array(string()),
|
|
57450
57831
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57451
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57832
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57452
57833
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57453
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57834
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57454
57835
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57455
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57836
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57456
57837
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57457
57838
|
doorOpen: boolean().nullable(),
|
|
57458
57839
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57476,7 +57857,7 @@ object({
|
|
|
57476
57857
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57477
57858
|
machineCareDue: boolean().nullable(),
|
|
57478
57859
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57479
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57860
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57480
57861
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57481
57862
|
halfLoad: boolean().nullable(),
|
|
57482
57863
|
hygienePlus: boolean().nullable(),
|
|
@@ -57491,7 +57872,7 @@ object({
|
|
|
57491
57872
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57492
57873
|
activeEvents: array(string()),
|
|
57493
57874
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57494
|
-
errorCode: number().nullable(),
|
|
57875
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57495
57876
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57496
57877
|
errorLabel: string().nullable(),
|
|
57497
57878
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57637,24 +58018,14 @@ object({
|
|
|
57637
58018
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57638
58019
|
lastPressedAt: number().nullable(),
|
|
57639
58020
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57640
|
-
pressCountSinceStart: number()
|
|
58021
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57641
58022
|
});
|
|
57642
58023
|
object({
|
|
57643
58024
|
deviceId: number(),
|
|
57644
58025
|
timestamp: number()
|
|
57645
58026
|
});
|
|
57646
58027
|
DeviceType.Button, DeviceType.Camera;
|
|
57647
|
-
|
|
57648
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57649
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57650
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57651
|
-
* The option set is stable across observations; it is persisted in the
|
|
57652
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57653
|
-
* stored in `sourceInfo`.
|
|
57654
|
-
*/
|
|
57655
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57656
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57657
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
58028
|
+
_enum([
|
|
57658
58029
|
"date",
|
|
57659
58030
|
"time",
|
|
57660
58031
|
"datetime"
|
|
@@ -57662,12 +58033,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57662
58033
|
object({
|
|
57663
58034
|
value: string(),
|
|
57664
58035
|
/**
|
|
57665
|
-
* Set
|
|
57666
|
-
* as
|
|
57667
|
-
*
|
|
57668
|
-
* a time-only sensor → `'time'`.
|
|
58036
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
58037
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
58038
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57669
58039
|
*/
|
|
57670
|
-
|
|
58040
|
+
timestamp: boolean().optional(),
|
|
57671
58041
|
/** Ms epoch when the slice was last updated. */
|
|
57672
58042
|
lastFetchedAt: number()
|
|
57673
58043
|
});
|
|
@@ -57686,13 +58056,13 @@ var EventFireSchema = object({
|
|
|
57686
58056
|
deviceId: number(),
|
|
57687
58057
|
eventType: string(),
|
|
57688
58058
|
data: record(string(), unknown()).nullable(),
|
|
57689
|
-
timestamp: number(),
|
|
57690
|
-
seq: number()
|
|
58059
|
+
timestamp: number().meta(readingMeta("none")),
|
|
58060
|
+
seq: number().meta(readingMeta("count"))
|
|
57691
58061
|
});
|
|
57692
58062
|
object({
|
|
57693
58063
|
eventTypes: array(string()),
|
|
57694
58064
|
lastEvent: EventFireSchema.nullable(),
|
|
57695
|
-
eventCountSinceStart: number()
|
|
58065
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57696
58066
|
});
|
|
57697
58067
|
DeviceType.EventEmitter;
|
|
57698
58068
|
var IdentitySchema = object({
|
|
@@ -58081,10 +58451,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58081
58451
|
object({
|
|
58082
58452
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58083
58453
|
* speed surface (single-speed fan). */
|
|
58084
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58454
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58085
58455
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58086
58456
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58087
|
-
percentageStep: number().positive().optional(),
|
|
58457
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58088
58458
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58089
58459
|
* — empty string when no preset is active or supported. */
|
|
58090
58460
|
preset: string(),
|
|
@@ -58166,7 +58536,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58166
58536
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58167
58537
|
model: string().nullable(),
|
|
58168
58538
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58169
|
-
channelCount: number().nullable(),
|
|
58539
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58170
58540
|
/**
|
|
58171
58541
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58172
58542
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58198,9 +58568,39 @@ object({
|
|
|
58198
58568
|
lastChangedAt: number()
|
|
58199
58569
|
});
|
|
58200
58570
|
DeviceType.Sensor;
|
|
58571
|
+
object({
|
|
58572
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58573
|
+
results: array(object({
|
|
58574
|
+
deviceId: number().int().nonnegative(),
|
|
58575
|
+
cap: string().min(1),
|
|
58576
|
+
method: string().min(1),
|
|
58577
|
+
ok: boolean(),
|
|
58578
|
+
error: string().optional(),
|
|
58579
|
+
/** Ms epoch of the attempt. */
|
|
58580
|
+
at: number()
|
|
58581
|
+
})) });
|
|
58582
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58583
|
+
object({
|
|
58584
|
+
/** Members whose current value entered the aggregate. */
|
|
58585
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58586
|
+
precision: 0,
|
|
58587
|
+
label: "Reporting"
|
|
58588
|
+
})),
|
|
58589
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58590
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58591
|
+
precision: 0,
|
|
58592
|
+
label: "Excluded"
|
|
58593
|
+
})),
|
|
58594
|
+
/** `included` + `excluded`. */
|
|
58595
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58596
|
+
precision: 0,
|
|
58597
|
+
label: "Members"
|
|
58598
|
+
}))
|
|
58599
|
+
});
|
|
58600
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58201
58601
|
object({
|
|
58202
58602
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58203
|
-
position: number().min(0).max(100).nullable(),
|
|
58603
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58204
58604
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58205
58605
|
lastFetchedAt: number()
|
|
58206
58606
|
});
|
|
@@ -58209,9 +58609,9 @@ object({
|
|
|
58209
58609
|
/** Whether the humidifier is currently on. */
|
|
58210
58610
|
on: boolean(),
|
|
58211
58611
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58212
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58612
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58213
58613
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58214
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58614
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58215
58615
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58216
58616
|
* device has no mode surface. */
|
|
58217
58617
|
mode: string().nullable(),
|
|
@@ -58221,9 +58621,9 @@ object({
|
|
|
58221
58621
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58222
58622
|
action: string().nullable(),
|
|
58223
58623
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58224
|
-
minHumidity: number().nullable(),
|
|
58624
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58225
58625
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58226
|
-
maxHumidity: number().nullable(),
|
|
58626
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58227
58627
|
/** Ms epoch when the slice was last updated. */
|
|
58228
58628
|
lastChangedAt: number()
|
|
58229
58629
|
});
|
|
@@ -58247,22 +58647,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58247
58647
|
auth: "protected"
|
|
58248
58648
|
});
|
|
58249
58649
|
object({
|
|
58250
|
-
/** Current relative humidity, 0..100. */
|
|
58251
|
-
percent: number().min(0).max(100).meta({
|
|
58252
|
-
|
|
58650
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58651
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58652
|
+
precision: 0,
|
|
58253
58653
|
label: "Humidity"
|
|
58254
|
-
}),
|
|
58654
|
+
})),
|
|
58255
58655
|
/** Ms epoch when the slice was last updated. */
|
|
58256
|
-
lastFetchedAt: number()
|
|
58257
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58258
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58259
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58260
|
-
unit: string().optional(),
|
|
58261
|
-
/** Suggested decimal places for numeric display.
|
|
58262
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58263
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58264
|
-
* auto-formatting when absent. */
|
|
58265
|
-
precision: number().int().min(0).max(10).optional()
|
|
58656
|
+
lastFetchedAt: number()
|
|
58266
58657
|
});
|
|
58267
58658
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58268
58659
|
object({
|
|
@@ -58270,7 +58661,7 @@ object({
|
|
|
58270
58661
|
* entity exposes no `entity_picture` (yet). */
|
|
58271
58662
|
url: string().nullable(),
|
|
58272
58663
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58273
|
-
lastUpdated: number().nullable()
|
|
58664
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58274
58665
|
});
|
|
58275
58666
|
DeviceType.Image;
|
|
58276
58667
|
/**
|
|
@@ -58326,19 +58717,19 @@ var NormalizedRangeSchema = object({
|
|
|
58326
58717
|
});
|
|
58327
58718
|
object({
|
|
58328
58719
|
/** Normalized 0–100. */
|
|
58329
|
-
brightness: number().optional(),
|
|
58720
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58330
58721
|
/** Normalized 0–100. */
|
|
58331
|
-
contrast: number().optional(),
|
|
58722
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58332
58723
|
/** Normalized 0–100. */
|
|
58333
|
-
saturation: number().optional(),
|
|
58724
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58334
58725
|
/** Normalized 0–100. */
|
|
58335
|
-
sharpness: number().optional(),
|
|
58726
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58336
58727
|
mirror: boolean().optional(),
|
|
58337
58728
|
flip: boolean().optional(),
|
|
58338
58729
|
rotate: ImageRotateSchema.optional(),
|
|
58339
58730
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58340
58731
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58341
|
-
warmth: number().optional(),
|
|
58732
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58342
58733
|
exposureMode: ExposureModeSchema.optional(),
|
|
58343
58734
|
backlightMode: BacklightModeSchema.optional(),
|
|
58344
58735
|
lastFetchedAt: number()
|
|
@@ -58583,10 +58974,10 @@ var IntercomAbilitySchema = object({
|
|
|
58583
58974
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58584
58975
|
codecs: array(string()),
|
|
58585
58976
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58586
|
-
sampleRate: number(),
|
|
58977
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58587
58978
|
duplex: _enum(["half", "full"]),
|
|
58588
58979
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58589
|
-
maxBacklogMs: number()
|
|
58980
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58590
58981
|
});
|
|
58591
58982
|
var IntercomStatusSchema = object({
|
|
58592
58983
|
/** True while a talk session is open. */
|
|
@@ -58697,13 +59088,13 @@ object({
|
|
|
58697
59088
|
activity: LawnMowerActivitySchema,
|
|
58698
59089
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58699
59090
|
* reading. */
|
|
58700
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
59091
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58701
59092
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58702
59093
|
* task is active / progress is unavailable. */
|
|
58703
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59094
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58704
59095
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58705
59096
|
* or null when unknown. */
|
|
58706
|
-
currentCode: number().nullable(),
|
|
59097
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58707
59098
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58708
59099
|
currentCodeLabel: string().nullable(),
|
|
58709
59100
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59165,7 +59556,7 @@ object({
|
|
|
59165
59556
|
state: MediaPlayerStateSchema,
|
|
59166
59557
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59167
59558
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59168
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59559
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59169
59560
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59170
59561
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59171
59562
|
isMuted: boolean().nullable(),
|
|
@@ -59178,10 +59569,10 @@ object({
|
|
|
59178
59569
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59179
59570
|
/** Current playback position in ms. Null when not seekable or
|
|
59180
59571
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59181
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59572
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59182
59573
|
/** Total duration of the current media in ms. Null when unknown
|
|
59183
59574
|
* (live stream) or nothing is playing. */
|
|
59184
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59575
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59185
59576
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59186
59577
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59187
59578
|
shuffle: boolean().nullable(),
|
|
@@ -59481,7 +59872,7 @@ object({
|
|
|
59481
59872
|
* it, every provider seeded it at boot, and every session left it
|
|
59482
59873
|
* `detected: true` after its detach.
|
|
59483
59874
|
*/
|
|
59484
|
-
autoClearAfterMs: number().nullable()
|
|
59875
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59485
59876
|
});
|
|
59486
59877
|
/**
|
|
59487
59878
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59531,7 +59922,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59531
59922
|
});
|
|
59532
59923
|
object({
|
|
59533
59924
|
enabled: boolean(),
|
|
59534
|
-
sensitivity: number(),
|
|
59925
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59535
59926
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59536
59927
|
regions: array(MotionZoneRegionSchema),
|
|
59537
59928
|
lastFetchedAt: number()
|
|
@@ -59835,7 +60226,7 @@ var NavigationStatusSchema = object({
|
|
|
59835
60226
|
following: boolean(),
|
|
59836
60227
|
flash: boolean(),
|
|
59837
60228
|
lightMode: NavigationLightModeSchema,
|
|
59838
|
-
lightLevel: number().min(40).max(100),
|
|
60229
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59839
60230
|
/** Ms epoch when the slice was last updated. */
|
|
59840
60231
|
lastChangedAt: number()
|
|
59841
60232
|
});
|
|
@@ -59881,13 +60272,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59881
60272
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59882
60273
|
* SKIP a null rather than coerce it.
|
|
59883
60274
|
*/
|
|
59884
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
60275
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59885
60276
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59886
|
-
rssiDbm: number().optional(),
|
|
60277
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59887
60278
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59888
60279
|
ssid: string().optional(),
|
|
59889
60280
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59890
|
-
lastUpdated: number()
|
|
60281
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59891
60282
|
});
|
|
59892
60283
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59893
60284
|
deviceId: number(),
|
|
@@ -60206,7 +60597,7 @@ object({
|
|
|
60206
60597
|
lastError: string().nullable(),
|
|
60207
60598
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60208
60599
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60209
|
-
queueDepth: number().int().nonnegative(),
|
|
60600
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60210
60601
|
/** Per-feature capability matrix — authoritative source for the
|
|
60211
60602
|
* compose-form field gating. */
|
|
60212
60603
|
supports: NotifierSupportsSchema
|
|
@@ -60256,15 +60647,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60256
60647
|
acceptedAt: number()
|
|
60257
60648
|
});
|
|
60258
60649
|
object({
|
|
60259
|
-
|
|
60260
|
-
|
|
60261
|
-
* Populated live from the upstream source on each state push.
|
|
60262
|
-
* Absent for unitless sensors. */
|
|
60263
|
-
unit: string().optional(),
|
|
60264
|
-
/** Suggested decimal places for numeric display.
|
|
60265
|
-
* Populated live from the upstream source when provided.
|
|
60266
|
-
* Falls back to auto-formatting when absent. */
|
|
60267
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60650
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60651
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60268
60652
|
/** Ms epoch when the slice was last updated. */
|
|
60269
60653
|
lastFetchedAt: number()
|
|
60270
60654
|
});
|
|
@@ -60554,23 +60938,26 @@ object({
|
|
|
60554
60938
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60555
60939
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60556
60940
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60557
|
-
foodLevel: number().nullable(),
|
|
60941
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60558
60942
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60559
60943
|
* single-hopper models. */
|
|
60560
|
-
food1: number().nullable(),
|
|
60944
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60561
60945
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60562
60946
|
* single-hopper models. */
|
|
60563
|
-
food2: number().nullable(),
|
|
60947
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60564
60948
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60565
60949
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60566
60950
|
* below the feeder's low threshold. */
|
|
60567
60951
|
lowFood: boolean(),
|
|
60568
60952
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60569
60953
|
* device has no battery reading. */
|
|
60570
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60571
|
-
/**
|
|
60572
|
-
*
|
|
60573
|
-
|
|
60954
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60955
|
+
/**
|
|
60956
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
60957
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
60958
|
+
* model has no desiccant sensor.
|
|
60959
|
+
*/
|
|
60960
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60574
60961
|
/** True while a feed is in progress. */
|
|
60575
60962
|
feeding: boolean(),
|
|
60576
60963
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60581,7 +60968,7 @@ object({
|
|
|
60581
60968
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60582
60969
|
error: string().nullable(),
|
|
60583
60970
|
/** Raw device error code (0 / null = no error). */
|
|
60584
|
-
errorCode: number().nullable(),
|
|
60971
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60585
60972
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60586
60973
|
isDualHopper: boolean(),
|
|
60587
60974
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60591,7 +60978,7 @@ object({
|
|
|
60591
60978
|
/** Play a chime when dispensing. */
|
|
60592
60979
|
feedSound: boolean(),
|
|
60593
60980
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60594
|
-
volume: number(),
|
|
60981
|
+
volume: number().meta(readingMeta("none")),
|
|
60595
60982
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60596
60983
|
lastFetchedAt: number()
|
|
60597
60984
|
});
|
|
@@ -61028,36 +61415,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61028
61415
|
});
|
|
61029
61416
|
object({
|
|
61030
61417
|
/** Instantaneous power draw in watts. */
|
|
61031
|
-
watts: number().optional().meta({
|
|
61032
|
-
unit: "W",
|
|
61033
|
-
label: "Power"
|
|
61034
|
-
}),
|
|
61418
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61035
61419
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61036
|
-
kwhTotal: number().optional().meta({
|
|
61037
|
-
unit: "kWh",
|
|
61038
|
-
label: "Energy"
|
|
61039
|
-
}),
|
|
61420
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61040
61421
|
/** Voltage in volts. */
|
|
61041
|
-
volts: number().optional(),
|
|
61422
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61042
61423
|
/** Current in amperes. */
|
|
61043
|
-
amps: number().optional(),
|
|
61044
|
-
/** Apparent power in volt-amperes
|
|
61045
|
-
va: number().optional(),
|
|
61424
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61425
|
+
/** Apparent power in volt-amperes. */
|
|
61426
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61046
61427
|
/** Power factor (0..1) if reported. */
|
|
61047
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61428
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61048
61429
|
/** Ms epoch when the slice was last updated. */
|
|
61049
|
-
lastFetchedAt: number()
|
|
61050
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61051
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61052
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61053
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61054
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61055
|
-
unit: string().optional(),
|
|
61056
|
-
/** Suggested decimal places for numeric display.
|
|
61057
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61058
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61059
|
-
* auto-formatting when absent. */
|
|
61060
|
-
precision: number().int().min(0).max(10).optional()
|
|
61430
|
+
lastFetchedAt: number()
|
|
61061
61431
|
});
|
|
61062
61432
|
DeviceType.Sensor;
|
|
61063
61433
|
/**
|
|
@@ -61078,11 +61448,11 @@ DeviceType.Sensor;
|
|
|
61078
61448
|
*/
|
|
61079
61449
|
var GpsLocationSchema = object({
|
|
61080
61450
|
/** Latitude in decimal degrees, -90..90. */
|
|
61081
|
-
latitude: number().min(-90).max(90),
|
|
61451
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61082
61452
|
/** Longitude in decimal degrees, -180..180. */
|
|
61083
|
-
longitude: number().min(-180).max(180),
|
|
61453
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61084
61454
|
/** Reported accuracy in meters (lower = better). */
|
|
61085
|
-
accuracyMeters: number().nonnegative()
|
|
61455
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61086
61456
|
});
|
|
61087
61457
|
object({
|
|
61088
61458
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61094,25 +61464,16 @@ object({
|
|
|
61094
61464
|
gps: GpsLocationSchema.nullable(),
|
|
61095
61465
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61096
61466
|
* when not reported. */
|
|
61097
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61467
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61098
61468
|
/** Ms epoch when the slice was last updated. */
|
|
61099
61469
|
lastChangedAt: number()
|
|
61100
61470
|
});
|
|
61101
61471
|
DeviceType.Presence;
|
|
61102
61472
|
object({
|
|
61103
|
-
/** Current pressure in hPa. */
|
|
61104
|
-
hpa: number(),
|
|
61473
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61474
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61105
61475
|
/** Ms epoch when the slice was last updated. */
|
|
61106
|
-
lastFetchedAt: number()
|
|
61107
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61108
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61109
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61110
|
-
unit: string().optional(),
|
|
61111
|
-
/** Suggested decimal places for numeric display.
|
|
61112
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61113
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61114
|
-
* auto-formatting when absent. */
|
|
61115
|
-
precision: number().int().min(0).max(10).optional()
|
|
61476
|
+
lastFetchedAt: number()
|
|
61116
61477
|
});
|
|
61117
61478
|
DeviceType.Sensor;
|
|
61118
61479
|
/**
|
|
@@ -61445,8 +61806,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61445
61806
|
}), _void(), { kind: "mutation" });
|
|
61446
61807
|
var PtzAutotrackSettingsSchema = object({
|
|
61447
61808
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61448
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61449
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61809
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61810
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61450
61811
|
});
|
|
61451
61812
|
/**
|
|
61452
61813
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61503,7 +61864,7 @@ object({
|
|
|
61503
61864
|
/** null = unknown — never coerced to false (D393). */
|
|
61504
61865
|
running: boolean().nullable(),
|
|
61505
61866
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61506
|
-
since: number().nullable(),
|
|
61867
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61507
61868
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61508
61869
|
phase: string().nullable(),
|
|
61509
61870
|
/** null until a reading has been published (D393). */
|
|
@@ -62701,9 +63062,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62701
63062
|
*/
|
|
62702
63063
|
var RecordWindowSchema = object({
|
|
62703
63064
|
trigger: RecordTriggerSchema,
|
|
62704
|
-
day: number().int().min(0).max(6),
|
|
62705
|
-
startMinute: number().int().min(0).max(1439),
|
|
62706
|
-
endMinute: number().int().min(1).max(1440)
|
|
63065
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
63066
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
63067
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62707
63068
|
});
|
|
62708
63069
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62709
63070
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62772,10 +63133,10 @@ object({
|
|
|
62772
63133
|
/** Master "record to the card at all" switch. */
|
|
62773
63134
|
enabled: boolean().nullable(),
|
|
62774
63135
|
overwriteWhenFull: boolean().nullable(),
|
|
62775
|
-
preRecordSec: number().nullable(),
|
|
62776
|
-
postRecordSec: number().nullable(),
|
|
63136
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
63137
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62777
63138
|
/** Length of one recorded file, in minutes. */
|
|
62778
|
-
segmentMinutes: number().nullable(),
|
|
63139
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62779
63140
|
/** The primary track's weekly windows, flattened. */
|
|
62780
63141
|
windows: array(RecordWindowSchema),
|
|
62781
63142
|
/**
|
|
@@ -62791,7 +63152,7 @@ object({
|
|
|
62791
63152
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62792
63153
|
* writable.
|
|
62793
63154
|
*/
|
|
62794
|
-
unreadableWindows: number(),
|
|
63155
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62795
63156
|
/**
|
|
62796
63157
|
* The camera is scheduled to record and has NO usable storage.
|
|
62797
63158
|
*
|
|
@@ -63428,7 +63789,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63428
63789
|
url: string().optional(),
|
|
63429
63790
|
codec: string().optional(),
|
|
63430
63791
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63431
|
-
fps: number().positive().optional(),
|
|
63792
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63432
63793
|
label: string().optional(),
|
|
63433
63794
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63434
63795
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63458,18 +63819,18 @@ var StreamProfileSchema = _enum([
|
|
|
63458
63819
|
]);
|
|
63459
63820
|
/** The current encoding config of one stream profile. */
|
|
63460
63821
|
var StreamProfileConfigSchema = object({
|
|
63461
|
-
width: number(),
|
|
63462
|
-
height: number(),
|
|
63822
|
+
width: number().meta(readingMeta("none")),
|
|
63823
|
+
height: number().meta(readingMeta("none")),
|
|
63463
63824
|
codec: _enum(["h264", "h265"]),
|
|
63464
|
-
framerate: number(),
|
|
63465
|
-
bitrate: number(),
|
|
63825
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63826
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63466
63827
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63467
63828
|
encoderProfile: _enum([
|
|
63468
63829
|
"high",
|
|
63469
63830
|
"main",
|
|
63470
63831
|
"baseline"
|
|
63471
63832
|
]).optional(),
|
|
63472
|
-
gop: number().optional(),
|
|
63833
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63473
63834
|
/**
|
|
63474
63835
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63475
63836
|
*
|
|
@@ -64112,23 +64473,13 @@ object({
|
|
|
64112
64473
|
});
|
|
64113
64474
|
DeviceType.Sensor;
|
|
64114
64475
|
object({
|
|
64115
|
-
/** Current temperature in Celsius. */
|
|
64116
|
-
celsius: number().meta({
|
|
64117
|
-
|
|
64476
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64477
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64478
|
+
precision: 1,
|
|
64118
64479
|
label: "Temperature"
|
|
64119
|
-
}),
|
|
64480
|
+
})),
|
|
64120
64481
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64121
|
-
lastFetchedAt: number()
|
|
64122
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64123
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64124
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64125
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64126
|
-
unit: string().optional(),
|
|
64127
|
-
/** Suggested decimal places for numeric display.
|
|
64128
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64129
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64130
|
-
* auto-formatting when absent. */
|
|
64131
|
-
precision: number().int().min(0).max(10).optional()
|
|
64482
|
+
lastFetchedAt: number()
|
|
64132
64483
|
});
|
|
64133
64484
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64134
64485
|
/**
|
|
@@ -64380,16 +64731,16 @@ object({
|
|
|
64380
64731
|
]),
|
|
64381
64732
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64382
64733
|
* reading. */
|
|
64383
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64734
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64384
64735
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64385
64736
|
* the vacuum has no speed control. */
|
|
64386
64737
|
fanSpeed: string().nullable(),
|
|
64387
64738
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64388
64739
|
availableFanSpeeds: array(string()),
|
|
64389
64740
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64390
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64741
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64391
64742
|
/** Current error code (0 / null = no error). */
|
|
64392
|
-
errorCode: number().nullable(),
|
|
64743
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64393
64744
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64394
64745
|
errorLabel: string().nullable(),
|
|
64395
64746
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64428,7 +64779,7 @@ object({
|
|
|
64428
64779
|
]),
|
|
64429
64780
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64430
64781
|
* intermediate position surface. */
|
|
64431
|
-
position: number().min(0).max(100).nullable(),
|
|
64782
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64432
64783
|
/** Ms epoch when the slice was last updated. */
|
|
64433
64784
|
lastChangedAt: number()
|
|
64434
64785
|
});
|
|
@@ -64456,9 +64807,9 @@ object({
|
|
|
64456
64807
|
DeviceType.Sensor;
|
|
64457
64808
|
object({
|
|
64458
64809
|
/** Current measured temperature. Null when not reported. */
|
|
64459
|
-
currentTemp: number().nullable(),
|
|
64810
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64460
64811
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64461
|
-
targetTemp: number().nullable(),
|
|
64812
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64462
64813
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64463
64814
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64464
64815
|
* device reports an unknown state. */
|
|
@@ -64469,9 +64820,9 @@ object({
|
|
|
64469
64820
|
* has no away surface. */
|
|
64470
64821
|
away: boolean().nullable(),
|
|
64471
64822
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64472
|
-
minTemp: number().nullable(),
|
|
64823
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64473
64824
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64474
|
-
maxTemp: number().nullable(),
|
|
64825
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64475
64826
|
/** Ms epoch when the slice was last updated. */
|
|
64476
64827
|
lastChangedAt: number()
|
|
64477
64828
|
});
|
|
@@ -64495,25 +64846,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64495
64846
|
auth: "protected"
|
|
64496
64847
|
});
|
|
64497
64848
|
object({
|
|
64498
|
-
/** Verbatim
|
|
64499
|
-
* when no condition has been reported yet. */
|
|
64849
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64500
64850
|
condition: string().nullable(),
|
|
64501
|
-
/** Current temperature in
|
|
64502
|
-
temperature: number().nullable(),
|
|
64503
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64504
|
-
temperatureUnit: string().nullable(),
|
|
64851
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64852
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64505
64853
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64506
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64507
|
-
/** Barometric pressure in
|
|
64508
|
-
pressure: number().nullable(),
|
|
64509
|
-
/**
|
|
64510
|
-
|
|
64511
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64512
|
-
windSpeed: number().nullable(),
|
|
64513
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64514
|
-
windSpeedUnit: string().nullable(),
|
|
64854
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64855
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64856
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64857
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64858
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64515
64859
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64516
|
-
windBearing: number().nullable(),
|
|
64860
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64517
64861
|
/** Ms epoch when the slice was last updated. */
|
|
64518
64862
|
lastFetchedAt: number()
|
|
64519
64863
|
});
|
|
@@ -65425,6 +65769,13 @@ Object.freeze({
|
|
|
65425
65769
|
access: "view",
|
|
65426
65770
|
role: "admin"
|
|
65427
65771
|
},
|
|
65772
|
+
"addons.getPackageDocs": {
|
|
65773
|
+
capName: "addons",
|
|
65774
|
+
capScope: "system",
|
|
65775
|
+
addonId: null,
|
|
65776
|
+
access: "view",
|
|
65777
|
+
role: "admin"
|
|
65778
|
+
},
|
|
65428
65779
|
"addons.getVersions": {
|
|
65429
65780
|
capName: "addons",
|
|
65430
65781
|
capScope: "system",
|
|
@@ -68533,6 +68884,20 @@ Object.freeze({
|
|
|
68533
68884
|
access: "view",
|
|
68534
68885
|
role: "viewer"
|
|
68535
68886
|
},
|
|
68887
|
+
"groupCommands.getStatus": {
|
|
68888
|
+
capName: "group-commands",
|
|
68889
|
+
capScope: "device",
|
|
68890
|
+
addonId: null,
|
|
68891
|
+
access: "view",
|
|
68892
|
+
role: "viewer"
|
|
68893
|
+
},
|
|
68894
|
+
"groupStatus.getStatus": {
|
|
68895
|
+
capName: "group-status",
|
|
68896
|
+
capScope: "device",
|
|
68897
|
+
addonId: null,
|
|
68898
|
+
access: "view",
|
|
68899
|
+
role: "viewer"
|
|
68900
|
+
},
|
|
68536
68901
|
"heatingValve.getStatus": {
|
|
68537
68902
|
capName: "heating-valve",
|
|
68538
68903
|
capScope: "device",
|
|
@@ -78355,6 +78720,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78355
78720
|
icon: "flame"
|
|
78356
78721
|
}]
|
|
78357
78722
|
},
|
|
78723
|
+
"group-commands": {
|
|
78724
|
+
scope: "device",
|
|
78725
|
+
noun: t("Group command", "Comando di gruppo")
|
|
78726
|
+
},
|
|
78727
|
+
"group-status": {
|
|
78728
|
+
scope: "device",
|
|
78729
|
+
noun: t("Group", "Gruppo"),
|
|
78730
|
+
state: [
|
|
78731
|
+
{
|
|
78732
|
+
kind: "numeric",
|
|
78733
|
+
field: "included",
|
|
78734
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
78735
|
+
label: t("Reporting", "Rispondono"),
|
|
78736
|
+
icon: "users"
|
|
78737
|
+
},
|
|
78738
|
+
{
|
|
78739
|
+
kind: "numeric",
|
|
78740
|
+
field: "excluded",
|
|
78741
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
78742
|
+
label: t("Excluded", "Esclusi"),
|
|
78743
|
+
icon: "users"
|
|
78744
|
+
},
|
|
78745
|
+
{
|
|
78746
|
+
kind: "numeric",
|
|
78747
|
+
field: "total",
|
|
78748
|
+
quantity: t("the member count", "il numero di membri"),
|
|
78749
|
+
label: t("Members", "Membri"),
|
|
78750
|
+
icon: "sigma"
|
|
78751
|
+
}
|
|
78752
|
+
]
|
|
78753
|
+
},
|
|
78358
78754
|
"humidity-sensor": {
|
|
78359
78755
|
scope: "device",
|
|
78360
78756
|
noun: t("Humidity", "Umidità"),
|
|
@@ -78388,7 +78784,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78388
78784
|
field: "value",
|
|
78389
78785
|
quantity: t("the reading", "il valore"),
|
|
78390
78786
|
label: t("Reading", "Valore"),
|
|
78391
|
-
unitField: "unit",
|
|
78392
78787
|
icon: "gauge"
|
|
78393
78788
|
}]
|
|
78394
78789
|
},
|
|
@@ -78524,7 +78919,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78524
78919
|
field: "temperature",
|
|
78525
78920
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78526
78921
|
label: t("Temperature", "Temperatura"),
|
|
78527
|
-
|
|
78922
|
+
unit: "°C",
|
|
78528
78923
|
icon: "thermometer"
|
|
78529
78924
|
},
|
|
78530
78925
|
{
|
|
@@ -78540,7 +78935,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78540
78935
|
field: "windSpeed",
|
|
78541
78936
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78542
78937
|
label: t("Wind", "Vento"),
|
|
78543
|
-
|
|
78938
|
+
unit: "m/s",
|
|
78544
78939
|
icon: "wind"
|
|
78545
78940
|
},
|
|
78546
78941
|
{
|
|
@@ -78548,7 +78943,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78548
78943
|
field: "pressure",
|
|
78549
78944
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78550
78945
|
label: t("Pressure", "Pressione"),
|
|
78551
|
-
|
|
78946
|
+
unit: "hPa",
|
|
78552
78947
|
icon: "gauge"
|
|
78553
78948
|
}
|
|
78554
78949
|
]
|
|
@@ -79821,6 +80216,16 @@ Object.freeze({
|
|
|
79821
80216
|
form: "single",
|
|
79822
80217
|
optional: false
|
|
79823
80218
|
}],
|
|
80219
|
+
"groupCommands.getStatus": [{
|
|
80220
|
+
name: "deviceId",
|
|
80221
|
+
form: "single",
|
|
80222
|
+
optional: false
|
|
80223
|
+
}],
|
|
80224
|
+
"groupStatus.getStatus": [{
|
|
80225
|
+
name: "deviceId",
|
|
80226
|
+
form: "single",
|
|
80227
|
+
optional: false
|
|
80228
|
+
}],
|
|
79824
80229
|
"heatingValve.getStatus": [{
|
|
79825
80230
|
name: "deviceId",
|
|
79826
80231
|
form: "single",
|
|
@@ -81685,6 +82090,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
81685
82090
|
targetId: string().min(1),
|
|
81686
82091
|
enabled: boolean(),
|
|
81687
82092
|
debounceMs: number().nonnegative(),
|
|
82093
|
+
edges: array(_enum([
|
|
82094
|
+
"rising",
|
|
82095
|
+
"button",
|
|
82096
|
+
"native-event"
|
|
82097
|
+
])).min(1).optional(),
|
|
81688
82098
|
sources: array(OverrideSourceSchema).min(1)
|
|
81689
82099
|
});
|
|
81690
82100
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -81800,6 +82210,8 @@ new Map(Object.entries({
|
|
|
81800
82210
|
"detection-blind": "device-events",
|
|
81801
82211
|
"motion-noisy": "device-events",
|
|
81802
82212
|
"motion-calm": "device-events",
|
|
82213
|
+
"package-llm-silent": "device-events",
|
|
82214
|
+
"package-llm-answered": "device-events",
|
|
81803
82215
|
"recording-stalled": "device-events",
|
|
81804
82216
|
"recording-healthy": "device-events",
|
|
81805
82217
|
"recording-degraded": "device-events",
|
|
@@ -81883,6 +82295,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
81883
82295
|
label: "Motion without a subject",
|
|
81884
82296
|
kinds: ["motion-noisy", "motion-calm"]
|
|
81885
82297
|
},
|
|
82298
|
+
{
|
|
82299
|
+
id: "package-llm",
|
|
82300
|
+
family: "device-events",
|
|
82301
|
+
label: "Package confirm",
|
|
82302
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
82303
|
+
},
|
|
81886
82304
|
{
|
|
81887
82305
|
id: "recording",
|
|
81888
82306
|
family: "device-events",
|
|
@@ -82064,6 +82482,8 @@ var DEVICE_EVENTS = [
|
|
|
82064
82482
|
"detection-blind",
|
|
82065
82483
|
"motion-noisy",
|
|
82066
82484
|
"motion-calm",
|
|
82485
|
+
"package-llm-silent",
|
|
82486
|
+
"package-llm-answered",
|
|
82067
82487
|
"recording-stalled",
|
|
82068
82488
|
"recording-healthy",
|
|
82069
82489
|
"recording-degraded",
|
|
@@ -82332,6 +82752,15 @@ new Map([
|
|
|
82332
82752
|
snapshotLabel: "Cameras with constant motion now",
|
|
82333
82753
|
snapshotSection: null
|
|
82334
82754
|
},
|
|
82755
|
+
{
|
|
82756
|
+
id: "package-llm-confirm",
|
|
82757
|
+
family: "device-events",
|
|
82758
|
+
label: "Package confirm (not answering / answering again)",
|
|
82759
|
+
bad: ["package-llm-silent"],
|
|
82760
|
+
recovery: ["package-llm-answered"],
|
|
82761
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
82762
|
+
snapshotSection: null
|
|
82763
|
+
},
|
|
82335
82764
|
{
|
|
82336
82765
|
id: "recording-health",
|
|
82337
82766
|
family: "device-events",
|