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