@camstack/addon-post-analysis 1.2.636 → 1.2.637
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/{clip-model-registry-BV-RBus_.mjs → clip-model-registry-DF_J6DGP.mjs} +312 -495
- package/dist/{clip-model-registry-DgRbne5j.js → clip-model-registry-GzUKh4GO.js} +312 -495
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Coin4M0B.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-CD4U2vp3.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CLg3GhZM.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-c7viEcQt.mjs → hostInit-Bdn1ny7s.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +1 -1
- package/dist/pipeline-analytics/index.mjs +1 -1
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-j6sD2jfA.mjs +0 -26
|
@@ -5632,7 +5632,7 @@ var ZodIssueCode = {
|
|
|
5632
5632
|
var ZodFirstPartyTypeKind;
|
|
5633
5633
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5634
5634
|
//#endregion
|
|
5635
|
-
//#region ../types/dist/sleep-
|
|
5635
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5636
5636
|
/**
|
|
5637
5637
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5638
5638
|
* window to float samples (D455).
|
|
@@ -8332,6 +8332,52 @@ function defineRecordKinds(specs) {
|
|
|
8332
8332
|
}
|
|
8333
8333
|
return out;
|
|
8334
8334
|
}
|
|
8335
|
+
var READING_QUANTITIES = [
|
|
8336
|
+
"temperature",
|
|
8337
|
+
"pressure",
|
|
8338
|
+
"speed",
|
|
8339
|
+
"precipitation",
|
|
8340
|
+
"precipitation-rate",
|
|
8341
|
+
"length",
|
|
8342
|
+
"area",
|
|
8343
|
+
"illuminance",
|
|
8344
|
+
"irradiance",
|
|
8345
|
+
"power",
|
|
8346
|
+
"energy",
|
|
8347
|
+
"voltage",
|
|
8348
|
+
"current",
|
|
8349
|
+
"apparent-power",
|
|
8350
|
+
"humidity",
|
|
8351
|
+
"percentage",
|
|
8352
|
+
"concentration-volume",
|
|
8353
|
+
"concentration-mass",
|
|
8354
|
+
"concentration-ppb",
|
|
8355
|
+
"volume",
|
|
8356
|
+
"duration",
|
|
8357
|
+
"duration-ms",
|
|
8358
|
+
"information",
|
|
8359
|
+
"sound-level",
|
|
8360
|
+
"signal-level",
|
|
8361
|
+
"colour-temperature",
|
|
8362
|
+
"angle",
|
|
8363
|
+
"bitrate",
|
|
8364
|
+
"rate",
|
|
8365
|
+
"mass",
|
|
8366
|
+
"index",
|
|
8367
|
+
"ratio",
|
|
8368
|
+
"count",
|
|
8369
|
+
"none",
|
|
8370
|
+
"device"
|
|
8371
|
+
];
|
|
8372
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8373
|
+
new Set(READING_QUANTITIES);
|
|
8374
|
+
function readingMeta(quantity, extras) {
|
|
8375
|
+
return {
|
|
8376
|
+
quantity,
|
|
8377
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8378
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8379
|
+
};
|
|
8380
|
+
}
|
|
8335
8381
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8336
8382
|
var CamProfileSchema = _enum([
|
|
8337
8383
|
"high",
|
|
@@ -8359,8 +8405,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8359
8405
|
"derived"
|
|
8360
8406
|
]);
|
|
8361
8407
|
var CamStreamResolutionSchema = object({
|
|
8362
|
-
width: number().int().positive(),
|
|
8363
|
-
height: number().int().positive()
|
|
8408
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8409
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8364
8410
|
});
|
|
8365
8411
|
var CameraStreamSchema = object({
|
|
8366
8412
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -9089,14 +9135,6 @@ Object.freeze({
|
|
|
9089
9135
|
{
|
|
9090
9136
|
"path": "aqi",
|
|
9091
9137
|
"valueType": "number"
|
|
9092
|
-
},
|
|
9093
|
-
{
|
|
9094
|
-
"path": "unit",
|
|
9095
|
-
"valueType": "string"
|
|
9096
|
-
},
|
|
9097
|
-
{
|
|
9098
|
-
"path": "precision",
|
|
9099
|
-
"valueType": "number"
|
|
9100
9138
|
}
|
|
9101
9139
|
],
|
|
9102
9140
|
"alarm-panel": [
|
|
@@ -9132,20 +9170,10 @@ Object.freeze({
|
|
|
9132
9170
|
"valueType": "boolean"
|
|
9133
9171
|
}
|
|
9134
9172
|
],
|
|
9135
|
-
"ambient-light-sensor": [
|
|
9136
|
-
|
|
9137
|
-
|
|
9138
|
-
|
|
9139
|
-
},
|
|
9140
|
-
{
|
|
9141
|
-
"path": "unit",
|
|
9142
|
-
"valueType": "string"
|
|
9143
|
-
},
|
|
9144
|
-
{
|
|
9145
|
-
"path": "precision",
|
|
9146
|
-
"valueType": "number"
|
|
9147
|
-
}
|
|
9148
|
-
],
|
|
9173
|
+
"ambient-light-sensor": [{
|
|
9174
|
+
"path": "lux",
|
|
9175
|
+
"valueType": "number"
|
|
9176
|
+
}],
|
|
9149
9177
|
"audio-metrics": [
|
|
9150
9178
|
{
|
|
9151
9179
|
"path": "ts",
|
|
@@ -9225,6 +9253,10 @@ Object.freeze({
|
|
|
9225
9253
|
"path": "lastUpdated",
|
|
9226
9254
|
"valueType": "number"
|
|
9227
9255
|
},
|
|
9256
|
+
{
|
|
9257
|
+
"path": "volts",
|
|
9258
|
+
"valueType": "number"
|
|
9259
|
+
},
|
|
9228
9260
|
{
|
|
9229
9261
|
"path": "lastContactAt",
|
|
9230
9262
|
"valueType": "number"
|
|
@@ -9467,10 +9499,6 @@ Object.freeze({
|
|
|
9467
9499
|
"datetime"
|
|
9468
9500
|
]
|
|
9469
9501
|
},
|
|
9470
|
-
{
|
|
9471
|
-
"path": "unit",
|
|
9472
|
-
"valueType": "string"
|
|
9473
|
-
},
|
|
9474
9502
|
{
|
|
9475
9503
|
"path": "min",
|
|
9476
9504
|
"valueType": "number"
|
|
@@ -9482,19 +9510,6 @@ Object.freeze({
|
|
|
9482
9510
|
{
|
|
9483
9511
|
"path": "step",
|
|
9484
9512
|
"valueType": "number"
|
|
9485
|
-
},
|
|
9486
|
-
{
|
|
9487
|
-
"path": "precision",
|
|
9488
|
-
"valueType": "number"
|
|
9489
|
-
},
|
|
9490
|
-
{
|
|
9491
|
-
"path": "format",
|
|
9492
|
-
"valueType": "enum",
|
|
9493
|
-
"enumValues": [
|
|
9494
|
-
"date",
|
|
9495
|
-
"time",
|
|
9496
|
-
"datetime"
|
|
9497
|
-
]
|
|
9498
9513
|
}
|
|
9499
9514
|
],
|
|
9500
9515
|
"cover": [
|
|
@@ -9735,13 +9750,8 @@ Object.freeze({
|
|
|
9735
9750
|
"path": "value",
|
|
9736
9751
|
"valueType": "string"
|
|
9737
9752
|
}, {
|
|
9738
|
-
"path": "
|
|
9739
|
-
"valueType": "
|
|
9740
|
-
"enumValues": [
|
|
9741
|
-
"date",
|
|
9742
|
-
"time",
|
|
9743
|
-
"datetime"
|
|
9744
|
-
]
|
|
9753
|
+
"path": "timestamp",
|
|
9754
|
+
"valueType": "boolean"
|
|
9745
9755
|
}],
|
|
9746
9756
|
"event-emitter": [
|
|
9747
9757
|
{
|
|
@@ -9848,20 +9858,10 @@ Object.freeze({
|
|
|
9848
9858
|
"valueType": "number"
|
|
9849
9859
|
}
|
|
9850
9860
|
],
|
|
9851
|
-
"humidity-sensor": [
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
},
|
|
9856
|
-
{
|
|
9857
|
-
"path": "unit",
|
|
9858
|
-
"valueType": "string"
|
|
9859
|
-
},
|
|
9860
|
-
{
|
|
9861
|
-
"path": "precision",
|
|
9862
|
-
"valueType": "number"
|
|
9863
|
-
}
|
|
9864
|
-
],
|
|
9861
|
+
"humidity-sensor": [{
|
|
9862
|
+
"path": "percent",
|
|
9863
|
+
"valueType": "number"
|
|
9864
|
+
}],
|
|
9865
9865
|
"image": [{
|
|
9866
9866
|
"path": "url",
|
|
9867
9867
|
"valueType": "string"
|
|
@@ -10200,20 +10200,10 @@ Object.freeze({
|
|
|
10200
10200
|
"valueType": "boolean"
|
|
10201
10201
|
}
|
|
10202
10202
|
],
|
|
10203
|
-
"numeric-sensor": [
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
},
|
|
10208
|
-
{
|
|
10209
|
-
"path": "unit",
|
|
10210
|
-
"valueType": "string"
|
|
10211
|
-
},
|
|
10212
|
-
{
|
|
10213
|
-
"path": "precision",
|
|
10214
|
-
"valueType": "number"
|
|
10215
|
-
}
|
|
10216
|
-
],
|
|
10203
|
+
"numeric-sensor": [{
|
|
10204
|
+
"path": "value",
|
|
10205
|
+
"valueType": "number"
|
|
10206
|
+
}],
|
|
10217
10207
|
"pet-feeder": [
|
|
10218
10208
|
{
|
|
10219
10209
|
"path": "foodLevel",
|
|
@@ -10305,14 +10295,6 @@ Object.freeze({
|
|
|
10305
10295
|
{
|
|
10306
10296
|
"path": "powerFactor",
|
|
10307
10297
|
"valueType": "number"
|
|
10308
|
-
},
|
|
10309
|
-
{
|
|
10310
|
-
"path": "unit",
|
|
10311
|
-
"valueType": "string"
|
|
10312
|
-
},
|
|
10313
|
-
{
|
|
10314
|
-
"path": "precision",
|
|
10315
|
-
"valueType": "number"
|
|
10316
10298
|
}
|
|
10317
10299
|
],
|
|
10318
10300
|
"presence": [
|
|
@@ -10341,20 +10323,10 @@ Object.freeze({
|
|
|
10341
10323
|
"valueType": "number"
|
|
10342
10324
|
}
|
|
10343
10325
|
],
|
|
10344
|
-
"pressure-sensor": [
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
},
|
|
10349
|
-
{
|
|
10350
|
-
"path": "unit",
|
|
10351
|
-
"valueType": "string"
|
|
10352
|
-
},
|
|
10353
|
-
{
|
|
10354
|
-
"path": "precision",
|
|
10355
|
-
"valueType": "number"
|
|
10356
|
-
}
|
|
10357
|
-
],
|
|
10326
|
+
"pressure-sensor": [{
|
|
10327
|
+
"path": "hpa",
|
|
10328
|
+
"valueType": "number"
|
|
10329
|
+
}],
|
|
10358
10330
|
"privacy-mask": [{
|
|
10359
10331
|
"path": "enabled",
|
|
10360
10332
|
"valueType": "boolean"
|
|
@@ -10665,20 +10637,10 @@ Object.freeze({
|
|
|
10665
10637
|
"path": "tampered",
|
|
10666
10638
|
"valueType": "boolean"
|
|
10667
10639
|
}],
|
|
10668
|
-
"temperature-sensor": [
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
},
|
|
10673
|
-
{
|
|
10674
|
-
"path": "unit",
|
|
10675
|
-
"valueType": "string"
|
|
10676
|
-
},
|
|
10677
|
-
{
|
|
10678
|
-
"path": "precision",
|
|
10679
|
-
"valueType": "number"
|
|
10680
|
-
}
|
|
10681
|
-
],
|
|
10640
|
+
"temperature-sensor": [{
|
|
10641
|
+
"path": "celsius",
|
|
10642
|
+
"valueType": "number"
|
|
10643
|
+
}],
|
|
10682
10644
|
"update": [
|
|
10683
10645
|
{
|
|
10684
10646
|
"path": "currentVersion",
|
|
@@ -10789,10 +10751,6 @@ Object.freeze({
|
|
|
10789
10751
|
"path": "temperature",
|
|
10790
10752
|
"valueType": "number"
|
|
10791
10753
|
},
|
|
10792
|
-
{
|
|
10793
|
-
"path": "temperatureUnit",
|
|
10794
|
-
"valueType": "string"
|
|
10795
|
-
},
|
|
10796
10754
|
{
|
|
10797
10755
|
"path": "humidity",
|
|
10798
10756
|
"valueType": "number"
|
|
@@ -10801,18 +10759,10 @@ Object.freeze({
|
|
|
10801
10759
|
"path": "pressure",
|
|
10802
10760
|
"valueType": "number"
|
|
10803
10761
|
},
|
|
10804
|
-
{
|
|
10805
|
-
"path": "pressureUnit",
|
|
10806
|
-
"valueType": "string"
|
|
10807
|
-
},
|
|
10808
10762
|
{
|
|
10809
10763
|
"path": "windSpeed",
|
|
10810
10764
|
"valueType": "number"
|
|
10811
10765
|
},
|
|
10812
|
-
{
|
|
10813
|
-
"path": "windSpeedUnit",
|
|
10814
|
-
"valueType": "string"
|
|
10815
|
-
},
|
|
10816
10766
|
{
|
|
10817
10767
|
"path": "windBearing",
|
|
10818
10768
|
"valueType": "number"
|
|
@@ -19360,7 +19310,8 @@ var CompositionProblemSchema = object({
|
|
|
19360
19310
|
"item-field-reserved",
|
|
19361
19311
|
"target-missing",
|
|
19362
19312
|
"target-unreadable",
|
|
19363
|
-
"not-replaceable"
|
|
19313
|
+
"not-replaceable",
|
|
19314
|
+
"native-capability-replace"
|
|
19364
19315
|
]),
|
|
19365
19316
|
path: string(),
|
|
19366
19317
|
message: string()
|
|
@@ -19418,9 +19369,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
19418
19369
|
reads: array(CompositionFieldReadSchema)
|
|
19419
19370
|
});
|
|
19420
19371
|
/**
|
|
19421
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
19422
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
19423
|
-
*
|
|
19372
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
19373
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
19374
|
+
* Replacing a capability the device already serves is refused
|
|
19375
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
19376
|
+
* wire for a claim the hub already holds.
|
|
19424
19377
|
*/
|
|
19425
19378
|
var CompositionFeatureModeSchema = _enum([
|
|
19426
19379
|
"new",
|
|
@@ -21313,12 +21266,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
21313
21266
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
21314
21267
|
* in-place so dispatch keeps working.
|
|
21315
21268
|
*
|
|
21316
|
-
* **
|
|
21317
|
-
*
|
|
21318
|
-
*
|
|
21319
|
-
*
|
|
21320
|
-
* (`ha-domain-mapping`)
|
|
21321
|
-
* stored after that point.
|
|
21269
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
21270
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
21271
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
21272
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
21273
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
21274
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
21322
21275
|
*
|
|
21323
21276
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
21324
21277
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -21332,6 +21285,14 @@ var SourceInfoSchema = object({
|
|
|
21332
21285
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
21333
21286
|
* Used to detect rename when `id` changes. */
|
|
21334
21287
|
uniqueId: string().optional(),
|
|
21288
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
21289
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
21290
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
21291
|
+
dateTimeShape: _enum([
|
|
21292
|
+
"date",
|
|
21293
|
+
"time",
|
|
21294
|
+
"datetime"
|
|
21295
|
+
]).optional(),
|
|
21335
21296
|
/** Provider-specific extras that don't fit the structured slots.
|
|
21336
21297
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
21337
21298
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -42359,7 +42320,8 @@ method(object({
|
|
|
42359
42320
|
"enum"
|
|
42360
42321
|
]),
|
|
42361
42322
|
enumValues: array(string()).optional(),
|
|
42362
|
-
item: boolean().optional()
|
|
42323
|
+
item: boolean().optional(),
|
|
42324
|
+
quantity: ReadingQuantitySchema.optional()
|
|
42363
42325
|
})).readonly(),
|
|
42364
42326
|
itemArray: object({
|
|
42365
42327
|
path: string(),
|
|
@@ -46426,8 +46388,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
46426
46388
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
46427
46389
|
var MaskGridShapeSchema = object({
|
|
46428
46390
|
kind: literal("grid"),
|
|
46429
|
-
gridWidth: number(),
|
|
46430
|
-
gridHeight: number(),
|
|
46391
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
46392
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
46431
46393
|
cells: array(boolean())
|
|
46432
46394
|
});
|
|
46433
46395
|
discriminatedUnion("kind", [
|
|
@@ -59753,27 +59715,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
59753
59715
|
*/
|
|
59754
59716
|
var AirQualitySensorStatusSchema = object({
|
|
59755
59717
|
/** Carbon dioxide concentration in ppm. */
|
|
59756
|
-
co2Ppm: number().min(0).optional(),
|
|
59718
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
59757
59719
|
/** Total volatile organic compounds in ppb. */
|
|
59758
|
-
vocPpb: number().min(0).optional(),
|
|
59720
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
59759
59721
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
59760
|
-
pm25: number().min(0).optional(),
|
|
59722
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
59761
59723
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
59762
|
-
pm10: number().min(0).optional(),
|
|
59724
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
59763
59725
|
/** Composite AQI value (typically 0..500). */
|
|
59764
|
-
aqi: number().optional(),
|
|
59726
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
59765
59727
|
/** Ms epoch when the slice was last updated. */
|
|
59766
|
-
lastFetchedAt: number()
|
|
59767
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
59768
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
59769
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
59770
|
-
* per slice is unambiguous. */
|
|
59771
|
-
unit: string().optional(),
|
|
59772
|
-
/** Suggested decimal places for numeric display.
|
|
59773
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59774
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59775
|
-
* auto-formatting when absent. */
|
|
59776
|
-
precision: number().int().min(0).max(10).optional()
|
|
59728
|
+
lastFetchedAt: number()
|
|
59777
59729
|
});
|
|
59778
59730
|
var airQualitySensorCapability = {
|
|
59779
59731
|
name: "air-quality-sensor",
|
|
@@ -59810,12 +59762,12 @@ var airQualitySensorCapability = {
|
|
|
59810
59762
|
},
|
|
59811
59763
|
pm25: {
|
|
59812
59764
|
kind: "gauge",
|
|
59813
|
-
unit: "
|
|
59765
|
+
unit: "µg/m³",
|
|
59814
59766
|
deadband: 1
|
|
59815
59767
|
},
|
|
59816
59768
|
pm10: {
|
|
59817
59769
|
kind: "gauge",
|
|
59818
|
-
unit: "
|
|
59770
|
+
unit: "µg/m³",
|
|
59819
59771
|
deadband: 1
|
|
59820
59772
|
},
|
|
59821
59773
|
aqi: {
|
|
@@ -59833,22 +59785,13 @@ var airQualitySensorCapability = {
|
|
|
59833
59785
|
* entries with `device_class: illuminance`.
|
|
59834
59786
|
*/
|
|
59835
59787
|
var AmbientLightSensorStatusSchema = object({
|
|
59836
|
-
/** Current illuminance in lux (lx). */
|
|
59837
|
-
lux: number().min(0).meta({
|
|
59838
|
-
|
|
59788
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
59789
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
59790
|
+
precision: 0,
|
|
59839
59791
|
label: "Illuminance"
|
|
59840
|
-
}),
|
|
59792
|
+
})),
|
|
59841
59793
|
/** Ms epoch when the slice was last updated. */
|
|
59842
|
-
lastFetchedAt: number()
|
|
59843
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59844
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59845
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59846
|
-
unit: string().optional(),
|
|
59847
|
-
/** Suggested decimal places for numeric display.
|
|
59848
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59849
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59850
|
-
* auto-formatting when absent. */
|
|
59851
|
-
precision: number().int().min(0).max(10).optional()
|
|
59794
|
+
lastFetchedAt: number()
|
|
59852
59795
|
});
|
|
59853
59796
|
var ambientLightSensorCapability = {
|
|
59854
59797
|
name: "ambient-light-sensor",
|
|
@@ -59880,12 +59823,7 @@ var ambientLightSensorCapability = {
|
|
|
59880
59823
|
} } },
|
|
59881
59824
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59882
59825
|
* whether persisting is worth a SQLite commit. */
|
|
59883
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59884
|
-
customize: {
|
|
59885
|
-
version: 1,
|
|
59886
|
-
advanced: "derive",
|
|
59887
|
-
targets: []
|
|
59888
|
-
}
|
|
59826
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59889
59827
|
};
|
|
59890
59828
|
/**
|
|
59891
59829
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -60112,10 +60050,7 @@ var BatteryStatusSchema = object({
|
|
|
60112
60050
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
60113
60051
|
* declines to band a non-finite reading, which is the correct shape.
|
|
60114
60052
|
*/
|
|
60115
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
60116
|
-
unit: "%",
|
|
60117
|
-
label: "Charge"
|
|
60118
|
-
}),
|
|
60053
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
60119
60054
|
/**
|
|
60120
60055
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
60121
60056
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -60142,7 +60077,14 @@ var BatteryStatusSchema = object({
|
|
|
60142
60077
|
*/
|
|
60143
60078
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
60144
60079
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60145
|
-
lastUpdated: number(),
|
|
60080
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
60081
|
+
/**
|
|
60082
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
60083
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
60084
|
+
* that only report charge. A second reading on this cap, not a second
|
|
60085
|
+
* `numeric-sensor` on the same device.
|
|
60086
|
+
*/
|
|
60087
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
60146
60088
|
/**
|
|
60147
60089
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
60148
60090
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -60194,7 +60136,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
60194
60136
|
/** Generic Customize target for the percentage reading (D936). */
|
|
60195
60137
|
var batteryCustomize = {
|
|
60196
60138
|
version: 1,
|
|
60197
|
-
advanced: "derive",
|
|
60198
60139
|
targets: [{
|
|
60199
60140
|
id: "percentage",
|
|
60200
60141
|
cardinality: "scalar",
|
|
@@ -60203,7 +60144,7 @@ var batteryCustomize = {
|
|
|
60203
60144
|
stateField: "percentage"
|
|
60204
60145
|
},
|
|
60205
60146
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
60206
|
-
apply: "add
|
|
60147
|
+
apply: "add",
|
|
60207
60148
|
path: "percentage",
|
|
60208
60149
|
sources: [{
|
|
60209
60150
|
kind: "field",
|
|
@@ -60324,10 +60265,16 @@ onStatusChanged: { data: object({
|
|
|
60324
60265
|
/**
|
|
60325
60266
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
60326
60267
|
*/
|
|
60327
|
-
history: { fields: {
|
|
60328
|
-
|
|
60329
|
-
|
|
60330
|
-
|
|
60268
|
+
history: { fields: {
|
|
60269
|
+
percentage: {
|
|
60270
|
+
kind: "gauge",
|
|
60271
|
+
unit: "%"
|
|
60272
|
+
},
|
|
60273
|
+
volts: {
|
|
60274
|
+
kind: "gauge",
|
|
60275
|
+
unit: "V"
|
|
60276
|
+
}
|
|
60277
|
+
} },
|
|
60331
60278
|
customize: batteryCustomize,
|
|
60332
60279
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60333
60280
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -60374,12 +60321,7 @@ var binaryCapability = {
|
|
|
60374
60321
|
history: { fields: { on: { kind: "boolean" } } },
|
|
60375
60322
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60376
60323
|
* whether persisting is worth a SQLite commit. */
|
|
60377
|
-
volatileStateFields: ["lastChangedAt"]
|
|
60378
|
-
customize: {
|
|
60379
|
-
version: 1,
|
|
60380
|
-
advanced: "derive",
|
|
60381
|
-
targets: []
|
|
60382
|
-
}
|
|
60324
|
+
volatileStateFields: ["lastChangedAt"]
|
|
60383
60325
|
};
|
|
60384
60326
|
/**
|
|
60385
60327
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -60395,7 +60337,7 @@ var binaryCapability = {
|
|
|
60395
60337
|
*/
|
|
60396
60338
|
var BrightnessStatusSchema = object({
|
|
60397
60339
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
60398
|
-
percentage: number().min(0).max(100),
|
|
60340
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
60399
60341
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
60400
60342
|
lastChangedAt: number()
|
|
60401
60343
|
});
|
|
@@ -60876,21 +60818,21 @@ var ClimateControlStatusSchema = object({
|
|
|
60876
60818
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
60877
60819
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
60878
60820
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
60879
|
-
target: number().nullable(),
|
|
60821
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
60880
60822
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
60881
60823
|
* in `heat_cool` mode. */
|
|
60882
|
-
targetHigh: number().nullable(),
|
|
60824
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
60883
60825
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
60884
60826
|
* in `heat_cool` mode. */
|
|
60885
|
-
targetLow: number().nullable(),
|
|
60827
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
60886
60828
|
/** Target relative humidity (0..100). Null when the device has no
|
|
60887
60829
|
* humidity control. */
|
|
60888
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60830
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60889
60831
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
60890
60832
|
* the device's internal sensor. */
|
|
60891
|
-
currentTemp: number().nullable(),
|
|
60833
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
60892
60834
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
60893
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60835
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60894
60836
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
60895
60837
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
60896
60838
|
swingVertical: boolean().nullable(),
|
|
@@ -60898,11 +60840,11 @@ var ClimateControlStatusSchema = object({
|
|
|
60898
60840
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
60899
60841
|
swingHorizontal: boolean().nullable(),
|
|
60900
60842
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
60901
|
-
minTemp: number().nullable().optional(),
|
|
60843
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
60902
60844
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
60903
|
-
maxTemp: number().nullable().optional(),
|
|
60845
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
60904
60846
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
60905
|
-
tempStep: number().positive().nullable().optional(),
|
|
60847
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
60906
60848
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
60907
60849
|
lastFetchedAt: number()
|
|
60908
60850
|
});
|
|
@@ -61044,17 +60986,17 @@ var climateControlCapability = {
|
|
|
61044
60986
|
* modes to expose in the picker without a slice fetch.
|
|
61045
60987
|
*/
|
|
61046
60988
|
var RgbTripletSchema = object({
|
|
61047
|
-
r: number().int().min(0).max(255),
|
|
61048
|
-
g: number().int().min(0).max(255),
|
|
61049
|
-
b: number().int().min(0).max(255)
|
|
60989
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
60990
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
60991
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
61050
60992
|
});
|
|
61051
60993
|
var HsvTripletSchema = object({
|
|
61052
60994
|
/** Hue in degrees, 0..360. */
|
|
61053
|
-
h: number().min(0).max(360),
|
|
60995
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
61054
60996
|
/** Saturation as 0..100 inclusive. */
|
|
61055
|
-
s: number().min(0).max(100),
|
|
60997
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
61056
60998
|
/** Value/brightness as 0..100 inclusive. */
|
|
61057
|
-
v: number().min(0).max(100)
|
|
60999
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
61058
61000
|
});
|
|
61059
61001
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
61060
61002
|
object({
|
|
@@ -61083,7 +61025,7 @@ var ColorStatusSchema = object({
|
|
|
61083
61025
|
/** Populated when `mode === 'hsv'`. */
|
|
61084
61026
|
hsv: HsvTripletSchema.optional(),
|
|
61085
61027
|
/** Populated when `mode === 'mired'`. */
|
|
61086
|
-
mireds: number().int().optional(),
|
|
61028
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
61087
61029
|
/** Ms epoch of the last operator-driven change. */
|
|
61088
61030
|
lastChangedAt: number()
|
|
61089
61031
|
});
|
|
@@ -61292,18 +61234,12 @@ var FORM_OF_KIND = {
|
|
|
61292
61234
|
function consumableFormOf(item) {
|
|
61293
61235
|
return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
|
|
61294
61236
|
}
|
|
61295
|
-
/**
|
|
61296
|
-
|
|
61297
|
-
|
|
61298
|
-
"days",
|
|
61299
|
-
"hours",
|
|
61300
|
-
"cycles"
|
|
61301
|
-
]);
|
|
61302
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
61303
|
-
* days). `value` null = unknown (D393). */
|
|
61237
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
61238
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
61239
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
61304
61240
|
var ConsumableRemainingSchema = object({
|
|
61305
|
-
value: number().min(0).nullable(),
|
|
61306
|
-
|
|
61241
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
61242
|
+
kind: ConsumableRemainingKindSchema
|
|
61307
61243
|
});
|
|
61308
61244
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
61309
61245
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -61316,7 +61252,7 @@ var ConsumableItemSchema = object({
|
|
|
61316
61252
|
/** Display name. */
|
|
61317
61253
|
label: string().min(1),
|
|
61318
61254
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
61319
|
-
level: number().min(0).max(100).nullable(),
|
|
61255
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61320
61256
|
/** The provider's discrete verdict when known (binary mode). */
|
|
61321
61257
|
status: ConsumableStatusSchema.nullable(),
|
|
61322
61258
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -61398,8 +61334,8 @@ var consumablesCustomize = {
|
|
|
61398
61334
|
transforms: [{ kind: "identity" }]
|
|
61399
61335
|
}],
|
|
61400
61336
|
literals: [{
|
|
61401
|
-
path: "remaining.
|
|
61402
|
-
values: [...
|
|
61337
|
+
path: "remaining.kind",
|
|
61338
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
61403
61339
|
}]
|
|
61404
61340
|
},
|
|
61405
61341
|
{
|
|
@@ -61528,7 +61464,6 @@ reset: method(object({
|
|
|
61528
61464
|
},
|
|
61529
61465
|
"remaining.value": {
|
|
61530
61466
|
kind: "gauge",
|
|
61531
|
-
unitFrom: "remaining.unit",
|
|
61532
61467
|
deadband: 1,
|
|
61533
61468
|
displayName: "Remaining"
|
|
61534
61469
|
}
|
|
@@ -61598,10 +61533,9 @@ var contactCapability = {
|
|
|
61598
61533
|
* (empty array for the other kinds). It lives in the slice because
|
|
61599
61534
|
* HA `select.*` entities may update their options at runtime.
|
|
61600
61535
|
*
|
|
61601
|
-
*
|
|
61602
|
-
*
|
|
61603
|
-
*
|
|
61604
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
61536
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
61537
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
61538
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
61605
61539
|
*/
|
|
61606
61540
|
var ControlStatusSchema = object({
|
|
61607
61541
|
kind: _enum([
|
|
@@ -61613,39 +61547,17 @@ var ControlStatusSchema = object({
|
|
|
61613
61547
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
61614
61548
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
61615
61549
|
* or time-only — HA accepts all three forms). */
|
|
61616
|
-
value: union([number(), string()]),
|
|
61550
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
61617
61551
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
61618
61552
|
options: array(string()),
|
|
61619
61553
|
/** Ms epoch when the slice was last updated. */
|
|
61620
61554
|
lastChangedAt: number(),
|
|
61621
|
-
/**
|
|
61622
|
-
|
|
61623
|
-
|
|
61624
|
-
|
|
61625
|
-
/**
|
|
61626
|
-
|
|
61627
|
-
min: number().optional(),
|
|
61628
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
61629
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
61630
|
-
max: number().optional(),
|
|
61631
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
61632
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
61633
|
-
step: number().optional(),
|
|
61634
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
61635
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
61636
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
61637
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
61638
|
-
precision: number().int().min(0).max(10).optional(),
|
|
61639
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
61640
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
61641
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
61642
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
61643
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
61644
|
-
format: _enum([
|
|
61645
|
-
"date",
|
|
61646
|
-
"time",
|
|
61647
|
-
"datetime"
|
|
61648
|
-
]).optional()
|
|
61555
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
61556
|
+
min: number().optional().meta(readingMeta("device")),
|
|
61557
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
61558
|
+
max: number().optional().meta(readingMeta("device")),
|
|
61559
|
+
/** Step increment, in the device quantity's base unit. */
|
|
61560
|
+
step: number().optional().meta(readingMeta("device"))
|
|
61649
61561
|
});
|
|
61650
61562
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
61651
61563
|
object({
|
|
@@ -61733,9 +61645,9 @@ var CoverStatusSchema = object({
|
|
|
61733
61645
|
state: CoverStateSchema,
|
|
61734
61646
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
61735
61647
|
* no intermediate position surface. */
|
|
61736
|
-
position: number().min(0).max(100).nullable(),
|
|
61648
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61737
61649
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
61738
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
61650
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61739
61651
|
/** Ms epoch when the slice was last updated. */
|
|
61740
61652
|
lastChangedAt: number()
|
|
61741
61653
|
});
|
|
@@ -61838,9 +61750,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
61838
61750
|
var DayNightStatusSchema = object({
|
|
61839
61751
|
mode: DayNightModeSchema,
|
|
61840
61752
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
61841
|
-
sensitivity: number().optional(),
|
|
61753
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
61842
61754
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
61843
|
-
switchDelaySec: number().optional(),
|
|
61755
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
61844
61756
|
lastFetchedAt: number()
|
|
61845
61757
|
});
|
|
61846
61758
|
/**
|
|
@@ -62058,11 +61970,11 @@ var DishwasherStatusSchema = object({
|
|
|
62058
61970
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
62059
61971
|
availablePrograms: array(string()),
|
|
62060
61972
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
62061
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
61973
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
62062
61974
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
62063
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
61975
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
62064
61976
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
62065
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
61977
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62066
61978
|
/** True when the door is reported open; null when the door state is not known. */
|
|
62067
61979
|
doorOpen: boolean().nullable(),
|
|
62068
61980
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -62086,7 +61998,7 @@ var DishwasherStatusSchema = object({
|
|
|
62086
61998
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
62087
61999
|
machineCareDue: boolean().nullable(),
|
|
62088
62000
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
62089
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
62001
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
62090
62002
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
62091
62003
|
halfLoad: boolean().nullable(),
|
|
62092
62004
|
hygienePlus: boolean().nullable(),
|
|
@@ -62101,7 +62013,7 @@ var DishwasherStatusSchema = object({
|
|
|
62101
62013
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
62102
62014
|
activeEvents: array(string()),
|
|
62103
62015
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
62104
|
-
errorCode: number().nullable(),
|
|
62016
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
62105
62017
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
62106
62018
|
errorLabel: string().nullable(),
|
|
62107
62019
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -62332,7 +62244,7 @@ var DoorbellStatusSchema = object({
|
|
|
62332
62244
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
62333
62245
|
lastPressedAt: number().nullable(),
|
|
62334
62246
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
62335
|
-
pressCountSinceStart: number()
|
|
62247
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
62336
62248
|
});
|
|
62337
62249
|
var DoorbellPressEventSchema = object({
|
|
62338
62250
|
deviceId: number(),
|
|
@@ -62397,17 +62309,7 @@ onPressed: {
|
|
|
62397
62309
|
history: "none",
|
|
62398
62310
|
customize: doorbellCustomize
|
|
62399
62311
|
};
|
|
62400
|
-
|
|
62401
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
62402
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
62403
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
62404
|
-
* The option set is stable across observations; it is persisted in the
|
|
62405
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
62406
|
-
* stored in `sourceInfo`.
|
|
62407
|
-
*/
|
|
62408
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
62409
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
62410
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
62312
|
+
_enum([
|
|
62411
62313
|
"date",
|
|
62412
62314
|
"time",
|
|
62413
62315
|
"datetime"
|
|
@@ -62415,12 +62317,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
62415
62317
|
var EnumSensorStatusSchema = object({
|
|
62416
62318
|
value: string(),
|
|
62417
62319
|
/**
|
|
62418
|
-
* Set
|
|
62419
|
-
* as
|
|
62420
|
-
*
|
|
62421
|
-
* a time-only sensor → `'time'`.
|
|
62320
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
62321
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
62322
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
62422
62323
|
*/
|
|
62423
|
-
|
|
62324
|
+
timestamp: boolean().optional(),
|
|
62424
62325
|
/** Ms epoch when the slice was last updated. */
|
|
62425
62326
|
lastFetchedAt: number()
|
|
62426
62327
|
});
|
|
@@ -62447,11 +62348,11 @@ var enumSensorCapability = {
|
|
|
62447
62348
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
62448
62349
|
* operation state, an HVAC action). The option set is per device, so the
|
|
62449
62350
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
62450
|
-
* `
|
|
62351
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
62451
62352
|
*/
|
|
62452
62353
|
history: { fields: { value: {
|
|
62453
62354
|
kind: "enum",
|
|
62454
|
-
skipWhenSet: "
|
|
62355
|
+
skipWhenSet: "timestamp"
|
|
62455
62356
|
} } },
|
|
62456
62357
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62457
62358
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -62471,13 +62372,13 @@ var EventFireSchema = object({
|
|
|
62471
62372
|
deviceId: number(),
|
|
62472
62373
|
eventType: string(),
|
|
62473
62374
|
data: record(string(), unknown()).nullable(),
|
|
62474
|
-
timestamp: number(),
|
|
62475
|
-
seq: number()
|
|
62375
|
+
timestamp: number().meta(readingMeta("none")),
|
|
62376
|
+
seq: number().meta(readingMeta("count"))
|
|
62476
62377
|
});
|
|
62477
62378
|
var EventEmitterStatusSchema = object({
|
|
62478
62379
|
eventTypes: array(string()),
|
|
62479
62380
|
lastEvent: EventFireSchema.nullable(),
|
|
62480
|
-
eventCountSinceStart: number()
|
|
62381
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
62481
62382
|
});
|
|
62482
62383
|
var eventEmitterCapability = {
|
|
62483
62384
|
name: "event-emitter",
|
|
@@ -62930,10 +62831,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
62930
62831
|
var FanControlStatusSchema = object({
|
|
62931
62832
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
62932
62833
|
* speed surface (single-speed fan). */
|
|
62933
|
-
percentage: number().min(0).max(100).nullable(),
|
|
62834
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62934
62835
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
62935
62836
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
62936
|
-
percentageStep: number().positive().optional(),
|
|
62837
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
62937
62838
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
62938
62839
|
* — empty string when no preset is active or supported. */
|
|
62939
62840
|
preset: string(),
|
|
@@ -63054,7 +62955,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
63054
62955
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
63055
62956
|
model: string().nullable(),
|
|
63056
62957
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
63057
|
-
channelCount: number().nullable(),
|
|
62958
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
63058
62959
|
/**
|
|
63059
62960
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
63060
62961
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -63179,7 +63080,7 @@ var gasCapability = {
|
|
|
63179
63080
|
};
|
|
63180
63081
|
var HeatingValveStatusSchema = object({
|
|
63181
63082
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
63182
|
-
position: number().min(0).max(100).nullable(),
|
|
63083
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63183
63084
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
63184
63085
|
lastFetchedAt: number()
|
|
63185
63086
|
});
|
|
@@ -63222,9 +63123,9 @@ var HumidifierStatusSchema = object({
|
|
|
63222
63123
|
/** Whether the humidifier is currently on. */
|
|
63223
63124
|
on: boolean(),
|
|
63224
63125
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
63225
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
63126
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63226
63127
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
63227
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
63128
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63228
63129
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
63229
63130
|
* device has no mode surface. */
|
|
63230
63131
|
mode: string().nullable(),
|
|
@@ -63234,9 +63135,9 @@ var HumidifierStatusSchema = object({
|
|
|
63234
63135
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
63235
63136
|
action: string().nullable(),
|
|
63236
63137
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
63237
|
-
minHumidity: number().nullable(),
|
|
63138
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
63238
63139
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
63239
|
-
maxHumidity: number().nullable(),
|
|
63140
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
63240
63141
|
/** Ms epoch when the slice was last updated. */
|
|
63241
63142
|
lastChangedAt: number()
|
|
63242
63143
|
});
|
|
@@ -63306,22 +63207,13 @@ var humidifierCapability = {
|
|
|
63306
63207
|
* `sourceInfo`.
|
|
63307
63208
|
*/
|
|
63308
63209
|
var HumiditySensorStatusSchema = object({
|
|
63309
|
-
/** Current relative humidity, 0..100. */
|
|
63310
|
-
percent: number().min(0).max(100).meta({
|
|
63311
|
-
|
|
63210
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
63211
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
63212
|
+
precision: 0,
|
|
63312
63213
|
label: "Humidity"
|
|
63313
|
-
}),
|
|
63214
|
+
})),
|
|
63314
63215
|
/** Ms epoch when the slice was last updated. */
|
|
63315
|
-
lastFetchedAt: number()
|
|
63316
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63317
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63318
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63319
|
-
unit: string().optional(),
|
|
63320
|
-
/** Suggested decimal places for numeric display.
|
|
63321
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63322
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63323
|
-
* auto-formatting when absent. */
|
|
63324
|
-
precision: number().int().min(0).max(10).optional()
|
|
63216
|
+
lastFetchedAt: number()
|
|
63325
63217
|
});
|
|
63326
63218
|
var humiditySensorCapability = {
|
|
63327
63219
|
name: "humidity-sensor",
|
|
@@ -63352,12 +63244,7 @@ var humiditySensorCapability = {
|
|
|
63352
63244
|
} } },
|
|
63353
63245
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63354
63246
|
* whether persisting is worth a SQLite commit. */
|
|
63355
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63356
|
-
customize: {
|
|
63357
|
-
version: 1,
|
|
63358
|
-
advanced: "derive",
|
|
63359
|
-
targets: []
|
|
63360
|
-
}
|
|
63247
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63361
63248
|
};
|
|
63362
63249
|
/**
|
|
63363
63250
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -63378,7 +63265,7 @@ var ImageStatusSchema = object({
|
|
|
63378
63265
|
* entity exposes no `entity_picture` (yet). */
|
|
63379
63266
|
url: string().nullable(),
|
|
63380
63267
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
63381
|
-
lastUpdated: number().nullable()
|
|
63268
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
63382
63269
|
});
|
|
63383
63270
|
var imageCapability = {
|
|
63384
63271
|
name: "image",
|
|
@@ -63466,19 +63353,19 @@ var NormalizedRangeSchema = object({
|
|
|
63466
63353
|
*/
|
|
63467
63354
|
var ImageSettingsStatusSchema = object({
|
|
63468
63355
|
/** Normalized 0–100. */
|
|
63469
|
-
brightness: number().optional(),
|
|
63356
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
63470
63357
|
/** Normalized 0–100. */
|
|
63471
|
-
contrast: number().optional(),
|
|
63358
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
63472
63359
|
/** Normalized 0–100. */
|
|
63473
|
-
saturation: number().optional(),
|
|
63360
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
63474
63361
|
/** Normalized 0–100. */
|
|
63475
|
-
sharpness: number().optional(),
|
|
63362
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
63476
63363
|
mirror: boolean().optional(),
|
|
63477
63364
|
flip: boolean().optional(),
|
|
63478
63365
|
rotate: ImageRotateSchema.optional(),
|
|
63479
63366
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
63480
63367
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
63481
|
-
warmth: number().optional(),
|
|
63368
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
63482
63369
|
exposureMode: ExposureModeSchema.optional(),
|
|
63483
63370
|
backlightMode: BacklightModeSchema.optional(),
|
|
63484
63371
|
lastFetchedAt: number()
|
|
@@ -63757,10 +63644,10 @@ var IntercomAbilitySchema = object({
|
|
|
63757
63644
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
63758
63645
|
codecs: array(string()),
|
|
63759
63646
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
63760
|
-
sampleRate: number(),
|
|
63647
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
63761
63648
|
duplex: _enum(["half", "full"]),
|
|
63762
63649
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
63763
|
-
maxBacklogMs: number()
|
|
63650
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
63764
63651
|
});
|
|
63765
63652
|
var IntercomStatusSchema = object({
|
|
63766
63653
|
/** True while a talk session is open. */
|
|
@@ -63987,13 +63874,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
63987
63874
|
activity: LawnMowerActivitySchema,
|
|
63988
63875
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
63989
63876
|
* reading. */
|
|
63990
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
63877
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63991
63878
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
63992
63879
|
* task is active / progress is unavailable. */
|
|
63993
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
63880
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63994
63881
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
63995
63882
|
* or null when unknown. */
|
|
63996
|
-
currentCode: number().nullable(),
|
|
63883
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
63997
63884
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
63998
63885
|
currentCodeLabel: string().nullable(),
|
|
63999
63886
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -64547,7 +64434,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
64547
64434
|
state: MediaPlayerStateSchema,
|
|
64548
64435
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
64549
64436
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
64550
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
64437
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64551
64438
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
64552
64439
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
64553
64440
|
isMuted: boolean().nullable(),
|
|
@@ -64560,10 +64447,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
64560
64447
|
currentMedia: MediaInfoSchema.nullable(),
|
|
64561
64448
|
/** Current playback position in ms. Null when not seekable or
|
|
64562
64449
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
64563
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
64450
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64564
64451
|
/** Total duration of the current media in ms. Null when unknown
|
|
64565
64452
|
* (live stream) or nothing is playing. */
|
|
64566
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
64453
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64567
64454
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
64568
64455
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
64569
64456
|
shuffle: boolean().nullable(),
|
|
@@ -64872,7 +64759,7 @@ var motionCustomize = {
|
|
|
64872
64759
|
eventName: "onMotionChanged"
|
|
64873
64760
|
},
|
|
64874
64761
|
deviceTypes: [DeviceType.Camera],
|
|
64875
|
-
apply: "
|
|
64762
|
+
apply: "add",
|
|
64876
64763
|
applyAuthority: {
|
|
64877
64764
|
kind: "camera-sensors",
|
|
64878
64765
|
timeoutField: "motionCooldownMs"
|
|
@@ -64969,7 +64856,7 @@ var MotionStatusSchema = object({
|
|
|
64969
64856
|
* it, every provider seeded it at boot, and every session left it
|
|
64970
64857
|
* `detected: true` after its detach.
|
|
64971
64858
|
*/
|
|
64972
|
-
autoClearAfterMs: number().nullable()
|
|
64859
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
64973
64860
|
});
|
|
64974
64861
|
/**
|
|
64975
64862
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -65151,7 +65038,7 @@ var MotionZoneRegionSchema = object({
|
|
|
65151
65038
|
* the grid region(s). */
|
|
65152
65039
|
var MotionZoneStatusSchema = object({
|
|
65153
65040
|
enabled: boolean(),
|
|
65154
|
-
sensitivity: number(),
|
|
65041
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
65155
65042
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
65156
65043
|
regions: array(MotionZoneRegionSchema),
|
|
65157
65044
|
lastFetchedAt: number()
|
|
@@ -65521,7 +65408,7 @@ var NavigationStatusSchema = object({
|
|
|
65521
65408
|
following: boolean(),
|
|
65522
65409
|
flash: boolean(),
|
|
65523
65410
|
lightMode: NavigationLightModeSchema,
|
|
65524
|
-
lightLevel: number().min(40).max(100),
|
|
65411
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
65525
65412
|
/** Ms epoch when the slice was last updated. */
|
|
65526
65413
|
lastChangedAt: number()
|
|
65527
65414
|
});
|
|
@@ -65655,13 +65542,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
65655
65542
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
65656
65543
|
* SKIP a null rather than coerce it.
|
|
65657
65544
|
*/
|
|
65658
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
65545
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65659
65546
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
65660
|
-
rssiDbm: number().optional(),
|
|
65547
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
65661
65548
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
65662
65549
|
ssid: string().optional(),
|
|
65663
65550
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
65664
|
-
lastUpdated: number()
|
|
65551
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
65665
65552
|
});
|
|
65666
65553
|
var networkLinkCapability = {
|
|
65667
65554
|
name: "network-link",
|
|
@@ -66046,7 +65933,7 @@ var NotifierStatusSchema = object({
|
|
|
66046
65933
|
lastError: string().nullable(),
|
|
66047
65934
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
66048
65935
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
66049
|
-
queueDepth: number().int().nonnegative(),
|
|
65936
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
66050
65937
|
/** Per-feature capability matrix — authoritative source for the
|
|
66051
65938
|
* compose-form field gating. */
|
|
66052
65939
|
supports: NotifierSupportsSchema
|
|
@@ -66138,11 +66025,9 @@ onSent: { data: object({
|
|
|
66138
66025
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
66139
66026
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
66140
66027
|
*
|
|
66141
|
-
* The
|
|
66142
|
-
*
|
|
66143
|
-
*
|
|
66144
|
-
* The UI reads them directly from the slice — they are the single source
|
|
66145
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
66028
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
66029
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
66030
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
66146
66031
|
*
|
|
66147
66032
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
66148
66033
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -66151,15 +66036,8 @@ onSent: { data: object({
|
|
|
66151
66036
|
* numeric values land here.
|
|
66152
66037
|
*/
|
|
66153
66038
|
var NumericSensorStatusSchema = object({
|
|
66154
|
-
|
|
66155
|
-
|
|
66156
|
-
* Populated live from the upstream source on each state push.
|
|
66157
|
-
* Absent for unitless sensors. */
|
|
66158
|
-
unit: string().optional(),
|
|
66159
|
-
/** Suggested decimal places for numeric display.
|
|
66160
|
-
* Populated live from the upstream source when provided.
|
|
66161
|
-
* Falls back to auto-formatting when absent. */
|
|
66162
|
-
precision: number().int().min(0).max(10).optional(),
|
|
66039
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
66040
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
66163
66041
|
/** Ms epoch when the slice was last updated. */
|
|
66164
66042
|
lastFetchedAt: number()
|
|
66165
66043
|
});
|
|
@@ -66183,11 +66061,11 @@ var numericSensorCapability = {
|
|
|
66183
66061
|
*/
|
|
66184
66062
|
durability: "restored",
|
|
66185
66063
|
/**
|
|
66186
|
-
* History (D850): recorded series. The unit is
|
|
66064
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
66065
|
+
* resolved when the series is read — the cap has no single unit.
|
|
66187
66066
|
*/
|
|
66188
66067
|
history: { fields: { value: {
|
|
66189
66068
|
kind: "gauge",
|
|
66190
|
-
unitFrom: "unit",
|
|
66191
66069
|
minIntervalMs: 3e4
|
|
66192
66070
|
} } },
|
|
66193
66071
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -66479,23 +66357,26 @@ var PetFeederStatusSchema = object({
|
|
|
66479
66357
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
66480
66358
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
66481
66359
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
66482
|
-
foodLevel: number().nullable(),
|
|
66360
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
66483
66361
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
66484
66362
|
* single-hopper models. */
|
|
66485
|
-
food1: number().nullable(),
|
|
66363
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
66486
66364
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
66487
66365
|
* single-hopper models. */
|
|
66488
|
-
food2: number().nullable(),
|
|
66366
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
66489
66367
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
66490
66368
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
66491
66369
|
* below the feeder's low threshold. */
|
|
66492
66370
|
lowFood: boolean(),
|
|
66493
66371
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
66494
66372
|
* device has no battery reading. */
|
|
66495
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
66496
|
-
/**
|
|
66497
|
-
*
|
|
66498
|
-
|
|
66373
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
66374
|
+
/**
|
|
66375
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
66376
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
66377
|
+
* model has no desiccant sensor.
|
|
66378
|
+
*/
|
|
66379
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
66499
66380
|
/** True while a feed is in progress. */
|
|
66500
66381
|
feeding: boolean(),
|
|
66501
66382
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -66506,7 +66387,7 @@ var PetFeederStatusSchema = object({
|
|
|
66506
66387
|
* with `errorCode` for consumers that want the raw integer. */
|
|
66507
66388
|
error: string().nullable(),
|
|
66508
66389
|
/** Raw device error code (0 / null = no error). */
|
|
66509
|
-
errorCode: number().nullable(),
|
|
66390
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
66510
66391
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
66511
66392
|
isDualHopper: boolean(),
|
|
66512
66393
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -66516,7 +66397,7 @@ var PetFeederStatusSchema = object({
|
|
|
66516
66397
|
/** Play a chime when dispensing. */
|
|
66517
66398
|
feedSound: boolean(),
|
|
66518
66399
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
66519
|
-
volume: number(),
|
|
66400
|
+
volume: number().meta(readingMeta("none")),
|
|
66520
66401
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
66521
66402
|
lastFetchedAt: number()
|
|
66522
66403
|
});
|
|
@@ -66635,7 +66516,7 @@ var petFeederCapability = {
|
|
|
66635
66516
|
},
|
|
66636
66517
|
desiccantLeftDays: {
|
|
66637
66518
|
kind: "gauge",
|
|
66638
|
-
unit: "
|
|
66519
|
+
unit: "s"
|
|
66639
66520
|
}
|
|
66640
66521
|
} }
|
|
66641
66522
|
};
|
|
@@ -67071,36 +66952,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
67071
66952
|
*/
|
|
67072
66953
|
var PowerMeterStatusSchema = object({
|
|
67073
66954
|
/** Instantaneous power draw in watts. */
|
|
67074
|
-
watts: number().optional().meta({
|
|
67075
|
-
unit: "W",
|
|
67076
|
-
label: "Power"
|
|
67077
|
-
}),
|
|
66955
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
67078
66956
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
67079
|
-
kwhTotal: number().optional().meta({
|
|
67080
|
-
unit: "kWh",
|
|
67081
|
-
label: "Energy"
|
|
67082
|
-
}),
|
|
66957
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
67083
66958
|
/** Voltage in volts. */
|
|
67084
|
-
volts: number().optional(),
|
|
66959
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
67085
66960
|
/** Current in amperes. */
|
|
67086
|
-
amps: number().optional(),
|
|
67087
|
-
/** Apparent power in volt-amperes
|
|
67088
|
-
va: number().optional(),
|
|
66961
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
66962
|
+
/** Apparent power in volt-amperes. */
|
|
66963
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
67089
66964
|
/** Power factor (0..1) if reported. */
|
|
67090
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
66965
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
67091
66966
|
/** Ms epoch when the slice was last updated. */
|
|
67092
|
-
lastFetchedAt: number()
|
|
67093
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
67094
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
67095
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
67096
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
67097
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
67098
|
-
unit: string().optional(),
|
|
67099
|
-
/** Suggested decimal places for numeric display.
|
|
67100
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67101
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67102
|
-
* auto-formatting when absent. */
|
|
67103
|
-
precision: number().int().min(0).max(10).optional()
|
|
66967
|
+
lastFetchedAt: number()
|
|
67104
66968
|
});
|
|
67105
66969
|
var powerMeterCapability = {
|
|
67106
66970
|
name: "power-meter",
|
|
@@ -67164,12 +67028,7 @@ var powerMeterCapability = {
|
|
|
67164
67028
|
} },
|
|
67165
67029
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67166
67030
|
* whether persisting is worth a SQLite commit. */
|
|
67167
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67168
|
-
customize: {
|
|
67169
|
-
version: 1,
|
|
67170
|
-
advanced: "derive",
|
|
67171
|
-
targets: []
|
|
67172
|
-
}
|
|
67031
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67173
67032
|
};
|
|
67174
67033
|
/**
|
|
67175
67034
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -67189,11 +67048,11 @@ var powerMeterCapability = {
|
|
|
67189
67048
|
*/
|
|
67190
67049
|
var GpsLocationSchema = object({
|
|
67191
67050
|
/** Latitude in decimal degrees, -90..90. */
|
|
67192
|
-
latitude: number().min(-90).max(90),
|
|
67051
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
67193
67052
|
/** Longitude in decimal degrees, -180..180. */
|
|
67194
|
-
longitude: number().min(-180).max(180),
|
|
67053
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
67195
67054
|
/** Reported accuracy in meters (lower = better). */
|
|
67196
|
-
accuracyMeters: number().nonnegative()
|
|
67055
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
67197
67056
|
});
|
|
67198
67057
|
var PresenceStatusSchema = object({
|
|
67199
67058
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -67205,7 +67064,7 @@ var PresenceStatusSchema = object({
|
|
|
67205
67064
|
gps: GpsLocationSchema.nullable(),
|
|
67206
67065
|
/** Optional battery level of the tracking device (0..100). Null
|
|
67207
67066
|
* when not reported. */
|
|
67208
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
67067
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67209
67068
|
/** Ms epoch when the slice was last updated. */
|
|
67210
67069
|
lastChangedAt: number()
|
|
67211
67070
|
});
|
|
@@ -67255,19 +67114,10 @@ var presenceCapability = {
|
|
|
67255
67114
|
* `sourceInfo`.
|
|
67256
67115
|
*/
|
|
67257
67116
|
var PressureSensorStatusSchema = object({
|
|
67258
|
-
/** Current pressure in hPa. */
|
|
67259
|
-
hpa: number(),
|
|
67117
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
67118
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
67260
67119
|
/** Ms epoch when the slice was last updated. */
|
|
67261
|
-
lastFetchedAt: number()
|
|
67262
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67263
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67264
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
67265
|
-
unit: string().optional(),
|
|
67266
|
-
/** Suggested decimal places for numeric display.
|
|
67267
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67268
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67269
|
-
* auto-formatting when absent. */
|
|
67270
|
-
precision: number().int().min(0).max(10).optional()
|
|
67120
|
+
lastFetchedAt: number()
|
|
67271
67121
|
});
|
|
67272
67122
|
var pressureSensorCapability = {
|
|
67273
67123
|
name: "pressure-sensor",
|
|
@@ -67681,8 +67531,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
67681
67531
|
}), _void(), { kind: "mutation" });
|
|
67682
67532
|
var PtzAutotrackSettingsSchema = object({
|
|
67683
67533
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
67684
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
67685
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
67534
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
67535
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
67686
67536
|
});
|
|
67687
67537
|
/**
|
|
67688
67538
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -67836,7 +67686,7 @@ var RunningStateStatusSchema = object({
|
|
|
67836
67686
|
/** null = unknown — never coerced to false (D393). */
|
|
67837
67687
|
running: boolean().nullable(),
|
|
67838
67688
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
67839
|
-
since: number().nullable(),
|
|
67689
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
67840
67690
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
67841
67691
|
phase: string().nullable(),
|
|
67842
67692
|
/** null until a reading has been published (D393). */
|
|
@@ -67851,7 +67701,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
67851
67701
|
/** Generic Customize target for the running boolean (D936). */
|
|
67852
67702
|
var runningCustomize = {
|
|
67853
67703
|
version: 1,
|
|
67854
|
-
advanced: "derive",
|
|
67855
67704
|
targets: [{
|
|
67856
67705
|
id: "running",
|
|
67857
67706
|
cardinality: "scalar",
|
|
@@ -67871,7 +67720,7 @@ var runningCustomize = {
|
|
|
67871
67720
|
DeviceType.Thermostat,
|
|
67872
67721
|
DeviceType.PetFeeder
|
|
67873
67722
|
],
|
|
67874
|
-
apply: "add
|
|
67723
|
+
apply: "add",
|
|
67875
67724
|
path: "running",
|
|
67876
67725
|
sources: [
|
|
67877
67726
|
{
|
|
@@ -69167,9 +69016,9 @@ var RecordTriggerSchema = _enum([
|
|
|
69167
69016
|
*/
|
|
69168
69017
|
var RecordWindowSchema = object({
|
|
69169
69018
|
trigger: RecordTriggerSchema,
|
|
69170
|
-
day: number().int().min(0).max(6),
|
|
69171
|
-
startMinute: number().int().min(0).max(1439),
|
|
69172
|
-
endMinute: number().int().min(1).max(1440)
|
|
69019
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
69020
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
69021
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
69173
69022
|
});
|
|
69174
69023
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
69175
69024
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -69245,10 +69094,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
69245
69094
|
/** Master "record to the card at all" switch. */
|
|
69246
69095
|
enabled: boolean().nullable(),
|
|
69247
69096
|
overwriteWhenFull: boolean().nullable(),
|
|
69248
|
-
preRecordSec: number().nullable(),
|
|
69249
|
-
postRecordSec: number().nullable(),
|
|
69097
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
69098
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
69250
69099
|
/** Length of one recorded file, in minutes. */
|
|
69251
|
-
segmentMinutes: number().nullable(),
|
|
69100
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
69252
69101
|
/** The primary track's weekly windows, flattened. */
|
|
69253
69102
|
windows: array(RecordWindowSchema),
|
|
69254
69103
|
/**
|
|
@@ -69264,7 +69113,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
69264
69113
|
* provider reporting a non-zero count also reports the schedule as not
|
|
69265
69114
|
* writable.
|
|
69266
69115
|
*/
|
|
69267
|
-
unreadableWindows: number(),
|
|
69116
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
69268
69117
|
/**
|
|
69269
69118
|
* The camera is scheduled to record and has NO usable storage.
|
|
69270
69119
|
*
|
|
@@ -70127,7 +69976,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
70127
69976
|
url: string().optional(),
|
|
70128
69977
|
codec: string().optional(),
|
|
70129
69978
|
resolution: CamStreamResolutionSchema.optional(),
|
|
70130
|
-
fps: number().positive().optional(),
|
|
69979
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
70131
69980
|
label: string().optional(),
|
|
70132
69981
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
70133
69982
|
deviceFeatures: array(string()).optional(),
|
|
@@ -70214,18 +70063,18 @@ var StreamProfileSchema = _enum([
|
|
|
70214
70063
|
]);
|
|
70215
70064
|
/** The current encoding config of one stream profile. */
|
|
70216
70065
|
var StreamProfileConfigSchema = object({
|
|
70217
|
-
width: number(),
|
|
70218
|
-
height: number(),
|
|
70066
|
+
width: number().meta(readingMeta("none")),
|
|
70067
|
+
height: number().meta(readingMeta("none")),
|
|
70219
70068
|
codec: _enum(["h264", "h265"]),
|
|
70220
|
-
framerate: number(),
|
|
70221
|
-
bitrate: number(),
|
|
70069
|
+
framerate: number().meta(readingMeta("rate")),
|
|
70070
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
70222
70071
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
70223
70072
|
encoderProfile: _enum([
|
|
70224
70073
|
"high",
|
|
70225
70074
|
"main",
|
|
70226
70075
|
"baseline"
|
|
70227
70076
|
]).optional(),
|
|
70228
|
-
gop: number().optional(),
|
|
70077
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
70229
70078
|
/**
|
|
70230
70079
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
70231
70080
|
*
|
|
@@ -70446,12 +70295,7 @@ var switchCapability = {
|
|
|
70446
70295
|
label: "On",
|
|
70447
70296
|
kind: "boolean"
|
|
70448
70297
|
}
|
|
70449
|
-
}] }
|
|
70450
|
-
customize: {
|
|
70451
|
-
version: 1,
|
|
70452
|
-
advanced: "derive",
|
|
70453
|
-
targets: []
|
|
70454
|
-
}
|
|
70298
|
+
}] }
|
|
70455
70299
|
};
|
|
70456
70300
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
70457
70301
|
function hasControlCharacter(value) {
|
|
@@ -71034,35 +70878,21 @@ var tamperCapability = {
|
|
|
71034
70878
|
* entries with `device_class: temperature` and any future native
|
|
71035
70879
|
* thermometer.
|
|
71036
70880
|
*
|
|
71037
|
-
*
|
|
71038
|
-
*
|
|
71039
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
71040
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
71041
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
71042
|
-
* `sourceInfo`.
|
|
70881
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
70882
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
71043
70883
|
*
|
|
71044
70884
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
71045
70885
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
71046
70886
|
* changed" steady state.
|
|
71047
70887
|
*/
|
|
71048
70888
|
var TemperatureSensorStatusSchema = object({
|
|
71049
|
-
/** Current temperature in Celsius. */
|
|
71050
|
-
celsius: number().meta({
|
|
71051
|
-
|
|
70889
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
70890
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
70891
|
+
precision: 1,
|
|
71052
70892
|
label: "Temperature"
|
|
71053
|
-
}),
|
|
70893
|
+
})),
|
|
71054
70894
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
71055
|
-
lastFetchedAt: number()
|
|
71056
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
71057
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
71058
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
71059
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
71060
|
-
unit: string().optional(),
|
|
71061
|
-
/** Suggested decimal places for numeric display.
|
|
71062
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
71063
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
71064
|
-
* auto-formatting when absent. */
|
|
71065
|
-
precision: number().int().min(0).max(10).optional()
|
|
70895
|
+
lastFetchedAt: number()
|
|
71066
70896
|
});
|
|
71067
70897
|
var temperatureSensorCapability = {
|
|
71068
70898
|
name: "temperature-sensor",
|
|
@@ -71093,12 +70923,7 @@ var temperatureSensorCapability = {
|
|
|
71093
70923
|
} } },
|
|
71094
70924
|
/** Clock fields: written, but excluded from the compare that decides
|
|
71095
70925
|
* whether persisting is worth a SQLite commit. */
|
|
71096
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
71097
|
-
customize: {
|
|
71098
|
-
version: 1,
|
|
71099
|
-
advanced: "derive",
|
|
71100
|
-
targets: []
|
|
71101
|
-
}
|
|
70926
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
71102
70927
|
};
|
|
71103
70928
|
/**
|
|
71104
70929
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -71381,16 +71206,16 @@ var VacuumControlStatusSchema = object({
|
|
|
71381
71206
|
]),
|
|
71382
71207
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
71383
71208
|
* reading. */
|
|
71384
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
71209
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71385
71210
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
71386
71211
|
* the vacuum has no speed control. */
|
|
71387
71212
|
fanSpeed: string().nullable(),
|
|
71388
71213
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
71389
71214
|
availableFanSpeeds: array(string()),
|
|
71390
71215
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
71391
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
71216
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71392
71217
|
/** Current error code (0 / null = no error). */
|
|
71393
|
-
errorCode: number().nullable(),
|
|
71218
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
71394
71219
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
71395
71220
|
errorLabel: string().nullable(),
|
|
71396
71221
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -71468,7 +71293,7 @@ var ValveStatusSchema = object({
|
|
|
71468
71293
|
]),
|
|
71469
71294
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
71470
71295
|
* intermediate position surface. */
|
|
71471
|
-
position: number().min(0).max(100).nullable(),
|
|
71296
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71472
71297
|
/** Ms epoch when the slice was last updated. */
|
|
71473
71298
|
lastChangedAt: number()
|
|
71474
71299
|
});
|
|
@@ -71576,9 +71401,9 @@ var vibrationCapability = {
|
|
|
71576
71401
|
*/
|
|
71577
71402
|
var WaterHeaterStatusSchema = object({
|
|
71578
71403
|
/** Current measured temperature. Null when not reported. */
|
|
71579
|
-
currentTemp: number().nullable(),
|
|
71404
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71580
71405
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
71581
|
-
targetTemp: number().nullable(),
|
|
71406
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71582
71407
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
71583
71408
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
71584
71409
|
* device reports an unknown state. */
|
|
@@ -71589,9 +71414,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
71589
71414
|
* has no away surface. */
|
|
71590
71415
|
away: boolean().nullable(),
|
|
71591
71416
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
71592
|
-
minTemp: number().nullable(),
|
|
71417
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71593
71418
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
71594
|
-
maxTemp: number().nullable(),
|
|
71419
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71595
71420
|
/** Ms epoch when the slice was last updated. */
|
|
71596
71421
|
lastChangedAt: number()
|
|
71597
71422
|
});
|
|
@@ -71676,25 +71501,18 @@ var waterHeaterCapability = {
|
|
|
71676
71501
|
* Forecast deferred — current conditions only for v1.
|
|
71677
71502
|
*/
|
|
71678
71503
|
var WeatherStatusSchema = object({
|
|
71679
|
-
/** Verbatim
|
|
71680
|
-
* when no condition has been reported yet. */
|
|
71504
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
71681
71505
|
condition: string().nullable(),
|
|
71682
|
-
/** Current temperature in
|
|
71683
|
-
temperature: number().nullable(),
|
|
71684
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
71685
|
-
temperatureUnit: string().nullable(),
|
|
71506
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
71507
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
71686
71508
|
/** Relative humidity (0..100). Null when not provided. */
|
|
71687
|
-
humidity: number().min(0).max(100).nullable(),
|
|
71688
|
-
/** Barometric pressure in
|
|
71689
|
-
pressure: number().nullable(),
|
|
71690
|
-
/**
|
|
71691
|
-
|
|
71692
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
71693
|
-
windSpeed: number().nullable(),
|
|
71694
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
71695
|
-
windSpeedUnit: string().nullable(),
|
|
71509
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
71510
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
71511
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
71512
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
71513
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
71696
71514
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
71697
|
-
windBearing: number().nullable(),
|
|
71515
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
71698
71516
|
/** Ms epoch when the slice was last updated. */
|
|
71699
71517
|
lastFetchedAt: number()
|
|
71700
71518
|
});
|
|
@@ -71722,12 +71540,12 @@ var weatherCapability = {
|
|
|
71722
71540
|
*/
|
|
71723
71541
|
durability: "session",
|
|
71724
71542
|
/**
|
|
71725
|
-
* History (D850): recorded series.
|
|
71543
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
71726
71544
|
*/
|
|
71727
71545
|
history: { fields: {
|
|
71728
71546
|
temperature: {
|
|
71729
71547
|
kind: "gauge",
|
|
71730
|
-
|
|
71548
|
+
unit: "°C",
|
|
71731
71549
|
deadband: .2
|
|
71732
71550
|
},
|
|
71733
71551
|
humidity: {
|
|
@@ -71737,12 +71555,12 @@ var weatherCapability = {
|
|
|
71737
71555
|
},
|
|
71738
71556
|
pressure: {
|
|
71739
71557
|
kind: "gauge",
|
|
71740
|
-
|
|
71558
|
+
unit: "hPa",
|
|
71741
71559
|
deadband: .5
|
|
71742
71560
|
},
|
|
71743
71561
|
windSpeed: {
|
|
71744
71562
|
kind: "gauge",
|
|
71745
|
-
|
|
71563
|
+
unit: "m/s",
|
|
71746
71564
|
deadband: .5
|
|
71747
71565
|
}
|
|
71748
71566
|
} }
|
|
@@ -86882,7 +86700,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86882
86700
|
field: "value",
|
|
86883
86701
|
quantity: t("the reading", "il valore"),
|
|
86884
86702
|
label: t("Reading", "Valore"),
|
|
86885
|
-
unitField: "unit",
|
|
86886
86703
|
icon: "gauge"
|
|
86887
86704
|
}]
|
|
86888
86705
|
},
|
|
@@ -87018,7 +86835,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87018
86835
|
field: "temperature",
|
|
87019
86836
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
87020
86837
|
label: t("Temperature", "Temperatura"),
|
|
87021
|
-
|
|
86838
|
+
unit: "°C",
|
|
87022
86839
|
icon: "thermometer"
|
|
87023
86840
|
},
|
|
87024
86841
|
{
|
|
@@ -87034,7 +86851,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87034
86851
|
field: "windSpeed",
|
|
87035
86852
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
87036
86853
|
label: t("Wind", "Vento"),
|
|
87037
|
-
|
|
86854
|
+
unit: "m/s",
|
|
87038
86855
|
icon: "wind"
|
|
87039
86856
|
},
|
|
87040
86857
|
{
|
|
@@ -87042,7 +86859,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87042
86859
|
field: "pressure",
|
|
87043
86860
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
87044
86861
|
label: t("Pressure", "Pressione"),
|
|
87045
|
-
|
|
86862
|
+
unit: "hPa",
|
|
87046
86863
|
icon: "gauge"
|
|
87047
86864
|
}
|
|
87048
86865
|
]
|