@camstack/addon-matter-broker 0.2.147 → 0.2.148
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/addon.js +312 -496
- package/dist/addon.mjs +312 -496
- package/package.json +1 -1
package/dist/addon.mjs
CHANGED
|
@@ -5579,7 +5579,7 @@ var ZodIssueCode = {
|
|
|
5579
5579
|
var ZodFirstPartyTypeKind;
|
|
5580
5580
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5581
5581
|
//#endregion
|
|
5582
|
-
//#region ../types/dist/sleep-
|
|
5582
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5583
5583
|
/**
|
|
5584
5584
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5585
5585
|
* window to float samples (D455).
|
|
@@ -8321,6 +8321,52 @@ function defineEntryKind(name, spec) {
|
|
|
8321
8321
|
if (defined === void 0) throw new DeclarationRefusedError(`entry kind "${name}" was not built`);
|
|
8322
8322
|
return defined;
|
|
8323
8323
|
}
|
|
8324
|
+
var READING_QUANTITIES = [
|
|
8325
|
+
"temperature",
|
|
8326
|
+
"pressure",
|
|
8327
|
+
"speed",
|
|
8328
|
+
"precipitation",
|
|
8329
|
+
"precipitation-rate",
|
|
8330
|
+
"length",
|
|
8331
|
+
"area",
|
|
8332
|
+
"illuminance",
|
|
8333
|
+
"irradiance",
|
|
8334
|
+
"power",
|
|
8335
|
+
"energy",
|
|
8336
|
+
"voltage",
|
|
8337
|
+
"current",
|
|
8338
|
+
"apparent-power",
|
|
8339
|
+
"humidity",
|
|
8340
|
+
"percentage",
|
|
8341
|
+
"concentration-volume",
|
|
8342
|
+
"concentration-mass",
|
|
8343
|
+
"concentration-ppb",
|
|
8344
|
+
"volume",
|
|
8345
|
+
"duration",
|
|
8346
|
+
"duration-ms",
|
|
8347
|
+
"information",
|
|
8348
|
+
"sound-level",
|
|
8349
|
+
"signal-level",
|
|
8350
|
+
"colour-temperature",
|
|
8351
|
+
"angle",
|
|
8352
|
+
"bitrate",
|
|
8353
|
+
"rate",
|
|
8354
|
+
"mass",
|
|
8355
|
+
"index",
|
|
8356
|
+
"ratio",
|
|
8357
|
+
"count",
|
|
8358
|
+
"none",
|
|
8359
|
+
"device"
|
|
8360
|
+
];
|
|
8361
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8362
|
+
new Set(READING_QUANTITIES);
|
|
8363
|
+
function readingMeta(quantity, extras) {
|
|
8364
|
+
return {
|
|
8365
|
+
quantity,
|
|
8366
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8367
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8368
|
+
};
|
|
8369
|
+
}
|
|
8324
8370
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
8325
8371
|
var CamProfileSchema = _enum([
|
|
8326
8372
|
"high",
|
|
@@ -8348,8 +8394,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8348
8394
|
"derived"
|
|
8349
8395
|
]);
|
|
8350
8396
|
var CamStreamResolutionSchema = object({
|
|
8351
|
-
width: number().int().positive(),
|
|
8352
|
-
height: number().int().positive()
|
|
8397
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8398
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8353
8399
|
});
|
|
8354
8400
|
var CameraStreamSchema = object({
|
|
8355
8401
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8996,14 +9042,6 @@ Object.freeze({
|
|
|
8996
9042
|
{
|
|
8997
9043
|
"path": "aqi",
|
|
8998
9044
|
"valueType": "number"
|
|
8999
|
-
},
|
|
9000
|
-
{
|
|
9001
|
-
"path": "unit",
|
|
9002
|
-
"valueType": "string"
|
|
9003
|
-
},
|
|
9004
|
-
{
|
|
9005
|
-
"path": "precision",
|
|
9006
|
-
"valueType": "number"
|
|
9007
9045
|
}
|
|
9008
9046
|
],
|
|
9009
9047
|
"alarm-panel": [
|
|
@@ -9039,20 +9077,10 @@ Object.freeze({
|
|
|
9039
9077
|
"valueType": "boolean"
|
|
9040
9078
|
}
|
|
9041
9079
|
],
|
|
9042
|
-
"ambient-light-sensor": [
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
},
|
|
9047
|
-
{
|
|
9048
|
-
"path": "unit",
|
|
9049
|
-
"valueType": "string"
|
|
9050
|
-
},
|
|
9051
|
-
{
|
|
9052
|
-
"path": "precision",
|
|
9053
|
-
"valueType": "number"
|
|
9054
|
-
}
|
|
9055
|
-
],
|
|
9080
|
+
"ambient-light-sensor": [{
|
|
9081
|
+
"path": "lux",
|
|
9082
|
+
"valueType": "number"
|
|
9083
|
+
}],
|
|
9056
9084
|
"audio-metrics": [
|
|
9057
9085
|
{
|
|
9058
9086
|
"path": "ts",
|
|
@@ -9132,6 +9160,10 @@ Object.freeze({
|
|
|
9132
9160
|
"path": "lastUpdated",
|
|
9133
9161
|
"valueType": "number"
|
|
9134
9162
|
},
|
|
9163
|
+
{
|
|
9164
|
+
"path": "volts",
|
|
9165
|
+
"valueType": "number"
|
|
9166
|
+
},
|
|
9135
9167
|
{
|
|
9136
9168
|
"path": "lastContactAt",
|
|
9137
9169
|
"valueType": "number"
|
|
@@ -9374,10 +9406,6 @@ Object.freeze({
|
|
|
9374
9406
|
"datetime"
|
|
9375
9407
|
]
|
|
9376
9408
|
},
|
|
9377
|
-
{
|
|
9378
|
-
"path": "unit",
|
|
9379
|
-
"valueType": "string"
|
|
9380
|
-
},
|
|
9381
9409
|
{
|
|
9382
9410
|
"path": "min",
|
|
9383
9411
|
"valueType": "number"
|
|
@@ -9389,19 +9417,6 @@ Object.freeze({
|
|
|
9389
9417
|
{
|
|
9390
9418
|
"path": "step",
|
|
9391
9419
|
"valueType": "number"
|
|
9392
|
-
},
|
|
9393
|
-
{
|
|
9394
|
-
"path": "precision",
|
|
9395
|
-
"valueType": "number"
|
|
9396
|
-
},
|
|
9397
|
-
{
|
|
9398
|
-
"path": "format",
|
|
9399
|
-
"valueType": "enum",
|
|
9400
|
-
"enumValues": [
|
|
9401
|
-
"date",
|
|
9402
|
-
"time",
|
|
9403
|
-
"datetime"
|
|
9404
|
-
]
|
|
9405
9420
|
}
|
|
9406
9421
|
],
|
|
9407
9422
|
"cover": [
|
|
@@ -9642,13 +9657,8 @@ Object.freeze({
|
|
|
9642
9657
|
"path": "value",
|
|
9643
9658
|
"valueType": "string"
|
|
9644
9659
|
}, {
|
|
9645
|
-
"path": "
|
|
9646
|
-
"valueType": "
|
|
9647
|
-
"enumValues": [
|
|
9648
|
-
"date",
|
|
9649
|
-
"time",
|
|
9650
|
-
"datetime"
|
|
9651
|
-
]
|
|
9660
|
+
"path": "timestamp",
|
|
9661
|
+
"valueType": "boolean"
|
|
9652
9662
|
}],
|
|
9653
9663
|
"event-emitter": [
|
|
9654
9664
|
{
|
|
@@ -9755,20 +9765,10 @@ Object.freeze({
|
|
|
9755
9765
|
"valueType": "number"
|
|
9756
9766
|
}
|
|
9757
9767
|
],
|
|
9758
|
-
"humidity-sensor": [
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
},
|
|
9763
|
-
{
|
|
9764
|
-
"path": "unit",
|
|
9765
|
-
"valueType": "string"
|
|
9766
|
-
},
|
|
9767
|
-
{
|
|
9768
|
-
"path": "precision",
|
|
9769
|
-
"valueType": "number"
|
|
9770
|
-
}
|
|
9771
|
-
],
|
|
9768
|
+
"humidity-sensor": [{
|
|
9769
|
+
"path": "percent",
|
|
9770
|
+
"valueType": "number"
|
|
9771
|
+
}],
|
|
9772
9772
|
"image": [{
|
|
9773
9773
|
"path": "url",
|
|
9774
9774
|
"valueType": "string"
|
|
@@ -10107,20 +10107,10 @@ Object.freeze({
|
|
|
10107
10107
|
"valueType": "boolean"
|
|
10108
10108
|
}
|
|
10109
10109
|
],
|
|
10110
|
-
"numeric-sensor": [
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
},
|
|
10115
|
-
{
|
|
10116
|
-
"path": "unit",
|
|
10117
|
-
"valueType": "string"
|
|
10118
|
-
},
|
|
10119
|
-
{
|
|
10120
|
-
"path": "precision",
|
|
10121
|
-
"valueType": "number"
|
|
10122
|
-
}
|
|
10123
|
-
],
|
|
10110
|
+
"numeric-sensor": [{
|
|
10111
|
+
"path": "value",
|
|
10112
|
+
"valueType": "number"
|
|
10113
|
+
}],
|
|
10124
10114
|
"pet-feeder": [
|
|
10125
10115
|
{
|
|
10126
10116
|
"path": "foodLevel",
|
|
@@ -10212,14 +10202,6 @@ Object.freeze({
|
|
|
10212
10202
|
{
|
|
10213
10203
|
"path": "powerFactor",
|
|
10214
10204
|
"valueType": "number"
|
|
10215
|
-
},
|
|
10216
|
-
{
|
|
10217
|
-
"path": "unit",
|
|
10218
|
-
"valueType": "string"
|
|
10219
|
-
},
|
|
10220
|
-
{
|
|
10221
|
-
"path": "precision",
|
|
10222
|
-
"valueType": "number"
|
|
10223
10205
|
}
|
|
10224
10206
|
],
|
|
10225
10207
|
"presence": [
|
|
@@ -10248,20 +10230,10 @@ Object.freeze({
|
|
|
10248
10230
|
"valueType": "number"
|
|
10249
10231
|
}
|
|
10250
10232
|
],
|
|
10251
|
-
"pressure-sensor": [
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
},
|
|
10256
|
-
{
|
|
10257
|
-
"path": "unit",
|
|
10258
|
-
"valueType": "string"
|
|
10259
|
-
},
|
|
10260
|
-
{
|
|
10261
|
-
"path": "precision",
|
|
10262
|
-
"valueType": "number"
|
|
10263
|
-
}
|
|
10264
|
-
],
|
|
10233
|
+
"pressure-sensor": [{
|
|
10234
|
+
"path": "hpa",
|
|
10235
|
+
"valueType": "number"
|
|
10236
|
+
}],
|
|
10265
10237
|
"privacy-mask": [{
|
|
10266
10238
|
"path": "enabled",
|
|
10267
10239
|
"valueType": "boolean"
|
|
@@ -10572,20 +10544,10 @@ Object.freeze({
|
|
|
10572
10544
|
"path": "tampered",
|
|
10573
10545
|
"valueType": "boolean"
|
|
10574
10546
|
}],
|
|
10575
|
-
"temperature-sensor": [
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
},
|
|
10580
|
-
{
|
|
10581
|
-
"path": "unit",
|
|
10582
|
-
"valueType": "string"
|
|
10583
|
-
},
|
|
10584
|
-
{
|
|
10585
|
-
"path": "precision",
|
|
10586
|
-
"valueType": "number"
|
|
10587
|
-
}
|
|
10588
|
-
],
|
|
10547
|
+
"temperature-sensor": [{
|
|
10548
|
+
"path": "celsius",
|
|
10549
|
+
"valueType": "number"
|
|
10550
|
+
}],
|
|
10589
10551
|
"update": [
|
|
10590
10552
|
{
|
|
10591
10553
|
"path": "currentVersion",
|
|
@@ -10696,10 +10658,6 @@ Object.freeze({
|
|
|
10696
10658
|
"path": "temperature",
|
|
10697
10659
|
"valueType": "number"
|
|
10698
10660
|
},
|
|
10699
|
-
{
|
|
10700
|
-
"path": "temperatureUnit",
|
|
10701
|
-
"valueType": "string"
|
|
10702
|
-
},
|
|
10703
10661
|
{
|
|
10704
10662
|
"path": "humidity",
|
|
10705
10663
|
"valueType": "number"
|
|
@@ -10708,18 +10666,10 @@ Object.freeze({
|
|
|
10708
10666
|
"path": "pressure",
|
|
10709
10667
|
"valueType": "number"
|
|
10710
10668
|
},
|
|
10711
|
-
{
|
|
10712
|
-
"path": "pressureUnit",
|
|
10713
|
-
"valueType": "string"
|
|
10714
|
-
},
|
|
10715
10669
|
{
|
|
10716
10670
|
"path": "windSpeed",
|
|
10717
10671
|
"valueType": "number"
|
|
10718
10672
|
},
|
|
10719
|
-
{
|
|
10720
|
-
"path": "windSpeedUnit",
|
|
10721
|
-
"valueType": "string"
|
|
10722
|
-
},
|
|
10723
10673
|
{
|
|
10724
10674
|
"path": "windBearing",
|
|
10725
10675
|
"valueType": "number"
|
|
@@ -18232,7 +18182,8 @@ var CompositionProblemSchema = object({
|
|
|
18232
18182
|
"item-field-reserved",
|
|
18233
18183
|
"target-missing",
|
|
18234
18184
|
"target-unreadable",
|
|
18235
|
-
"not-replaceable"
|
|
18185
|
+
"not-replaceable",
|
|
18186
|
+
"native-capability-replace"
|
|
18236
18187
|
]),
|
|
18237
18188
|
path: string$2(),
|
|
18238
18189
|
message: string$2()
|
|
@@ -18290,9 +18241,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
18290
18241
|
reads: array(CompositionFieldReadSchema)
|
|
18291
18242
|
});
|
|
18292
18243
|
/**
|
|
18293
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
18294
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
18295
|
-
*
|
|
18244
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
18245
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
18246
|
+
* Replacing a capability the device already serves is refused
|
|
18247
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
18248
|
+
* wire for a claim the hub already holds.
|
|
18296
18249
|
*/
|
|
18297
18250
|
var CompositionFeatureModeSchema = _enum([
|
|
18298
18251
|
"new",
|
|
@@ -20178,12 +20131,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
20178
20131
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20179
20132
|
* in-place so dispatch keeps working.
|
|
20180
20133
|
*
|
|
20181
|
-
* **
|
|
20182
|
-
*
|
|
20183
|
-
*
|
|
20184
|
-
*
|
|
20185
|
-
* (`ha-domain-mapping`)
|
|
20186
|
-
* stored after that point.
|
|
20134
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20135
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20136
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20137
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20138
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20139
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20187
20140
|
*
|
|
20188
20141
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20189
20142
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20197,6 +20150,14 @@ var SourceInfoSchema = object({
|
|
|
20197
20150
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20198
20151
|
* Used to detect rename when `id` changes. */
|
|
20199
20152
|
uniqueId: string$2().optional(),
|
|
20153
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20154
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20155
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20156
|
+
dateTimeShape: _enum([
|
|
20157
|
+
"date",
|
|
20158
|
+
"time",
|
|
20159
|
+
"datetime"
|
|
20160
|
+
]).optional(),
|
|
20200
20161
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20201
20162
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20202
20163
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -41318,7 +41279,8 @@ method(object({
|
|
|
41318
41279
|
"enum"
|
|
41319
41280
|
]),
|
|
41320
41281
|
enumValues: array(string$2()).optional(),
|
|
41321
|
-
item: boolean().optional()
|
|
41282
|
+
item: boolean().optional(),
|
|
41283
|
+
quantity: ReadingQuantitySchema.optional()
|
|
41322
41284
|
})).readonly(),
|
|
41323
41285
|
itemArray: object({
|
|
41324
41286
|
path: string$2(),
|
|
@@ -45162,8 +45124,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
45162
45124
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
45163
45125
|
var MaskGridShapeSchema = object({
|
|
45164
45126
|
kind: literal("grid"),
|
|
45165
|
-
gridWidth: number(),
|
|
45166
|
-
gridHeight: number(),
|
|
45127
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
45128
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
45167
45129
|
cells: array(boolean())
|
|
45168
45130
|
});
|
|
45169
45131
|
discriminatedUnion("kind", [
|
|
@@ -56643,27 +56605,17 @@ method(object({ nodeId: string$2().optional() }).optional(), array(AddonListItem
|
|
|
56643
56605
|
*/
|
|
56644
56606
|
var AirQualitySensorStatusSchema = object({
|
|
56645
56607
|
/** Carbon dioxide concentration in ppm. */
|
|
56646
|
-
co2Ppm: number().min(0).optional(),
|
|
56608
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56647
56609
|
/** Total volatile organic compounds in ppb. */
|
|
56648
|
-
vocPpb: number().min(0).optional(),
|
|
56610
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56649
56611
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56650
|
-
pm25: number().min(0).optional(),
|
|
56612
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56651
56613
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56652
|
-
pm10: number().min(0).optional(),
|
|
56614
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56653
56615
|
/** Composite AQI value (typically 0..500). */
|
|
56654
|
-
aqi: number().optional(),
|
|
56616
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56655
56617
|
/** Ms epoch when the slice was last updated. */
|
|
56656
|
-
lastFetchedAt: number()
|
|
56657
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56658
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56659
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56660
|
-
* per slice is unambiguous. */
|
|
56661
|
-
unit: string$2().optional(),
|
|
56662
|
-
/** Suggested decimal places for numeric display.
|
|
56663
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56664
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56665
|
-
* auto-formatting when absent. */
|
|
56666
|
-
precision: number().int().min(0).max(10).optional()
|
|
56618
|
+
lastFetchedAt: number()
|
|
56667
56619
|
});
|
|
56668
56620
|
var airQualitySensorCapability = {
|
|
56669
56621
|
name: "air-quality-sensor",
|
|
@@ -56700,12 +56652,12 @@ var airQualitySensorCapability = {
|
|
|
56700
56652
|
},
|
|
56701
56653
|
pm25: {
|
|
56702
56654
|
kind: "gauge",
|
|
56703
|
-
unit: "
|
|
56655
|
+
unit: "µg/m³",
|
|
56704
56656
|
deadband: 1
|
|
56705
56657
|
},
|
|
56706
56658
|
pm10: {
|
|
56707
56659
|
kind: "gauge",
|
|
56708
|
-
unit: "
|
|
56660
|
+
unit: "µg/m³",
|
|
56709
56661
|
deadband: 1
|
|
56710
56662
|
},
|
|
56711
56663
|
aqi: {
|
|
@@ -56723,22 +56675,13 @@ var airQualitySensorCapability = {
|
|
|
56723
56675
|
* entries with `device_class: illuminance`.
|
|
56724
56676
|
*/
|
|
56725
56677
|
var AmbientLightSensorStatusSchema = object({
|
|
56726
|
-
/** Current illuminance in lux (lx). */
|
|
56727
|
-
lux: number().min(0).meta({
|
|
56728
|
-
|
|
56678
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56679
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56680
|
+
precision: 0,
|
|
56729
56681
|
label: "Illuminance"
|
|
56730
|
-
}),
|
|
56682
|
+
})),
|
|
56731
56683
|
/** Ms epoch when the slice was last updated. */
|
|
56732
|
-
lastFetchedAt: number()
|
|
56733
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56734
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56735
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56736
|
-
unit: string$2().optional(),
|
|
56737
|
-
/** Suggested decimal places for numeric display.
|
|
56738
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56739
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56740
|
-
* auto-formatting when absent. */
|
|
56741
|
-
precision: number().int().min(0).max(10).optional()
|
|
56684
|
+
lastFetchedAt: number()
|
|
56742
56685
|
});
|
|
56743
56686
|
var ambientLightSensorCapability = {
|
|
56744
56687
|
name: "ambient-light-sensor",
|
|
@@ -56770,12 +56713,7 @@ var ambientLightSensorCapability = {
|
|
|
56770
56713
|
} } },
|
|
56771
56714
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56772
56715
|
* whether persisting is worth a SQLite commit. */
|
|
56773
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56774
|
-
customize: {
|
|
56775
|
-
version: 1,
|
|
56776
|
-
advanced: "derive",
|
|
56777
|
-
targets: []
|
|
56778
|
-
}
|
|
56716
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56779
56717
|
};
|
|
56780
56718
|
/**
|
|
56781
56719
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -57002,10 +56940,7 @@ var BatteryStatusSchema = object({
|
|
|
57002
56940
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57003
56941
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57004
56942
|
*/
|
|
57005
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
57006
|
-
unit: "%",
|
|
57007
|
-
label: "Charge"
|
|
57008
|
-
}),
|
|
56943
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57009
56944
|
/**
|
|
57010
56945
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57011
56946
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57032,7 +56967,14 @@ var BatteryStatusSchema = object({
|
|
|
57032
56967
|
*/
|
|
57033
56968
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
57034
56969
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
57035
|
-
lastUpdated: number(),
|
|
56970
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56971
|
+
/**
|
|
56972
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56973
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56974
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56975
|
+
* `numeric-sensor` on the same device.
|
|
56976
|
+
*/
|
|
56977
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57036
56978
|
/**
|
|
57037
56979
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57038
56980
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57084,7 +57026,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57084
57026
|
/** Generic Customize target for the percentage reading (D936). */
|
|
57085
57027
|
var batteryCustomize = {
|
|
57086
57028
|
version: 1,
|
|
57087
|
-
advanced: "derive",
|
|
57088
57029
|
targets: [{
|
|
57089
57030
|
id: "percentage",
|
|
57090
57031
|
cardinality: "scalar",
|
|
@@ -57093,7 +57034,7 @@ var batteryCustomize = {
|
|
|
57093
57034
|
stateField: "percentage"
|
|
57094
57035
|
},
|
|
57095
57036
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57096
|
-
apply: "add
|
|
57037
|
+
apply: "add",
|
|
57097
57038
|
path: "percentage",
|
|
57098
57039
|
sources: [{
|
|
57099
57040
|
kind: "field",
|
|
@@ -57214,10 +57155,16 @@ onStatusChanged: { data: object({
|
|
|
57214
57155
|
/**
|
|
57215
57156
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57216
57157
|
*/
|
|
57217
|
-
history: { fields: {
|
|
57218
|
-
|
|
57219
|
-
|
|
57220
|
-
|
|
57158
|
+
history: { fields: {
|
|
57159
|
+
percentage: {
|
|
57160
|
+
kind: "gauge",
|
|
57161
|
+
unit: "%"
|
|
57162
|
+
},
|
|
57163
|
+
volts: {
|
|
57164
|
+
kind: "gauge",
|
|
57165
|
+
unit: "V"
|
|
57166
|
+
}
|
|
57167
|
+
} },
|
|
57221
57168
|
customize: batteryCustomize,
|
|
57222
57169
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57223
57170
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -57264,12 +57211,7 @@ var binaryCapability = {
|
|
|
57264
57211
|
history: { fields: { on: { kind: "boolean" } } },
|
|
57265
57212
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57266
57213
|
* whether persisting is worth a SQLite commit. */
|
|
57267
|
-
volatileStateFields: ["lastChangedAt"]
|
|
57268
|
-
customize: {
|
|
57269
|
-
version: 1,
|
|
57270
|
-
advanced: "derive",
|
|
57271
|
-
targets: []
|
|
57272
|
-
}
|
|
57214
|
+
volatileStateFields: ["lastChangedAt"]
|
|
57273
57215
|
};
|
|
57274
57216
|
/**
|
|
57275
57217
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -57285,7 +57227,7 @@ var binaryCapability = {
|
|
|
57285
57227
|
*/
|
|
57286
57228
|
var BrightnessStatusSchema = object({
|
|
57287
57229
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57288
|
-
percentage: number().min(0).max(100),
|
|
57230
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57289
57231
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57290
57232
|
lastChangedAt: number()
|
|
57291
57233
|
});
|
|
@@ -57756,21 +57698,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57756
57698
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57757
57699
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57758
57700
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57759
|
-
target: number().nullable(),
|
|
57701
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57760
57702
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57761
57703
|
* in `heat_cool` mode. */
|
|
57762
|
-
targetHigh: number().nullable(),
|
|
57704
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57763
57705
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57764
57706
|
* in `heat_cool` mode. */
|
|
57765
|
-
targetLow: number().nullable(),
|
|
57707
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57766
57708
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57767
57709
|
* humidity control. */
|
|
57768
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57710
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57769
57711
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57770
57712
|
* the device's internal sensor. */
|
|
57771
|
-
currentTemp: number().nullable(),
|
|
57713
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57772
57714
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57773
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57715
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57774
57716
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57775
57717
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57776
57718
|
swingVertical: boolean().nullable(),
|
|
@@ -57778,11 +57720,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57778
57720
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57779
57721
|
swingHorizontal: boolean().nullable(),
|
|
57780
57722
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57781
|
-
minTemp: number().nullable().optional(),
|
|
57723
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57782
57724
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57783
|
-
maxTemp: number().nullable().optional(),
|
|
57725
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57784
57726
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57785
|
-
tempStep: number().positive().nullable().optional(),
|
|
57727
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57786
57728
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57787
57729
|
lastFetchedAt: number()
|
|
57788
57730
|
});
|
|
@@ -57924,17 +57866,17 @@ var climateControlCapability = {
|
|
|
57924
57866
|
* modes to expose in the picker without a slice fetch.
|
|
57925
57867
|
*/
|
|
57926
57868
|
var RgbTripletSchema = object({
|
|
57927
|
-
r: number().int().min(0).max(255),
|
|
57928
|
-
g: number().int().min(0).max(255),
|
|
57929
|
-
b: number().int().min(0).max(255)
|
|
57869
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57870
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57871
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57930
57872
|
});
|
|
57931
57873
|
var HsvTripletSchema = object({
|
|
57932
57874
|
/** Hue in degrees, 0..360. */
|
|
57933
|
-
h: number().min(0).max(360),
|
|
57875
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57934
57876
|
/** Saturation as 0..100 inclusive. */
|
|
57935
|
-
s: number().min(0).max(100),
|
|
57877
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57936
57878
|
/** Value/brightness as 0..100 inclusive. */
|
|
57937
|
-
v: number().min(0).max(100)
|
|
57879
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57938
57880
|
});
|
|
57939
57881
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57940
57882
|
object({
|
|
@@ -57963,7 +57905,7 @@ var ColorStatusSchema = object({
|
|
|
57963
57905
|
/** Populated when `mode === 'hsv'`. */
|
|
57964
57906
|
hsv: HsvTripletSchema.optional(),
|
|
57965
57907
|
/** Populated when `mode === 'mired'`. */
|
|
57966
|
-
mireds: number().int().optional(),
|
|
57908
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57967
57909
|
/** Ms epoch of the last operator-driven change. */
|
|
57968
57910
|
lastChangedAt: number()
|
|
57969
57911
|
});
|
|
@@ -58158,18 +58100,12 @@ _enum([
|
|
|
58158
58100
|
"empty",
|
|
58159
58101
|
"full"
|
|
58160
58102
|
]);
|
|
58161
|
-
/**
|
|
58162
|
-
|
|
58163
|
-
|
|
58164
|
-
"days",
|
|
58165
|
-
"hours",
|
|
58166
|
-
"cycles"
|
|
58167
|
-
]);
|
|
58168
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
58169
|
-
* days). `value` null = unknown (D393). */
|
|
58103
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
58104
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
58105
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
58170
58106
|
var ConsumableRemainingSchema = object({
|
|
58171
|
-
value: number().min(0).nullable(),
|
|
58172
|
-
|
|
58107
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
58108
|
+
kind: ConsumableRemainingKindSchema
|
|
58173
58109
|
});
|
|
58174
58110
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
58175
58111
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -58182,7 +58118,7 @@ var ConsumableItemSchema = object({
|
|
|
58182
58118
|
/** Display name. */
|
|
58183
58119
|
label: string$2().min(1),
|
|
58184
58120
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
58185
|
-
level: number().min(0).max(100).nullable(),
|
|
58121
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58186
58122
|
/** The provider's discrete verdict when known (binary mode). */
|
|
58187
58123
|
status: ConsumableStatusSchema.nullable(),
|
|
58188
58124
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -58264,8 +58200,8 @@ var consumablesCustomize = {
|
|
|
58264
58200
|
transforms: [{ kind: "identity" }]
|
|
58265
58201
|
}],
|
|
58266
58202
|
literals: [{
|
|
58267
|
-
path: "remaining.
|
|
58268
|
-
values: [...
|
|
58203
|
+
path: "remaining.kind",
|
|
58204
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
58269
58205
|
}]
|
|
58270
58206
|
},
|
|
58271
58207
|
{
|
|
@@ -58394,7 +58330,6 @@ reset: method(object({
|
|
|
58394
58330
|
},
|
|
58395
58331
|
"remaining.value": {
|
|
58396
58332
|
kind: "gauge",
|
|
58397
|
-
unitFrom: "remaining.unit",
|
|
58398
58333
|
deadband: 1,
|
|
58399
58334
|
displayName: "Remaining"
|
|
58400
58335
|
}
|
|
@@ -58464,10 +58399,9 @@ var contactCapability = {
|
|
|
58464
58399
|
* (empty array for the other kinds). It lives in the slice because
|
|
58465
58400
|
* HA `select.*` entities may update their options at runtime.
|
|
58466
58401
|
*
|
|
58467
|
-
*
|
|
58468
|
-
*
|
|
58469
|
-
*
|
|
58470
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58402
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58403
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58404
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58471
58405
|
*/
|
|
58472
58406
|
var ControlStatusSchema = object({
|
|
58473
58407
|
kind: _enum([
|
|
@@ -58479,39 +58413,17 @@ var ControlStatusSchema = object({
|
|
|
58479
58413
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58480
58414
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58481
58415
|
* or time-only — HA accepts all three forms). */
|
|
58482
|
-
value: union([number(), string$2()]),
|
|
58416
|
+
value: union([number().meta(readingMeta("device")), string$2()]),
|
|
58483
58417
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58484
58418
|
options: array(string$2()),
|
|
58485
58419
|
/** Ms epoch when the slice was last updated. */
|
|
58486
58420
|
lastChangedAt: number(),
|
|
58487
|
-
/**
|
|
58488
|
-
|
|
58489
|
-
|
|
58490
|
-
|
|
58491
|
-
/**
|
|
58492
|
-
|
|
58493
|
-
min: number().optional(),
|
|
58494
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58495
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58496
|
-
max: number().optional(),
|
|
58497
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58498
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58499
|
-
step: number().optional(),
|
|
58500
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58501
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58502
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58503
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58504
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58505
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58506
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58507
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58508
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58509
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58510
|
-
format: _enum([
|
|
58511
|
-
"date",
|
|
58512
|
-
"time",
|
|
58513
|
-
"datetime"
|
|
58514
|
-
]).optional()
|
|
58421
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58422
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58423
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58424
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58425
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58426
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58515
58427
|
});
|
|
58516
58428
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58517
58429
|
object({
|
|
@@ -58577,9 +58489,9 @@ var CoverStatusSchema = object({
|
|
|
58577
58489
|
]),
|
|
58578
58490
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58579
58491
|
* no intermediate position surface. */
|
|
58580
|
-
position: number().min(0).max(100).nullable(),
|
|
58492
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58581
58493
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58582
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58494
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58583
58495
|
/** Ms epoch when the slice was last updated. */
|
|
58584
58496
|
lastChangedAt: number()
|
|
58585
58497
|
});
|
|
@@ -58682,9 +58594,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58682
58594
|
var DayNightStatusSchema = object({
|
|
58683
58595
|
mode: DayNightModeSchema,
|
|
58684
58596
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58685
|
-
sensitivity: number().optional(),
|
|
58597
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58686
58598
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58687
|
-
switchDelaySec: number().optional(),
|
|
58599
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58688
58600
|
lastFetchedAt: number()
|
|
58689
58601
|
});
|
|
58690
58602
|
/**
|
|
@@ -58902,11 +58814,11 @@ var DishwasherStatusSchema = object({
|
|
|
58902
58814
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58903
58815
|
availablePrograms: array(string$2()),
|
|
58904
58816
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58905
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
58817
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58906
58818
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58907
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
58819
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58908
58820
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58909
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58821
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58910
58822
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58911
58823
|
doorOpen: boolean().nullable(),
|
|
58912
58824
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58930,7 +58842,7 @@ var DishwasherStatusSchema = object({
|
|
|
58930
58842
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58931
58843
|
machineCareDue: boolean().nullable(),
|
|
58932
58844
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58933
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
58845
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58934
58846
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58935
58847
|
halfLoad: boolean().nullable(),
|
|
58936
58848
|
hygienePlus: boolean().nullable(),
|
|
@@ -58945,7 +58857,7 @@ var DishwasherStatusSchema = object({
|
|
|
58945
58857
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58946
58858
|
activeEvents: array(string$2()),
|
|
58947
58859
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58948
|
-
errorCode: number().nullable(),
|
|
58860
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58949
58861
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58950
58862
|
errorLabel: string$2().nullable(),
|
|
58951
58863
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -59176,7 +59088,7 @@ var DoorbellStatusSchema = object({
|
|
|
59176
59088
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
59177
59089
|
lastPressedAt: number().nullable(),
|
|
59178
59090
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
59179
|
-
pressCountSinceStart: number()
|
|
59091
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
59180
59092
|
});
|
|
59181
59093
|
var DoorbellPressEventSchema = object({
|
|
59182
59094
|
deviceId: number(),
|
|
@@ -59241,17 +59153,7 @@ onPressed: {
|
|
|
59241
59153
|
history: "none",
|
|
59242
59154
|
customize: doorbellCustomize
|
|
59243
59155
|
};
|
|
59244
|
-
|
|
59245
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
59246
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
59247
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
59248
|
-
* The option set is stable across observations; it is persisted in the
|
|
59249
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
59250
|
-
* stored in `sourceInfo`.
|
|
59251
|
-
*/
|
|
59252
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
59253
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
59254
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
59156
|
+
_enum([
|
|
59255
59157
|
"date",
|
|
59256
59158
|
"time",
|
|
59257
59159
|
"datetime"
|
|
@@ -59259,12 +59161,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
59259
59161
|
var EnumSensorStatusSchema = object({
|
|
59260
59162
|
value: string$2(),
|
|
59261
59163
|
/**
|
|
59262
|
-
* Set
|
|
59263
|
-
* as
|
|
59264
|
-
*
|
|
59265
|
-
* a time-only sensor → `'time'`.
|
|
59164
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
59165
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
59166
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
59266
59167
|
*/
|
|
59267
|
-
|
|
59168
|
+
timestamp: boolean().optional(),
|
|
59268
59169
|
/** Ms epoch when the slice was last updated. */
|
|
59269
59170
|
lastFetchedAt: number()
|
|
59270
59171
|
});
|
|
@@ -59291,11 +59192,11 @@ var enumSensorCapability = {
|
|
|
59291
59192
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59292
59193
|
* operation state, an HVAC action). The option set is per device, so the
|
|
59293
59194
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59294
|
-
* `
|
|
59195
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
59295
59196
|
*/
|
|
59296
59197
|
history: { fields: { value: {
|
|
59297
59198
|
kind: "enum",
|
|
59298
|
-
skipWhenSet: "
|
|
59199
|
+
skipWhenSet: "timestamp"
|
|
59299
59200
|
} } },
|
|
59300
59201
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59301
59202
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -59315,13 +59216,13 @@ var EventFireSchema = object({
|
|
|
59315
59216
|
deviceId: number(),
|
|
59316
59217
|
eventType: string$2(),
|
|
59317
59218
|
data: record(string$2(), unknown()).nullable(),
|
|
59318
|
-
timestamp: number(),
|
|
59319
|
-
seq: number()
|
|
59219
|
+
timestamp: number().meta(readingMeta("none")),
|
|
59220
|
+
seq: number().meta(readingMeta("count"))
|
|
59320
59221
|
});
|
|
59321
59222
|
var EventEmitterStatusSchema = object({
|
|
59322
59223
|
eventTypes: array(string$2()),
|
|
59323
59224
|
lastEvent: EventFireSchema.nullable(),
|
|
59324
|
-
eventCountSinceStart: number()
|
|
59225
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
59325
59226
|
});
|
|
59326
59227
|
var eventEmitterCapability = {
|
|
59327
59228
|
name: "event-emitter",
|
|
@@ -59734,10 +59635,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59734
59635
|
var FanControlStatusSchema = object({
|
|
59735
59636
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59736
59637
|
* speed surface (single-speed fan). */
|
|
59737
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59638
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59738
59639
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59739
59640
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59740
|
-
percentageStep: number().positive().optional(),
|
|
59641
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59741
59642
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59742
59643
|
* — empty string when no preset is active or supported. */
|
|
59743
59644
|
preset: string$2(),
|
|
@@ -59858,7 +59759,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59858
59759
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59859
59760
|
model: string$2().nullable(),
|
|
59860
59761
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59861
|
-
channelCount: number().nullable(),
|
|
59762
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59862
59763
|
/**
|
|
59863
59764
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59864
59765
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59983,7 +59884,7 @@ var gasCapability = {
|
|
|
59983
59884
|
};
|
|
59984
59885
|
var HeatingValveStatusSchema = object({
|
|
59985
59886
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59986
|
-
position: number().min(0).max(100).nullable(),
|
|
59887
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59987
59888
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59988
59889
|
lastFetchedAt: number()
|
|
59989
59890
|
});
|
|
@@ -60026,9 +59927,9 @@ var HumidifierStatusSchema = object({
|
|
|
60026
59927
|
/** Whether the humidifier is currently on. */
|
|
60027
59928
|
on: boolean(),
|
|
60028
59929
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
60029
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
59930
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60030
59931
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
60031
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
59932
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
60032
59933
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
60033
59934
|
* device has no mode surface. */
|
|
60034
59935
|
mode: string$2().nullable(),
|
|
@@ -60038,9 +59939,9 @@ var HumidifierStatusSchema = object({
|
|
|
60038
59939
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
60039
59940
|
action: string$2().nullable(),
|
|
60040
59941
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
60041
|
-
minHumidity: number().nullable(),
|
|
59942
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60042
59943
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
60043
|
-
maxHumidity: number().nullable(),
|
|
59944
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
60044
59945
|
/** Ms epoch when the slice was last updated. */
|
|
60045
59946
|
lastChangedAt: number()
|
|
60046
59947
|
});
|
|
@@ -60110,22 +60011,13 @@ var humidifierCapability = {
|
|
|
60110
60011
|
* `sourceInfo`.
|
|
60111
60012
|
*/
|
|
60112
60013
|
var HumiditySensorStatusSchema = object({
|
|
60113
|
-
/** Current relative humidity, 0..100. */
|
|
60114
|
-
percent: number().min(0).max(100).meta({
|
|
60115
|
-
|
|
60014
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60015
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60016
|
+
precision: 0,
|
|
60116
60017
|
label: "Humidity"
|
|
60117
|
-
}),
|
|
60018
|
+
})),
|
|
60118
60019
|
/** Ms epoch when the slice was last updated. */
|
|
60119
|
-
lastFetchedAt: number()
|
|
60120
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
60121
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
60122
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
60123
|
-
unit: string$2().optional(),
|
|
60124
|
-
/** Suggested decimal places for numeric display.
|
|
60125
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
60126
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
60127
|
-
* auto-formatting when absent. */
|
|
60128
|
-
precision: number().int().min(0).max(10).optional()
|
|
60020
|
+
lastFetchedAt: number()
|
|
60129
60021
|
});
|
|
60130
60022
|
var humiditySensorCapability = {
|
|
60131
60023
|
name: "humidity-sensor",
|
|
@@ -60156,12 +60048,7 @@ var humiditySensorCapability = {
|
|
|
60156
60048
|
} } },
|
|
60157
60049
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60158
60050
|
* whether persisting is worth a SQLite commit. */
|
|
60159
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
60160
|
-
customize: {
|
|
60161
|
-
version: 1,
|
|
60162
|
-
advanced: "derive",
|
|
60163
|
-
targets: []
|
|
60164
|
-
}
|
|
60051
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
60165
60052
|
};
|
|
60166
60053
|
/**
|
|
60167
60054
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -60182,7 +60069,7 @@ var ImageStatusSchema = object({
|
|
|
60182
60069
|
* entity exposes no `entity_picture` (yet). */
|
|
60183
60070
|
url: string$2().nullable(),
|
|
60184
60071
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
60185
|
-
lastUpdated: number().nullable()
|
|
60072
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
60186
60073
|
});
|
|
60187
60074
|
var imageCapability = {
|
|
60188
60075
|
name: "image",
|
|
@@ -60270,19 +60157,19 @@ var NormalizedRangeSchema = object({
|
|
|
60270
60157
|
*/
|
|
60271
60158
|
var ImageSettingsStatusSchema = object({
|
|
60272
60159
|
/** Normalized 0–100. */
|
|
60273
|
-
brightness: number().optional(),
|
|
60160
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
60274
60161
|
/** Normalized 0–100. */
|
|
60275
|
-
contrast: number().optional(),
|
|
60162
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
60276
60163
|
/** Normalized 0–100. */
|
|
60277
|
-
saturation: number().optional(),
|
|
60164
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
60278
60165
|
/** Normalized 0–100. */
|
|
60279
|
-
sharpness: number().optional(),
|
|
60166
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
60280
60167
|
mirror: boolean().optional(),
|
|
60281
60168
|
flip: boolean().optional(),
|
|
60282
60169
|
rotate: ImageRotateSchema.optional(),
|
|
60283
60170
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
60284
60171
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
60285
|
-
warmth: number().optional(),
|
|
60172
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
60286
60173
|
exposureMode: ExposureModeSchema.optional(),
|
|
60287
60174
|
backlightMode: BacklightModeSchema.optional(),
|
|
60288
60175
|
lastFetchedAt: number()
|
|
@@ -60561,10 +60448,10 @@ var IntercomAbilitySchema = object({
|
|
|
60561
60448
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60562
60449
|
codecs: array(string$2()),
|
|
60563
60450
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60564
|
-
sampleRate: number(),
|
|
60451
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60565
60452
|
duplex: _enum(["half", "full"]),
|
|
60566
60453
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60567
|
-
maxBacklogMs: number()
|
|
60454
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60568
60455
|
});
|
|
60569
60456
|
var IntercomStatusSchema = object({
|
|
60570
60457
|
/** True while a talk session is open. */
|
|
@@ -60791,13 +60678,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60791
60678
|
activity: LawnMowerActivitySchema,
|
|
60792
60679
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60793
60680
|
* reading. */
|
|
60794
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60681
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60795
60682
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60796
60683
|
* task is active / progress is unavailable. */
|
|
60797
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60684
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60798
60685
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60799
60686
|
* or null when unknown. */
|
|
60800
|
-
currentCode: number().nullable(),
|
|
60687
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60801
60688
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60802
60689
|
currentCodeLabel: string$2().nullable(),
|
|
60803
60690
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -61330,7 +61217,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
61330
61217
|
state: MediaPlayerStateSchema,
|
|
61331
61218
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
61332
61219
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
61333
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
61220
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61334
61221
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
61335
61222
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
61336
61223
|
isMuted: boolean().nullable(),
|
|
@@ -61343,10 +61230,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61343
61230
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61344
61231
|
/** Current playback position in ms. Null when not seekable or
|
|
61345
61232
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61346
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
61233
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61347
61234
|
/** Total duration of the current media in ms. Null when unknown
|
|
61348
61235
|
* (live stream) or nothing is playing. */
|
|
61349
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
61236
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61350
61237
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61351
61238
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61352
61239
|
shuffle: boolean().nullable(),
|
|
@@ -61655,7 +61542,7 @@ var motionCustomize = {
|
|
|
61655
61542
|
eventName: "onMotionChanged"
|
|
61656
61543
|
},
|
|
61657
61544
|
deviceTypes: [DeviceType.Camera],
|
|
61658
|
-
apply: "
|
|
61545
|
+
apply: "add",
|
|
61659
61546
|
applyAuthority: {
|
|
61660
61547
|
kind: "camera-sensors",
|
|
61661
61548
|
timeoutField: "motionCooldownMs"
|
|
@@ -61727,7 +61614,7 @@ var MotionStatusSchema = object({
|
|
|
61727
61614
|
* it, every provider seeded it at boot, and every session left it
|
|
61728
61615
|
* `detected: true` after its detach.
|
|
61729
61616
|
*/
|
|
61730
|
-
autoClearAfterMs: number().nullable()
|
|
61617
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61731
61618
|
});
|
|
61732
61619
|
/**
|
|
61733
61620
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61909,7 +61796,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61909
61796
|
* the grid region(s). */
|
|
61910
61797
|
var MotionZoneStatusSchema = object({
|
|
61911
61798
|
enabled: boolean(),
|
|
61912
|
-
sensitivity: number(),
|
|
61799
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61913
61800
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61914
61801
|
regions: array(MotionZoneRegionSchema),
|
|
61915
61802
|
lastFetchedAt: number()
|
|
@@ -62279,7 +62166,7 @@ var NavigationStatusSchema = object({
|
|
|
62279
62166
|
following: boolean(),
|
|
62280
62167
|
flash: boolean(),
|
|
62281
62168
|
lightMode: NavigationLightModeSchema,
|
|
62282
|
-
lightLevel: number().min(40).max(100),
|
|
62169
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
62283
62170
|
/** Ms epoch when the slice was last updated. */
|
|
62284
62171
|
lastChangedAt: number()
|
|
62285
62172
|
});
|
|
@@ -62413,13 +62300,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62413
62300
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62414
62301
|
* SKIP a null rather than coerce it.
|
|
62415
62302
|
*/
|
|
62416
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62303
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62417
62304
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62418
|
-
rssiDbm: number().optional(),
|
|
62305
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62419
62306
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62420
62307
|
ssid: string$2().optional(),
|
|
62421
62308
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62422
|
-
lastUpdated: number()
|
|
62309
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62423
62310
|
});
|
|
62424
62311
|
var networkLinkCapability = {
|
|
62425
62312
|
name: "network-link",
|
|
@@ -62804,7 +62691,7 @@ var NotifierStatusSchema = object({
|
|
|
62804
62691
|
lastError: string$2().nullable(),
|
|
62805
62692
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62806
62693
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62807
|
-
queueDepth: number().int().nonnegative(),
|
|
62694
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62808
62695
|
/** Per-feature capability matrix — authoritative source for the
|
|
62809
62696
|
* compose-form field gating. */
|
|
62810
62697
|
supports: NotifierSupportsSchema
|
|
@@ -62896,11 +62783,9 @@ onSent: { data: object({
|
|
|
62896
62783
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62897
62784
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62898
62785
|
*
|
|
62899
|
-
* The
|
|
62900
|
-
*
|
|
62901
|
-
*
|
|
62902
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62903
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
62786
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
62787
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
62788
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62904
62789
|
*
|
|
62905
62790
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62906
62791
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62909,15 +62794,8 @@ onSent: { data: object({
|
|
|
62909
62794
|
* numeric values land here.
|
|
62910
62795
|
*/
|
|
62911
62796
|
var NumericSensorStatusSchema = object({
|
|
62912
|
-
|
|
62913
|
-
|
|
62914
|
-
* Populated live from the upstream source on each state push.
|
|
62915
|
-
* Absent for unitless sensors. */
|
|
62916
|
-
unit: string$2().optional(),
|
|
62917
|
-
/** Suggested decimal places for numeric display.
|
|
62918
|
-
* Populated live from the upstream source when provided.
|
|
62919
|
-
* Falls back to auto-formatting when absent. */
|
|
62920
|
-
precision: number().int().min(0).max(10).optional(),
|
|
62797
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
62798
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62921
62799
|
/** Ms epoch when the slice was last updated. */
|
|
62922
62800
|
lastFetchedAt: number()
|
|
62923
62801
|
});
|
|
@@ -62941,11 +62819,11 @@ var numericSensorCapability = {
|
|
|
62941
62819
|
*/
|
|
62942
62820
|
durability: "restored",
|
|
62943
62821
|
/**
|
|
62944
|
-
* History (D850): recorded series. The unit is
|
|
62822
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
62823
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62945
62824
|
*/
|
|
62946
62825
|
history: { fields: { value: {
|
|
62947
62826
|
kind: "gauge",
|
|
62948
|
-
unitFrom: "unit",
|
|
62949
62827
|
minIntervalMs: 3e4
|
|
62950
62828
|
} } },
|
|
62951
62829
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -63237,23 +63115,26 @@ var PetFeederStatusSchema = object({
|
|
|
63237
63115
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
63238
63116
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
63239
63117
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
63240
|
-
foodLevel: number().nullable(),
|
|
63118
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
63241
63119
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63242
63120
|
* single-hopper models. */
|
|
63243
|
-
food1: number().nullable(),
|
|
63121
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
63244
63122
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
63245
63123
|
* single-hopper models. */
|
|
63246
|
-
food2: number().nullable(),
|
|
63124
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
63247
63125
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63248
63126
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
63249
63127
|
* below the feeder's low threshold. */
|
|
63250
63128
|
lowFood: boolean(),
|
|
63251
63129
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63252
63130
|
* device has no battery reading. */
|
|
63253
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
63254
|
-
/**
|
|
63255
|
-
*
|
|
63256
|
-
|
|
63131
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63132
|
+
/**
|
|
63133
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
63134
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
63135
|
+
* model has no desiccant sensor.
|
|
63136
|
+
*/
|
|
63137
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
63257
63138
|
/** True while a feed is in progress. */
|
|
63258
63139
|
feeding: boolean(),
|
|
63259
63140
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -63264,7 +63145,7 @@ var PetFeederStatusSchema = object({
|
|
|
63264
63145
|
* with `errorCode` for consumers that want the raw integer. */
|
|
63265
63146
|
error: string$2().nullable(),
|
|
63266
63147
|
/** Raw device error code (0 / null = no error). */
|
|
63267
|
-
errorCode: number().nullable(),
|
|
63148
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
63268
63149
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
63269
63150
|
isDualHopper: boolean(),
|
|
63270
63151
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -63274,7 +63155,7 @@ var PetFeederStatusSchema = object({
|
|
|
63274
63155
|
/** Play a chime when dispensing. */
|
|
63275
63156
|
feedSound: boolean(),
|
|
63276
63157
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
63277
|
-
volume: number(),
|
|
63158
|
+
volume: number().meta(readingMeta("none")),
|
|
63278
63159
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
63279
63160
|
lastFetchedAt: number()
|
|
63280
63161
|
});
|
|
@@ -63393,7 +63274,7 @@ var petFeederCapability = {
|
|
|
63393
63274
|
},
|
|
63394
63275
|
desiccantLeftDays: {
|
|
63395
63276
|
kind: "gauge",
|
|
63396
|
-
unit: "
|
|
63277
|
+
unit: "s"
|
|
63397
63278
|
}
|
|
63398
63279
|
} }
|
|
63399
63280
|
};
|
|
@@ -63794,36 +63675,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63794
63675
|
*/
|
|
63795
63676
|
var PowerMeterStatusSchema = object({
|
|
63796
63677
|
/** Instantaneous power draw in watts. */
|
|
63797
|
-
watts: number().optional().meta({
|
|
63798
|
-
unit: "W",
|
|
63799
|
-
label: "Power"
|
|
63800
|
-
}),
|
|
63678
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63801
63679
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63802
|
-
kwhTotal: number().optional().meta({
|
|
63803
|
-
unit: "kWh",
|
|
63804
|
-
label: "Energy"
|
|
63805
|
-
}),
|
|
63680
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63806
63681
|
/** Voltage in volts. */
|
|
63807
|
-
volts: number().optional(),
|
|
63682
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63808
63683
|
/** Current in amperes. */
|
|
63809
|
-
amps: number().optional(),
|
|
63810
|
-
/** Apparent power in volt-amperes
|
|
63811
|
-
va: number().optional(),
|
|
63684
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
63685
|
+
/** Apparent power in volt-amperes. */
|
|
63686
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63812
63687
|
/** Power factor (0..1) if reported. */
|
|
63813
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
63688
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63814
63689
|
/** Ms epoch when the slice was last updated. */
|
|
63815
|
-
lastFetchedAt: number()
|
|
63816
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63817
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63818
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63819
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63820
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63821
|
-
unit: string$2().optional(),
|
|
63822
|
-
/** Suggested decimal places for numeric display.
|
|
63823
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63824
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63825
|
-
* auto-formatting when absent. */
|
|
63826
|
-
precision: number().int().min(0).max(10).optional()
|
|
63690
|
+
lastFetchedAt: number()
|
|
63827
63691
|
});
|
|
63828
63692
|
var powerMeterCapability = {
|
|
63829
63693
|
name: "power-meter",
|
|
@@ -63887,12 +63751,7 @@ var powerMeterCapability = {
|
|
|
63887
63751
|
} },
|
|
63888
63752
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63889
63753
|
* whether persisting is worth a SQLite commit. */
|
|
63890
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63891
|
-
customize: {
|
|
63892
|
-
version: 1,
|
|
63893
|
-
advanced: "derive",
|
|
63894
|
-
targets: []
|
|
63895
|
-
}
|
|
63754
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63896
63755
|
};
|
|
63897
63756
|
/**
|
|
63898
63757
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63912,11 +63771,11 @@ var powerMeterCapability = {
|
|
|
63912
63771
|
*/
|
|
63913
63772
|
var GpsLocationSchema = object({
|
|
63914
63773
|
/** Latitude in decimal degrees, -90..90. */
|
|
63915
|
-
latitude: number().min(-90).max(90),
|
|
63774
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63916
63775
|
/** Longitude in decimal degrees, -180..180. */
|
|
63917
|
-
longitude: number().min(-180).max(180),
|
|
63776
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63918
63777
|
/** Reported accuracy in meters (lower = better). */
|
|
63919
|
-
accuracyMeters: number().nonnegative()
|
|
63778
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63920
63779
|
});
|
|
63921
63780
|
var PresenceStatusSchema = object({
|
|
63922
63781
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63928,7 +63787,7 @@ var PresenceStatusSchema = object({
|
|
|
63928
63787
|
gps: GpsLocationSchema.nullable(),
|
|
63929
63788
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63930
63789
|
* when not reported. */
|
|
63931
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
63790
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63932
63791
|
/** Ms epoch when the slice was last updated. */
|
|
63933
63792
|
lastChangedAt: number()
|
|
63934
63793
|
});
|
|
@@ -63978,19 +63837,10 @@ var presenceCapability = {
|
|
|
63978
63837
|
* `sourceInfo`.
|
|
63979
63838
|
*/
|
|
63980
63839
|
var PressureSensorStatusSchema = object({
|
|
63981
|
-
/** Current pressure in hPa. */
|
|
63982
|
-
hpa: number(),
|
|
63840
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
63841
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63983
63842
|
/** Ms epoch when the slice was last updated. */
|
|
63984
|
-
lastFetchedAt: number()
|
|
63985
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63986
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63987
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63988
|
-
unit: string$2().optional(),
|
|
63989
|
-
/** Suggested decimal places for numeric display.
|
|
63990
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63991
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63992
|
-
* auto-formatting when absent. */
|
|
63993
|
-
precision: number().int().min(0).max(10).optional()
|
|
63843
|
+
lastFetchedAt: number()
|
|
63994
63844
|
});
|
|
63995
63845
|
var pressureSensorCapability = {
|
|
63996
63846
|
name: "pressure-sensor",
|
|
@@ -64404,8 +64254,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64404
64254
|
}), _void(), { kind: "mutation" });
|
|
64405
64255
|
var PtzAutotrackSettingsSchema = object({
|
|
64406
64256
|
targetType: string$2().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64407
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64408
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64257
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64258
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64409
64259
|
});
|
|
64410
64260
|
/**
|
|
64411
64261
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64559,7 +64409,7 @@ var RunningStateStatusSchema = object({
|
|
|
64559
64409
|
/** null = unknown — never coerced to false (D393). */
|
|
64560
64410
|
running: boolean().nullable(),
|
|
64561
64411
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64562
|
-
since: number().nullable(),
|
|
64412
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64563
64413
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64564
64414
|
phase: string$2().nullable(),
|
|
64565
64415
|
/** null until a reading has been published (D393). */
|
|
@@ -64574,7 +64424,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64574
64424
|
/** Generic Customize target for the running boolean (D936). */
|
|
64575
64425
|
var runningCustomize = {
|
|
64576
64426
|
version: 1,
|
|
64577
|
-
advanced: "derive",
|
|
64578
64427
|
targets: [{
|
|
64579
64428
|
id: "running",
|
|
64580
64429
|
cardinality: "scalar",
|
|
@@ -64594,7 +64443,7 @@ var runningCustomize = {
|
|
|
64594
64443
|
DeviceType.Thermostat,
|
|
64595
64444
|
DeviceType.PetFeeder
|
|
64596
64445
|
],
|
|
64597
|
-
apply: "add
|
|
64446
|
+
apply: "add",
|
|
64598
64447
|
path: "running",
|
|
64599
64448
|
sources: [
|
|
64600
64449
|
{
|
|
@@ -65858,9 +65707,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65858
65707
|
*/
|
|
65859
65708
|
var RecordWindowSchema = object({
|
|
65860
65709
|
trigger: RecordTriggerSchema,
|
|
65861
|
-
day: number().int().min(0).max(6),
|
|
65862
|
-
startMinute: number().int().min(0).max(1439),
|
|
65863
|
-
endMinute: number().int().min(1).max(1440)
|
|
65710
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
65711
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
65712
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65864
65713
|
});
|
|
65865
65714
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65866
65715
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65936,10 +65785,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65936
65785
|
/** Master "record to the card at all" switch. */
|
|
65937
65786
|
enabled: boolean().nullable(),
|
|
65938
65787
|
overwriteWhenFull: boolean().nullable(),
|
|
65939
|
-
preRecordSec: number().nullable(),
|
|
65940
|
-
postRecordSec: number().nullable(),
|
|
65788
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65789
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65941
65790
|
/** Length of one recorded file, in minutes. */
|
|
65942
|
-
segmentMinutes: number().nullable(),
|
|
65791
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65943
65792
|
/** The primary track's weekly windows, flattened. */
|
|
65944
65793
|
windows: array(RecordWindowSchema),
|
|
65945
65794
|
/**
|
|
@@ -65955,7 +65804,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65955
65804
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65956
65805
|
* writable.
|
|
65957
65806
|
*/
|
|
65958
|
-
unreadableWindows: number(),
|
|
65807
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65959
65808
|
/**
|
|
65960
65809
|
* The camera is scheduled to record and has NO usable storage.
|
|
65961
65810
|
*
|
|
@@ -66800,7 +66649,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66800
66649
|
url: string$2().optional(),
|
|
66801
66650
|
codec: string$2().optional(),
|
|
66802
66651
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66803
|
-
fps: number().positive().optional(),
|
|
66652
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66804
66653
|
label: string$2().optional(),
|
|
66805
66654
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66806
66655
|
deviceFeatures: array(string$2()).optional(),
|
|
@@ -66887,18 +66736,18 @@ var StreamProfileSchema = _enum([
|
|
|
66887
66736
|
]);
|
|
66888
66737
|
/** The current encoding config of one stream profile. */
|
|
66889
66738
|
var StreamProfileConfigSchema = object({
|
|
66890
|
-
width: number(),
|
|
66891
|
-
height: number(),
|
|
66739
|
+
width: number().meta(readingMeta("none")),
|
|
66740
|
+
height: number().meta(readingMeta("none")),
|
|
66892
66741
|
codec: _enum(["h264", "h265"]),
|
|
66893
|
-
framerate: number(),
|
|
66894
|
-
bitrate: number(),
|
|
66742
|
+
framerate: number().meta(readingMeta("rate")),
|
|
66743
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66895
66744
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66896
66745
|
encoderProfile: _enum([
|
|
66897
66746
|
"high",
|
|
66898
66747
|
"main",
|
|
66899
66748
|
"baseline"
|
|
66900
66749
|
]).optional(),
|
|
66901
|
-
gop: number().optional(),
|
|
66750
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66902
66751
|
/**
|
|
66903
66752
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66904
66753
|
*
|
|
@@ -67119,12 +66968,7 @@ var switchCapability = {
|
|
|
67119
66968
|
label: "On",
|
|
67120
66969
|
kind: "boolean"
|
|
67121
66970
|
}
|
|
67122
|
-
}] }
|
|
67123
|
-
customize: {
|
|
67124
|
-
version: 1,
|
|
67125
|
-
advanced: "derive",
|
|
67126
|
-
targets: []
|
|
67127
|
-
}
|
|
66971
|
+
}] }
|
|
67128
66972
|
};
|
|
67129
66973
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
67130
66974
|
function hasControlCharacter(value) {
|
|
@@ -67707,35 +67551,21 @@ var tamperCapability = {
|
|
|
67707
67551
|
* entries with `device_class: temperature` and any future native
|
|
67708
67552
|
* thermometer.
|
|
67709
67553
|
*
|
|
67710
|
-
*
|
|
67711
|
-
*
|
|
67712
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67713
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67714
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67715
|
-
* `sourceInfo`.
|
|
67554
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67555
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67716
67556
|
*
|
|
67717
67557
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67718
67558
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67719
67559
|
* changed" steady state.
|
|
67720
67560
|
*/
|
|
67721
67561
|
var TemperatureSensorStatusSchema = object({
|
|
67722
|
-
/** Current temperature in Celsius. */
|
|
67723
|
-
celsius: number().meta({
|
|
67724
|
-
|
|
67562
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67563
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67564
|
+
precision: 1,
|
|
67725
67565
|
label: "Temperature"
|
|
67726
|
-
}),
|
|
67566
|
+
})),
|
|
67727
67567
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67728
|
-
lastFetchedAt: number()
|
|
67729
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67730
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67731
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67732
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67733
|
-
unit: string$2().optional(),
|
|
67734
|
-
/** Suggested decimal places for numeric display.
|
|
67735
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67736
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67737
|
-
* auto-formatting when absent. */
|
|
67738
|
-
precision: number().int().min(0).max(10).optional()
|
|
67568
|
+
lastFetchedAt: number()
|
|
67739
67569
|
});
|
|
67740
67570
|
var temperatureSensorCapability = {
|
|
67741
67571
|
name: "temperature-sensor",
|
|
@@ -67766,12 +67596,7 @@ var temperatureSensorCapability = {
|
|
|
67766
67596
|
} } },
|
|
67767
67597
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67768
67598
|
* whether persisting is worth a SQLite commit. */
|
|
67769
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67770
|
-
customize: {
|
|
67771
|
-
version: 1,
|
|
67772
|
-
advanced: "derive",
|
|
67773
|
-
targets: []
|
|
67774
|
-
}
|
|
67599
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67775
67600
|
};
|
|
67776
67601
|
/**
|
|
67777
67602
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -68054,16 +67879,16 @@ var VacuumControlStatusSchema = object({
|
|
|
68054
67879
|
]),
|
|
68055
67880
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
68056
67881
|
* reading. */
|
|
68057
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
67882
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68058
67883
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
68059
67884
|
* the vacuum has no speed control. */
|
|
68060
67885
|
fanSpeed: string$2().nullable(),
|
|
68061
67886
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68062
67887
|
availableFanSpeeds: array(string$2()),
|
|
68063
67888
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68064
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
67889
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68065
67890
|
/** Current error code (0 / null = no error). */
|
|
68066
|
-
errorCode: number().nullable(),
|
|
67891
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68067
67892
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
68068
67893
|
errorLabel: string$2().nullable(),
|
|
68069
67894
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -68141,7 +67966,7 @@ var ValveStatusSchema = object({
|
|
|
68141
67966
|
]),
|
|
68142
67967
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
68143
67968
|
* intermediate position surface. */
|
|
68144
|
-
position: number().min(0).max(100).nullable(),
|
|
67969
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68145
67970
|
/** Ms epoch when the slice was last updated. */
|
|
68146
67971
|
lastChangedAt: number()
|
|
68147
67972
|
});
|
|
@@ -68249,9 +68074,9 @@ var vibrationCapability = {
|
|
|
68249
68074
|
*/
|
|
68250
68075
|
var WaterHeaterStatusSchema = object({
|
|
68251
68076
|
/** Current measured temperature. Null when not reported. */
|
|
68252
|
-
currentTemp: number().nullable(),
|
|
68077
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68253
68078
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
68254
|
-
targetTemp: number().nullable(),
|
|
68079
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68255
68080
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
68256
68081
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
68257
68082
|
* device reports an unknown state. */
|
|
@@ -68262,9 +68087,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
68262
68087
|
* has no away surface. */
|
|
68263
68088
|
away: boolean().nullable(),
|
|
68264
68089
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
68265
|
-
minTemp: number().nullable(),
|
|
68090
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68266
68091
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
68267
|
-
maxTemp: number().nullable(),
|
|
68092
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
68268
68093
|
/** Ms epoch when the slice was last updated. */
|
|
68269
68094
|
lastChangedAt: number()
|
|
68270
68095
|
});
|
|
@@ -68349,25 +68174,18 @@ var waterHeaterCapability = {
|
|
|
68349
68174
|
* Forecast deferred — current conditions only for v1.
|
|
68350
68175
|
*/
|
|
68351
68176
|
var WeatherStatusSchema = object({
|
|
68352
|
-
/** Verbatim
|
|
68353
|
-
* when no condition has been reported yet. */
|
|
68177
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
68354
68178
|
condition: string$2().nullable(),
|
|
68355
|
-
/** Current temperature in
|
|
68356
|
-
temperature: number().nullable(),
|
|
68357
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68358
|
-
temperatureUnit: string$2().nullable(),
|
|
68179
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
68180
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68359
68181
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68360
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68361
|
-
/** Barometric pressure in
|
|
68362
|
-
pressure: number().nullable(),
|
|
68363
|
-
/**
|
|
68364
|
-
|
|
68365
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68366
|
-
windSpeed: number().nullable(),
|
|
68367
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68368
|
-
windSpeedUnit: string$2().nullable(),
|
|
68182
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
68183
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
68184
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
68185
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
68186
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68369
68187
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68370
|
-
windBearing: number().nullable(),
|
|
68188
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68371
68189
|
/** Ms epoch when the slice was last updated. */
|
|
68372
68190
|
lastFetchedAt: number()
|
|
68373
68191
|
});
|
|
@@ -68395,12 +68213,12 @@ var weatherCapability = {
|
|
|
68395
68213
|
*/
|
|
68396
68214
|
durability: "session",
|
|
68397
68215
|
/**
|
|
68398
|
-
* History (D850): recorded series.
|
|
68216
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68399
68217
|
*/
|
|
68400
68218
|
history: { fields: {
|
|
68401
68219
|
temperature: {
|
|
68402
68220
|
kind: "gauge",
|
|
68403
|
-
|
|
68221
|
+
unit: "°C",
|
|
68404
68222
|
deadband: .2
|
|
68405
68223
|
},
|
|
68406
68224
|
humidity: {
|
|
@@ -68410,12 +68228,12 @@ var weatherCapability = {
|
|
|
68410
68228
|
},
|
|
68411
68229
|
pressure: {
|
|
68412
68230
|
kind: "gauge",
|
|
68413
|
-
|
|
68231
|
+
unit: "hPa",
|
|
68414
68232
|
deadband: .5
|
|
68415
68233
|
},
|
|
68416
68234
|
windSpeed: {
|
|
68417
68235
|
kind: "gauge",
|
|
68418
|
-
|
|
68236
|
+
unit: "m/s",
|
|
68419
68237
|
deadband: .5
|
|
68420
68238
|
}
|
|
68421
68239
|
} }
|
|
@@ -83985,7 +83803,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83985
83803
|
field: "value",
|
|
83986
83804
|
quantity: t("the reading", "il valore"),
|
|
83987
83805
|
label: t("Reading", "Valore"),
|
|
83988
|
-
unitField: "unit",
|
|
83989
83806
|
icon: "gauge"
|
|
83990
83807
|
}]
|
|
83991
83808
|
},
|
|
@@ -84121,7 +83938,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84121
83938
|
field: "temperature",
|
|
84122
83939
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
84123
83940
|
label: t("Temperature", "Temperatura"),
|
|
84124
|
-
|
|
83941
|
+
unit: "°C",
|
|
84125
83942
|
icon: "thermometer"
|
|
84126
83943
|
},
|
|
84127
83944
|
{
|
|
@@ -84137,7 +83954,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84137
83954
|
field: "windSpeed",
|
|
84138
83955
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
84139
83956
|
label: t("Wind", "Vento"),
|
|
84140
|
-
|
|
83957
|
+
unit: "m/s",
|
|
84141
83958
|
icon: "wind"
|
|
84142
83959
|
},
|
|
84143
83960
|
{
|
|
@@ -84145,7 +83962,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84145
83962
|
field: "pressure",
|
|
84146
83963
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
84147
83964
|
label: t("Pressure", "Pressione"),
|
|
84148
|
-
|
|
83965
|
+
unit: "hPa",
|
|
84149
83966
|
icon: "gauge"
|
|
84150
83967
|
}
|
|
84151
83968
|
]
|
|
@@ -197437,7 +197254,6 @@ function decodeElectricalPower(attributeId, value) {
|
|
|
197437
197254
|
cap: "power-meter",
|
|
197438
197255
|
patch: {
|
|
197439
197256
|
watts: mw / 1e3,
|
|
197440
|
-
unit: "W",
|
|
197441
197257
|
lastFetchedAt: Date.now()
|
|
197442
197258
|
}
|
|
197443
197259
|
};
|