@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
|
@@ -5663,7 +5663,7 @@ var ZodIssueCode = {
|
|
|
5663
5663
|
var ZodFirstPartyTypeKind;
|
|
5664
5664
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5665
5665
|
//#endregion
|
|
5666
|
-
//#region ../types/dist/sleep-
|
|
5666
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5667
5667
|
/**
|
|
5668
5668
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5669
5669
|
* window to float samples (D455).
|
|
@@ -8363,6 +8363,52 @@ function defineRecordKinds(specs) {
|
|
|
8363
8363
|
}
|
|
8364
8364
|
return out;
|
|
8365
8365
|
}
|
|
8366
|
+
var READING_QUANTITIES = [
|
|
8367
|
+
"temperature",
|
|
8368
|
+
"pressure",
|
|
8369
|
+
"speed",
|
|
8370
|
+
"precipitation",
|
|
8371
|
+
"precipitation-rate",
|
|
8372
|
+
"length",
|
|
8373
|
+
"area",
|
|
8374
|
+
"illuminance",
|
|
8375
|
+
"irradiance",
|
|
8376
|
+
"power",
|
|
8377
|
+
"energy",
|
|
8378
|
+
"voltage",
|
|
8379
|
+
"current",
|
|
8380
|
+
"apparent-power",
|
|
8381
|
+
"humidity",
|
|
8382
|
+
"percentage",
|
|
8383
|
+
"concentration-volume",
|
|
8384
|
+
"concentration-mass",
|
|
8385
|
+
"concentration-ppb",
|
|
8386
|
+
"volume",
|
|
8387
|
+
"duration",
|
|
8388
|
+
"duration-ms",
|
|
8389
|
+
"information",
|
|
8390
|
+
"sound-level",
|
|
8391
|
+
"signal-level",
|
|
8392
|
+
"colour-temperature",
|
|
8393
|
+
"angle",
|
|
8394
|
+
"bitrate",
|
|
8395
|
+
"rate",
|
|
8396
|
+
"mass",
|
|
8397
|
+
"index",
|
|
8398
|
+
"ratio",
|
|
8399
|
+
"count",
|
|
8400
|
+
"none",
|
|
8401
|
+
"device"
|
|
8402
|
+
];
|
|
8403
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8404
|
+
new Set(READING_QUANTITIES);
|
|
8405
|
+
function readingMeta(quantity, extras) {
|
|
8406
|
+
return {
|
|
8407
|
+
quantity,
|
|
8408
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8409
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8410
|
+
};
|
|
8411
|
+
}
|
|
8366
8412
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8367
8413
|
var CamProfileSchema = _enum([
|
|
8368
8414
|
"high",
|
|
@@ -8390,8 +8436,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8390
8436
|
"derived"
|
|
8391
8437
|
]);
|
|
8392
8438
|
var CamStreamResolutionSchema = object({
|
|
8393
|
-
width: number().int().positive(),
|
|
8394
|
-
height: number().int().positive()
|
|
8439
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8440
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8395
8441
|
});
|
|
8396
8442
|
var CameraStreamSchema = object({
|
|
8397
8443
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -9120,14 +9166,6 @@ Object.freeze({
|
|
|
9120
9166
|
{
|
|
9121
9167
|
"path": "aqi",
|
|
9122
9168
|
"valueType": "number"
|
|
9123
|
-
},
|
|
9124
|
-
{
|
|
9125
|
-
"path": "unit",
|
|
9126
|
-
"valueType": "string"
|
|
9127
|
-
},
|
|
9128
|
-
{
|
|
9129
|
-
"path": "precision",
|
|
9130
|
-
"valueType": "number"
|
|
9131
9169
|
}
|
|
9132
9170
|
],
|
|
9133
9171
|
"alarm-panel": [
|
|
@@ -9163,20 +9201,10 @@ Object.freeze({
|
|
|
9163
9201
|
"valueType": "boolean"
|
|
9164
9202
|
}
|
|
9165
9203
|
],
|
|
9166
|
-
"ambient-light-sensor": [
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
},
|
|
9171
|
-
{
|
|
9172
|
-
"path": "unit",
|
|
9173
|
-
"valueType": "string"
|
|
9174
|
-
},
|
|
9175
|
-
{
|
|
9176
|
-
"path": "precision",
|
|
9177
|
-
"valueType": "number"
|
|
9178
|
-
}
|
|
9179
|
-
],
|
|
9204
|
+
"ambient-light-sensor": [{
|
|
9205
|
+
"path": "lux",
|
|
9206
|
+
"valueType": "number"
|
|
9207
|
+
}],
|
|
9180
9208
|
"audio-metrics": [
|
|
9181
9209
|
{
|
|
9182
9210
|
"path": "ts",
|
|
@@ -9256,6 +9284,10 @@ Object.freeze({
|
|
|
9256
9284
|
"path": "lastUpdated",
|
|
9257
9285
|
"valueType": "number"
|
|
9258
9286
|
},
|
|
9287
|
+
{
|
|
9288
|
+
"path": "volts",
|
|
9289
|
+
"valueType": "number"
|
|
9290
|
+
},
|
|
9259
9291
|
{
|
|
9260
9292
|
"path": "lastContactAt",
|
|
9261
9293
|
"valueType": "number"
|
|
@@ -9498,10 +9530,6 @@ Object.freeze({
|
|
|
9498
9530
|
"datetime"
|
|
9499
9531
|
]
|
|
9500
9532
|
},
|
|
9501
|
-
{
|
|
9502
|
-
"path": "unit",
|
|
9503
|
-
"valueType": "string"
|
|
9504
|
-
},
|
|
9505
9533
|
{
|
|
9506
9534
|
"path": "min",
|
|
9507
9535
|
"valueType": "number"
|
|
@@ -9513,19 +9541,6 @@ Object.freeze({
|
|
|
9513
9541
|
{
|
|
9514
9542
|
"path": "step",
|
|
9515
9543
|
"valueType": "number"
|
|
9516
|
-
},
|
|
9517
|
-
{
|
|
9518
|
-
"path": "precision",
|
|
9519
|
-
"valueType": "number"
|
|
9520
|
-
},
|
|
9521
|
-
{
|
|
9522
|
-
"path": "format",
|
|
9523
|
-
"valueType": "enum",
|
|
9524
|
-
"enumValues": [
|
|
9525
|
-
"date",
|
|
9526
|
-
"time",
|
|
9527
|
-
"datetime"
|
|
9528
|
-
]
|
|
9529
9544
|
}
|
|
9530
9545
|
],
|
|
9531
9546
|
"cover": [
|
|
@@ -9766,13 +9781,8 @@ Object.freeze({
|
|
|
9766
9781
|
"path": "value",
|
|
9767
9782
|
"valueType": "string"
|
|
9768
9783
|
}, {
|
|
9769
|
-
"path": "
|
|
9770
|
-
"valueType": "
|
|
9771
|
-
"enumValues": [
|
|
9772
|
-
"date",
|
|
9773
|
-
"time",
|
|
9774
|
-
"datetime"
|
|
9775
|
-
]
|
|
9784
|
+
"path": "timestamp",
|
|
9785
|
+
"valueType": "boolean"
|
|
9776
9786
|
}],
|
|
9777
9787
|
"event-emitter": [
|
|
9778
9788
|
{
|
|
@@ -9879,20 +9889,10 @@ Object.freeze({
|
|
|
9879
9889
|
"valueType": "number"
|
|
9880
9890
|
}
|
|
9881
9891
|
],
|
|
9882
|
-
"humidity-sensor": [
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
},
|
|
9887
|
-
{
|
|
9888
|
-
"path": "unit",
|
|
9889
|
-
"valueType": "string"
|
|
9890
|
-
},
|
|
9891
|
-
{
|
|
9892
|
-
"path": "precision",
|
|
9893
|
-
"valueType": "number"
|
|
9894
|
-
}
|
|
9895
|
-
],
|
|
9892
|
+
"humidity-sensor": [{
|
|
9893
|
+
"path": "percent",
|
|
9894
|
+
"valueType": "number"
|
|
9895
|
+
}],
|
|
9896
9896
|
"image": [{
|
|
9897
9897
|
"path": "url",
|
|
9898
9898
|
"valueType": "string"
|
|
@@ -10231,20 +10231,10 @@ Object.freeze({
|
|
|
10231
10231
|
"valueType": "boolean"
|
|
10232
10232
|
}
|
|
10233
10233
|
],
|
|
10234
|
-
"numeric-sensor": [
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
},
|
|
10239
|
-
{
|
|
10240
|
-
"path": "unit",
|
|
10241
|
-
"valueType": "string"
|
|
10242
|
-
},
|
|
10243
|
-
{
|
|
10244
|
-
"path": "precision",
|
|
10245
|
-
"valueType": "number"
|
|
10246
|
-
}
|
|
10247
|
-
],
|
|
10234
|
+
"numeric-sensor": [{
|
|
10235
|
+
"path": "value",
|
|
10236
|
+
"valueType": "number"
|
|
10237
|
+
}],
|
|
10248
10238
|
"pet-feeder": [
|
|
10249
10239
|
{
|
|
10250
10240
|
"path": "foodLevel",
|
|
@@ -10336,14 +10326,6 @@ Object.freeze({
|
|
|
10336
10326
|
{
|
|
10337
10327
|
"path": "powerFactor",
|
|
10338
10328
|
"valueType": "number"
|
|
10339
|
-
},
|
|
10340
|
-
{
|
|
10341
|
-
"path": "unit",
|
|
10342
|
-
"valueType": "string"
|
|
10343
|
-
},
|
|
10344
|
-
{
|
|
10345
|
-
"path": "precision",
|
|
10346
|
-
"valueType": "number"
|
|
10347
10329
|
}
|
|
10348
10330
|
],
|
|
10349
10331
|
"presence": [
|
|
@@ -10372,20 +10354,10 @@ Object.freeze({
|
|
|
10372
10354
|
"valueType": "number"
|
|
10373
10355
|
}
|
|
10374
10356
|
],
|
|
10375
|
-
"pressure-sensor": [
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
},
|
|
10380
|
-
{
|
|
10381
|
-
"path": "unit",
|
|
10382
|
-
"valueType": "string"
|
|
10383
|
-
},
|
|
10384
|
-
{
|
|
10385
|
-
"path": "precision",
|
|
10386
|
-
"valueType": "number"
|
|
10387
|
-
}
|
|
10388
|
-
],
|
|
10357
|
+
"pressure-sensor": [{
|
|
10358
|
+
"path": "hpa",
|
|
10359
|
+
"valueType": "number"
|
|
10360
|
+
}],
|
|
10389
10361
|
"privacy-mask": [{
|
|
10390
10362
|
"path": "enabled",
|
|
10391
10363
|
"valueType": "boolean"
|
|
@@ -10696,20 +10668,10 @@ Object.freeze({
|
|
|
10696
10668
|
"path": "tampered",
|
|
10697
10669
|
"valueType": "boolean"
|
|
10698
10670
|
}],
|
|
10699
|
-
"temperature-sensor": [
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
},
|
|
10704
|
-
{
|
|
10705
|
-
"path": "unit",
|
|
10706
|
-
"valueType": "string"
|
|
10707
|
-
},
|
|
10708
|
-
{
|
|
10709
|
-
"path": "precision",
|
|
10710
|
-
"valueType": "number"
|
|
10711
|
-
}
|
|
10712
|
-
],
|
|
10671
|
+
"temperature-sensor": [{
|
|
10672
|
+
"path": "celsius",
|
|
10673
|
+
"valueType": "number"
|
|
10674
|
+
}],
|
|
10713
10675
|
"update": [
|
|
10714
10676
|
{
|
|
10715
10677
|
"path": "currentVersion",
|
|
@@ -10820,10 +10782,6 @@ Object.freeze({
|
|
|
10820
10782
|
"path": "temperature",
|
|
10821
10783
|
"valueType": "number"
|
|
10822
10784
|
},
|
|
10823
|
-
{
|
|
10824
|
-
"path": "temperatureUnit",
|
|
10825
|
-
"valueType": "string"
|
|
10826
|
-
},
|
|
10827
10785
|
{
|
|
10828
10786
|
"path": "humidity",
|
|
10829
10787
|
"valueType": "number"
|
|
@@ -10832,18 +10790,10 @@ Object.freeze({
|
|
|
10832
10790
|
"path": "pressure",
|
|
10833
10791
|
"valueType": "number"
|
|
10834
10792
|
},
|
|
10835
|
-
{
|
|
10836
|
-
"path": "pressureUnit",
|
|
10837
|
-
"valueType": "string"
|
|
10838
|
-
},
|
|
10839
10793
|
{
|
|
10840
10794
|
"path": "windSpeed",
|
|
10841
10795
|
"valueType": "number"
|
|
10842
10796
|
},
|
|
10843
|
-
{
|
|
10844
|
-
"path": "windSpeedUnit",
|
|
10845
|
-
"valueType": "string"
|
|
10846
|
-
},
|
|
10847
10797
|
{
|
|
10848
10798
|
"path": "windBearing",
|
|
10849
10799
|
"valueType": "number"
|
|
@@ -19391,7 +19341,8 @@ var CompositionProblemSchema = object({
|
|
|
19391
19341
|
"item-field-reserved",
|
|
19392
19342
|
"target-missing",
|
|
19393
19343
|
"target-unreadable",
|
|
19394
|
-
"not-replaceable"
|
|
19344
|
+
"not-replaceable",
|
|
19345
|
+
"native-capability-replace"
|
|
19395
19346
|
]),
|
|
19396
19347
|
path: string(),
|
|
19397
19348
|
message: string()
|
|
@@ -19449,9 +19400,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
19449
19400
|
reads: array(CompositionFieldReadSchema)
|
|
19450
19401
|
});
|
|
19451
19402
|
/**
|
|
19452
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
19453
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
19454
|
-
*
|
|
19403
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
19404
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
19405
|
+
* Replacing a capability the device already serves is refused
|
|
19406
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
19407
|
+
* wire for a claim the hub already holds.
|
|
19455
19408
|
*/
|
|
19456
19409
|
var CompositionFeatureModeSchema = _enum([
|
|
19457
19410
|
"new",
|
|
@@ -21344,12 +21297,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
21344
21297
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
21345
21298
|
* in-place so dispatch keeps working.
|
|
21346
21299
|
*
|
|
21347
|
-
* **
|
|
21348
|
-
*
|
|
21349
|
-
*
|
|
21350
|
-
*
|
|
21351
|
-
* (`ha-domain-mapping`)
|
|
21352
|
-
* stored after that point.
|
|
21300
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
21301
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
21302
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
21303
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
21304
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
21305
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
21353
21306
|
*
|
|
21354
21307
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
21355
21308
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -21363,6 +21316,14 @@ var SourceInfoSchema = object({
|
|
|
21363
21316
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
21364
21317
|
* Used to detect rename when `id` changes. */
|
|
21365
21318
|
uniqueId: string().optional(),
|
|
21319
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
21320
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
21321
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
21322
|
+
dateTimeShape: _enum([
|
|
21323
|
+
"date",
|
|
21324
|
+
"time",
|
|
21325
|
+
"datetime"
|
|
21326
|
+
]).optional(),
|
|
21366
21327
|
/** Provider-specific extras that don't fit the structured slots.
|
|
21367
21328
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
21368
21329
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -42390,7 +42351,8 @@ method(object({
|
|
|
42390
42351
|
"enum"
|
|
42391
42352
|
]),
|
|
42392
42353
|
enumValues: array(string()).optional(),
|
|
42393
|
-
item: boolean().optional()
|
|
42354
|
+
item: boolean().optional(),
|
|
42355
|
+
quantity: ReadingQuantitySchema.optional()
|
|
42394
42356
|
})).readonly(),
|
|
42395
42357
|
itemArray: object({
|
|
42396
42358
|
path: string(),
|
|
@@ -46457,8 +46419,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
46457
46419
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
46458
46420
|
var MaskGridShapeSchema = object({
|
|
46459
46421
|
kind: literal("grid"),
|
|
46460
|
-
gridWidth: number(),
|
|
46461
|
-
gridHeight: number(),
|
|
46422
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
46423
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
46462
46424
|
cells: array(boolean())
|
|
46463
46425
|
});
|
|
46464
46426
|
discriminatedUnion("kind", [
|
|
@@ -59784,27 +59746,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
59784
59746
|
*/
|
|
59785
59747
|
var AirQualitySensorStatusSchema = object({
|
|
59786
59748
|
/** Carbon dioxide concentration in ppm. */
|
|
59787
|
-
co2Ppm: number().min(0).optional(),
|
|
59749
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
59788
59750
|
/** Total volatile organic compounds in ppb. */
|
|
59789
|
-
vocPpb: number().min(0).optional(),
|
|
59751
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
59790
59752
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
59791
|
-
pm25: number().min(0).optional(),
|
|
59753
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
59792
59754
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
59793
|
-
pm10: number().min(0).optional(),
|
|
59755
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
59794
59756
|
/** Composite AQI value (typically 0..500). */
|
|
59795
|
-
aqi: number().optional(),
|
|
59757
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
59796
59758
|
/** Ms epoch when the slice was last updated. */
|
|
59797
|
-
lastFetchedAt: number()
|
|
59798
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
59799
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
59800
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
59801
|
-
* per slice is unambiguous. */
|
|
59802
|
-
unit: string().optional(),
|
|
59803
|
-
/** Suggested decimal places for numeric display.
|
|
59804
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59805
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59806
|
-
* auto-formatting when absent. */
|
|
59807
|
-
precision: number().int().min(0).max(10).optional()
|
|
59759
|
+
lastFetchedAt: number()
|
|
59808
59760
|
});
|
|
59809
59761
|
var airQualitySensorCapability = {
|
|
59810
59762
|
name: "air-quality-sensor",
|
|
@@ -59841,12 +59793,12 @@ var airQualitySensorCapability = {
|
|
|
59841
59793
|
},
|
|
59842
59794
|
pm25: {
|
|
59843
59795
|
kind: "gauge",
|
|
59844
|
-
unit: "
|
|
59796
|
+
unit: "µg/m³",
|
|
59845
59797
|
deadband: 1
|
|
59846
59798
|
},
|
|
59847
59799
|
pm10: {
|
|
59848
59800
|
kind: "gauge",
|
|
59849
|
-
unit: "
|
|
59801
|
+
unit: "µg/m³",
|
|
59850
59802
|
deadband: 1
|
|
59851
59803
|
},
|
|
59852
59804
|
aqi: {
|
|
@@ -59864,22 +59816,13 @@ var airQualitySensorCapability = {
|
|
|
59864
59816
|
* entries with `device_class: illuminance`.
|
|
59865
59817
|
*/
|
|
59866
59818
|
var AmbientLightSensorStatusSchema = object({
|
|
59867
|
-
/** Current illuminance in lux (lx). */
|
|
59868
|
-
lux: number().min(0).meta({
|
|
59869
|
-
|
|
59819
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
59820
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
59821
|
+
precision: 0,
|
|
59870
59822
|
label: "Illuminance"
|
|
59871
|
-
}),
|
|
59823
|
+
})),
|
|
59872
59824
|
/** Ms epoch when the slice was last updated. */
|
|
59873
|
-
lastFetchedAt: number()
|
|
59874
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59875
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59876
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59877
|
-
unit: string().optional(),
|
|
59878
|
-
/** Suggested decimal places for numeric display.
|
|
59879
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59880
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59881
|
-
* auto-formatting when absent. */
|
|
59882
|
-
precision: number().int().min(0).max(10).optional()
|
|
59825
|
+
lastFetchedAt: number()
|
|
59883
59826
|
});
|
|
59884
59827
|
var ambientLightSensorCapability = {
|
|
59885
59828
|
name: "ambient-light-sensor",
|
|
@@ -59911,12 +59854,7 @@ var ambientLightSensorCapability = {
|
|
|
59911
59854
|
} } },
|
|
59912
59855
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59913
59856
|
* whether persisting is worth a SQLite commit. */
|
|
59914
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59915
|
-
customize: {
|
|
59916
|
-
version: 1,
|
|
59917
|
-
advanced: "derive",
|
|
59918
|
-
targets: []
|
|
59919
|
-
}
|
|
59857
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59920
59858
|
};
|
|
59921
59859
|
/**
|
|
59922
59860
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -60143,10 +60081,7 @@ var BatteryStatusSchema = object({
|
|
|
60143
60081
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
60144
60082
|
* declines to band a non-finite reading, which is the correct shape.
|
|
60145
60083
|
*/
|
|
60146
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
60147
|
-
unit: "%",
|
|
60148
|
-
label: "Charge"
|
|
60149
|
-
}),
|
|
60084
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
60150
60085
|
/**
|
|
60151
60086
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
60152
60087
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -60173,7 +60108,14 @@ var BatteryStatusSchema = object({
|
|
|
60173
60108
|
*/
|
|
60174
60109
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
60175
60110
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
60176
|
-
lastUpdated: number(),
|
|
60111
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
60112
|
+
/**
|
|
60113
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
60114
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
60115
|
+
* that only report charge. A second reading on this cap, not a second
|
|
60116
|
+
* `numeric-sensor` on the same device.
|
|
60117
|
+
*/
|
|
60118
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
60177
60119
|
/**
|
|
60178
60120
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
60179
60121
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -60225,7 +60167,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
60225
60167
|
/** Generic Customize target for the percentage reading (D936). */
|
|
60226
60168
|
var batteryCustomize = {
|
|
60227
60169
|
version: 1,
|
|
60228
|
-
advanced: "derive",
|
|
60229
60170
|
targets: [{
|
|
60230
60171
|
id: "percentage",
|
|
60231
60172
|
cardinality: "scalar",
|
|
@@ -60234,7 +60175,7 @@ var batteryCustomize = {
|
|
|
60234
60175
|
stateField: "percentage"
|
|
60235
60176
|
},
|
|
60236
60177
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
60237
|
-
apply: "add
|
|
60178
|
+
apply: "add",
|
|
60238
60179
|
path: "percentage",
|
|
60239
60180
|
sources: [{
|
|
60240
60181
|
kind: "field",
|
|
@@ -60355,10 +60296,16 @@ onStatusChanged: { data: object({
|
|
|
60355
60296
|
/**
|
|
60356
60297
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
60357
60298
|
*/
|
|
60358
|
-
history: { fields: {
|
|
60359
|
-
|
|
60360
|
-
|
|
60361
|
-
|
|
60299
|
+
history: { fields: {
|
|
60300
|
+
percentage: {
|
|
60301
|
+
kind: "gauge",
|
|
60302
|
+
unit: "%"
|
|
60303
|
+
},
|
|
60304
|
+
volts: {
|
|
60305
|
+
kind: "gauge",
|
|
60306
|
+
unit: "V"
|
|
60307
|
+
}
|
|
60308
|
+
} },
|
|
60362
60309
|
customize: batteryCustomize,
|
|
60363
60310
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60364
60311
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -60405,12 +60352,7 @@ var binaryCapability = {
|
|
|
60405
60352
|
history: { fields: { on: { kind: "boolean" } } },
|
|
60406
60353
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60407
60354
|
* whether persisting is worth a SQLite commit. */
|
|
60408
|
-
volatileStateFields: ["lastChangedAt"]
|
|
60409
|
-
customize: {
|
|
60410
|
-
version: 1,
|
|
60411
|
-
advanced: "derive",
|
|
60412
|
-
targets: []
|
|
60413
|
-
}
|
|
60355
|
+
volatileStateFields: ["lastChangedAt"]
|
|
60414
60356
|
};
|
|
60415
60357
|
/**
|
|
60416
60358
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -60426,7 +60368,7 @@ var binaryCapability = {
|
|
|
60426
60368
|
*/
|
|
60427
60369
|
var BrightnessStatusSchema = object({
|
|
60428
60370
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
60429
|
-
percentage: number().min(0).max(100),
|
|
60371
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
60430
60372
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
60431
60373
|
lastChangedAt: number()
|
|
60432
60374
|
});
|
|
@@ -60907,21 +60849,21 @@ var ClimateControlStatusSchema = object({
|
|
|
60907
60849
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
60908
60850
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
60909
60851
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
60910
|
-
target: number().nullable(),
|
|
60852
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
60911
60853
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
60912
60854
|
* in `heat_cool` mode. */
|
|
60913
|
-
targetHigh: number().nullable(),
|
|
60855
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
60914
60856
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
60915
60857
|
* in `heat_cool` mode. */
|
|
60916
|
-
targetLow: number().nullable(),
|
|
60858
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
60917
60859
|
/** Target relative humidity (0..100). Null when the device has no
|
|
60918
60860
|
* humidity control. */
|
|
60919
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
60861
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60920
60862
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
60921
60863
|
* the device's internal sensor. */
|
|
60922
|
-
currentTemp: number().nullable(),
|
|
60864
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
60923
60865
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
60924
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
60866
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60925
60867
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
60926
60868
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
60927
60869
|
swingVertical: boolean().nullable(),
|
|
@@ -60929,11 +60871,11 @@ var ClimateControlStatusSchema = object({
|
|
|
60929
60871
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
60930
60872
|
swingHorizontal: boolean().nullable(),
|
|
60931
60873
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
60932
|
-
minTemp: number().nullable().optional(),
|
|
60874
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
60933
60875
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
60934
|
-
maxTemp: number().nullable().optional(),
|
|
60876
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
60935
60877
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
60936
|
-
tempStep: number().positive().nullable().optional(),
|
|
60878
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
60937
60879
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
60938
60880
|
lastFetchedAt: number()
|
|
60939
60881
|
});
|
|
@@ -61075,17 +61017,17 @@ var climateControlCapability = {
|
|
|
61075
61017
|
* modes to expose in the picker without a slice fetch.
|
|
61076
61018
|
*/
|
|
61077
61019
|
var RgbTripletSchema = object({
|
|
61078
|
-
r: number().int().min(0).max(255),
|
|
61079
|
-
g: number().int().min(0).max(255),
|
|
61080
|
-
b: number().int().min(0).max(255)
|
|
61020
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
61021
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
61022
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
61081
61023
|
});
|
|
61082
61024
|
var HsvTripletSchema = object({
|
|
61083
61025
|
/** Hue in degrees, 0..360. */
|
|
61084
|
-
h: number().min(0).max(360),
|
|
61026
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
61085
61027
|
/** Saturation as 0..100 inclusive. */
|
|
61086
|
-
s: number().min(0).max(100),
|
|
61028
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
61087
61029
|
/** Value/brightness as 0..100 inclusive. */
|
|
61088
|
-
v: number().min(0).max(100)
|
|
61030
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
61089
61031
|
});
|
|
61090
61032
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
61091
61033
|
object({
|
|
@@ -61114,7 +61056,7 @@ var ColorStatusSchema = object({
|
|
|
61114
61056
|
/** Populated when `mode === 'hsv'`. */
|
|
61115
61057
|
hsv: HsvTripletSchema.optional(),
|
|
61116
61058
|
/** Populated when `mode === 'mired'`. */
|
|
61117
|
-
mireds: number().int().optional(),
|
|
61059
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
61118
61060
|
/** Ms epoch of the last operator-driven change. */
|
|
61119
61061
|
lastChangedAt: number()
|
|
61120
61062
|
});
|
|
@@ -61323,18 +61265,12 @@ var FORM_OF_KIND = {
|
|
|
61323
61265
|
function consumableFormOf(item) {
|
|
61324
61266
|
return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
|
|
61325
61267
|
}
|
|
61326
|
-
/**
|
|
61327
|
-
|
|
61328
|
-
|
|
61329
|
-
"days",
|
|
61330
|
-
"hours",
|
|
61331
|
-
"cycles"
|
|
61332
|
-
]);
|
|
61333
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
61334
|
-
* days). `value` null = unknown (D393). */
|
|
61268
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
61269
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
61270
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
61335
61271
|
var ConsumableRemainingSchema = object({
|
|
61336
|
-
value: number().min(0).nullable(),
|
|
61337
|
-
|
|
61272
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
61273
|
+
kind: ConsumableRemainingKindSchema
|
|
61338
61274
|
});
|
|
61339
61275
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
61340
61276
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -61347,7 +61283,7 @@ var ConsumableItemSchema = object({
|
|
|
61347
61283
|
/** Display name. */
|
|
61348
61284
|
label: string().min(1),
|
|
61349
61285
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
61350
|
-
level: number().min(0).max(100).nullable(),
|
|
61286
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61351
61287
|
/** The provider's discrete verdict when known (binary mode). */
|
|
61352
61288
|
status: ConsumableStatusSchema.nullable(),
|
|
61353
61289
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -61429,8 +61365,8 @@ var consumablesCustomize = {
|
|
|
61429
61365
|
transforms: [{ kind: "identity" }]
|
|
61430
61366
|
}],
|
|
61431
61367
|
literals: [{
|
|
61432
|
-
path: "remaining.
|
|
61433
|
-
values: [...
|
|
61368
|
+
path: "remaining.kind",
|
|
61369
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
61434
61370
|
}]
|
|
61435
61371
|
},
|
|
61436
61372
|
{
|
|
@@ -61559,7 +61495,6 @@ reset: method(object({
|
|
|
61559
61495
|
},
|
|
61560
61496
|
"remaining.value": {
|
|
61561
61497
|
kind: "gauge",
|
|
61562
|
-
unitFrom: "remaining.unit",
|
|
61563
61498
|
deadband: 1,
|
|
61564
61499
|
displayName: "Remaining"
|
|
61565
61500
|
}
|
|
@@ -61629,10 +61564,9 @@ var contactCapability = {
|
|
|
61629
61564
|
* (empty array for the other kinds). It lives in the slice because
|
|
61630
61565
|
* HA `select.*` entities may update their options at runtime.
|
|
61631
61566
|
*
|
|
61632
|
-
*
|
|
61633
|
-
*
|
|
61634
|
-
*
|
|
61635
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
61567
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
61568
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
61569
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
61636
61570
|
*/
|
|
61637
61571
|
var ControlStatusSchema = object({
|
|
61638
61572
|
kind: _enum([
|
|
@@ -61644,39 +61578,17 @@ var ControlStatusSchema = object({
|
|
|
61644
61578
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
61645
61579
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
61646
61580
|
* or time-only — HA accepts all three forms). */
|
|
61647
|
-
value: union([number(), string()]),
|
|
61581
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
61648
61582
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
61649
61583
|
options: array(string()),
|
|
61650
61584
|
/** Ms epoch when the slice was last updated. */
|
|
61651
61585
|
lastChangedAt: number(),
|
|
61652
|
-
/**
|
|
61653
|
-
|
|
61654
|
-
|
|
61655
|
-
|
|
61656
|
-
/**
|
|
61657
|
-
|
|
61658
|
-
min: number().optional(),
|
|
61659
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
61660
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
61661
|
-
max: number().optional(),
|
|
61662
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
61663
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
61664
|
-
step: number().optional(),
|
|
61665
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
61666
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
61667
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
61668
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
61669
|
-
precision: number().int().min(0).max(10).optional(),
|
|
61670
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
61671
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
61672
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
61673
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
61674
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
61675
|
-
format: _enum([
|
|
61676
|
-
"date",
|
|
61677
|
-
"time",
|
|
61678
|
-
"datetime"
|
|
61679
|
-
]).optional()
|
|
61586
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
61587
|
+
min: number().optional().meta(readingMeta("device")),
|
|
61588
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
61589
|
+
max: number().optional().meta(readingMeta("device")),
|
|
61590
|
+
/** Step increment, in the device quantity's base unit. */
|
|
61591
|
+
step: number().optional().meta(readingMeta("device"))
|
|
61680
61592
|
});
|
|
61681
61593
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
61682
61594
|
object({
|
|
@@ -61764,9 +61676,9 @@ var CoverStatusSchema = object({
|
|
|
61764
61676
|
state: CoverStateSchema,
|
|
61765
61677
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
61766
61678
|
* no intermediate position surface. */
|
|
61767
|
-
position: number().min(0).max(100).nullable(),
|
|
61679
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61768
61680
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
61769
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
61681
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61770
61682
|
/** Ms epoch when the slice was last updated. */
|
|
61771
61683
|
lastChangedAt: number()
|
|
61772
61684
|
});
|
|
@@ -61869,9 +61781,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
61869
61781
|
var DayNightStatusSchema = object({
|
|
61870
61782
|
mode: DayNightModeSchema,
|
|
61871
61783
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
61872
|
-
sensitivity: number().optional(),
|
|
61784
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
61873
61785
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
61874
|
-
switchDelaySec: number().optional(),
|
|
61786
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
61875
61787
|
lastFetchedAt: number()
|
|
61876
61788
|
});
|
|
61877
61789
|
/**
|
|
@@ -62089,11 +62001,11 @@ var DishwasherStatusSchema = object({
|
|
|
62089
62001
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
62090
62002
|
availablePrograms: array(string()),
|
|
62091
62003
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
62092
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
62004
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
62093
62005
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
62094
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
62006
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
62095
62007
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
62096
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
62008
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62097
62009
|
/** True when the door is reported open; null when the door state is not known. */
|
|
62098
62010
|
doorOpen: boolean().nullable(),
|
|
62099
62011
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -62117,7 +62029,7 @@ var DishwasherStatusSchema = object({
|
|
|
62117
62029
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
62118
62030
|
machineCareDue: boolean().nullable(),
|
|
62119
62031
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
62120
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
62032
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
62121
62033
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
62122
62034
|
halfLoad: boolean().nullable(),
|
|
62123
62035
|
hygienePlus: boolean().nullable(),
|
|
@@ -62132,7 +62044,7 @@ var DishwasherStatusSchema = object({
|
|
|
62132
62044
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
62133
62045
|
activeEvents: array(string()),
|
|
62134
62046
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
62135
|
-
errorCode: number().nullable(),
|
|
62047
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
62136
62048
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
62137
62049
|
errorLabel: string().nullable(),
|
|
62138
62050
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -62344,6 +62256,7 @@ var doorbellCustomize = {
|
|
|
62344
62256
|
applyAuthority: { kind: "composition-claim" },
|
|
62345
62257
|
eventName: "onPressed",
|
|
62346
62258
|
edges: ["rising"],
|
|
62259
|
+
defaultEdge: "rising",
|
|
62347
62260
|
timestampPath: "lastPressedAt",
|
|
62348
62261
|
counterPath: "pressCountSinceStart",
|
|
62349
62262
|
highWater: "composer-advance",
|
|
@@ -62362,7 +62275,7 @@ var DoorbellStatusSchema = object({
|
|
|
62362
62275
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
62363
62276
|
lastPressedAt: number().nullable(),
|
|
62364
62277
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
62365
|
-
pressCountSinceStart: number()
|
|
62278
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
62366
62279
|
});
|
|
62367
62280
|
var DoorbellPressEventSchema = object({
|
|
62368
62281
|
deviceId: number(),
|
|
@@ -62427,17 +62340,7 @@ onPressed: {
|
|
|
62427
62340
|
history: "none",
|
|
62428
62341
|
customize: doorbellCustomize
|
|
62429
62342
|
};
|
|
62430
|
-
|
|
62431
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
62432
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
62433
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
62434
|
-
* The option set is stable across observations; it is persisted in the
|
|
62435
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
62436
|
-
* stored in `sourceInfo`.
|
|
62437
|
-
*/
|
|
62438
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
62439
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
62440
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
62343
|
+
_enum([
|
|
62441
62344
|
"date",
|
|
62442
62345
|
"time",
|
|
62443
62346
|
"datetime"
|
|
@@ -62445,12 +62348,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
62445
62348
|
var EnumSensorStatusSchema = object({
|
|
62446
62349
|
value: string(),
|
|
62447
62350
|
/**
|
|
62448
|
-
* Set
|
|
62449
|
-
* as
|
|
62450
|
-
*
|
|
62451
|
-
* a time-only sensor → `'time'`.
|
|
62351
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
62352
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
62353
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
62452
62354
|
*/
|
|
62453
|
-
|
|
62355
|
+
timestamp: boolean().optional(),
|
|
62454
62356
|
/** Ms epoch when the slice was last updated. */
|
|
62455
62357
|
lastFetchedAt: number()
|
|
62456
62358
|
});
|
|
@@ -62477,11 +62379,11 @@ var enumSensorCapability = {
|
|
|
62477
62379
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
62478
62380
|
* operation state, an HVAC action). The option set is per device, so the
|
|
62479
62381
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
62480
|
-
* `
|
|
62382
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
62481
62383
|
*/
|
|
62482
62384
|
history: { fields: { value: {
|
|
62483
62385
|
kind: "enum",
|
|
62484
|
-
skipWhenSet: "
|
|
62386
|
+
skipWhenSet: "timestamp"
|
|
62485
62387
|
} } },
|
|
62486
62388
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62487
62389
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -62501,13 +62403,13 @@ var EventFireSchema = object({
|
|
|
62501
62403
|
deviceId: number(),
|
|
62502
62404
|
eventType: string(),
|
|
62503
62405
|
data: record(string(), unknown()).nullable(),
|
|
62504
|
-
timestamp: number(),
|
|
62505
|
-
seq: number()
|
|
62406
|
+
timestamp: number().meta(readingMeta("none")),
|
|
62407
|
+
seq: number().meta(readingMeta("count"))
|
|
62506
62408
|
});
|
|
62507
62409
|
var EventEmitterStatusSchema = object({
|
|
62508
62410
|
eventTypes: array(string()),
|
|
62509
62411
|
lastEvent: EventFireSchema.nullable(),
|
|
62510
|
-
eventCountSinceStart: number()
|
|
62412
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
62511
62413
|
});
|
|
62512
62414
|
var eventEmitterCapability = {
|
|
62513
62415
|
name: "event-emitter",
|
|
@@ -62960,10 +62862,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
62960
62862
|
var FanControlStatusSchema = object({
|
|
62961
62863
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
62962
62864
|
* speed surface (single-speed fan). */
|
|
62963
|
-
percentage: number().min(0).max(100).nullable(),
|
|
62865
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62964
62866
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
62965
62867
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
62966
|
-
percentageStep: number().positive().optional(),
|
|
62868
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
62967
62869
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
62968
62870
|
* — empty string when no preset is active or supported. */
|
|
62969
62871
|
preset: string(),
|
|
@@ -63084,7 +62986,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
63084
62986
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
63085
62987
|
model: string().nullable(),
|
|
63086
62988
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
63087
|
-
channelCount: number().nullable(),
|
|
62989
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
63088
62990
|
/**
|
|
63089
62991
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
63090
62992
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -63209,7 +63111,7 @@ var gasCapability = {
|
|
|
63209
63111
|
};
|
|
63210
63112
|
var HeatingValveStatusSchema = object({
|
|
63211
63113
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
63212
|
-
position: number().min(0).max(100).nullable(),
|
|
63114
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63213
63115
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
63214
63116
|
lastFetchedAt: number()
|
|
63215
63117
|
});
|
|
@@ -63252,9 +63154,9 @@ var HumidifierStatusSchema = object({
|
|
|
63252
63154
|
/** Whether the humidifier is currently on. */
|
|
63253
63155
|
on: boolean(),
|
|
63254
63156
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
63255
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
63157
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63256
63158
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
63257
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
63159
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63258
63160
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
63259
63161
|
* device has no mode surface. */
|
|
63260
63162
|
mode: string().nullable(),
|
|
@@ -63264,9 +63166,9 @@ var HumidifierStatusSchema = object({
|
|
|
63264
63166
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
63265
63167
|
action: string().nullable(),
|
|
63266
63168
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
63267
|
-
minHumidity: number().nullable(),
|
|
63169
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
63268
63170
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
63269
|
-
maxHumidity: number().nullable(),
|
|
63171
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
63270
63172
|
/** Ms epoch when the slice was last updated. */
|
|
63271
63173
|
lastChangedAt: number()
|
|
63272
63174
|
});
|
|
@@ -63336,22 +63238,13 @@ var humidifierCapability = {
|
|
|
63336
63238
|
* `sourceInfo`.
|
|
63337
63239
|
*/
|
|
63338
63240
|
var HumiditySensorStatusSchema = object({
|
|
63339
|
-
/** Current relative humidity, 0..100. */
|
|
63340
|
-
percent: number().min(0).max(100).meta({
|
|
63341
|
-
|
|
63241
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
63242
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
63243
|
+
precision: 0,
|
|
63342
63244
|
label: "Humidity"
|
|
63343
|
-
}),
|
|
63245
|
+
})),
|
|
63344
63246
|
/** Ms epoch when the slice was last updated. */
|
|
63345
|
-
lastFetchedAt: number()
|
|
63346
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63347
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63348
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63349
|
-
unit: string().optional(),
|
|
63350
|
-
/** Suggested decimal places for numeric display.
|
|
63351
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63352
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63353
|
-
* auto-formatting when absent. */
|
|
63354
|
-
precision: number().int().min(0).max(10).optional()
|
|
63247
|
+
lastFetchedAt: number()
|
|
63355
63248
|
});
|
|
63356
63249
|
var humiditySensorCapability = {
|
|
63357
63250
|
name: "humidity-sensor",
|
|
@@ -63382,12 +63275,7 @@ var humiditySensorCapability = {
|
|
|
63382
63275
|
} } },
|
|
63383
63276
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63384
63277
|
* whether persisting is worth a SQLite commit. */
|
|
63385
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63386
|
-
customize: {
|
|
63387
|
-
version: 1,
|
|
63388
|
-
advanced: "derive",
|
|
63389
|
-
targets: []
|
|
63390
|
-
}
|
|
63278
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63391
63279
|
};
|
|
63392
63280
|
/**
|
|
63393
63281
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -63408,7 +63296,7 @@ var ImageStatusSchema = object({
|
|
|
63408
63296
|
* entity exposes no `entity_picture` (yet). */
|
|
63409
63297
|
url: string().nullable(),
|
|
63410
63298
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
63411
|
-
lastUpdated: number().nullable()
|
|
63299
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
63412
63300
|
});
|
|
63413
63301
|
var imageCapability = {
|
|
63414
63302
|
name: "image",
|
|
@@ -63496,19 +63384,19 @@ var NormalizedRangeSchema = object({
|
|
|
63496
63384
|
*/
|
|
63497
63385
|
var ImageSettingsStatusSchema = object({
|
|
63498
63386
|
/** Normalized 0–100. */
|
|
63499
|
-
brightness: number().optional(),
|
|
63387
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
63500
63388
|
/** Normalized 0–100. */
|
|
63501
|
-
contrast: number().optional(),
|
|
63389
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
63502
63390
|
/** Normalized 0–100. */
|
|
63503
|
-
saturation: number().optional(),
|
|
63391
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
63504
63392
|
/** Normalized 0–100. */
|
|
63505
|
-
sharpness: number().optional(),
|
|
63393
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
63506
63394
|
mirror: boolean().optional(),
|
|
63507
63395
|
flip: boolean().optional(),
|
|
63508
63396
|
rotate: ImageRotateSchema.optional(),
|
|
63509
63397
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
63510
63398
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
63511
|
-
warmth: number().optional(),
|
|
63399
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
63512
63400
|
exposureMode: ExposureModeSchema.optional(),
|
|
63513
63401
|
backlightMode: BacklightModeSchema.optional(),
|
|
63514
63402
|
lastFetchedAt: number()
|
|
@@ -63787,10 +63675,10 @@ var IntercomAbilitySchema = object({
|
|
|
63787
63675
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
63788
63676
|
codecs: array(string()),
|
|
63789
63677
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
63790
|
-
sampleRate: number(),
|
|
63678
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
63791
63679
|
duplex: _enum(["half", "full"]),
|
|
63792
63680
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
63793
|
-
maxBacklogMs: number()
|
|
63681
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
63794
63682
|
});
|
|
63795
63683
|
var IntercomStatusSchema = object({
|
|
63796
63684
|
/** True while a talk session is open. */
|
|
@@ -64017,13 +63905,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
64017
63905
|
activity: LawnMowerActivitySchema,
|
|
64018
63906
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
64019
63907
|
* reading. */
|
|
64020
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
63908
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64021
63909
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
64022
63910
|
* task is active / progress is unavailable. */
|
|
64023
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
63911
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64024
63912
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
64025
63913
|
* or null when unknown. */
|
|
64026
|
-
currentCode: number().nullable(),
|
|
63914
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
64027
63915
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
64028
63916
|
currentCodeLabel: string().nullable(),
|
|
64029
63917
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -64577,7 +64465,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
64577
64465
|
state: MediaPlayerStateSchema,
|
|
64578
64466
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
64579
64467
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
64580
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
64468
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64581
64469
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
64582
64470
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
64583
64471
|
isMuted: boolean().nullable(),
|
|
@@ -64590,10 +64478,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
64590
64478
|
currentMedia: MediaInfoSchema.nullable(),
|
|
64591
64479
|
/** Current playback position in ms. Null when not seekable or
|
|
64592
64480
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
64593
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
64481
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64594
64482
|
/** Total duration of the current media in ms. Null when unknown
|
|
64595
64483
|
* (live stream) or nothing is playing. */
|
|
64596
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
64484
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64597
64485
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
64598
64486
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
64599
64487
|
shuffle: boolean().nullable(),
|
|
@@ -64902,7 +64790,7 @@ var motionCustomize = {
|
|
|
64902
64790
|
eventName: "onMotionChanged"
|
|
64903
64791
|
},
|
|
64904
64792
|
deviceTypes: [DeviceType.Camera],
|
|
64905
|
-
apply: "
|
|
64793
|
+
apply: "add",
|
|
64906
64794
|
applyAuthority: {
|
|
64907
64795
|
kind: "camera-sensors",
|
|
64908
64796
|
timeoutField: "motionCooldownMs"
|
|
@@ -64999,7 +64887,7 @@ var MotionStatusSchema = object({
|
|
|
64999
64887
|
* it, every provider seeded it at boot, and every session left it
|
|
65000
64888
|
* `detected: true` after its detach.
|
|
65001
64889
|
*/
|
|
65002
|
-
autoClearAfterMs: number().nullable()
|
|
64890
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
65003
64891
|
});
|
|
65004
64892
|
/**
|
|
65005
64893
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -65181,7 +65069,7 @@ var MotionZoneRegionSchema = object({
|
|
|
65181
65069
|
* the grid region(s). */
|
|
65182
65070
|
var MotionZoneStatusSchema = object({
|
|
65183
65071
|
enabled: boolean(),
|
|
65184
|
-
sensitivity: number(),
|
|
65072
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
65185
65073
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
65186
65074
|
regions: array(MotionZoneRegionSchema),
|
|
65187
65075
|
lastFetchedAt: number()
|
|
@@ -65551,7 +65439,7 @@ var NavigationStatusSchema = object({
|
|
|
65551
65439
|
following: boolean(),
|
|
65552
65440
|
flash: boolean(),
|
|
65553
65441
|
lightMode: NavigationLightModeSchema,
|
|
65554
|
-
lightLevel: number().min(40).max(100),
|
|
65442
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
65555
65443
|
/** Ms epoch when the slice was last updated. */
|
|
65556
65444
|
lastChangedAt: number()
|
|
65557
65445
|
});
|
|
@@ -65685,13 +65573,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
65685
65573
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
65686
65574
|
* SKIP a null rather than coerce it.
|
|
65687
65575
|
*/
|
|
65688
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
65576
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65689
65577
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
65690
|
-
rssiDbm: number().optional(),
|
|
65578
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
65691
65579
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
65692
65580
|
ssid: string().optional(),
|
|
65693
65581
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
65694
|
-
lastUpdated: number()
|
|
65582
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
65695
65583
|
});
|
|
65696
65584
|
var networkLinkCapability = {
|
|
65697
65585
|
name: "network-link",
|
|
@@ -66076,7 +65964,7 @@ var NotifierStatusSchema = object({
|
|
|
66076
65964
|
lastError: string().nullable(),
|
|
66077
65965
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
66078
65966
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
66079
|
-
queueDepth: number().int().nonnegative(),
|
|
65967
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
66080
65968
|
/** Per-feature capability matrix — authoritative source for the
|
|
66081
65969
|
* compose-form field gating. */
|
|
66082
65970
|
supports: NotifierSupportsSchema
|
|
@@ -66168,11 +66056,9 @@ onSent: { data: object({
|
|
|
66168
66056
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
66169
66057
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
66170
66058
|
*
|
|
66171
|
-
* The
|
|
66172
|
-
*
|
|
66173
|
-
*
|
|
66174
|
-
* The UI reads them directly from the slice — they are the single source
|
|
66175
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
66059
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
66060
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
66061
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
66176
66062
|
*
|
|
66177
66063
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
66178
66064
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -66181,15 +66067,8 @@ onSent: { data: object({
|
|
|
66181
66067
|
* numeric values land here.
|
|
66182
66068
|
*/
|
|
66183
66069
|
var NumericSensorStatusSchema = object({
|
|
66184
|
-
|
|
66185
|
-
|
|
66186
|
-
* Populated live from the upstream source on each state push.
|
|
66187
|
-
* Absent for unitless sensors. */
|
|
66188
|
-
unit: string().optional(),
|
|
66189
|
-
/** Suggested decimal places for numeric display.
|
|
66190
|
-
* Populated live from the upstream source when provided.
|
|
66191
|
-
* Falls back to auto-formatting when absent. */
|
|
66192
|
-
precision: number().int().min(0).max(10).optional(),
|
|
66070
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
66071
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
66193
66072
|
/** Ms epoch when the slice was last updated. */
|
|
66194
66073
|
lastFetchedAt: number()
|
|
66195
66074
|
});
|
|
@@ -66213,11 +66092,11 @@ var numericSensorCapability = {
|
|
|
66213
66092
|
*/
|
|
66214
66093
|
durability: "restored",
|
|
66215
66094
|
/**
|
|
66216
|
-
* History (D850): recorded series. The unit is
|
|
66095
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
66096
|
+
* resolved when the series is read — the cap has no single unit.
|
|
66217
66097
|
*/
|
|
66218
66098
|
history: { fields: { value: {
|
|
66219
66099
|
kind: "gauge",
|
|
66220
|
-
unitFrom: "unit",
|
|
66221
66100
|
minIntervalMs: 3e4
|
|
66222
66101
|
} } },
|
|
66223
66102
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -66509,23 +66388,26 @@ var PetFeederStatusSchema = object({
|
|
|
66509
66388
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
66510
66389
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
66511
66390
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
66512
|
-
foodLevel: number().nullable(),
|
|
66391
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
66513
66392
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
66514
66393
|
* single-hopper models. */
|
|
66515
|
-
food1: number().nullable(),
|
|
66394
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
66516
66395
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
66517
66396
|
* single-hopper models. */
|
|
66518
|
-
food2: number().nullable(),
|
|
66397
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
66519
66398
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
66520
66399
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
66521
66400
|
* below the feeder's low threshold. */
|
|
66522
66401
|
lowFood: boolean(),
|
|
66523
66402
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
66524
66403
|
* device has no battery reading. */
|
|
66525
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
66526
|
-
/**
|
|
66527
|
-
*
|
|
66528
|
-
|
|
66404
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
66405
|
+
/**
|
|
66406
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
66407
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
66408
|
+
* model has no desiccant sensor.
|
|
66409
|
+
*/
|
|
66410
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
66529
66411
|
/** True while a feed is in progress. */
|
|
66530
66412
|
feeding: boolean(),
|
|
66531
66413
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -66536,7 +66418,7 @@ var PetFeederStatusSchema = object({
|
|
|
66536
66418
|
* with `errorCode` for consumers that want the raw integer. */
|
|
66537
66419
|
error: string().nullable(),
|
|
66538
66420
|
/** Raw device error code (0 / null = no error). */
|
|
66539
|
-
errorCode: number().nullable(),
|
|
66421
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
66540
66422
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
66541
66423
|
isDualHopper: boolean(),
|
|
66542
66424
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -66546,7 +66428,7 @@ var PetFeederStatusSchema = object({
|
|
|
66546
66428
|
/** Play a chime when dispensing. */
|
|
66547
66429
|
feedSound: boolean(),
|
|
66548
66430
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
66549
|
-
volume: number(),
|
|
66431
|
+
volume: number().meta(readingMeta("none")),
|
|
66550
66432
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
66551
66433
|
lastFetchedAt: number()
|
|
66552
66434
|
});
|
|
@@ -66665,7 +66547,7 @@ var petFeederCapability = {
|
|
|
66665
66547
|
},
|
|
66666
66548
|
desiccantLeftDays: {
|
|
66667
66549
|
kind: "gauge",
|
|
66668
|
-
unit: "
|
|
66550
|
+
unit: "s"
|
|
66669
66551
|
}
|
|
66670
66552
|
} }
|
|
66671
66553
|
};
|
|
@@ -67101,36 +66983,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
67101
66983
|
*/
|
|
67102
66984
|
var PowerMeterStatusSchema = object({
|
|
67103
66985
|
/** Instantaneous power draw in watts. */
|
|
67104
|
-
watts: number().optional().meta({
|
|
67105
|
-
unit: "W",
|
|
67106
|
-
label: "Power"
|
|
67107
|
-
}),
|
|
66986
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
67108
66987
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
67109
|
-
kwhTotal: number().optional().meta({
|
|
67110
|
-
unit: "kWh",
|
|
67111
|
-
label: "Energy"
|
|
67112
|
-
}),
|
|
66988
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
67113
66989
|
/** Voltage in volts. */
|
|
67114
|
-
volts: number().optional(),
|
|
66990
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
67115
66991
|
/** Current in amperes. */
|
|
67116
|
-
amps: number().optional(),
|
|
67117
|
-
/** Apparent power in volt-amperes
|
|
67118
|
-
va: number().optional(),
|
|
66992
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
66993
|
+
/** Apparent power in volt-amperes. */
|
|
66994
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
67119
66995
|
/** Power factor (0..1) if reported. */
|
|
67120
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
66996
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
67121
66997
|
/** Ms epoch when the slice was last updated. */
|
|
67122
|
-
lastFetchedAt: number()
|
|
67123
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
67124
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
67125
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
67126
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
67127
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
67128
|
-
unit: string().optional(),
|
|
67129
|
-
/** Suggested decimal places for numeric display.
|
|
67130
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67131
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67132
|
-
* auto-formatting when absent. */
|
|
67133
|
-
precision: number().int().min(0).max(10).optional()
|
|
66998
|
+
lastFetchedAt: number()
|
|
67134
66999
|
});
|
|
67135
67000
|
var powerMeterCapability = {
|
|
67136
67001
|
name: "power-meter",
|
|
@@ -67194,12 +67059,7 @@ var powerMeterCapability = {
|
|
|
67194
67059
|
} },
|
|
67195
67060
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67196
67061
|
* whether persisting is worth a SQLite commit. */
|
|
67197
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67198
|
-
customize: {
|
|
67199
|
-
version: 1,
|
|
67200
|
-
advanced: "derive",
|
|
67201
|
-
targets: []
|
|
67202
|
-
}
|
|
67062
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67203
67063
|
};
|
|
67204
67064
|
/**
|
|
67205
67065
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -67219,11 +67079,11 @@ var powerMeterCapability = {
|
|
|
67219
67079
|
*/
|
|
67220
67080
|
var GpsLocationSchema = object({
|
|
67221
67081
|
/** Latitude in decimal degrees, -90..90. */
|
|
67222
|
-
latitude: number().min(-90).max(90),
|
|
67082
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
67223
67083
|
/** Longitude in decimal degrees, -180..180. */
|
|
67224
|
-
longitude: number().min(-180).max(180),
|
|
67084
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
67225
67085
|
/** Reported accuracy in meters (lower = better). */
|
|
67226
|
-
accuracyMeters: number().nonnegative()
|
|
67086
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
67227
67087
|
});
|
|
67228
67088
|
var PresenceStatusSchema = object({
|
|
67229
67089
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -67235,7 +67095,7 @@ var PresenceStatusSchema = object({
|
|
|
67235
67095
|
gps: GpsLocationSchema.nullable(),
|
|
67236
67096
|
/** Optional battery level of the tracking device (0..100). Null
|
|
67237
67097
|
* when not reported. */
|
|
67238
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
67098
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67239
67099
|
/** Ms epoch when the slice was last updated. */
|
|
67240
67100
|
lastChangedAt: number()
|
|
67241
67101
|
});
|
|
@@ -67285,19 +67145,10 @@ var presenceCapability = {
|
|
|
67285
67145
|
* `sourceInfo`.
|
|
67286
67146
|
*/
|
|
67287
67147
|
var PressureSensorStatusSchema = object({
|
|
67288
|
-
/** Current pressure in hPa. */
|
|
67289
|
-
hpa: number(),
|
|
67148
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
67149
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
67290
67150
|
/** Ms epoch when the slice was last updated. */
|
|
67291
|
-
lastFetchedAt: number()
|
|
67292
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67293
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67294
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
67295
|
-
unit: string().optional(),
|
|
67296
|
-
/** Suggested decimal places for numeric display.
|
|
67297
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67298
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67299
|
-
* auto-formatting when absent. */
|
|
67300
|
-
precision: number().int().min(0).max(10).optional()
|
|
67151
|
+
lastFetchedAt: number()
|
|
67301
67152
|
});
|
|
67302
67153
|
var pressureSensorCapability = {
|
|
67303
67154
|
name: "pressure-sensor",
|
|
@@ -67711,8 +67562,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
67711
67562
|
}), _void(), { kind: "mutation" });
|
|
67712
67563
|
var PtzAutotrackSettingsSchema = object({
|
|
67713
67564
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
67714
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
67715
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
67565
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
67566
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
67716
67567
|
});
|
|
67717
67568
|
/**
|
|
67718
67569
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -67866,7 +67717,7 @@ var RunningStateStatusSchema = object({
|
|
|
67866
67717
|
/** null = unknown — never coerced to false (D393). */
|
|
67867
67718
|
running: boolean().nullable(),
|
|
67868
67719
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
67869
|
-
since: number().nullable(),
|
|
67720
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
67870
67721
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
67871
67722
|
phase: string().nullable(),
|
|
67872
67723
|
/** null until a reading has been published (D393). */
|
|
@@ -67881,7 +67732,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
67881
67732
|
/** Generic Customize target for the running boolean (D936). */
|
|
67882
67733
|
var runningCustomize = {
|
|
67883
67734
|
version: 1,
|
|
67884
|
-
advanced: "derive",
|
|
67885
67735
|
targets: [{
|
|
67886
67736
|
id: "running",
|
|
67887
67737
|
cardinality: "scalar",
|
|
@@ -67901,7 +67751,7 @@ var runningCustomize = {
|
|
|
67901
67751
|
DeviceType.Thermostat,
|
|
67902
67752
|
DeviceType.PetFeeder
|
|
67903
67753
|
],
|
|
67904
|
-
apply: "add
|
|
67754
|
+
apply: "add",
|
|
67905
67755
|
path: "running",
|
|
67906
67756
|
sources: [
|
|
67907
67757
|
{
|
|
@@ -67917,6 +67767,7 @@ var runningCustomize = {
|
|
|
67917
67767
|
requiredUnit: "W",
|
|
67918
67768
|
transforms: [{
|
|
67919
67769
|
kind: "threshold",
|
|
67770
|
+
comparisons: ["gte", "lte"],
|
|
67920
67771
|
comparison: "gte",
|
|
67921
67772
|
defaultThreshold: 5,
|
|
67922
67773
|
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
@@ -69196,9 +69047,9 @@ var RecordTriggerSchema = _enum([
|
|
|
69196
69047
|
*/
|
|
69197
69048
|
var RecordWindowSchema = object({
|
|
69198
69049
|
trigger: RecordTriggerSchema,
|
|
69199
|
-
day: number().int().min(0).max(6),
|
|
69200
|
-
startMinute: number().int().min(0).max(1439),
|
|
69201
|
-
endMinute: number().int().min(1).max(1440)
|
|
69050
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
69051
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
69052
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
69202
69053
|
});
|
|
69203
69054
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
69204
69055
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -69274,10 +69125,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
69274
69125
|
/** Master "record to the card at all" switch. */
|
|
69275
69126
|
enabled: boolean().nullable(),
|
|
69276
69127
|
overwriteWhenFull: boolean().nullable(),
|
|
69277
|
-
preRecordSec: number().nullable(),
|
|
69278
|
-
postRecordSec: number().nullable(),
|
|
69128
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
69129
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
69279
69130
|
/** Length of one recorded file, in minutes. */
|
|
69280
|
-
segmentMinutes: number().nullable(),
|
|
69131
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
69281
69132
|
/** The primary track's weekly windows, flattened. */
|
|
69282
69133
|
windows: array(RecordWindowSchema),
|
|
69283
69134
|
/**
|
|
@@ -69293,7 +69144,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
69293
69144
|
* provider reporting a non-zero count also reports the schedule as not
|
|
69294
69145
|
* writable.
|
|
69295
69146
|
*/
|
|
69296
|
-
unreadableWindows: number(),
|
|
69147
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
69297
69148
|
/**
|
|
69298
69149
|
* The camera is scheduled to record and has NO usable storage.
|
|
69299
69150
|
*
|
|
@@ -70156,7 +70007,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
70156
70007
|
url: string().optional(),
|
|
70157
70008
|
codec: string().optional(),
|
|
70158
70009
|
resolution: CamStreamResolutionSchema.optional(),
|
|
70159
|
-
fps: number().positive().optional(),
|
|
70010
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
70160
70011
|
label: string().optional(),
|
|
70161
70012
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
70162
70013
|
deviceFeatures: array(string()).optional(),
|
|
@@ -70243,18 +70094,18 @@ var StreamProfileSchema = _enum([
|
|
|
70243
70094
|
]);
|
|
70244
70095
|
/** The current encoding config of one stream profile. */
|
|
70245
70096
|
var StreamProfileConfigSchema = object({
|
|
70246
|
-
width: number(),
|
|
70247
|
-
height: number(),
|
|
70097
|
+
width: number().meta(readingMeta("none")),
|
|
70098
|
+
height: number().meta(readingMeta("none")),
|
|
70248
70099
|
codec: _enum(["h264", "h265"]),
|
|
70249
|
-
framerate: number(),
|
|
70250
|
-
bitrate: number(),
|
|
70100
|
+
framerate: number().meta(readingMeta("rate")),
|
|
70101
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
70251
70102
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
70252
70103
|
encoderProfile: _enum([
|
|
70253
70104
|
"high",
|
|
70254
70105
|
"main",
|
|
70255
70106
|
"baseline"
|
|
70256
70107
|
]).optional(),
|
|
70257
|
-
gop: number().optional(),
|
|
70108
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
70258
70109
|
/**
|
|
70259
70110
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
70260
70111
|
*
|
|
@@ -70475,12 +70326,7 @@ var switchCapability = {
|
|
|
70475
70326
|
label: "On",
|
|
70476
70327
|
kind: "boolean"
|
|
70477
70328
|
}
|
|
70478
|
-
}] }
|
|
70479
|
-
customize: {
|
|
70480
|
-
version: 1,
|
|
70481
|
-
advanced: "derive",
|
|
70482
|
-
targets: []
|
|
70483
|
-
}
|
|
70329
|
+
}] }
|
|
70484
70330
|
};
|
|
70485
70331
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
70486
70332
|
function hasControlCharacter(value) {
|
|
@@ -71063,35 +70909,21 @@ var tamperCapability = {
|
|
|
71063
70909
|
* entries with `device_class: temperature` and any future native
|
|
71064
70910
|
* thermometer.
|
|
71065
70911
|
*
|
|
71066
|
-
*
|
|
71067
|
-
*
|
|
71068
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
71069
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
71070
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
71071
|
-
* `sourceInfo`.
|
|
70912
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
70913
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
71072
70914
|
*
|
|
71073
70915
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
71074
70916
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
71075
70917
|
* changed" steady state.
|
|
71076
70918
|
*/
|
|
71077
70919
|
var TemperatureSensorStatusSchema = object({
|
|
71078
|
-
/** Current temperature in Celsius. */
|
|
71079
|
-
celsius: number().meta({
|
|
71080
|
-
|
|
70920
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
70921
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
70922
|
+
precision: 1,
|
|
71081
70923
|
label: "Temperature"
|
|
71082
|
-
}),
|
|
70924
|
+
})),
|
|
71083
70925
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
71084
|
-
lastFetchedAt: number()
|
|
71085
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
71086
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
71087
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
71088
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
71089
|
-
unit: string().optional(),
|
|
71090
|
-
/** Suggested decimal places for numeric display.
|
|
71091
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
71092
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
71093
|
-
* auto-formatting when absent. */
|
|
71094
|
-
precision: number().int().min(0).max(10).optional()
|
|
70926
|
+
lastFetchedAt: number()
|
|
71095
70927
|
});
|
|
71096
70928
|
var temperatureSensorCapability = {
|
|
71097
70929
|
name: "temperature-sensor",
|
|
@@ -71122,12 +70954,7 @@ var temperatureSensorCapability = {
|
|
|
71122
70954
|
} } },
|
|
71123
70955
|
/** Clock fields: written, but excluded from the compare that decides
|
|
71124
70956
|
* whether persisting is worth a SQLite commit. */
|
|
71125
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
71126
|
-
customize: {
|
|
71127
|
-
version: 1,
|
|
71128
|
-
advanced: "derive",
|
|
71129
|
-
targets: []
|
|
71130
|
-
}
|
|
70957
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
71131
70958
|
};
|
|
71132
70959
|
/**
|
|
71133
70960
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -71410,16 +71237,16 @@ var VacuumControlStatusSchema = object({
|
|
|
71410
71237
|
]),
|
|
71411
71238
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
71412
71239
|
* reading. */
|
|
71413
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
71240
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71414
71241
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
71415
71242
|
* the vacuum has no speed control. */
|
|
71416
71243
|
fanSpeed: string().nullable(),
|
|
71417
71244
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
71418
71245
|
availableFanSpeeds: array(string()),
|
|
71419
71246
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
71420
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
71247
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71421
71248
|
/** Current error code (0 / null = no error). */
|
|
71422
|
-
errorCode: number().nullable(),
|
|
71249
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
71423
71250
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
71424
71251
|
errorLabel: string().nullable(),
|
|
71425
71252
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -71497,7 +71324,7 @@ var ValveStatusSchema = object({
|
|
|
71497
71324
|
]),
|
|
71498
71325
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
71499
71326
|
* intermediate position surface. */
|
|
71500
|
-
position: number().min(0).max(100).nullable(),
|
|
71327
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
71501
71328
|
/** Ms epoch when the slice was last updated. */
|
|
71502
71329
|
lastChangedAt: number()
|
|
71503
71330
|
});
|
|
@@ -71605,9 +71432,9 @@ var vibrationCapability = {
|
|
|
71605
71432
|
*/
|
|
71606
71433
|
var WaterHeaterStatusSchema = object({
|
|
71607
71434
|
/** Current measured temperature. Null when not reported. */
|
|
71608
|
-
currentTemp: number().nullable(),
|
|
71435
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71609
71436
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
71610
|
-
targetTemp: number().nullable(),
|
|
71437
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71611
71438
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
71612
71439
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
71613
71440
|
* device reports an unknown state. */
|
|
@@ -71618,9 +71445,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
71618
71445
|
* has no away surface. */
|
|
71619
71446
|
away: boolean().nullable(),
|
|
71620
71447
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
71621
|
-
minTemp: number().nullable(),
|
|
71448
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71622
71449
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
71623
|
-
maxTemp: number().nullable(),
|
|
71450
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
71624
71451
|
/** Ms epoch when the slice was last updated. */
|
|
71625
71452
|
lastChangedAt: number()
|
|
71626
71453
|
});
|
|
@@ -71705,25 +71532,18 @@ var waterHeaterCapability = {
|
|
|
71705
71532
|
* Forecast deferred — current conditions only for v1.
|
|
71706
71533
|
*/
|
|
71707
71534
|
var WeatherStatusSchema = object({
|
|
71708
|
-
/** Verbatim
|
|
71709
|
-
* when no condition has been reported yet. */
|
|
71535
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
71710
71536
|
condition: string().nullable(),
|
|
71711
|
-
/** Current temperature in
|
|
71712
|
-
temperature: number().nullable(),
|
|
71713
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
71714
|
-
temperatureUnit: string().nullable(),
|
|
71537
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
71538
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
71715
71539
|
/** Relative humidity (0..100). Null when not provided. */
|
|
71716
|
-
humidity: number().min(0).max(100).nullable(),
|
|
71717
|
-
/** Barometric pressure in
|
|
71718
|
-
pressure: number().nullable(),
|
|
71719
|
-
/**
|
|
71720
|
-
|
|
71721
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
71722
|
-
windSpeed: number().nullable(),
|
|
71723
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
71724
|
-
windSpeedUnit: string().nullable(),
|
|
71540
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
71541
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
71542
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
71543
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
71544
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
71725
71545
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
71726
|
-
windBearing: number().nullable(),
|
|
71546
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
71727
71547
|
/** Ms epoch when the slice was last updated. */
|
|
71728
71548
|
lastFetchedAt: number()
|
|
71729
71549
|
});
|
|
@@ -71751,12 +71571,12 @@ var weatherCapability = {
|
|
|
71751
71571
|
*/
|
|
71752
71572
|
durability: "session",
|
|
71753
71573
|
/**
|
|
71754
|
-
* History (D850): recorded series.
|
|
71574
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
71755
71575
|
*/
|
|
71756
71576
|
history: { fields: {
|
|
71757
71577
|
temperature: {
|
|
71758
71578
|
kind: "gauge",
|
|
71759
|
-
|
|
71579
|
+
unit: "°C",
|
|
71760
71580
|
deadband: .2
|
|
71761
71581
|
},
|
|
71762
71582
|
humidity: {
|
|
@@ -71766,12 +71586,12 @@ var weatherCapability = {
|
|
|
71766
71586
|
},
|
|
71767
71587
|
pressure: {
|
|
71768
71588
|
kind: "gauge",
|
|
71769
|
-
|
|
71589
|
+
unit: "hPa",
|
|
71770
71590
|
deadband: .5
|
|
71771
71591
|
},
|
|
71772
71592
|
windSpeed: {
|
|
71773
71593
|
kind: "gauge",
|
|
71774
|
-
|
|
71594
|
+
unit: "m/s",
|
|
71775
71595
|
deadband: .5
|
|
71776
71596
|
}
|
|
71777
71597
|
} }
|
|
@@ -86911,7 +86731,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86911
86731
|
field: "value",
|
|
86912
86732
|
quantity: t("the reading", "il valore"),
|
|
86913
86733
|
label: t("Reading", "Valore"),
|
|
86914
|
-
unitField: "unit",
|
|
86915
86734
|
icon: "gauge"
|
|
86916
86735
|
}]
|
|
86917
86736
|
},
|
|
@@ -87047,7 +86866,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87047
86866
|
field: "temperature",
|
|
87048
86867
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
87049
86868
|
label: t("Temperature", "Temperatura"),
|
|
87050
|
-
|
|
86869
|
+
unit: "°C",
|
|
87051
86870
|
icon: "thermometer"
|
|
87052
86871
|
},
|
|
87053
86872
|
{
|
|
@@ -87063,7 +86882,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87063
86882
|
field: "windSpeed",
|
|
87064
86883
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
87065
86884
|
label: t("Wind", "Vento"),
|
|
87066
|
-
|
|
86885
|
+
unit: "m/s",
|
|
87067
86886
|
icon: "wind"
|
|
87068
86887
|
},
|
|
87069
86888
|
{
|
|
@@ -87071,7 +86890,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
87071
86890
|
field: "pressure",
|
|
87072
86891
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
87073
86892
|
label: t("Pressure", "Pressione"),
|
|
87074
|
-
|
|
86893
|
+
unit: "hPa",
|
|
87075
86894
|
icon: "gauge"
|
|
87076
86895
|
}
|
|
87077
86896
|
]
|
|
@@ -90305,6 +90124,11 @@ var PulseOverrideDraftSchema = object({
|
|
|
90305
90124
|
targetId: string().min(1),
|
|
90306
90125
|
enabled: boolean(),
|
|
90307
90126
|
debounceMs: number().nonnegative(),
|
|
90127
|
+
edges: array(_enum([
|
|
90128
|
+
"rising",
|
|
90129
|
+
"button",
|
|
90130
|
+
"native-event"
|
|
90131
|
+
])).min(1).optional(),
|
|
90308
90132
|
sources: array(OverrideSourceSchema).min(1)
|
|
90309
90133
|
});
|
|
90310
90134
|
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
|