@camstack/addon-model-studio 1.1.296 → 1.1.297
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-DOhuE4t6.mjs → MotionZonesSettings-D_HfgGVx.mjs} +21 -21
- package/dist/{PrivacyMaskSettings-BtQIysUm.mjs → PrivacyMaskSettings-lrZujhrs.mjs} +4 -4
- package/dist/{SceneMonitorEditor-B4cEP3UH.mjs → SceneMonitorEditor-D_k9w6y8.mjs} +71 -71
- package/dist/_stub.js +4254 -4181
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DoLsYz9K.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-U1Dq0t4d.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DX4Jz8LK.mjs +26 -0
- package/dist/{hostInit-BfsN6Dh3.mjs → hostInit-lgxajgO5.mjs} +2 -2
- package/dist/model-studio.addon.js +273 -422
- package/dist/model-studio.addon.mjs +273 -422
- package/dist/{player-overlays-BVHDRE8f.mjs → player-overlays-BErbmrZZ.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-CI-NtcQi.mjs → responsive-BaiZrRiv.mjs} +13 -10
- package/dist/{scene-monitor-copy-CvzuJJ8Z.mjs → scene-monitor-copy-DSS-RbWQ.mjs} +1 -1
- package/dist/{square-CsljmL2M.mjs → square-CjAc_uJa.mjs} +1 -1
- package/dist/{trash-2-DwX9K1LA.mjs → trash-2--He_-Iao.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CoN9WY8L.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-ZIEWPFwu.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CDZyIXC0.mjs +0 -26
|
@@ -5803,7 +5803,7 @@ var ZodIssueCode = {
|
|
|
5803
5803
|
var ZodFirstPartyTypeKind;
|
|
5804
5804
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5805
5805
|
//#endregion
|
|
5806
|
-
//#region ../types/dist/sleep-
|
|
5806
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5807
5807
|
/**
|
|
5808
5808
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5809
5809
|
* window to float samples (D455).
|
|
@@ -8290,6 +8290,52 @@ var RecordKindDeclarationSchema = object({
|
|
|
8290
8290
|
}).strict();
|
|
8291
8291
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
8292
8292
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
8293
|
+
var READING_QUANTITIES = [
|
|
8294
|
+
"temperature",
|
|
8295
|
+
"pressure",
|
|
8296
|
+
"speed",
|
|
8297
|
+
"precipitation",
|
|
8298
|
+
"precipitation-rate",
|
|
8299
|
+
"length",
|
|
8300
|
+
"area",
|
|
8301
|
+
"illuminance",
|
|
8302
|
+
"irradiance",
|
|
8303
|
+
"power",
|
|
8304
|
+
"energy",
|
|
8305
|
+
"voltage",
|
|
8306
|
+
"current",
|
|
8307
|
+
"apparent-power",
|
|
8308
|
+
"humidity",
|
|
8309
|
+
"percentage",
|
|
8310
|
+
"concentration-volume",
|
|
8311
|
+
"concentration-mass",
|
|
8312
|
+
"concentration-ppb",
|
|
8313
|
+
"volume",
|
|
8314
|
+
"duration",
|
|
8315
|
+
"duration-ms",
|
|
8316
|
+
"information",
|
|
8317
|
+
"sound-level",
|
|
8318
|
+
"signal-level",
|
|
8319
|
+
"colour-temperature",
|
|
8320
|
+
"angle",
|
|
8321
|
+
"bitrate",
|
|
8322
|
+
"rate",
|
|
8323
|
+
"mass",
|
|
8324
|
+
"index",
|
|
8325
|
+
"ratio",
|
|
8326
|
+
"count",
|
|
8327
|
+
"none",
|
|
8328
|
+
"device"
|
|
8329
|
+
];
|
|
8330
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8331
|
+
new Set(READING_QUANTITIES);
|
|
8332
|
+
function readingMeta(quantity, extras) {
|
|
8333
|
+
return {
|
|
8334
|
+
quantity,
|
|
8335
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8336
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8337
|
+
};
|
|
8338
|
+
}
|
|
8293
8339
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8294
8340
|
var CamProfileSchema = _enum([
|
|
8295
8341
|
"high",
|
|
@@ -8317,8 +8363,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8317
8363
|
"derived"
|
|
8318
8364
|
]);
|
|
8319
8365
|
var CamStreamResolutionSchema = object({
|
|
8320
|
-
width: number().int().positive(),
|
|
8321
|
-
height: number().int().positive()
|
|
8366
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8367
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8322
8368
|
});
|
|
8323
8369
|
var CameraStreamSchema = object({
|
|
8324
8370
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -9042,14 +9088,6 @@ Object.freeze({
|
|
|
9042
9088
|
{
|
|
9043
9089
|
"path": "aqi",
|
|
9044
9090
|
"valueType": "number"
|
|
9045
|
-
},
|
|
9046
|
-
{
|
|
9047
|
-
"path": "unit",
|
|
9048
|
-
"valueType": "string"
|
|
9049
|
-
},
|
|
9050
|
-
{
|
|
9051
|
-
"path": "precision",
|
|
9052
|
-
"valueType": "number"
|
|
9053
9091
|
}
|
|
9054
9092
|
],
|
|
9055
9093
|
"alarm-panel": [
|
|
@@ -9085,20 +9123,10 @@ Object.freeze({
|
|
|
9085
9123
|
"valueType": "boolean"
|
|
9086
9124
|
}
|
|
9087
9125
|
],
|
|
9088
|
-
"ambient-light-sensor": [
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
},
|
|
9093
|
-
{
|
|
9094
|
-
"path": "unit",
|
|
9095
|
-
"valueType": "string"
|
|
9096
|
-
},
|
|
9097
|
-
{
|
|
9098
|
-
"path": "precision",
|
|
9099
|
-
"valueType": "number"
|
|
9100
|
-
}
|
|
9101
|
-
],
|
|
9126
|
+
"ambient-light-sensor": [{
|
|
9127
|
+
"path": "lux",
|
|
9128
|
+
"valueType": "number"
|
|
9129
|
+
}],
|
|
9102
9130
|
"audio-metrics": [
|
|
9103
9131
|
{
|
|
9104
9132
|
"path": "ts",
|
|
@@ -9178,6 +9206,10 @@ Object.freeze({
|
|
|
9178
9206
|
"path": "lastUpdated",
|
|
9179
9207
|
"valueType": "number"
|
|
9180
9208
|
},
|
|
9209
|
+
{
|
|
9210
|
+
"path": "volts",
|
|
9211
|
+
"valueType": "number"
|
|
9212
|
+
},
|
|
9181
9213
|
{
|
|
9182
9214
|
"path": "lastContactAt",
|
|
9183
9215
|
"valueType": "number"
|
|
@@ -9420,10 +9452,6 @@ Object.freeze({
|
|
|
9420
9452
|
"datetime"
|
|
9421
9453
|
]
|
|
9422
9454
|
},
|
|
9423
|
-
{
|
|
9424
|
-
"path": "unit",
|
|
9425
|
-
"valueType": "string"
|
|
9426
|
-
},
|
|
9427
9455
|
{
|
|
9428
9456
|
"path": "min",
|
|
9429
9457
|
"valueType": "number"
|
|
@@ -9435,19 +9463,6 @@ Object.freeze({
|
|
|
9435
9463
|
{
|
|
9436
9464
|
"path": "step",
|
|
9437
9465
|
"valueType": "number"
|
|
9438
|
-
},
|
|
9439
|
-
{
|
|
9440
|
-
"path": "precision",
|
|
9441
|
-
"valueType": "number"
|
|
9442
|
-
},
|
|
9443
|
-
{
|
|
9444
|
-
"path": "format",
|
|
9445
|
-
"valueType": "enum",
|
|
9446
|
-
"enumValues": [
|
|
9447
|
-
"date",
|
|
9448
|
-
"time",
|
|
9449
|
-
"datetime"
|
|
9450
|
-
]
|
|
9451
9466
|
}
|
|
9452
9467
|
],
|
|
9453
9468
|
"cover": [
|
|
@@ -9688,13 +9703,8 @@ Object.freeze({
|
|
|
9688
9703
|
"path": "value",
|
|
9689
9704
|
"valueType": "string"
|
|
9690
9705
|
}, {
|
|
9691
|
-
"path": "
|
|
9692
|
-
"valueType": "
|
|
9693
|
-
"enumValues": [
|
|
9694
|
-
"date",
|
|
9695
|
-
"time",
|
|
9696
|
-
"datetime"
|
|
9697
|
-
]
|
|
9706
|
+
"path": "timestamp",
|
|
9707
|
+
"valueType": "boolean"
|
|
9698
9708
|
}],
|
|
9699
9709
|
"event-emitter": [
|
|
9700
9710
|
{
|
|
@@ -9801,20 +9811,10 @@ Object.freeze({
|
|
|
9801
9811
|
"valueType": "number"
|
|
9802
9812
|
}
|
|
9803
9813
|
],
|
|
9804
|
-
"humidity-sensor": [
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
},
|
|
9809
|
-
{
|
|
9810
|
-
"path": "unit",
|
|
9811
|
-
"valueType": "string"
|
|
9812
|
-
},
|
|
9813
|
-
{
|
|
9814
|
-
"path": "precision",
|
|
9815
|
-
"valueType": "number"
|
|
9816
|
-
}
|
|
9817
|
-
],
|
|
9814
|
+
"humidity-sensor": [{
|
|
9815
|
+
"path": "percent",
|
|
9816
|
+
"valueType": "number"
|
|
9817
|
+
}],
|
|
9818
9818
|
"image": [{
|
|
9819
9819
|
"path": "url",
|
|
9820
9820
|
"valueType": "string"
|
|
@@ -10153,20 +10153,10 @@ Object.freeze({
|
|
|
10153
10153
|
"valueType": "boolean"
|
|
10154
10154
|
}
|
|
10155
10155
|
],
|
|
10156
|
-
"numeric-sensor": [
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
},
|
|
10161
|
-
{
|
|
10162
|
-
"path": "unit",
|
|
10163
|
-
"valueType": "string"
|
|
10164
|
-
},
|
|
10165
|
-
{
|
|
10166
|
-
"path": "precision",
|
|
10167
|
-
"valueType": "number"
|
|
10168
|
-
}
|
|
10169
|
-
],
|
|
10156
|
+
"numeric-sensor": [{
|
|
10157
|
+
"path": "value",
|
|
10158
|
+
"valueType": "number"
|
|
10159
|
+
}],
|
|
10170
10160
|
"pet-feeder": [
|
|
10171
10161
|
{
|
|
10172
10162
|
"path": "foodLevel",
|
|
@@ -10258,14 +10248,6 @@ Object.freeze({
|
|
|
10258
10248
|
{
|
|
10259
10249
|
"path": "powerFactor",
|
|
10260
10250
|
"valueType": "number"
|
|
10261
|
-
},
|
|
10262
|
-
{
|
|
10263
|
-
"path": "unit",
|
|
10264
|
-
"valueType": "string"
|
|
10265
|
-
},
|
|
10266
|
-
{
|
|
10267
|
-
"path": "precision",
|
|
10268
|
-
"valueType": "number"
|
|
10269
10251
|
}
|
|
10270
10252
|
],
|
|
10271
10253
|
"presence": [
|
|
@@ -10294,20 +10276,10 @@ Object.freeze({
|
|
|
10294
10276
|
"valueType": "number"
|
|
10295
10277
|
}
|
|
10296
10278
|
],
|
|
10297
|
-
"pressure-sensor": [
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
},
|
|
10302
|
-
{
|
|
10303
|
-
"path": "unit",
|
|
10304
|
-
"valueType": "string"
|
|
10305
|
-
},
|
|
10306
|
-
{
|
|
10307
|
-
"path": "precision",
|
|
10308
|
-
"valueType": "number"
|
|
10309
|
-
}
|
|
10310
|
-
],
|
|
10279
|
+
"pressure-sensor": [{
|
|
10280
|
+
"path": "hpa",
|
|
10281
|
+
"valueType": "number"
|
|
10282
|
+
}],
|
|
10311
10283
|
"privacy-mask": [{
|
|
10312
10284
|
"path": "enabled",
|
|
10313
10285
|
"valueType": "boolean"
|
|
@@ -10618,20 +10590,10 @@ Object.freeze({
|
|
|
10618
10590
|
"path": "tampered",
|
|
10619
10591
|
"valueType": "boolean"
|
|
10620
10592
|
}],
|
|
10621
|
-
"temperature-sensor": [
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
},
|
|
10626
|
-
{
|
|
10627
|
-
"path": "unit",
|
|
10628
|
-
"valueType": "string"
|
|
10629
|
-
},
|
|
10630
|
-
{
|
|
10631
|
-
"path": "precision",
|
|
10632
|
-
"valueType": "number"
|
|
10633
|
-
}
|
|
10634
|
-
],
|
|
10593
|
+
"temperature-sensor": [{
|
|
10594
|
+
"path": "celsius",
|
|
10595
|
+
"valueType": "number"
|
|
10596
|
+
}],
|
|
10635
10597
|
"update": [
|
|
10636
10598
|
{
|
|
10637
10599
|
"path": "currentVersion",
|
|
@@ -10742,10 +10704,6 @@ Object.freeze({
|
|
|
10742
10704
|
"path": "temperature",
|
|
10743
10705
|
"valueType": "number"
|
|
10744
10706
|
},
|
|
10745
|
-
{
|
|
10746
|
-
"path": "temperatureUnit",
|
|
10747
|
-
"valueType": "string"
|
|
10748
|
-
},
|
|
10749
10707
|
{
|
|
10750
10708
|
"path": "humidity",
|
|
10751
10709
|
"valueType": "number"
|
|
@@ -10754,18 +10712,10 @@ Object.freeze({
|
|
|
10754
10712
|
"path": "pressure",
|
|
10755
10713
|
"valueType": "number"
|
|
10756
10714
|
},
|
|
10757
|
-
{
|
|
10758
|
-
"path": "pressureUnit",
|
|
10759
|
-
"valueType": "string"
|
|
10760
|
-
},
|
|
10761
10715
|
{
|
|
10762
10716
|
"path": "windSpeed",
|
|
10763
10717
|
"valueType": "number"
|
|
10764
10718
|
},
|
|
10765
|
-
{
|
|
10766
|
-
"path": "windSpeedUnit",
|
|
10767
|
-
"valueType": "string"
|
|
10768
|
-
},
|
|
10769
10719
|
{
|
|
10770
10720
|
"path": "windBearing",
|
|
10771
10721
|
"valueType": "number"
|
|
@@ -18269,7 +18219,8 @@ var CompositionProblemSchema = object({
|
|
|
18269
18219
|
"item-field-reserved",
|
|
18270
18220
|
"target-missing",
|
|
18271
18221
|
"target-unreadable",
|
|
18272
|
-
"not-replaceable"
|
|
18222
|
+
"not-replaceable",
|
|
18223
|
+
"native-capability-replace"
|
|
18273
18224
|
]),
|
|
18274
18225
|
path: string(),
|
|
18275
18226
|
message: string()
|
|
@@ -18327,9 +18278,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18327
18278
|
reads: array(CompositionFieldReadSchema)
|
|
18328
18279
|
});
|
|
18329
18280
|
/**
|
|
18330
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18331
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18332
|
-
*
|
|
18281
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18282
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18283
|
+
* Replacing a capability the device already serves is refused
|
|
18284
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18285
|
+
* wire for a claim the hub already holds.
|
|
18333
18286
|
*/
|
|
18334
18287
|
var CompositionFeatureModeSchema = _enum([
|
|
18335
18288
|
"new",
|
|
@@ -20243,12 +20196,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20243
20196
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20244
20197
|
* in-place so dispatch keeps working.
|
|
20245
20198
|
*
|
|
20246
|
-
* **
|
|
20247
|
-
*
|
|
20248
|
-
*
|
|
20249
|
-
*
|
|
20250
|
-
* (`ha-domain-mapping`)
|
|
20251
|
-
* stored after that point.
|
|
20199
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20200
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20201
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20202
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20203
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20204
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20252
20205
|
*
|
|
20253
20206
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20254
20207
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20262,6 +20215,14 @@ var SourceInfoSchema = object({
|
|
|
20262
20215
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20263
20216
|
* Used to detect rename when `id` changes. */
|
|
20264
20217
|
uniqueId: string().optional(),
|
|
20218
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20219
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20220
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20221
|
+
dateTimeShape: _enum([
|
|
20222
|
+
"date",
|
|
20223
|
+
"time",
|
|
20224
|
+
"datetime"
|
|
20225
|
+
]).optional(),
|
|
20265
20226
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20266
20227
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20267
20228
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41174,7 +41135,8 @@ method(object({
|
|
|
41174
41135
|
"enum"
|
|
41175
41136
|
]),
|
|
41176
41137
|
enumValues: array(string()).optional(),
|
|
41177
|
-
item: boolean().optional()
|
|
41138
|
+
item: boolean().optional(),
|
|
41139
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41178
41140
|
})).readonly(),
|
|
41179
41141
|
itemArray: object({
|
|
41180
41142
|
path: string(),
|
|
@@ -44980,8 +44942,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44980
44942
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44981
44943
|
var MaskGridShapeSchema = object({
|
|
44982
44944
|
kind: literal("grid"),
|
|
44983
|
-
gridWidth: number(),
|
|
44984
|
-
gridHeight: number(),
|
|
44945
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
44946
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44985
44947
|
cells: array(boolean())
|
|
44986
44948
|
});
|
|
44987
44949
|
discriminatedUnion("kind", [
|
|
@@ -56375,46 +56337,27 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56375
56337
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
56376
56338
|
object({
|
|
56377
56339
|
/** Carbon dioxide concentration in ppm. */
|
|
56378
|
-
co2Ppm: number().min(0).optional(),
|
|
56340
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56379
56341
|
/** Total volatile organic compounds in ppb. */
|
|
56380
|
-
vocPpb: number().min(0).optional(),
|
|
56342
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56381
56343
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56382
|
-
pm25: number().min(0).optional(),
|
|
56344
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56383
56345
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56384
|
-
pm10: number().min(0).optional(),
|
|
56346
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56385
56347
|
/** Composite AQI value (typically 0..500). */
|
|
56386
|
-
aqi: number().optional(),
|
|
56348
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56387
56349
|
/** Ms epoch when the slice was last updated. */
|
|
56388
|
-
lastFetchedAt: number()
|
|
56389
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56390
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56391
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56392
|
-
* per slice is unambiguous. */
|
|
56393
|
-
unit: string().optional(),
|
|
56394
|
-
/** Suggested decimal places for numeric display.
|
|
56395
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56396
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56397
|
-
* auto-formatting when absent. */
|
|
56398
|
-
precision: number().int().min(0).max(10).optional()
|
|
56350
|
+
lastFetchedAt: number()
|
|
56399
56351
|
});
|
|
56400
56352
|
DeviceType.Sensor;
|
|
56401
56353
|
object({
|
|
56402
|
-
/** Current illuminance in lux (lx). */
|
|
56403
|
-
lux: number().min(0).meta({
|
|
56404
|
-
|
|
56354
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56355
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56356
|
+
precision: 0,
|
|
56405
56357
|
label: "Illuminance"
|
|
56406
|
-
}),
|
|
56358
|
+
})),
|
|
56407
56359
|
/** Ms epoch when the slice was last updated. */
|
|
56408
|
-
lastFetchedAt: number()
|
|
56409
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56410
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56411
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56412
|
-
unit: string().optional(),
|
|
56413
|
-
/** Suggested decimal places for numeric display.
|
|
56414
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56415
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56416
|
-
* auto-formatting when absent. */
|
|
56417
|
-
precision: number().int().min(0).max(10).optional()
|
|
56360
|
+
lastFetchedAt: number()
|
|
56418
56361
|
});
|
|
56419
56362
|
DeviceType.Sensor;
|
|
56420
56363
|
/**
|
|
@@ -56559,10 +56502,7 @@ var BatteryStatusSchema = object({
|
|
|
56559
56502
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56560
56503
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56561
56504
|
*/
|
|
56562
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56563
|
-
unit: "%",
|
|
56564
|
-
label: "Charge"
|
|
56565
|
-
}),
|
|
56505
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56566
56506
|
/**
|
|
56567
56507
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56568
56508
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56589,7 +56529,14 @@ var BatteryStatusSchema = object({
|
|
|
56589
56529
|
*/
|
|
56590
56530
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56591
56531
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56592
|
-
lastUpdated: number(),
|
|
56532
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56533
|
+
/**
|
|
56534
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56535
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56536
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56537
|
+
* `numeric-sensor` on the same device.
|
|
56538
|
+
*/
|
|
56539
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56593
56540
|
/**
|
|
56594
56541
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56595
56542
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56649,7 +56596,7 @@ object({
|
|
|
56649
56596
|
DeviceType.Sensor;
|
|
56650
56597
|
object({
|
|
56651
56598
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56652
|
-
percentage: number().min(0).max(100),
|
|
56599
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56653
56600
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56654
56601
|
lastChangedAt: number()
|
|
56655
56602
|
});
|
|
@@ -57034,21 +56981,21 @@ object({
|
|
|
57034
56981
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57035
56982
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57036
56983
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57037
|
-
target: number().nullable(),
|
|
56984
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57038
56985
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57039
56986
|
* in `heat_cool` mode. */
|
|
57040
|
-
targetHigh: number().nullable(),
|
|
56987
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57041
56988
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57042
56989
|
* in `heat_cool` mode. */
|
|
57043
|
-
targetLow: number().nullable(),
|
|
56990
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57044
56991
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57045
56992
|
* humidity control. */
|
|
57046
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
56993
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57047
56994
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57048
56995
|
* the device's internal sensor. */
|
|
57049
|
-
currentTemp: number().nullable(),
|
|
56996
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57050
56997
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57051
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
56998
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57052
56999
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57053
57000
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57054
57001
|
swingVertical: boolean().nullable(),
|
|
@@ -57056,11 +57003,11 @@ object({
|
|
|
57056
57003
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57057
57004
|
swingHorizontal: boolean().nullable(),
|
|
57058
57005
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57059
|
-
minTemp: number().nullable().optional(),
|
|
57006
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57060
57007
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57061
|
-
maxTemp: number().nullable().optional(),
|
|
57008
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57062
57009
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57063
|
-
tempStep: number().positive().nullable().optional(),
|
|
57010
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57064
57011
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57065
57012
|
lastFetchedAt: number()
|
|
57066
57013
|
});
|
|
@@ -57139,17 +57086,17 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
|
|
|
57139
57086
|
* modes to expose in the picker without a slice fetch.
|
|
57140
57087
|
*/
|
|
57141
57088
|
var RgbTripletSchema = object({
|
|
57142
|
-
r: number().int().min(0).max(255),
|
|
57143
|
-
g: number().int().min(0).max(255),
|
|
57144
|
-
b: number().int().min(0).max(255)
|
|
57089
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57090
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57091
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57145
57092
|
});
|
|
57146
57093
|
var HsvTripletSchema = object({
|
|
57147
57094
|
/** Hue in degrees, 0..360. */
|
|
57148
|
-
h: number().min(0).max(360),
|
|
57095
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57149
57096
|
/** Saturation as 0..100 inclusive. */
|
|
57150
|
-
s: number().min(0).max(100),
|
|
57097
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57151
57098
|
/** Value/brightness as 0..100 inclusive. */
|
|
57152
|
-
v: number().min(0).max(100)
|
|
57099
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57153
57100
|
});
|
|
57154
57101
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57155
57102
|
object({
|
|
@@ -57178,7 +57125,7 @@ object({
|
|
|
57178
57125
|
/** Populated when `mode === 'hsv'`. */
|
|
57179
57126
|
hsv: HsvTripletSchema.optional(),
|
|
57180
57127
|
/** Populated when `mode === 'mired'`. */
|
|
57181
|
-
mireds: number().int().optional(),
|
|
57128
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57182
57129
|
/** Ms epoch of the last operator-driven change. */
|
|
57183
57130
|
lastChangedAt: number()
|
|
57184
57131
|
});
|
|
@@ -57302,18 +57249,12 @@ _enum([
|
|
|
57302
57249
|
"empty",
|
|
57303
57250
|
"full"
|
|
57304
57251
|
]);
|
|
57305
|
-
/**
|
|
57306
|
-
|
|
57307
|
-
|
|
57308
|
-
"days",
|
|
57309
|
-
"hours",
|
|
57310
|
-
"cycles"
|
|
57311
|
-
]);
|
|
57312
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57313
|
-
* days). `value` null = unknown (D393). */
|
|
57252
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57253
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57254
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57314
57255
|
var ConsumableRemainingSchema = object({
|
|
57315
|
-
value: number().min(0).nullable(),
|
|
57316
|
-
|
|
57256
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57257
|
+
kind: ConsumableRemainingKindSchema
|
|
57317
57258
|
});
|
|
57318
57259
|
var ConsumablesStatusSchema = object({
|
|
57319
57260
|
items: array(object({
|
|
@@ -57322,7 +57263,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57322
57263
|
/** Display name. */
|
|
57323
57264
|
label: string().min(1),
|
|
57324
57265
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57325
|
-
level: number().min(0).max(100).nullable(),
|
|
57266
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57326
57267
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57327
57268
|
status: ConsumableStatusSchema.nullable(),
|
|
57328
57269
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57339,7 +57280,7 @@ var ConsumablesStatusSchema = object({
|
|
|
57339
57280
|
})),
|
|
57340
57281
|
lastChangedAt: number()
|
|
57341
57282
|
});
|
|
57342
|
-
Object.values(DeviceType), [...
|
|
57283
|
+
Object.values(DeviceType), [...ConsumableRemainingKindSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
|
|
57343
57284
|
Object.values(DeviceType), method(object({
|
|
57344
57285
|
deviceId: number().int().nonnegative(),
|
|
57345
57286
|
key: string().min(1)
|
|
@@ -57364,39 +57305,17 @@ object({
|
|
|
57364
57305
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
57365
57306
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
57366
57307
|
* or time-only — HA accepts all three forms). */
|
|
57367
|
-
value: union([number(), string()]),
|
|
57308
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
57368
57309
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
57369
57310
|
options: array(string()),
|
|
57370
57311
|
/** Ms epoch when the slice was last updated. */
|
|
57371
57312
|
lastChangedAt: number(),
|
|
57372
|
-
/**
|
|
57373
|
-
|
|
57374
|
-
|
|
57375
|
-
|
|
57376
|
-
/**
|
|
57377
|
-
|
|
57378
|
-
min: number().optional(),
|
|
57379
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
57380
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57381
|
-
max: number().optional(),
|
|
57382
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
57383
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
57384
|
-
step: number().optional(),
|
|
57385
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
57386
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
57387
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
57388
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
57389
|
-
precision: number().int().min(0).max(10).optional(),
|
|
57390
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
57391
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
57392
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
57393
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
57394
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
57395
|
-
format: _enum([
|
|
57396
|
-
"date",
|
|
57397
|
-
"time",
|
|
57398
|
-
"datetime"
|
|
57399
|
-
]).optional()
|
|
57313
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
57314
|
+
min: number().optional().meta(readingMeta("device")),
|
|
57315
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
57316
|
+
max: number().optional().meta(readingMeta("device")),
|
|
57317
|
+
/** Step increment, in the device quantity's base unit. */
|
|
57318
|
+
step: number().optional().meta(readingMeta("device"))
|
|
57400
57319
|
});
|
|
57401
57320
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
57402
57321
|
object({
|
|
@@ -57434,9 +57353,9 @@ object({
|
|
|
57434
57353
|
]),
|
|
57435
57354
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
57436
57355
|
* no intermediate position surface. */
|
|
57437
|
-
position: number().min(0).max(100).nullable(),
|
|
57356
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57438
57357
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
57439
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
57358
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57440
57359
|
/** Ms epoch when the slice was last updated. */
|
|
57441
57360
|
lastChangedAt: number()
|
|
57442
57361
|
});
|
|
@@ -57494,9 +57413,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
57494
57413
|
object({
|
|
57495
57414
|
mode: DayNightModeSchema,
|
|
57496
57415
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
57497
|
-
sensitivity: number().optional(),
|
|
57416
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
57498
57417
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
57499
|
-
switchDelaySec: number().optional(),
|
|
57418
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
57500
57419
|
lastFetchedAt: number()
|
|
57501
57420
|
});
|
|
57502
57421
|
/**
|
|
@@ -57651,11 +57570,11 @@ object({
|
|
|
57651
57570
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
57652
57571
|
availablePrograms: array(string()),
|
|
57653
57572
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
57654
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
57573
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57655
57574
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
57656
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
57575
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
57657
57576
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
57658
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
57577
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57659
57578
|
/** True when the door is reported open; null when the door state is not known. */
|
|
57660
57579
|
doorOpen: boolean().nullable(),
|
|
57661
57580
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -57679,7 +57598,7 @@ object({
|
|
|
57679
57598
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
57680
57599
|
machineCareDue: boolean().nullable(),
|
|
57681
57600
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
57682
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
57601
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
57683
57602
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
57684
57603
|
halfLoad: boolean().nullable(),
|
|
57685
57604
|
hygienePlus: boolean().nullable(),
|
|
@@ -57694,7 +57613,7 @@ object({
|
|
|
57694
57613
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
57695
57614
|
activeEvents: array(string()),
|
|
57696
57615
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
57697
|
-
errorCode: number().nullable(),
|
|
57616
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
57698
57617
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
57699
57618
|
errorLabel: string().nullable(),
|
|
57700
57619
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -57840,24 +57759,14 @@ object({
|
|
|
57840
57759
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
57841
57760
|
lastPressedAt: number().nullable(),
|
|
57842
57761
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
57843
|
-
pressCountSinceStart: number()
|
|
57762
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
57844
57763
|
});
|
|
57845
57764
|
object({
|
|
57846
57765
|
deviceId: number(),
|
|
57847
57766
|
timestamp: number()
|
|
57848
57767
|
});
|
|
57849
57768
|
DeviceType.Button, DeviceType.Camera;
|
|
57850
|
-
|
|
57851
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
57852
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
57853
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
57854
|
-
* The option set is stable across observations; it is persisted in the
|
|
57855
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
57856
|
-
* stored in `sourceInfo`.
|
|
57857
|
-
*/
|
|
57858
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
57859
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
57860
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
57769
|
+
_enum([
|
|
57861
57770
|
"date",
|
|
57862
57771
|
"time",
|
|
57863
57772
|
"datetime"
|
|
@@ -57865,12 +57774,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
57865
57774
|
object({
|
|
57866
57775
|
value: string(),
|
|
57867
57776
|
/**
|
|
57868
|
-
* Set
|
|
57869
|
-
* as
|
|
57870
|
-
*
|
|
57871
|
-
* a time-only sensor → `'time'`.
|
|
57777
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
57778
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
57779
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
57872
57780
|
*/
|
|
57873
|
-
|
|
57781
|
+
timestamp: boolean().optional(),
|
|
57874
57782
|
/** Ms epoch when the slice was last updated. */
|
|
57875
57783
|
lastFetchedAt: number()
|
|
57876
57784
|
});
|
|
@@ -57889,13 +57797,13 @@ var EventFireSchema = object({
|
|
|
57889
57797
|
deviceId: number(),
|
|
57890
57798
|
eventType: string(),
|
|
57891
57799
|
data: record(string(), unknown()).nullable(),
|
|
57892
|
-
timestamp: number(),
|
|
57893
|
-
seq: number()
|
|
57800
|
+
timestamp: number().meta(readingMeta("none")),
|
|
57801
|
+
seq: number().meta(readingMeta("count"))
|
|
57894
57802
|
});
|
|
57895
57803
|
object({
|
|
57896
57804
|
eventTypes: array(string()),
|
|
57897
57805
|
lastEvent: EventFireSchema.nullable(),
|
|
57898
|
-
eventCountSinceStart: number()
|
|
57806
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
57899
57807
|
});
|
|
57900
57808
|
DeviceType.EventEmitter;
|
|
57901
57809
|
var IdentitySchema = object({
|
|
@@ -58284,10 +58192,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
58284
58192
|
object({
|
|
58285
58193
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
58286
58194
|
* speed surface (single-speed fan). */
|
|
58287
|
-
percentage: number().min(0).max(100).nullable(),
|
|
58195
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58288
58196
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
58289
58197
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
58290
|
-
percentageStep: number().positive().optional(),
|
|
58198
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
58291
58199
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
58292
58200
|
* — empty string when no preset is active or supported. */
|
|
58293
58201
|
preset: string(),
|
|
@@ -58369,7 +58277,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
58369
58277
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
58370
58278
|
model: string().nullable(),
|
|
58371
58279
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
58372
|
-
channelCount: number().nullable(),
|
|
58280
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
58373
58281
|
/**
|
|
58374
58282
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
58375
58283
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -58403,7 +58311,7 @@ object({
|
|
|
58403
58311
|
DeviceType.Sensor;
|
|
58404
58312
|
object({
|
|
58405
58313
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
58406
|
-
position: number().min(0).max(100).nullable(),
|
|
58314
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58407
58315
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
58408
58316
|
lastFetchedAt: number()
|
|
58409
58317
|
});
|
|
@@ -58412,9 +58320,9 @@ object({
|
|
|
58412
58320
|
/** Whether the humidifier is currently on. */
|
|
58413
58321
|
on: boolean(),
|
|
58414
58322
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
58415
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
58323
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58416
58324
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
58417
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
58325
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
58418
58326
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
58419
58327
|
* device has no mode surface. */
|
|
58420
58328
|
mode: string().nullable(),
|
|
@@ -58424,9 +58332,9 @@ object({
|
|
|
58424
58332
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
58425
58333
|
action: string().nullable(),
|
|
58426
58334
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
58427
|
-
minHumidity: number().nullable(),
|
|
58335
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58428
58336
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
58429
|
-
maxHumidity: number().nullable(),
|
|
58337
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
58430
58338
|
/** Ms epoch when the slice was last updated. */
|
|
58431
58339
|
lastChangedAt: number()
|
|
58432
58340
|
});
|
|
@@ -58450,22 +58358,13 @@ DeviceType.Humidifier, method(object({
|
|
|
58450
58358
|
auth: "protected"
|
|
58451
58359
|
});
|
|
58452
58360
|
object({
|
|
58453
|
-
/** Current relative humidity, 0..100. */
|
|
58454
|
-
percent: number().min(0).max(100).meta({
|
|
58455
|
-
|
|
58361
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
58362
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
58363
|
+
precision: 0,
|
|
58456
58364
|
label: "Humidity"
|
|
58457
|
-
}),
|
|
58365
|
+
})),
|
|
58458
58366
|
/** Ms epoch when the slice was last updated. */
|
|
58459
|
-
lastFetchedAt: number()
|
|
58460
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
58461
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
58462
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
58463
|
-
unit: string().optional(),
|
|
58464
|
-
/** Suggested decimal places for numeric display.
|
|
58465
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
58466
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
58467
|
-
* auto-formatting when absent. */
|
|
58468
|
-
precision: number().int().min(0).max(10).optional()
|
|
58367
|
+
lastFetchedAt: number()
|
|
58469
58368
|
});
|
|
58470
58369
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
58471
58370
|
object({
|
|
@@ -58473,7 +58372,7 @@ object({
|
|
|
58473
58372
|
* entity exposes no `entity_picture` (yet). */
|
|
58474
58373
|
url: string().nullable(),
|
|
58475
58374
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
58476
|
-
lastUpdated: number().nullable()
|
|
58375
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
58477
58376
|
});
|
|
58478
58377
|
DeviceType.Image;
|
|
58479
58378
|
/**
|
|
@@ -58529,19 +58428,19 @@ var NormalizedRangeSchema = object({
|
|
|
58529
58428
|
});
|
|
58530
58429
|
object({
|
|
58531
58430
|
/** Normalized 0–100. */
|
|
58532
|
-
brightness: number().optional(),
|
|
58431
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
58533
58432
|
/** Normalized 0–100. */
|
|
58534
|
-
contrast: number().optional(),
|
|
58433
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
58535
58434
|
/** Normalized 0–100. */
|
|
58536
|
-
saturation: number().optional(),
|
|
58435
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
58537
58436
|
/** Normalized 0–100. */
|
|
58538
|
-
sharpness: number().optional(),
|
|
58437
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
58539
58438
|
mirror: boolean().optional(),
|
|
58540
58439
|
flip: boolean().optional(),
|
|
58541
58440
|
rotate: ImageRotateSchema.optional(),
|
|
58542
58441
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
58543
58442
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
58544
|
-
warmth: number().optional(),
|
|
58443
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
58545
58444
|
exposureMode: ExposureModeSchema.optional(),
|
|
58546
58445
|
backlightMode: BacklightModeSchema.optional(),
|
|
58547
58446
|
lastFetchedAt: number()
|
|
@@ -58786,10 +58685,10 @@ var IntercomAbilitySchema = object({
|
|
|
58786
58685
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
58787
58686
|
codecs: array(string()),
|
|
58788
58687
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
58789
|
-
sampleRate: number(),
|
|
58688
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
58790
58689
|
duplex: _enum(["half", "full"]),
|
|
58791
58690
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
58792
|
-
maxBacklogMs: number()
|
|
58691
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
58793
58692
|
});
|
|
58794
58693
|
var IntercomStatusSchema = object({
|
|
58795
58694
|
/** True while a talk session is open. */
|
|
@@ -58900,13 +58799,13 @@ object({
|
|
|
58900
58799
|
activity: LawnMowerActivitySchema,
|
|
58901
58800
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
58902
58801
|
* reading. */
|
|
58903
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
58802
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58904
58803
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
58905
58804
|
* task is active / progress is unavailable. */
|
|
58906
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58805
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58907
58806
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
58908
58807
|
* or null when unknown. */
|
|
58909
|
-
currentCode: number().nullable(),
|
|
58808
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
58910
58809
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
58911
58810
|
currentCodeLabel: string().nullable(),
|
|
58912
58811
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -59368,7 +59267,7 @@ object({
|
|
|
59368
59267
|
state: MediaPlayerStateSchema,
|
|
59369
59268
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
59370
59269
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
59371
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
59270
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59372
59271
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
59373
59272
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
59374
59273
|
isMuted: boolean().nullable(),
|
|
@@ -59381,10 +59280,10 @@ object({
|
|
|
59381
59280
|
currentMedia: MediaInfoSchema.nullable(),
|
|
59382
59281
|
/** Current playback position in ms. Null when not seekable or
|
|
59383
59282
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
59384
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
59283
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59385
59284
|
/** Total duration of the current media in ms. Null when unknown
|
|
59386
59285
|
* (live stream) or nothing is playing. */
|
|
59387
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
59286
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
59388
59287
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
59389
59288
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
59390
59289
|
shuffle: boolean().nullable(),
|
|
@@ -59684,7 +59583,7 @@ object({
|
|
|
59684
59583
|
* it, every provider seeded it at boot, and every session left it
|
|
59685
59584
|
* `detected: true` after its detach.
|
|
59686
59585
|
*/
|
|
59687
|
-
autoClearAfterMs: number().nullable()
|
|
59586
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
59688
59587
|
});
|
|
59689
59588
|
/**
|
|
59690
59589
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -59734,7 +59633,7 @@ var MotionZoneRegionSchema = object({
|
|
|
59734
59633
|
});
|
|
59735
59634
|
object({
|
|
59736
59635
|
enabled: boolean(),
|
|
59737
|
-
sensitivity: number(),
|
|
59636
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
59738
59637
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
59739
59638
|
regions: array(MotionZoneRegionSchema),
|
|
59740
59639
|
lastFetchedAt: number()
|
|
@@ -60038,7 +59937,7 @@ var NavigationStatusSchema = object({
|
|
|
60038
59937
|
following: boolean(),
|
|
60039
59938
|
flash: boolean(),
|
|
60040
59939
|
lightMode: NavigationLightModeSchema,
|
|
60041
|
-
lightLevel: number().min(40).max(100),
|
|
59940
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
60042
59941
|
/** Ms epoch when the slice was last updated. */
|
|
60043
59942
|
lastChangedAt: number()
|
|
60044
59943
|
});
|
|
@@ -60084,13 +59983,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
60084
59983
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
60085
59984
|
* SKIP a null rather than coerce it.
|
|
60086
59985
|
*/
|
|
60087
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
59986
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60088
59987
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
60089
|
-
rssiDbm: number().optional(),
|
|
59988
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
60090
59989
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
60091
59990
|
ssid: string().optional(),
|
|
60092
59991
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60093
|
-
lastUpdated: number()
|
|
59992
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
60094
59993
|
});
|
|
60095
59994
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.Light, DeviceType.Lock, DeviceType.Siren, object({
|
|
60096
59995
|
deviceId: number(),
|
|
@@ -60409,7 +60308,7 @@ object({
|
|
|
60409
60308
|
lastError: string().nullable(),
|
|
60410
60309
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
60411
60310
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
60412
|
-
queueDepth: number().int().nonnegative(),
|
|
60311
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
60413
60312
|
/** Per-feature capability matrix — authoritative source for the
|
|
60414
60313
|
* compose-form field gating. */
|
|
60415
60314
|
supports: NotifierSupportsSchema
|
|
@@ -60459,15 +60358,8 @@ DeviceType.Notifier, method(NotifierSendInputSchema, NotifierSendResultSchema, {
|
|
|
60459
60358
|
acceptedAt: number()
|
|
60460
60359
|
});
|
|
60461
60360
|
object({
|
|
60462
|
-
|
|
60463
|
-
|
|
60464
|
-
* Populated live from the upstream source on each state push.
|
|
60465
|
-
* Absent for unitless sensors. */
|
|
60466
|
-
unit: string().optional(),
|
|
60467
|
-
/** Suggested decimal places for numeric display.
|
|
60468
|
-
* Populated live from the upstream source when provided.
|
|
60469
|
-
* Falls back to auto-formatting when absent. */
|
|
60470
|
-
precision: number().int().min(0).max(10).optional(),
|
|
60361
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
60362
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
60471
60363
|
/** Ms epoch when the slice was last updated. */
|
|
60472
60364
|
lastFetchedAt: number()
|
|
60473
60365
|
});
|
|
@@ -60757,23 +60649,26 @@ object({
|
|
|
60757
60649
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
60758
60650
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
60759
60651
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
60760
|
-
foodLevel: number().nullable(),
|
|
60652
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
60761
60653
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
60762
60654
|
* single-hopper models. */
|
|
60763
|
-
food1: number().nullable(),
|
|
60655
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
60764
60656
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
60765
60657
|
* single-hopper models. */
|
|
60766
|
-
food2: number().nullable(),
|
|
60658
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
60767
60659
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
60768
60660
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
60769
60661
|
* below the feeder's low threshold. */
|
|
60770
60662
|
lowFood: boolean(),
|
|
60771
60663
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
60772
60664
|
* device has no battery reading. */
|
|
60773
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
60774
|
-
/**
|
|
60775
|
-
*
|
|
60776
|
-
|
|
60665
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60666
|
+
/**
|
|
60667
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
60668
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
60669
|
+
* model has no desiccant sensor.
|
|
60670
|
+
*/
|
|
60671
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
60777
60672
|
/** True while a feed is in progress. */
|
|
60778
60673
|
feeding: boolean(),
|
|
60779
60674
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -60784,7 +60679,7 @@ object({
|
|
|
60784
60679
|
* with `errorCode` for consumers that want the raw integer. */
|
|
60785
60680
|
error: string().nullable(),
|
|
60786
60681
|
/** Raw device error code (0 / null = no error). */
|
|
60787
|
-
errorCode: number().nullable(),
|
|
60682
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
60788
60683
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
60789
60684
|
isDualHopper: boolean(),
|
|
60790
60685
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -60794,7 +60689,7 @@ object({
|
|
|
60794
60689
|
/** Play a chime when dispensing. */
|
|
60795
60690
|
feedSound: boolean(),
|
|
60796
60691
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
60797
|
-
volume: number(),
|
|
60692
|
+
volume: number().meta(readingMeta("none")),
|
|
60798
60693
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
60799
60694
|
lastFetchedAt: number()
|
|
60800
60695
|
});
|
|
@@ -61231,36 +61126,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61231
61126
|
});
|
|
61232
61127
|
object({
|
|
61233
61128
|
/** Instantaneous power draw in watts. */
|
|
61234
|
-
watts: number().optional().meta({
|
|
61235
|
-
unit: "W",
|
|
61236
|
-
label: "Power"
|
|
61237
|
-
}),
|
|
61129
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
61238
61130
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61239
|
-
kwhTotal: number().optional().meta({
|
|
61240
|
-
unit: "kWh",
|
|
61241
|
-
label: "Energy"
|
|
61242
|
-
}),
|
|
61131
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
61243
61132
|
/** Voltage in volts. */
|
|
61244
|
-
volts: number().optional(),
|
|
61133
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
61245
61134
|
/** Current in amperes. */
|
|
61246
|
-
amps: number().optional(),
|
|
61247
|
-
/** Apparent power in volt-amperes
|
|
61248
|
-
va: number().optional(),
|
|
61135
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
61136
|
+
/** Apparent power in volt-amperes. */
|
|
61137
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
61249
61138
|
/** Power factor (0..1) if reported. */
|
|
61250
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
61139
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
61251
61140
|
/** Ms epoch when the slice was last updated. */
|
|
61252
|
-
lastFetchedAt: number()
|
|
61253
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
61254
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
61255
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
61256
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
61257
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
61258
|
-
unit: string().optional(),
|
|
61259
|
-
/** Suggested decimal places for numeric display.
|
|
61260
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61261
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61262
|
-
* auto-formatting when absent. */
|
|
61263
|
-
precision: number().int().min(0).max(10).optional()
|
|
61141
|
+
lastFetchedAt: number()
|
|
61264
61142
|
});
|
|
61265
61143
|
DeviceType.Sensor;
|
|
61266
61144
|
/**
|
|
@@ -61281,11 +61159,11 @@ DeviceType.Sensor;
|
|
|
61281
61159
|
*/
|
|
61282
61160
|
var GpsLocationSchema = object({
|
|
61283
61161
|
/** Latitude in decimal degrees, -90..90. */
|
|
61284
|
-
latitude: number().min(-90).max(90),
|
|
61162
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
61285
61163
|
/** Longitude in decimal degrees, -180..180. */
|
|
61286
|
-
longitude: number().min(-180).max(180),
|
|
61164
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
61287
61165
|
/** Reported accuracy in meters (lower = better). */
|
|
61288
|
-
accuracyMeters: number().nonnegative()
|
|
61166
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
61289
61167
|
});
|
|
61290
61168
|
object({
|
|
61291
61169
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -61297,25 +61175,16 @@ object({
|
|
|
61297
61175
|
gps: GpsLocationSchema.nullable(),
|
|
61298
61176
|
/** Optional battery level of the tracking device (0..100). Null
|
|
61299
61177
|
* when not reported. */
|
|
61300
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
61178
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61301
61179
|
/** Ms epoch when the slice was last updated. */
|
|
61302
61180
|
lastChangedAt: number()
|
|
61303
61181
|
});
|
|
61304
61182
|
DeviceType.Presence;
|
|
61305
61183
|
object({
|
|
61306
|
-
/** Current pressure in hPa. */
|
|
61307
|
-
hpa: number(),
|
|
61184
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
61185
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
61308
61186
|
/** Ms epoch when the slice was last updated. */
|
|
61309
|
-
lastFetchedAt: number()
|
|
61310
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
61311
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
61312
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
61313
|
-
unit: string().optional(),
|
|
61314
|
-
/** Suggested decimal places for numeric display.
|
|
61315
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
61316
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
61317
|
-
* auto-formatting when absent. */
|
|
61318
|
-
precision: number().int().min(0).max(10).optional()
|
|
61187
|
+
lastFetchedAt: number()
|
|
61319
61188
|
});
|
|
61320
61189
|
DeviceType.Sensor;
|
|
61321
61190
|
/**
|
|
@@ -61648,8 +61517,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
61648
61517
|
}), _void(), { kind: "mutation" });
|
|
61649
61518
|
var PtzAutotrackSettingsSchema = object({
|
|
61650
61519
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
61651
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
61652
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
61520
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
61521
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
61653
61522
|
});
|
|
61654
61523
|
/**
|
|
61655
61524
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -61706,7 +61575,7 @@ object({
|
|
|
61706
61575
|
/** null = unknown — never coerced to false (D393). */
|
|
61707
61576
|
running: boolean().nullable(),
|
|
61708
61577
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61709
|
-
since: number().nullable(),
|
|
61578
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
61710
61579
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61711
61580
|
phase: string().nullable(),
|
|
61712
61581
|
/** null until a reading has been published (D393). */
|
|
@@ -62904,9 +62773,9 @@ var RecordTriggerSchema = _enum([
|
|
|
62904
62773
|
*/
|
|
62905
62774
|
var RecordWindowSchema = object({
|
|
62906
62775
|
trigger: RecordTriggerSchema,
|
|
62907
|
-
day: number().int().min(0).max(6),
|
|
62908
|
-
startMinute: number().int().min(0).max(1439),
|
|
62909
|
-
endMinute: number().int().min(1).max(1440)
|
|
62776
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
62777
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
62778
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
62910
62779
|
});
|
|
62911
62780
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
62912
62781
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -62975,10 +62844,10 @@ object({
|
|
|
62975
62844
|
/** Master "record to the card at all" switch. */
|
|
62976
62845
|
enabled: boolean().nullable(),
|
|
62977
62846
|
overwriteWhenFull: boolean().nullable(),
|
|
62978
|
-
preRecordSec: number().nullable(),
|
|
62979
|
-
postRecordSec: number().nullable(),
|
|
62847
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62848
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
62980
62849
|
/** Length of one recorded file, in minutes. */
|
|
62981
|
-
segmentMinutes: number().nullable(),
|
|
62850
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
62982
62851
|
/** The primary track's weekly windows, flattened. */
|
|
62983
62852
|
windows: array(RecordWindowSchema),
|
|
62984
62853
|
/**
|
|
@@ -62994,7 +62863,7 @@ object({
|
|
|
62994
62863
|
* provider reporting a non-zero count also reports the schedule as not
|
|
62995
62864
|
* writable.
|
|
62996
62865
|
*/
|
|
62997
|
-
unreadableWindows: number(),
|
|
62866
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
62998
62867
|
/**
|
|
62999
62868
|
* The camera is scheduled to record and has NO usable storage.
|
|
63000
62869
|
*
|
|
@@ -63631,7 +63500,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
63631
63500
|
url: string().optional(),
|
|
63632
63501
|
codec: string().optional(),
|
|
63633
63502
|
resolution: CamStreamResolutionSchema.optional(),
|
|
63634
|
-
fps: number().positive().optional(),
|
|
63503
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
63635
63504
|
label: string().optional(),
|
|
63636
63505
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
63637
63506
|
deviceFeatures: array(string()).optional(),
|
|
@@ -63661,18 +63530,18 @@ var StreamProfileSchema = _enum([
|
|
|
63661
63530
|
]);
|
|
63662
63531
|
/** The current encoding config of one stream profile. */
|
|
63663
63532
|
var StreamProfileConfigSchema = object({
|
|
63664
|
-
width: number(),
|
|
63665
|
-
height: number(),
|
|
63533
|
+
width: number().meta(readingMeta("none")),
|
|
63534
|
+
height: number().meta(readingMeta("none")),
|
|
63666
63535
|
codec: _enum(["h264", "h265"]),
|
|
63667
|
-
framerate: number(),
|
|
63668
|
-
bitrate: number(),
|
|
63536
|
+
framerate: number().meta(readingMeta("rate")),
|
|
63537
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
63669
63538
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
63670
63539
|
encoderProfile: _enum([
|
|
63671
63540
|
"high",
|
|
63672
63541
|
"main",
|
|
63673
63542
|
"baseline"
|
|
63674
63543
|
]).optional(),
|
|
63675
|
-
gop: number().optional(),
|
|
63544
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
63676
63545
|
/**
|
|
63677
63546
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
63678
63547
|
*
|
|
@@ -64315,23 +64184,13 @@ object({
|
|
|
64315
64184
|
});
|
|
64316
64185
|
DeviceType.Sensor;
|
|
64317
64186
|
object({
|
|
64318
|
-
/** Current temperature in Celsius. */
|
|
64319
|
-
celsius: number().meta({
|
|
64320
|
-
|
|
64187
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
64188
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
64189
|
+
precision: 1,
|
|
64321
64190
|
label: "Temperature"
|
|
64322
|
-
}),
|
|
64191
|
+
})),
|
|
64323
64192
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64324
|
-
lastFetchedAt: number()
|
|
64325
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
64326
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
64327
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
64328
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
64329
|
-
unit: string().optional(),
|
|
64330
|
-
/** Suggested decimal places for numeric display.
|
|
64331
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
64332
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
64333
|
-
* auto-formatting when absent. */
|
|
64334
|
-
precision: number().int().min(0).max(10).optional()
|
|
64193
|
+
lastFetchedAt: number()
|
|
64335
64194
|
});
|
|
64336
64195
|
DeviceType.Sensor, DeviceType.Thermostat;
|
|
64337
64196
|
/**
|
|
@@ -64583,16 +64442,16 @@ object({
|
|
|
64583
64442
|
]),
|
|
64584
64443
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64585
64444
|
* reading. */
|
|
64586
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
64445
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64587
64446
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
64588
64447
|
* the vacuum has no speed control. */
|
|
64589
64448
|
fanSpeed: string().nullable(),
|
|
64590
64449
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
64591
64450
|
availableFanSpeeds: array(string()),
|
|
64592
64451
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
64593
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
64452
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64594
64453
|
/** Current error code (0 / null = no error). */
|
|
64595
|
-
errorCode: number().nullable(),
|
|
64454
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
64596
64455
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
64597
64456
|
errorLabel: string().nullable(),
|
|
64598
64457
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64631,7 +64490,7 @@ object({
|
|
|
64631
64490
|
]),
|
|
64632
64491
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
64633
64492
|
* intermediate position surface. */
|
|
64634
|
-
position: number().min(0).max(100).nullable(),
|
|
64493
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64635
64494
|
/** Ms epoch when the slice was last updated. */
|
|
64636
64495
|
lastChangedAt: number()
|
|
64637
64496
|
});
|
|
@@ -64659,9 +64518,9 @@ object({
|
|
|
64659
64518
|
DeviceType.Sensor;
|
|
64660
64519
|
object({
|
|
64661
64520
|
/** Current measured temperature. Null when not reported. */
|
|
64662
|
-
currentTemp: number().nullable(),
|
|
64521
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64663
64522
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
64664
|
-
targetTemp: number().nullable(),
|
|
64523
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64665
64524
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
64666
64525
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
64667
64526
|
* device reports an unknown state. */
|
|
@@ -64672,9 +64531,9 @@ object({
|
|
|
64672
64531
|
* has no away surface. */
|
|
64673
64532
|
away: boolean().nullable(),
|
|
64674
64533
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
64675
|
-
minTemp: number().nullable(),
|
|
64534
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64676
64535
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
64677
|
-
maxTemp: number().nullable(),
|
|
64536
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
64678
64537
|
/** Ms epoch when the slice was last updated. */
|
|
64679
64538
|
lastChangedAt: number()
|
|
64680
64539
|
});
|
|
@@ -64698,25 +64557,18 @@ DeviceType.WaterHeater, method(object({
|
|
|
64698
64557
|
auth: "protected"
|
|
64699
64558
|
});
|
|
64700
64559
|
object({
|
|
64701
|
-
/** Verbatim
|
|
64702
|
-
* when no condition has been reported yet. */
|
|
64560
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
64703
64561
|
condition: string().nullable(),
|
|
64704
|
-
/** Current temperature in
|
|
64705
|
-
temperature: number().nullable(),
|
|
64706
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
64707
|
-
temperatureUnit: string().nullable(),
|
|
64562
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
64563
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
64708
64564
|
/** Relative humidity (0..100). Null when not provided. */
|
|
64709
|
-
humidity: number().min(0).max(100).nullable(),
|
|
64710
|
-
/** Barometric pressure in
|
|
64711
|
-
pressure: number().nullable(),
|
|
64712
|
-
/**
|
|
64713
|
-
|
|
64714
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
64715
|
-
windSpeed: number().nullable(),
|
|
64716
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
64717
|
-
windSpeedUnit: string().nullable(),
|
|
64565
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
64566
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
64567
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
64568
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
64569
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
64718
64570
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
64719
|
-
windBearing: number().nullable(),
|
|
64571
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
64720
64572
|
/** Ms epoch when the slice was last updated. */
|
|
64721
64573
|
lastFetchedAt: number()
|
|
64722
64574
|
});
|
|
@@ -78689,7 +78541,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78689
78541
|
field: "value",
|
|
78690
78542
|
quantity: t("the reading", "il valore"),
|
|
78691
78543
|
label: t("Reading", "Valore"),
|
|
78692
|
-
unitField: "unit",
|
|
78693
78544
|
icon: "gauge"
|
|
78694
78545
|
}]
|
|
78695
78546
|
},
|
|
@@ -78825,7 +78676,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78825
78676
|
field: "temperature",
|
|
78826
78677
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
78827
78678
|
label: t("Temperature", "Temperatura"),
|
|
78828
|
-
|
|
78679
|
+
unit: "°C",
|
|
78829
78680
|
icon: "thermometer"
|
|
78830
78681
|
},
|
|
78831
78682
|
{
|
|
@@ -78841,7 +78692,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78841
78692
|
field: "windSpeed",
|
|
78842
78693
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
78843
78694
|
label: t("Wind", "Vento"),
|
|
78844
|
-
|
|
78695
|
+
unit: "m/s",
|
|
78845
78696
|
icon: "wind"
|
|
78846
78697
|
},
|
|
78847
78698
|
{
|
|
@@ -78849,7 +78700,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78849
78700
|
field: "pressure",
|
|
78850
78701
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
78851
78702
|
label: t("Pressure", "Pressione"),
|
|
78852
|
-
|
|
78703
|
+
unit: "hPa",
|
|
78853
78704
|
icon: "gauge"
|
|
78854
78705
|
}
|
|
78855
78706
|
]
|