@camstack/addon-provider-onvif 1.2.148 → 1.2.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +20 -0
- package/dist/addon.js +856 -432
- package/dist/addon.mjs +856 -432
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
//#region \0rolldown/runtime.js
|
|
3
3
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
4
4
|
//#endregion
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -328,6 +328,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
328
328
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
329
329
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
330
330
|
/**
|
|
331
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
332
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
333
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
334
|
+
*/
|
|
335
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
336
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
337
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
338
|
+
/**
|
|
331
339
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
332
340
|
* (a settings change via `setAgentInferenceDevices` /
|
|
333
341
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5437,7 +5445,7 @@ var ZodIssueCode = {
|
|
|
5437
5445
|
var ZodFirstPartyTypeKind;
|
|
5438
5446
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5439
5447
|
//#endregion
|
|
5440
|
-
//#region ../types/dist/sleep-
|
|
5448
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5441
5449
|
/**
|
|
5442
5450
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5443
5451
|
* window to float samples (D455).
|
|
@@ -7924,6 +7932,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
7924
7932
|
}).strict();
|
|
7925
7933
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
7926
7934
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
7935
|
+
var READING_QUANTITIES = [
|
|
7936
|
+
"temperature",
|
|
7937
|
+
"pressure",
|
|
7938
|
+
"speed",
|
|
7939
|
+
"precipitation",
|
|
7940
|
+
"precipitation-rate",
|
|
7941
|
+
"length",
|
|
7942
|
+
"area",
|
|
7943
|
+
"illuminance",
|
|
7944
|
+
"irradiance",
|
|
7945
|
+
"power",
|
|
7946
|
+
"energy",
|
|
7947
|
+
"voltage",
|
|
7948
|
+
"current",
|
|
7949
|
+
"apparent-power",
|
|
7950
|
+
"humidity",
|
|
7951
|
+
"percentage",
|
|
7952
|
+
"concentration-volume",
|
|
7953
|
+
"concentration-mass",
|
|
7954
|
+
"concentration-ppb",
|
|
7955
|
+
"volume",
|
|
7956
|
+
"duration",
|
|
7957
|
+
"duration-ms",
|
|
7958
|
+
"information",
|
|
7959
|
+
"sound-level",
|
|
7960
|
+
"signal-level",
|
|
7961
|
+
"colour-temperature",
|
|
7962
|
+
"angle",
|
|
7963
|
+
"bitrate",
|
|
7964
|
+
"rate",
|
|
7965
|
+
"mass",
|
|
7966
|
+
"index",
|
|
7967
|
+
"ratio",
|
|
7968
|
+
"count",
|
|
7969
|
+
"none",
|
|
7970
|
+
"device"
|
|
7971
|
+
];
|
|
7972
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
7973
|
+
new Set(READING_QUANTITIES);
|
|
7974
|
+
/**
|
|
7975
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
7976
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
7977
|
+
*/
|
|
7978
|
+
var QUANTITY_BASE = {
|
|
7979
|
+
temperature: "°C",
|
|
7980
|
+
pressure: "hPa",
|
|
7981
|
+
speed: "m/s",
|
|
7982
|
+
precipitation: "mm",
|
|
7983
|
+
"precipitation-rate": "mm/h",
|
|
7984
|
+
length: "m",
|
|
7985
|
+
area: "m²",
|
|
7986
|
+
illuminance: "lx",
|
|
7987
|
+
irradiance: "W/m²",
|
|
7988
|
+
power: "W",
|
|
7989
|
+
energy: "kWh",
|
|
7990
|
+
voltage: "V",
|
|
7991
|
+
current: "A",
|
|
7992
|
+
"apparent-power": "VA",
|
|
7993
|
+
humidity: "%",
|
|
7994
|
+
percentage: "%",
|
|
7995
|
+
"concentration-volume": "ppm",
|
|
7996
|
+
"concentration-mass": "µg/m³",
|
|
7997
|
+
"concentration-ppb": "ppb",
|
|
7998
|
+
volume: "L",
|
|
7999
|
+
duration: "s",
|
|
8000
|
+
"duration-ms": "ms",
|
|
8001
|
+
information: "B",
|
|
8002
|
+
"sound-level": "dBFS",
|
|
8003
|
+
"signal-level": "dBm",
|
|
8004
|
+
"colour-temperature": "mired",
|
|
8005
|
+
angle: "°",
|
|
8006
|
+
bitrate: "kbps",
|
|
8007
|
+
rate: "fps",
|
|
8008
|
+
mass: "kg",
|
|
8009
|
+
index: "none",
|
|
8010
|
+
ratio: "none",
|
|
8011
|
+
count: "none",
|
|
8012
|
+
none: "none",
|
|
8013
|
+
device: "device"
|
|
8014
|
+
};
|
|
8015
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8016
|
+
function baseUnitOf(quantity) {
|
|
8017
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8018
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8019
|
+
return symbol;
|
|
8020
|
+
}
|
|
8021
|
+
function readingMeta(quantity, extras) {
|
|
8022
|
+
return {
|
|
8023
|
+
quantity,
|
|
8024
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8025
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8026
|
+
};
|
|
8027
|
+
}
|
|
7927
8028
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
7928
8029
|
var CamProfileSchema = _enum([
|
|
7929
8030
|
"high",
|
|
@@ -7951,8 +8052,8 @@ var CamStreamKindSchema = _enum([
|
|
|
7951
8052
|
"derived"
|
|
7952
8053
|
]);
|
|
7953
8054
|
var CamStreamResolutionSchema = object({
|
|
7954
|
-
width: number().int().positive(),
|
|
7955
|
-
height: number().int().positive()
|
|
8055
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8056
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
7956
8057
|
});
|
|
7957
8058
|
var CameraStreamSchema = object({
|
|
7958
8059
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8466,6 +8567,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8466
8567
|
"filesystem-browse",
|
|
8467
8568
|
"flood",
|
|
8468
8569
|
"gas",
|
|
8570
|
+
"group-commands",
|
|
8571
|
+
"group-status",
|
|
8469
8572
|
"heating-valve",
|
|
8470
8573
|
"humidifier",
|
|
8471
8574
|
"humidity-sensor",
|
|
@@ -8595,14 +8698,6 @@ Object.freeze({
|
|
|
8595
8698
|
{
|
|
8596
8699
|
"path": "aqi",
|
|
8597
8700
|
"valueType": "number"
|
|
8598
|
-
},
|
|
8599
|
-
{
|
|
8600
|
-
"path": "unit",
|
|
8601
|
-
"valueType": "string"
|
|
8602
|
-
},
|
|
8603
|
-
{
|
|
8604
|
-
"path": "precision",
|
|
8605
|
-
"valueType": "number"
|
|
8606
8701
|
}
|
|
8607
8702
|
],
|
|
8608
8703
|
"alarm-panel": [
|
|
@@ -8638,20 +8733,10 @@ Object.freeze({
|
|
|
8638
8733
|
"valueType": "boolean"
|
|
8639
8734
|
}
|
|
8640
8735
|
],
|
|
8641
|
-
"ambient-light-sensor": [
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
},
|
|
8646
|
-
{
|
|
8647
|
-
"path": "unit",
|
|
8648
|
-
"valueType": "string"
|
|
8649
|
-
},
|
|
8650
|
-
{
|
|
8651
|
-
"path": "precision",
|
|
8652
|
-
"valueType": "number"
|
|
8653
|
-
}
|
|
8654
|
-
],
|
|
8736
|
+
"ambient-light-sensor": [{
|
|
8737
|
+
"path": "lux",
|
|
8738
|
+
"valueType": "number"
|
|
8739
|
+
}],
|
|
8655
8740
|
"audio-metrics": [
|
|
8656
8741
|
{
|
|
8657
8742
|
"path": "ts",
|
|
@@ -8731,6 +8816,10 @@ Object.freeze({
|
|
|
8731
8816
|
"path": "lastUpdated",
|
|
8732
8817
|
"valueType": "number"
|
|
8733
8818
|
},
|
|
8819
|
+
{
|
|
8820
|
+
"path": "volts",
|
|
8821
|
+
"valueType": "number"
|
|
8822
|
+
},
|
|
8734
8823
|
{
|
|
8735
8824
|
"path": "lastContactAt",
|
|
8736
8825
|
"valueType": "number"
|
|
@@ -8973,10 +9062,6 @@ Object.freeze({
|
|
|
8973
9062
|
"datetime"
|
|
8974
9063
|
]
|
|
8975
9064
|
},
|
|
8976
|
-
{
|
|
8977
|
-
"path": "unit",
|
|
8978
|
-
"valueType": "string"
|
|
8979
|
-
},
|
|
8980
9065
|
{
|
|
8981
9066
|
"path": "min",
|
|
8982
9067
|
"valueType": "number"
|
|
@@ -8988,19 +9073,6 @@ Object.freeze({
|
|
|
8988
9073
|
{
|
|
8989
9074
|
"path": "step",
|
|
8990
9075
|
"valueType": "number"
|
|
8991
|
-
},
|
|
8992
|
-
{
|
|
8993
|
-
"path": "precision",
|
|
8994
|
-
"valueType": "number"
|
|
8995
|
-
},
|
|
8996
|
-
{
|
|
8997
|
-
"path": "format",
|
|
8998
|
-
"valueType": "enum",
|
|
8999
|
-
"enumValues": [
|
|
9000
|
-
"date",
|
|
9001
|
-
"time",
|
|
9002
|
-
"datetime"
|
|
9003
|
-
]
|
|
9004
9076
|
}
|
|
9005
9077
|
],
|
|
9006
9078
|
"cover": [
|
|
@@ -9241,13 +9313,8 @@ Object.freeze({
|
|
|
9241
9313
|
"path": "value",
|
|
9242
9314
|
"valueType": "string"
|
|
9243
9315
|
}, {
|
|
9244
|
-
"path": "
|
|
9245
|
-
"valueType": "
|
|
9246
|
-
"enumValues": [
|
|
9247
|
-
"date",
|
|
9248
|
-
"time",
|
|
9249
|
-
"datetime"
|
|
9250
|
-
]
|
|
9316
|
+
"path": "timestamp",
|
|
9317
|
+
"valueType": "boolean"
|
|
9251
9318
|
}],
|
|
9252
9319
|
"event-emitter": [
|
|
9253
9320
|
{
|
|
@@ -9320,6 +9387,20 @@ Object.freeze({
|
|
|
9320
9387
|
"path": "detected",
|
|
9321
9388
|
"valueType": "boolean"
|
|
9322
9389
|
}],
|
|
9390
|
+
"group-status": [
|
|
9391
|
+
{
|
|
9392
|
+
"path": "included",
|
|
9393
|
+
"valueType": "number"
|
|
9394
|
+
},
|
|
9395
|
+
{
|
|
9396
|
+
"path": "excluded",
|
|
9397
|
+
"valueType": "number"
|
|
9398
|
+
},
|
|
9399
|
+
{
|
|
9400
|
+
"path": "total",
|
|
9401
|
+
"valueType": "number"
|
|
9402
|
+
}
|
|
9403
|
+
],
|
|
9323
9404
|
"heating-valve": [{
|
|
9324
9405
|
"path": "position",
|
|
9325
9406
|
"valueType": "number"
|
|
@@ -9354,20 +9435,10 @@ Object.freeze({
|
|
|
9354
9435
|
"valueType": "number"
|
|
9355
9436
|
}
|
|
9356
9437
|
],
|
|
9357
|
-
"humidity-sensor": [
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
},
|
|
9362
|
-
{
|
|
9363
|
-
"path": "unit",
|
|
9364
|
-
"valueType": "string"
|
|
9365
|
-
},
|
|
9366
|
-
{
|
|
9367
|
-
"path": "precision",
|
|
9368
|
-
"valueType": "number"
|
|
9369
|
-
}
|
|
9370
|
-
],
|
|
9438
|
+
"humidity-sensor": [{
|
|
9439
|
+
"path": "percent",
|
|
9440
|
+
"valueType": "number"
|
|
9441
|
+
}],
|
|
9371
9442
|
"image": [{
|
|
9372
9443
|
"path": "url",
|
|
9373
9444
|
"valueType": "string"
|
|
@@ -9706,20 +9777,10 @@ Object.freeze({
|
|
|
9706
9777
|
"valueType": "boolean"
|
|
9707
9778
|
}
|
|
9708
9779
|
],
|
|
9709
|
-
"numeric-sensor": [
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
},
|
|
9714
|
-
{
|
|
9715
|
-
"path": "unit",
|
|
9716
|
-
"valueType": "string"
|
|
9717
|
-
},
|
|
9718
|
-
{
|
|
9719
|
-
"path": "precision",
|
|
9720
|
-
"valueType": "number"
|
|
9721
|
-
}
|
|
9722
|
-
],
|
|
9780
|
+
"numeric-sensor": [{
|
|
9781
|
+
"path": "value",
|
|
9782
|
+
"valueType": "number"
|
|
9783
|
+
}],
|
|
9723
9784
|
"pet-feeder": [
|
|
9724
9785
|
{
|
|
9725
9786
|
"path": "foodLevel",
|
|
@@ -9811,14 +9872,6 @@ Object.freeze({
|
|
|
9811
9872
|
{
|
|
9812
9873
|
"path": "powerFactor",
|
|
9813
9874
|
"valueType": "number"
|
|
9814
|
-
},
|
|
9815
|
-
{
|
|
9816
|
-
"path": "unit",
|
|
9817
|
-
"valueType": "string"
|
|
9818
|
-
},
|
|
9819
|
-
{
|
|
9820
|
-
"path": "precision",
|
|
9821
|
-
"valueType": "number"
|
|
9822
9875
|
}
|
|
9823
9876
|
],
|
|
9824
9877
|
"presence": [
|
|
@@ -9847,20 +9900,10 @@ Object.freeze({
|
|
|
9847
9900
|
"valueType": "number"
|
|
9848
9901
|
}
|
|
9849
9902
|
],
|
|
9850
|
-
"pressure-sensor": [
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
},
|
|
9855
|
-
{
|
|
9856
|
-
"path": "unit",
|
|
9857
|
-
"valueType": "string"
|
|
9858
|
-
},
|
|
9859
|
-
{
|
|
9860
|
-
"path": "precision",
|
|
9861
|
-
"valueType": "number"
|
|
9862
|
-
}
|
|
9863
|
-
],
|
|
9903
|
+
"pressure-sensor": [{
|
|
9904
|
+
"path": "hpa",
|
|
9905
|
+
"valueType": "number"
|
|
9906
|
+
}],
|
|
9864
9907
|
"privacy-mask": [{
|
|
9865
9908
|
"path": "enabled",
|
|
9866
9909
|
"valueType": "boolean"
|
|
@@ -10171,20 +10214,10 @@ Object.freeze({
|
|
|
10171
10214
|
"path": "tampered",
|
|
10172
10215
|
"valueType": "boolean"
|
|
10173
10216
|
}],
|
|
10174
|
-
"temperature-sensor": [
|
|
10175
|
-
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
},
|
|
10179
|
-
{
|
|
10180
|
-
"path": "unit",
|
|
10181
|
-
"valueType": "string"
|
|
10182
|
-
},
|
|
10183
|
-
{
|
|
10184
|
-
"path": "precision",
|
|
10185
|
-
"valueType": "number"
|
|
10186
|
-
}
|
|
10187
|
-
],
|
|
10217
|
+
"temperature-sensor": [{
|
|
10218
|
+
"path": "celsius",
|
|
10219
|
+
"valueType": "number"
|
|
10220
|
+
}],
|
|
10188
10221
|
"update": [
|
|
10189
10222
|
{
|
|
10190
10223
|
"path": "currentVersion",
|
|
@@ -10295,10 +10328,6 @@ Object.freeze({
|
|
|
10295
10328
|
"path": "temperature",
|
|
10296
10329
|
"valueType": "number"
|
|
10297
10330
|
},
|
|
10298
|
-
{
|
|
10299
|
-
"path": "temperatureUnit",
|
|
10300
|
-
"valueType": "string"
|
|
10301
|
-
},
|
|
10302
10331
|
{
|
|
10303
10332
|
"path": "humidity",
|
|
10304
10333
|
"valueType": "number"
|
|
@@ -10307,18 +10336,10 @@ Object.freeze({
|
|
|
10307
10336
|
"path": "pressure",
|
|
10308
10337
|
"valueType": "number"
|
|
10309
10338
|
},
|
|
10310
|
-
{
|
|
10311
|
-
"path": "pressureUnit",
|
|
10312
|
-
"valueType": "string"
|
|
10313
|
-
},
|
|
10314
10339
|
{
|
|
10315
10340
|
"path": "windSpeed",
|
|
10316
10341
|
"valueType": "number"
|
|
10317
10342
|
},
|
|
10318
|
-
{
|
|
10319
|
-
"path": "windSpeedUnit",
|
|
10320
|
-
"valueType": "string"
|
|
10321
|
-
},
|
|
10322
10343
|
{
|
|
10323
10344
|
"path": "windBearing",
|
|
10324
10345
|
"valueType": "number"
|
|
@@ -10721,7 +10742,7 @@ function errMsg(err) {
|
|
|
10721
10742
|
return String(err);
|
|
10722
10743
|
}
|
|
10723
10744
|
//#endregion
|
|
10724
|
-
//#region ../types/dist/composition-
|
|
10745
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10725
10746
|
/**
|
|
10726
10747
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10727
10748
|
*
|
|
@@ -11476,15 +11497,74 @@ function validateExpressionSource(src) {
|
|
|
11476
11497
|
}
|
|
11477
11498
|
return null;
|
|
11478
11499
|
}
|
|
11479
|
-
/**
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11500
|
+
/**
|
|
11501
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11502
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11503
|
+
* `composition.ts` (D659).
|
|
11504
|
+
*/
|
|
11483
11505
|
var CompositionSourceRefSchema = object({
|
|
11484
11506
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11485
11507
|
addonId: string().min(1),
|
|
11486
11508
|
stableId: string().min(1)
|
|
11487
11509
|
});
|
|
11510
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11511
|
+
"temperature",
|
|
11512
|
+
"humidity",
|
|
11513
|
+
"pressure",
|
|
11514
|
+
"illuminance",
|
|
11515
|
+
"power",
|
|
11516
|
+
"energy",
|
|
11517
|
+
"battery",
|
|
11518
|
+
"numeric",
|
|
11519
|
+
"motion",
|
|
11520
|
+
"contact",
|
|
11521
|
+
"leak",
|
|
11522
|
+
"smoke",
|
|
11523
|
+
"occupancy",
|
|
11524
|
+
"binary",
|
|
11525
|
+
"switch",
|
|
11526
|
+
"light"
|
|
11527
|
+
];
|
|
11528
|
+
var NUMERIC_AGGREGATES = [
|
|
11529
|
+
"mean",
|
|
11530
|
+
"median",
|
|
11531
|
+
"min",
|
|
11532
|
+
"max",
|
|
11533
|
+
"sum"
|
|
11534
|
+
];
|
|
11535
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11536
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11537
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11538
|
+
var AGGREGATE_REDUCERS = [
|
|
11539
|
+
"mean",
|
|
11540
|
+
"median",
|
|
11541
|
+
"min",
|
|
11542
|
+
"max",
|
|
11543
|
+
"sum",
|
|
11544
|
+
"any",
|
|
11545
|
+
"all"
|
|
11546
|
+
];
|
|
11547
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11548
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11549
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11550
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11551
|
+
var HelperMemberSchema = object({
|
|
11552
|
+
source: CompositionSourceRefSchema,
|
|
11553
|
+
cap: string().min(1),
|
|
11554
|
+
fieldPath: string().min(1)
|
|
11555
|
+
});
|
|
11556
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11557
|
+
kind: literal("group"),
|
|
11558
|
+
templateId: GroupTemplateIdSchema,
|
|
11559
|
+
aggregate: AggregateReducerSchema,
|
|
11560
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11561
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11562
|
+
active: ActiveCriterionSchema.optional()
|
|
11563
|
+
})]);
|
|
11564
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11565
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11566
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11567
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11488
11568
|
/** One field of one capability of one source device. */
|
|
11489
11569
|
var CompositionFieldReadSchema = object({
|
|
11490
11570
|
source: CompositionSourceRefSchema,
|
|
@@ -11528,7 +11608,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11528
11608
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11529
11609
|
CompositionFromSourceSchema,
|
|
11530
11610
|
CompositionExpressionSourceSchema,
|
|
11531
|
-
CompositionCodeSourceSchema
|
|
11611
|
+
CompositionCodeSourceSchema,
|
|
11612
|
+
object({
|
|
11613
|
+
kind: literal("aggregate"),
|
|
11614
|
+
reducer: _enum([
|
|
11615
|
+
"mean",
|
|
11616
|
+
"median",
|
|
11617
|
+
"min",
|
|
11618
|
+
"max",
|
|
11619
|
+
"sum",
|
|
11620
|
+
"any",
|
|
11621
|
+
"all"
|
|
11622
|
+
]),
|
|
11623
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11624
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11625
|
+
publish: _enum([
|
|
11626
|
+
"value",
|
|
11627
|
+
"included",
|
|
11628
|
+
"excluded",
|
|
11629
|
+
"total"
|
|
11630
|
+
]),
|
|
11631
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11632
|
+
empty: _enum([
|
|
11633
|
+
"null",
|
|
11634
|
+
"omit",
|
|
11635
|
+
"offline"
|
|
11636
|
+
])
|
|
11637
|
+
})
|
|
11532
11638
|
]);
|
|
11533
11639
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11534
11640
|
kind: literal("forward"),
|
|
@@ -11574,7 +11680,13 @@ var CompositionSchema = object({
|
|
|
11574
11680
|
kind: literal("existing"),
|
|
11575
11681
|
device: CompositionSourceRefSchema
|
|
11576
11682
|
})]),
|
|
11577
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11683
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11684
|
+
/**
|
|
11685
|
+
* Present when the block is a helper template. Absent on a free
|
|
11686
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11687
|
+
* never the compiled features.
|
|
11688
|
+
*/
|
|
11689
|
+
helper: HelperSpecSchema.optional()
|
|
11578
11690
|
}).superRefine((composition, ctx) => {
|
|
11579
11691
|
const seen = /* @__PURE__ */ new Set();
|
|
11580
11692
|
composition.features.forEach((feature, index) => {
|
|
@@ -17676,7 +17788,11 @@ var CompositionProblemSchema = object({
|
|
|
17676
17788
|
"item-field-reserved",
|
|
17677
17789
|
"target-missing",
|
|
17678
17790
|
"target-unreadable",
|
|
17679
|
-
"not-replaceable"
|
|
17791
|
+
"not-replaceable",
|
|
17792
|
+
"native-capability-replace",
|
|
17793
|
+
"mixed-quantity",
|
|
17794
|
+
"helper-mismatch",
|
|
17795
|
+
"member-constraint"
|
|
17680
17796
|
]),
|
|
17681
17797
|
path: string(),
|
|
17682
17798
|
message: string()
|
|
@@ -17697,7 +17813,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17697
17813
|
"null",
|
|
17698
17814
|
"offline",
|
|
17699
17815
|
"unknown",
|
|
17700
|
-
"release"
|
|
17816
|
+
"release",
|
|
17817
|
+
"omit"
|
|
17701
17818
|
]);
|
|
17702
17819
|
/**
|
|
17703
17820
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -17734,9 +17851,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17734
17851
|
reads: array(CompositionFieldReadSchema)
|
|
17735
17852
|
});
|
|
17736
17853
|
/**
|
|
17737
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17738
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17739
|
-
*
|
|
17854
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
17855
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
17856
|
+
* Replacing a capability the device already serves is refused
|
|
17857
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
17858
|
+
* wire for a claim the hub already holds.
|
|
17740
17859
|
*/
|
|
17741
17860
|
var CompositionFeatureModeSchema = _enum([
|
|
17742
17861
|
"new",
|
|
@@ -17909,6 +18028,275 @@ Object.freeze({
|
|
|
17909
18028
|
result: ["number", "null"]
|
|
17910
18029
|
}
|
|
17911
18030
|
});
|
|
18031
|
+
/**
|
|
18032
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18033
|
+
* Data, not a form default written into the block.
|
|
18034
|
+
*/
|
|
18035
|
+
var NOW = {
|
|
18036
|
+
fieldPath: "lastFetchedAt",
|
|
18037
|
+
expr: "now"
|
|
18038
|
+
};
|
|
18039
|
+
var CHANGED = {
|
|
18040
|
+
fieldPath: "lastChangedAt",
|
|
18041
|
+
expr: "now"
|
|
18042
|
+
};
|
|
18043
|
+
function numeric(input) {
|
|
18044
|
+
return {
|
|
18045
|
+
...input,
|
|
18046
|
+
family: "numeric",
|
|
18047
|
+
deviceType: DeviceType.Sensor,
|
|
18048
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18049
|
+
commandCaps: [],
|
|
18050
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18051
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18052
|
+
accept: [{
|
|
18053
|
+
cap: input.outputCap,
|
|
18054
|
+
fieldPath: input.outputField
|
|
18055
|
+
}]
|
|
18056
|
+
};
|
|
18057
|
+
}
|
|
18058
|
+
function binary(input) {
|
|
18059
|
+
return {
|
|
18060
|
+
...input,
|
|
18061
|
+
family: "binary",
|
|
18062
|
+
deviceType: DeviceType.Sensor,
|
|
18063
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18064
|
+
commandCaps: [],
|
|
18065
|
+
quantity: "none",
|
|
18066
|
+
baseUnit: void 0,
|
|
18067
|
+
aggregates: BINARY_AGGREGATES,
|
|
18068
|
+
empty: "offline"
|
|
18069
|
+
};
|
|
18070
|
+
}
|
|
18071
|
+
var GROUP_TEMPLATES = [
|
|
18072
|
+
numeric({
|
|
18073
|
+
id: "temperature",
|
|
18074
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18075
|
+
role: DeviceRole.TemperatureSensor,
|
|
18076
|
+
outputCap: "temperature-sensor",
|
|
18077
|
+
outputField: "celsius",
|
|
18078
|
+
quantity: "temperature",
|
|
18079
|
+
defaultAggregate: "mean",
|
|
18080
|
+
empty: "null",
|
|
18081
|
+
companions: [NOW]
|
|
18082
|
+
}),
|
|
18083
|
+
numeric({
|
|
18084
|
+
id: "humidity",
|
|
18085
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18086
|
+
role: DeviceRole.HumiditySensor,
|
|
18087
|
+
outputCap: "humidity-sensor",
|
|
18088
|
+
outputField: "percent",
|
|
18089
|
+
quantity: "humidity",
|
|
18090
|
+
defaultAggregate: "mean",
|
|
18091
|
+
empty: "null",
|
|
18092
|
+
companions: [NOW]
|
|
18093
|
+
}),
|
|
18094
|
+
numeric({
|
|
18095
|
+
id: "pressure",
|
|
18096
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18097
|
+
role: DeviceRole.PressureSensor,
|
|
18098
|
+
outputCap: "pressure-sensor",
|
|
18099
|
+
outputField: "hpa",
|
|
18100
|
+
quantity: "pressure",
|
|
18101
|
+
defaultAggregate: "mean",
|
|
18102
|
+
empty: "null",
|
|
18103
|
+
companions: [NOW]
|
|
18104
|
+
}),
|
|
18105
|
+
numeric({
|
|
18106
|
+
id: "illuminance",
|
|
18107
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18108
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18109
|
+
outputCap: "ambient-light-sensor",
|
|
18110
|
+
outputField: "lux",
|
|
18111
|
+
quantity: "illuminance",
|
|
18112
|
+
defaultAggregate: "mean",
|
|
18113
|
+
empty: "null",
|
|
18114
|
+
companions: [NOW]
|
|
18115
|
+
}),
|
|
18116
|
+
numeric({
|
|
18117
|
+
id: "power",
|
|
18118
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18119
|
+
role: DeviceRole.PowerSensor,
|
|
18120
|
+
outputCap: "power-meter",
|
|
18121
|
+
outputField: "watts",
|
|
18122
|
+
quantity: "power",
|
|
18123
|
+
defaultAggregate: "sum",
|
|
18124
|
+
empty: "omit",
|
|
18125
|
+
companions: [NOW]
|
|
18126
|
+
}),
|
|
18127
|
+
numeric({
|
|
18128
|
+
id: "energy",
|
|
18129
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18130
|
+
role: DeviceRole.EnergySensor,
|
|
18131
|
+
outputCap: "power-meter",
|
|
18132
|
+
outputField: "kwhTotal",
|
|
18133
|
+
quantity: "energy",
|
|
18134
|
+
defaultAggregate: "sum",
|
|
18135
|
+
empty: "omit",
|
|
18136
|
+
companions: [NOW]
|
|
18137
|
+
}),
|
|
18138
|
+
numeric({
|
|
18139
|
+
id: "battery",
|
|
18140
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18141
|
+
role: DeviceRole.BatterySensor,
|
|
18142
|
+
outputCap: "battery",
|
|
18143
|
+
outputField: "percentage",
|
|
18144
|
+
quantity: "percentage",
|
|
18145
|
+
defaultAggregate: "mean",
|
|
18146
|
+
empty: "null",
|
|
18147
|
+
companions: [
|
|
18148
|
+
{
|
|
18149
|
+
fieldPath: "charging",
|
|
18150
|
+
expr: "\"unknown\""
|
|
18151
|
+
},
|
|
18152
|
+
{
|
|
18153
|
+
fieldPath: "sleeping",
|
|
18154
|
+
expr: "false"
|
|
18155
|
+
},
|
|
18156
|
+
{
|
|
18157
|
+
fieldPath: "lastUpdated",
|
|
18158
|
+
expr: "now"
|
|
18159
|
+
}
|
|
18160
|
+
]
|
|
18161
|
+
}),
|
|
18162
|
+
numeric({
|
|
18163
|
+
id: "numeric",
|
|
18164
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18165
|
+
role: DeviceRole.NumericSensor,
|
|
18166
|
+
outputCap: "numeric-sensor",
|
|
18167
|
+
outputField: "value",
|
|
18168
|
+
quantity: "device",
|
|
18169
|
+
defaultAggregate: "mean",
|
|
18170
|
+
empty: "null",
|
|
18171
|
+
companions: [NOW]
|
|
18172
|
+
}),
|
|
18173
|
+
binary({
|
|
18174
|
+
id: "motion",
|
|
18175
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18176
|
+
role: DeviceRole.MotionSensor,
|
|
18177
|
+
outputCap: "motion",
|
|
18178
|
+
outputField: "detected",
|
|
18179
|
+
defaultAggregate: "any",
|
|
18180
|
+
accept: [{
|
|
18181
|
+
cap: "motion",
|
|
18182
|
+
fieldPath: "detected"
|
|
18183
|
+
}],
|
|
18184
|
+
companions: [{
|
|
18185
|
+
fieldPath: "lastDetectedAt",
|
|
18186
|
+
expr: "null"
|
|
18187
|
+
}, {
|
|
18188
|
+
fieldPath: "autoClearAfterMs",
|
|
18189
|
+
expr: "null"
|
|
18190
|
+
}]
|
|
18191
|
+
}),
|
|
18192
|
+
binary({
|
|
18193
|
+
id: "contact",
|
|
18194
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18195
|
+
role: DeviceRole.ContactSensor,
|
|
18196
|
+
outputCap: "contact",
|
|
18197
|
+
outputField: "entryOpen",
|
|
18198
|
+
defaultAggregate: "any",
|
|
18199
|
+
accept: [{
|
|
18200
|
+
cap: "contact",
|
|
18201
|
+
fieldPath: "entryOpen"
|
|
18202
|
+
}],
|
|
18203
|
+
companions: [CHANGED]
|
|
18204
|
+
}),
|
|
18205
|
+
binary({
|
|
18206
|
+
id: "leak",
|
|
18207
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18208
|
+
role: DeviceRole.LeakSensor,
|
|
18209
|
+
outputCap: "flood",
|
|
18210
|
+
outputField: "flooded",
|
|
18211
|
+
defaultAggregate: "any",
|
|
18212
|
+
accept: [{
|
|
18213
|
+
cap: "flood",
|
|
18214
|
+
fieldPath: "flooded"
|
|
18215
|
+
}],
|
|
18216
|
+
companions: [CHANGED]
|
|
18217
|
+
}),
|
|
18218
|
+
binary({
|
|
18219
|
+
id: "smoke",
|
|
18220
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18221
|
+
role: DeviceRole.SmokeSensor,
|
|
18222
|
+
outputCap: "smoke",
|
|
18223
|
+
outputField: "detected",
|
|
18224
|
+
defaultAggregate: "any",
|
|
18225
|
+
accept: [{
|
|
18226
|
+
cap: "smoke",
|
|
18227
|
+
fieldPath: "detected"
|
|
18228
|
+
}],
|
|
18229
|
+
companions: [CHANGED]
|
|
18230
|
+
}),
|
|
18231
|
+
binary({
|
|
18232
|
+
id: "occupancy",
|
|
18233
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18234
|
+
role: DeviceRole.BinarySensor,
|
|
18235
|
+
outputCap: "binary",
|
|
18236
|
+
outputField: "on",
|
|
18237
|
+
defaultAggregate: "any",
|
|
18238
|
+
accept: [{
|
|
18239
|
+
cap: "motion",
|
|
18240
|
+
fieldPath: "detected"
|
|
18241
|
+
}, {
|
|
18242
|
+
cap: "binary",
|
|
18243
|
+
fieldPath: "on"
|
|
18244
|
+
}],
|
|
18245
|
+
companions: [CHANGED]
|
|
18246
|
+
}),
|
|
18247
|
+
binary({
|
|
18248
|
+
id: "binary",
|
|
18249
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18250
|
+
role: DeviceRole.BinarySensor,
|
|
18251
|
+
outputCap: "binary",
|
|
18252
|
+
outputField: "on",
|
|
18253
|
+
defaultAggregate: "any",
|
|
18254
|
+
accept: [{
|
|
18255
|
+
cap: "binary",
|
|
18256
|
+
fieldPath: "on"
|
|
18257
|
+
}],
|
|
18258
|
+
companions: [CHANGED]
|
|
18259
|
+
}),
|
|
18260
|
+
actuator({
|
|
18261
|
+
id: "switch",
|
|
18262
|
+
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.",
|
|
18263
|
+
deviceType: DeviceType.Switch,
|
|
18264
|
+
outputCap: "switch",
|
|
18265
|
+
commandCaps: ["switch"]
|
|
18266
|
+
}),
|
|
18267
|
+
actuator({
|
|
18268
|
+
id: "light",
|
|
18269
|
+
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.",
|
|
18270
|
+
deviceType: DeviceType.Light,
|
|
18271
|
+
outputCap: "switch",
|
|
18272
|
+
commandCaps: [
|
|
18273
|
+
"switch",
|
|
18274
|
+
"brightness",
|
|
18275
|
+
"color"
|
|
18276
|
+
]
|
|
18277
|
+
})
|
|
18278
|
+
];
|
|
18279
|
+
function actuator(input) {
|
|
18280
|
+
return {
|
|
18281
|
+
...input,
|
|
18282
|
+
family: "actuator",
|
|
18283
|
+
role: void 0,
|
|
18284
|
+
memberDeviceType: input.deviceType,
|
|
18285
|
+
outputField: "on",
|
|
18286
|
+
quantity: "none",
|
|
18287
|
+
baseUnit: void 0,
|
|
18288
|
+
aggregates: BINARY_AGGREGATES,
|
|
18289
|
+
defaultAggregate: "any",
|
|
18290
|
+
empty: "offline",
|
|
18291
|
+
accept: [{
|
|
18292
|
+
cap: "switch",
|
|
18293
|
+
fieldPath: "on"
|
|
18294
|
+
}],
|
|
18295
|
+
companions: [CHANGED]
|
|
18296
|
+
};
|
|
18297
|
+
}
|
|
18298
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18299
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
17912
18300
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
17913
18301
|
/**
|
|
17914
18302
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19735,12 +20123,12 @@ function buildDeviceAdminUrl(parts) {
|
|
|
19735
20123
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19736
20124
|
* in-place so dispatch keeps working.
|
|
19737
20125
|
*
|
|
19738
|
-
* **
|
|
19739
|
-
*
|
|
19740
|
-
*
|
|
19741
|
-
*
|
|
19742
|
-
* (`ha-domain-mapping`)
|
|
19743
|
-
* stored after that point.
|
|
20126
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20127
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20128
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20129
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20130
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20131
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19744
20132
|
*
|
|
19745
20133
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19746
20134
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19754,6 +20142,14 @@ var SourceInfoSchema = object({
|
|
|
19754
20142
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19755
20143
|
* Used to detect rename when `id` changes. */
|
|
19756
20144
|
uniqueId: string().optional(),
|
|
20145
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20146
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20147
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20148
|
+
dateTimeShape: _enum([
|
|
20149
|
+
"date",
|
|
20150
|
+
"time",
|
|
20151
|
+
"datetime"
|
|
20152
|
+
]).optional(),
|
|
19757
20153
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19758
20154
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19759
20155
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40747,7 +41143,8 @@ method(object({
|
|
|
40747
41143
|
"enum"
|
|
40748
41144
|
]),
|
|
40749
41145
|
enumValues: array(string()).optional(),
|
|
40750
|
-
item: boolean().optional()
|
|
41146
|
+
item: boolean().optional(),
|
|
41147
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40751
41148
|
})).readonly(),
|
|
40752
41149
|
itemArray: object({
|
|
40753
41150
|
path: string(),
|
|
@@ -44547,8 +44944,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44547
44944
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44548
44945
|
var MaskGridShapeSchema = object({
|
|
44549
44946
|
kind: literal("grid"),
|
|
44550
|
-
gridWidth: number(),
|
|
44551
|
-
gridHeight: number(),
|
|
44947
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
44948
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44552
44949
|
cells: array(boolean())
|
|
44553
44950
|
});
|
|
44554
44951
|
discriminatedUnion("kind", [
|
|
@@ -44660,6 +45057,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44660
45057
|
"detection-blind",
|
|
44661
45058
|
"motion-noisy",
|
|
44662
45059
|
"motion-calm",
|
|
45060
|
+
"package-llm-silent",
|
|
45061
|
+
"package-llm-answered",
|
|
44663
45062
|
"recording-stalled",
|
|
44664
45063
|
"recording-healthy",
|
|
44665
45064
|
"recording-degraded",
|
|
@@ -55778,6 +56177,28 @@ var PackageVersionInfoSchema = object({
|
|
|
55778
56177
|
deprecated: string().optional(),
|
|
55779
56178
|
distTags: array(string()).readonly()
|
|
55780
56179
|
});
|
|
56180
|
+
/**
|
|
56181
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56182
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56183
|
+
* tarball failure — never an empty string standing in for either.
|
|
56184
|
+
*/
|
|
56185
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56186
|
+
object({
|
|
56187
|
+
status: literal("ok"),
|
|
56188
|
+
markdown: string()
|
|
56189
|
+
}),
|
|
56190
|
+
object({ status: literal("missing") }),
|
|
56191
|
+
object({
|
|
56192
|
+
status: literal("error"),
|
|
56193
|
+
message: string()
|
|
56194
|
+
})
|
|
56195
|
+
]);
|
|
56196
|
+
var PackageDocsSchema = object({
|
|
56197
|
+
name: string(),
|
|
56198
|
+
version: string(),
|
|
56199
|
+
readme: PackageDocBodySchema,
|
|
56200
|
+
changelog: PackageDocBodySchema
|
|
56201
|
+
});
|
|
55781
56202
|
var SearchResultSchema = object({
|
|
55782
56203
|
name: string(),
|
|
55783
56204
|
version: string(),
|
|
@@ -55996,7 +56417,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
55996
56417
|
}), object({ success: literal(true) }), {
|
|
55997
56418
|
kind: "mutation",
|
|
55998
56419
|
auth: "admin"
|
|
55999
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56420
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56421
|
+
name: string().min(1),
|
|
56422
|
+
version: string().min(1).optional()
|
|
56423
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56000
56424
|
kind: "mutation",
|
|
56001
56425
|
auth: "admin"
|
|
56002
56426
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56046,46 +56470,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56046
56470
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56047
56471
|
object({
|
|
56048
56472
|
/** Carbon dioxide concentration in ppm. */
|
|
56049
|
-
co2Ppm: number().min(0).optional(),
|
|
56473
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56050
56474
|
/** Total volatile organic compounds in ppb. */
|
|
56051
|
-
vocPpb: number().min(0).optional(),
|
|
56475
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56052
56476
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56053
|
-
pm25: number().min(0).optional(),
|
|
56477
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56054
56478
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56055
|
-
pm10: number().min(0).optional(),
|
|
56479
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56056
56480
|
/** Composite AQI value (typically 0..500). */
|
|
56057
|
-
aqi: number().optional(),
|
|
56481
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56058
56482
|
/** Ms epoch when the slice was last updated. */
|
|
56059
|
-
lastFetchedAt: number()
|
|
56060
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56061
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56062
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56063
|
-
* per slice is unambiguous. */
|
|
56064
|
-
unit: string().optional(),
|
|
56065
|
-
/** Suggested decimal places for numeric display.
|
|
56066
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56067
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56068
|
-
* auto-formatting when absent. */
|
|
56069
|
-
precision: number().int().min(0).max(10).optional()
|
|
56483
|
+
lastFetchedAt: number()
|
|
56070
56484
|
});
|
|
56071
56485
|
DeviceType.Sensor;
|
|
56072
56486
|
object({
|
|
56073
|
-
/** Current illuminance in lux (lx). */
|
|
56074
|
-
lux: number().min(0).meta({
|
|
56075
|
-
|
|
56487
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56488
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56489
|
+
precision: 0,
|
|
56076
56490
|
label: "Illuminance"
|
|
56077
|
-
}),
|
|
56491
|
+
})),
|
|
56078
56492
|
/** Ms epoch when the slice was last updated. */
|
|
56079
|
-
lastFetchedAt: number()
|
|
56080
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56081
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56082
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56083
|
-
unit: string().optional(),
|
|
56084
|
-
/** Suggested decimal places for numeric display.
|
|
56085
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56086
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56087
|
-
* auto-formatting when absent. */
|
|
56088
|
-
precision: number().int().min(0).max(10).optional()
|
|
56493
|
+
lastFetchedAt: number()
|
|
56089
56494
|
});
|
|
56090
56495
|
DeviceType.Sensor;
|
|
56091
56496
|
/**
|
|
@@ -56230,10 +56635,7 @@ var BatteryStatusSchema = object({
|
|
|
56230
56635
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56231
56636
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56232
56637
|
*/
|
|
56233
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56234
|
-
unit: "%",
|
|
56235
|
-
label: "Charge"
|
|
56236
|
-
}),
|
|
56638
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56237
56639
|
/**
|
|
56238
56640
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56239
56641
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56260,7 +56662,14 @@ var BatteryStatusSchema = object({
|
|
|
56260
56662
|
*/
|
|
56261
56663
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56262
56664
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56263
|
-
lastUpdated: number(),
|
|
56665
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56666
|
+
/**
|
|
56667
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56668
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56669
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56670
|
+
* `numeric-sensor` on the same device.
|
|
56671
|
+
*/
|
|
56672
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56264
56673
|
/**
|
|
56265
56674
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56266
56675
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56320,7 +56729,7 @@ object({
|
|
|
56320
56729
|
DeviceType.Sensor;
|
|
56321
56730
|
object({
|
|
56322
56731
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56323
|
-
percentage: number().min(0).max(100),
|
|
56732
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56324
56733
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56325
56734
|
lastChangedAt: number()
|
|
56326
56735
|
});
|
|
@@ -56705,21 +57114,21 @@ object({
|
|
|
56705
57114
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56706
57115
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56707
57116
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56708
|
-
target: number().nullable(),
|
|
57117
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56709
57118
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56710
57119
|
* in `heat_cool` mode. */
|
|
56711
|
-
targetHigh: number().nullable(),
|
|
57120
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56712
57121
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56713
57122
|
* in `heat_cool` mode. */
|
|
56714
|
-
targetLow: number().nullable(),
|
|
57123
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56715
57124
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56716
57125
|
* humidity control. */
|
|
56717
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57126
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56718
57127
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56719
57128
|
* the device's internal sensor. */
|
|
56720
|
-
currentTemp: number().nullable(),
|
|
57129
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56721
57130
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56722
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57131
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56723
57132
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56724
57133
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56725
57134
|
swingVertical: boolean().nullable(),
|
|
@@ -56727,11 +57136,11 @@ object({
|
|
|
56727
57136
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56728
57137
|
swingHorizontal: boolean().nullable(),
|
|
56729
57138
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56730
|
-
minTemp: number().nullable().optional(),
|
|
57139
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56731
57140
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56732
|
-
maxTemp: number().nullable().optional(),
|
|
57141
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56733
57142
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56734
|
-
tempStep: number().positive().nullable().optional(),
|
|
57143
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56735
57144
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56736
57145
|
lastFetchedAt: number()
|
|
56737
57146
|
});
|
|
@@ -56810,17 +57219,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
56810
57219
|
* modes to expose in the picker without a slice fetch.
|
|
56811
57220
|
*/
|
|
56812
57221
|
var RgbTripletSchema = object({
|
|
56813
|
-
r: number().int().min(0).max(255),
|
|
56814
|
-
g: number().int().min(0).max(255),
|
|
56815
|
-
b: number().int().min(0).max(255)
|
|
57222
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57223
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57224
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
56816
57225
|
});
|
|
56817
57226
|
var HsvTripletSchema = object({
|
|
56818
57227
|
/** Hue in degrees, 0..360. */
|
|
56819
|
-
h: number().min(0).max(360),
|
|
57228
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
56820
57229
|
/** Saturation as 0..100 inclusive. */
|
|
56821
|
-
s: number().min(0).max(100),
|
|
57230
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
56822
57231
|
/** Value/brightness as 0..100 inclusive. */
|
|
56823
|
-
v: number().min(0).max(100)
|
|
57232
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
56824
57233
|
});
|
|
56825
57234
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
56826
57235
|
object({
|
|
@@ -56849,7 +57258,7 @@ object({
|
|
|
56849
57258
|
/** Populated when `mode === 'hsv'`. */
|
|
56850
57259
|
hsv: HsvTripletSchema.optional(),
|
|
56851
57260
|
/** Populated when `mode === 'mired'`. */
|
|
56852
|
-
mireds: number().int().optional(),
|
|
57261
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
56853
57262
|
/** Ms epoch of the last operator-driven change. */
|
|
56854
57263
|
lastChangedAt: number()
|
|
56855
57264
|
});
|
|
@@ -56973,18 +57382,12 @@ _enum([
|
|
|
56973
57382
|
"empty",
|
|
56974
57383
|
"full"
|
|
56975
57384
|
]);
|
|
56976
|
-
/**
|
|
56977
|
-
|
|
56978
|
-
|
|
56979
|
-
"days",
|
|
56980
|
-
"hours",
|
|
56981
|
-
"cycles"
|
|
56982
|
-
]);
|
|
56983
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
56984
|
-
* days). `value` null = unknown (D393). */
|
|
57385
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57386
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57387
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
56985
57388
|
var ConsumableRemainingSchema = object({
|
|
56986
|
-
value: number().min(0).nullable(),
|
|
56987
|
-
|
|
57389
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57390
|
+
kind: ConsumableRemainingKindSchema
|
|
56988
57391
|
});
|
|
56989
57392
|
var ConsumablesStatusSchema = object({
|
|
56990
57393
|
items: array(object({
|
|
@@ -56993,7 +57396,7 @@ var ConsumablesStatusSchema = object({
|
|
|
56993
57396
|
/** Display name. */
|
|
56994
57397
|
label: string().min(1),
|
|
56995
57398
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
56996
|
-
level: number().min(0).max(100).nullable(),
|
|
57399
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
56997
57400
|
/** The provider's discrete verdict when known (binary mode). */
|
|
56998
57401
|
status: ConsumableStatusSchema.nullable(),
|
|
56999
57402
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57010,7 +57413,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57010
57413
|
})),
|
|
57011
57414
|
lastChangedAt: number()
|
|
57012
57415
|
});
|
|
57013
|
-
Object.values(DeviceType), [...
|
|
57416
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57014
57417
|
Object.values(DeviceType), method(object({
|
|
57015
57418
|
deviceId: number().int().nonnegative(),
|
|
57016
57419
|
key: string().min(1)
|
|
@@ -57035,39 +57438,17 @@ object({
|
|
|
57035
57438
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57036
57439
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57037
57440
|
* or time-only — HA accepts all three forms). */
|
|
57038
|
-
value: union([number(), string()]),
|
|
57441
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57039
57442
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57040
57443
|
options: array(string()),
|
|
57041
57444
|
/** Ms epoch when the slice was last updated. */
|
|
57042
57445
|
lastChangedAt: number(),
|
|
57043
|
-
/**
|
|
57044
|
-
|
|
57045
|
-
|
|
57046
|
-
|
|
57047
|
-
/**
|
|
57048
|
-
|
|
57049
|
-
min: number().optional(),
|
|
57050
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57051
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57052
|
-
max: number().optional(),
|
|
57053
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57054
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57055
|
-
step: number().optional(),
|
|
57056
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57057
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57058
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57059
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57060
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57061
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57062
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57063
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57064
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57065
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57066
|
-
format: _enum([
|
|
57067
|
-
"date",
|
|
57068
|
-
"time",
|
|
57069
|
-
"datetime"
|
|
57070
|
-
]).optional()
|
|
57446
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57447
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57448
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57449
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57450
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57451
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57071
57452
|
});
|
|
57072
57453
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57073
57454
|
object({
|
|
@@ -57105,9 +57486,9 @@ object({
|
|
|
57105
57486
|
]),
|
|
57106
57487
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57107
57488
|
* no intermediate position surface. */
|
|
57108
|
-
position: number().min(0).max(100).nullable(),
|
|
57489
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57109
57490
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57110
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57491
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57111
57492
|
/** Ms epoch when the slice was last updated. */
|
|
57112
57493
|
lastChangedAt: number()
|
|
57113
57494
|
});
|
|
@@ -57165,9 +57546,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57165
57546
|
object({
|
|
57166
57547
|
mode: DayNightModeSchema,
|
|
57167
57548
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57168
|
-
sensitivity: number().optional(),
|
|
57549
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57169
57550
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57170
|
-
switchDelaySec: number().optional(),
|
|
57551
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57171
57552
|
lastFetchedAt: number()
|
|
57172
57553
|
});
|
|
57173
57554
|
/**
|
|
@@ -57322,11 +57703,11 @@ object({
|
|
|
57322
57703
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57323
57704
|
availablePrograms: array(string()),
|
|
57324
57705
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57325
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57706
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57326
57707
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57327
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57708
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57328
57709
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57329
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57710
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57330
57711
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57331
57712
|
doorOpen: boolean().nullable(),
|
|
57332
57713
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57350,7 +57731,7 @@ object({
|
|
|
57350
57731
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57351
57732
|
machineCareDue: boolean().nullable(),
|
|
57352
57733
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57353
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57734
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57354
57735
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57355
57736
|
halfLoad: boolean().nullable(),
|
|
57356
57737
|
hygienePlus: boolean().nullable(),
|
|
@@ -57365,7 +57746,7 @@ object({
|
|
|
57365
57746
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57366
57747
|
activeEvents: array(string()),
|
|
57367
57748
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57368
|
-
errorCode: number().nullable(),
|
|
57749
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57369
57750
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57370
57751
|
errorLabel: string().nullable(),
|
|
57371
57752
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57511,24 +57892,14 @@ object({
|
|
|
57511
57892
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57512
57893
|
lastPressedAt: number().nullable(),
|
|
57513
57894
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57514
|
-
pressCountSinceStart: number()
|
|
57895
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57515
57896
|
});
|
|
57516
57897
|
object({
|
|
57517
57898
|
deviceId: number(),
|
|
57518
57899
|
timestamp: number()
|
|
57519
57900
|
});
|
|
57520
57901
|
DeviceType.Button, DeviceType.Camera;
|
|
57521
|
-
|
|
57522
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57523
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57524
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57525
|
-
* The option set is stable across observations; it is persisted in the
|
|
57526
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57527
|
-
* stored in `sourceInfo`.
|
|
57528
|
-
*/
|
|
57529
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57530
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57531
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
57902
|
+
_enum([
|
|
57532
57903
|
"date",
|
|
57533
57904
|
"time",
|
|
57534
57905
|
"datetime"
|
|
@@ -57536,12 +57907,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57536
57907
|
object({
|
|
57537
57908
|
value: string(),
|
|
57538
57909
|
/**
|
|
57539
|
-
* Set
|
|
57540
|
-
* as
|
|
57541
|
-
*
|
|
57542
|
-
* a time-only sensor → `'time'`.
|
|
57910
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
57911
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
57912
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57543
57913
|
*/
|
|
57544
|
-
|
|
57914
|
+
timestamp: boolean().optional(),
|
|
57545
57915
|
/** Ms epoch when the slice was last updated. */
|
|
57546
57916
|
lastFetchedAt: number()
|
|
57547
57917
|
});
|
|
@@ -57560,13 +57930,13 @@ var EventFireSchema = object({
|
|
|
57560
57930
|
deviceId: number(),
|
|
57561
57931
|
eventType: string(),
|
|
57562
57932
|
data: record(string(), unknown()).nullable(),
|
|
57563
|
-
timestamp: number(),
|
|
57564
|
-
seq: number()
|
|
57933
|
+
timestamp: number().meta(readingMeta("none")),
|
|
57934
|
+
seq: number().meta(readingMeta("count"))
|
|
57565
57935
|
});
|
|
57566
57936
|
object({
|
|
57567
57937
|
eventTypes: array(string()),
|
|
57568
57938
|
lastEvent: EventFireSchema.nullable(),
|
|
57569
|
-
eventCountSinceStart: number()
|
|
57939
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57570
57940
|
});
|
|
57571
57941
|
DeviceType.EventEmitter;
|
|
57572
57942
|
var IdentitySchema = object({
|
|
@@ -57955,10 +58325,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
57955
58325
|
object({
|
|
57956
58326
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
57957
58327
|
* speed surface (single-speed fan). */
|
|
57958
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58328
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57959
58329
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
57960
58330
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
57961
|
-
percentageStep: number().positive().optional(),
|
|
58331
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
57962
58332
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
57963
58333
|
* — empty string when no preset is active or supported. */
|
|
57964
58334
|
preset: string(),
|
|
@@ -58040,7 +58410,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58040
58410
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58041
58411
|
model: string().nullable(),
|
|
58042
58412
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58043
|
-
channelCount: number().nullable(),
|
|
58413
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58044
58414
|
/**
|
|
58045
58415
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58046
58416
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58072,9 +58442,39 @@ object({
|
|
|
58072
58442
|
lastChangedAt: number()
|
|
58073
58443
|
});
|
|
58074
58444
|
DeviceType.Sensor;
|
|
58445
|
+
object({
|
|
58446
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58447
|
+
results: array(object({
|
|
58448
|
+
deviceId: number().int().nonnegative(),
|
|
58449
|
+
cap: string().min(1),
|
|
58450
|
+
method: string().min(1),
|
|
58451
|
+
ok: boolean(),
|
|
58452
|
+
error: string().optional(),
|
|
58453
|
+
/** Ms epoch of the attempt. */
|
|
58454
|
+
at: number()
|
|
58455
|
+
})) });
|
|
58456
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58457
|
+
object({
|
|
58458
|
+
/** Members whose current value entered the aggregate. */
|
|
58459
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58460
|
+
precision: 0,
|
|
58461
|
+
label: "Reporting"
|
|
58462
|
+
})),
|
|
58463
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58464
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58465
|
+
precision: 0,
|
|
58466
|
+
label: "Excluded"
|
|
58467
|
+
})),
|
|
58468
|
+
/** `included` + `excluded`. */
|
|
58469
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58470
|
+
precision: 0,
|
|
58471
|
+
label: "Members"
|
|
58472
|
+
}))
|
|
58473
|
+
});
|
|
58474
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58075
58475
|
object({
|
|
58076
58476
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58077
|
-
position: number().min(0).max(100).nullable(),
|
|
58477
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58078
58478
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58079
58479
|
lastFetchedAt: number()
|
|
58080
58480
|
});
|
|
@@ -58083,9 +58483,9 @@ object({
|
|
|
58083
58483
|
/** Whether the humidifier is currently on. */
|
|
58084
58484
|
on: boolean(),
|
|
58085
58485
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58086
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58486
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58087
58487
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58088
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58488
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58089
58489
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58090
58490
|
* device has no mode surface. */
|
|
58091
58491
|
mode: string().nullable(),
|
|
@@ -58095,9 +58495,9 @@ object({
|
|
|
58095
58495
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58096
58496
|
action: string().nullable(),
|
|
58097
58497
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58098
|
-
minHumidity: number().nullable(),
|
|
58498
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58099
58499
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58100
|
-
maxHumidity: number().nullable(),
|
|
58500
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58101
58501
|
/** Ms epoch when the slice was last updated. */
|
|
58102
58502
|
lastChangedAt: number()
|
|
58103
58503
|
});
|
|
@@ -58121,22 +58521,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58121
58521
|
auth: "protected"
|
|
58122
58522
|
});
|
|
58123
58523
|
object({
|
|
58124
|
-
/** Current relative humidity, 0..100. */
|
|
58125
|
-
percent: number().min(0).max(100).meta({
|
|
58126
|
-
|
|
58524
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58525
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58526
|
+
precision: 0,
|
|
58127
58527
|
label: "Humidity"
|
|
58128
|
-
}),
|
|
58528
|
+
})),
|
|
58129
58529
|
/** Ms epoch when the slice was last updated. */
|
|
58130
|
-
lastFetchedAt: number()
|
|
58131
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58132
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58133
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58134
|
-
unit: string().optional(),
|
|
58135
|
-
/** Suggested decimal places for numeric display.
|
|
58136
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58137
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58138
|
-
* auto-formatting when absent. */
|
|
58139
|
-
precision: number().int().min(0).max(10).optional()
|
|
58530
|
+
lastFetchedAt: number()
|
|
58140
58531
|
});
|
|
58141
58532
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58142
58533
|
object({
|
|
@@ -58144,7 +58535,7 @@ object({
|
|
|
58144
58535
|
* entity exposes no `entity_picture` (yet). */
|
|
58145
58536
|
url: string().nullable(),
|
|
58146
58537
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58147
|
-
lastUpdated: number().nullable()
|
|
58538
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58148
58539
|
});
|
|
58149
58540
|
DeviceType.Image;
|
|
58150
58541
|
/**
|
|
@@ -58200,19 +58591,19 @@ var NormalizedRangeSchema = object({
|
|
|
58200
58591
|
});
|
|
58201
58592
|
object({
|
|
58202
58593
|
/** Normalized 0–100. */
|
|
58203
|
-
brightness: number().optional(),
|
|
58594
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58204
58595
|
/** Normalized 0–100. */
|
|
58205
|
-
contrast: number().optional(),
|
|
58596
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58206
58597
|
/** Normalized 0–100. */
|
|
58207
|
-
saturation: number().optional(),
|
|
58598
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58208
58599
|
/** Normalized 0–100. */
|
|
58209
|
-
sharpness: number().optional(),
|
|
58600
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58210
58601
|
mirror: boolean().optional(),
|
|
58211
58602
|
flip: boolean().optional(),
|
|
58212
58603
|
rotate: ImageRotateSchema.optional(),
|
|
58213
58604
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58214
58605
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58215
|
-
warmth: number().optional(),
|
|
58606
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58216
58607
|
exposureMode: ExposureModeSchema.optional(),
|
|
58217
58608
|
backlightMode: BacklightModeSchema.optional(),
|
|
58218
58609
|
lastFetchedAt: number()
|
|
@@ -58457,10 +58848,10 @@ var IntercomAbilitySchema = object({
|
|
|
58457
58848
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58458
58849
|
codecs: array(string()),
|
|
58459
58850
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58460
|
-
sampleRate: number(),
|
|
58851
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58461
58852
|
duplex: _enum(["half", "full"]),
|
|
58462
58853
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58463
|
-
maxBacklogMs: number()
|
|
58854
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58464
58855
|
});
|
|
58465
58856
|
var IntercomStatusSchema = object({
|
|
58466
58857
|
/** True while a talk session is open. */
|
|
@@ -58571,13 +58962,13 @@ object({
|
|
|
58571
58962
|
activity: LawnMowerActivitySchema,
|
|
58572
58963
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58573
58964
|
* reading. */
|
|
58574
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
58965
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58575
58966
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58576
58967
|
* task is active / progress is unavailable. */
|
|
58577
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58968
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58578
58969
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58579
58970
|
* or null when unknown. */
|
|
58580
|
-
currentCode: number().nullable(),
|
|
58971
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58581
58972
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58582
58973
|
currentCodeLabel: string().nullable(),
|
|
58583
58974
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59039,7 +59430,7 @@ object({
|
|
|
59039
59430
|
state: MediaPlayerStateSchema,
|
|
59040
59431
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59041
59432
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59042
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59433
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59043
59434
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59044
59435
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59045
59436
|
isMuted: boolean().nullable(),
|
|
@@ -59052,10 +59443,10 @@ object({
|
|
|
59052
59443
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59053
59444
|
/** Current playback position in ms. Null when not seekable or
|
|
59054
59445
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59055
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59446
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59056
59447
|
/** Total duration of the current media in ms. Null when unknown
|
|
59057
59448
|
* (live stream) or nothing is playing. */
|
|
59058
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59449
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59059
59450
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59060
59451
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59061
59452
|
shuffle: boolean().nullable(),
|
|
@@ -59355,7 +59746,7 @@ object({
|
|
|
59355
59746
|
* it, every provider seeded it at boot, and every session left it
|
|
59356
59747
|
* `detected: true` after its detach.
|
|
59357
59748
|
*/
|
|
59358
|
-
autoClearAfterMs: number().nullable()
|
|
59749
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59359
59750
|
});
|
|
59360
59751
|
/**
|
|
59361
59752
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59405,7 +59796,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59405
59796
|
});
|
|
59406
59797
|
object({
|
|
59407
59798
|
enabled: boolean(),
|
|
59408
|
-
sensitivity: number(),
|
|
59799
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59409
59800
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59410
59801
|
regions: array(MotionZoneRegionSchema),
|
|
59411
59802
|
lastFetchedAt: number()
|
|
@@ -59709,7 +60100,7 @@ var NavigationStatusSchema = object({
|
|
|
59709
60100
|
following: boolean(),
|
|
59710
60101
|
flash: boolean(),
|
|
59711
60102
|
lightMode: NavigationLightModeSchema,
|
|
59712
|
-
lightLevel: number().min(40).max(100),
|
|
60103
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59713
60104
|
/** Ms epoch when the slice was last updated. */
|
|
59714
60105
|
lastChangedAt: number()
|
|
59715
60106
|
});
|
|
@@ -59755,13 +60146,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59755
60146
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59756
60147
|
* SKIP a null rather than coerce it.
|
|
59757
60148
|
*/
|
|
59758
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
60149
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59759
60150
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59760
|
-
rssiDbm: number().optional(),
|
|
60151
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59761
60152
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59762
60153
|
ssid: string().optional(),
|
|
59763
60154
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59764
|
-
lastUpdated: number()
|
|
60155
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59765
60156
|
});
|
|
59766
60157
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59767
60158
|
deviceId: number(),
|
|
@@ -60080,7 +60471,7 @@ object({
|
|
|
60080
60471
|
lastError: string().nullable(),
|
|
60081
60472
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60082
60473
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60083
|
-
queueDepth: number().int().nonnegative(),
|
|
60474
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60084
60475
|
/** Per-feature capability matrix — authoritative source for the
|
|
60085
60476
|
* compose-form field gating. */
|
|
60086
60477
|
supports: NotifierSupportsSchema
|
|
@@ -60130,15 +60521,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60130
60521
|
acceptedAt: number()
|
|
60131
60522
|
});
|
|
60132
60523
|
object({
|
|
60133
|
-
|
|
60134
|
-
|
|
60135
|
-
* Populated live from the upstream source on each state push.
|
|
60136
|
-
* Absent for unitless sensors. */
|
|
60137
|
-
unit: string().optional(),
|
|
60138
|
-
/** Suggested decimal places for numeric display.
|
|
60139
|
-
* Populated live from the upstream source when provided.
|
|
60140
|
-
* Falls back to auto-formatting when absent. */
|
|
60141
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60524
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60525
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60142
60526
|
/** Ms epoch when the slice was last updated. */
|
|
60143
60527
|
lastFetchedAt: number()
|
|
60144
60528
|
});
|
|
@@ -60428,23 +60812,26 @@ object({
|
|
|
60428
60812
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60429
60813
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60430
60814
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60431
|
-
foodLevel: number().nullable(),
|
|
60815
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60432
60816
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60433
60817
|
* single-hopper models. */
|
|
60434
|
-
food1: number().nullable(),
|
|
60818
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60435
60819
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60436
60820
|
* single-hopper models. */
|
|
60437
|
-
food2: number().nullable(),
|
|
60821
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60438
60822
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60439
60823
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60440
60824
|
* below the feeder's low threshold. */
|
|
60441
60825
|
lowFood: boolean(),
|
|
60442
60826
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60443
60827
|
* device has no battery reading. */
|
|
60444
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60445
|
-
/**
|
|
60446
|
-
*
|
|
60447
|
-
|
|
60828
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60829
|
+
/**
|
|
60830
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
60831
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
60832
|
+
* model has no desiccant sensor.
|
|
60833
|
+
*/
|
|
60834
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60448
60835
|
/** True while a feed is in progress. */
|
|
60449
60836
|
feeding: boolean(),
|
|
60450
60837
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60455,7 +60842,7 @@ object({
|
|
|
60455
60842
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60456
60843
|
error: string().nullable(),
|
|
60457
60844
|
/** Raw device error code (0 / null = no error). */
|
|
60458
|
-
errorCode: number().nullable(),
|
|
60845
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60459
60846
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60460
60847
|
isDualHopper: boolean(),
|
|
60461
60848
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60465,7 +60852,7 @@ object({
|
|
|
60465
60852
|
/** Play a chime when dispensing. */
|
|
60466
60853
|
feedSound: boolean(),
|
|
60467
60854
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60468
|
-
volume: number(),
|
|
60855
|
+
volume: number().meta(readingMeta("none")),
|
|
60469
60856
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60470
60857
|
lastFetchedAt: number()
|
|
60471
60858
|
});
|
|
@@ -60902,36 +61289,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
60902
61289
|
});
|
|
60903
61290
|
object({
|
|
60904
61291
|
/** Instantaneous power draw in watts. */
|
|
60905
|
-
watts: number().optional().meta({
|
|
60906
|
-
unit: "W",
|
|
60907
|
-
label: "Power"
|
|
60908
|
-
}),
|
|
61292
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
60909
61293
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
60910
|
-
kwhTotal: number().optional().meta({
|
|
60911
|
-
unit: "kWh",
|
|
60912
|
-
label: "Energy"
|
|
60913
|
-
}),
|
|
61294
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
60914
61295
|
/** Voltage in volts. */
|
|
60915
|
-
volts: number().optional(),
|
|
61296
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
60916
61297
|
/** Current in amperes. */
|
|
60917
|
-
amps: number().optional(),
|
|
60918
|
-
/** Apparent power in volt-amperes
|
|
60919
|
-
va: number().optional(),
|
|
61298
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61299
|
+
/** Apparent power in volt-amperes. */
|
|
61300
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
60920
61301
|
/** Power factor (0..1) if reported. */
|
|
60921
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61302
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
60922
61303
|
/** Ms epoch when the slice was last updated. */
|
|
60923
|
-
lastFetchedAt: number()
|
|
60924
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
60925
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
60926
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
60927
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
60928
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
60929
|
-
unit: string().optional(),
|
|
60930
|
-
/** Suggested decimal places for numeric display.
|
|
60931
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60932
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60933
|
-
* auto-formatting when absent. */
|
|
60934
|
-
precision: number().int().min(0).max(10).optional()
|
|
61304
|
+
lastFetchedAt: number()
|
|
60935
61305
|
});
|
|
60936
61306
|
DeviceType.Sensor;
|
|
60937
61307
|
/**
|
|
@@ -60952,11 +61322,11 @@ DeviceType.Sensor;
|
|
|
60952
61322
|
*/
|
|
60953
61323
|
var GpsLocationSchema = object({
|
|
60954
61324
|
/** Latitude in decimal degrees, -90..90. */
|
|
60955
|
-
latitude: number().min(-90).max(90),
|
|
61325
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
60956
61326
|
/** Longitude in decimal degrees, -180..180. */
|
|
60957
|
-
longitude: number().min(-180).max(180),
|
|
61327
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
60958
61328
|
/** Reported accuracy in meters (lower = better). */
|
|
60959
|
-
accuracyMeters: number().nonnegative()
|
|
61329
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
60960
61330
|
});
|
|
60961
61331
|
object({
|
|
60962
61332
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -60968,25 +61338,16 @@ object({
|
|
|
60968
61338
|
gps: GpsLocationSchema.nullable(),
|
|
60969
61339
|
/** Optional battery level of the tracking device (0..100). Null
|
|
60970
61340
|
* when not reported. */
|
|
60971
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61341
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60972
61342
|
/** Ms epoch when the slice was last updated. */
|
|
60973
61343
|
lastChangedAt: number()
|
|
60974
61344
|
});
|
|
60975
61345
|
DeviceType.Presence;
|
|
60976
61346
|
object({
|
|
60977
|
-
/** Current pressure in hPa. */
|
|
60978
|
-
hpa: number(),
|
|
61347
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61348
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
60979
61349
|
/** Ms epoch when the slice was last updated. */
|
|
60980
|
-
lastFetchedAt: number()
|
|
60981
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60982
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60983
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60984
|
-
unit: string().optional(),
|
|
60985
|
-
/** Suggested decimal places for numeric display.
|
|
60986
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60987
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60988
|
-
* auto-formatting when absent. */
|
|
60989
|
-
precision: number().int().min(0).max(10).optional()
|
|
61350
|
+
lastFetchedAt: number()
|
|
60990
61351
|
});
|
|
60991
61352
|
DeviceType.Sensor;
|
|
60992
61353
|
/**
|
|
@@ -61411,8 +61772,8 @@ var ptzCapability = {
|
|
|
61411
61772
|
};
|
|
61412
61773
|
var PtzAutotrackSettingsSchema = object({
|
|
61413
61774
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61414
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61415
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61775
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61776
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61416
61777
|
});
|
|
61417
61778
|
/**
|
|
61418
61779
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61469,7 +61830,7 @@ object({
|
|
|
61469
61830
|
/** null = unknown — never coerced to false (D393). */
|
|
61470
61831
|
running: boolean().nullable(),
|
|
61471
61832
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61472
|
-
since: number().nullable(),
|
|
61833
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61473
61834
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61474
61835
|
phase: string().nullable(),
|
|
61475
61836
|
/** null until a reading has been published (D393). */
|
|
@@ -62667,9 +63028,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62667
63028
|
*/
|
|
62668
63029
|
var RecordWindowSchema = object({
|
|
62669
63030
|
trigger: RecordTriggerSchema,
|
|
62670
|
-
day: number().int().min(0).max(6),
|
|
62671
|
-
startMinute: number().int().min(0).max(1439),
|
|
62672
|
-
endMinute: number().int().min(1).max(1440)
|
|
63031
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
63032
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
63033
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62673
63034
|
});
|
|
62674
63035
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62675
63036
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62738,10 +63099,10 @@ object({
|
|
|
62738
63099
|
/** Master "record to the card at all" switch. */
|
|
62739
63100
|
enabled: boolean().nullable(),
|
|
62740
63101
|
overwriteWhenFull: boolean().nullable(),
|
|
62741
|
-
preRecordSec: number().nullable(),
|
|
62742
|
-
postRecordSec: number().nullable(),
|
|
63102
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
63103
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62743
63104
|
/** Length of one recorded file, in minutes. */
|
|
62744
|
-
segmentMinutes: number().nullable(),
|
|
63105
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62745
63106
|
/** The primary track's weekly windows, flattened. */
|
|
62746
63107
|
windows: array(RecordWindowSchema),
|
|
62747
63108
|
/**
|
|
@@ -62757,7 +63118,7 @@ object({
|
|
|
62757
63118
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62758
63119
|
* writable.
|
|
62759
63120
|
*/
|
|
62760
|
-
unreadableWindows: number(),
|
|
63121
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62761
63122
|
/**
|
|
62762
63123
|
* The camera is scheduled to record and has NO usable storage.
|
|
62763
63124
|
*
|
|
@@ -63394,7 +63755,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63394
63755
|
url: string().optional(),
|
|
63395
63756
|
codec: string().optional(),
|
|
63396
63757
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63397
|
-
fps: number().positive().optional(),
|
|
63758
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63398
63759
|
label: string().optional(),
|
|
63399
63760
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63400
63761
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63424,18 +63785,18 @@ var StreamProfileSchema = _enum([
|
|
|
63424
63785
|
]);
|
|
63425
63786
|
/** The current encoding config of one stream profile. */
|
|
63426
63787
|
var StreamProfileConfigSchema = object({
|
|
63427
|
-
width: number(),
|
|
63428
|
-
height: number(),
|
|
63788
|
+
width: number().meta(readingMeta("none")),
|
|
63789
|
+
height: number().meta(readingMeta("none")),
|
|
63429
63790
|
codec: _enum(["h264", "h265"]),
|
|
63430
|
-
framerate: number(),
|
|
63431
|
-
bitrate: number(),
|
|
63791
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63792
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63432
63793
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63433
63794
|
encoderProfile: _enum([
|
|
63434
63795
|
"high",
|
|
63435
63796
|
"main",
|
|
63436
63797
|
"baseline"
|
|
63437
63798
|
]).optional(),
|
|
63438
|
-
gop: number().optional(),
|
|
63799
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63439
63800
|
/**
|
|
63440
63801
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63441
63802
|
*
|
|
@@ -64078,23 +64439,13 @@ object({
|
|
|
64078
64439
|
});
|
|
64079
64440
|
DeviceType.Sensor;
|
|
64080
64441
|
object({
|
|
64081
|
-
/** Current temperature in Celsius. */
|
|
64082
|
-
celsius: number().meta({
|
|
64083
|
-
|
|
64442
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64443
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64444
|
+
precision: 1,
|
|
64084
64445
|
label: "Temperature"
|
|
64085
|
-
}),
|
|
64446
|
+
})),
|
|
64086
64447
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64087
|
-
lastFetchedAt: number()
|
|
64088
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64089
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64090
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64091
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64092
|
-
unit: string().optional(),
|
|
64093
|
-
/** Suggested decimal places for numeric display.
|
|
64094
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64095
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64096
|
-
* auto-formatting when absent. */
|
|
64097
|
-
precision: number().int().min(0).max(10).optional()
|
|
64448
|
+
lastFetchedAt: number()
|
|
64098
64449
|
});
|
|
64099
64450
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64100
64451
|
/**
|
|
@@ -64346,16 +64697,16 @@ object({
|
|
|
64346
64697
|
]),
|
|
64347
64698
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64348
64699
|
* reading. */
|
|
64349
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64700
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64350
64701
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64351
64702
|
* the vacuum has no speed control. */
|
|
64352
64703
|
fanSpeed: string().nullable(),
|
|
64353
64704
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64354
64705
|
availableFanSpeeds: array(string()),
|
|
64355
64706
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64356
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64707
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64357
64708
|
/** Current error code (0 / null = no error). */
|
|
64358
|
-
errorCode: number().nullable(),
|
|
64709
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64359
64710
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64360
64711
|
errorLabel: string().nullable(),
|
|
64361
64712
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64394,7 +64745,7 @@ object({
|
|
|
64394
64745
|
]),
|
|
64395
64746
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64396
64747
|
* intermediate position surface. */
|
|
64397
|
-
position: number().min(0).max(100).nullable(),
|
|
64748
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64398
64749
|
/** Ms epoch when the slice was last updated. */
|
|
64399
64750
|
lastChangedAt: number()
|
|
64400
64751
|
});
|
|
@@ -64422,9 +64773,9 @@ object({
|
|
|
64422
64773
|
DeviceType.Sensor;
|
|
64423
64774
|
object({
|
|
64424
64775
|
/** Current measured temperature. Null when not reported. */
|
|
64425
|
-
currentTemp: number().nullable(),
|
|
64776
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64426
64777
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64427
|
-
targetTemp: number().nullable(),
|
|
64778
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64428
64779
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64429
64780
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64430
64781
|
* device reports an unknown state. */
|
|
@@ -64435,9 +64786,9 @@ object({
|
|
|
64435
64786
|
* has no away surface. */
|
|
64436
64787
|
away: boolean().nullable(),
|
|
64437
64788
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64438
|
-
minTemp: number().nullable(),
|
|
64789
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64439
64790
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64440
|
-
maxTemp: number().nullable(),
|
|
64791
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64441
64792
|
/** Ms epoch when the slice was last updated. */
|
|
64442
64793
|
lastChangedAt: number()
|
|
64443
64794
|
});
|
|
@@ -64461,25 +64812,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64461
64812
|
auth: "protected"
|
|
64462
64813
|
});
|
|
64463
64814
|
object({
|
|
64464
|
-
/** Verbatim
|
|
64465
|
-
* when no condition has been reported yet. */
|
|
64815
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64466
64816
|
condition: string().nullable(),
|
|
64467
|
-
/** Current temperature in
|
|
64468
|
-
temperature: number().nullable(),
|
|
64469
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64470
|
-
temperatureUnit: string().nullable(),
|
|
64817
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64818
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64471
64819
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64472
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64473
|
-
/** Barometric pressure in
|
|
64474
|
-
pressure: number().nullable(),
|
|
64475
|
-
/**
|
|
64476
|
-
|
|
64477
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64478
|
-
windSpeed: number().nullable(),
|
|
64479
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64480
|
-
windSpeedUnit: string().nullable(),
|
|
64820
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64821
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64822
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64823
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64824
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64481
64825
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64482
|
-
windBearing: number().nullable(),
|
|
64826
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64483
64827
|
/** Ms epoch when the slice was last updated. */
|
|
64484
64828
|
lastFetchedAt: number()
|
|
64485
64829
|
});
|
|
@@ -66216,6 +66560,13 @@ Object.freeze({
|
|
|
66216
66560
|
access: "view",
|
|
66217
66561
|
role: "admin"
|
|
66218
66562
|
},
|
|
66563
|
+
"addons.getPackageDocs": {
|
|
66564
|
+
capName: "addons",
|
|
66565
|
+
capScope: "system",
|
|
66566
|
+
addonId: null,
|
|
66567
|
+
access: "view",
|
|
66568
|
+
role: "admin"
|
|
66569
|
+
},
|
|
66219
66570
|
"addons.getVersions": {
|
|
66220
66571
|
capName: "addons",
|
|
66221
66572
|
capScope: "system",
|
|
@@ -69324,6 +69675,20 @@ Object.freeze({
|
|
|
69324
69675
|
access: "view",
|
|
69325
69676
|
role: "viewer"
|
|
69326
69677
|
},
|
|
69678
|
+
"groupCommands.getStatus": {
|
|
69679
|
+
capName: "group-commands",
|
|
69680
|
+
capScope: "device",
|
|
69681
|
+
addonId: null,
|
|
69682
|
+
access: "view",
|
|
69683
|
+
role: "viewer"
|
|
69684
|
+
},
|
|
69685
|
+
"groupStatus.getStatus": {
|
|
69686
|
+
capName: "group-status",
|
|
69687
|
+
capScope: "device",
|
|
69688
|
+
addonId: null,
|
|
69689
|
+
access: "view",
|
|
69690
|
+
role: "viewer"
|
|
69691
|
+
},
|
|
69327
69692
|
"heatingValve.getStatus": {
|
|
69328
69693
|
capName: "heating-valve",
|
|
69329
69694
|
capScope: "device",
|
|
@@ -79146,6 +79511,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79146
79511
|
icon: "flame"
|
|
79147
79512
|
}]
|
|
79148
79513
|
},
|
|
79514
|
+
"group-commands": {
|
|
79515
|
+
scope: "device",
|
|
79516
|
+
noun: t("Group command", "Comando di gruppo")
|
|
79517
|
+
},
|
|
79518
|
+
"group-status": {
|
|
79519
|
+
scope: "device",
|
|
79520
|
+
noun: t("Group", "Gruppo"),
|
|
79521
|
+
state: [
|
|
79522
|
+
{
|
|
79523
|
+
kind: "numeric",
|
|
79524
|
+
field: "included",
|
|
79525
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
79526
|
+
label: t("Reporting", "Rispondono"),
|
|
79527
|
+
icon: "users"
|
|
79528
|
+
},
|
|
79529
|
+
{
|
|
79530
|
+
kind: "numeric",
|
|
79531
|
+
field: "excluded",
|
|
79532
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
79533
|
+
label: t("Excluded", "Esclusi"),
|
|
79534
|
+
icon: "users"
|
|
79535
|
+
},
|
|
79536
|
+
{
|
|
79537
|
+
kind: "numeric",
|
|
79538
|
+
field: "total",
|
|
79539
|
+
quantity: t("the member count", "il numero di membri"),
|
|
79540
|
+
label: t("Members", "Membri"),
|
|
79541
|
+
icon: "sigma"
|
|
79542
|
+
}
|
|
79543
|
+
]
|
|
79544
|
+
},
|
|
79149
79545
|
"humidity-sensor": {
|
|
79150
79546
|
scope: "device",
|
|
79151
79547
|
noun: t("Humidity", "Umidità"),
|
|
@@ -79179,7 +79575,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79179
79575
|
field: "value",
|
|
79180
79576
|
quantity: t("the reading", "il valore"),
|
|
79181
79577
|
label: t("Reading", "Valore"),
|
|
79182
|
-
unitField: "unit",
|
|
79183
79578
|
icon: "gauge"
|
|
79184
79579
|
}]
|
|
79185
79580
|
},
|
|
@@ -79315,7 +79710,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79315
79710
|
field: "temperature",
|
|
79316
79711
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
79317
79712
|
label: t("Temperature", "Temperatura"),
|
|
79318
|
-
|
|
79713
|
+
unit: "°C",
|
|
79319
79714
|
icon: "thermometer"
|
|
79320
79715
|
},
|
|
79321
79716
|
{
|
|
@@ -79331,7 +79726,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79331
79726
|
field: "windSpeed",
|
|
79332
79727
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
79333
79728
|
label: t("Wind", "Vento"),
|
|
79334
|
-
|
|
79729
|
+
unit: "m/s",
|
|
79335
79730
|
icon: "wind"
|
|
79336
79731
|
},
|
|
79337
79732
|
{
|
|
@@ -79339,7 +79734,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
79339
79734
|
field: "pressure",
|
|
79340
79735
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
79341
79736
|
label: t("Pressure", "Pressione"),
|
|
79342
|
-
|
|
79737
|
+
unit: "hPa",
|
|
79343
79738
|
icon: "gauge"
|
|
79344
79739
|
}
|
|
79345
79740
|
]
|
|
@@ -80678,6 +81073,16 @@ Object.freeze({
|
|
|
80678
81073
|
form: "single",
|
|
80679
81074
|
optional: false
|
|
80680
81075
|
}],
|
|
81076
|
+
"groupCommands.getStatus": [{
|
|
81077
|
+
name: "deviceId",
|
|
81078
|
+
form: "single",
|
|
81079
|
+
optional: false
|
|
81080
|
+
}],
|
|
81081
|
+
"groupStatus.getStatus": [{
|
|
81082
|
+
name: "deviceId",
|
|
81083
|
+
form: "single",
|
|
81084
|
+
optional: false
|
|
81085
|
+
}],
|
|
80681
81086
|
"heatingValve.getStatus": [{
|
|
80682
81087
|
name: "deviceId",
|
|
80683
81088
|
form: "single",
|
|
@@ -82662,6 +83067,8 @@ new Map(Object.entries({
|
|
|
82662
83067
|
"detection-blind": "device-events",
|
|
82663
83068
|
"motion-noisy": "device-events",
|
|
82664
83069
|
"motion-calm": "device-events",
|
|
83070
|
+
"package-llm-silent": "device-events",
|
|
83071
|
+
"package-llm-answered": "device-events",
|
|
82665
83072
|
"recording-stalled": "device-events",
|
|
82666
83073
|
"recording-healthy": "device-events",
|
|
82667
83074
|
"recording-degraded": "device-events",
|
|
@@ -82745,6 +83152,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
82745
83152
|
label: "Motion without a subject",
|
|
82746
83153
|
kinds: ["motion-noisy", "motion-calm"]
|
|
82747
83154
|
},
|
|
83155
|
+
{
|
|
83156
|
+
id: "package-llm",
|
|
83157
|
+
family: "device-events",
|
|
83158
|
+
label: "Package confirm",
|
|
83159
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
83160
|
+
},
|
|
82748
83161
|
{
|
|
82749
83162
|
id: "recording",
|
|
82750
83163
|
family: "device-events",
|
|
@@ -82926,6 +83339,8 @@ var DEVICE_EVENTS = [
|
|
|
82926
83339
|
"detection-blind",
|
|
82927
83340
|
"motion-noisy",
|
|
82928
83341
|
"motion-calm",
|
|
83342
|
+
"package-llm-silent",
|
|
83343
|
+
"package-llm-answered",
|
|
82929
83344
|
"recording-stalled",
|
|
82930
83345
|
"recording-healthy",
|
|
82931
83346
|
"recording-degraded",
|
|
@@ -83194,6 +83609,15 @@ new Map([
|
|
|
83194
83609
|
snapshotLabel: "Cameras with constant motion now",
|
|
83195
83610
|
snapshotSection: null
|
|
83196
83611
|
},
|
|
83612
|
+
{
|
|
83613
|
+
id: "package-llm-confirm",
|
|
83614
|
+
family: "device-events",
|
|
83615
|
+
label: "Package confirm (not answering / answering again)",
|
|
83616
|
+
bad: ["package-llm-silent"],
|
|
83617
|
+
recovery: ["package-llm-answered"],
|
|
83618
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
83619
|
+
snapshotSection: null
|
|
83620
|
+
},
|
|
83197
83621
|
{
|
|
83198
83622
|
id: "recording-health",
|
|
83199
83623
|
family: "device-events",
|