@camstack/addon-provider-amcrest 0.2.159 → 0.2.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +20 -0
- package/dist/addon.js +966 -509
- package/dist/addon.mjs +966 -509
- package/package.json +10 -3
package/dist/addon.js
CHANGED
|
@@ -35,7 +35,7 @@ let node_stream_promises = require("node:stream/promises");
|
|
|
35
35
|
let node_child_process = require("node:child_process");
|
|
36
36
|
require("node:zlib");
|
|
37
37
|
let node_os = require("node:os");
|
|
38
|
-
//#region ../types/dist/event-category-
|
|
38
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
39
39
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
40
40
|
EventCategory["SystemBoot"] = "system.boot";
|
|
41
41
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -361,6 +361,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
361
361
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
362
362
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
363
363
|
/**
|
|
364
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
365
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
366
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
367
|
+
*/
|
|
368
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
369
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
370
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
371
|
+
/**
|
|
364
372
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
365
373
|
* (a settings change via `setAgentInferenceDevices` /
|
|
366
374
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5470,7 +5478,7 @@ var ZodIssueCode = {
|
|
|
5470
5478
|
var ZodFirstPartyTypeKind;
|
|
5471
5479
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5472
5480
|
//#endregion
|
|
5473
|
-
//#region ../types/dist/sleep-
|
|
5481
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5474
5482
|
/**
|
|
5475
5483
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5476
5484
|
* window to float samples (D455).
|
|
@@ -8024,6 +8032,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
8024
8032
|
}).strict();
|
|
8025
8033
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8026
8034
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8035
|
+
var READING_QUANTITIES = [
|
|
8036
|
+
"temperature",
|
|
8037
|
+
"pressure",
|
|
8038
|
+
"speed",
|
|
8039
|
+
"precipitation",
|
|
8040
|
+
"precipitation-rate",
|
|
8041
|
+
"length",
|
|
8042
|
+
"area",
|
|
8043
|
+
"illuminance",
|
|
8044
|
+
"irradiance",
|
|
8045
|
+
"power",
|
|
8046
|
+
"energy",
|
|
8047
|
+
"voltage",
|
|
8048
|
+
"current",
|
|
8049
|
+
"apparent-power",
|
|
8050
|
+
"humidity",
|
|
8051
|
+
"percentage",
|
|
8052
|
+
"concentration-volume",
|
|
8053
|
+
"concentration-mass",
|
|
8054
|
+
"concentration-ppb",
|
|
8055
|
+
"volume",
|
|
8056
|
+
"duration",
|
|
8057
|
+
"duration-ms",
|
|
8058
|
+
"information",
|
|
8059
|
+
"sound-level",
|
|
8060
|
+
"signal-level",
|
|
8061
|
+
"colour-temperature",
|
|
8062
|
+
"angle",
|
|
8063
|
+
"bitrate",
|
|
8064
|
+
"rate",
|
|
8065
|
+
"mass",
|
|
8066
|
+
"index",
|
|
8067
|
+
"ratio",
|
|
8068
|
+
"count",
|
|
8069
|
+
"none",
|
|
8070
|
+
"device"
|
|
8071
|
+
];
|
|
8072
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8073
|
+
new Set(READING_QUANTITIES);
|
|
8074
|
+
/**
|
|
8075
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8076
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8077
|
+
*/
|
|
8078
|
+
var QUANTITY_BASE = {
|
|
8079
|
+
temperature: "°C",
|
|
8080
|
+
pressure: "hPa",
|
|
8081
|
+
speed: "m/s",
|
|
8082
|
+
precipitation: "mm",
|
|
8083
|
+
"precipitation-rate": "mm/h",
|
|
8084
|
+
length: "m",
|
|
8085
|
+
area: "m²",
|
|
8086
|
+
illuminance: "lx",
|
|
8087
|
+
irradiance: "W/m²",
|
|
8088
|
+
power: "W",
|
|
8089
|
+
energy: "kWh",
|
|
8090
|
+
voltage: "V",
|
|
8091
|
+
current: "A",
|
|
8092
|
+
"apparent-power": "VA",
|
|
8093
|
+
humidity: "%",
|
|
8094
|
+
percentage: "%",
|
|
8095
|
+
"concentration-volume": "ppm",
|
|
8096
|
+
"concentration-mass": "µg/m³",
|
|
8097
|
+
"concentration-ppb": "ppb",
|
|
8098
|
+
volume: "L",
|
|
8099
|
+
duration: "s",
|
|
8100
|
+
"duration-ms": "ms",
|
|
8101
|
+
information: "B",
|
|
8102
|
+
"sound-level": "dBFS",
|
|
8103
|
+
"signal-level": "dBm",
|
|
8104
|
+
"colour-temperature": "mired",
|
|
8105
|
+
angle: "°",
|
|
8106
|
+
bitrate: "kbps",
|
|
8107
|
+
rate: "fps",
|
|
8108
|
+
mass: "kg",
|
|
8109
|
+
index: "none",
|
|
8110
|
+
ratio: "none",
|
|
8111
|
+
count: "none",
|
|
8112
|
+
none: "none",
|
|
8113
|
+
device: "device"
|
|
8114
|
+
};
|
|
8115
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8116
|
+
function baseUnitOf(quantity) {
|
|
8117
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8118
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8119
|
+
return symbol;
|
|
8120
|
+
}
|
|
8121
|
+
function readingMeta(quantity, extras) {
|
|
8122
|
+
return {
|
|
8123
|
+
quantity,
|
|
8124
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8125
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8126
|
+
};
|
|
8127
|
+
}
|
|
8027
8128
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8028
8129
|
var CamProfileSchema = _enum([
|
|
8029
8130
|
"high",
|
|
@@ -8051,8 +8152,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8051
8152
|
"derived"
|
|
8052
8153
|
]);
|
|
8053
8154
|
var CamStreamResolutionSchema = object({
|
|
8054
|
-
width: number().int().positive(),
|
|
8055
|
-
height: number().int().positive()
|
|
8155
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8156
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8056
8157
|
});
|
|
8057
8158
|
var CameraStreamSchema = object({
|
|
8058
8159
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8570,6 +8671,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8570
8671
|
"filesystem-browse",
|
|
8571
8672
|
"flood",
|
|
8572
8673
|
"gas",
|
|
8674
|
+
"group-commands",
|
|
8675
|
+
"group-status",
|
|
8573
8676
|
"heating-valve",
|
|
8574
8677
|
"humidifier",
|
|
8575
8678
|
"humidity-sensor",
|
|
@@ -8699,14 +8802,6 @@ Object.freeze({
|
|
|
8699
8802
|
{
|
|
8700
8803
|
"path": "aqi",
|
|
8701
8804
|
"valueType": "number"
|
|
8702
|
-
},
|
|
8703
|
-
{
|
|
8704
|
-
"path": "unit",
|
|
8705
|
-
"valueType": "string"
|
|
8706
|
-
},
|
|
8707
|
-
{
|
|
8708
|
-
"path": "precision",
|
|
8709
|
-
"valueType": "number"
|
|
8710
8805
|
}
|
|
8711
8806
|
],
|
|
8712
8807
|
"alarm-panel": [
|
|
@@ -8742,20 +8837,10 @@ Object.freeze({
|
|
|
8742
8837
|
"valueType": "boolean"
|
|
8743
8838
|
}
|
|
8744
8839
|
],
|
|
8745
|
-
"ambient-light-sensor": [
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
},
|
|
8750
|
-
{
|
|
8751
|
-
"path": "unit",
|
|
8752
|
-
"valueType": "string"
|
|
8753
|
-
},
|
|
8754
|
-
{
|
|
8755
|
-
"path": "precision",
|
|
8756
|
-
"valueType": "number"
|
|
8757
|
-
}
|
|
8758
|
-
],
|
|
8840
|
+
"ambient-light-sensor": [{
|
|
8841
|
+
"path": "lux",
|
|
8842
|
+
"valueType": "number"
|
|
8843
|
+
}],
|
|
8759
8844
|
"audio-metrics": [
|
|
8760
8845
|
{
|
|
8761
8846
|
"path": "ts",
|
|
@@ -8835,6 +8920,10 @@ Object.freeze({
|
|
|
8835
8920
|
"path": "lastUpdated",
|
|
8836
8921
|
"valueType": "number"
|
|
8837
8922
|
},
|
|
8923
|
+
{
|
|
8924
|
+
"path": "volts",
|
|
8925
|
+
"valueType": "number"
|
|
8926
|
+
},
|
|
8838
8927
|
{
|
|
8839
8928
|
"path": "lastContactAt",
|
|
8840
8929
|
"valueType": "number"
|
|
@@ -9077,10 +9166,6 @@ Object.freeze({
|
|
|
9077
9166
|
"datetime"
|
|
9078
9167
|
]
|
|
9079
9168
|
},
|
|
9080
|
-
{
|
|
9081
|
-
"path": "unit",
|
|
9082
|
-
"valueType": "string"
|
|
9083
|
-
},
|
|
9084
9169
|
{
|
|
9085
9170
|
"path": "min",
|
|
9086
9171
|
"valueType": "number"
|
|
@@ -9092,19 +9177,6 @@ Object.freeze({
|
|
|
9092
9177
|
{
|
|
9093
9178
|
"path": "step",
|
|
9094
9179
|
"valueType": "number"
|
|
9095
|
-
},
|
|
9096
|
-
{
|
|
9097
|
-
"path": "precision",
|
|
9098
|
-
"valueType": "number"
|
|
9099
|
-
},
|
|
9100
|
-
{
|
|
9101
|
-
"path": "format",
|
|
9102
|
-
"valueType": "enum",
|
|
9103
|
-
"enumValues": [
|
|
9104
|
-
"date",
|
|
9105
|
-
"time",
|
|
9106
|
-
"datetime"
|
|
9107
|
-
]
|
|
9108
9180
|
}
|
|
9109
9181
|
],
|
|
9110
9182
|
"cover": [
|
|
@@ -9345,13 +9417,8 @@ Object.freeze({
|
|
|
9345
9417
|
"path": "value",
|
|
9346
9418
|
"valueType": "string"
|
|
9347
9419
|
}, {
|
|
9348
|
-
"path": "
|
|
9349
|
-
"valueType": "
|
|
9350
|
-
"enumValues": [
|
|
9351
|
-
"date",
|
|
9352
|
-
"time",
|
|
9353
|
-
"datetime"
|
|
9354
|
-
]
|
|
9420
|
+
"path": "timestamp",
|
|
9421
|
+
"valueType": "boolean"
|
|
9355
9422
|
}],
|
|
9356
9423
|
"event-emitter": [
|
|
9357
9424
|
{
|
|
@@ -9424,6 +9491,20 @@ Object.freeze({
|
|
|
9424
9491
|
"path": "detected",
|
|
9425
9492
|
"valueType": "boolean"
|
|
9426
9493
|
}],
|
|
9494
|
+
"group-status": [
|
|
9495
|
+
{
|
|
9496
|
+
"path": "included",
|
|
9497
|
+
"valueType": "number"
|
|
9498
|
+
},
|
|
9499
|
+
{
|
|
9500
|
+
"path": "excluded",
|
|
9501
|
+
"valueType": "number"
|
|
9502
|
+
},
|
|
9503
|
+
{
|
|
9504
|
+
"path": "total",
|
|
9505
|
+
"valueType": "number"
|
|
9506
|
+
}
|
|
9507
|
+
],
|
|
9427
9508
|
"heating-valve": [{
|
|
9428
9509
|
"path": "position",
|
|
9429
9510
|
"valueType": "number"
|
|
@@ -9458,20 +9539,10 @@ Object.freeze({
|
|
|
9458
9539
|
"valueType": "number"
|
|
9459
9540
|
}
|
|
9460
9541
|
],
|
|
9461
|
-
"humidity-sensor": [
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
},
|
|
9466
|
-
{
|
|
9467
|
-
"path": "unit",
|
|
9468
|
-
"valueType": "string"
|
|
9469
|
-
},
|
|
9470
|
-
{
|
|
9471
|
-
"path": "precision",
|
|
9472
|
-
"valueType": "number"
|
|
9473
|
-
}
|
|
9474
|
-
],
|
|
9542
|
+
"humidity-sensor": [{
|
|
9543
|
+
"path": "percent",
|
|
9544
|
+
"valueType": "number"
|
|
9545
|
+
}],
|
|
9475
9546
|
"image": [{
|
|
9476
9547
|
"path": "url",
|
|
9477
9548
|
"valueType": "string"
|
|
@@ -9810,20 +9881,10 @@ Object.freeze({
|
|
|
9810
9881
|
"valueType": "boolean"
|
|
9811
9882
|
}
|
|
9812
9883
|
],
|
|
9813
|
-
"numeric-sensor": [
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
},
|
|
9818
|
-
{
|
|
9819
|
-
"path": "unit",
|
|
9820
|
-
"valueType": "string"
|
|
9821
|
-
},
|
|
9822
|
-
{
|
|
9823
|
-
"path": "precision",
|
|
9824
|
-
"valueType": "number"
|
|
9825
|
-
}
|
|
9826
|
-
],
|
|
9884
|
+
"numeric-sensor": [{
|
|
9885
|
+
"path": "value",
|
|
9886
|
+
"valueType": "number"
|
|
9887
|
+
}],
|
|
9827
9888
|
"pet-feeder": [
|
|
9828
9889
|
{
|
|
9829
9890
|
"path": "foodLevel",
|
|
@@ -9915,14 +9976,6 @@ Object.freeze({
|
|
|
9915
9976
|
{
|
|
9916
9977
|
"path": "powerFactor",
|
|
9917
9978
|
"valueType": "number"
|
|
9918
|
-
},
|
|
9919
|
-
{
|
|
9920
|
-
"path": "unit",
|
|
9921
|
-
"valueType": "string"
|
|
9922
|
-
},
|
|
9923
|
-
{
|
|
9924
|
-
"path": "precision",
|
|
9925
|
-
"valueType": "number"
|
|
9926
9979
|
}
|
|
9927
9980
|
],
|
|
9928
9981
|
"presence": [
|
|
@@ -9951,20 +10004,10 @@ Object.freeze({
|
|
|
9951
10004
|
"valueType": "number"
|
|
9952
10005
|
}
|
|
9953
10006
|
],
|
|
9954
|
-
"pressure-sensor": [
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
},
|
|
9959
|
-
{
|
|
9960
|
-
"path": "unit",
|
|
9961
|
-
"valueType": "string"
|
|
9962
|
-
},
|
|
9963
|
-
{
|
|
9964
|
-
"path": "precision",
|
|
9965
|
-
"valueType": "number"
|
|
9966
|
-
}
|
|
9967
|
-
],
|
|
10007
|
+
"pressure-sensor": [{
|
|
10008
|
+
"path": "hpa",
|
|
10009
|
+
"valueType": "number"
|
|
10010
|
+
}],
|
|
9968
10011
|
"privacy-mask": [{
|
|
9969
10012
|
"path": "enabled",
|
|
9970
10013
|
"valueType": "boolean"
|
|
@@ -10275,20 +10318,10 @@ Object.freeze({
|
|
|
10275
10318
|
"path": "tampered",
|
|
10276
10319
|
"valueType": "boolean"
|
|
10277
10320
|
}],
|
|
10278
|
-
"temperature-sensor": [
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
},
|
|
10283
|
-
{
|
|
10284
|
-
"path": "unit",
|
|
10285
|
-
"valueType": "string"
|
|
10286
|
-
},
|
|
10287
|
-
{
|
|
10288
|
-
"path": "precision",
|
|
10289
|
-
"valueType": "number"
|
|
10290
|
-
}
|
|
10291
|
-
],
|
|
10321
|
+
"temperature-sensor": [{
|
|
10322
|
+
"path": "celsius",
|
|
10323
|
+
"valueType": "number"
|
|
10324
|
+
}],
|
|
10292
10325
|
"update": [
|
|
10293
10326
|
{
|
|
10294
10327
|
"path": "currentVersion",
|
|
@@ -10399,10 +10432,6 @@ Object.freeze({
|
|
|
10399
10432
|
"path": "temperature",
|
|
10400
10433
|
"valueType": "number"
|
|
10401
10434
|
},
|
|
10402
|
-
{
|
|
10403
|
-
"path": "temperatureUnit",
|
|
10404
|
-
"valueType": "string"
|
|
10405
|
-
},
|
|
10406
10435
|
{
|
|
10407
10436
|
"path": "humidity",
|
|
10408
10437
|
"valueType": "number"
|
|
@@ -10411,18 +10440,10 @@ Object.freeze({
|
|
|
10411
10440
|
"path": "pressure",
|
|
10412
10441
|
"valueType": "number"
|
|
10413
10442
|
},
|
|
10414
|
-
{
|
|
10415
|
-
"path": "pressureUnit",
|
|
10416
|
-
"valueType": "string"
|
|
10417
|
-
},
|
|
10418
10443
|
{
|
|
10419
10444
|
"path": "windSpeed",
|
|
10420
10445
|
"valueType": "number"
|
|
10421
10446
|
},
|
|
10422
|
-
{
|
|
10423
|
-
"path": "windSpeedUnit",
|
|
10424
|
-
"valueType": "string"
|
|
10425
|
-
},
|
|
10426
10447
|
{
|
|
10427
10448
|
"path": "windBearing",
|
|
10428
10449
|
"valueType": "number"
|
|
@@ -10829,7 +10850,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10829
10850
|
return DeviceRole;
|
|
10830
10851
|
}({});
|
|
10831
10852
|
//#endregion
|
|
10832
|
-
//#region ../types/dist/composition-
|
|
10853
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10833
10854
|
/**
|
|
10834
10855
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10835
10856
|
*
|
|
@@ -11584,15 +11605,74 @@ function validateExpressionSource(src) {
|
|
|
11584
11605
|
}
|
|
11585
11606
|
return null;
|
|
11586
11607
|
}
|
|
11587
|
-
/**
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11608
|
+
/**
|
|
11609
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11610
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11611
|
+
* `composition.ts` (D659).
|
|
11612
|
+
*/
|
|
11591
11613
|
var CompositionSourceRefSchema = object({
|
|
11592
11614
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11593
11615
|
addonId: string().min(1),
|
|
11594
11616
|
stableId: string().min(1)
|
|
11595
11617
|
});
|
|
11618
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11619
|
+
"temperature",
|
|
11620
|
+
"humidity",
|
|
11621
|
+
"pressure",
|
|
11622
|
+
"illuminance",
|
|
11623
|
+
"power",
|
|
11624
|
+
"energy",
|
|
11625
|
+
"battery",
|
|
11626
|
+
"numeric",
|
|
11627
|
+
"motion",
|
|
11628
|
+
"contact",
|
|
11629
|
+
"leak",
|
|
11630
|
+
"smoke",
|
|
11631
|
+
"occupancy",
|
|
11632
|
+
"binary",
|
|
11633
|
+
"switch",
|
|
11634
|
+
"light"
|
|
11635
|
+
];
|
|
11636
|
+
var NUMERIC_AGGREGATES = [
|
|
11637
|
+
"mean",
|
|
11638
|
+
"median",
|
|
11639
|
+
"min",
|
|
11640
|
+
"max",
|
|
11641
|
+
"sum"
|
|
11642
|
+
];
|
|
11643
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11644
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11645
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11646
|
+
var AGGREGATE_REDUCERS = [
|
|
11647
|
+
"mean",
|
|
11648
|
+
"median",
|
|
11649
|
+
"min",
|
|
11650
|
+
"max",
|
|
11651
|
+
"sum",
|
|
11652
|
+
"any",
|
|
11653
|
+
"all"
|
|
11654
|
+
];
|
|
11655
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11656
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11657
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11658
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11659
|
+
var HelperMemberSchema = object({
|
|
11660
|
+
source: CompositionSourceRefSchema,
|
|
11661
|
+
cap: string().min(1),
|
|
11662
|
+
fieldPath: string().min(1)
|
|
11663
|
+
});
|
|
11664
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11665
|
+
kind: literal("group"),
|
|
11666
|
+
templateId: GroupTemplateIdSchema,
|
|
11667
|
+
aggregate: AggregateReducerSchema,
|
|
11668
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11669
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11670
|
+
active: ActiveCriterionSchema.optional()
|
|
11671
|
+
})]);
|
|
11672
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11673
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11674
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11675
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11596
11676
|
/** One field of one capability of one source device. */
|
|
11597
11677
|
var CompositionFieldReadSchema = object({
|
|
11598
11678
|
source: CompositionSourceRefSchema,
|
|
@@ -11636,7 +11716,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11636
11716
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11637
11717
|
CompositionFromSourceSchema,
|
|
11638
11718
|
CompositionExpressionSourceSchema,
|
|
11639
|
-
CompositionCodeSourceSchema
|
|
11719
|
+
CompositionCodeSourceSchema,
|
|
11720
|
+
object({
|
|
11721
|
+
kind: literal("aggregate"),
|
|
11722
|
+
reducer: _enum([
|
|
11723
|
+
"mean",
|
|
11724
|
+
"median",
|
|
11725
|
+
"min",
|
|
11726
|
+
"max",
|
|
11727
|
+
"sum",
|
|
11728
|
+
"any",
|
|
11729
|
+
"all"
|
|
11730
|
+
]),
|
|
11731
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11732
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11733
|
+
publish: _enum([
|
|
11734
|
+
"value",
|
|
11735
|
+
"included",
|
|
11736
|
+
"excluded",
|
|
11737
|
+
"total"
|
|
11738
|
+
]),
|
|
11739
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11740
|
+
empty: _enum([
|
|
11741
|
+
"null",
|
|
11742
|
+
"omit",
|
|
11743
|
+
"offline"
|
|
11744
|
+
])
|
|
11745
|
+
})
|
|
11640
11746
|
]);
|
|
11641
11747
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11642
11748
|
kind: literal("forward"),
|
|
@@ -11682,7 +11788,13 @@ var CompositionSchema = object({
|
|
|
11682
11788
|
kind: literal("existing"),
|
|
11683
11789
|
device: CompositionSourceRefSchema
|
|
11684
11790
|
})]),
|
|
11685
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11791
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11792
|
+
/**
|
|
11793
|
+
* Present when the block is a helper template. Absent on a free
|
|
11794
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11795
|
+
* never the compiled features.
|
|
11796
|
+
*/
|
|
11797
|
+
helper: HelperSpecSchema.optional()
|
|
11686
11798
|
}).superRefine((composition, ctx) => {
|
|
11687
11799
|
const seen = /* @__PURE__ */ new Set();
|
|
11688
11800
|
composition.features.forEach((feature, index) => {
|
|
@@ -17928,7 +18040,11 @@ var CompositionProblemSchema = object({
|
|
|
17928
18040
|
"item-field-reserved",
|
|
17929
18041
|
"target-missing",
|
|
17930
18042
|
"target-unreadable",
|
|
17931
|
-
"not-replaceable"
|
|
18043
|
+
"not-replaceable",
|
|
18044
|
+
"native-capability-replace",
|
|
18045
|
+
"mixed-quantity",
|
|
18046
|
+
"helper-mismatch",
|
|
18047
|
+
"member-constraint"
|
|
17932
18048
|
]),
|
|
17933
18049
|
path: string(),
|
|
17934
18050
|
message: string()
|
|
@@ -17949,7 +18065,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17949
18065
|
"null",
|
|
17950
18066
|
"offline",
|
|
17951
18067
|
"unknown",
|
|
17952
|
-
"release"
|
|
18068
|
+
"release",
|
|
18069
|
+
"omit"
|
|
17953
18070
|
]);
|
|
17954
18071
|
/**
|
|
17955
18072
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -17986,9 +18103,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17986
18103
|
reads: array(CompositionFieldReadSchema)
|
|
17987
18104
|
});
|
|
17988
18105
|
/**
|
|
17989
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17990
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17991
|
-
*
|
|
18106
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18107
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18108
|
+
* Replacing a capability the device already serves is refused
|
|
18109
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18110
|
+
* wire for a claim the hub already holds.
|
|
17992
18111
|
*/
|
|
17993
18112
|
var CompositionFeatureModeSchema = _enum([
|
|
17994
18113
|
"new",
|
|
@@ -18161,6 +18280,275 @@ Object.freeze({
|
|
|
18161
18280
|
result: ["number", "null"]
|
|
18162
18281
|
}
|
|
18163
18282
|
});
|
|
18283
|
+
/**
|
|
18284
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18285
|
+
* Data, not a form default written into the block.
|
|
18286
|
+
*/
|
|
18287
|
+
var NOW = {
|
|
18288
|
+
fieldPath: "lastFetchedAt",
|
|
18289
|
+
expr: "now"
|
|
18290
|
+
};
|
|
18291
|
+
var CHANGED = {
|
|
18292
|
+
fieldPath: "lastChangedAt",
|
|
18293
|
+
expr: "now"
|
|
18294
|
+
};
|
|
18295
|
+
function numeric(input) {
|
|
18296
|
+
return {
|
|
18297
|
+
...input,
|
|
18298
|
+
family: "numeric",
|
|
18299
|
+
deviceType: DeviceType.Sensor,
|
|
18300
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18301
|
+
commandCaps: [],
|
|
18302
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18303
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18304
|
+
accept: [{
|
|
18305
|
+
cap: input.outputCap,
|
|
18306
|
+
fieldPath: input.outputField
|
|
18307
|
+
}]
|
|
18308
|
+
};
|
|
18309
|
+
}
|
|
18310
|
+
function binary(input) {
|
|
18311
|
+
return {
|
|
18312
|
+
...input,
|
|
18313
|
+
family: "binary",
|
|
18314
|
+
deviceType: DeviceType.Sensor,
|
|
18315
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18316
|
+
commandCaps: [],
|
|
18317
|
+
quantity: "none",
|
|
18318
|
+
baseUnit: void 0,
|
|
18319
|
+
aggregates: BINARY_AGGREGATES,
|
|
18320
|
+
empty: "offline"
|
|
18321
|
+
};
|
|
18322
|
+
}
|
|
18323
|
+
var GROUP_TEMPLATES = [
|
|
18324
|
+
numeric({
|
|
18325
|
+
id: "temperature",
|
|
18326
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18327
|
+
role: DeviceRole.TemperatureSensor,
|
|
18328
|
+
outputCap: "temperature-sensor",
|
|
18329
|
+
outputField: "celsius",
|
|
18330
|
+
quantity: "temperature",
|
|
18331
|
+
defaultAggregate: "mean",
|
|
18332
|
+
empty: "null",
|
|
18333
|
+
companions: [NOW]
|
|
18334
|
+
}),
|
|
18335
|
+
numeric({
|
|
18336
|
+
id: "humidity",
|
|
18337
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18338
|
+
role: DeviceRole.HumiditySensor,
|
|
18339
|
+
outputCap: "humidity-sensor",
|
|
18340
|
+
outputField: "percent",
|
|
18341
|
+
quantity: "humidity",
|
|
18342
|
+
defaultAggregate: "mean",
|
|
18343
|
+
empty: "null",
|
|
18344
|
+
companions: [NOW]
|
|
18345
|
+
}),
|
|
18346
|
+
numeric({
|
|
18347
|
+
id: "pressure",
|
|
18348
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18349
|
+
role: DeviceRole.PressureSensor,
|
|
18350
|
+
outputCap: "pressure-sensor",
|
|
18351
|
+
outputField: "hpa",
|
|
18352
|
+
quantity: "pressure",
|
|
18353
|
+
defaultAggregate: "mean",
|
|
18354
|
+
empty: "null",
|
|
18355
|
+
companions: [NOW]
|
|
18356
|
+
}),
|
|
18357
|
+
numeric({
|
|
18358
|
+
id: "illuminance",
|
|
18359
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18360
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18361
|
+
outputCap: "ambient-light-sensor",
|
|
18362
|
+
outputField: "lux",
|
|
18363
|
+
quantity: "illuminance",
|
|
18364
|
+
defaultAggregate: "mean",
|
|
18365
|
+
empty: "null",
|
|
18366
|
+
companions: [NOW]
|
|
18367
|
+
}),
|
|
18368
|
+
numeric({
|
|
18369
|
+
id: "power",
|
|
18370
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18371
|
+
role: DeviceRole.PowerSensor,
|
|
18372
|
+
outputCap: "power-meter",
|
|
18373
|
+
outputField: "watts",
|
|
18374
|
+
quantity: "power",
|
|
18375
|
+
defaultAggregate: "sum",
|
|
18376
|
+
empty: "omit",
|
|
18377
|
+
companions: [NOW]
|
|
18378
|
+
}),
|
|
18379
|
+
numeric({
|
|
18380
|
+
id: "energy",
|
|
18381
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18382
|
+
role: DeviceRole.EnergySensor,
|
|
18383
|
+
outputCap: "power-meter",
|
|
18384
|
+
outputField: "kwhTotal",
|
|
18385
|
+
quantity: "energy",
|
|
18386
|
+
defaultAggregate: "sum",
|
|
18387
|
+
empty: "omit",
|
|
18388
|
+
companions: [NOW]
|
|
18389
|
+
}),
|
|
18390
|
+
numeric({
|
|
18391
|
+
id: "battery",
|
|
18392
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18393
|
+
role: DeviceRole.BatterySensor,
|
|
18394
|
+
outputCap: "battery",
|
|
18395
|
+
outputField: "percentage",
|
|
18396
|
+
quantity: "percentage",
|
|
18397
|
+
defaultAggregate: "mean",
|
|
18398
|
+
empty: "null",
|
|
18399
|
+
companions: [
|
|
18400
|
+
{
|
|
18401
|
+
fieldPath: "charging",
|
|
18402
|
+
expr: "\"unknown\""
|
|
18403
|
+
},
|
|
18404
|
+
{
|
|
18405
|
+
fieldPath: "sleeping",
|
|
18406
|
+
expr: "false"
|
|
18407
|
+
},
|
|
18408
|
+
{
|
|
18409
|
+
fieldPath: "lastUpdated",
|
|
18410
|
+
expr: "now"
|
|
18411
|
+
}
|
|
18412
|
+
]
|
|
18413
|
+
}),
|
|
18414
|
+
numeric({
|
|
18415
|
+
id: "numeric",
|
|
18416
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18417
|
+
role: DeviceRole.NumericSensor,
|
|
18418
|
+
outputCap: "numeric-sensor",
|
|
18419
|
+
outputField: "value",
|
|
18420
|
+
quantity: "device",
|
|
18421
|
+
defaultAggregate: "mean",
|
|
18422
|
+
empty: "null",
|
|
18423
|
+
companions: [NOW]
|
|
18424
|
+
}),
|
|
18425
|
+
binary({
|
|
18426
|
+
id: "motion",
|
|
18427
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18428
|
+
role: DeviceRole.MotionSensor,
|
|
18429
|
+
outputCap: "motion",
|
|
18430
|
+
outputField: "detected",
|
|
18431
|
+
defaultAggregate: "any",
|
|
18432
|
+
accept: [{
|
|
18433
|
+
cap: "motion",
|
|
18434
|
+
fieldPath: "detected"
|
|
18435
|
+
}],
|
|
18436
|
+
companions: [{
|
|
18437
|
+
fieldPath: "lastDetectedAt",
|
|
18438
|
+
expr: "null"
|
|
18439
|
+
}, {
|
|
18440
|
+
fieldPath: "autoClearAfterMs",
|
|
18441
|
+
expr: "null"
|
|
18442
|
+
}]
|
|
18443
|
+
}),
|
|
18444
|
+
binary({
|
|
18445
|
+
id: "contact",
|
|
18446
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18447
|
+
role: DeviceRole.ContactSensor,
|
|
18448
|
+
outputCap: "contact",
|
|
18449
|
+
outputField: "entryOpen",
|
|
18450
|
+
defaultAggregate: "any",
|
|
18451
|
+
accept: [{
|
|
18452
|
+
cap: "contact",
|
|
18453
|
+
fieldPath: "entryOpen"
|
|
18454
|
+
}],
|
|
18455
|
+
companions: [CHANGED]
|
|
18456
|
+
}),
|
|
18457
|
+
binary({
|
|
18458
|
+
id: "leak",
|
|
18459
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18460
|
+
role: DeviceRole.LeakSensor,
|
|
18461
|
+
outputCap: "flood",
|
|
18462
|
+
outputField: "flooded",
|
|
18463
|
+
defaultAggregate: "any",
|
|
18464
|
+
accept: [{
|
|
18465
|
+
cap: "flood",
|
|
18466
|
+
fieldPath: "flooded"
|
|
18467
|
+
}],
|
|
18468
|
+
companions: [CHANGED]
|
|
18469
|
+
}),
|
|
18470
|
+
binary({
|
|
18471
|
+
id: "smoke",
|
|
18472
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18473
|
+
role: DeviceRole.SmokeSensor,
|
|
18474
|
+
outputCap: "smoke",
|
|
18475
|
+
outputField: "detected",
|
|
18476
|
+
defaultAggregate: "any",
|
|
18477
|
+
accept: [{
|
|
18478
|
+
cap: "smoke",
|
|
18479
|
+
fieldPath: "detected"
|
|
18480
|
+
}],
|
|
18481
|
+
companions: [CHANGED]
|
|
18482
|
+
}),
|
|
18483
|
+
binary({
|
|
18484
|
+
id: "occupancy",
|
|
18485
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18486
|
+
role: DeviceRole.BinarySensor,
|
|
18487
|
+
outputCap: "binary",
|
|
18488
|
+
outputField: "on",
|
|
18489
|
+
defaultAggregate: "any",
|
|
18490
|
+
accept: [{
|
|
18491
|
+
cap: "motion",
|
|
18492
|
+
fieldPath: "detected"
|
|
18493
|
+
}, {
|
|
18494
|
+
cap: "binary",
|
|
18495
|
+
fieldPath: "on"
|
|
18496
|
+
}],
|
|
18497
|
+
companions: [CHANGED]
|
|
18498
|
+
}),
|
|
18499
|
+
binary({
|
|
18500
|
+
id: "binary",
|
|
18501
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18502
|
+
role: DeviceRole.BinarySensor,
|
|
18503
|
+
outputCap: "binary",
|
|
18504
|
+
outputField: "on",
|
|
18505
|
+
defaultAggregate: "any",
|
|
18506
|
+
accept: [{
|
|
18507
|
+
cap: "binary",
|
|
18508
|
+
fieldPath: "on"
|
|
18509
|
+
}],
|
|
18510
|
+
companions: [CHANGED]
|
|
18511
|
+
}),
|
|
18512
|
+
actuator({
|
|
18513
|
+
id: "switch",
|
|
18514
|
+
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.",
|
|
18515
|
+
deviceType: DeviceType.Switch,
|
|
18516
|
+
outputCap: "switch",
|
|
18517
|
+
commandCaps: ["switch"]
|
|
18518
|
+
}),
|
|
18519
|
+
actuator({
|
|
18520
|
+
id: "light",
|
|
18521
|
+
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.",
|
|
18522
|
+
deviceType: DeviceType.Light,
|
|
18523
|
+
outputCap: "switch",
|
|
18524
|
+
commandCaps: [
|
|
18525
|
+
"switch",
|
|
18526
|
+
"brightness",
|
|
18527
|
+
"color"
|
|
18528
|
+
]
|
|
18529
|
+
})
|
|
18530
|
+
];
|
|
18531
|
+
function actuator(input) {
|
|
18532
|
+
return {
|
|
18533
|
+
...input,
|
|
18534
|
+
family: "actuator",
|
|
18535
|
+
role: void 0,
|
|
18536
|
+
memberDeviceType: input.deviceType,
|
|
18537
|
+
outputField: "on",
|
|
18538
|
+
quantity: "none",
|
|
18539
|
+
baseUnit: void 0,
|
|
18540
|
+
aggregates: BINARY_AGGREGATES,
|
|
18541
|
+
defaultAggregate: "any",
|
|
18542
|
+
empty: "offline",
|
|
18543
|
+
accept: [{
|
|
18544
|
+
cap: "switch",
|
|
18545
|
+
fieldPath: "on"
|
|
18546
|
+
}],
|
|
18547
|
+
companions: [CHANGED]
|
|
18548
|
+
};
|
|
18549
|
+
}
|
|
18550
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18551
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18164
18552
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18165
18553
|
/**
|
|
18166
18554
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19987,12 +20375,12 @@ function buildDeviceAdminUrl(parts) {
|
|
|
19987
20375
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19988
20376
|
* in-place so dispatch keeps working.
|
|
19989
20377
|
*
|
|
19990
|
-
* **
|
|
19991
|
-
*
|
|
19992
|
-
*
|
|
19993
|
-
*
|
|
19994
|
-
* (`ha-domain-mapping`)
|
|
19995
|
-
* stored after that point.
|
|
20378
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20379
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20380
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20381
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20382
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20383
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19996
20384
|
*
|
|
19997
20385
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19998
20386
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20006,6 +20394,14 @@ var SourceInfoSchema = object({
|
|
|
20006
20394
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20007
20395
|
* Used to detect rename when `id` changes. */
|
|
20008
20396
|
uniqueId: string().optional(),
|
|
20397
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20398
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20399
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20400
|
+
dateTimeShape: _enum([
|
|
20401
|
+
"date",
|
|
20402
|
+
"time",
|
|
20403
|
+
"datetime"
|
|
20404
|
+
]).optional(),
|
|
20009
20405
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20010
20406
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20011
20407
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41110,7 +41506,8 @@ method(object({
|
|
|
41110
41506
|
"enum"
|
|
41111
41507
|
]),
|
|
41112
41508
|
enumValues: array(string()).optional(),
|
|
41113
|
-
item: boolean().optional()
|
|
41509
|
+
item: boolean().optional(),
|
|
41510
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41114
41511
|
})).readonly(),
|
|
41115
41512
|
itemArray: object({
|
|
41116
41513
|
path: string(),
|
|
@@ -44954,8 +45351,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44954
45351
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44955
45352
|
var MaskGridShapeSchema = object({
|
|
44956
45353
|
kind: literal("grid"),
|
|
44957
|
-
gridWidth: number(),
|
|
44958
|
-
gridHeight: number(),
|
|
45354
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45355
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44959
45356
|
cells: array(boolean())
|
|
44960
45357
|
});
|
|
44961
45358
|
discriminatedUnion("kind", [
|
|
@@ -45067,6 +45464,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45067
45464
|
"detection-blind",
|
|
45068
45465
|
"motion-noisy",
|
|
45069
45466
|
"motion-calm",
|
|
45467
|
+
"package-llm-silent",
|
|
45468
|
+
"package-llm-answered",
|
|
45070
45469
|
"recording-stalled",
|
|
45071
45470
|
"recording-healthy",
|
|
45072
45471
|
"recording-degraded",
|
|
@@ -56671,6 +57070,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56671
57070
|
deprecated: string().optional(),
|
|
56672
57071
|
distTags: array(string()).readonly()
|
|
56673
57072
|
});
|
|
57073
|
+
/**
|
|
57074
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
57075
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
57076
|
+
* tarball failure — never an empty string standing in for either.
|
|
57077
|
+
*/
|
|
57078
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
57079
|
+
object({
|
|
57080
|
+
status: literal("ok"),
|
|
57081
|
+
markdown: string()
|
|
57082
|
+
}),
|
|
57083
|
+
object({ status: literal("missing") }),
|
|
57084
|
+
object({
|
|
57085
|
+
status: literal("error"),
|
|
57086
|
+
message: string()
|
|
57087
|
+
})
|
|
57088
|
+
]);
|
|
57089
|
+
var PackageDocsSchema = object({
|
|
57090
|
+
name: string(),
|
|
57091
|
+
version: string(),
|
|
57092
|
+
readme: PackageDocBodySchema,
|
|
57093
|
+
changelog: PackageDocBodySchema
|
|
57094
|
+
});
|
|
56674
57095
|
var SearchResultSchema = object({
|
|
56675
57096
|
name: string(),
|
|
56676
57097
|
version: string(),
|
|
@@ -56889,7 +57310,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56889
57310
|
}), object({ success: literal(true) }), {
|
|
56890
57311
|
kind: "mutation",
|
|
56891
57312
|
auth: "admin"
|
|
56892
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57313
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57314
|
+
name: string().min(1),
|
|
57315
|
+
version: string().min(1).optional()
|
|
57316
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56893
57317
|
kind: "mutation",
|
|
56894
57318
|
auth: "admin"
|
|
56895
57319
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56948,27 +57372,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56948
57372
|
*/
|
|
56949
57373
|
var AirQualitySensorStatusSchema = object({
|
|
56950
57374
|
/** Carbon dioxide concentration in ppm. */
|
|
56951
|
-
co2Ppm: number().min(0).optional(),
|
|
57375
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56952
57376
|
/** Total volatile organic compounds in ppb. */
|
|
56953
|
-
vocPpb: number().min(0).optional(),
|
|
57377
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56954
57378
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56955
|
-
pm25: number().min(0).optional(),
|
|
57379
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56956
57380
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56957
|
-
pm10: number().min(0).optional(),
|
|
57381
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56958
57382
|
/** Composite AQI value (typically 0..500). */
|
|
56959
|
-
aqi: number().optional(),
|
|
57383
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56960
57384
|
/** Ms epoch when the slice was last updated. */
|
|
56961
|
-
lastFetchedAt: number()
|
|
56962
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56963
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56964
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56965
|
-
* per slice is unambiguous. */
|
|
56966
|
-
unit: string().optional(),
|
|
56967
|
-
/** Suggested decimal places for numeric display.
|
|
56968
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56969
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56970
|
-
* auto-formatting when absent. */
|
|
56971
|
-
precision: number().int().min(0).max(10).optional()
|
|
57385
|
+
lastFetchedAt: number()
|
|
56972
57386
|
});
|
|
56973
57387
|
var airQualitySensorCapability = {
|
|
56974
57388
|
name: "air-quality-sensor",
|
|
@@ -57005,12 +57419,12 @@ var airQualitySensorCapability = {
|
|
|
57005
57419
|
},
|
|
57006
57420
|
pm25: {
|
|
57007
57421
|
kind: "gauge",
|
|
57008
|
-
unit: "
|
|
57422
|
+
unit: "µg/m³",
|
|
57009
57423
|
deadband: 1
|
|
57010
57424
|
},
|
|
57011
57425
|
pm10: {
|
|
57012
57426
|
kind: "gauge",
|
|
57013
|
-
unit: "
|
|
57427
|
+
unit: "µg/m³",
|
|
57014
57428
|
deadband: 1
|
|
57015
57429
|
},
|
|
57016
57430
|
aqi: {
|
|
@@ -57028,22 +57442,13 @@ var airQualitySensorCapability = {
|
|
|
57028
57442
|
* entries with `device_class: illuminance`.
|
|
57029
57443
|
*/
|
|
57030
57444
|
var AmbientLightSensorStatusSchema = object({
|
|
57031
|
-
/** Current illuminance in lux (lx). */
|
|
57032
|
-
lux: number().min(0).meta({
|
|
57033
|
-
|
|
57445
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57446
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57447
|
+
precision: 0,
|
|
57034
57448
|
label: "Illuminance"
|
|
57035
|
-
}),
|
|
57449
|
+
})),
|
|
57036
57450
|
/** Ms epoch when the slice was last updated. */
|
|
57037
|
-
lastFetchedAt: number()
|
|
57038
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
57039
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
57040
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
57041
|
-
unit: string().optional(),
|
|
57042
|
-
/** Suggested decimal places for numeric display.
|
|
57043
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
57044
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
57045
|
-
* auto-formatting when absent. */
|
|
57046
|
-
precision: number().int().min(0).max(10).optional()
|
|
57451
|
+
lastFetchedAt: number()
|
|
57047
57452
|
});
|
|
57048
57453
|
var ambientLightSensorCapability = {
|
|
57049
57454
|
name: "ambient-light-sensor",
|
|
@@ -57075,12 +57480,7 @@ var ambientLightSensorCapability = {
|
|
|
57075
57480
|
} } },
|
|
57076
57481
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57077
57482
|
* whether persisting is worth a SQLite commit. */
|
|
57078
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
57079
|
-
customize: {
|
|
57080
|
-
version: 1,
|
|
57081
|
-
advanced: "derive",
|
|
57082
|
-
targets: []
|
|
57083
|
-
}
|
|
57483
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
57084
57484
|
};
|
|
57085
57485
|
/**
|
|
57086
57486
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57307,10 +57707,7 @@ var BatteryStatusSchema = object({
|
|
|
57307
57707
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57308
57708
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57309
57709
|
*/
|
|
57310
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57311
|
-
unit: "%",
|
|
57312
|
-
label: "Charge"
|
|
57313
|
-
}),
|
|
57710
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57314
57711
|
/**
|
|
57315
57712
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57316
57713
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57337,7 +57734,14 @@ var BatteryStatusSchema = object({
|
|
|
57337
57734
|
*/
|
|
57338
57735
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57339
57736
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57340
|
-
lastUpdated: number(),
|
|
57737
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57738
|
+
/**
|
|
57739
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57740
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57741
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57742
|
+
* `numeric-sensor` on the same device.
|
|
57743
|
+
*/
|
|
57744
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57341
57745
|
/**
|
|
57342
57746
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57343
57747
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57389,7 +57793,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57389
57793
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57390
57794
|
var batteryCustomize = {
|
|
57391
57795
|
version: 1,
|
|
57392
|
-
advanced: "derive",
|
|
57393
57796
|
targets: [{
|
|
57394
57797
|
id: "percentage",
|
|
57395
57798
|
cardinality: "scalar",
|
|
@@ -57398,7 +57801,7 @@ var batteryCustomize = {
|
|
|
57398
57801
|
stateField: "percentage"
|
|
57399
57802
|
},
|
|
57400
57803
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57401
|
-
apply: "add
|
|
57804
|
+
apply: "add",
|
|
57402
57805
|
path: "percentage",
|
|
57403
57806
|
sources: [{
|
|
57404
57807
|
kind: "field",
|
|
@@ -57519,10 +57922,16 @@ onStatusChanged: { data: object({
|
|
|
57519
57922
|
/**
|
|
57520
57923
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57521
57924
|
*/
|
|
57522
|
-
history: { fields: {
|
|
57523
|
-
|
|
57524
|
-
|
|
57525
|
-
|
|
57925
|
+
history: { fields: {
|
|
57926
|
+
percentage: {
|
|
57927
|
+
kind: "gauge",
|
|
57928
|
+
unit: "%"
|
|
57929
|
+
},
|
|
57930
|
+
volts: {
|
|
57931
|
+
kind: "gauge",
|
|
57932
|
+
unit: "V"
|
|
57933
|
+
}
|
|
57934
|
+
} },
|
|
57526
57935
|
customize: batteryCustomize,
|
|
57527
57936
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57528
57937
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57569,12 +57978,7 @@ var binaryCapability = {
|
|
|
57569
57978
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57570
57979
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57571
57980
|
* whether persisting is worth a SQLite commit. */
|
|
57572
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57573
|
-
customize: {
|
|
57574
|
-
version: 1,
|
|
57575
|
-
advanced: "derive",
|
|
57576
|
-
targets: []
|
|
57577
|
-
}
|
|
57981
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57578
57982
|
};
|
|
57579
57983
|
/**
|
|
57580
57984
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57590,7 +57994,7 @@ var binaryCapability = {
|
|
|
57590
57994
|
*/
|
|
57591
57995
|
var BrightnessStatusSchema = object({
|
|
57592
57996
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57593
|
-
percentage: number().min(0).max(100),
|
|
57997
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57594
57998
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57595
57999
|
lastChangedAt: number()
|
|
57596
58000
|
});
|
|
@@ -58044,21 +58448,21 @@ var ClimateControlStatusSchema = object({
|
|
|
58044
58448
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
58045
58449
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
58046
58450
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
58047
|
-
target: number().nullable(),
|
|
58451
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
58048
58452
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
58049
58453
|
* in `heat_cool` mode. */
|
|
58050
|
-
targetHigh: number().nullable(),
|
|
58454
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
58051
58455
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
58052
58456
|
* in `heat_cool` mode. */
|
|
58053
|
-
targetLow: number().nullable(),
|
|
58457
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
58054
58458
|
/** Target relative humidity (0..100). Null when the device has no
|
|
58055
58459
|
* humidity control. */
|
|
58056
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58460
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58057
58461
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
58058
58462
|
* the device's internal sensor. */
|
|
58059
|
-
currentTemp: number().nullable(),
|
|
58463
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
58060
58464
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
58061
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58465
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58062
58466
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
58063
58467
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
58064
58468
|
swingVertical: boolean().nullable(),
|
|
@@ -58066,11 +58470,11 @@ var ClimateControlStatusSchema = object({
|
|
|
58066
58470
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
58067
58471
|
swingHorizontal: boolean().nullable(),
|
|
58068
58472
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58069
|
-
minTemp: number().nullable().optional(),
|
|
58473
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58070
58474
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
58071
|
-
maxTemp: number().nullable().optional(),
|
|
58475
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
58072
58476
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
58073
|
-
tempStep: number().positive().nullable().optional(),
|
|
58477
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
58074
58478
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
58075
58479
|
lastFetchedAt: number()
|
|
58076
58480
|
});
|
|
@@ -58212,17 +58616,17 @@ var climateControlCapability = {
|
|
|
58212
58616
|
* modes to expose in the picker without a slice fetch.
|
|
58213
58617
|
*/
|
|
58214
58618
|
var RgbTripletSchema = object({
|
|
58215
|
-
r: number().int().min(0).max(255),
|
|
58216
|
-
g: number().int().min(0).max(255),
|
|
58217
|
-
b: number().int().min(0).max(255)
|
|
58619
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58620
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58621
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
58218
58622
|
});
|
|
58219
58623
|
var HsvTripletSchema = object({
|
|
58220
58624
|
/** Hue in degrees, 0..360. */
|
|
58221
|
-
h: number().min(0).max(360),
|
|
58625
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
58222
58626
|
/** Saturation as 0..100 inclusive. */
|
|
58223
|
-
s: number().min(0).max(100),
|
|
58627
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
58224
58628
|
/** Value/brightness as 0..100 inclusive. */
|
|
58225
|
-
v: number().min(0).max(100)
|
|
58629
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
58226
58630
|
});
|
|
58227
58631
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
58228
58632
|
object({
|
|
@@ -58251,7 +58655,7 @@ var ColorStatusSchema = object({
|
|
|
58251
58655
|
/** Populated when `mode === 'hsv'`. */
|
|
58252
58656
|
hsv: HsvTripletSchema.optional(),
|
|
58253
58657
|
/** Populated when `mode === 'mired'`. */
|
|
58254
|
-
mireds: number().int().optional(),
|
|
58658
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58255
58659
|
/** Ms epoch of the last operator-driven change. */
|
|
58256
58660
|
lastChangedAt: number()
|
|
58257
58661
|
});
|
|
@@ -58446,18 +58850,12 @@ _enum([
|
|
|
58446
58850
|
"empty",
|
|
58447
58851
|
"full"
|
|
58448
58852
|
]);
|
|
58449
|
-
/**
|
|
58450
|
-
|
|
58451
|
-
|
|
58452
|
-
"days",
|
|
58453
|
-
"hours",
|
|
58454
|
-
"cycles"
|
|
58455
|
-
]);
|
|
58456
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
58457
|
-
* days). `value` null = unknown (D393). */
|
|
58853
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58854
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58855
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
58458
58856
|
var ConsumableRemainingSchema = object({
|
|
58459
|
-
value: number().min(0).nullable(),
|
|
58460
|
-
|
|
58857
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58858
|
+
kind: ConsumableRemainingKindSchema
|
|
58461
58859
|
});
|
|
58462
58860
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
58463
58861
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -58470,7 +58868,7 @@ var ConsumableItemSchema = object({
|
|
|
58470
58868
|
/** Display name. */
|
|
58471
58869
|
label: string().min(1),
|
|
58472
58870
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
58473
|
-
level: number().min(0).max(100).nullable(),
|
|
58871
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58474
58872
|
/** The provider's discrete verdict when known (binary mode). */
|
|
58475
58873
|
status: ConsumableStatusSchema.nullable(),
|
|
58476
58874
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58552,8 +58950,8 @@ var consumablesCustomize = {
|
|
|
58552
58950
|
transforms: [{ kind: "identity" }]
|
|
58553
58951
|
}],
|
|
58554
58952
|
literals: [{
|
|
58555
|
-
path: "remaining.
|
|
58556
|
-
values: [...
|
|
58953
|
+
path: "remaining.kind",
|
|
58954
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58557
58955
|
}]
|
|
58558
58956
|
},
|
|
58559
58957
|
{
|
|
@@ -58682,7 +59080,6 @@ reset: method(object({
|
|
|
58682
59080
|
},
|
|
58683
59081
|
"remaining.value": {
|
|
58684
59082
|
kind: "gauge",
|
|
58685
|
-
unitFrom: "remaining.unit",
|
|
58686
59083
|
deadband: 1,
|
|
58687
59084
|
displayName: "Remaining"
|
|
58688
59085
|
}
|
|
@@ -58752,10 +59149,9 @@ var contactCapability = {
|
|
|
58752
59149
|
* (empty array for the other kinds). It lives in the slice because
|
|
58753
59150
|
* HA `select.*` entities may update their options at runtime.
|
|
58754
59151
|
*
|
|
58755
|
-
*
|
|
58756
|
-
*
|
|
58757
|
-
*
|
|
58758
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
59152
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
59153
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
59154
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58759
59155
|
*/
|
|
58760
59156
|
var ControlStatusSchema = object({
|
|
58761
59157
|
kind: _enum([
|
|
@@ -58767,39 +59163,17 @@ var ControlStatusSchema = object({
|
|
|
58767
59163
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58768
59164
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58769
59165
|
* or time-only — HA accepts all three forms). */
|
|
58770
|
-
value: union([number(), string()]),
|
|
59166
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58771
59167
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58772
59168
|
options: array(string()),
|
|
58773
59169
|
/** Ms epoch when the slice was last updated. */
|
|
58774
59170
|
lastChangedAt: number(),
|
|
58775
|
-
/**
|
|
58776
|
-
|
|
58777
|
-
|
|
58778
|
-
|
|
58779
|
-
/**
|
|
58780
|
-
|
|
58781
|
-
min: number().optional(),
|
|
58782
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58783
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58784
|
-
max: number().optional(),
|
|
58785
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58786
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58787
|
-
step: number().optional(),
|
|
58788
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58789
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58790
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58791
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58792
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58793
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58794
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58795
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58796
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58797
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58798
|
-
format: _enum([
|
|
58799
|
-
"date",
|
|
58800
|
-
"time",
|
|
58801
|
-
"datetime"
|
|
58802
|
-
]).optional()
|
|
59171
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
59172
|
+
min: number().optional().meta(readingMeta("device")),
|
|
59173
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
59174
|
+
max: number().optional().meta(readingMeta("device")),
|
|
59175
|
+
/** Step increment, in the device quantity's base unit. */
|
|
59176
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58803
59177
|
});
|
|
58804
59178
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58805
59179
|
object({
|
|
@@ -58865,9 +59239,9 @@ var CoverStatusSchema = object({
|
|
|
58865
59239
|
]),
|
|
58866
59240
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58867
59241
|
* no intermediate position surface. */
|
|
58868
|
-
position: number().min(0).max(100).nullable(),
|
|
59242
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58869
59243
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58870
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
59244
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58871
59245
|
/** Ms epoch when the slice was last updated. */
|
|
58872
59246
|
lastChangedAt: number()
|
|
58873
59247
|
});
|
|
@@ -58970,9 +59344,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58970
59344
|
var DayNightStatusSchema = object({
|
|
58971
59345
|
mode: DayNightModeSchema,
|
|
58972
59346
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58973
|
-
sensitivity: number().optional(),
|
|
59347
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58974
59348
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58975
|
-
switchDelaySec: number().optional(),
|
|
59349
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58976
59350
|
lastFetchedAt: number()
|
|
58977
59351
|
});
|
|
58978
59352
|
/**
|
|
@@ -59190,11 +59564,11 @@ var DishwasherStatusSchema = object({
|
|
|
59190
59564
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59191
59565
|
availablePrograms: array(string()),
|
|
59192
59566
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59193
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59567
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59194
59568
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59195
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59569
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59196
59570
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59197
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59571
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59198
59572
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59199
59573
|
doorOpen: boolean().nullable(),
|
|
59200
59574
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59218,7 +59592,7 @@ var DishwasherStatusSchema = object({
|
|
|
59218
59592
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
59219
59593
|
machineCareDue: boolean().nullable(),
|
|
59220
59594
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
59221
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59595
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
59222
59596
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
59223
59597
|
halfLoad: boolean().nullable(),
|
|
59224
59598
|
hygienePlus: boolean().nullable(),
|
|
@@ -59233,7 +59607,7 @@ var DishwasherStatusSchema = object({
|
|
|
59233
59607
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
59234
59608
|
activeEvents: array(string()),
|
|
59235
59609
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
59236
|
-
errorCode: number().nullable(),
|
|
59610
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
59237
59611
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
59238
59612
|
errorLabel: string().nullable(),
|
|
59239
59613
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -59445,6 +59819,7 @@ var doorbellCustomize = {
|
|
|
59445
59819
|
applyAuthority: { kind: "composition-claim" },
|
|
59446
59820
|
eventName: "onPressed",
|
|
59447
59821
|
edges: ["rising"],
|
|
59822
|
+
defaultEdge: "rising",
|
|
59448
59823
|
timestampPath: "lastPressedAt",
|
|
59449
59824
|
counterPath: "pressCountSinceStart",
|
|
59450
59825
|
highWater: "composer-advance",
|
|
@@ -59463,7 +59838,7 @@ var DoorbellStatusSchema = object({
|
|
|
59463
59838
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
59464
59839
|
lastPressedAt: number().nullable(),
|
|
59465
59840
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
59466
|
-
pressCountSinceStart: number()
|
|
59841
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
59467
59842
|
});
|
|
59468
59843
|
var DoorbellPressEventSchema = object({
|
|
59469
59844
|
deviceId: number(),
|
|
@@ -59528,17 +59903,7 @@ onPressed: {
|
|
|
59528
59903
|
history: "none",
|
|
59529
59904
|
customize: doorbellCustomize
|
|
59530
59905
|
};
|
|
59531
|
-
|
|
59532
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59533
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59534
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59535
|
-
* The option set is stable across observations; it is persisted in the
|
|
59536
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59537
|
-
* stored in `sourceInfo`.
|
|
59538
|
-
*/
|
|
59539
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59540
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59541
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59906
|
+
_enum([
|
|
59542
59907
|
"date",
|
|
59543
59908
|
"time",
|
|
59544
59909
|
"datetime"
|
|
@@ -59546,12 +59911,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59546
59911
|
var EnumSensorStatusSchema = object({
|
|
59547
59912
|
value: string(),
|
|
59548
59913
|
/**
|
|
59549
|
-
* Set
|
|
59550
|
-
* as
|
|
59551
|
-
*
|
|
59552
|
-
* a time-only sensor → `'time'`.
|
|
59914
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59915
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59916
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59553
59917
|
*/
|
|
59554
|
-
|
|
59918
|
+
timestamp: boolean().optional(),
|
|
59555
59919
|
/** Ms epoch when the slice was last updated. */
|
|
59556
59920
|
lastFetchedAt: number()
|
|
59557
59921
|
});
|
|
@@ -59578,11 +59942,11 @@ var enumSensorCapability = {
|
|
|
59578
59942
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59579
59943
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59580
59944
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59581
|
-
* `
|
|
59945
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59582
59946
|
*/
|
|
59583
59947
|
history: { fields: { value: {
|
|
59584
59948
|
kind: "enum",
|
|
59585
|
-
skipWhenSet: "
|
|
59949
|
+
skipWhenSet: "timestamp"
|
|
59586
59950
|
} } },
|
|
59587
59951
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59588
59952
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59602,13 +59966,13 @@ var EventFireSchema = object({
|
|
|
59602
59966
|
deviceId: number(),
|
|
59603
59967
|
eventType: string(),
|
|
59604
59968
|
data: record(string(), unknown()).nullable(),
|
|
59605
|
-
timestamp: number(),
|
|
59606
|
-
seq: number()
|
|
59969
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59970
|
+
seq: number().meta(readingMeta("count"))
|
|
59607
59971
|
});
|
|
59608
59972
|
var EventEmitterStatusSchema = object({
|
|
59609
59973
|
eventTypes: array(string()),
|
|
59610
59974
|
lastEvent: EventFireSchema.nullable(),
|
|
59611
|
-
eventCountSinceStart: number()
|
|
59975
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59612
59976
|
});
|
|
59613
59977
|
var eventEmitterCapability = {
|
|
59614
59978
|
name: "event-emitter",
|
|
@@ -60021,10 +60385,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60021
60385
|
var FanControlStatusSchema = object({
|
|
60022
60386
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60023
60387
|
* speed surface (single-speed fan). */
|
|
60024
|
-
percentage: number().min(0).max(100).nullable(),
|
|
60388
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60025
60389
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60026
60390
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60027
|
-
percentageStep: number().positive().optional(),
|
|
60391
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
60028
60392
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
60029
60393
|
* — empty string when no preset is active or supported. */
|
|
60030
60394
|
preset: string(),
|
|
@@ -60145,7 +60509,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
60145
60509
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
60146
60510
|
model: string().nullable(),
|
|
60147
60511
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
60148
|
-
channelCount: number().nullable(),
|
|
60512
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
60149
60513
|
/**
|
|
60150
60514
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
60151
60515
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -60268,9 +60632,91 @@ var gasCapability = {
|
|
|
60268
60632
|
* whether persisting is worth a SQLite commit. */
|
|
60269
60633
|
volatileStateFields: ["lastChangedAt"]
|
|
60270
60634
|
};
|
|
60635
|
+
var GroupCommandsSchema = object({
|
|
60636
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60637
|
+
results: array(object({
|
|
60638
|
+
deviceId: number().int().nonnegative(),
|
|
60639
|
+
cap: string().min(1),
|
|
60640
|
+
method: string().min(1),
|
|
60641
|
+
ok: boolean(),
|
|
60642
|
+
error: string().optional(),
|
|
60643
|
+
/** Ms epoch of the attempt. */
|
|
60644
|
+
at: number()
|
|
60645
|
+
})) });
|
|
60646
|
+
var groupCommandsCapability = {
|
|
60647
|
+
name: "group-commands",
|
|
60648
|
+
scope: "device",
|
|
60649
|
+
deviceNative: true,
|
|
60650
|
+
mode: "singleton",
|
|
60651
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60652
|
+
methods: {},
|
|
60653
|
+
status: {
|
|
60654
|
+
schema: GroupCommandsSchema,
|
|
60655
|
+
kind: "push"
|
|
60656
|
+
},
|
|
60657
|
+
runtimeState: GroupCommandsSchema,
|
|
60658
|
+
/**
|
|
60659
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60660
|
+
* failure would outlive the command that caused it.
|
|
60661
|
+
*
|
|
60662
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60663
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60664
|
+
*/
|
|
60665
|
+
durability: "session",
|
|
60666
|
+
history: "none"
|
|
60667
|
+
};
|
|
60668
|
+
/**
|
|
60669
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60670
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60671
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60672
|
+
* series that later statistics read is the output cap's own history block.
|
|
60673
|
+
*/
|
|
60674
|
+
var GroupStatusSchema = object({
|
|
60675
|
+
/** Members whose current value entered the aggregate. */
|
|
60676
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60677
|
+
precision: 0,
|
|
60678
|
+
label: "Reporting"
|
|
60679
|
+
})),
|
|
60680
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60681
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60682
|
+
precision: 0,
|
|
60683
|
+
label: "Excluded"
|
|
60684
|
+
})),
|
|
60685
|
+
/** `included` + `excluded`. */
|
|
60686
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60687
|
+
precision: 0,
|
|
60688
|
+
label: "Members"
|
|
60689
|
+
}))
|
|
60690
|
+
});
|
|
60691
|
+
var groupStatusCapability = {
|
|
60692
|
+
name: "group-status",
|
|
60693
|
+
scope: "device",
|
|
60694
|
+
deviceNative: true,
|
|
60695
|
+
mode: "singleton",
|
|
60696
|
+
deviceTypes: [
|
|
60697
|
+
DeviceType.Sensor,
|
|
60698
|
+
DeviceType.Switch,
|
|
60699
|
+
DeviceType.Light
|
|
60700
|
+
],
|
|
60701
|
+
methods: {},
|
|
60702
|
+
status: {
|
|
60703
|
+
schema: GroupStatusSchema,
|
|
60704
|
+
kind: "push"
|
|
60705
|
+
},
|
|
60706
|
+
runtimeState: GroupStatusSchema,
|
|
60707
|
+
/**
|
|
60708
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60709
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60710
|
+
*
|
|
60711
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60712
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60713
|
+
*/
|
|
60714
|
+
durability: "session",
|
|
60715
|
+
history: "none"
|
|
60716
|
+
};
|
|
60271
60717
|
var HeatingValveStatusSchema = object({
|
|
60272
60718
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60273
|
-
position: number().min(0).max(100).nullable(),
|
|
60719
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60274
60720
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
60275
60721
|
lastFetchedAt: number()
|
|
60276
60722
|
});
|
|
@@ -60313,9 +60759,9 @@ var HumidifierStatusSchema = object({
|
|
|
60313
60759
|
/** Whether the humidifier is currently on. */
|
|
60314
60760
|
on: boolean(),
|
|
60315
60761
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60316
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60762
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60317
60763
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60318
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60764
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60319
60765
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60320
60766
|
* device has no mode surface. */
|
|
60321
60767
|
mode: string().nullable(),
|
|
@@ -60325,9 +60771,9 @@ var HumidifierStatusSchema = object({
|
|
|
60325
60771
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60326
60772
|
action: string().nullable(),
|
|
60327
60773
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60328
|
-
minHumidity: number().nullable(),
|
|
60774
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60329
60775
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60330
|
-
maxHumidity: number().nullable(),
|
|
60776
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60331
60777
|
/** Ms epoch when the slice was last updated. */
|
|
60332
60778
|
lastChangedAt: number()
|
|
60333
60779
|
});
|
|
@@ -60397,22 +60843,13 @@ var humidifierCapability = {
|
|
|
60397
60843
|
* `sourceInfo`.
|
|
60398
60844
|
*/
|
|
60399
60845
|
var HumiditySensorStatusSchema = object({
|
|
60400
|
-
/** Current relative humidity, 0..100. */
|
|
60401
|
-
percent: number().min(0).max(100).meta({
|
|
60402
|
-
|
|
60846
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60847
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60848
|
+
precision: 0,
|
|
60403
60849
|
label: "Humidity"
|
|
60404
|
-
}),
|
|
60850
|
+
})),
|
|
60405
60851
|
/** Ms epoch when the slice was last updated. */
|
|
60406
|
-
lastFetchedAt: number()
|
|
60407
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60408
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60409
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60410
|
-
unit: string().optional(),
|
|
60411
|
-
/** Suggested decimal places for numeric display.
|
|
60412
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60413
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60414
|
-
* auto-formatting when absent. */
|
|
60415
|
-
precision: number().int().min(0).max(10).optional()
|
|
60852
|
+
lastFetchedAt: number()
|
|
60416
60853
|
});
|
|
60417
60854
|
var humiditySensorCapability = {
|
|
60418
60855
|
name: "humidity-sensor",
|
|
@@ -60443,12 +60880,7 @@ var humiditySensorCapability = {
|
|
|
60443
60880
|
} } },
|
|
60444
60881
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60445
60882
|
* whether persisting is worth a SQLite commit. */
|
|
60446
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60447
|
-
customize: {
|
|
60448
|
-
version: 1,
|
|
60449
|
-
advanced: "derive",
|
|
60450
|
-
targets: []
|
|
60451
|
-
}
|
|
60883
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60452
60884
|
};
|
|
60453
60885
|
/**
|
|
60454
60886
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -60469,7 +60901,7 @@ var ImageStatusSchema = object({
|
|
|
60469
60901
|
* entity exposes no `entity_picture` (yet). */
|
|
60470
60902
|
url: string().nullable(),
|
|
60471
60903
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
60472
|
-
lastUpdated: number().nullable()
|
|
60904
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
60473
60905
|
});
|
|
60474
60906
|
var imageCapability = {
|
|
60475
60907
|
name: "image",
|
|
@@ -60557,19 +60989,19 @@ var NormalizedRangeSchema = object({
|
|
|
60557
60989
|
*/
|
|
60558
60990
|
var ImageSettingsStatusSchema = object({
|
|
60559
60991
|
/** Normalized 0–100. */
|
|
60560
|
-
brightness: number().optional(),
|
|
60992
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60561
60993
|
/** Normalized 0–100. */
|
|
60562
|
-
contrast: number().optional(),
|
|
60994
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60563
60995
|
/** Normalized 0–100. */
|
|
60564
|
-
saturation: number().optional(),
|
|
60996
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60565
60997
|
/** Normalized 0–100. */
|
|
60566
|
-
sharpness: number().optional(),
|
|
60998
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60567
60999
|
mirror: boolean().optional(),
|
|
60568
61000
|
flip: boolean().optional(),
|
|
60569
61001
|
rotate: ImageRotateSchema.optional(),
|
|
60570
61002
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60571
61003
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60572
|
-
warmth: number().optional(),
|
|
61004
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60573
61005
|
exposureMode: ExposureModeSchema.optional(),
|
|
60574
61006
|
backlightMode: BacklightModeSchema.optional(),
|
|
60575
61007
|
lastFetchedAt: number()
|
|
@@ -60848,10 +61280,10 @@ var IntercomAbilitySchema = object({
|
|
|
60848
61280
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60849
61281
|
codecs: array(string()),
|
|
60850
61282
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60851
|
-
sampleRate: number(),
|
|
61283
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60852
61284
|
duplex: _enum(["half", "full"]),
|
|
60853
61285
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60854
|
-
maxBacklogMs: number()
|
|
61286
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60855
61287
|
});
|
|
60856
61288
|
var IntercomStatusSchema = object({
|
|
60857
61289
|
/** True while a talk session is open. */
|
|
@@ -61078,13 +61510,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61078
61510
|
activity: LawnMowerActivitySchema,
|
|
61079
61511
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
61080
61512
|
* reading. */
|
|
61081
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
61513
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61082
61514
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61083
61515
|
* task is active / progress is unavailable. */
|
|
61084
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61516
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61085
61517
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61086
61518
|
* or null when unknown. */
|
|
61087
|
-
currentCode: number().nullable(),
|
|
61519
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
61088
61520
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
61089
61521
|
currentCodeLabel: string().nullable(),
|
|
61090
61522
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61617,7 +62049,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61617
62049
|
state: MediaPlayerStateSchema,
|
|
61618
62050
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61619
62051
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61620
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
62052
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61621
62053
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61622
62054
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61623
62055
|
isMuted: boolean().nullable(),
|
|
@@ -61630,10 +62062,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61630
62062
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61631
62063
|
/** Current playback position in ms. Null when not seekable or
|
|
61632
62064
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61633
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
62065
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61634
62066
|
/** Total duration of the current media in ms. Null when unknown
|
|
61635
62067
|
* (live stream) or nothing is playing. */
|
|
61636
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
62068
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61637
62069
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61638
62070
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61639
62071
|
shuffle: boolean().nullable(),
|
|
@@ -61942,7 +62374,7 @@ var motionCustomize = {
|
|
|
61942
62374
|
eventName: "onMotionChanged"
|
|
61943
62375
|
},
|
|
61944
62376
|
deviceTypes: [DeviceType.Camera],
|
|
61945
|
-
apply: "
|
|
62377
|
+
apply: "add",
|
|
61946
62378
|
applyAuthority: {
|
|
61947
62379
|
kind: "camera-sensors",
|
|
61948
62380
|
timeoutField: "motionCooldownMs"
|
|
@@ -62014,7 +62446,7 @@ var MotionStatusSchema = object({
|
|
|
62014
62446
|
* it, every provider seeded it at boot, and every session left it
|
|
62015
62447
|
* `detected: true` after its detach.
|
|
62016
62448
|
*/
|
|
62017
|
-
autoClearAfterMs: number().nullable()
|
|
62449
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
62018
62450
|
});
|
|
62019
62451
|
/**
|
|
62020
62452
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -62051,12 +62483,18 @@ var motionCapability = {
|
|
|
62051
62483
|
methods: {
|
|
62052
62484
|
/**
|
|
62053
62485
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
62054
|
-
* for consumers that don't need the full status object
|
|
62055
|
-
*
|
|
62056
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
62057
|
-
* consumer.
|
|
62486
|
+
* for consumers that don't need the full status object. A composed
|
|
62487
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
62058
62488
|
*/
|
|
62059
62489
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62490
|
+
/**
|
|
62491
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62492
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62493
|
+
*/
|
|
62494
|
+
composedMethods: { isDetected: {
|
|
62495
|
+
kind: "slice",
|
|
62496
|
+
field: "detected"
|
|
62497
|
+
} },
|
|
62060
62498
|
events: {
|
|
62061
62499
|
/**
|
|
62062
62500
|
* Fires every time the runner transitions a camera between
|
|
@@ -62196,7 +62634,7 @@ var MotionZoneRegionSchema = object({
|
|
|
62196
62634
|
* the grid region(s). */
|
|
62197
62635
|
var MotionZoneStatusSchema = object({
|
|
62198
62636
|
enabled: boolean(),
|
|
62199
|
-
sensitivity: number(),
|
|
62637
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
62200
62638
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
62201
62639
|
regions: array(MotionZoneRegionSchema),
|
|
62202
62640
|
lastFetchedAt: number()
|
|
@@ -62566,7 +63004,7 @@ var NavigationStatusSchema = object({
|
|
|
62566
63004
|
following: boolean(),
|
|
62567
63005
|
flash: boolean(),
|
|
62568
63006
|
lightMode: NavigationLightModeSchema,
|
|
62569
|
-
lightLevel: number().min(40).max(100),
|
|
63007
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62570
63008
|
/** Ms epoch when the slice was last updated. */
|
|
62571
63009
|
lastChangedAt: number()
|
|
62572
63010
|
});
|
|
@@ -62700,13 +63138,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62700
63138
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62701
63139
|
* SKIP a null rather than coerce it.
|
|
62702
63140
|
*/
|
|
62703
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
63141
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62704
63142
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62705
|
-
rssiDbm: number().optional(),
|
|
63143
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62706
63144
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62707
63145
|
ssid: string().optional(),
|
|
62708
63146
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62709
|
-
lastUpdated: number()
|
|
63147
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62710
63148
|
});
|
|
62711
63149
|
var networkLinkCapability = {
|
|
62712
63150
|
name: "network-link",
|
|
@@ -63091,7 +63529,7 @@ var NotifierStatusSchema = object({
|
|
|
63091
63529
|
lastError: string().nullable(),
|
|
63092
63530
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
63093
63531
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
63094
|
-
queueDepth: number().int().nonnegative(),
|
|
63532
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
63095
63533
|
/** Per-feature capability matrix — authoritative source for the
|
|
63096
63534
|
* compose-form field gating. */
|
|
63097
63535
|
supports: NotifierSupportsSchema
|
|
@@ -63183,11 +63621,9 @@ onSent: { data: object({
|
|
|
63183
63621
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
63184
63622
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
63185
63623
|
*
|
|
63186
|
-
* The
|
|
63187
|
-
*
|
|
63188
|
-
*
|
|
63189
|
-
* The UI reads them directly from the slice — they are the single source
|
|
63190
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63624
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63625
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63626
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
63191
63627
|
*
|
|
63192
63628
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
63193
63629
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -63196,15 +63632,8 @@ onSent: { data: object({
|
|
|
63196
63632
|
* numeric values land here.
|
|
63197
63633
|
*/
|
|
63198
63634
|
var NumericSensorStatusSchema = object({
|
|
63199
|
-
|
|
63200
|
-
|
|
63201
|
-
* Populated live from the upstream source on each state push.
|
|
63202
|
-
* Absent for unitless sensors. */
|
|
63203
|
-
unit: string().optional(),
|
|
63204
|
-
/** Suggested decimal places for numeric display.
|
|
63205
|
-
* Populated live from the upstream source when provided.
|
|
63206
|
-
* Falls back to auto-formatting when absent. */
|
|
63207
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63635
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63636
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
63208
63637
|
/** Ms epoch when the slice was last updated. */
|
|
63209
63638
|
lastFetchedAt: number()
|
|
63210
63639
|
});
|
|
@@ -63228,11 +63657,11 @@ var numericSensorCapability = {
|
|
|
63228
63657
|
*/
|
|
63229
63658
|
durability: "restored",
|
|
63230
63659
|
/**
|
|
63231
|
-
* History (D850): recorded series. The unit is
|
|
63660
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63661
|
+
* resolved when the series is read — the cap has no single unit.
|
|
63232
63662
|
*/
|
|
63233
63663
|
history: { fields: { value: {
|
|
63234
63664
|
kind: "gauge",
|
|
63235
|
-
unitFrom: "unit",
|
|
63236
63665
|
minIntervalMs: 3e4
|
|
63237
63666
|
} } },
|
|
63238
63667
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63570,23 +63999,26 @@ var PetFeederStatusSchema = object({
|
|
|
63570
63999
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63571
64000
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63572
64001
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63573
|
-
foodLevel: number().nullable(),
|
|
64002
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63574
64003
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63575
64004
|
* single-hopper models. */
|
|
63576
|
-
food1: number().nullable(),
|
|
64005
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63577
64006
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63578
64007
|
* single-hopper models. */
|
|
63579
|
-
food2: number().nullable(),
|
|
64008
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63580
64009
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63581
64010
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63582
64011
|
* below the feeder's low threshold. */
|
|
63583
64012
|
lowFood: boolean(),
|
|
63584
64013
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63585
64014
|
* device has no battery reading. */
|
|
63586
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63587
|
-
/**
|
|
63588
|
-
*
|
|
63589
|
-
|
|
64015
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64016
|
+
/**
|
|
64017
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
64018
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
64019
|
+
* model has no desiccant sensor.
|
|
64020
|
+
*/
|
|
64021
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63590
64022
|
/** True while a feed is in progress. */
|
|
63591
64023
|
feeding: boolean(),
|
|
63592
64024
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63597,7 +64029,7 @@ var PetFeederStatusSchema = object({
|
|
|
63597
64029
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63598
64030
|
error: string().nullable(),
|
|
63599
64031
|
/** Raw device error code (0 / null = no error). */
|
|
63600
|
-
errorCode: number().nullable(),
|
|
64032
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63601
64033
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63602
64034
|
isDualHopper: boolean(),
|
|
63603
64035
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63607,7 +64039,7 @@ var PetFeederStatusSchema = object({
|
|
|
63607
64039
|
/** Play a chime when dispensing. */
|
|
63608
64040
|
feedSound: boolean(),
|
|
63609
64041
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63610
|
-
volume: number(),
|
|
64042
|
+
volume: number().meta(readingMeta("none")),
|
|
63611
64043
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63612
64044
|
lastFetchedAt: number()
|
|
63613
64045
|
});
|
|
@@ -63726,7 +64158,7 @@ var petFeederCapability = {
|
|
|
63726
64158
|
},
|
|
63727
64159
|
desiccantLeftDays: {
|
|
63728
64160
|
kind: "gauge",
|
|
63729
|
-
unit: "
|
|
64161
|
+
unit: "s"
|
|
63730
64162
|
}
|
|
63731
64163
|
} }
|
|
63732
64164
|
};
|
|
@@ -64127,36 +64559,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64127
64559
|
*/
|
|
64128
64560
|
var PowerMeterStatusSchema = object({
|
|
64129
64561
|
/** Instantaneous power draw in watts. */
|
|
64130
|
-
watts: number().optional().meta({
|
|
64131
|
-
unit: "W",
|
|
64132
|
-
label: "Power"
|
|
64133
|
-
}),
|
|
64562
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64134
64563
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64135
|
-
kwhTotal: number().optional().meta({
|
|
64136
|
-
unit: "kWh",
|
|
64137
|
-
label: "Energy"
|
|
64138
|
-
}),
|
|
64564
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64139
64565
|
/** Voltage in volts. */
|
|
64140
|
-
volts: number().optional(),
|
|
64566
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
64141
64567
|
/** Current in amperes. */
|
|
64142
|
-
amps: number().optional(),
|
|
64143
|
-
/** Apparent power in volt-amperes
|
|
64144
|
-
va: number().optional(),
|
|
64568
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
64569
|
+
/** Apparent power in volt-amperes. */
|
|
64570
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
64145
64571
|
/** Power factor (0..1) if reported. */
|
|
64146
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
64572
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64147
64573
|
/** Ms epoch when the slice was last updated. */
|
|
64148
|
-
lastFetchedAt: number()
|
|
64149
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
64150
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
64151
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
64152
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
64153
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
64154
|
-
unit: string().optional(),
|
|
64155
|
-
/** Suggested decimal places for numeric display.
|
|
64156
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64157
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64158
|
-
* auto-formatting when absent. */
|
|
64159
|
-
precision: number().int().min(0).max(10).optional()
|
|
64574
|
+
lastFetchedAt: number()
|
|
64160
64575
|
});
|
|
64161
64576
|
var powerMeterCapability = {
|
|
64162
64577
|
name: "power-meter",
|
|
@@ -64220,12 +64635,7 @@ var powerMeterCapability = {
|
|
|
64220
64635
|
} },
|
|
64221
64636
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64222
64637
|
* whether persisting is worth a SQLite commit. */
|
|
64223
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64224
|
-
customize: {
|
|
64225
|
-
version: 1,
|
|
64226
|
-
advanced: "derive",
|
|
64227
|
-
targets: []
|
|
64228
|
-
}
|
|
64638
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64229
64639
|
};
|
|
64230
64640
|
/**
|
|
64231
64641
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64245,11 +64655,11 @@ var powerMeterCapability = {
|
|
|
64245
64655
|
*/
|
|
64246
64656
|
var GpsLocationSchema = object({
|
|
64247
64657
|
/** Latitude in decimal degrees, -90..90. */
|
|
64248
|
-
latitude: number().min(-90).max(90),
|
|
64658
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
64249
64659
|
/** Longitude in decimal degrees, -180..180. */
|
|
64250
|
-
longitude: number().min(-180).max(180),
|
|
64660
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
64251
64661
|
/** Reported accuracy in meters (lower = better). */
|
|
64252
|
-
accuracyMeters: number().nonnegative()
|
|
64662
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
64253
64663
|
});
|
|
64254
64664
|
var PresenceStatusSchema = object({
|
|
64255
64665
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -64261,7 +64671,7 @@ var PresenceStatusSchema = object({
|
|
|
64261
64671
|
gps: GpsLocationSchema.nullable(),
|
|
64262
64672
|
/** Optional battery level of the tracking device (0..100). Null
|
|
64263
64673
|
* when not reported. */
|
|
64264
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64674
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64265
64675
|
/** Ms epoch when the slice was last updated. */
|
|
64266
64676
|
lastChangedAt: number()
|
|
64267
64677
|
});
|
|
@@ -64311,19 +64721,10 @@ var presenceCapability = {
|
|
|
64311
64721
|
* `sourceInfo`.
|
|
64312
64722
|
*/
|
|
64313
64723
|
var PressureSensorStatusSchema = object({
|
|
64314
|
-
/** Current pressure in hPa. */
|
|
64315
|
-
hpa: number(),
|
|
64724
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64725
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64316
64726
|
/** Ms epoch when the slice was last updated. */
|
|
64317
|
-
lastFetchedAt: number()
|
|
64318
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64319
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64320
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64321
|
-
unit: string().optional(),
|
|
64322
|
-
/** Suggested decimal places for numeric display.
|
|
64323
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64324
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64325
|
-
* auto-formatting when absent. */
|
|
64326
|
-
precision: number().int().min(0).max(10).optional()
|
|
64727
|
+
lastFetchedAt: number()
|
|
64327
64728
|
});
|
|
64328
64729
|
var pressureSensorCapability = {
|
|
64329
64730
|
name: "pressure-sensor",
|
|
@@ -64849,8 +65250,8 @@ var ptzCapability = {
|
|
|
64849
65250
|
};
|
|
64850
65251
|
var PtzAutotrackSettingsSchema = object({
|
|
64851
65252
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64852
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64853
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
65253
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
65254
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64854
65255
|
});
|
|
64855
65256
|
/**
|
|
64856
65257
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -65004,7 +65405,7 @@ var RunningStateStatusSchema = object({
|
|
|
65004
65405
|
/** null = unknown — never coerced to false (D393). */
|
|
65005
65406
|
running: boolean().nullable(),
|
|
65006
65407
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
65007
|
-
since: number().nullable(),
|
|
65408
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
65008
65409
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
65009
65410
|
phase: string().nullable(),
|
|
65010
65411
|
/** null until a reading has been published (D393). */
|
|
@@ -65019,7 +65420,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
65019
65420
|
/** Generic Customize target for the running boolean (D936). */
|
|
65020
65421
|
var runningCustomize = {
|
|
65021
65422
|
version: 1,
|
|
65022
|
-
advanced: "derive",
|
|
65023
65423
|
targets: [{
|
|
65024
65424
|
id: "running",
|
|
65025
65425
|
cardinality: "scalar",
|
|
@@ -65039,7 +65439,7 @@ var runningCustomize = {
|
|
|
65039
65439
|
DeviceType.Thermostat,
|
|
65040
65440
|
DeviceType.PetFeeder
|
|
65041
65441
|
],
|
|
65042
|
-
apply: "add
|
|
65442
|
+
apply: "add",
|
|
65043
65443
|
path: "running",
|
|
65044
65444
|
sources: [
|
|
65045
65445
|
{
|
|
@@ -65055,6 +65455,7 @@ var runningCustomize = {
|
|
|
65055
65455
|
requiredUnit: "W",
|
|
65056
65456
|
transforms: [{
|
|
65057
65457
|
kind: "threshold",
|
|
65458
|
+
comparisons: ["gte", "lte"],
|
|
65058
65459
|
comparison: "gte",
|
|
65059
65460
|
defaultThreshold: 5,
|
|
65060
65461
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -66306,9 +66707,9 @@ var RecordTriggerSchema = _enum([
|
|
|
66306
66707
|
*/
|
|
66307
66708
|
var RecordWindowSchema = object({
|
|
66308
66709
|
trigger: RecordTriggerSchema,
|
|
66309
|
-
day: number().int().min(0).max(6),
|
|
66310
|
-
startMinute: number().int().min(0).max(1439),
|
|
66311
|
-
endMinute: number().int().min(1).max(1440)
|
|
66710
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66711
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66712
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
66312
66713
|
});
|
|
66313
66714
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
66314
66715
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -66384,10 +66785,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
66384
66785
|
/** Master "record to the card at all" switch. */
|
|
66385
66786
|
enabled: boolean().nullable(),
|
|
66386
66787
|
overwriteWhenFull: boolean().nullable(),
|
|
66387
|
-
preRecordSec: number().nullable(),
|
|
66388
|
-
postRecordSec: number().nullable(),
|
|
66788
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66789
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66389
66790
|
/** Length of one recorded file, in minutes. */
|
|
66390
|
-
segmentMinutes: number().nullable(),
|
|
66791
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
66391
66792
|
/** The primary track's weekly windows, flattened. */
|
|
66392
66793
|
windows: array(RecordWindowSchema),
|
|
66393
66794
|
/**
|
|
@@ -66403,7 +66804,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
66403
66804
|
* provider reporting a non-zero count also reports the schedule as not
|
|
66404
66805
|
* writable.
|
|
66405
66806
|
*/
|
|
66406
|
-
unreadableWindows: number(),
|
|
66807
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
66407
66808
|
/**
|
|
66408
66809
|
* The camera is scheduled to record and has NO usable storage.
|
|
66409
66810
|
*
|
|
@@ -67350,7 +67751,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
67350
67751
|
url: string().optional(),
|
|
67351
67752
|
codec: string().optional(),
|
|
67352
67753
|
resolution: CamStreamResolutionSchema.optional(),
|
|
67353
|
-
fps: number().positive().optional(),
|
|
67754
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
67354
67755
|
label: string().optional(),
|
|
67355
67756
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
67356
67757
|
deviceFeatures: array(string()).optional(),
|
|
@@ -67437,18 +67838,18 @@ var StreamProfileSchema = _enum([
|
|
|
67437
67838
|
]);
|
|
67438
67839
|
/** The current encoding config of one stream profile. */
|
|
67439
67840
|
var StreamProfileConfigSchema = object({
|
|
67440
|
-
width: number(),
|
|
67441
|
-
height: number(),
|
|
67841
|
+
width: number().meta(readingMeta("none")),
|
|
67842
|
+
height: number().meta(readingMeta("none")),
|
|
67442
67843
|
codec: _enum(["h264", "h265"]),
|
|
67443
|
-
framerate: number(),
|
|
67444
|
-
bitrate: number(),
|
|
67844
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67845
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
67445
67846
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
67446
67847
|
encoderProfile: _enum([
|
|
67447
67848
|
"high",
|
|
67448
67849
|
"main",
|
|
67449
67850
|
"baseline"
|
|
67450
67851
|
]).optional(),
|
|
67451
|
-
gop: number().optional(),
|
|
67852
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
67452
67853
|
/**
|
|
67453
67854
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
67454
67855
|
*
|
|
@@ -67867,12 +68268,7 @@ var switchCapability = {
|
|
|
67867
68268
|
label: "On",
|
|
67868
68269
|
kind: "boolean"
|
|
67869
68270
|
}
|
|
67870
|
-
}] }
|
|
67871
|
-
customize: {
|
|
67872
|
-
version: 1,
|
|
67873
|
-
advanced: "derive",
|
|
67874
|
-
targets: []
|
|
67875
|
-
}
|
|
68271
|
+
}] }
|
|
67876
68272
|
};
|
|
67877
68273
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
67878
68274
|
function hasControlCharacter(value) {
|
|
@@ -68455,35 +68851,21 @@ var tamperCapability = {
|
|
|
68455
68851
|
* entries with `device_class: temperature` and any future native
|
|
68456
68852
|
* thermometer.
|
|
68457
68853
|
*
|
|
68458
|
-
*
|
|
68459
|
-
*
|
|
68460
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
68461
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
68462
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
68463
|
-
* `sourceInfo`.
|
|
68854
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
68855
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
68464
68856
|
*
|
|
68465
68857
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
68466
68858
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
68467
68859
|
* changed" steady state.
|
|
68468
68860
|
*/
|
|
68469
68861
|
var TemperatureSensorStatusSchema = object({
|
|
68470
|
-
/** Current temperature in Celsius. */
|
|
68471
|
-
celsius: number().meta({
|
|
68472
|
-
|
|
68862
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68863
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
68864
|
+
precision: 1,
|
|
68473
68865
|
label: "Temperature"
|
|
68474
|
-
}),
|
|
68866
|
+
})),
|
|
68475
68867
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
68476
|
-
lastFetchedAt: number()
|
|
68477
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
68478
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
68479
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
68480
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
68481
|
-
unit: string().optional(),
|
|
68482
|
-
/** Suggested decimal places for numeric display.
|
|
68483
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
68484
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
68485
|
-
* auto-formatting when absent. */
|
|
68486
|
-
precision: number().int().min(0).max(10).optional()
|
|
68868
|
+
lastFetchedAt: number()
|
|
68487
68869
|
});
|
|
68488
68870
|
var temperatureSensorCapability = {
|
|
68489
68871
|
name: "temperature-sensor",
|
|
@@ -68514,12 +68896,7 @@ var temperatureSensorCapability = {
|
|
|
68514
68896
|
} } },
|
|
68515
68897
|
/** Clock fields: written, but excluded from the compare that decides
|
|
68516
68898
|
* whether persisting is worth a SQLite commit. */
|
|
68517
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
68518
|
-
customize: {
|
|
68519
|
-
version: 1,
|
|
68520
|
-
advanced: "derive",
|
|
68521
|
-
targets: []
|
|
68522
|
-
}
|
|
68899
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
68523
68900
|
};
|
|
68524
68901
|
/**
|
|
68525
68902
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -68802,16 +69179,16 @@ var VacuumControlStatusSchema = object({
|
|
|
68802
69179
|
]),
|
|
68803
69180
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
68804
69181
|
* reading. */
|
|
68805
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
69182
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68806
69183
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
68807
69184
|
* the vacuum has no speed control. */
|
|
68808
69185
|
fanSpeed: string().nullable(),
|
|
68809
69186
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68810
69187
|
availableFanSpeeds: array(string()),
|
|
68811
69188
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68812
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
69189
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68813
69190
|
/** Current error code (0 / null = no error). */
|
|
68814
|
-
errorCode: number().nullable(),
|
|
69191
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68815
69192
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
68816
69193
|
errorLabel: string().nullable(),
|
|
68817
69194
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -68889,7 +69266,7 @@ var ValveStatusSchema = object({
|
|
|
68889
69266
|
]),
|
|
68890
69267
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
68891
69268
|
* intermediate position surface. */
|
|
68892
|
-
position: number().min(0).max(100).nullable(),
|
|
69269
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68893
69270
|
/** Ms epoch when the slice was last updated. */
|
|
68894
69271
|
lastChangedAt: number()
|
|
68895
69272
|
});
|
|
@@ -68997,9 +69374,9 @@ var vibrationCapability = {
|
|
|
68997
69374
|
*/
|
|
68998
69375
|
var WaterHeaterStatusSchema = object({
|
|
68999
69376
|
/** Current measured temperature. Null when not reported. */
|
|
69000
|
-
currentTemp: number().nullable(),
|
|
69377
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69001
69378
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
69002
|
-
targetTemp: number().nullable(),
|
|
69379
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69003
69380
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
69004
69381
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
69005
69382
|
* device reports an unknown state. */
|
|
@@ -69010,9 +69387,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
69010
69387
|
* has no away surface. */
|
|
69011
69388
|
away: boolean().nullable(),
|
|
69012
69389
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
69013
|
-
minTemp: number().nullable(),
|
|
69390
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69014
69391
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
69015
|
-
maxTemp: number().nullable(),
|
|
69392
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
69016
69393
|
/** Ms epoch when the slice was last updated. */
|
|
69017
69394
|
lastChangedAt: number()
|
|
69018
69395
|
});
|
|
@@ -69097,25 +69474,18 @@ var waterHeaterCapability = {
|
|
|
69097
69474
|
* Forecast deferred — current conditions only for v1.
|
|
69098
69475
|
*/
|
|
69099
69476
|
var WeatherStatusSchema = object({
|
|
69100
|
-
/** Verbatim
|
|
69101
|
-
* when no condition has been reported yet. */
|
|
69477
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
69102
69478
|
condition: string().nullable(),
|
|
69103
|
-
/** Current temperature in
|
|
69104
|
-
temperature: number().nullable(),
|
|
69105
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
69106
|
-
temperatureUnit: string().nullable(),
|
|
69479
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
69480
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
69107
69481
|
/** Relative humidity (0..100). Null when not provided. */
|
|
69108
|
-
humidity: number().min(0).max(100).nullable(),
|
|
69109
|
-
/** Barometric pressure in
|
|
69110
|
-
pressure: number().nullable(),
|
|
69111
|
-
/**
|
|
69112
|
-
|
|
69113
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
69114
|
-
windSpeed: number().nullable(),
|
|
69115
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
69116
|
-
windSpeedUnit: string().nullable(),
|
|
69482
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
69483
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
69484
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
69485
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
69486
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
69117
69487
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
69118
|
-
windBearing: number().nullable(),
|
|
69488
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
69119
69489
|
/** Ms epoch when the slice was last updated. */
|
|
69120
69490
|
lastFetchedAt: number()
|
|
69121
69491
|
});
|
|
@@ -69143,12 +69513,12 @@ var weatherCapability = {
|
|
|
69143
69513
|
*/
|
|
69144
69514
|
durability: "session",
|
|
69145
69515
|
/**
|
|
69146
|
-
* History (D850): recorded series.
|
|
69516
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
69147
69517
|
*/
|
|
69148
69518
|
history: { fields: {
|
|
69149
69519
|
temperature: {
|
|
69150
69520
|
kind: "gauge",
|
|
69151
|
-
|
|
69521
|
+
unit: "°C",
|
|
69152
69522
|
deadband: .2
|
|
69153
69523
|
},
|
|
69154
69524
|
humidity: {
|
|
@@ -69158,12 +69528,12 @@ var weatherCapability = {
|
|
|
69158
69528
|
},
|
|
69159
69529
|
pressure: {
|
|
69160
69530
|
kind: "gauge",
|
|
69161
|
-
|
|
69531
|
+
unit: "hPa",
|
|
69162
69532
|
deadband: .5
|
|
69163
69533
|
},
|
|
69164
69534
|
windSpeed: {
|
|
69165
69535
|
kind: "gauge",
|
|
69166
|
-
|
|
69536
|
+
unit: "m/s",
|
|
69167
69537
|
deadband: .5
|
|
69168
69538
|
}
|
|
69169
69539
|
} }
|
|
@@ -70527,6 +70897,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70527
70897
|
featureProbe: featureProbeCapability,
|
|
70528
70898
|
flood: floodCapability,
|
|
70529
70899
|
gas: gasCapability,
|
|
70900
|
+
groupCommands: groupCommandsCapability,
|
|
70901
|
+
groupStatus: groupStatusCapability,
|
|
70530
70902
|
heatingValve: heatingValveCapability,
|
|
70531
70903
|
humidifier: humidifierCapability,
|
|
70532
70904
|
humiditySensor: humiditySensorCapability,
|
|
@@ -71907,6 +72279,13 @@ Object.freeze({
|
|
|
71907
72279
|
access: "view",
|
|
71908
72280
|
role: "admin"
|
|
71909
72281
|
},
|
|
72282
|
+
"addons.getPackageDocs": {
|
|
72283
|
+
capName: "addons",
|
|
72284
|
+
capScope: "system",
|
|
72285
|
+
addonId: null,
|
|
72286
|
+
access: "view",
|
|
72287
|
+
role: "admin"
|
|
72288
|
+
},
|
|
71910
72289
|
"addons.getVersions": {
|
|
71911
72290
|
capName: "addons",
|
|
71912
72291
|
capScope: "system",
|
|
@@ -75015,6 +75394,20 @@ Object.freeze({
|
|
|
75015
75394
|
access: "view",
|
|
75016
75395
|
role: "viewer"
|
|
75017
75396
|
},
|
|
75397
|
+
"groupCommands.getStatus": {
|
|
75398
|
+
capName: "group-commands",
|
|
75399
|
+
capScope: "device",
|
|
75400
|
+
addonId: null,
|
|
75401
|
+
access: "view",
|
|
75402
|
+
role: "viewer"
|
|
75403
|
+
},
|
|
75404
|
+
"groupStatus.getStatus": {
|
|
75405
|
+
capName: "group-status",
|
|
75406
|
+
capScope: "device",
|
|
75407
|
+
addonId: null,
|
|
75408
|
+
access: "view",
|
|
75409
|
+
role: "viewer"
|
|
75410
|
+
},
|
|
75018
75411
|
"heatingValve.getStatus": {
|
|
75019
75412
|
capName: "heating-valve",
|
|
75020
75413
|
capScope: "device",
|
|
@@ -84837,6 +85230,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84837
85230
|
icon: "flame"
|
|
84838
85231
|
}]
|
|
84839
85232
|
},
|
|
85233
|
+
"group-commands": {
|
|
85234
|
+
scope: "device",
|
|
85235
|
+
noun: t("Group command", "Comando di gruppo")
|
|
85236
|
+
},
|
|
85237
|
+
"group-status": {
|
|
85238
|
+
scope: "device",
|
|
85239
|
+
noun: t("Group", "Gruppo"),
|
|
85240
|
+
state: [
|
|
85241
|
+
{
|
|
85242
|
+
kind: "numeric",
|
|
85243
|
+
field: "included",
|
|
85244
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
85245
|
+
label: t("Reporting", "Rispondono"),
|
|
85246
|
+
icon: "users"
|
|
85247
|
+
},
|
|
85248
|
+
{
|
|
85249
|
+
kind: "numeric",
|
|
85250
|
+
field: "excluded",
|
|
85251
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
85252
|
+
label: t("Excluded", "Esclusi"),
|
|
85253
|
+
icon: "users"
|
|
85254
|
+
},
|
|
85255
|
+
{
|
|
85256
|
+
kind: "numeric",
|
|
85257
|
+
field: "total",
|
|
85258
|
+
quantity: t("the member count", "il numero di membri"),
|
|
85259
|
+
label: t("Members", "Membri"),
|
|
85260
|
+
icon: "sigma"
|
|
85261
|
+
}
|
|
85262
|
+
]
|
|
85263
|
+
},
|
|
84840
85264
|
"humidity-sensor": {
|
|
84841
85265
|
scope: "device",
|
|
84842
85266
|
noun: t("Humidity", "Umidità"),
|
|
@@ -84870,7 +85294,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84870
85294
|
field: "value",
|
|
84871
85295
|
quantity: t("the reading", "il valore"),
|
|
84872
85296
|
label: t("Reading", "Valore"),
|
|
84873
|
-
unitField: "unit",
|
|
84874
85297
|
icon: "gauge"
|
|
84875
85298
|
}]
|
|
84876
85299
|
},
|
|
@@ -85006,7 +85429,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85006
85429
|
field: "temperature",
|
|
85007
85430
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
85008
85431
|
label: t("Temperature", "Temperatura"),
|
|
85009
|
-
|
|
85432
|
+
unit: "°C",
|
|
85010
85433
|
icon: "thermometer"
|
|
85011
85434
|
},
|
|
85012
85435
|
{
|
|
@@ -85022,7 +85445,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85022
85445
|
field: "windSpeed",
|
|
85023
85446
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
85024
85447
|
label: t("Wind", "Vento"),
|
|
85025
|
-
|
|
85448
|
+
unit: "m/s",
|
|
85026
85449
|
icon: "wind"
|
|
85027
85450
|
},
|
|
85028
85451
|
{
|
|
@@ -85030,7 +85453,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85030
85453
|
field: "pressure",
|
|
85031
85454
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
85032
85455
|
label: t("Pressure", "Pressione"),
|
|
85033
|
-
|
|
85456
|
+
unit: "hPa",
|
|
85034
85457
|
icon: "gauge"
|
|
85035
85458
|
}
|
|
85036
85459
|
]
|
|
@@ -86509,6 +86932,16 @@ Object.freeze({
|
|
|
86509
86932
|
form: "single",
|
|
86510
86933
|
optional: false
|
|
86511
86934
|
}],
|
|
86935
|
+
"groupCommands.getStatus": [{
|
|
86936
|
+
name: "deviceId",
|
|
86937
|
+
form: "single",
|
|
86938
|
+
optional: false
|
|
86939
|
+
}],
|
|
86940
|
+
"groupStatus.getStatus": [{
|
|
86941
|
+
name: "deviceId",
|
|
86942
|
+
form: "single",
|
|
86943
|
+
optional: false
|
|
86944
|
+
}],
|
|
86512
86945
|
"heatingValve.getStatus": [{
|
|
86513
86946
|
name: "deviceId",
|
|
86514
86947
|
form: "single",
|
|
@@ -88373,6 +88806,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
88373
88806
|
targetId: string().min(1),
|
|
88374
88807
|
enabled: boolean(),
|
|
88375
88808
|
debounceMs: number().nonnegative(),
|
|
88809
|
+
edges: array(_enum([
|
|
88810
|
+
"rising",
|
|
88811
|
+
"button",
|
|
88812
|
+
"native-event"
|
|
88813
|
+
])).min(1).optional(),
|
|
88376
88814
|
sources: array(OverrideSourceSchema).min(1)
|
|
88377
88815
|
});
|
|
88378
88816
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -88488,6 +88926,8 @@ new Map(Object.entries({
|
|
|
88488
88926
|
"detection-blind": "device-events",
|
|
88489
88927
|
"motion-noisy": "device-events",
|
|
88490
88928
|
"motion-calm": "device-events",
|
|
88929
|
+
"package-llm-silent": "device-events",
|
|
88930
|
+
"package-llm-answered": "device-events",
|
|
88491
88931
|
"recording-stalled": "device-events",
|
|
88492
88932
|
"recording-healthy": "device-events",
|
|
88493
88933
|
"recording-degraded": "device-events",
|
|
@@ -88571,6 +89011,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
88571
89011
|
label: "Motion without a subject",
|
|
88572
89012
|
kinds: ["motion-noisy", "motion-calm"]
|
|
88573
89013
|
},
|
|
89014
|
+
{
|
|
89015
|
+
id: "package-llm",
|
|
89016
|
+
family: "device-events",
|
|
89017
|
+
label: "Package confirm",
|
|
89018
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
89019
|
+
},
|
|
88574
89020
|
{
|
|
88575
89021
|
id: "recording",
|
|
88576
89022
|
family: "device-events",
|
|
@@ -88752,6 +89198,8 @@ var DEVICE_EVENTS = [
|
|
|
88752
89198
|
"detection-blind",
|
|
88753
89199
|
"motion-noisy",
|
|
88754
89200
|
"motion-calm",
|
|
89201
|
+
"package-llm-silent",
|
|
89202
|
+
"package-llm-answered",
|
|
88755
89203
|
"recording-stalled",
|
|
88756
89204
|
"recording-healthy",
|
|
88757
89205
|
"recording-degraded",
|
|
@@ -89020,6 +89468,15 @@ new Map([
|
|
|
89020
89468
|
snapshotLabel: "Cameras with constant motion now",
|
|
89021
89469
|
snapshotSection: null
|
|
89022
89470
|
},
|
|
89471
|
+
{
|
|
89472
|
+
id: "package-llm-confirm",
|
|
89473
|
+
family: "device-events",
|
|
89474
|
+
label: "Package confirm (not answering / answering again)",
|
|
89475
|
+
bad: ["package-llm-silent"],
|
|
89476
|
+
recovery: ["package-llm-answered"],
|
|
89477
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
89478
|
+
snapshotSection: null
|
|
89479
|
+
},
|
|
89023
89480
|
{
|
|
89024
89481
|
id: "recording-health",
|
|
89025
89482
|
family: "device-events",
|