@camstack/addon-smtp-nodemailer 1.2.141 → 1.2.142
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +19 -0
- package/dist/smtp.addon.js +856 -432
- package/dist/smtp.addon.mjs +856 -432
- package/package.json +4 -2
package/dist/smtp.addon.js
CHANGED
|
@@ -36,7 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
}) : target, mod));
|
|
37
37
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
38
|
//#endregion
|
|
39
|
-
//#region ../types/dist/event-category-
|
|
39
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
40
40
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
41
41
|
EventCategory["SystemBoot"] = "system.boot";
|
|
42
42
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -362,6 +362,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
362
362
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
363
363
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
364
364
|
/**
|
|
365
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
366
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
367
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
368
|
+
*/
|
|
369
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
370
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
371
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
372
|
+
/**
|
|
365
373
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
366
374
|
* (a settings change via `setAgentInferenceDevices` /
|
|
367
375
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5471,7 +5479,7 @@ var ZodIssueCode = {
|
|
|
5471
5479
|
var ZodFirstPartyTypeKind;
|
|
5472
5480
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5473
5481
|
//#endregion
|
|
5474
|
-
//#region ../types/dist/sleep-
|
|
5482
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5475
5483
|
/**
|
|
5476
5484
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5477
5485
|
* window to float samples (D455).
|
|
@@ -7958,6 +7966,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
7958
7966
|
}).strict();
|
|
7959
7967
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
7960
7968
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
7969
|
+
var READING_QUANTITIES = [
|
|
7970
|
+
"temperature",
|
|
7971
|
+
"pressure",
|
|
7972
|
+
"speed",
|
|
7973
|
+
"precipitation",
|
|
7974
|
+
"precipitation-rate",
|
|
7975
|
+
"length",
|
|
7976
|
+
"area",
|
|
7977
|
+
"illuminance",
|
|
7978
|
+
"irradiance",
|
|
7979
|
+
"power",
|
|
7980
|
+
"energy",
|
|
7981
|
+
"voltage",
|
|
7982
|
+
"current",
|
|
7983
|
+
"apparent-power",
|
|
7984
|
+
"humidity",
|
|
7985
|
+
"percentage",
|
|
7986
|
+
"concentration-volume",
|
|
7987
|
+
"concentration-mass",
|
|
7988
|
+
"concentration-ppb",
|
|
7989
|
+
"volume",
|
|
7990
|
+
"duration",
|
|
7991
|
+
"duration-ms",
|
|
7992
|
+
"information",
|
|
7993
|
+
"sound-level",
|
|
7994
|
+
"signal-level",
|
|
7995
|
+
"colour-temperature",
|
|
7996
|
+
"angle",
|
|
7997
|
+
"bitrate",
|
|
7998
|
+
"rate",
|
|
7999
|
+
"mass",
|
|
8000
|
+
"index",
|
|
8001
|
+
"ratio",
|
|
8002
|
+
"count",
|
|
8003
|
+
"none",
|
|
8004
|
+
"device"
|
|
8005
|
+
];
|
|
8006
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8007
|
+
new Set(READING_QUANTITIES);
|
|
8008
|
+
/**
|
|
8009
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8010
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8011
|
+
*/
|
|
8012
|
+
var QUANTITY_BASE = {
|
|
8013
|
+
temperature: "°C",
|
|
8014
|
+
pressure: "hPa",
|
|
8015
|
+
speed: "m/s",
|
|
8016
|
+
precipitation: "mm",
|
|
8017
|
+
"precipitation-rate": "mm/h",
|
|
8018
|
+
length: "m",
|
|
8019
|
+
area: "m²",
|
|
8020
|
+
illuminance: "lx",
|
|
8021
|
+
irradiance: "W/m²",
|
|
8022
|
+
power: "W",
|
|
8023
|
+
energy: "kWh",
|
|
8024
|
+
voltage: "V",
|
|
8025
|
+
current: "A",
|
|
8026
|
+
"apparent-power": "VA",
|
|
8027
|
+
humidity: "%",
|
|
8028
|
+
percentage: "%",
|
|
8029
|
+
"concentration-volume": "ppm",
|
|
8030
|
+
"concentration-mass": "µg/m³",
|
|
8031
|
+
"concentration-ppb": "ppb",
|
|
8032
|
+
volume: "L",
|
|
8033
|
+
duration: "s",
|
|
8034
|
+
"duration-ms": "ms",
|
|
8035
|
+
information: "B",
|
|
8036
|
+
"sound-level": "dBFS",
|
|
8037
|
+
"signal-level": "dBm",
|
|
8038
|
+
"colour-temperature": "mired",
|
|
8039
|
+
angle: "°",
|
|
8040
|
+
bitrate: "kbps",
|
|
8041
|
+
rate: "fps",
|
|
8042
|
+
mass: "kg",
|
|
8043
|
+
index: "none",
|
|
8044
|
+
ratio: "none",
|
|
8045
|
+
count: "none",
|
|
8046
|
+
none: "none",
|
|
8047
|
+
device: "device"
|
|
8048
|
+
};
|
|
8049
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8050
|
+
function baseUnitOf(quantity) {
|
|
8051
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8052
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8053
|
+
return symbol;
|
|
8054
|
+
}
|
|
8055
|
+
function readingMeta(quantity, extras) {
|
|
8056
|
+
return {
|
|
8057
|
+
quantity,
|
|
8058
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8059
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8060
|
+
};
|
|
8061
|
+
}
|
|
7961
8062
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
7962
8063
|
var CamProfileSchema = _enum([
|
|
7963
8064
|
"high",
|
|
@@ -7985,8 +8086,8 @@ var CamStreamKindSchema = _enum([
|
|
|
7985
8086
|
"derived"
|
|
7986
8087
|
]);
|
|
7987
8088
|
var CamStreamResolutionSchema = object({
|
|
7988
|
-
width: number().int().positive(),
|
|
7989
|
-
height: number().int().positive()
|
|
8089
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8090
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
7990
8091
|
});
|
|
7991
8092
|
var CameraStreamSchema = object({
|
|
7992
8093
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8500,6 +8601,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8500
8601
|
"filesystem-browse",
|
|
8501
8602
|
"flood",
|
|
8502
8603
|
"gas",
|
|
8604
|
+
"group-commands",
|
|
8605
|
+
"group-status",
|
|
8503
8606
|
"heating-valve",
|
|
8504
8607
|
"humidifier",
|
|
8505
8608
|
"humidity-sensor",
|
|
@@ -8629,14 +8732,6 @@ Object.freeze({
|
|
|
8629
8732
|
{
|
|
8630
8733
|
"path": "aqi",
|
|
8631
8734
|
"valueType": "number"
|
|
8632
|
-
},
|
|
8633
|
-
{
|
|
8634
|
-
"path": "unit",
|
|
8635
|
-
"valueType": "string"
|
|
8636
|
-
},
|
|
8637
|
-
{
|
|
8638
|
-
"path": "precision",
|
|
8639
|
-
"valueType": "number"
|
|
8640
8735
|
}
|
|
8641
8736
|
],
|
|
8642
8737
|
"alarm-panel": [
|
|
@@ -8672,20 +8767,10 @@ Object.freeze({
|
|
|
8672
8767
|
"valueType": "boolean"
|
|
8673
8768
|
}
|
|
8674
8769
|
],
|
|
8675
|
-
"ambient-light-sensor": [
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
},
|
|
8680
|
-
{
|
|
8681
|
-
"path": "unit",
|
|
8682
|
-
"valueType": "string"
|
|
8683
|
-
},
|
|
8684
|
-
{
|
|
8685
|
-
"path": "precision",
|
|
8686
|
-
"valueType": "number"
|
|
8687
|
-
}
|
|
8688
|
-
],
|
|
8770
|
+
"ambient-light-sensor": [{
|
|
8771
|
+
"path": "lux",
|
|
8772
|
+
"valueType": "number"
|
|
8773
|
+
}],
|
|
8689
8774
|
"audio-metrics": [
|
|
8690
8775
|
{
|
|
8691
8776
|
"path": "ts",
|
|
@@ -8765,6 +8850,10 @@ Object.freeze({
|
|
|
8765
8850
|
"path": "lastUpdated",
|
|
8766
8851
|
"valueType": "number"
|
|
8767
8852
|
},
|
|
8853
|
+
{
|
|
8854
|
+
"path": "volts",
|
|
8855
|
+
"valueType": "number"
|
|
8856
|
+
},
|
|
8768
8857
|
{
|
|
8769
8858
|
"path": "lastContactAt",
|
|
8770
8859
|
"valueType": "number"
|
|
@@ -9007,10 +9096,6 @@ Object.freeze({
|
|
|
9007
9096
|
"datetime"
|
|
9008
9097
|
]
|
|
9009
9098
|
},
|
|
9010
|
-
{
|
|
9011
|
-
"path": "unit",
|
|
9012
|
-
"valueType": "string"
|
|
9013
|
-
},
|
|
9014
9099
|
{
|
|
9015
9100
|
"path": "min",
|
|
9016
9101
|
"valueType": "number"
|
|
@@ -9022,19 +9107,6 @@ Object.freeze({
|
|
|
9022
9107
|
{
|
|
9023
9108
|
"path": "step",
|
|
9024
9109
|
"valueType": "number"
|
|
9025
|
-
},
|
|
9026
|
-
{
|
|
9027
|
-
"path": "precision",
|
|
9028
|
-
"valueType": "number"
|
|
9029
|
-
},
|
|
9030
|
-
{
|
|
9031
|
-
"path": "format",
|
|
9032
|
-
"valueType": "enum",
|
|
9033
|
-
"enumValues": [
|
|
9034
|
-
"date",
|
|
9035
|
-
"time",
|
|
9036
|
-
"datetime"
|
|
9037
|
-
]
|
|
9038
9110
|
}
|
|
9039
9111
|
],
|
|
9040
9112
|
"cover": [
|
|
@@ -9275,13 +9347,8 @@ Object.freeze({
|
|
|
9275
9347
|
"path": "value",
|
|
9276
9348
|
"valueType": "string"
|
|
9277
9349
|
}, {
|
|
9278
|
-
"path": "
|
|
9279
|
-
"valueType": "
|
|
9280
|
-
"enumValues": [
|
|
9281
|
-
"date",
|
|
9282
|
-
"time",
|
|
9283
|
-
"datetime"
|
|
9284
|
-
]
|
|
9350
|
+
"path": "timestamp",
|
|
9351
|
+
"valueType": "boolean"
|
|
9285
9352
|
}],
|
|
9286
9353
|
"event-emitter": [
|
|
9287
9354
|
{
|
|
@@ -9354,6 +9421,20 @@ Object.freeze({
|
|
|
9354
9421
|
"path": "detected",
|
|
9355
9422
|
"valueType": "boolean"
|
|
9356
9423
|
}],
|
|
9424
|
+
"group-status": [
|
|
9425
|
+
{
|
|
9426
|
+
"path": "included",
|
|
9427
|
+
"valueType": "number"
|
|
9428
|
+
},
|
|
9429
|
+
{
|
|
9430
|
+
"path": "excluded",
|
|
9431
|
+
"valueType": "number"
|
|
9432
|
+
},
|
|
9433
|
+
{
|
|
9434
|
+
"path": "total",
|
|
9435
|
+
"valueType": "number"
|
|
9436
|
+
}
|
|
9437
|
+
],
|
|
9357
9438
|
"heating-valve": [{
|
|
9358
9439
|
"path": "position",
|
|
9359
9440
|
"valueType": "number"
|
|
@@ -9388,20 +9469,10 @@ Object.freeze({
|
|
|
9388
9469
|
"valueType": "number"
|
|
9389
9470
|
}
|
|
9390
9471
|
],
|
|
9391
|
-
"humidity-sensor": [
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
},
|
|
9396
|
-
{
|
|
9397
|
-
"path": "unit",
|
|
9398
|
-
"valueType": "string"
|
|
9399
|
-
},
|
|
9400
|
-
{
|
|
9401
|
-
"path": "precision",
|
|
9402
|
-
"valueType": "number"
|
|
9403
|
-
}
|
|
9404
|
-
],
|
|
9472
|
+
"humidity-sensor": [{
|
|
9473
|
+
"path": "percent",
|
|
9474
|
+
"valueType": "number"
|
|
9475
|
+
}],
|
|
9405
9476
|
"image": [{
|
|
9406
9477
|
"path": "url",
|
|
9407
9478
|
"valueType": "string"
|
|
@@ -9740,20 +9811,10 @@ Object.freeze({
|
|
|
9740
9811
|
"valueType": "boolean"
|
|
9741
9812
|
}
|
|
9742
9813
|
],
|
|
9743
|
-
"numeric-sensor": [
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
},
|
|
9748
|
-
{
|
|
9749
|
-
"path": "unit",
|
|
9750
|
-
"valueType": "string"
|
|
9751
|
-
},
|
|
9752
|
-
{
|
|
9753
|
-
"path": "precision",
|
|
9754
|
-
"valueType": "number"
|
|
9755
|
-
}
|
|
9756
|
-
],
|
|
9814
|
+
"numeric-sensor": [{
|
|
9815
|
+
"path": "value",
|
|
9816
|
+
"valueType": "number"
|
|
9817
|
+
}],
|
|
9757
9818
|
"pet-feeder": [
|
|
9758
9819
|
{
|
|
9759
9820
|
"path": "foodLevel",
|
|
@@ -9845,14 +9906,6 @@ Object.freeze({
|
|
|
9845
9906
|
{
|
|
9846
9907
|
"path": "powerFactor",
|
|
9847
9908
|
"valueType": "number"
|
|
9848
|
-
},
|
|
9849
|
-
{
|
|
9850
|
-
"path": "unit",
|
|
9851
|
-
"valueType": "string"
|
|
9852
|
-
},
|
|
9853
|
-
{
|
|
9854
|
-
"path": "precision",
|
|
9855
|
-
"valueType": "number"
|
|
9856
9909
|
}
|
|
9857
9910
|
],
|
|
9858
9911
|
"presence": [
|
|
@@ -9881,20 +9934,10 @@ Object.freeze({
|
|
|
9881
9934
|
"valueType": "number"
|
|
9882
9935
|
}
|
|
9883
9936
|
],
|
|
9884
|
-
"pressure-sensor": [
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
},
|
|
9889
|
-
{
|
|
9890
|
-
"path": "unit",
|
|
9891
|
-
"valueType": "string"
|
|
9892
|
-
},
|
|
9893
|
-
{
|
|
9894
|
-
"path": "precision",
|
|
9895
|
-
"valueType": "number"
|
|
9896
|
-
}
|
|
9897
|
-
],
|
|
9937
|
+
"pressure-sensor": [{
|
|
9938
|
+
"path": "hpa",
|
|
9939
|
+
"valueType": "number"
|
|
9940
|
+
}],
|
|
9898
9941
|
"privacy-mask": [{
|
|
9899
9942
|
"path": "enabled",
|
|
9900
9943
|
"valueType": "boolean"
|
|
@@ -10205,20 +10248,10 @@ Object.freeze({
|
|
|
10205
10248
|
"path": "tampered",
|
|
10206
10249
|
"valueType": "boolean"
|
|
10207
10250
|
}],
|
|
10208
|
-
"temperature-sensor": [
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
},
|
|
10213
|
-
{
|
|
10214
|
-
"path": "unit",
|
|
10215
|
-
"valueType": "string"
|
|
10216
|
-
},
|
|
10217
|
-
{
|
|
10218
|
-
"path": "precision",
|
|
10219
|
-
"valueType": "number"
|
|
10220
|
-
}
|
|
10221
|
-
],
|
|
10251
|
+
"temperature-sensor": [{
|
|
10252
|
+
"path": "celsius",
|
|
10253
|
+
"valueType": "number"
|
|
10254
|
+
}],
|
|
10222
10255
|
"update": [
|
|
10223
10256
|
{
|
|
10224
10257
|
"path": "currentVersion",
|
|
@@ -10329,10 +10362,6 @@ Object.freeze({
|
|
|
10329
10362
|
"path": "temperature",
|
|
10330
10363
|
"valueType": "number"
|
|
10331
10364
|
},
|
|
10332
|
-
{
|
|
10333
|
-
"path": "temperatureUnit",
|
|
10334
|
-
"valueType": "string"
|
|
10335
|
-
},
|
|
10336
10365
|
{
|
|
10337
10366
|
"path": "humidity",
|
|
10338
10367
|
"valueType": "number"
|
|
@@ -10341,18 +10370,10 @@ Object.freeze({
|
|
|
10341
10370
|
"path": "pressure",
|
|
10342
10371
|
"valueType": "number"
|
|
10343
10372
|
},
|
|
10344
|
-
{
|
|
10345
|
-
"path": "pressureUnit",
|
|
10346
|
-
"valueType": "string"
|
|
10347
|
-
},
|
|
10348
10373
|
{
|
|
10349
10374
|
"path": "windSpeed",
|
|
10350
10375
|
"valueType": "number"
|
|
10351
10376
|
},
|
|
10352
|
-
{
|
|
10353
|
-
"path": "windSpeedUnit",
|
|
10354
|
-
"valueType": "string"
|
|
10355
|
-
},
|
|
10356
10377
|
{
|
|
10357
10378
|
"path": "windBearing",
|
|
10358
10379
|
"valueType": "number"
|
|
@@ -10745,7 +10766,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10745
10766
|
return DeviceRole;
|
|
10746
10767
|
}({});
|
|
10747
10768
|
//#endregion
|
|
10748
|
-
//#region ../types/dist/composition-
|
|
10769
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10749
10770
|
/**
|
|
10750
10771
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10751
10772
|
*
|
|
@@ -11500,15 +11521,74 @@ function validateExpressionSource(src) {
|
|
|
11500
11521
|
}
|
|
11501
11522
|
return null;
|
|
11502
11523
|
}
|
|
11503
|
-
/**
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
|
|
11524
|
+
/**
|
|
11525
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11526
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11527
|
+
* `composition.ts` (D659).
|
|
11528
|
+
*/
|
|
11507
11529
|
var CompositionSourceRefSchema = object({
|
|
11508
11530
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11509
11531
|
addonId: string().min(1),
|
|
11510
11532
|
stableId: string().min(1)
|
|
11511
11533
|
});
|
|
11534
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11535
|
+
"temperature",
|
|
11536
|
+
"humidity",
|
|
11537
|
+
"pressure",
|
|
11538
|
+
"illuminance",
|
|
11539
|
+
"power",
|
|
11540
|
+
"energy",
|
|
11541
|
+
"battery",
|
|
11542
|
+
"numeric",
|
|
11543
|
+
"motion",
|
|
11544
|
+
"contact",
|
|
11545
|
+
"leak",
|
|
11546
|
+
"smoke",
|
|
11547
|
+
"occupancy",
|
|
11548
|
+
"binary",
|
|
11549
|
+
"switch",
|
|
11550
|
+
"light"
|
|
11551
|
+
];
|
|
11552
|
+
var NUMERIC_AGGREGATES = [
|
|
11553
|
+
"mean",
|
|
11554
|
+
"median",
|
|
11555
|
+
"min",
|
|
11556
|
+
"max",
|
|
11557
|
+
"sum"
|
|
11558
|
+
];
|
|
11559
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11560
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11561
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11562
|
+
var AGGREGATE_REDUCERS = [
|
|
11563
|
+
"mean",
|
|
11564
|
+
"median",
|
|
11565
|
+
"min",
|
|
11566
|
+
"max",
|
|
11567
|
+
"sum",
|
|
11568
|
+
"any",
|
|
11569
|
+
"all"
|
|
11570
|
+
];
|
|
11571
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11572
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11573
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11574
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11575
|
+
var HelperMemberSchema = object({
|
|
11576
|
+
source: CompositionSourceRefSchema,
|
|
11577
|
+
cap: string().min(1),
|
|
11578
|
+
fieldPath: string().min(1)
|
|
11579
|
+
});
|
|
11580
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11581
|
+
kind: literal("group"),
|
|
11582
|
+
templateId: GroupTemplateIdSchema,
|
|
11583
|
+
aggregate: AggregateReducerSchema,
|
|
11584
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11585
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11586
|
+
active: ActiveCriterionSchema.optional()
|
|
11587
|
+
})]);
|
|
11588
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11589
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11590
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11591
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11512
11592
|
/** One field of one capability of one source device. */
|
|
11513
11593
|
var CompositionFieldReadSchema = object({
|
|
11514
11594
|
source: CompositionSourceRefSchema,
|
|
@@ -11552,7 +11632,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11552
11632
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11553
11633
|
CompositionFromSourceSchema,
|
|
11554
11634
|
CompositionExpressionSourceSchema,
|
|
11555
|
-
CompositionCodeSourceSchema
|
|
11635
|
+
CompositionCodeSourceSchema,
|
|
11636
|
+
object({
|
|
11637
|
+
kind: literal("aggregate"),
|
|
11638
|
+
reducer: _enum([
|
|
11639
|
+
"mean",
|
|
11640
|
+
"median",
|
|
11641
|
+
"min",
|
|
11642
|
+
"max",
|
|
11643
|
+
"sum",
|
|
11644
|
+
"any",
|
|
11645
|
+
"all"
|
|
11646
|
+
]),
|
|
11647
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11648
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11649
|
+
publish: _enum([
|
|
11650
|
+
"value",
|
|
11651
|
+
"included",
|
|
11652
|
+
"excluded",
|
|
11653
|
+
"total"
|
|
11654
|
+
]),
|
|
11655
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11656
|
+
empty: _enum([
|
|
11657
|
+
"null",
|
|
11658
|
+
"omit",
|
|
11659
|
+
"offline"
|
|
11660
|
+
])
|
|
11661
|
+
})
|
|
11556
11662
|
]);
|
|
11557
11663
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11558
11664
|
kind: literal("forward"),
|
|
@@ -11598,7 +11704,13 @@ var CompositionSchema = object({
|
|
|
11598
11704
|
kind: literal("existing"),
|
|
11599
11705
|
device: CompositionSourceRefSchema
|
|
11600
11706
|
})]),
|
|
11601
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11707
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11708
|
+
/**
|
|
11709
|
+
* Present when the block is a helper template. Absent on a free
|
|
11710
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11711
|
+
* never the compiled features.
|
|
11712
|
+
*/
|
|
11713
|
+
helper: HelperSpecSchema.optional()
|
|
11602
11714
|
}).superRefine((composition, ctx) => {
|
|
11603
11715
|
const seen = /* @__PURE__ */ new Set();
|
|
11604
11716
|
composition.features.forEach((feature, index) => {
|
|
@@ -17700,7 +17812,11 @@ var CompositionProblemSchema = object({
|
|
|
17700
17812
|
"item-field-reserved",
|
|
17701
17813
|
"target-missing",
|
|
17702
17814
|
"target-unreadable",
|
|
17703
|
-
"not-replaceable"
|
|
17815
|
+
"not-replaceable",
|
|
17816
|
+
"native-capability-replace",
|
|
17817
|
+
"mixed-quantity",
|
|
17818
|
+
"helper-mismatch",
|
|
17819
|
+
"member-constraint"
|
|
17704
17820
|
]),
|
|
17705
17821
|
path: string(),
|
|
17706
17822
|
message: string()
|
|
@@ -17721,7 +17837,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17721
17837
|
"null",
|
|
17722
17838
|
"offline",
|
|
17723
17839
|
"unknown",
|
|
17724
|
-
"release"
|
|
17840
|
+
"release",
|
|
17841
|
+
"omit"
|
|
17725
17842
|
]);
|
|
17726
17843
|
/**
|
|
17727
17844
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -17758,9 +17875,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17758
17875
|
reads: array(CompositionFieldReadSchema)
|
|
17759
17876
|
});
|
|
17760
17877
|
/**
|
|
17761
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17762
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17763
|
-
*
|
|
17878
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
17879
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
17880
|
+
* Replacing a capability the device already serves is refused
|
|
17881
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
17882
|
+
* wire for a claim the hub already holds.
|
|
17764
17883
|
*/
|
|
17765
17884
|
var CompositionFeatureModeSchema = _enum([
|
|
17766
17885
|
"new",
|
|
@@ -17933,6 +18052,275 @@ Object.freeze({
|
|
|
17933
18052
|
result: ["number", "null"]
|
|
17934
18053
|
}
|
|
17935
18054
|
});
|
|
18055
|
+
/**
|
|
18056
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18057
|
+
* Data, not a form default written into the block.
|
|
18058
|
+
*/
|
|
18059
|
+
var NOW = {
|
|
18060
|
+
fieldPath: "lastFetchedAt",
|
|
18061
|
+
expr: "now"
|
|
18062
|
+
};
|
|
18063
|
+
var CHANGED = {
|
|
18064
|
+
fieldPath: "lastChangedAt",
|
|
18065
|
+
expr: "now"
|
|
18066
|
+
};
|
|
18067
|
+
function numeric(input) {
|
|
18068
|
+
return {
|
|
18069
|
+
...input,
|
|
18070
|
+
family: "numeric",
|
|
18071
|
+
deviceType: DeviceType.Sensor,
|
|
18072
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18073
|
+
commandCaps: [],
|
|
18074
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18075
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18076
|
+
accept: [{
|
|
18077
|
+
cap: input.outputCap,
|
|
18078
|
+
fieldPath: input.outputField
|
|
18079
|
+
}]
|
|
18080
|
+
};
|
|
18081
|
+
}
|
|
18082
|
+
function binary(input) {
|
|
18083
|
+
return {
|
|
18084
|
+
...input,
|
|
18085
|
+
family: "binary",
|
|
18086
|
+
deviceType: DeviceType.Sensor,
|
|
18087
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18088
|
+
commandCaps: [],
|
|
18089
|
+
quantity: "none",
|
|
18090
|
+
baseUnit: void 0,
|
|
18091
|
+
aggregates: BINARY_AGGREGATES,
|
|
18092
|
+
empty: "offline"
|
|
18093
|
+
};
|
|
18094
|
+
}
|
|
18095
|
+
var GROUP_TEMPLATES = [
|
|
18096
|
+
numeric({
|
|
18097
|
+
id: "temperature",
|
|
18098
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18099
|
+
role: DeviceRole.TemperatureSensor,
|
|
18100
|
+
outputCap: "temperature-sensor",
|
|
18101
|
+
outputField: "celsius",
|
|
18102
|
+
quantity: "temperature",
|
|
18103
|
+
defaultAggregate: "mean",
|
|
18104
|
+
empty: "null",
|
|
18105
|
+
companions: [NOW]
|
|
18106
|
+
}),
|
|
18107
|
+
numeric({
|
|
18108
|
+
id: "humidity",
|
|
18109
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18110
|
+
role: DeviceRole.HumiditySensor,
|
|
18111
|
+
outputCap: "humidity-sensor",
|
|
18112
|
+
outputField: "percent",
|
|
18113
|
+
quantity: "humidity",
|
|
18114
|
+
defaultAggregate: "mean",
|
|
18115
|
+
empty: "null",
|
|
18116
|
+
companions: [NOW]
|
|
18117
|
+
}),
|
|
18118
|
+
numeric({
|
|
18119
|
+
id: "pressure",
|
|
18120
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18121
|
+
role: DeviceRole.PressureSensor,
|
|
18122
|
+
outputCap: "pressure-sensor",
|
|
18123
|
+
outputField: "hpa",
|
|
18124
|
+
quantity: "pressure",
|
|
18125
|
+
defaultAggregate: "mean",
|
|
18126
|
+
empty: "null",
|
|
18127
|
+
companions: [NOW]
|
|
18128
|
+
}),
|
|
18129
|
+
numeric({
|
|
18130
|
+
id: "illuminance",
|
|
18131
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18132
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18133
|
+
outputCap: "ambient-light-sensor",
|
|
18134
|
+
outputField: "lux",
|
|
18135
|
+
quantity: "illuminance",
|
|
18136
|
+
defaultAggregate: "mean",
|
|
18137
|
+
empty: "null",
|
|
18138
|
+
companions: [NOW]
|
|
18139
|
+
}),
|
|
18140
|
+
numeric({
|
|
18141
|
+
id: "power",
|
|
18142
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18143
|
+
role: DeviceRole.PowerSensor,
|
|
18144
|
+
outputCap: "power-meter",
|
|
18145
|
+
outputField: "watts",
|
|
18146
|
+
quantity: "power",
|
|
18147
|
+
defaultAggregate: "sum",
|
|
18148
|
+
empty: "omit",
|
|
18149
|
+
companions: [NOW]
|
|
18150
|
+
}),
|
|
18151
|
+
numeric({
|
|
18152
|
+
id: "energy",
|
|
18153
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18154
|
+
role: DeviceRole.EnergySensor,
|
|
18155
|
+
outputCap: "power-meter",
|
|
18156
|
+
outputField: "kwhTotal",
|
|
18157
|
+
quantity: "energy",
|
|
18158
|
+
defaultAggregate: "sum",
|
|
18159
|
+
empty: "omit",
|
|
18160
|
+
companions: [NOW]
|
|
18161
|
+
}),
|
|
18162
|
+
numeric({
|
|
18163
|
+
id: "battery",
|
|
18164
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18165
|
+
role: DeviceRole.BatterySensor,
|
|
18166
|
+
outputCap: "battery",
|
|
18167
|
+
outputField: "percentage",
|
|
18168
|
+
quantity: "percentage",
|
|
18169
|
+
defaultAggregate: "mean",
|
|
18170
|
+
empty: "null",
|
|
18171
|
+
companions: [
|
|
18172
|
+
{
|
|
18173
|
+
fieldPath: "charging",
|
|
18174
|
+
expr: "\"unknown\""
|
|
18175
|
+
},
|
|
18176
|
+
{
|
|
18177
|
+
fieldPath: "sleeping",
|
|
18178
|
+
expr: "false"
|
|
18179
|
+
},
|
|
18180
|
+
{
|
|
18181
|
+
fieldPath: "lastUpdated",
|
|
18182
|
+
expr: "now"
|
|
18183
|
+
}
|
|
18184
|
+
]
|
|
18185
|
+
}),
|
|
18186
|
+
numeric({
|
|
18187
|
+
id: "numeric",
|
|
18188
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18189
|
+
role: DeviceRole.NumericSensor,
|
|
18190
|
+
outputCap: "numeric-sensor",
|
|
18191
|
+
outputField: "value",
|
|
18192
|
+
quantity: "device",
|
|
18193
|
+
defaultAggregate: "mean",
|
|
18194
|
+
empty: "null",
|
|
18195
|
+
companions: [NOW]
|
|
18196
|
+
}),
|
|
18197
|
+
binary({
|
|
18198
|
+
id: "motion",
|
|
18199
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18200
|
+
role: DeviceRole.MotionSensor,
|
|
18201
|
+
outputCap: "motion",
|
|
18202
|
+
outputField: "detected",
|
|
18203
|
+
defaultAggregate: "any",
|
|
18204
|
+
accept: [{
|
|
18205
|
+
cap: "motion",
|
|
18206
|
+
fieldPath: "detected"
|
|
18207
|
+
}],
|
|
18208
|
+
companions: [{
|
|
18209
|
+
fieldPath: "lastDetectedAt",
|
|
18210
|
+
expr: "null"
|
|
18211
|
+
}, {
|
|
18212
|
+
fieldPath: "autoClearAfterMs",
|
|
18213
|
+
expr: "null"
|
|
18214
|
+
}]
|
|
18215
|
+
}),
|
|
18216
|
+
binary({
|
|
18217
|
+
id: "contact",
|
|
18218
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18219
|
+
role: DeviceRole.ContactSensor,
|
|
18220
|
+
outputCap: "contact",
|
|
18221
|
+
outputField: "entryOpen",
|
|
18222
|
+
defaultAggregate: "any",
|
|
18223
|
+
accept: [{
|
|
18224
|
+
cap: "contact",
|
|
18225
|
+
fieldPath: "entryOpen"
|
|
18226
|
+
}],
|
|
18227
|
+
companions: [CHANGED]
|
|
18228
|
+
}),
|
|
18229
|
+
binary({
|
|
18230
|
+
id: "leak",
|
|
18231
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18232
|
+
role: DeviceRole.LeakSensor,
|
|
18233
|
+
outputCap: "flood",
|
|
18234
|
+
outputField: "flooded",
|
|
18235
|
+
defaultAggregate: "any",
|
|
18236
|
+
accept: [{
|
|
18237
|
+
cap: "flood",
|
|
18238
|
+
fieldPath: "flooded"
|
|
18239
|
+
}],
|
|
18240
|
+
companions: [CHANGED]
|
|
18241
|
+
}),
|
|
18242
|
+
binary({
|
|
18243
|
+
id: "smoke",
|
|
18244
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18245
|
+
role: DeviceRole.SmokeSensor,
|
|
18246
|
+
outputCap: "smoke",
|
|
18247
|
+
outputField: "detected",
|
|
18248
|
+
defaultAggregate: "any",
|
|
18249
|
+
accept: [{
|
|
18250
|
+
cap: "smoke",
|
|
18251
|
+
fieldPath: "detected"
|
|
18252
|
+
}],
|
|
18253
|
+
companions: [CHANGED]
|
|
18254
|
+
}),
|
|
18255
|
+
binary({
|
|
18256
|
+
id: "occupancy",
|
|
18257
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18258
|
+
role: DeviceRole.BinarySensor,
|
|
18259
|
+
outputCap: "binary",
|
|
18260
|
+
outputField: "on",
|
|
18261
|
+
defaultAggregate: "any",
|
|
18262
|
+
accept: [{
|
|
18263
|
+
cap: "motion",
|
|
18264
|
+
fieldPath: "detected"
|
|
18265
|
+
}, {
|
|
18266
|
+
cap: "binary",
|
|
18267
|
+
fieldPath: "on"
|
|
18268
|
+
}],
|
|
18269
|
+
companions: [CHANGED]
|
|
18270
|
+
}),
|
|
18271
|
+
binary({
|
|
18272
|
+
id: "binary",
|
|
18273
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18274
|
+
role: DeviceRole.BinarySensor,
|
|
18275
|
+
outputCap: "binary",
|
|
18276
|
+
outputField: "on",
|
|
18277
|
+
defaultAggregate: "any",
|
|
18278
|
+
accept: [{
|
|
18279
|
+
cap: "binary",
|
|
18280
|
+
fieldPath: "on"
|
|
18281
|
+
}],
|
|
18282
|
+
companions: [CHANGED]
|
|
18283
|
+
}),
|
|
18284
|
+
actuator({
|
|
18285
|
+
id: "switch",
|
|
18286
|
+
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.",
|
|
18287
|
+
deviceType: DeviceType.Switch,
|
|
18288
|
+
outputCap: "switch",
|
|
18289
|
+
commandCaps: ["switch"]
|
|
18290
|
+
}),
|
|
18291
|
+
actuator({
|
|
18292
|
+
id: "light",
|
|
18293
|
+
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.",
|
|
18294
|
+
deviceType: DeviceType.Light,
|
|
18295
|
+
outputCap: "switch",
|
|
18296
|
+
commandCaps: [
|
|
18297
|
+
"switch",
|
|
18298
|
+
"brightness",
|
|
18299
|
+
"color"
|
|
18300
|
+
]
|
|
18301
|
+
})
|
|
18302
|
+
];
|
|
18303
|
+
function actuator(input) {
|
|
18304
|
+
return {
|
|
18305
|
+
...input,
|
|
18306
|
+
family: "actuator",
|
|
18307
|
+
role: void 0,
|
|
18308
|
+
memberDeviceType: input.deviceType,
|
|
18309
|
+
outputField: "on",
|
|
18310
|
+
quantity: "none",
|
|
18311
|
+
baseUnit: void 0,
|
|
18312
|
+
aggregates: BINARY_AGGREGATES,
|
|
18313
|
+
defaultAggregate: "any",
|
|
18314
|
+
empty: "offline",
|
|
18315
|
+
accept: [{
|
|
18316
|
+
cap: "switch",
|
|
18317
|
+
fieldPath: "on"
|
|
18318
|
+
}],
|
|
18319
|
+
companions: [CHANGED]
|
|
18320
|
+
};
|
|
18321
|
+
}
|
|
18322
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18323
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
17936
18324
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
17937
18325
|
/**
|
|
17938
18326
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19646,12 +20034,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
19646
20034
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19647
20035
|
* in-place so dispatch keeps working.
|
|
19648
20036
|
*
|
|
19649
|
-
* **
|
|
19650
|
-
*
|
|
19651
|
-
*
|
|
19652
|
-
*
|
|
19653
|
-
* (`ha-domain-mapping`)
|
|
19654
|
-
* stored after that point.
|
|
20037
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20038
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20039
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20040
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20041
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20042
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19655
20043
|
*
|
|
19656
20044
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19657
20045
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19665,6 +20053,14 @@ var SourceInfoSchema = object({
|
|
|
19665
20053
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19666
20054
|
* Used to detect rename when `id` changes. */
|
|
19667
20055
|
uniqueId: string().optional(),
|
|
20056
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20057
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20058
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20059
|
+
dateTimeShape: _enum([
|
|
20060
|
+
"date",
|
|
20061
|
+
"time",
|
|
20062
|
+
"datetime"
|
|
20063
|
+
]).optional(),
|
|
19668
20064
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19669
20065
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19670
20066
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40577,7 +40973,8 @@ method(object({
|
|
|
40577
40973
|
"enum"
|
|
40578
40974
|
]),
|
|
40579
40975
|
enumValues: array(string()).optional(),
|
|
40580
|
-
item: boolean().optional()
|
|
40976
|
+
item: boolean().optional(),
|
|
40977
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40581
40978
|
})).readonly(),
|
|
40582
40979
|
itemArray: object({
|
|
40583
40980
|
path: string(),
|
|
@@ -44377,8 +44774,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44377
44774
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44378
44775
|
var MaskGridShapeSchema = object({
|
|
44379
44776
|
kind: literal("grid"),
|
|
44380
|
-
gridWidth: number(),
|
|
44381
|
-
gridHeight: number(),
|
|
44777
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
44778
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44382
44779
|
cells: array(boolean())
|
|
44383
44780
|
});
|
|
44384
44781
|
discriminatedUnion("kind", [
|
|
@@ -44490,6 +44887,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44490
44887
|
"detection-blind",
|
|
44491
44888
|
"motion-noisy",
|
|
44492
44889
|
"motion-calm",
|
|
44890
|
+
"package-llm-silent",
|
|
44891
|
+
"package-llm-answered",
|
|
44493
44892
|
"recording-stalled",
|
|
44494
44893
|
"recording-healthy",
|
|
44495
44894
|
"recording-degraded",
|
|
@@ -55517,6 +55916,28 @@ var PackageVersionInfoSchema = object({
|
|
|
55517
55916
|
deprecated: string().optional(),
|
|
55518
55917
|
distTags: array(string()).readonly()
|
|
55519
55918
|
});
|
|
55919
|
+
/**
|
|
55920
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
55921
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
55922
|
+
* tarball failure — never an empty string standing in for either.
|
|
55923
|
+
*/
|
|
55924
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
55925
|
+
object({
|
|
55926
|
+
status: literal("ok"),
|
|
55927
|
+
markdown: string()
|
|
55928
|
+
}),
|
|
55929
|
+
object({ status: literal("missing") }),
|
|
55930
|
+
object({
|
|
55931
|
+
status: literal("error"),
|
|
55932
|
+
message: string()
|
|
55933
|
+
})
|
|
55934
|
+
]);
|
|
55935
|
+
var PackageDocsSchema = object({
|
|
55936
|
+
name: string(),
|
|
55937
|
+
version: string(),
|
|
55938
|
+
readme: PackageDocBodySchema,
|
|
55939
|
+
changelog: PackageDocBodySchema
|
|
55940
|
+
});
|
|
55520
55941
|
var SearchResultSchema = object({
|
|
55521
55942
|
name: string(),
|
|
55522
55943
|
version: string(),
|
|
@@ -55735,7 +56156,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
55735
56156
|
}), object({ success: literal(true) }), {
|
|
55736
56157
|
kind: "mutation",
|
|
55737
56158
|
auth: "admin"
|
|
55738
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56159
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56160
|
+
name: string().min(1),
|
|
56161
|
+
version: string().min(1).optional()
|
|
56162
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
55739
56163
|
kind: "mutation",
|
|
55740
56164
|
auth: "admin"
|
|
55741
56165
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -55785,46 +56209,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
55785
56209
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
55786
56210
|
object({
|
|
55787
56211
|
/** Carbon dioxide concentration in ppm. */
|
|
55788
|
-
co2Ppm: number().min(0).optional(),
|
|
56212
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
55789
56213
|
/** Total volatile organic compounds in ppb. */
|
|
55790
|
-
vocPpb: number().min(0).optional(),
|
|
56214
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
55791
56215
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
55792
|
-
pm25: number().min(0).optional(),
|
|
56216
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
55793
56217
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
55794
|
-
pm10: number().min(0).optional(),
|
|
56218
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
55795
56219
|
/** Composite AQI value (typically 0..500). */
|
|
55796
|
-
aqi: number().optional(),
|
|
56220
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
55797
56221
|
/** Ms epoch when the slice was last updated. */
|
|
55798
|
-
lastFetchedAt: number()
|
|
55799
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
55800
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
55801
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
55802
|
-
* per slice is unambiguous. */
|
|
55803
|
-
unit: string().optional(),
|
|
55804
|
-
/** Suggested decimal places for numeric display.
|
|
55805
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
55806
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
55807
|
-
* auto-formatting when absent. */
|
|
55808
|
-
precision: number().int().min(0).max(10).optional()
|
|
56222
|
+
lastFetchedAt: number()
|
|
55809
56223
|
});
|
|
55810
56224
|
DeviceType.Sensor;
|
|
55811
56225
|
object({
|
|
55812
|
-
/** Current illuminance in lux (lx). */
|
|
55813
|
-
lux: number().min(0).meta({
|
|
55814
|
-
|
|
56226
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56227
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56228
|
+
precision: 0,
|
|
55815
56229
|
label: "Illuminance"
|
|
55816
|
-
}),
|
|
56230
|
+
})),
|
|
55817
56231
|
/** Ms epoch when the slice was last updated. */
|
|
55818
|
-
lastFetchedAt: number()
|
|
55819
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
55820
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
55821
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
55822
|
-
unit: string().optional(),
|
|
55823
|
-
/** Suggested decimal places for numeric display.
|
|
55824
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
55825
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
55826
|
-
* auto-formatting when absent. */
|
|
55827
|
-
precision: number().int().min(0).max(10).optional()
|
|
56232
|
+
lastFetchedAt: number()
|
|
55828
56233
|
});
|
|
55829
56234
|
DeviceType.Sensor;
|
|
55830
56235
|
/**
|
|
@@ -55969,10 +56374,7 @@ var BatteryStatusSchema = object({
|
|
|
55969
56374
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
55970
56375
|
* declines to band a non-finite reading, which is the correct shape.
|
|
55971
56376
|
*/
|
|
55972
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
55973
|
-
unit: "%",
|
|
55974
|
-
label: "Charge"
|
|
55975
|
-
}),
|
|
56377
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
55976
56378
|
/**
|
|
55977
56379
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
55978
56380
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -55999,7 +56401,14 @@ var BatteryStatusSchema = object({
|
|
|
55999
56401
|
*/
|
|
56000
56402
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56001
56403
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56002
|
-
lastUpdated: number(),
|
|
56404
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56405
|
+
/**
|
|
56406
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56407
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56408
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56409
|
+
* `numeric-sensor` on the same device.
|
|
56410
|
+
*/
|
|
56411
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56003
56412
|
/**
|
|
56004
56413
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56005
56414
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56059,7 +56468,7 @@ object({
|
|
|
56059
56468
|
DeviceType.Sensor;
|
|
56060
56469
|
object({
|
|
56061
56470
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56062
|
-
percentage: number().min(0).max(100),
|
|
56471
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56063
56472
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56064
56473
|
lastChangedAt: number()
|
|
56065
56474
|
});
|
|
@@ -56444,21 +56853,21 @@ object({
|
|
|
56444
56853
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56445
56854
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56446
56855
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56447
|
-
target: number().nullable(),
|
|
56856
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56448
56857
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56449
56858
|
* in `heat_cool` mode. */
|
|
56450
|
-
targetHigh: number().nullable(),
|
|
56859
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56451
56860
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56452
56861
|
* in `heat_cool` mode. */
|
|
56453
|
-
targetLow: number().nullable(),
|
|
56862
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56454
56863
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56455
56864
|
* humidity control. */
|
|
56456
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
56865
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56457
56866
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56458
56867
|
* the device's internal sensor. */
|
|
56459
|
-
currentTemp: number().nullable(),
|
|
56868
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56460
56869
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56461
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
56870
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56462
56871
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56463
56872
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56464
56873
|
swingVertical: boolean().nullable(),
|
|
@@ -56466,11 +56875,11 @@ object({
|
|
|
56466
56875
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56467
56876
|
swingHorizontal: boolean().nullable(),
|
|
56468
56877
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56469
|
-
minTemp: number().nullable().optional(),
|
|
56878
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56470
56879
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56471
|
-
maxTemp: number().nullable().optional(),
|
|
56880
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56472
56881
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56473
|
-
tempStep: number().positive().nullable().optional(),
|
|
56882
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56474
56883
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56475
56884
|
lastFetchedAt: number()
|
|
56476
56885
|
});
|
|
@@ -56549,17 +56958,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
56549
56958
|
* modes to expose in the picker without a slice fetch.
|
|
56550
56959
|
*/
|
|
56551
56960
|
var RgbTripletSchema = object({
|
|
56552
|
-
r: number().int().min(0).max(255),
|
|
56553
|
-
g: number().int().min(0).max(255),
|
|
56554
|
-
b: number().int().min(0).max(255)
|
|
56961
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
56962
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
56963
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
56555
56964
|
});
|
|
56556
56965
|
var HsvTripletSchema = object({
|
|
56557
56966
|
/** Hue in degrees, 0..360. */
|
|
56558
|
-
h: number().min(0).max(360),
|
|
56967
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
56559
56968
|
/** Saturation as 0..100 inclusive. */
|
|
56560
|
-
s: number().min(0).max(100),
|
|
56969
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
56561
56970
|
/** Value/brightness as 0..100 inclusive. */
|
|
56562
|
-
v: number().min(0).max(100)
|
|
56971
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
56563
56972
|
});
|
|
56564
56973
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
56565
56974
|
object({
|
|
@@ -56588,7 +56997,7 @@ object({
|
|
|
56588
56997
|
/** Populated when `mode === 'hsv'`. */
|
|
56589
56998
|
hsv: HsvTripletSchema.optional(),
|
|
56590
56999
|
/** Populated when `mode === 'mired'`. */
|
|
56591
|
-
mireds: number().int().optional(),
|
|
57000
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
56592
57001
|
/** Ms epoch of the last operator-driven change. */
|
|
56593
57002
|
lastChangedAt: number()
|
|
56594
57003
|
});
|
|
@@ -56712,18 +57121,12 @@ _enum([
|
|
|
56712
57121
|
"empty",
|
|
56713
57122
|
"full"
|
|
56714
57123
|
]);
|
|
56715
|
-
/**
|
|
56716
|
-
|
|
56717
|
-
|
|
56718
|
-
"days",
|
|
56719
|
-
"hours",
|
|
56720
|
-
"cycles"
|
|
56721
|
-
]);
|
|
56722
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
56723
|
-
* days). `value` null = unknown (D393). */
|
|
57124
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57125
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57126
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
56724
57127
|
var ConsumableRemainingSchema = object({
|
|
56725
|
-
value: number().min(0).nullable(),
|
|
56726
|
-
|
|
57128
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57129
|
+
kind: ConsumableRemainingKindSchema
|
|
56727
57130
|
});
|
|
56728
57131
|
var ConsumablesStatusSchema = object({
|
|
56729
57132
|
items: array(object({
|
|
@@ -56732,7 +57135,7 @@ var ConsumablesStatusSchema = object({
|
|
|
56732
57135
|
/** Display name. */
|
|
56733
57136
|
label: string().min(1),
|
|
56734
57137
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
56735
|
-
level: number().min(0).max(100).nullable(),
|
|
57138
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
56736
57139
|
/** The provider's discrete verdict when known (binary mode). */
|
|
56737
57140
|
status: ConsumableStatusSchema.nullable(),
|
|
56738
57141
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -56749,7 +57152,7 @@ var ConsumablesStatusSchema = object({
|
|
|
56749
57152
|
})),
|
|
56750
57153
|
lastChangedAt: number()
|
|
56751
57154
|
});
|
|
56752
|
-
Object.values(DeviceType), [...
|
|
57155
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
56753
57156
|
Object.values(DeviceType), method(object({
|
|
56754
57157
|
deviceId: number().int().nonnegative(),
|
|
56755
57158
|
key: string().min(1)
|
|
@@ -56774,39 +57177,17 @@ object({
|
|
|
56774
57177
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
56775
57178
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
56776
57179
|
* or time-only — HA accepts all three forms). */
|
|
56777
|
-
value: union([number(), string()]),
|
|
57180
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
56778
57181
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
56779
57182
|
options: array(string()),
|
|
56780
57183
|
/** Ms epoch when the slice was last updated. */
|
|
56781
57184
|
lastChangedAt: number(),
|
|
56782
|
-
/**
|
|
56783
|
-
|
|
56784
|
-
|
|
56785
|
-
|
|
56786
|
-
/**
|
|
56787
|
-
|
|
56788
|
-
min: number().optional(),
|
|
56789
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
56790
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
56791
|
-
max: number().optional(),
|
|
56792
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
56793
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
56794
|
-
step: number().optional(),
|
|
56795
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
56796
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
56797
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
56798
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
56799
|
-
precision: number().int().min(0).max(10).optional(),
|
|
56800
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
56801
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
56802
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
56803
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
56804
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
56805
|
-
format: _enum([
|
|
56806
|
-
"date",
|
|
56807
|
-
"time",
|
|
56808
|
-
"datetime"
|
|
56809
|
-
]).optional()
|
|
57185
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57186
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57187
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57188
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57189
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57190
|
+
step: number().optional().meta(readingMeta("device"))
|
|
56810
57191
|
});
|
|
56811
57192
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
56812
57193
|
object({
|
|
@@ -56844,9 +57225,9 @@ object({
|
|
|
56844
57225
|
]),
|
|
56845
57226
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
56846
57227
|
* no intermediate position surface. */
|
|
56847
|
-
position: number().min(0).max(100).nullable(),
|
|
57228
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
56848
57229
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
56849
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57230
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
56850
57231
|
/** Ms epoch when the slice was last updated. */
|
|
56851
57232
|
lastChangedAt: number()
|
|
56852
57233
|
});
|
|
@@ -56904,9 +57285,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
56904
57285
|
object({
|
|
56905
57286
|
mode: DayNightModeSchema,
|
|
56906
57287
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
56907
|
-
sensitivity: number().optional(),
|
|
57288
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
56908
57289
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
56909
|
-
switchDelaySec: number().optional(),
|
|
57290
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
56910
57291
|
lastFetchedAt: number()
|
|
56911
57292
|
});
|
|
56912
57293
|
/**
|
|
@@ -57061,11 +57442,11 @@ object({
|
|
|
57061
57442
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57062
57443
|
availablePrograms: array(string()),
|
|
57063
57444
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57064
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57445
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57065
57446
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57066
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57447
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57067
57448
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57068
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57449
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57069
57450
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57070
57451
|
doorOpen: boolean().nullable(),
|
|
57071
57452
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57089,7 +57470,7 @@ object({
|
|
|
57089
57470
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57090
57471
|
machineCareDue: boolean().nullable(),
|
|
57091
57472
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57092
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57473
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57093
57474
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57094
57475
|
halfLoad: boolean().nullable(),
|
|
57095
57476
|
hygienePlus: boolean().nullable(),
|
|
@@ -57104,7 +57485,7 @@ object({
|
|
|
57104
57485
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57105
57486
|
activeEvents: array(string()),
|
|
57106
57487
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57107
|
-
errorCode: number().nullable(),
|
|
57488
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57108
57489
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57109
57490
|
errorLabel: string().nullable(),
|
|
57110
57491
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57250,24 +57631,14 @@ object({
|
|
|
57250
57631
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57251
57632
|
lastPressedAt: number().nullable(),
|
|
57252
57633
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57253
|
-
pressCountSinceStart: number()
|
|
57634
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57254
57635
|
});
|
|
57255
57636
|
object({
|
|
57256
57637
|
deviceId: number(),
|
|
57257
57638
|
timestamp: number()
|
|
57258
57639
|
});
|
|
57259
57640
|
DeviceType.Button, DeviceType.Camera;
|
|
57260
|
-
|
|
57261
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57262
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57263
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57264
|
-
* The option set is stable across observations; it is persisted in the
|
|
57265
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57266
|
-
* stored in `sourceInfo`.
|
|
57267
|
-
*/
|
|
57268
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57269
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57270
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
57641
|
+
_enum([
|
|
57271
57642
|
"date",
|
|
57272
57643
|
"time",
|
|
57273
57644
|
"datetime"
|
|
@@ -57275,12 +57646,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57275
57646
|
object({
|
|
57276
57647
|
value: string(),
|
|
57277
57648
|
/**
|
|
57278
|
-
* Set
|
|
57279
|
-
* as
|
|
57280
|
-
*
|
|
57281
|
-
* a time-only sensor → `'time'`.
|
|
57649
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
57650
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
57651
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57282
57652
|
*/
|
|
57283
|
-
|
|
57653
|
+
timestamp: boolean().optional(),
|
|
57284
57654
|
/** Ms epoch when the slice was last updated. */
|
|
57285
57655
|
lastFetchedAt: number()
|
|
57286
57656
|
});
|
|
@@ -57299,13 +57669,13 @@ var EventFireSchema = object({
|
|
|
57299
57669
|
deviceId: number(),
|
|
57300
57670
|
eventType: string(),
|
|
57301
57671
|
data: record(string(), unknown()).nullable(),
|
|
57302
|
-
timestamp: number(),
|
|
57303
|
-
seq: number()
|
|
57672
|
+
timestamp: number().meta(readingMeta("none")),
|
|
57673
|
+
seq: number().meta(readingMeta("count"))
|
|
57304
57674
|
});
|
|
57305
57675
|
object({
|
|
57306
57676
|
eventTypes: array(string()),
|
|
57307
57677
|
lastEvent: EventFireSchema.nullable(),
|
|
57308
|
-
eventCountSinceStart: number()
|
|
57678
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57309
57679
|
});
|
|
57310
57680
|
DeviceType.EventEmitter;
|
|
57311
57681
|
var IdentitySchema = object({
|
|
@@ -57694,10 +58064,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
57694
58064
|
object({
|
|
57695
58065
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
57696
58066
|
* speed surface (single-speed fan). */
|
|
57697
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58067
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57698
58068
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
57699
58069
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
57700
|
-
percentageStep: number().positive().optional(),
|
|
58070
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
57701
58071
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
57702
58072
|
* — empty string when no preset is active or supported. */
|
|
57703
58073
|
preset: string(),
|
|
@@ -57779,7 +58149,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
57779
58149
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
57780
58150
|
model: string().nullable(),
|
|
57781
58151
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
57782
|
-
channelCount: number().nullable(),
|
|
58152
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
57783
58153
|
/**
|
|
57784
58154
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
57785
58155
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -57811,9 +58181,39 @@ object({
|
|
|
57811
58181
|
lastChangedAt: number()
|
|
57812
58182
|
});
|
|
57813
58183
|
DeviceType.Sensor;
|
|
58184
|
+
object({
|
|
58185
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58186
|
+
results: array(object({
|
|
58187
|
+
deviceId: number().int().nonnegative(),
|
|
58188
|
+
cap: string().min(1),
|
|
58189
|
+
method: string().min(1),
|
|
58190
|
+
ok: boolean(),
|
|
58191
|
+
error: string().optional(),
|
|
58192
|
+
/** Ms epoch of the attempt. */
|
|
58193
|
+
at: number()
|
|
58194
|
+
})) });
|
|
58195
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58196
|
+
object({
|
|
58197
|
+
/** Members whose current value entered the aggregate. */
|
|
58198
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58199
|
+
precision: 0,
|
|
58200
|
+
label: "Reporting"
|
|
58201
|
+
})),
|
|
58202
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58203
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58204
|
+
precision: 0,
|
|
58205
|
+
label: "Excluded"
|
|
58206
|
+
})),
|
|
58207
|
+
/** `included` + `excluded`. */
|
|
58208
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58209
|
+
precision: 0,
|
|
58210
|
+
label: "Members"
|
|
58211
|
+
}))
|
|
58212
|
+
});
|
|
58213
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
57814
58214
|
object({
|
|
57815
58215
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
57816
|
-
position: number().min(0).max(100).nullable(),
|
|
58216
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57817
58217
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
57818
58218
|
lastFetchedAt: number()
|
|
57819
58219
|
});
|
|
@@ -57822,9 +58222,9 @@ object({
|
|
|
57822
58222
|
/** Whether the humidifier is currently on. */
|
|
57823
58223
|
on: boolean(),
|
|
57824
58224
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
57825
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58225
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57826
58226
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
57827
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58227
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57828
58228
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
57829
58229
|
* device has no mode surface. */
|
|
57830
58230
|
mode: string().nullable(),
|
|
@@ -57834,9 +58234,9 @@ object({
|
|
|
57834
58234
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
57835
58235
|
action: string().nullable(),
|
|
57836
58236
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
57837
|
-
minHumidity: number().nullable(),
|
|
58237
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
57838
58238
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
57839
|
-
maxHumidity: number().nullable(),
|
|
58239
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
57840
58240
|
/** Ms epoch when the slice was last updated. */
|
|
57841
58241
|
lastChangedAt: number()
|
|
57842
58242
|
});
|
|
@@ -57860,22 +58260,13 @@ DeviceType.Humidifier, method(object({
|
|
|
57860
58260
|
auth: "protected"
|
|
57861
58261
|
});
|
|
57862
58262
|
object({
|
|
57863
|
-
/** Current relative humidity, 0..100. */
|
|
57864
|
-
percent: number().min(0).max(100).meta({
|
|
57865
|
-
|
|
58263
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58264
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58265
|
+
precision: 0,
|
|
57866
58266
|
label: "Humidity"
|
|
57867
|
-
}),
|
|
58267
|
+
})),
|
|
57868
58268
|
/** Ms epoch when the slice was last updated. */
|
|
57869
|
-
lastFetchedAt: number()
|
|
57870
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
57871
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
57872
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
57873
|
-
unit: string().optional(),
|
|
57874
|
-
/** Suggested decimal places for numeric display.
|
|
57875
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57876
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57877
|
-
* auto-formatting when absent. */
|
|
57878
|
-
precision: number().int().min(0).max(10).optional()
|
|
58269
|
+
lastFetchedAt: number()
|
|
57879
58270
|
});
|
|
57880
58271
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
57881
58272
|
object({
|
|
@@ -57883,7 +58274,7 @@ object({
|
|
|
57883
58274
|
* entity exposes no `entity_picture` (yet). */
|
|
57884
58275
|
url: string().nullable(),
|
|
57885
58276
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
57886
|
-
lastUpdated: number().nullable()
|
|
58277
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
57887
58278
|
});
|
|
57888
58279
|
DeviceType.Image;
|
|
57889
58280
|
/**
|
|
@@ -57939,19 +58330,19 @@ var NormalizedRangeSchema = object({
|
|
|
57939
58330
|
});
|
|
57940
58331
|
object({
|
|
57941
58332
|
/** Normalized 0–100. */
|
|
57942
|
-
brightness: number().optional(),
|
|
58333
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
57943
58334
|
/** Normalized 0–100. */
|
|
57944
|
-
contrast: number().optional(),
|
|
58335
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
57945
58336
|
/** Normalized 0–100. */
|
|
57946
|
-
saturation: number().optional(),
|
|
58337
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
57947
58338
|
/** Normalized 0–100. */
|
|
57948
|
-
sharpness: number().optional(),
|
|
58339
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
57949
58340
|
mirror: boolean().optional(),
|
|
57950
58341
|
flip: boolean().optional(),
|
|
57951
58342
|
rotate: ImageRotateSchema.optional(),
|
|
57952
58343
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
57953
58344
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
57954
|
-
warmth: number().optional(),
|
|
58345
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
57955
58346
|
exposureMode: ExposureModeSchema.optional(),
|
|
57956
58347
|
backlightMode: BacklightModeSchema.optional(),
|
|
57957
58348
|
lastFetchedAt: number()
|
|
@@ -58196,10 +58587,10 @@ var IntercomAbilitySchema = object({
|
|
|
58196
58587
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58197
58588
|
codecs: array(string()),
|
|
58198
58589
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58199
|
-
sampleRate: number(),
|
|
58590
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58200
58591
|
duplex: _enum(["half", "full"]),
|
|
58201
58592
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58202
|
-
maxBacklogMs: number()
|
|
58593
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58203
58594
|
});
|
|
58204
58595
|
var IntercomStatusSchema = object({
|
|
58205
58596
|
/** True while a talk session is open. */
|
|
@@ -58310,13 +58701,13 @@ object({
|
|
|
58310
58701
|
activity: LawnMowerActivitySchema,
|
|
58311
58702
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58312
58703
|
* reading. */
|
|
58313
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
58704
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58314
58705
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58315
58706
|
* task is active / progress is unavailable. */
|
|
58316
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58707
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58317
58708
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58318
58709
|
* or null when unknown. */
|
|
58319
|
-
currentCode: number().nullable(),
|
|
58710
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58320
58711
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58321
58712
|
currentCodeLabel: string().nullable(),
|
|
58322
58713
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -58778,7 +59169,7 @@ object({
|
|
|
58778
59169
|
state: MediaPlayerStateSchema,
|
|
58779
59170
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
58780
59171
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
58781
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59172
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58782
59173
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
58783
59174
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
58784
59175
|
isMuted: boolean().nullable(),
|
|
@@ -58791,10 +59182,10 @@ object({
|
|
|
58791
59182
|
currentMedia: MediaInfoSchema.nullable(),
|
|
58792
59183
|
/** Current playback position in ms. Null when not seekable or
|
|
58793
59184
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
58794
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59185
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
58795
59186
|
/** Total duration of the current media in ms. Null when unknown
|
|
58796
59187
|
* (live stream) or nothing is playing. */
|
|
58797
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59188
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
58798
59189
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
58799
59190
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
58800
59191
|
shuffle: boolean().nullable(),
|
|
@@ -59094,7 +59485,7 @@ object({
|
|
|
59094
59485
|
* it, every provider seeded it at boot, and every session left it
|
|
59095
59486
|
* `detected: true` after its detach.
|
|
59096
59487
|
*/
|
|
59097
|
-
autoClearAfterMs: number().nullable()
|
|
59488
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59098
59489
|
});
|
|
59099
59490
|
/**
|
|
59100
59491
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59144,7 +59535,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59144
59535
|
});
|
|
59145
59536
|
object({
|
|
59146
59537
|
enabled: boolean(),
|
|
59147
|
-
sensitivity: number(),
|
|
59538
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59148
59539
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59149
59540
|
regions: array(MotionZoneRegionSchema),
|
|
59150
59541
|
lastFetchedAt: number()
|
|
@@ -59448,7 +59839,7 @@ var NavigationStatusSchema = object({
|
|
|
59448
59839
|
following: boolean(),
|
|
59449
59840
|
flash: boolean(),
|
|
59450
59841
|
lightMode: NavigationLightModeSchema,
|
|
59451
|
-
lightLevel: number().min(40).max(100),
|
|
59842
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59452
59843
|
/** Ms epoch when the slice was last updated. */
|
|
59453
59844
|
lastChangedAt: number()
|
|
59454
59845
|
});
|
|
@@ -59494,13 +59885,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59494
59885
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59495
59886
|
* SKIP a null rather than coerce it.
|
|
59496
59887
|
*/
|
|
59497
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
59888
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59498
59889
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59499
|
-
rssiDbm: number().optional(),
|
|
59890
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59500
59891
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59501
59892
|
ssid: string().optional(),
|
|
59502
59893
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59503
|
-
lastUpdated: number()
|
|
59894
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59504
59895
|
});
|
|
59505
59896
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59506
59897
|
deviceId: number(),
|
|
@@ -59819,7 +60210,7 @@ object({
|
|
|
59819
60210
|
lastError: string().nullable(),
|
|
59820
60211
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
59821
60212
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
59822
|
-
queueDepth: number().int().nonnegative(),
|
|
60213
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
59823
60214
|
/** Per-feature capability matrix — authoritative source for the
|
|
59824
60215
|
* compose-form field gating. */
|
|
59825
60216
|
supports: NotifierSupportsSchema
|
|
@@ -59869,15 +60260,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
59869
60260
|
acceptedAt: number()
|
|
59870
60261
|
});
|
|
59871
60262
|
object({
|
|
59872
|
-
|
|
59873
|
-
|
|
59874
|
-
* Populated live from the upstream source on each state push.
|
|
59875
|
-
* Absent for unitless sensors. */
|
|
59876
|
-
unit: string().optional(),
|
|
59877
|
-
/** Suggested decimal places for numeric display.
|
|
59878
|
-
* Populated live from the upstream source when provided.
|
|
59879
|
-
* Falls back to auto-formatting when absent. */
|
|
59880
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60263
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60264
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
59881
60265
|
/** Ms epoch when the slice was last updated. */
|
|
59882
60266
|
lastFetchedAt: number()
|
|
59883
60267
|
});
|
|
@@ -60167,23 +60551,26 @@ object({
|
|
|
60167
60551
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60168
60552
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60169
60553
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60170
|
-
foodLevel: number().nullable(),
|
|
60554
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60171
60555
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60172
60556
|
* single-hopper models. */
|
|
60173
|
-
food1: number().nullable(),
|
|
60557
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60174
60558
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60175
60559
|
* single-hopper models. */
|
|
60176
|
-
food2: number().nullable(),
|
|
60560
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60177
60561
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60178
60562
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60179
60563
|
* below the feeder's low threshold. */
|
|
60180
60564
|
lowFood: boolean(),
|
|
60181
60565
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60182
60566
|
* device has no battery reading. */
|
|
60183
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60184
|
-
/**
|
|
60185
|
-
*
|
|
60186
|
-
|
|
60567
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60568
|
+
/**
|
|
60569
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
60570
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
60571
|
+
* model has no desiccant sensor.
|
|
60572
|
+
*/
|
|
60573
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60187
60574
|
/** True while a feed is in progress. */
|
|
60188
60575
|
feeding: boolean(),
|
|
60189
60576
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60194,7 +60581,7 @@ object({
|
|
|
60194
60581
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60195
60582
|
error: string().nullable(),
|
|
60196
60583
|
/** Raw device error code (0 / null = no error). */
|
|
60197
|
-
errorCode: number().nullable(),
|
|
60584
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60198
60585
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60199
60586
|
isDualHopper: boolean(),
|
|
60200
60587
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60204,7 +60591,7 @@ object({
|
|
|
60204
60591
|
/** Play a chime when dispensing. */
|
|
60205
60592
|
feedSound: boolean(),
|
|
60206
60593
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60207
|
-
volume: number(),
|
|
60594
|
+
volume: number().meta(readingMeta("none")),
|
|
60208
60595
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60209
60596
|
lastFetchedAt: number()
|
|
60210
60597
|
});
|
|
@@ -60641,36 +61028,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
60641
61028
|
});
|
|
60642
61029
|
object({
|
|
60643
61030
|
/** Instantaneous power draw in watts. */
|
|
60644
|
-
watts: number().optional().meta({
|
|
60645
|
-
unit: "W",
|
|
60646
|
-
label: "Power"
|
|
60647
|
-
}),
|
|
61031
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
60648
61032
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
60649
|
-
kwhTotal: number().optional().meta({
|
|
60650
|
-
unit: "kWh",
|
|
60651
|
-
label: "Energy"
|
|
60652
|
-
}),
|
|
61033
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
60653
61034
|
/** Voltage in volts. */
|
|
60654
|
-
volts: number().optional(),
|
|
61035
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
60655
61036
|
/** Current in amperes. */
|
|
60656
|
-
amps: number().optional(),
|
|
60657
|
-
/** Apparent power in volt-amperes
|
|
60658
|
-
va: number().optional(),
|
|
61037
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61038
|
+
/** Apparent power in volt-amperes. */
|
|
61039
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
60659
61040
|
/** Power factor (0..1) if reported. */
|
|
60660
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61041
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
60661
61042
|
/** Ms epoch when the slice was last updated. */
|
|
60662
|
-
lastFetchedAt: number()
|
|
60663
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
60664
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
60665
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
60666
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
60667
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
60668
|
-
unit: string().optional(),
|
|
60669
|
-
/** Suggested decimal places for numeric display.
|
|
60670
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60671
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60672
|
-
* auto-formatting when absent. */
|
|
60673
|
-
precision: number().int().min(0).max(10).optional()
|
|
61043
|
+
lastFetchedAt: number()
|
|
60674
61044
|
});
|
|
60675
61045
|
DeviceType.Sensor;
|
|
60676
61046
|
/**
|
|
@@ -60691,11 +61061,11 @@ DeviceType.Sensor;
|
|
|
60691
61061
|
*/
|
|
60692
61062
|
var GpsLocationSchema = object({
|
|
60693
61063
|
/** Latitude in decimal degrees, -90..90. */
|
|
60694
|
-
latitude: number().min(-90).max(90),
|
|
61064
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
60695
61065
|
/** Longitude in decimal degrees, -180..180. */
|
|
60696
|
-
longitude: number().min(-180).max(180),
|
|
61066
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
60697
61067
|
/** Reported accuracy in meters (lower = better). */
|
|
60698
|
-
accuracyMeters: number().nonnegative()
|
|
61068
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
60699
61069
|
});
|
|
60700
61070
|
object({
|
|
60701
61071
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -60707,25 +61077,16 @@ object({
|
|
|
60707
61077
|
gps: GpsLocationSchema.nullable(),
|
|
60708
61078
|
/** Optional battery level of the tracking device (0..100). Null
|
|
60709
61079
|
* when not reported. */
|
|
60710
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61080
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60711
61081
|
/** Ms epoch when the slice was last updated. */
|
|
60712
61082
|
lastChangedAt: number()
|
|
60713
61083
|
});
|
|
60714
61084
|
DeviceType.Presence;
|
|
60715
61085
|
object({
|
|
60716
|
-
/** Current pressure in hPa. */
|
|
60717
|
-
hpa: number(),
|
|
61086
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61087
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
60718
61088
|
/** Ms epoch when the slice was last updated. */
|
|
60719
|
-
lastFetchedAt: number()
|
|
60720
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60721
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60722
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60723
|
-
unit: string().optional(),
|
|
60724
|
-
/** Suggested decimal places for numeric display.
|
|
60725
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60726
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60727
|
-
* auto-formatting when absent. */
|
|
60728
|
-
precision: number().int().min(0).max(10).optional()
|
|
61089
|
+
lastFetchedAt: number()
|
|
60729
61090
|
});
|
|
60730
61091
|
DeviceType.Sensor;
|
|
60731
61092
|
/**
|
|
@@ -61058,8 +61419,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61058
61419
|
}), _void(), { kind: "mutation" });
|
|
61059
61420
|
var PtzAutotrackSettingsSchema = object({
|
|
61060
61421
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61061
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61062
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61422
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61423
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61063
61424
|
});
|
|
61064
61425
|
/**
|
|
61065
61426
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61116,7 +61477,7 @@ object({
|
|
|
61116
61477
|
/** null = unknown — never coerced to false (D393). */
|
|
61117
61478
|
running: boolean().nullable(),
|
|
61118
61479
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61119
|
-
since: number().nullable(),
|
|
61480
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61120
61481
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61121
61482
|
phase: string().nullable(),
|
|
61122
61483
|
/** null until a reading has been published (D393). */
|
|
@@ -62314,9 +62675,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62314
62675
|
*/
|
|
62315
62676
|
var RecordWindowSchema = object({
|
|
62316
62677
|
trigger: RecordTriggerSchema,
|
|
62317
|
-
day: number().int().min(0).max(6),
|
|
62318
|
-
startMinute: number().int().min(0).max(1439),
|
|
62319
|
-
endMinute: number().int().min(1).max(1440)
|
|
62678
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
62679
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
62680
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62320
62681
|
});
|
|
62321
62682
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62322
62683
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62385,10 +62746,10 @@ object({
|
|
|
62385
62746
|
/** Master "record to the card at all" switch. */
|
|
62386
62747
|
enabled: boolean().nullable(),
|
|
62387
62748
|
overwriteWhenFull: boolean().nullable(),
|
|
62388
|
-
preRecordSec: number().nullable(),
|
|
62389
|
-
postRecordSec: number().nullable(),
|
|
62749
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62750
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62390
62751
|
/** Length of one recorded file, in minutes. */
|
|
62391
|
-
segmentMinutes: number().nullable(),
|
|
62752
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62392
62753
|
/** The primary track's weekly windows, flattened. */
|
|
62393
62754
|
windows: array(RecordWindowSchema),
|
|
62394
62755
|
/**
|
|
@@ -62404,7 +62765,7 @@ object({
|
|
|
62404
62765
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62405
62766
|
* writable.
|
|
62406
62767
|
*/
|
|
62407
|
-
unreadableWindows: number(),
|
|
62768
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62408
62769
|
/**
|
|
62409
62770
|
* The camera is scheduled to record and has NO usable storage.
|
|
62410
62771
|
*
|
|
@@ -63041,7 +63402,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63041
63402
|
url: string().optional(),
|
|
63042
63403
|
codec: string().optional(),
|
|
63043
63404
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63044
|
-
fps: number().positive().optional(),
|
|
63405
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63045
63406
|
label: string().optional(),
|
|
63046
63407
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63047
63408
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63071,18 +63432,18 @@ var StreamProfileSchema = _enum([
|
|
|
63071
63432
|
]);
|
|
63072
63433
|
/** The current encoding config of one stream profile. */
|
|
63073
63434
|
var StreamProfileConfigSchema = object({
|
|
63074
|
-
width: number(),
|
|
63075
|
-
height: number(),
|
|
63435
|
+
width: number().meta(readingMeta("none")),
|
|
63436
|
+
height: number().meta(readingMeta("none")),
|
|
63076
63437
|
codec: _enum(["h264", "h265"]),
|
|
63077
|
-
framerate: number(),
|
|
63078
|
-
bitrate: number(),
|
|
63438
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63439
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63079
63440
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63080
63441
|
encoderProfile: _enum([
|
|
63081
63442
|
"high",
|
|
63082
63443
|
"main",
|
|
63083
63444
|
"baseline"
|
|
63084
63445
|
]).optional(),
|
|
63085
|
-
gop: number().optional(),
|
|
63446
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63086
63447
|
/**
|
|
63087
63448
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63088
63449
|
*
|
|
@@ -63725,23 +64086,13 @@ object({
|
|
|
63725
64086
|
});
|
|
63726
64087
|
DeviceType.Sensor;
|
|
63727
64088
|
object({
|
|
63728
|
-
/** Current temperature in Celsius. */
|
|
63729
|
-
celsius: number().meta({
|
|
63730
|
-
|
|
64089
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64090
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64091
|
+
precision: 1,
|
|
63731
64092
|
label: "Temperature"
|
|
63732
|
-
}),
|
|
64093
|
+
})),
|
|
63733
64094
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
63734
|
-
lastFetchedAt: number()
|
|
63735
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63736
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63737
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
63738
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
63739
|
-
unit: string().optional(),
|
|
63740
|
-
/** Suggested decimal places for numeric display.
|
|
63741
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63742
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63743
|
-
* auto-formatting when absent. */
|
|
63744
|
-
precision: number().int().min(0).max(10).optional()
|
|
64095
|
+
lastFetchedAt: number()
|
|
63745
64096
|
});
|
|
63746
64097
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
63747
64098
|
/**
|
|
@@ -63993,16 +64344,16 @@ object({
|
|
|
63993
64344
|
]),
|
|
63994
64345
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
63995
64346
|
* reading. */
|
|
63996
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64347
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63997
64348
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
63998
64349
|
* the vacuum has no speed control. */
|
|
63999
64350
|
fanSpeed: string().nullable(),
|
|
64000
64351
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64001
64352
|
availableFanSpeeds: array(string()),
|
|
64002
64353
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64003
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64354
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64004
64355
|
/** Current error code (0 / null = no error). */
|
|
64005
|
-
errorCode: number().nullable(),
|
|
64356
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64006
64357
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64007
64358
|
errorLabel: string().nullable(),
|
|
64008
64359
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64041,7 +64392,7 @@ object({
|
|
|
64041
64392
|
]),
|
|
64042
64393
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64043
64394
|
* intermediate position surface. */
|
|
64044
|
-
position: number().min(0).max(100).nullable(),
|
|
64395
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64045
64396
|
/** Ms epoch when the slice was last updated. */
|
|
64046
64397
|
lastChangedAt: number()
|
|
64047
64398
|
});
|
|
@@ -64069,9 +64420,9 @@ object({
|
|
|
64069
64420
|
DeviceType.Sensor;
|
|
64070
64421
|
object({
|
|
64071
64422
|
/** Current measured temperature. Null when not reported. */
|
|
64072
|
-
currentTemp: number().nullable(),
|
|
64423
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64073
64424
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64074
|
-
targetTemp: number().nullable(),
|
|
64425
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64075
64426
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64076
64427
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64077
64428
|
* device reports an unknown state. */
|
|
@@ -64082,9 +64433,9 @@ object({
|
|
|
64082
64433
|
* has no away surface. */
|
|
64083
64434
|
away: boolean().nullable(),
|
|
64084
64435
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64085
|
-
minTemp: number().nullable(),
|
|
64436
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64086
64437
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64087
|
-
maxTemp: number().nullable(),
|
|
64438
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64088
64439
|
/** Ms epoch when the slice was last updated. */
|
|
64089
64440
|
lastChangedAt: number()
|
|
64090
64441
|
});
|
|
@@ -64108,25 +64459,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64108
64459
|
auth: "protected"
|
|
64109
64460
|
});
|
|
64110
64461
|
object({
|
|
64111
|
-
/** Verbatim
|
|
64112
|
-
* when no condition has been reported yet. */
|
|
64462
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64113
64463
|
condition: string().nullable(),
|
|
64114
|
-
/** Current temperature in
|
|
64115
|
-
temperature: number().nullable(),
|
|
64116
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64117
|
-
temperatureUnit: string().nullable(),
|
|
64464
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64465
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64118
64466
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64119
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64120
|
-
/** Barometric pressure in
|
|
64121
|
-
pressure: number().nullable(),
|
|
64122
|
-
/**
|
|
64123
|
-
|
|
64124
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64125
|
-
windSpeed: number().nullable(),
|
|
64126
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64127
|
-
windSpeedUnit: string().nullable(),
|
|
64467
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64468
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64469
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64470
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64471
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64128
64472
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64129
|
-
windBearing: number().nullable(),
|
|
64473
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64130
64474
|
/** Ms epoch when the slice was last updated. */
|
|
64131
64475
|
lastFetchedAt: number()
|
|
64132
64476
|
});
|
|
@@ -65038,6 +65382,13 @@ Object.freeze({
|
|
|
65038
65382
|
access: "view",
|
|
65039
65383
|
role: "admin"
|
|
65040
65384
|
},
|
|
65385
|
+
"addons.getPackageDocs": {
|
|
65386
|
+
capName: "addons",
|
|
65387
|
+
capScope: "system",
|
|
65388
|
+
addonId: null,
|
|
65389
|
+
access: "view",
|
|
65390
|
+
role: "admin"
|
|
65391
|
+
},
|
|
65041
65392
|
"addons.getVersions": {
|
|
65042
65393
|
capName: "addons",
|
|
65043
65394
|
capScope: "system",
|
|
@@ -68146,6 +68497,20 @@ Object.freeze({
|
|
|
68146
68497
|
access: "view",
|
|
68147
68498
|
role: "viewer"
|
|
68148
68499
|
},
|
|
68500
|
+
"groupCommands.getStatus": {
|
|
68501
|
+
capName: "group-commands",
|
|
68502
|
+
capScope: "device",
|
|
68503
|
+
addonId: null,
|
|
68504
|
+
access: "view",
|
|
68505
|
+
role: "viewer"
|
|
68506
|
+
},
|
|
68507
|
+
"groupStatus.getStatus": {
|
|
68508
|
+
capName: "group-status",
|
|
68509
|
+
capScope: "device",
|
|
68510
|
+
addonId: null,
|
|
68511
|
+
access: "view",
|
|
68512
|
+
role: "viewer"
|
|
68513
|
+
},
|
|
68149
68514
|
"heatingValve.getStatus": {
|
|
68150
68515
|
capName: "heating-valve",
|
|
68151
68516
|
capScope: "device",
|
|
@@ -77968,6 +78333,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
77968
78333
|
icon: "flame"
|
|
77969
78334
|
}]
|
|
77970
78335
|
},
|
|
78336
|
+
"group-commands": {
|
|
78337
|
+
scope: "device",
|
|
78338
|
+
noun: t("Group command", "Comando di gruppo")
|
|
78339
|
+
},
|
|
78340
|
+
"group-status": {
|
|
78341
|
+
scope: "device",
|
|
78342
|
+
noun: t("Group", "Gruppo"),
|
|
78343
|
+
state: [
|
|
78344
|
+
{
|
|
78345
|
+
kind: "numeric",
|
|
78346
|
+
field: "included",
|
|
78347
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
78348
|
+
label: t("Reporting", "Rispondono"),
|
|
78349
|
+
icon: "users"
|
|
78350
|
+
},
|
|
78351
|
+
{
|
|
78352
|
+
kind: "numeric",
|
|
78353
|
+
field: "excluded",
|
|
78354
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
78355
|
+
label: t("Excluded", "Esclusi"),
|
|
78356
|
+
icon: "users"
|
|
78357
|
+
},
|
|
78358
|
+
{
|
|
78359
|
+
kind: "numeric",
|
|
78360
|
+
field: "total",
|
|
78361
|
+
quantity: t("the member count", "il numero di membri"),
|
|
78362
|
+
label: t("Members", "Membri"),
|
|
78363
|
+
icon: "sigma"
|
|
78364
|
+
}
|
|
78365
|
+
]
|
|
78366
|
+
},
|
|
77971
78367
|
"humidity-sensor": {
|
|
77972
78368
|
scope: "device",
|
|
77973
78369
|
noun: t("Humidity", "Umidità"),
|
|
@@ -78001,7 +78397,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78001
78397
|
field: "value",
|
|
78002
78398
|
quantity: t("the reading", "il valore"),
|
|
78003
78399
|
label: t("Reading", "Valore"),
|
|
78004
|
-
unitField: "unit",
|
|
78005
78400
|
icon: "gauge"
|
|
78006
78401
|
}]
|
|
78007
78402
|
},
|
|
@@ -78137,7 +78532,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78137
78532
|
field: "temperature",
|
|
78138
78533
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78139
78534
|
label: t("Temperature", "Temperatura"),
|
|
78140
|
-
|
|
78535
|
+
unit: "°C",
|
|
78141
78536
|
icon: "thermometer"
|
|
78142
78537
|
},
|
|
78143
78538
|
{
|
|
@@ -78153,7 +78548,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78153
78548
|
field: "windSpeed",
|
|
78154
78549
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78155
78550
|
label: t("Wind", "Vento"),
|
|
78156
|
-
|
|
78551
|
+
unit: "m/s",
|
|
78157
78552
|
icon: "wind"
|
|
78158
78553
|
},
|
|
78159
78554
|
{
|
|
@@ -78161,7 +78556,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78161
78556
|
field: "pressure",
|
|
78162
78557
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78163
78558
|
label: t("Pressure", "Pressione"),
|
|
78164
|
-
|
|
78559
|
+
unit: "hPa",
|
|
78165
78560
|
icon: "gauge"
|
|
78166
78561
|
}
|
|
78167
78562
|
]
|
|
@@ -79434,6 +79829,16 @@ Object.freeze({
|
|
|
79434
79829
|
form: "single",
|
|
79435
79830
|
optional: false
|
|
79436
79831
|
}],
|
|
79832
|
+
"groupCommands.getStatus": [{
|
|
79833
|
+
name: "deviceId",
|
|
79834
|
+
form: "single",
|
|
79835
|
+
optional: false
|
|
79836
|
+
}],
|
|
79837
|
+
"groupStatus.getStatus": [{
|
|
79838
|
+
name: "deviceId",
|
|
79839
|
+
form: "single",
|
|
79840
|
+
optional: false
|
|
79841
|
+
}],
|
|
79437
79842
|
"heatingValve.getStatus": [{
|
|
79438
79843
|
name: "deviceId",
|
|
79439
79844
|
form: "single",
|
|
@@ -81418,6 +81823,8 @@ new Map(Object.entries({
|
|
|
81418
81823
|
"detection-blind": "device-events",
|
|
81419
81824
|
"motion-noisy": "device-events",
|
|
81420
81825
|
"motion-calm": "device-events",
|
|
81826
|
+
"package-llm-silent": "device-events",
|
|
81827
|
+
"package-llm-answered": "device-events",
|
|
81421
81828
|
"recording-stalled": "device-events",
|
|
81422
81829
|
"recording-healthy": "device-events",
|
|
81423
81830
|
"recording-degraded": "device-events",
|
|
@@ -81501,6 +81908,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
81501
81908
|
label: "Motion without a subject",
|
|
81502
81909
|
kinds: ["motion-noisy", "motion-calm"]
|
|
81503
81910
|
},
|
|
81911
|
+
{
|
|
81912
|
+
id: "package-llm",
|
|
81913
|
+
family: "device-events",
|
|
81914
|
+
label: "Package confirm",
|
|
81915
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
81916
|
+
},
|
|
81504
81917
|
{
|
|
81505
81918
|
id: "recording",
|
|
81506
81919
|
family: "device-events",
|
|
@@ -81682,6 +82095,8 @@ var DEVICE_EVENTS = [
|
|
|
81682
82095
|
"detection-blind",
|
|
81683
82096
|
"motion-noisy",
|
|
81684
82097
|
"motion-calm",
|
|
82098
|
+
"package-llm-silent",
|
|
82099
|
+
"package-llm-answered",
|
|
81685
82100
|
"recording-stalled",
|
|
81686
82101
|
"recording-healthy",
|
|
81687
82102
|
"recording-degraded",
|
|
@@ -81950,6 +82365,15 @@ new Map([
|
|
|
81950
82365
|
snapshotLabel: "Cameras with constant motion now",
|
|
81951
82366
|
snapshotSection: null
|
|
81952
82367
|
},
|
|
82368
|
+
{
|
|
82369
|
+
id: "package-llm-confirm",
|
|
82370
|
+
family: "device-events",
|
|
82371
|
+
label: "Package confirm (not answering / answering again)",
|
|
82372
|
+
bad: ["package-llm-silent"],
|
|
82373
|
+
recovery: ["package-llm-answered"],
|
|
82374
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
82375
|
+
snapshotSection: null
|
|
82376
|
+
},
|
|
81953
82377
|
{
|
|
81954
82378
|
id: "recording-health",
|
|
81955
82379
|
family: "device-events",
|