@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
|
@@ -5567,7 +5567,7 @@ var ZodIssueCode = {
|
|
|
5567
5567
|
var ZodFirstPartyTypeKind;
|
|
5568
5568
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5569
5569
|
//#endregion
|
|
5570
|
-
//#region ../types/dist/sleep-
|
|
5570
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5571
5571
|
/**
|
|
5572
5572
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5573
5573
|
* window to float samples (D455).
|
|
@@ -8302,6 +8302,52 @@ function defineEntryKind(name, spec) {
|
|
|
8302
8302
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8303
8303
|
return defined;
|
|
8304
8304
|
}
|
|
8305
|
+
var READING_QUANTITIES = [
|
|
8306
|
+
"temperature",
|
|
8307
|
+
"pressure",
|
|
8308
|
+
"speed",
|
|
8309
|
+
"precipitation",
|
|
8310
|
+
"precipitation-rate",
|
|
8311
|
+
"length",
|
|
8312
|
+
"area",
|
|
8313
|
+
"illuminance",
|
|
8314
|
+
"irradiance",
|
|
8315
|
+
"power",
|
|
8316
|
+
"energy",
|
|
8317
|
+
"voltage",
|
|
8318
|
+
"current",
|
|
8319
|
+
"apparent-power",
|
|
8320
|
+
"humidity",
|
|
8321
|
+
"percentage",
|
|
8322
|
+
"concentration-volume",
|
|
8323
|
+
"concentration-mass",
|
|
8324
|
+
"concentration-ppb",
|
|
8325
|
+
"volume",
|
|
8326
|
+
"duration",
|
|
8327
|
+
"duration-ms",
|
|
8328
|
+
"information",
|
|
8329
|
+
"sound-level",
|
|
8330
|
+
"signal-level",
|
|
8331
|
+
"colour-temperature",
|
|
8332
|
+
"angle",
|
|
8333
|
+
"bitrate",
|
|
8334
|
+
"rate",
|
|
8335
|
+
"mass",
|
|
8336
|
+
"index",
|
|
8337
|
+
"ratio",
|
|
8338
|
+
"count",
|
|
8339
|
+
"none",
|
|
8340
|
+
"device"
|
|
8341
|
+
];
|
|
8342
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8343
|
+
new Set(READING_QUANTITIES);
|
|
8344
|
+
function readingMeta(quantity, extras) {
|
|
8345
|
+
return {
|
|
8346
|
+
quantity,
|
|
8347
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8348
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8349
|
+
};
|
|
8350
|
+
}
|
|
8305
8351
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8306
8352
|
var CamProfileSchema = _enum([
|
|
8307
8353
|
"high",
|
|
@@ -8329,8 +8375,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8329
8375
|
"derived"
|
|
8330
8376
|
]);
|
|
8331
8377
|
var CamStreamResolutionSchema = object({
|
|
8332
|
-
width: number().int().positive(),
|
|
8333
|
-
height: number().int().positive()
|
|
8378
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8379
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8334
8380
|
});
|
|
8335
8381
|
var CameraStreamSchema = object({
|
|
8336
8382
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8973,14 +9019,6 @@ Object.freeze({
|
|
|
8973
9019
|
{
|
|
8974
9020
|
"path": "aqi",
|
|
8975
9021
|
"valueType": "number"
|
|
8976
|
-
},
|
|
8977
|
-
{
|
|
8978
|
-
"path": "unit",
|
|
8979
|
-
"valueType": "string"
|
|
8980
|
-
},
|
|
8981
|
-
{
|
|
8982
|
-
"path": "precision",
|
|
8983
|
-
"valueType": "number"
|
|
8984
9022
|
}
|
|
8985
9023
|
],
|
|
8986
9024
|
"alarm-panel": [
|
|
@@ -9016,20 +9054,10 @@ Object.freeze({
|
|
|
9016
9054
|
"valueType": "boolean"
|
|
9017
9055
|
}
|
|
9018
9056
|
],
|
|
9019
|
-
"ambient-light-sensor": [
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
},
|
|
9024
|
-
{
|
|
9025
|
-
"path": "unit",
|
|
9026
|
-
"valueType": "string"
|
|
9027
|
-
},
|
|
9028
|
-
{
|
|
9029
|
-
"path": "precision",
|
|
9030
|
-
"valueType": "number"
|
|
9031
|
-
}
|
|
9032
|
-
],
|
|
9057
|
+
"ambient-light-sensor": [{
|
|
9058
|
+
"path": "lux",
|
|
9059
|
+
"valueType": "number"
|
|
9060
|
+
}],
|
|
9033
9061
|
"audio-metrics": [
|
|
9034
9062
|
{
|
|
9035
9063
|
"path": "ts",
|
|
@@ -9109,6 +9137,10 @@ Object.freeze({
|
|
|
9109
9137
|
"path": "lastUpdated",
|
|
9110
9138
|
"valueType": "number"
|
|
9111
9139
|
},
|
|
9140
|
+
{
|
|
9141
|
+
"path": "volts",
|
|
9142
|
+
"valueType": "number"
|
|
9143
|
+
},
|
|
9112
9144
|
{
|
|
9113
9145
|
"path": "lastContactAt",
|
|
9114
9146
|
"valueType": "number"
|
|
@@ -9351,10 +9383,6 @@ Object.freeze({
|
|
|
9351
9383
|
"datetime"
|
|
9352
9384
|
]
|
|
9353
9385
|
},
|
|
9354
|
-
{
|
|
9355
|
-
"path": "unit",
|
|
9356
|
-
"valueType": "string"
|
|
9357
|
-
},
|
|
9358
9386
|
{
|
|
9359
9387
|
"path": "min",
|
|
9360
9388
|
"valueType": "number"
|
|
@@ -9366,19 +9394,6 @@ Object.freeze({
|
|
|
9366
9394
|
{
|
|
9367
9395
|
"path": "step",
|
|
9368
9396
|
"valueType": "number"
|
|
9369
|
-
},
|
|
9370
|
-
{
|
|
9371
|
-
"path": "precision",
|
|
9372
|
-
"valueType": "number"
|
|
9373
|
-
},
|
|
9374
|
-
{
|
|
9375
|
-
"path": "format",
|
|
9376
|
-
"valueType": "enum",
|
|
9377
|
-
"enumValues": [
|
|
9378
|
-
"date",
|
|
9379
|
-
"time",
|
|
9380
|
-
"datetime"
|
|
9381
|
-
]
|
|
9382
9397
|
}
|
|
9383
9398
|
],
|
|
9384
9399
|
"cover": [
|
|
@@ -9619,13 +9634,8 @@ Object.freeze({
|
|
|
9619
9634
|
"path": "value",
|
|
9620
9635
|
"valueType": "string"
|
|
9621
9636
|
}, {
|
|
9622
|
-
"path": "
|
|
9623
|
-
"valueType": "
|
|
9624
|
-
"enumValues": [
|
|
9625
|
-
"date",
|
|
9626
|
-
"time",
|
|
9627
|
-
"datetime"
|
|
9628
|
-
]
|
|
9637
|
+
"path": "timestamp",
|
|
9638
|
+
"valueType": "boolean"
|
|
9629
9639
|
}],
|
|
9630
9640
|
"event-emitter": [
|
|
9631
9641
|
{
|
|
@@ -9732,20 +9742,10 @@ Object.freeze({
|
|
|
9732
9742
|
"valueType": "number"
|
|
9733
9743
|
}
|
|
9734
9744
|
],
|
|
9735
|
-
"humidity-sensor": [
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
},
|
|
9740
|
-
{
|
|
9741
|
-
"path": "unit",
|
|
9742
|
-
"valueType": "string"
|
|
9743
|
-
},
|
|
9744
|
-
{
|
|
9745
|
-
"path": "precision",
|
|
9746
|
-
"valueType": "number"
|
|
9747
|
-
}
|
|
9748
|
-
],
|
|
9745
|
+
"humidity-sensor": [{
|
|
9746
|
+
"path": "percent",
|
|
9747
|
+
"valueType": "number"
|
|
9748
|
+
}],
|
|
9749
9749
|
"image": [{
|
|
9750
9750
|
"path": "url",
|
|
9751
9751
|
"valueType": "string"
|
|
@@ -10084,20 +10084,10 @@ Object.freeze({
|
|
|
10084
10084
|
"valueType": "boolean"
|
|
10085
10085
|
}
|
|
10086
10086
|
],
|
|
10087
|
-
"numeric-sensor": [
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
},
|
|
10092
|
-
{
|
|
10093
|
-
"path": "unit",
|
|
10094
|
-
"valueType": "string"
|
|
10095
|
-
},
|
|
10096
|
-
{
|
|
10097
|
-
"path": "precision",
|
|
10098
|
-
"valueType": "number"
|
|
10099
|
-
}
|
|
10100
|
-
],
|
|
10087
|
+
"numeric-sensor": [{
|
|
10088
|
+
"path": "value",
|
|
10089
|
+
"valueType": "number"
|
|
10090
|
+
}],
|
|
10101
10091
|
"pet-feeder": [
|
|
10102
10092
|
{
|
|
10103
10093
|
"path": "foodLevel",
|
|
@@ -10189,14 +10179,6 @@ Object.freeze({
|
|
|
10189
10179
|
{
|
|
10190
10180
|
"path": "powerFactor",
|
|
10191
10181
|
"valueType": "number"
|
|
10192
|
-
},
|
|
10193
|
-
{
|
|
10194
|
-
"path": "unit",
|
|
10195
|
-
"valueType": "string"
|
|
10196
|
-
},
|
|
10197
|
-
{
|
|
10198
|
-
"path": "precision",
|
|
10199
|
-
"valueType": "number"
|
|
10200
10182
|
}
|
|
10201
10183
|
],
|
|
10202
10184
|
"presence": [
|
|
@@ -10225,20 +10207,10 @@ Object.freeze({
|
|
|
10225
10207
|
"valueType": "number"
|
|
10226
10208
|
}
|
|
10227
10209
|
],
|
|
10228
|
-
"pressure-sensor": [
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
},
|
|
10233
|
-
{
|
|
10234
|
-
"path": "unit",
|
|
10235
|
-
"valueType": "string"
|
|
10236
|
-
},
|
|
10237
|
-
{
|
|
10238
|
-
"path": "precision",
|
|
10239
|
-
"valueType": "number"
|
|
10240
|
-
}
|
|
10241
|
-
],
|
|
10210
|
+
"pressure-sensor": [{
|
|
10211
|
+
"path": "hpa",
|
|
10212
|
+
"valueType": "number"
|
|
10213
|
+
}],
|
|
10242
10214
|
"privacy-mask": [{
|
|
10243
10215
|
"path": "enabled",
|
|
10244
10216
|
"valueType": "boolean"
|
|
@@ -10549,20 +10521,10 @@ Object.freeze({
|
|
|
10549
10521
|
"path": "tampered",
|
|
10550
10522
|
"valueType": "boolean"
|
|
10551
10523
|
}],
|
|
10552
|
-
"temperature-sensor": [
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
},
|
|
10557
|
-
{
|
|
10558
|
-
"path": "unit",
|
|
10559
|
-
"valueType": "string"
|
|
10560
|
-
},
|
|
10561
|
-
{
|
|
10562
|
-
"path": "precision",
|
|
10563
|
-
"valueType": "number"
|
|
10564
|
-
}
|
|
10565
|
-
],
|
|
10524
|
+
"temperature-sensor": [{
|
|
10525
|
+
"path": "celsius",
|
|
10526
|
+
"valueType": "number"
|
|
10527
|
+
}],
|
|
10566
10528
|
"update": [
|
|
10567
10529
|
{
|
|
10568
10530
|
"path": "currentVersion",
|
|
@@ -10673,10 +10635,6 @@ Object.freeze({
|
|
|
10673
10635
|
"path": "temperature",
|
|
10674
10636
|
"valueType": "number"
|
|
10675
10637
|
},
|
|
10676
|
-
{
|
|
10677
|
-
"path": "temperatureUnit",
|
|
10678
|
-
"valueType": "string"
|
|
10679
|
-
},
|
|
10680
10638
|
{
|
|
10681
10639
|
"path": "humidity",
|
|
10682
10640
|
"valueType": "number"
|
|
@@ -10685,18 +10643,10 @@ Object.freeze({
|
|
|
10685
10643
|
"path": "pressure",
|
|
10686
10644
|
"valueType": "number"
|
|
10687
10645
|
},
|
|
10688
|
-
{
|
|
10689
|
-
"path": "pressureUnit",
|
|
10690
|
-
"valueType": "string"
|
|
10691
|
-
},
|
|
10692
10646
|
{
|
|
10693
10647
|
"path": "windSpeed",
|
|
10694
10648
|
"valueType": "number"
|
|
10695
10649
|
},
|
|
10696
|
-
{
|
|
10697
|
-
"path": "windSpeedUnit",
|
|
10698
|
-
"valueType": "string"
|
|
10699
|
-
},
|
|
10700
10650
|
{
|
|
10701
10651
|
"path": "windBearing",
|
|
10702
10652
|
"valueType": "number"
|
|
@@ -18079,7 +18029,8 @@ var CompositionProblemSchema = object({
|
|
|
18079
18029
|
"item-field-reserved",
|
|
18080
18030
|
"target-missing",
|
|
18081
18031
|
"target-unreadable",
|
|
18082
|
-
"not-replaceable"
|
|
18032
|
+
"not-replaceable",
|
|
18033
|
+
"native-capability-replace"
|
|
18083
18034
|
]),
|
|
18084
18035
|
path: string(),
|
|
18085
18036
|
message: string()
|
|
@@ -18137,9 +18088,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18137
18088
|
reads: array(CompositionFieldReadSchema)
|
|
18138
18089
|
});
|
|
18139
18090
|
/**
|
|
18140
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18141
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18142
|
-
*
|
|
18091
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18092
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18093
|
+
* Replacing a capability the device already serves is refused
|
|
18094
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18095
|
+
* wire for a claim the hub already holds.
|
|
18143
18096
|
*/
|
|
18144
18097
|
var CompositionFeatureModeSchema = _enum([
|
|
18145
18098
|
"new",
|
|
@@ -20025,12 +19978,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20025
19978
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20026
19979
|
* in-place so dispatch keeps working.
|
|
20027
19980
|
*
|
|
20028
|
-
* **
|
|
20029
|
-
*
|
|
20030
|
-
*
|
|
20031
|
-
*
|
|
20032
|
-
* (`ha-domain-mapping`)
|
|
20033
|
-
* stored after that point.
|
|
19981
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
19982
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
19983
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
19984
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
19985
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
19986
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20034
19987
|
*
|
|
20035
19988
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20036
19989
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20044,6 +19997,14 @@ var SourceInfoSchema = object({
|
|
|
20044
19997
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20045
19998
|
* Used to detect rename when `id` changes. */
|
|
20046
19999
|
uniqueId: string().optional(),
|
|
20000
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20001
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20002
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20003
|
+
dateTimeShape: _enum([
|
|
20004
|
+
"date",
|
|
20005
|
+
"time",
|
|
20006
|
+
"datetime"
|
|
20007
|
+
]).optional(),
|
|
20047
20008
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20048
20009
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20049
20010
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -40956,7 +40917,8 @@ method(object({
|
|
|
40956
40917
|
"enum"
|
|
40957
40918
|
]),
|
|
40958
40919
|
enumValues: array(string()).optional(),
|
|
40959
|
-
item: boolean().optional()
|
|
40920
|
+
item: boolean().optional(),
|
|
40921
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40960
40922
|
})).readonly(),
|
|
40961
40923
|
itemArray: object({
|
|
40962
40924
|
path: string(),
|
|
@@ -44756,8 +44718,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44756
44718
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44757
44719
|
var MaskGridShapeSchema = object({
|
|
44758
44720
|
kind: literal("grid"),
|
|
44759
|
-
gridWidth: number(),
|
|
44760
|
-
gridHeight: number(),
|
|
44721
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
44722
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44761
44723
|
cells: array(boolean())
|
|
44762
44724
|
});
|
|
44763
44725
|
discriminatedUnion("kind", [
|
|
@@ -56151,46 +56113,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56151
56113
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56152
56114
|
object({
|
|
56153
56115
|
/** Carbon dioxide concentration in ppm. */
|
|
56154
|
-
co2Ppm: number().min(0).optional(),
|
|
56116
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56155
56117
|
/** Total volatile organic compounds in ppb. */
|
|
56156
|
-
vocPpb: number().min(0).optional(),
|
|
56118
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56157
56119
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56158
|
-
pm25: number().min(0).optional(),
|
|
56120
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56159
56121
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56160
|
-
pm10: number().min(0).optional(),
|
|
56122
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56161
56123
|
/** Composite AQI value (typically 0..500). */
|
|
56162
|
-
aqi: number().optional(),
|
|
56124
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56163
56125
|
/** Ms epoch when the slice was last updated. */
|
|
56164
|
-
lastFetchedAt: number()
|
|
56165
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56166
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56167
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56168
|
-
* per slice is unambiguous. */
|
|
56169
|
-
unit: string().optional(),
|
|
56170
|
-
/** Suggested decimal places for numeric display.
|
|
56171
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56172
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56173
|
-
* auto-formatting when absent. */
|
|
56174
|
-
precision: number().int().min(0).max(10).optional()
|
|
56126
|
+
lastFetchedAt: number()
|
|
56175
56127
|
});
|
|
56176
56128
|
DeviceType.Sensor;
|
|
56177
56129
|
object({
|
|
56178
|
-
/** Current illuminance in lux (lx). */
|
|
56179
|
-
lux: number().min(0).meta({
|
|
56180
|
-
|
|
56130
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56131
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56132
|
+
precision: 0,
|
|
56181
56133
|
label: "Illuminance"
|
|
56182
|
-
}),
|
|
56134
|
+
})),
|
|
56183
56135
|
/** Ms epoch when the slice was last updated. */
|
|
56184
|
-
lastFetchedAt: number()
|
|
56185
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56186
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56187
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56188
|
-
unit: string().optional(),
|
|
56189
|
-
/** Suggested decimal places for numeric display.
|
|
56190
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56191
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56192
|
-
* auto-formatting when absent. */
|
|
56193
|
-
precision: number().int().min(0).max(10).optional()
|
|
56136
|
+
lastFetchedAt: number()
|
|
56194
56137
|
});
|
|
56195
56138
|
DeviceType.Sensor;
|
|
56196
56139
|
/**
|
|
@@ -56335,10 +56278,7 @@ var BatteryStatusSchema = object({
|
|
|
56335
56278
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56336
56279
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56337
56280
|
*/
|
|
56338
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56339
|
-
unit: "%",
|
|
56340
|
-
label: "Charge"
|
|
56341
|
-
}),
|
|
56281
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56342
56282
|
/**
|
|
56343
56283
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56344
56284
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56365,7 +56305,14 @@ var BatteryStatusSchema = object({
|
|
|
56365
56305
|
*/
|
|
56366
56306
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56367
56307
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56368
|
-
lastUpdated: number(),
|
|
56308
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56309
|
+
/**
|
|
56310
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56311
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56312
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56313
|
+
* `numeric-sensor` on the same device.
|
|
56314
|
+
*/
|
|
56315
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56369
56316
|
/**
|
|
56370
56317
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56371
56318
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56425,7 +56372,7 @@ object({
|
|
|
56425
56372
|
DeviceType.Sensor;
|
|
56426
56373
|
object({
|
|
56427
56374
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56428
|
-
percentage: number().min(0).max(100),
|
|
56375
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56429
56376
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56430
56377
|
lastChangedAt: number()
|
|
56431
56378
|
});
|
|
@@ -56810,21 +56757,21 @@ object({
|
|
|
56810
56757
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
56811
56758
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
56812
56759
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
56813
|
-
target: number().nullable(),
|
|
56760
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
56814
56761
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
56815
56762
|
* in `heat_cool` mode. */
|
|
56816
|
-
targetHigh: number().nullable(),
|
|
56763
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
56817
56764
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
56818
56765
|
* in `heat_cool` mode. */
|
|
56819
|
-
targetLow: number().nullable(),
|
|
56766
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
56820
56767
|
/** Target relative humidity (0..100). Null when the device has no
|
|
56821
56768
|
* humidity control. */
|
|
56822
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
56769
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56823
56770
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
56824
56771
|
* the device's internal sensor. */
|
|
56825
|
-
currentTemp: number().nullable(),
|
|
56772
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
56826
56773
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
56827
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
56774
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
56828
56775
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
56829
56776
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
56830
56777
|
swingVertical: boolean().nullable(),
|
|
@@ -56832,11 +56779,11 @@ object({
|
|
|
56832
56779
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
56833
56780
|
swingHorizontal: boolean().nullable(),
|
|
56834
56781
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56835
|
-
minTemp: number().nullable().optional(),
|
|
56782
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56836
56783
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
56837
|
-
maxTemp: number().nullable().optional(),
|
|
56784
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
56838
56785
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
56839
|
-
tempStep: number().positive().nullable().optional(),
|
|
56786
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
56840
56787
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
56841
56788
|
lastFetchedAt: number()
|
|
56842
56789
|
});
|
|
@@ -56915,17 +56862,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
56915
56862
|
* modes to expose in the picker without a slice fetch.
|
|
56916
56863
|
*/
|
|
56917
56864
|
var RgbTripletSchema = object({
|
|
56918
|
-
r: number().int().min(0).max(255),
|
|
56919
|
-
g: number().int().min(0).max(255),
|
|
56920
|
-
b: number().int().min(0).max(255)
|
|
56865
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
56866
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
56867
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
56921
56868
|
});
|
|
56922
56869
|
var HsvTripletSchema = object({
|
|
56923
56870
|
/** Hue in degrees, 0..360. */
|
|
56924
|
-
h: number().min(0).max(360),
|
|
56871
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
56925
56872
|
/** Saturation as 0..100 inclusive. */
|
|
56926
|
-
s: number().min(0).max(100),
|
|
56873
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
56927
56874
|
/** Value/brightness as 0..100 inclusive. */
|
|
56928
|
-
v: number().min(0).max(100)
|
|
56875
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
56929
56876
|
});
|
|
56930
56877
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
56931
56878
|
object({
|
|
@@ -56954,7 +56901,7 @@ object({
|
|
|
56954
56901
|
/** Populated when `mode === 'hsv'`. */
|
|
56955
56902
|
hsv: HsvTripletSchema.optional(),
|
|
56956
56903
|
/** Populated when `mode === 'mired'`. */
|
|
56957
|
-
mireds: number().int().optional(),
|
|
56904
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
56958
56905
|
/** Ms epoch of the last operator-driven change. */
|
|
56959
56906
|
lastChangedAt: number()
|
|
56960
56907
|
});
|
|
@@ -57078,18 +57025,12 @@ _enum([
|
|
|
57078
57025
|
"empty",
|
|
57079
57026
|
"full"
|
|
57080
57027
|
]);
|
|
57081
|
-
/**
|
|
57082
|
-
|
|
57083
|
-
|
|
57084
|
-
"days",
|
|
57085
|
-
"hours",
|
|
57086
|
-
"cycles"
|
|
57087
|
-
]);
|
|
57088
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57089
|
-
* days). `value` null = unknown (D393). */
|
|
57028
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57029
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57030
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57090
57031
|
var ConsumableRemainingSchema = object({
|
|
57091
|
-
value: number().min(0).nullable(),
|
|
57092
|
-
|
|
57032
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57033
|
+
kind: ConsumableRemainingKindSchema
|
|
57093
57034
|
});
|
|
57094
57035
|
var ConsumablesStatusSchema = object({
|
|
57095
57036
|
items: array(object({
|
|
@@ -57098,7 +57039,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57098
57039
|
/** Display name. */
|
|
57099
57040
|
label: string().min(1),
|
|
57100
57041
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57101
|
-
level: number().min(0).max(100).nullable(),
|
|
57042
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57102
57043
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57103
57044
|
status: ConsumableStatusSchema.nullable(),
|
|
57104
57045
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57115,7 +57056,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57115
57056
|
})),
|
|
57116
57057
|
lastChangedAt: number()
|
|
57117
57058
|
});
|
|
57118
|
-
Object.values(DeviceType), [...
|
|
57059
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57119
57060
|
Object.values(DeviceType), method(object({
|
|
57120
57061
|
deviceId: number().int().nonnegative(),
|
|
57121
57062
|
key: string().min(1)
|
|
@@ -57140,39 +57081,17 @@ object({
|
|
|
57140
57081
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57141
57082
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57142
57083
|
* or time-only — HA accepts all three forms). */
|
|
57143
|
-
value: union([number(), string()]),
|
|
57084
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57144
57085
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57145
57086
|
options: array(string()),
|
|
57146
57087
|
/** Ms epoch when the slice was last updated. */
|
|
57147
57088
|
lastChangedAt: number(),
|
|
57148
|
-
/**
|
|
57149
|
-
|
|
57150
|
-
|
|
57151
|
-
|
|
57152
|
-
/**
|
|
57153
|
-
|
|
57154
|
-
min: number().optional(),
|
|
57155
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57156
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57157
|
-
max: number().optional(),
|
|
57158
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57159
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57160
|
-
step: number().optional(),
|
|
57161
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57162
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57163
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57164
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57165
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57166
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57167
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57168
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57169
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57170
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57171
|
-
format: _enum([
|
|
57172
|
-
"date",
|
|
57173
|
-
"time",
|
|
57174
|
-
"datetime"
|
|
57175
|
-
]).optional()
|
|
57089
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57090
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57091
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57092
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57093
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57094
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57176
57095
|
});
|
|
57177
57096
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57178
57097
|
object({
|
|
@@ -57210,9 +57129,9 @@ object({
|
|
|
57210
57129
|
]),
|
|
57211
57130
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57212
57131
|
* no intermediate position surface. */
|
|
57213
|
-
position: number().min(0).max(100).nullable(),
|
|
57132
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57214
57133
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57215
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57134
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57216
57135
|
/** Ms epoch when the slice was last updated. */
|
|
57217
57136
|
lastChangedAt: number()
|
|
57218
57137
|
});
|
|
@@ -57270,9 +57189,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57270
57189
|
object({
|
|
57271
57190
|
mode: DayNightModeSchema,
|
|
57272
57191
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57273
|
-
sensitivity: number().optional(),
|
|
57192
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57274
57193
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57275
|
-
switchDelaySec: number().optional(),
|
|
57194
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57276
57195
|
lastFetchedAt: number()
|
|
57277
57196
|
});
|
|
57278
57197
|
/**
|
|
@@ -57427,11 +57346,11 @@ object({
|
|
|
57427
57346
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57428
57347
|
availablePrograms: array(string()),
|
|
57429
57348
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57430
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57349
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57431
57350
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57432
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57351
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57433
57352
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57434
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57353
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57435
57354
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57436
57355
|
doorOpen: boolean().nullable(),
|
|
57437
57356
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57455,7 +57374,7 @@ object({
|
|
|
57455
57374
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57456
57375
|
machineCareDue: boolean().nullable(),
|
|
57457
57376
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57458
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57377
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57459
57378
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57460
57379
|
halfLoad: boolean().nullable(),
|
|
57461
57380
|
hygienePlus: boolean().nullable(),
|
|
@@ -57470,7 +57389,7 @@ object({
|
|
|
57470
57389
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57471
57390
|
activeEvents: array(string()),
|
|
57472
57391
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57473
|
-
errorCode: number().nullable(),
|
|
57392
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57474
57393
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57475
57394
|
errorLabel: string().nullable(),
|
|
57476
57395
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57616,24 +57535,14 @@ object({
|
|
|
57616
57535
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57617
57536
|
lastPressedAt: number().nullable(),
|
|
57618
57537
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57619
|
-
pressCountSinceStart: number()
|
|
57538
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57620
57539
|
});
|
|
57621
57540
|
object({
|
|
57622
57541
|
deviceId: number(),
|
|
57623
57542
|
timestamp: number()
|
|
57624
57543
|
});
|
|
57625
57544
|
DeviceType.Button, DeviceType.Camera;
|
|
57626
|
-
|
|
57627
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57628
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57629
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57630
|
-
* The option set is stable across observations; it is persisted in the
|
|
57631
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57632
|
-
* stored in `sourceInfo`.
|
|
57633
|
-
*/
|
|
57634
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57635
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57636
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
57545
|
+
_enum([
|
|
57637
57546
|
"date",
|
|
57638
57547
|
"time",
|
|
57639
57548
|
"datetime"
|
|
@@ -57641,12 +57550,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57641
57550
|
object({
|
|
57642
57551
|
value: string(),
|
|
57643
57552
|
/**
|
|
57644
|
-
* Set
|
|
57645
|
-
* as
|
|
57646
|
-
*
|
|
57647
|
-
* a time-only sensor → `'time'`.
|
|
57553
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
57554
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
57555
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57648
57556
|
*/
|
|
57649
|
-
|
|
57557
|
+
timestamp: boolean().optional(),
|
|
57650
57558
|
/** Ms epoch when the slice was last updated. */
|
|
57651
57559
|
lastFetchedAt: number()
|
|
57652
57560
|
});
|
|
@@ -57665,13 +57573,13 @@ var EventFireSchema = object({
|
|
|
57665
57573
|
deviceId: number(),
|
|
57666
57574
|
eventType: string(),
|
|
57667
57575
|
data: record(string(), unknown()).nullable(),
|
|
57668
|
-
timestamp: number(),
|
|
57669
|
-
seq: number()
|
|
57576
|
+
timestamp: number().meta(readingMeta("none")),
|
|
57577
|
+
seq: number().meta(readingMeta("count"))
|
|
57670
57578
|
});
|
|
57671
57579
|
object({
|
|
57672
57580
|
eventTypes: array(string()),
|
|
57673
57581
|
lastEvent: EventFireSchema.nullable(),
|
|
57674
|
-
eventCountSinceStart: number()
|
|
57582
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57675
57583
|
});
|
|
57676
57584
|
DeviceType.EventEmitter;
|
|
57677
57585
|
var IdentitySchema = object({
|
|
@@ -58060,10 +57968,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58060
57968
|
object({
|
|
58061
57969
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58062
57970
|
* speed surface (single-speed fan). */
|
|
58063
|
-
percentage: number().min(0).max(100).nullable(),
|
|
57971
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58064
57972
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58065
57973
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58066
|
-
percentageStep: number().positive().optional(),
|
|
57974
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58067
57975
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58068
57976
|
* — empty string when no preset is active or supported. */
|
|
58069
57977
|
preset: string(),
|
|
@@ -58145,7 +58053,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58145
58053
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58146
58054
|
model: string().nullable(),
|
|
58147
58055
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58148
|
-
channelCount: number().nullable(),
|
|
58056
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58149
58057
|
/**
|
|
58150
58058
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58151
58059
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58179,7 +58087,7 @@ object({
|
|
|
58179
58087
|
DeviceType.Sensor;
|
|
58180
58088
|
object({
|
|
58181
58089
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58182
|
-
position: number().min(0).max(100).nullable(),
|
|
58090
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58183
58091
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58184
58092
|
lastFetchedAt: number()
|
|
58185
58093
|
});
|
|
@@ -58188,9 +58096,9 @@ object({
|
|
|
58188
58096
|
/** Whether the humidifier is currently on. */
|
|
58189
58097
|
on: boolean(),
|
|
58190
58098
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58191
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58099
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58192
58100
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58193
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58101
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58194
58102
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58195
58103
|
* device has no mode surface. */
|
|
58196
58104
|
mode: string().nullable(),
|
|
@@ -58200,9 +58108,9 @@ object({
|
|
|
58200
58108
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58201
58109
|
action: string().nullable(),
|
|
58202
58110
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58203
|
-
minHumidity: number().nullable(),
|
|
58111
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58204
58112
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58205
|
-
maxHumidity: number().nullable(),
|
|
58113
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58206
58114
|
/** Ms epoch when the slice was last updated. */
|
|
58207
58115
|
lastChangedAt: number()
|
|
58208
58116
|
});
|
|
@@ -58226,22 +58134,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58226
58134
|
auth: "protected"
|
|
58227
58135
|
});
|
|
58228
58136
|
object({
|
|
58229
|
-
/** Current relative humidity, 0..100. */
|
|
58230
|
-
percent: number().min(0).max(100).meta({
|
|
58231
|
-
|
|
58137
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58138
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58139
|
+
precision: 0,
|
|
58232
58140
|
label: "Humidity"
|
|
58233
|
-
}),
|
|
58141
|
+
})),
|
|
58234
58142
|
/** Ms epoch when the slice was last updated. */
|
|
58235
|
-
lastFetchedAt: number()
|
|
58236
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58237
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58238
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58239
|
-
unit: string().optional(),
|
|
58240
|
-
/** Suggested decimal places for numeric display.
|
|
58241
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58242
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58243
|
-
* auto-formatting when absent. */
|
|
58244
|
-
precision: number().int().min(0).max(10).optional()
|
|
58143
|
+
lastFetchedAt: number()
|
|
58245
58144
|
});
|
|
58246
58145
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58247
58146
|
object({
|
|
@@ -58249,7 +58148,7 @@ object({
|
|
|
58249
58148
|
* entity exposes no `entity_picture` (yet). */
|
|
58250
58149
|
url: string().nullable(),
|
|
58251
58150
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58252
|
-
lastUpdated: number().nullable()
|
|
58151
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58253
58152
|
});
|
|
58254
58153
|
DeviceType.Image;
|
|
58255
58154
|
/**
|
|
@@ -58305,19 +58204,19 @@ var NormalizedRangeSchema = object({
|
|
|
58305
58204
|
});
|
|
58306
58205
|
object({
|
|
58307
58206
|
/** Normalized 0–100. */
|
|
58308
|
-
brightness: number().optional(),
|
|
58207
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58309
58208
|
/** Normalized 0–100. */
|
|
58310
|
-
contrast: number().optional(),
|
|
58209
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58311
58210
|
/** Normalized 0–100. */
|
|
58312
|
-
saturation: number().optional(),
|
|
58211
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58313
58212
|
/** Normalized 0–100. */
|
|
58314
|
-
sharpness: number().optional(),
|
|
58213
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58315
58214
|
mirror: boolean().optional(),
|
|
58316
58215
|
flip: boolean().optional(),
|
|
58317
58216
|
rotate: ImageRotateSchema.optional(),
|
|
58318
58217
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58319
58218
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58320
|
-
warmth: number().optional(),
|
|
58219
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58321
58220
|
exposureMode: ExposureModeSchema.optional(),
|
|
58322
58221
|
backlightMode: BacklightModeSchema.optional(),
|
|
58323
58222
|
lastFetchedAt: number()
|
|
@@ -58562,10 +58461,10 @@ var IntercomAbilitySchema = object({
|
|
|
58562
58461
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58563
58462
|
codecs: array(string()),
|
|
58564
58463
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58565
|
-
sampleRate: number(),
|
|
58464
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58566
58465
|
duplex: _enum(["half", "full"]),
|
|
58567
58466
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58568
|
-
maxBacklogMs: number()
|
|
58467
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58569
58468
|
});
|
|
58570
58469
|
var IntercomStatusSchema = object({
|
|
58571
58470
|
/** True while a talk session is open. */
|
|
@@ -58676,13 +58575,13 @@ object({
|
|
|
58676
58575
|
activity: LawnMowerActivitySchema,
|
|
58677
58576
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58678
58577
|
* reading. */
|
|
58679
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
58578
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58680
58579
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58681
58580
|
* task is active / progress is unavailable. */
|
|
58682
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58581
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58683
58582
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58684
58583
|
* or null when unknown. */
|
|
58685
|
-
currentCode: number().nullable(),
|
|
58584
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58686
58585
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58687
58586
|
currentCodeLabel: string().nullable(),
|
|
58688
58587
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59144,7 +59043,7 @@ object({
|
|
|
59144
59043
|
state: MediaPlayerStateSchema,
|
|
59145
59044
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59146
59045
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59147
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59046
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59148
59047
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59149
59048
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59150
59049
|
isMuted: boolean().nullable(),
|
|
@@ -59157,10 +59056,10 @@ object({
|
|
|
59157
59056
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59158
59057
|
/** Current playback position in ms. Null when not seekable or
|
|
59159
59058
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59160
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59059
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59161
59060
|
/** Total duration of the current media in ms. Null when unknown
|
|
59162
59061
|
* (live stream) or nothing is playing. */
|
|
59163
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59062
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59164
59063
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59165
59064
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59166
59065
|
shuffle: boolean().nullable(),
|
|
@@ -59460,7 +59359,7 @@ object({
|
|
|
59460
59359
|
* it, every provider seeded it at boot, and every session left it
|
|
59461
59360
|
* `detected: true` after its detach.
|
|
59462
59361
|
*/
|
|
59463
|
-
autoClearAfterMs: number().nullable()
|
|
59362
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59464
59363
|
});
|
|
59465
59364
|
/**
|
|
59466
59365
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59510,7 +59409,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59510
59409
|
});
|
|
59511
59410
|
object({
|
|
59512
59411
|
enabled: boolean(),
|
|
59513
|
-
sensitivity: number(),
|
|
59412
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59514
59413
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59515
59414
|
regions: array(MotionZoneRegionSchema),
|
|
59516
59415
|
lastFetchedAt: number()
|
|
@@ -59814,7 +59713,7 @@ var NavigationStatusSchema = object({
|
|
|
59814
59713
|
following: boolean(),
|
|
59815
59714
|
flash: boolean(),
|
|
59816
59715
|
lightMode: NavigationLightModeSchema,
|
|
59817
|
-
lightLevel: number().min(40).max(100),
|
|
59716
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
59818
59717
|
/** Ms epoch when the slice was last updated. */
|
|
59819
59718
|
lastChangedAt: number()
|
|
59820
59719
|
});
|
|
@@ -59860,13 +59759,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
59860
59759
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
59861
59760
|
* SKIP a null rather than coerce it.
|
|
59862
59761
|
*/
|
|
59863
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
59762
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59864
59763
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
59865
|
-
rssiDbm: number().optional(),
|
|
59764
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
59866
59765
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
59867
59766
|
ssid: string().optional(),
|
|
59868
59767
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
59869
|
-
lastUpdated: number()
|
|
59768
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
59870
59769
|
});
|
|
59871
59770
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
59872
59771
|
deviceId: number(),
|
|
@@ -60185,7 +60084,7 @@ object({
|
|
|
60185
60084
|
lastError: string().nullable(),
|
|
60186
60085
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60187
60086
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60188
|
-
queueDepth: number().int().nonnegative(),
|
|
60087
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60189
60088
|
/** Per-feature capability matrix — authoritative source for the
|
|
60190
60089
|
* compose-form field gating. */
|
|
60191
60090
|
supports: NotifierSupportsSchema
|
|
@@ -60235,15 +60134,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60235
60134
|
acceptedAt: number()
|
|
60236
60135
|
});
|
|
60237
60136
|
object({
|
|
60238
|
-
|
|
60239
|
-
|
|
60240
|
-
* Populated live from the upstream source on each state push.
|
|
60241
|
-
* Absent for unitless sensors. */
|
|
60242
|
-
unit: string().optional(),
|
|
60243
|
-
/** Suggested decimal places for numeric display.
|
|
60244
|
-
* Populated live from the upstream source when provided.
|
|
60245
|
-
* Falls back to auto-formatting when absent. */
|
|
60246
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60137
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60138
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60247
60139
|
/** Ms epoch when the slice was last updated. */
|
|
60248
60140
|
lastFetchedAt: number()
|
|
60249
60141
|
});
|
|
@@ -60533,23 +60425,26 @@ object({
|
|
|
60533
60425
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60534
60426
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60535
60427
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60536
|
-
foodLevel: number().nullable(),
|
|
60428
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60537
60429
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60538
60430
|
* single-hopper models. */
|
|
60539
|
-
food1: number().nullable(),
|
|
60431
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60540
60432
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60541
60433
|
* single-hopper models. */
|
|
60542
|
-
food2: number().nullable(),
|
|
60434
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60543
60435
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60544
60436
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60545
60437
|
* below the feeder's low threshold. */
|
|
60546
60438
|
lowFood: boolean(),
|
|
60547
60439
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60548
60440
|
* device has no battery reading. */
|
|
60549
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60550
|
-
/**
|
|
60551
|
-
*
|
|
60552
|
-
|
|
60441
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60442
|
+
/**
|
|
60443
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
60444
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
60445
|
+
* model has no desiccant sensor.
|
|
60446
|
+
*/
|
|
60447
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60553
60448
|
/** True while a feed is in progress. */
|
|
60554
60449
|
feeding: boolean(),
|
|
60555
60450
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60560,7 +60455,7 @@ object({
|
|
|
60560
60455
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60561
60456
|
error: string().nullable(),
|
|
60562
60457
|
/** Raw device error code (0 / null = no error). */
|
|
60563
|
-
errorCode: number().nullable(),
|
|
60458
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60564
60459
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60565
60460
|
isDualHopper: boolean(),
|
|
60566
60461
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60570,7 +60465,7 @@ object({
|
|
|
60570
60465
|
/** Play a chime when dispensing. */
|
|
60571
60466
|
feedSound: boolean(),
|
|
60572
60467
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60573
|
-
volume: number(),
|
|
60468
|
+
volume: number().meta(readingMeta("none")),
|
|
60574
60469
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60575
60470
|
lastFetchedAt: number()
|
|
60576
60471
|
});
|
|
@@ -61007,36 +60902,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61007
60902
|
});
|
|
61008
60903
|
object({
|
|
61009
60904
|
/** Instantaneous power draw in watts. */
|
|
61010
|
-
watts: number().optional().meta({
|
|
61011
|
-
unit: "W",
|
|
61012
|
-
label: "Power"
|
|
61013
|
-
}),
|
|
60905
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61014
60906
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61015
|
-
kwhTotal: number().optional().meta({
|
|
61016
|
-
unit: "kWh",
|
|
61017
|
-
label: "Energy"
|
|
61018
|
-
}),
|
|
60907
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61019
60908
|
/** Voltage in volts. */
|
|
61020
|
-
volts: number().optional(),
|
|
60909
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61021
60910
|
/** Current in amperes. */
|
|
61022
|
-
amps: number().optional(),
|
|
61023
|
-
/** Apparent power in volt-amperes
|
|
61024
|
-
va: number().optional(),
|
|
60911
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
60912
|
+
/** Apparent power in volt-amperes. */
|
|
60913
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61025
60914
|
/** Power factor (0..1) if reported. */
|
|
61026
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
60915
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61027
60916
|
/** Ms epoch when the slice was last updated. */
|
|
61028
|
-
lastFetchedAt: number()
|
|
61029
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61030
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61031
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61032
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61033
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61034
|
-
unit: string().optional(),
|
|
61035
|
-
/** Suggested decimal places for numeric display.
|
|
61036
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61037
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61038
|
-
* auto-formatting when absent. */
|
|
61039
|
-
precision: number().int().min(0).max(10).optional()
|
|
60917
|
+
lastFetchedAt: number()
|
|
61040
60918
|
});
|
|
61041
60919
|
DeviceType.Sensor;
|
|
61042
60920
|
/**
|
|
@@ -61057,11 +60935,11 @@ DeviceType.Sensor;
|
|
|
61057
60935
|
*/
|
|
61058
60936
|
var GpsLocationSchema = object({
|
|
61059
60937
|
/** Latitude in decimal degrees, -90..90. */
|
|
61060
|
-
latitude: number().min(-90).max(90),
|
|
60938
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61061
60939
|
/** Longitude in decimal degrees, -180..180. */
|
|
61062
|
-
longitude: number().min(-180).max(180),
|
|
60940
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61063
60941
|
/** Reported accuracy in meters (lower = better). */
|
|
61064
|
-
accuracyMeters: number().nonnegative()
|
|
60942
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61065
60943
|
});
|
|
61066
60944
|
object({
|
|
61067
60945
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61073,25 +60951,16 @@ object({
|
|
|
61073
60951
|
gps: GpsLocationSchema.nullable(),
|
|
61074
60952
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61075
60953
|
* when not reported. */
|
|
61076
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
60954
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61077
60955
|
/** Ms epoch when the slice was last updated. */
|
|
61078
60956
|
lastChangedAt: number()
|
|
61079
60957
|
});
|
|
61080
60958
|
DeviceType.Presence;
|
|
61081
60959
|
object({
|
|
61082
|
-
/** Current pressure in hPa. */
|
|
61083
|
-
hpa: number(),
|
|
60960
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
60961
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61084
60962
|
/** Ms epoch when the slice was last updated. */
|
|
61085
|
-
lastFetchedAt: number()
|
|
61086
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61087
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61088
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61089
|
-
unit: string().optional(),
|
|
61090
|
-
/** Suggested decimal places for numeric display.
|
|
61091
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61092
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61093
|
-
* auto-formatting when absent. */
|
|
61094
|
-
precision: number().int().min(0).max(10).optional()
|
|
60963
|
+
lastFetchedAt: number()
|
|
61095
60964
|
});
|
|
61096
60965
|
DeviceType.Sensor;
|
|
61097
60966
|
/**
|
|
@@ -61424,8 +61293,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61424
61293
|
}), _void(), { kind: "mutation" });
|
|
61425
61294
|
var PtzAutotrackSettingsSchema = object({
|
|
61426
61295
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61427
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61428
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61296
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61297
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61429
61298
|
});
|
|
61430
61299
|
/**
|
|
61431
61300
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61482,7 +61351,7 @@ object({
|
|
|
61482
61351
|
/** null = unknown — never coerced to false (D393). */
|
|
61483
61352
|
running: boolean().nullable(),
|
|
61484
61353
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61485
|
-
since: number().nullable(),
|
|
61354
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61486
61355
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61487
61356
|
phase: string().nullable(),
|
|
61488
61357
|
/** null until a reading has been published (D393). */
|
|
@@ -62680,9 +62549,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62680
62549
|
*/
|
|
62681
62550
|
var RecordWindowSchema = object({
|
|
62682
62551
|
trigger: RecordTriggerSchema,
|
|
62683
|
-
day: number().int().min(0).max(6),
|
|
62684
|
-
startMinute: number().int().min(0).max(1439),
|
|
62685
|
-
endMinute: number().int().min(1).max(1440)
|
|
62552
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
62553
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
62554
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62686
62555
|
});
|
|
62687
62556
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62688
62557
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62751,10 +62620,10 @@ object({
|
|
|
62751
62620
|
/** Master "record to the card at all" switch. */
|
|
62752
62621
|
enabled: boolean().nullable(),
|
|
62753
62622
|
overwriteWhenFull: boolean().nullable(),
|
|
62754
|
-
preRecordSec: number().nullable(),
|
|
62755
|
-
postRecordSec: number().nullable(),
|
|
62623
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62624
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62756
62625
|
/** Length of one recorded file, in minutes. */
|
|
62757
|
-
segmentMinutes: number().nullable(),
|
|
62626
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62758
62627
|
/** The primary track's weekly windows, flattened. */
|
|
62759
62628
|
windows: array(RecordWindowSchema),
|
|
62760
62629
|
/**
|
|
@@ -62770,7 +62639,7 @@ object({
|
|
|
62770
62639
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62771
62640
|
* writable.
|
|
62772
62641
|
*/
|
|
62773
|
-
unreadableWindows: number(),
|
|
62642
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62774
62643
|
/**
|
|
62775
62644
|
* The camera is scheduled to record and has NO usable storage.
|
|
62776
62645
|
*
|
|
@@ -63407,7 +63276,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63407
63276
|
url: string().optional(),
|
|
63408
63277
|
codec: string().optional(),
|
|
63409
63278
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63410
|
-
fps: number().positive().optional(),
|
|
63279
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63411
63280
|
label: string().optional(),
|
|
63412
63281
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63413
63282
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63437,18 +63306,18 @@ var StreamProfileSchema = _enum([
|
|
|
63437
63306
|
]);
|
|
63438
63307
|
/** The current encoding config of one stream profile. */
|
|
63439
63308
|
var StreamProfileConfigSchema = object({
|
|
63440
|
-
width: number(),
|
|
63441
|
-
height: number(),
|
|
63309
|
+
width: number().meta(readingMeta("none")),
|
|
63310
|
+
height: number().meta(readingMeta("none")),
|
|
63442
63311
|
codec: _enum(["h264", "h265"]),
|
|
63443
|
-
framerate: number(),
|
|
63444
|
-
bitrate: number(),
|
|
63312
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63313
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63445
63314
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63446
63315
|
encoderProfile: _enum([
|
|
63447
63316
|
"high",
|
|
63448
63317
|
"main",
|
|
63449
63318
|
"baseline"
|
|
63450
63319
|
]).optional(),
|
|
63451
|
-
gop: number().optional(),
|
|
63320
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63452
63321
|
/**
|
|
63453
63322
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63454
63323
|
*
|
|
@@ -64091,23 +63960,13 @@ object({
|
|
|
64091
63960
|
});
|
|
64092
63961
|
DeviceType.Sensor;
|
|
64093
63962
|
object({
|
|
64094
|
-
/** Current temperature in Celsius. */
|
|
64095
|
-
celsius: number().meta({
|
|
64096
|
-
|
|
63963
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
63964
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
63965
|
+
precision: 1,
|
|
64097
63966
|
label: "Temperature"
|
|
64098
|
-
}),
|
|
63967
|
+
})),
|
|
64099
63968
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64100
|
-
lastFetchedAt: number()
|
|
64101
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64102
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64103
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64104
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64105
|
-
unit: string().optional(),
|
|
64106
|
-
/** Suggested decimal places for numeric display.
|
|
64107
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64108
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64109
|
-
* auto-formatting when absent. */
|
|
64110
|
-
precision: number().int().min(0).max(10).optional()
|
|
63969
|
+
lastFetchedAt: number()
|
|
64111
63970
|
});
|
|
64112
63971
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64113
63972
|
/**
|
|
@@ -64359,16 +64218,16 @@ object({
|
|
|
64359
64218
|
]),
|
|
64360
64219
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64361
64220
|
* reading. */
|
|
64362
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64221
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64363
64222
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64364
64223
|
* the vacuum has no speed control. */
|
|
64365
64224
|
fanSpeed: string().nullable(),
|
|
64366
64225
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64367
64226
|
availableFanSpeeds: array(string()),
|
|
64368
64227
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64369
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64228
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64370
64229
|
/** Current error code (0 / null = no error). */
|
|
64371
|
-
errorCode: number().nullable(),
|
|
64230
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64372
64231
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64373
64232
|
errorLabel: string().nullable(),
|
|
64374
64233
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64407,7 +64266,7 @@ object({
|
|
|
64407
64266
|
]),
|
|
64408
64267
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64409
64268
|
* intermediate position surface. */
|
|
64410
|
-
position: number().min(0).max(100).nullable(),
|
|
64269
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64411
64270
|
/** Ms epoch when the slice was last updated. */
|
|
64412
64271
|
lastChangedAt: number()
|
|
64413
64272
|
});
|
|
@@ -64435,9 +64294,9 @@ object({
|
|
|
64435
64294
|
DeviceType.Sensor;
|
|
64436
64295
|
object({
|
|
64437
64296
|
/** Current measured temperature. Null when not reported. */
|
|
64438
|
-
currentTemp: number().nullable(),
|
|
64297
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64439
64298
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64440
|
-
targetTemp: number().nullable(),
|
|
64299
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64441
64300
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64442
64301
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64443
64302
|
* device reports an unknown state. */
|
|
@@ -64448,9 +64307,9 @@ object({
|
|
|
64448
64307
|
* has no away surface. */
|
|
64449
64308
|
away: boolean().nullable(),
|
|
64450
64309
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64451
|
-
minTemp: number().nullable(),
|
|
64310
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64452
64311
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64453
|
-
maxTemp: number().nullable(),
|
|
64312
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64454
64313
|
/** Ms epoch when the slice was last updated. */
|
|
64455
64314
|
lastChangedAt: number()
|
|
64456
64315
|
});
|
|
@@ -64474,25 +64333,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64474
64333
|
auth: "protected"
|
|
64475
64334
|
});
|
|
64476
64335
|
object({
|
|
64477
|
-
/** Verbatim
|
|
64478
|
-
* when no condition has been reported yet. */
|
|
64336
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64479
64337
|
condition: string().nullable(),
|
|
64480
|
-
/** Current temperature in
|
|
64481
|
-
temperature: number().nullable(),
|
|
64482
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64483
|
-
temperatureUnit: string().nullable(),
|
|
64338
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64339
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64484
64340
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64485
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64486
|
-
/** Barometric pressure in
|
|
64487
|
-
pressure: number().nullable(),
|
|
64488
|
-
/**
|
|
64489
|
-
|
|
64490
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64491
|
-
windSpeed: number().nullable(),
|
|
64492
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64493
|
-
windSpeedUnit: string().nullable(),
|
|
64341
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64342
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64343
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64344
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64345
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64494
64346
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64495
|
-
windBearing: number().nullable(),
|
|
64347
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64496
64348
|
/** Ms epoch when the slice was last updated. */
|
|
64497
64349
|
lastFetchedAt: number()
|
|
64498
64350
|
});
|
|
@@ -78469,7 +78321,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78469
78321
|
field: "value",
|
|
78470
78322
|
quantity: t("the reading", "il valore"),
|
|
78471
78323
|
label: t("Reading", "Valore"),
|
|
78472
|
-
unitField: "unit",
|
|
78473
78324
|
icon: "gauge"
|
|
78474
78325
|
}]
|
|
78475
78326
|
},
|
|
@@ -78605,7 +78456,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78605
78456
|
field: "temperature",
|
|
78606
78457
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78607
78458
|
label: t("Temperature", "Temperatura"),
|
|
78608
|
-
|
|
78459
|
+
unit: "°C",
|
|
78609
78460
|
icon: "thermometer"
|
|
78610
78461
|
},
|
|
78611
78462
|
{
|
|
@@ -78621,7 +78472,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78621
78472
|
field: "windSpeed",
|
|
78622
78473
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78623
78474
|
label: t("Wind", "Vento"),
|
|
78624
|
-
|
|
78475
|
+
unit: "m/s",
|
|
78625
78476
|
icon: "wind"
|
|
78626
78477
|
},
|
|
78627
78478
|
{
|
|
@@ -78629,7 +78480,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78629
78480
|
field: "pressure",
|
|
78630
78481
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78631
78482
|
label: t("Pressure", "Pressione"),
|
|
78632
|
-
|
|
78483
|
+
unit: "hPa",
|
|
78633
78484
|
icon: "gauge"
|
|
78634
78485
|
}
|
|
78635
78486
|
]
|