@camstack/addon-google-services 0.2.30 → 0.2.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +19 -0
- package/dist/google-services.addon.js +861 -432
- package/dist/google-services.addon.mjs +861 -432
- package/package.json +13 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
//#region ../types/dist/event-category-
|
|
2
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
3
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
5
5
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -325,6 +325,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
325
325
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
326
326
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
327
327
|
/**
|
|
328
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
329
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
330
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
331
|
+
*/
|
|
332
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
333
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
334
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
335
|
+
/**
|
|
328
336
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
329
337
|
* (a settings change via `setAgentInferenceDevices` /
|
|
330
338
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5567,7 +5575,7 @@ var ZodIssueCode = {
|
|
|
5567
5575
|
var ZodFirstPartyTypeKind;
|
|
5568
5576
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5569
5577
|
//#endregion
|
|
5570
|
-
//#region ../types/dist/sleep-
|
|
5578
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5571
5579
|
/**
|
|
5572
5580
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5573
5581
|
* window to float samples (D455).
|
|
@@ -8309,6 +8317,99 @@ function defineEntryKind(name, spec) {
|
|
|
8309
8317
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8310
8318
|
return defined;
|
|
8311
8319
|
}
|
|
8320
|
+
var READING_QUANTITIES = [
|
|
8321
|
+
"temperature",
|
|
8322
|
+
"pressure",
|
|
8323
|
+
"speed",
|
|
8324
|
+
"precipitation",
|
|
8325
|
+
"precipitation-rate",
|
|
8326
|
+
"length",
|
|
8327
|
+
"area",
|
|
8328
|
+
"illuminance",
|
|
8329
|
+
"irradiance",
|
|
8330
|
+
"power",
|
|
8331
|
+
"energy",
|
|
8332
|
+
"voltage",
|
|
8333
|
+
"current",
|
|
8334
|
+
"apparent-power",
|
|
8335
|
+
"humidity",
|
|
8336
|
+
"percentage",
|
|
8337
|
+
"concentration-volume",
|
|
8338
|
+
"concentration-mass",
|
|
8339
|
+
"concentration-ppb",
|
|
8340
|
+
"volume",
|
|
8341
|
+
"duration",
|
|
8342
|
+
"duration-ms",
|
|
8343
|
+
"information",
|
|
8344
|
+
"sound-level",
|
|
8345
|
+
"signal-level",
|
|
8346
|
+
"colour-temperature",
|
|
8347
|
+
"angle",
|
|
8348
|
+
"bitrate",
|
|
8349
|
+
"rate",
|
|
8350
|
+
"mass",
|
|
8351
|
+
"index",
|
|
8352
|
+
"ratio",
|
|
8353
|
+
"count",
|
|
8354
|
+
"none",
|
|
8355
|
+
"device"
|
|
8356
|
+
];
|
|
8357
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8358
|
+
new Set(READING_QUANTITIES);
|
|
8359
|
+
/**
|
|
8360
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8361
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8362
|
+
*/
|
|
8363
|
+
var QUANTITY_BASE = {
|
|
8364
|
+
temperature: "°C",
|
|
8365
|
+
pressure: "hPa",
|
|
8366
|
+
speed: "m/s",
|
|
8367
|
+
precipitation: "mm",
|
|
8368
|
+
"precipitation-rate": "mm/h",
|
|
8369
|
+
length: "m",
|
|
8370
|
+
area: "m²",
|
|
8371
|
+
illuminance: "lx",
|
|
8372
|
+
irradiance: "W/m²",
|
|
8373
|
+
power: "W",
|
|
8374
|
+
energy: "kWh",
|
|
8375
|
+
voltage: "V",
|
|
8376
|
+
current: "A",
|
|
8377
|
+
"apparent-power": "VA",
|
|
8378
|
+
humidity: "%",
|
|
8379
|
+
percentage: "%",
|
|
8380
|
+
"concentration-volume": "ppm",
|
|
8381
|
+
"concentration-mass": "µg/m³",
|
|
8382
|
+
"concentration-ppb": "ppb",
|
|
8383
|
+
volume: "L",
|
|
8384
|
+
duration: "s",
|
|
8385
|
+
"duration-ms": "ms",
|
|
8386
|
+
information: "B",
|
|
8387
|
+
"sound-level": "dBFS",
|
|
8388
|
+
"signal-level": "dBm",
|
|
8389
|
+
"colour-temperature": "mired",
|
|
8390
|
+
angle: "°",
|
|
8391
|
+
bitrate: "kbps",
|
|
8392
|
+
rate: "fps",
|
|
8393
|
+
mass: "kg",
|
|
8394
|
+
index: "none",
|
|
8395
|
+
ratio: "none",
|
|
8396
|
+
count: "none",
|
|
8397
|
+
none: "none",
|
|
8398
|
+
device: "device"
|
|
8399
|
+
};
|
|
8400
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8401
|
+
function baseUnitOf(quantity) {
|
|
8402
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8403
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8404
|
+
return symbol;
|
|
8405
|
+
}
|
|
8406
|
+
function readingMeta(quantity, extras) {
|
|
8407
|
+
return {
|
|
8408
|
+
quantity,
|
|
8409
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8410
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8411
|
+
};
|
|
8412
|
+
}
|
|
8312
8413
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8313
8414
|
var CamProfileSchema = _enum([
|
|
8314
8415
|
"high",
|
|
@@ -8336,8 +8437,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8336
8437
|
"derived"
|
|
8337
8438
|
]);
|
|
8338
8439
|
var CamStreamResolutionSchema = object({
|
|
8339
|
-
width: number().int().positive(),
|
|
8340
|
-
height: number().int().positive()
|
|
8440
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8441
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8341
8442
|
});
|
|
8342
8443
|
var CameraStreamSchema = object({
|
|
8343
8444
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8851,6 +8952,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8851
8952
|
"filesystem-browse",
|
|
8852
8953
|
"flood",
|
|
8853
8954
|
"gas",
|
|
8955
|
+
"group-commands",
|
|
8956
|
+
"group-status",
|
|
8854
8957
|
"heating-valve",
|
|
8855
8958
|
"humidifier",
|
|
8856
8959
|
"humidity-sensor",
|
|
@@ -8980,14 +9083,6 @@ Object.freeze({
|
|
|
8980
9083
|
{
|
|
8981
9084
|
"path": "aqi",
|
|
8982
9085
|
"valueType": "number"
|
|
8983
|
-
},
|
|
8984
|
-
{
|
|
8985
|
-
"path": "unit",
|
|
8986
|
-
"valueType": "string"
|
|
8987
|
-
},
|
|
8988
|
-
{
|
|
8989
|
-
"path": "precision",
|
|
8990
|
-
"valueType": "number"
|
|
8991
9086
|
}
|
|
8992
9087
|
],
|
|
8993
9088
|
"alarm-panel": [
|
|
@@ -9023,20 +9118,10 @@ Object.freeze({
|
|
|
9023
9118
|
"valueType": "boolean"
|
|
9024
9119
|
}
|
|
9025
9120
|
],
|
|
9026
|
-
"ambient-light-sensor": [
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
},
|
|
9031
|
-
{
|
|
9032
|
-
"path": "unit",
|
|
9033
|
-
"valueType": "string"
|
|
9034
|
-
},
|
|
9035
|
-
{
|
|
9036
|
-
"path": "precision",
|
|
9037
|
-
"valueType": "number"
|
|
9038
|
-
}
|
|
9039
|
-
],
|
|
9121
|
+
"ambient-light-sensor": [{
|
|
9122
|
+
"path": "lux",
|
|
9123
|
+
"valueType": "number"
|
|
9124
|
+
}],
|
|
9040
9125
|
"audio-metrics": [
|
|
9041
9126
|
{
|
|
9042
9127
|
"path": "ts",
|
|
@@ -9116,6 +9201,10 @@ Object.freeze({
|
|
|
9116
9201
|
"path": "lastUpdated",
|
|
9117
9202
|
"valueType": "number"
|
|
9118
9203
|
},
|
|
9204
|
+
{
|
|
9205
|
+
"path": "volts",
|
|
9206
|
+
"valueType": "number"
|
|
9207
|
+
},
|
|
9119
9208
|
{
|
|
9120
9209
|
"path": "lastContactAt",
|
|
9121
9210
|
"valueType": "number"
|
|
@@ -9358,10 +9447,6 @@ Object.freeze({
|
|
|
9358
9447
|
"datetime"
|
|
9359
9448
|
]
|
|
9360
9449
|
},
|
|
9361
|
-
{
|
|
9362
|
-
"path": "unit",
|
|
9363
|
-
"valueType": "string"
|
|
9364
|
-
},
|
|
9365
9450
|
{
|
|
9366
9451
|
"path": "min",
|
|
9367
9452
|
"valueType": "number"
|
|
@@ -9373,19 +9458,6 @@ Object.freeze({
|
|
|
9373
9458
|
{
|
|
9374
9459
|
"path": "step",
|
|
9375
9460
|
"valueType": "number"
|
|
9376
|
-
},
|
|
9377
|
-
{
|
|
9378
|
-
"path": "precision",
|
|
9379
|
-
"valueType": "number"
|
|
9380
|
-
},
|
|
9381
|
-
{
|
|
9382
|
-
"path": "format",
|
|
9383
|
-
"valueType": "enum",
|
|
9384
|
-
"enumValues": [
|
|
9385
|
-
"date",
|
|
9386
|
-
"time",
|
|
9387
|
-
"datetime"
|
|
9388
|
-
]
|
|
9389
9461
|
}
|
|
9390
9462
|
],
|
|
9391
9463
|
"cover": [
|
|
@@ -9626,13 +9698,8 @@ Object.freeze({
|
|
|
9626
9698
|
"path": "value",
|
|
9627
9699
|
"valueType": "string"
|
|
9628
9700
|
}, {
|
|
9629
|
-
"path": "
|
|
9630
|
-
"valueType": "
|
|
9631
|
-
"enumValues": [
|
|
9632
|
-
"date",
|
|
9633
|
-
"time",
|
|
9634
|
-
"datetime"
|
|
9635
|
-
]
|
|
9701
|
+
"path": "timestamp",
|
|
9702
|
+
"valueType": "boolean"
|
|
9636
9703
|
}],
|
|
9637
9704
|
"event-emitter": [
|
|
9638
9705
|
{
|
|
@@ -9705,6 +9772,20 @@ Object.freeze({
|
|
|
9705
9772
|
"path": "detected",
|
|
9706
9773
|
"valueType": "boolean"
|
|
9707
9774
|
}],
|
|
9775
|
+
"group-status": [
|
|
9776
|
+
{
|
|
9777
|
+
"path": "included",
|
|
9778
|
+
"valueType": "number"
|
|
9779
|
+
},
|
|
9780
|
+
{
|
|
9781
|
+
"path": "excluded",
|
|
9782
|
+
"valueType": "number"
|
|
9783
|
+
},
|
|
9784
|
+
{
|
|
9785
|
+
"path": "total",
|
|
9786
|
+
"valueType": "number"
|
|
9787
|
+
}
|
|
9788
|
+
],
|
|
9708
9789
|
"heating-valve": [{
|
|
9709
9790
|
"path": "position",
|
|
9710
9791
|
"valueType": "number"
|
|
@@ -9739,20 +9820,10 @@ Object.freeze({
|
|
|
9739
9820
|
"valueType": "number"
|
|
9740
9821
|
}
|
|
9741
9822
|
],
|
|
9742
|
-
"humidity-sensor": [
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
},
|
|
9747
|
-
{
|
|
9748
|
-
"path": "unit",
|
|
9749
|
-
"valueType": "string"
|
|
9750
|
-
},
|
|
9751
|
-
{
|
|
9752
|
-
"path": "precision",
|
|
9753
|
-
"valueType": "number"
|
|
9754
|
-
}
|
|
9755
|
-
],
|
|
9823
|
+
"humidity-sensor": [{
|
|
9824
|
+
"path": "percent",
|
|
9825
|
+
"valueType": "number"
|
|
9826
|
+
}],
|
|
9756
9827
|
"image": [{
|
|
9757
9828
|
"path": "url",
|
|
9758
9829
|
"valueType": "string"
|
|
@@ -10091,20 +10162,10 @@ Object.freeze({
|
|
|
10091
10162
|
"valueType": "boolean"
|
|
10092
10163
|
}
|
|
10093
10164
|
],
|
|
10094
|
-
"numeric-sensor": [
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
},
|
|
10099
|
-
{
|
|
10100
|
-
"path": "unit",
|
|
10101
|
-
"valueType": "string"
|
|
10102
|
-
},
|
|
10103
|
-
{
|
|
10104
|
-
"path": "precision",
|
|
10105
|
-
"valueType": "number"
|
|
10106
|
-
}
|
|
10107
|
-
],
|
|
10165
|
+
"numeric-sensor": [{
|
|
10166
|
+
"path": "value",
|
|
10167
|
+
"valueType": "number"
|
|
10168
|
+
}],
|
|
10108
10169
|
"pet-feeder": [
|
|
10109
10170
|
{
|
|
10110
10171
|
"path": "foodLevel",
|
|
@@ -10196,14 +10257,6 @@ Object.freeze({
|
|
|
10196
10257
|
{
|
|
10197
10258
|
"path": "powerFactor",
|
|
10198
10259
|
"valueType": "number"
|
|
10199
|
-
},
|
|
10200
|
-
{
|
|
10201
|
-
"path": "unit",
|
|
10202
|
-
"valueType": "string"
|
|
10203
|
-
},
|
|
10204
|
-
{
|
|
10205
|
-
"path": "precision",
|
|
10206
|
-
"valueType": "number"
|
|
10207
10260
|
}
|
|
10208
10261
|
],
|
|
10209
10262
|
"presence": [
|
|
@@ -10232,20 +10285,10 @@ Object.freeze({
|
|
|
10232
10285
|
"valueType": "number"
|
|
10233
10286
|
}
|
|
10234
10287
|
],
|
|
10235
|
-
"pressure-sensor": [
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
},
|
|
10240
|
-
{
|
|
10241
|
-
"path": "unit",
|
|
10242
|
-
"valueType": "string"
|
|
10243
|
-
},
|
|
10244
|
-
{
|
|
10245
|
-
"path": "precision",
|
|
10246
|
-
"valueType": "number"
|
|
10247
|
-
}
|
|
10248
|
-
],
|
|
10288
|
+
"pressure-sensor": [{
|
|
10289
|
+
"path": "hpa",
|
|
10290
|
+
"valueType": "number"
|
|
10291
|
+
}],
|
|
10249
10292
|
"privacy-mask": [{
|
|
10250
10293
|
"path": "enabled",
|
|
10251
10294
|
"valueType": "boolean"
|
|
@@ -10556,20 +10599,10 @@ Object.freeze({
|
|
|
10556
10599
|
"path": "tampered",
|
|
10557
10600
|
"valueType": "boolean"
|
|
10558
10601
|
}],
|
|
10559
|
-
"temperature-sensor": [
|
|
10560
|
-
|
|
10561
|
-
|
|
10562
|
-
|
|
10563
|
-
},
|
|
10564
|
-
{
|
|
10565
|
-
"path": "unit",
|
|
10566
|
-
"valueType": "string"
|
|
10567
|
-
},
|
|
10568
|
-
{
|
|
10569
|
-
"path": "precision",
|
|
10570
|
-
"valueType": "number"
|
|
10571
|
-
}
|
|
10572
|
-
],
|
|
10602
|
+
"temperature-sensor": [{
|
|
10603
|
+
"path": "celsius",
|
|
10604
|
+
"valueType": "number"
|
|
10605
|
+
}],
|
|
10573
10606
|
"update": [
|
|
10574
10607
|
{
|
|
10575
10608
|
"path": "currentVersion",
|
|
@@ -10680,10 +10713,6 @@ Object.freeze({
|
|
|
10680
10713
|
"path": "temperature",
|
|
10681
10714
|
"valueType": "number"
|
|
10682
10715
|
},
|
|
10683
|
-
{
|
|
10684
|
-
"path": "temperatureUnit",
|
|
10685
|
-
"valueType": "string"
|
|
10686
|
-
},
|
|
10687
10716
|
{
|
|
10688
10717
|
"path": "humidity",
|
|
10689
10718
|
"valueType": "number"
|
|
@@ -10692,18 +10721,10 @@ Object.freeze({
|
|
|
10692
10721
|
"path": "pressure",
|
|
10693
10722
|
"valueType": "number"
|
|
10694
10723
|
},
|
|
10695
|
-
{
|
|
10696
|
-
"path": "pressureUnit",
|
|
10697
|
-
"valueType": "string"
|
|
10698
|
-
},
|
|
10699
10724
|
{
|
|
10700
10725
|
"path": "windSpeed",
|
|
10701
10726
|
"valueType": "number"
|
|
10702
10727
|
},
|
|
10703
|
-
{
|
|
10704
|
-
"path": "windSpeedUnit",
|
|
10705
|
-
"valueType": "string"
|
|
10706
|
-
},
|
|
10707
10728
|
{
|
|
10708
10729
|
"path": "windBearing",
|
|
10709
10730
|
"valueType": "number"
|
|
@@ -11110,7 +11131,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11110
11131
|
return DeviceRole;
|
|
11111
11132
|
}({});
|
|
11112
11133
|
//#endregion
|
|
11113
|
-
//#region ../types/dist/composition-
|
|
11134
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11114
11135
|
/**
|
|
11115
11136
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11116
11137
|
*
|
|
@@ -11865,15 +11886,74 @@ function validateExpressionSource(src) {
|
|
|
11865
11886
|
}
|
|
11866
11887
|
return null;
|
|
11867
11888
|
}
|
|
11868
|
-
/**
|
|
11869
|
-
|
|
11870
|
-
|
|
11871
|
-
|
|
11889
|
+
/**
|
|
11890
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11891
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11892
|
+
* `composition.ts` (D659).
|
|
11893
|
+
*/
|
|
11872
11894
|
var CompositionSourceRefSchema = object({
|
|
11873
11895
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11874
11896
|
addonId: string().min(1),
|
|
11875
11897
|
stableId: string().min(1)
|
|
11876
11898
|
});
|
|
11899
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11900
|
+
"temperature",
|
|
11901
|
+
"humidity",
|
|
11902
|
+
"pressure",
|
|
11903
|
+
"illuminance",
|
|
11904
|
+
"power",
|
|
11905
|
+
"energy",
|
|
11906
|
+
"battery",
|
|
11907
|
+
"numeric",
|
|
11908
|
+
"motion",
|
|
11909
|
+
"contact",
|
|
11910
|
+
"leak",
|
|
11911
|
+
"smoke",
|
|
11912
|
+
"occupancy",
|
|
11913
|
+
"binary",
|
|
11914
|
+
"switch",
|
|
11915
|
+
"light"
|
|
11916
|
+
];
|
|
11917
|
+
var NUMERIC_AGGREGATES = [
|
|
11918
|
+
"mean",
|
|
11919
|
+
"median",
|
|
11920
|
+
"min",
|
|
11921
|
+
"max",
|
|
11922
|
+
"sum"
|
|
11923
|
+
];
|
|
11924
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11925
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11926
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11927
|
+
var AGGREGATE_REDUCERS = [
|
|
11928
|
+
"mean",
|
|
11929
|
+
"median",
|
|
11930
|
+
"min",
|
|
11931
|
+
"max",
|
|
11932
|
+
"sum",
|
|
11933
|
+
"any",
|
|
11934
|
+
"all"
|
|
11935
|
+
];
|
|
11936
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11937
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11938
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11939
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11940
|
+
var HelperMemberSchema = object({
|
|
11941
|
+
source: CompositionSourceRefSchema,
|
|
11942
|
+
cap: string().min(1),
|
|
11943
|
+
fieldPath: string().min(1)
|
|
11944
|
+
});
|
|
11945
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11946
|
+
kind: literal("group"),
|
|
11947
|
+
templateId: GroupTemplateIdSchema,
|
|
11948
|
+
aggregate: AggregateReducerSchema,
|
|
11949
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11950
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11951
|
+
active: ActiveCriterionSchema.optional()
|
|
11952
|
+
})]);
|
|
11953
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11954
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11955
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11956
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11877
11957
|
/** One field of one capability of one source device. */
|
|
11878
11958
|
var CompositionFieldReadSchema = object({
|
|
11879
11959
|
source: CompositionSourceRefSchema,
|
|
@@ -11917,7 +11997,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11917
11997
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11918
11998
|
CompositionFromSourceSchema,
|
|
11919
11999
|
CompositionExpressionSourceSchema,
|
|
11920
|
-
CompositionCodeSourceSchema
|
|
12000
|
+
CompositionCodeSourceSchema,
|
|
12001
|
+
object({
|
|
12002
|
+
kind: literal("aggregate"),
|
|
12003
|
+
reducer: _enum([
|
|
12004
|
+
"mean",
|
|
12005
|
+
"median",
|
|
12006
|
+
"min",
|
|
12007
|
+
"max",
|
|
12008
|
+
"sum",
|
|
12009
|
+
"any",
|
|
12010
|
+
"all"
|
|
12011
|
+
]),
|
|
12012
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12013
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12014
|
+
publish: _enum([
|
|
12015
|
+
"value",
|
|
12016
|
+
"included",
|
|
12017
|
+
"excluded",
|
|
12018
|
+
"total"
|
|
12019
|
+
]),
|
|
12020
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12021
|
+
empty: _enum([
|
|
12022
|
+
"null",
|
|
12023
|
+
"omit",
|
|
12024
|
+
"offline"
|
|
12025
|
+
])
|
|
12026
|
+
})
|
|
11921
12027
|
]);
|
|
11922
12028
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11923
12029
|
kind: literal("forward"),
|
|
@@ -11963,7 +12069,13 @@ var CompositionSchema = object({
|
|
|
11963
12069
|
kind: literal("existing"),
|
|
11964
12070
|
device: CompositionSourceRefSchema
|
|
11965
12071
|
})]),
|
|
11966
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12072
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12073
|
+
/**
|
|
12074
|
+
* Present when the block is a helper template. Absent on a free
|
|
12075
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12076
|
+
* never the compiled features.
|
|
12077
|
+
*/
|
|
12078
|
+
helper: HelperSpecSchema.optional()
|
|
11967
12079
|
}).superRefine((composition, ctx) => {
|
|
11968
12080
|
const seen = /* @__PURE__ */ new Set();
|
|
11969
12081
|
composition.features.forEach((feature, index) => {
|
|
@@ -18250,7 +18362,11 @@ var CompositionProblemSchema = object({
|
|
|
18250
18362
|
"item-field-reserved",
|
|
18251
18363
|
"target-missing",
|
|
18252
18364
|
"target-unreadable",
|
|
18253
|
-
"not-replaceable"
|
|
18365
|
+
"not-replaceable",
|
|
18366
|
+
"native-capability-replace",
|
|
18367
|
+
"mixed-quantity",
|
|
18368
|
+
"helper-mismatch",
|
|
18369
|
+
"member-constraint"
|
|
18254
18370
|
]),
|
|
18255
18371
|
path: string(),
|
|
18256
18372
|
message: string()
|
|
@@ -18271,7 +18387,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18271
18387
|
"null",
|
|
18272
18388
|
"offline",
|
|
18273
18389
|
"unknown",
|
|
18274
|
-
"release"
|
|
18390
|
+
"release",
|
|
18391
|
+
"omit"
|
|
18275
18392
|
]);
|
|
18276
18393
|
/**
|
|
18277
18394
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18308,9 +18425,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18308
18425
|
reads: array(CompositionFieldReadSchema)
|
|
18309
18426
|
});
|
|
18310
18427
|
/**
|
|
18311
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18312
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18313
|
-
*
|
|
18428
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18429
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18430
|
+
* Replacing a capability the device already serves is refused
|
|
18431
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18432
|
+
* wire for a claim the hub already holds.
|
|
18314
18433
|
*/
|
|
18315
18434
|
var CompositionFeatureModeSchema = _enum([
|
|
18316
18435
|
"new",
|
|
@@ -18483,6 +18602,275 @@ Object.freeze({
|
|
|
18483
18602
|
result: ["number", "null"]
|
|
18484
18603
|
}
|
|
18485
18604
|
});
|
|
18605
|
+
/**
|
|
18606
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18607
|
+
* Data, not a form default written into the block.
|
|
18608
|
+
*/
|
|
18609
|
+
var NOW = {
|
|
18610
|
+
fieldPath: "lastFetchedAt",
|
|
18611
|
+
expr: "now"
|
|
18612
|
+
};
|
|
18613
|
+
var CHANGED = {
|
|
18614
|
+
fieldPath: "lastChangedAt",
|
|
18615
|
+
expr: "now"
|
|
18616
|
+
};
|
|
18617
|
+
function numeric(input) {
|
|
18618
|
+
return {
|
|
18619
|
+
...input,
|
|
18620
|
+
family: "numeric",
|
|
18621
|
+
deviceType: DeviceType.Sensor,
|
|
18622
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18623
|
+
commandCaps: [],
|
|
18624
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18625
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18626
|
+
accept: [{
|
|
18627
|
+
cap: input.outputCap,
|
|
18628
|
+
fieldPath: input.outputField
|
|
18629
|
+
}]
|
|
18630
|
+
};
|
|
18631
|
+
}
|
|
18632
|
+
function binary(input) {
|
|
18633
|
+
return {
|
|
18634
|
+
...input,
|
|
18635
|
+
family: "binary",
|
|
18636
|
+
deviceType: DeviceType.Sensor,
|
|
18637
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18638
|
+
commandCaps: [],
|
|
18639
|
+
quantity: "none",
|
|
18640
|
+
baseUnit: void 0,
|
|
18641
|
+
aggregates: BINARY_AGGREGATES,
|
|
18642
|
+
empty: "offline"
|
|
18643
|
+
};
|
|
18644
|
+
}
|
|
18645
|
+
var GROUP_TEMPLATES = [
|
|
18646
|
+
numeric({
|
|
18647
|
+
id: "temperature",
|
|
18648
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18649
|
+
role: DeviceRole.TemperatureSensor,
|
|
18650
|
+
outputCap: "temperature-sensor",
|
|
18651
|
+
outputField: "celsius",
|
|
18652
|
+
quantity: "temperature",
|
|
18653
|
+
defaultAggregate: "mean",
|
|
18654
|
+
empty: "null",
|
|
18655
|
+
companions: [NOW]
|
|
18656
|
+
}),
|
|
18657
|
+
numeric({
|
|
18658
|
+
id: "humidity",
|
|
18659
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18660
|
+
role: DeviceRole.HumiditySensor,
|
|
18661
|
+
outputCap: "humidity-sensor",
|
|
18662
|
+
outputField: "percent",
|
|
18663
|
+
quantity: "humidity",
|
|
18664
|
+
defaultAggregate: "mean",
|
|
18665
|
+
empty: "null",
|
|
18666
|
+
companions: [NOW]
|
|
18667
|
+
}),
|
|
18668
|
+
numeric({
|
|
18669
|
+
id: "pressure",
|
|
18670
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18671
|
+
role: DeviceRole.PressureSensor,
|
|
18672
|
+
outputCap: "pressure-sensor",
|
|
18673
|
+
outputField: "hpa",
|
|
18674
|
+
quantity: "pressure",
|
|
18675
|
+
defaultAggregate: "mean",
|
|
18676
|
+
empty: "null",
|
|
18677
|
+
companions: [NOW]
|
|
18678
|
+
}),
|
|
18679
|
+
numeric({
|
|
18680
|
+
id: "illuminance",
|
|
18681
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18682
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18683
|
+
outputCap: "ambient-light-sensor",
|
|
18684
|
+
outputField: "lux",
|
|
18685
|
+
quantity: "illuminance",
|
|
18686
|
+
defaultAggregate: "mean",
|
|
18687
|
+
empty: "null",
|
|
18688
|
+
companions: [NOW]
|
|
18689
|
+
}),
|
|
18690
|
+
numeric({
|
|
18691
|
+
id: "power",
|
|
18692
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18693
|
+
role: DeviceRole.PowerSensor,
|
|
18694
|
+
outputCap: "power-meter",
|
|
18695
|
+
outputField: "watts",
|
|
18696
|
+
quantity: "power",
|
|
18697
|
+
defaultAggregate: "sum",
|
|
18698
|
+
empty: "omit",
|
|
18699
|
+
companions: [NOW]
|
|
18700
|
+
}),
|
|
18701
|
+
numeric({
|
|
18702
|
+
id: "energy",
|
|
18703
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18704
|
+
role: DeviceRole.EnergySensor,
|
|
18705
|
+
outputCap: "power-meter",
|
|
18706
|
+
outputField: "kwhTotal",
|
|
18707
|
+
quantity: "energy",
|
|
18708
|
+
defaultAggregate: "sum",
|
|
18709
|
+
empty: "omit",
|
|
18710
|
+
companions: [NOW]
|
|
18711
|
+
}),
|
|
18712
|
+
numeric({
|
|
18713
|
+
id: "battery",
|
|
18714
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18715
|
+
role: DeviceRole.BatterySensor,
|
|
18716
|
+
outputCap: "battery",
|
|
18717
|
+
outputField: "percentage",
|
|
18718
|
+
quantity: "percentage",
|
|
18719
|
+
defaultAggregate: "mean",
|
|
18720
|
+
empty: "null",
|
|
18721
|
+
companions: [
|
|
18722
|
+
{
|
|
18723
|
+
fieldPath: "charging",
|
|
18724
|
+
expr: "\"unknown\""
|
|
18725
|
+
},
|
|
18726
|
+
{
|
|
18727
|
+
fieldPath: "sleeping",
|
|
18728
|
+
expr: "false"
|
|
18729
|
+
},
|
|
18730
|
+
{
|
|
18731
|
+
fieldPath: "lastUpdated",
|
|
18732
|
+
expr: "now"
|
|
18733
|
+
}
|
|
18734
|
+
]
|
|
18735
|
+
}),
|
|
18736
|
+
numeric({
|
|
18737
|
+
id: "numeric",
|
|
18738
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18739
|
+
role: DeviceRole.NumericSensor,
|
|
18740
|
+
outputCap: "numeric-sensor",
|
|
18741
|
+
outputField: "value",
|
|
18742
|
+
quantity: "device",
|
|
18743
|
+
defaultAggregate: "mean",
|
|
18744
|
+
empty: "null",
|
|
18745
|
+
companions: [NOW]
|
|
18746
|
+
}),
|
|
18747
|
+
binary({
|
|
18748
|
+
id: "motion",
|
|
18749
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18750
|
+
role: DeviceRole.MotionSensor,
|
|
18751
|
+
outputCap: "motion",
|
|
18752
|
+
outputField: "detected",
|
|
18753
|
+
defaultAggregate: "any",
|
|
18754
|
+
accept: [{
|
|
18755
|
+
cap: "motion",
|
|
18756
|
+
fieldPath: "detected"
|
|
18757
|
+
}],
|
|
18758
|
+
companions: [{
|
|
18759
|
+
fieldPath: "lastDetectedAt",
|
|
18760
|
+
expr: "null"
|
|
18761
|
+
}, {
|
|
18762
|
+
fieldPath: "autoClearAfterMs",
|
|
18763
|
+
expr: "null"
|
|
18764
|
+
}]
|
|
18765
|
+
}),
|
|
18766
|
+
binary({
|
|
18767
|
+
id: "contact",
|
|
18768
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18769
|
+
role: DeviceRole.ContactSensor,
|
|
18770
|
+
outputCap: "contact",
|
|
18771
|
+
outputField: "entryOpen",
|
|
18772
|
+
defaultAggregate: "any",
|
|
18773
|
+
accept: [{
|
|
18774
|
+
cap: "contact",
|
|
18775
|
+
fieldPath: "entryOpen"
|
|
18776
|
+
}],
|
|
18777
|
+
companions: [CHANGED]
|
|
18778
|
+
}),
|
|
18779
|
+
binary({
|
|
18780
|
+
id: "leak",
|
|
18781
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18782
|
+
role: DeviceRole.LeakSensor,
|
|
18783
|
+
outputCap: "flood",
|
|
18784
|
+
outputField: "flooded",
|
|
18785
|
+
defaultAggregate: "any",
|
|
18786
|
+
accept: [{
|
|
18787
|
+
cap: "flood",
|
|
18788
|
+
fieldPath: "flooded"
|
|
18789
|
+
}],
|
|
18790
|
+
companions: [CHANGED]
|
|
18791
|
+
}),
|
|
18792
|
+
binary({
|
|
18793
|
+
id: "smoke",
|
|
18794
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18795
|
+
role: DeviceRole.SmokeSensor,
|
|
18796
|
+
outputCap: "smoke",
|
|
18797
|
+
outputField: "detected",
|
|
18798
|
+
defaultAggregate: "any",
|
|
18799
|
+
accept: [{
|
|
18800
|
+
cap: "smoke",
|
|
18801
|
+
fieldPath: "detected"
|
|
18802
|
+
}],
|
|
18803
|
+
companions: [CHANGED]
|
|
18804
|
+
}),
|
|
18805
|
+
binary({
|
|
18806
|
+
id: "occupancy",
|
|
18807
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18808
|
+
role: DeviceRole.BinarySensor,
|
|
18809
|
+
outputCap: "binary",
|
|
18810
|
+
outputField: "on",
|
|
18811
|
+
defaultAggregate: "any",
|
|
18812
|
+
accept: [{
|
|
18813
|
+
cap: "motion",
|
|
18814
|
+
fieldPath: "detected"
|
|
18815
|
+
}, {
|
|
18816
|
+
cap: "binary",
|
|
18817
|
+
fieldPath: "on"
|
|
18818
|
+
}],
|
|
18819
|
+
companions: [CHANGED]
|
|
18820
|
+
}),
|
|
18821
|
+
binary({
|
|
18822
|
+
id: "binary",
|
|
18823
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18824
|
+
role: DeviceRole.BinarySensor,
|
|
18825
|
+
outputCap: "binary",
|
|
18826
|
+
outputField: "on",
|
|
18827
|
+
defaultAggregate: "any",
|
|
18828
|
+
accept: [{
|
|
18829
|
+
cap: "binary",
|
|
18830
|
+
fieldPath: "on"
|
|
18831
|
+
}],
|
|
18832
|
+
companions: [CHANGED]
|
|
18833
|
+
}),
|
|
18834
|
+
actuator({
|
|
18835
|
+
id: "switch",
|
|
18836
|
+
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.",
|
|
18837
|
+
deviceType: DeviceType.Switch,
|
|
18838
|
+
outputCap: "switch",
|
|
18839
|
+
commandCaps: ["switch"]
|
|
18840
|
+
}),
|
|
18841
|
+
actuator({
|
|
18842
|
+
id: "light",
|
|
18843
|
+
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.",
|
|
18844
|
+
deviceType: DeviceType.Light,
|
|
18845
|
+
outputCap: "switch",
|
|
18846
|
+
commandCaps: [
|
|
18847
|
+
"switch",
|
|
18848
|
+
"brightness",
|
|
18849
|
+
"color"
|
|
18850
|
+
]
|
|
18851
|
+
})
|
|
18852
|
+
];
|
|
18853
|
+
function actuator(input) {
|
|
18854
|
+
return {
|
|
18855
|
+
...input,
|
|
18856
|
+
family: "actuator",
|
|
18857
|
+
role: void 0,
|
|
18858
|
+
memberDeviceType: input.deviceType,
|
|
18859
|
+
outputField: "on",
|
|
18860
|
+
quantity: "none",
|
|
18861
|
+
baseUnit: void 0,
|
|
18862
|
+
aggregates: BINARY_AGGREGATES,
|
|
18863
|
+
defaultAggregate: "any",
|
|
18864
|
+
empty: "offline",
|
|
18865
|
+
accept: [{
|
|
18866
|
+
cap: "switch",
|
|
18867
|
+
fieldPath: "on"
|
|
18868
|
+
}],
|
|
18869
|
+
companions: [CHANGED]
|
|
18870
|
+
};
|
|
18871
|
+
}
|
|
18872
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18873
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18486
18874
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18487
18875
|
/**
|
|
18488
18876
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -20196,12 +20584,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20196
20584
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20197
20585
|
* in-place so dispatch keeps working.
|
|
20198
20586
|
*
|
|
20199
|
-
* **
|
|
20200
|
-
*
|
|
20201
|
-
*
|
|
20202
|
-
*
|
|
20203
|
-
* (`ha-domain-mapping`)
|
|
20204
|
-
* stored after that point.
|
|
20587
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20588
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20589
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20590
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20591
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20592
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20205
20593
|
*
|
|
20206
20594
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20207
20595
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20215,6 +20603,14 @@ var SourceInfoSchema = object({
|
|
|
20215
20603
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20216
20604
|
* Used to detect rename when `id` changes. */
|
|
20217
20605
|
uniqueId: string().optional(),
|
|
20606
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20607
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20608
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20609
|
+
dateTimeShape: _enum([
|
|
20610
|
+
"date",
|
|
20611
|
+
"time",
|
|
20612
|
+
"datetime"
|
|
20613
|
+
]).optional(),
|
|
20218
20614
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20219
20615
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20220
20616
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41127,7 +41523,8 @@ method(object({
|
|
|
41127
41523
|
"enum"
|
|
41128
41524
|
]),
|
|
41129
41525
|
enumValues: array(string()).optional(),
|
|
41130
|
-
item: boolean().optional()
|
|
41526
|
+
item: boolean().optional(),
|
|
41527
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41131
41528
|
})).readonly(),
|
|
41132
41529
|
itemArray: object({
|
|
41133
41530
|
path: string(),
|
|
@@ -44927,8 +45324,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44927
45324
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44928
45325
|
var MaskGridShapeSchema = object({
|
|
44929
45326
|
kind: literal("grid"),
|
|
44930
|
-
gridWidth: number(),
|
|
44931
|
-
gridHeight: number(),
|
|
45327
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45328
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44932
45329
|
cells: array(boolean())
|
|
44933
45330
|
});
|
|
44934
45331
|
discriminatedUnion("kind", [
|
|
@@ -45040,6 +45437,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45040
45437
|
"detection-blind",
|
|
45041
45438
|
"motion-noisy",
|
|
45042
45439
|
"motion-calm",
|
|
45440
|
+
"package-llm-silent",
|
|
45441
|
+
"package-llm-answered",
|
|
45043
45442
|
"recording-stalled",
|
|
45044
45443
|
"recording-healthy",
|
|
45045
45444
|
"recording-degraded",
|
|
@@ -56067,6 +56466,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56067
56466
|
deprecated: string().optional(),
|
|
56068
56467
|
distTags: array(string()).readonly()
|
|
56069
56468
|
});
|
|
56469
|
+
/**
|
|
56470
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56471
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56472
|
+
* tarball failure — never an empty string standing in for either.
|
|
56473
|
+
*/
|
|
56474
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56475
|
+
object({
|
|
56476
|
+
status: literal("ok"),
|
|
56477
|
+
markdown: string()
|
|
56478
|
+
}),
|
|
56479
|
+
object({ status: literal("missing") }),
|
|
56480
|
+
object({
|
|
56481
|
+
status: literal("error"),
|
|
56482
|
+
message: string()
|
|
56483
|
+
})
|
|
56484
|
+
]);
|
|
56485
|
+
var PackageDocsSchema = object({
|
|
56486
|
+
name: string(),
|
|
56487
|
+
version: string(),
|
|
56488
|
+
readme: PackageDocBodySchema,
|
|
56489
|
+
changelog: PackageDocBodySchema
|
|
56490
|
+
});
|
|
56070
56491
|
var SearchResultSchema = object({
|
|
56071
56492
|
name: string(),
|
|
56072
56493
|
version: string(),
|
|
@@ -56285,7 +56706,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56285
56706
|
}), object({ success: literal(true) }), {
|
|
56286
56707
|
kind: "mutation",
|
|
56287
56708
|
auth: "admin"
|
|
56288
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56709
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56710
|
+
name: string().min(1),
|
|
56711
|
+
version: string().min(1).optional()
|
|
56712
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56289
56713
|
kind: "mutation",
|
|
56290
56714
|
auth: "admin"
|
|
56291
56715
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -56335,46 +56759,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56335
56759
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56336
56760
|
object({
|
|
56337
56761
|
/** Carbon dioxide concentration in ppm. */
|
|
56338
|
-
co2Ppm: number().min(0).optional(),
|
|
56762
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56339
56763
|
/** Total volatile organic compounds in ppb. */
|
|
56340
|
-
vocPpb: number().min(0).optional(),
|
|
56764
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56341
56765
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56342
|
-
pm25: number().min(0).optional(),
|
|
56766
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56343
56767
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56344
|
-
pm10: number().min(0).optional(),
|
|
56768
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56345
56769
|
/** Composite AQI value (typically 0..500). */
|
|
56346
|
-
aqi: number().optional(),
|
|
56770
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56347
56771
|
/** Ms epoch when the slice was last updated. */
|
|
56348
|
-
lastFetchedAt: number()
|
|
56349
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56350
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56351
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56352
|
-
* per slice is unambiguous. */
|
|
56353
|
-
unit: string().optional(),
|
|
56354
|
-
/** Suggested decimal places for numeric display.
|
|
56355
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56356
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56357
|
-
* auto-formatting when absent. */
|
|
56358
|
-
precision: number().int().min(0).max(10).optional()
|
|
56772
|
+
lastFetchedAt: number()
|
|
56359
56773
|
});
|
|
56360
56774
|
DeviceType.Sensor;
|
|
56361
56775
|
object({
|
|
56362
|
-
/** Current illuminance in lux (lx). */
|
|
56363
|
-
lux: number().min(0).meta({
|
|
56364
|
-
|
|
56776
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56777
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56778
|
+
precision: 0,
|
|
56365
56779
|
label: "Illuminance"
|
|
56366
|
-
}),
|
|
56780
|
+
})),
|
|
56367
56781
|
/** Ms epoch when the slice was last updated. */
|
|
56368
|
-
lastFetchedAt: number()
|
|
56369
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56370
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56371
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56372
|
-
unit: string().optional(),
|
|
56373
|
-
/** Suggested decimal places for numeric display.
|
|
56374
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56375
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56376
|
-
* auto-formatting when absent. */
|
|
56377
|
-
precision: number().int().min(0).max(10).optional()
|
|
56782
|
+
lastFetchedAt: number()
|
|
56378
56783
|
});
|
|
56379
56784
|
DeviceType.Sensor;
|
|
56380
56785
|
/**
|
|
@@ -56519,10 +56924,7 @@ var BatteryStatusSchema = object({
|
|
|
56519
56924
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56520
56925
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56521
56926
|
*/
|
|
56522
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56523
|
-
unit: "%",
|
|
56524
|
-
label: "Charge"
|
|
56525
|
-
}),
|
|
56927
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56526
56928
|
/**
|
|
56527
56929
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56528
56930
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56549,7 +56951,14 @@ var BatteryStatusSchema = object({
|
|
|
56549
56951
|
*/
|
|
56550
56952
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56551
56953
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56552
|
-
lastUpdated: number(),
|
|
56954
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56955
|
+
/**
|
|
56956
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56957
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56958
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56959
|
+
* `numeric-sensor` on the same device.
|
|
56960
|
+
*/
|
|
56961
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56553
56962
|
/**
|
|
56554
56963
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56555
56964
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56609,7 +57018,7 @@ object({
|
|
|
56609
57018
|
DeviceType.Sensor;
|
|
56610
57019
|
object({
|
|
56611
57020
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56612
|
-
percentage: number().min(0).max(100),
|
|
57021
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56613
57022
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56614
57023
|
lastChangedAt: number()
|
|
56615
57024
|
});
|
|
@@ -57004,21 +57413,21 @@ object({
|
|
|
57004
57413
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57005
57414
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57006
57415
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57007
|
-
target: number().nullable(),
|
|
57416
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57008
57417
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57009
57418
|
* in `heat_cool` mode. */
|
|
57010
|
-
targetHigh: number().nullable(),
|
|
57419
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57011
57420
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57012
57421
|
* in `heat_cool` mode. */
|
|
57013
|
-
targetLow: number().nullable(),
|
|
57422
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57014
57423
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57015
57424
|
* humidity control. */
|
|
57016
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57425
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57017
57426
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57018
57427
|
* the device's internal sensor. */
|
|
57019
|
-
currentTemp: number().nullable(),
|
|
57428
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57020
57429
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57021
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57430
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57022
57431
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57023
57432
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57024
57433
|
swingVertical: boolean().nullable(),
|
|
@@ -57026,11 +57435,11 @@ object({
|
|
|
57026
57435
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57027
57436
|
swingHorizontal: boolean().nullable(),
|
|
57028
57437
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57029
|
-
minTemp: number().nullable().optional(),
|
|
57438
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57030
57439
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57031
|
-
maxTemp: number().nullable().optional(),
|
|
57440
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57032
57441
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57033
|
-
tempStep: number().positive().nullable().optional(),
|
|
57442
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57034
57443
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57035
57444
|
lastFetchedAt: number()
|
|
57036
57445
|
});
|
|
@@ -57109,17 +57518,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
57109
57518
|
* modes to expose in the picker without a slice fetch.
|
|
57110
57519
|
*/
|
|
57111
57520
|
var RgbTripletSchema = object({
|
|
57112
|
-
r: number().int().min(0).max(255),
|
|
57113
|
-
g: number().int().min(0).max(255),
|
|
57114
|
-
b: number().int().min(0).max(255)
|
|
57521
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57522
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57523
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57115
57524
|
});
|
|
57116
57525
|
var HsvTripletSchema = object({
|
|
57117
57526
|
/** Hue in degrees, 0..360. */
|
|
57118
|
-
h: number().min(0).max(360),
|
|
57527
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57119
57528
|
/** Saturation as 0..100 inclusive. */
|
|
57120
|
-
s: number().min(0).max(100),
|
|
57529
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57121
57530
|
/** Value/brightness as 0..100 inclusive. */
|
|
57122
|
-
v: number().min(0).max(100)
|
|
57531
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57123
57532
|
});
|
|
57124
57533
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57125
57534
|
object({
|
|
@@ -57148,7 +57557,7 @@ object({
|
|
|
57148
57557
|
/** Populated when `mode === 'hsv'`. */
|
|
57149
57558
|
hsv: HsvTripletSchema.optional(),
|
|
57150
57559
|
/** Populated when `mode === 'mired'`. */
|
|
57151
|
-
mireds: number().int().optional(),
|
|
57560
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57152
57561
|
/** Ms epoch of the last operator-driven change. */
|
|
57153
57562
|
lastChangedAt: number()
|
|
57154
57563
|
});
|
|
@@ -57272,18 +57681,12 @@ _enum([
|
|
|
57272
57681
|
"empty",
|
|
57273
57682
|
"full"
|
|
57274
57683
|
]);
|
|
57275
|
-
/**
|
|
57276
|
-
|
|
57277
|
-
|
|
57278
|
-
"days",
|
|
57279
|
-
"hours",
|
|
57280
|
-
"cycles"
|
|
57281
|
-
]);
|
|
57282
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57283
|
-
* days). `value` null = unknown (D393). */
|
|
57684
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57685
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57686
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57284
57687
|
var ConsumableRemainingSchema = object({
|
|
57285
|
-
value: number().min(0).nullable(),
|
|
57286
|
-
|
|
57688
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57689
|
+
kind: ConsumableRemainingKindSchema
|
|
57287
57690
|
});
|
|
57288
57691
|
var ConsumablesStatusSchema = object({
|
|
57289
57692
|
items: array(object({
|
|
@@ -57292,7 +57695,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57292
57695
|
/** Display name. */
|
|
57293
57696
|
label: string().min(1),
|
|
57294
57697
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57295
|
-
level: number().min(0).max(100).nullable(),
|
|
57698
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57296
57699
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57297
57700
|
status: ConsumableStatusSchema.nullable(),
|
|
57298
57701
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57309,7 +57712,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57309
57712
|
})),
|
|
57310
57713
|
lastChangedAt: number()
|
|
57311
57714
|
});
|
|
57312
|
-
Object.values(DeviceType), [...
|
|
57715
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57313
57716
|
Object.values(DeviceType), method(object({
|
|
57314
57717
|
deviceId: number().int().nonnegative(),
|
|
57315
57718
|
key: string().min(1)
|
|
@@ -57334,39 +57737,17 @@ object({
|
|
|
57334
57737
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57335
57738
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57336
57739
|
* or time-only — HA accepts all three forms). */
|
|
57337
|
-
value: union([number(), string()]),
|
|
57740
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57338
57741
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57339
57742
|
options: array(string()),
|
|
57340
57743
|
/** Ms epoch when the slice was last updated. */
|
|
57341
57744
|
lastChangedAt: number(),
|
|
57342
|
-
/**
|
|
57343
|
-
|
|
57344
|
-
|
|
57345
|
-
|
|
57346
|
-
/**
|
|
57347
|
-
|
|
57348
|
-
min: number().optional(),
|
|
57349
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57350
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57351
|
-
max: number().optional(),
|
|
57352
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57353
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57354
|
-
step: number().optional(),
|
|
57355
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57356
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57357
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57358
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57359
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57360
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57361
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57362
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57363
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57364
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57365
|
-
format: _enum([
|
|
57366
|
-
"date",
|
|
57367
|
-
"time",
|
|
57368
|
-
"datetime"
|
|
57369
|
-
]).optional()
|
|
57745
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57746
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57747
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57748
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57749
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57750
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57370
57751
|
});
|
|
57371
57752
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57372
57753
|
object({
|
|
@@ -57404,9 +57785,9 @@ object({
|
|
|
57404
57785
|
]),
|
|
57405
57786
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57406
57787
|
* no intermediate position surface. */
|
|
57407
|
-
position: number().min(0).max(100).nullable(),
|
|
57788
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57408
57789
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57409
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57790
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57410
57791
|
/** Ms epoch when the slice was last updated. */
|
|
57411
57792
|
lastChangedAt: number()
|
|
57412
57793
|
});
|
|
@@ -57464,9 +57845,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57464
57845
|
object({
|
|
57465
57846
|
mode: DayNightModeSchema,
|
|
57466
57847
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57467
|
-
sensitivity: number().optional(),
|
|
57848
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57468
57849
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57469
|
-
switchDelaySec: number().optional(),
|
|
57850
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57470
57851
|
lastFetchedAt: number()
|
|
57471
57852
|
});
|
|
57472
57853
|
/**
|
|
@@ -57621,11 +58002,11 @@ object({
|
|
|
57621
58002
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57622
58003
|
availablePrograms: array(string()),
|
|
57623
58004
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57624
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
58005
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57625
58006
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57626
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
58007
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57627
58008
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57628
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58009
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57629
58010
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57630
58011
|
doorOpen: boolean().nullable(),
|
|
57631
58012
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57649,7 +58030,7 @@ object({
|
|
|
57649
58030
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57650
58031
|
machineCareDue: boolean().nullable(),
|
|
57651
58032
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57652
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
58033
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57653
58034
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57654
58035
|
halfLoad: boolean().nullable(),
|
|
57655
58036
|
hygienePlus: boolean().nullable(),
|
|
@@ -57664,7 +58045,7 @@ object({
|
|
|
57664
58045
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57665
58046
|
activeEvents: array(string()),
|
|
57666
58047
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57667
|
-
errorCode: number().nullable(),
|
|
58048
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57668
58049
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57669
58050
|
errorLabel: string().nullable(),
|
|
57670
58051
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57810,24 +58191,14 @@ object({
|
|
|
57810
58191
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57811
58192
|
lastPressedAt: number().nullable(),
|
|
57812
58193
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57813
|
-
pressCountSinceStart: number()
|
|
58194
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57814
58195
|
});
|
|
57815
58196
|
object({
|
|
57816
58197
|
deviceId: number(),
|
|
57817
58198
|
timestamp: number()
|
|
57818
58199
|
});
|
|
57819
58200
|
DeviceType.Button, DeviceType.Camera;
|
|
57820
|
-
|
|
57821
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57822
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57823
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57824
|
-
* The option set is stable across observations; it is persisted in the
|
|
57825
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57826
|
-
* stored in `sourceInfo`.
|
|
57827
|
-
*/
|
|
57828
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57829
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57830
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
58201
|
+
_enum([
|
|
57831
58202
|
"date",
|
|
57832
58203
|
"time",
|
|
57833
58204
|
"datetime"
|
|
@@ -57835,12 +58206,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57835
58206
|
object({
|
|
57836
58207
|
value: string(),
|
|
57837
58208
|
/**
|
|
57838
|
-
* Set
|
|
57839
|
-
* as
|
|
57840
|
-
*
|
|
57841
|
-
* a time-only sensor → `'time'`.
|
|
58209
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
58210
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
58211
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57842
58212
|
*/
|
|
57843
|
-
|
|
58213
|
+
timestamp: boolean().optional(),
|
|
57844
58214
|
/** Ms epoch when the slice was last updated. */
|
|
57845
58215
|
lastFetchedAt: number()
|
|
57846
58216
|
});
|
|
@@ -57859,13 +58229,13 @@ var EventFireSchema = object({
|
|
|
57859
58229
|
deviceId: number(),
|
|
57860
58230
|
eventType: string(),
|
|
57861
58231
|
data: record(string(), unknown()).nullable(),
|
|
57862
|
-
timestamp: number(),
|
|
57863
|
-
seq: number()
|
|
58232
|
+
timestamp: number().meta(readingMeta("none")),
|
|
58233
|
+
seq: number().meta(readingMeta("count"))
|
|
57864
58234
|
});
|
|
57865
58235
|
object({
|
|
57866
58236
|
eventTypes: array(string()),
|
|
57867
58237
|
lastEvent: EventFireSchema.nullable(),
|
|
57868
|
-
eventCountSinceStart: number()
|
|
58238
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57869
58239
|
});
|
|
57870
58240
|
DeviceType.EventEmitter;
|
|
57871
58241
|
var IdentitySchema = object({
|
|
@@ -58254,10 +58624,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58254
58624
|
object({
|
|
58255
58625
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58256
58626
|
* speed surface (single-speed fan). */
|
|
58257
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58627
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58258
58628
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58259
58629
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58260
|
-
percentageStep: number().positive().optional(),
|
|
58630
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58261
58631
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58262
58632
|
* — empty string when no preset is active or supported. */
|
|
58263
58633
|
preset: string(),
|
|
@@ -58339,7 +58709,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58339
58709
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58340
58710
|
model: string().nullable(),
|
|
58341
58711
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58342
|
-
channelCount: number().nullable(),
|
|
58712
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58343
58713
|
/**
|
|
58344
58714
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58345
58715
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58371,9 +58741,39 @@ object({
|
|
|
58371
58741
|
lastChangedAt: number()
|
|
58372
58742
|
});
|
|
58373
58743
|
DeviceType.Sensor;
|
|
58744
|
+
object({
|
|
58745
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
58746
|
+
results: array(object({
|
|
58747
|
+
deviceId: number().int().nonnegative(),
|
|
58748
|
+
cap: string().min(1),
|
|
58749
|
+
method: string().min(1),
|
|
58750
|
+
ok: boolean(),
|
|
58751
|
+
error: string().optional(),
|
|
58752
|
+
/** Ms epoch of the attempt. */
|
|
58753
|
+
at: number()
|
|
58754
|
+
})) });
|
|
58755
|
+
DeviceType.Switch, DeviceType.Light;
|
|
58756
|
+
object({
|
|
58757
|
+
/** Members whose current value entered the aggregate. */
|
|
58758
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
58759
|
+
precision: 0,
|
|
58760
|
+
label: "Reporting"
|
|
58761
|
+
})),
|
|
58762
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
58763
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
58764
|
+
precision: 0,
|
|
58765
|
+
label: "Excluded"
|
|
58766
|
+
})),
|
|
58767
|
+
/** `included` + `excluded`. */
|
|
58768
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
58769
|
+
precision: 0,
|
|
58770
|
+
label: "Members"
|
|
58771
|
+
}))
|
|
58772
|
+
});
|
|
58773
|
+
DeviceType.Sensor, DeviceType.Switch, DeviceType.Light;
|
|
58374
58774
|
object({
|
|
58375
58775
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58376
|
-
position: number().min(0).max(100).nullable(),
|
|
58776
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58377
58777
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58378
58778
|
lastFetchedAt: number()
|
|
58379
58779
|
});
|
|
@@ -58382,9 +58782,9 @@ object({
|
|
|
58382
58782
|
/** Whether the humidifier is currently on. */
|
|
58383
58783
|
on: boolean(),
|
|
58384
58784
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58385
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58785
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58386
58786
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58387
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58787
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58388
58788
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58389
58789
|
* device has no mode surface. */
|
|
58390
58790
|
mode: string().nullable(),
|
|
@@ -58394,9 +58794,9 @@ object({
|
|
|
58394
58794
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58395
58795
|
action: string().nullable(),
|
|
58396
58796
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58397
|
-
minHumidity: number().nullable(),
|
|
58797
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58398
58798
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58399
|
-
maxHumidity: number().nullable(),
|
|
58799
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58400
58800
|
/** Ms epoch when the slice was last updated. */
|
|
58401
58801
|
lastChangedAt: number()
|
|
58402
58802
|
});
|
|
@@ -58420,22 +58820,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58420
58820
|
auth: "protected"
|
|
58421
58821
|
});
|
|
58422
58822
|
object({
|
|
58423
|
-
/** Current relative humidity, 0..100. */
|
|
58424
|
-
percent: number().min(0).max(100).meta({
|
|
58425
|
-
|
|
58823
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58824
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58825
|
+
precision: 0,
|
|
58426
58826
|
label: "Humidity"
|
|
58427
|
-
}),
|
|
58827
|
+
})),
|
|
58428
58828
|
/** Ms epoch when the slice was last updated. */
|
|
58429
|
-
lastFetchedAt: number()
|
|
58430
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58431
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58432
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58433
|
-
unit: string().optional(),
|
|
58434
|
-
/** Suggested decimal places for numeric display.
|
|
58435
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58436
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58437
|
-
* auto-formatting when absent. */
|
|
58438
|
-
precision: number().int().min(0).max(10).optional()
|
|
58829
|
+
lastFetchedAt: number()
|
|
58439
58830
|
});
|
|
58440
58831
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58441
58832
|
object({
|
|
@@ -58443,7 +58834,7 @@ object({
|
|
|
58443
58834
|
* entity exposes no `entity_picture` (yet). */
|
|
58444
58835
|
url: string().nullable(),
|
|
58445
58836
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58446
|
-
lastUpdated: number().nullable()
|
|
58837
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58447
58838
|
});
|
|
58448
58839
|
DeviceType.Image;
|
|
58449
58840
|
/**
|
|
@@ -58499,19 +58890,19 @@ var NormalizedRangeSchema = object({
|
|
|
58499
58890
|
});
|
|
58500
58891
|
object({
|
|
58501
58892
|
/** Normalized 0–100. */
|
|
58502
|
-
brightness: number().optional(),
|
|
58893
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58503
58894
|
/** Normalized 0–100. */
|
|
58504
|
-
contrast: number().optional(),
|
|
58895
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58505
58896
|
/** Normalized 0–100. */
|
|
58506
|
-
saturation: number().optional(),
|
|
58897
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58507
58898
|
/** Normalized 0–100. */
|
|
58508
|
-
sharpness: number().optional(),
|
|
58899
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58509
58900
|
mirror: boolean().optional(),
|
|
58510
58901
|
flip: boolean().optional(),
|
|
58511
58902
|
rotate: ImageRotateSchema.optional(),
|
|
58512
58903
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58513
58904
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58514
|
-
warmth: number().optional(),
|
|
58905
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58515
58906
|
exposureMode: ExposureModeSchema.optional(),
|
|
58516
58907
|
backlightMode: BacklightModeSchema.optional(),
|
|
58517
58908
|
lastFetchedAt: number()
|
|
@@ -58756,10 +59147,10 @@ var IntercomAbilitySchema = object({
|
|
|
58756
59147
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58757
59148
|
codecs: array(string()),
|
|
58758
59149
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58759
|
-
sampleRate: number(),
|
|
59150
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58760
59151
|
duplex: _enum(["half", "full"]),
|
|
58761
59152
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58762
|
-
maxBacklogMs: number()
|
|
59153
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58763
59154
|
});
|
|
58764
59155
|
var IntercomStatusSchema = object({
|
|
58765
59156
|
/** True while a talk session is open. */
|
|
@@ -58870,13 +59261,13 @@ object({
|
|
|
58870
59261
|
activity: LawnMowerActivitySchema,
|
|
58871
59262
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58872
59263
|
* reading. */
|
|
58873
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
59264
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58874
59265
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58875
59266
|
* task is active / progress is unavailable. */
|
|
58876
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
59267
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58877
59268
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58878
59269
|
* or null when unknown. */
|
|
58879
|
-
currentCode: number().nullable(),
|
|
59270
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58880
59271
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58881
59272
|
currentCodeLabel: string().nullable(),
|
|
58882
59273
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59338,7 +59729,7 @@ object({
|
|
|
59338
59729
|
state: MediaPlayerStateSchema,
|
|
59339
59730
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59340
59731
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59341
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59732
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59342
59733
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59343
59734
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59344
59735
|
isMuted: boolean().nullable(),
|
|
@@ -59351,10 +59742,10 @@ object({
|
|
|
59351
59742
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59352
59743
|
/** Current playback position in ms. Null when not seekable or
|
|
59353
59744
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59354
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59745
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59355
59746
|
/** Total duration of the current media in ms. Null when unknown
|
|
59356
59747
|
* (live stream) or nothing is playing. */
|
|
59357
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59748
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59358
59749
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59359
59750
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59360
59751
|
shuffle: boolean().nullable(),
|
|
@@ -59654,7 +60045,7 @@ object({
|
|
|
59654
60045
|
* it, every provider seeded it at boot, and every session left it
|
|
59655
60046
|
* `detected: true` after its detach.
|
|
59656
60047
|
*/
|
|
59657
|
-
autoClearAfterMs: number().nullable()
|
|
60048
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59658
60049
|
});
|
|
59659
60050
|
/**
|
|
59660
60051
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59704,7 +60095,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59704
60095
|
});
|
|
59705
60096
|
object({
|
|
59706
60097
|
enabled: boolean(),
|
|
59707
|
-
sensitivity: number(),
|
|
60098
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59708
60099
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59709
60100
|
regions: array(MotionZoneRegionSchema),
|
|
59710
60101
|
lastFetchedAt: number()
|
|
@@ -60008,7 +60399,7 @@ var NavigationStatusSchema = object({
|
|
|
60008
60399
|
following: boolean(),
|
|
60009
60400
|
flash: boolean(),
|
|
60010
60401
|
lightMode: NavigationLightModeSchema,
|
|
60011
|
-
lightLevel: number().min(40).max(100),
|
|
60402
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
60012
60403
|
/** Ms epoch when the slice was last updated. */
|
|
60013
60404
|
lastChangedAt: number()
|
|
60014
60405
|
});
|
|
@@ -60054,13 +60445,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
60054
60445
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
60055
60446
|
* SKIP a null rather than coerce it.
|
|
60056
60447
|
*/
|
|
60057
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
60448
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60058
60449
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
60059
|
-
rssiDbm: number().optional(),
|
|
60450
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
60060
60451
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
60061
60452
|
ssid: string().optional(),
|
|
60062
60453
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60063
|
-
lastUpdated: number()
|
|
60454
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
60064
60455
|
});
|
|
60065
60456
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
60066
60457
|
deviceId: number(),
|
|
@@ -60379,7 +60770,7 @@ object({
|
|
|
60379
60770
|
lastError: string().nullable(),
|
|
60380
60771
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60381
60772
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60382
|
-
queueDepth: number().int().nonnegative(),
|
|
60773
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60383
60774
|
/** Per-feature capability matrix — authoritative source for the
|
|
60384
60775
|
* compose-form field gating. */
|
|
60385
60776
|
supports: NotifierSupportsSchema
|
|
@@ -60429,15 +60820,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60429
60820
|
acceptedAt: number()
|
|
60430
60821
|
});
|
|
60431
60822
|
object({
|
|
60432
|
-
|
|
60433
|
-
|
|
60434
|
-
* Populated live from the upstream source on each state push.
|
|
60435
|
-
* Absent for unitless sensors. */
|
|
60436
|
-
unit: string().optional(),
|
|
60437
|
-
/** Suggested decimal places for numeric display.
|
|
60438
|
-
* Populated live from the upstream source when provided.
|
|
60439
|
-
* Falls back to auto-formatting when absent. */
|
|
60440
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60823
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60824
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60441
60825
|
/** Ms epoch when the slice was last updated. */
|
|
60442
60826
|
lastFetchedAt: number()
|
|
60443
60827
|
});
|
|
@@ -60727,23 +61111,26 @@ object({
|
|
|
60727
61111
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60728
61112
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60729
61113
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60730
|
-
foodLevel: number().nullable(),
|
|
61114
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60731
61115
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60732
61116
|
* single-hopper models. */
|
|
60733
|
-
food1: number().nullable(),
|
|
61117
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60734
61118
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60735
61119
|
* single-hopper models. */
|
|
60736
|
-
food2: number().nullable(),
|
|
61120
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60737
61121
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60738
61122
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60739
61123
|
* below the feeder's low threshold. */
|
|
60740
61124
|
lowFood: boolean(),
|
|
60741
61125
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60742
61126
|
* device has no battery reading. */
|
|
60743
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60744
|
-
/**
|
|
60745
|
-
*
|
|
60746
|
-
|
|
61127
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61128
|
+
/**
|
|
61129
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
61130
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
61131
|
+
* model has no desiccant sensor.
|
|
61132
|
+
*/
|
|
61133
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60747
61134
|
/** True while a feed is in progress. */
|
|
60748
61135
|
feeding: boolean(),
|
|
60749
61136
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60754,7 +61141,7 @@ object({
|
|
|
60754
61141
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60755
61142
|
error: string().nullable(),
|
|
60756
61143
|
/** Raw device error code (0 / null = no error). */
|
|
60757
|
-
errorCode: number().nullable(),
|
|
61144
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60758
61145
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60759
61146
|
isDualHopper: boolean(),
|
|
60760
61147
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60764,7 +61151,7 @@ object({
|
|
|
60764
61151
|
/** Play a chime when dispensing. */
|
|
60765
61152
|
feedSound: boolean(),
|
|
60766
61153
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60767
|
-
volume: number(),
|
|
61154
|
+
volume: number().meta(readingMeta("none")),
|
|
60768
61155
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60769
61156
|
lastFetchedAt: number()
|
|
60770
61157
|
});
|
|
@@ -61201,36 +61588,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61201
61588
|
});
|
|
61202
61589
|
object({
|
|
61203
61590
|
/** Instantaneous power draw in watts. */
|
|
61204
|
-
watts: number().optional().meta({
|
|
61205
|
-
unit: "W",
|
|
61206
|
-
label: "Power"
|
|
61207
|
-
}),
|
|
61591
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61208
61592
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61209
|
-
kwhTotal: number().optional().meta({
|
|
61210
|
-
unit: "kWh",
|
|
61211
|
-
label: "Energy"
|
|
61212
|
-
}),
|
|
61593
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61213
61594
|
/** Voltage in volts. */
|
|
61214
|
-
volts: number().optional(),
|
|
61595
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61215
61596
|
/** Current in amperes. */
|
|
61216
|
-
amps: number().optional(),
|
|
61217
|
-
/** Apparent power in volt-amperes
|
|
61218
|
-
va: number().optional(),
|
|
61597
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61598
|
+
/** Apparent power in volt-amperes. */
|
|
61599
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61219
61600
|
/** Power factor (0..1) if reported. */
|
|
61220
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61601
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61221
61602
|
/** Ms epoch when the slice was last updated. */
|
|
61222
|
-
lastFetchedAt: number()
|
|
61223
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61224
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61225
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61226
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61227
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61228
|
-
unit: string().optional(),
|
|
61229
|
-
/** Suggested decimal places for numeric display.
|
|
61230
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61231
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61232
|
-
* auto-formatting when absent. */
|
|
61233
|
-
precision: number().int().min(0).max(10).optional()
|
|
61603
|
+
lastFetchedAt: number()
|
|
61234
61604
|
});
|
|
61235
61605
|
DeviceType.Sensor;
|
|
61236
61606
|
/**
|
|
@@ -61251,11 +61621,11 @@ DeviceType.Sensor;
|
|
|
61251
61621
|
*/
|
|
61252
61622
|
var GpsLocationSchema = object({
|
|
61253
61623
|
/** Latitude in decimal degrees, -90..90. */
|
|
61254
|
-
latitude: number().min(-90).max(90),
|
|
61624
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61255
61625
|
/** Longitude in decimal degrees, -180..180. */
|
|
61256
|
-
longitude: number().min(-180).max(180),
|
|
61626
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61257
61627
|
/** Reported accuracy in meters (lower = better). */
|
|
61258
|
-
accuracyMeters: number().nonnegative()
|
|
61628
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61259
61629
|
});
|
|
61260
61630
|
object({
|
|
61261
61631
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61267,25 +61637,16 @@ object({
|
|
|
61267
61637
|
gps: GpsLocationSchema.nullable(),
|
|
61268
61638
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61269
61639
|
* when not reported. */
|
|
61270
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61640
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61271
61641
|
/** Ms epoch when the slice was last updated. */
|
|
61272
61642
|
lastChangedAt: number()
|
|
61273
61643
|
});
|
|
61274
61644
|
DeviceType.Presence;
|
|
61275
61645
|
object({
|
|
61276
|
-
/** Current pressure in hPa. */
|
|
61277
|
-
hpa: number(),
|
|
61646
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61647
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61278
61648
|
/** Ms epoch when the slice was last updated. */
|
|
61279
|
-
lastFetchedAt: number()
|
|
61280
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61281
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61282
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61283
|
-
unit: string().optional(),
|
|
61284
|
-
/** Suggested decimal places for numeric display.
|
|
61285
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61286
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61287
|
-
* auto-formatting when absent. */
|
|
61288
|
-
precision: number().int().min(0).max(10).optional()
|
|
61649
|
+
lastFetchedAt: number()
|
|
61289
61650
|
});
|
|
61290
61651
|
DeviceType.Sensor;
|
|
61291
61652
|
/**
|
|
@@ -61618,8 +61979,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61618
61979
|
}), _void(), { kind: "mutation" });
|
|
61619
61980
|
var PtzAutotrackSettingsSchema = object({
|
|
61620
61981
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61621
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61622
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61982
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61983
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61623
61984
|
});
|
|
61624
61985
|
/**
|
|
61625
61986
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61676,7 +62037,7 @@ object({
|
|
|
61676
62037
|
/** null = unknown — never coerced to false (D393). */
|
|
61677
62038
|
running: boolean().nullable(),
|
|
61678
62039
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61679
|
-
since: number().nullable(),
|
|
62040
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61680
62041
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61681
62042
|
phase: string().nullable(),
|
|
61682
62043
|
/** null until a reading has been published (D393). */
|
|
@@ -62874,9 +63235,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62874
63235
|
*/
|
|
62875
63236
|
var RecordWindowSchema = object({
|
|
62876
63237
|
trigger: RecordTriggerSchema,
|
|
62877
|
-
day: number().int().min(0).max(6),
|
|
62878
|
-
startMinute: number().int().min(0).max(1439),
|
|
62879
|
-
endMinute: number().int().min(1).max(1440)
|
|
63238
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
63239
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
63240
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62880
63241
|
});
|
|
62881
63242
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62882
63243
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62945,10 +63306,10 @@ object({
|
|
|
62945
63306
|
/** Master "record to the card at all" switch. */
|
|
62946
63307
|
enabled: boolean().nullable(),
|
|
62947
63308
|
overwriteWhenFull: boolean().nullable(),
|
|
62948
|
-
preRecordSec: number().nullable(),
|
|
62949
|
-
postRecordSec: number().nullable(),
|
|
63309
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
63310
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62950
63311
|
/** Length of one recorded file, in minutes. */
|
|
62951
|
-
segmentMinutes: number().nullable(),
|
|
63312
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62952
63313
|
/** The primary track's weekly windows, flattened. */
|
|
62953
63314
|
windows: array(RecordWindowSchema),
|
|
62954
63315
|
/**
|
|
@@ -62964,7 +63325,7 @@ object({
|
|
|
62964
63325
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62965
63326
|
* writable.
|
|
62966
63327
|
*/
|
|
62967
|
-
unreadableWindows: number(),
|
|
63328
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62968
63329
|
/**
|
|
62969
63330
|
* The camera is scheduled to record and has NO usable storage.
|
|
62970
63331
|
*
|
|
@@ -63601,7 +63962,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63601
63962
|
url: string().optional(),
|
|
63602
63963
|
codec: string().optional(),
|
|
63603
63964
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63604
|
-
fps: number().positive().optional(),
|
|
63965
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63605
63966
|
label: string().optional(),
|
|
63606
63967
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63607
63968
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63631,18 +63992,18 @@ var StreamProfileSchema = _enum([
|
|
|
63631
63992
|
]);
|
|
63632
63993
|
/** The current encoding config of one stream profile. */
|
|
63633
63994
|
var StreamProfileConfigSchema = object({
|
|
63634
|
-
width: number(),
|
|
63635
|
-
height: number(),
|
|
63995
|
+
width: number().meta(readingMeta("none")),
|
|
63996
|
+
height: number().meta(readingMeta("none")),
|
|
63636
63997
|
codec: _enum(["h264", "h265"]),
|
|
63637
|
-
framerate: number(),
|
|
63638
|
-
bitrate: number(),
|
|
63998
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63999
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63639
64000
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63640
64001
|
encoderProfile: _enum([
|
|
63641
64002
|
"high",
|
|
63642
64003
|
"main",
|
|
63643
64004
|
"baseline"
|
|
63644
64005
|
]).optional(),
|
|
63645
|
-
gop: number().optional(),
|
|
64006
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63646
64007
|
/**
|
|
63647
64008
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63648
64009
|
*
|
|
@@ -64285,23 +64646,13 @@ object({
|
|
|
64285
64646
|
});
|
|
64286
64647
|
DeviceType.Sensor;
|
|
64287
64648
|
object({
|
|
64288
|
-
/** Current temperature in Celsius. */
|
|
64289
|
-
celsius: number().meta({
|
|
64290
|
-
|
|
64649
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64650
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64651
|
+
precision: 1,
|
|
64291
64652
|
label: "Temperature"
|
|
64292
|
-
}),
|
|
64653
|
+
})),
|
|
64293
64654
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64294
|
-
lastFetchedAt: number()
|
|
64295
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64296
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64297
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64298
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64299
|
-
unit: string().optional(),
|
|
64300
|
-
/** Suggested decimal places for numeric display.
|
|
64301
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64302
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64303
|
-
* auto-formatting when absent. */
|
|
64304
|
-
precision: number().int().min(0).max(10).optional()
|
|
64655
|
+
lastFetchedAt: number()
|
|
64305
64656
|
});
|
|
64306
64657
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64307
64658
|
/**
|
|
@@ -64553,16 +64904,16 @@ object({
|
|
|
64553
64904
|
]),
|
|
64554
64905
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64555
64906
|
* reading. */
|
|
64556
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64907
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64557
64908
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64558
64909
|
* the vacuum has no speed control. */
|
|
64559
64910
|
fanSpeed: string().nullable(),
|
|
64560
64911
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64561
64912
|
availableFanSpeeds: array(string()),
|
|
64562
64913
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64563
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64914
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64564
64915
|
/** Current error code (0 / null = no error). */
|
|
64565
|
-
errorCode: number().nullable(),
|
|
64916
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64566
64917
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64567
64918
|
errorLabel: string().nullable(),
|
|
64568
64919
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64601,7 +64952,7 @@ object({
|
|
|
64601
64952
|
]),
|
|
64602
64953
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64603
64954
|
* intermediate position surface. */
|
|
64604
|
-
position: number().min(0).max(100).nullable(),
|
|
64955
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64605
64956
|
/** Ms epoch when the slice was last updated. */
|
|
64606
64957
|
lastChangedAt: number()
|
|
64607
64958
|
});
|
|
@@ -64629,9 +64980,9 @@ object({
|
|
|
64629
64980
|
DeviceType.Sensor;
|
|
64630
64981
|
object({
|
|
64631
64982
|
/** Current measured temperature. Null when not reported. */
|
|
64632
|
-
currentTemp: number().nullable(),
|
|
64983
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64633
64984
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64634
|
-
targetTemp: number().nullable(),
|
|
64985
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64635
64986
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64636
64987
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64637
64988
|
* device reports an unknown state. */
|
|
@@ -64642,9 +64993,9 @@ object({
|
|
|
64642
64993
|
* has no away surface. */
|
|
64643
64994
|
away: boolean().nullable(),
|
|
64644
64995
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64645
|
-
minTemp: number().nullable(),
|
|
64996
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64646
64997
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64647
|
-
maxTemp: number().nullable(),
|
|
64998
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64648
64999
|
/** Ms epoch when the slice was last updated. */
|
|
64649
65000
|
lastChangedAt: number()
|
|
64650
65001
|
});
|
|
@@ -64668,25 +65019,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64668
65019
|
auth: "protected"
|
|
64669
65020
|
});
|
|
64670
65021
|
object({
|
|
64671
|
-
/** Verbatim
|
|
64672
|
-
* when no condition has been reported yet. */
|
|
65022
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64673
65023
|
condition: string().nullable(),
|
|
64674
|
-
/** Current temperature in
|
|
64675
|
-
temperature: number().nullable(),
|
|
64676
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64677
|
-
temperatureUnit: string().nullable(),
|
|
65024
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
65025
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64678
65026
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64679
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64680
|
-
/** Barometric pressure in
|
|
64681
|
-
pressure: number().nullable(),
|
|
64682
|
-
/**
|
|
64683
|
-
|
|
64684
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64685
|
-
windSpeed: number().nullable(),
|
|
64686
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64687
|
-
windSpeedUnit: string().nullable(),
|
|
65027
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
65028
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
65029
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
65030
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
65031
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64688
65032
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64689
|
-
windBearing: number().nullable(),
|
|
65033
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64690
65034
|
/** Ms epoch when the slice was last updated. */
|
|
64691
65035
|
lastFetchedAt: number()
|
|
64692
65036
|
});
|
|
@@ -65598,6 +65942,13 @@ Object.freeze({
|
|
|
65598
65942
|
access: "view",
|
|
65599
65943
|
role: "admin"
|
|
65600
65944
|
},
|
|
65945
|
+
"addons.getPackageDocs": {
|
|
65946
|
+
capName: "addons",
|
|
65947
|
+
capScope: "system",
|
|
65948
|
+
addonId: null,
|
|
65949
|
+
access: "view",
|
|
65950
|
+
role: "admin"
|
|
65951
|
+
},
|
|
65601
65952
|
"addons.getVersions": {
|
|
65602
65953
|
capName: "addons",
|
|
65603
65954
|
capScope: "system",
|
|
@@ -68706,6 +69057,20 @@ Object.freeze({
|
|
|
68706
69057
|
access: "view",
|
|
68707
69058
|
role: "viewer"
|
|
68708
69059
|
},
|
|
69060
|
+
"groupCommands.getStatus": {
|
|
69061
|
+
capName: "group-commands",
|
|
69062
|
+
capScope: "device",
|
|
69063
|
+
addonId: null,
|
|
69064
|
+
access: "view",
|
|
69065
|
+
role: "viewer"
|
|
69066
|
+
},
|
|
69067
|
+
"groupStatus.getStatus": {
|
|
69068
|
+
capName: "group-status",
|
|
69069
|
+
capScope: "device",
|
|
69070
|
+
addonId: null,
|
|
69071
|
+
access: "view",
|
|
69072
|
+
role: "viewer"
|
|
69073
|
+
},
|
|
68709
69074
|
"heatingValve.getStatus": {
|
|
68710
69075
|
capName: "heating-valve",
|
|
68711
69076
|
capScope: "device",
|
|
@@ -78528,6 +78893,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78528
78893
|
icon: "flame"
|
|
78529
78894
|
}]
|
|
78530
78895
|
},
|
|
78896
|
+
"group-commands": {
|
|
78897
|
+
scope: "device",
|
|
78898
|
+
noun: t("Group command", "Comando di gruppo")
|
|
78899
|
+
},
|
|
78900
|
+
"group-status": {
|
|
78901
|
+
scope: "device",
|
|
78902
|
+
noun: t("Group", "Gruppo"),
|
|
78903
|
+
state: [
|
|
78904
|
+
{
|
|
78905
|
+
kind: "numeric",
|
|
78906
|
+
field: "included",
|
|
78907
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
78908
|
+
label: t("Reporting", "Rispondono"),
|
|
78909
|
+
icon: "users"
|
|
78910
|
+
},
|
|
78911
|
+
{
|
|
78912
|
+
kind: "numeric",
|
|
78913
|
+
field: "excluded",
|
|
78914
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
78915
|
+
label: t("Excluded", "Esclusi"),
|
|
78916
|
+
icon: "users"
|
|
78917
|
+
},
|
|
78918
|
+
{
|
|
78919
|
+
kind: "numeric",
|
|
78920
|
+
field: "total",
|
|
78921
|
+
quantity: t("the member count", "il numero di membri"),
|
|
78922
|
+
label: t("Members", "Membri"),
|
|
78923
|
+
icon: "sigma"
|
|
78924
|
+
}
|
|
78925
|
+
]
|
|
78926
|
+
},
|
|
78531
78927
|
"humidity-sensor": {
|
|
78532
78928
|
scope: "device",
|
|
78533
78929
|
noun: t("Humidity", "Umidità"),
|
|
@@ -78561,7 +78957,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78561
78957
|
field: "value",
|
|
78562
78958
|
quantity: t("the reading", "il valore"),
|
|
78563
78959
|
label: t("Reading", "Valore"),
|
|
78564
|
-
unitField: "unit",
|
|
78565
78960
|
icon: "gauge"
|
|
78566
78961
|
}]
|
|
78567
78962
|
},
|
|
@@ -78697,7 +79092,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78697
79092
|
field: "temperature",
|
|
78698
79093
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78699
79094
|
label: t("Temperature", "Temperatura"),
|
|
78700
|
-
|
|
79095
|
+
unit: "°C",
|
|
78701
79096
|
icon: "thermometer"
|
|
78702
79097
|
},
|
|
78703
79098
|
{
|
|
@@ -78713,7 +79108,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78713
79108
|
field: "windSpeed",
|
|
78714
79109
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78715
79110
|
label: t("Wind", "Vento"),
|
|
78716
|
-
|
|
79111
|
+
unit: "m/s",
|
|
78717
79112
|
icon: "wind"
|
|
78718
79113
|
},
|
|
78719
79114
|
{
|
|
@@ -78721,7 +79116,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78721
79116
|
field: "pressure",
|
|
78722
79117
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78723
79118
|
label: t("Pressure", "Pressione"),
|
|
78724
|
-
|
|
79119
|
+
unit: "hPa",
|
|
78725
79120
|
icon: "gauge"
|
|
78726
79121
|
}
|
|
78727
79122
|
]
|
|
@@ -79994,6 +80389,16 @@ Object.freeze({
|
|
|
79994
80389
|
form: "single",
|
|
79995
80390
|
optional: false
|
|
79996
80391
|
}],
|
|
80392
|
+
"groupCommands.getStatus": [{
|
|
80393
|
+
name: "deviceId",
|
|
80394
|
+
form: "single",
|
|
80395
|
+
optional: false
|
|
80396
|
+
}],
|
|
80397
|
+
"groupStatus.getStatus": [{
|
|
80398
|
+
name: "deviceId",
|
|
80399
|
+
form: "single",
|
|
80400
|
+
optional: false
|
|
80401
|
+
}],
|
|
79997
80402
|
"heatingValve.getStatus": [{
|
|
79998
80403
|
name: "deviceId",
|
|
79999
80404
|
form: "single",
|
|
@@ -81858,6 +82263,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
81858
82263
|
targetId: string().min(1),
|
|
81859
82264
|
enabled: boolean(),
|
|
81860
82265
|
debounceMs: number().nonnegative(),
|
|
82266
|
+
edges: array(_enum([
|
|
82267
|
+
"rising",
|
|
82268
|
+
"button",
|
|
82269
|
+
"native-event"
|
|
82270
|
+
])).min(1).optional(),
|
|
81861
82271
|
sources: array(OverrideSourceSchema).min(1)
|
|
81862
82272
|
});
|
|
81863
82273
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|
|
@@ -81973,6 +82383,8 @@ new Map(Object.entries({
|
|
|
81973
82383
|
"detection-blind": "device-events",
|
|
81974
82384
|
"motion-noisy": "device-events",
|
|
81975
82385
|
"motion-calm": "device-events",
|
|
82386
|
+
"package-llm-silent": "device-events",
|
|
82387
|
+
"package-llm-answered": "device-events",
|
|
81976
82388
|
"recording-stalled": "device-events",
|
|
81977
82389
|
"recording-healthy": "device-events",
|
|
81978
82390
|
"recording-degraded": "device-events",
|
|
@@ -82056,6 +82468,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
82056
82468
|
label: "Motion without a subject",
|
|
82057
82469
|
kinds: ["motion-noisy", "motion-calm"]
|
|
82058
82470
|
},
|
|
82471
|
+
{
|
|
82472
|
+
id: "package-llm",
|
|
82473
|
+
family: "device-events",
|
|
82474
|
+
label: "Package confirm",
|
|
82475
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
82476
|
+
},
|
|
82059
82477
|
{
|
|
82060
82478
|
id: "recording",
|
|
82061
82479
|
family: "device-events",
|
|
@@ -82237,6 +82655,8 @@ var DEVICE_EVENTS = [
|
|
|
82237
82655
|
"detection-blind",
|
|
82238
82656
|
"motion-noisy",
|
|
82239
82657
|
"motion-calm",
|
|
82658
|
+
"package-llm-silent",
|
|
82659
|
+
"package-llm-answered",
|
|
82240
82660
|
"recording-stalled",
|
|
82241
82661
|
"recording-healthy",
|
|
82242
82662
|
"recording-degraded",
|
|
@@ -82505,6 +82925,15 @@ new Map([
|
|
|
82505
82925
|
snapshotLabel: "Cameras with constant motion now",
|
|
82506
82926
|
snapshotSection: null
|
|
82507
82927
|
},
|
|
82928
|
+
{
|
|
82929
|
+
id: "package-llm-confirm",
|
|
82930
|
+
family: "device-events",
|
|
82931
|
+
label: "Package confirm (not answering / answering again)",
|
|
82932
|
+
bad: ["package-llm-silent"],
|
|
82933
|
+
recovery: ["package-llm-answered"],
|
|
82934
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
82935
|
+
snapshotSection: null
|
|
82936
|
+
},
|
|
82508
82937
|
{
|
|
82509
82938
|
id: "recording-health",
|
|
82510
82939
|
family: "device-events",
|