@camstack/addon-notifiers 1.2.620 → 1.2.622
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +19 -0
- package/dist/addon.js +861 -432
- package/dist/addon.mjs +861 -432
- package/package.json +13 -2
package/dist/addon.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -328,6 +328,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
328
328
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
329
329
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
330
330
|
/**
|
|
331
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
332
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
333
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
334
|
+
*/
|
|
335
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
336
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
337
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
338
|
+
/**
|
|
331
339
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
332
340
|
* (a settings change via `setAgentInferenceDevices` /
|
|
333
341
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5570,7 +5578,7 @@ var ZodIssueCode = {
|
|
|
5570
5578
|
var ZodFirstPartyTypeKind;
|
|
5571
5579
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5572
5580
|
//#endregion
|
|
5573
|
-
//#region ../types/dist/sleep-
|
|
5581
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5574
5582
|
/**
|
|
5575
5583
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5576
5584
|
* window to float samples (D455).
|
|
@@ -8270,6 +8278,99 @@ function defineRecordKinds(specs) {
|
|
|
8270
8278
|
}
|
|
8271
8279
|
return out;
|
|
8272
8280
|
}
|
|
8281
|
+
var READING_QUANTITIES = [
|
|
8282
|
+
"temperature",
|
|
8283
|
+
"pressure",
|
|
8284
|
+
"speed",
|
|
8285
|
+
"precipitation",
|
|
8286
|
+
"precipitation-rate",
|
|
8287
|
+
"length",
|
|
8288
|
+
"area",
|
|
8289
|
+
"illuminance",
|
|
8290
|
+
"irradiance",
|
|
8291
|
+
"power",
|
|
8292
|
+
"energy",
|
|
8293
|
+
"voltage",
|
|
8294
|
+
"current",
|
|
8295
|
+
"apparent-power",
|
|
8296
|
+
"humidity",
|
|
8297
|
+
"percentage",
|
|
8298
|
+
"concentration-volume",
|
|
8299
|
+
"concentration-mass",
|
|
8300
|
+
"concentration-ppb",
|
|
8301
|
+
"volume",
|
|
8302
|
+
"duration",
|
|
8303
|
+
"duration-ms",
|
|
8304
|
+
"information",
|
|
8305
|
+
"sound-level",
|
|
8306
|
+
"signal-level",
|
|
8307
|
+
"colour-temperature",
|
|
8308
|
+
"angle",
|
|
8309
|
+
"bitrate",
|
|
8310
|
+
"rate",
|
|
8311
|
+
"mass",
|
|
8312
|
+
"index",
|
|
8313
|
+
"ratio",
|
|
8314
|
+
"count",
|
|
8315
|
+
"none",
|
|
8316
|
+
"device"
|
|
8317
|
+
];
|
|
8318
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8319
|
+
new Set(READING_QUANTITIES);
|
|
8320
|
+
/**
|
|
8321
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8322
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8323
|
+
*/
|
|
8324
|
+
var QUANTITY_BASE = {
|
|
8325
|
+
temperature: "°C",
|
|
8326
|
+
pressure: "hPa",
|
|
8327
|
+
speed: "m/s",
|
|
8328
|
+
precipitation: "mm",
|
|
8329
|
+
"precipitation-rate": "mm/h",
|
|
8330
|
+
length: "m",
|
|
8331
|
+
area: "m²",
|
|
8332
|
+
illuminance: "lx",
|
|
8333
|
+
irradiance: "W/m²",
|
|
8334
|
+
power: "W",
|
|
8335
|
+
energy: "kWh",
|
|
8336
|
+
voltage: "V",
|
|
8337
|
+
current: "A",
|
|
8338
|
+
"apparent-power": "VA",
|
|
8339
|
+
humidity: "%",
|
|
8340
|
+
percentage: "%",
|
|
8341
|
+
"concentration-volume": "ppm",
|
|
8342
|
+
"concentration-mass": "µg/m³",
|
|
8343
|
+
"concentration-ppb": "ppb",
|
|
8344
|
+
volume: "L",
|
|
8345
|
+
duration: "s",
|
|
8346
|
+
"duration-ms": "ms",
|
|
8347
|
+
information: "B",
|
|
8348
|
+
"sound-level": "dBFS",
|
|
8349
|
+
"signal-level": "dBm",
|
|
8350
|
+
"colour-temperature": "mired",
|
|
8351
|
+
angle: "°",
|
|
8352
|
+
bitrate: "kbps",
|
|
8353
|
+
rate: "fps",
|
|
8354
|
+
mass: "kg",
|
|
8355
|
+
index: "none",
|
|
8356
|
+
ratio: "none",
|
|
8357
|
+
count: "none",
|
|
8358
|
+
none: "none",
|
|
8359
|
+
device: "device"
|
|
8360
|
+
};
|
|
8361
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8362
|
+
function baseUnitOf(quantity) {
|
|
8363
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8364
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8365
|
+
return symbol;
|
|
8366
|
+
}
|
|
8367
|
+
function readingMeta(quantity, extras) {
|
|
8368
|
+
return {
|
|
8369
|
+
quantity,
|
|
8370
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8371
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8372
|
+
};
|
|
8373
|
+
}
|
|
8273
8374
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8274
8375
|
var CamProfileSchema = _enum([
|
|
8275
8376
|
"high",
|
|
@@ -8297,8 +8398,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8297
8398
|
"derived"
|
|
8298
8399
|
]);
|
|
8299
8400
|
var CamStreamResolutionSchema = object({
|
|
8300
|
-
width: number().int().positive(),
|
|
8301
|
-
height: number().int().positive()
|
|
8401
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8402
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8302
8403
|
});
|
|
8303
8404
|
var CameraStreamSchema = object({
|
|
8304
8405
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8834,6 +8935,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8834
8935
|
"filesystem-browse",
|
|
8835
8936
|
"flood",
|
|
8836
8937
|
"gas",
|
|
8938
|
+
"group-commands",
|
|
8939
|
+
"group-status",
|
|
8837
8940
|
"heating-valve",
|
|
8838
8941
|
"humidifier",
|
|
8839
8942
|
"humidity-sensor",
|
|
@@ -8963,14 +9066,6 @@ Object.freeze({
|
|
|
8963
9066
|
{
|
|
8964
9067
|
"path": "aqi",
|
|
8965
9068
|
"valueType": "number"
|
|
8966
|
-
},
|
|
8967
|
-
{
|
|
8968
|
-
"path": "unit",
|
|
8969
|
-
"valueType": "string"
|
|
8970
|
-
},
|
|
8971
|
-
{
|
|
8972
|
-
"path": "precision",
|
|
8973
|
-
"valueType": "number"
|
|
8974
9069
|
}
|
|
8975
9070
|
],
|
|
8976
9071
|
"alarm-panel": [
|
|
@@ -9006,20 +9101,10 @@ Object.freeze({
|
|
|
9006
9101
|
"valueType": "boolean"
|
|
9007
9102
|
}
|
|
9008
9103
|
],
|
|
9009
|
-
"ambient-light-sensor": [
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
},
|
|
9014
|
-
{
|
|
9015
|
-
"path": "unit",
|
|
9016
|
-
"valueType": "string"
|
|
9017
|
-
},
|
|
9018
|
-
{
|
|
9019
|
-
"path": "precision",
|
|
9020
|
-
"valueType": "number"
|
|
9021
|
-
}
|
|
9022
|
-
],
|
|
9104
|
+
"ambient-light-sensor": [{
|
|
9105
|
+
"path": "lux",
|
|
9106
|
+
"valueType": "number"
|
|
9107
|
+
}],
|
|
9023
9108
|
"audio-metrics": [
|
|
9024
9109
|
{
|
|
9025
9110
|
"path": "ts",
|
|
@@ -9099,6 +9184,10 @@ Object.freeze({
|
|
|
9099
9184
|
"path": "lastUpdated",
|
|
9100
9185
|
"valueType": "number"
|
|
9101
9186
|
},
|
|
9187
|
+
{
|
|
9188
|
+
"path": "volts",
|
|
9189
|
+
"valueType": "number"
|
|
9190
|
+
},
|
|
9102
9191
|
{
|
|
9103
9192
|
"path": "lastContactAt",
|
|
9104
9193
|
"valueType": "number"
|
|
@@ -9341,10 +9430,6 @@ Object.freeze({
|
|
|
9341
9430
|
"datetime"
|
|
9342
9431
|
]
|
|
9343
9432
|
},
|
|
9344
|
-
{
|
|
9345
|
-
"path": "unit",
|
|
9346
|
-
"valueType": "string"
|
|
9347
|
-
},
|
|
9348
9433
|
{
|
|
9349
9434
|
"path": "min",
|
|
9350
9435
|
"valueType": "number"
|
|
@@ -9356,19 +9441,6 @@ Object.freeze({
|
|
|
9356
9441
|
{
|
|
9357
9442
|
"path": "step",
|
|
9358
9443
|
"valueType": "number"
|
|
9359
|
-
},
|
|
9360
|
-
{
|
|
9361
|
-
"path": "precision",
|
|
9362
|
-
"valueType": "number"
|
|
9363
|
-
},
|
|
9364
|
-
{
|
|
9365
|
-
"path": "format",
|
|
9366
|
-
"valueType": "enum",
|
|
9367
|
-
"enumValues": [
|
|
9368
|
-
"date",
|
|
9369
|
-
"time",
|
|
9370
|
-
"datetime"
|
|
9371
|
-
]
|
|
9372
9444
|
}
|
|
9373
9445
|
],
|
|
9374
9446
|
"cover": [
|
|
@@ -9609,13 +9681,8 @@ Object.freeze({
|
|
|
9609
9681
|
"path": "value",
|
|
9610
9682
|
"valueType": "string"
|
|
9611
9683
|
}, {
|
|
9612
|
-
"path": "
|
|
9613
|
-
"valueType": "
|
|
9614
|
-
"enumValues": [
|
|
9615
|
-
"date",
|
|
9616
|
-
"time",
|
|
9617
|
-
"datetime"
|
|
9618
|
-
]
|
|
9684
|
+
"path": "timestamp",
|
|
9685
|
+
"valueType": "boolean"
|
|
9619
9686
|
}],
|
|
9620
9687
|
"event-emitter": [
|
|
9621
9688
|
{
|
|
@@ -9688,6 +9755,20 @@ Object.freeze({
|
|
|
9688
9755
|
"path": "detected",
|
|
9689
9756
|
"valueType": "boolean"
|
|
9690
9757
|
}],
|
|
9758
|
+
"group-status": [
|
|
9759
|
+
{
|
|
9760
|
+
"path": "included",
|
|
9761
|
+
"valueType": "number"
|
|
9762
|
+
},
|
|
9763
|
+
{
|
|
9764
|
+
"path": "excluded",
|
|
9765
|
+
"valueType": "number"
|
|
9766
|
+
},
|
|
9767
|
+
{
|
|
9768
|
+
"path": "total",
|
|
9769
|
+
"valueType": "number"
|
|
9770
|
+
}
|
|
9771
|
+
],
|
|
9691
9772
|
"heating-valve": [{
|
|
9692
9773
|
"path": "position",
|
|
9693
9774
|
"valueType": "number"
|
|
@@ -9722,20 +9803,10 @@ Object.freeze({
|
|
|
9722
9803
|
"valueType": "number"
|
|
9723
9804
|
}
|
|
9724
9805
|
],
|
|
9725
|
-
"humidity-sensor": [
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
},
|
|
9730
|
-
{
|
|
9731
|
-
"path": "unit",
|
|
9732
|
-
"valueType": "string"
|
|
9733
|
-
},
|
|
9734
|
-
{
|
|
9735
|
-
"path": "precision",
|
|
9736
|
-
"valueType": "number"
|
|
9737
|
-
}
|
|
9738
|
-
],
|
|
9806
|
+
"humidity-sensor": [{
|
|
9807
|
+
"path": "percent",
|
|
9808
|
+
"valueType": "number"
|
|
9809
|
+
}],
|
|
9739
9810
|
"image": [{
|
|
9740
9811
|
"path": "url",
|
|
9741
9812
|
"valueType": "string"
|
|
@@ -10074,20 +10145,10 @@ Object.freeze({
|
|
|
10074
10145
|
"valueType": "boolean"
|
|
10075
10146
|
}
|
|
10076
10147
|
],
|
|
10077
|
-
"numeric-sensor": [
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
},
|
|
10082
|
-
{
|
|
10083
|
-
"path": "unit",
|
|
10084
|
-
"valueType": "string"
|
|
10085
|
-
},
|
|
10086
|
-
{
|
|
10087
|
-
"path": "precision",
|
|
10088
|
-
"valueType": "number"
|
|
10089
|
-
}
|
|
10090
|
-
],
|
|
10148
|
+
"numeric-sensor": [{
|
|
10149
|
+
"path": "value",
|
|
10150
|
+
"valueType": "number"
|
|
10151
|
+
}],
|
|
10091
10152
|
"pet-feeder": [
|
|
10092
10153
|
{
|
|
10093
10154
|
"path": "foodLevel",
|
|
@@ -10179,14 +10240,6 @@ Object.freeze({
|
|
|
10179
10240
|
{
|
|
10180
10241
|
"path": "powerFactor",
|
|
10181
10242
|
"valueType": "number"
|
|
10182
|
-
},
|
|
10183
|
-
{
|
|
10184
|
-
"path": "unit",
|
|
10185
|
-
"valueType": "string"
|
|
10186
|
-
},
|
|
10187
|
-
{
|
|
10188
|
-
"path": "precision",
|
|
10189
|
-
"valueType": "number"
|
|
10190
10243
|
}
|
|
10191
10244
|
],
|
|
10192
10245
|
"presence": [
|
|
@@ -10215,20 +10268,10 @@ Object.freeze({
|
|
|
10215
10268
|
"valueType": "number"
|
|
10216
10269
|
}
|
|
10217
10270
|
],
|
|
10218
|
-
"pressure-sensor": [
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
},
|
|
10223
|
-
{
|
|
10224
|
-
"path": "unit",
|
|
10225
|
-
"valueType": "string"
|
|
10226
|
-
},
|
|
10227
|
-
{
|
|
10228
|
-
"path": "precision",
|
|
10229
|
-
"valueType": "number"
|
|
10230
|
-
}
|
|
10231
|
-
],
|
|
10271
|
+
"pressure-sensor": [{
|
|
10272
|
+
"path": "hpa",
|
|
10273
|
+
"valueType": "number"
|
|
10274
|
+
}],
|
|
10232
10275
|
"privacy-mask": [{
|
|
10233
10276
|
"path": "enabled",
|
|
10234
10277
|
"valueType": "boolean"
|
|
@@ -10539,20 +10582,10 @@ Object.freeze({
|
|
|
10539
10582
|
"path": "tampered",
|
|
10540
10583
|
"valueType": "boolean"
|
|
10541
10584
|
}],
|
|
10542
|
-
"temperature-sensor": [
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
},
|
|
10547
|
-
{
|
|
10548
|
-
"path": "unit",
|
|
10549
|
-
"valueType": "string"
|
|
10550
|
-
},
|
|
10551
|
-
{
|
|
10552
|
-
"path": "precision",
|
|
10553
|
-
"valueType": "number"
|
|
10554
|
-
}
|
|
10555
|
-
],
|
|
10585
|
+
"temperature-sensor": [{
|
|
10586
|
+
"path": "celsius",
|
|
10587
|
+
"valueType": "number"
|
|
10588
|
+
}],
|
|
10556
10589
|
"update": [
|
|
10557
10590
|
{
|
|
10558
10591
|
"path": "currentVersion",
|
|
@@ -10663,10 +10696,6 @@ Object.freeze({
|
|
|
10663
10696
|
"path": "temperature",
|
|
10664
10697
|
"valueType": "number"
|
|
10665
10698
|
},
|
|
10666
|
-
{
|
|
10667
|
-
"path": "temperatureUnit",
|
|
10668
|
-
"valueType": "string"
|
|
10669
|
-
},
|
|
10670
10699
|
{
|
|
10671
10700
|
"path": "humidity",
|
|
10672
10701
|
"valueType": "number"
|
|
@@ -10675,18 +10704,10 @@ Object.freeze({
|
|
|
10675
10704
|
"path": "pressure",
|
|
10676
10705
|
"valueType": "number"
|
|
10677
10706
|
},
|
|
10678
|
-
{
|
|
10679
|
-
"path": "pressureUnit",
|
|
10680
|
-
"valueType": "string"
|
|
10681
|
-
},
|
|
10682
10707
|
{
|
|
10683
10708
|
"path": "windSpeed",
|
|
10684
10709
|
"valueType": "number"
|
|
10685
10710
|
},
|
|
10686
|
-
{
|
|
10687
|
-
"path": "windSpeedUnit",
|
|
10688
|
-
"valueType": "string"
|
|
10689
|
-
},
|
|
10690
10711
|
{
|
|
10691
10712
|
"path": "windBearing",
|
|
10692
10713
|
"valueType": "number"
|
|
@@ -11093,7 +11114,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11093
11114
|
return DeviceRole;
|
|
11094
11115
|
}({});
|
|
11095
11116
|
//#endregion
|
|
11096
|
-
//#region ../types/dist/composition-
|
|
11117
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11097
11118
|
/**
|
|
11098
11119
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11099
11120
|
*
|
|
@@ -11848,15 +11869,74 @@ function validateExpressionSource(src) {
|
|
|
11848
11869
|
}
|
|
11849
11870
|
return null;
|
|
11850
11871
|
}
|
|
11851
|
-
/**
|
|
11852
|
-
|
|
11853
|
-
|
|
11854
|
-
|
|
11872
|
+
/**
|
|
11873
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11874
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11875
|
+
* `composition.ts` (D659).
|
|
11876
|
+
*/
|
|
11855
11877
|
var CompositionSourceRefSchema = object({
|
|
11856
11878
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11857
11879
|
addonId: string().min(1),
|
|
11858
11880
|
stableId: string().min(1)
|
|
11859
11881
|
});
|
|
11882
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11883
|
+
"temperature",
|
|
11884
|
+
"humidity",
|
|
11885
|
+
"pressure",
|
|
11886
|
+
"illuminance",
|
|
11887
|
+
"power",
|
|
11888
|
+
"energy",
|
|
11889
|
+
"battery",
|
|
11890
|
+
"numeric",
|
|
11891
|
+
"motion",
|
|
11892
|
+
"contact",
|
|
11893
|
+
"leak",
|
|
11894
|
+
"smoke",
|
|
11895
|
+
"occupancy",
|
|
11896
|
+
"binary",
|
|
11897
|
+
"switch",
|
|
11898
|
+
"light"
|
|
11899
|
+
];
|
|
11900
|
+
var NUMERIC_AGGREGATES = [
|
|
11901
|
+
"mean",
|
|
11902
|
+
"median",
|
|
11903
|
+
"min",
|
|
11904
|
+
"max",
|
|
11905
|
+
"sum"
|
|
11906
|
+
];
|
|
11907
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11908
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11909
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11910
|
+
var AGGREGATE_REDUCERS = [
|
|
11911
|
+
"mean",
|
|
11912
|
+
"median",
|
|
11913
|
+
"min",
|
|
11914
|
+
"max",
|
|
11915
|
+
"sum",
|
|
11916
|
+
"any",
|
|
11917
|
+
"all"
|
|
11918
|
+
];
|
|
11919
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11920
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11921
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11922
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11923
|
+
var HelperMemberSchema = object({
|
|
11924
|
+
source: CompositionSourceRefSchema,
|
|
11925
|
+
cap: string().min(1),
|
|
11926
|
+
fieldPath: string().min(1)
|
|
11927
|
+
});
|
|
11928
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11929
|
+
kind: literal("group"),
|
|
11930
|
+
templateId: GroupTemplateIdSchema,
|
|
11931
|
+
aggregate: AggregateReducerSchema,
|
|
11932
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11933
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11934
|
+
active: ActiveCriterionSchema.optional()
|
|
11935
|
+
})]);
|
|
11936
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11937
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11938
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11939
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11860
11940
|
/** One field of one capability of one source device. */
|
|
11861
11941
|
var CompositionFieldReadSchema = object({
|
|
11862
11942
|
source: CompositionSourceRefSchema,
|
|
@@ -11900,7 +11980,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11900
11980
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11901
11981
|
CompositionFromSourceSchema,
|
|
11902
11982
|
CompositionExpressionSourceSchema,
|
|
11903
|
-
CompositionCodeSourceSchema
|
|
11983
|
+
CompositionCodeSourceSchema,
|
|
11984
|
+
object({
|
|
11985
|
+
kind: literal("aggregate"),
|
|
11986
|
+
reducer: _enum([
|
|
11987
|
+
"mean",
|
|
11988
|
+
"median",
|
|
11989
|
+
"min",
|
|
11990
|
+
"max",
|
|
11991
|
+
"sum",
|
|
11992
|
+
"any",
|
|
11993
|
+
"all"
|
|
11994
|
+
]),
|
|
11995
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11996
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11997
|
+
publish: _enum([
|
|
11998
|
+
"value",
|
|
11999
|
+
"included",
|
|
12000
|
+
"excluded",
|
|
12001
|
+
"total"
|
|
12002
|
+
]),
|
|
12003
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12004
|
+
empty: _enum([
|
|
12005
|
+
"null",
|
|
12006
|
+
"omit",
|
|
12007
|
+
"offline"
|
|
12008
|
+
])
|
|
12009
|
+
})
|
|
11904
12010
|
]);
|
|
11905
12011
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11906
12012
|
kind: literal("forward"),
|
|
@@ -11946,7 +12052,13 @@ var CompositionSchema = object({
|
|
|
11946
12052
|
kind: literal("existing"),
|
|
11947
12053
|
device: CompositionSourceRefSchema
|
|
11948
12054
|
})]),
|
|
11949
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12055
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12056
|
+
/**
|
|
12057
|
+
* Present when the block is a helper template. Absent on a free
|
|
12058
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12059
|
+
* never the compiled features.
|
|
12060
|
+
*/
|
|
12061
|
+
helper: HelperSpecSchema.optional()
|
|
11950
12062
|
}).superRefine((composition, ctx) => {
|
|
11951
12063
|
const seen = /* @__PURE__ */ new Set();
|
|
11952
12064
|
composition.features.forEach((feature, index) => {
|
|
@@ -18184,7 +18296,11 @@ var CompositionProblemSchema = object({
|
|
|
18184
18296
|
"item-field-reserved",
|
|
18185
18297
|
"target-missing",
|
|
18186
18298
|
"target-unreadable",
|
|
18187
|
-
"not-replaceable"
|
|
18299
|
+
"not-replaceable",
|
|
18300
|
+
"native-capability-replace",
|
|
18301
|
+
"mixed-quantity",
|
|
18302
|
+
"helper-mismatch",
|
|
18303
|
+
"member-constraint"
|
|
18188
18304
|
]),
|
|
18189
18305
|
path: string(),
|
|
18190
18306
|
message: string()
|
|
@@ -18205,7 +18321,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18205
18321
|
"null",
|
|
18206
18322
|
"offline",
|
|
18207
18323
|
"unknown",
|
|
18208
|
-
"release"
|
|
18324
|
+
"release",
|
|
18325
|
+
"omit"
|
|
18209
18326
|
]);
|
|
18210
18327
|
/**
|
|
18211
18328
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18242,9 +18359,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18242
18359
|
reads: array(CompositionFieldReadSchema)
|
|
18243
18360
|
});
|
|
18244
18361
|
/**
|
|
18245
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18246
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18247
|
-
*
|
|
18362
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18363
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18364
|
+
* Replacing a capability the device already serves is refused
|
|
18365
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18366
|
+
* wire for a claim the hub already holds.
|
|
18248
18367
|
*/
|
|
18249
18368
|
var CompositionFeatureModeSchema = _enum([
|
|
18250
18369
|
"new",
|
|
@@ -18417,6 +18536,275 @@ Object.freeze({
|
|
|
18417
18536
|
result: ["number", "null"]
|
|
18418
18537
|
}
|
|
18419
18538
|
});
|
|
18539
|
+
/**
|
|
18540
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18541
|
+
* Data, not a form default written into the block.
|
|
18542
|
+
*/
|
|
18543
|
+
var NOW = {
|
|
18544
|
+
fieldPath: "lastFetchedAt",
|
|
18545
|
+
expr: "now"
|
|
18546
|
+
};
|
|
18547
|
+
var CHANGED = {
|
|
18548
|
+
fieldPath: "lastChangedAt",
|
|
18549
|
+
expr: "now"
|
|
18550
|
+
};
|
|
18551
|
+
function numeric(input) {
|
|
18552
|
+
return {
|
|
18553
|
+
...input,
|
|
18554
|
+
family: "numeric",
|
|
18555
|
+
deviceType: DeviceType.Sensor,
|
|
18556
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18557
|
+
commandCaps: [],
|
|
18558
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18559
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18560
|
+
accept: [{
|
|
18561
|
+
cap: input.outputCap,
|
|
18562
|
+
fieldPath: input.outputField
|
|
18563
|
+
}]
|
|
18564
|
+
};
|
|
18565
|
+
}
|
|
18566
|
+
function binary(input) {
|
|
18567
|
+
return {
|
|
18568
|
+
...input,
|
|
18569
|
+
family: "binary",
|
|
18570
|
+
deviceType: DeviceType.Sensor,
|
|
18571
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18572
|
+
commandCaps: [],
|
|
18573
|
+
quantity: "none",
|
|
18574
|
+
baseUnit: void 0,
|
|
18575
|
+
aggregates: BINARY_AGGREGATES,
|
|
18576
|
+
empty: "offline"
|
|
18577
|
+
};
|
|
18578
|
+
}
|
|
18579
|
+
var GROUP_TEMPLATES = [
|
|
18580
|
+
numeric({
|
|
18581
|
+
id: "temperature",
|
|
18582
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18583
|
+
role: DeviceRole.TemperatureSensor,
|
|
18584
|
+
outputCap: "temperature-sensor",
|
|
18585
|
+
outputField: "celsius",
|
|
18586
|
+
quantity: "temperature",
|
|
18587
|
+
defaultAggregate: "mean",
|
|
18588
|
+
empty: "null",
|
|
18589
|
+
companions: [NOW]
|
|
18590
|
+
}),
|
|
18591
|
+
numeric({
|
|
18592
|
+
id: "humidity",
|
|
18593
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18594
|
+
role: DeviceRole.HumiditySensor,
|
|
18595
|
+
outputCap: "humidity-sensor",
|
|
18596
|
+
outputField: "percent",
|
|
18597
|
+
quantity: "humidity",
|
|
18598
|
+
defaultAggregate: "mean",
|
|
18599
|
+
empty: "null",
|
|
18600
|
+
companions: [NOW]
|
|
18601
|
+
}),
|
|
18602
|
+
numeric({
|
|
18603
|
+
id: "pressure",
|
|
18604
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18605
|
+
role: DeviceRole.PressureSensor,
|
|
18606
|
+
outputCap: "pressure-sensor",
|
|
18607
|
+
outputField: "hpa",
|
|
18608
|
+
quantity: "pressure",
|
|
18609
|
+
defaultAggregate: "mean",
|
|
18610
|
+
empty: "null",
|
|
18611
|
+
companions: [NOW]
|
|
18612
|
+
}),
|
|
18613
|
+
numeric({
|
|
18614
|
+
id: "illuminance",
|
|
18615
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18616
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18617
|
+
outputCap: "ambient-light-sensor",
|
|
18618
|
+
outputField: "lux",
|
|
18619
|
+
quantity: "illuminance",
|
|
18620
|
+
defaultAggregate: "mean",
|
|
18621
|
+
empty: "null",
|
|
18622
|
+
companions: [NOW]
|
|
18623
|
+
}),
|
|
18624
|
+
numeric({
|
|
18625
|
+
id: "power",
|
|
18626
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18627
|
+
role: DeviceRole.PowerSensor,
|
|
18628
|
+
outputCap: "power-meter",
|
|
18629
|
+
outputField: "watts",
|
|
18630
|
+
quantity: "power",
|
|
18631
|
+
defaultAggregate: "sum",
|
|
18632
|
+
empty: "omit",
|
|
18633
|
+
companions: [NOW]
|
|
18634
|
+
}),
|
|
18635
|
+
numeric({
|
|
18636
|
+
id: "energy",
|
|
18637
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18638
|
+
role: DeviceRole.EnergySensor,
|
|
18639
|
+
outputCap: "power-meter",
|
|
18640
|
+
outputField: "kwhTotal",
|
|
18641
|
+
quantity: "energy",
|
|
18642
|
+
defaultAggregate: "sum",
|
|
18643
|
+
empty: "omit",
|
|
18644
|
+
companions: [NOW]
|
|
18645
|
+
}),
|
|
18646
|
+
numeric({
|
|
18647
|
+
id: "battery",
|
|
18648
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18649
|
+
role: DeviceRole.BatterySensor,
|
|
18650
|
+
outputCap: "battery",
|
|
18651
|
+
outputField: "percentage",
|
|
18652
|
+
quantity: "percentage",
|
|
18653
|
+
defaultAggregate: "mean",
|
|
18654
|
+
empty: "null",
|
|
18655
|
+
companions: [
|
|
18656
|
+
{
|
|
18657
|
+
fieldPath: "charging",
|
|
18658
|
+
expr: "\"unknown\""
|
|
18659
|
+
},
|
|
18660
|
+
{
|
|
18661
|
+
fieldPath: "sleeping",
|
|
18662
|
+
expr: "false"
|
|
18663
|
+
},
|
|
18664
|
+
{
|
|
18665
|
+
fieldPath: "lastUpdated",
|
|
18666
|
+
expr: "now"
|
|
18667
|
+
}
|
|
18668
|
+
]
|
|
18669
|
+
}),
|
|
18670
|
+
numeric({
|
|
18671
|
+
id: "numeric",
|
|
18672
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18673
|
+
role: DeviceRole.NumericSensor,
|
|
18674
|
+
outputCap: "numeric-sensor",
|
|
18675
|
+
outputField: "value",
|
|
18676
|
+
quantity: "device",
|
|
18677
|
+
defaultAggregate: "mean",
|
|
18678
|
+
empty: "null",
|
|
18679
|
+
companions: [NOW]
|
|
18680
|
+
}),
|
|
18681
|
+
binary({
|
|
18682
|
+
id: "motion",
|
|
18683
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18684
|
+
role: DeviceRole.MotionSensor,
|
|
18685
|
+
outputCap: "motion",
|
|
18686
|
+
outputField: "detected",
|
|
18687
|
+
defaultAggregate: "any",
|
|
18688
|
+
accept: [{
|
|
18689
|
+
cap: "motion",
|
|
18690
|
+
fieldPath: "detected"
|
|
18691
|
+
}],
|
|
18692
|
+
companions: [{
|
|
18693
|
+
fieldPath: "lastDetectedAt",
|
|
18694
|
+
expr: "null"
|
|
18695
|
+
}, {
|
|
18696
|
+
fieldPath: "autoClearAfterMs",
|
|
18697
|
+
expr: "null"
|
|
18698
|
+
}]
|
|
18699
|
+
}),
|
|
18700
|
+
binary({
|
|
18701
|
+
id: "contact",
|
|
18702
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18703
|
+
role: DeviceRole.ContactSensor,
|
|
18704
|
+
outputCap: "contact",
|
|
18705
|
+
outputField: "entryOpen",
|
|
18706
|
+
defaultAggregate: "any",
|
|
18707
|
+
accept: [{
|
|
18708
|
+
cap: "contact",
|
|
18709
|
+
fieldPath: "entryOpen"
|
|
18710
|
+
}],
|
|
18711
|
+
companions: [CHANGED]
|
|
18712
|
+
}),
|
|
18713
|
+
binary({
|
|
18714
|
+
id: "leak",
|
|
18715
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18716
|
+
role: DeviceRole.LeakSensor,
|
|
18717
|
+
outputCap: "flood",
|
|
18718
|
+
outputField: "flooded",
|
|
18719
|
+
defaultAggregate: "any",
|
|
18720
|
+
accept: [{
|
|
18721
|
+
cap: "flood",
|
|
18722
|
+
fieldPath: "flooded"
|
|
18723
|
+
}],
|
|
18724
|
+
companions: [CHANGED]
|
|
18725
|
+
}),
|
|
18726
|
+
binary({
|
|
18727
|
+
id: "smoke",
|
|
18728
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18729
|
+
role: DeviceRole.SmokeSensor,
|
|
18730
|
+
outputCap: "smoke",
|
|
18731
|
+
outputField: "detected",
|
|
18732
|
+
defaultAggregate: "any",
|
|
18733
|
+
accept: [{
|
|
18734
|
+
cap: "smoke",
|
|
18735
|
+
fieldPath: "detected"
|
|
18736
|
+
}],
|
|
18737
|
+
companions: [CHANGED]
|
|
18738
|
+
}),
|
|
18739
|
+
binary({
|
|
18740
|
+
id: "occupancy",
|
|
18741
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18742
|
+
role: DeviceRole.BinarySensor,
|
|
18743
|
+
outputCap: "binary",
|
|
18744
|
+
outputField: "on",
|
|
18745
|
+
defaultAggregate: "any",
|
|
18746
|
+
accept: [{
|
|
18747
|
+
cap: "motion",
|
|
18748
|
+
fieldPath: "detected"
|
|
18749
|
+
}, {
|
|
18750
|
+
cap: "binary",
|
|
18751
|
+
fieldPath: "on"
|
|
18752
|
+
}],
|
|
18753
|
+
companions: [CHANGED]
|
|
18754
|
+
}),
|
|
18755
|
+
binary({
|
|
18756
|
+
id: "binary",
|
|
18757
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18758
|
+
role: DeviceRole.BinarySensor,
|
|
18759
|
+
outputCap: "binary",
|
|
18760
|
+
outputField: "on",
|
|
18761
|
+
defaultAggregate: "any",
|
|
18762
|
+
accept: [{
|
|
18763
|
+
cap: "binary",
|
|
18764
|
+
fieldPath: "on"
|
|
18765
|
+
}],
|
|
18766
|
+
companions: [CHANGED]
|
|
18767
|
+
}),
|
|
18768
|
+
actuator({
|
|
18769
|
+
id: "switch",
|
|
18770
|
+
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.",
|
|
18771
|
+
deviceType: DeviceType.Switch,
|
|
18772
|
+
outputCap: "switch",
|
|
18773
|
+
commandCaps: ["switch"]
|
|
18774
|
+
}),
|
|
18775
|
+
actuator({
|
|
18776
|
+
id: "light",
|
|
18777
|
+
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.",
|
|
18778
|
+
deviceType: DeviceType.Light,
|
|
18779
|
+
outputCap: "switch",
|
|
18780
|
+
commandCaps: [
|
|
18781
|
+
"switch",
|
|
18782
|
+
"brightness",
|
|
18783
|
+
"color"
|
|
18784
|
+
]
|
|
18785
|
+
})
|
|
18786
|
+
];
|
|
18787
|
+
function actuator(input) {
|
|
18788
|
+
return {
|
|
18789
|
+
...input,
|
|
18790
|
+
family: "actuator",
|
|
18791
|
+
role: void 0,
|
|
18792
|
+
memberDeviceType: input.deviceType,
|
|
18793
|
+
outputField: "on",
|
|
18794
|
+
quantity: "none",
|
|
18795
|
+
baseUnit: void 0,
|
|
18796
|
+
aggregates: BINARY_AGGREGATES,
|
|
18797
|
+
defaultAggregate: "any",
|
|
18798
|
+
empty: "offline",
|
|
18799
|
+
accept: [{
|
|
18800
|
+
cap: "switch",
|
|
18801
|
+
fieldPath: "on"
|
|
18802
|
+
}],
|
|
18803
|
+
companions: [CHANGED]
|
|
18804
|
+
};
|
|
18805
|
+
}
|
|
18806
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18807
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18420
18808
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18421
18809
|
/**
|
|
18422
18810
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20130,12 +20518,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20130
20518
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20131
20519
|
* in-place so dispatch keeps working.
|
|
20132
20520
|
*
|
|
20133
|
-
* **
|
|
20134
|
-
*
|
|
20135
|
-
*
|
|
20136
|
-
*
|
|
20137
|
-
* (`ha-domain-mapping`)
|
|
20138
|
-
* stored after that point.
|
|
20521
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20522
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20523
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20524
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20525
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20526
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20139
20527
|
*
|
|
20140
20528
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20141
20529
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20149,6 +20537,14 @@ var SourceInfoSchema = object({
|
|
|
20149
20537
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20150
20538
|
* Used to detect rename when `id` changes. */
|
|
20151
20539
|
uniqueId: string().optional(),
|
|
20540
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20541
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20542
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20543
|
+
dateTimeShape: _enum([
|
|
20544
|
+
"date",
|
|
20545
|
+
"time",
|
|
20546
|
+
"datetime"
|
|
20547
|
+
]).optional(),
|
|
20152
20548
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20153
20549
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20154
20550
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41061,7 +41457,8 @@ method(object({
|
|
|
41061
41457
|
"enum"
|
|
41062
41458
|
]),
|
|
41063
41459
|
enumValues: array(string()).optional(),
|
|
41064
|
-
item: boolean().optional()
|
|
41460
|
+
item: boolean().optional(),
|
|
41461
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41065
41462
|
})).readonly(),
|
|
41066
41463
|
itemArray: object({
|
|
41067
41464
|
path: string(),
|
|
@@ -44883,8 +45280,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44883
45280
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44884
45281
|
var MaskGridShapeSchema = object({
|
|
44885
45282
|
kind: literal("grid"),
|
|
44886
|
-
gridWidth: number(),
|
|
44887
|
-
gridHeight: number(),
|
|
45283
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45284
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44888
45285
|
cells: array(boolean())
|
|
44889
45286
|
});
|
|
44890
45287
|
discriminatedUnion("kind", [
|
|
@@ -44996,6 +45393,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44996
45393
|
"detection-blind",
|
|
44997
45394
|
"motion-noisy",
|
|
44998
45395
|
"motion-calm",
|
|
45396
|
+
"package-llm-silent",
|
|
45397
|
+
"package-llm-answered",
|
|
44999
45398
|
"recording-stalled",
|
|
45000
45399
|
"recording-healthy",
|
|
45001
45400
|
"recording-degraded",
|
|
@@ -56010,6 +56409,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56010
56409
|
deprecated: string().optional(),
|
|
56011
56410
|
distTags: array(string()).readonly()
|
|
56012
56411
|
});
|
|
56412
|
+
/**
|
|
56413
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56414
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56415
|
+
* tarball failure — never an empty string standing in for either.
|
|
56416
|
+
*/
|
|
56417
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56418
|
+
object({
|
|
56419
|
+
status: literal("ok"),
|
|
56420
|
+
markdown: string()
|
|
56421
|
+
}),
|
|
56422
|
+
object({ status: literal("missing") }),
|
|
56423
|
+
object({
|
|
56424
|
+
status: literal("error"),
|
|
56425
|
+
message: string()
|
|
56426
|
+
})
|
|
56427
|
+
]);
|
|
56428
|
+
var PackageDocsSchema = object({
|
|
56429
|
+
name: string(),
|
|
56430
|
+
version: string(),
|
|
56431
|
+
readme: PackageDocBodySchema,
|
|
56432
|
+
changelog: PackageDocBodySchema
|
|
56433
|
+
});
|
|
56013
56434
|
var SearchResultSchema = object({
|
|
56014
56435
|
name: string(),
|
|
56015
56436
|
version: string(),
|
|
@@ -56228,7 +56649,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56228
56649
|
}), object({ success: literal(true) }), {
|
|
56229
56650
|
kind: "mutation",
|
|
56230
56651
|
auth: "admin"
|
|
56231
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56652
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56653
|
+
name: string().min(1),
|
|
56654
|
+
version: string().min(1).optional()
|
|
56655
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56232
56656
|
kind: "mutation",
|
|
56233
56657
|
auth: "admin"
|
|
56234
56658
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56278,46 +56702,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56278
56702
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56279
56703
|
object({
|
|
56280
56704
|
/** Carbon dioxide concentration in ppm. */
|
|
56281
|
-
co2Ppm: number().min(0).optional(),
|
|
56705
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56282
56706
|
/** Total volatile organic compounds in ppb. */
|
|
56283
|
-
vocPpb: number().min(0).optional(),
|
|
56707
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56284
56708
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56285
|
-
pm25: number().min(0).optional(),
|
|
56709
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56286
56710
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56287
|
-
pm10: number().min(0).optional(),
|
|
56711
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56288
56712
|
/** Composite AQI value (typically 0..500). */
|
|
56289
|
-
aqi: number().optional(),
|
|
56713
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56290
56714
|
/** Ms epoch when the slice was last updated. */
|
|
56291
|
-
lastFetchedAt: number()
|
|
56292
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56293
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56294
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56295
|
-
* per slice is unambiguous. */
|
|
56296
|
-
unit: string().optional(),
|
|
56297
|
-
/** Suggested decimal places for numeric display.
|
|
56298
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56299
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56300
|
-
* auto-formatting when absent. */
|
|
56301
|
-
precision: number().int().min(0).max(10).optional()
|
|
56715
|
+
lastFetchedAt: number()
|
|
56302
56716
|
});
|
|
56303
56717
|
DeviceType.Sensor;
|
|
56304
56718
|
object({
|
|
56305
|
-
/** Current illuminance in lux (lx). */
|
|
56306
|
-
lux: number().min(0).meta({
|
|
56307
|
-
|
|
56719
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56720
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56721
|
+
precision: 0,
|
|
56308
56722
|
label: "Illuminance"
|
|
56309
|
-
}),
|
|
56723
|
+
})),
|
|
56310
56724
|
/** Ms epoch when the slice was last updated. */
|
|
56311
|
-
lastFetchedAt: number()
|
|
56312
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56313
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56314
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56315
|
-
unit: string().optional(),
|
|
56316
|
-
/** Suggested decimal places for numeric display.
|
|
56317
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56318
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56319
|
-
* auto-formatting when absent. */
|
|
56320
|
-
precision: number().int().min(0).max(10).optional()
|
|
56725
|
+
lastFetchedAt: number()
|
|
56321
56726
|
});
|
|
56322
56727
|
DeviceType.Sensor;
|
|
56323
56728
|
/**
|
|
@@ -56462,10 +56867,7 @@ var BatteryStatusSchema = object({
|
|
|
56462
56867
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56463
56868
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56464
56869
|
*/
|
|
56465
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56466
|
-
unit: "%",
|
|
56467
|
-
label: "Charge"
|
|
56468
|
-
}),
|
|
56870
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56469
56871
|
/**
|
|
56470
56872
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56471
56873
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56492,7 +56894,14 @@ var BatteryStatusSchema = object({
|
|
|
56492
56894
|
*/
|
|
56493
56895
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56494
56896
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56495
|
-
lastUpdated: number(),
|
|
56897
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56898
|
+
/**
|
|
56899
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56900
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56901
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56902
|
+
* `numeric-sensor` on the same device.
|
|
56903
|
+
*/
|
|
56904
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56496
56905
|
/**
|
|
56497
56906
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56498
56907
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56552,7 +56961,7 @@ object({
|
|
|
56552
56961
|
DeviceType.Sensor;
|
|
56553
56962
|
object({
|
|
56554
56963
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56555
|
-
percentage: number().min(0).max(100),
|
|
56964
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56556
56965
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56557
56966
|
lastChangedAt: number()
|
|
56558
56967
|
});
|
|
@@ -56937,21 +57346,21 @@ object({
|
|
|
56937
57346
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56938
57347
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56939
57348
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56940
|
-
target: number().nullable(),
|
|
57349
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56941
57350
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56942
57351
|
* in `heat_cool` mode. */
|
|
56943
|
-
targetHigh: number().nullable(),
|
|
57352
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56944
57353
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56945
57354
|
* in `heat_cool` mode. */
|
|
56946
|
-
targetLow: number().nullable(),
|
|
57355
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56947
57356
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56948
57357
|
* humidity control. */
|
|
56949
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57358
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56950
57359
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56951
57360
|
* the device's internal sensor. */
|
|
56952
|
-
currentTemp: number().nullable(),
|
|
57361
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56953
57362
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56954
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57363
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56955
57364
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56956
57365
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56957
57366
|
swingVertical: boolean().nullable(),
|
|
@@ -56959,11 +57368,11 @@ object({
|
|
|
56959
57368
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56960
57369
|
swingHorizontal: boolean().nullable(),
|
|
56961
57370
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56962
|
-
minTemp: number().nullable().optional(),
|
|
57371
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56963
57372
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56964
|
-
maxTemp: number().nullable().optional(),
|
|
57373
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56965
57374
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56966
|
-
tempStep: number().positive().nullable().optional(),
|
|
57375
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56967
57376
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56968
57377
|
lastFetchedAt: number()
|
|
56969
57378
|
});
|
|
@@ -57042,17 +57451,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
57042
57451
|
* modes to expose in the picker without a slice fetch.
|
|
57043
57452
|
*/
|
|
57044
57453
|
var RgbTripletSchema = object({
|
|
57045
|
-
r: number().int().min(0).max(255),
|
|
57046
|
-
g: number().int().min(0).max(255),
|
|
57047
|
-
b: number().int().min(0).max(255)
|
|
57454
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57455
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57456
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57048
57457
|
});
|
|
57049
57458
|
var HsvTripletSchema = object({
|
|
57050
57459
|
/** Hue in degrees, 0..360. */
|
|
57051
|
-
h: number().min(0).max(360),
|
|
57460
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57052
57461
|
/** Saturation as 0..100 inclusive. */
|
|
57053
|
-
s: number().min(0).max(100),
|
|
57462
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57054
57463
|
/** Value/brightness as 0..100 inclusive. */
|
|
57055
|
-
v: number().min(0).max(100)
|
|
57464
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57056
57465
|
});
|
|
57057
57466
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57058
57467
|
object({
|
|
@@ -57081,7 +57490,7 @@ object({
|
|
|
57081
57490
|
/** Populated when `mode === 'hsv'`. */
|
|
57082
57491
|
hsv: HsvTripletSchema.optional(),
|
|
57083
57492
|
/** Populated when `mode === 'mired'`. */
|
|
57084
|
-
mireds: number().int().optional(),
|
|
57493
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57085
57494
|
/** Ms epoch of the last operator-driven change. */
|
|
57086
57495
|
lastChangedAt: number()
|
|
57087
57496
|
});
|
|
@@ -57205,18 +57614,12 @@ _enum([
|
|
|
57205
57614
|
"empty",
|
|
57206
57615
|
"full"
|
|
57207
57616
|
]);
|
|
57208
|
-
/**
|
|
57209
|
-
|
|
57210
|
-
|
|
57211
|
-
"days",
|
|
57212
|
-
"hours",
|
|
57213
|
-
"cycles"
|
|
57214
|
-
]);
|
|
57215
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57216
|
-
* days). `value` null = unknown (D393). */
|
|
57617
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57618
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57619
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57217
57620
|
var ConsumableRemainingSchema = object({
|
|
57218
|
-
value: number().min(0).nullable(),
|
|
57219
|
-
|
|
57621
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57622
|
+
kind: ConsumableRemainingKindSchema
|
|
57220
57623
|
});
|
|
57221
57624
|
var ConsumablesStatusSchema = object({
|
|
57222
57625
|
items: array(object({
|
|
@@ -57225,7 +57628,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57225
57628
|
/** Display name. */
|
|
57226
57629
|
label: string().min(1),
|
|
57227
57630
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57228
|
-
level: number().min(0).max(100).nullable(),
|
|
57631
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57229
57632
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57230
57633
|
status: ConsumableStatusSchema.nullable(),
|
|
57231
57634
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57242,7 +57645,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57242
57645
|
})),
|
|
57243
57646
|
lastChangedAt: number()
|
|
57244
57647
|
});
|
|
57245
|
-
Object.values(DeviceType), [...
|
|
57648
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57246
57649
|
Object.values(DeviceType), method(object({
|
|
57247
57650
|
deviceId: number().int().nonnegative(),
|
|
57248
57651
|
key: string().min(1)
|
|
@@ -57267,39 +57670,17 @@ object({
|
|
|
57267
57670
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57268
57671
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57269
57672
|
* or time-only — HA accepts all three forms). */
|
|
57270
|
-
value: union([number(), string()]),
|
|
57673
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57271
57674
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57272
57675
|
options: array(string()),
|
|
57273
57676
|
/** Ms epoch when the slice was last updated. */
|
|
57274
57677
|
lastChangedAt: number(),
|
|
57275
|
-
/**
|
|
57276
|
-
|
|
57277
|
-
|
|
57278
|
-
|
|
57279
|
-
/**
|
|
57280
|
-
|
|
57281
|
-
min: number().optional(),
|
|
57282
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57283
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57284
|
-
max: number().optional(),
|
|
57285
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57286
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57287
|
-
step: number().optional(),
|
|
57288
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57289
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57290
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57291
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57292
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57293
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57294
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57295
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57296
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57297
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57298
|
-
format: _enum([
|
|
57299
|
-
"date",
|
|
57300
|
-
"time",
|
|
57301
|
-
"datetime"
|
|
57302
|
-
]).optional()
|
|
57678
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57679
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57680
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57681
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57682
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57683
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57303
57684
|
});
|
|
57304
57685
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57305
57686
|
object({
|
|
@@ -57337,9 +57718,9 @@ object({
|
|
|
57337
57718
|
]),
|
|
57338
57719
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57339
57720
|
* no intermediate position surface. */
|
|
57340
|
-
position: number().min(0).max(100).nullable(),
|
|
57721
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57341
57722
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57342
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57723
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57343
57724
|
/** Ms epoch when the slice was last updated. */
|
|
57344
57725
|
lastChangedAt: number()
|
|
57345
57726
|
});
|
|
@@ -57397,9 +57778,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57397
57778
|
object({
|
|
57398
57779
|
mode: DayNightModeSchema,
|
|
57399
57780
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57400
|
-
sensitivity: number().optional(),
|
|
57781
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57401
57782
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57402
|
-
switchDelaySec: number().optional(),
|
|
57783
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57403
57784
|
lastFetchedAt: number()
|
|
57404
57785
|
});
|
|
57405
57786
|
/**
|
|
@@ -57554,11 +57935,11 @@ object({
|
|
|
57554
57935
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57555
57936
|
availablePrograms: array(string()),
|
|
57556
57937
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57557
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57938
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57558
57939
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57559
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57940
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57560
57941
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57561
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57942
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57562
57943
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57563
57944
|
doorOpen: boolean().nullable(),
|
|
57564
57945
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57582,7 +57963,7 @@ object({
|
|
|
57582
57963
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57583
57964
|
machineCareDue: boolean().nullable(),
|
|
57584
57965
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57585
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57966
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57586
57967
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57587
57968
|
halfLoad: boolean().nullable(),
|
|
57588
57969
|
hygienePlus: boolean().nullable(),
|
|
@@ -57597,7 +57978,7 @@ object({
|
|
|
57597
57978
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57598
57979
|
activeEvents: array(string()),
|
|
57599
57980
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57600
|
-
errorCode: number().nullable(),
|
|
57981
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57601
57982
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57602
57983
|
errorLabel: string().nullable(),
|
|
57603
57984
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57743,24 +58124,14 @@ object({
|
|
|
57743
58124
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57744
58125
|
lastPressedAt: number().nullable(),
|
|
57745
58126
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57746
|
-
pressCountSinceStart: number()
|
|
58127
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57747
58128
|
});
|
|
57748
58129
|
object({
|
|
57749
58130
|
deviceId: number(),
|
|
57750
58131
|
timestamp: number()
|
|
57751
58132
|
});
|
|
57752
58133
|
DeviceType.Button, DeviceType.Camera;
|
|
57753
|
-
|
|
57754
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57755
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57756
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57757
|
-
* The option set is stable across observations; it is persisted in the
|
|
57758
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57759
|
-
* stored in `sourceInfo`.
|
|
57760
|
-
*/
|
|
57761
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57762
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57763
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
58134
|
+
_enum([
|
|
57764
58135
|
"date",
|
|
57765
58136
|
"time",
|
|
57766
58137
|
"datetime"
|
|
@@ -57768,12 +58139,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57768
58139
|
object({
|
|
57769
58140
|
value: string(),
|
|
57770
58141
|
/**
|
|
57771
|
-
* Set
|
|
57772
|
-
* as
|
|
57773
|
-
*
|
|
57774
|
-
* a time-only sensor → `'time'`.
|
|
58142
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
58143
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
58144
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57775
58145
|
*/
|
|
57776
|
-
|
|
58146
|
+
timestamp: boolean().optional(),
|
|
57777
58147
|
/** Ms epoch when the slice was last updated. */
|
|
57778
58148
|
lastFetchedAt: number()
|
|
57779
58149
|
});
|
|
@@ -57792,13 +58162,13 @@ var EventFireSchema = object({
|
|
|
57792
58162
|
deviceId: number(),
|
|
57793
58163
|
eventType: string(),
|
|
57794
58164
|
data: record(string(), unknown()).nullable(),
|
|
57795
|
-
timestamp: number(),
|
|
57796
|
-
seq: number()
|
|
58165
|
+
timestamp: number().meta(readingMeta("none")),
|
|
58166
|
+
seq: number().meta(readingMeta("count"))
|
|
57797
58167
|
});
|
|
57798
58168
|
object({
|
|
57799
58169
|
eventTypes: array(string()),
|
|
57800
58170
|
lastEvent: EventFireSchema.nullable(),
|
|
57801
|
-
eventCountSinceStart: number()
|
|
58171
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57802
58172
|
});
|
|
57803
58173
|
DeviceType.EventEmitter;
|
|
57804
58174
|
var IdentitySchema = object({
|
|
@@ -58187,10 +58557,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58187
58557
|
object({
|
|
58188
58558
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58189
58559
|
* speed surface (single-speed fan). */
|
|
58190
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58560
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58191
58561
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58192
58562
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58193
|
-
percentageStep: number().positive().optional(),
|
|
58563
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58194
58564
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58195
58565
|
* — empty string when no preset is active or supported. */
|
|
58196
58566
|
preset: string(),
|
|
@@ -58272,7 +58642,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58272
58642
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58273
58643
|
model: string().nullable(),
|
|
58274
58644
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58275
|
-
channelCount: number().nullable(),
|
|
58645
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58276
58646
|
/**
|
|
58277
58647
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58278
58648
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58304,9 +58674,39 @@ object({
|
|
|
58304
58674
|
lastChangedAt: number()
|
|
58305
58675
|
});
|
|
58306
58676
|
DeviceType.Sensor;
|
|
58677
|
+
object({
|
|
58678
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58679
|
+
results: array(object({
|
|
58680
|
+
deviceId: number().int().nonnegative(),
|
|
58681
|
+
cap: string().min(1),
|
|
58682
|
+
method: string().min(1),
|
|
58683
|
+
ok: boolean(),
|
|
58684
|
+
error: string().optional(),
|
|
58685
|
+
/** Ms epoch of the attempt. */
|
|
58686
|
+
at: number()
|
|
58687
|
+
})) });
|
|
58688
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58689
|
+
object({
|
|
58690
|
+
/** Members whose current value entered the aggregate. */
|
|
58691
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58692
|
+
precision: 0,
|
|
58693
|
+
label: "Reporting"
|
|
58694
|
+
})),
|
|
58695
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58696
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58697
|
+
precision: 0,
|
|
58698
|
+
label: "Excluded"
|
|
58699
|
+
})),
|
|
58700
|
+
/** `included` + `excluded`. */
|
|
58701
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58702
|
+
precision: 0,
|
|
58703
|
+
label: "Members"
|
|
58704
|
+
}))
|
|
58705
|
+
});
|
|
58706
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58307
58707
|
object({
|
|
58308
58708
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58309
|
-
position: number().min(0).max(100).nullable(),
|
|
58709
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58310
58710
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58311
58711
|
lastFetchedAt: number()
|
|
58312
58712
|
});
|
|
@@ -58315,9 +58715,9 @@ object({
|
|
|
58315
58715
|
/** Whether the humidifier is currently on. */
|
|
58316
58716
|
on: boolean(),
|
|
58317
58717
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58318
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58718
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58319
58719
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58320
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58720
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58321
58721
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58322
58722
|
* device has no mode surface. */
|
|
58323
58723
|
mode: string().nullable(),
|
|
@@ -58327,9 +58727,9 @@ object({
|
|
|
58327
58727
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58328
58728
|
action: string().nullable(),
|
|
58329
58729
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58330
|
-
minHumidity: number().nullable(),
|
|
58730
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58331
58731
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58332
|
-
maxHumidity: number().nullable(),
|
|
58732
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58333
58733
|
/** Ms epoch when the slice was last updated. */
|
|
58334
58734
|
lastChangedAt: number()
|
|
58335
58735
|
});
|
|
@@ -58353,22 +58753,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58353
58753
|
auth: "protected"
|
|
58354
58754
|
});
|
|
58355
58755
|
object({
|
|
58356
|
-
/** Current relative humidity, 0..100. */
|
|
58357
|
-
percent: number().min(0).max(100).meta({
|
|
58358
|
-
|
|
58756
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58757
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58758
|
+
precision: 0,
|
|
58359
58759
|
label: "Humidity"
|
|
58360
|
-
}),
|
|
58760
|
+
})),
|
|
58361
58761
|
/** Ms epoch when the slice was last updated. */
|
|
58362
|
-
lastFetchedAt: number()
|
|
58363
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58364
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58365
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58366
|
-
unit: string().optional(),
|
|
58367
|
-
/** Suggested decimal places for numeric display.
|
|
58368
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58369
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58370
|
-
* auto-formatting when absent. */
|
|
58371
|
-
precision: number().int().min(0).max(10).optional()
|
|
58762
|
+
lastFetchedAt: number()
|
|
58372
58763
|
});
|
|
58373
58764
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58374
58765
|
object({
|
|
@@ -58376,7 +58767,7 @@ object({
|
|
|
58376
58767
|
* entity exposes no `entity_picture` (yet). */
|
|
58377
58768
|
url: string().nullable(),
|
|
58378
58769
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58379
|
-
lastUpdated: number().nullable()
|
|
58770
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58380
58771
|
});
|
|
58381
58772
|
DeviceType.Image;
|
|
58382
58773
|
/**
|
|
@@ -58432,19 +58823,19 @@ var NormalizedRangeSchema = object({
|
|
|
58432
58823
|
});
|
|
58433
58824
|
object({
|
|
58434
58825
|
/** Normalized 0–100. */
|
|
58435
|
-
brightness: number().optional(),
|
|
58826
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58436
58827
|
/** Normalized 0–100. */
|
|
58437
|
-
contrast: number().optional(),
|
|
58828
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58438
58829
|
/** Normalized 0–100. */
|
|
58439
|
-
saturation: number().optional(),
|
|
58830
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58440
58831
|
/** Normalized 0–100. */
|
|
58441
|
-
sharpness: number().optional(),
|
|
58832
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58442
58833
|
mirror: boolean().optional(),
|
|
58443
58834
|
flip: boolean().optional(),
|
|
58444
58835
|
rotate: ImageRotateSchema.optional(),
|
|
58445
58836
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58446
58837
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58447
|
-
warmth: number().optional(),
|
|
58838
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58448
58839
|
exposureMode: ExposureModeSchema.optional(),
|
|
58449
58840
|
backlightMode: BacklightModeSchema.optional(),
|
|
58450
58841
|
lastFetchedAt: number()
|
|
@@ -58689,10 +59080,10 @@ var IntercomAbilitySchema = object({
|
|
|
58689
59080
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58690
59081
|
codecs: array(string()),
|
|
58691
59082
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58692
|
-
sampleRate: number(),
|
|
59083
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58693
59084
|
duplex: _enum(["half", "full"]),
|
|
58694
59085
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58695
|
-
maxBacklogMs: number()
|
|
59086
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58696
59087
|
});
|
|
58697
59088
|
var IntercomStatusSchema = object({
|
|
58698
59089
|
/** True while a talk session is open. */
|
|
@@ -58803,13 +59194,13 @@ object({
|
|
|
58803
59194
|
activity: LawnMowerActivitySchema,
|
|
58804
59195
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58805
59196
|
* reading. */
|
|
58806
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
59197
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58807
59198
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58808
59199
|
* task is active / progress is unavailable. */
|
|
58809
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59200
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58810
59201
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58811
59202
|
* or null when unknown. */
|
|
58812
|
-
currentCode: number().nullable(),
|
|
59203
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58813
59204
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58814
59205
|
currentCodeLabel: string().nullable(),
|
|
58815
59206
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59271,7 +59662,7 @@ object({
|
|
|
59271
59662
|
state: MediaPlayerStateSchema,
|
|
59272
59663
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59273
59664
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59274
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59665
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59275
59666
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59276
59667
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59277
59668
|
isMuted: boolean().nullable(),
|
|
@@ -59284,10 +59675,10 @@ object({
|
|
|
59284
59675
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59285
59676
|
/** Current playback position in ms. Null when not seekable or
|
|
59286
59677
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59287
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59678
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59288
59679
|
/** Total duration of the current media in ms. Null when unknown
|
|
59289
59680
|
* (live stream) or nothing is playing. */
|
|
59290
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59681
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59291
59682
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59292
59683
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59293
59684
|
shuffle: boolean().nullable(),
|
|
@@ -59587,7 +59978,7 @@ object({
|
|
|
59587
59978
|
* it, every provider seeded it at boot, and every session left it
|
|
59588
59979
|
* `detected: true` after its detach.
|
|
59589
59980
|
*/
|
|
59590
|
-
autoClearAfterMs: number().nullable()
|
|
59981
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59591
59982
|
});
|
|
59592
59983
|
/**
|
|
59593
59984
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59637,7 +60028,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59637
60028
|
});
|
|
59638
60029
|
object({
|
|
59639
60030
|
enabled: boolean(),
|
|
59640
|
-
sensitivity: number(),
|
|
60031
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59641
60032
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59642
60033
|
regions: array(MotionZoneRegionSchema),
|
|
59643
60034
|
lastFetchedAt: number()
|
|
@@ -59941,7 +60332,7 @@ var NavigationStatusSchema = object({
|
|
|
59941
60332
|
following: boolean(),
|
|
59942
60333
|
flash: boolean(),
|
|
59943
60334
|
lightMode: NavigationLightModeSchema,
|
|
59944
|
-
lightLevel: number().min(40).max(100),
|
|
60335
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59945
60336
|
/** Ms epoch when the slice was last updated. */
|
|
59946
60337
|
lastChangedAt: number()
|
|
59947
60338
|
});
|
|
@@ -59987,13 +60378,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59987
60378
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59988
60379
|
* SKIP a null rather than coerce it.
|
|
59989
60380
|
*/
|
|
59990
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
60381
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59991
60382
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59992
|
-
rssiDbm: number().optional(),
|
|
60383
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59993
60384
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59994
60385
|
ssid: string().optional(),
|
|
59995
60386
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59996
|
-
lastUpdated: number()
|
|
60387
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59997
60388
|
});
|
|
59998
60389
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59999
60390
|
deviceId: number(),
|
|
@@ -60312,7 +60703,7 @@ object({
|
|
|
60312
60703
|
lastError: string().nullable(),
|
|
60313
60704
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60314
60705
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60315
|
-
queueDepth: number().int().nonnegative(),
|
|
60706
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60316
60707
|
/** Per-feature capability matrix — authoritative source for the
|
|
60317
60708
|
* compose-form field gating. */
|
|
60318
60709
|
supports: NotifierSupportsSchema
|
|
@@ -60362,15 +60753,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60362
60753
|
acceptedAt: number()
|
|
60363
60754
|
});
|
|
60364
60755
|
object({
|
|
60365
|
-
|
|
60366
|
-
|
|
60367
|
-
* Populated live from the upstream source on each state push.
|
|
60368
|
-
* Absent for unitless sensors. */
|
|
60369
|
-
unit: string().optional(),
|
|
60370
|
-
/** Suggested decimal places for numeric display.
|
|
60371
|
-
* Populated live from the upstream source when provided.
|
|
60372
|
-
* Falls back to auto-formatting when absent. */
|
|
60373
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60756
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60757
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60374
60758
|
/** Ms epoch when the slice was last updated. */
|
|
60375
60759
|
lastFetchedAt: number()
|
|
60376
60760
|
});
|
|
@@ -60660,23 +61044,26 @@ object({
|
|
|
60660
61044
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60661
61045
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60662
61046
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60663
|
-
foodLevel: number().nullable(),
|
|
61047
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60664
61048
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60665
61049
|
* single-hopper models. */
|
|
60666
|
-
food1: number().nullable(),
|
|
61050
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60667
61051
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60668
61052
|
* single-hopper models. */
|
|
60669
|
-
food2: number().nullable(),
|
|
61053
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60670
61054
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60671
61055
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60672
61056
|
* below the feeder's low threshold. */
|
|
60673
61057
|
lowFood: boolean(),
|
|
60674
61058
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60675
61059
|
* device has no battery reading. */
|
|
60676
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60677
|
-
/**
|
|
60678
|
-
*
|
|
60679
|
-
|
|
61060
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61061
|
+
/**
|
|
61062
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
61063
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
61064
|
+
* model has no desiccant sensor.
|
|
61065
|
+
*/
|
|
61066
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60680
61067
|
/** True while a feed is in progress. */
|
|
60681
61068
|
feeding: boolean(),
|
|
60682
61069
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60687,7 +61074,7 @@ object({
|
|
|
60687
61074
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60688
61075
|
error: string().nullable(),
|
|
60689
61076
|
/** Raw device error code (0 / null = no error). */
|
|
60690
|
-
errorCode: number().nullable(),
|
|
61077
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60691
61078
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60692
61079
|
isDualHopper: boolean(),
|
|
60693
61080
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60697,7 +61084,7 @@ object({
|
|
|
60697
61084
|
/** Play a chime when dispensing. */
|
|
60698
61085
|
feedSound: boolean(),
|
|
60699
61086
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60700
|
-
volume: number(),
|
|
61087
|
+
volume: number().meta(readingMeta("none")),
|
|
60701
61088
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60702
61089
|
lastFetchedAt: number()
|
|
60703
61090
|
});
|
|
@@ -61134,36 +61521,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61134
61521
|
});
|
|
61135
61522
|
object({
|
|
61136
61523
|
/** Instantaneous power draw in watts. */
|
|
61137
|
-
watts: number().optional().meta({
|
|
61138
|
-
unit: "W",
|
|
61139
|
-
label: "Power"
|
|
61140
|
-
}),
|
|
61524
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61141
61525
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61142
|
-
kwhTotal: number().optional().meta({
|
|
61143
|
-
unit: "kWh",
|
|
61144
|
-
label: "Energy"
|
|
61145
|
-
}),
|
|
61526
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61146
61527
|
/** Voltage in volts. */
|
|
61147
|
-
volts: number().optional(),
|
|
61528
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61148
61529
|
/** Current in amperes. */
|
|
61149
|
-
amps: number().optional(),
|
|
61150
|
-
/** Apparent power in volt-amperes
|
|
61151
|
-
va: number().optional(),
|
|
61530
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61531
|
+
/** Apparent power in volt-amperes. */
|
|
61532
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61152
61533
|
/** Power factor (0..1) if reported. */
|
|
61153
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61534
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61154
61535
|
/** Ms epoch when the slice was last updated. */
|
|
61155
|
-
lastFetchedAt: number()
|
|
61156
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61157
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61158
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61159
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61160
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61161
|
-
unit: string().optional(),
|
|
61162
|
-
/** Suggested decimal places for numeric display.
|
|
61163
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61164
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61165
|
-
* auto-formatting when absent. */
|
|
61166
|
-
precision: number().int().min(0).max(10).optional()
|
|
61536
|
+
lastFetchedAt: number()
|
|
61167
61537
|
});
|
|
61168
61538
|
DeviceType.Sensor;
|
|
61169
61539
|
/**
|
|
@@ -61184,11 +61554,11 @@ DeviceType.Sensor;
|
|
|
61184
61554
|
*/
|
|
61185
61555
|
var GpsLocationSchema = object({
|
|
61186
61556
|
/** Latitude in decimal degrees, -90..90. */
|
|
61187
|
-
latitude: number().min(-90).max(90),
|
|
61557
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61188
61558
|
/** Longitude in decimal degrees, -180..180. */
|
|
61189
|
-
longitude: number().min(-180).max(180),
|
|
61559
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61190
61560
|
/** Reported accuracy in meters (lower = better). */
|
|
61191
|
-
accuracyMeters: number().nonnegative()
|
|
61561
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61192
61562
|
});
|
|
61193
61563
|
object({
|
|
61194
61564
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61200,25 +61570,16 @@ object({
|
|
|
61200
61570
|
gps: GpsLocationSchema.nullable(),
|
|
61201
61571
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61202
61572
|
* when not reported. */
|
|
61203
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61573
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61204
61574
|
/** Ms epoch when the slice was last updated. */
|
|
61205
61575
|
lastChangedAt: number()
|
|
61206
61576
|
});
|
|
61207
61577
|
DeviceType.Presence;
|
|
61208
61578
|
object({
|
|
61209
|
-
/** Current pressure in hPa. */
|
|
61210
|
-
hpa: number(),
|
|
61579
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61580
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61211
61581
|
/** Ms epoch when the slice was last updated. */
|
|
61212
|
-
lastFetchedAt: number()
|
|
61213
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61214
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61215
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61216
|
-
unit: string().optional(),
|
|
61217
|
-
/** Suggested decimal places for numeric display.
|
|
61218
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61219
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61220
|
-
* auto-formatting when absent. */
|
|
61221
|
-
precision: number().int().min(0).max(10).optional()
|
|
61582
|
+
lastFetchedAt: number()
|
|
61222
61583
|
});
|
|
61223
61584
|
DeviceType.Sensor;
|
|
61224
61585
|
/**
|
|
@@ -61551,8 +61912,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61551
61912
|
}), _void(), { kind: "mutation" });
|
|
61552
61913
|
var PtzAutotrackSettingsSchema = object({
|
|
61553
61914
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61554
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61555
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61915
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61916
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61556
61917
|
});
|
|
61557
61918
|
/**
|
|
61558
61919
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61609,7 +61970,7 @@ object({
|
|
|
61609
61970
|
/** null = unknown — never coerced to false (D393). */
|
|
61610
61971
|
running: boolean().nullable(),
|
|
61611
61972
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61612
|
-
since: number().nullable(),
|
|
61973
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61613
61974
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61614
61975
|
phase: string().nullable(),
|
|
61615
61976
|
/** null until a reading has been published (D393). */
|
|
@@ -62807,9 +63168,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62807
63168
|
*/
|
|
62808
63169
|
var RecordWindowSchema = object({
|
|
62809
63170
|
trigger: RecordTriggerSchema,
|
|
62810
|
-
day: number().int().min(0).max(6),
|
|
62811
|
-
startMinute: number().int().min(0).max(1439),
|
|
62812
|
-
endMinute: number().int().min(1).max(1440)
|
|
63171
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
63172
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
63173
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62813
63174
|
});
|
|
62814
63175
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62815
63176
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62878,10 +63239,10 @@ object({
|
|
|
62878
63239
|
/** Master "record to the card at all" switch. */
|
|
62879
63240
|
enabled: boolean().nullable(),
|
|
62880
63241
|
overwriteWhenFull: boolean().nullable(),
|
|
62881
|
-
preRecordSec: number().nullable(),
|
|
62882
|
-
postRecordSec: number().nullable(),
|
|
63242
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
63243
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62883
63244
|
/** Length of one recorded file, in minutes. */
|
|
62884
|
-
segmentMinutes: number().nullable(),
|
|
63245
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62885
63246
|
/** The primary track's weekly windows, flattened. */
|
|
62886
63247
|
windows: array(RecordWindowSchema),
|
|
62887
63248
|
/**
|
|
@@ -62897,7 +63258,7 @@ object({
|
|
|
62897
63258
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62898
63259
|
* writable.
|
|
62899
63260
|
*/
|
|
62900
|
-
unreadableWindows: number(),
|
|
63261
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62901
63262
|
/**
|
|
62902
63263
|
* The camera is scheduled to record and has NO usable storage.
|
|
62903
63264
|
*
|
|
@@ -63534,7 +63895,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63534
63895
|
url: string().optional(),
|
|
63535
63896
|
codec: string().optional(),
|
|
63536
63897
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63537
|
-
fps: number().positive().optional(),
|
|
63898
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63538
63899
|
label: string().optional(),
|
|
63539
63900
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63540
63901
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63564,18 +63925,18 @@ var StreamProfileSchema = _enum([
|
|
|
63564
63925
|
]);
|
|
63565
63926
|
/** The current encoding config of one stream profile. */
|
|
63566
63927
|
var StreamProfileConfigSchema = object({
|
|
63567
|
-
width: number(),
|
|
63568
|
-
height: number(),
|
|
63928
|
+
width: number().meta(readingMeta("none")),
|
|
63929
|
+
height: number().meta(readingMeta("none")),
|
|
63569
63930
|
codec: _enum(["h264", "h265"]),
|
|
63570
|
-
framerate: number(),
|
|
63571
|
-
bitrate: number(),
|
|
63931
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63932
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63572
63933
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63573
63934
|
encoderProfile: _enum([
|
|
63574
63935
|
"high",
|
|
63575
63936
|
"main",
|
|
63576
63937
|
"baseline"
|
|
63577
63938
|
]).optional(),
|
|
63578
|
-
gop: number().optional(),
|
|
63939
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63579
63940
|
/**
|
|
63580
63941
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63581
63942
|
*
|
|
@@ -64218,23 +64579,13 @@ object({
|
|
|
64218
64579
|
});
|
|
64219
64580
|
DeviceType.Sensor;
|
|
64220
64581
|
object({
|
|
64221
|
-
/** Current temperature in Celsius. */
|
|
64222
|
-
celsius: number().meta({
|
|
64223
|
-
|
|
64582
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64583
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64584
|
+
precision: 1,
|
|
64224
64585
|
label: "Temperature"
|
|
64225
|
-
}),
|
|
64586
|
+
})),
|
|
64226
64587
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64227
|
-
lastFetchedAt: number()
|
|
64228
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64229
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64230
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64231
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64232
|
-
unit: string().optional(),
|
|
64233
|
-
/** Suggested decimal places for numeric display.
|
|
64234
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64235
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64236
|
-
* auto-formatting when absent. */
|
|
64237
|
-
precision: number().int().min(0).max(10).optional()
|
|
64588
|
+
lastFetchedAt: number()
|
|
64238
64589
|
});
|
|
64239
64590
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64240
64591
|
/**
|
|
@@ -64486,16 +64837,16 @@ object({
|
|
|
64486
64837
|
]),
|
|
64487
64838
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64488
64839
|
* reading. */
|
|
64489
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64840
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64490
64841
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64491
64842
|
* the vacuum has no speed control. */
|
|
64492
64843
|
fanSpeed: string().nullable(),
|
|
64493
64844
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64494
64845
|
availableFanSpeeds: array(string()),
|
|
64495
64846
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64496
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64847
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64497
64848
|
/** Current error code (0 / null = no error). */
|
|
64498
|
-
errorCode: number().nullable(),
|
|
64849
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64499
64850
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64500
64851
|
errorLabel: string().nullable(),
|
|
64501
64852
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64534,7 +64885,7 @@ object({
|
|
|
64534
64885
|
]),
|
|
64535
64886
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64536
64887
|
* intermediate position surface. */
|
|
64537
|
-
position: number().min(0).max(100).nullable(),
|
|
64888
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64538
64889
|
/** Ms epoch when the slice was last updated. */
|
|
64539
64890
|
lastChangedAt: number()
|
|
64540
64891
|
});
|
|
@@ -64562,9 +64913,9 @@ object({
|
|
|
64562
64913
|
DeviceType.Sensor;
|
|
64563
64914
|
object({
|
|
64564
64915
|
/** Current measured temperature. Null when not reported. */
|
|
64565
|
-
currentTemp: number().nullable(),
|
|
64916
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64566
64917
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64567
|
-
targetTemp: number().nullable(),
|
|
64918
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64568
64919
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64569
64920
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64570
64921
|
* device reports an unknown state. */
|
|
@@ -64575,9 +64926,9 @@ object({
|
|
|
64575
64926
|
* has no away surface. */
|
|
64576
64927
|
away: boolean().nullable(),
|
|
64577
64928
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64578
|
-
minTemp: number().nullable(),
|
|
64929
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64579
64930
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64580
|
-
maxTemp: number().nullable(),
|
|
64931
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64581
64932
|
/** Ms epoch when the slice was last updated. */
|
|
64582
64933
|
lastChangedAt: number()
|
|
64583
64934
|
});
|
|
@@ -64601,25 +64952,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64601
64952
|
auth: "protected"
|
|
64602
64953
|
});
|
|
64603
64954
|
object({
|
|
64604
|
-
/** Verbatim
|
|
64605
|
-
* when no condition has been reported yet. */
|
|
64955
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64606
64956
|
condition: string().nullable(),
|
|
64607
|
-
/** Current temperature in
|
|
64608
|
-
temperature: number().nullable(),
|
|
64609
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64610
|
-
temperatureUnit: string().nullable(),
|
|
64957
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64958
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64611
64959
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64612
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64613
|
-
/** Barometric pressure in
|
|
64614
|
-
pressure: number().nullable(),
|
|
64615
|
-
/**
|
|
64616
|
-
|
|
64617
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64618
|
-
windSpeed: number().nullable(),
|
|
64619
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64620
|
-
windSpeedUnit: string().nullable(),
|
|
64960
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64961
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64962
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64963
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64964
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64621
64965
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64622
|
-
windBearing: number().nullable(),
|
|
64966
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64623
64967
|
/** Ms epoch when the slice was last updated. */
|
|
64624
64968
|
lastFetchedAt: number()
|
|
64625
64969
|
});
|
|
@@ -65531,6 +65875,13 @@ Object.freeze({
|
|
|
65531
65875
|
access: "view",
|
|
65532
65876
|
role: "admin"
|
|
65533
65877
|
},
|
|
65878
|
+
"addons.getPackageDocs": {
|
|
65879
|
+
capName: "addons",
|
|
65880
|
+
capScope: "system",
|
|
65881
|
+
addonId: null,
|
|
65882
|
+
access: "view",
|
|
65883
|
+
role: "admin"
|
|
65884
|
+
},
|
|
65534
65885
|
"addons.getVersions": {
|
|
65535
65886
|
capName: "addons",
|
|
65536
65887
|
capScope: "system",
|
|
@@ -68639,6 +68990,20 @@ Object.freeze({
|
|
|
68639
68990
|
access: "view",
|
|
68640
68991
|
role: "viewer"
|
|
68641
68992
|
},
|
|
68993
|
+
"groupCommands.getStatus": {
|
|
68994
|
+
capName: "group-commands",
|
|
68995
|
+
capScope: "device",
|
|
68996
|
+
addonId: null,
|
|
68997
|
+
access: "view",
|
|
68998
|
+
role: "viewer"
|
|
68999
|
+
},
|
|
69000
|
+
"groupStatus.getStatus": {
|
|
69001
|
+
capName: "group-status",
|
|
69002
|
+
capScope: "device",
|
|
69003
|
+
addonId: null,
|
|
69004
|
+
access: "view",
|
|
69005
|
+
role: "viewer"
|
|
69006
|
+
},
|
|
68642
69007
|
"heatingValve.getStatus": {
|
|
68643
69008
|
capName: "heating-valve",
|
|
68644
69009
|
capScope: "device",
|
|
@@ -78461,6 +78826,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78461
78826
|
icon: "flame"
|
|
78462
78827
|
}]
|
|
78463
78828
|
},
|
|
78829
|
+
"group-commands": {
|
|
78830
|
+
scope: "device",
|
|
78831
|
+
noun: t("Group command", "Comando di gruppo")
|
|
78832
|
+
},
|
|
78833
|
+
"group-status": {
|
|
78834
|
+
scope: "device",
|
|
78835
|
+
noun: t("Group", "Gruppo"),
|
|
78836
|
+
state: [
|
|
78837
|
+
{
|
|
78838
|
+
kind: "numeric",
|
|
78839
|
+
field: "included",
|
|
78840
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
78841
|
+
label: t("Reporting", "Rispondono"),
|
|
78842
|
+
icon: "users"
|
|
78843
|
+
},
|
|
78844
|
+
{
|
|
78845
|
+
kind: "numeric",
|
|
78846
|
+
field: "excluded",
|
|
78847
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
78848
|
+
label: t("Excluded", "Esclusi"),
|
|
78849
|
+
icon: "users"
|
|
78850
|
+
},
|
|
78851
|
+
{
|
|
78852
|
+
kind: "numeric",
|
|
78853
|
+
field: "total",
|
|
78854
|
+
quantity: t("the member count", "il numero di membri"),
|
|
78855
|
+
label: t("Members", "Membri"),
|
|
78856
|
+
icon: "sigma"
|
|
78857
|
+
}
|
|
78858
|
+
]
|
|
78859
|
+
},
|
|
78464
78860
|
"humidity-sensor": {
|
|
78465
78861
|
scope: "device",
|
|
78466
78862
|
noun: t("Humidity", "Umidità"),
|
|
@@ -78494,7 +78890,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78494
78890
|
field: "value",
|
|
78495
78891
|
quantity: t("the reading", "il valore"),
|
|
78496
78892
|
label: t("Reading", "Valore"),
|
|
78497
|
-
unitField: "unit",
|
|
78498
78893
|
icon: "gauge"
|
|
78499
78894
|
}]
|
|
78500
78895
|
},
|
|
@@ -78630,7 +79025,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78630
79025
|
field: "temperature",
|
|
78631
79026
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78632
79027
|
label: t("Temperature", "Temperatura"),
|
|
78633
|
-
|
|
79028
|
+
unit: "°C",
|
|
78634
79029
|
icon: "thermometer"
|
|
78635
79030
|
},
|
|
78636
79031
|
{
|
|
@@ -78646,7 +79041,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78646
79041
|
field: "windSpeed",
|
|
78647
79042
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78648
79043
|
label: t("Wind", "Vento"),
|
|
78649
|
-
|
|
79044
|
+
unit: "m/s",
|
|
78650
79045
|
icon: "wind"
|
|
78651
79046
|
},
|
|
78652
79047
|
{
|
|
@@ -78654,7 +79049,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78654
79049
|
field: "pressure",
|
|
78655
79050
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78656
79051
|
label: t("Pressure", "Pressione"),
|
|
78657
|
-
|
|
79052
|
+
unit: "hPa",
|
|
78658
79053
|
icon: "gauge"
|
|
78659
79054
|
}
|
|
78660
79055
|
]
|
|
@@ -79927,6 +80322,16 @@ Object.freeze({
|
|
|
79927
80322
|
form: "single",
|
|
79928
80323
|
optional: false
|
|
79929
80324
|
}],
|
|
80325
|
+
"groupCommands.getStatus": [{
|
|
80326
|
+
name: "deviceId",
|
|
80327
|
+
form: "single",
|
|
80328
|
+
optional: false
|
|
80329
|
+
}],
|
|
80330
|
+
"groupStatus.getStatus": [{
|
|
80331
|
+
name: "deviceId",
|
|
80332
|
+
form: "single",
|
|
80333
|
+
optional: false
|
|
80334
|
+
}],
|
|
79930
80335
|
"heatingValve.getStatus": [{
|
|
79931
80336
|
name: "deviceId",
|
|
79932
80337
|
form: "single",
|
|
@@ -81791,6 +82196,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
81791
82196
|
targetId: string().min(1),
|
|
81792
82197
|
enabled: boolean(),
|
|
81793
82198
|
debounceMs: number().nonnegative(),
|
|
82199
|
+
edges: array(_enum([
|
|
82200
|
+
"rising",
|
|
82201
|
+
"button",
|
|
82202
|
+
"native-event"
|
|
82203
|
+
])).min(1).optional(),
|
|
81794
82204
|
sources: array(OverrideSourceSchema).min(1)
|
|
81795
82205
|
});
|
|
81796
82206
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -82113,6 +82523,8 @@ new Map(Object.entries({
|
|
|
82113
82523
|
"detection-blind": "device-events",
|
|
82114
82524
|
"motion-noisy": "device-events",
|
|
82115
82525
|
"motion-calm": "device-events",
|
|
82526
|
+
"package-llm-silent": "device-events",
|
|
82527
|
+
"package-llm-answered": "device-events",
|
|
82116
82528
|
"recording-stalled": "device-events",
|
|
82117
82529
|
"recording-healthy": "device-events",
|
|
82118
82530
|
"recording-degraded": "device-events",
|
|
@@ -82196,6 +82608,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
82196
82608
|
label: "Motion without a subject",
|
|
82197
82609
|
kinds: ["motion-noisy", "motion-calm"]
|
|
82198
82610
|
},
|
|
82611
|
+
{
|
|
82612
|
+
id: "package-llm",
|
|
82613
|
+
family: "device-events",
|
|
82614
|
+
label: "Package confirm",
|
|
82615
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
82616
|
+
},
|
|
82199
82617
|
{
|
|
82200
82618
|
id: "recording",
|
|
82201
82619
|
family: "device-events",
|
|
@@ -82377,6 +82795,8 @@ var DEVICE_EVENTS = [
|
|
|
82377
82795
|
"detection-blind",
|
|
82378
82796
|
"motion-noisy",
|
|
82379
82797
|
"motion-calm",
|
|
82798
|
+
"package-llm-silent",
|
|
82799
|
+
"package-llm-answered",
|
|
82380
82800
|
"recording-stalled",
|
|
82381
82801
|
"recording-healthy",
|
|
82382
82802
|
"recording-degraded",
|
|
@@ -82645,6 +83065,15 @@ new Map([
|
|
|
82645
83065
|
snapshotLabel: "Cameras with constant motion now",
|
|
82646
83066
|
snapshotSection: null
|
|
82647
83067
|
},
|
|
83068
|
+
{
|
|
83069
|
+
id: "package-llm-confirm",
|
|
83070
|
+
family: "device-events",
|
|
83071
|
+
label: "Package confirm (not answering / answering again)",
|
|
83072
|
+
bad: ["package-llm-silent"],
|
|
83073
|
+
recovery: ["package-llm-answered"],
|
|
83074
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
83075
|
+
snapshotSection: null
|
|
83076
|
+
},
|
|
82648
83077
|
{
|
|
82649
83078
|
id: "recording-health",
|
|
82650
83079
|
family: "device-events",
|