@camstack/addon-import-alexa 0.2.147 → 0.2.148
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 +18 -0
- package/dist/addon.js +959 -509
- package/dist/addon.mjs +959 -509
- package/package.json +4 -2
package/dist/addon.mjs
CHANGED
|
@@ -38,7 +38,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
38
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
39
39
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
40
40
|
//#endregion
|
|
41
|
-
//#region ../types/dist/event-category-
|
|
41
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
42
42
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
43
43
|
EventCategory["SystemBoot"] = "system.boot";
|
|
44
44
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -364,6 +364,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
364
364
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
365
365
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
366
366
|
/**
|
|
367
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
368
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
369
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
370
|
+
*/
|
|
371
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
372
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
373
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
374
|
+
/**
|
|
367
375
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
368
376
|
* (a settings change via `setAgentInferenceDevices` /
|
|
369
377
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5606,7 +5614,7 @@ var ZodIssueCode = {
|
|
|
5606
5614
|
var ZodFirstPartyTypeKind;
|
|
5607
5615
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5608
5616
|
//#endregion
|
|
5609
|
-
//#region ../types/dist/sleep-
|
|
5617
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5610
5618
|
/**
|
|
5611
5619
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5612
5620
|
* window to float samples (D455).
|
|
@@ -8348,6 +8356,99 @@ function defineEntryKind(name, spec) {
|
|
|
8348
8356
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8349
8357
|
return defined;
|
|
8350
8358
|
}
|
|
8359
|
+
var READING_QUANTITIES = [
|
|
8360
|
+
"temperature",
|
|
8361
|
+
"pressure",
|
|
8362
|
+
"speed",
|
|
8363
|
+
"precipitation",
|
|
8364
|
+
"precipitation-rate",
|
|
8365
|
+
"length",
|
|
8366
|
+
"area",
|
|
8367
|
+
"illuminance",
|
|
8368
|
+
"irradiance",
|
|
8369
|
+
"power",
|
|
8370
|
+
"energy",
|
|
8371
|
+
"voltage",
|
|
8372
|
+
"current",
|
|
8373
|
+
"apparent-power",
|
|
8374
|
+
"humidity",
|
|
8375
|
+
"percentage",
|
|
8376
|
+
"concentration-volume",
|
|
8377
|
+
"concentration-mass",
|
|
8378
|
+
"concentration-ppb",
|
|
8379
|
+
"volume",
|
|
8380
|
+
"duration",
|
|
8381
|
+
"duration-ms",
|
|
8382
|
+
"information",
|
|
8383
|
+
"sound-level",
|
|
8384
|
+
"signal-level",
|
|
8385
|
+
"colour-temperature",
|
|
8386
|
+
"angle",
|
|
8387
|
+
"bitrate",
|
|
8388
|
+
"rate",
|
|
8389
|
+
"mass",
|
|
8390
|
+
"index",
|
|
8391
|
+
"ratio",
|
|
8392
|
+
"count",
|
|
8393
|
+
"none",
|
|
8394
|
+
"device"
|
|
8395
|
+
];
|
|
8396
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8397
|
+
new Set(READING_QUANTITIES);
|
|
8398
|
+
/**
|
|
8399
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8400
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8401
|
+
*/
|
|
8402
|
+
var QUANTITY_BASE = {
|
|
8403
|
+
temperature: "°C",
|
|
8404
|
+
pressure: "hPa",
|
|
8405
|
+
speed: "m/s",
|
|
8406
|
+
precipitation: "mm",
|
|
8407
|
+
"precipitation-rate": "mm/h",
|
|
8408
|
+
length: "m",
|
|
8409
|
+
area: "m²",
|
|
8410
|
+
illuminance: "lx",
|
|
8411
|
+
irradiance: "W/m²",
|
|
8412
|
+
power: "W",
|
|
8413
|
+
energy: "kWh",
|
|
8414
|
+
voltage: "V",
|
|
8415
|
+
current: "A",
|
|
8416
|
+
"apparent-power": "VA",
|
|
8417
|
+
humidity: "%",
|
|
8418
|
+
percentage: "%",
|
|
8419
|
+
"concentration-volume": "ppm",
|
|
8420
|
+
"concentration-mass": "µg/m³",
|
|
8421
|
+
"concentration-ppb": "ppb",
|
|
8422
|
+
volume: "L",
|
|
8423
|
+
duration: "s",
|
|
8424
|
+
"duration-ms": "ms",
|
|
8425
|
+
information: "B",
|
|
8426
|
+
"sound-level": "dBFS",
|
|
8427
|
+
"signal-level": "dBm",
|
|
8428
|
+
"colour-temperature": "mired",
|
|
8429
|
+
angle: "°",
|
|
8430
|
+
bitrate: "kbps",
|
|
8431
|
+
rate: "fps",
|
|
8432
|
+
mass: "kg",
|
|
8433
|
+
index: "none",
|
|
8434
|
+
ratio: "none",
|
|
8435
|
+
count: "none",
|
|
8436
|
+
none: "none",
|
|
8437
|
+
device: "device"
|
|
8438
|
+
};
|
|
8439
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8440
|
+
function baseUnitOf(quantity) {
|
|
8441
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8442
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8443
|
+
return symbol;
|
|
8444
|
+
}
|
|
8445
|
+
function readingMeta(quantity, extras) {
|
|
8446
|
+
return {
|
|
8447
|
+
quantity,
|
|
8448
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8449
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8450
|
+
};
|
|
8451
|
+
}
|
|
8351
8452
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8352
8453
|
var CamProfileSchema = _enum([
|
|
8353
8454
|
"high",
|
|
@@ -8375,8 +8476,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8375
8476
|
"derived"
|
|
8376
8477
|
]);
|
|
8377
8478
|
var CamStreamResolutionSchema = object({
|
|
8378
|
-
width: number().int().positive(),
|
|
8379
|
-
height: number().int().positive()
|
|
8479
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8480
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8380
8481
|
});
|
|
8381
8482
|
var CameraStreamSchema = object({
|
|
8382
8483
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8894,6 +8995,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8894
8995
|
"filesystem-browse",
|
|
8895
8996
|
"flood",
|
|
8896
8997
|
"gas",
|
|
8998
|
+
"group-commands",
|
|
8999
|
+
"group-status",
|
|
8897
9000
|
"heating-valve",
|
|
8898
9001
|
"humidifier",
|
|
8899
9002
|
"humidity-sensor",
|
|
@@ -9023,14 +9126,6 @@ Object.freeze({
|
|
|
9023
9126
|
{
|
|
9024
9127
|
"path": "aqi",
|
|
9025
9128
|
"valueType": "number"
|
|
9026
|
-
},
|
|
9027
|
-
{
|
|
9028
|
-
"path": "unit",
|
|
9029
|
-
"valueType": "string"
|
|
9030
|
-
},
|
|
9031
|
-
{
|
|
9032
|
-
"path": "precision",
|
|
9033
|
-
"valueType": "number"
|
|
9034
9129
|
}
|
|
9035
9130
|
],
|
|
9036
9131
|
"alarm-panel": [
|
|
@@ -9066,20 +9161,10 @@ Object.freeze({
|
|
|
9066
9161
|
"valueType": "boolean"
|
|
9067
9162
|
}
|
|
9068
9163
|
],
|
|
9069
|
-
"ambient-light-sensor": [
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
},
|
|
9074
|
-
{
|
|
9075
|
-
"path": "unit",
|
|
9076
|
-
"valueType": "string"
|
|
9077
|
-
},
|
|
9078
|
-
{
|
|
9079
|
-
"path": "precision",
|
|
9080
|
-
"valueType": "number"
|
|
9081
|
-
}
|
|
9082
|
-
],
|
|
9164
|
+
"ambient-light-sensor": [{
|
|
9165
|
+
"path": "lux",
|
|
9166
|
+
"valueType": "number"
|
|
9167
|
+
}],
|
|
9083
9168
|
"audio-metrics": [
|
|
9084
9169
|
{
|
|
9085
9170
|
"path": "ts",
|
|
@@ -9159,6 +9244,10 @@ Object.freeze({
|
|
|
9159
9244
|
"path": "lastUpdated",
|
|
9160
9245
|
"valueType": "number"
|
|
9161
9246
|
},
|
|
9247
|
+
{
|
|
9248
|
+
"path": "volts",
|
|
9249
|
+
"valueType": "number"
|
|
9250
|
+
},
|
|
9162
9251
|
{
|
|
9163
9252
|
"path": "lastContactAt",
|
|
9164
9253
|
"valueType": "number"
|
|
@@ -9401,10 +9490,6 @@ Object.freeze({
|
|
|
9401
9490
|
"datetime"
|
|
9402
9491
|
]
|
|
9403
9492
|
},
|
|
9404
|
-
{
|
|
9405
|
-
"path": "unit",
|
|
9406
|
-
"valueType": "string"
|
|
9407
|
-
},
|
|
9408
9493
|
{
|
|
9409
9494
|
"path": "min",
|
|
9410
9495
|
"valueType": "number"
|
|
@@ -9416,19 +9501,6 @@ Object.freeze({
|
|
|
9416
9501
|
{
|
|
9417
9502
|
"path": "step",
|
|
9418
9503
|
"valueType": "number"
|
|
9419
|
-
},
|
|
9420
|
-
{
|
|
9421
|
-
"path": "precision",
|
|
9422
|
-
"valueType": "number"
|
|
9423
|
-
},
|
|
9424
|
-
{
|
|
9425
|
-
"path": "format",
|
|
9426
|
-
"valueType": "enum",
|
|
9427
|
-
"enumValues": [
|
|
9428
|
-
"date",
|
|
9429
|
-
"time",
|
|
9430
|
-
"datetime"
|
|
9431
|
-
]
|
|
9432
9504
|
}
|
|
9433
9505
|
],
|
|
9434
9506
|
"cover": [
|
|
@@ -9669,13 +9741,8 @@ Object.freeze({
|
|
|
9669
9741
|
"path": "value",
|
|
9670
9742
|
"valueType": "string"
|
|
9671
9743
|
}, {
|
|
9672
|
-
"path": "
|
|
9673
|
-
"valueType": "
|
|
9674
|
-
"enumValues": [
|
|
9675
|
-
"date",
|
|
9676
|
-
"time",
|
|
9677
|
-
"datetime"
|
|
9678
|
-
]
|
|
9744
|
+
"path": "timestamp",
|
|
9745
|
+
"valueType": "boolean"
|
|
9679
9746
|
}],
|
|
9680
9747
|
"event-emitter": [
|
|
9681
9748
|
{
|
|
@@ -9748,6 +9815,20 @@ Object.freeze({
|
|
|
9748
9815
|
"path": "detected",
|
|
9749
9816
|
"valueType": "boolean"
|
|
9750
9817
|
}],
|
|
9818
|
+
"group-status": [
|
|
9819
|
+
{
|
|
9820
|
+
"path": "included",
|
|
9821
|
+
"valueType": "number"
|
|
9822
|
+
},
|
|
9823
|
+
{
|
|
9824
|
+
"path": "excluded",
|
|
9825
|
+
"valueType": "number"
|
|
9826
|
+
},
|
|
9827
|
+
{
|
|
9828
|
+
"path": "total",
|
|
9829
|
+
"valueType": "number"
|
|
9830
|
+
}
|
|
9831
|
+
],
|
|
9751
9832
|
"heating-valve": [{
|
|
9752
9833
|
"path": "position",
|
|
9753
9834
|
"valueType": "number"
|
|
@@ -9782,20 +9863,10 @@ Object.freeze({
|
|
|
9782
9863
|
"valueType": "number"
|
|
9783
9864
|
}
|
|
9784
9865
|
],
|
|
9785
|
-
"humidity-sensor": [
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
},
|
|
9790
|
-
{
|
|
9791
|
-
"path": "unit",
|
|
9792
|
-
"valueType": "string"
|
|
9793
|
-
},
|
|
9794
|
-
{
|
|
9795
|
-
"path": "precision",
|
|
9796
|
-
"valueType": "number"
|
|
9797
|
-
}
|
|
9798
|
-
],
|
|
9866
|
+
"humidity-sensor": [{
|
|
9867
|
+
"path": "percent",
|
|
9868
|
+
"valueType": "number"
|
|
9869
|
+
}],
|
|
9799
9870
|
"image": [{
|
|
9800
9871
|
"path": "url",
|
|
9801
9872
|
"valueType": "string"
|
|
@@ -10134,20 +10205,10 @@ Object.freeze({
|
|
|
10134
10205
|
"valueType": "boolean"
|
|
10135
10206
|
}
|
|
10136
10207
|
],
|
|
10137
|
-
"numeric-sensor": [
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
},
|
|
10142
|
-
{
|
|
10143
|
-
"path": "unit",
|
|
10144
|
-
"valueType": "string"
|
|
10145
|
-
},
|
|
10146
|
-
{
|
|
10147
|
-
"path": "precision",
|
|
10148
|
-
"valueType": "number"
|
|
10149
|
-
}
|
|
10150
|
-
],
|
|
10208
|
+
"numeric-sensor": [{
|
|
10209
|
+
"path": "value",
|
|
10210
|
+
"valueType": "number"
|
|
10211
|
+
}],
|
|
10151
10212
|
"pet-feeder": [
|
|
10152
10213
|
{
|
|
10153
10214
|
"path": "foodLevel",
|
|
@@ -10239,14 +10300,6 @@ Object.freeze({
|
|
|
10239
10300
|
{
|
|
10240
10301
|
"path": "powerFactor",
|
|
10241
10302
|
"valueType": "number"
|
|
10242
|
-
},
|
|
10243
|
-
{
|
|
10244
|
-
"path": "unit",
|
|
10245
|
-
"valueType": "string"
|
|
10246
|
-
},
|
|
10247
|
-
{
|
|
10248
|
-
"path": "precision",
|
|
10249
|
-
"valueType": "number"
|
|
10250
10303
|
}
|
|
10251
10304
|
],
|
|
10252
10305
|
"presence": [
|
|
@@ -10275,20 +10328,10 @@ Object.freeze({
|
|
|
10275
10328
|
"valueType": "number"
|
|
10276
10329
|
}
|
|
10277
10330
|
],
|
|
10278
|
-
"pressure-sensor": [
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
},
|
|
10283
|
-
{
|
|
10284
|
-
"path": "unit",
|
|
10285
|
-
"valueType": "string"
|
|
10286
|
-
},
|
|
10287
|
-
{
|
|
10288
|
-
"path": "precision",
|
|
10289
|
-
"valueType": "number"
|
|
10290
|
-
}
|
|
10291
|
-
],
|
|
10331
|
+
"pressure-sensor": [{
|
|
10332
|
+
"path": "hpa",
|
|
10333
|
+
"valueType": "number"
|
|
10334
|
+
}],
|
|
10292
10335
|
"privacy-mask": [{
|
|
10293
10336
|
"path": "enabled",
|
|
10294
10337
|
"valueType": "boolean"
|
|
@@ -10599,20 +10642,10 @@ Object.freeze({
|
|
|
10599
10642
|
"path": "tampered",
|
|
10600
10643
|
"valueType": "boolean"
|
|
10601
10644
|
}],
|
|
10602
|
-
"temperature-sensor": [
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
},
|
|
10607
|
-
{
|
|
10608
|
-
"path": "unit",
|
|
10609
|
-
"valueType": "string"
|
|
10610
|
-
},
|
|
10611
|
-
{
|
|
10612
|
-
"path": "precision",
|
|
10613
|
-
"valueType": "number"
|
|
10614
|
-
}
|
|
10615
|
-
],
|
|
10645
|
+
"temperature-sensor": [{
|
|
10646
|
+
"path": "celsius",
|
|
10647
|
+
"valueType": "number"
|
|
10648
|
+
}],
|
|
10616
10649
|
"update": [
|
|
10617
10650
|
{
|
|
10618
10651
|
"path": "currentVersion",
|
|
@@ -10723,10 +10756,6 @@ Object.freeze({
|
|
|
10723
10756
|
"path": "temperature",
|
|
10724
10757
|
"valueType": "number"
|
|
10725
10758
|
},
|
|
10726
|
-
{
|
|
10727
|
-
"path": "temperatureUnit",
|
|
10728
|
-
"valueType": "string"
|
|
10729
|
-
},
|
|
10730
10759
|
{
|
|
10731
10760
|
"path": "humidity",
|
|
10732
10761
|
"valueType": "number"
|
|
@@ -10735,18 +10764,10 @@ Object.freeze({
|
|
|
10735
10764
|
"path": "pressure",
|
|
10736
10765
|
"valueType": "number"
|
|
10737
10766
|
},
|
|
10738
|
-
{
|
|
10739
|
-
"path": "pressureUnit",
|
|
10740
|
-
"valueType": "string"
|
|
10741
|
-
},
|
|
10742
10767
|
{
|
|
10743
10768
|
"path": "windSpeed",
|
|
10744
10769
|
"valueType": "number"
|
|
10745
10770
|
},
|
|
10746
|
-
{
|
|
10747
|
-
"path": "windSpeedUnit",
|
|
10748
|
-
"valueType": "string"
|
|
10749
|
-
},
|
|
10750
10771
|
{
|
|
10751
10772
|
"path": "windBearing",
|
|
10752
10773
|
"valueType": "number"
|
|
@@ -11149,7 +11170,7 @@ function errMsg(err) {
|
|
|
11149
11170
|
return String(err);
|
|
11150
11171
|
}
|
|
11151
11172
|
//#endregion
|
|
11152
|
-
//#region ../types/dist/composition-
|
|
11173
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11153
11174
|
/**
|
|
11154
11175
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11155
11176
|
*
|
|
@@ -11904,15 +11925,74 @@ function validateExpressionSource(src) {
|
|
|
11904
11925
|
}
|
|
11905
11926
|
return null;
|
|
11906
11927
|
}
|
|
11907
|
-
/**
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11928
|
+
/**
|
|
11929
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11930
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11931
|
+
* `composition.ts` (D659).
|
|
11932
|
+
*/
|
|
11911
11933
|
var CompositionSourceRefSchema = object({
|
|
11912
11934
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11913
11935
|
addonId: string().min(1),
|
|
11914
11936
|
stableId: string().min(1)
|
|
11915
11937
|
});
|
|
11938
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11939
|
+
"temperature",
|
|
11940
|
+
"humidity",
|
|
11941
|
+
"pressure",
|
|
11942
|
+
"illuminance",
|
|
11943
|
+
"power",
|
|
11944
|
+
"energy",
|
|
11945
|
+
"battery",
|
|
11946
|
+
"numeric",
|
|
11947
|
+
"motion",
|
|
11948
|
+
"contact",
|
|
11949
|
+
"leak",
|
|
11950
|
+
"smoke",
|
|
11951
|
+
"occupancy",
|
|
11952
|
+
"binary",
|
|
11953
|
+
"switch",
|
|
11954
|
+
"light"
|
|
11955
|
+
];
|
|
11956
|
+
var NUMERIC_AGGREGATES = [
|
|
11957
|
+
"mean",
|
|
11958
|
+
"median",
|
|
11959
|
+
"min",
|
|
11960
|
+
"max",
|
|
11961
|
+
"sum"
|
|
11962
|
+
];
|
|
11963
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11964
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11965
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11966
|
+
var AGGREGATE_REDUCERS = [
|
|
11967
|
+
"mean",
|
|
11968
|
+
"median",
|
|
11969
|
+
"min",
|
|
11970
|
+
"max",
|
|
11971
|
+
"sum",
|
|
11972
|
+
"any",
|
|
11973
|
+
"all"
|
|
11974
|
+
];
|
|
11975
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11976
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11977
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11978
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11979
|
+
var HelperMemberSchema = object({
|
|
11980
|
+
source: CompositionSourceRefSchema,
|
|
11981
|
+
cap: string().min(1),
|
|
11982
|
+
fieldPath: string().min(1)
|
|
11983
|
+
});
|
|
11984
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11985
|
+
kind: literal("group"),
|
|
11986
|
+
templateId: GroupTemplateIdSchema,
|
|
11987
|
+
aggregate: AggregateReducerSchema,
|
|
11988
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11989
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11990
|
+
active: ActiveCriterionSchema.optional()
|
|
11991
|
+
})]);
|
|
11992
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11993
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11994
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11995
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11916
11996
|
/** One field of one capability of one source device. */
|
|
11917
11997
|
var CompositionFieldReadSchema = object({
|
|
11918
11998
|
source: CompositionSourceRefSchema,
|
|
@@ -11956,7 +12036,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11956
12036
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11957
12037
|
CompositionFromSourceSchema,
|
|
11958
12038
|
CompositionExpressionSourceSchema,
|
|
11959
|
-
CompositionCodeSourceSchema
|
|
12039
|
+
CompositionCodeSourceSchema,
|
|
12040
|
+
object({
|
|
12041
|
+
kind: literal("aggregate"),
|
|
12042
|
+
reducer: _enum([
|
|
12043
|
+
"mean",
|
|
12044
|
+
"median",
|
|
12045
|
+
"min",
|
|
12046
|
+
"max",
|
|
12047
|
+
"sum",
|
|
12048
|
+
"any",
|
|
12049
|
+
"all"
|
|
12050
|
+
]),
|
|
12051
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12052
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12053
|
+
publish: _enum([
|
|
12054
|
+
"value",
|
|
12055
|
+
"included",
|
|
12056
|
+
"excluded",
|
|
12057
|
+
"total"
|
|
12058
|
+
]),
|
|
12059
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12060
|
+
empty: _enum([
|
|
12061
|
+
"null",
|
|
12062
|
+
"omit",
|
|
12063
|
+
"offline"
|
|
12064
|
+
])
|
|
12065
|
+
})
|
|
11960
12066
|
]);
|
|
11961
12067
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11962
12068
|
kind: literal("forward"),
|
|
@@ -12002,7 +12108,13 @@ var CompositionSchema = object({
|
|
|
12002
12108
|
kind: literal("existing"),
|
|
12003
12109
|
device: CompositionSourceRefSchema
|
|
12004
12110
|
})]),
|
|
12005
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12111
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12112
|
+
/**
|
|
12113
|
+
* Present when the block is a helper template. Absent on a free
|
|
12114
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12115
|
+
* never the compiled features.
|
|
12116
|
+
*/
|
|
12117
|
+
helper: HelperSpecSchema.optional()
|
|
12006
12118
|
}).superRefine((composition, ctx) => {
|
|
12007
12119
|
const seen = /* @__PURE__ */ new Set();
|
|
12008
12120
|
composition.features.forEach((feature, index) => {
|
|
@@ -18395,7 +18507,11 @@ var CompositionProblemSchema = object({
|
|
|
18395
18507
|
"item-field-reserved",
|
|
18396
18508
|
"target-missing",
|
|
18397
18509
|
"target-unreadable",
|
|
18398
|
-
"not-replaceable"
|
|
18510
|
+
"not-replaceable",
|
|
18511
|
+
"native-capability-replace",
|
|
18512
|
+
"mixed-quantity",
|
|
18513
|
+
"helper-mismatch",
|
|
18514
|
+
"member-constraint"
|
|
18399
18515
|
]),
|
|
18400
18516
|
path: string(),
|
|
18401
18517
|
message: string()
|
|
@@ -18416,7 +18532,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18416
18532
|
"null",
|
|
18417
18533
|
"offline",
|
|
18418
18534
|
"unknown",
|
|
18419
|
-
"release"
|
|
18535
|
+
"release",
|
|
18536
|
+
"omit"
|
|
18420
18537
|
]);
|
|
18421
18538
|
/**
|
|
18422
18539
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18453,9 +18570,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18453
18570
|
reads: array(CompositionFieldReadSchema)
|
|
18454
18571
|
});
|
|
18455
18572
|
/**
|
|
18456
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18457
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18458
|
-
*
|
|
18573
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18574
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18575
|
+
* Replacing a capability the device already serves is refused
|
|
18576
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18577
|
+
* wire for a claim the hub already holds.
|
|
18459
18578
|
*/
|
|
18460
18579
|
var CompositionFeatureModeSchema = _enum([
|
|
18461
18580
|
"new",
|
|
@@ -18628,6 +18747,275 @@ Object.freeze({
|
|
|
18628
18747
|
result: ["number", "null"]
|
|
18629
18748
|
}
|
|
18630
18749
|
});
|
|
18750
|
+
/**
|
|
18751
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18752
|
+
* Data, not a form default written into the block.
|
|
18753
|
+
*/
|
|
18754
|
+
var NOW = {
|
|
18755
|
+
fieldPath: "lastFetchedAt",
|
|
18756
|
+
expr: "now"
|
|
18757
|
+
};
|
|
18758
|
+
var CHANGED = {
|
|
18759
|
+
fieldPath: "lastChangedAt",
|
|
18760
|
+
expr: "now"
|
|
18761
|
+
};
|
|
18762
|
+
function numeric(input) {
|
|
18763
|
+
return {
|
|
18764
|
+
...input,
|
|
18765
|
+
family: "numeric",
|
|
18766
|
+
deviceType: DeviceType.Sensor,
|
|
18767
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18768
|
+
commandCaps: [],
|
|
18769
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18770
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18771
|
+
accept: [{
|
|
18772
|
+
cap: input.outputCap,
|
|
18773
|
+
fieldPath: input.outputField
|
|
18774
|
+
}]
|
|
18775
|
+
};
|
|
18776
|
+
}
|
|
18777
|
+
function binary(input) {
|
|
18778
|
+
return {
|
|
18779
|
+
...input,
|
|
18780
|
+
family: "binary",
|
|
18781
|
+
deviceType: DeviceType.Sensor,
|
|
18782
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18783
|
+
commandCaps: [],
|
|
18784
|
+
quantity: "none",
|
|
18785
|
+
baseUnit: void 0,
|
|
18786
|
+
aggregates: BINARY_AGGREGATES,
|
|
18787
|
+
empty: "offline"
|
|
18788
|
+
};
|
|
18789
|
+
}
|
|
18790
|
+
var GROUP_TEMPLATES = [
|
|
18791
|
+
numeric({
|
|
18792
|
+
id: "temperature",
|
|
18793
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18794
|
+
role: DeviceRole.TemperatureSensor,
|
|
18795
|
+
outputCap: "temperature-sensor",
|
|
18796
|
+
outputField: "celsius",
|
|
18797
|
+
quantity: "temperature",
|
|
18798
|
+
defaultAggregate: "mean",
|
|
18799
|
+
empty: "null",
|
|
18800
|
+
companions: [NOW]
|
|
18801
|
+
}),
|
|
18802
|
+
numeric({
|
|
18803
|
+
id: "humidity",
|
|
18804
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18805
|
+
role: DeviceRole.HumiditySensor,
|
|
18806
|
+
outputCap: "humidity-sensor",
|
|
18807
|
+
outputField: "percent",
|
|
18808
|
+
quantity: "humidity",
|
|
18809
|
+
defaultAggregate: "mean",
|
|
18810
|
+
empty: "null",
|
|
18811
|
+
companions: [NOW]
|
|
18812
|
+
}),
|
|
18813
|
+
numeric({
|
|
18814
|
+
id: "pressure",
|
|
18815
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18816
|
+
role: DeviceRole.PressureSensor,
|
|
18817
|
+
outputCap: "pressure-sensor",
|
|
18818
|
+
outputField: "hpa",
|
|
18819
|
+
quantity: "pressure",
|
|
18820
|
+
defaultAggregate: "mean",
|
|
18821
|
+
empty: "null",
|
|
18822
|
+
companions: [NOW]
|
|
18823
|
+
}),
|
|
18824
|
+
numeric({
|
|
18825
|
+
id: "illuminance",
|
|
18826
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18827
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18828
|
+
outputCap: "ambient-light-sensor",
|
|
18829
|
+
outputField: "lux",
|
|
18830
|
+
quantity: "illuminance",
|
|
18831
|
+
defaultAggregate: "mean",
|
|
18832
|
+
empty: "null",
|
|
18833
|
+
companions: [NOW]
|
|
18834
|
+
}),
|
|
18835
|
+
numeric({
|
|
18836
|
+
id: "power",
|
|
18837
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18838
|
+
role: DeviceRole.PowerSensor,
|
|
18839
|
+
outputCap: "power-meter",
|
|
18840
|
+
outputField: "watts",
|
|
18841
|
+
quantity: "power",
|
|
18842
|
+
defaultAggregate: "sum",
|
|
18843
|
+
empty: "omit",
|
|
18844
|
+
companions: [NOW]
|
|
18845
|
+
}),
|
|
18846
|
+
numeric({
|
|
18847
|
+
id: "energy",
|
|
18848
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18849
|
+
role: DeviceRole.EnergySensor,
|
|
18850
|
+
outputCap: "power-meter",
|
|
18851
|
+
outputField: "kwhTotal",
|
|
18852
|
+
quantity: "energy",
|
|
18853
|
+
defaultAggregate: "sum",
|
|
18854
|
+
empty: "omit",
|
|
18855
|
+
companions: [NOW]
|
|
18856
|
+
}),
|
|
18857
|
+
numeric({
|
|
18858
|
+
id: "battery",
|
|
18859
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18860
|
+
role: DeviceRole.BatterySensor,
|
|
18861
|
+
outputCap: "battery",
|
|
18862
|
+
outputField: "percentage",
|
|
18863
|
+
quantity: "percentage",
|
|
18864
|
+
defaultAggregate: "mean",
|
|
18865
|
+
empty: "null",
|
|
18866
|
+
companions: [
|
|
18867
|
+
{
|
|
18868
|
+
fieldPath: "charging",
|
|
18869
|
+
expr: "\"unknown\""
|
|
18870
|
+
},
|
|
18871
|
+
{
|
|
18872
|
+
fieldPath: "sleeping",
|
|
18873
|
+
expr: "false"
|
|
18874
|
+
},
|
|
18875
|
+
{
|
|
18876
|
+
fieldPath: "lastUpdated",
|
|
18877
|
+
expr: "now"
|
|
18878
|
+
}
|
|
18879
|
+
]
|
|
18880
|
+
}),
|
|
18881
|
+
numeric({
|
|
18882
|
+
id: "numeric",
|
|
18883
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18884
|
+
role: DeviceRole.NumericSensor,
|
|
18885
|
+
outputCap: "numeric-sensor",
|
|
18886
|
+
outputField: "value",
|
|
18887
|
+
quantity: "device",
|
|
18888
|
+
defaultAggregate: "mean",
|
|
18889
|
+
empty: "null",
|
|
18890
|
+
companions: [NOW]
|
|
18891
|
+
}),
|
|
18892
|
+
binary({
|
|
18893
|
+
id: "motion",
|
|
18894
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18895
|
+
role: DeviceRole.MotionSensor,
|
|
18896
|
+
outputCap: "motion",
|
|
18897
|
+
outputField: "detected",
|
|
18898
|
+
defaultAggregate: "any",
|
|
18899
|
+
accept: [{
|
|
18900
|
+
cap: "motion",
|
|
18901
|
+
fieldPath: "detected"
|
|
18902
|
+
}],
|
|
18903
|
+
companions: [{
|
|
18904
|
+
fieldPath: "lastDetectedAt",
|
|
18905
|
+
expr: "null"
|
|
18906
|
+
}, {
|
|
18907
|
+
fieldPath: "autoClearAfterMs",
|
|
18908
|
+
expr: "null"
|
|
18909
|
+
}]
|
|
18910
|
+
}),
|
|
18911
|
+
binary({
|
|
18912
|
+
id: "contact",
|
|
18913
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18914
|
+
role: DeviceRole.ContactSensor,
|
|
18915
|
+
outputCap: "contact",
|
|
18916
|
+
outputField: "entryOpen",
|
|
18917
|
+
defaultAggregate: "any",
|
|
18918
|
+
accept: [{
|
|
18919
|
+
cap: "contact",
|
|
18920
|
+
fieldPath: "entryOpen"
|
|
18921
|
+
}],
|
|
18922
|
+
companions: [CHANGED]
|
|
18923
|
+
}),
|
|
18924
|
+
binary({
|
|
18925
|
+
id: "leak",
|
|
18926
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18927
|
+
role: DeviceRole.LeakSensor,
|
|
18928
|
+
outputCap: "flood",
|
|
18929
|
+
outputField: "flooded",
|
|
18930
|
+
defaultAggregate: "any",
|
|
18931
|
+
accept: [{
|
|
18932
|
+
cap: "flood",
|
|
18933
|
+
fieldPath: "flooded"
|
|
18934
|
+
}],
|
|
18935
|
+
companions: [CHANGED]
|
|
18936
|
+
}),
|
|
18937
|
+
binary({
|
|
18938
|
+
id: "smoke",
|
|
18939
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18940
|
+
role: DeviceRole.SmokeSensor,
|
|
18941
|
+
outputCap: "smoke",
|
|
18942
|
+
outputField: "detected",
|
|
18943
|
+
defaultAggregate: "any",
|
|
18944
|
+
accept: [{
|
|
18945
|
+
cap: "smoke",
|
|
18946
|
+
fieldPath: "detected"
|
|
18947
|
+
}],
|
|
18948
|
+
companions: [CHANGED]
|
|
18949
|
+
}),
|
|
18950
|
+
binary({
|
|
18951
|
+
id: "occupancy",
|
|
18952
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18953
|
+
role: DeviceRole.BinarySensor,
|
|
18954
|
+
outputCap: "binary",
|
|
18955
|
+
outputField: "on",
|
|
18956
|
+
defaultAggregate: "any",
|
|
18957
|
+
accept: [{
|
|
18958
|
+
cap: "motion",
|
|
18959
|
+
fieldPath: "detected"
|
|
18960
|
+
}, {
|
|
18961
|
+
cap: "binary",
|
|
18962
|
+
fieldPath: "on"
|
|
18963
|
+
}],
|
|
18964
|
+
companions: [CHANGED]
|
|
18965
|
+
}),
|
|
18966
|
+
binary({
|
|
18967
|
+
id: "binary",
|
|
18968
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18969
|
+
role: DeviceRole.BinarySensor,
|
|
18970
|
+
outputCap: "binary",
|
|
18971
|
+
outputField: "on",
|
|
18972
|
+
defaultAggregate: "any",
|
|
18973
|
+
accept: [{
|
|
18974
|
+
cap: "binary",
|
|
18975
|
+
fieldPath: "on"
|
|
18976
|
+
}],
|
|
18977
|
+
companions: [CHANGED]
|
|
18978
|
+
}),
|
|
18979
|
+
actuator({
|
|
18980
|
+
id: "switch",
|
|
18981
|
+
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.",
|
|
18982
|
+
deviceType: DeviceType.Switch,
|
|
18983
|
+
outputCap: "switch",
|
|
18984
|
+
commandCaps: ["switch"]
|
|
18985
|
+
}),
|
|
18986
|
+
actuator({
|
|
18987
|
+
id: "light",
|
|
18988
|
+
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.",
|
|
18989
|
+
deviceType: DeviceType.Light,
|
|
18990
|
+
outputCap: "switch",
|
|
18991
|
+
commandCaps: [
|
|
18992
|
+
"switch",
|
|
18993
|
+
"brightness",
|
|
18994
|
+
"color"
|
|
18995
|
+
]
|
|
18996
|
+
})
|
|
18997
|
+
];
|
|
18998
|
+
function actuator(input) {
|
|
18999
|
+
return {
|
|
19000
|
+
...input,
|
|
19001
|
+
family: "actuator",
|
|
19002
|
+
role: void 0,
|
|
19003
|
+
memberDeviceType: input.deviceType,
|
|
19004
|
+
outputField: "on",
|
|
19005
|
+
quantity: "none",
|
|
19006
|
+
baseUnit: void 0,
|
|
19007
|
+
aggregates: BINARY_AGGREGATES,
|
|
19008
|
+
defaultAggregate: "any",
|
|
19009
|
+
empty: "offline",
|
|
19010
|
+
accept: [{
|
|
19011
|
+
cap: "switch",
|
|
19012
|
+
fieldPath: "on"
|
|
19013
|
+
}],
|
|
19014
|
+
companions: [CHANGED]
|
|
19015
|
+
};
|
|
19016
|
+
}
|
|
19017
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
19018
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18631
19019
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18632
19020
|
/**
|
|
18633
19021
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20341,12 +20729,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20341
20729
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20342
20730
|
* in-place so dispatch keeps working.
|
|
20343
20731
|
*
|
|
20344
|
-
* **
|
|
20345
|
-
*
|
|
20346
|
-
*
|
|
20347
|
-
*
|
|
20348
|
-
* (`ha-domain-mapping`)
|
|
20349
|
-
* stored after that point.
|
|
20732
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20733
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20734
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20735
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20736
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20737
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20350
20738
|
*
|
|
20351
20739
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20352
20740
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20360,6 +20748,14 @@ var SourceInfoSchema = object({
|
|
|
20360
20748
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20361
20749
|
* Used to detect rename when `id` changes. */
|
|
20362
20750
|
uniqueId: string().optional(),
|
|
20751
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20752
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20753
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20754
|
+
dateTimeShape: _enum([
|
|
20755
|
+
"date",
|
|
20756
|
+
"time",
|
|
20757
|
+
"datetime"
|
|
20758
|
+
]).optional(),
|
|
20363
20759
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20364
20760
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20365
20761
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41481,7 +41877,8 @@ method(object({
|
|
|
41481
41877
|
"enum"
|
|
41482
41878
|
]),
|
|
41483
41879
|
enumValues: array(string()).optional(),
|
|
41484
|
-
item: boolean().optional()
|
|
41880
|
+
item: boolean().optional(),
|
|
41881
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41485
41882
|
})).readonly(),
|
|
41486
41883
|
itemArray: object({
|
|
41487
41884
|
path: string(),
|
|
@@ -45325,8 +45722,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
45325
45722
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
45326
45723
|
var MaskGridShapeSchema = object({
|
|
45327
45724
|
kind: literal("grid"),
|
|
45328
|
-
gridWidth: number(),
|
|
45329
|
-
gridHeight: number(),
|
|
45725
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45726
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
45330
45727
|
cells: array(boolean())
|
|
45331
45728
|
});
|
|
45332
45729
|
discriminatedUnion("kind", [
|
|
@@ -45438,6 +45835,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45438
45835
|
"detection-blind",
|
|
45439
45836
|
"motion-noisy",
|
|
45440
45837
|
"motion-calm",
|
|
45838
|
+
"package-llm-silent",
|
|
45839
|
+
"package-llm-answered",
|
|
45441
45840
|
"recording-stalled",
|
|
45442
45841
|
"recording-healthy",
|
|
45443
45842
|
"recording-degraded",
|
|
@@ -56529,6 +56928,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56529
56928
|
deprecated: string().optional(),
|
|
56530
56929
|
distTags: array(string()).readonly()
|
|
56531
56930
|
});
|
|
56931
|
+
/**
|
|
56932
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56933
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56934
|
+
* tarball failure — never an empty string standing in for either.
|
|
56935
|
+
*/
|
|
56936
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56937
|
+
object({
|
|
56938
|
+
status: literal("ok"),
|
|
56939
|
+
markdown: string()
|
|
56940
|
+
}),
|
|
56941
|
+
object({ status: literal("missing") }),
|
|
56942
|
+
object({
|
|
56943
|
+
status: literal("error"),
|
|
56944
|
+
message: string()
|
|
56945
|
+
})
|
|
56946
|
+
]);
|
|
56947
|
+
var PackageDocsSchema = object({
|
|
56948
|
+
name: string(),
|
|
56949
|
+
version: string(),
|
|
56950
|
+
readme: PackageDocBodySchema,
|
|
56951
|
+
changelog: PackageDocBodySchema
|
|
56952
|
+
});
|
|
56532
56953
|
var SearchResultSchema = object({
|
|
56533
56954
|
name: string(),
|
|
56534
56955
|
version: string(),
|
|
@@ -56747,7 +57168,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56747
57168
|
}), object({ success: literal(true) }), {
|
|
56748
57169
|
kind: "mutation",
|
|
56749
57170
|
auth: "admin"
|
|
56750
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57171
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57172
|
+
name: string().min(1),
|
|
57173
|
+
version: string().min(1).optional()
|
|
57174
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56751
57175
|
kind: "mutation",
|
|
56752
57176
|
auth: "admin"
|
|
56753
57177
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56806,27 +57230,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56806
57230
|
*/
|
|
56807
57231
|
var AirQualitySensorStatusSchema = object({
|
|
56808
57232
|
/** Carbon dioxide concentration in ppm. */
|
|
56809
|
-
co2Ppm: number().min(0).optional(),
|
|
57233
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56810
57234
|
/** Total volatile organic compounds in ppb. */
|
|
56811
|
-
vocPpb: number().min(0).optional(),
|
|
57235
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56812
57236
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56813
|
-
pm25: number().min(0).optional(),
|
|
57237
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56814
57238
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56815
|
-
pm10: number().min(0).optional(),
|
|
57239
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56816
57240
|
/** Composite AQI value (typically 0..500). */
|
|
56817
|
-
aqi: number().optional(),
|
|
57241
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56818
57242
|
/** Ms epoch when the slice was last updated. */
|
|
56819
|
-
lastFetchedAt: number()
|
|
56820
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56821
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56822
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56823
|
-
* per slice is unambiguous. */
|
|
56824
|
-
unit: string().optional(),
|
|
56825
|
-
/** Suggested decimal places for numeric display.
|
|
56826
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56827
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56828
|
-
* auto-formatting when absent. */
|
|
56829
|
-
precision: number().int().min(0).max(10).optional()
|
|
57243
|
+
lastFetchedAt: number()
|
|
56830
57244
|
});
|
|
56831
57245
|
var airQualitySensorCapability = {
|
|
56832
57246
|
name: "air-quality-sensor",
|
|
@@ -56863,12 +57277,12 @@ var airQualitySensorCapability = {
|
|
|
56863
57277
|
},
|
|
56864
57278
|
pm25: {
|
|
56865
57279
|
kind: "gauge",
|
|
56866
|
-
unit: "
|
|
57280
|
+
unit: "µg/m³",
|
|
56867
57281
|
deadband: 1
|
|
56868
57282
|
},
|
|
56869
57283
|
pm10: {
|
|
56870
57284
|
kind: "gauge",
|
|
56871
|
-
unit: "
|
|
57285
|
+
unit: "µg/m³",
|
|
56872
57286
|
deadband: 1
|
|
56873
57287
|
},
|
|
56874
57288
|
aqi: {
|
|
@@ -56886,22 +57300,13 @@ var airQualitySensorCapability = {
|
|
|
56886
57300
|
* entries with `device_class: illuminance`.
|
|
56887
57301
|
*/
|
|
56888
57302
|
var AmbientLightSensorStatusSchema = object({
|
|
56889
|
-
/** Current illuminance in lux (lx). */
|
|
56890
|
-
lux: number().min(0).meta({
|
|
56891
|
-
|
|
57303
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57304
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57305
|
+
precision: 0,
|
|
56892
57306
|
label: "Illuminance"
|
|
56893
|
-
}),
|
|
57307
|
+
})),
|
|
56894
57308
|
/** Ms epoch when the slice was last updated. */
|
|
56895
|
-
lastFetchedAt: number()
|
|
56896
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56897
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56898
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56899
|
-
unit: string().optional(),
|
|
56900
|
-
/** Suggested decimal places for numeric display.
|
|
56901
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56902
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56903
|
-
* auto-formatting when absent. */
|
|
56904
|
-
precision: number().int().min(0).max(10).optional()
|
|
57309
|
+
lastFetchedAt: number()
|
|
56905
57310
|
});
|
|
56906
57311
|
var ambientLightSensorCapability = {
|
|
56907
57312
|
name: "ambient-light-sensor",
|
|
@@ -56933,12 +57338,7 @@ var ambientLightSensorCapability = {
|
|
|
56933
57338
|
} } },
|
|
56934
57339
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56935
57340
|
* whether persisting is worth a SQLite commit. */
|
|
56936
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56937
|
-
customize: {
|
|
56938
|
-
version: 1,
|
|
56939
|
-
advanced: "derive",
|
|
56940
|
-
targets: []
|
|
56941
|
-
}
|
|
57341
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56942
57342
|
};
|
|
56943
57343
|
/**
|
|
56944
57344
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57165,10 +57565,7 @@ var BatteryStatusSchema = object({
|
|
|
57165
57565
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57166
57566
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57167
57567
|
*/
|
|
57168
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57169
|
-
unit: "%",
|
|
57170
|
-
label: "Charge"
|
|
57171
|
-
}),
|
|
57568
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57172
57569
|
/**
|
|
57173
57570
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57174
57571
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57195,7 +57592,14 @@ var BatteryStatusSchema = object({
|
|
|
57195
57592
|
*/
|
|
57196
57593
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57197
57594
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57198
|
-
lastUpdated: number(),
|
|
57595
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
57596
|
+
/**
|
|
57597
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
57598
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
57599
|
+
* that only report charge. A second reading on this cap, not a second
|
|
57600
|
+
* `numeric-sensor` on the same device.
|
|
57601
|
+
*/
|
|
57602
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57199
57603
|
/**
|
|
57200
57604
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57201
57605
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57247,7 +57651,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57247
57651
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57248
57652
|
var batteryCustomize = {
|
|
57249
57653
|
version: 1,
|
|
57250
|
-
advanced: "derive",
|
|
57251
57654
|
targets: [{
|
|
57252
57655
|
id: "percentage",
|
|
57253
57656
|
cardinality: "scalar",
|
|
@@ -57256,7 +57659,7 @@ var batteryCustomize = {
|
|
|
57256
57659
|
stateField: "percentage"
|
|
57257
57660
|
},
|
|
57258
57661
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57259
|
-
apply: "add
|
|
57662
|
+
apply: "add",
|
|
57260
57663
|
path: "percentage",
|
|
57261
57664
|
sources: [{
|
|
57262
57665
|
kind: "field",
|
|
@@ -57377,10 +57780,16 @@ onStatusChanged: { data: object({
|
|
|
57377
57780
|
/**
|
|
57378
57781
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57379
57782
|
*/
|
|
57380
|
-
history: { fields: {
|
|
57381
|
-
|
|
57382
|
-
|
|
57383
|
-
|
|
57783
|
+
history: { fields: {
|
|
57784
|
+
percentage: {
|
|
57785
|
+
kind: "gauge",
|
|
57786
|
+
unit: "%"
|
|
57787
|
+
},
|
|
57788
|
+
volts: {
|
|
57789
|
+
kind: "gauge",
|
|
57790
|
+
unit: "V"
|
|
57791
|
+
}
|
|
57792
|
+
} },
|
|
57384
57793
|
customize: batteryCustomize,
|
|
57385
57794
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57386
57795
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57427,12 +57836,7 @@ var binaryCapability = {
|
|
|
57427
57836
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57428
57837
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57429
57838
|
* whether persisting is worth a SQLite commit. */
|
|
57430
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57431
|
-
customize: {
|
|
57432
|
-
version: 1,
|
|
57433
|
-
advanced: "derive",
|
|
57434
|
-
targets: []
|
|
57435
|
-
}
|
|
57839
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57436
57840
|
};
|
|
57437
57841
|
/**
|
|
57438
57842
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57448,7 +57852,7 @@ var binaryCapability = {
|
|
|
57448
57852
|
*/
|
|
57449
57853
|
var BrightnessStatusSchema = object({
|
|
57450
57854
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57451
|
-
percentage: number().min(0).max(100),
|
|
57855
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57452
57856
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57453
57857
|
lastChangedAt: number()
|
|
57454
57858
|
});
|
|
@@ -57919,21 +58323,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57919
58323
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57920
58324
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57921
58325
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57922
|
-
target: number().nullable(),
|
|
58326
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57923
58327
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57924
58328
|
* in `heat_cool` mode. */
|
|
57925
|
-
targetHigh: number().nullable(),
|
|
58329
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57926
58330
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57927
58331
|
* in `heat_cool` mode. */
|
|
57928
|
-
targetLow: number().nullable(),
|
|
58332
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57929
58333
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57930
58334
|
* humidity control. */
|
|
57931
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58335
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57932
58336
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57933
58337
|
* the device's internal sensor. */
|
|
57934
|
-
currentTemp: number().nullable(),
|
|
58338
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57935
58339
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57936
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58340
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57937
58341
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57938
58342
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57939
58343
|
swingVertical: boolean().nullable(),
|
|
@@ -57941,11 +58345,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57941
58345
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57942
58346
|
swingHorizontal: boolean().nullable(),
|
|
57943
58347
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57944
|
-
minTemp: number().nullable().optional(),
|
|
58348
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57945
58349
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57946
|
-
maxTemp: number().nullable().optional(),
|
|
58350
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57947
58351
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57948
|
-
tempStep: number().positive().nullable().optional(),
|
|
58352
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57949
58353
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57950
58354
|
lastFetchedAt: number()
|
|
57951
58355
|
});
|
|
@@ -58087,17 +58491,17 @@ var climateControlCapability = {
|
|
|
58087
58491
|
* modes to expose in the picker without a slice fetch.
|
|
58088
58492
|
*/
|
|
58089
58493
|
var RgbTripletSchema = object({
|
|
58090
|
-
r: number().int().min(0).max(255),
|
|
58091
|
-
g: number().int().min(0).max(255),
|
|
58092
|
-
b: number().int().min(0).max(255)
|
|
58494
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58495
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
58496
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
58093
58497
|
});
|
|
58094
58498
|
var HsvTripletSchema = object({
|
|
58095
58499
|
/** Hue in degrees, 0..360. */
|
|
58096
|
-
h: number().min(0).max(360),
|
|
58500
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
58097
58501
|
/** Saturation as 0..100 inclusive. */
|
|
58098
|
-
s: number().min(0).max(100),
|
|
58502
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
58099
58503
|
/** Value/brightness as 0..100 inclusive. */
|
|
58100
|
-
v: number().min(0).max(100)
|
|
58504
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
58101
58505
|
});
|
|
58102
58506
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
58103
58507
|
object({
|
|
@@ -58126,7 +58530,7 @@ var ColorStatusSchema = object({
|
|
|
58126
58530
|
/** Populated when `mode === 'hsv'`. */
|
|
58127
58531
|
hsv: HsvTripletSchema.optional(),
|
|
58128
58532
|
/** Populated when `mode === 'mired'`. */
|
|
58129
|
-
mireds: number().int().optional(),
|
|
58533
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58130
58534
|
/** Ms epoch of the last operator-driven change. */
|
|
58131
58535
|
lastChangedAt: number()
|
|
58132
58536
|
});
|
|
@@ -58321,18 +58725,12 @@ _enum([
|
|
|
58321
58725
|
"empty",
|
|
58322
58726
|
"full"
|
|
58323
58727
|
]);
|
|
58324
|
-
/**
|
|
58325
|
-
|
|
58326
|
-
|
|
58327
|
-
"days",
|
|
58328
|
-
"hours",
|
|
58329
|
-
"cycles"
|
|
58330
|
-
]);
|
|
58331
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
58332
|
-
* days). `value` null = unknown (D393). */
|
|
58728
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58729
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58730
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
58333
58731
|
var ConsumableRemainingSchema = object({
|
|
58334
|
-
value: number().min(0).nullable(),
|
|
58335
|
-
|
|
58732
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58733
|
+
kind: ConsumableRemainingKindSchema
|
|
58336
58734
|
});
|
|
58337
58735
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
58338
58736
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -58345,7 +58743,7 @@ var ConsumableItemSchema = object({
|
|
|
58345
58743
|
/** Display name. */
|
|
58346
58744
|
label: string().min(1),
|
|
58347
58745
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
58348
|
-
level: number().min(0).max(100).nullable(),
|
|
58746
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58349
58747
|
/** The provider's discrete verdict when known (binary mode). */
|
|
58350
58748
|
status: ConsumableStatusSchema.nullable(),
|
|
58351
58749
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58427,8 +58825,8 @@ var consumablesCustomize = {
|
|
|
58427
58825
|
transforms: [{ kind: "identity" }]
|
|
58428
58826
|
}],
|
|
58429
58827
|
literals: [{
|
|
58430
|
-
path: "remaining.
|
|
58431
|
-
values: [...
|
|
58828
|
+
path: "remaining.kind",
|
|
58829
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58432
58830
|
}]
|
|
58433
58831
|
},
|
|
58434
58832
|
{
|
|
@@ -58557,7 +58955,6 @@ reset: method(object({
|
|
|
58557
58955
|
},
|
|
58558
58956
|
"remaining.value": {
|
|
58559
58957
|
kind: "gauge",
|
|
58560
|
-
unitFrom: "remaining.unit",
|
|
58561
58958
|
deadband: 1,
|
|
58562
58959
|
displayName: "Remaining"
|
|
58563
58960
|
}
|
|
@@ -58627,10 +59024,9 @@ var contactCapability = {
|
|
|
58627
59024
|
* (empty array for the other kinds). It lives in the slice because
|
|
58628
59025
|
* HA `select.*` entities may update their options at runtime.
|
|
58629
59026
|
*
|
|
58630
|
-
*
|
|
58631
|
-
*
|
|
58632
|
-
*
|
|
58633
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
59027
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
59028
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
59029
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58634
59030
|
*/
|
|
58635
59031
|
var ControlStatusSchema = object({
|
|
58636
59032
|
kind: _enum([
|
|
@@ -58642,39 +59038,17 @@ var ControlStatusSchema = object({
|
|
|
58642
59038
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58643
59039
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58644
59040
|
* or time-only — HA accepts all three forms). */
|
|
58645
|
-
value: union([number(), string()]),
|
|
59041
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58646
59042
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58647
59043
|
options: array(string()),
|
|
58648
59044
|
/** Ms epoch when the slice was last updated. */
|
|
58649
59045
|
lastChangedAt: number(),
|
|
58650
|
-
/**
|
|
58651
|
-
|
|
58652
|
-
|
|
58653
|
-
|
|
58654
|
-
/**
|
|
58655
|
-
|
|
58656
|
-
min: number().optional(),
|
|
58657
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58658
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58659
|
-
max: number().optional(),
|
|
58660
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58661
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58662
|
-
step: number().optional(),
|
|
58663
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58664
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58665
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58666
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58667
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58668
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58669
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58670
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58671
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58672
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58673
|
-
format: _enum([
|
|
58674
|
-
"date",
|
|
58675
|
-
"time",
|
|
58676
|
-
"datetime"
|
|
58677
|
-
]).optional()
|
|
59046
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
59047
|
+
min: number().optional().meta(readingMeta("device")),
|
|
59048
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
59049
|
+
max: number().optional().meta(readingMeta("device")),
|
|
59050
|
+
/** Step increment, in the device quantity's base unit. */
|
|
59051
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58678
59052
|
});
|
|
58679
59053
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58680
59054
|
object({
|
|
@@ -58740,9 +59114,9 @@ var CoverStatusSchema = object({
|
|
|
58740
59114
|
]),
|
|
58741
59115
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58742
59116
|
* no intermediate position surface. */
|
|
58743
|
-
position: number().min(0).max(100).nullable(),
|
|
59117
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58744
59118
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58745
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
59119
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58746
59120
|
/** Ms epoch when the slice was last updated. */
|
|
58747
59121
|
lastChangedAt: number()
|
|
58748
59122
|
});
|
|
@@ -58845,9 +59219,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58845
59219
|
var DayNightStatusSchema = object({
|
|
58846
59220
|
mode: DayNightModeSchema,
|
|
58847
59221
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58848
|
-
sensitivity: number().optional(),
|
|
59222
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58849
59223
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58850
|
-
switchDelaySec: number().optional(),
|
|
59224
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58851
59225
|
lastFetchedAt: number()
|
|
58852
59226
|
});
|
|
58853
59227
|
/**
|
|
@@ -59065,11 +59439,11 @@ var DishwasherStatusSchema = object({
|
|
|
59065
59439
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59066
59440
|
availablePrograms: array(string()),
|
|
59067
59441
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59068
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
59442
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59069
59443
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59070
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
59444
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59071
59445
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59072
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59446
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59073
59447
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59074
59448
|
doorOpen: boolean().nullable(),
|
|
59075
59449
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59093,7 +59467,7 @@ var DishwasherStatusSchema = object({
|
|
|
59093
59467
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
59094
59468
|
machineCareDue: boolean().nullable(),
|
|
59095
59469
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
59096
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
59470
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
59097
59471
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
59098
59472
|
halfLoad: boolean().nullable(),
|
|
59099
59473
|
hygienePlus: boolean().nullable(),
|
|
@@ -59108,7 +59482,7 @@ var DishwasherStatusSchema = object({
|
|
|
59108
59482
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
59109
59483
|
activeEvents: array(string()),
|
|
59110
59484
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
59111
|
-
errorCode: number().nullable(),
|
|
59485
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
59112
59486
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
59113
59487
|
errorLabel: string().nullable(),
|
|
59114
59488
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -59339,7 +59713,7 @@ var DoorbellStatusSchema = object({
|
|
|
59339
59713
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
59340
59714
|
lastPressedAt: number().nullable(),
|
|
59341
59715
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
59342
|
-
pressCountSinceStart: number()
|
|
59716
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
59343
59717
|
});
|
|
59344
59718
|
var DoorbellPressEventSchema = object({
|
|
59345
59719
|
deviceId: number(),
|
|
@@ -59404,17 +59778,7 @@ onPressed: {
|
|
|
59404
59778
|
history: "none",
|
|
59405
59779
|
customize: doorbellCustomize
|
|
59406
59780
|
};
|
|
59407
|
-
|
|
59408
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59409
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59410
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59411
|
-
* The option set is stable across observations; it is persisted in the
|
|
59412
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59413
|
-
* stored in `sourceInfo`.
|
|
59414
|
-
*/
|
|
59415
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59416
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59417
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59781
|
+
_enum([
|
|
59418
59782
|
"date",
|
|
59419
59783
|
"time",
|
|
59420
59784
|
"datetime"
|
|
@@ -59422,12 +59786,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59422
59786
|
var EnumSensorStatusSchema = object({
|
|
59423
59787
|
value: string(),
|
|
59424
59788
|
/**
|
|
59425
|
-
* Set
|
|
59426
|
-
* as
|
|
59427
|
-
*
|
|
59428
|
-
* a time-only sensor → `'time'`.
|
|
59789
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59790
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59791
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59429
59792
|
*/
|
|
59430
|
-
|
|
59793
|
+
timestamp: boolean().optional(),
|
|
59431
59794
|
/** Ms epoch when the slice was last updated. */
|
|
59432
59795
|
lastFetchedAt: number()
|
|
59433
59796
|
});
|
|
@@ -59454,11 +59817,11 @@ var enumSensorCapability = {
|
|
|
59454
59817
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59455
59818
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59456
59819
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59457
|
-
* `
|
|
59820
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59458
59821
|
*/
|
|
59459
59822
|
history: { fields: { value: {
|
|
59460
59823
|
kind: "enum",
|
|
59461
|
-
skipWhenSet: "
|
|
59824
|
+
skipWhenSet: "timestamp"
|
|
59462
59825
|
} } },
|
|
59463
59826
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59464
59827
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59478,13 +59841,13 @@ var EventFireSchema = object({
|
|
|
59478
59841
|
deviceId: number(),
|
|
59479
59842
|
eventType: string(),
|
|
59480
59843
|
data: record(string(), unknown()).nullable(),
|
|
59481
|
-
timestamp: number(),
|
|
59482
|
-
seq: number()
|
|
59844
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59845
|
+
seq: number().meta(readingMeta("count"))
|
|
59483
59846
|
});
|
|
59484
59847
|
var EventEmitterStatusSchema = object({
|
|
59485
59848
|
eventTypes: array(string()),
|
|
59486
59849
|
lastEvent: EventFireSchema.nullable(),
|
|
59487
|
-
eventCountSinceStart: number()
|
|
59850
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59488
59851
|
});
|
|
59489
59852
|
var eventEmitterCapability = {
|
|
59490
59853
|
name: "event-emitter",
|
|
@@ -59897,10 +60260,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59897
60260
|
var FanControlStatusSchema = object({
|
|
59898
60261
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59899
60262
|
* speed surface (single-speed fan). */
|
|
59900
|
-
percentage: number().min(0).max(100).nullable(),
|
|
60263
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59901
60264
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59902
60265
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59903
|
-
percentageStep: number().positive().optional(),
|
|
60266
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59904
60267
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59905
60268
|
* — empty string when no preset is active or supported. */
|
|
59906
60269
|
preset: string(),
|
|
@@ -60021,7 +60384,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
60021
60384
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
60022
60385
|
model: string().nullable(),
|
|
60023
60386
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
60024
|
-
channelCount: number().nullable(),
|
|
60387
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
60025
60388
|
/**
|
|
60026
60389
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
60027
60390
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -60144,9 +60507,91 @@ var gasCapability = {
|
|
|
60144
60507
|
* whether persisting is worth a SQLite commit. */
|
|
60145
60508
|
volatileStateFields: ["lastChangedAt"]
|
|
60146
60509
|
};
|
|
60510
|
+
var GroupCommandsSchema = object({
|
|
60511
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60512
|
+
results: array(object({
|
|
60513
|
+
deviceId: number().int().nonnegative(),
|
|
60514
|
+
cap: string().min(1),
|
|
60515
|
+
method: string().min(1),
|
|
60516
|
+
ok: boolean(),
|
|
60517
|
+
error: string().optional(),
|
|
60518
|
+
/** Ms epoch of the attempt. */
|
|
60519
|
+
at: number()
|
|
60520
|
+
})) });
|
|
60521
|
+
var groupCommandsCapability = {
|
|
60522
|
+
name: "group-commands",
|
|
60523
|
+
scope: "device",
|
|
60524
|
+
deviceNative: true,
|
|
60525
|
+
mode: "singleton",
|
|
60526
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60527
|
+
methods: {},
|
|
60528
|
+
status: {
|
|
60529
|
+
schema: GroupCommandsSchema,
|
|
60530
|
+
kind: "push"
|
|
60531
|
+
},
|
|
60532
|
+
runtimeState: GroupCommandsSchema,
|
|
60533
|
+
/**
|
|
60534
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60535
|
+
* failure would outlive the command that caused it.
|
|
60536
|
+
*
|
|
60537
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60538
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60539
|
+
*/
|
|
60540
|
+
durability: "session",
|
|
60541
|
+
history: "none"
|
|
60542
|
+
};
|
|
60543
|
+
/**
|
|
60544
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60545
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60546
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60547
|
+
* series that later statistics read is the output cap's own history block.
|
|
60548
|
+
*/
|
|
60549
|
+
var GroupStatusSchema = object({
|
|
60550
|
+
/** Members whose current value entered the aggregate. */
|
|
60551
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60552
|
+
precision: 0,
|
|
60553
|
+
label: "Reporting"
|
|
60554
|
+
})),
|
|
60555
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60556
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60557
|
+
precision: 0,
|
|
60558
|
+
label: "Excluded"
|
|
60559
|
+
})),
|
|
60560
|
+
/** `included` + `excluded`. */
|
|
60561
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60562
|
+
precision: 0,
|
|
60563
|
+
label: "Members"
|
|
60564
|
+
}))
|
|
60565
|
+
});
|
|
60566
|
+
var groupStatusCapability = {
|
|
60567
|
+
name: "group-status",
|
|
60568
|
+
scope: "device",
|
|
60569
|
+
deviceNative: true,
|
|
60570
|
+
mode: "singleton",
|
|
60571
|
+
deviceTypes: [
|
|
60572
|
+
DeviceType.Sensor,
|
|
60573
|
+
DeviceType.Switch,
|
|
60574
|
+
DeviceType.Light
|
|
60575
|
+
],
|
|
60576
|
+
methods: {},
|
|
60577
|
+
status: {
|
|
60578
|
+
schema: GroupStatusSchema,
|
|
60579
|
+
kind: "push"
|
|
60580
|
+
},
|
|
60581
|
+
runtimeState: GroupStatusSchema,
|
|
60582
|
+
/**
|
|
60583
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60584
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60585
|
+
*
|
|
60586
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60587
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60588
|
+
*/
|
|
60589
|
+
durability: "session",
|
|
60590
|
+
history: "none"
|
|
60591
|
+
};
|
|
60147
60592
|
var HeatingValveStatusSchema = object({
|
|
60148
60593
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60149
|
-
position: number().min(0).max(100).nullable(),
|
|
60594
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60150
60595
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
60151
60596
|
lastFetchedAt: number()
|
|
60152
60597
|
});
|
|
@@ -60189,9 +60634,9 @@ var HumidifierStatusSchema = object({
|
|
|
60189
60634
|
/** Whether the humidifier is currently on. */
|
|
60190
60635
|
on: boolean(),
|
|
60191
60636
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60192
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60637
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60193
60638
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60194
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60639
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60195
60640
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60196
60641
|
* device has no mode surface. */
|
|
60197
60642
|
mode: string().nullable(),
|
|
@@ -60201,9 +60646,9 @@ var HumidifierStatusSchema = object({
|
|
|
60201
60646
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60202
60647
|
action: string().nullable(),
|
|
60203
60648
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60204
|
-
minHumidity: number().nullable(),
|
|
60649
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60205
60650
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60206
|
-
maxHumidity: number().nullable(),
|
|
60651
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60207
60652
|
/** Ms epoch when the slice was last updated. */
|
|
60208
60653
|
lastChangedAt: number()
|
|
60209
60654
|
});
|
|
@@ -60273,22 +60718,13 @@ var humidifierCapability = {
|
|
|
60273
60718
|
* `sourceInfo`.
|
|
60274
60719
|
*/
|
|
60275
60720
|
var HumiditySensorStatusSchema = object({
|
|
60276
|
-
/** Current relative humidity, 0..100. */
|
|
60277
|
-
percent: number().min(0).max(100).meta({
|
|
60278
|
-
|
|
60721
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60722
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60723
|
+
precision: 0,
|
|
60279
60724
|
label: "Humidity"
|
|
60280
|
-
}),
|
|
60725
|
+
})),
|
|
60281
60726
|
/** Ms epoch when the slice was last updated. */
|
|
60282
|
-
lastFetchedAt: number()
|
|
60283
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60284
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60285
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60286
|
-
unit: string().optional(),
|
|
60287
|
-
/** Suggested decimal places for numeric display.
|
|
60288
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60289
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60290
|
-
* auto-formatting when absent. */
|
|
60291
|
-
precision: number().int().min(0).max(10).optional()
|
|
60727
|
+
lastFetchedAt: number()
|
|
60292
60728
|
});
|
|
60293
60729
|
var humiditySensorCapability = {
|
|
60294
60730
|
name: "humidity-sensor",
|
|
@@ -60319,12 +60755,7 @@ var humiditySensorCapability = {
|
|
|
60319
60755
|
} } },
|
|
60320
60756
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60321
60757
|
* whether persisting is worth a SQLite commit. */
|
|
60322
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60323
|
-
customize: {
|
|
60324
|
-
version: 1,
|
|
60325
|
-
advanced: "derive",
|
|
60326
|
-
targets: []
|
|
60327
|
-
}
|
|
60758
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60328
60759
|
};
|
|
60329
60760
|
/**
|
|
60330
60761
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -60345,7 +60776,7 @@ var ImageStatusSchema = object({
|
|
|
60345
60776
|
* entity exposes no `entity_picture` (yet). */
|
|
60346
60777
|
url: string().nullable(),
|
|
60347
60778
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
60348
|
-
lastUpdated: number().nullable()
|
|
60779
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
60349
60780
|
});
|
|
60350
60781
|
var imageCapability = {
|
|
60351
60782
|
name: "image",
|
|
@@ -60433,19 +60864,19 @@ var NormalizedRangeSchema = object({
|
|
|
60433
60864
|
*/
|
|
60434
60865
|
var ImageSettingsStatusSchema = object({
|
|
60435
60866
|
/** Normalized 0–100. */
|
|
60436
|
-
brightness: number().optional(),
|
|
60867
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60437
60868
|
/** Normalized 0–100. */
|
|
60438
|
-
contrast: number().optional(),
|
|
60869
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60439
60870
|
/** Normalized 0–100. */
|
|
60440
|
-
saturation: number().optional(),
|
|
60871
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60441
60872
|
/** Normalized 0–100. */
|
|
60442
|
-
sharpness: number().optional(),
|
|
60873
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60443
60874
|
mirror: boolean().optional(),
|
|
60444
60875
|
flip: boolean().optional(),
|
|
60445
60876
|
rotate: ImageRotateSchema.optional(),
|
|
60446
60877
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60447
60878
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60448
|
-
warmth: number().optional(),
|
|
60879
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60449
60880
|
exposureMode: ExposureModeSchema.optional(),
|
|
60450
60881
|
backlightMode: BacklightModeSchema.optional(),
|
|
60451
60882
|
lastFetchedAt: number()
|
|
@@ -60724,10 +61155,10 @@ var IntercomAbilitySchema = object({
|
|
|
60724
61155
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60725
61156
|
codecs: array(string()),
|
|
60726
61157
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60727
|
-
sampleRate: number(),
|
|
61158
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60728
61159
|
duplex: _enum(["half", "full"]),
|
|
60729
61160
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60730
|
-
maxBacklogMs: number()
|
|
61161
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60731
61162
|
});
|
|
60732
61163
|
var IntercomStatusSchema = object({
|
|
60733
61164
|
/** True while a talk session is open. */
|
|
@@ -60954,13 +61385,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60954
61385
|
activity: LawnMowerActivitySchema,
|
|
60955
61386
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60956
61387
|
* reading. */
|
|
60957
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
61388
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60958
61389
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60959
61390
|
* task is active / progress is unavailable. */
|
|
60960
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61391
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60961
61392
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60962
61393
|
* or null when unknown. */
|
|
60963
|
-
currentCode: number().nullable(),
|
|
61394
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60964
61395
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60965
61396
|
currentCodeLabel: string().nullable(),
|
|
60966
61397
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61493,7 +61924,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61493
61924
|
state: MediaPlayerStateSchema,
|
|
61494
61925
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61495
61926
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61496
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61927
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61497
61928
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61498
61929
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61499
61930
|
isMuted: boolean().nullable(),
|
|
@@ -61506,10 +61937,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61506
61937
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61507
61938
|
/** Current playback position in ms. Null when not seekable or
|
|
61508
61939
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61509
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61940
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61510
61941
|
/** Total duration of the current media in ms. Null when unknown
|
|
61511
61942
|
* (live stream) or nothing is playing. */
|
|
61512
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61943
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61513
61944
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61514
61945
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61515
61946
|
shuffle: boolean().nullable(),
|
|
@@ -61818,7 +62249,7 @@ var motionCustomize = {
|
|
|
61818
62249
|
eventName: "onMotionChanged"
|
|
61819
62250
|
},
|
|
61820
62251
|
deviceTypes: [DeviceType.Camera],
|
|
61821
|
-
apply: "
|
|
62252
|
+
apply: "add",
|
|
61822
62253
|
applyAuthority: {
|
|
61823
62254
|
kind: "camera-sensors",
|
|
61824
62255
|
timeoutField: "motionCooldownMs"
|
|
@@ -61890,7 +62321,7 @@ var MotionStatusSchema = object({
|
|
|
61890
62321
|
* it, every provider seeded it at boot, and every session left it
|
|
61891
62322
|
* `detected: true` after its detach.
|
|
61892
62323
|
*/
|
|
61893
|
-
autoClearAfterMs: number().nullable()
|
|
62324
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61894
62325
|
});
|
|
61895
62326
|
/**
|
|
61896
62327
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61927,12 +62358,18 @@ var motionCapability = {
|
|
|
61927
62358
|
methods: {
|
|
61928
62359
|
/**
|
|
61929
62360
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61930
|
-
* for consumers that don't need the full status object
|
|
61931
|
-
*
|
|
61932
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61933
|
-
* consumer.
|
|
62361
|
+
* for consumers that don't need the full status object. A composed
|
|
62362
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61934
62363
|
*/
|
|
61935
62364
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62365
|
+
/**
|
|
62366
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62367
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62368
|
+
*/
|
|
62369
|
+
composedMethods: { isDetected: {
|
|
62370
|
+
kind: "slice",
|
|
62371
|
+
field: "detected"
|
|
62372
|
+
} },
|
|
61936
62373
|
events: {
|
|
61937
62374
|
/**
|
|
61938
62375
|
* Fires every time the runner transitions a camera between
|
|
@@ -62072,7 +62509,7 @@ var MotionZoneRegionSchema = object({
|
|
|
62072
62509
|
* the grid region(s). */
|
|
62073
62510
|
var MotionZoneStatusSchema = object({
|
|
62074
62511
|
enabled: boolean(),
|
|
62075
|
-
sensitivity: number(),
|
|
62512
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
62076
62513
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
62077
62514
|
regions: array(MotionZoneRegionSchema),
|
|
62078
62515
|
lastFetchedAt: number()
|
|
@@ -62442,7 +62879,7 @@ var NavigationStatusSchema = object({
|
|
|
62442
62879
|
following: boolean(),
|
|
62443
62880
|
flash: boolean(),
|
|
62444
62881
|
lightMode: NavigationLightModeSchema,
|
|
62445
|
-
lightLevel: number().min(40).max(100),
|
|
62882
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62446
62883
|
/** Ms epoch when the slice was last updated. */
|
|
62447
62884
|
lastChangedAt: number()
|
|
62448
62885
|
});
|
|
@@ -62576,13 +63013,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62576
63013
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62577
63014
|
* SKIP a null rather than coerce it.
|
|
62578
63015
|
*/
|
|
62579
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
63016
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62580
63017
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62581
|
-
rssiDbm: number().optional(),
|
|
63018
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62582
63019
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62583
63020
|
ssid: string().optional(),
|
|
62584
63021
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62585
|
-
lastUpdated: number()
|
|
63022
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62586
63023
|
});
|
|
62587
63024
|
var networkLinkCapability = {
|
|
62588
63025
|
name: "network-link",
|
|
@@ -62967,7 +63404,7 @@ var NotifierStatusSchema = object({
|
|
|
62967
63404
|
lastError: string().nullable(),
|
|
62968
63405
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62969
63406
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62970
|
-
queueDepth: number().int().nonnegative(),
|
|
63407
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62971
63408
|
/** Per-feature capability matrix — authoritative source for the
|
|
62972
63409
|
* compose-form field gating. */
|
|
62973
63410
|
supports: NotifierSupportsSchema
|
|
@@ -63059,11 +63496,9 @@ onSent: { data: object({
|
|
|
63059
63496
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
63060
63497
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
63061
63498
|
*
|
|
63062
|
-
* The
|
|
63063
|
-
*
|
|
63064
|
-
*
|
|
63065
|
-
* The UI reads them directly from the slice — they are the single source
|
|
63066
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
63499
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
63500
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
63501
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
63067
63502
|
*
|
|
63068
63503
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
63069
63504
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -63072,15 +63507,8 @@ onSent: { data: object({
|
|
|
63072
63507
|
* numeric values land here.
|
|
63073
63508
|
*/
|
|
63074
63509
|
var NumericSensorStatusSchema = object({
|
|
63075
|
-
|
|
63076
|
-
|
|
63077
|
-
* Populated live from the upstream source on each state push.
|
|
63078
|
-
* Absent for unitless sensors. */
|
|
63079
|
-
unit: string().optional(),
|
|
63080
|
-
/** Suggested decimal places for numeric display.
|
|
63081
|
-
* Populated live from the upstream source when provided.
|
|
63082
|
-
* Falls back to auto-formatting when absent. */
|
|
63083
|
-
precision: number().int().min(0).max(10).optional(),
|
|
63510
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
63511
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
63084
63512
|
/** Ms epoch when the slice was last updated. */
|
|
63085
63513
|
lastFetchedAt: number()
|
|
63086
63514
|
});
|
|
@@ -63104,11 +63532,11 @@ var numericSensorCapability = {
|
|
|
63104
63532
|
*/
|
|
63105
63533
|
durability: "restored",
|
|
63106
63534
|
/**
|
|
63107
|
-
* History (D850): recorded series. The unit is
|
|
63535
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
63536
|
+
* resolved when the series is read — the cap has no single unit.
|
|
63108
63537
|
*/
|
|
63109
63538
|
history: { fields: { value: {
|
|
63110
63539
|
kind: "gauge",
|
|
63111
|
-
unitFrom: "unit",
|
|
63112
63540
|
minIntervalMs: 3e4
|
|
63113
63541
|
} } },
|
|
63114
63542
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63400,23 +63828,26 @@ var PetFeederStatusSchema = object({
|
|
|
63400
63828
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63401
63829
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63402
63830
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63403
|
-
foodLevel: number().nullable(),
|
|
63831
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63404
63832
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63405
63833
|
* single-hopper models. */
|
|
63406
|
-
food1: number().nullable(),
|
|
63834
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63407
63835
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63408
63836
|
* single-hopper models. */
|
|
63409
|
-
food2: number().nullable(),
|
|
63837
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63410
63838
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63411
63839
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63412
63840
|
* below the feeder's low threshold. */
|
|
63413
63841
|
lowFood: boolean(),
|
|
63414
63842
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63415
63843
|
* device has no battery reading. */
|
|
63416
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63417
|
-
/**
|
|
63418
|
-
*
|
|
63419
|
-
|
|
63844
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63845
|
+
/**
|
|
63846
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63847
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63848
|
+
* model has no desiccant sensor.
|
|
63849
|
+
*/
|
|
63850
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63420
63851
|
/** True while a feed is in progress. */
|
|
63421
63852
|
feeding: boolean(),
|
|
63422
63853
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63427,7 +63858,7 @@ var PetFeederStatusSchema = object({
|
|
|
63427
63858
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63428
63859
|
error: string().nullable(),
|
|
63429
63860
|
/** Raw device error code (0 / null = no error). */
|
|
63430
|
-
errorCode: number().nullable(),
|
|
63861
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63431
63862
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63432
63863
|
isDualHopper: boolean(),
|
|
63433
63864
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63437,7 +63868,7 @@ var PetFeederStatusSchema = object({
|
|
|
63437
63868
|
/** Play a chime when dispensing. */
|
|
63438
63869
|
feedSound: boolean(),
|
|
63439
63870
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63440
|
-
volume: number(),
|
|
63871
|
+
volume: number().meta(readingMeta("none")),
|
|
63441
63872
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63442
63873
|
lastFetchedAt: number()
|
|
63443
63874
|
});
|
|
@@ -63556,7 +63987,7 @@ var petFeederCapability = {
|
|
|
63556
63987
|
},
|
|
63557
63988
|
desiccantLeftDays: {
|
|
63558
63989
|
kind: "gauge",
|
|
63559
|
-
unit: "
|
|
63990
|
+
unit: "s"
|
|
63560
63991
|
}
|
|
63561
63992
|
} }
|
|
63562
63993
|
};
|
|
@@ -63957,36 +64388,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63957
64388
|
*/
|
|
63958
64389
|
var PowerMeterStatusSchema = object({
|
|
63959
64390
|
/** Instantaneous power draw in watts. */
|
|
63960
|
-
watts: number().optional().meta({
|
|
63961
|
-
unit: "W",
|
|
63962
|
-
label: "Power"
|
|
63963
|
-
}),
|
|
64391
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63964
64392
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63965
|
-
kwhTotal: number().optional().meta({
|
|
63966
|
-
unit: "kWh",
|
|
63967
|
-
label: "Energy"
|
|
63968
|
-
}),
|
|
64393
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63969
64394
|
/** Voltage in volts. */
|
|
63970
|
-
volts: number().optional(),
|
|
64395
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63971
64396
|
/** Current in amperes. */
|
|
63972
|
-
amps: number().optional(),
|
|
63973
|
-
/** Apparent power in volt-amperes
|
|
63974
|
-
va: number().optional(),
|
|
64397
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
64398
|
+
/** Apparent power in volt-amperes. */
|
|
64399
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63975
64400
|
/** Power factor (0..1) if reported. */
|
|
63976
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
64401
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63977
64402
|
/** Ms epoch when the slice was last updated. */
|
|
63978
|
-
lastFetchedAt: number()
|
|
63979
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63980
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63981
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63982
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63983
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63984
|
-
unit: string().optional(),
|
|
63985
|
-
/** Suggested decimal places for numeric display.
|
|
63986
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63987
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63988
|
-
* auto-formatting when absent. */
|
|
63989
|
-
precision: number().int().min(0).max(10).optional()
|
|
64403
|
+
lastFetchedAt: number()
|
|
63990
64404
|
});
|
|
63991
64405
|
var powerMeterCapability = {
|
|
63992
64406
|
name: "power-meter",
|
|
@@ -64050,12 +64464,7 @@ var powerMeterCapability = {
|
|
|
64050
64464
|
} },
|
|
64051
64465
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64052
64466
|
* whether persisting is worth a SQLite commit. */
|
|
64053
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
64054
|
-
customize: {
|
|
64055
|
-
version: 1,
|
|
64056
|
-
advanced: "derive",
|
|
64057
|
-
targets: []
|
|
64058
|
-
}
|
|
64467
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
64059
64468
|
};
|
|
64060
64469
|
/**
|
|
64061
64470
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -64075,11 +64484,11 @@ var powerMeterCapability = {
|
|
|
64075
64484
|
*/
|
|
64076
64485
|
var GpsLocationSchema = object({
|
|
64077
64486
|
/** Latitude in decimal degrees, -90..90. */
|
|
64078
|
-
latitude: number().min(-90).max(90),
|
|
64487
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
64079
64488
|
/** Longitude in decimal degrees, -180..180. */
|
|
64080
|
-
longitude: number().min(-180).max(180),
|
|
64489
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
64081
64490
|
/** Reported accuracy in meters (lower = better). */
|
|
64082
|
-
accuracyMeters: number().nonnegative()
|
|
64491
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
64083
64492
|
});
|
|
64084
64493
|
var PresenceStatusSchema = object({
|
|
64085
64494
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -64091,7 +64500,7 @@ var PresenceStatusSchema = object({
|
|
|
64091
64500
|
gps: GpsLocationSchema.nullable(),
|
|
64092
64501
|
/** Optional battery level of the tracking device (0..100). Null
|
|
64093
64502
|
* when not reported. */
|
|
64094
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
64503
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64095
64504
|
/** Ms epoch when the slice was last updated. */
|
|
64096
64505
|
lastChangedAt: number()
|
|
64097
64506
|
});
|
|
@@ -64141,19 +64550,10 @@ var presenceCapability = {
|
|
|
64141
64550
|
* `sourceInfo`.
|
|
64142
64551
|
*/
|
|
64143
64552
|
var PressureSensorStatusSchema = object({
|
|
64144
|
-
/** Current pressure in hPa. */
|
|
64145
|
-
hpa: number(),
|
|
64553
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64554
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64146
64555
|
/** Ms epoch when the slice was last updated. */
|
|
64147
|
-
lastFetchedAt: number()
|
|
64148
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64149
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64150
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
64151
|
-
unit: string().optional(),
|
|
64152
|
-
/** Suggested decimal places for numeric display.
|
|
64153
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64154
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64155
|
-
* auto-formatting when absent. */
|
|
64156
|
-
precision: number().int().min(0).max(10).optional()
|
|
64556
|
+
lastFetchedAt: number()
|
|
64157
64557
|
});
|
|
64158
64558
|
var pressureSensorCapability = {
|
|
64159
64559
|
name: "pressure-sensor",
|
|
@@ -64567,8 +64967,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64567
64967
|
}), _void(), { kind: "mutation" });
|
|
64568
64968
|
var PtzAutotrackSettingsSchema = object({
|
|
64569
64969
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64570
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64571
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64970
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64971
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64572
64972
|
});
|
|
64573
64973
|
/**
|
|
64574
64974
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64722,7 +65122,7 @@ var RunningStateStatusSchema = object({
|
|
|
64722
65122
|
/** null = unknown — never coerced to false (D393). */
|
|
64723
65123
|
running: boolean().nullable(),
|
|
64724
65124
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64725
|
-
since: number().nullable(),
|
|
65125
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64726
65126
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64727
65127
|
phase: string().nullable(),
|
|
64728
65128
|
/** null until a reading has been published (D393). */
|
|
@@ -64737,7 +65137,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64737
65137
|
/** Generic Customize target for the running boolean (D936). */
|
|
64738
65138
|
var runningCustomize = {
|
|
64739
65139
|
version: 1,
|
|
64740
|
-
advanced: "derive",
|
|
64741
65140
|
targets: [{
|
|
64742
65141
|
id: "running",
|
|
64743
65142
|
cardinality: "scalar",
|
|
@@ -64757,7 +65156,7 @@ var runningCustomize = {
|
|
|
64757
65156
|
DeviceType.Thermostat,
|
|
64758
65157
|
DeviceType.PetFeeder
|
|
64759
65158
|
],
|
|
64760
|
-
apply: "add
|
|
65159
|
+
apply: "add",
|
|
64761
65160
|
path: "running",
|
|
64762
65161
|
sources: [
|
|
64763
65162
|
{
|
|
@@ -66021,9 +66420,9 @@ var RecordTriggerSchema = _enum([
|
|
|
66021
66420
|
*/
|
|
66022
66421
|
var RecordWindowSchema = object({
|
|
66023
66422
|
trigger: RecordTriggerSchema,
|
|
66024
|
-
day: number().int().min(0).max(6),
|
|
66025
|
-
startMinute: number().int().min(0).max(1439),
|
|
66026
|
-
endMinute: number().int().min(1).max(1440)
|
|
66423
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
66424
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
66425
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
66027
66426
|
});
|
|
66028
66427
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
66029
66428
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -66099,10 +66498,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
66099
66498
|
/** Master "record to the card at all" switch. */
|
|
66100
66499
|
enabled: boolean().nullable(),
|
|
66101
66500
|
overwriteWhenFull: boolean().nullable(),
|
|
66102
|
-
preRecordSec: number().nullable(),
|
|
66103
|
-
postRecordSec: number().nullable(),
|
|
66501
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66502
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
66104
66503
|
/** Length of one recorded file, in minutes. */
|
|
66105
|
-
segmentMinutes: number().nullable(),
|
|
66504
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
66106
66505
|
/** The primary track's weekly windows, flattened. */
|
|
66107
66506
|
windows: array(RecordWindowSchema),
|
|
66108
66507
|
/**
|
|
@@ -66118,7 +66517,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
66118
66517
|
* provider reporting a non-zero count also reports the schedule as not
|
|
66119
66518
|
* writable.
|
|
66120
66519
|
*/
|
|
66121
|
-
unreadableWindows: number(),
|
|
66520
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
66122
66521
|
/**
|
|
66123
66522
|
* The camera is scheduled to record and has NO usable storage.
|
|
66124
66523
|
*
|
|
@@ -66963,7 +67362,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66963
67362
|
url: string().optional(),
|
|
66964
67363
|
codec: string().optional(),
|
|
66965
67364
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66966
|
-
fps: number().positive().optional(),
|
|
67365
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66967
67366
|
label: string().optional(),
|
|
66968
67367
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66969
67368
|
deviceFeatures: array(string()).optional(),
|
|
@@ -67050,18 +67449,18 @@ var StreamProfileSchema = _enum([
|
|
|
67050
67449
|
]);
|
|
67051
67450
|
/** The current encoding config of one stream profile. */
|
|
67052
67451
|
var StreamProfileConfigSchema = object({
|
|
67053
|
-
width: number(),
|
|
67054
|
-
height: number(),
|
|
67452
|
+
width: number().meta(readingMeta("none")),
|
|
67453
|
+
height: number().meta(readingMeta("none")),
|
|
67055
67454
|
codec: _enum(["h264", "h265"]),
|
|
67056
|
-
framerate: number(),
|
|
67057
|
-
bitrate: number(),
|
|
67455
|
+
framerate: number().meta(readingMeta("rate")),
|
|
67456
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
67058
67457
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
67059
67458
|
encoderProfile: _enum([
|
|
67060
67459
|
"high",
|
|
67061
67460
|
"main",
|
|
67062
67461
|
"baseline"
|
|
67063
67462
|
]).optional(),
|
|
67064
|
-
gop: number().optional(),
|
|
67463
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
67065
67464
|
/**
|
|
67066
67465
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
67067
67466
|
*
|
|
@@ -67282,12 +67681,7 @@ var switchCapability = {
|
|
|
67282
67681
|
label: "On",
|
|
67283
67682
|
kind: "boolean"
|
|
67284
67683
|
}
|
|
67285
|
-
}] }
|
|
67286
|
-
customize: {
|
|
67287
|
-
version: 1,
|
|
67288
|
-
advanced: "derive",
|
|
67289
|
-
targets: []
|
|
67290
|
-
}
|
|
67684
|
+
}] }
|
|
67291
67685
|
};
|
|
67292
67686
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
67293
67687
|
function hasControlCharacter(value) {
|
|
@@ -67870,35 +68264,21 @@ var tamperCapability = {
|
|
|
67870
68264
|
* entries with `device_class: temperature` and any future native
|
|
67871
68265
|
* thermometer.
|
|
67872
68266
|
*
|
|
67873
|
-
*
|
|
67874
|
-
*
|
|
67875
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67876
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67877
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67878
|
-
* `sourceInfo`.
|
|
68267
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
68268
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67879
68269
|
*
|
|
67880
68270
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67881
68271
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67882
68272
|
* changed" steady state.
|
|
67883
68273
|
*/
|
|
67884
68274
|
var TemperatureSensorStatusSchema = object({
|
|
67885
|
-
/** Current temperature in Celsius. */
|
|
67886
|
-
celsius: number().meta({
|
|
67887
|
-
|
|
68275
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68276
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
68277
|
+
precision: 1,
|
|
67888
68278
|
label: "Temperature"
|
|
67889
|
-
}),
|
|
68279
|
+
})),
|
|
67890
68280
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67891
|
-
lastFetchedAt: number()
|
|
67892
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67893
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67894
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67895
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67896
|
-
unit: string().optional(),
|
|
67897
|
-
/** Suggested decimal places for numeric display.
|
|
67898
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67899
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67900
|
-
* auto-formatting when absent. */
|
|
67901
|
-
precision: number().int().min(0).max(10).optional()
|
|
68281
|
+
lastFetchedAt: number()
|
|
67902
68282
|
});
|
|
67903
68283
|
var temperatureSensorCapability = {
|
|
67904
68284
|
name: "temperature-sensor",
|
|
@@ -67929,12 +68309,7 @@ var temperatureSensorCapability = {
|
|
|
67929
68309
|
} } },
|
|
67930
68310
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67931
68311
|
* whether persisting is worth a SQLite commit. */
|
|
67932
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67933
|
-
customize: {
|
|
67934
|
-
version: 1,
|
|
67935
|
-
advanced: "derive",
|
|
67936
|
-
targets: []
|
|
67937
|
-
}
|
|
68312
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67938
68313
|
};
|
|
67939
68314
|
/**
|
|
67940
68315
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -68217,16 +68592,16 @@ var VacuumControlStatusSchema = object({
|
|
|
68217
68592
|
]),
|
|
68218
68593
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
68219
68594
|
* reading. */
|
|
68220
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
68595
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68221
68596
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
68222
68597
|
* the vacuum has no speed control. */
|
|
68223
68598
|
fanSpeed: string().nullable(),
|
|
68224
68599
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68225
68600
|
availableFanSpeeds: array(string()),
|
|
68226
68601
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68227
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
68602
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68228
68603
|
/** Current error code (0 / null = no error). */
|
|
68229
|
-
errorCode: number().nullable(),
|
|
68604
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68230
68605
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
68231
68606
|
errorLabel: string().nullable(),
|
|
68232
68607
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -68304,7 +68679,7 @@ var ValveStatusSchema = object({
|
|
|
68304
68679
|
]),
|
|
68305
68680
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
68306
68681
|
* intermediate position surface. */
|
|
68307
|
-
position: number().min(0).max(100).nullable(),
|
|
68682
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68308
68683
|
/** Ms epoch when the slice was last updated. */
|
|
68309
68684
|
lastChangedAt: number()
|
|
68310
68685
|
});
|
|
@@ -68412,9 +68787,9 @@ var vibrationCapability = {
|
|
|
68412
68787
|
*/
|
|
68413
68788
|
var WaterHeaterStatusSchema = object({
|
|
68414
68789
|
/** Current measured temperature. Null when not reported. */
|
|
68415
|
-
currentTemp: number().nullable(),
|
|
68790
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68416
68791
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68417
|
-
targetTemp: number().nullable(),
|
|
68792
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68418
68793
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68419
68794
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68420
68795
|
* device reports an unknown state. */
|
|
@@ -68425,9 +68800,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68425
68800
|
* has no away surface. */
|
|
68426
68801
|
away: boolean().nullable(),
|
|
68427
68802
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68428
|
-
minTemp: number().nullable(),
|
|
68803
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68429
68804
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68430
|
-
maxTemp: number().nullable(),
|
|
68805
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68431
68806
|
/** Ms epoch when the slice was last updated. */
|
|
68432
68807
|
lastChangedAt: number()
|
|
68433
68808
|
});
|
|
@@ -68512,25 +68887,18 @@ var waterHeaterCapability = {
|
|
|
68512
68887
|
* Forecast deferred — current conditions only for v1.
|
|
68513
68888
|
*/
|
|
68514
68889
|
var WeatherStatusSchema = object({
|
|
68515
|
-
/** Verbatim
|
|
68516
|
-
* when no condition has been reported yet. */
|
|
68890
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68517
68891
|
condition: string().nullable(),
|
|
68518
|
-
/** Current temperature in
|
|
68519
|
-
temperature: number().nullable(),
|
|
68520
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68521
|
-
temperatureUnit: string().nullable(),
|
|
68892
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68893
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68522
68894
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68523
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68524
|
-
/** Barometric pressure in
|
|
68525
|
-
pressure: number().nullable(),
|
|
68526
|
-
/**
|
|
68527
|
-
|
|
68528
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68529
|
-
windSpeed: number().nullable(),
|
|
68530
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68531
|
-
windSpeedUnit: string().nullable(),
|
|
68895
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68896
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68897
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68898
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68899
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68532
68900
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68533
|
-
windBearing: number().nullable(),
|
|
68901
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68534
68902
|
/** Ms epoch when the slice was last updated. */
|
|
68535
68903
|
lastFetchedAt: number()
|
|
68536
68904
|
});
|
|
@@ -68558,12 +68926,12 @@ var weatherCapability = {
|
|
|
68558
68926
|
*/
|
|
68559
68927
|
durability: "session",
|
|
68560
68928
|
/**
|
|
68561
|
-
* History (D850): recorded series.
|
|
68929
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68562
68930
|
*/
|
|
68563
68931
|
history: { fields: {
|
|
68564
68932
|
temperature: {
|
|
68565
68933
|
kind: "gauge",
|
|
68566
|
-
|
|
68934
|
+
unit: "°C",
|
|
68567
68935
|
deadband: .2
|
|
68568
68936
|
},
|
|
68569
68937
|
humidity: {
|
|
@@ -68573,12 +68941,12 @@ var weatherCapability = {
|
|
|
68573
68941
|
},
|
|
68574
68942
|
pressure: {
|
|
68575
68943
|
kind: "gauge",
|
|
68576
|
-
|
|
68944
|
+
unit: "hPa",
|
|
68577
68945
|
deadband: .5
|
|
68578
68946
|
},
|
|
68579
68947
|
windSpeed: {
|
|
68580
68948
|
kind: "gauge",
|
|
68581
|
-
|
|
68949
|
+
unit: "m/s",
|
|
68582
68950
|
deadband: .5
|
|
68583
68951
|
}
|
|
68584
68952
|
} }
|
|
@@ -69809,6 +70177,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69809
70177
|
featureProbe: featureProbeCapability,
|
|
69810
70178
|
flood: floodCapability,
|
|
69811
70179
|
gas: gasCapability,
|
|
70180
|
+
groupCommands: groupCommandsCapability,
|
|
70181
|
+
groupStatus: groupStatusCapability,
|
|
69812
70182
|
heatingValve: heatingValveCapability,
|
|
69813
70183
|
humidifier: humidifierCapability,
|
|
69814
70184
|
humiditySensor: humiditySensorCapability,
|
|
@@ -71185,6 +71555,13 @@ Object.freeze({
|
|
|
71185
71555
|
access: "view",
|
|
71186
71556
|
role: "admin"
|
|
71187
71557
|
},
|
|
71558
|
+
"addons.getPackageDocs": {
|
|
71559
|
+
capName: "addons",
|
|
71560
|
+
capScope: "system",
|
|
71561
|
+
addonId: null,
|
|
71562
|
+
access: "view",
|
|
71563
|
+
role: "admin"
|
|
71564
|
+
},
|
|
71188
71565
|
"addons.getVersions": {
|
|
71189
71566
|
capName: "addons",
|
|
71190
71567
|
capScope: "system",
|
|
@@ -74293,6 +74670,20 @@ Object.freeze({
|
|
|
74293
74670
|
access: "view",
|
|
74294
74671
|
role: "viewer"
|
|
74295
74672
|
},
|
|
74673
|
+
"groupCommands.getStatus": {
|
|
74674
|
+
capName: "group-commands",
|
|
74675
|
+
capScope: "device",
|
|
74676
|
+
addonId: null,
|
|
74677
|
+
access: "view",
|
|
74678
|
+
role: "viewer"
|
|
74679
|
+
},
|
|
74680
|
+
"groupStatus.getStatus": {
|
|
74681
|
+
capName: "group-status",
|
|
74682
|
+
capScope: "device",
|
|
74683
|
+
addonId: null,
|
|
74684
|
+
access: "view",
|
|
74685
|
+
role: "viewer"
|
|
74686
|
+
},
|
|
74296
74687
|
"heatingValve.getStatus": {
|
|
74297
74688
|
capName: "heating-valve",
|
|
74298
74689
|
capScope: "device",
|
|
@@ -84115,6 +84506,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84115
84506
|
icon: "flame"
|
|
84116
84507
|
}]
|
|
84117
84508
|
},
|
|
84509
|
+
"group-commands": {
|
|
84510
|
+
scope: "device",
|
|
84511
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84512
|
+
},
|
|
84513
|
+
"group-status": {
|
|
84514
|
+
scope: "device",
|
|
84515
|
+
noun: t("Group", "Gruppo"),
|
|
84516
|
+
state: [
|
|
84517
|
+
{
|
|
84518
|
+
kind: "numeric",
|
|
84519
|
+
field: "included",
|
|
84520
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84521
|
+
label: t("Reporting", "Rispondono"),
|
|
84522
|
+
icon: "users"
|
|
84523
|
+
},
|
|
84524
|
+
{
|
|
84525
|
+
kind: "numeric",
|
|
84526
|
+
field: "excluded",
|
|
84527
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84528
|
+
label: t("Excluded", "Esclusi"),
|
|
84529
|
+
icon: "users"
|
|
84530
|
+
},
|
|
84531
|
+
{
|
|
84532
|
+
kind: "numeric",
|
|
84533
|
+
field: "total",
|
|
84534
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84535
|
+
label: t("Members", "Membri"),
|
|
84536
|
+
icon: "sigma"
|
|
84537
|
+
}
|
|
84538
|
+
]
|
|
84539
|
+
},
|
|
84118
84540
|
"humidity-sensor": {
|
|
84119
84541
|
scope: "device",
|
|
84120
84542
|
noun: t("Humidity", "Umidità"),
|
|
@@ -84148,7 +84570,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84148
84570
|
field: "value",
|
|
84149
84571
|
quantity: t("the reading", "il valore"),
|
|
84150
84572
|
label: t("Reading", "Valore"),
|
|
84151
|
-
unitField: "unit",
|
|
84152
84573
|
icon: "gauge"
|
|
84153
84574
|
}]
|
|
84154
84575
|
},
|
|
@@ -84284,7 +84705,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84284
84705
|
field: "temperature",
|
|
84285
84706
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
84286
84707
|
label: t("Temperature", "Temperatura"),
|
|
84287
|
-
|
|
84708
|
+
unit: "°C",
|
|
84288
84709
|
icon: "thermometer"
|
|
84289
84710
|
},
|
|
84290
84711
|
{
|
|
@@ -84300,7 +84721,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84300
84721
|
field: "windSpeed",
|
|
84301
84722
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
84302
84723
|
label: t("Wind", "Vento"),
|
|
84303
|
-
|
|
84724
|
+
unit: "m/s",
|
|
84304
84725
|
icon: "wind"
|
|
84305
84726
|
},
|
|
84306
84727
|
{
|
|
@@ -84308,7 +84729,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84308
84729
|
field: "pressure",
|
|
84309
84730
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
84310
84731
|
label: t("Pressure", "Pressione"),
|
|
84311
|
-
|
|
84732
|
+
unit: "hPa",
|
|
84312
84733
|
icon: "gauge"
|
|
84313
84734
|
}
|
|
84314
84735
|
]
|
|
@@ -85581,6 +86002,16 @@ Object.freeze({
|
|
|
85581
86002
|
form: "single",
|
|
85582
86003
|
optional: false
|
|
85583
86004
|
}],
|
|
86005
|
+
"groupCommands.getStatus": [{
|
|
86006
|
+
name: "deviceId",
|
|
86007
|
+
form: "single",
|
|
86008
|
+
optional: false
|
|
86009
|
+
}],
|
|
86010
|
+
"groupStatus.getStatus": [{
|
|
86011
|
+
name: "deviceId",
|
|
86012
|
+
form: "single",
|
|
86013
|
+
optional: false
|
|
86014
|
+
}],
|
|
85584
86015
|
"heatingValve.getStatus": [{
|
|
85585
86016
|
name: "deviceId",
|
|
85586
86017
|
form: "single",
|
|
@@ -87565,6 +87996,8 @@ new Map(Object.entries({
|
|
|
87565
87996
|
"detection-blind": "device-events",
|
|
87566
87997
|
"motion-noisy": "device-events",
|
|
87567
87998
|
"motion-calm": "device-events",
|
|
87999
|
+
"package-llm-silent": "device-events",
|
|
88000
|
+
"package-llm-answered": "device-events",
|
|
87568
88001
|
"recording-stalled": "device-events",
|
|
87569
88002
|
"recording-healthy": "device-events",
|
|
87570
88003
|
"recording-degraded": "device-events",
|
|
@@ -87648,6 +88081,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87648
88081
|
label: "Motion without a subject",
|
|
87649
88082
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87650
88083
|
},
|
|
88084
|
+
{
|
|
88085
|
+
id: "package-llm",
|
|
88086
|
+
family: "device-events",
|
|
88087
|
+
label: "Package confirm",
|
|
88088
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
88089
|
+
},
|
|
87651
88090
|
{
|
|
87652
88091
|
id: "recording",
|
|
87653
88092
|
family: "device-events",
|
|
@@ -87829,6 +88268,8 @@ var DEVICE_EVENTS = [
|
|
|
87829
88268
|
"detection-blind",
|
|
87830
88269
|
"motion-noisy",
|
|
87831
88270
|
"motion-calm",
|
|
88271
|
+
"package-llm-silent",
|
|
88272
|
+
"package-llm-answered",
|
|
87832
88273
|
"recording-stalled",
|
|
87833
88274
|
"recording-healthy",
|
|
87834
88275
|
"recording-degraded",
|
|
@@ -88097,6 +88538,15 @@ new Map([
|
|
|
88097
88538
|
snapshotLabel: "Cameras with constant motion now",
|
|
88098
88539
|
snapshotSection: null
|
|
88099
88540
|
},
|
|
88541
|
+
{
|
|
88542
|
+
id: "package-llm-confirm",
|
|
88543
|
+
family: "device-events",
|
|
88544
|
+
label: "Package confirm (not answering / answering again)",
|
|
88545
|
+
bad: ["package-llm-silent"],
|
|
88546
|
+
recovery: ["package-llm-answered"],
|
|
88547
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88548
|
+
snapshotSection: null
|
|
88549
|
+
},
|
|
88100
88550
|
{
|
|
88101
88551
|
id: "recording-health",
|
|
88102
88552
|
family: "device-events",
|