@camstack/addon-training 0.1.82 → 0.1.83
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/dist/{MotionZonesSettings-Ca-6XXfI.mjs → MotionZonesSettings-ua7eMlj6.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-BCUM9T8S.mjs → PrivacyMaskSettings-tOwuzUR7.mjs} +2 -2
- package/dist/{SceneMonitorEditor-CjJ891SK.mjs → SceneMonitorEditor-D70yDpkr.mjs} +1 -1
- package/dist/_stub.js +5358 -5290
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-vEOlZUQt.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-CX_OmaCS.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CF6J142s.mjs +26 -0
- package/dist/{dist-CQOH32eF.mjs → dist-BK5jIqgk.mjs} +273 -422
- package/dist/{dist-VJTyi7FX.js → dist-BinKWWJ5.js} +273 -422
- package/dist/{hostInit-CvOJdSqn.mjs → hostInit-DR72gpW3.mjs} +2 -2
- package/dist/index.js +1 -1
- package/dist/orchestrator/training.addon.js +1 -1
- package/dist/orchestrator/training.addon.mjs +1 -1
- package/dist/{player-overlays-Bk8LUHwl.mjs → player-overlays-DCStC-vp.mjs} +1 -1
- package/dist/providers/modal/training-modal.addon.js +1 -1
- package/dist/providers/modal/training-modal.addon.mjs +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-DkRlf-GQ.mjs → responsive-DsQ48pYk.mjs} +16 -13
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-DNg-tEZh.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-BToJVQAB.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-9NmkfCw8.mjs +0 -26
|
@@ -5600,7 +5600,7 @@ var ZodIssueCode = {
|
|
|
5600
5600
|
var ZodFirstPartyTypeKind;
|
|
5601
5601
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5602
5602
|
//#endregion
|
|
5603
|
-
//#region ../types/dist/sleep-
|
|
5603
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5604
5604
|
/**
|
|
5605
5605
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5606
5606
|
* window to float samples (D455).
|
|
@@ -8335,6 +8335,52 @@ function defineEntryKind(name, spec) {
|
|
|
8335
8335
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8336
8336
|
return defined;
|
|
8337
8337
|
}
|
|
8338
|
+
var READING_QUANTITIES = [
|
|
8339
|
+
"temperature",
|
|
8340
|
+
"pressure",
|
|
8341
|
+
"speed",
|
|
8342
|
+
"precipitation",
|
|
8343
|
+
"precipitation-rate",
|
|
8344
|
+
"length",
|
|
8345
|
+
"area",
|
|
8346
|
+
"illuminance",
|
|
8347
|
+
"irradiance",
|
|
8348
|
+
"power",
|
|
8349
|
+
"energy",
|
|
8350
|
+
"voltage",
|
|
8351
|
+
"current",
|
|
8352
|
+
"apparent-power",
|
|
8353
|
+
"humidity",
|
|
8354
|
+
"percentage",
|
|
8355
|
+
"concentration-volume",
|
|
8356
|
+
"concentration-mass",
|
|
8357
|
+
"concentration-ppb",
|
|
8358
|
+
"volume",
|
|
8359
|
+
"duration",
|
|
8360
|
+
"duration-ms",
|
|
8361
|
+
"information",
|
|
8362
|
+
"sound-level",
|
|
8363
|
+
"signal-level",
|
|
8364
|
+
"colour-temperature",
|
|
8365
|
+
"angle",
|
|
8366
|
+
"bitrate",
|
|
8367
|
+
"rate",
|
|
8368
|
+
"mass",
|
|
8369
|
+
"index",
|
|
8370
|
+
"ratio",
|
|
8371
|
+
"count",
|
|
8372
|
+
"none",
|
|
8373
|
+
"device"
|
|
8374
|
+
];
|
|
8375
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8376
|
+
new Set(READING_QUANTITIES);
|
|
8377
|
+
function readingMeta(quantity, extras) {
|
|
8378
|
+
return {
|
|
8379
|
+
quantity,
|
|
8380
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8381
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8382
|
+
};
|
|
8383
|
+
}
|
|
8338
8384
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8339
8385
|
var CamProfileSchema = _enum([
|
|
8340
8386
|
"high",
|
|
@@ -8362,8 +8408,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8362
8408
|
"derived"
|
|
8363
8409
|
]);
|
|
8364
8410
|
var CamStreamResolutionSchema = object({
|
|
8365
|
-
width: number().int().positive(),
|
|
8366
|
-
height: number().int().positive()
|
|
8411
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8412
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8367
8413
|
});
|
|
8368
8414
|
var CameraStreamSchema = object({
|
|
8369
8415
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -9006,14 +9052,6 @@ Object.freeze({
|
|
|
9006
9052
|
{
|
|
9007
9053
|
"path": "aqi",
|
|
9008
9054
|
"valueType": "number"
|
|
9009
|
-
},
|
|
9010
|
-
{
|
|
9011
|
-
"path": "unit",
|
|
9012
|
-
"valueType": "string"
|
|
9013
|
-
},
|
|
9014
|
-
{
|
|
9015
|
-
"path": "precision",
|
|
9016
|
-
"valueType": "number"
|
|
9017
9055
|
}
|
|
9018
9056
|
],
|
|
9019
9057
|
"alarm-panel": [
|
|
@@ -9049,20 +9087,10 @@ Object.freeze({
|
|
|
9049
9087
|
"valueType": "boolean"
|
|
9050
9088
|
}
|
|
9051
9089
|
],
|
|
9052
|
-
"ambient-light-sensor": [
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
},
|
|
9057
|
-
{
|
|
9058
|
-
"path": "unit",
|
|
9059
|
-
"valueType": "string"
|
|
9060
|
-
},
|
|
9061
|
-
{
|
|
9062
|
-
"path": "precision",
|
|
9063
|
-
"valueType": "number"
|
|
9064
|
-
}
|
|
9065
|
-
],
|
|
9090
|
+
"ambient-light-sensor": [{
|
|
9091
|
+
"path": "lux",
|
|
9092
|
+
"valueType": "number"
|
|
9093
|
+
}],
|
|
9066
9094
|
"audio-metrics": [
|
|
9067
9095
|
{
|
|
9068
9096
|
"path": "ts",
|
|
@@ -9142,6 +9170,10 @@ Object.freeze({
|
|
|
9142
9170
|
"path": "lastUpdated",
|
|
9143
9171
|
"valueType": "number"
|
|
9144
9172
|
},
|
|
9173
|
+
{
|
|
9174
|
+
"path": "volts",
|
|
9175
|
+
"valueType": "number"
|
|
9176
|
+
},
|
|
9145
9177
|
{
|
|
9146
9178
|
"path": "lastContactAt",
|
|
9147
9179
|
"valueType": "number"
|
|
@@ -9384,10 +9416,6 @@ Object.freeze({
|
|
|
9384
9416
|
"datetime"
|
|
9385
9417
|
]
|
|
9386
9418
|
},
|
|
9387
|
-
{
|
|
9388
|
-
"path": "unit",
|
|
9389
|
-
"valueType": "string"
|
|
9390
|
-
},
|
|
9391
9419
|
{
|
|
9392
9420
|
"path": "min",
|
|
9393
9421
|
"valueType": "number"
|
|
@@ -9399,19 +9427,6 @@ Object.freeze({
|
|
|
9399
9427
|
{
|
|
9400
9428
|
"path": "step",
|
|
9401
9429
|
"valueType": "number"
|
|
9402
|
-
},
|
|
9403
|
-
{
|
|
9404
|
-
"path": "precision",
|
|
9405
|
-
"valueType": "number"
|
|
9406
|
-
},
|
|
9407
|
-
{
|
|
9408
|
-
"path": "format",
|
|
9409
|
-
"valueType": "enum",
|
|
9410
|
-
"enumValues": [
|
|
9411
|
-
"date",
|
|
9412
|
-
"time",
|
|
9413
|
-
"datetime"
|
|
9414
|
-
]
|
|
9415
9430
|
}
|
|
9416
9431
|
],
|
|
9417
9432
|
"cover": [
|
|
@@ -9652,13 +9667,8 @@ Object.freeze({
|
|
|
9652
9667
|
"path": "value",
|
|
9653
9668
|
"valueType": "string"
|
|
9654
9669
|
}, {
|
|
9655
|
-
"path": "
|
|
9656
|
-
"valueType": "
|
|
9657
|
-
"enumValues": [
|
|
9658
|
-
"date",
|
|
9659
|
-
"time",
|
|
9660
|
-
"datetime"
|
|
9661
|
-
]
|
|
9670
|
+
"path": "timestamp",
|
|
9671
|
+
"valueType": "boolean"
|
|
9662
9672
|
}],
|
|
9663
9673
|
"event-emitter": [
|
|
9664
9674
|
{
|
|
@@ -9765,20 +9775,10 @@ Object.freeze({
|
|
|
9765
9775
|
"valueType": "number"
|
|
9766
9776
|
}
|
|
9767
9777
|
],
|
|
9768
|
-
"humidity-sensor": [
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
},
|
|
9773
|
-
{
|
|
9774
|
-
"path": "unit",
|
|
9775
|
-
"valueType": "string"
|
|
9776
|
-
},
|
|
9777
|
-
{
|
|
9778
|
-
"path": "precision",
|
|
9779
|
-
"valueType": "number"
|
|
9780
|
-
}
|
|
9781
|
-
],
|
|
9778
|
+
"humidity-sensor": [{
|
|
9779
|
+
"path": "percent",
|
|
9780
|
+
"valueType": "number"
|
|
9781
|
+
}],
|
|
9782
9782
|
"image": [{
|
|
9783
9783
|
"path": "url",
|
|
9784
9784
|
"valueType": "string"
|
|
@@ -10117,20 +10117,10 @@ Object.freeze({
|
|
|
10117
10117
|
"valueType": "boolean"
|
|
10118
10118
|
}
|
|
10119
10119
|
],
|
|
10120
|
-
"numeric-sensor": [
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
},
|
|
10125
|
-
{
|
|
10126
|
-
"path": "unit",
|
|
10127
|
-
"valueType": "string"
|
|
10128
|
-
},
|
|
10129
|
-
{
|
|
10130
|
-
"path": "precision",
|
|
10131
|
-
"valueType": "number"
|
|
10132
|
-
}
|
|
10133
|
-
],
|
|
10120
|
+
"numeric-sensor": [{
|
|
10121
|
+
"path": "value",
|
|
10122
|
+
"valueType": "number"
|
|
10123
|
+
}],
|
|
10134
10124
|
"pet-feeder": [
|
|
10135
10125
|
{
|
|
10136
10126
|
"path": "foodLevel",
|
|
@@ -10222,14 +10212,6 @@ Object.freeze({
|
|
|
10222
10212
|
{
|
|
10223
10213
|
"path": "powerFactor",
|
|
10224
10214
|
"valueType": "number"
|
|
10225
|
-
},
|
|
10226
|
-
{
|
|
10227
|
-
"path": "unit",
|
|
10228
|
-
"valueType": "string"
|
|
10229
|
-
},
|
|
10230
|
-
{
|
|
10231
|
-
"path": "precision",
|
|
10232
|
-
"valueType": "number"
|
|
10233
10215
|
}
|
|
10234
10216
|
],
|
|
10235
10217
|
"presence": [
|
|
@@ -10258,20 +10240,10 @@ Object.freeze({
|
|
|
10258
10240
|
"valueType": "number"
|
|
10259
10241
|
}
|
|
10260
10242
|
],
|
|
10261
|
-
"pressure-sensor": [
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
},
|
|
10266
|
-
{
|
|
10267
|
-
"path": "unit",
|
|
10268
|
-
"valueType": "string"
|
|
10269
|
-
},
|
|
10270
|
-
{
|
|
10271
|
-
"path": "precision",
|
|
10272
|
-
"valueType": "number"
|
|
10273
|
-
}
|
|
10274
|
-
],
|
|
10243
|
+
"pressure-sensor": [{
|
|
10244
|
+
"path": "hpa",
|
|
10245
|
+
"valueType": "number"
|
|
10246
|
+
}],
|
|
10275
10247
|
"privacy-mask": [{
|
|
10276
10248
|
"path": "enabled",
|
|
10277
10249
|
"valueType": "boolean"
|
|
@@ -10582,20 +10554,10 @@ Object.freeze({
|
|
|
10582
10554
|
"path": "tampered",
|
|
10583
10555
|
"valueType": "boolean"
|
|
10584
10556
|
}],
|
|
10585
|
-
"temperature-sensor": [
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
},
|
|
10590
|
-
{
|
|
10591
|
-
"path": "unit",
|
|
10592
|
-
"valueType": "string"
|
|
10593
|
-
},
|
|
10594
|
-
{
|
|
10595
|
-
"path": "precision",
|
|
10596
|
-
"valueType": "number"
|
|
10597
|
-
}
|
|
10598
|
-
],
|
|
10557
|
+
"temperature-sensor": [{
|
|
10558
|
+
"path": "celsius",
|
|
10559
|
+
"valueType": "number"
|
|
10560
|
+
}],
|
|
10599
10561
|
"update": [
|
|
10600
10562
|
{
|
|
10601
10563
|
"path": "currentVersion",
|
|
@@ -10706,10 +10668,6 @@ Object.freeze({
|
|
|
10706
10668
|
"path": "temperature",
|
|
10707
10669
|
"valueType": "number"
|
|
10708
10670
|
},
|
|
10709
|
-
{
|
|
10710
|
-
"path": "temperatureUnit",
|
|
10711
|
-
"valueType": "string"
|
|
10712
|
-
},
|
|
10713
10671
|
{
|
|
10714
10672
|
"path": "humidity",
|
|
10715
10673
|
"valueType": "number"
|
|
@@ -10718,18 +10676,10 @@ Object.freeze({
|
|
|
10718
10676
|
"path": "pressure",
|
|
10719
10677
|
"valueType": "number"
|
|
10720
10678
|
},
|
|
10721
|
-
{
|
|
10722
|
-
"path": "pressureUnit",
|
|
10723
|
-
"valueType": "string"
|
|
10724
|
-
},
|
|
10725
10679
|
{
|
|
10726
10680
|
"path": "windSpeed",
|
|
10727
10681
|
"valueType": "number"
|
|
10728
10682
|
},
|
|
10729
|
-
{
|
|
10730
|
-
"path": "windSpeedUnit",
|
|
10731
|
-
"valueType": "string"
|
|
10732
|
-
},
|
|
10733
10683
|
{
|
|
10734
10684
|
"path": "windBearing",
|
|
10735
10685
|
"valueType": "number"
|
|
@@ -18112,7 +18062,8 @@ var CompositionProblemSchema = object({
|
|
|
18112
18062
|
"item-field-reserved",
|
|
18113
18063
|
"target-missing",
|
|
18114
18064
|
"target-unreadable",
|
|
18115
|
-
"not-replaceable"
|
|
18065
|
+
"not-replaceable",
|
|
18066
|
+
"native-capability-replace"
|
|
18116
18067
|
]),
|
|
18117
18068
|
path: string(),
|
|
18118
18069
|
message: string()
|
|
@@ -18170,9 +18121,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18170
18121
|
reads: array(CompositionFieldReadSchema)
|
|
18171
18122
|
});
|
|
18172
18123
|
/**
|
|
18173
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18174
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18175
|
-
*
|
|
18124
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18125
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18126
|
+
* Replacing a capability the device already serves is refused
|
|
18127
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18128
|
+
* wire for a claim the hub already holds.
|
|
18176
18129
|
*/
|
|
18177
18130
|
var CompositionFeatureModeSchema = _enum([
|
|
18178
18131
|
"new",
|
|
@@ -20058,12 +20011,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20058
20011
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20059
20012
|
* in-place so dispatch keeps working.
|
|
20060
20013
|
*
|
|
20061
|
-
* **
|
|
20062
|
-
*
|
|
20063
|
-
*
|
|
20064
|
-
*
|
|
20065
|
-
* (`ha-domain-mapping`)
|
|
20066
|
-
* stored after that point.
|
|
20014
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20015
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20016
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20017
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20018
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20019
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20067
20020
|
*
|
|
20068
20021
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20069
20022
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20077,6 +20030,14 @@ var SourceInfoSchema = object({
|
|
|
20077
20030
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20078
20031
|
* Used to detect rename when `id` changes. */
|
|
20079
20032
|
uniqueId: string().optional(),
|
|
20033
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20034
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20035
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20036
|
+
dateTimeShape: _enum([
|
|
20037
|
+
"date",
|
|
20038
|
+
"time",
|
|
20039
|
+
"datetime"
|
|
20040
|
+
]).optional(),
|
|
20080
20041
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20081
20042
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20082
20043
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40989,7 +40950,8 @@ method(object({
|
|
|
40989
40950
|
"enum"
|
|
40990
40951
|
]),
|
|
40991
40952
|
enumValues: array(string()).optional(),
|
|
40992
|
-
item: boolean().optional()
|
|
40953
|
+
item: boolean().optional(),
|
|
40954
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40993
40955
|
})).readonly(),
|
|
40994
40956
|
itemArray: object({
|
|
40995
40957
|
path: string(),
|
|
@@ -44789,8 +44751,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44789
44751
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44790
44752
|
var MaskGridShapeSchema = object({
|
|
44791
44753
|
kind: literal("grid"),
|
|
44792
|
-
gridWidth: number(),
|
|
44793
|
-
gridHeight: number(),
|
|
44754
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
44755
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44794
44756
|
cells: array(boolean())
|
|
44795
44757
|
});
|
|
44796
44758
|
discriminatedUnion("kind", [
|
|
@@ -56184,46 +56146,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56184
56146
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56185
56147
|
object({
|
|
56186
56148
|
/** Carbon dioxide concentration in ppm. */
|
|
56187
|
-
co2Ppm: number().min(0).optional(),
|
|
56149
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56188
56150
|
/** Total volatile organic compounds in ppb. */
|
|
56189
|
-
vocPpb: number().min(0).optional(),
|
|
56151
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56190
56152
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56191
|
-
pm25: number().min(0).optional(),
|
|
56153
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56192
56154
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56193
|
-
pm10: number().min(0).optional(),
|
|
56155
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56194
56156
|
/** Composite AQI value (typically 0..500). */
|
|
56195
|
-
aqi: number().optional(),
|
|
56157
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56196
56158
|
/** Ms epoch when the slice was last updated. */
|
|
56197
|
-
lastFetchedAt: number()
|
|
56198
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56199
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56200
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56201
|
-
* per slice is unambiguous. */
|
|
56202
|
-
unit: string().optional(),
|
|
56203
|
-
/** Suggested decimal places for numeric display.
|
|
56204
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56205
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56206
|
-
* auto-formatting when absent. */
|
|
56207
|
-
precision: number().int().min(0).max(10).optional()
|
|
56159
|
+
lastFetchedAt: number()
|
|
56208
56160
|
});
|
|
56209
56161
|
DeviceType.Sensor;
|
|
56210
56162
|
object({
|
|
56211
|
-
/** Current illuminance in lux (lx). */
|
|
56212
|
-
lux: number().min(0).meta({
|
|
56213
|
-
|
|
56163
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56164
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56165
|
+
precision: 0,
|
|
56214
56166
|
label: "Illuminance"
|
|
56215
|
-
}),
|
|
56167
|
+
})),
|
|
56216
56168
|
/** Ms epoch when the slice was last updated. */
|
|
56217
|
-
lastFetchedAt: number()
|
|
56218
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56219
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56220
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56221
|
-
unit: string().optional(),
|
|
56222
|
-
/** Suggested decimal places for numeric display.
|
|
56223
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56224
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56225
|
-
* auto-formatting when absent. */
|
|
56226
|
-
precision: number().int().min(0).max(10).optional()
|
|
56169
|
+
lastFetchedAt: number()
|
|
56227
56170
|
});
|
|
56228
56171
|
DeviceType.Sensor;
|
|
56229
56172
|
/**
|
|
@@ -56368,10 +56311,7 @@ var BatteryStatusSchema = object({
|
|
|
56368
56311
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56369
56312
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56370
56313
|
*/
|
|
56371
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56372
|
-
unit: "%",
|
|
56373
|
-
label: "Charge"
|
|
56374
|
-
}),
|
|
56314
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56375
56315
|
/**
|
|
56376
56316
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56377
56317
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56398,7 +56338,14 @@ var BatteryStatusSchema = object({
|
|
|
56398
56338
|
*/
|
|
56399
56339
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56400
56340
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56401
|
-
lastUpdated: number(),
|
|
56341
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56342
|
+
/**
|
|
56343
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56344
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56345
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56346
|
+
* `numeric-sensor` on the same device.
|
|
56347
|
+
*/
|
|
56348
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56402
56349
|
/**
|
|
56403
56350
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56404
56351
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56458,7 +56405,7 @@ object({
|
|
|
56458
56405
|
DeviceType.Sensor;
|
|
56459
56406
|
object({
|
|
56460
56407
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56461
|
-
percentage: number().min(0).max(100),
|
|
56408
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56462
56409
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56463
56410
|
lastChangedAt: number()
|
|
56464
56411
|
});
|
|
@@ -56843,21 +56790,21 @@ object({
|
|
|
56843
56790
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56844
56791
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56845
56792
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56846
|
-
target: number().nullable(),
|
|
56793
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56847
56794
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56848
56795
|
* in `heat_cool` mode. */
|
|
56849
|
-
targetHigh: number().nullable(),
|
|
56796
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56850
56797
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56851
56798
|
* in `heat_cool` mode. */
|
|
56852
|
-
targetLow: number().nullable(),
|
|
56799
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56853
56800
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56854
56801
|
* humidity control. */
|
|
56855
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
56802
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56856
56803
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56857
56804
|
* the device's internal sensor. */
|
|
56858
|
-
currentTemp: number().nullable(),
|
|
56805
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56859
56806
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56860
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
56807
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56861
56808
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56862
56809
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56863
56810
|
swingVertical: boolean().nullable(),
|
|
@@ -56865,11 +56812,11 @@ object({
|
|
|
56865
56812
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56866
56813
|
swingHorizontal: boolean().nullable(),
|
|
56867
56814
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56868
|
-
minTemp: number().nullable().optional(),
|
|
56815
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56869
56816
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56870
|
-
maxTemp: number().nullable().optional(),
|
|
56817
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56871
56818
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56872
|
-
tempStep: number().positive().nullable().optional(),
|
|
56819
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56873
56820
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56874
56821
|
lastFetchedAt: number()
|
|
56875
56822
|
});
|
|
@@ -56948,17 +56895,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
56948
56895
|
* modes to expose in the picker without a slice fetch.
|
|
56949
56896
|
*/
|
|
56950
56897
|
var RgbTripletSchema = object({
|
|
56951
|
-
r: number().int().min(0).max(255),
|
|
56952
|
-
g: number().int().min(0).max(255),
|
|
56953
|
-
b: number().int().min(0).max(255)
|
|
56898
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
56899
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
56900
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
56954
56901
|
});
|
|
56955
56902
|
var HsvTripletSchema = object({
|
|
56956
56903
|
/** Hue in degrees, 0..360. */
|
|
56957
|
-
h: number().min(0).max(360),
|
|
56904
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
56958
56905
|
/** Saturation as 0..100 inclusive. */
|
|
56959
|
-
s: number().min(0).max(100),
|
|
56906
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
56960
56907
|
/** Value/brightness as 0..100 inclusive. */
|
|
56961
|
-
v: number().min(0).max(100)
|
|
56908
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
56962
56909
|
});
|
|
56963
56910
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
56964
56911
|
object({
|
|
@@ -56987,7 +56934,7 @@ object({
|
|
|
56987
56934
|
/** Populated when `mode === 'hsv'`. */
|
|
56988
56935
|
hsv: HsvTripletSchema.optional(),
|
|
56989
56936
|
/** Populated when `mode === 'mired'`. */
|
|
56990
|
-
mireds: number().int().optional(),
|
|
56937
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
56991
56938
|
/** Ms epoch of the last operator-driven change. */
|
|
56992
56939
|
lastChangedAt: number()
|
|
56993
56940
|
});
|
|
@@ -57111,18 +57058,12 @@ _enum([
|
|
|
57111
57058
|
"empty",
|
|
57112
57059
|
"full"
|
|
57113
57060
|
]);
|
|
57114
|
-
/**
|
|
57115
|
-
|
|
57116
|
-
|
|
57117
|
-
"days",
|
|
57118
|
-
"hours",
|
|
57119
|
-
"cycles"
|
|
57120
|
-
]);
|
|
57121
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57122
|
-
* days). `value` null = unknown (D393). */
|
|
57061
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57062
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57063
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57123
57064
|
var ConsumableRemainingSchema = object({
|
|
57124
|
-
value: number().min(0).nullable(),
|
|
57125
|
-
|
|
57065
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57066
|
+
kind: ConsumableRemainingKindSchema
|
|
57126
57067
|
});
|
|
57127
57068
|
var ConsumablesStatusSchema = object({
|
|
57128
57069
|
items: array(object({
|
|
@@ -57131,7 +57072,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57131
57072
|
/** Display name. */
|
|
57132
57073
|
label: string().min(1),
|
|
57133
57074
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57134
|
-
level: number().min(0).max(100).nullable(),
|
|
57075
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57135
57076
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57136
57077
|
status: ConsumableStatusSchema.nullable(),
|
|
57137
57078
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57148,7 +57089,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57148
57089
|
})),
|
|
57149
57090
|
lastChangedAt: number()
|
|
57150
57091
|
});
|
|
57151
|
-
Object.values(DeviceType), [...
|
|
57092
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57152
57093
|
Object.values(DeviceType), method(object({
|
|
57153
57094
|
deviceId: number().int().nonnegative(),
|
|
57154
57095
|
key: string().min(1)
|
|
@@ -57173,39 +57114,17 @@ object({
|
|
|
57173
57114
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57174
57115
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57175
57116
|
* or time-only — HA accepts all three forms). */
|
|
57176
|
-
value: union([number(), string()]),
|
|
57117
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57177
57118
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57178
57119
|
options: array(string()),
|
|
57179
57120
|
/** Ms epoch when the slice was last updated. */
|
|
57180
57121
|
lastChangedAt: number(),
|
|
57181
|
-
/**
|
|
57182
|
-
|
|
57183
|
-
|
|
57184
|
-
|
|
57185
|
-
/**
|
|
57186
|
-
|
|
57187
|
-
min: number().optional(),
|
|
57188
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57189
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57190
|
-
max: number().optional(),
|
|
57191
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57192
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57193
|
-
step: number().optional(),
|
|
57194
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57195
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57196
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57197
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57198
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57199
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57200
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57201
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57202
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57203
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57204
|
-
format: _enum([
|
|
57205
|
-
"date",
|
|
57206
|
-
"time",
|
|
57207
|
-
"datetime"
|
|
57208
|
-
]).optional()
|
|
57122
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57123
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57124
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57125
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57126
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57127
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57209
57128
|
});
|
|
57210
57129
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57211
57130
|
object({
|
|
@@ -57243,9 +57162,9 @@ object({
|
|
|
57243
57162
|
]),
|
|
57244
57163
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57245
57164
|
* no intermediate position surface. */
|
|
57246
|
-
position: number().min(0).max(100).nullable(),
|
|
57165
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57247
57166
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57248
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57167
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57249
57168
|
/** Ms epoch when the slice was last updated. */
|
|
57250
57169
|
lastChangedAt: number()
|
|
57251
57170
|
});
|
|
@@ -57303,9 +57222,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57303
57222
|
object({
|
|
57304
57223
|
mode: DayNightModeSchema,
|
|
57305
57224
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57306
|
-
sensitivity: number().optional(),
|
|
57225
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57307
57226
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57308
|
-
switchDelaySec: number().optional(),
|
|
57227
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57309
57228
|
lastFetchedAt: number()
|
|
57310
57229
|
});
|
|
57311
57230
|
/**
|
|
@@ -57460,11 +57379,11 @@ object({
|
|
|
57460
57379
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57461
57380
|
availablePrograms: array(string()),
|
|
57462
57381
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57463
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57382
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57464
57383
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57465
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57384
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57466
57385
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57467
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57386
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57468
57387
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57469
57388
|
doorOpen: boolean().nullable(),
|
|
57470
57389
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57488,7 +57407,7 @@ object({
|
|
|
57488
57407
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57489
57408
|
machineCareDue: boolean().nullable(),
|
|
57490
57409
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57491
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57410
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57492
57411
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57493
57412
|
halfLoad: boolean().nullable(),
|
|
57494
57413
|
hygienePlus: boolean().nullable(),
|
|
@@ -57503,7 +57422,7 @@ object({
|
|
|
57503
57422
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57504
57423
|
activeEvents: array(string()),
|
|
57505
57424
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57506
|
-
errorCode: number().nullable(),
|
|
57425
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57507
57426
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57508
57427
|
errorLabel: string().nullable(),
|
|
57509
57428
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57649,24 +57568,14 @@ object({
|
|
|
57649
57568
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57650
57569
|
lastPressedAt: number().nullable(),
|
|
57651
57570
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57652
|
-
pressCountSinceStart: number()
|
|
57571
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57653
57572
|
});
|
|
57654
57573
|
object({
|
|
57655
57574
|
deviceId: number(),
|
|
57656
57575
|
timestamp: number()
|
|
57657
57576
|
});
|
|
57658
57577
|
DeviceType.Button, DeviceType.Camera;
|
|
57659
|
-
|
|
57660
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57661
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57662
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57663
|
-
* The option set is stable across observations; it is persisted in the
|
|
57664
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57665
|
-
* stored in `sourceInfo`.
|
|
57666
|
-
*/
|
|
57667
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57668
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57669
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
57578
|
+
_enum([
|
|
57670
57579
|
"date",
|
|
57671
57580
|
"time",
|
|
57672
57581
|
"datetime"
|
|
@@ -57674,12 +57583,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57674
57583
|
object({
|
|
57675
57584
|
value: string(),
|
|
57676
57585
|
/**
|
|
57677
|
-
* Set
|
|
57678
|
-
* as
|
|
57679
|
-
*
|
|
57680
|
-
* a time-only sensor → `'time'`.
|
|
57586
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
57587
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
57588
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57681
57589
|
*/
|
|
57682
|
-
|
|
57590
|
+
timestamp: boolean().optional(),
|
|
57683
57591
|
/** Ms epoch when the slice was last updated. */
|
|
57684
57592
|
lastFetchedAt: number()
|
|
57685
57593
|
});
|
|
@@ -57698,13 +57606,13 @@ var EventFireSchema = object({
|
|
|
57698
57606
|
deviceId: number(),
|
|
57699
57607
|
eventType: string(),
|
|
57700
57608
|
data: record(string(), unknown()).nullable(),
|
|
57701
|
-
timestamp: number(),
|
|
57702
|
-
seq: number()
|
|
57609
|
+
timestamp: number().meta(readingMeta("none")),
|
|
57610
|
+
seq: number().meta(readingMeta("count"))
|
|
57703
57611
|
});
|
|
57704
57612
|
object({
|
|
57705
57613
|
eventTypes: array(string()),
|
|
57706
57614
|
lastEvent: EventFireSchema.nullable(),
|
|
57707
|
-
eventCountSinceStart: number()
|
|
57615
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57708
57616
|
});
|
|
57709
57617
|
DeviceType.EventEmitter;
|
|
57710
57618
|
var IdentitySchema = object({
|
|
@@ -58093,10 +58001,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58093
58001
|
object({
|
|
58094
58002
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58095
58003
|
* speed surface (single-speed fan). */
|
|
58096
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58004
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58097
58005
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58098
58006
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58099
|
-
percentageStep: number().positive().optional(),
|
|
58007
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58100
58008
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58101
58009
|
* — empty string when no preset is active or supported. */
|
|
58102
58010
|
preset: string(),
|
|
@@ -58178,7 +58086,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58178
58086
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58179
58087
|
model: string().nullable(),
|
|
58180
58088
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58181
|
-
channelCount: number().nullable(),
|
|
58089
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58182
58090
|
/**
|
|
58183
58091
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58184
58092
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58212,7 +58120,7 @@ object({
|
|
|
58212
58120
|
DeviceType.Sensor;
|
|
58213
58121
|
object({
|
|
58214
58122
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58215
|
-
position: number().min(0).max(100).nullable(),
|
|
58123
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58216
58124
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58217
58125
|
lastFetchedAt: number()
|
|
58218
58126
|
});
|
|
@@ -58221,9 +58129,9 @@ object({
|
|
|
58221
58129
|
/** Whether the humidifier is currently on. */
|
|
58222
58130
|
on: boolean(),
|
|
58223
58131
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58224
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58132
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58225
58133
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58226
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58134
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58227
58135
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58228
58136
|
* device has no mode surface. */
|
|
58229
58137
|
mode: string().nullable(),
|
|
@@ -58233,9 +58141,9 @@ object({
|
|
|
58233
58141
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58234
58142
|
action: string().nullable(),
|
|
58235
58143
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58236
|
-
minHumidity: number().nullable(),
|
|
58144
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58237
58145
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58238
|
-
maxHumidity: number().nullable(),
|
|
58146
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58239
58147
|
/** Ms epoch when the slice was last updated. */
|
|
58240
58148
|
lastChangedAt: number()
|
|
58241
58149
|
});
|
|
@@ -58259,22 +58167,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58259
58167
|
auth: "protected"
|
|
58260
58168
|
});
|
|
58261
58169
|
object({
|
|
58262
|
-
/** Current relative humidity, 0..100. */
|
|
58263
|
-
percent: number().min(0).max(100).meta({
|
|
58264
|
-
|
|
58170
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58171
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58172
|
+
precision: 0,
|
|
58265
58173
|
label: "Humidity"
|
|
58266
|
-
}),
|
|
58174
|
+
})),
|
|
58267
58175
|
/** Ms epoch when the slice was last updated. */
|
|
58268
|
-
lastFetchedAt: number()
|
|
58269
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58270
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58271
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58272
|
-
unit: string().optional(),
|
|
58273
|
-
/** Suggested decimal places for numeric display.
|
|
58274
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58275
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58276
|
-
* auto-formatting when absent. */
|
|
58277
|
-
precision: number().int().min(0).max(10).optional()
|
|
58176
|
+
lastFetchedAt: number()
|
|
58278
58177
|
});
|
|
58279
58178
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58280
58179
|
object({
|
|
@@ -58282,7 +58181,7 @@ object({
|
|
|
58282
58181
|
* entity exposes no `entity_picture` (yet). */
|
|
58283
58182
|
url: string().nullable(),
|
|
58284
58183
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58285
|
-
lastUpdated: number().nullable()
|
|
58184
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58286
58185
|
});
|
|
58287
58186
|
DeviceType.Image;
|
|
58288
58187
|
/**
|
|
@@ -58338,19 +58237,19 @@ var NormalizedRangeSchema = object({
|
|
|
58338
58237
|
});
|
|
58339
58238
|
object({
|
|
58340
58239
|
/** Normalized 0–100. */
|
|
58341
|
-
brightness: number().optional(),
|
|
58240
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58342
58241
|
/** Normalized 0–100. */
|
|
58343
|
-
contrast: number().optional(),
|
|
58242
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58344
58243
|
/** Normalized 0–100. */
|
|
58345
|
-
saturation: number().optional(),
|
|
58244
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58346
58245
|
/** Normalized 0–100. */
|
|
58347
|
-
sharpness: number().optional(),
|
|
58246
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58348
58247
|
mirror: boolean().optional(),
|
|
58349
58248
|
flip: boolean().optional(),
|
|
58350
58249
|
rotate: ImageRotateSchema.optional(),
|
|
58351
58250
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58352
58251
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58353
|
-
warmth: number().optional(),
|
|
58252
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58354
58253
|
exposureMode: ExposureModeSchema.optional(),
|
|
58355
58254
|
backlightMode: BacklightModeSchema.optional(),
|
|
58356
58255
|
lastFetchedAt: number()
|
|
@@ -58595,10 +58494,10 @@ var IntercomAbilitySchema = object({
|
|
|
58595
58494
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58596
58495
|
codecs: array(string()),
|
|
58597
58496
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58598
|
-
sampleRate: number(),
|
|
58497
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58599
58498
|
duplex: _enum(["half", "full"]),
|
|
58600
58499
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58601
|
-
maxBacklogMs: number()
|
|
58500
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58602
58501
|
});
|
|
58603
58502
|
var IntercomStatusSchema = object({
|
|
58604
58503
|
/** True while a talk session is open. */
|
|
@@ -58709,13 +58608,13 @@ object({
|
|
|
58709
58608
|
activity: LawnMowerActivitySchema,
|
|
58710
58609
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58711
58610
|
* reading. */
|
|
58712
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
58611
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58713
58612
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58714
58613
|
* task is active / progress is unavailable. */
|
|
58715
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58614
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58716
58615
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58717
58616
|
* or null when unknown. */
|
|
58718
|
-
currentCode: number().nullable(),
|
|
58617
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58719
58618
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58720
58619
|
currentCodeLabel: string().nullable(),
|
|
58721
58620
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59177,7 +59076,7 @@ object({
|
|
|
59177
59076
|
state: MediaPlayerStateSchema,
|
|
59178
59077
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59179
59078
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59180
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59079
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59181
59080
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59182
59081
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59183
59082
|
isMuted: boolean().nullable(),
|
|
@@ -59190,10 +59089,10 @@ object({
|
|
|
59190
59089
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59191
59090
|
/** Current playback position in ms. Null when not seekable or
|
|
59192
59091
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59193
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59092
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59194
59093
|
/** Total duration of the current media in ms. Null when unknown
|
|
59195
59094
|
* (live stream) or nothing is playing. */
|
|
59196
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59095
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59197
59096
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59198
59097
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59199
59098
|
shuffle: boolean().nullable(),
|
|
@@ -59493,7 +59392,7 @@ object({
|
|
|
59493
59392
|
* it, every provider seeded it at boot, and every session left it
|
|
59494
59393
|
* `detected: true` after its detach.
|
|
59495
59394
|
*/
|
|
59496
|
-
autoClearAfterMs: number().nullable()
|
|
59395
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59497
59396
|
});
|
|
59498
59397
|
/**
|
|
59499
59398
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59543,7 +59442,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59543
59442
|
});
|
|
59544
59443
|
object({
|
|
59545
59444
|
enabled: boolean(),
|
|
59546
|
-
sensitivity: number(),
|
|
59445
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59547
59446
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59548
59447
|
regions: array(MotionZoneRegionSchema),
|
|
59549
59448
|
lastFetchedAt: number()
|
|
@@ -59847,7 +59746,7 @@ var NavigationStatusSchema = object({
|
|
|
59847
59746
|
following: boolean(),
|
|
59848
59747
|
flash: boolean(),
|
|
59849
59748
|
lightMode: NavigationLightModeSchema,
|
|
59850
|
-
lightLevel: number().min(40).max(100),
|
|
59749
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59851
59750
|
/** Ms epoch when the slice was last updated. */
|
|
59852
59751
|
lastChangedAt: number()
|
|
59853
59752
|
});
|
|
@@ -59893,13 +59792,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59893
59792
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59894
59793
|
* SKIP a null rather than coerce it.
|
|
59895
59794
|
*/
|
|
59896
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
59795
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59897
59796
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59898
|
-
rssiDbm: number().optional(),
|
|
59797
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59899
59798
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59900
59799
|
ssid: string().optional(),
|
|
59901
59800
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59902
|
-
lastUpdated: number()
|
|
59801
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59903
59802
|
});
|
|
59904
59803
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59905
59804
|
deviceId: number(),
|
|
@@ -60218,7 +60117,7 @@ object({
|
|
|
60218
60117
|
lastError: string().nullable(),
|
|
60219
60118
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60220
60119
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60221
|
-
queueDepth: number().int().nonnegative(),
|
|
60120
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60222
60121
|
/** Per-feature capability matrix — authoritative source for the
|
|
60223
60122
|
* compose-form field gating. */
|
|
60224
60123
|
supports: NotifierSupportsSchema
|
|
@@ -60268,15 +60167,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60268
60167
|
acceptedAt: number()
|
|
60269
60168
|
});
|
|
60270
60169
|
object({
|
|
60271
|
-
|
|
60272
|
-
|
|
60273
|
-
* Populated live from the upstream source on each state push.
|
|
60274
|
-
* Absent for unitless sensors. */
|
|
60275
|
-
unit: string().optional(),
|
|
60276
|
-
/** Suggested decimal places for numeric display.
|
|
60277
|
-
* Populated live from the upstream source when provided.
|
|
60278
|
-
* Falls back to auto-formatting when absent. */
|
|
60279
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60170
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60171
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60280
60172
|
/** Ms epoch when the slice was last updated. */
|
|
60281
60173
|
lastFetchedAt: number()
|
|
60282
60174
|
});
|
|
@@ -60566,23 +60458,26 @@ object({
|
|
|
60566
60458
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60567
60459
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60568
60460
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60569
|
-
foodLevel: number().nullable(),
|
|
60461
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60570
60462
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60571
60463
|
* single-hopper models. */
|
|
60572
|
-
food1: number().nullable(),
|
|
60464
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60573
60465
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60574
60466
|
* single-hopper models. */
|
|
60575
|
-
food2: number().nullable(),
|
|
60467
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60576
60468
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60577
60469
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60578
60470
|
* below the feeder's low threshold. */
|
|
60579
60471
|
lowFood: boolean(),
|
|
60580
60472
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60581
60473
|
* device has no battery reading. */
|
|
60582
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60583
|
-
/**
|
|
60584
|
-
*
|
|
60585
|
-
|
|
60474
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60475
|
+
/**
|
|
60476
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
60477
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
60478
|
+
* model has no desiccant sensor.
|
|
60479
|
+
*/
|
|
60480
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60586
60481
|
/** True while a feed is in progress. */
|
|
60587
60482
|
feeding: boolean(),
|
|
60588
60483
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60593,7 +60488,7 @@ object({
|
|
|
60593
60488
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60594
60489
|
error: string().nullable(),
|
|
60595
60490
|
/** Raw device error code (0 / null = no error). */
|
|
60596
|
-
errorCode: number().nullable(),
|
|
60491
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60597
60492
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60598
60493
|
isDualHopper: boolean(),
|
|
60599
60494
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60603,7 +60498,7 @@ object({
|
|
|
60603
60498
|
/** Play a chime when dispensing. */
|
|
60604
60499
|
feedSound: boolean(),
|
|
60605
60500
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60606
|
-
volume: number(),
|
|
60501
|
+
volume: number().meta(readingMeta("none")),
|
|
60607
60502
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60608
60503
|
lastFetchedAt: number()
|
|
60609
60504
|
});
|
|
@@ -61040,36 +60935,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61040
60935
|
});
|
|
61041
60936
|
object({
|
|
61042
60937
|
/** Instantaneous power draw in watts. */
|
|
61043
|
-
watts: number().optional().meta({
|
|
61044
|
-
unit: "W",
|
|
61045
|
-
label: "Power"
|
|
61046
|
-
}),
|
|
60938
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61047
60939
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61048
|
-
kwhTotal: number().optional().meta({
|
|
61049
|
-
unit: "kWh",
|
|
61050
|
-
label: "Energy"
|
|
61051
|
-
}),
|
|
60940
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61052
60941
|
/** Voltage in volts. */
|
|
61053
|
-
volts: number().optional(),
|
|
60942
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61054
60943
|
/** Current in amperes. */
|
|
61055
|
-
amps: number().optional(),
|
|
61056
|
-
/** Apparent power in volt-amperes
|
|
61057
|
-
va: number().optional(),
|
|
60944
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
60945
|
+
/** Apparent power in volt-amperes. */
|
|
60946
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61058
60947
|
/** Power factor (0..1) if reported. */
|
|
61059
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
60948
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61060
60949
|
/** Ms epoch when the slice was last updated. */
|
|
61061
|
-
lastFetchedAt: number()
|
|
61062
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61063
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61064
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61065
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61066
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61067
|
-
unit: string().optional(),
|
|
61068
|
-
/** Suggested decimal places for numeric display.
|
|
61069
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61070
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61071
|
-
* auto-formatting when absent. */
|
|
61072
|
-
precision: number().int().min(0).max(10).optional()
|
|
60950
|
+
lastFetchedAt: number()
|
|
61073
60951
|
});
|
|
61074
60952
|
DeviceType.Sensor;
|
|
61075
60953
|
/**
|
|
@@ -61090,11 +60968,11 @@ DeviceType.Sensor;
|
|
|
61090
60968
|
*/
|
|
61091
60969
|
var GpsLocationSchema = object({
|
|
61092
60970
|
/** Latitude in decimal degrees, -90..90. */
|
|
61093
|
-
latitude: number().min(-90).max(90),
|
|
60971
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61094
60972
|
/** Longitude in decimal degrees, -180..180. */
|
|
61095
|
-
longitude: number().min(-180).max(180),
|
|
60973
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61096
60974
|
/** Reported accuracy in meters (lower = better). */
|
|
61097
|
-
accuracyMeters: number().nonnegative()
|
|
60975
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61098
60976
|
});
|
|
61099
60977
|
object({
|
|
61100
60978
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61106,25 +60984,16 @@ object({
|
|
|
61106
60984
|
gps: GpsLocationSchema.nullable(),
|
|
61107
60985
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61108
60986
|
* when not reported. */
|
|
61109
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
60987
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61110
60988
|
/** Ms epoch when the slice was last updated. */
|
|
61111
60989
|
lastChangedAt: number()
|
|
61112
60990
|
});
|
|
61113
60991
|
DeviceType.Presence;
|
|
61114
60992
|
object({
|
|
61115
|
-
/** Current pressure in hPa. */
|
|
61116
|
-
hpa: number(),
|
|
60993
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
60994
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61117
60995
|
/** Ms epoch when the slice was last updated. */
|
|
61118
|
-
lastFetchedAt: number()
|
|
61119
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61120
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61121
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61122
|
-
unit: string().optional(),
|
|
61123
|
-
/** Suggested decimal places for numeric display.
|
|
61124
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61125
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61126
|
-
* auto-formatting when absent. */
|
|
61127
|
-
precision: number().int().min(0).max(10).optional()
|
|
60996
|
+
lastFetchedAt: number()
|
|
61128
60997
|
});
|
|
61129
60998
|
DeviceType.Sensor;
|
|
61130
60999
|
/**
|
|
@@ -61457,8 +61326,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61457
61326
|
}), _void(), { kind: "mutation" });
|
|
61458
61327
|
var PtzAutotrackSettingsSchema = object({
|
|
61459
61328
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61460
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61461
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61329
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61330
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61462
61331
|
});
|
|
61463
61332
|
/**
|
|
61464
61333
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61515,7 +61384,7 @@ object({
|
|
|
61515
61384
|
/** null = unknown — never coerced to false (D393). */
|
|
61516
61385
|
running: boolean().nullable(),
|
|
61517
61386
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61518
|
-
since: number().nullable(),
|
|
61387
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61519
61388
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61520
61389
|
phase: string().nullable(),
|
|
61521
61390
|
/** null until a reading has been published (D393). */
|
|
@@ -62713,9 +62582,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62713
62582
|
*/
|
|
62714
62583
|
var RecordWindowSchema = object({
|
|
62715
62584
|
trigger: RecordTriggerSchema,
|
|
62716
|
-
day: number().int().min(0).max(6),
|
|
62717
|
-
startMinute: number().int().min(0).max(1439),
|
|
62718
|
-
endMinute: number().int().min(1).max(1440)
|
|
62585
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
62586
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
62587
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62719
62588
|
});
|
|
62720
62589
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62721
62590
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62784,10 +62653,10 @@ object({
|
|
|
62784
62653
|
/** Master "record to the card at all" switch. */
|
|
62785
62654
|
enabled: boolean().nullable(),
|
|
62786
62655
|
overwriteWhenFull: boolean().nullable(),
|
|
62787
|
-
preRecordSec: number().nullable(),
|
|
62788
|
-
postRecordSec: number().nullable(),
|
|
62656
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62657
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62789
62658
|
/** Length of one recorded file, in minutes. */
|
|
62790
|
-
segmentMinutes: number().nullable(),
|
|
62659
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62791
62660
|
/** The primary track's weekly windows, flattened. */
|
|
62792
62661
|
windows: array(RecordWindowSchema),
|
|
62793
62662
|
/**
|
|
@@ -62803,7 +62672,7 @@ object({
|
|
|
62803
62672
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62804
62673
|
* writable.
|
|
62805
62674
|
*/
|
|
62806
|
-
unreadableWindows: number(),
|
|
62675
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62807
62676
|
/**
|
|
62808
62677
|
* The camera is scheduled to record and has NO usable storage.
|
|
62809
62678
|
*
|
|
@@ -63440,7 +63309,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63440
63309
|
url: string().optional(),
|
|
63441
63310
|
codec: string().optional(),
|
|
63442
63311
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63443
|
-
fps: number().positive().optional(),
|
|
63312
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63444
63313
|
label: string().optional(),
|
|
63445
63314
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63446
63315
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63470,18 +63339,18 @@ var StreamProfileSchema = _enum([
|
|
|
63470
63339
|
]);
|
|
63471
63340
|
/** The current encoding config of one stream profile. */
|
|
63472
63341
|
var StreamProfileConfigSchema = object({
|
|
63473
|
-
width: number(),
|
|
63474
|
-
height: number(),
|
|
63342
|
+
width: number().meta(readingMeta("none")),
|
|
63343
|
+
height: number().meta(readingMeta("none")),
|
|
63475
63344
|
codec: _enum(["h264", "h265"]),
|
|
63476
|
-
framerate: number(),
|
|
63477
|
-
bitrate: number(),
|
|
63345
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63346
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63478
63347
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63479
63348
|
encoderProfile: _enum([
|
|
63480
63349
|
"high",
|
|
63481
63350
|
"main",
|
|
63482
63351
|
"baseline"
|
|
63483
63352
|
]).optional(),
|
|
63484
|
-
gop: number().optional(),
|
|
63353
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63485
63354
|
/**
|
|
63486
63355
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63487
63356
|
*
|
|
@@ -64124,23 +63993,13 @@ object({
|
|
|
64124
63993
|
});
|
|
64125
63994
|
DeviceType.Sensor;
|
|
64126
63995
|
object({
|
|
64127
|
-
/** Current temperature in Celsius. */
|
|
64128
|
-
celsius: number().meta({
|
|
64129
|
-
|
|
63996
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
63997
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
63998
|
+
precision: 1,
|
|
64130
63999
|
label: "Temperature"
|
|
64131
|
-
}),
|
|
64000
|
+
})),
|
|
64132
64001
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64133
|
-
lastFetchedAt: number()
|
|
64134
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64135
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64136
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64137
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64138
|
-
unit: string().optional(),
|
|
64139
|
-
/** Suggested decimal places for numeric display.
|
|
64140
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64141
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64142
|
-
* auto-formatting when absent. */
|
|
64143
|
-
precision: number().int().min(0).max(10).optional()
|
|
64002
|
+
lastFetchedAt: number()
|
|
64144
64003
|
});
|
|
64145
64004
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64146
64005
|
/**
|
|
@@ -64392,16 +64251,16 @@ object({
|
|
|
64392
64251
|
]),
|
|
64393
64252
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64394
64253
|
* reading. */
|
|
64395
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64254
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64396
64255
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64397
64256
|
* the vacuum has no speed control. */
|
|
64398
64257
|
fanSpeed: string().nullable(),
|
|
64399
64258
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64400
64259
|
availableFanSpeeds: array(string()),
|
|
64401
64260
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64402
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64261
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64403
64262
|
/** Current error code (0 / null = no error). */
|
|
64404
|
-
errorCode: number().nullable(),
|
|
64263
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64405
64264
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64406
64265
|
errorLabel: string().nullable(),
|
|
64407
64266
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64440,7 +64299,7 @@ object({
|
|
|
64440
64299
|
]),
|
|
64441
64300
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64442
64301
|
* intermediate position surface. */
|
|
64443
|
-
position: number().min(0).max(100).nullable(),
|
|
64302
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64444
64303
|
/** Ms epoch when the slice was last updated. */
|
|
64445
64304
|
lastChangedAt: number()
|
|
64446
64305
|
});
|
|
@@ -64468,9 +64327,9 @@ object({
|
|
|
64468
64327
|
DeviceType.Sensor;
|
|
64469
64328
|
object({
|
|
64470
64329
|
/** Current measured temperature. Null when not reported. */
|
|
64471
|
-
currentTemp: number().nullable(),
|
|
64330
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64472
64331
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64473
|
-
targetTemp: number().nullable(),
|
|
64332
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64474
64333
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64475
64334
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64476
64335
|
* device reports an unknown state. */
|
|
@@ -64481,9 +64340,9 @@ object({
|
|
|
64481
64340
|
* has no away surface. */
|
|
64482
64341
|
away: boolean().nullable(),
|
|
64483
64342
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64484
|
-
minTemp: number().nullable(),
|
|
64343
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64485
64344
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64486
|
-
maxTemp: number().nullable(),
|
|
64345
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64487
64346
|
/** Ms epoch when the slice was last updated. */
|
|
64488
64347
|
lastChangedAt: number()
|
|
64489
64348
|
});
|
|
@@ -64507,25 +64366,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64507
64366
|
auth: "protected"
|
|
64508
64367
|
});
|
|
64509
64368
|
object({
|
|
64510
|
-
/** Verbatim
|
|
64511
|
-
* when no condition has been reported yet. */
|
|
64369
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64512
64370
|
condition: string().nullable(),
|
|
64513
|
-
/** Current temperature in
|
|
64514
|
-
temperature: number().nullable(),
|
|
64515
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64516
|
-
temperatureUnit: string().nullable(),
|
|
64371
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64372
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64517
64373
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64518
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64519
|
-
/** Barometric pressure in
|
|
64520
|
-
pressure: number().nullable(),
|
|
64521
|
-
/**
|
|
64522
|
-
|
|
64523
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64524
|
-
windSpeed: number().nullable(),
|
|
64525
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64526
|
-
windSpeedUnit: string().nullable(),
|
|
64374
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64375
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64376
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64377
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64378
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64527
64379
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64528
|
-
windBearing: number().nullable(),
|
|
64380
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64529
64381
|
/** Ms epoch when the slice was last updated. */
|
|
64530
64382
|
lastFetchedAt: number()
|
|
64531
64383
|
});
|
|
@@ -78502,7 +78354,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78502
78354
|
field: "value",
|
|
78503
78355
|
quantity: t("the reading", "il valore"),
|
|
78504
78356
|
label: t("Reading", "Valore"),
|
|
78505
|
-
unitField: "unit",
|
|
78506
78357
|
icon: "gauge"
|
|
78507
78358
|
}]
|
|
78508
78359
|
},
|
|
@@ -78638,7 +78489,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78638
78489
|
field: "temperature",
|
|
78639
78490
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78640
78491
|
label: t("Temperature", "Temperatura"),
|
|
78641
|
-
|
|
78492
|
+
unit: "°C",
|
|
78642
78493
|
icon: "thermometer"
|
|
78643
78494
|
},
|
|
78644
78495
|
{
|
|
@@ -78654,7 +78505,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78654
78505
|
field: "windSpeed",
|
|
78655
78506
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78656
78507
|
label: t("Wind", "Vento"),
|
|
78657
|
-
|
|
78508
|
+
unit: "m/s",
|
|
78658
78509
|
icon: "wind"
|
|
78659
78510
|
},
|
|
78660
78511
|
{
|
|
@@ -78662,7 +78513,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78662
78513
|
field: "pressure",
|
|
78663
78514
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78664
78515
|
label: t("Pressure", "Pressione"),
|
|
78665
|
-
|
|
78516
|
+
unit: "hPa",
|
|
78666
78517
|
icon: "gauge"
|
|
78667
78518
|
}
|
|
78668
78519
|
]
|