@camstack/addon-post-analysis 1.2.635 → 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-CySP4L5r.mjs → clip-model-registry-DF_J6DGP.mjs} +319 -495
- package/dist/{clip-model-registry-BHSAAWz-.js → clip-model-registry-GzUKh4GO.js} +319 -495
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Cnd14w_u.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-CD4U2vp3.mjs} +3 -3
- 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/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bcrs7B9G.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-DxMujleG.mjs → hostInit-Bdn1ny7s.mjs} +3 -3
- 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 +7 -2
- 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
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-MOlfkem8.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. */
|
|
@@ -62313,6 +62225,7 @@ var doorbellCustomize = {
|
|
|
62313
62225
|
applyAuthority: { kind: "composition-claim" },
|
|
62314
62226
|
eventName: "onPressed",
|
|
62315
62227
|
edges: ["rising"],
|
|
62228
|
+
defaultEdge: "rising",
|
|
62316
62229
|
timestampPath: "lastPressedAt",
|
|
62317
62230
|
counterPath: "pressCountSinceStart",
|
|
62318
62231
|
highWater: "composer-advance",
|
|
@@ -62331,7 +62244,7 @@ var DoorbellStatusSchema = object({
|
|
|
62331
62244
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
62332
62245
|
lastPressedAt: number().nullable(),
|
|
62333
62246
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
62334
|
-
pressCountSinceStart: number()
|
|
62247
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
62335
62248
|
});
|
|
62336
62249
|
var DoorbellPressEventSchema = object({
|
|
62337
62250
|
deviceId: number(),
|
|
@@ -62396,17 +62309,7 @@ onPressed: {
|
|
|
62396
62309
|
history: "none",
|
|
62397
62310
|
customize: doorbellCustomize
|
|
62398
62311
|
};
|
|
62399
|
-
|
|
62400
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
62401
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
62402
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
62403
|
-
* The option set is stable across observations; it is persisted in the
|
|
62404
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
62405
|
-
* stored in `sourceInfo`.
|
|
62406
|
-
*/
|
|
62407
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
62408
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
62409
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
62312
|
+
_enum([
|
|
62410
62313
|
"date",
|
|
62411
62314
|
"time",
|
|
62412
62315
|
"datetime"
|
|
@@ -62414,12 +62317,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
62414
62317
|
var EnumSensorStatusSchema = object({
|
|
62415
62318
|
value: string(),
|
|
62416
62319
|
/**
|
|
62417
|
-
* Set
|
|
62418
|
-
* as
|
|
62419
|
-
*
|
|
62420
|
-
* 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.
|
|
62421
62323
|
*/
|
|
62422
|
-
|
|
62324
|
+
timestamp: boolean().optional(),
|
|
62423
62325
|
/** Ms epoch when the slice was last updated. */
|
|
62424
62326
|
lastFetchedAt: number()
|
|
62425
62327
|
});
|
|
@@ -62446,11 +62348,11 @@ var enumSensorCapability = {
|
|
|
62446
62348
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
62447
62349
|
* operation state, an HVAC action). The option set is per device, so the
|
|
62448
62350
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
62449
|
-
* `
|
|
62351
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
62450
62352
|
*/
|
|
62451
62353
|
history: { fields: { value: {
|
|
62452
62354
|
kind: "enum",
|
|
62453
|
-
skipWhenSet: "
|
|
62355
|
+
skipWhenSet: "timestamp"
|
|
62454
62356
|
} } },
|
|
62455
62357
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62456
62358
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -62470,13 +62372,13 @@ var EventFireSchema = object({
|
|
|
62470
62372
|
deviceId: number(),
|
|
62471
62373
|
eventType: string(),
|
|
62472
62374
|
data: record(string(), unknown()).nullable(),
|
|
62473
|
-
timestamp: number(),
|
|
62474
|
-
seq: number()
|
|
62375
|
+
timestamp: number().meta(readingMeta("none")),
|
|
62376
|
+
seq: number().meta(readingMeta("count"))
|
|
62475
62377
|
});
|
|
62476
62378
|
var EventEmitterStatusSchema = object({
|
|
62477
62379
|
eventTypes: array(string()),
|
|
62478
62380
|
lastEvent: EventFireSchema.nullable(),
|
|
62479
|
-
eventCountSinceStart: number()
|
|
62381
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
62480
62382
|
});
|
|
62481
62383
|
var eventEmitterCapability = {
|
|
62482
62384
|
name: "event-emitter",
|
|
@@ -62929,10 +62831,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
62929
62831
|
var FanControlStatusSchema = object({
|
|
62930
62832
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
62931
62833
|
* speed surface (single-speed fan). */
|
|
62932
|
-
percentage: number().min(0).max(100).nullable(),
|
|
62834
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62933
62835
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
62934
62836
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
62935
|
-
percentageStep: number().positive().optional(),
|
|
62837
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
62936
62838
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
62937
62839
|
* — empty string when no preset is active or supported. */
|
|
62938
62840
|
preset: string(),
|
|
@@ -63053,7 +62955,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
63053
62955
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
63054
62956
|
model: string().nullable(),
|
|
63055
62957
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
63056
|
-
channelCount: number().nullable(),
|
|
62958
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
63057
62959
|
/**
|
|
63058
62960
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
63059
62961
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -63178,7 +63080,7 @@ var gasCapability = {
|
|
|
63178
63080
|
};
|
|
63179
63081
|
var HeatingValveStatusSchema = object({
|
|
63180
63082
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
63181
|
-
position: number().min(0).max(100).nullable(),
|
|
63083
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63182
63084
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
63183
63085
|
lastFetchedAt: number()
|
|
63184
63086
|
});
|
|
@@ -63221,9 +63123,9 @@ var HumidifierStatusSchema = object({
|
|
|
63221
63123
|
/** Whether the humidifier is currently on. */
|
|
63222
63124
|
on: boolean(),
|
|
63223
63125
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
63224
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
63126
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63225
63127
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
63226
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
63128
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63227
63129
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
63228
63130
|
* device has no mode surface. */
|
|
63229
63131
|
mode: string().nullable(),
|
|
@@ -63233,9 +63135,9 @@ var HumidifierStatusSchema = object({
|
|
|
63233
63135
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
63234
63136
|
action: string().nullable(),
|
|
63235
63137
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
63236
|
-
minHumidity: number().nullable(),
|
|
63138
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
63237
63139
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
63238
|
-
maxHumidity: number().nullable(),
|
|
63140
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
63239
63141
|
/** Ms epoch when the slice was last updated. */
|
|
63240
63142
|
lastChangedAt: number()
|
|
63241
63143
|
});
|
|
@@ -63305,22 +63207,13 @@ var humidifierCapability = {
|
|
|
63305
63207
|
* `sourceInfo`.
|
|
63306
63208
|
*/
|
|
63307
63209
|
var HumiditySensorStatusSchema = object({
|
|
63308
|
-
/** Current relative humidity, 0..100. */
|
|
63309
|
-
percent: number().min(0).max(100).meta({
|
|
63310
|
-
|
|
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,
|
|
63311
63213
|
label: "Humidity"
|
|
63312
|
-
}),
|
|
63214
|
+
})),
|
|
63313
63215
|
/** Ms epoch when the slice was last updated. */
|
|
63314
|
-
lastFetchedAt: number()
|
|
63315
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63316
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63317
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63318
|
-
unit: string().optional(),
|
|
63319
|
-
/** Suggested decimal places for numeric display.
|
|
63320
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63321
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63322
|
-
* auto-formatting when absent. */
|
|
63323
|
-
precision: number().int().min(0).max(10).optional()
|
|
63216
|
+
lastFetchedAt: number()
|
|
63324
63217
|
});
|
|
63325
63218
|
var humiditySensorCapability = {
|
|
63326
63219
|
name: "humidity-sensor",
|
|
@@ -63351,12 +63244,7 @@ var humiditySensorCapability = {
|
|
|
63351
63244
|
} } },
|
|
63352
63245
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63353
63246
|
* whether persisting is worth a SQLite commit. */
|
|
63354
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63355
|
-
customize: {
|
|
63356
|
-
version: 1,
|
|
63357
|
-
advanced: "derive",
|
|
63358
|
-
targets: []
|
|
63359
|
-
}
|
|
63247
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63360
63248
|
};
|
|
63361
63249
|
/**
|
|
63362
63250
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -63377,7 +63265,7 @@ var ImageStatusSchema = object({
|
|
|
63377
63265
|
* entity exposes no `entity_picture` (yet). */
|
|
63378
63266
|
url: string().nullable(),
|
|
63379
63267
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
63380
|
-
lastUpdated: number().nullable()
|
|
63268
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
63381
63269
|
});
|
|
63382
63270
|
var imageCapability = {
|
|
63383
63271
|
name: "image",
|
|
@@ -63465,19 +63353,19 @@ var NormalizedRangeSchema = object({
|
|
|
63465
63353
|
*/
|
|
63466
63354
|
var ImageSettingsStatusSchema = object({
|
|
63467
63355
|
/** Normalized 0–100. */
|
|
63468
|
-
brightness: number().optional(),
|
|
63356
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
63469
63357
|
/** Normalized 0–100. */
|
|
63470
|
-
contrast: number().optional(),
|
|
63358
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
63471
63359
|
/** Normalized 0–100. */
|
|
63472
|
-
saturation: number().optional(),
|
|
63360
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
63473
63361
|
/** Normalized 0–100. */
|
|
63474
|
-
sharpness: number().optional(),
|
|
63362
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
63475
63363
|
mirror: boolean().optional(),
|
|
63476
63364
|
flip: boolean().optional(),
|
|
63477
63365
|
rotate: ImageRotateSchema.optional(),
|
|
63478
63366
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
63479
63367
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
63480
|
-
warmth: number().optional(),
|
|
63368
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
63481
63369
|
exposureMode: ExposureModeSchema.optional(),
|
|
63482
63370
|
backlightMode: BacklightModeSchema.optional(),
|
|
63483
63371
|
lastFetchedAt: number()
|
|
@@ -63756,10 +63644,10 @@ var IntercomAbilitySchema = object({
|
|
|
63756
63644
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
63757
63645
|
codecs: array(string()),
|
|
63758
63646
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
63759
|
-
sampleRate: number(),
|
|
63647
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
63760
63648
|
duplex: _enum(["half", "full"]),
|
|
63761
63649
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
63762
|
-
maxBacklogMs: number()
|
|
63650
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
63763
63651
|
});
|
|
63764
63652
|
var IntercomStatusSchema = object({
|
|
63765
63653
|
/** True while a talk session is open. */
|
|
@@ -63986,13 +63874,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
63986
63874
|
activity: LawnMowerActivitySchema,
|
|
63987
63875
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
63988
63876
|
* reading. */
|
|
63989
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
63877
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63990
63878
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
63991
63879
|
* task is active / progress is unavailable. */
|
|
63992
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
63880
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63993
63881
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
63994
63882
|
* or null when unknown. */
|
|
63995
|
-
currentCode: number().nullable(),
|
|
63883
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
63996
63884
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
63997
63885
|
currentCodeLabel: string().nullable(),
|
|
63998
63886
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -64546,7 +64434,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
64546
64434
|
state: MediaPlayerStateSchema,
|
|
64547
64435
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
64548
64436
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
64549
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
64437
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64550
64438
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
64551
64439
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
64552
64440
|
isMuted: boolean().nullable(),
|
|
@@ -64559,10 +64447,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
64559
64447
|
currentMedia: MediaInfoSchema.nullable(),
|
|
64560
64448
|
/** Current playback position in ms. Null when not seekable or
|
|
64561
64449
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
64562
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
64450
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64563
64451
|
/** Total duration of the current media in ms. Null when unknown
|
|
64564
64452
|
* (live stream) or nothing is playing. */
|
|
64565
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
64453
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64566
64454
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
64567
64455
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
64568
64456
|
shuffle: boolean().nullable(),
|
|
@@ -64871,7 +64759,7 @@ var motionCustomize = {
|
|
|
64871
64759
|
eventName: "onMotionChanged"
|
|
64872
64760
|
},
|
|
64873
64761
|
deviceTypes: [DeviceType.Camera],
|
|
64874
|
-
apply: "
|
|
64762
|
+
apply: "add",
|
|
64875
64763
|
applyAuthority: {
|
|
64876
64764
|
kind: "camera-sensors",
|
|
64877
64765
|
timeoutField: "motionCooldownMs"
|
|
@@ -64968,7 +64856,7 @@ var MotionStatusSchema = object({
|
|
|
64968
64856
|
* it, every provider seeded it at boot, and every session left it
|
|
64969
64857
|
* `detected: true` after its detach.
|
|
64970
64858
|
*/
|
|
64971
|
-
autoClearAfterMs: number().nullable()
|
|
64859
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
64972
64860
|
});
|
|
64973
64861
|
/**
|
|
64974
64862
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -65150,7 +65038,7 @@ var MotionZoneRegionSchema = object({
|
|
|
65150
65038
|
* the grid region(s). */
|
|
65151
65039
|
var MotionZoneStatusSchema = object({
|
|
65152
65040
|
enabled: boolean(),
|
|
65153
|
-
sensitivity: number(),
|
|
65041
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
65154
65042
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
65155
65043
|
regions: array(MotionZoneRegionSchema),
|
|
65156
65044
|
lastFetchedAt: number()
|
|
@@ -65520,7 +65408,7 @@ var NavigationStatusSchema = object({
|
|
|
65520
65408
|
following: boolean(),
|
|
65521
65409
|
flash: boolean(),
|
|
65522
65410
|
lightMode: NavigationLightModeSchema,
|
|
65523
|
-
lightLevel: number().min(40).max(100),
|
|
65411
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
65524
65412
|
/** Ms epoch when the slice was last updated. */
|
|
65525
65413
|
lastChangedAt: number()
|
|
65526
65414
|
});
|
|
@@ -65654,13 +65542,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
65654
65542
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
65655
65543
|
* SKIP a null rather than coerce it.
|
|
65656
65544
|
*/
|
|
65657
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
65545
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65658
65546
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
65659
|
-
rssiDbm: number().optional(),
|
|
65547
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
65660
65548
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
65661
65549
|
ssid: string().optional(),
|
|
65662
65550
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
65663
|
-
lastUpdated: number()
|
|
65551
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
65664
65552
|
});
|
|
65665
65553
|
var networkLinkCapability = {
|
|
65666
65554
|
name: "network-link",
|
|
@@ -66045,7 +65933,7 @@ var NotifierStatusSchema = object({
|
|
|
66045
65933
|
lastError: string().nullable(),
|
|
66046
65934
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
66047
65935
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
66048
|
-
queueDepth: number().int().nonnegative(),
|
|
65936
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
66049
65937
|
/** Per-feature capability matrix — authoritative source for the
|
|
66050
65938
|
* compose-form field gating. */
|
|
66051
65939
|
supports: NotifierSupportsSchema
|
|
@@ -66137,11 +66025,9 @@ onSent: { data: object({
|
|
|
66137
66025
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
66138
66026
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
66139
66027
|
*
|
|
66140
|
-
* The
|
|
66141
|
-
*
|
|
66142
|
-
*
|
|
66143
|
-
* The UI reads them directly from the slice — they are the single source
|
|
66144
|
-
* 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).
|
|
66145
66031
|
*
|
|
66146
66032
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
66147
66033
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -66150,15 +66036,8 @@ onSent: { data: object({
|
|
|
66150
66036
|
* numeric values land here.
|
|
66151
66037
|
*/
|
|
66152
66038
|
var NumericSensorStatusSchema = object({
|
|
66153
|
-
|
|
66154
|
-
|
|
66155
|
-
* Populated live from the upstream source on each state push.
|
|
66156
|
-
* Absent for unitless sensors. */
|
|
66157
|
-
unit: string().optional(),
|
|
66158
|
-
/** Suggested decimal places for numeric display.
|
|
66159
|
-
* Populated live from the upstream source when provided.
|
|
66160
|
-
* Falls back to auto-formatting when absent. */
|
|
66161
|
-
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")),
|
|
66162
66041
|
/** Ms epoch when the slice was last updated. */
|
|
66163
66042
|
lastFetchedAt: number()
|
|
66164
66043
|
});
|
|
@@ -66182,11 +66061,11 @@ var numericSensorCapability = {
|
|
|
66182
66061
|
*/
|
|
66183
66062
|
durability: "restored",
|
|
66184
66063
|
/**
|
|
66185
|
-
* 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.
|
|
66186
66066
|
*/
|
|
66187
66067
|
history: { fields: { value: {
|
|
66188
66068
|
kind: "gauge",
|
|
66189
|
-
unitFrom: "unit",
|
|
66190
66069
|
minIntervalMs: 3e4
|
|
66191
66070
|
} } },
|
|
66192
66071
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -66478,23 +66357,26 @@ var PetFeederStatusSchema = object({
|
|
|
66478
66357
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
66479
66358
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
66480
66359
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
66481
|
-
foodLevel: number().nullable(),
|
|
66360
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
66482
66361
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
66483
66362
|
* single-hopper models. */
|
|
66484
|
-
food1: number().nullable(),
|
|
66363
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
66485
66364
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
66486
66365
|
* single-hopper models. */
|
|
66487
|
-
food2: number().nullable(),
|
|
66366
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
66488
66367
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
66489
66368
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
66490
66369
|
* below the feeder's low threshold. */
|
|
66491
66370
|
lowFood: boolean(),
|
|
66492
66371
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
66493
66372
|
* device has no battery reading. */
|
|
66494
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
66495
|
-
/**
|
|
66496
|
-
*
|
|
66497
|
-
|
|
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")),
|
|
66498
66380
|
/** True while a feed is in progress. */
|
|
66499
66381
|
feeding: boolean(),
|
|
66500
66382
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -66505,7 +66387,7 @@ var PetFeederStatusSchema = object({
|
|
|
66505
66387
|
* with `errorCode` for consumers that want the raw integer. */
|
|
66506
66388
|
error: string().nullable(),
|
|
66507
66389
|
/** Raw device error code (0 / null = no error). */
|
|
66508
|
-
errorCode: number().nullable(),
|
|
66390
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
66509
66391
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
66510
66392
|
isDualHopper: boolean(),
|
|
66511
66393
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -66515,7 +66397,7 @@ var PetFeederStatusSchema = object({
|
|
|
66515
66397
|
/** Play a chime when dispensing. */
|
|
66516
66398
|
feedSound: boolean(),
|
|
66517
66399
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
66518
|
-
volume: number(),
|
|
66400
|
+
volume: number().meta(readingMeta("none")),
|
|
66519
66401
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
66520
66402
|
lastFetchedAt: number()
|
|
66521
66403
|
});
|
|
@@ -66634,7 +66516,7 @@ var petFeederCapability = {
|
|
|
66634
66516
|
},
|
|
66635
66517
|
desiccantLeftDays: {
|
|
66636
66518
|
kind: "gauge",
|
|
66637
|
-
unit: "
|
|
66519
|
+
unit: "s"
|
|
66638
66520
|
}
|
|
66639
66521
|
} }
|
|
66640
66522
|
};
|
|
@@ -67070,36 +66952,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
67070
66952
|
*/
|
|
67071
66953
|
var PowerMeterStatusSchema = object({
|
|
67072
66954
|
/** Instantaneous power draw in watts. */
|
|
67073
|
-
watts: number().optional().meta({
|
|
67074
|
-
unit: "W",
|
|
67075
|
-
label: "Power"
|
|
67076
|
-
}),
|
|
66955
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
67077
66956
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
67078
|
-
kwhTotal: number().optional().meta({
|
|
67079
|
-
unit: "kWh",
|
|
67080
|
-
label: "Energy"
|
|
67081
|
-
}),
|
|
66957
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
67082
66958
|
/** Voltage in volts. */
|
|
67083
|
-
volts: number().optional(),
|
|
66959
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
67084
66960
|
/** Current in amperes. */
|
|
67085
|
-
amps: number().optional(),
|
|
67086
|
-
/** Apparent power in volt-amperes
|
|
67087
|
-
va: number().optional(),
|
|
66961
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
66962
|
+
/** Apparent power in volt-amperes. */
|
|
66963
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
67088
66964
|
/** Power factor (0..1) if reported. */
|
|
67089
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
66965
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
67090
66966
|
/** Ms epoch when the slice was last updated. */
|
|
67091
|
-
lastFetchedAt: number()
|
|
67092
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
67093
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
67094
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
67095
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
67096
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
67097
|
-
unit: string().optional(),
|
|
67098
|
-
/** Suggested decimal places for numeric display.
|
|
67099
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67100
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67101
|
-
* auto-formatting when absent. */
|
|
67102
|
-
precision: number().int().min(0).max(10).optional()
|
|
66967
|
+
lastFetchedAt: number()
|
|
67103
66968
|
});
|
|
67104
66969
|
var powerMeterCapability = {
|
|
67105
66970
|
name: "power-meter",
|
|
@@ -67163,12 +67028,7 @@ var powerMeterCapability = {
|
|
|
67163
67028
|
} },
|
|
67164
67029
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67165
67030
|
* whether persisting is worth a SQLite commit. */
|
|
67166
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67167
|
-
customize: {
|
|
67168
|
-
version: 1,
|
|
67169
|
-
advanced: "derive",
|
|
67170
|
-
targets: []
|
|
67171
|
-
}
|
|
67031
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67172
67032
|
};
|
|
67173
67033
|
/**
|
|
67174
67034
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -67188,11 +67048,11 @@ var powerMeterCapability = {
|
|
|
67188
67048
|
*/
|
|
67189
67049
|
var GpsLocationSchema = object({
|
|
67190
67050
|
/** Latitude in decimal degrees, -90..90. */
|
|
67191
|
-
latitude: number().min(-90).max(90),
|
|
67051
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
67192
67052
|
/** Longitude in decimal degrees, -180..180. */
|
|
67193
|
-
longitude: number().min(-180).max(180),
|
|
67053
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
67194
67054
|
/** Reported accuracy in meters (lower = better). */
|
|
67195
|
-
accuracyMeters: number().nonnegative()
|
|
67055
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
67196
67056
|
});
|
|
67197
67057
|
var PresenceStatusSchema = object({
|
|
67198
67058
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -67204,7 +67064,7 @@ var PresenceStatusSchema = object({
|
|
|
67204
67064
|
gps: GpsLocationSchema.nullable(),
|
|
67205
67065
|
/** Optional battery level of the tracking device (0..100). Null
|
|
67206
67066
|
* when not reported. */
|
|
67207
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
67067
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67208
67068
|
/** Ms epoch when the slice was last updated. */
|
|
67209
67069
|
lastChangedAt: number()
|
|
67210
67070
|
});
|
|
@@ -67254,19 +67114,10 @@ var presenceCapability = {
|
|
|
67254
67114
|
* `sourceInfo`.
|
|
67255
67115
|
*/
|
|
67256
67116
|
var PressureSensorStatusSchema = object({
|
|
67257
|
-
/** Current pressure in hPa. */
|
|
67258
|
-
hpa: number(),
|
|
67117
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
67118
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
67259
67119
|
/** Ms epoch when the slice was last updated. */
|
|
67260
|
-
lastFetchedAt: number()
|
|
67261
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67262
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67263
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
67264
|
-
unit: string().optional(),
|
|
67265
|
-
/** Suggested decimal places for numeric display.
|
|
67266
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67267
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67268
|
-
* auto-formatting when absent. */
|
|
67269
|
-
precision: number().int().min(0).max(10).optional()
|
|
67120
|
+
lastFetchedAt: number()
|
|
67270
67121
|
});
|
|
67271
67122
|
var pressureSensorCapability = {
|
|
67272
67123
|
name: "pressure-sensor",
|
|
@@ -67680,8 +67531,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
67680
67531
|
}), _void(), { kind: "mutation" });
|
|
67681
67532
|
var PtzAutotrackSettingsSchema = object({
|
|
67682
67533
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
67683
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
67684
|
-
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"))
|
|
67685
67536
|
});
|
|
67686
67537
|
/**
|
|
67687
67538
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -67835,7 +67686,7 @@ var RunningStateStatusSchema = object({
|
|
|
67835
67686
|
/** null = unknown — never coerced to false (D393). */
|
|
67836
67687
|
running: boolean().nullable(),
|
|
67837
67688
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
67838
|
-
since: number().nullable(),
|
|
67689
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
67839
67690
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
67840
67691
|
phase: string().nullable(),
|
|
67841
67692
|
/** null until a reading has been published (D393). */
|
|
@@ -67850,7 +67701,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
67850
67701
|
/** Generic Customize target for the running boolean (D936). */
|
|
67851
67702
|
var runningCustomize = {
|
|
67852
67703
|
version: 1,
|
|
67853
|
-
advanced: "derive",
|
|
67854
67704
|
targets: [{
|
|
67855
67705
|
id: "running",
|
|
67856
67706
|
cardinality: "scalar",
|
|
@@ -67870,7 +67720,7 @@ var runningCustomize = {
|
|
|
67870
67720
|
DeviceType.Thermostat,
|
|
67871
67721
|
DeviceType.PetFeeder
|
|
67872
67722
|
],
|
|
67873
|
-
apply: "add
|
|
67723
|
+
apply: "add",
|
|
67874
67724
|
path: "running",
|
|
67875
67725
|
sources: [
|
|
67876
67726
|
{
|
|
@@ -67886,6 +67736,7 @@ var runningCustomize = {
|
|
|
67886
67736
|
requiredUnit: "W",
|
|
67887
67737
|
transforms: [{
|
|
67888
67738
|
kind: "threshold",
|
|
67739
|
+
comparisons: ["gte", "lte"],
|
|
67889
67740
|
comparison: "gte",
|
|
67890
67741
|
defaultThreshold: 5,
|
|
67891
67742
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -69165,9 +69016,9 @@ var RecordTriggerSchema = _enum([
|
|
|
69165
69016
|
*/
|
|
69166
69017
|
var RecordWindowSchema = object({
|
|
69167
69018
|
trigger: RecordTriggerSchema,
|
|
69168
|
-
day: number().int().min(0).max(6),
|
|
69169
|
-
startMinute: number().int().min(0).max(1439),
|
|
69170
|
-
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"))
|
|
69171
69022
|
});
|
|
69172
69023
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
69173
69024
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -69243,10 +69094,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
69243
69094
|
/** Master "record to the card at all" switch. */
|
|
69244
69095
|
enabled: boolean().nullable(),
|
|
69245
69096
|
overwriteWhenFull: boolean().nullable(),
|
|
69246
|
-
preRecordSec: number().nullable(),
|
|
69247
|
-
postRecordSec: number().nullable(),
|
|
69097
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
69098
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
69248
69099
|
/** Length of one recorded file, in minutes. */
|
|
69249
|
-
segmentMinutes: number().nullable(),
|
|
69100
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
69250
69101
|
/** The primary track's weekly windows, flattened. */
|
|
69251
69102
|
windows: array(RecordWindowSchema),
|
|
69252
69103
|
/**
|
|
@@ -69262,7 +69113,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
69262
69113
|
* provider reporting a non-zero count also reports the schedule as not
|
|
69263
69114
|
* writable.
|
|
69264
69115
|
*/
|
|
69265
|
-
unreadableWindows: number(),
|
|
69116
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
69266
69117
|
/**
|
|
69267
69118
|
* The camera is scheduled to record and has NO usable storage.
|
|
69268
69119
|
*
|
|
@@ -70125,7 +69976,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
70125
69976
|
url: string().optional(),
|
|
70126
69977
|
codec: string().optional(),
|
|
70127
69978
|
resolution: CamStreamResolutionSchema.optional(),
|
|
70128
|
-
fps: number().positive().optional(),
|
|
69979
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
70129
69980
|
label: string().optional(),
|
|
70130
69981
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
70131
69982
|
deviceFeatures: array(string()).optional(),
|
|
@@ -70212,18 +70063,18 @@ var StreamProfileSchema = _enum([
|
|
|
70212
70063
|
]);
|
|
70213
70064
|
/** The current encoding config of one stream profile. */
|
|
70214
70065
|
var StreamProfileConfigSchema = object({
|
|
70215
|
-
width: number(),
|
|
70216
|
-
height: number(),
|
|
70066
|
+
width: number().meta(readingMeta("none")),
|
|
70067
|
+
height: number().meta(readingMeta("none")),
|
|
70217
70068
|
codec: _enum(["h264", "h265"]),
|
|
70218
|
-
framerate: number(),
|
|
70219
|
-
bitrate: number(),
|
|
70069
|
+
framerate: number().meta(readingMeta("rate")),
|
|
70070
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
70220
70071
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
70221
70072
|
encoderProfile: _enum([
|
|
70222
70073
|
"high",
|
|
70223
70074
|
"main",
|
|
70224
70075
|
"baseline"
|
|
70225
70076
|
]).optional(),
|
|
70226
|
-
gop: number().optional(),
|
|
70077
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
70227
70078
|
/**
|
|
70228
70079
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
70229
70080
|
*
|
|
@@ -70444,12 +70295,7 @@ var switchCapability = {
|
|
|
70444
70295
|
label: "On",
|
|
70445
70296
|
kind: "boolean"
|
|
70446
70297
|
}
|
|
70447
|
-
}] }
|
|
70448
|
-
customize: {
|
|
70449
|
-
version: 1,
|
|
70450
|
-
advanced: "derive",
|
|
70451
|
-
targets: []
|
|
70452
|
-
}
|
|
70298
|
+
}] }
|
|
70453
70299
|
};
|
|
70454
70300
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
70455
70301
|
function hasControlCharacter(value) {
|
|
@@ -71032,35 +70878,21 @@ var tamperCapability = {
|
|
|
71032
70878
|
* entries with `device_class: temperature` and any future native
|
|
71033
70879
|
* thermometer.
|
|
71034
70880
|
*
|
|
71035
|
-
*
|
|
71036
|
-
*
|
|
71037
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
71038
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
71039
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
71040
|
-
* `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.
|
|
71041
70883
|
*
|
|
71042
70884
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
71043
70885
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
71044
70886
|
* changed" steady state.
|
|
71045
70887
|
*/
|
|
71046
70888
|
var TemperatureSensorStatusSchema = object({
|
|
71047
|
-
/** Current temperature in Celsius. */
|
|
71048
|
-
celsius: number().meta({
|
|
71049
|
-
|
|
70889
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
70890
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
70891
|
+
precision: 1,
|
|
71050
70892
|
label: "Temperature"
|
|
71051
|
-
}),
|
|
70893
|
+
})),
|
|
71052
70894
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
71053
|
-
lastFetchedAt: number()
|
|
71054
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
71055
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
71056
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
71057
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
71058
|
-
unit: string().optional(),
|
|
71059
|
-
/** Suggested decimal places for numeric display.
|
|
71060
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
71061
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
71062
|
-
* auto-formatting when absent. */
|
|
71063
|
-
precision: number().int().min(0).max(10).optional()
|
|
70895
|
+
lastFetchedAt: number()
|
|
71064
70896
|
});
|
|
71065
70897
|
var temperatureSensorCapability = {
|
|
71066
70898
|
name: "temperature-sensor",
|
|
@@ -71091,12 +70923,7 @@ var temperatureSensorCapability = {
|
|
|
71091
70923
|
} } },
|
|
71092
70924
|
/** Clock fields: written, but excluded from the compare that decides
|
|
71093
70925
|
* whether persisting is worth a SQLite commit. */
|
|
71094
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
71095
|
-
customize: {
|
|
71096
|
-
version: 1,
|
|
71097
|
-
advanced: "derive",
|
|
71098
|
-
targets: []
|
|
71099
|
-
}
|
|
70926
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
71100
70927
|
};
|
|
71101
70928
|
/**
|
|
71102
70929
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -71379,16 +71206,16 @@ var VacuumControlStatusSchema = object({
|
|
|
71379
71206
|
]),
|
|
71380
71207
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
71381
71208
|
* reading. */
|
|
71382
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
71209
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71383
71210
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
71384
71211
|
* the vacuum has no speed control. */
|
|
71385
71212
|
fanSpeed: string().nullable(),
|
|
71386
71213
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
71387
71214
|
availableFanSpeeds: array(string()),
|
|
71388
71215
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
71389
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
71216
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71390
71217
|
/** Current error code (0 / null = no error). */
|
|
71391
|
-
errorCode: number().nullable(),
|
|
71218
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
71392
71219
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
71393
71220
|
errorLabel: string().nullable(),
|
|
71394
71221
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -71466,7 +71293,7 @@ var ValveStatusSchema = object({
|
|
|
71466
71293
|
]),
|
|
71467
71294
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
71468
71295
|
* intermediate position surface. */
|
|
71469
|
-
position: number().min(0).max(100).nullable(),
|
|
71296
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71470
71297
|
/** Ms epoch when the slice was last updated. */
|
|
71471
71298
|
lastChangedAt: number()
|
|
71472
71299
|
});
|
|
@@ -71574,9 +71401,9 @@ var vibrationCapability = {
|
|
|
71574
71401
|
*/
|
|
71575
71402
|
var WaterHeaterStatusSchema = object({
|
|
71576
71403
|
/** Current measured temperature. Null when not reported. */
|
|
71577
|
-
currentTemp: number().nullable(),
|
|
71404
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71578
71405
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
71579
|
-
targetTemp: number().nullable(),
|
|
71406
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71580
71407
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
71581
71408
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
71582
71409
|
* device reports an unknown state. */
|
|
@@ -71587,9 +71414,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
71587
71414
|
* has no away surface. */
|
|
71588
71415
|
away: boolean().nullable(),
|
|
71589
71416
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
71590
|
-
minTemp: number().nullable(),
|
|
71417
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71591
71418
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
71592
|
-
maxTemp: number().nullable(),
|
|
71419
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71593
71420
|
/** Ms epoch when the slice was last updated. */
|
|
71594
71421
|
lastChangedAt: number()
|
|
71595
71422
|
});
|
|
@@ -71674,25 +71501,18 @@ var waterHeaterCapability = {
|
|
|
71674
71501
|
* Forecast deferred — current conditions only for v1.
|
|
71675
71502
|
*/
|
|
71676
71503
|
var WeatherStatusSchema = object({
|
|
71677
|
-
/** Verbatim
|
|
71678
|
-
* when no condition has been reported yet. */
|
|
71504
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
71679
71505
|
condition: string().nullable(),
|
|
71680
|
-
/** Current temperature in
|
|
71681
|
-
temperature: number().nullable(),
|
|
71682
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
71683
|
-
temperatureUnit: string().nullable(),
|
|
71506
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
71507
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
71684
71508
|
/** Relative humidity (0..100). Null when not provided. */
|
|
71685
|
-
humidity: number().min(0).max(100).nullable(),
|
|
71686
|
-
/** Barometric pressure in
|
|
71687
|
-
pressure: number().nullable(),
|
|
71688
|
-
/**
|
|
71689
|
-
|
|
71690
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
71691
|
-
windSpeed: number().nullable(),
|
|
71692
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
71693
|
-
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")),
|
|
71694
71514
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
71695
|
-
windBearing: number().nullable(),
|
|
71515
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
71696
71516
|
/** Ms epoch when the slice was last updated. */
|
|
71697
71517
|
lastFetchedAt: number()
|
|
71698
71518
|
});
|
|
@@ -71720,12 +71540,12 @@ var weatherCapability = {
|
|
|
71720
71540
|
*/
|
|
71721
71541
|
durability: "session",
|
|
71722
71542
|
/**
|
|
71723
|
-
* History (D850): recorded series.
|
|
71543
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
71724
71544
|
*/
|
|
71725
71545
|
history: { fields: {
|
|
71726
71546
|
temperature: {
|
|
71727
71547
|
kind: "gauge",
|
|
71728
|
-
|
|
71548
|
+
unit: "°C",
|
|
71729
71549
|
deadband: .2
|
|
71730
71550
|
},
|
|
71731
71551
|
humidity: {
|
|
@@ -71735,12 +71555,12 @@ var weatherCapability = {
|
|
|
71735
71555
|
},
|
|
71736
71556
|
pressure: {
|
|
71737
71557
|
kind: "gauge",
|
|
71738
|
-
|
|
71558
|
+
unit: "hPa",
|
|
71739
71559
|
deadband: .5
|
|
71740
71560
|
},
|
|
71741
71561
|
windSpeed: {
|
|
71742
71562
|
kind: "gauge",
|
|
71743
|
-
|
|
71563
|
+
unit: "m/s",
|
|
71744
71564
|
deadband: .5
|
|
71745
71565
|
}
|
|
71746
71566
|
} }
|
|
@@ -86880,7 +86700,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86880
86700
|
field: "value",
|
|
86881
86701
|
quantity: t("the reading", "il valore"),
|
|
86882
86702
|
label: t("Reading", "Valore"),
|
|
86883
|
-
unitField: "unit",
|
|
86884
86703
|
icon: "gauge"
|
|
86885
86704
|
}]
|
|
86886
86705
|
},
|
|
@@ -87016,7 +86835,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87016
86835
|
field: "temperature",
|
|
87017
86836
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
87018
86837
|
label: t("Temperature", "Temperatura"),
|
|
87019
|
-
|
|
86838
|
+
unit: "°C",
|
|
87020
86839
|
icon: "thermometer"
|
|
87021
86840
|
},
|
|
87022
86841
|
{
|
|
@@ -87032,7 +86851,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87032
86851
|
field: "windSpeed",
|
|
87033
86852
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
87034
86853
|
label: t("Wind", "Vento"),
|
|
87035
|
-
|
|
86854
|
+
unit: "m/s",
|
|
87036
86855
|
icon: "wind"
|
|
87037
86856
|
},
|
|
87038
86857
|
{
|
|
@@ -87040,7 +86859,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87040
86859
|
field: "pressure",
|
|
87041
86860
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
87042
86861
|
label: t("Pressure", "Pressione"),
|
|
87043
|
-
|
|
86862
|
+
unit: "hPa",
|
|
87044
86863
|
icon: "gauge"
|
|
87045
86864
|
}
|
|
87046
86865
|
]
|
|
@@ -90274,6 +90093,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
90274
90093
|
targetId: string().min(1),
|
|
90275
90094
|
enabled: boolean(),
|
|
90276
90095
|
debounceMs: number().nonnegative(),
|
|
90096
|
+
edges: array(_enum([
|
|
90097
|
+
"rising",
|
|
90098
|
+
"button",
|
|
90099
|
+
"native-event"
|
|
90100
|
+
])).min(1).optional(),
|
|
90277
90101
|
sources: array(OverrideSourceSchema).min(1)
|
|
90278
90102
|
});
|
|
90279
90103
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|