@camstack/addon-terminal 0.1.152 → 0.1.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +19 -0
- package/dist/addon.js +966 -509
- package/dist/addon.mjs +966 -509
- package/package.json +10 -3
package/dist/addon.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { createServer } from "node:http";
|
|
|
8
8
|
//#region \0rolldown/runtime.js
|
|
9
9
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
10
10
|
//#endregion
|
|
11
|
-
//#region ../types/dist/event-category-
|
|
11
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
12
12
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
13
13
|
EventCategory["SystemBoot"] = "system.boot";
|
|
14
14
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -334,6 +334,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
334
334
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
335
335
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
336
336
|
/**
|
|
337
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
338
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
339
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
340
|
+
*/
|
|
341
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
342
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
343
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
344
|
+
/**
|
|
337
345
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
338
346
|
* (a settings change via `setAgentInferenceDevices` /
|
|
339
347
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5443,7 +5451,7 @@ var ZodIssueCode = {
|
|
|
5443
5451
|
var ZodFirstPartyTypeKind;
|
|
5444
5452
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5445
5453
|
//#endregion
|
|
5446
|
-
//#region ../types/dist/sleep-
|
|
5454
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5447
5455
|
/**
|
|
5448
5456
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5449
5457
|
* window to float samples (D455).
|
|
@@ -7997,6 +8005,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
7997
8005
|
}).strict();
|
|
7998
8006
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
7999
8007
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8008
|
+
var READING_QUANTITIES = [
|
|
8009
|
+
"temperature",
|
|
8010
|
+
"pressure",
|
|
8011
|
+
"speed",
|
|
8012
|
+
"precipitation",
|
|
8013
|
+
"precipitation-rate",
|
|
8014
|
+
"length",
|
|
8015
|
+
"area",
|
|
8016
|
+
"illuminance",
|
|
8017
|
+
"irradiance",
|
|
8018
|
+
"power",
|
|
8019
|
+
"energy",
|
|
8020
|
+
"voltage",
|
|
8021
|
+
"current",
|
|
8022
|
+
"apparent-power",
|
|
8023
|
+
"humidity",
|
|
8024
|
+
"percentage",
|
|
8025
|
+
"concentration-volume",
|
|
8026
|
+
"concentration-mass",
|
|
8027
|
+
"concentration-ppb",
|
|
8028
|
+
"volume",
|
|
8029
|
+
"duration",
|
|
8030
|
+
"duration-ms",
|
|
8031
|
+
"information",
|
|
8032
|
+
"sound-level",
|
|
8033
|
+
"signal-level",
|
|
8034
|
+
"colour-temperature",
|
|
8035
|
+
"angle",
|
|
8036
|
+
"bitrate",
|
|
8037
|
+
"rate",
|
|
8038
|
+
"mass",
|
|
8039
|
+
"index",
|
|
8040
|
+
"ratio",
|
|
8041
|
+
"count",
|
|
8042
|
+
"none",
|
|
8043
|
+
"device"
|
|
8044
|
+
];
|
|
8045
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8046
|
+
new Set(READING_QUANTITIES);
|
|
8047
|
+
/**
|
|
8048
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8049
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8050
|
+
*/
|
|
8051
|
+
var QUANTITY_BASE = {
|
|
8052
|
+
temperature: "°C",
|
|
8053
|
+
pressure: "hPa",
|
|
8054
|
+
speed: "m/s",
|
|
8055
|
+
precipitation: "mm",
|
|
8056
|
+
"precipitation-rate": "mm/h",
|
|
8057
|
+
length: "m",
|
|
8058
|
+
area: "m²",
|
|
8059
|
+
illuminance: "lx",
|
|
8060
|
+
irradiance: "W/m²",
|
|
8061
|
+
power: "W",
|
|
8062
|
+
energy: "kWh",
|
|
8063
|
+
voltage: "V",
|
|
8064
|
+
current: "A",
|
|
8065
|
+
"apparent-power": "VA",
|
|
8066
|
+
humidity: "%",
|
|
8067
|
+
percentage: "%",
|
|
8068
|
+
"concentration-volume": "ppm",
|
|
8069
|
+
"concentration-mass": "µg/m³",
|
|
8070
|
+
"concentration-ppb": "ppb",
|
|
8071
|
+
volume: "L",
|
|
8072
|
+
duration: "s",
|
|
8073
|
+
"duration-ms": "ms",
|
|
8074
|
+
information: "B",
|
|
8075
|
+
"sound-level": "dBFS",
|
|
8076
|
+
"signal-level": "dBm",
|
|
8077
|
+
"colour-temperature": "mired",
|
|
8078
|
+
angle: "°",
|
|
8079
|
+
bitrate: "kbps",
|
|
8080
|
+
rate: "fps",
|
|
8081
|
+
mass: "kg",
|
|
8082
|
+
index: "none",
|
|
8083
|
+
ratio: "none",
|
|
8084
|
+
count: "none",
|
|
8085
|
+
none: "none",
|
|
8086
|
+
device: "device"
|
|
8087
|
+
};
|
|
8088
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8089
|
+
function baseUnitOf(quantity) {
|
|
8090
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8091
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8092
|
+
return symbol;
|
|
8093
|
+
}
|
|
8094
|
+
function readingMeta(quantity, extras) {
|
|
8095
|
+
return {
|
|
8096
|
+
quantity,
|
|
8097
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8098
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8099
|
+
};
|
|
8100
|
+
}
|
|
8000
8101
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8001
8102
|
var CamProfileSchema = _enum([
|
|
8002
8103
|
"high",
|
|
@@ -8024,8 +8125,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8024
8125
|
"derived"
|
|
8025
8126
|
]);
|
|
8026
8127
|
var CamStreamResolutionSchema = object({
|
|
8027
|
-
width: number().int().positive(),
|
|
8028
|
-
height: number().int().positive()
|
|
8128
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8129
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8029
8130
|
});
|
|
8030
8131
|
var CameraStreamSchema = object({
|
|
8031
8132
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8602,6 +8703,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8602
8703
|
"filesystem-browse",
|
|
8603
8704
|
"flood",
|
|
8604
8705
|
"gas",
|
|
8706
|
+
"group-commands",
|
|
8707
|
+
"group-status",
|
|
8605
8708
|
"heating-valve",
|
|
8606
8709
|
"humidifier",
|
|
8607
8710
|
"humidity-sensor",
|
|
@@ -8731,14 +8834,6 @@ Object.freeze({
|
|
|
8731
8834
|
{
|
|
8732
8835
|
"path": "aqi",
|
|
8733
8836
|
"valueType": "number"
|
|
8734
|
-
},
|
|
8735
|
-
{
|
|
8736
|
-
"path": "unit",
|
|
8737
|
-
"valueType": "string"
|
|
8738
|
-
},
|
|
8739
|
-
{
|
|
8740
|
-
"path": "precision",
|
|
8741
|
-
"valueType": "number"
|
|
8742
8837
|
}
|
|
8743
8838
|
],
|
|
8744
8839
|
"alarm-panel": [
|
|
@@ -8774,20 +8869,10 @@ Object.freeze({
|
|
|
8774
8869
|
"valueType": "boolean"
|
|
8775
8870
|
}
|
|
8776
8871
|
],
|
|
8777
|
-
"ambient-light-sensor": [
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
},
|
|
8782
|
-
{
|
|
8783
|
-
"path": "unit",
|
|
8784
|
-
"valueType": "string"
|
|
8785
|
-
},
|
|
8786
|
-
{
|
|
8787
|
-
"path": "precision",
|
|
8788
|
-
"valueType": "number"
|
|
8789
|
-
}
|
|
8790
|
-
],
|
|
8872
|
+
"ambient-light-sensor": [{
|
|
8873
|
+
"path": "lux",
|
|
8874
|
+
"valueType": "number"
|
|
8875
|
+
}],
|
|
8791
8876
|
"audio-metrics": [
|
|
8792
8877
|
{
|
|
8793
8878
|
"path": "ts",
|
|
@@ -8867,6 +8952,10 @@ Object.freeze({
|
|
|
8867
8952
|
"path": "lastUpdated",
|
|
8868
8953
|
"valueType": "number"
|
|
8869
8954
|
},
|
|
8955
|
+
{
|
|
8956
|
+
"path": "volts",
|
|
8957
|
+
"valueType": "number"
|
|
8958
|
+
},
|
|
8870
8959
|
{
|
|
8871
8960
|
"path": "lastContactAt",
|
|
8872
8961
|
"valueType": "number"
|
|
@@ -9109,10 +9198,6 @@ Object.freeze({
|
|
|
9109
9198
|
"datetime"
|
|
9110
9199
|
]
|
|
9111
9200
|
},
|
|
9112
|
-
{
|
|
9113
|
-
"path": "unit",
|
|
9114
|
-
"valueType": "string"
|
|
9115
|
-
},
|
|
9116
9201
|
{
|
|
9117
9202
|
"path": "min",
|
|
9118
9203
|
"valueType": "number"
|
|
@@ -9124,19 +9209,6 @@ Object.freeze({
|
|
|
9124
9209
|
{
|
|
9125
9210
|
"path": "step",
|
|
9126
9211
|
"valueType": "number"
|
|
9127
|
-
},
|
|
9128
|
-
{
|
|
9129
|
-
"path": "precision",
|
|
9130
|
-
"valueType": "number"
|
|
9131
|
-
},
|
|
9132
|
-
{
|
|
9133
|
-
"path": "format",
|
|
9134
|
-
"valueType": "enum",
|
|
9135
|
-
"enumValues": [
|
|
9136
|
-
"date",
|
|
9137
|
-
"time",
|
|
9138
|
-
"datetime"
|
|
9139
|
-
]
|
|
9140
9212
|
}
|
|
9141
9213
|
],
|
|
9142
9214
|
"cover": [
|
|
@@ -9377,13 +9449,8 @@ Object.freeze({
|
|
|
9377
9449
|
"path": "value",
|
|
9378
9450
|
"valueType": "string"
|
|
9379
9451
|
}, {
|
|
9380
|
-
"path": "
|
|
9381
|
-
"valueType": "
|
|
9382
|
-
"enumValues": [
|
|
9383
|
-
"date",
|
|
9384
|
-
"time",
|
|
9385
|
-
"datetime"
|
|
9386
|
-
]
|
|
9452
|
+
"path": "timestamp",
|
|
9453
|
+
"valueType": "boolean"
|
|
9387
9454
|
}],
|
|
9388
9455
|
"event-emitter": [
|
|
9389
9456
|
{
|
|
@@ -9456,6 +9523,20 @@ Object.freeze({
|
|
|
9456
9523
|
"path": "detected",
|
|
9457
9524
|
"valueType": "boolean"
|
|
9458
9525
|
}],
|
|
9526
|
+
"group-status": [
|
|
9527
|
+
{
|
|
9528
|
+
"path": "included",
|
|
9529
|
+
"valueType": "number"
|
|
9530
|
+
},
|
|
9531
|
+
{
|
|
9532
|
+
"path": "excluded",
|
|
9533
|
+
"valueType": "number"
|
|
9534
|
+
},
|
|
9535
|
+
{
|
|
9536
|
+
"path": "total",
|
|
9537
|
+
"valueType": "number"
|
|
9538
|
+
}
|
|
9539
|
+
],
|
|
9459
9540
|
"heating-valve": [{
|
|
9460
9541
|
"path": "position",
|
|
9461
9542
|
"valueType": "number"
|
|
@@ -9490,20 +9571,10 @@ Object.freeze({
|
|
|
9490
9571
|
"valueType": "number"
|
|
9491
9572
|
}
|
|
9492
9573
|
],
|
|
9493
|
-
"humidity-sensor": [
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
},
|
|
9498
|
-
{
|
|
9499
|
-
"path": "unit",
|
|
9500
|
-
"valueType": "string"
|
|
9501
|
-
},
|
|
9502
|
-
{
|
|
9503
|
-
"path": "precision",
|
|
9504
|
-
"valueType": "number"
|
|
9505
|
-
}
|
|
9506
|
-
],
|
|
9574
|
+
"humidity-sensor": [{
|
|
9575
|
+
"path": "percent",
|
|
9576
|
+
"valueType": "number"
|
|
9577
|
+
}],
|
|
9507
9578
|
"image": [{
|
|
9508
9579
|
"path": "url",
|
|
9509
9580
|
"valueType": "string"
|
|
@@ -9842,20 +9913,10 @@ Object.freeze({
|
|
|
9842
9913
|
"valueType": "boolean"
|
|
9843
9914
|
}
|
|
9844
9915
|
],
|
|
9845
|
-
"numeric-sensor": [
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
},
|
|
9850
|
-
{
|
|
9851
|
-
"path": "unit",
|
|
9852
|
-
"valueType": "string"
|
|
9853
|
-
},
|
|
9854
|
-
{
|
|
9855
|
-
"path": "precision",
|
|
9856
|
-
"valueType": "number"
|
|
9857
|
-
}
|
|
9858
|
-
],
|
|
9916
|
+
"numeric-sensor": [{
|
|
9917
|
+
"path": "value",
|
|
9918
|
+
"valueType": "number"
|
|
9919
|
+
}],
|
|
9859
9920
|
"pet-feeder": [
|
|
9860
9921
|
{
|
|
9861
9922
|
"path": "foodLevel",
|
|
@@ -9947,14 +10008,6 @@ Object.freeze({
|
|
|
9947
10008
|
{
|
|
9948
10009
|
"path": "powerFactor",
|
|
9949
10010
|
"valueType": "number"
|
|
9950
|
-
},
|
|
9951
|
-
{
|
|
9952
|
-
"path": "unit",
|
|
9953
|
-
"valueType": "string"
|
|
9954
|
-
},
|
|
9955
|
-
{
|
|
9956
|
-
"path": "precision",
|
|
9957
|
-
"valueType": "number"
|
|
9958
10011
|
}
|
|
9959
10012
|
],
|
|
9960
10013
|
"presence": [
|
|
@@ -9983,20 +10036,10 @@ Object.freeze({
|
|
|
9983
10036
|
"valueType": "number"
|
|
9984
10037
|
}
|
|
9985
10038
|
],
|
|
9986
|
-
"pressure-sensor": [
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
},
|
|
9991
|
-
{
|
|
9992
|
-
"path": "unit",
|
|
9993
|
-
"valueType": "string"
|
|
9994
|
-
},
|
|
9995
|
-
{
|
|
9996
|
-
"path": "precision",
|
|
9997
|
-
"valueType": "number"
|
|
9998
|
-
}
|
|
9999
|
-
],
|
|
10039
|
+
"pressure-sensor": [{
|
|
10040
|
+
"path": "hpa",
|
|
10041
|
+
"valueType": "number"
|
|
10042
|
+
}],
|
|
10000
10043
|
"privacy-mask": [{
|
|
10001
10044
|
"path": "enabled",
|
|
10002
10045
|
"valueType": "boolean"
|
|
@@ -10307,20 +10350,10 @@ Object.freeze({
|
|
|
10307
10350
|
"path": "tampered",
|
|
10308
10351
|
"valueType": "boolean"
|
|
10309
10352
|
}],
|
|
10310
|
-
"temperature-sensor": [
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
},
|
|
10315
|
-
{
|
|
10316
|
-
"path": "unit",
|
|
10317
|
-
"valueType": "string"
|
|
10318
|
-
},
|
|
10319
|
-
{
|
|
10320
|
-
"path": "precision",
|
|
10321
|
-
"valueType": "number"
|
|
10322
|
-
}
|
|
10323
|
-
],
|
|
10353
|
+
"temperature-sensor": [{
|
|
10354
|
+
"path": "celsius",
|
|
10355
|
+
"valueType": "number"
|
|
10356
|
+
}],
|
|
10324
10357
|
"update": [
|
|
10325
10358
|
{
|
|
10326
10359
|
"path": "currentVersion",
|
|
@@ -10431,10 +10464,6 @@ Object.freeze({
|
|
|
10431
10464
|
"path": "temperature",
|
|
10432
10465
|
"valueType": "number"
|
|
10433
10466
|
},
|
|
10434
|
-
{
|
|
10435
|
-
"path": "temperatureUnit",
|
|
10436
|
-
"valueType": "string"
|
|
10437
|
-
},
|
|
10438
10467
|
{
|
|
10439
10468
|
"path": "humidity",
|
|
10440
10469
|
"valueType": "number"
|
|
@@ -10443,18 +10472,10 @@ Object.freeze({
|
|
|
10443
10472
|
"path": "pressure",
|
|
10444
10473
|
"valueType": "number"
|
|
10445
10474
|
},
|
|
10446
|
-
{
|
|
10447
|
-
"path": "pressureUnit",
|
|
10448
|
-
"valueType": "string"
|
|
10449
|
-
},
|
|
10450
10475
|
{
|
|
10451
10476
|
"path": "windSpeed",
|
|
10452
10477
|
"valueType": "number"
|
|
10453
10478
|
},
|
|
10454
|
-
{
|
|
10455
|
-
"path": "windSpeedUnit",
|
|
10456
|
-
"valueType": "string"
|
|
10457
|
-
},
|
|
10458
10479
|
{
|
|
10459
10480
|
"path": "windBearing",
|
|
10460
10481
|
"valueType": "number"
|
|
@@ -10857,7 +10878,7 @@ function errMsg(err) {
|
|
|
10857
10878
|
return String(err);
|
|
10858
10879
|
}
|
|
10859
10880
|
//#endregion
|
|
10860
|
-
//#region ../types/dist/composition-
|
|
10881
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10861
10882
|
/**
|
|
10862
10883
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10863
10884
|
*
|
|
@@ -11612,15 +11633,74 @@ function validateExpressionSource(src) {
|
|
|
11612
11633
|
}
|
|
11613
11634
|
return null;
|
|
11614
11635
|
}
|
|
11615
|
-
/**
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11636
|
+
/**
|
|
11637
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11638
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11639
|
+
* `composition.ts` (D659).
|
|
11640
|
+
*/
|
|
11619
11641
|
var CompositionSourceRefSchema = object({
|
|
11620
11642
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11621
11643
|
addonId: string().min(1),
|
|
11622
11644
|
stableId: string().min(1)
|
|
11623
11645
|
});
|
|
11646
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11647
|
+
"temperature",
|
|
11648
|
+
"humidity",
|
|
11649
|
+
"pressure",
|
|
11650
|
+
"illuminance",
|
|
11651
|
+
"power",
|
|
11652
|
+
"energy",
|
|
11653
|
+
"battery",
|
|
11654
|
+
"numeric",
|
|
11655
|
+
"motion",
|
|
11656
|
+
"contact",
|
|
11657
|
+
"leak",
|
|
11658
|
+
"smoke",
|
|
11659
|
+
"occupancy",
|
|
11660
|
+
"binary",
|
|
11661
|
+
"switch",
|
|
11662
|
+
"light"
|
|
11663
|
+
];
|
|
11664
|
+
var NUMERIC_AGGREGATES = [
|
|
11665
|
+
"mean",
|
|
11666
|
+
"median",
|
|
11667
|
+
"min",
|
|
11668
|
+
"max",
|
|
11669
|
+
"sum"
|
|
11670
|
+
];
|
|
11671
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11672
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11673
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11674
|
+
var AGGREGATE_REDUCERS = [
|
|
11675
|
+
"mean",
|
|
11676
|
+
"median",
|
|
11677
|
+
"min",
|
|
11678
|
+
"max",
|
|
11679
|
+
"sum",
|
|
11680
|
+
"any",
|
|
11681
|
+
"all"
|
|
11682
|
+
];
|
|
11683
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11684
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11685
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11686
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11687
|
+
var HelperMemberSchema = object({
|
|
11688
|
+
source: CompositionSourceRefSchema,
|
|
11689
|
+
cap: string().min(1),
|
|
11690
|
+
fieldPath: string().min(1)
|
|
11691
|
+
});
|
|
11692
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11693
|
+
kind: literal("group"),
|
|
11694
|
+
templateId: GroupTemplateIdSchema,
|
|
11695
|
+
aggregate: AggregateReducerSchema,
|
|
11696
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11697
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11698
|
+
active: ActiveCriterionSchema.optional()
|
|
11699
|
+
})]);
|
|
11700
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11701
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11702
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11703
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11624
11704
|
/** One field of one capability of one source device. */
|
|
11625
11705
|
var CompositionFieldReadSchema = object({
|
|
11626
11706
|
source: CompositionSourceRefSchema,
|
|
@@ -11664,7 +11744,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11664
11744
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11665
11745
|
CompositionFromSourceSchema,
|
|
11666
11746
|
CompositionExpressionSourceSchema,
|
|
11667
|
-
CompositionCodeSourceSchema
|
|
11747
|
+
CompositionCodeSourceSchema,
|
|
11748
|
+
object({
|
|
11749
|
+
kind: literal("aggregate"),
|
|
11750
|
+
reducer: _enum([
|
|
11751
|
+
"mean",
|
|
11752
|
+
"median",
|
|
11753
|
+
"min",
|
|
11754
|
+
"max",
|
|
11755
|
+
"sum",
|
|
11756
|
+
"any",
|
|
11757
|
+
"all"
|
|
11758
|
+
]),
|
|
11759
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11760
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11761
|
+
publish: _enum([
|
|
11762
|
+
"value",
|
|
11763
|
+
"included",
|
|
11764
|
+
"excluded",
|
|
11765
|
+
"total"
|
|
11766
|
+
]),
|
|
11767
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11768
|
+
empty: _enum([
|
|
11769
|
+
"null",
|
|
11770
|
+
"omit",
|
|
11771
|
+
"offline"
|
|
11772
|
+
])
|
|
11773
|
+
})
|
|
11668
11774
|
]);
|
|
11669
11775
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11670
11776
|
kind: literal("forward"),
|
|
@@ -11710,7 +11816,13 @@ var CompositionSchema = object({
|
|
|
11710
11816
|
kind: literal("existing"),
|
|
11711
11817
|
device: CompositionSourceRefSchema
|
|
11712
11818
|
})]),
|
|
11713
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11819
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11820
|
+
/**
|
|
11821
|
+
* Present when the block is a helper template. Absent on a free
|
|
11822
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11823
|
+
* never the compiled features.
|
|
11824
|
+
*/
|
|
11825
|
+
helper: HelperSpecSchema.optional()
|
|
11714
11826
|
}).superRefine((composition, ctx) => {
|
|
11715
11827
|
const seen = /* @__PURE__ */ new Set();
|
|
11716
11828
|
composition.features.forEach((feature, index) => {
|
|
@@ -17950,7 +18062,11 @@ var CompositionProblemSchema = object({
|
|
|
17950
18062
|
"item-field-reserved",
|
|
17951
18063
|
"target-missing",
|
|
17952
18064
|
"target-unreadable",
|
|
17953
|
-
"not-replaceable"
|
|
18065
|
+
"not-replaceable",
|
|
18066
|
+
"native-capability-replace",
|
|
18067
|
+
"mixed-quantity",
|
|
18068
|
+
"helper-mismatch",
|
|
18069
|
+
"member-constraint"
|
|
17954
18070
|
]),
|
|
17955
18071
|
path: string(),
|
|
17956
18072
|
message: string()
|
|
@@ -17971,7 +18087,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17971
18087
|
"null",
|
|
17972
18088
|
"offline",
|
|
17973
18089
|
"unknown",
|
|
17974
|
-
"release"
|
|
18090
|
+
"release",
|
|
18091
|
+
"omit"
|
|
17975
18092
|
]);
|
|
17976
18093
|
/**
|
|
17977
18094
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18008,9 +18125,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18008
18125
|
reads: array(CompositionFieldReadSchema)
|
|
18009
18126
|
});
|
|
18010
18127
|
/**
|
|
18011
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18012
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18013
|
-
*
|
|
18128
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18129
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18130
|
+
* Replacing a capability the device already serves is refused
|
|
18131
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18132
|
+
* wire for a claim the hub already holds.
|
|
18014
18133
|
*/
|
|
18015
18134
|
var CompositionFeatureModeSchema = _enum([
|
|
18016
18135
|
"new",
|
|
@@ -18183,6 +18302,275 @@ Object.freeze({
|
|
|
18183
18302
|
result: ["number", "null"]
|
|
18184
18303
|
}
|
|
18185
18304
|
});
|
|
18305
|
+
/**
|
|
18306
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18307
|
+
* Data, not a form default written into the block.
|
|
18308
|
+
*/
|
|
18309
|
+
var NOW = {
|
|
18310
|
+
fieldPath: "lastFetchedAt",
|
|
18311
|
+
expr: "now"
|
|
18312
|
+
};
|
|
18313
|
+
var CHANGED = {
|
|
18314
|
+
fieldPath: "lastChangedAt",
|
|
18315
|
+
expr: "now"
|
|
18316
|
+
};
|
|
18317
|
+
function numeric(input) {
|
|
18318
|
+
return {
|
|
18319
|
+
...input,
|
|
18320
|
+
family: "numeric",
|
|
18321
|
+
deviceType: DeviceType.Sensor,
|
|
18322
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18323
|
+
commandCaps: [],
|
|
18324
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18325
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18326
|
+
accept: [{
|
|
18327
|
+
cap: input.outputCap,
|
|
18328
|
+
fieldPath: input.outputField
|
|
18329
|
+
}]
|
|
18330
|
+
};
|
|
18331
|
+
}
|
|
18332
|
+
function binary(input) {
|
|
18333
|
+
return {
|
|
18334
|
+
...input,
|
|
18335
|
+
family: "binary",
|
|
18336
|
+
deviceType: DeviceType.Sensor,
|
|
18337
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18338
|
+
commandCaps: [],
|
|
18339
|
+
quantity: "none",
|
|
18340
|
+
baseUnit: void 0,
|
|
18341
|
+
aggregates: BINARY_AGGREGATES,
|
|
18342
|
+
empty: "offline"
|
|
18343
|
+
};
|
|
18344
|
+
}
|
|
18345
|
+
var GROUP_TEMPLATES = [
|
|
18346
|
+
numeric({
|
|
18347
|
+
id: "temperature",
|
|
18348
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18349
|
+
role: DeviceRole.TemperatureSensor,
|
|
18350
|
+
outputCap: "temperature-sensor",
|
|
18351
|
+
outputField: "celsius",
|
|
18352
|
+
quantity: "temperature",
|
|
18353
|
+
defaultAggregate: "mean",
|
|
18354
|
+
empty: "null",
|
|
18355
|
+
companions: [NOW]
|
|
18356
|
+
}),
|
|
18357
|
+
numeric({
|
|
18358
|
+
id: "humidity",
|
|
18359
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18360
|
+
role: DeviceRole.HumiditySensor,
|
|
18361
|
+
outputCap: "humidity-sensor",
|
|
18362
|
+
outputField: "percent",
|
|
18363
|
+
quantity: "humidity",
|
|
18364
|
+
defaultAggregate: "mean",
|
|
18365
|
+
empty: "null",
|
|
18366
|
+
companions: [NOW]
|
|
18367
|
+
}),
|
|
18368
|
+
numeric({
|
|
18369
|
+
id: "pressure",
|
|
18370
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18371
|
+
role: DeviceRole.PressureSensor,
|
|
18372
|
+
outputCap: "pressure-sensor",
|
|
18373
|
+
outputField: "hpa",
|
|
18374
|
+
quantity: "pressure",
|
|
18375
|
+
defaultAggregate: "mean",
|
|
18376
|
+
empty: "null",
|
|
18377
|
+
companions: [NOW]
|
|
18378
|
+
}),
|
|
18379
|
+
numeric({
|
|
18380
|
+
id: "illuminance",
|
|
18381
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18382
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18383
|
+
outputCap: "ambient-light-sensor",
|
|
18384
|
+
outputField: "lux",
|
|
18385
|
+
quantity: "illuminance",
|
|
18386
|
+
defaultAggregate: "mean",
|
|
18387
|
+
empty: "null",
|
|
18388
|
+
companions: [NOW]
|
|
18389
|
+
}),
|
|
18390
|
+
numeric({
|
|
18391
|
+
id: "power",
|
|
18392
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18393
|
+
role: DeviceRole.PowerSensor,
|
|
18394
|
+
outputCap: "power-meter",
|
|
18395
|
+
outputField: "watts",
|
|
18396
|
+
quantity: "power",
|
|
18397
|
+
defaultAggregate: "sum",
|
|
18398
|
+
empty: "omit",
|
|
18399
|
+
companions: [NOW]
|
|
18400
|
+
}),
|
|
18401
|
+
numeric({
|
|
18402
|
+
id: "energy",
|
|
18403
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18404
|
+
role: DeviceRole.EnergySensor,
|
|
18405
|
+
outputCap: "power-meter",
|
|
18406
|
+
outputField: "kwhTotal",
|
|
18407
|
+
quantity: "energy",
|
|
18408
|
+
defaultAggregate: "sum",
|
|
18409
|
+
empty: "omit",
|
|
18410
|
+
companions: [NOW]
|
|
18411
|
+
}),
|
|
18412
|
+
numeric({
|
|
18413
|
+
id: "battery",
|
|
18414
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18415
|
+
role: DeviceRole.BatterySensor,
|
|
18416
|
+
outputCap: "battery",
|
|
18417
|
+
outputField: "percentage",
|
|
18418
|
+
quantity: "percentage",
|
|
18419
|
+
defaultAggregate: "mean",
|
|
18420
|
+
empty: "null",
|
|
18421
|
+
companions: [
|
|
18422
|
+
{
|
|
18423
|
+
fieldPath: "charging",
|
|
18424
|
+
expr: "\"unknown\""
|
|
18425
|
+
},
|
|
18426
|
+
{
|
|
18427
|
+
fieldPath: "sleeping",
|
|
18428
|
+
expr: "false"
|
|
18429
|
+
},
|
|
18430
|
+
{
|
|
18431
|
+
fieldPath: "lastUpdated",
|
|
18432
|
+
expr: "now"
|
|
18433
|
+
}
|
|
18434
|
+
]
|
|
18435
|
+
}),
|
|
18436
|
+
numeric({
|
|
18437
|
+
id: "numeric",
|
|
18438
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18439
|
+
role: DeviceRole.NumericSensor,
|
|
18440
|
+
outputCap: "numeric-sensor",
|
|
18441
|
+
outputField: "value",
|
|
18442
|
+
quantity: "device",
|
|
18443
|
+
defaultAggregate: "mean",
|
|
18444
|
+
empty: "null",
|
|
18445
|
+
companions: [NOW]
|
|
18446
|
+
}),
|
|
18447
|
+
binary({
|
|
18448
|
+
id: "motion",
|
|
18449
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18450
|
+
role: DeviceRole.MotionSensor,
|
|
18451
|
+
outputCap: "motion",
|
|
18452
|
+
outputField: "detected",
|
|
18453
|
+
defaultAggregate: "any",
|
|
18454
|
+
accept: [{
|
|
18455
|
+
cap: "motion",
|
|
18456
|
+
fieldPath: "detected"
|
|
18457
|
+
}],
|
|
18458
|
+
companions: [{
|
|
18459
|
+
fieldPath: "lastDetectedAt",
|
|
18460
|
+
expr: "null"
|
|
18461
|
+
}, {
|
|
18462
|
+
fieldPath: "autoClearAfterMs",
|
|
18463
|
+
expr: "null"
|
|
18464
|
+
}]
|
|
18465
|
+
}),
|
|
18466
|
+
binary({
|
|
18467
|
+
id: "contact",
|
|
18468
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18469
|
+
role: DeviceRole.ContactSensor,
|
|
18470
|
+
outputCap: "contact",
|
|
18471
|
+
outputField: "entryOpen",
|
|
18472
|
+
defaultAggregate: "any",
|
|
18473
|
+
accept: [{
|
|
18474
|
+
cap: "contact",
|
|
18475
|
+
fieldPath: "entryOpen"
|
|
18476
|
+
}],
|
|
18477
|
+
companions: [CHANGED]
|
|
18478
|
+
}),
|
|
18479
|
+
binary({
|
|
18480
|
+
id: "leak",
|
|
18481
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18482
|
+
role: DeviceRole.LeakSensor,
|
|
18483
|
+
outputCap: "flood",
|
|
18484
|
+
outputField: "flooded",
|
|
18485
|
+
defaultAggregate: "any",
|
|
18486
|
+
accept: [{
|
|
18487
|
+
cap: "flood",
|
|
18488
|
+
fieldPath: "flooded"
|
|
18489
|
+
}],
|
|
18490
|
+
companions: [CHANGED]
|
|
18491
|
+
}),
|
|
18492
|
+
binary({
|
|
18493
|
+
id: "smoke",
|
|
18494
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18495
|
+
role: DeviceRole.SmokeSensor,
|
|
18496
|
+
outputCap: "smoke",
|
|
18497
|
+
outputField: "detected",
|
|
18498
|
+
defaultAggregate: "any",
|
|
18499
|
+
accept: [{
|
|
18500
|
+
cap: "smoke",
|
|
18501
|
+
fieldPath: "detected"
|
|
18502
|
+
}],
|
|
18503
|
+
companions: [CHANGED]
|
|
18504
|
+
}),
|
|
18505
|
+
binary({
|
|
18506
|
+
id: "occupancy",
|
|
18507
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18508
|
+
role: DeviceRole.BinarySensor,
|
|
18509
|
+
outputCap: "binary",
|
|
18510
|
+
outputField: "on",
|
|
18511
|
+
defaultAggregate: "any",
|
|
18512
|
+
accept: [{
|
|
18513
|
+
cap: "motion",
|
|
18514
|
+
fieldPath: "detected"
|
|
18515
|
+
}, {
|
|
18516
|
+
cap: "binary",
|
|
18517
|
+
fieldPath: "on"
|
|
18518
|
+
}],
|
|
18519
|
+
companions: [CHANGED]
|
|
18520
|
+
}),
|
|
18521
|
+
binary({
|
|
18522
|
+
id: "binary",
|
|
18523
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18524
|
+
role: DeviceRole.BinarySensor,
|
|
18525
|
+
outputCap: "binary",
|
|
18526
|
+
outputField: "on",
|
|
18527
|
+
defaultAggregate: "any",
|
|
18528
|
+
accept: [{
|
|
18529
|
+
cap: "binary",
|
|
18530
|
+
fieldPath: "on"
|
|
18531
|
+
}],
|
|
18532
|
+
companions: [CHANGED]
|
|
18533
|
+
}),
|
|
18534
|
+
actuator({
|
|
18535
|
+
id: "switch",
|
|
18536
|
+
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.",
|
|
18537
|
+
deviceType: DeviceType.Switch,
|
|
18538
|
+
outputCap: "switch",
|
|
18539
|
+
commandCaps: ["switch"]
|
|
18540
|
+
}),
|
|
18541
|
+
actuator({
|
|
18542
|
+
id: "light",
|
|
18543
|
+
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.",
|
|
18544
|
+
deviceType: DeviceType.Light,
|
|
18545
|
+
outputCap: "switch",
|
|
18546
|
+
commandCaps: [
|
|
18547
|
+
"switch",
|
|
18548
|
+
"brightness",
|
|
18549
|
+
"color"
|
|
18550
|
+
]
|
|
18551
|
+
})
|
|
18552
|
+
];
|
|
18553
|
+
function actuator(input) {
|
|
18554
|
+
return {
|
|
18555
|
+
...input,
|
|
18556
|
+
family: "actuator",
|
|
18557
|
+
role: void 0,
|
|
18558
|
+
memberDeviceType: input.deviceType,
|
|
18559
|
+
outputField: "on",
|
|
18560
|
+
quantity: "none",
|
|
18561
|
+
baseUnit: void 0,
|
|
18562
|
+
aggregates: BINARY_AGGREGATES,
|
|
18563
|
+
defaultAggregate: "any",
|
|
18564
|
+
empty: "offline",
|
|
18565
|
+
accept: [{
|
|
18566
|
+
cap: "switch",
|
|
18567
|
+
fieldPath: "on"
|
|
18568
|
+
}],
|
|
18569
|
+
companions: [CHANGED]
|
|
18570
|
+
};
|
|
18571
|
+
}
|
|
18572
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18573
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18186
18574
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18187
18575
|
/**
|
|
18188
18576
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -19896,12 +20284,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
19896
20284
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19897
20285
|
* in-place so dispatch keeps working.
|
|
19898
20286
|
*
|
|
19899
|
-
* **
|
|
19900
|
-
*
|
|
19901
|
-
*
|
|
19902
|
-
*
|
|
19903
|
-
* (`ha-domain-mapping`)
|
|
19904
|
-
* stored after that point.
|
|
20287
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20288
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20289
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20290
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20291
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20292
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19905
20293
|
*
|
|
19906
20294
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19907
20295
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19915,6 +20303,14 @@ var SourceInfoSchema = object({
|
|
|
19915
20303
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19916
20304
|
* Used to detect rename when `id` changes. */
|
|
19917
20305
|
uniqueId: string().optional(),
|
|
20306
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20307
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20308
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20309
|
+
dateTimeShape: _enum([
|
|
20310
|
+
"date",
|
|
20311
|
+
"time",
|
|
20312
|
+
"datetime"
|
|
20313
|
+
]).optional(),
|
|
19918
20314
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19919
20315
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19920
20316
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40938,7 +41334,8 @@ method(object({
|
|
|
40938
41334
|
"enum"
|
|
40939
41335
|
]),
|
|
40940
41336
|
enumValues: array(string()).optional(),
|
|
40941
|
-
item: boolean().optional()
|
|
41337
|
+
item: boolean().optional(),
|
|
41338
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40942
41339
|
})).readonly(),
|
|
40943
41340
|
itemArray: object({
|
|
40944
41341
|
path: string(),
|
|
@@ -44782,8 +45179,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44782
45179
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44783
45180
|
var MaskGridShapeSchema = object({
|
|
44784
45181
|
kind: literal("grid"),
|
|
44785
|
-
gridWidth: number(),
|
|
44786
|
-
gridHeight: number(),
|
|
45182
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45183
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44787
45184
|
cells: array(boolean())
|
|
44788
45185
|
});
|
|
44789
45186
|
discriminatedUnion("kind", [
|
|
@@ -44895,6 +45292,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
44895
45292
|
"detection-blind",
|
|
44896
45293
|
"motion-noisy",
|
|
44897
45294
|
"motion-calm",
|
|
45295
|
+
"package-llm-silent",
|
|
45296
|
+
"package-llm-answered",
|
|
44898
45297
|
"recording-stalled",
|
|
44899
45298
|
"recording-healthy",
|
|
44900
45299
|
"recording-degraded",
|
|
@@ -56134,6 +56533,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56134
56533
|
deprecated: string().optional(),
|
|
56135
56534
|
distTags: array(string()).readonly()
|
|
56136
56535
|
});
|
|
56536
|
+
/**
|
|
56537
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56538
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56539
|
+
* tarball failure — never an empty string standing in for either.
|
|
56540
|
+
*/
|
|
56541
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56542
|
+
object({
|
|
56543
|
+
status: literal("ok"),
|
|
56544
|
+
markdown: string()
|
|
56545
|
+
}),
|
|
56546
|
+
object({ status: literal("missing") }),
|
|
56547
|
+
object({
|
|
56548
|
+
status: literal("error"),
|
|
56549
|
+
message: string()
|
|
56550
|
+
})
|
|
56551
|
+
]);
|
|
56552
|
+
var PackageDocsSchema = object({
|
|
56553
|
+
name: string(),
|
|
56554
|
+
version: string(),
|
|
56555
|
+
readme: PackageDocBodySchema,
|
|
56556
|
+
changelog: PackageDocBodySchema
|
|
56557
|
+
});
|
|
56137
56558
|
var SearchResultSchema = object({
|
|
56138
56559
|
name: string(),
|
|
56139
56560
|
version: string(),
|
|
@@ -56352,7 +56773,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56352
56773
|
}), object({ success: literal(true) }), {
|
|
56353
56774
|
kind: "mutation",
|
|
56354
56775
|
auth: "admin"
|
|
56355
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56776
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56777
|
+
name: string().min(1),
|
|
56778
|
+
version: string().min(1).optional()
|
|
56779
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56356
56780
|
kind: "mutation",
|
|
56357
56781
|
auth: "admin"
|
|
56358
56782
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56411,27 +56835,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56411
56835
|
*/
|
|
56412
56836
|
var AirQualitySensorStatusSchema = object({
|
|
56413
56837
|
/** Carbon dioxide concentration in ppm. */
|
|
56414
|
-
co2Ppm: number().min(0).optional(),
|
|
56838
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56415
56839
|
/** Total volatile organic compounds in ppb. */
|
|
56416
|
-
vocPpb: number().min(0).optional(),
|
|
56840
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56417
56841
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56418
|
-
pm25: number().min(0).optional(),
|
|
56842
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56419
56843
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56420
|
-
pm10: number().min(0).optional(),
|
|
56844
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56421
56845
|
/** Composite AQI value (typically 0..500). */
|
|
56422
|
-
aqi: number().optional(),
|
|
56846
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56423
56847
|
/** Ms epoch when the slice was last updated. */
|
|
56424
|
-
lastFetchedAt: number()
|
|
56425
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56426
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56427
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56428
|
-
* per slice is unambiguous. */
|
|
56429
|
-
unit: string().optional(),
|
|
56430
|
-
/** Suggested decimal places for numeric display.
|
|
56431
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56432
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56433
|
-
* auto-formatting when absent. */
|
|
56434
|
-
precision: number().int().min(0).max(10).optional()
|
|
56848
|
+
lastFetchedAt: number()
|
|
56435
56849
|
});
|
|
56436
56850
|
var airQualitySensorCapability = {
|
|
56437
56851
|
name: "air-quality-sensor",
|
|
@@ -56468,12 +56882,12 @@ var airQualitySensorCapability = {
|
|
|
56468
56882
|
},
|
|
56469
56883
|
pm25: {
|
|
56470
56884
|
kind: "gauge",
|
|
56471
|
-
unit: "
|
|
56885
|
+
unit: "µg/m³",
|
|
56472
56886
|
deadband: 1
|
|
56473
56887
|
},
|
|
56474
56888
|
pm10: {
|
|
56475
56889
|
kind: "gauge",
|
|
56476
|
-
unit: "
|
|
56890
|
+
unit: "µg/m³",
|
|
56477
56891
|
deadband: 1
|
|
56478
56892
|
},
|
|
56479
56893
|
aqi: {
|
|
@@ -56491,22 +56905,13 @@ var airQualitySensorCapability = {
|
|
|
56491
56905
|
* entries with `device_class: illuminance`.
|
|
56492
56906
|
*/
|
|
56493
56907
|
var AmbientLightSensorStatusSchema = object({
|
|
56494
|
-
/** Current illuminance in lux (lx). */
|
|
56495
|
-
lux: number().min(0).meta({
|
|
56496
|
-
|
|
56908
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56909
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56910
|
+
precision: 0,
|
|
56497
56911
|
label: "Illuminance"
|
|
56498
|
-
}),
|
|
56912
|
+
})),
|
|
56499
56913
|
/** Ms epoch when the slice was last updated. */
|
|
56500
|
-
lastFetchedAt: number()
|
|
56501
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56502
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56503
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56504
|
-
unit: string().optional(),
|
|
56505
|
-
/** Suggested decimal places for numeric display.
|
|
56506
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56507
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56508
|
-
* auto-formatting when absent. */
|
|
56509
|
-
precision: number().int().min(0).max(10).optional()
|
|
56914
|
+
lastFetchedAt: number()
|
|
56510
56915
|
});
|
|
56511
56916
|
var ambientLightSensorCapability = {
|
|
56512
56917
|
name: "ambient-light-sensor",
|
|
@@ -56538,12 +56943,7 @@ var ambientLightSensorCapability = {
|
|
|
56538
56943
|
} } },
|
|
56539
56944
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56540
56945
|
* whether persisting is worth a SQLite commit. */
|
|
56541
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56542
|
-
customize: {
|
|
56543
|
-
version: 1,
|
|
56544
|
-
advanced: "derive",
|
|
56545
|
-
targets: []
|
|
56546
|
-
}
|
|
56946
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56547
56947
|
};
|
|
56548
56948
|
/**
|
|
56549
56949
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -56770,10 +57170,7 @@ var BatteryStatusSchema = object({
|
|
|
56770
57170
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56771
57171
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56772
57172
|
*/
|
|
56773
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56774
|
-
unit: "%",
|
|
56775
|
-
label: "Charge"
|
|
56776
|
-
}),
|
|
57173
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56777
57174
|
/**
|
|
56778
57175
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56779
57176
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56800,7 +57197,14 @@ var BatteryStatusSchema = object({
|
|
|
56800
57197
|
*/
|
|
56801
57198
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56802
57199
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56803
|
-
lastUpdated: number(),
|
|
57200
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57201
|
+
/**
|
|
57202
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57203
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57204
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57205
|
+
* `numeric-sensor` on the same device.
|
|
57206
|
+
*/
|
|
57207
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56804
57208
|
/**
|
|
56805
57209
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56806
57210
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56852,7 +57256,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
56852
57256
|
/** Generic Customize target for the percentage reading (D936). */
|
|
56853
57257
|
var batteryCustomize = {
|
|
56854
57258
|
version: 1,
|
|
56855
|
-
advanced: "derive",
|
|
56856
57259
|
targets: [{
|
|
56857
57260
|
id: "percentage",
|
|
56858
57261
|
cardinality: "scalar",
|
|
@@ -56861,7 +57264,7 @@ var batteryCustomize = {
|
|
|
56861
57264
|
stateField: "percentage"
|
|
56862
57265
|
},
|
|
56863
57266
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
56864
|
-
apply: "add
|
|
57267
|
+
apply: "add",
|
|
56865
57268
|
path: "percentage",
|
|
56866
57269
|
sources: [{
|
|
56867
57270
|
kind: "field",
|
|
@@ -56982,10 +57385,16 @@ onStatusChanged: { data: object({
|
|
|
56982
57385
|
/**
|
|
56983
57386
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
56984
57387
|
*/
|
|
56985
|
-
history: { fields: {
|
|
56986
|
-
|
|
56987
|
-
|
|
56988
|
-
|
|
57388
|
+
history: { fields: {
|
|
57389
|
+
percentage: {
|
|
57390
|
+
kind: "gauge",
|
|
57391
|
+
unit: "%"
|
|
57392
|
+
},
|
|
57393
|
+
volts: {
|
|
57394
|
+
kind: "gauge",
|
|
57395
|
+
unit: "V"
|
|
57396
|
+
}
|
|
57397
|
+
} },
|
|
56989
57398
|
customize: batteryCustomize,
|
|
56990
57399
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56991
57400
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57032,12 +57441,7 @@ var binaryCapability = {
|
|
|
57032
57441
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57033
57442
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57034
57443
|
* whether persisting is worth a SQLite commit. */
|
|
57035
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57036
|
-
customize: {
|
|
57037
|
-
version: 1,
|
|
57038
|
-
advanced: "derive",
|
|
57039
|
-
targets: []
|
|
57040
|
-
}
|
|
57444
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57041
57445
|
};
|
|
57042
57446
|
/**
|
|
57043
57447
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57053,7 +57457,7 @@ var binaryCapability = {
|
|
|
57053
57457
|
*/
|
|
57054
57458
|
var BrightnessStatusSchema = object({
|
|
57055
57459
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57056
|
-
percentage: number().min(0).max(100),
|
|
57460
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57057
57461
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57058
57462
|
lastChangedAt: number()
|
|
57059
57463
|
});
|
|
@@ -57507,21 +57911,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57507
57911
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57508
57912
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57509
57913
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57510
|
-
target: number().nullable(),
|
|
57914
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57511
57915
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57512
57916
|
* in `heat_cool` mode. */
|
|
57513
|
-
targetHigh: number().nullable(),
|
|
57917
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57514
57918
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57515
57919
|
* in `heat_cool` mode. */
|
|
57516
|
-
targetLow: number().nullable(),
|
|
57920
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57517
57921
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57518
57922
|
* humidity control. */
|
|
57519
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57923
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57520
57924
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57521
57925
|
* the device's internal sensor. */
|
|
57522
|
-
currentTemp: number().nullable(),
|
|
57926
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57523
57927
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57524
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57928
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57525
57929
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57526
57930
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57527
57931
|
swingVertical: boolean().nullable(),
|
|
@@ -57529,11 +57933,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57529
57933
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57530
57934
|
swingHorizontal: boolean().nullable(),
|
|
57531
57935
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57532
|
-
minTemp: number().nullable().optional(),
|
|
57936
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57533
57937
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57534
|
-
maxTemp: number().nullable().optional(),
|
|
57938
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57535
57939
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57536
|
-
tempStep: number().positive().nullable().optional(),
|
|
57940
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57537
57941
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57538
57942
|
lastFetchedAt: number()
|
|
57539
57943
|
});
|
|
@@ -57675,17 +58079,17 @@ var climateControlCapability = {
|
|
|
57675
58079
|
* modes to expose in the picker without a slice fetch.
|
|
57676
58080
|
*/
|
|
57677
58081
|
var RgbTripletSchema = object({
|
|
57678
|
-
r: number().int().min(0).max(255),
|
|
57679
|
-
g: number().int().min(0).max(255),
|
|
57680
|
-
b: number().int().min(0).max(255)
|
|
58082
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58083
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58084
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57681
58085
|
});
|
|
57682
58086
|
var HsvTripletSchema = object({
|
|
57683
58087
|
/** Hue in degrees, 0..360. */
|
|
57684
|
-
h: number().min(0).max(360),
|
|
58088
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57685
58089
|
/** Saturation as 0..100 inclusive. */
|
|
57686
|
-
s: number().min(0).max(100),
|
|
58090
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57687
58091
|
/** Value/brightness as 0..100 inclusive. */
|
|
57688
|
-
v: number().min(0).max(100)
|
|
58092
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57689
58093
|
});
|
|
57690
58094
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57691
58095
|
object({
|
|
@@ -57714,7 +58118,7 @@ var ColorStatusSchema = object({
|
|
|
57714
58118
|
/** Populated when `mode === 'hsv'`. */
|
|
57715
58119
|
hsv: HsvTripletSchema.optional(),
|
|
57716
58120
|
/** Populated when `mode === 'mired'`. */
|
|
57717
|
-
mireds: number().int().optional(),
|
|
58121
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57718
58122
|
/** Ms epoch of the last operator-driven change. */
|
|
57719
58123
|
lastChangedAt: number()
|
|
57720
58124
|
});
|
|
@@ -57909,18 +58313,12 @@ _enum([
|
|
|
57909
58313
|
"empty",
|
|
57910
58314
|
"full"
|
|
57911
58315
|
]);
|
|
57912
|
-
/**
|
|
57913
|
-
|
|
57914
|
-
|
|
57915
|
-
"days",
|
|
57916
|
-
"hours",
|
|
57917
|
-
"cycles"
|
|
57918
|
-
]);
|
|
57919
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57920
|
-
* days). `value` null = unknown (D393). */
|
|
58316
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58317
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58318
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57921
58319
|
var ConsumableRemainingSchema = object({
|
|
57922
|
-
value: number().min(0).nullable(),
|
|
57923
|
-
|
|
58320
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58321
|
+
kind: ConsumableRemainingKindSchema
|
|
57924
58322
|
});
|
|
57925
58323
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
57926
58324
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -57933,7 +58331,7 @@ var ConsumableItemSchema = object({
|
|
|
57933
58331
|
/** Display name. */
|
|
57934
58332
|
label: string().min(1),
|
|
57935
58333
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57936
|
-
level: number().min(0).max(100).nullable(),
|
|
58334
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57937
58335
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57938
58336
|
status: ConsumableStatusSchema.nullable(),
|
|
57939
58337
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58015,8 +58413,8 @@ var consumablesCustomize = {
|
|
|
58015
58413
|
transforms: [{ kind: "identity" }]
|
|
58016
58414
|
}],
|
|
58017
58415
|
literals: [{
|
|
58018
|
-
path: "remaining.
|
|
58019
|
-
values: [...
|
|
58416
|
+
path: "remaining.kind",
|
|
58417
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58020
58418
|
}]
|
|
58021
58419
|
},
|
|
58022
58420
|
{
|
|
@@ -58145,7 +58543,6 @@ reset: method(object({
|
|
|
58145
58543
|
},
|
|
58146
58544
|
"remaining.value": {
|
|
58147
58545
|
kind: "gauge",
|
|
58148
|
-
unitFrom: "remaining.unit",
|
|
58149
58546
|
deadband: 1,
|
|
58150
58547
|
displayName: "Remaining"
|
|
58151
58548
|
}
|
|
@@ -58215,10 +58612,9 @@ var contactCapability = {
|
|
|
58215
58612
|
* (empty array for the other kinds). It lives in the slice because
|
|
58216
58613
|
* HA `select.*` entities may update their options at runtime.
|
|
58217
58614
|
*
|
|
58218
|
-
*
|
|
58219
|
-
*
|
|
58220
|
-
*
|
|
58221
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58615
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58616
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58617
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58222
58618
|
*/
|
|
58223
58619
|
var ControlStatusSchema = object({
|
|
58224
58620
|
kind: _enum([
|
|
@@ -58230,39 +58626,17 @@ var ControlStatusSchema = object({
|
|
|
58230
58626
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58231
58627
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58232
58628
|
* or time-only — HA accepts all three forms). */
|
|
58233
|
-
value: union([number(), string()]),
|
|
58629
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58234
58630
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58235
58631
|
options: array(string()),
|
|
58236
58632
|
/** Ms epoch when the slice was last updated. */
|
|
58237
58633
|
lastChangedAt: number(),
|
|
58238
|
-
/**
|
|
58239
|
-
|
|
58240
|
-
|
|
58241
|
-
|
|
58242
|
-
/**
|
|
58243
|
-
|
|
58244
|
-
min: number().optional(),
|
|
58245
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58246
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58247
|
-
max: number().optional(),
|
|
58248
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58249
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58250
|
-
step: number().optional(),
|
|
58251
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58252
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58253
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58254
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58255
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58256
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58257
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58258
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58259
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58260
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58261
|
-
format: _enum([
|
|
58262
|
-
"date",
|
|
58263
|
-
"time",
|
|
58264
|
-
"datetime"
|
|
58265
|
-
]).optional()
|
|
58634
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58635
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58636
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58637
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58638
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58639
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58266
58640
|
});
|
|
58267
58641
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58268
58642
|
object({
|
|
@@ -58328,9 +58702,9 @@ var CoverStatusSchema = object({
|
|
|
58328
58702
|
]),
|
|
58329
58703
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58330
58704
|
* no intermediate position surface. */
|
|
58331
|
-
position: number().min(0).max(100).nullable(),
|
|
58705
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58332
58706
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58333
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58707
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58334
58708
|
/** Ms epoch when the slice was last updated. */
|
|
58335
58709
|
lastChangedAt: number()
|
|
58336
58710
|
});
|
|
@@ -58433,9 +58807,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58433
58807
|
var DayNightStatusSchema = object({
|
|
58434
58808
|
mode: DayNightModeSchema,
|
|
58435
58809
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58436
|
-
sensitivity: number().optional(),
|
|
58810
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58437
58811
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58438
|
-
switchDelaySec: number().optional(),
|
|
58812
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58439
58813
|
lastFetchedAt: number()
|
|
58440
58814
|
});
|
|
58441
58815
|
/**
|
|
@@ -58653,11 +59027,11 @@ var DishwasherStatusSchema = object({
|
|
|
58653
59027
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58654
59028
|
availablePrograms: array(string()),
|
|
58655
59029
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58656
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59030
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58657
59031
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58658
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59032
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58659
59033
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58660
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59034
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58661
59035
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58662
59036
|
doorOpen: boolean().nullable(),
|
|
58663
59037
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58681,7 +59055,7 @@ var DishwasherStatusSchema = object({
|
|
|
58681
59055
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58682
59056
|
machineCareDue: boolean().nullable(),
|
|
58683
59057
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58684
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59058
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58685
59059
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58686
59060
|
halfLoad: boolean().nullable(),
|
|
58687
59061
|
hygienePlus: boolean().nullable(),
|
|
@@ -58696,7 +59070,7 @@ var DishwasherStatusSchema = object({
|
|
|
58696
59070
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58697
59071
|
activeEvents: array(string()),
|
|
58698
59072
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58699
|
-
errorCode: number().nullable(),
|
|
59073
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58700
59074
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58701
59075
|
errorLabel: string().nullable(),
|
|
58702
59076
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -58908,6 +59282,7 @@ var doorbellCustomize = {
|
|
|
58908
59282
|
applyAuthority: { kind: "composition-claim" },
|
|
58909
59283
|
eventName: "onPressed",
|
|
58910
59284
|
edges: ["rising"],
|
|
59285
|
+
defaultEdge: "rising",
|
|
58911
59286
|
timestampPath: "lastPressedAt",
|
|
58912
59287
|
counterPath: "pressCountSinceStart",
|
|
58913
59288
|
highWater: "composer-advance",
|
|
@@ -58926,7 +59301,7 @@ var DoorbellStatusSchema = object({
|
|
|
58926
59301
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
58927
59302
|
lastPressedAt: number().nullable(),
|
|
58928
59303
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
58929
|
-
pressCountSinceStart: number()
|
|
59304
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
58930
59305
|
});
|
|
58931
59306
|
var DoorbellPressEventSchema = object({
|
|
58932
59307
|
deviceId: number(),
|
|
@@ -58991,17 +59366,7 @@ onPressed: {
|
|
|
58991
59366
|
history: "none",
|
|
58992
59367
|
customize: doorbellCustomize
|
|
58993
59368
|
};
|
|
58994
|
-
|
|
58995
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
58996
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
58997
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
58998
|
-
* The option set is stable across observations; it is persisted in the
|
|
58999
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59000
|
-
* stored in `sourceInfo`.
|
|
59001
|
-
*/
|
|
59002
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59003
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59004
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59369
|
+
_enum([
|
|
59005
59370
|
"date",
|
|
59006
59371
|
"time",
|
|
59007
59372
|
"datetime"
|
|
@@ -59009,12 +59374,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59009
59374
|
var EnumSensorStatusSchema = object({
|
|
59010
59375
|
value: string(),
|
|
59011
59376
|
/**
|
|
59012
|
-
* Set
|
|
59013
|
-
* as
|
|
59014
|
-
*
|
|
59015
|
-
* a time-only sensor → `'time'`.
|
|
59377
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59378
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59379
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59016
59380
|
*/
|
|
59017
|
-
|
|
59381
|
+
timestamp: boolean().optional(),
|
|
59018
59382
|
/** Ms epoch when the slice was last updated. */
|
|
59019
59383
|
lastFetchedAt: number()
|
|
59020
59384
|
});
|
|
@@ -59041,11 +59405,11 @@ var enumSensorCapability = {
|
|
|
59041
59405
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59042
59406
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59043
59407
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59044
|
-
* `
|
|
59408
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59045
59409
|
*/
|
|
59046
59410
|
history: { fields: { value: {
|
|
59047
59411
|
kind: "enum",
|
|
59048
|
-
skipWhenSet: "
|
|
59412
|
+
skipWhenSet: "timestamp"
|
|
59049
59413
|
} } },
|
|
59050
59414
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59051
59415
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59065,13 +59429,13 @@ var EventFireSchema = object({
|
|
|
59065
59429
|
deviceId: number(),
|
|
59066
59430
|
eventType: string(),
|
|
59067
59431
|
data: record(string(), unknown()).nullable(),
|
|
59068
|
-
timestamp: number(),
|
|
59069
|
-
seq: number()
|
|
59432
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59433
|
+
seq: number().meta(readingMeta("count"))
|
|
59070
59434
|
});
|
|
59071
59435
|
var EventEmitterStatusSchema = object({
|
|
59072
59436
|
eventTypes: array(string()),
|
|
59073
59437
|
lastEvent: EventFireSchema.nullable(),
|
|
59074
|
-
eventCountSinceStart: number()
|
|
59438
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59075
59439
|
});
|
|
59076
59440
|
var eventEmitterCapability = {
|
|
59077
59441
|
name: "event-emitter",
|
|
@@ -59484,10 +59848,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59484
59848
|
var FanControlStatusSchema = object({
|
|
59485
59849
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59486
59850
|
* speed surface (single-speed fan). */
|
|
59487
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59851
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59488
59852
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59489
59853
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59490
|
-
percentageStep: number().positive().optional(),
|
|
59854
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59491
59855
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59492
59856
|
* — empty string when no preset is active or supported. */
|
|
59493
59857
|
preset: string(),
|
|
@@ -59608,7 +59972,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59608
59972
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59609
59973
|
model: string().nullable(),
|
|
59610
59974
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59611
|
-
channelCount: number().nullable(),
|
|
59975
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59612
59976
|
/**
|
|
59613
59977
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59614
59978
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59731,9 +60095,91 @@ var gasCapability = {
|
|
|
59731
60095
|
* whether persisting is worth a SQLite commit. */
|
|
59732
60096
|
volatileStateFields: ["lastChangedAt"]
|
|
59733
60097
|
};
|
|
60098
|
+
var GroupCommandsSchema = object({
|
|
60099
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60100
|
+
results: array(object({
|
|
60101
|
+
deviceId: number().int().nonnegative(),
|
|
60102
|
+
cap: string().min(1),
|
|
60103
|
+
method: string().min(1),
|
|
60104
|
+
ok: boolean(),
|
|
60105
|
+
error: string().optional(),
|
|
60106
|
+
/** Ms epoch of the attempt. */
|
|
60107
|
+
at: number()
|
|
60108
|
+
})) });
|
|
60109
|
+
var groupCommandsCapability = {
|
|
60110
|
+
name: "group-commands",
|
|
60111
|
+
scope: "device",
|
|
60112
|
+
deviceNative: true,
|
|
60113
|
+
mode: "singleton",
|
|
60114
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60115
|
+
methods: {},
|
|
60116
|
+
status: {
|
|
60117
|
+
schema: GroupCommandsSchema,
|
|
60118
|
+
kind: "push"
|
|
60119
|
+
},
|
|
60120
|
+
runtimeState: GroupCommandsSchema,
|
|
60121
|
+
/**
|
|
60122
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60123
|
+
* failure would outlive the command that caused it.
|
|
60124
|
+
*
|
|
60125
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60126
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60127
|
+
*/
|
|
60128
|
+
durability: "session",
|
|
60129
|
+
history: "none"
|
|
60130
|
+
};
|
|
60131
|
+
/**
|
|
60132
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60133
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60134
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60135
|
+
* series that later statistics read is the output cap's own history block.
|
|
60136
|
+
*/
|
|
60137
|
+
var GroupStatusSchema = object({
|
|
60138
|
+
/** Members whose current value entered the aggregate. */
|
|
60139
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60140
|
+
precision: 0,
|
|
60141
|
+
label: "Reporting"
|
|
60142
|
+
})),
|
|
60143
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60144
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60145
|
+
precision: 0,
|
|
60146
|
+
label: "Excluded"
|
|
60147
|
+
})),
|
|
60148
|
+
/** `included` + `excluded`. */
|
|
60149
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60150
|
+
precision: 0,
|
|
60151
|
+
label: "Members"
|
|
60152
|
+
}))
|
|
60153
|
+
});
|
|
60154
|
+
var groupStatusCapability = {
|
|
60155
|
+
name: "group-status",
|
|
60156
|
+
scope: "device",
|
|
60157
|
+
deviceNative: true,
|
|
60158
|
+
mode: "singleton",
|
|
60159
|
+
deviceTypes: [
|
|
60160
|
+
DeviceType.Sensor,
|
|
60161
|
+
DeviceType.Switch,
|
|
60162
|
+
DeviceType.Light
|
|
60163
|
+
],
|
|
60164
|
+
methods: {},
|
|
60165
|
+
status: {
|
|
60166
|
+
schema: GroupStatusSchema,
|
|
60167
|
+
kind: "push"
|
|
60168
|
+
},
|
|
60169
|
+
runtimeState: GroupStatusSchema,
|
|
60170
|
+
/**
|
|
60171
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60172
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60173
|
+
*
|
|
60174
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60175
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60176
|
+
*/
|
|
60177
|
+
durability: "session",
|
|
60178
|
+
history: "none"
|
|
60179
|
+
};
|
|
59734
60180
|
var HeatingValveStatusSchema = object({
|
|
59735
60181
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59736
|
-
position: number().min(0).max(100).nullable(),
|
|
60182
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59737
60183
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59738
60184
|
lastFetchedAt: number()
|
|
59739
60185
|
});
|
|
@@ -59776,9 +60222,9 @@ var HumidifierStatusSchema = object({
|
|
|
59776
60222
|
/** Whether the humidifier is currently on. */
|
|
59777
60223
|
on: boolean(),
|
|
59778
60224
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59779
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60225
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59780
60226
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59781
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60227
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59782
60228
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59783
60229
|
* device has no mode surface. */
|
|
59784
60230
|
mode: string().nullable(),
|
|
@@ -59788,9 +60234,9 @@ var HumidifierStatusSchema = object({
|
|
|
59788
60234
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59789
60235
|
action: string().nullable(),
|
|
59790
60236
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59791
|
-
minHumidity: number().nullable(),
|
|
60237
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59792
60238
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59793
|
-
maxHumidity: number().nullable(),
|
|
60239
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59794
60240
|
/** Ms epoch when the slice was last updated. */
|
|
59795
60241
|
lastChangedAt: number()
|
|
59796
60242
|
});
|
|
@@ -59860,22 +60306,13 @@ var humidifierCapability = {
|
|
|
59860
60306
|
* `sourceInfo`.
|
|
59861
60307
|
*/
|
|
59862
60308
|
var HumiditySensorStatusSchema = object({
|
|
59863
|
-
/** Current relative humidity, 0..100. */
|
|
59864
|
-
percent: number().min(0).max(100).meta({
|
|
59865
|
-
|
|
60309
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60310
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60311
|
+
precision: 0,
|
|
59866
60312
|
label: "Humidity"
|
|
59867
|
-
}),
|
|
60313
|
+
})),
|
|
59868
60314
|
/** Ms epoch when the slice was last updated. */
|
|
59869
|
-
lastFetchedAt: number()
|
|
59870
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59871
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59872
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59873
|
-
unit: string().optional(),
|
|
59874
|
-
/** Suggested decimal places for numeric display.
|
|
59875
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59876
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59877
|
-
* auto-formatting when absent. */
|
|
59878
|
-
precision: number().int().min(0).max(10).optional()
|
|
60315
|
+
lastFetchedAt: number()
|
|
59879
60316
|
});
|
|
59880
60317
|
var humiditySensorCapability = {
|
|
59881
60318
|
name: "humidity-sensor",
|
|
@@ -59906,12 +60343,7 @@ var humiditySensorCapability = {
|
|
|
59906
60343
|
} } },
|
|
59907
60344
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59908
60345
|
* whether persisting is worth a SQLite commit. */
|
|
59909
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59910
|
-
customize: {
|
|
59911
|
-
version: 1,
|
|
59912
|
-
advanced: "derive",
|
|
59913
|
-
targets: []
|
|
59914
|
-
}
|
|
60346
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59915
60347
|
};
|
|
59916
60348
|
/**
|
|
59917
60349
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -59932,7 +60364,7 @@ var ImageStatusSchema = object({
|
|
|
59932
60364
|
* entity exposes no `entity_picture` (yet). */
|
|
59933
60365
|
url: string().nullable(),
|
|
59934
60366
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
59935
|
-
lastUpdated: number().nullable()
|
|
60367
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
59936
60368
|
});
|
|
59937
60369
|
var imageCapability = {
|
|
59938
60370
|
name: "image",
|
|
@@ -60020,19 +60452,19 @@ var NormalizedRangeSchema = object({
|
|
|
60020
60452
|
*/
|
|
60021
60453
|
var ImageSettingsStatusSchema = object({
|
|
60022
60454
|
/** Normalized 0–100. */
|
|
60023
|
-
brightness: number().optional(),
|
|
60455
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60024
60456
|
/** Normalized 0–100. */
|
|
60025
|
-
contrast: number().optional(),
|
|
60457
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60026
60458
|
/** Normalized 0–100. */
|
|
60027
|
-
saturation: number().optional(),
|
|
60459
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60028
60460
|
/** Normalized 0–100. */
|
|
60029
|
-
sharpness: number().optional(),
|
|
60461
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60030
60462
|
mirror: boolean().optional(),
|
|
60031
60463
|
flip: boolean().optional(),
|
|
60032
60464
|
rotate: ImageRotateSchema.optional(),
|
|
60033
60465
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60034
60466
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60035
|
-
warmth: number().optional(),
|
|
60467
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60036
60468
|
exposureMode: ExposureModeSchema.optional(),
|
|
60037
60469
|
backlightMode: BacklightModeSchema.optional(),
|
|
60038
60470
|
lastFetchedAt: number()
|
|
@@ -60311,10 +60743,10 @@ var IntercomAbilitySchema = object({
|
|
|
60311
60743
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60312
60744
|
codecs: array(string()),
|
|
60313
60745
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60314
|
-
sampleRate: number(),
|
|
60746
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60315
60747
|
duplex: _enum(["half", "full"]),
|
|
60316
60748
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60317
|
-
maxBacklogMs: number()
|
|
60749
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60318
60750
|
});
|
|
60319
60751
|
var IntercomStatusSchema = object({
|
|
60320
60752
|
/** True while a talk session is open. */
|
|
@@ -60541,13 +60973,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60541
60973
|
activity: LawnMowerActivitySchema,
|
|
60542
60974
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60543
60975
|
* reading. */
|
|
60544
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60976
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60545
60977
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60546
60978
|
* task is active / progress is unavailable. */
|
|
60547
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60979
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60548
60980
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60549
60981
|
* or null when unknown. */
|
|
60550
|
-
currentCode: number().nullable(),
|
|
60982
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60551
60983
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60552
60984
|
currentCodeLabel: string().nullable(),
|
|
60553
60985
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61080,7 +61512,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61080
61512
|
state: MediaPlayerStateSchema,
|
|
61081
61513
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61082
61514
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61083
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61515
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61084
61516
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61085
61517
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61086
61518
|
isMuted: boolean().nullable(),
|
|
@@ -61093,10 +61525,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61093
61525
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61094
61526
|
/** Current playback position in ms. Null when not seekable or
|
|
61095
61527
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61096
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61528
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61097
61529
|
/** Total duration of the current media in ms. Null when unknown
|
|
61098
61530
|
* (live stream) or nothing is playing. */
|
|
61099
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61531
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61100
61532
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61101
61533
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61102
61534
|
shuffle: boolean().nullable(),
|
|
@@ -61405,7 +61837,7 @@ var motionCustomize = {
|
|
|
61405
61837
|
eventName: "onMotionChanged"
|
|
61406
61838
|
},
|
|
61407
61839
|
deviceTypes: [DeviceType.Camera],
|
|
61408
|
-
apply: "
|
|
61840
|
+
apply: "add",
|
|
61409
61841
|
applyAuthority: {
|
|
61410
61842
|
kind: "camera-sensors",
|
|
61411
61843
|
timeoutField: "motionCooldownMs"
|
|
@@ -61477,7 +61909,7 @@ var MotionStatusSchema = object({
|
|
|
61477
61909
|
* it, every provider seeded it at boot, and every session left it
|
|
61478
61910
|
* `detected: true` after its detach.
|
|
61479
61911
|
*/
|
|
61480
|
-
autoClearAfterMs: number().nullable()
|
|
61912
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61481
61913
|
});
|
|
61482
61914
|
/**
|
|
61483
61915
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61514,12 +61946,18 @@ var motionCapability = {
|
|
|
61514
61946
|
methods: {
|
|
61515
61947
|
/**
|
|
61516
61948
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61517
|
-
* for consumers that don't need the full status object
|
|
61518
|
-
*
|
|
61519
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61520
|
-
* consumer.
|
|
61949
|
+
* for consumers that don't need the full status object. A composed
|
|
61950
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61521
61951
|
*/
|
|
61522
61952
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
61953
|
+
/**
|
|
61954
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
61955
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
61956
|
+
*/
|
|
61957
|
+
composedMethods: { isDetected: {
|
|
61958
|
+
kind: "slice",
|
|
61959
|
+
field: "detected"
|
|
61960
|
+
} },
|
|
61523
61961
|
events: {
|
|
61524
61962
|
/**
|
|
61525
61963
|
* Fires every time the runner transitions a camera between
|
|
@@ -61659,7 +62097,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61659
62097
|
* the grid region(s). */
|
|
61660
62098
|
var MotionZoneStatusSchema = object({
|
|
61661
62099
|
enabled: boolean(),
|
|
61662
|
-
sensitivity: number(),
|
|
62100
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61663
62101
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61664
62102
|
regions: array(MotionZoneRegionSchema),
|
|
61665
62103
|
lastFetchedAt: number()
|
|
@@ -62029,7 +62467,7 @@ var NavigationStatusSchema = object({
|
|
|
62029
62467
|
following: boolean(),
|
|
62030
62468
|
flash: boolean(),
|
|
62031
62469
|
lightMode: NavigationLightModeSchema,
|
|
62032
|
-
lightLevel: number().min(40).max(100),
|
|
62470
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62033
62471
|
/** Ms epoch when the slice was last updated. */
|
|
62034
62472
|
lastChangedAt: number()
|
|
62035
62473
|
});
|
|
@@ -62163,13 +62601,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62163
62601
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62164
62602
|
* SKIP a null rather than coerce it.
|
|
62165
62603
|
*/
|
|
62166
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62604
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62167
62605
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62168
|
-
rssiDbm: number().optional(),
|
|
62606
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62169
62607
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62170
62608
|
ssid: string().optional(),
|
|
62171
62609
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62172
|
-
lastUpdated: number()
|
|
62610
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62173
62611
|
});
|
|
62174
62612
|
var networkLinkCapability = {
|
|
62175
62613
|
name: "network-link",
|
|
@@ -62554,7 +62992,7 @@ var NotifierStatusSchema = object({
|
|
|
62554
62992
|
lastError: string().nullable(),
|
|
62555
62993
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62556
62994
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62557
|
-
queueDepth: number().int().nonnegative(),
|
|
62995
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62558
62996
|
/** Per-feature capability matrix — authoritative source for the
|
|
62559
62997
|
* compose-form field gating. */
|
|
62560
62998
|
supports: NotifierSupportsSchema
|
|
@@ -62646,11 +63084,9 @@ onSent: { data: object({
|
|
|
62646
63084
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62647
63085
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62648
63086
|
*
|
|
62649
|
-
* The
|
|
62650
|
-
*
|
|
62651
|
-
*
|
|
62652
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62653
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63087
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63088
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63089
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62654
63090
|
*
|
|
62655
63091
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62656
63092
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62659,15 +63095,8 @@ onSent: { data: object({
|
|
|
62659
63095
|
* numeric values land here.
|
|
62660
63096
|
*/
|
|
62661
63097
|
var NumericSensorStatusSchema = object({
|
|
62662
|
-
|
|
62663
|
-
|
|
62664
|
-
* Populated live from the upstream source on each state push.
|
|
62665
|
-
* Absent for unitless sensors. */
|
|
62666
|
-
unit: string().optional(),
|
|
62667
|
-
/** Suggested decimal places for numeric display.
|
|
62668
|
-
* Populated live from the upstream source when provided.
|
|
62669
|
-
* Falls back to auto-formatting when absent. */
|
|
62670
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63098
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63099
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62671
63100
|
/** Ms epoch when the slice was last updated. */
|
|
62672
63101
|
lastFetchedAt: number()
|
|
62673
63102
|
});
|
|
@@ -62691,11 +63120,11 @@ var numericSensorCapability = {
|
|
|
62691
63120
|
*/
|
|
62692
63121
|
durability: "restored",
|
|
62693
63122
|
/**
|
|
62694
|
-
* History (D850): recorded series. The unit is
|
|
63123
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63124
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62695
63125
|
*/
|
|
62696
63126
|
history: { fields: { value: {
|
|
62697
63127
|
kind: "gauge",
|
|
62698
|
-
unitFrom: "unit",
|
|
62699
63128
|
minIntervalMs: 3e4
|
|
62700
63129
|
} } },
|
|
62701
63130
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -62987,23 +63416,26 @@ var PetFeederStatusSchema = object({
|
|
|
62987
63416
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
62988
63417
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
62989
63418
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
62990
|
-
foodLevel: number().nullable(),
|
|
63419
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
62991
63420
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
62992
63421
|
* single-hopper models. */
|
|
62993
|
-
food1: number().nullable(),
|
|
63422
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
62994
63423
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
62995
63424
|
* single-hopper models. */
|
|
62996
|
-
food2: number().nullable(),
|
|
63425
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
62997
63426
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
62998
63427
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
62999
63428
|
* below the feeder's low threshold. */
|
|
63000
63429
|
lowFood: boolean(),
|
|
63001
63430
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63002
63431
|
* device has no battery reading. */
|
|
63003
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63004
|
-
/**
|
|
63005
|
-
*
|
|
63006
|
-
|
|
63432
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63433
|
+
/**
|
|
63434
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63435
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63436
|
+
* model has no desiccant sensor.
|
|
63437
|
+
*/
|
|
63438
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63007
63439
|
/** True while a feed is in progress. */
|
|
63008
63440
|
feeding: boolean(),
|
|
63009
63441
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63014,7 +63446,7 @@ var PetFeederStatusSchema = object({
|
|
|
63014
63446
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63015
63447
|
error: string().nullable(),
|
|
63016
63448
|
/** Raw device error code (0 / null = no error). */
|
|
63017
|
-
errorCode: number().nullable(),
|
|
63449
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63018
63450
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63019
63451
|
isDualHopper: boolean(),
|
|
63020
63452
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63024,7 +63456,7 @@ var PetFeederStatusSchema = object({
|
|
|
63024
63456
|
/** Play a chime when dispensing. */
|
|
63025
63457
|
feedSound: boolean(),
|
|
63026
63458
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63027
|
-
volume: number(),
|
|
63459
|
+
volume: number().meta(readingMeta("none")),
|
|
63028
63460
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63029
63461
|
lastFetchedAt: number()
|
|
63030
63462
|
});
|
|
@@ -63143,7 +63575,7 @@ var petFeederCapability = {
|
|
|
63143
63575
|
},
|
|
63144
63576
|
desiccantLeftDays: {
|
|
63145
63577
|
kind: "gauge",
|
|
63146
|
-
unit: "
|
|
63578
|
+
unit: "s"
|
|
63147
63579
|
}
|
|
63148
63580
|
} }
|
|
63149
63581
|
};
|
|
@@ -63544,36 +63976,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63544
63976
|
*/
|
|
63545
63977
|
var PowerMeterStatusSchema = object({
|
|
63546
63978
|
/** Instantaneous power draw in watts. */
|
|
63547
|
-
watts: number().optional().meta({
|
|
63548
|
-
unit: "W",
|
|
63549
|
-
label: "Power"
|
|
63550
|
-
}),
|
|
63979
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63551
63980
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63552
|
-
kwhTotal: number().optional().meta({
|
|
63553
|
-
unit: "kWh",
|
|
63554
|
-
label: "Energy"
|
|
63555
|
-
}),
|
|
63981
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63556
63982
|
/** Voltage in volts. */
|
|
63557
|
-
volts: number().optional(),
|
|
63983
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63558
63984
|
/** Current in amperes. */
|
|
63559
|
-
amps: number().optional(),
|
|
63560
|
-
/** Apparent power in volt-amperes
|
|
63561
|
-
va: number().optional(),
|
|
63985
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
63986
|
+
/** Apparent power in volt-amperes. */
|
|
63987
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63562
63988
|
/** Power factor (0..1) if reported. */
|
|
63563
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
63989
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63564
63990
|
/** Ms epoch when the slice was last updated. */
|
|
63565
|
-
lastFetchedAt: number()
|
|
63566
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63567
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63568
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63569
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63570
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63571
|
-
unit: string().optional(),
|
|
63572
|
-
/** Suggested decimal places for numeric display.
|
|
63573
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63574
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63575
|
-
* auto-formatting when absent. */
|
|
63576
|
-
precision: number().int().min(0).max(10).optional()
|
|
63991
|
+
lastFetchedAt: number()
|
|
63577
63992
|
});
|
|
63578
63993
|
var powerMeterCapability = {
|
|
63579
63994
|
name: "power-meter",
|
|
@@ -63637,12 +64052,7 @@ var powerMeterCapability = {
|
|
|
63637
64052
|
} },
|
|
63638
64053
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63639
64054
|
* whether persisting is worth a SQLite commit. */
|
|
63640
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63641
|
-
customize: {
|
|
63642
|
-
version: 1,
|
|
63643
|
-
advanced: "derive",
|
|
63644
|
-
targets: []
|
|
63645
|
-
}
|
|
64055
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63646
64056
|
};
|
|
63647
64057
|
/**
|
|
63648
64058
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63662,11 +64072,11 @@ var powerMeterCapability = {
|
|
|
63662
64072
|
*/
|
|
63663
64073
|
var GpsLocationSchema = object({
|
|
63664
64074
|
/** Latitude in decimal degrees, -90..90. */
|
|
63665
|
-
latitude: number().min(-90).max(90),
|
|
64075
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63666
64076
|
/** Longitude in decimal degrees, -180..180. */
|
|
63667
|
-
longitude: number().min(-180).max(180),
|
|
64077
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63668
64078
|
/** Reported accuracy in meters (lower = better). */
|
|
63669
|
-
accuracyMeters: number().nonnegative()
|
|
64079
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63670
64080
|
});
|
|
63671
64081
|
var PresenceStatusSchema = object({
|
|
63672
64082
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63678,7 +64088,7 @@ var PresenceStatusSchema = object({
|
|
|
63678
64088
|
gps: GpsLocationSchema.nullable(),
|
|
63679
64089
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63680
64090
|
* when not reported. */
|
|
63681
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64091
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63682
64092
|
/** Ms epoch when the slice was last updated. */
|
|
63683
64093
|
lastChangedAt: number()
|
|
63684
64094
|
});
|
|
@@ -63728,19 +64138,10 @@ var presenceCapability = {
|
|
|
63728
64138
|
* `sourceInfo`.
|
|
63729
64139
|
*/
|
|
63730
64140
|
var PressureSensorStatusSchema = object({
|
|
63731
|
-
/** Current pressure in hPa. */
|
|
63732
|
-
hpa: number(),
|
|
64141
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64142
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63733
64143
|
/** Ms epoch when the slice was last updated. */
|
|
63734
|
-
lastFetchedAt: number()
|
|
63735
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63736
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63737
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63738
|
-
unit: string().optional(),
|
|
63739
|
-
/** Suggested decimal places for numeric display.
|
|
63740
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63741
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63742
|
-
* auto-formatting when absent. */
|
|
63743
|
-
precision: number().int().min(0).max(10).optional()
|
|
64144
|
+
lastFetchedAt: number()
|
|
63744
64145
|
});
|
|
63745
64146
|
var pressureSensorCapability = {
|
|
63746
64147
|
name: "pressure-sensor",
|
|
@@ -64154,8 +64555,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64154
64555
|
}), _void(), { kind: "mutation" });
|
|
64155
64556
|
var PtzAutotrackSettingsSchema = object({
|
|
64156
64557
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64157
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64158
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64558
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64559
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64159
64560
|
});
|
|
64160
64561
|
/**
|
|
64161
64562
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64309,7 +64710,7 @@ var RunningStateStatusSchema = object({
|
|
|
64309
64710
|
/** null = unknown — never coerced to false (D393). */
|
|
64310
64711
|
running: boolean().nullable(),
|
|
64311
64712
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64312
|
-
since: number().nullable(),
|
|
64713
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64313
64714
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64314
64715
|
phase: string().nullable(),
|
|
64315
64716
|
/** null until a reading has been published (D393). */
|
|
@@ -64324,7 +64725,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64324
64725
|
/** Generic Customize target for the running boolean (D936). */
|
|
64325
64726
|
var runningCustomize = {
|
|
64326
64727
|
version: 1,
|
|
64327
|
-
advanced: "derive",
|
|
64328
64728
|
targets: [{
|
|
64329
64729
|
id: "running",
|
|
64330
64730
|
cardinality: "scalar",
|
|
@@ -64344,7 +64744,7 @@ var runningCustomize = {
|
|
|
64344
64744
|
DeviceType.Thermostat,
|
|
64345
64745
|
DeviceType.PetFeeder
|
|
64346
64746
|
],
|
|
64347
|
-
apply: "add
|
|
64747
|
+
apply: "add",
|
|
64348
64748
|
path: "running",
|
|
64349
64749
|
sources: [
|
|
64350
64750
|
{
|
|
@@ -64360,6 +64760,7 @@ var runningCustomize = {
|
|
|
64360
64760
|
requiredUnit: "W",
|
|
64361
64761
|
transforms: [{
|
|
64362
64762
|
kind: "threshold",
|
|
64763
|
+
comparisons: ["gte", "lte"],
|
|
64363
64764
|
comparison: "gte",
|
|
64364
64765
|
defaultThreshold: 5,
|
|
64365
64766
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -65607,9 +66008,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65607
66008
|
*/
|
|
65608
66009
|
var RecordWindowSchema = object({
|
|
65609
66010
|
trigger: RecordTriggerSchema,
|
|
65610
|
-
day: number().int().min(0).max(6),
|
|
65611
|
-
startMinute: number().int().min(0).max(1439),
|
|
65612
|
-
endMinute: number().int().min(1).max(1440)
|
|
66011
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66012
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66013
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65613
66014
|
});
|
|
65614
66015
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65615
66016
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65685,10 +66086,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65685
66086
|
/** Master "record to the card at all" switch. */
|
|
65686
66087
|
enabled: boolean().nullable(),
|
|
65687
66088
|
overwriteWhenFull: boolean().nullable(),
|
|
65688
|
-
preRecordSec: number().nullable(),
|
|
65689
|
-
postRecordSec: number().nullable(),
|
|
66089
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66090
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65690
66091
|
/** Length of one recorded file, in minutes. */
|
|
65691
|
-
segmentMinutes: number().nullable(),
|
|
66092
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65692
66093
|
/** The primary track's weekly windows, flattened. */
|
|
65693
66094
|
windows: array(RecordWindowSchema),
|
|
65694
66095
|
/**
|
|
@@ -65704,7 +66105,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65704
66105
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65705
66106
|
* writable.
|
|
65706
66107
|
*/
|
|
65707
|
-
unreadableWindows: number(),
|
|
66108
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65708
66109
|
/**
|
|
65709
66110
|
* The camera is scheduled to record and has NO usable storage.
|
|
65710
66111
|
*
|
|
@@ -66549,7 +66950,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66549
66950
|
url: string().optional(),
|
|
66550
66951
|
codec: string().optional(),
|
|
66551
66952
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66552
|
-
fps: number().positive().optional(),
|
|
66953
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66553
66954
|
label: string().optional(),
|
|
66554
66955
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66555
66956
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66636,18 +67037,18 @@ var StreamProfileSchema = _enum([
|
|
|
66636
67037
|
]);
|
|
66637
67038
|
/** The current encoding config of one stream profile. */
|
|
66638
67039
|
var StreamProfileConfigSchema = object({
|
|
66639
|
-
width: number(),
|
|
66640
|
-
height: number(),
|
|
67040
|
+
width: number().meta(readingMeta("none")),
|
|
67041
|
+
height: number().meta(readingMeta("none")),
|
|
66641
67042
|
codec: _enum(["h264", "h265"]),
|
|
66642
|
-
framerate: number(),
|
|
66643
|
-
bitrate: number(),
|
|
67043
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67044
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66644
67045
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66645
67046
|
encoderProfile: _enum([
|
|
66646
67047
|
"high",
|
|
66647
67048
|
"main",
|
|
66648
67049
|
"baseline"
|
|
66649
67050
|
]).optional(),
|
|
66650
|
-
gop: number().optional(),
|
|
67051
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66651
67052
|
/**
|
|
66652
67053
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66653
67054
|
*
|
|
@@ -66868,12 +67269,7 @@ var switchCapability = {
|
|
|
66868
67269
|
label: "On",
|
|
66869
67270
|
kind: "boolean"
|
|
66870
67271
|
}
|
|
66871
|
-
}] }
|
|
66872
|
-
customize: {
|
|
66873
|
-
version: 1,
|
|
66874
|
-
advanced: "derive",
|
|
66875
|
-
targets: []
|
|
66876
|
-
}
|
|
67272
|
+
}] }
|
|
66877
67273
|
};
|
|
66878
67274
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66879
67275
|
function hasControlCharacter(value) {
|
|
@@ -67456,35 +67852,21 @@ var tamperCapability = {
|
|
|
67456
67852
|
* entries with `device_class: temperature` and any future native
|
|
67457
67853
|
* thermometer.
|
|
67458
67854
|
*
|
|
67459
|
-
*
|
|
67460
|
-
*
|
|
67461
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67462
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67463
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67464
|
-
* `sourceInfo`.
|
|
67855
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67856
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67465
67857
|
*
|
|
67466
67858
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67467
67859
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67468
67860
|
* changed" steady state.
|
|
67469
67861
|
*/
|
|
67470
67862
|
var TemperatureSensorStatusSchema = object({
|
|
67471
|
-
/** Current temperature in Celsius. */
|
|
67472
|
-
celsius: number().meta({
|
|
67473
|
-
|
|
67863
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67864
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67865
|
+
precision: 1,
|
|
67474
67866
|
label: "Temperature"
|
|
67475
|
-
}),
|
|
67867
|
+
})),
|
|
67476
67868
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67477
|
-
lastFetchedAt: number()
|
|
67478
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67479
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67480
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67481
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67482
|
-
unit: string().optional(),
|
|
67483
|
-
/** Suggested decimal places for numeric display.
|
|
67484
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67485
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67486
|
-
* auto-formatting when absent. */
|
|
67487
|
-
precision: number().int().min(0).max(10).optional()
|
|
67869
|
+
lastFetchedAt: number()
|
|
67488
67870
|
});
|
|
67489
67871
|
var temperatureSensorCapability = {
|
|
67490
67872
|
name: "temperature-sensor",
|
|
@@ -67515,12 +67897,7 @@ var temperatureSensorCapability = {
|
|
|
67515
67897
|
} } },
|
|
67516
67898
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67517
67899
|
* whether persisting is worth a SQLite commit. */
|
|
67518
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67519
|
-
customize: {
|
|
67520
|
-
version: 1,
|
|
67521
|
-
advanced: "derive",
|
|
67522
|
-
targets: []
|
|
67523
|
-
}
|
|
67900
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67524
67901
|
};
|
|
67525
67902
|
/**
|
|
67526
67903
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67803,16 +68180,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67803
68180
|
]),
|
|
67804
68181
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67805
68182
|
* reading. */
|
|
67806
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68183
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67807
68184
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67808
68185
|
* the vacuum has no speed control. */
|
|
67809
68186
|
fanSpeed: string().nullable(),
|
|
67810
68187
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67811
68188
|
availableFanSpeeds: array(string()),
|
|
67812
68189
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67813
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68190
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67814
68191
|
/** Current error code (0 / null = no error). */
|
|
67815
|
-
errorCode: number().nullable(),
|
|
68192
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67816
68193
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67817
68194
|
errorLabel: string().nullable(),
|
|
67818
68195
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67890,7 +68267,7 @@ var ValveStatusSchema = object({
|
|
|
67890
68267
|
]),
|
|
67891
68268
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67892
68269
|
* intermediate position surface. */
|
|
67893
|
-
position: number().min(0).max(100).nullable(),
|
|
68270
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67894
68271
|
/** Ms epoch when the slice was last updated. */
|
|
67895
68272
|
lastChangedAt: number()
|
|
67896
68273
|
});
|
|
@@ -67998,9 +68375,9 @@ var vibrationCapability = {
|
|
|
67998
68375
|
*/
|
|
67999
68376
|
var WaterHeaterStatusSchema = object({
|
|
68000
68377
|
/** Current measured temperature. Null when not reported. */
|
|
68001
|
-
currentTemp: number().nullable(),
|
|
68378
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68002
68379
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68003
|
-
targetTemp: number().nullable(),
|
|
68380
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68004
68381
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68005
68382
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68006
68383
|
* device reports an unknown state. */
|
|
@@ -68011,9 +68388,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68011
68388
|
* has no away surface. */
|
|
68012
68389
|
away: boolean().nullable(),
|
|
68013
68390
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68014
|
-
minTemp: number().nullable(),
|
|
68391
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68015
68392
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68016
|
-
maxTemp: number().nullable(),
|
|
68393
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68017
68394
|
/** Ms epoch when the slice was last updated. */
|
|
68018
68395
|
lastChangedAt: number()
|
|
68019
68396
|
});
|
|
@@ -68098,25 +68475,18 @@ var waterHeaterCapability = {
|
|
|
68098
68475
|
* Forecast deferred — current conditions only for v1.
|
|
68099
68476
|
*/
|
|
68100
68477
|
var WeatherStatusSchema = object({
|
|
68101
|
-
/** Verbatim
|
|
68102
|
-
* when no condition has been reported yet. */
|
|
68478
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68103
68479
|
condition: string().nullable(),
|
|
68104
|
-
/** Current temperature in
|
|
68105
|
-
temperature: number().nullable(),
|
|
68106
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68107
|
-
temperatureUnit: string().nullable(),
|
|
68480
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68481
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68108
68482
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68109
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68110
|
-
/** Barometric pressure in
|
|
68111
|
-
pressure: number().nullable(),
|
|
68112
|
-
/**
|
|
68113
|
-
|
|
68114
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68115
|
-
windSpeed: number().nullable(),
|
|
68116
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68117
|
-
windSpeedUnit: string().nullable(),
|
|
68483
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68484
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68485
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68486
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68487
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68118
68488
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68119
|
-
windBearing: number().nullable(),
|
|
68489
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68120
68490
|
/** Ms epoch when the slice was last updated. */
|
|
68121
68491
|
lastFetchedAt: number()
|
|
68122
68492
|
});
|
|
@@ -68144,12 +68514,12 @@ var weatherCapability = {
|
|
|
68144
68514
|
*/
|
|
68145
68515
|
durability: "session",
|
|
68146
68516
|
/**
|
|
68147
|
-
* History (D850): recorded series.
|
|
68517
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68148
68518
|
*/
|
|
68149
68519
|
history: { fields: {
|
|
68150
68520
|
temperature: {
|
|
68151
68521
|
kind: "gauge",
|
|
68152
|
-
|
|
68522
|
+
unit: "°C",
|
|
68153
68523
|
deadband: .2
|
|
68154
68524
|
},
|
|
68155
68525
|
humidity: {
|
|
@@ -68159,12 +68529,12 @@ var weatherCapability = {
|
|
|
68159
68529
|
},
|
|
68160
68530
|
pressure: {
|
|
68161
68531
|
kind: "gauge",
|
|
68162
|
-
|
|
68532
|
+
unit: "hPa",
|
|
68163
68533
|
deadband: .5
|
|
68164
68534
|
},
|
|
68165
68535
|
windSpeed: {
|
|
68166
68536
|
kind: "gauge",
|
|
68167
|
-
|
|
68537
|
+
unit: "m/s",
|
|
68168
68538
|
deadband: .5
|
|
68169
68539
|
}
|
|
68170
68540
|
} }
|
|
@@ -69395,6 +69765,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69395
69765
|
featureProbe: featureProbeCapability,
|
|
69396
69766
|
flood: floodCapability,
|
|
69397
69767
|
gas: gasCapability,
|
|
69768
|
+
groupCommands: groupCommandsCapability,
|
|
69769
|
+
groupStatus: groupStatusCapability,
|
|
69398
69770
|
heatingValve: heatingValveCapability,
|
|
69399
69771
|
humidifier: humidifierCapability,
|
|
69400
69772
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70288,6 +70660,13 @@ Object.freeze({
|
|
|
70288
70660
|
access: "view",
|
|
70289
70661
|
role: "admin"
|
|
70290
70662
|
},
|
|
70663
|
+
"addons.getPackageDocs": {
|
|
70664
|
+
capName: "addons",
|
|
70665
|
+
capScope: "system",
|
|
70666
|
+
addonId: null,
|
|
70667
|
+
access: "view",
|
|
70668
|
+
role: "admin"
|
|
70669
|
+
},
|
|
70291
70670
|
"addons.getVersions": {
|
|
70292
70671
|
capName: "addons",
|
|
70293
70672
|
capScope: "system",
|
|
@@ -73396,6 +73775,20 @@ Object.freeze({
|
|
|
73396
73775
|
access: "view",
|
|
73397
73776
|
role: "viewer"
|
|
73398
73777
|
},
|
|
73778
|
+
"groupCommands.getStatus": {
|
|
73779
|
+
capName: "group-commands",
|
|
73780
|
+
capScope: "device",
|
|
73781
|
+
addonId: null,
|
|
73782
|
+
access: "view",
|
|
73783
|
+
role: "viewer"
|
|
73784
|
+
},
|
|
73785
|
+
"groupStatus.getStatus": {
|
|
73786
|
+
capName: "group-status",
|
|
73787
|
+
capScope: "device",
|
|
73788
|
+
addonId: null,
|
|
73789
|
+
access: "view",
|
|
73790
|
+
role: "viewer"
|
|
73791
|
+
},
|
|
73399
73792
|
"heatingValve.getStatus": {
|
|
73400
73793
|
capName: "heating-valve",
|
|
73401
73794
|
capScope: "device",
|
|
@@ -83218,6 +83611,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83218
83611
|
icon: "flame"
|
|
83219
83612
|
}]
|
|
83220
83613
|
},
|
|
83614
|
+
"group-commands": {
|
|
83615
|
+
scope: "device",
|
|
83616
|
+
noun: t("Group command", "Comando di gruppo")
|
|
83617
|
+
},
|
|
83618
|
+
"group-status": {
|
|
83619
|
+
scope: "device",
|
|
83620
|
+
noun: t("Group", "Gruppo"),
|
|
83621
|
+
state: [
|
|
83622
|
+
{
|
|
83623
|
+
kind: "numeric",
|
|
83624
|
+
field: "included",
|
|
83625
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
83626
|
+
label: t("Reporting", "Rispondono"),
|
|
83627
|
+
icon: "users"
|
|
83628
|
+
},
|
|
83629
|
+
{
|
|
83630
|
+
kind: "numeric",
|
|
83631
|
+
field: "excluded",
|
|
83632
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
83633
|
+
label: t("Excluded", "Esclusi"),
|
|
83634
|
+
icon: "users"
|
|
83635
|
+
},
|
|
83636
|
+
{
|
|
83637
|
+
kind: "numeric",
|
|
83638
|
+
field: "total",
|
|
83639
|
+
quantity: t("the member count", "il numero di membri"),
|
|
83640
|
+
label: t("Members", "Membri"),
|
|
83641
|
+
icon: "sigma"
|
|
83642
|
+
}
|
|
83643
|
+
]
|
|
83644
|
+
},
|
|
83221
83645
|
"humidity-sensor": {
|
|
83222
83646
|
scope: "device",
|
|
83223
83647
|
noun: t("Humidity", "Umidità"),
|
|
@@ -83251,7 +83675,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83251
83675
|
field: "value",
|
|
83252
83676
|
quantity: t("the reading", "il valore"),
|
|
83253
83677
|
label: t("Reading", "Valore"),
|
|
83254
|
-
unitField: "unit",
|
|
83255
83678
|
icon: "gauge"
|
|
83256
83679
|
}]
|
|
83257
83680
|
},
|
|
@@ -83387,7 +83810,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83387
83810
|
field: "temperature",
|
|
83388
83811
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83389
83812
|
label: t("Temperature", "Temperatura"),
|
|
83390
|
-
|
|
83813
|
+
unit: "°C",
|
|
83391
83814
|
icon: "thermometer"
|
|
83392
83815
|
},
|
|
83393
83816
|
{
|
|
@@ -83403,7 +83826,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83403
83826
|
field: "windSpeed",
|
|
83404
83827
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83405
83828
|
label: t("Wind", "Vento"),
|
|
83406
|
-
|
|
83829
|
+
unit: "m/s",
|
|
83407
83830
|
icon: "wind"
|
|
83408
83831
|
},
|
|
83409
83832
|
{
|
|
@@ -83411,7 +83834,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83411
83834
|
field: "pressure",
|
|
83412
83835
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83413
83836
|
label: t("Pressure", "Pressione"),
|
|
83414
|
-
|
|
83837
|
+
unit: "hPa",
|
|
83415
83838
|
icon: "gauge"
|
|
83416
83839
|
}
|
|
83417
83840
|
]
|
|
@@ -84684,6 +85107,16 @@ Object.freeze({
|
|
|
84684
85107
|
form: "single",
|
|
84685
85108
|
optional: false
|
|
84686
85109
|
}],
|
|
85110
|
+
"groupCommands.getStatus": [{
|
|
85111
|
+
name: "deviceId",
|
|
85112
|
+
form: "single",
|
|
85113
|
+
optional: false
|
|
85114
|
+
}],
|
|
85115
|
+
"groupStatus.getStatus": [{
|
|
85116
|
+
name: "deviceId",
|
|
85117
|
+
form: "single",
|
|
85118
|
+
optional: false
|
|
85119
|
+
}],
|
|
84687
85120
|
"heatingValve.getStatus": [{
|
|
84688
85121
|
name: "deviceId",
|
|
84689
85122
|
form: "single",
|
|
@@ -86548,6 +86981,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
86548
86981
|
targetId: string().min(1),
|
|
86549
86982
|
enabled: boolean(),
|
|
86550
86983
|
debounceMs: number().nonnegative(),
|
|
86984
|
+
edges: array(_enum([
|
|
86985
|
+
"rising",
|
|
86986
|
+
"button",
|
|
86987
|
+
"native-event"
|
|
86988
|
+
])).min(1).optional(),
|
|
86551
86989
|
sources: array(OverrideSourceSchema).min(1)
|
|
86552
86990
|
});
|
|
86553
86991
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -86663,6 +87101,8 @@ new Map(Object.entries({
|
|
|
86663
87101
|
"detection-blind": "device-events",
|
|
86664
87102
|
"motion-noisy": "device-events",
|
|
86665
87103
|
"motion-calm": "device-events",
|
|
87104
|
+
"package-llm-silent": "device-events",
|
|
87105
|
+
"package-llm-answered": "device-events",
|
|
86666
87106
|
"recording-stalled": "device-events",
|
|
86667
87107
|
"recording-healthy": "device-events",
|
|
86668
87108
|
"recording-degraded": "device-events",
|
|
@@ -86746,6 +87186,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
86746
87186
|
label: "Motion without a subject",
|
|
86747
87187
|
kinds: ["motion-noisy", "motion-calm"]
|
|
86748
87188
|
},
|
|
87189
|
+
{
|
|
87190
|
+
id: "package-llm",
|
|
87191
|
+
family: "device-events",
|
|
87192
|
+
label: "Package confirm",
|
|
87193
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87194
|
+
},
|
|
86749
87195
|
{
|
|
86750
87196
|
id: "recording",
|
|
86751
87197
|
family: "device-events",
|
|
@@ -86927,6 +87373,8 @@ var DEVICE_EVENTS = [
|
|
|
86927
87373
|
"detection-blind",
|
|
86928
87374
|
"motion-noisy",
|
|
86929
87375
|
"motion-calm",
|
|
87376
|
+
"package-llm-silent",
|
|
87377
|
+
"package-llm-answered",
|
|
86930
87378
|
"recording-stalled",
|
|
86931
87379
|
"recording-healthy",
|
|
86932
87380
|
"recording-degraded",
|
|
@@ -87195,6 +87643,15 @@ new Map([
|
|
|
87195
87643
|
snapshotLabel: "Cameras with constant motion now",
|
|
87196
87644
|
snapshotSection: null
|
|
87197
87645
|
},
|
|
87646
|
+
{
|
|
87647
|
+
id: "package-llm-confirm",
|
|
87648
|
+
family: "device-events",
|
|
87649
|
+
label: "Package confirm (not answering / answering again)",
|
|
87650
|
+
bad: ["package-llm-silent"],
|
|
87651
|
+
recovery: ["package-llm-answered"],
|
|
87652
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
87653
|
+
snapshotSection: null
|
|
87654
|
+
},
|
|
87198
87655
|
{
|
|
87199
87656
|
id: "recording-health",
|
|
87200
87657
|
family: "device-events",
|