@camstack/addon-provider-bosch 0.1.24 → 0.1.25
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/{account-integration-offline-Dcy3K68x.js → account-integration-offline-BPV9TTp1.js} +1 -1
- package/dist/{account-integration-offline-BPXEESM5.mjs → account-integration-offline-BcUPRaQD.mjs} +1 -1
- package/dist/{dist-cVQVYhpv.js → dist-Csx3t_1B.js} +918 -495
- package/dist/{dist-QNoZItyP.mjs → dist-DPDLG8_g.mjs} +907 -496
- package/dist/home-connect/addon.js +17 -5
- package/dist/home-connect/addon.mjs +17 -5
- package/dist/homecom/addon.js +2 -2
- package/dist/homecom/addon.mjs +2 -2
- package/dist/shc/addon.js +1 -1
- package/dist/shc/addon.mjs +1 -1
- package/package.json +1 -1
|
@@ -5434,7 +5434,7 @@ var ZodIssueCode = {
|
|
|
5434
5434
|
var ZodFirstPartyTypeKind;
|
|
5435
5435
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5436
5436
|
//#endregion
|
|
5437
|
-
//#region ../types/dist/sleep-
|
|
5437
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
5438
5438
|
/**
|
|
5439
5439
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5440
5440
|
* window to float samples (D455).
|
|
@@ -7992,6 +7992,99 @@ var RecordKindDeclarationSchema = object({
|
|
|
7992
7992
|
}).strict();
|
|
7993
7993
|
/** The kind names: lower-case, dash separated, short enough for an index name. */
|
|
7994
7994
|
var RecordKindNameSchema = string().regex(/^[a-z][a-z0-9-]{0,47}$/);
|
|
7995
|
+
var READING_QUANTITIES = [
|
|
7996
|
+
"temperature",
|
|
7997
|
+
"pressure",
|
|
7998
|
+
"speed",
|
|
7999
|
+
"precipitation",
|
|
8000
|
+
"precipitation-rate",
|
|
8001
|
+
"length",
|
|
8002
|
+
"area",
|
|
8003
|
+
"illuminance",
|
|
8004
|
+
"irradiance",
|
|
8005
|
+
"power",
|
|
8006
|
+
"energy",
|
|
8007
|
+
"voltage",
|
|
8008
|
+
"current",
|
|
8009
|
+
"apparent-power",
|
|
8010
|
+
"humidity",
|
|
8011
|
+
"percentage",
|
|
8012
|
+
"concentration-volume",
|
|
8013
|
+
"concentration-mass",
|
|
8014
|
+
"concentration-ppb",
|
|
8015
|
+
"volume",
|
|
8016
|
+
"duration",
|
|
8017
|
+
"duration-ms",
|
|
8018
|
+
"information",
|
|
8019
|
+
"sound-level",
|
|
8020
|
+
"signal-level",
|
|
8021
|
+
"colour-temperature",
|
|
8022
|
+
"angle",
|
|
8023
|
+
"bitrate",
|
|
8024
|
+
"rate",
|
|
8025
|
+
"mass",
|
|
8026
|
+
"index",
|
|
8027
|
+
"ratio",
|
|
8028
|
+
"count",
|
|
8029
|
+
"none",
|
|
8030
|
+
"device"
|
|
8031
|
+
];
|
|
8032
|
+
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8033
|
+
new Set(READING_QUANTITIES);
|
|
8034
|
+
/**
|
|
8035
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8036
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8037
|
+
*/
|
|
8038
|
+
var QUANTITY_BASE = {
|
|
8039
|
+
temperature: "°C",
|
|
8040
|
+
pressure: "hPa",
|
|
8041
|
+
speed: "m/s",
|
|
8042
|
+
precipitation: "mm",
|
|
8043
|
+
"precipitation-rate": "mm/h",
|
|
8044
|
+
length: "m",
|
|
8045
|
+
area: "m²",
|
|
8046
|
+
illuminance: "lx",
|
|
8047
|
+
irradiance: "W/m²",
|
|
8048
|
+
power: "W",
|
|
8049
|
+
energy: "kWh",
|
|
8050
|
+
voltage: "V",
|
|
8051
|
+
current: "A",
|
|
8052
|
+
"apparent-power": "VA",
|
|
8053
|
+
humidity: "%",
|
|
8054
|
+
percentage: "%",
|
|
8055
|
+
"concentration-volume": "ppm",
|
|
8056
|
+
"concentration-mass": "µg/m³",
|
|
8057
|
+
"concentration-ppb": "ppb",
|
|
8058
|
+
volume: "L",
|
|
8059
|
+
duration: "s",
|
|
8060
|
+
"duration-ms": "ms",
|
|
8061
|
+
information: "B",
|
|
8062
|
+
"sound-level": "dBFS",
|
|
8063
|
+
"signal-level": "dBm",
|
|
8064
|
+
"colour-temperature": "mired",
|
|
8065
|
+
angle: "°",
|
|
8066
|
+
bitrate: "kbps",
|
|
8067
|
+
rate: "fps",
|
|
8068
|
+
mass: "kg",
|
|
8069
|
+
index: "none",
|
|
8070
|
+
ratio: "none",
|
|
8071
|
+
count: "none",
|
|
8072
|
+
none: "none",
|
|
8073
|
+
device: "device"
|
|
8074
|
+
};
|
|
8075
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8076
|
+
function baseUnitOf(quantity) {
|
|
8077
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8078
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8079
|
+
return symbol;
|
|
8080
|
+
}
|
|
8081
|
+
function readingMeta(quantity, extras) {
|
|
8082
|
+
return {
|
|
8083
|
+
quantity,
|
|
8084
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
8085
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
8086
|
+
};
|
|
8087
|
+
}
|
|
7995
8088
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
7996
8089
|
var CamProfileSchema = _enum([
|
|
7997
8090
|
"high",
|
|
@@ -8019,8 +8112,8 @@ var CamStreamKindSchema = _enum([
|
|
|
8019
8112
|
"derived"
|
|
8020
8113
|
]);
|
|
8021
8114
|
var CamStreamResolutionSchema = object({
|
|
8022
|
-
width: number().int().positive(),
|
|
8023
|
-
height: number().int().positive()
|
|
8115
|
+
width: number().int().positive().meta(readingMeta("none")),
|
|
8116
|
+
height: number().int().positive().meta(readingMeta("none"))
|
|
8024
8117
|
});
|
|
8025
8118
|
var CameraStreamSchema = object({
|
|
8026
8119
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -8689,14 +8782,6 @@ Object.freeze({
|
|
|
8689
8782
|
{
|
|
8690
8783
|
"path": "aqi",
|
|
8691
8784
|
"valueType": "number"
|
|
8692
|
-
},
|
|
8693
|
-
{
|
|
8694
|
-
"path": "unit",
|
|
8695
|
-
"valueType": "string"
|
|
8696
|
-
},
|
|
8697
|
-
{
|
|
8698
|
-
"path": "precision",
|
|
8699
|
-
"valueType": "number"
|
|
8700
8785
|
}
|
|
8701
8786
|
],
|
|
8702
8787
|
"alarm-panel": [
|
|
@@ -8732,20 +8817,10 @@ Object.freeze({
|
|
|
8732
8817
|
"valueType": "boolean"
|
|
8733
8818
|
}
|
|
8734
8819
|
],
|
|
8735
|
-
"ambient-light-sensor": [
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
},
|
|
8740
|
-
{
|
|
8741
|
-
"path": "unit",
|
|
8742
|
-
"valueType": "string"
|
|
8743
|
-
},
|
|
8744
|
-
{
|
|
8745
|
-
"path": "precision",
|
|
8746
|
-
"valueType": "number"
|
|
8747
|
-
}
|
|
8748
|
-
],
|
|
8820
|
+
"ambient-light-sensor": [{
|
|
8821
|
+
"path": "lux",
|
|
8822
|
+
"valueType": "number"
|
|
8823
|
+
}],
|
|
8749
8824
|
"audio-metrics": [
|
|
8750
8825
|
{
|
|
8751
8826
|
"path": "ts",
|
|
@@ -8825,6 +8900,10 @@ Object.freeze({
|
|
|
8825
8900
|
"path": "lastUpdated",
|
|
8826
8901
|
"valueType": "number"
|
|
8827
8902
|
},
|
|
8903
|
+
{
|
|
8904
|
+
"path": "volts",
|
|
8905
|
+
"valueType": "number"
|
|
8906
|
+
},
|
|
8828
8907
|
{
|
|
8829
8908
|
"path": "lastContactAt",
|
|
8830
8909
|
"valueType": "number"
|
|
@@ -9067,10 +9146,6 @@ Object.freeze({
|
|
|
9067
9146
|
"datetime"
|
|
9068
9147
|
]
|
|
9069
9148
|
},
|
|
9070
|
-
{
|
|
9071
|
-
"path": "unit",
|
|
9072
|
-
"valueType": "string"
|
|
9073
|
-
},
|
|
9074
9149
|
{
|
|
9075
9150
|
"path": "min",
|
|
9076
9151
|
"valueType": "number"
|
|
@@ -9082,19 +9157,6 @@ Object.freeze({
|
|
|
9082
9157
|
{
|
|
9083
9158
|
"path": "step",
|
|
9084
9159
|
"valueType": "number"
|
|
9085
|
-
},
|
|
9086
|
-
{
|
|
9087
|
-
"path": "precision",
|
|
9088
|
-
"valueType": "number"
|
|
9089
|
-
},
|
|
9090
|
-
{
|
|
9091
|
-
"path": "format",
|
|
9092
|
-
"valueType": "enum",
|
|
9093
|
-
"enumValues": [
|
|
9094
|
-
"date",
|
|
9095
|
-
"time",
|
|
9096
|
-
"datetime"
|
|
9097
|
-
]
|
|
9098
9160
|
}
|
|
9099
9161
|
],
|
|
9100
9162
|
"cover": [
|
|
@@ -9335,13 +9397,8 @@ Object.freeze({
|
|
|
9335
9397
|
"path": "value",
|
|
9336
9398
|
"valueType": "string"
|
|
9337
9399
|
}, {
|
|
9338
|
-
"path": "
|
|
9339
|
-
"valueType": "
|
|
9340
|
-
"enumValues": [
|
|
9341
|
-
"date",
|
|
9342
|
-
"time",
|
|
9343
|
-
"datetime"
|
|
9344
|
-
]
|
|
9400
|
+
"path": "timestamp",
|
|
9401
|
+
"valueType": "boolean"
|
|
9345
9402
|
}],
|
|
9346
9403
|
"event-emitter": [
|
|
9347
9404
|
{
|
|
@@ -9448,20 +9505,10 @@ Object.freeze({
|
|
|
9448
9505
|
"valueType": "number"
|
|
9449
9506
|
}
|
|
9450
9507
|
],
|
|
9451
|
-
"humidity-sensor": [
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
},
|
|
9456
|
-
{
|
|
9457
|
-
"path": "unit",
|
|
9458
|
-
"valueType": "string"
|
|
9459
|
-
},
|
|
9460
|
-
{
|
|
9461
|
-
"path": "precision",
|
|
9462
|
-
"valueType": "number"
|
|
9463
|
-
}
|
|
9464
|
-
],
|
|
9508
|
+
"humidity-sensor": [{
|
|
9509
|
+
"path": "percent",
|
|
9510
|
+
"valueType": "number"
|
|
9511
|
+
}],
|
|
9465
9512
|
"image": [{
|
|
9466
9513
|
"path": "url",
|
|
9467
9514
|
"valueType": "string"
|
|
@@ -9800,20 +9847,10 @@ Object.freeze({
|
|
|
9800
9847
|
"valueType": "boolean"
|
|
9801
9848
|
}
|
|
9802
9849
|
],
|
|
9803
|
-
"numeric-sensor": [
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
},
|
|
9808
|
-
{
|
|
9809
|
-
"path": "unit",
|
|
9810
|
-
"valueType": "string"
|
|
9811
|
-
},
|
|
9812
|
-
{
|
|
9813
|
-
"path": "precision",
|
|
9814
|
-
"valueType": "number"
|
|
9815
|
-
}
|
|
9816
|
-
],
|
|
9850
|
+
"numeric-sensor": [{
|
|
9851
|
+
"path": "value",
|
|
9852
|
+
"valueType": "number"
|
|
9853
|
+
}],
|
|
9817
9854
|
"pet-feeder": [
|
|
9818
9855
|
{
|
|
9819
9856
|
"path": "foodLevel",
|
|
@@ -9905,14 +9942,6 @@ Object.freeze({
|
|
|
9905
9942
|
{
|
|
9906
9943
|
"path": "powerFactor",
|
|
9907
9944
|
"valueType": "number"
|
|
9908
|
-
},
|
|
9909
|
-
{
|
|
9910
|
-
"path": "unit",
|
|
9911
|
-
"valueType": "string"
|
|
9912
|
-
},
|
|
9913
|
-
{
|
|
9914
|
-
"path": "precision",
|
|
9915
|
-
"valueType": "number"
|
|
9916
9945
|
}
|
|
9917
9946
|
],
|
|
9918
9947
|
"presence": [
|
|
@@ -9941,20 +9970,10 @@ Object.freeze({
|
|
|
9941
9970
|
"valueType": "number"
|
|
9942
9971
|
}
|
|
9943
9972
|
],
|
|
9944
|
-
"pressure-sensor": [
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
|
|
9948
|
-
},
|
|
9949
|
-
{
|
|
9950
|
-
"path": "unit",
|
|
9951
|
-
"valueType": "string"
|
|
9952
|
-
},
|
|
9953
|
-
{
|
|
9954
|
-
"path": "precision",
|
|
9955
|
-
"valueType": "number"
|
|
9956
|
-
}
|
|
9957
|
-
],
|
|
9973
|
+
"pressure-sensor": [{
|
|
9974
|
+
"path": "hpa",
|
|
9975
|
+
"valueType": "number"
|
|
9976
|
+
}],
|
|
9958
9977
|
"privacy-mask": [{
|
|
9959
9978
|
"path": "enabled",
|
|
9960
9979
|
"valueType": "boolean"
|
|
@@ -10265,20 +10284,10 @@ Object.freeze({
|
|
|
10265
10284
|
"path": "tampered",
|
|
10266
10285
|
"valueType": "boolean"
|
|
10267
10286
|
}],
|
|
10268
|
-
"temperature-sensor": [
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
10272
|
-
},
|
|
10273
|
-
{
|
|
10274
|
-
"path": "unit",
|
|
10275
|
-
"valueType": "string"
|
|
10276
|
-
},
|
|
10277
|
-
{
|
|
10278
|
-
"path": "precision",
|
|
10279
|
-
"valueType": "number"
|
|
10280
|
-
}
|
|
10281
|
-
],
|
|
10287
|
+
"temperature-sensor": [{
|
|
10288
|
+
"path": "celsius",
|
|
10289
|
+
"valueType": "number"
|
|
10290
|
+
}],
|
|
10282
10291
|
"update": [
|
|
10283
10292
|
{
|
|
10284
10293
|
"path": "currentVersion",
|
|
@@ -10389,10 +10398,6 @@ Object.freeze({
|
|
|
10389
10398
|
"path": "temperature",
|
|
10390
10399
|
"valueType": "number"
|
|
10391
10400
|
},
|
|
10392
|
-
{
|
|
10393
|
-
"path": "temperatureUnit",
|
|
10394
|
-
"valueType": "string"
|
|
10395
|
-
},
|
|
10396
10401
|
{
|
|
10397
10402
|
"path": "humidity",
|
|
10398
10403
|
"valueType": "number"
|
|
@@ -10401,18 +10406,10 @@ Object.freeze({
|
|
|
10401
10406
|
"path": "pressure",
|
|
10402
10407
|
"valueType": "number"
|
|
10403
10408
|
},
|
|
10404
|
-
{
|
|
10405
|
-
"path": "pressureUnit",
|
|
10406
|
-
"valueType": "string"
|
|
10407
|
-
},
|
|
10408
10409
|
{
|
|
10409
10410
|
"path": "windSpeed",
|
|
10410
10411
|
"valueType": "number"
|
|
10411
10412
|
},
|
|
10412
|
-
{
|
|
10413
|
-
"path": "windSpeedUnit",
|
|
10414
|
-
"valueType": "string"
|
|
10415
|
-
},
|
|
10416
10413
|
{
|
|
10417
10414
|
"path": "windBearing",
|
|
10418
10415
|
"valueType": "number"
|
|
@@ -17876,7 +17873,8 @@ var CompositionProblemSchema = object({
|
|
|
17876
17873
|
"item-field-reserved",
|
|
17877
17874
|
"target-missing",
|
|
17878
17875
|
"target-unreadable",
|
|
17879
|
-
"not-replaceable"
|
|
17876
|
+
"not-replaceable",
|
|
17877
|
+
"native-capability-replace"
|
|
17880
17878
|
]),
|
|
17881
17879
|
path: string(),
|
|
17882
17880
|
message: string()
|
|
@@ -17934,9 +17932,11 @@ var CompositionFieldPlanSchema = object({
|
|
|
17934
17932
|
reads: array(CompositionFieldReadSchema)
|
|
17935
17933
|
});
|
|
17936
17934
|
/**
|
|
17937
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17938
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17939
|
-
*
|
|
17935
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
17936
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
17937
|
+
* Replacing a capability the device already serves is refused
|
|
17938
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
17939
|
+
* wire for a claim the hub already holds.
|
|
17940
17940
|
*/
|
|
17941
17941
|
var CompositionFeatureModeSchema = _enum([
|
|
17942
17942
|
"new",
|
|
@@ -19822,12 +19822,12 @@ method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema
|
|
|
19822
19822
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
19823
19823
|
* in-place so dispatch keeps working.
|
|
19824
19824
|
*
|
|
19825
|
-
* **
|
|
19826
|
-
*
|
|
19827
|
-
*
|
|
19828
|
-
*
|
|
19829
|
-
* (`ha-domain-mapping`)
|
|
19830
|
-
* stored after that point.
|
|
19825
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
19826
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
19827
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
19828
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
19829
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
19830
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
19831
19831
|
*
|
|
19832
19832
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
19833
19833
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -19841,6 +19841,14 @@ var SourceInfoSchema = object({
|
|
|
19841
19841
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
19842
19842
|
* Used to detect rename when `id` changes. */
|
|
19843
19843
|
uniqueId: string().optional(),
|
|
19844
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
19845
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
19846
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
19847
|
+
dateTimeShape: _enum([
|
|
19848
|
+
"date",
|
|
19849
|
+
"time",
|
|
19850
|
+
"datetime"
|
|
19851
|
+
]).optional(),
|
|
19844
19852
|
/** Provider-specific extras that don't fit the structured slots.
|
|
19845
19853
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
19846
19854
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -19886,6 +19894,80 @@ function mergeSourceInfo(prev, patch) {
|
|
|
19886
19894
|
return next;
|
|
19887
19895
|
}
|
|
19888
19896
|
/**
|
|
19897
|
+
* Coerce common unit-of-measurement string variants to a canonical form
|
|
19898
|
+
* so the UI's display templates can rely on stable strings. Pure
|
|
19899
|
+
* passthrough for unknown units — kept conservative on purpose, the goal
|
|
19900
|
+
* is to normalise the long tail of HA `unit_of_measurement` values that
|
|
19901
|
+
* have multiple historical spellings (`'°C'` vs `'C'` vs `'celsius'`).
|
|
19902
|
+
*
|
|
19903
|
+
* Extend the map as we encounter real-world data. Returning the raw
|
|
19904
|
+
* input for unknown values is intentional: providers should never
|
|
19905
|
+
* lose information silently here.
|
|
19906
|
+
*/
|
|
19907
|
+
function normalizeUnit(raw) {
|
|
19908
|
+
if (raw == null) return void 0;
|
|
19909
|
+
const trimmed = raw.trim();
|
|
19910
|
+
if (trimmed === "") return void 0;
|
|
19911
|
+
const lower = trimmed.toLowerCase();
|
|
19912
|
+
if (lower === "°c" || lower === "c" || lower === "celsius") return "°C";
|
|
19913
|
+
if (lower === "°f" || lower === "f" || lower === "fahrenheit") return "°F";
|
|
19914
|
+
if (lower === "k" || lower === "kelvin") return "K";
|
|
19915
|
+
if (lower === "%" || lower === "percent" || lower === "percentage") return "%";
|
|
19916
|
+
if (lower === "lx" || lower === "lux") return "lx";
|
|
19917
|
+
if (lower === "hpa" || lower === "hectopascal") return "hPa";
|
|
19918
|
+
if (lower === "kpa") return "kPa";
|
|
19919
|
+
if (lower === "pa") return "Pa";
|
|
19920
|
+
if (lower === "mbar" || lower === "millibar") return "mbar";
|
|
19921
|
+
if (lower === "w" || lower === "watt") return "W";
|
|
19922
|
+
if (lower === "kw" || lower === "kilowatt") return "kW";
|
|
19923
|
+
if (lower === "wh" || lower === "watt-hour") return "Wh";
|
|
19924
|
+
if (lower === "kwh" || lower === "kilowatt-hour") return "kWh";
|
|
19925
|
+
if (lower === "v" || lower === "volt") return "V";
|
|
19926
|
+
if (lower === "a" || lower === "amp" || lower === "ampere") return "A";
|
|
19927
|
+
if (lower === "ma" || lower === "milliampere") return "mA";
|
|
19928
|
+
if (lower === "va") return "VA";
|
|
19929
|
+
if (lower === "ppm") return "ppm";
|
|
19930
|
+
if (lower === "ppb") return "ppb";
|
|
19931
|
+
if (lower === "µg/m³" || lower === "ug/m3" || lower === "µg/m3") return "µg/m³";
|
|
19932
|
+
if (lower === "km/h" || lower === "kph") return "km/h";
|
|
19933
|
+
if (lower === "mph") return "mph";
|
|
19934
|
+
if (lower === "m/s") return "m/s";
|
|
19935
|
+
if (lower === "m") return "m";
|
|
19936
|
+
if (lower === "m²" || lower === "m2") return "m²";
|
|
19937
|
+
if (lower === "mm") return "mm";
|
|
19938
|
+
if (lower === "cm") return "cm";
|
|
19939
|
+
if (lower === "km") return "km";
|
|
19940
|
+
if (lower === "in" || lower === "inch" || lower === "inches") return "in";
|
|
19941
|
+
if (lower === "ft" || lower === "foot" || lower === "feet") return "ft";
|
|
19942
|
+
if (lower === "kg") return "kg";
|
|
19943
|
+
if (lower === "g") return "g";
|
|
19944
|
+
if (lower === "l" || lower === "liter" || lower === "litre" || lower === "liters" || lower === "litres") return "L";
|
|
19945
|
+
if (lower === "ml") return "mL";
|
|
19946
|
+
if (lower === "gal" || lower === "gallon" || lower === "gallons") return "gal";
|
|
19947
|
+
if (lower === "s" || lower === "sec" || lower === "second" || lower === "seconds") return "s";
|
|
19948
|
+
if (lower === "ms") return "ms";
|
|
19949
|
+
if (lower === "min" || lower === "minute" || lower === "minutes") return "min";
|
|
19950
|
+
if (lower === "h" || lower === "hr" || lower === "hour" || lower === "hours") return "h";
|
|
19951
|
+
if (lower === "d" || lower === "day" || lower === "days") return "d";
|
|
19952
|
+
if (lower === "b" || lower === "byte" || lower === "bytes") return "B";
|
|
19953
|
+
if (lower === "kib") return "KiB";
|
|
19954
|
+
if (lower === "mib") return "MiB";
|
|
19955
|
+
if (lower === "gib") return "GiB";
|
|
19956
|
+
if (lower === "tib") return "TiB";
|
|
19957
|
+
if (lower === "kb") return "kB";
|
|
19958
|
+
if (lower === "mb") return "MB";
|
|
19959
|
+
if (lower === "gb") return "GB";
|
|
19960
|
+
if (lower === "dbm") return "dBm";
|
|
19961
|
+
if (lower === "dbfs") return "dBFS";
|
|
19962
|
+
if (lower === "inhg") return "inHg";
|
|
19963
|
+
if (lower === "mm/h") return "mm/h";
|
|
19964
|
+
if (lower === "w/m²" || lower === "w/m2") return "W/m²";
|
|
19965
|
+
if (lower === "°" || lower === "deg" || lower === "degree" || lower === "degrees") return "°";
|
|
19966
|
+
if (lower === "kbps") return "kbps";
|
|
19967
|
+
if (lower === "fps") return "fps";
|
|
19968
|
+
return trimmed;
|
|
19969
|
+
}
|
|
19970
|
+
/**
|
|
19889
19971
|
* Key under which `SourceInfo` lives inside `DeviceMeta.metadata`. The
|
|
19890
19972
|
* blob is a free-form `Record<string, unknown>` shared with hardware-
|
|
19891
19973
|
* identity fields (`manufacturer`, `model`, `firmware`, …); SourceInfo
|
|
@@ -40962,7 +41044,8 @@ method(object({
|
|
|
40962
41044
|
"enum"
|
|
40963
41045
|
]),
|
|
40964
41046
|
enumValues: array(string()).optional(),
|
|
40965
|
-
item: boolean().optional()
|
|
41047
|
+
item: boolean().optional(),
|
|
41048
|
+
quantity: ReadingQuantitySchema.optional()
|
|
40966
41049
|
})).readonly(),
|
|
40967
41050
|
itemArray: object({
|
|
40968
41051
|
path: string(),
|
|
@@ -44806,8 +44889,8 @@ var MaskPolygonShapeSchema = object({
|
|
|
44806
44889
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
44807
44890
|
var MaskGridShapeSchema = object({
|
|
44808
44891
|
kind: literal("grid"),
|
|
44809
|
-
gridWidth: number(),
|
|
44810
|
-
gridHeight: number(),
|
|
44892
|
+
gridWidth: number().meta(readingMeta("none")),
|
|
44893
|
+
gridHeight: number().meta(readingMeta("none")),
|
|
44811
44894
|
cells: array(boolean())
|
|
44812
44895
|
});
|
|
44813
44896
|
discriminatedUnion("kind", [
|
|
@@ -56287,27 +56370,17 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56287
56370
|
*/
|
|
56288
56371
|
var AirQualitySensorStatusSchema = object({
|
|
56289
56372
|
/** Carbon dioxide concentration in ppm. */
|
|
56290
|
-
co2Ppm: number().min(0).optional(),
|
|
56373
|
+
co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
56291
56374
|
/** Total volatile organic compounds in ppb. */
|
|
56292
|
-
vocPpb: number().min(0).optional(),
|
|
56375
|
+
vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
56293
56376
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
56294
|
-
pm25: number().min(0).optional(),
|
|
56377
|
+
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56295
56378
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
56296
|
-
pm10: number().min(0).optional(),
|
|
56379
|
+
pm10: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
56297
56380
|
/** Composite AQI value (typically 0..500). */
|
|
56298
|
-
aqi: number().optional(),
|
|
56381
|
+
aqi: number().optional().meta(readingMeta("index")),
|
|
56299
56382
|
/** Ms epoch when the slice was last updated. */
|
|
56300
|
-
lastFetchedAt: number()
|
|
56301
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
56302
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
56303
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
56304
|
-
* per slice is unambiguous. */
|
|
56305
|
-
unit: string().optional(),
|
|
56306
|
-
/** Suggested decimal places for numeric display.
|
|
56307
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56308
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56309
|
-
* auto-formatting when absent. */
|
|
56310
|
-
precision: number().int().min(0).max(10).optional()
|
|
56383
|
+
lastFetchedAt: number()
|
|
56311
56384
|
});
|
|
56312
56385
|
var airQualitySensorCapability = {
|
|
56313
56386
|
name: "air-quality-sensor",
|
|
@@ -56344,12 +56417,12 @@ var airQualitySensorCapability = {
|
|
|
56344
56417
|
},
|
|
56345
56418
|
pm25: {
|
|
56346
56419
|
kind: "gauge",
|
|
56347
|
-
unit: "
|
|
56420
|
+
unit: "µg/m³",
|
|
56348
56421
|
deadband: 1
|
|
56349
56422
|
},
|
|
56350
56423
|
pm10: {
|
|
56351
56424
|
kind: "gauge",
|
|
56352
|
-
unit: "
|
|
56425
|
+
unit: "µg/m³",
|
|
56353
56426
|
deadband: 1
|
|
56354
56427
|
},
|
|
56355
56428
|
aqi: {
|
|
@@ -56367,22 +56440,13 @@ var airQualitySensorCapability = {
|
|
|
56367
56440
|
* entries with `device_class: illuminance`.
|
|
56368
56441
|
*/
|
|
56369
56442
|
var AmbientLightSensorStatusSchema = object({
|
|
56370
|
-
/** Current illuminance in lux (lx). */
|
|
56371
|
-
lux: number().min(0).meta({
|
|
56372
|
-
|
|
56443
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
56444
|
+
lux: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
56445
|
+
precision: 0,
|
|
56373
56446
|
label: "Illuminance"
|
|
56374
|
-
}),
|
|
56447
|
+
})),
|
|
56375
56448
|
/** Ms epoch when the slice was last updated. */
|
|
56376
|
-
lastFetchedAt: number()
|
|
56377
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
56378
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
56379
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
56380
|
-
unit: string().optional(),
|
|
56381
|
-
/** Suggested decimal places for numeric display.
|
|
56382
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
56383
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
56384
|
-
* auto-formatting when absent. */
|
|
56385
|
-
precision: number().int().min(0).max(10).optional()
|
|
56449
|
+
lastFetchedAt: number()
|
|
56386
56450
|
});
|
|
56387
56451
|
var ambientLightSensorCapability = {
|
|
56388
56452
|
name: "ambient-light-sensor",
|
|
@@ -56414,12 +56478,7 @@ var ambientLightSensorCapability = {
|
|
|
56414
56478
|
} } },
|
|
56415
56479
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56416
56480
|
* whether persisting is worth a SQLite commit. */
|
|
56417
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
56418
|
-
customize: {
|
|
56419
|
-
version: 1,
|
|
56420
|
-
advanced: "derive",
|
|
56421
|
-
targets: []
|
|
56422
|
-
}
|
|
56481
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
56423
56482
|
};
|
|
56424
56483
|
/**
|
|
56425
56484
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -56646,10 +56705,7 @@ var BatteryStatusSchema = object({
|
|
|
56646
56705
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56647
56706
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56648
56707
|
*/
|
|
56649
|
-
percentage: number().min(0).max(100).nullable().meta({
|
|
56650
|
-
unit: "%",
|
|
56651
|
-
label: "Charge"
|
|
56652
|
-
}),
|
|
56708
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
56653
56709
|
/**
|
|
56654
56710
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56655
56711
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56676,7 +56732,14 @@ var BatteryStatusSchema = object({
|
|
|
56676
56732
|
*/
|
|
56677
56733
|
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56678
56734
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56679
|
-
lastUpdated: number(),
|
|
56735
|
+
lastUpdated: number().meta(readingMeta("none")),
|
|
56736
|
+
/**
|
|
56737
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
56738
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
56739
|
+
* that only report charge. A second reading on this cap, not a second
|
|
56740
|
+
* `numeric-sensor` on the same device.
|
|
56741
|
+
*/
|
|
56742
|
+
volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
56680
56743
|
/**
|
|
56681
56744
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
56682
56745
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -56728,7 +56791,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
56728
56791
|
/** Generic Customize target for the percentage reading (D936). */
|
|
56729
56792
|
var batteryCustomize = {
|
|
56730
56793
|
version: 1,
|
|
56731
|
-
advanced: "derive",
|
|
56732
56794
|
targets: [{
|
|
56733
56795
|
id: "percentage",
|
|
56734
56796
|
cardinality: "scalar",
|
|
@@ -56737,7 +56799,7 @@ var batteryCustomize = {
|
|
|
56737
56799
|
stateField: "percentage"
|
|
56738
56800
|
},
|
|
56739
56801
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
56740
|
-
apply: "add
|
|
56802
|
+
apply: "add",
|
|
56741
56803
|
path: "percentage",
|
|
56742
56804
|
sources: [{
|
|
56743
56805
|
kind: "field",
|
|
@@ -56858,10 +56920,16 @@ onStatusChanged: { data: object({
|
|
|
56858
56920
|
/**
|
|
56859
56921
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
56860
56922
|
*/
|
|
56861
|
-
history: { fields: {
|
|
56862
|
-
|
|
56863
|
-
|
|
56864
|
-
|
|
56923
|
+
history: { fields: {
|
|
56924
|
+
percentage: {
|
|
56925
|
+
kind: "gauge",
|
|
56926
|
+
unit: "%"
|
|
56927
|
+
},
|
|
56928
|
+
volts: {
|
|
56929
|
+
kind: "gauge",
|
|
56930
|
+
unit: "V"
|
|
56931
|
+
}
|
|
56932
|
+
} },
|
|
56865
56933
|
customize: batteryCustomize,
|
|
56866
56934
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56867
56935
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -56908,12 +56976,7 @@ var binaryCapability = {
|
|
|
56908
56976
|
history: { fields: { on: { kind: "boolean" } } },
|
|
56909
56977
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56910
56978
|
* whether persisting is worth a SQLite commit. */
|
|
56911
|
-
volatileStateFields: ["lastChangedAt"]
|
|
56912
|
-
customize: {
|
|
56913
|
-
version: 1,
|
|
56914
|
-
advanced: "derive",
|
|
56915
|
-
targets: []
|
|
56916
|
-
}
|
|
56979
|
+
volatileStateFields: ["lastChangedAt"]
|
|
56917
56980
|
};
|
|
56918
56981
|
/**
|
|
56919
56982
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -56929,7 +56992,7 @@ var binaryCapability = {
|
|
|
56929
56992
|
*/
|
|
56930
56993
|
var BrightnessStatusSchema = object({
|
|
56931
56994
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
56932
|
-
percentage: number().min(0).max(100),
|
|
56995
|
+
percentage: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
56933
56996
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
56934
56997
|
lastChangedAt: number()
|
|
56935
56998
|
});
|
|
@@ -57383,21 +57446,21 @@ var ClimateControlStatusSchema = object({
|
|
|
57383
57446
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
57384
57447
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
57385
57448
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
57386
|
-
target: number().nullable(),
|
|
57449
|
+
target: number().nullable().meta(readingMeta("temperature")),
|
|
57387
57450
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
57388
57451
|
* in `heat_cool` mode. */
|
|
57389
|
-
targetHigh: number().nullable(),
|
|
57452
|
+
targetHigh: number().nullable().meta(readingMeta("temperature")),
|
|
57390
57453
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
57391
57454
|
* in `heat_cool` mode. */
|
|
57392
|
-
targetLow: number().nullable(),
|
|
57455
|
+
targetLow: number().nullable().meta(readingMeta("temperature")),
|
|
57393
57456
|
/** Target relative humidity (0..100). Null when the device has no
|
|
57394
57457
|
* humidity control. */
|
|
57395
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
57458
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57396
57459
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
57397
57460
|
* the device's internal sensor. */
|
|
57398
|
-
currentTemp: number().nullable(),
|
|
57461
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
57399
57462
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
57400
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
57463
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
57401
57464
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
57402
57465
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
57403
57466
|
swingVertical: boolean().nullable(),
|
|
@@ -57405,11 +57468,11 @@ var ClimateControlStatusSchema = object({
|
|
|
57405
57468
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
57406
57469
|
swingHorizontal: boolean().nullable(),
|
|
57407
57470
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57408
|
-
minTemp: number().nullable().optional(),
|
|
57471
|
+
minTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57409
57472
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
57410
|
-
maxTemp: number().nullable().optional(),
|
|
57473
|
+
maxTemp: number().nullable().optional().meta(readingMeta("temperature")),
|
|
57411
57474
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
57412
|
-
tempStep: number().positive().nullable().optional(),
|
|
57475
|
+
tempStep: number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
57413
57476
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
57414
57477
|
lastFetchedAt: number()
|
|
57415
57478
|
});
|
|
@@ -57551,17 +57614,17 @@ var climateControlCapability = {
|
|
|
57551
57614
|
* modes to expose in the picker without a slice fetch.
|
|
57552
57615
|
*/
|
|
57553
57616
|
var RgbTripletSchema = object({
|
|
57554
|
-
r: number().int().min(0).max(255),
|
|
57555
|
-
g: number().int().min(0).max(255),
|
|
57556
|
-
b: number().int().min(0).max(255)
|
|
57617
|
+
r: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57618
|
+
g: number().int().min(0).max(255).meta(readingMeta("none")),
|
|
57619
|
+
b: number().int().min(0).max(255).meta(readingMeta("none"))
|
|
57557
57620
|
});
|
|
57558
57621
|
var HsvTripletSchema = object({
|
|
57559
57622
|
/** Hue in degrees, 0..360. */
|
|
57560
|
-
h: number().min(0).max(360),
|
|
57623
|
+
h: number().min(0).max(360).meta(readingMeta("none")),
|
|
57561
57624
|
/** Saturation as 0..100 inclusive. */
|
|
57562
|
-
s: number().min(0).max(100),
|
|
57625
|
+
s: number().min(0).max(100).meta(readingMeta("none")),
|
|
57563
57626
|
/** Value/brightness as 0..100 inclusive. */
|
|
57564
|
-
v: number().min(0).max(100)
|
|
57627
|
+
v: number().min(0).max(100).meta(readingMeta("none"))
|
|
57565
57628
|
});
|
|
57566
57629
|
var ColorInputSchema = discriminatedUnion("mode", [
|
|
57567
57630
|
object({
|
|
@@ -57590,7 +57653,7 @@ var ColorStatusSchema = object({
|
|
|
57590
57653
|
/** Populated when `mode === 'hsv'`. */
|
|
57591
57654
|
hsv: HsvTripletSchema.optional(),
|
|
57592
57655
|
/** Populated when `mode === 'mired'`. */
|
|
57593
|
-
mireds: number().int().optional(),
|
|
57656
|
+
mireds: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
57594
57657
|
/** Ms epoch of the last operator-driven change. */
|
|
57595
57658
|
lastChangedAt: number()
|
|
57596
57659
|
});
|
|
@@ -57793,18 +57856,12 @@ _enum([
|
|
|
57793
57856
|
"empty",
|
|
57794
57857
|
"full"
|
|
57795
57858
|
]);
|
|
57796
|
-
/**
|
|
57797
|
-
|
|
57798
|
-
|
|
57799
|
-
"days",
|
|
57800
|
-
"hours",
|
|
57801
|
-
"cycles"
|
|
57802
|
-
]);
|
|
57803
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
57804
|
-
* days). `value` null = unknown (D393). */
|
|
57859
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
57860
|
+
var ConsumableRemainingKindSchema = _enum(["duration", "count"]);
|
|
57861
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
57805
57862
|
var ConsumableRemainingSchema = object({
|
|
57806
|
-
value: number().min(0).nullable(),
|
|
57807
|
-
|
|
57863
|
+
value: number().min(0).nullable().meta(readingMeta("device")),
|
|
57864
|
+
kind: ConsumableRemainingKindSchema
|
|
57808
57865
|
});
|
|
57809
57866
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
57810
57867
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -57817,7 +57874,7 @@ var ConsumableItemSchema = object({
|
|
|
57817
57874
|
/** Display name. */
|
|
57818
57875
|
label: string().min(1),
|
|
57819
57876
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
57820
|
-
level: number().min(0).max(100).nullable(),
|
|
57877
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
57821
57878
|
/** The provider's discrete verdict when known (binary mode). */
|
|
57822
57879
|
status: ConsumableStatusSchema.nullable(),
|
|
57823
57880
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -57899,8 +57956,8 @@ var consumablesCustomize = {
|
|
|
57899
57956
|
transforms: [{ kind: "identity" }]
|
|
57900
57957
|
}],
|
|
57901
57958
|
literals: [{
|
|
57902
|
-
path: "remaining.
|
|
57903
|
-
values: [...
|
|
57959
|
+
path: "remaining.kind",
|
|
57960
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
57904
57961
|
}]
|
|
57905
57962
|
},
|
|
57906
57963
|
{
|
|
@@ -58029,7 +58086,6 @@ reset: method(object({
|
|
|
58029
58086
|
},
|
|
58030
58087
|
"remaining.value": {
|
|
58031
58088
|
kind: "gauge",
|
|
58032
|
-
unitFrom: "remaining.unit",
|
|
58033
58089
|
deadband: 1,
|
|
58034
58090
|
displayName: "Remaining"
|
|
58035
58091
|
}
|
|
@@ -58099,10 +58155,9 @@ var contactCapability = {
|
|
|
58099
58155
|
* (empty array for the other kinds). It lives in the slice because
|
|
58100
58156
|
* HA `select.*` entities may update their options at runtime.
|
|
58101
58157
|
*
|
|
58102
|
-
*
|
|
58103
|
-
*
|
|
58104
|
-
*
|
|
58105
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
58158
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
58159
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
58160
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
58106
58161
|
*/
|
|
58107
58162
|
var ControlStatusSchema = object({
|
|
58108
58163
|
kind: _enum([
|
|
@@ -58114,39 +58169,17 @@ var ControlStatusSchema = object({
|
|
|
58114
58169
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
58115
58170
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
58116
58171
|
* or time-only — HA accepts all three forms). */
|
|
58117
|
-
value: union([number(), string()]),
|
|
58172
|
+
value: union([number().meta(readingMeta("device")), string()]),
|
|
58118
58173
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
58119
58174
|
options: array(string()),
|
|
58120
58175
|
/** Ms epoch when the slice was last updated. */
|
|
58121
58176
|
lastChangedAt: number(),
|
|
58122
|
-
/**
|
|
58123
|
-
|
|
58124
|
-
|
|
58125
|
-
|
|
58126
|
-
/**
|
|
58127
|
-
|
|
58128
|
-
min: number().optional(),
|
|
58129
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
58130
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58131
|
-
max: number().optional(),
|
|
58132
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
58133
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
58134
|
-
step: number().optional(),
|
|
58135
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
58136
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
58137
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
58138
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
58139
|
-
precision: number().int().min(0).max(10).optional(),
|
|
58140
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
58141
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
58142
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
58143
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
58144
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
58145
|
-
format: _enum([
|
|
58146
|
-
"date",
|
|
58147
|
-
"time",
|
|
58148
|
-
"datetime"
|
|
58149
|
-
]).optional()
|
|
58177
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
58178
|
+
min: number().optional().meta(readingMeta("device")),
|
|
58179
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
58180
|
+
max: number().optional().meta(readingMeta("device")),
|
|
58181
|
+
/** Step increment, in the device quantity's base unit. */
|
|
58182
|
+
step: number().optional().meta(readingMeta("device"))
|
|
58150
58183
|
});
|
|
58151
58184
|
var ControlSetValueInputSchema = discriminatedUnion("kind", [
|
|
58152
58185
|
object({
|
|
@@ -58212,9 +58245,9 @@ var CoverStatusSchema = object({
|
|
|
58212
58245
|
]),
|
|
58213
58246
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
58214
58247
|
* no intermediate position surface. */
|
|
58215
|
-
position: number().min(0).max(100).nullable(),
|
|
58248
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58216
58249
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
58217
|
-
tiltPosition: number().min(0).max(100).nullable(),
|
|
58250
|
+
tiltPosition: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58218
58251
|
/** Ms epoch when the slice was last updated. */
|
|
58219
58252
|
lastChangedAt: number()
|
|
58220
58253
|
});
|
|
@@ -58317,9 +58350,9 @@ var NormalizedRangeSchema$1 = object({
|
|
|
58317
58350
|
var DayNightStatusSchema = object({
|
|
58318
58351
|
mode: DayNightModeSchema,
|
|
58319
58352
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
58320
|
-
sensitivity: number().optional(),
|
|
58353
|
+
sensitivity: number().optional().meta(readingMeta("none")),
|
|
58321
58354
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
58322
|
-
switchDelaySec: number().optional(),
|
|
58355
|
+
switchDelaySec: number().optional().meta(readingMeta("duration")),
|
|
58323
58356
|
lastFetchedAt: number()
|
|
58324
58357
|
});
|
|
58325
58358
|
/**
|
|
@@ -58537,11 +58570,11 @@ var DishwasherStatusSchema = object({
|
|
|
58537
58570
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
58538
58571
|
availablePrograms: array(string()),
|
|
58539
58572
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
58540
|
-
remainingSeconds: number().int().nonnegative().nullable(),
|
|
58573
|
+
remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58541
58574
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
58542
|
-
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
58575
|
+
delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
58543
58576
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
58544
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
58577
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
58545
58578
|
/** True when the door is reported open; null when the door state is not known. */
|
|
58546
58579
|
doorOpen: boolean().nullable(),
|
|
58547
58580
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -58565,7 +58598,7 @@ var DishwasherStatusSchema = object({
|
|
|
58565
58598
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
58566
58599
|
machineCareDue: boolean().nullable(),
|
|
58567
58600
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
58568
|
-
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
58601
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
58569
58602
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
58570
58603
|
halfLoad: boolean().nullable(),
|
|
58571
58604
|
hygienePlus: boolean().nullable(),
|
|
@@ -58580,7 +58613,7 @@ var DishwasherStatusSchema = object({
|
|
|
58580
58613
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
58581
58614
|
activeEvents: array(string()),
|
|
58582
58615
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
58583
|
-
errorCode: number().nullable(),
|
|
58616
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
58584
58617
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
58585
58618
|
errorLabel: string().nullable(),
|
|
58586
58619
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -58811,7 +58844,7 @@ var DoorbellStatusSchema = object({
|
|
|
58811
58844
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
58812
58845
|
lastPressedAt: number().nullable(),
|
|
58813
58846
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
58814
|
-
pressCountSinceStart: number()
|
|
58847
|
+
pressCountSinceStart: number().meta(readingMeta("count"))
|
|
58815
58848
|
});
|
|
58816
58849
|
var DoorbellPressEventSchema = object({
|
|
58817
58850
|
deviceId: number(),
|
|
@@ -58876,17 +58909,7 @@ onPressed: {
|
|
|
58876
58909
|
history: "none",
|
|
58877
58910
|
customize: doorbellCustomize
|
|
58878
58911
|
};
|
|
58879
|
-
|
|
58880
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
58881
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
58882
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
58883
|
-
* The option set is stable across observations; it is persisted in the
|
|
58884
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
58885
|
-
* stored in `sourceInfo`.
|
|
58886
|
-
*/
|
|
58887
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
58888
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
58889
|
-
var EnumSensorDateTimeFormatSchema = _enum([
|
|
58912
|
+
_enum([
|
|
58890
58913
|
"date",
|
|
58891
58914
|
"time",
|
|
58892
58915
|
"datetime"
|
|
@@ -58894,12 +58917,11 @@ var EnumSensorDateTimeFormatSchema = _enum([
|
|
|
58894
58917
|
var EnumSensorStatusSchema = object({
|
|
58895
58918
|
value: string(),
|
|
58896
58919
|
/**
|
|
58897
|
-
* Set
|
|
58898
|
-
* as
|
|
58899
|
-
*
|
|
58900
|
-
* a time-only sensor → `'time'`.
|
|
58920
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
58921
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
58922
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
58901
58923
|
*/
|
|
58902
|
-
|
|
58924
|
+
timestamp: boolean().optional(),
|
|
58903
58925
|
/** Ms epoch when the slice was last updated. */
|
|
58904
58926
|
lastFetchedAt: number()
|
|
58905
58927
|
});
|
|
@@ -58926,11 +58948,11 @@ var enumSensorCapability = {
|
|
|
58926
58948
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
58927
58949
|
* operation state, an HVAC action). The option set is per device, so the
|
|
58928
58950
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
58929
|
-
* `
|
|
58951
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
58930
58952
|
*/
|
|
58931
58953
|
history: { fields: { value: {
|
|
58932
58954
|
kind: "enum",
|
|
58933
|
-
skipWhenSet: "
|
|
58955
|
+
skipWhenSet: "timestamp"
|
|
58934
58956
|
} } },
|
|
58935
58957
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58936
58958
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -58950,13 +58972,13 @@ var EventFireSchema = object({
|
|
|
58950
58972
|
deviceId: number(),
|
|
58951
58973
|
eventType: string(),
|
|
58952
58974
|
data: record(string(), unknown()).nullable(),
|
|
58953
|
-
timestamp: number(),
|
|
58954
|
-
seq: number()
|
|
58975
|
+
timestamp: number().meta(readingMeta("none")),
|
|
58976
|
+
seq: number().meta(readingMeta("count"))
|
|
58955
58977
|
});
|
|
58956
58978
|
var EventEmitterStatusSchema = object({
|
|
58957
58979
|
eventTypes: array(string()),
|
|
58958
58980
|
lastEvent: EventFireSchema.nullable(),
|
|
58959
|
-
eventCountSinceStart: number()
|
|
58981
|
+
eventCountSinceStart: number().meta(readingMeta("count"))
|
|
58960
58982
|
});
|
|
58961
58983
|
var eventEmitterCapability = {
|
|
58962
58984
|
name: "event-emitter",
|
|
@@ -59369,10 +59391,10 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
59369
59391
|
var FanControlStatusSchema = object({
|
|
59370
59392
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
59371
59393
|
* speed surface (single-speed fan). */
|
|
59372
|
-
percentage: number().min(0).max(100).nullable(),
|
|
59394
|
+
percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59373
59395
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
59374
59396
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
59375
|
-
percentageStep: number().positive().optional(),
|
|
59397
|
+
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
59376
59398
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
59377
59399
|
* — empty string when no preset is active or supported. */
|
|
59378
59400
|
preset: string(),
|
|
@@ -59493,7 +59515,7 @@ var FeatureProbeStatusSchema = object({
|
|
|
59493
59515
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
59494
59516
|
model: string().nullable(),
|
|
59495
59517
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
59496
|
-
channelCount: number().nullable(),
|
|
59518
|
+
channelCount: number().nullable().meta(readingMeta("count")),
|
|
59497
59519
|
/**
|
|
59498
59520
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
59499
59521
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -59618,7 +59640,7 @@ var gasCapability = {
|
|
|
59618
59640
|
};
|
|
59619
59641
|
var HeatingValveStatusSchema = object({
|
|
59620
59642
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59621
|
-
position: number().min(0).max(100).nullable(),
|
|
59643
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59622
59644
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
59623
59645
|
lastFetchedAt: number()
|
|
59624
59646
|
});
|
|
@@ -59661,9 +59683,9 @@ var HumidifierStatusSchema = object({
|
|
|
59661
59683
|
/** Whether the humidifier is currently on. */
|
|
59662
59684
|
on: boolean(),
|
|
59663
59685
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
59664
|
-
currentHumidity: number().min(0).max(100).nullable(),
|
|
59686
|
+
currentHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59665
59687
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
59666
|
-
targetHumidity: number().min(0).max(100).nullable(),
|
|
59688
|
+
targetHumidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
59667
59689
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
59668
59690
|
* device has no mode surface. */
|
|
59669
59691
|
mode: string().nullable(),
|
|
@@ -59673,9 +59695,9 @@ var HumidifierStatusSchema = object({
|
|
|
59673
59695
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
59674
59696
|
action: string().nullable(),
|
|
59675
59697
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
59676
|
-
minHumidity: number().nullable(),
|
|
59698
|
+
minHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59677
59699
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
59678
|
-
maxHumidity: number().nullable(),
|
|
59700
|
+
maxHumidity: number().nullable().meta(readingMeta("humidity")),
|
|
59679
59701
|
/** Ms epoch when the slice was last updated. */
|
|
59680
59702
|
lastChangedAt: number()
|
|
59681
59703
|
});
|
|
@@ -59745,22 +59767,13 @@ var humidifierCapability = {
|
|
|
59745
59767
|
* `sourceInfo`.
|
|
59746
59768
|
*/
|
|
59747
59769
|
var HumiditySensorStatusSchema = object({
|
|
59748
|
-
/** Current relative humidity, 0..100. */
|
|
59749
|
-
percent: number().min(0).max(100).meta({
|
|
59750
|
-
|
|
59770
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
59771
|
+
percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
59772
|
+
precision: 0,
|
|
59751
59773
|
label: "Humidity"
|
|
59752
|
-
}),
|
|
59774
|
+
})),
|
|
59753
59775
|
/** Ms epoch when the slice was last updated. */
|
|
59754
|
-
lastFetchedAt: number()
|
|
59755
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
59756
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
59757
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
59758
|
-
unit: string().optional(),
|
|
59759
|
-
/** Suggested decimal places for numeric display.
|
|
59760
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
59761
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
59762
|
-
* auto-formatting when absent. */
|
|
59763
|
-
precision: number().int().min(0).max(10).optional()
|
|
59776
|
+
lastFetchedAt: number()
|
|
59764
59777
|
});
|
|
59765
59778
|
var humiditySensorCapability = {
|
|
59766
59779
|
name: "humidity-sensor",
|
|
@@ -59791,12 +59804,7 @@ var humiditySensorCapability = {
|
|
|
59791
59804
|
} } },
|
|
59792
59805
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59793
59806
|
* whether persisting is worth a SQLite commit. */
|
|
59794
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
59795
|
-
customize: {
|
|
59796
|
-
version: 1,
|
|
59797
|
-
advanced: "derive",
|
|
59798
|
-
targets: []
|
|
59799
|
-
}
|
|
59807
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
59800
59808
|
};
|
|
59801
59809
|
/**
|
|
59802
59810
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -59817,7 +59825,7 @@ var ImageStatusSchema = object({
|
|
|
59817
59825
|
* entity exposes no `entity_picture` (yet). */
|
|
59818
59826
|
url: string().nullable(),
|
|
59819
59827
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
59820
|
-
lastUpdated: number().nullable()
|
|
59828
|
+
lastUpdated: number().nullable().meta(readingMeta("none"))
|
|
59821
59829
|
});
|
|
59822
59830
|
var imageCapability = {
|
|
59823
59831
|
name: "image",
|
|
@@ -59905,19 +59913,19 @@ var NormalizedRangeSchema = object({
|
|
|
59905
59913
|
*/
|
|
59906
59914
|
var ImageSettingsStatusSchema = object({
|
|
59907
59915
|
/** Normalized 0–100. */
|
|
59908
|
-
brightness: number().optional(),
|
|
59916
|
+
brightness: number().optional().meta(readingMeta("none")),
|
|
59909
59917
|
/** Normalized 0–100. */
|
|
59910
|
-
contrast: number().optional(),
|
|
59918
|
+
contrast: number().optional().meta(readingMeta("none")),
|
|
59911
59919
|
/** Normalized 0–100. */
|
|
59912
|
-
saturation: number().optional(),
|
|
59920
|
+
saturation: number().optional().meta(readingMeta("none")),
|
|
59913
59921
|
/** Normalized 0–100. */
|
|
59914
|
-
sharpness: number().optional(),
|
|
59922
|
+
sharpness: number().optional().meta(readingMeta("none")),
|
|
59915
59923
|
mirror: boolean().optional(),
|
|
59916
59924
|
flip: boolean().optional(),
|
|
59917
59925
|
rotate: ImageRotateSchema.optional(),
|
|
59918
59926
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
59919
59927
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
59920
|
-
warmth: number().optional(),
|
|
59928
|
+
warmth: number().optional().meta(readingMeta("none")),
|
|
59921
59929
|
exposureMode: ExposureModeSchema.optional(),
|
|
59922
59930
|
backlightMode: BacklightModeSchema.optional(),
|
|
59923
59931
|
lastFetchedAt: number()
|
|
@@ -60196,10 +60204,10 @@ var IntercomAbilitySchema = object({
|
|
|
60196
60204
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
60197
60205
|
codecs: array(string()),
|
|
60198
60206
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
60199
|
-
sampleRate: number(),
|
|
60207
|
+
sampleRate: number().meta(readingMeta("none")),
|
|
60200
60208
|
duplex: _enum(["half", "full"]),
|
|
60201
60209
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
60202
|
-
maxBacklogMs: number()
|
|
60210
|
+
maxBacklogMs: number().meta(readingMeta("duration-ms"))
|
|
60203
60211
|
});
|
|
60204
60212
|
var IntercomStatusSchema = object({
|
|
60205
60213
|
/** True while a talk session is open. */
|
|
@@ -60426,13 +60434,13 @@ var LawnMowerControlStatusSchema = object({
|
|
|
60426
60434
|
activity: LawnMowerActivitySchema,
|
|
60427
60435
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
60428
60436
|
* reading. */
|
|
60429
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
60437
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60430
60438
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
60431
60439
|
* task is active / progress is unavailable. */
|
|
60432
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
60440
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60433
60441
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
60434
60442
|
* or null when unknown. */
|
|
60435
|
-
currentCode: number().nullable(),
|
|
60443
|
+
currentCode: number().nullable().meta(readingMeta("none")),
|
|
60436
60444
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
60437
60445
|
currentCodeLabel: string().nullable(),
|
|
60438
60446
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -60965,7 +60973,7 @@ var MediaPlayerStatusSchema = object({
|
|
|
60965
60973
|
state: MediaPlayerStateSchema,
|
|
60966
60974
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
60967
60975
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
60968
|
-
volumeLevel: number().min(0).max(100).nullable(),
|
|
60976
|
+
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60969
60977
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
60970
60978
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
60971
60979
|
isMuted: boolean().nullable(),
|
|
@@ -60978,10 +60986,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
60978
60986
|
currentMedia: MediaInfoSchema.nullable(),
|
|
60979
60987
|
/** Current playback position in ms. Null when not seekable or
|
|
60980
60988
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
60981
|
-
positionMs: number().int().nonnegative().nullable(),
|
|
60989
|
+
positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
60982
60990
|
/** Total duration of the current media in ms. Null when unknown
|
|
60983
60991
|
* (live stream) or nothing is playing. */
|
|
60984
|
-
durationMs: number().int().nonnegative().nullable(),
|
|
60992
|
+
durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
60985
60993
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
60986
60994
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
60987
60995
|
shuffle: boolean().nullable(),
|
|
@@ -61290,7 +61298,7 @@ var motionCustomize = {
|
|
|
61290
61298
|
eventName: "onMotionChanged"
|
|
61291
61299
|
},
|
|
61292
61300
|
deviceTypes: [DeviceType.Camera],
|
|
61293
|
-
apply: "
|
|
61301
|
+
apply: "add",
|
|
61294
61302
|
applyAuthority: {
|
|
61295
61303
|
kind: "camera-sensors",
|
|
61296
61304
|
timeoutField: "motionCooldownMs"
|
|
@@ -61362,7 +61370,7 @@ var MotionStatusSchema = object({
|
|
|
61362
61370
|
* it, every provider seeded it at boot, and every session left it
|
|
61363
61371
|
* `detected: true` after its detach.
|
|
61364
61372
|
*/
|
|
61365
|
-
autoClearAfterMs: number().nullable()
|
|
61373
|
+
autoClearAfterMs: number().nullable().meta(readingMeta("duration-ms"))
|
|
61366
61374
|
});
|
|
61367
61375
|
/**
|
|
61368
61376
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -61544,7 +61552,7 @@ var MotionZoneRegionSchema = object({
|
|
|
61544
61552
|
* the grid region(s). */
|
|
61545
61553
|
var MotionZoneStatusSchema = object({
|
|
61546
61554
|
enabled: boolean(),
|
|
61547
|
-
sensitivity: number(),
|
|
61555
|
+
sensitivity: number().meta(readingMeta("none")),
|
|
61548
61556
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
61549
61557
|
regions: array(MotionZoneRegionSchema),
|
|
61550
61558
|
lastFetchedAt: number()
|
|
@@ -61914,7 +61922,7 @@ var NavigationStatusSchema = object({
|
|
|
61914
61922
|
following: boolean(),
|
|
61915
61923
|
flash: boolean(),
|
|
61916
61924
|
lightMode: NavigationLightModeSchema,
|
|
61917
|
-
lightLevel: number().min(40).max(100),
|
|
61925
|
+
lightLevel: number().min(40).max(100).meta(readingMeta("none")),
|
|
61918
61926
|
/** Ms epoch when the slice was last updated. */
|
|
61919
61927
|
lastChangedAt: number()
|
|
61920
61928
|
});
|
|
@@ -62048,13 +62056,13 @@ var NetworkLinkStatusSchema = object({
|
|
|
62048
62056
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62049
62057
|
* SKIP a null rather than coerce it.
|
|
62050
62058
|
*/
|
|
62051
|
-
signalPercent: number().min(0).max(100).nullable(),
|
|
62059
|
+
signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62052
62060
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62053
|
-
rssiDbm: number().optional(),
|
|
62061
|
+
rssiDbm: number().optional().meta(readingMeta("signal-level")),
|
|
62054
62062
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62055
62063
|
ssid: string().optional(),
|
|
62056
62064
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62057
|
-
lastUpdated: number()
|
|
62065
|
+
lastUpdated: number().meta(readingMeta("none"))
|
|
62058
62066
|
});
|
|
62059
62067
|
var networkLinkCapability = {
|
|
62060
62068
|
name: "network-link",
|
|
@@ -62439,7 +62447,7 @@ var NotifierStatusSchema = object({
|
|
|
62439
62447
|
lastError: string().nullable(),
|
|
62440
62448
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
62441
62449
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
62442
|
-
queueDepth: number().int().nonnegative(),
|
|
62450
|
+
queueDepth: number().int().nonnegative().meta(readingMeta("count")),
|
|
62443
62451
|
/** Per-feature capability matrix — authoritative source for the
|
|
62444
62452
|
* compose-form field gating. */
|
|
62445
62453
|
supports: NotifierSupportsSchema
|
|
@@ -62531,11 +62539,9 @@ onSent: { data: object({
|
|
|
62531
62539
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
62532
62540
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
62533
62541
|
*
|
|
62534
|
-
* The
|
|
62535
|
-
*
|
|
62536
|
-
*
|
|
62537
|
-
* The UI reads them directly from the slice — they are the single source
|
|
62538
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
62542
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
62543
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
62544
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
62539
62545
|
*
|
|
62540
62546
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
62541
62547
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -62544,15 +62550,8 @@ onSent: { data: object({
|
|
|
62544
62550
|
* numeric values land here.
|
|
62545
62551
|
*/
|
|
62546
62552
|
var NumericSensorStatusSchema = object({
|
|
62547
|
-
|
|
62548
|
-
|
|
62549
|
-
* Populated live from the upstream source on each state push.
|
|
62550
|
-
* Absent for unitless sensors. */
|
|
62551
|
-
unit: string().optional(),
|
|
62552
|
-
/** Suggested decimal places for numeric display.
|
|
62553
|
-
* Populated live from the upstream source when provided.
|
|
62554
|
-
* Falls back to auto-formatting when absent. */
|
|
62555
|
-
precision: number().int().min(0).max(10).optional(),
|
|
62553
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
62554
|
+
value: number().nullable().meta(readingMeta("device")),
|
|
62556
62555
|
/** Ms epoch when the slice was last updated. */
|
|
62557
62556
|
lastFetchedAt: number()
|
|
62558
62557
|
});
|
|
@@ -62576,11 +62575,11 @@ var numericSensorCapability = {
|
|
|
62576
62575
|
*/
|
|
62577
62576
|
durability: "restored",
|
|
62578
62577
|
/**
|
|
62579
|
-
* History (D850): recorded series. The unit is
|
|
62578
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
62579
|
+
* resolved when the series is read — the cap has no single unit.
|
|
62580
62580
|
*/
|
|
62581
62581
|
history: { fields: { value: {
|
|
62582
62582
|
kind: "gauge",
|
|
62583
|
-
unitFrom: "unit",
|
|
62584
62583
|
minIntervalMs: 3e4
|
|
62585
62584
|
} } },
|
|
62586
62585
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -62872,23 +62871,26 @@ var PetFeederStatusSchema = object({
|
|
|
62872
62871
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
62873
62872
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
62874
62873
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
62875
|
-
foodLevel: number().nullable(),
|
|
62874
|
+
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
62876
62875
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
62877
62876
|
* single-hopper models. */
|
|
62878
|
-
food1: number().nullable(),
|
|
62877
|
+
food1: number().nullable().meta(readingMeta("none")),
|
|
62879
62878
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
62880
62879
|
* single-hopper models. */
|
|
62881
|
-
food2: number().nullable(),
|
|
62880
|
+
food2: number().nullable().meta(readingMeta("none")),
|
|
62882
62881
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
62883
62882
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
62884
62883
|
* below the feeder's low threshold. */
|
|
62885
62884
|
lowFood: boolean(),
|
|
62886
62885
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
62887
62886
|
* device has no battery reading. */
|
|
62888
|
-
batteryPower: number().min(0).max(100).nullable(),
|
|
62889
|
-
/**
|
|
62890
|
-
*
|
|
62891
|
-
|
|
62887
|
+
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62888
|
+
/**
|
|
62889
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
62890
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
62891
|
+
* model has no desiccant sensor.
|
|
62892
|
+
*/
|
|
62893
|
+
desiccantLeftDays: number().nullable().meta(readingMeta("duration")),
|
|
62892
62894
|
/** True while a feed is in progress. */
|
|
62893
62895
|
feeding: boolean(),
|
|
62894
62896
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -62899,7 +62901,7 @@ var PetFeederStatusSchema = object({
|
|
|
62899
62901
|
* with `errorCode` for consumers that want the raw integer. */
|
|
62900
62902
|
error: string().nullable(),
|
|
62901
62903
|
/** Raw device error code (0 / null = no error). */
|
|
62902
|
-
errorCode: number().nullable(),
|
|
62904
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
62903
62905
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
62904
62906
|
isDualHopper: boolean(),
|
|
62905
62907
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -62909,7 +62911,7 @@ var PetFeederStatusSchema = object({
|
|
|
62909
62911
|
/** Play a chime when dispensing. */
|
|
62910
62912
|
feedSound: boolean(),
|
|
62911
62913
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
62912
|
-
volume: number(),
|
|
62914
|
+
volume: number().meta(readingMeta("none")),
|
|
62913
62915
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
62914
62916
|
lastFetchedAt: number()
|
|
62915
62917
|
});
|
|
@@ -63028,7 +63030,7 @@ var petFeederCapability = {
|
|
|
63028
63030
|
},
|
|
63029
63031
|
desiccantLeftDays: {
|
|
63030
63032
|
kind: "gauge",
|
|
63031
|
-
unit: "
|
|
63033
|
+
unit: "s"
|
|
63032
63034
|
}
|
|
63033
63035
|
} }
|
|
63034
63036
|
};
|
|
@@ -63429,36 +63431,19 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
63429
63431
|
*/
|
|
63430
63432
|
var PowerMeterStatusSchema = object({
|
|
63431
63433
|
/** Instantaneous power draw in watts. */
|
|
63432
|
-
watts: number().optional().meta({
|
|
63433
|
-
unit: "W",
|
|
63434
|
-
label: "Power"
|
|
63435
|
-
}),
|
|
63434
|
+
watts: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
63436
63435
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
63437
|
-
kwhTotal: number().optional().meta({
|
|
63438
|
-
unit: "kWh",
|
|
63439
|
-
label: "Energy"
|
|
63440
|
-
}),
|
|
63436
|
+
kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
63441
63437
|
/** Voltage in volts. */
|
|
63442
|
-
volts: number().optional(),
|
|
63438
|
+
volts: number().optional().meta(readingMeta("voltage")),
|
|
63443
63439
|
/** Current in amperes. */
|
|
63444
|
-
amps: number().optional(),
|
|
63445
|
-
/** Apparent power in volt-amperes
|
|
63446
|
-
va: number().optional(),
|
|
63440
|
+
amps: number().optional().meta(readingMeta("current")),
|
|
63441
|
+
/** Apparent power in volt-amperes. */
|
|
63442
|
+
va: number().optional().meta(readingMeta("apparent-power")),
|
|
63447
63443
|
/** Power factor (0..1) if reported. */
|
|
63448
|
-
powerFactor: number().min(0).max(1).optional(),
|
|
63444
|
+
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
63449
63445
|
/** Ms epoch when the slice was last updated. */
|
|
63450
|
-
lastFetchedAt: number()
|
|
63451
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
63452
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
63453
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
63454
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
63455
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
63456
|
-
unit: string().optional(),
|
|
63457
|
-
/** Suggested decimal places for numeric display.
|
|
63458
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63459
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63460
|
-
* auto-formatting when absent. */
|
|
63461
|
-
precision: number().int().min(0).max(10).optional()
|
|
63446
|
+
lastFetchedAt: number()
|
|
63462
63447
|
});
|
|
63463
63448
|
var powerMeterCapability = {
|
|
63464
63449
|
name: "power-meter",
|
|
@@ -63522,12 +63507,7 @@ var powerMeterCapability = {
|
|
|
63522
63507
|
} },
|
|
63523
63508
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63524
63509
|
* whether persisting is worth a SQLite commit. */
|
|
63525
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
63526
|
-
customize: {
|
|
63527
|
-
version: 1,
|
|
63528
|
-
advanced: "derive",
|
|
63529
|
-
targets: []
|
|
63530
|
-
}
|
|
63510
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
63531
63511
|
};
|
|
63532
63512
|
/**
|
|
63533
63513
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -63547,11 +63527,11 @@ var powerMeterCapability = {
|
|
|
63547
63527
|
*/
|
|
63548
63528
|
var GpsLocationSchema = object({
|
|
63549
63529
|
/** Latitude in decimal degrees, -90..90. */
|
|
63550
|
-
latitude: number().min(-90).max(90),
|
|
63530
|
+
latitude: number().min(-90).max(90).meta(readingMeta("angle")),
|
|
63551
63531
|
/** Longitude in decimal degrees, -180..180. */
|
|
63552
|
-
longitude: number().min(-180).max(180),
|
|
63532
|
+
longitude: number().min(-180).max(180).meta(readingMeta("angle")),
|
|
63553
63533
|
/** Reported accuracy in meters (lower = better). */
|
|
63554
|
-
accuracyMeters: number().nonnegative()
|
|
63534
|
+
accuracyMeters: number().nonnegative().meta(readingMeta("length"))
|
|
63555
63535
|
});
|
|
63556
63536
|
var PresenceStatusSchema = object({
|
|
63557
63537
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -63563,7 +63543,7 @@ var PresenceStatusSchema = object({
|
|
|
63563
63543
|
gps: GpsLocationSchema.nullable(),
|
|
63564
63544
|
/** Optional battery level of the tracking device (0..100). Null
|
|
63565
63545
|
* when not reported. */
|
|
63566
|
-
batteryPercent: number().min(0).max(100).nullable(),
|
|
63546
|
+
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63567
63547
|
/** Ms epoch when the slice was last updated. */
|
|
63568
63548
|
lastChangedAt: number()
|
|
63569
63549
|
});
|
|
@@ -63613,19 +63593,10 @@ var presenceCapability = {
|
|
|
63613
63593
|
* `sourceInfo`.
|
|
63614
63594
|
*/
|
|
63615
63595
|
var PressureSensorStatusSchema = object({
|
|
63616
|
-
/** Current pressure in hPa. */
|
|
63617
|
-
hpa: number(),
|
|
63596
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
63597
|
+
hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
63618
63598
|
/** Ms epoch when the slice was last updated. */
|
|
63619
|
-
lastFetchedAt: number()
|
|
63620
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
63621
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
63622
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
63623
|
-
unit: string().optional(),
|
|
63624
|
-
/** Suggested decimal places for numeric display.
|
|
63625
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
63626
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
63627
|
-
* auto-formatting when absent. */
|
|
63628
|
-
precision: number().int().min(0).max(10).optional()
|
|
63599
|
+
lastFetchedAt: number()
|
|
63629
63600
|
});
|
|
63630
63601
|
var pressureSensorCapability = {
|
|
63631
63602
|
name: "pressure-sensor",
|
|
@@ -64039,8 +64010,8 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
|
|
|
64039
64010
|
}), _void(), { kind: "mutation" });
|
|
64040
64011
|
var PtzAutotrackSettingsSchema = object({
|
|
64041
64012
|
targetType: string().describe("Vendor target string (people/vehicle/pet); empty = camera default"),
|
|
64042
|
-
stopDelaySeconds: number().int().min(0).max(300),
|
|
64043
|
-
disappearDelaySeconds: number().int().min(0).max(300)
|
|
64013
|
+
stopDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
64014
|
+
disappearDelaySeconds: number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
64044
64015
|
});
|
|
64045
64016
|
/**
|
|
64046
64017
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -64202,7 +64173,7 @@ var RunningStateStatusSchema = object({
|
|
|
64202
64173
|
/** null = unknown — never coerced to false (D393). */
|
|
64203
64174
|
running: boolean().nullable(),
|
|
64204
64175
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
64205
|
-
since: number().nullable(),
|
|
64176
|
+
since: number().nullable().meta(readingMeta("none")),
|
|
64206
64177
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
64207
64178
|
phase: string().nullable(),
|
|
64208
64179
|
/** null until a reading has been published (D393). */
|
|
@@ -64217,7 +64188,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
64217
64188
|
/** Generic Customize target for the running boolean (D936). */
|
|
64218
64189
|
var runningCustomize = {
|
|
64219
64190
|
version: 1,
|
|
64220
|
-
advanced: "derive",
|
|
64221
64191
|
targets: [{
|
|
64222
64192
|
id: "running",
|
|
64223
64193
|
cardinality: "scalar",
|
|
@@ -64237,7 +64207,7 @@ var runningCustomize = {
|
|
|
64237
64207
|
DeviceType.Thermostat,
|
|
64238
64208
|
DeviceType.PetFeeder
|
|
64239
64209
|
],
|
|
64240
|
-
apply: "add
|
|
64210
|
+
apply: "add",
|
|
64241
64211
|
path: "running",
|
|
64242
64212
|
sources: [
|
|
64243
64213
|
{
|
|
@@ -65501,9 +65471,9 @@ var RecordTriggerSchema = _enum([
|
|
|
65501
65471
|
*/
|
|
65502
65472
|
var RecordWindowSchema = object({
|
|
65503
65473
|
trigger: RecordTriggerSchema,
|
|
65504
|
-
day: number().int().min(0).max(6),
|
|
65505
|
-
startMinute: number().int().min(0).max(1439),
|
|
65506
|
-
endMinute: number().int().min(1).max(1440)
|
|
65474
|
+
day: number().int().min(0).max(6).meta(readingMeta("none")),
|
|
65475
|
+
startMinute: number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
65476
|
+
endMinute: number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
65507
65477
|
});
|
|
65508
65478
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
65509
65479
|
var OnboardStorageVolumeSchema = object({
|
|
@@ -65579,10 +65549,10 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65579
65549
|
/** Master "record to the card at all" switch. */
|
|
65580
65550
|
enabled: boolean().nullable(),
|
|
65581
65551
|
overwriteWhenFull: boolean().nullable(),
|
|
65582
|
-
preRecordSec: number().nullable(),
|
|
65583
|
-
postRecordSec: number().nullable(),
|
|
65552
|
+
preRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65553
|
+
postRecordSec: number().nullable().meta(readingMeta("duration")),
|
|
65584
65554
|
/** Length of one recorded file, in minutes. */
|
|
65585
|
-
segmentMinutes: number().nullable(),
|
|
65555
|
+
segmentMinutes: number().nullable().meta(readingMeta("none")),
|
|
65586
65556
|
/** The primary track's weekly windows, flattened. */
|
|
65587
65557
|
windows: array(RecordWindowSchema),
|
|
65588
65558
|
/**
|
|
@@ -65598,7 +65568,7 @@ var RecordingOnboardStatusSchema = object({
|
|
|
65598
65568
|
* provider reporting a non-zero count also reports the schedule as not
|
|
65599
65569
|
* writable.
|
|
65600
65570
|
*/
|
|
65601
|
-
unreadableWindows: number(),
|
|
65571
|
+
unreadableWindows: number().meta(readingMeta("count")),
|
|
65602
65572
|
/**
|
|
65603
65573
|
* The camera is scheduled to record and has NO usable storage.
|
|
65604
65574
|
*
|
|
@@ -66443,7 +66413,7 @@ var CamStreamDescriptorSchema = object({
|
|
|
66443
66413
|
url: string().optional(),
|
|
66444
66414
|
codec: string().optional(),
|
|
66445
66415
|
resolution: CamStreamResolutionSchema.optional(),
|
|
66446
|
-
fps: number().positive().optional(),
|
|
66416
|
+
fps: number().positive().optional().meta(readingMeta("rate")),
|
|
66447
66417
|
label: string().optional(),
|
|
66448
66418
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
66449
66419
|
deviceFeatures: array(string()).optional(),
|
|
@@ -66530,18 +66500,18 @@ var StreamProfileSchema = _enum([
|
|
|
66530
66500
|
]);
|
|
66531
66501
|
/** The current encoding config of one stream profile. */
|
|
66532
66502
|
var StreamProfileConfigSchema = object({
|
|
66533
|
-
width: number(),
|
|
66534
|
-
height: number(),
|
|
66503
|
+
width: number().meta(readingMeta("none")),
|
|
66504
|
+
height: number().meta(readingMeta("none")),
|
|
66535
66505
|
codec: _enum(["h264", "h265"]),
|
|
66536
|
-
framerate: number(),
|
|
66537
|
-
bitrate: number(),
|
|
66506
|
+
framerate: number().meta(readingMeta("rate")),
|
|
66507
|
+
bitrate: number().meta(readingMeta("bitrate")),
|
|
66538
66508
|
bitrateMode: _enum(["vbr", "cbr"]).optional(),
|
|
66539
66509
|
encoderProfile: _enum([
|
|
66540
66510
|
"high",
|
|
66541
66511
|
"main",
|
|
66542
66512
|
"baseline"
|
|
66543
66513
|
]).optional(),
|
|
66544
|
-
gop: number().optional(),
|
|
66514
|
+
gop: number().optional().meta(readingMeta("none")),
|
|
66545
66515
|
/**
|
|
66546
66516
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
66547
66517
|
*
|
|
@@ -66762,12 +66732,7 @@ var switchCapability = {
|
|
|
66762
66732
|
label: "On",
|
|
66763
66733
|
kind: "boolean"
|
|
66764
66734
|
}
|
|
66765
|
-
}] }
|
|
66766
|
-
customize: {
|
|
66767
|
-
version: 1,
|
|
66768
|
-
advanced: "derive",
|
|
66769
|
-
targets: []
|
|
66770
|
-
}
|
|
66735
|
+
}] }
|
|
66771
66736
|
};
|
|
66772
66737
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
66773
66738
|
function hasControlCharacter(value) {
|
|
@@ -67350,35 +67315,21 @@ var tamperCapability = {
|
|
|
67350
67315
|
* entries with `device_class: temperature` and any future native
|
|
67351
67316
|
* thermometer.
|
|
67352
67317
|
*
|
|
67353
|
-
*
|
|
67354
|
-
*
|
|
67355
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
67356
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
67357
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
67358
|
-
* `sourceInfo`.
|
|
67318
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
67319
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
67359
67320
|
*
|
|
67360
67321
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
67361
67322
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
67362
67323
|
* changed" steady state.
|
|
67363
67324
|
*/
|
|
67364
67325
|
var TemperatureSensorStatusSchema = object({
|
|
67365
|
-
/** Current temperature in Celsius. */
|
|
67366
|
-
celsius: number().meta({
|
|
67367
|
-
|
|
67326
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
67327
|
+
celsius: number().nullable().meta(readingMeta("temperature", {
|
|
67328
|
+
precision: 1,
|
|
67368
67329
|
label: "Temperature"
|
|
67369
|
-
}),
|
|
67330
|
+
})),
|
|
67370
67331
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
67371
|
-
lastFetchedAt: number()
|
|
67372
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
67373
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
67374
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
67375
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
67376
|
-
unit: string().optional(),
|
|
67377
|
-
/** Suggested decimal places for numeric display.
|
|
67378
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
67379
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
67380
|
-
* auto-formatting when absent. */
|
|
67381
|
-
precision: number().int().min(0).max(10).optional()
|
|
67332
|
+
lastFetchedAt: number()
|
|
67382
67333
|
});
|
|
67383
67334
|
var temperatureSensorCapability = {
|
|
67384
67335
|
name: "temperature-sensor",
|
|
@@ -67409,12 +67360,7 @@ var temperatureSensorCapability = {
|
|
|
67409
67360
|
} } },
|
|
67410
67361
|
/** Clock fields: written, but excluded from the compare that decides
|
|
67411
67362
|
* whether persisting is worth a SQLite commit. */
|
|
67412
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
67413
|
-
customize: {
|
|
67414
|
-
version: 1,
|
|
67415
|
-
advanced: "derive",
|
|
67416
|
-
targets: []
|
|
67417
|
-
}
|
|
67363
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
67418
67364
|
};
|
|
67419
67365
|
/**
|
|
67420
67366
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -67697,16 +67643,16 @@ var VacuumControlStatusSchema = object({
|
|
|
67697
67643
|
]),
|
|
67698
67644
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
67699
67645
|
* reading. */
|
|
67700
|
-
batteryLevel: number().min(0).max(100).nullable(),
|
|
67646
|
+
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67701
67647
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
67702
67648
|
* the vacuum has no speed control. */
|
|
67703
67649
|
fanSpeed: string().nullable(),
|
|
67704
67650
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
67705
67651
|
availableFanSpeeds: array(string()),
|
|
67706
67652
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
67707
|
-
progressPercent: number().min(0).max(100).nullable(),
|
|
67653
|
+
progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67708
67654
|
/** Current error code (0 / null = no error). */
|
|
67709
|
-
errorCode: number().nullable(),
|
|
67655
|
+
errorCode: number().nullable().meta(readingMeta("none")),
|
|
67710
67656
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
67711
67657
|
errorLabel: string().nullable(),
|
|
67712
67658
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -67784,7 +67730,7 @@ var ValveStatusSchema = object({
|
|
|
67784
67730
|
]),
|
|
67785
67731
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
67786
67732
|
* intermediate position surface. */
|
|
67787
|
-
position: number().min(0).max(100).nullable(),
|
|
67733
|
+
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67788
67734
|
/** Ms epoch when the slice was last updated. */
|
|
67789
67735
|
lastChangedAt: number()
|
|
67790
67736
|
});
|
|
@@ -67892,9 +67838,9 @@ var vibrationCapability = {
|
|
|
67892
67838
|
*/
|
|
67893
67839
|
var WaterHeaterStatusSchema = object({
|
|
67894
67840
|
/** Current measured temperature. Null when not reported. */
|
|
67895
|
-
currentTemp: number().nullable(),
|
|
67841
|
+
currentTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67896
67842
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
67897
|
-
targetTemp: number().nullable(),
|
|
67843
|
+
targetTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67898
67844
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
67899
67845
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
67900
67846
|
* device reports an unknown state. */
|
|
@@ -67905,9 +67851,9 @@ var WaterHeaterStatusSchema = object({
|
|
|
67905
67851
|
* has no away surface. */
|
|
67906
67852
|
away: boolean().nullable(),
|
|
67907
67853
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
67908
|
-
minTemp: number().nullable(),
|
|
67854
|
+
minTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67909
67855
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
67910
|
-
maxTemp: number().nullable(),
|
|
67856
|
+
maxTemp: number().nullable().meta(readingMeta("temperature")),
|
|
67911
67857
|
/** Ms epoch when the slice was last updated. */
|
|
67912
67858
|
lastChangedAt: number()
|
|
67913
67859
|
});
|
|
@@ -67992,25 +67938,18 @@ var waterHeaterCapability = {
|
|
|
67992
67938
|
* Forecast deferred — current conditions only for v1.
|
|
67993
67939
|
*/
|
|
67994
67940
|
var WeatherStatusSchema = object({
|
|
67995
|
-
/** Verbatim
|
|
67996
|
-
* when no condition has been reported yet. */
|
|
67941
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
67997
67942
|
condition: string().nullable(),
|
|
67998
|
-
/** Current temperature in
|
|
67999
|
-
temperature: number().nullable(),
|
|
68000
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
68001
|
-
temperatureUnit: string().nullable(),
|
|
67943
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
67944
|
+
temperature: number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
68002
67945
|
/** Relative humidity (0..100). Null when not provided. */
|
|
68003
|
-
humidity: number().min(0).max(100).nullable(),
|
|
68004
|
-
/** Barometric pressure in
|
|
68005
|
-
pressure: number().nullable(),
|
|
68006
|
-
/**
|
|
68007
|
-
|
|
68008
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
68009
|
-
windSpeed: number().nullable(),
|
|
68010
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
68011
|
-
windSpeedUnit: string().nullable(),
|
|
67946
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
67947
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
67948
|
+
pressure: number().nullable().meta(readingMeta("pressure")),
|
|
67949
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
67950
|
+
windSpeed: number().nullable().meta(readingMeta("speed")),
|
|
68012
67951
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
68013
|
-
windBearing: number().nullable(),
|
|
67952
|
+
windBearing: number().nullable().meta(readingMeta("angle")),
|
|
68014
67953
|
/** Ms epoch when the slice was last updated. */
|
|
68015
67954
|
lastFetchedAt: number()
|
|
68016
67955
|
});
|
|
@@ -68038,12 +67977,12 @@ var weatherCapability = {
|
|
|
68038
67977
|
*/
|
|
68039
67978
|
durability: "session",
|
|
68040
67979
|
/**
|
|
68041
|
-
* History (D850): recorded series.
|
|
67980
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
68042
67981
|
*/
|
|
68043
67982
|
history: { fields: {
|
|
68044
67983
|
temperature: {
|
|
68045
67984
|
kind: "gauge",
|
|
68046
|
-
|
|
67985
|
+
unit: "°C",
|
|
68047
67986
|
deadband: .2
|
|
68048
67987
|
},
|
|
68049
67988
|
humidity: {
|
|
@@ -68053,12 +67992,12 @@ var weatherCapability = {
|
|
|
68053
67992
|
},
|
|
68054
67993
|
pressure: {
|
|
68055
67994
|
kind: "gauge",
|
|
68056
|
-
|
|
67995
|
+
unit: "hPa",
|
|
68057
67996
|
deadband: .5
|
|
68058
67997
|
},
|
|
68059
67998
|
windSpeed: {
|
|
68060
67999
|
kind: "gauge",
|
|
68061
|
-
|
|
68000
|
+
unit: "m/s",
|
|
68062
68001
|
deadband: .5
|
|
68063
68002
|
}
|
|
68064
68003
|
} }
|
|
@@ -68990,6 +68929,389 @@ function runningFromDishwasherOperation(operation, program, previous, fetchedAt,
|
|
|
68990
68929
|
if (operation === "Pause") return nativeSlice(false, "Pause", previous, transitionAtMs, fetchedAt, null);
|
|
68991
68930
|
return nativeSlice(false, operation, previous, transitionAtMs, fetchedAt, null);
|
|
68992
68931
|
}
|
|
68932
|
+
/**
|
|
68933
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
68934
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
68935
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
68936
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
68937
|
+
*/
|
|
68938
|
+
var UNIT_TABLE = {
|
|
68939
|
+
"°C": {
|
|
68940
|
+
dimension: "temperature",
|
|
68941
|
+
factor: 1,
|
|
68942
|
+
offset: 0
|
|
68943
|
+
},
|
|
68944
|
+
"°F": {
|
|
68945
|
+
dimension: "temperature",
|
|
68946
|
+
factor: 5 / 9,
|
|
68947
|
+
offset: -160 / 9
|
|
68948
|
+
},
|
|
68949
|
+
K: {
|
|
68950
|
+
dimension: "temperature",
|
|
68951
|
+
factor: 1,
|
|
68952
|
+
offset: -273.15
|
|
68953
|
+
},
|
|
68954
|
+
hPa: {
|
|
68955
|
+
dimension: "pressure",
|
|
68956
|
+
factor: 1,
|
|
68957
|
+
offset: 0
|
|
68958
|
+
},
|
|
68959
|
+
kPa: {
|
|
68960
|
+
dimension: "pressure",
|
|
68961
|
+
factor: 10,
|
|
68962
|
+
offset: 0
|
|
68963
|
+
},
|
|
68964
|
+
Pa: {
|
|
68965
|
+
dimension: "pressure",
|
|
68966
|
+
factor: .01,
|
|
68967
|
+
offset: 0
|
|
68968
|
+
},
|
|
68969
|
+
mbar: {
|
|
68970
|
+
dimension: "pressure",
|
|
68971
|
+
factor: 1,
|
|
68972
|
+
offset: 0
|
|
68973
|
+
},
|
|
68974
|
+
bar: {
|
|
68975
|
+
dimension: "pressure",
|
|
68976
|
+
factor: 1e3,
|
|
68977
|
+
offset: 0
|
|
68978
|
+
},
|
|
68979
|
+
inHg: {
|
|
68980
|
+
dimension: "pressure",
|
|
68981
|
+
factor: 33.8639,
|
|
68982
|
+
offset: 0
|
|
68983
|
+
},
|
|
68984
|
+
mmHg: {
|
|
68985
|
+
dimension: "pressure",
|
|
68986
|
+
factor: 1.33322,
|
|
68987
|
+
offset: 0
|
|
68988
|
+
},
|
|
68989
|
+
psi: {
|
|
68990
|
+
dimension: "pressure",
|
|
68991
|
+
factor: 68.9476,
|
|
68992
|
+
offset: 0
|
|
68993
|
+
},
|
|
68994
|
+
"m/s": {
|
|
68995
|
+
dimension: "speed",
|
|
68996
|
+
factor: 1,
|
|
68997
|
+
offset: 0
|
|
68998
|
+
},
|
|
68999
|
+
"km/h": {
|
|
69000
|
+
dimension: "speed",
|
|
69001
|
+
factor: 1 / 3.6,
|
|
69002
|
+
offset: 0
|
|
69003
|
+
},
|
|
69004
|
+
mph: {
|
|
69005
|
+
dimension: "speed",
|
|
69006
|
+
factor: .44704,
|
|
69007
|
+
offset: 0
|
|
69008
|
+
},
|
|
69009
|
+
kn: {
|
|
69010
|
+
dimension: "speed",
|
|
69011
|
+
factor: .514444,
|
|
69012
|
+
offset: 0
|
|
69013
|
+
},
|
|
69014
|
+
"mm/h": {
|
|
69015
|
+
dimension: "precipitation-rate",
|
|
69016
|
+
factor: 1,
|
|
69017
|
+
offset: 0
|
|
69018
|
+
},
|
|
69019
|
+
"in/h": {
|
|
69020
|
+
dimension: "precipitation-rate",
|
|
69021
|
+
factor: 25.4,
|
|
69022
|
+
offset: 0
|
|
69023
|
+
},
|
|
69024
|
+
m: {
|
|
69025
|
+
dimension: "length",
|
|
69026
|
+
factor: 1,
|
|
69027
|
+
offset: 0
|
|
69028
|
+
},
|
|
69029
|
+
mm: {
|
|
69030
|
+
dimension: "length",
|
|
69031
|
+
factor: .001,
|
|
69032
|
+
offset: 0
|
|
69033
|
+
},
|
|
69034
|
+
cm: {
|
|
69035
|
+
dimension: "length",
|
|
69036
|
+
factor: .01,
|
|
69037
|
+
offset: 0
|
|
69038
|
+
},
|
|
69039
|
+
km: {
|
|
69040
|
+
dimension: "length",
|
|
69041
|
+
factor: 1e3,
|
|
69042
|
+
offset: 0
|
|
69043
|
+
},
|
|
69044
|
+
in: {
|
|
69045
|
+
dimension: "length",
|
|
69046
|
+
factor: .0254,
|
|
69047
|
+
offset: 0
|
|
69048
|
+
},
|
|
69049
|
+
ft: {
|
|
69050
|
+
dimension: "length",
|
|
69051
|
+
factor: .3048,
|
|
69052
|
+
offset: 0
|
|
69053
|
+
},
|
|
69054
|
+
mi: {
|
|
69055
|
+
dimension: "length",
|
|
69056
|
+
factor: 1609.344,
|
|
69057
|
+
offset: 0
|
|
69058
|
+
},
|
|
69059
|
+
"m²": {
|
|
69060
|
+
dimension: "area",
|
|
69061
|
+
factor: 1,
|
|
69062
|
+
offset: 0
|
|
69063
|
+
},
|
|
69064
|
+
lx: {
|
|
69065
|
+
dimension: "illuminance",
|
|
69066
|
+
factor: 1,
|
|
69067
|
+
offset: 0
|
|
69068
|
+
},
|
|
69069
|
+
"W/m²": {
|
|
69070
|
+
dimension: "irradiance",
|
|
69071
|
+
factor: 1,
|
|
69072
|
+
offset: 0
|
|
69073
|
+
},
|
|
69074
|
+
W: {
|
|
69075
|
+
dimension: "power",
|
|
69076
|
+
factor: 1,
|
|
69077
|
+
offset: 0
|
|
69078
|
+
},
|
|
69079
|
+
kW: {
|
|
69080
|
+
dimension: "power",
|
|
69081
|
+
factor: 1e3,
|
|
69082
|
+
offset: 0
|
|
69083
|
+
},
|
|
69084
|
+
VA: {
|
|
69085
|
+
dimension: "apparent-power",
|
|
69086
|
+
factor: 1,
|
|
69087
|
+
offset: 0
|
|
69088
|
+
},
|
|
69089
|
+
Wh: {
|
|
69090
|
+
dimension: "energy",
|
|
69091
|
+
factor: 1,
|
|
69092
|
+
offset: 0
|
|
69093
|
+
},
|
|
69094
|
+
kWh: {
|
|
69095
|
+
dimension: "energy",
|
|
69096
|
+
factor: 1e3,
|
|
69097
|
+
offset: 0
|
|
69098
|
+
},
|
|
69099
|
+
MWh: {
|
|
69100
|
+
dimension: "energy",
|
|
69101
|
+
factor: 1e6,
|
|
69102
|
+
offset: 0
|
|
69103
|
+
},
|
|
69104
|
+
V: {
|
|
69105
|
+
dimension: "voltage",
|
|
69106
|
+
factor: 1,
|
|
69107
|
+
offset: 0
|
|
69108
|
+
},
|
|
69109
|
+
mV: {
|
|
69110
|
+
dimension: "voltage",
|
|
69111
|
+
factor: .001,
|
|
69112
|
+
offset: 0
|
|
69113
|
+
},
|
|
69114
|
+
A: {
|
|
69115
|
+
dimension: "current",
|
|
69116
|
+
factor: 1,
|
|
69117
|
+
offset: 0
|
|
69118
|
+
},
|
|
69119
|
+
mA: {
|
|
69120
|
+
dimension: "current",
|
|
69121
|
+
factor: .001,
|
|
69122
|
+
offset: 0
|
|
69123
|
+
},
|
|
69124
|
+
ppm: {
|
|
69125
|
+
dimension: "concentration-volume",
|
|
69126
|
+
factor: 1,
|
|
69127
|
+
offset: 0
|
|
69128
|
+
},
|
|
69129
|
+
ppb: {
|
|
69130
|
+
dimension: "concentration-volume",
|
|
69131
|
+
factor: .001,
|
|
69132
|
+
offset: 0
|
|
69133
|
+
},
|
|
69134
|
+
"µg/m³": {
|
|
69135
|
+
dimension: "concentration-mass",
|
|
69136
|
+
factor: 1,
|
|
69137
|
+
offset: 0
|
|
69138
|
+
},
|
|
69139
|
+
"mg/m³": {
|
|
69140
|
+
dimension: "concentration-mass",
|
|
69141
|
+
factor: 1e3,
|
|
69142
|
+
offset: 0
|
|
69143
|
+
},
|
|
69144
|
+
kg: {
|
|
69145
|
+
dimension: "mass",
|
|
69146
|
+
factor: 1,
|
|
69147
|
+
offset: 0
|
|
69148
|
+
},
|
|
69149
|
+
g: {
|
|
69150
|
+
dimension: "mass",
|
|
69151
|
+
factor: .001,
|
|
69152
|
+
offset: 0
|
|
69153
|
+
},
|
|
69154
|
+
lb: {
|
|
69155
|
+
dimension: "mass",
|
|
69156
|
+
factor: .453592,
|
|
69157
|
+
offset: 0
|
|
69158
|
+
},
|
|
69159
|
+
oz: {
|
|
69160
|
+
dimension: "mass",
|
|
69161
|
+
factor: .0283495,
|
|
69162
|
+
offset: 0
|
|
69163
|
+
},
|
|
69164
|
+
"%": {
|
|
69165
|
+
dimension: "percentage",
|
|
69166
|
+
factor: 1,
|
|
69167
|
+
offset: 0
|
|
69168
|
+
},
|
|
69169
|
+
L: {
|
|
69170
|
+
dimension: "volume",
|
|
69171
|
+
factor: 1,
|
|
69172
|
+
offset: 0
|
|
69173
|
+
},
|
|
69174
|
+
mL: {
|
|
69175
|
+
dimension: "volume",
|
|
69176
|
+
factor: .001,
|
|
69177
|
+
offset: 0
|
|
69178
|
+
},
|
|
69179
|
+
gal: {
|
|
69180
|
+
dimension: "volume",
|
|
69181
|
+
factor: 3.785411784,
|
|
69182
|
+
offset: 0
|
|
69183
|
+
},
|
|
69184
|
+
s: {
|
|
69185
|
+
dimension: "duration",
|
|
69186
|
+
factor: 1,
|
|
69187
|
+
offset: 0
|
|
69188
|
+
},
|
|
69189
|
+
ms: {
|
|
69190
|
+
dimension: "duration",
|
|
69191
|
+
factor: .001,
|
|
69192
|
+
offset: 0
|
|
69193
|
+
},
|
|
69194
|
+
min: {
|
|
69195
|
+
dimension: "duration",
|
|
69196
|
+
factor: 60,
|
|
69197
|
+
offset: 0
|
|
69198
|
+
},
|
|
69199
|
+
h: {
|
|
69200
|
+
dimension: "duration",
|
|
69201
|
+
factor: 3600,
|
|
69202
|
+
offset: 0
|
|
69203
|
+
},
|
|
69204
|
+
d: {
|
|
69205
|
+
dimension: "duration",
|
|
69206
|
+
factor: 86400,
|
|
69207
|
+
offset: 0
|
|
69208
|
+
},
|
|
69209
|
+
B: {
|
|
69210
|
+
dimension: "information",
|
|
69211
|
+
factor: 1,
|
|
69212
|
+
offset: 0
|
|
69213
|
+
},
|
|
69214
|
+
KiB: {
|
|
69215
|
+
dimension: "information",
|
|
69216
|
+
factor: 1024,
|
|
69217
|
+
offset: 0
|
|
69218
|
+
},
|
|
69219
|
+
MiB: {
|
|
69220
|
+
dimension: "information",
|
|
69221
|
+
factor: 1024 ** 2,
|
|
69222
|
+
offset: 0
|
|
69223
|
+
},
|
|
69224
|
+
GiB: {
|
|
69225
|
+
dimension: "information",
|
|
69226
|
+
factor: 1024 ** 3,
|
|
69227
|
+
offset: 0
|
|
69228
|
+
},
|
|
69229
|
+
TiB: {
|
|
69230
|
+
dimension: "information",
|
|
69231
|
+
factor: 1024 ** 4,
|
|
69232
|
+
offset: 0
|
|
69233
|
+
},
|
|
69234
|
+
kB: {
|
|
69235
|
+
dimension: "information",
|
|
69236
|
+
factor: 1e3,
|
|
69237
|
+
offset: 0
|
|
69238
|
+
},
|
|
69239
|
+
MB: {
|
|
69240
|
+
dimension: "information",
|
|
69241
|
+
factor: 1e6,
|
|
69242
|
+
offset: 0
|
|
69243
|
+
},
|
|
69244
|
+
GB: {
|
|
69245
|
+
dimension: "information",
|
|
69246
|
+
factor: 1e9,
|
|
69247
|
+
offset: 0
|
|
69248
|
+
},
|
|
69249
|
+
"°": {
|
|
69250
|
+
dimension: "angle",
|
|
69251
|
+
factor: 1,
|
|
69252
|
+
offset: 0
|
|
69253
|
+
},
|
|
69254
|
+
dBFS: {
|
|
69255
|
+
dimension: "sound-level",
|
|
69256
|
+
factor: 1,
|
|
69257
|
+
offset: 0
|
|
69258
|
+
},
|
|
69259
|
+
dBm: {
|
|
69260
|
+
dimension: "signal-level",
|
|
69261
|
+
factor: 1,
|
|
69262
|
+
offset: 0
|
|
69263
|
+
},
|
|
69264
|
+
mired: {
|
|
69265
|
+
dimension: "colour-temperature",
|
|
69266
|
+
factor: 1,
|
|
69267
|
+
offset: 0
|
|
69268
|
+
},
|
|
69269
|
+
kbps: {
|
|
69270
|
+
dimension: "bitrate",
|
|
69271
|
+
factor: 1,
|
|
69272
|
+
offset: 0
|
|
69273
|
+
},
|
|
69274
|
+
Mbps: {
|
|
69275
|
+
dimension: "bitrate",
|
|
69276
|
+
factor: 1e3,
|
|
69277
|
+
offset: 0
|
|
69278
|
+
},
|
|
69279
|
+
fps: {
|
|
69280
|
+
dimension: "rate",
|
|
69281
|
+
factor: 1,
|
|
69282
|
+
offset: 0
|
|
69283
|
+
}
|
|
69284
|
+
};
|
|
69285
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
69286
|
+
function specFor(unit) {
|
|
69287
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
69288
|
+
}
|
|
69289
|
+
/** The dimension a unit belongs to, or `undefined` for an unknown unit. */
|
|
69290
|
+
function unitDimension(unit) {
|
|
69291
|
+
return specFor(unit)?.dimension;
|
|
69292
|
+
}
|
|
69293
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
69294
|
+
function toCanonical(value, spec) {
|
|
69295
|
+
return value * spec.factor + spec.offset;
|
|
69296
|
+
}
|
|
69297
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
69298
|
+
function fromCanonical(canonical, spec) {
|
|
69299
|
+
return (canonical - spec.offset) / spec.factor;
|
|
69300
|
+
}
|
|
69301
|
+
/**
|
|
69302
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
69303
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
69304
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
69305
|
+
*/
|
|
69306
|
+
function tryConvertUnit(value, from, to) {
|
|
69307
|
+
if (from === to) return value;
|
|
69308
|
+
const fromSpec = specFor(from);
|
|
69309
|
+
if (!fromSpec) return void 0;
|
|
69310
|
+
const toSpec = specFor(to);
|
|
69311
|
+
if (!toSpec) return void 0;
|
|
69312
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
69313
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
69314
|
+
}
|
|
68993
69315
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
68994
69316
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
68995
69317
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
@@ -83659,7 +83981,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83659
83981
|
field: "value",
|
|
83660
83982
|
quantity: t("the reading", "il valore"),
|
|
83661
83983
|
label: t("Reading", "Valore"),
|
|
83662
|
-
unitField: "unit",
|
|
83663
83984
|
icon: "gauge"
|
|
83664
83985
|
}]
|
|
83665
83986
|
},
|
|
@@ -83795,7 +84116,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83795
84116
|
field: "temperature",
|
|
83796
84117
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
83797
84118
|
label: t("Temperature", "Temperatura"),
|
|
83798
|
-
|
|
84119
|
+
unit: "°C",
|
|
83799
84120
|
icon: "thermometer"
|
|
83800
84121
|
},
|
|
83801
84122
|
{
|
|
@@ -83811,7 +84132,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83811
84132
|
field: "windSpeed",
|
|
83812
84133
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
83813
84134
|
label: t("Wind", "Vento"),
|
|
83814
|
-
|
|
84135
|
+
unit: "m/s",
|
|
83815
84136
|
icon: "wind"
|
|
83816
84137
|
},
|
|
83817
84138
|
{
|
|
@@ -83819,7 +84140,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83819
84140
|
field: "pressure",
|
|
83820
84141
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
83821
84142
|
label: t("Pressure", "Pressione"),
|
|
83822
|
-
|
|
84143
|
+
unit: "hPa",
|
|
83823
84144
|
icon: "gauge"
|
|
83824
84145
|
}
|
|
83825
84146
|
]
|
|
@@ -88184,7 +88505,97 @@ DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
|
88184
88505
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
88185
88506
|
DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb;
|
|
88186
88507
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
88508
|
+
/**
|
|
88509
|
+
* Convert an upstream number into the stored base of its quantity (D944 §4).
|
|
88510
|
+
* An unknown unit or a unit from another dimension is a refusal: the caller
|
|
88511
|
+
* logs it and publishes null (D393). This function never guesses.
|
|
88512
|
+
*/
|
|
88513
|
+
var DIMENSION_QUANTITY = {
|
|
88514
|
+
temperature: "temperature",
|
|
88515
|
+
pressure: "pressure",
|
|
88516
|
+
speed: "speed",
|
|
88517
|
+
"precipitation-rate": "precipitation-rate",
|
|
88518
|
+
length: "length",
|
|
88519
|
+
area: "area",
|
|
88520
|
+
illuminance: "illuminance",
|
|
88521
|
+
irradiance: "irradiance",
|
|
88522
|
+
power: "power",
|
|
88523
|
+
"apparent-power": "apparent-power",
|
|
88524
|
+
energy: "energy",
|
|
88525
|
+
voltage: "voltage",
|
|
88526
|
+
current: "current",
|
|
88527
|
+
"concentration-volume": "concentration-volume",
|
|
88528
|
+
"concentration-mass": "concentration-mass",
|
|
88529
|
+
mass: "mass",
|
|
88530
|
+
percentage: "percentage",
|
|
88531
|
+
volume: "volume",
|
|
88532
|
+
duration: "duration",
|
|
88533
|
+
information: "information",
|
|
88534
|
+
angle: "angle",
|
|
88535
|
+
"sound-level": "sound-level",
|
|
88536
|
+
"signal-level": "signal-level",
|
|
88537
|
+
"colour-temperature": "colour-temperature",
|
|
88538
|
+
bitrate: "bitrate",
|
|
88539
|
+
rate: "rate"
|
|
88540
|
+
};
|
|
88541
|
+
/**
|
|
88542
|
+
* Quantity implied by a unit symbol. `ppb` and `ms` are the two symbols
|
|
88543
|
+
* whose stored base is not the dimension's canonical unit. `mm` is length;
|
|
88544
|
+
* precipitation is chosen by the caller (a device class), not by the symbol.
|
|
88545
|
+
*/
|
|
88546
|
+
function quantityFromUnit(rawUnit) {
|
|
88547
|
+
const unit = normalizeUnit(rawUnit);
|
|
88548
|
+
if (unit === void 0) return void 0;
|
|
88549
|
+
if (unit === "ppb") return "concentration-ppb";
|
|
88550
|
+
if (unit === "ms") return "duration-ms";
|
|
88551
|
+
const dimension = unitDimension(unit);
|
|
88552
|
+
if (dimension === void 0) return void 0;
|
|
88553
|
+
return DIMENSION_QUANTITY[dimension];
|
|
88554
|
+
}
|
|
88555
|
+
function ingestReading(input) {
|
|
88556
|
+
if (!Number.isFinite(input.value)) return {
|
|
88557
|
+
ok: false,
|
|
88558
|
+
reason: "non-finite"
|
|
88559
|
+
};
|
|
88560
|
+
if (input.quantity === "device") return {
|
|
88561
|
+
ok: false,
|
|
88562
|
+
reason: "unknown-unit"
|
|
88563
|
+
};
|
|
88564
|
+
const raw = input.rawUnit?.trim();
|
|
88565
|
+
if (raw === void 0 || raw.length === 0) return {
|
|
88566
|
+
ok: true,
|
|
88567
|
+
value: input.value
|
|
88568
|
+
};
|
|
88569
|
+
const unit = normalizeUnit(raw);
|
|
88570
|
+
if (unit === void 0) return {
|
|
88571
|
+
ok: false,
|
|
88572
|
+
reason: "unknown-unit"
|
|
88573
|
+
};
|
|
88574
|
+
const base = baseUnitOf(input.quantity);
|
|
88575
|
+
if (base === void 0) {
|
|
88576
|
+
if (unitDimension(unit) !== void 0) return {
|
|
88577
|
+
ok: false,
|
|
88578
|
+
reason: "cross-dimension"
|
|
88579
|
+
};
|
|
88580
|
+
return {
|
|
88581
|
+
ok: false,
|
|
88582
|
+
reason: "unknown-unit"
|
|
88583
|
+
};
|
|
88584
|
+
}
|
|
88585
|
+
const converted = tryConvertUnit(input.value, unit, base);
|
|
88586
|
+
if (converted === void 0) return unitDimension(unit) === void 0 ? {
|
|
88587
|
+
ok: false,
|
|
88588
|
+
reason: "unknown-unit"
|
|
88589
|
+
} : {
|
|
88590
|
+
ok: false,
|
|
88591
|
+
reason: "cross-dimension"
|
|
88592
|
+
};
|
|
88593
|
+
return {
|
|
88594
|
+
ok: true,
|
|
88595
|
+
value: converted
|
|
88596
|
+
};
|
|
88597
|
+
}
|
|
88187
88598
|
var MB = 1024 * 1024;
|
|
88188
88599
|
1024 * MB, 3072 * MB;
|
|
88189
88600
|
//#endregion
|
|
88190
|
-
export {
|
|
88601
|
+
export { isSecretMarker as A, unknown as B, waterHeaterCapability as C, createEvent as D, errMsg as E, number as F, object as I, record as L, _enum as M, array as N, customAction as O, literal as P, string as R, temperatureSensorCapability as S, DeviceType as T, EventCategory as V, powerMeterCapability as _, batteryCapability as a, runningStateCapability as b, connectionTestCapability as c, dishwasherCapability as d, enumSensorCapability as f, numericSensorCapability as g, ingestReading as h, RUNNING_STATE_COLD as i, isSecretMarkerLike as j, defineCustomActions as k, consumablesCapability as l, heatingValveCapability as m, BaseDeviceProvider as n, binaryCapability as o, eventEmitterCapability as p, DishwasherOperationStateSchema as r, climateControlCapability as s, BaseDevice as t, deviceAdoptionCapability as u, quantityFromUnit as v, DeviceRole as w, switchCapability as x, runningFromDishwasherOperation as y, union as z };
|