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