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