@camstack/addon-notifiers 1.2.621 → 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 +856 -432
- package/dist/addon.mjs +856 -432
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -29,7 +29,7 @@ let node_fs = require("node:fs");
|
|
|
29
29
|
let node_path = require("node:path");
|
|
30
30
|
node_path = __toESM(node_path);
|
|
31
31
|
let node_url = require("node:url");
|
|
32
|
-
//#region ../types/dist/event-category-
|
|
32
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
33
33
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
34
34
|
EventCategory["SystemBoot"] = "system.boot";
|
|
35
35
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -355,6 +355,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
355
355
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
356
356
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
357
357
|
/**
|
|
358
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
359
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
360
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
361
|
+
*/
|
|
362
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
363
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
364
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
365
|
+
/**
|
|
358
366
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
359
367
|
* (a settings change via `setAgentInferenceDevices` /
|
|
360
368
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5597,7 +5605,7 @@ var ZodIssueCode = {
|
|
|
5597
5605
|
var ZodFirstPartyTypeKind;
|
|
5598
5606
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5599
5607
|
//#endregion
|
|
5600
|
-
//#region ../types/dist/sleep-
|
|
5608
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5601
5609
|
/**
|
|
5602
5610
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5603
5611
|
* window to float samples (D455).
|
|
@@ -8297,6 +8305,99 @@ function defineRecordKinds(specs) {
|
|
|
8297
8305
|
}
|
|
8298
8306
|
return out;
|
|
8299
8307
|
}
|
|
8308
|
+
var READING_QUANTITIES = [
|
|
8309
|
+
"temperature",
|
|
8310
|
+
"pressure",
|
|
8311
|
+
"speed",
|
|
8312
|
+
"precipitation",
|
|
8313
|
+
"precipitation-rate",
|
|
8314
|
+
"length",
|
|
8315
|
+
"area",
|
|
8316
|
+
"illuminance",
|
|
8317
|
+
"irradiance",
|
|
8318
|
+
"power",
|
|
8319
|
+
"energy",
|
|
8320
|
+
"voltage",
|
|
8321
|
+
"current",
|
|
8322
|
+
"apparent-power",
|
|
8323
|
+
"humidity",
|
|
8324
|
+
"percentage",
|
|
8325
|
+
"concentration-volume",
|
|
8326
|
+
"concentration-mass",
|
|
8327
|
+
"concentration-ppb",
|
|
8328
|
+
"volume",
|
|
8329
|
+
"duration",
|
|
8330
|
+
"duration-ms",
|
|
8331
|
+
"information",
|
|
8332
|
+
"sound-level",
|
|
8333
|
+
"signal-level",
|
|
8334
|
+
"colour-temperature",
|
|
8335
|
+
"angle",
|
|
8336
|
+
"bitrate",
|
|
8337
|
+
"rate",
|
|
8338
|
+
"mass",
|
|
8339
|
+
"index",
|
|
8340
|
+
"ratio",
|
|
8341
|
+
"count",
|
|
8342
|
+
"none",
|
|
8343
|
+
"device"
|
|
8344
|
+
];
|
|
8345
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8346
|
+
new Set(READING_QUANTITIES);
|
|
8347
|
+
/**
|
|
8348
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8349
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8350
|
+
*/
|
|
8351
|
+
var QUANTITY_BASE = {
|
|
8352
|
+
temperature: "°C",
|
|
8353
|
+
pressure: "hPa",
|
|
8354
|
+
speed: "m/s",
|
|
8355
|
+
precipitation: "mm",
|
|
8356
|
+
"precipitation-rate": "mm/h",
|
|
8357
|
+
length: "m",
|
|
8358
|
+
area: "m²",
|
|
8359
|
+
illuminance: "lx",
|
|
8360
|
+
irradiance: "W/m²",
|
|
8361
|
+
power: "W",
|
|
8362
|
+
energy: "kWh",
|
|
8363
|
+
voltage: "V",
|
|
8364
|
+
current: "A",
|
|
8365
|
+
"apparent-power": "VA",
|
|
8366
|
+
humidity: "%",
|
|
8367
|
+
percentage: "%",
|
|
8368
|
+
"concentration-volume": "ppm",
|
|
8369
|
+
"concentration-mass": "µg/m³",
|
|
8370
|
+
"concentration-ppb": "ppb",
|
|
8371
|
+
volume: "L",
|
|
8372
|
+
duration: "s",
|
|
8373
|
+
"duration-ms": "ms",
|
|
8374
|
+
information: "B",
|
|
8375
|
+
"sound-level": "dBFS",
|
|
8376
|
+
"signal-level": "dBm",
|
|
8377
|
+
"colour-temperature": "mired",
|
|
8378
|
+
angle: "°",
|
|
8379
|
+
bitrate: "kbps",
|
|
8380
|
+
rate: "fps",
|
|
8381
|
+
mass: "kg",
|
|
8382
|
+
index: "none",
|
|
8383
|
+
ratio: "none",
|
|
8384
|
+
count: "none",
|
|
8385
|
+
none: "none",
|
|
8386
|
+
device: "device"
|
|
8387
|
+
};
|
|
8388
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8389
|
+
function baseUnitOf(quantity) {
|
|
8390
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8391
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8392
|
+
return symbol;
|
|
8393
|
+
}
|
|
8394
|
+
function readingMeta(quantity, extras) {
|
|
8395
|
+
return {
|
|
8396
|
+
quantity,
|
|
8397
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8398
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8399
|
+
};
|
|
8400
|
+
}
|
|
8300
8401
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8301
8402
|
var CamProfileSchema = _enum([
|
|
8302
8403
|
"high",
|
|
@@ -8324,8 +8425,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8324
8425
|
"derived"
|
|
8325
8426
|
]);
|
|
8326
8427
|
var CamStreamResolutionSchema = object({
|
|
8327
|
-
width: number().int().positive(),
|
|
8328
|
-
height: number().int().positive()
|
|
8428
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8429
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8329
8430
|
});
|
|
8330
8431
|
var CameraStreamSchema = object({
|
|
8331
8432
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8861,6 +8962,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8861
8962
|
"filesystem-browse",
|
|
8862
8963
|
"flood",
|
|
8863
8964
|
"gas",
|
|
8965
|
+
"group-commands",
|
|
8966
|
+
"group-status",
|
|
8864
8967
|
"heating-valve",
|
|
8865
8968
|
"humidifier",
|
|
8866
8969
|
"humidity-sensor",
|
|
@@ -8990,14 +9093,6 @@ Object.freeze({
|
|
|
8990
9093
|
{
|
|
8991
9094
|
"path": "aqi",
|
|
8992
9095
|
"valueType": "number"
|
|
8993
|
-
},
|
|
8994
|
-
{
|
|
8995
|
-
"path": "unit",
|
|
8996
|
-
"valueType": "string"
|
|
8997
|
-
},
|
|
8998
|
-
{
|
|
8999
|
-
"path": "precision",
|
|
9000
|
-
"valueType": "number"
|
|
9001
9096
|
}
|
|
9002
9097
|
],
|
|
9003
9098
|
"alarm-panel": [
|
|
@@ -9033,20 +9128,10 @@ Object.freeze({
|
|
|
9033
9128
|
"valueType": "boolean"
|
|
9034
9129
|
}
|
|
9035
9130
|
],
|
|
9036
|
-
"ambient-light-sensor": [
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
},
|
|
9041
|
-
{
|
|
9042
|
-
"path": "unit",
|
|
9043
|
-
"valueType": "string"
|
|
9044
|
-
},
|
|
9045
|
-
{
|
|
9046
|
-
"path": "precision",
|
|
9047
|
-
"valueType": "number"
|
|
9048
|
-
}
|
|
9049
|
-
],
|
|
9131
|
+
"ambient-light-sensor": [{
|
|
9132
|
+
"path": "lux",
|
|
9133
|
+
"valueType": "number"
|
|
9134
|
+
}],
|
|
9050
9135
|
"audio-metrics": [
|
|
9051
9136
|
{
|
|
9052
9137
|
"path": "ts",
|
|
@@ -9126,6 +9211,10 @@ Object.freeze({
|
|
|
9126
9211
|
"path": "lastUpdated",
|
|
9127
9212
|
"valueType": "number"
|
|
9128
9213
|
},
|
|
9214
|
+
{
|
|
9215
|
+
"path": "volts",
|
|
9216
|
+
"valueType": "number"
|
|
9217
|
+
},
|
|
9129
9218
|
{
|
|
9130
9219
|
"path": "lastContactAt",
|
|
9131
9220
|
"valueType": "number"
|
|
@@ -9368,10 +9457,6 @@ Object.freeze({
|
|
|
9368
9457
|
"datetime"
|
|
9369
9458
|
]
|
|
9370
9459
|
},
|
|
9371
|
-
{
|
|
9372
|
-
"path": "unit",
|
|
9373
|
-
"valueType": "string"
|
|
9374
|
-
},
|
|
9375
9460
|
{
|
|
9376
9461
|
"path": "min",
|
|
9377
9462
|
"valueType": "number"
|
|
@@ -9383,19 +9468,6 @@ Object.freeze({
|
|
|
9383
9468
|
{
|
|
9384
9469
|
"path": "step",
|
|
9385
9470
|
"valueType": "number"
|
|
9386
|
-
},
|
|
9387
|
-
{
|
|
9388
|
-
"path": "precision",
|
|
9389
|
-
"valueType": "number"
|
|
9390
|
-
},
|
|
9391
|
-
{
|
|
9392
|
-
"path": "format",
|
|
9393
|
-
"valueType": "enum",
|
|
9394
|
-
"enumValues": [
|
|
9395
|
-
"date",
|
|
9396
|
-
"time",
|
|
9397
|
-
"datetime"
|
|
9398
|
-
]
|
|
9399
9471
|
}
|
|
9400
9472
|
],
|
|
9401
9473
|
"cover": [
|
|
@@ -9636,13 +9708,8 @@ Object.freeze({
|
|
|
9636
9708
|
"path": "value",
|
|
9637
9709
|
"valueType": "string"
|
|
9638
9710
|
}, {
|
|
9639
|
-
"path": "
|
|
9640
|
-
"valueType": "
|
|
9641
|
-
"enumValues": [
|
|
9642
|
-
"date",
|
|
9643
|
-
"time",
|
|
9644
|
-
"datetime"
|
|
9645
|
-
]
|
|
9711
|
+
"path": "timestamp",
|
|
9712
|
+
"valueType": "boolean"
|
|
9646
9713
|
}],
|
|
9647
9714
|
"event-emitter": [
|
|
9648
9715
|
{
|
|
@@ -9715,6 +9782,20 @@ Object.freeze({
|
|
|
9715
9782
|
"path": "detected",
|
|
9716
9783
|
"valueType": "boolean"
|
|
9717
9784
|
}],
|
|
9785
|
+
"group-status": [
|
|
9786
|
+
{
|
|
9787
|
+
"path": "included",
|
|
9788
|
+
"valueType": "number"
|
|
9789
|
+
},
|
|
9790
|
+
{
|
|
9791
|
+
"path": "excluded",
|
|
9792
|
+
"valueType": "number"
|
|
9793
|
+
},
|
|
9794
|
+
{
|
|
9795
|
+
"path": "total",
|
|
9796
|
+
"valueType": "number"
|
|
9797
|
+
}
|
|
9798
|
+
],
|
|
9718
9799
|
"heating-valve": [{
|
|
9719
9800
|
"path": "position",
|
|
9720
9801
|
"valueType": "number"
|
|
@@ -9749,20 +9830,10 @@ Object.freeze({
|
|
|
9749
9830
|
"valueType": "number"
|
|
9750
9831
|
}
|
|
9751
9832
|
],
|
|
9752
|
-
"humidity-sensor": [
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
},
|
|
9757
|
-
{
|
|
9758
|
-
"path": "unit",
|
|
9759
|
-
"valueType": "string"
|
|
9760
|
-
},
|
|
9761
|
-
{
|
|
9762
|
-
"path": "precision",
|
|
9763
|
-
"valueType": "number"
|
|
9764
|
-
}
|
|
9765
|
-
],
|
|
9833
|
+
"humidity-sensor": [{
|
|
9834
|
+
"path": "percent",
|
|
9835
|
+
"valueType": "number"
|
|
9836
|
+
}],
|
|
9766
9837
|
"image": [{
|
|
9767
9838
|
"path": "url",
|
|
9768
9839
|
"valueType": "string"
|
|
@@ -10101,20 +10172,10 @@ Object.freeze({
|
|
|
10101
10172
|
"valueType": "boolean"
|
|
10102
10173
|
}
|
|
10103
10174
|
],
|
|
10104
|
-
"numeric-sensor": [
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
},
|
|
10109
|
-
{
|
|
10110
|
-
"path": "unit",
|
|
10111
|
-
"valueType": "string"
|
|
10112
|
-
},
|
|
10113
|
-
{
|
|
10114
|
-
"path": "precision",
|
|
10115
|
-
"valueType": "number"
|
|
10116
|
-
}
|
|
10117
|
-
],
|
|
10175
|
+
"numeric-sensor": [{
|
|
10176
|
+
"path": "value",
|
|
10177
|
+
"valueType": "number"
|
|
10178
|
+
}],
|
|
10118
10179
|
"pet-feeder": [
|
|
10119
10180
|
{
|
|
10120
10181
|
"path": "foodLevel",
|
|
@@ -10206,14 +10267,6 @@ Object.freeze({
|
|
|
10206
10267
|
{
|
|
10207
10268
|
"path": "powerFactor",
|
|
10208
10269
|
"valueType": "number"
|
|
10209
|
-
},
|
|
10210
|
-
{
|
|
10211
|
-
"path": "unit",
|
|
10212
|
-
"valueType": "string"
|
|
10213
|
-
},
|
|
10214
|
-
{
|
|
10215
|
-
"path": "precision",
|
|
10216
|
-
"valueType": "number"
|
|
10217
10270
|
}
|
|
10218
10271
|
],
|
|
10219
10272
|
"presence": [
|
|
@@ -10242,20 +10295,10 @@ Object.freeze({
|
|
|
10242
10295
|
"valueType": "number"
|
|
10243
10296
|
}
|
|
10244
10297
|
],
|
|
10245
|
-
"pressure-sensor": [
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
},
|
|
10250
|
-
{
|
|
10251
|
-
"path": "unit",
|
|
10252
|
-
"valueType": "string"
|
|
10253
|
-
},
|
|
10254
|
-
{
|
|
10255
|
-
"path": "precision",
|
|
10256
|
-
"valueType": "number"
|
|
10257
|
-
}
|
|
10258
|
-
],
|
|
10298
|
+
"pressure-sensor": [{
|
|
10299
|
+
"path": "hpa",
|
|
10300
|
+
"valueType": "number"
|
|
10301
|
+
}],
|
|
10259
10302
|
"privacy-mask": [{
|
|
10260
10303
|
"path": "enabled",
|
|
10261
10304
|
"valueType": "boolean"
|
|
@@ -10566,20 +10609,10 @@ Object.freeze({
|
|
|
10566
10609
|
"path": "tampered",
|
|
10567
10610
|
"valueType": "boolean"
|
|
10568
10611
|
}],
|
|
10569
|
-
"temperature-sensor": [
|
|
10570
|
-
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
},
|
|
10574
|
-
{
|
|
10575
|
-
"path": "unit",
|
|
10576
|
-
"valueType": "string"
|
|
10577
|
-
},
|
|
10578
|
-
{
|
|
10579
|
-
"path": "precision",
|
|
10580
|
-
"valueType": "number"
|
|
10581
|
-
}
|
|
10582
|
-
],
|
|
10612
|
+
"temperature-sensor": [{
|
|
10613
|
+
"path": "celsius",
|
|
10614
|
+
"valueType": "number"
|
|
10615
|
+
}],
|
|
10583
10616
|
"update": [
|
|
10584
10617
|
{
|
|
10585
10618
|
"path": "currentVersion",
|
|
@@ -10690,10 +10723,6 @@ Object.freeze({
|
|
|
10690
10723
|
"path": "temperature",
|
|
10691
10724
|
"valueType": "number"
|
|
10692
10725
|
},
|
|
10693
|
-
{
|
|
10694
|
-
"path": "temperatureUnit",
|
|
10695
|
-
"valueType": "string"
|
|
10696
|
-
},
|
|
10697
10726
|
{
|
|
10698
10727
|
"path": "humidity",
|
|
10699
10728
|
"valueType": "number"
|
|
@@ -10702,18 +10731,10 @@ Object.freeze({
|
|
|
10702
10731
|
"path": "pressure",
|
|
10703
10732
|
"valueType": "number"
|
|
10704
10733
|
},
|
|
10705
|
-
{
|
|
10706
|
-
"path": "pressureUnit",
|
|
10707
|
-
"valueType": "string"
|
|
10708
|
-
},
|
|
10709
10734
|
{
|
|
10710
10735
|
"path": "windSpeed",
|
|
10711
10736
|
"valueType": "number"
|
|
10712
10737
|
},
|
|
10713
|
-
{
|
|
10714
|
-
"path": "windSpeedUnit",
|
|
10715
|
-
"valueType": "string"
|
|
10716
|
-
},
|
|
10717
10738
|
{
|
|
10718
10739
|
"path": "windBearing",
|
|
10719
10740
|
"valueType": "number"
|
|
@@ -11120,7 +11141,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11120
11141
|
return DeviceRole;
|
|
11121
11142
|
}({});
|
|
11122
11143
|
//#endregion
|
|
11123
|
-
//#region ../types/dist/composition-
|
|
11144
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11124
11145
|
/**
|
|
11125
11146
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11126
11147
|
*
|
|
@@ -11875,15 +11896,74 @@ function validateExpressionSource(src) {
|
|
|
11875
11896
|
}
|
|
11876
11897
|
return null;
|
|
11877
11898
|
}
|
|
11878
|
-
/**
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11899
|
+
/**
|
|
11900
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11901
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11902
|
+
* `composition.ts` (D659).
|
|
11903
|
+
*/
|
|
11882
11904
|
var CompositionSourceRefSchema = object({
|
|
11883
11905
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11884
11906
|
addonId: string().min(1),
|
|
11885
11907
|
stableId: string().min(1)
|
|
11886
11908
|
});
|
|
11909
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11910
|
+
"temperature",
|
|
11911
|
+
"humidity",
|
|
11912
|
+
"pressure",
|
|
11913
|
+
"illuminance",
|
|
11914
|
+
"power",
|
|
11915
|
+
"energy",
|
|
11916
|
+
"battery",
|
|
11917
|
+
"numeric",
|
|
11918
|
+
"motion",
|
|
11919
|
+
"contact",
|
|
11920
|
+
"leak",
|
|
11921
|
+
"smoke",
|
|
11922
|
+
"occupancy",
|
|
11923
|
+
"binary",
|
|
11924
|
+
"switch",
|
|
11925
|
+
"light"
|
|
11926
|
+
];
|
|
11927
|
+
var NUMERIC_AGGREGATES = [
|
|
11928
|
+
"mean",
|
|
11929
|
+
"median",
|
|
11930
|
+
"min",
|
|
11931
|
+
"max",
|
|
11932
|
+
"sum"
|
|
11933
|
+
];
|
|
11934
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11935
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11936
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11937
|
+
var AGGREGATE_REDUCERS = [
|
|
11938
|
+
"mean",
|
|
11939
|
+
"median",
|
|
11940
|
+
"min",
|
|
11941
|
+
"max",
|
|
11942
|
+
"sum",
|
|
11943
|
+
"any",
|
|
11944
|
+
"all"
|
|
11945
|
+
];
|
|
11946
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11947
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11948
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11949
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11950
|
+
var HelperMemberSchema = object({
|
|
11951
|
+
source: CompositionSourceRefSchema,
|
|
11952
|
+
cap: string().min(1),
|
|
11953
|
+
fieldPath: string().min(1)
|
|
11954
|
+
});
|
|
11955
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11956
|
+
kind: literal("group"),
|
|
11957
|
+
templateId: GroupTemplateIdSchema,
|
|
11958
|
+
aggregate: AggregateReducerSchema,
|
|
11959
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11960
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11961
|
+
active: ActiveCriterionSchema.optional()
|
|
11962
|
+
})]);
|
|
11963
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11964
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11965
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11966
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11887
11967
|
/** One field of one capability of one source device. */
|
|
11888
11968
|
var CompositionFieldReadSchema = object({
|
|
11889
11969
|
source: CompositionSourceRefSchema,
|
|
@@ -11927,7 +12007,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11927
12007
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11928
12008
|
CompositionFromSourceSchema,
|
|
11929
12009
|
CompositionExpressionSourceSchema,
|
|
11930
|
-
CompositionCodeSourceSchema
|
|
12010
|
+
CompositionCodeSourceSchema,
|
|
12011
|
+
object({
|
|
12012
|
+
kind: literal("aggregate"),
|
|
12013
|
+
reducer: _enum([
|
|
12014
|
+
"mean",
|
|
12015
|
+
"median",
|
|
12016
|
+
"min",
|
|
12017
|
+
"max",
|
|
12018
|
+
"sum",
|
|
12019
|
+
"any",
|
|
12020
|
+
"all"
|
|
12021
|
+
]),
|
|
12022
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12023
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12024
|
+
publish: _enum([
|
|
12025
|
+
"value",
|
|
12026
|
+
"included",
|
|
12027
|
+
"excluded",
|
|
12028
|
+
"total"
|
|
12029
|
+
]),
|
|
12030
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12031
|
+
empty: _enum([
|
|
12032
|
+
"null",
|
|
12033
|
+
"omit",
|
|
12034
|
+
"offline"
|
|
12035
|
+
])
|
|
12036
|
+
})
|
|
11931
12037
|
]);
|
|
11932
12038
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11933
12039
|
kind: literal("forward"),
|
|
@@ -11973,7 +12079,13 @@ var CompositionSchema = object({
|
|
|
11973
12079
|
kind: literal("existing"),
|
|
11974
12080
|
device: CompositionSourceRefSchema
|
|
11975
12081
|
})]),
|
|
11976
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12082
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12083
|
+
/**
|
|
12084
|
+
* Present when the block is a helper template. Absent on a free
|
|
12085
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12086
|
+
* never the compiled features.
|
|
12087
|
+
*/
|
|
12088
|
+
helper: HelperSpecSchema.optional()
|
|
11977
12089
|
}).superRefine((composition, ctx) => {
|
|
11978
12090
|
const seen = /* @__PURE__ */ new Set();
|
|
11979
12091
|
composition.features.forEach((feature, index) => {
|
|
@@ -18211,7 +18323,11 @@ var CompositionProblemSchema = object({
|
|
|
18211
18323
|
"item-field-reserved",
|
|
18212
18324
|
"target-missing",
|
|
18213
18325
|
"target-unreadable",
|
|
18214
|
-
"not-replaceable"
|
|
18326
|
+
"not-replaceable",
|
|
18327
|
+
"native-capability-replace",
|
|
18328
|
+
"mixed-quantity",
|
|
18329
|
+
"helper-mismatch",
|
|
18330
|
+
"member-constraint"
|
|
18215
18331
|
]),
|
|
18216
18332
|
path: string(),
|
|
18217
18333
|
message: string()
|
|
@@ -18232,7 +18348,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18232
18348
|
"null",
|
|
18233
18349
|
"offline",
|
|
18234
18350
|
"unknown",
|
|
18235
|
-
"release"
|
|
18351
|
+
"release",
|
|
18352
|
+
"omit"
|
|
18236
18353
|
]);
|
|
18237
18354
|
/**
|
|
18238
18355
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18269,9 +18386,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18269
18386
|
reads: array(CompositionFieldReadSchema)
|
|
18270
18387
|
});
|
|
18271
18388
|
/**
|
|
18272
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18273
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18274
|
-
*
|
|
18389
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18390
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18391
|
+
* Replacing a capability the device already serves is refused
|
|
18392
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18393
|
+
* wire for a claim the hub already holds.
|
|
18275
18394
|
*/
|
|
18276
18395
|
var CompositionFeatureModeSchema = _enum([
|
|
18277
18396
|
"new",
|
|
@@ -18444,6 +18563,275 @@ Object.freeze({
|
|
|
18444
18563
|
result: ["number", "null"]
|
|
18445
18564
|
}
|
|
18446
18565
|
});
|
|
18566
|
+
/**
|
|
18567
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18568
|
+
* Data, not a form default written into the block.
|
|
18569
|
+
*/
|
|
18570
|
+
var NOW = {
|
|
18571
|
+
fieldPath: "lastFetchedAt",
|
|
18572
|
+
expr: "now"
|
|
18573
|
+
};
|
|
18574
|
+
var CHANGED = {
|
|
18575
|
+
fieldPath: "lastChangedAt",
|
|
18576
|
+
expr: "now"
|
|
18577
|
+
};
|
|
18578
|
+
function numeric(input) {
|
|
18579
|
+
return {
|
|
18580
|
+
...input,
|
|
18581
|
+
family: "numeric",
|
|
18582
|
+
deviceType: DeviceType.Sensor,
|
|
18583
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18584
|
+
commandCaps: [],
|
|
18585
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18586
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18587
|
+
accept: [{
|
|
18588
|
+
cap: input.outputCap,
|
|
18589
|
+
fieldPath: input.outputField
|
|
18590
|
+
}]
|
|
18591
|
+
};
|
|
18592
|
+
}
|
|
18593
|
+
function binary(input) {
|
|
18594
|
+
return {
|
|
18595
|
+
...input,
|
|
18596
|
+
family: "binary",
|
|
18597
|
+
deviceType: DeviceType.Sensor,
|
|
18598
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18599
|
+
commandCaps: [],
|
|
18600
|
+
quantity: "none",
|
|
18601
|
+
baseUnit: void 0,
|
|
18602
|
+
aggregates: BINARY_AGGREGATES,
|
|
18603
|
+
empty: "offline"
|
|
18604
|
+
};
|
|
18605
|
+
}
|
|
18606
|
+
var GROUP_TEMPLATES = [
|
|
18607
|
+
numeric({
|
|
18608
|
+
id: "temperature",
|
|
18609
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18610
|
+
role: DeviceRole.TemperatureSensor,
|
|
18611
|
+
outputCap: "temperature-sensor",
|
|
18612
|
+
outputField: "celsius",
|
|
18613
|
+
quantity: "temperature",
|
|
18614
|
+
defaultAggregate: "mean",
|
|
18615
|
+
empty: "null",
|
|
18616
|
+
companions: [NOW]
|
|
18617
|
+
}),
|
|
18618
|
+
numeric({
|
|
18619
|
+
id: "humidity",
|
|
18620
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18621
|
+
role: DeviceRole.HumiditySensor,
|
|
18622
|
+
outputCap: "humidity-sensor",
|
|
18623
|
+
outputField: "percent",
|
|
18624
|
+
quantity: "humidity",
|
|
18625
|
+
defaultAggregate: "mean",
|
|
18626
|
+
empty: "null",
|
|
18627
|
+
companions: [NOW]
|
|
18628
|
+
}),
|
|
18629
|
+
numeric({
|
|
18630
|
+
id: "pressure",
|
|
18631
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18632
|
+
role: DeviceRole.PressureSensor,
|
|
18633
|
+
outputCap: "pressure-sensor",
|
|
18634
|
+
outputField: "hpa",
|
|
18635
|
+
quantity: "pressure",
|
|
18636
|
+
defaultAggregate: "mean",
|
|
18637
|
+
empty: "null",
|
|
18638
|
+
companions: [NOW]
|
|
18639
|
+
}),
|
|
18640
|
+
numeric({
|
|
18641
|
+
id: "illuminance",
|
|
18642
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18643
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18644
|
+
outputCap: "ambient-light-sensor",
|
|
18645
|
+
outputField: "lux",
|
|
18646
|
+
quantity: "illuminance",
|
|
18647
|
+
defaultAggregate: "mean",
|
|
18648
|
+
empty: "null",
|
|
18649
|
+
companions: [NOW]
|
|
18650
|
+
}),
|
|
18651
|
+
numeric({
|
|
18652
|
+
id: "power",
|
|
18653
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18654
|
+
role: DeviceRole.PowerSensor,
|
|
18655
|
+
outputCap: "power-meter",
|
|
18656
|
+
outputField: "watts",
|
|
18657
|
+
quantity: "power",
|
|
18658
|
+
defaultAggregate: "sum",
|
|
18659
|
+
empty: "omit",
|
|
18660
|
+
companions: [NOW]
|
|
18661
|
+
}),
|
|
18662
|
+
numeric({
|
|
18663
|
+
id: "energy",
|
|
18664
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18665
|
+
role: DeviceRole.EnergySensor,
|
|
18666
|
+
outputCap: "power-meter",
|
|
18667
|
+
outputField: "kwhTotal",
|
|
18668
|
+
quantity: "energy",
|
|
18669
|
+
defaultAggregate: "sum",
|
|
18670
|
+
empty: "omit",
|
|
18671
|
+
companions: [NOW]
|
|
18672
|
+
}),
|
|
18673
|
+
numeric({
|
|
18674
|
+
id: "battery",
|
|
18675
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18676
|
+
role: DeviceRole.BatterySensor,
|
|
18677
|
+
outputCap: "battery",
|
|
18678
|
+
outputField: "percentage",
|
|
18679
|
+
quantity: "percentage",
|
|
18680
|
+
defaultAggregate: "mean",
|
|
18681
|
+
empty: "null",
|
|
18682
|
+
companions: [
|
|
18683
|
+
{
|
|
18684
|
+
fieldPath: "charging",
|
|
18685
|
+
expr: "\"unknown\""
|
|
18686
|
+
},
|
|
18687
|
+
{
|
|
18688
|
+
fieldPath: "sleeping",
|
|
18689
|
+
expr: "false"
|
|
18690
|
+
},
|
|
18691
|
+
{
|
|
18692
|
+
fieldPath: "lastUpdated",
|
|
18693
|
+
expr: "now"
|
|
18694
|
+
}
|
|
18695
|
+
]
|
|
18696
|
+
}),
|
|
18697
|
+
numeric({
|
|
18698
|
+
id: "numeric",
|
|
18699
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18700
|
+
role: DeviceRole.NumericSensor,
|
|
18701
|
+
outputCap: "numeric-sensor",
|
|
18702
|
+
outputField: "value",
|
|
18703
|
+
quantity: "device",
|
|
18704
|
+
defaultAggregate: "mean",
|
|
18705
|
+
empty: "null",
|
|
18706
|
+
companions: [NOW]
|
|
18707
|
+
}),
|
|
18708
|
+
binary({
|
|
18709
|
+
id: "motion",
|
|
18710
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18711
|
+
role: DeviceRole.MotionSensor,
|
|
18712
|
+
outputCap: "motion",
|
|
18713
|
+
outputField: "detected",
|
|
18714
|
+
defaultAggregate: "any",
|
|
18715
|
+
accept: [{
|
|
18716
|
+
cap: "motion",
|
|
18717
|
+
fieldPath: "detected"
|
|
18718
|
+
}],
|
|
18719
|
+
companions: [{
|
|
18720
|
+
fieldPath: "lastDetectedAt",
|
|
18721
|
+
expr: "null"
|
|
18722
|
+
}, {
|
|
18723
|
+
fieldPath: "autoClearAfterMs",
|
|
18724
|
+
expr: "null"
|
|
18725
|
+
}]
|
|
18726
|
+
}),
|
|
18727
|
+
binary({
|
|
18728
|
+
id: "contact",
|
|
18729
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18730
|
+
role: DeviceRole.ContactSensor,
|
|
18731
|
+
outputCap: "contact",
|
|
18732
|
+
outputField: "entryOpen",
|
|
18733
|
+
defaultAggregate: "any",
|
|
18734
|
+
accept: [{
|
|
18735
|
+
cap: "contact",
|
|
18736
|
+
fieldPath: "entryOpen"
|
|
18737
|
+
}],
|
|
18738
|
+
companions: [CHANGED]
|
|
18739
|
+
}),
|
|
18740
|
+
binary({
|
|
18741
|
+
id: "leak",
|
|
18742
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18743
|
+
role: DeviceRole.LeakSensor,
|
|
18744
|
+
outputCap: "flood",
|
|
18745
|
+
outputField: "flooded",
|
|
18746
|
+
defaultAggregate: "any",
|
|
18747
|
+
accept: [{
|
|
18748
|
+
cap: "flood",
|
|
18749
|
+
fieldPath: "flooded"
|
|
18750
|
+
}],
|
|
18751
|
+
companions: [CHANGED]
|
|
18752
|
+
}),
|
|
18753
|
+
binary({
|
|
18754
|
+
id: "smoke",
|
|
18755
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18756
|
+
role: DeviceRole.SmokeSensor,
|
|
18757
|
+
outputCap: "smoke",
|
|
18758
|
+
outputField: "detected",
|
|
18759
|
+
defaultAggregate: "any",
|
|
18760
|
+
accept: [{
|
|
18761
|
+
cap: "smoke",
|
|
18762
|
+
fieldPath: "detected"
|
|
18763
|
+
}],
|
|
18764
|
+
companions: [CHANGED]
|
|
18765
|
+
}),
|
|
18766
|
+
binary({
|
|
18767
|
+
id: "occupancy",
|
|
18768
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18769
|
+
role: DeviceRole.BinarySensor,
|
|
18770
|
+
outputCap: "binary",
|
|
18771
|
+
outputField: "on",
|
|
18772
|
+
defaultAggregate: "any",
|
|
18773
|
+
accept: [{
|
|
18774
|
+
cap: "motion",
|
|
18775
|
+
fieldPath: "detected"
|
|
18776
|
+
}, {
|
|
18777
|
+
cap: "binary",
|
|
18778
|
+
fieldPath: "on"
|
|
18779
|
+
}],
|
|
18780
|
+
companions: [CHANGED]
|
|
18781
|
+
}),
|
|
18782
|
+
binary({
|
|
18783
|
+
id: "binary",
|
|
18784
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18785
|
+
role: DeviceRole.BinarySensor,
|
|
18786
|
+
outputCap: "binary",
|
|
18787
|
+
outputField: "on",
|
|
18788
|
+
defaultAggregate: "any",
|
|
18789
|
+
accept: [{
|
|
18790
|
+
cap: "binary",
|
|
18791
|
+
fieldPath: "on"
|
|
18792
|
+
}],
|
|
18793
|
+
companions: [CHANGED]
|
|
18794
|
+
}),
|
|
18795
|
+
actuator({
|
|
18796
|
+
id: "switch",
|
|
18797
|
+
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.",
|
|
18798
|
+
deviceType: DeviceType.Switch,
|
|
18799
|
+
outputCap: "switch",
|
|
18800
|
+
commandCaps: ["switch"]
|
|
18801
|
+
}),
|
|
18802
|
+
actuator({
|
|
18803
|
+
id: "light",
|
|
18804
|
+
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.",
|
|
18805
|
+
deviceType: DeviceType.Light,
|
|
18806
|
+
outputCap: "switch",
|
|
18807
|
+
commandCaps: [
|
|
18808
|
+
"switch",
|
|
18809
|
+
"brightness",
|
|
18810
|
+
"color"
|
|
18811
|
+
]
|
|
18812
|
+
})
|
|
18813
|
+
];
|
|
18814
|
+
function actuator(input) {
|
|
18815
|
+
return {
|
|
18816
|
+
...input,
|
|
18817
|
+
family: "actuator",
|
|
18818
|
+
role: void 0,
|
|
18819
|
+
memberDeviceType: input.deviceType,
|
|
18820
|
+
outputField: "on",
|
|
18821
|
+
quantity: "none",
|
|
18822
|
+
baseUnit: void 0,
|
|
18823
|
+
aggregates: BINARY_AGGREGATES,
|
|
18824
|
+
defaultAggregate: "any",
|
|
18825
|
+
empty: "offline",
|
|
18826
|
+
accept: [{
|
|
18827
|
+
cap: "switch",
|
|
18828
|
+
fieldPath: "on"
|
|
18829
|
+
}],
|
|
18830
|
+
companions: [CHANGED]
|
|
18831
|
+
};
|
|
18832
|
+
}
|
|
18833
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18834
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18447
18835
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18448
18836
|
/**
|
|
18449
18837
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20157,12 +20545,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20157
20545
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20158
20546
|
* in-place so dispatch keeps working.
|
|
20159
20547
|
*
|
|
20160
|
-
* **
|
|
20161
|
-
*
|
|
20162
|
-
*
|
|
20163
|
-
*
|
|
20164
|
-
* (`ha-domain-mapping`)
|
|
20165
|
-
* stored after that point.
|
|
20548
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20549
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20550
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20551
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20552
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20553
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20166
20554
|
*
|
|
20167
20555
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20168
20556
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20176,6 +20564,14 @@ var SourceInfoSchema = object({
|
|
|
20176
20564
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20177
20565
|
* Used to detect rename when `id` changes. */
|
|
20178
20566
|
uniqueId: string().optional(),
|
|
20567
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20568
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20569
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20570
|
+
dateTimeShape: _enum([
|
|
20571
|
+
"date",
|
|
20572
|
+
"time",
|
|
20573
|
+
"datetime"
|
|
20574
|
+
]).optional(),
|
|
20179
20575
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20180
20576
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20181
20577
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41088,7 +41484,8 @@ method(object({
|
|
|
41088
41484
|
"enum"
|
|
41089
41485
|
]),
|
|
41090
41486
|
enumValues: array(string()).optional(),
|
|
41091
|
-
item: boolean().optional()
|
|
41487
|
+
item: boolean().optional(),
|
|
41488
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41092
41489
|
})).readonly(),
|
|
41093
41490
|
itemArray: object({
|
|
41094
41491
|
path: string(),
|
|
@@ -44910,8 +45307,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44910
45307
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44911
45308
|
var MaskGridShapeSchema = object({
|
|
44912
45309
|
kind: literal("grid"),
|
|
44913
|
-
gridWidth: number(),
|
|
44914
|
-
gridHeight: number(),
|
|
45310
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45311
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44915
45312
|
cells: array(boolean())
|
|
44916
45313
|
});
|
|
44917
45314
|
discriminatedUnion("kind", [
|
|
@@ -45023,6 +45420,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45023
45420
|
"detection-blind",
|
|
45024
45421
|
"motion-noisy",
|
|
45025
45422
|
"motion-calm",
|
|
45423
|
+
"package-llm-silent",
|
|
45424
|
+
"package-llm-answered",
|
|
45026
45425
|
"recording-stalled",
|
|
45027
45426
|
"recording-healthy",
|
|
45028
45427
|
"recording-degraded",
|
|
@@ -56037,6 +56436,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56037
56436
|
deprecated: string().optional(),
|
|
56038
56437
|
distTags: array(string()).readonly()
|
|
56039
56438
|
});
|
|
56439
|
+
/**
|
|
56440
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56441
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56442
|
+
* tarball failure — never an empty string standing in for either.
|
|
56443
|
+
*/
|
|
56444
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56445
|
+
object({
|
|
56446
|
+
status: literal("ok"),
|
|
56447
|
+
markdown: string()
|
|
56448
|
+
}),
|
|
56449
|
+
object({ status: literal("missing") }),
|
|
56450
|
+
object({
|
|
56451
|
+
status: literal("error"),
|
|
56452
|
+
message: string()
|
|
56453
|
+
})
|
|
56454
|
+
]);
|
|
56455
|
+
var PackageDocsSchema = object({
|
|
56456
|
+
name: string(),
|
|
56457
|
+
version: string(),
|
|
56458
|
+
readme: PackageDocBodySchema,
|
|
56459
|
+
changelog: PackageDocBodySchema
|
|
56460
|
+
});
|
|
56040
56461
|
var SearchResultSchema = object({
|
|
56041
56462
|
name: string(),
|
|
56042
56463
|
version: string(),
|
|
@@ -56255,7 +56676,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56255
56676
|
}), object({ success: literal(true) }), {
|
|
56256
56677
|
kind: "mutation",
|
|
56257
56678
|
auth: "admin"
|
|
56258
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56679
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56680
|
+
name: string().min(1),
|
|
56681
|
+
version: string().min(1).optional()
|
|
56682
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56259
56683
|
kind: "mutation",
|
|
56260
56684
|
auth: "admin"
|
|
56261
56685
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56305,46 +56729,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56305
56729
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56306
56730
|
object({
|
|
56307
56731
|
/** Carbon dioxide concentration in ppm. */
|
|
56308
|
-
co2Ppm: number().min(0).optional(),
|
|
56732
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56309
56733
|
/** Total volatile organic compounds in ppb. */
|
|
56310
|
-
vocPpb: number().min(0).optional(),
|
|
56734
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56311
56735
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56312
|
-
pm25: number().min(0).optional(),
|
|
56736
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56313
56737
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56314
|
-
pm10: number().min(0).optional(),
|
|
56738
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56315
56739
|
/** Composite AQI value (typically 0..500). */
|
|
56316
|
-
aqi: number().optional(),
|
|
56740
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56317
56741
|
/** Ms epoch when the slice was last updated. */
|
|
56318
|
-
lastFetchedAt: number()
|
|
56319
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56320
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56321
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56322
|
-
* per slice is unambiguous. */
|
|
56323
|
-
unit: string().optional(),
|
|
56324
|
-
/** Suggested decimal places for numeric display.
|
|
56325
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56326
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56327
|
-
* auto-formatting when absent. */
|
|
56328
|
-
precision: number().int().min(0).max(10).optional()
|
|
56742
|
+
lastFetchedAt: number()
|
|
56329
56743
|
});
|
|
56330
56744
|
DeviceType.Sensor;
|
|
56331
56745
|
object({
|
|
56332
|
-
/** Current illuminance in lux (lx). */
|
|
56333
|
-
lux: number().min(0).meta({
|
|
56334
|
-
|
|
56746
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56747
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56748
|
+
precision: 0,
|
|
56335
56749
|
label: "Illuminance"
|
|
56336
|
-
}),
|
|
56750
|
+
})),
|
|
56337
56751
|
/** Ms epoch when the slice was last updated. */
|
|
56338
|
-
lastFetchedAt: number()
|
|
56339
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56340
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56341
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56342
|
-
unit: string().optional(),
|
|
56343
|
-
/** Suggested decimal places for numeric display.
|
|
56344
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56345
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56346
|
-
* auto-formatting when absent. */
|
|
56347
|
-
precision: number().int().min(0).max(10).optional()
|
|
56752
|
+
lastFetchedAt: number()
|
|
56348
56753
|
});
|
|
56349
56754
|
DeviceType.Sensor;
|
|
56350
56755
|
/**
|
|
@@ -56489,10 +56894,7 @@ var BatteryStatusSchema = object({
|
|
|
56489
56894
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56490
56895
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56491
56896
|
*/
|
|
56492
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56493
|
-
unit: "%",
|
|
56494
|
-
label: "Charge"
|
|
56495
|
-
}),
|
|
56897
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56496
56898
|
/**
|
|
56497
56899
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56498
56900
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56519,7 +56921,14 @@ var BatteryStatusSchema = object({
|
|
|
56519
56921
|
*/
|
|
56520
56922
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56521
56923
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56522
|
-
lastUpdated: number(),
|
|
56924
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56925
|
+
/**
|
|
56926
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56927
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56928
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56929
|
+
* `numeric-sensor` on the same device.
|
|
56930
|
+
*/
|
|
56931
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56523
56932
|
/**
|
|
56524
56933
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56525
56934
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56579,7 +56988,7 @@ object({
|
|
|
56579
56988
|
DeviceType.Sensor;
|
|
56580
56989
|
object({
|
|
56581
56990
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56582
|
-
percentage: number().min(0).max(100),
|
|
56991
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56583
56992
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56584
56993
|
lastChangedAt: number()
|
|
56585
56994
|
});
|
|
@@ -56964,21 +57373,21 @@ object({
|
|
|
56964
57373
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56965
57374
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56966
57375
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56967
|
-
target: number().nullable(),
|
|
57376
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56968
57377
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56969
57378
|
* in `heat_cool` mode. */
|
|
56970
|
-
targetHigh: number().nullable(),
|
|
57379
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56971
57380
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56972
57381
|
* in `heat_cool` mode. */
|
|
56973
|
-
targetLow: number().nullable(),
|
|
57382
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56974
57383
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56975
57384
|
* humidity control. */
|
|
56976
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57385
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56977
57386
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56978
57387
|
* the device's internal sensor. */
|
|
56979
|
-
currentTemp: number().nullable(),
|
|
57388
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56980
57389
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56981
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57390
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56982
57391
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56983
57392
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56984
57393
|
swingVertical: boolean().nullable(),
|
|
@@ -56986,11 +57395,11 @@ object({
|
|
|
56986
57395
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56987
57396
|
swingHorizontal: boolean().nullable(),
|
|
56988
57397
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56989
|
-
minTemp: number().nullable().optional(),
|
|
57398
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56990
57399
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56991
|
-
maxTemp: number().nullable().optional(),
|
|
57400
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56992
57401
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56993
|
-
tempStep: number().positive().nullable().optional(),
|
|
57402
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56994
57403
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56995
57404
|
lastFetchedAt: number()
|
|
56996
57405
|
});
|
|
@@ -57069,17 +57478,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
57069
57478
|
* modes to expose in the picker without a slice fetch.
|
|
57070
57479
|
*/
|
|
57071
57480
|
var RgbTripletSchema = object({
|
|
57072
|
-
r: number().int().min(0).max(255),
|
|
57073
|
-
g: number().int().min(0).max(255),
|
|
57074
|
-
b: number().int().min(0).max(255)
|
|
57481
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57482
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57483
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57075
57484
|
});
|
|
57076
57485
|
var HsvTripletSchema = object({
|
|
57077
57486
|
/** Hue in degrees, 0..360. */
|
|
57078
|
-
h: number().min(0).max(360),
|
|
57487
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57079
57488
|
/** Saturation as 0..100 inclusive. */
|
|
57080
|
-
s: number().min(0).max(100),
|
|
57489
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57081
57490
|
/** Value/brightness as 0..100 inclusive. */
|
|
57082
|
-
v: number().min(0).max(100)
|
|
57491
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57083
57492
|
});
|
|
57084
57493
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57085
57494
|
object({
|
|
@@ -57108,7 +57517,7 @@ object({
|
|
|
57108
57517
|
/** Populated when `mode === 'hsv'`. */
|
|
57109
57518
|
hsv: HsvTripletSchema.optional(),
|
|
57110
57519
|
/** Populated when `mode === 'mired'`. */
|
|
57111
|
-
mireds: number().int().optional(),
|
|
57520
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57112
57521
|
/** Ms epoch of the last operator-driven change. */
|
|
57113
57522
|
lastChangedAt: number()
|
|
57114
57523
|
});
|
|
@@ -57232,18 +57641,12 @@ _enum([
|
|
|
57232
57641
|
"empty",
|
|
57233
57642
|
"full"
|
|
57234
57643
|
]);
|
|
57235
|
-
/**
|
|
57236
|
-
|
|
57237
|
-
|
|
57238
|
-
"days",
|
|
57239
|
-
"hours",
|
|
57240
|
-
"cycles"
|
|
57241
|
-
]);
|
|
57242
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57243
|
-
* days). `value` null = unknown (D393). */
|
|
57644
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57645
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57646
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57244
57647
|
var ConsumableRemainingSchema = object({
|
|
57245
|
-
value: number().min(0).nullable(),
|
|
57246
|
-
|
|
57648
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57649
|
+
kind: ConsumableRemainingKindSchema
|
|
57247
57650
|
});
|
|
57248
57651
|
var ConsumablesStatusSchema = object({
|
|
57249
57652
|
items: array(object({
|
|
@@ -57252,7 +57655,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57252
57655
|
/** Display name. */
|
|
57253
57656
|
label: string().min(1),
|
|
57254
57657
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57255
|
-
level: number().min(0).max(100).nullable(),
|
|
57658
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57256
57659
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57257
57660
|
status: ConsumableStatusSchema.nullable(),
|
|
57258
57661
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57269,7 +57672,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57269
57672
|
})),
|
|
57270
57673
|
lastChangedAt: number()
|
|
57271
57674
|
});
|
|
57272
|
-
Object.values(DeviceType), [...
|
|
57675
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57273
57676
|
Object.values(DeviceType), method(object({
|
|
57274
57677
|
deviceId: number().int().nonnegative(),
|
|
57275
57678
|
key: string().min(1)
|
|
@@ -57294,39 +57697,17 @@ object({
|
|
|
57294
57697
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57295
57698
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57296
57699
|
* or time-only — HA accepts all three forms). */
|
|
57297
|
-
value: union([number(), string()]),
|
|
57700
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57298
57701
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57299
57702
|
options: array(string()),
|
|
57300
57703
|
/** Ms epoch when the slice was last updated. */
|
|
57301
57704
|
lastChangedAt: number(),
|
|
57302
|
-
/**
|
|
57303
|
-
|
|
57304
|
-
|
|
57305
|
-
|
|
57306
|
-
/**
|
|
57307
|
-
|
|
57308
|
-
min: number().optional(),
|
|
57309
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57310
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57311
|
-
max: number().optional(),
|
|
57312
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57313
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57314
|
-
step: number().optional(),
|
|
57315
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57316
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57317
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57318
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57319
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57320
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57321
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57322
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57323
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57324
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57325
|
-
format: _enum([
|
|
57326
|
-
"date",
|
|
57327
|
-
"time",
|
|
57328
|
-
"datetime"
|
|
57329
|
-
]).optional()
|
|
57705
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57706
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57707
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57708
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57709
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57710
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57330
57711
|
});
|
|
57331
57712
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57332
57713
|
object({
|
|
@@ -57364,9 +57745,9 @@ object({
|
|
|
57364
57745
|
]),
|
|
57365
57746
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57366
57747
|
* no intermediate position surface. */
|
|
57367
|
-
position: number().min(0).max(100).nullable(),
|
|
57748
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57368
57749
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57369
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57750
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57370
57751
|
/** Ms epoch when the slice was last updated. */
|
|
57371
57752
|
lastChangedAt: number()
|
|
57372
57753
|
});
|
|
@@ -57424,9 +57805,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57424
57805
|
object({
|
|
57425
57806
|
mode: DayNightModeSchema,
|
|
57426
57807
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57427
|
-
sensitivity: number().optional(),
|
|
57808
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57428
57809
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57429
|
-
switchDelaySec: number().optional(),
|
|
57810
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57430
57811
|
lastFetchedAt: number()
|
|
57431
57812
|
});
|
|
57432
57813
|
/**
|
|
@@ -57581,11 +57962,11 @@ object({
|
|
|
57581
57962
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57582
57963
|
availablePrograms: array(string()),
|
|
57583
57964
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57584
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57965
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57585
57966
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57586
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57967
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57587
57968
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57588
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57969
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57589
57970
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57590
57971
|
doorOpen: boolean().nullable(),
|
|
57591
57972
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57609,7 +57990,7 @@ object({
|
|
|
57609
57990
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57610
57991
|
machineCareDue: boolean().nullable(),
|
|
57611
57992
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57612
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57993
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57613
57994
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57614
57995
|
halfLoad: boolean().nullable(),
|
|
57615
57996
|
hygienePlus: boolean().nullable(),
|
|
@@ -57624,7 +58005,7 @@ object({
|
|
|
57624
58005
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57625
58006
|
activeEvents: array(string()),
|
|
57626
58007
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57627
|
-
errorCode: number().nullable(),
|
|
58008
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57628
58009
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57629
58010
|
errorLabel: string().nullable(),
|
|
57630
58011
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57770,24 +58151,14 @@ object({
|
|
|
57770
58151
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57771
58152
|
lastPressedAt: number().nullable(),
|
|
57772
58153
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57773
|
-
pressCountSinceStart: number()
|
|
58154
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57774
58155
|
});
|
|
57775
58156
|
object({
|
|
57776
58157
|
deviceId: number(),
|
|
57777
58158
|
timestamp: number()
|
|
57778
58159
|
});
|
|
57779
58160
|
DeviceType.Button, DeviceType.Camera;
|
|
57780
|
-
|
|
57781
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57782
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57783
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57784
|
-
* The option set is stable across observations; it is persisted in the
|
|
57785
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57786
|
-
* stored in `sourceInfo`.
|
|
57787
|
-
*/
|
|
57788
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57789
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57790
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
58161
|
+
_enum([
|
|
57791
58162
|
"date",
|
|
57792
58163
|
"time",
|
|
57793
58164
|
"datetime"
|
|
@@ -57795,12 +58166,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57795
58166
|
object({
|
|
57796
58167
|
value: string(),
|
|
57797
58168
|
/**
|
|
57798
|
-
* Set
|
|
57799
|
-
* as
|
|
57800
|
-
*
|
|
57801
|
-
* a time-only sensor → `'time'`.
|
|
58169
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
58170
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
58171
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57802
58172
|
*/
|
|
57803
|
-
|
|
58173
|
+
timestamp: boolean().optional(),
|
|
57804
58174
|
/** Ms epoch when the slice was last updated. */
|
|
57805
58175
|
lastFetchedAt: number()
|
|
57806
58176
|
});
|
|
@@ -57819,13 +58189,13 @@ var EventFireSchema = object({
|
|
|
57819
58189
|
deviceId: number(),
|
|
57820
58190
|
eventType: string(),
|
|
57821
58191
|
data: record(string(), unknown()).nullable(),
|
|
57822
|
-
timestamp: number(),
|
|
57823
|
-
seq: number()
|
|
58192
|
+
timestamp: number().meta(readingMeta("none")),
|
|
58193
|
+
seq: number().meta(readingMeta("count"))
|
|
57824
58194
|
});
|
|
57825
58195
|
object({
|
|
57826
58196
|
eventTypes: array(string()),
|
|
57827
58197
|
lastEvent: EventFireSchema.nullable(),
|
|
57828
|
-
eventCountSinceStart: number()
|
|
58198
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57829
58199
|
});
|
|
57830
58200
|
DeviceType.EventEmitter;
|
|
57831
58201
|
var IdentitySchema = object({
|
|
@@ -58214,10 +58584,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58214
58584
|
object({
|
|
58215
58585
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58216
58586
|
* speed surface (single-speed fan). */
|
|
58217
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58587
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58218
58588
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58219
58589
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58220
|
-
percentageStep: number().positive().optional(),
|
|
58590
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58221
58591
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58222
58592
|
* — empty string when no preset is active or supported. */
|
|
58223
58593
|
preset: string(),
|
|
@@ -58299,7 +58669,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58299
58669
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58300
58670
|
model: string().nullable(),
|
|
58301
58671
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58302
|
-
channelCount: number().nullable(),
|
|
58672
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58303
58673
|
/**
|
|
58304
58674
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58305
58675
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58331,9 +58701,39 @@ object({
|
|
|
58331
58701
|
lastChangedAt: number()
|
|
58332
58702
|
});
|
|
58333
58703
|
DeviceType.Sensor;
|
|
58704
|
+
object({
|
|
58705
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58706
|
+
results: array(object({
|
|
58707
|
+
deviceId: number().int().nonnegative(),
|
|
58708
|
+
cap: string().min(1),
|
|
58709
|
+
method: string().min(1),
|
|
58710
|
+
ok: boolean(),
|
|
58711
|
+
error: string().optional(),
|
|
58712
|
+
/** Ms epoch of the attempt. */
|
|
58713
|
+
at: number()
|
|
58714
|
+
})) });
|
|
58715
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58716
|
+
object({
|
|
58717
|
+
/** Members whose current value entered the aggregate. */
|
|
58718
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58719
|
+
precision: 0,
|
|
58720
|
+
label: "Reporting"
|
|
58721
|
+
})),
|
|
58722
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58723
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58724
|
+
precision: 0,
|
|
58725
|
+
label: "Excluded"
|
|
58726
|
+
})),
|
|
58727
|
+
/** `included` + `excluded`. */
|
|
58728
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58729
|
+
precision: 0,
|
|
58730
|
+
label: "Members"
|
|
58731
|
+
}))
|
|
58732
|
+
});
|
|
58733
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58334
58734
|
object({
|
|
58335
58735
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58336
|
-
position: number().min(0).max(100).nullable(),
|
|
58736
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58337
58737
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58338
58738
|
lastFetchedAt: number()
|
|
58339
58739
|
});
|
|
@@ -58342,9 +58742,9 @@ object({
|
|
|
58342
58742
|
/** Whether the humidifier is currently on. */
|
|
58343
58743
|
on: boolean(),
|
|
58344
58744
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58345
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58745
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58346
58746
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58347
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58747
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58348
58748
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58349
58749
|
* device has no mode surface. */
|
|
58350
58750
|
mode: string().nullable(),
|
|
@@ -58354,9 +58754,9 @@ object({
|
|
|
58354
58754
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58355
58755
|
action: string().nullable(),
|
|
58356
58756
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58357
|
-
minHumidity: number().nullable(),
|
|
58757
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58358
58758
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58359
|
-
maxHumidity: number().nullable(),
|
|
58759
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58360
58760
|
/** Ms epoch when the slice was last updated. */
|
|
58361
58761
|
lastChangedAt: number()
|
|
58362
58762
|
});
|
|
@@ -58380,22 +58780,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58380
58780
|
auth: "protected"
|
|
58381
58781
|
});
|
|
58382
58782
|
object({
|
|
58383
|
-
/** Current relative humidity, 0..100. */
|
|
58384
|
-
percent: number().min(0).max(100).meta({
|
|
58385
|
-
|
|
58783
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58784
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58785
|
+
precision: 0,
|
|
58386
58786
|
label: "Humidity"
|
|
58387
|
-
}),
|
|
58787
|
+
})),
|
|
58388
58788
|
/** Ms epoch when the slice was last updated. */
|
|
58389
|
-
lastFetchedAt: number()
|
|
58390
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58391
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58392
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58393
|
-
unit: string().optional(),
|
|
58394
|
-
/** Suggested decimal places for numeric display.
|
|
58395
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58396
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58397
|
-
* auto-formatting when absent. */
|
|
58398
|
-
precision: number().int().min(0).max(10).optional()
|
|
58789
|
+
lastFetchedAt: number()
|
|
58399
58790
|
});
|
|
58400
58791
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58401
58792
|
object({
|
|
@@ -58403,7 +58794,7 @@ object({
|
|
|
58403
58794
|
* entity exposes no `entity_picture` (yet). */
|
|
58404
58795
|
url: string().nullable(),
|
|
58405
58796
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58406
|
-
lastUpdated: number().nullable()
|
|
58797
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58407
58798
|
});
|
|
58408
58799
|
DeviceType.Image;
|
|
58409
58800
|
/**
|
|
@@ -58459,19 +58850,19 @@ var NormalizedRangeSchema = object({
|
|
|
58459
58850
|
});
|
|
58460
58851
|
object({
|
|
58461
58852
|
/** Normalized 0–100. */
|
|
58462
|
-
brightness: number().optional(),
|
|
58853
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58463
58854
|
/** Normalized 0–100. */
|
|
58464
|
-
contrast: number().optional(),
|
|
58855
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58465
58856
|
/** Normalized 0–100. */
|
|
58466
|
-
saturation: number().optional(),
|
|
58857
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58467
58858
|
/** Normalized 0–100. */
|
|
58468
|
-
sharpness: number().optional(),
|
|
58859
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58469
58860
|
mirror: boolean().optional(),
|
|
58470
58861
|
flip: boolean().optional(),
|
|
58471
58862
|
rotate: ImageRotateSchema.optional(),
|
|
58472
58863
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58473
58864
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58474
|
-
warmth: number().optional(),
|
|
58865
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58475
58866
|
exposureMode: ExposureModeSchema.optional(),
|
|
58476
58867
|
backlightMode: BacklightModeSchema.optional(),
|
|
58477
58868
|
lastFetchedAt: number()
|
|
@@ -58716,10 +59107,10 @@ var IntercomAbilitySchema = object({
|
|
|
58716
59107
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58717
59108
|
codecs: array(string()),
|
|
58718
59109
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58719
|
-
sampleRate: number(),
|
|
59110
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58720
59111
|
duplex: _enum(["half", "full"]),
|
|
58721
59112
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58722
|
-
maxBacklogMs: number()
|
|
59113
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58723
59114
|
});
|
|
58724
59115
|
var IntercomStatusSchema = object({
|
|
58725
59116
|
/** True while a talk session is open. */
|
|
@@ -58830,13 +59221,13 @@ object({
|
|
|
58830
59221
|
activity: LawnMowerActivitySchema,
|
|
58831
59222
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58832
59223
|
* reading. */
|
|
58833
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
59224
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58834
59225
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58835
59226
|
* task is active / progress is unavailable. */
|
|
58836
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59227
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58837
59228
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58838
59229
|
* or null when unknown. */
|
|
58839
|
-
currentCode: number().nullable(),
|
|
59230
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58840
59231
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58841
59232
|
currentCodeLabel: string().nullable(),
|
|
58842
59233
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59298,7 +59689,7 @@ object({
|
|
|
59298
59689
|
state: MediaPlayerStateSchema,
|
|
59299
59690
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59300
59691
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59301
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59692
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59302
59693
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59303
59694
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59304
59695
|
isMuted: boolean().nullable(),
|
|
@@ -59311,10 +59702,10 @@ object({
|
|
|
59311
59702
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59312
59703
|
/** Current playback position in ms. Null when not seekable or
|
|
59313
59704
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59314
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59705
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59315
59706
|
/** Total duration of the current media in ms. Null when unknown
|
|
59316
59707
|
* (live stream) or nothing is playing. */
|
|
59317
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59708
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59318
59709
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59319
59710
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59320
59711
|
shuffle: boolean().nullable(),
|
|
@@ -59614,7 +60005,7 @@ object({
|
|
|
59614
60005
|
* it, every provider seeded it at boot, and every session left it
|
|
59615
60006
|
* `detected: true` after its detach.
|
|
59616
60007
|
*/
|
|
59617
|
-
autoClearAfterMs: number().nullable()
|
|
60008
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59618
60009
|
});
|
|
59619
60010
|
/**
|
|
59620
60011
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59664,7 +60055,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59664
60055
|
});
|
|
59665
60056
|
object({
|
|
59666
60057
|
enabled: boolean(),
|
|
59667
|
-
sensitivity: number(),
|
|
60058
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59668
60059
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59669
60060
|
regions: array(MotionZoneRegionSchema),
|
|
59670
60061
|
lastFetchedAt: number()
|
|
@@ -59968,7 +60359,7 @@ var NavigationStatusSchema = object({
|
|
|
59968
60359
|
following: boolean(),
|
|
59969
60360
|
flash: boolean(),
|
|
59970
60361
|
lightMode: NavigationLightModeSchema,
|
|
59971
|
-
lightLevel: number().min(40).max(100),
|
|
60362
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59972
60363
|
/** Ms epoch when the slice was last updated. */
|
|
59973
60364
|
lastChangedAt: number()
|
|
59974
60365
|
});
|
|
@@ -60014,13 +60405,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
60014
60405
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
60015
60406
|
* SKIP a null rather than coerce it.
|
|
60016
60407
|
*/
|
|
60017
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
60408
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60018
60409
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
60019
|
-
rssiDbm: number().optional(),
|
|
60410
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
60020
60411
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
60021
60412
|
ssid: string().optional(),
|
|
60022
60413
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60023
|
-
lastUpdated: number()
|
|
60414
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
60024
60415
|
});
|
|
60025
60416
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
60026
60417
|
deviceId: number(),
|
|
@@ -60339,7 +60730,7 @@ object({
|
|
|
60339
60730
|
lastError: string().nullable(),
|
|
60340
60731
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60341
60732
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60342
|
-
queueDepth: number().int().nonnegative(),
|
|
60733
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60343
60734
|
/** Per-feature capability matrix — authoritative source for the
|
|
60344
60735
|
* compose-form field gating. */
|
|
60345
60736
|
supports: NotifierSupportsSchema
|
|
@@ -60389,15 +60780,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60389
60780
|
acceptedAt: number()
|
|
60390
60781
|
});
|
|
60391
60782
|
object({
|
|
60392
|
-
|
|
60393
|
-
|
|
60394
|
-
* Populated live from the upstream source on each state push.
|
|
60395
|
-
* Absent for unitless sensors. */
|
|
60396
|
-
unit: string().optional(),
|
|
60397
|
-
/** Suggested decimal places for numeric display.
|
|
60398
|
-
* Populated live from the upstream source when provided.
|
|
60399
|
-
* Falls back to auto-formatting when absent. */
|
|
60400
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60783
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60784
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60401
60785
|
/** Ms epoch when the slice was last updated. */
|
|
60402
60786
|
lastFetchedAt: number()
|
|
60403
60787
|
});
|
|
@@ -60687,23 +61071,26 @@ object({
|
|
|
60687
61071
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60688
61072
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60689
61073
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60690
|
-
foodLevel: number().nullable(),
|
|
61074
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60691
61075
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60692
61076
|
* single-hopper models. */
|
|
60693
|
-
food1: number().nullable(),
|
|
61077
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60694
61078
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60695
61079
|
* single-hopper models. */
|
|
60696
|
-
food2: number().nullable(),
|
|
61080
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60697
61081
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60698
61082
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60699
61083
|
* below the feeder's low threshold. */
|
|
60700
61084
|
lowFood: boolean(),
|
|
60701
61085
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60702
61086
|
* device has no battery reading. */
|
|
60703
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60704
|
-
/**
|
|
60705
|
-
*
|
|
60706
|
-
|
|
61087
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61088
|
+
/**
|
|
61089
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
61090
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
61091
|
+
* model has no desiccant sensor.
|
|
61092
|
+
*/
|
|
61093
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60707
61094
|
/** True while a feed is in progress. */
|
|
60708
61095
|
feeding: boolean(),
|
|
60709
61096
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60714,7 +61101,7 @@ object({
|
|
|
60714
61101
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60715
61102
|
error: string().nullable(),
|
|
60716
61103
|
/** Raw device error code (0 / null = no error). */
|
|
60717
|
-
errorCode: number().nullable(),
|
|
61104
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60718
61105
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60719
61106
|
isDualHopper: boolean(),
|
|
60720
61107
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60724,7 +61111,7 @@ object({
|
|
|
60724
61111
|
/** Play a chime when dispensing. */
|
|
60725
61112
|
feedSound: boolean(),
|
|
60726
61113
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60727
|
-
volume: number(),
|
|
61114
|
+
volume: number().meta(readingMeta("none")),
|
|
60728
61115
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60729
61116
|
lastFetchedAt: number()
|
|
60730
61117
|
});
|
|
@@ -61161,36 +61548,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61161
61548
|
});
|
|
61162
61549
|
object({
|
|
61163
61550
|
/** Instantaneous power draw in watts. */
|
|
61164
|
-
watts: number().optional().meta({
|
|
61165
|
-
unit: "W",
|
|
61166
|
-
label: "Power"
|
|
61167
|
-
}),
|
|
61551
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61168
61552
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61169
|
-
kwhTotal: number().optional().meta({
|
|
61170
|
-
unit: "kWh",
|
|
61171
|
-
label: "Energy"
|
|
61172
|
-
}),
|
|
61553
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61173
61554
|
/** Voltage in volts. */
|
|
61174
|
-
volts: number().optional(),
|
|
61555
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61175
61556
|
/** Current in amperes. */
|
|
61176
|
-
amps: number().optional(),
|
|
61177
|
-
/** Apparent power in volt-amperes
|
|
61178
|
-
va: number().optional(),
|
|
61557
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61558
|
+
/** Apparent power in volt-amperes. */
|
|
61559
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61179
61560
|
/** Power factor (0..1) if reported. */
|
|
61180
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61561
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61181
61562
|
/** Ms epoch when the slice was last updated. */
|
|
61182
|
-
lastFetchedAt: number()
|
|
61183
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61184
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61185
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61186
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61187
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61188
|
-
unit: string().optional(),
|
|
61189
|
-
/** Suggested decimal places for numeric display.
|
|
61190
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61191
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61192
|
-
* auto-formatting when absent. */
|
|
61193
|
-
precision: number().int().min(0).max(10).optional()
|
|
61563
|
+
lastFetchedAt: number()
|
|
61194
61564
|
});
|
|
61195
61565
|
DeviceType.Sensor;
|
|
61196
61566
|
/**
|
|
@@ -61211,11 +61581,11 @@ DeviceType.Sensor;
|
|
|
61211
61581
|
*/
|
|
61212
61582
|
var GpsLocationSchema = object({
|
|
61213
61583
|
/** Latitude in decimal degrees, -90..90. */
|
|
61214
|
-
latitude: number().min(-90).max(90),
|
|
61584
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61215
61585
|
/** Longitude in decimal degrees, -180..180. */
|
|
61216
|
-
longitude: number().min(-180).max(180),
|
|
61586
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61217
61587
|
/** Reported accuracy in meters (lower = better). */
|
|
61218
|
-
accuracyMeters: number().nonnegative()
|
|
61588
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61219
61589
|
});
|
|
61220
61590
|
object({
|
|
61221
61591
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61227,25 +61597,16 @@ object({
|
|
|
61227
61597
|
gps: GpsLocationSchema.nullable(),
|
|
61228
61598
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61229
61599
|
* when not reported. */
|
|
61230
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61600
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61231
61601
|
/** Ms epoch when the slice was last updated. */
|
|
61232
61602
|
lastChangedAt: number()
|
|
61233
61603
|
});
|
|
61234
61604
|
DeviceType.Presence;
|
|
61235
61605
|
object({
|
|
61236
|
-
/** Current pressure in hPa. */
|
|
61237
|
-
hpa: number(),
|
|
61606
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61607
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61238
61608
|
/** Ms epoch when the slice was last updated. */
|
|
61239
|
-
lastFetchedAt: number()
|
|
61240
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61241
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61242
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61243
|
-
unit: string().optional(),
|
|
61244
|
-
/** Suggested decimal places for numeric display.
|
|
61245
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61246
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61247
|
-
* auto-formatting when absent. */
|
|
61248
|
-
precision: number().int().min(0).max(10).optional()
|
|
61609
|
+
lastFetchedAt: number()
|
|
61249
61610
|
});
|
|
61250
61611
|
DeviceType.Sensor;
|
|
61251
61612
|
/**
|
|
@@ -61578,8 +61939,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61578
61939
|
}), _void(), { kind: "mutation" });
|
|
61579
61940
|
var PtzAutotrackSettingsSchema = object({
|
|
61580
61941
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61581
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61582
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61942
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61943
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61583
61944
|
});
|
|
61584
61945
|
/**
|
|
61585
61946
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61636,7 +61997,7 @@ object({
|
|
|
61636
61997
|
/** null = unknown — never coerced to false (D393). */
|
|
61637
61998
|
running: boolean().nullable(),
|
|
61638
61999
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61639
|
-
since: number().nullable(),
|
|
62000
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61640
62001
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61641
62002
|
phase: string().nullable(),
|
|
61642
62003
|
/** null until a reading has been published (D393). */
|
|
@@ -62834,9 +63195,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62834
63195
|
*/
|
|
62835
63196
|
var RecordWindowSchema = object({
|
|
62836
63197
|
trigger: RecordTriggerSchema,
|
|
62837
|
-
day: number().int().min(0).max(6),
|
|
62838
|
-
startMinute: number().int().min(0).max(1439),
|
|
62839
|
-
endMinute: number().int().min(1).max(1440)
|
|
63198
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
63199
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
63200
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62840
63201
|
});
|
|
62841
63202
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62842
63203
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62905,10 +63266,10 @@ object({
|
|
|
62905
63266
|
/** Master "record to the card at all" switch. */
|
|
62906
63267
|
enabled: boolean().nullable(),
|
|
62907
63268
|
overwriteWhenFull: boolean().nullable(),
|
|
62908
|
-
preRecordSec: number().nullable(),
|
|
62909
|
-
postRecordSec: number().nullable(),
|
|
63269
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
63270
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62910
63271
|
/** Length of one recorded file, in minutes. */
|
|
62911
|
-
segmentMinutes: number().nullable(),
|
|
63272
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62912
63273
|
/** The primary track's weekly windows, flattened. */
|
|
62913
63274
|
windows: array(RecordWindowSchema),
|
|
62914
63275
|
/**
|
|
@@ -62924,7 +63285,7 @@ object({
|
|
|
62924
63285
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62925
63286
|
* writable.
|
|
62926
63287
|
*/
|
|
62927
|
-
unreadableWindows: number(),
|
|
63288
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62928
63289
|
/**
|
|
62929
63290
|
* The camera is scheduled to record and has NO usable storage.
|
|
62930
63291
|
*
|
|
@@ -63561,7 +63922,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63561
63922
|
url: string().optional(),
|
|
63562
63923
|
codec: string().optional(),
|
|
63563
63924
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63564
|
-
fps: number().positive().optional(),
|
|
63925
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63565
63926
|
label: string().optional(),
|
|
63566
63927
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63567
63928
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63591,18 +63952,18 @@ var StreamProfileSchema = _enum([
|
|
|
63591
63952
|
]);
|
|
63592
63953
|
/** The current encoding config of one stream profile. */
|
|
63593
63954
|
var StreamProfileConfigSchema = object({
|
|
63594
|
-
width: number(),
|
|
63595
|
-
height: number(),
|
|
63955
|
+
width: number().meta(readingMeta("none")),
|
|
63956
|
+
height: number().meta(readingMeta("none")),
|
|
63596
63957
|
codec: _enum(["h264", "h265"]),
|
|
63597
|
-
framerate: number(),
|
|
63598
|
-
bitrate: number(),
|
|
63958
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63959
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63599
63960
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63600
63961
|
encoderProfile: _enum([
|
|
63601
63962
|
"high",
|
|
63602
63963
|
"main",
|
|
63603
63964
|
"baseline"
|
|
63604
63965
|
]).optional(),
|
|
63605
|
-
gop: number().optional(),
|
|
63966
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63606
63967
|
/**
|
|
63607
63968
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63608
63969
|
*
|
|
@@ -64245,23 +64606,13 @@ object({
|
|
|
64245
64606
|
});
|
|
64246
64607
|
DeviceType.Sensor;
|
|
64247
64608
|
object({
|
|
64248
|
-
/** Current temperature in Celsius. */
|
|
64249
|
-
celsius: number().meta({
|
|
64250
|
-
|
|
64609
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64610
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64611
|
+
precision: 1,
|
|
64251
64612
|
label: "Temperature"
|
|
64252
|
-
}),
|
|
64613
|
+
})),
|
|
64253
64614
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64254
|
-
lastFetchedAt: number()
|
|
64255
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64256
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64257
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64258
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64259
|
-
unit: string().optional(),
|
|
64260
|
-
/** Suggested decimal places for numeric display.
|
|
64261
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64262
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64263
|
-
* auto-formatting when absent. */
|
|
64264
|
-
precision: number().int().min(0).max(10).optional()
|
|
64615
|
+
lastFetchedAt: number()
|
|
64265
64616
|
});
|
|
64266
64617
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64267
64618
|
/**
|
|
@@ -64513,16 +64864,16 @@ object({
|
|
|
64513
64864
|
]),
|
|
64514
64865
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64515
64866
|
* reading. */
|
|
64516
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64867
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64517
64868
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64518
64869
|
* the vacuum has no speed control. */
|
|
64519
64870
|
fanSpeed: string().nullable(),
|
|
64520
64871
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64521
64872
|
availableFanSpeeds: array(string()),
|
|
64522
64873
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64523
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64874
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64524
64875
|
/** Current error code (0 / null = no error). */
|
|
64525
|
-
errorCode: number().nullable(),
|
|
64876
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64526
64877
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64527
64878
|
errorLabel: string().nullable(),
|
|
64528
64879
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64561,7 +64912,7 @@ object({
|
|
|
64561
64912
|
]),
|
|
64562
64913
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64563
64914
|
* intermediate position surface. */
|
|
64564
|
-
position: number().min(0).max(100).nullable(),
|
|
64915
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64565
64916
|
/** Ms epoch when the slice was last updated. */
|
|
64566
64917
|
lastChangedAt: number()
|
|
64567
64918
|
});
|
|
@@ -64589,9 +64940,9 @@ object({
|
|
|
64589
64940
|
DeviceType.Sensor;
|
|
64590
64941
|
object({
|
|
64591
64942
|
/** Current measured temperature. Null when not reported. */
|
|
64592
|
-
currentTemp: number().nullable(),
|
|
64943
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64593
64944
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64594
|
-
targetTemp: number().nullable(),
|
|
64945
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64595
64946
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64596
64947
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64597
64948
|
* device reports an unknown state. */
|
|
@@ -64602,9 +64953,9 @@ object({
|
|
|
64602
64953
|
* has no away surface. */
|
|
64603
64954
|
away: boolean().nullable(),
|
|
64604
64955
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64605
|
-
minTemp: number().nullable(),
|
|
64956
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64606
64957
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64607
|
-
maxTemp: number().nullable(),
|
|
64958
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64608
64959
|
/** Ms epoch when the slice was last updated. */
|
|
64609
64960
|
lastChangedAt: number()
|
|
64610
64961
|
});
|
|
@@ -64628,25 +64979,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64628
64979
|
auth: "protected"
|
|
64629
64980
|
});
|
|
64630
64981
|
object({
|
|
64631
|
-
/** Verbatim
|
|
64632
|
-
* when no condition has been reported yet. */
|
|
64982
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64633
64983
|
condition: string().nullable(),
|
|
64634
|
-
/** Current temperature in
|
|
64635
|
-
temperature: number().nullable(),
|
|
64636
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64637
|
-
temperatureUnit: string().nullable(),
|
|
64984
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64985
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64638
64986
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64639
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64640
|
-
/** Barometric pressure in
|
|
64641
|
-
pressure: number().nullable(),
|
|
64642
|
-
/**
|
|
64643
|
-
|
|
64644
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64645
|
-
windSpeed: number().nullable(),
|
|
64646
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64647
|
-
windSpeedUnit: string().nullable(),
|
|
64987
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64988
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64989
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64990
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64991
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64648
64992
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64649
|
-
windBearing: number().nullable(),
|
|
64993
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64650
64994
|
/** Ms epoch when the slice was last updated. */
|
|
64651
64995
|
lastFetchedAt: number()
|
|
64652
64996
|
});
|
|
@@ -65558,6 +65902,13 @@ Object.freeze({
|
|
|
65558
65902
|
access: "view",
|
|
65559
65903
|
role: "admin"
|
|
65560
65904
|
},
|
|
65905
|
+
"addons.getPackageDocs": {
|
|
65906
|
+
capName: "addons",
|
|
65907
|
+
capScope: "system",
|
|
65908
|
+
addonId: null,
|
|
65909
|
+
access: "view",
|
|
65910
|
+
role: "admin"
|
|
65911
|
+
},
|
|
65561
65912
|
"addons.getVersions": {
|
|
65562
65913
|
capName: "addons",
|
|
65563
65914
|
capScope: "system",
|
|
@@ -68666,6 +69017,20 @@ Object.freeze({
|
|
|
68666
69017
|
access: "view",
|
|
68667
69018
|
role: "viewer"
|
|
68668
69019
|
},
|
|
69020
|
+
"groupCommands.getStatus": {
|
|
69021
|
+
capName: "group-commands",
|
|
69022
|
+
capScope: "device",
|
|
69023
|
+
addonId: null,
|
|
69024
|
+
access: "view",
|
|
69025
|
+
role: "viewer"
|
|
69026
|
+
},
|
|
69027
|
+
"groupStatus.getStatus": {
|
|
69028
|
+
capName: "group-status",
|
|
69029
|
+
capScope: "device",
|
|
69030
|
+
addonId: null,
|
|
69031
|
+
access: "view",
|
|
69032
|
+
role: "viewer"
|
|
69033
|
+
},
|
|
68669
69034
|
"heatingValve.getStatus": {
|
|
68670
69035
|
capName: "heating-valve",
|
|
68671
69036
|
capScope: "device",
|
|
@@ -78488,6 +78853,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78488
78853
|
icon: "flame"
|
|
78489
78854
|
}]
|
|
78490
78855
|
},
|
|
78856
|
+
"group-commands": {
|
|
78857
|
+
scope: "device",
|
|
78858
|
+
noun: t("Group command", "Comando di gruppo")
|
|
78859
|
+
},
|
|
78860
|
+
"group-status": {
|
|
78861
|
+
scope: "device",
|
|
78862
|
+
noun: t("Group", "Gruppo"),
|
|
78863
|
+
state: [
|
|
78864
|
+
{
|
|
78865
|
+
kind: "numeric",
|
|
78866
|
+
field: "included",
|
|
78867
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
78868
|
+
label: t("Reporting", "Rispondono"),
|
|
78869
|
+
icon: "users"
|
|
78870
|
+
},
|
|
78871
|
+
{
|
|
78872
|
+
kind: "numeric",
|
|
78873
|
+
field: "excluded",
|
|
78874
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
78875
|
+
label: t("Excluded", "Esclusi"),
|
|
78876
|
+
icon: "users"
|
|
78877
|
+
},
|
|
78878
|
+
{
|
|
78879
|
+
kind: "numeric",
|
|
78880
|
+
field: "total",
|
|
78881
|
+
quantity: t("the member count", "il numero di membri"),
|
|
78882
|
+
label: t("Members", "Membri"),
|
|
78883
|
+
icon: "sigma"
|
|
78884
|
+
}
|
|
78885
|
+
]
|
|
78886
|
+
},
|
|
78491
78887
|
"humidity-sensor": {
|
|
78492
78888
|
scope: "device",
|
|
78493
78889
|
noun: t("Humidity", "Umidità"),
|
|
@@ -78521,7 +78917,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78521
78917
|
field: "value",
|
|
78522
78918
|
quantity: t("the reading", "il valore"),
|
|
78523
78919
|
label: t("Reading", "Valore"),
|
|
78524
|
-
unitField: "unit",
|
|
78525
78920
|
icon: "gauge"
|
|
78526
78921
|
}]
|
|
78527
78922
|
},
|
|
@@ -78657,7 +79052,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78657
79052
|
field: "temperature",
|
|
78658
79053
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78659
79054
|
label: t("Temperature", "Temperatura"),
|
|
78660
|
-
|
|
79055
|
+
unit: "°C",
|
|
78661
79056
|
icon: "thermometer"
|
|
78662
79057
|
},
|
|
78663
79058
|
{
|
|
@@ -78673,7 +79068,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78673
79068
|
field: "windSpeed",
|
|
78674
79069
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78675
79070
|
label: t("Wind", "Vento"),
|
|
78676
|
-
|
|
79071
|
+
unit: "m/s",
|
|
78677
79072
|
icon: "wind"
|
|
78678
79073
|
},
|
|
78679
79074
|
{
|
|
@@ -78681,7 +79076,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78681
79076
|
field: "pressure",
|
|
78682
79077
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78683
79078
|
label: t("Pressure", "Pressione"),
|
|
78684
|
-
|
|
79079
|
+
unit: "hPa",
|
|
78685
79080
|
icon: "gauge"
|
|
78686
79081
|
}
|
|
78687
79082
|
]
|
|
@@ -79954,6 +80349,16 @@ Object.freeze({
|
|
|
79954
80349
|
form: "single",
|
|
79955
80350
|
optional: false
|
|
79956
80351
|
}],
|
|
80352
|
+
"groupCommands.getStatus": [{
|
|
80353
|
+
name: "deviceId",
|
|
80354
|
+
form: "single",
|
|
80355
|
+
optional: false
|
|
80356
|
+
}],
|
|
80357
|
+
"groupStatus.getStatus": [{
|
|
80358
|
+
name: "deviceId",
|
|
80359
|
+
form: "single",
|
|
80360
|
+
optional: false
|
|
80361
|
+
}],
|
|
79957
80362
|
"heatingValve.getStatus": [{
|
|
79958
80363
|
name: "deviceId",
|
|
79959
80364
|
form: "single",
|
|
@@ -82145,6 +82550,8 @@ new Map(Object.entries({
|
|
|
82145
82550
|
"detection-blind": "device-events",
|
|
82146
82551
|
"motion-noisy": "device-events",
|
|
82147
82552
|
"motion-calm": "device-events",
|
|
82553
|
+
"package-llm-silent": "device-events",
|
|
82554
|
+
"package-llm-answered": "device-events",
|
|
82148
82555
|
"recording-stalled": "device-events",
|
|
82149
82556
|
"recording-healthy": "device-events",
|
|
82150
82557
|
"recording-degraded": "device-events",
|
|
@@ -82228,6 +82635,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
82228
82635
|
label: "Motion without a subject",
|
|
82229
82636
|
kinds: ["motion-noisy", "motion-calm"]
|
|
82230
82637
|
},
|
|
82638
|
+
{
|
|
82639
|
+
id: "package-llm",
|
|
82640
|
+
family: "device-events",
|
|
82641
|
+
label: "Package confirm",
|
|
82642
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
82643
|
+
},
|
|
82231
82644
|
{
|
|
82232
82645
|
id: "recording",
|
|
82233
82646
|
family: "device-events",
|
|
@@ -82409,6 +82822,8 @@ var DEVICE_EVENTS = [
|
|
|
82409
82822
|
"detection-blind",
|
|
82410
82823
|
"motion-noisy",
|
|
82411
82824
|
"motion-calm",
|
|
82825
|
+
"package-llm-silent",
|
|
82826
|
+
"package-llm-answered",
|
|
82412
82827
|
"recording-stalled",
|
|
82413
82828
|
"recording-healthy",
|
|
82414
82829
|
"recording-degraded",
|
|
@@ -82677,6 +83092,15 @@ new Map([
|
|
|
82677
83092
|
snapshotLabel: "Cameras with constant motion now",
|
|
82678
83093
|
snapshotSection: null
|
|
82679
83094
|
},
|
|
83095
|
+
{
|
|
83096
|
+
id: "package-llm-confirm",
|
|
83097
|
+
family: "device-events",
|
|
83098
|
+
label: "Package confirm (not answering / answering again)",
|
|
83099
|
+
bad: ["package-llm-silent"],
|
|
83100
|
+
recovery: ["package-llm-answered"],
|
|
83101
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
83102
|
+
snapshotSection: null
|
|
83103
|
+
},
|
|
82680
83104
|
{
|
|
82681
83105
|
id: "recording-health",
|
|
82682
83106
|
family: "device-events",
|