@camstack/system 1.2.484 → 1.2.485
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/{agent-https-CW8aLMDL.js → agent-https-DBP7P-ee.js} +1 -1
- package/dist/{agent-https-DttPIFry.mjs → agent-https-_EXvi6F8.mjs} +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +13 -5
- package/dist/builtins/composer/composer.addon.mjs +13 -5
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-history/device-history.addon.d.ts +2 -0
- package/dist/builtins/device-history/device-history.addon.js +248 -4
- package/dist/builtins/device-history/device-history.addon.mjs +248 -4
- package/dist/builtins/device-history/query/history-query.d.ts +5 -1
- package/dist/builtins/device-history/runtime/history-runtime.d.ts +18 -1
- package/dist/builtins/device-history/store/history-schema.d.ts +2 -0
- package/dist/builtins/device-history/store/history-store.d.ts +11 -0
- package/dist/builtins/device-history/store/series-scale.d.ts +37 -0
- package/dist/builtins/device-manager/device-manager.addon.js +3 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +3 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +3 -3
- package/dist/builtins/system-config/system-config.addon.mjs +3 -3
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-DqRPHdtw.js → composition-sources-BSQneZV9.js} +1 -1
- package/dist/{composition-sources-DEsDonpg.mjs → composition-sources-BnZpIA8u.mjs} +1 -1
- package/dist/{constants-B3FDrBIq.mjs → constants-7D7xjw0h.mjs} +1 -1
- package/dist/{constants-71vf77HY.js → constants-CQfTeCnB.js} +1 -1
- package/dist/{device-ca-bhz04X_N.mjs → device-ca-Bzd6UO_c.mjs} +1 -1
- package/dist/{device-ca-BDPYXhkH.js → device-ca-D_4dI5gv.js} +1 -1
- package/dist/{dist-BT_THdzJ.mjs → dist-Df6c0RX_.mjs} +607 -522
- package/dist/{dist-k--OhKkO.js → dist-xCNJAQMh.js} +618 -521
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-DDgdvcQw.mjs → hub-mdns-ciao-D7GMnEz0.mjs} +2 -2
- package/dist/{hub-mdns-ciao-CGXfhvTk.js → hub-mdns-ciao-DRfmLR_Z.js} +2 -2
- package/dist/index.js +7 -7
- package/dist/index.mjs +7 -7
- package/dist/{restore-archive-z0XT2g29.mjs → restore-archive-Co70oRya.mjs} +1 -1
- package/dist/{restore-archive-B-GiglWt.js → restore-archive-DA7N6ZZA.js} +1 -1
- package/dist/{retention-DR0_xRTy.js → retention-DNDOPW7Z.js} +1 -1
- package/dist/{retention-DFkmhjeH.mjs → retention-DfCW-dZS.mjs} +1 -1
- package/dist/{wal-maintenance-CVDrL_BD.mjs → wal-maintenance-71-j48Ci.mjs} +0 -0
- package/dist/{wal-maintenance-C4cma95b.js → wal-maintenance-CA0L6WZ9.js} +0 -0
- package/package.json +1 -1
|
@@ -765,7 +765,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
765
765
|
return EventCategory;
|
|
766
766
|
}({});
|
|
767
767
|
//#endregion
|
|
768
|
-
//#region ../types/dist/sleep-
|
|
768
|
+
//#region ../types/dist/sleep-CARd6wZF.mjs
|
|
769
769
|
/**
|
|
770
770
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
771
771
|
* window to float samples (D455).
|
|
@@ -3801,6 +3801,112 @@ function assertTransactScope(members) {
|
|
|
3801
3801
|
if (missing.length > 0) throw new TransactRefusedError(`no-family: ${missing.map((m) => m.kind).join(", ")} declare no transactFamily; kinds that must agree through transact share one`);
|
|
3802
3802
|
if (new Set(kinds.map((m) => m.declaration.transactFamily)).size > 1) throw new TransactRefusedError(`cross-family: the ops span more than one transactFamily (${kinds.map((m) => `${m.kind}=${String(m.declaration.transactFamily)}`).join(", ")})`);
|
|
3803
3803
|
}
|
|
3804
|
+
var READING_QUANTITIES = [
|
|
3805
|
+
"temperature",
|
|
3806
|
+
"pressure",
|
|
3807
|
+
"speed",
|
|
3808
|
+
"precipitation",
|
|
3809
|
+
"precipitation-rate",
|
|
3810
|
+
"length",
|
|
3811
|
+
"area",
|
|
3812
|
+
"illuminance",
|
|
3813
|
+
"irradiance",
|
|
3814
|
+
"power",
|
|
3815
|
+
"energy",
|
|
3816
|
+
"voltage",
|
|
3817
|
+
"current",
|
|
3818
|
+
"apparent-power",
|
|
3819
|
+
"humidity",
|
|
3820
|
+
"percentage",
|
|
3821
|
+
"concentration-volume",
|
|
3822
|
+
"concentration-mass",
|
|
3823
|
+
"concentration-ppb",
|
|
3824
|
+
"volume",
|
|
3825
|
+
"duration",
|
|
3826
|
+
"duration-ms",
|
|
3827
|
+
"information",
|
|
3828
|
+
"sound-level",
|
|
3829
|
+
"signal-level",
|
|
3830
|
+
"colour-temperature",
|
|
3831
|
+
"angle",
|
|
3832
|
+
"bitrate",
|
|
3833
|
+
"rate",
|
|
3834
|
+
"mass",
|
|
3835
|
+
"index",
|
|
3836
|
+
"ratio",
|
|
3837
|
+
"count",
|
|
3838
|
+
"none",
|
|
3839
|
+
"device"
|
|
3840
|
+
];
|
|
3841
|
+
var ReadingQuantitySchema = zod.z.enum(READING_QUANTITIES);
|
|
3842
|
+
var QUANTITY_SET = new Set(READING_QUANTITIES);
|
|
3843
|
+
function isReadingQuantity(value) {
|
|
3844
|
+
return typeof value === "string" && QUANTITY_SET.has(value);
|
|
3845
|
+
}
|
|
3846
|
+
/**
|
|
3847
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
3848
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
3849
|
+
*/
|
|
3850
|
+
var QUANTITY_BASE = {
|
|
3851
|
+
temperature: "°C",
|
|
3852
|
+
pressure: "hPa",
|
|
3853
|
+
speed: "m/s",
|
|
3854
|
+
precipitation: "mm",
|
|
3855
|
+
"precipitation-rate": "mm/h",
|
|
3856
|
+
length: "m",
|
|
3857
|
+
area: "m²",
|
|
3858
|
+
illuminance: "lx",
|
|
3859
|
+
irradiance: "W/m²",
|
|
3860
|
+
power: "W",
|
|
3861
|
+
energy: "kWh",
|
|
3862
|
+
voltage: "V",
|
|
3863
|
+
current: "A",
|
|
3864
|
+
"apparent-power": "VA",
|
|
3865
|
+
humidity: "%",
|
|
3866
|
+
percentage: "%",
|
|
3867
|
+
"concentration-volume": "ppm",
|
|
3868
|
+
"concentration-mass": "µg/m³",
|
|
3869
|
+
"concentration-ppb": "ppb",
|
|
3870
|
+
volume: "L",
|
|
3871
|
+
duration: "s",
|
|
3872
|
+
"duration-ms": "ms",
|
|
3873
|
+
information: "B",
|
|
3874
|
+
"sound-level": "dBFS",
|
|
3875
|
+
"signal-level": "dBm",
|
|
3876
|
+
"colour-temperature": "mired",
|
|
3877
|
+
angle: "°",
|
|
3878
|
+
bitrate: "kbps",
|
|
3879
|
+
rate: "fps",
|
|
3880
|
+
mass: "kg",
|
|
3881
|
+
index: "none",
|
|
3882
|
+
ratio: "none",
|
|
3883
|
+
count: "none",
|
|
3884
|
+
none: "none",
|
|
3885
|
+
device: "device"
|
|
3886
|
+
};
|
|
3887
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
3888
|
+
function baseUnitOf(quantity) {
|
|
3889
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
3890
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
3891
|
+
return symbol;
|
|
3892
|
+
}
|
|
3893
|
+
/**
|
|
3894
|
+
* History catalog label for a quantity. Index and ratio keep the labels the
|
|
3895
|
+
* series already used (`count`, `ratio`). A polymorphic reading has no
|
|
3896
|
+
* single label.
|
|
3897
|
+
*/
|
|
3898
|
+
function historyUnitFor(quantity) {
|
|
3899
|
+
if (quantity === "index" || quantity === "count") return "count";
|
|
3900
|
+
if (quantity === "ratio") return "ratio";
|
|
3901
|
+
return baseUnitOf(quantity);
|
|
3902
|
+
}
|
|
3903
|
+
function readingMeta(quantity, extras) {
|
|
3904
|
+
return {
|
|
3905
|
+
quantity,
|
|
3906
|
+
...extras?.precision !== void 0 ? { precision: extras.precision } : {},
|
|
3907
|
+
...extras?.label !== void 0 ? { label: extras.label } : {}
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3804
3910
|
/** Shared Zod schemas used across streaming capabilities. */
|
|
3805
3911
|
var CamProfileSchema = zod.z.enum([
|
|
3806
3912
|
"high",
|
|
@@ -3828,8 +3934,8 @@ var CamStreamKindSchema = zod.z.enum([
|
|
|
3828
3934
|
"derived"
|
|
3829
3935
|
]);
|
|
3830
3936
|
var CamStreamResolutionSchema = zod.z.object({
|
|
3831
|
-
width: zod.z.number().int().positive(),
|
|
3832
|
-
height: zod.z.number().int().positive()
|
|
3937
|
+
width: zod.z.number().int().positive().meta(readingMeta("none")),
|
|
3938
|
+
height: zod.z.number().int().positive().meta(readingMeta("none"))
|
|
3833
3939
|
});
|
|
3834
3940
|
var CameraStreamSchema = zod.z.object({
|
|
3835
3941
|
/** Stable, provider-assigned id unique within the (deviceId) scope. */
|
|
@@ -5206,14 +5312,6 @@ Object.freeze({
|
|
|
5206
5312
|
{
|
|
5207
5313
|
"path": "aqi",
|
|
5208
5314
|
"valueType": "number"
|
|
5209
|
-
},
|
|
5210
|
-
{
|
|
5211
|
-
"path": "unit",
|
|
5212
|
-
"valueType": "string"
|
|
5213
|
-
},
|
|
5214
|
-
{
|
|
5215
|
-
"path": "precision",
|
|
5216
|
-
"valueType": "number"
|
|
5217
5315
|
}
|
|
5218
5316
|
],
|
|
5219
5317
|
"alarm-panel": [
|
|
@@ -5249,20 +5347,10 @@ Object.freeze({
|
|
|
5249
5347
|
"valueType": "boolean"
|
|
5250
5348
|
}
|
|
5251
5349
|
],
|
|
5252
|
-
"ambient-light-sensor": [
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
},
|
|
5257
|
-
{
|
|
5258
|
-
"path": "unit",
|
|
5259
|
-
"valueType": "string"
|
|
5260
|
-
},
|
|
5261
|
-
{
|
|
5262
|
-
"path": "precision",
|
|
5263
|
-
"valueType": "number"
|
|
5264
|
-
}
|
|
5265
|
-
],
|
|
5350
|
+
"ambient-light-sensor": [{
|
|
5351
|
+
"path": "lux",
|
|
5352
|
+
"valueType": "number"
|
|
5353
|
+
}],
|
|
5266
5354
|
"audio-metrics": [
|
|
5267
5355
|
{
|
|
5268
5356
|
"path": "ts",
|
|
@@ -5342,6 +5430,10 @@ Object.freeze({
|
|
|
5342
5430
|
"path": "lastUpdated",
|
|
5343
5431
|
"valueType": "number"
|
|
5344
5432
|
},
|
|
5433
|
+
{
|
|
5434
|
+
"path": "volts",
|
|
5435
|
+
"valueType": "number"
|
|
5436
|
+
},
|
|
5345
5437
|
{
|
|
5346
5438
|
"path": "lastContactAt",
|
|
5347
5439
|
"valueType": "number"
|
|
@@ -5584,10 +5676,6 @@ Object.freeze({
|
|
|
5584
5676
|
"datetime"
|
|
5585
5677
|
]
|
|
5586
5678
|
},
|
|
5587
|
-
{
|
|
5588
|
-
"path": "unit",
|
|
5589
|
-
"valueType": "string"
|
|
5590
|
-
},
|
|
5591
5679
|
{
|
|
5592
5680
|
"path": "min",
|
|
5593
5681
|
"valueType": "number"
|
|
@@ -5599,19 +5687,6 @@ Object.freeze({
|
|
|
5599
5687
|
{
|
|
5600
5688
|
"path": "step",
|
|
5601
5689
|
"valueType": "number"
|
|
5602
|
-
},
|
|
5603
|
-
{
|
|
5604
|
-
"path": "precision",
|
|
5605
|
-
"valueType": "number"
|
|
5606
|
-
},
|
|
5607
|
-
{
|
|
5608
|
-
"path": "format",
|
|
5609
|
-
"valueType": "enum",
|
|
5610
|
-
"enumValues": [
|
|
5611
|
-
"date",
|
|
5612
|
-
"time",
|
|
5613
|
-
"datetime"
|
|
5614
|
-
]
|
|
5615
5690
|
}
|
|
5616
5691
|
],
|
|
5617
5692
|
"cover": [
|
|
@@ -5852,13 +5927,8 @@ Object.freeze({
|
|
|
5852
5927
|
"path": "value",
|
|
5853
5928
|
"valueType": "string"
|
|
5854
5929
|
}, {
|
|
5855
|
-
"path": "
|
|
5856
|
-
"valueType": "
|
|
5857
|
-
"enumValues": [
|
|
5858
|
-
"date",
|
|
5859
|
-
"time",
|
|
5860
|
-
"datetime"
|
|
5861
|
-
]
|
|
5930
|
+
"path": "timestamp",
|
|
5931
|
+
"valueType": "boolean"
|
|
5862
5932
|
}],
|
|
5863
5933
|
"event-emitter": [
|
|
5864
5934
|
{
|
|
@@ -5965,20 +6035,10 @@ Object.freeze({
|
|
|
5965
6035
|
"valueType": "number"
|
|
5966
6036
|
}
|
|
5967
6037
|
],
|
|
5968
|
-
"humidity-sensor": [
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
},
|
|
5973
|
-
{
|
|
5974
|
-
"path": "unit",
|
|
5975
|
-
"valueType": "string"
|
|
5976
|
-
},
|
|
5977
|
-
{
|
|
5978
|
-
"path": "precision",
|
|
5979
|
-
"valueType": "number"
|
|
5980
|
-
}
|
|
5981
|
-
],
|
|
6038
|
+
"humidity-sensor": [{
|
|
6039
|
+
"path": "percent",
|
|
6040
|
+
"valueType": "number"
|
|
6041
|
+
}],
|
|
5982
6042
|
"image": [{
|
|
5983
6043
|
"path": "url",
|
|
5984
6044
|
"valueType": "string"
|
|
@@ -6317,20 +6377,10 @@ Object.freeze({
|
|
|
6317
6377
|
"valueType": "boolean"
|
|
6318
6378
|
}
|
|
6319
6379
|
],
|
|
6320
|
-
"numeric-sensor": [
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
},
|
|
6325
|
-
{
|
|
6326
|
-
"path": "unit",
|
|
6327
|
-
"valueType": "string"
|
|
6328
|
-
},
|
|
6329
|
-
{
|
|
6330
|
-
"path": "precision",
|
|
6331
|
-
"valueType": "number"
|
|
6332
|
-
}
|
|
6333
|
-
],
|
|
6380
|
+
"numeric-sensor": [{
|
|
6381
|
+
"path": "value",
|
|
6382
|
+
"valueType": "number"
|
|
6383
|
+
}],
|
|
6334
6384
|
"pet-feeder": [
|
|
6335
6385
|
{
|
|
6336
6386
|
"path": "foodLevel",
|
|
@@ -6422,14 +6472,6 @@ Object.freeze({
|
|
|
6422
6472
|
{
|
|
6423
6473
|
"path": "powerFactor",
|
|
6424
6474
|
"valueType": "number"
|
|
6425
|
-
},
|
|
6426
|
-
{
|
|
6427
|
-
"path": "unit",
|
|
6428
|
-
"valueType": "string"
|
|
6429
|
-
},
|
|
6430
|
-
{
|
|
6431
|
-
"path": "precision",
|
|
6432
|
-
"valueType": "number"
|
|
6433
6475
|
}
|
|
6434
6476
|
],
|
|
6435
6477
|
"presence": [
|
|
@@ -6458,20 +6500,10 @@ Object.freeze({
|
|
|
6458
6500
|
"valueType": "number"
|
|
6459
6501
|
}
|
|
6460
6502
|
],
|
|
6461
|
-
"pressure-sensor": [
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
},
|
|
6466
|
-
{
|
|
6467
|
-
"path": "unit",
|
|
6468
|
-
"valueType": "string"
|
|
6469
|
-
},
|
|
6470
|
-
{
|
|
6471
|
-
"path": "precision",
|
|
6472
|
-
"valueType": "number"
|
|
6473
|
-
}
|
|
6474
|
-
],
|
|
6503
|
+
"pressure-sensor": [{
|
|
6504
|
+
"path": "hpa",
|
|
6505
|
+
"valueType": "number"
|
|
6506
|
+
}],
|
|
6475
6507
|
"privacy-mask": [{
|
|
6476
6508
|
"path": "enabled",
|
|
6477
6509
|
"valueType": "boolean"
|
|
@@ -6782,20 +6814,10 @@ Object.freeze({
|
|
|
6782
6814
|
"path": "tampered",
|
|
6783
6815
|
"valueType": "boolean"
|
|
6784
6816
|
}],
|
|
6785
|
-
"temperature-sensor": [
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
},
|
|
6790
|
-
{
|
|
6791
|
-
"path": "unit",
|
|
6792
|
-
"valueType": "string"
|
|
6793
|
-
},
|
|
6794
|
-
{
|
|
6795
|
-
"path": "precision",
|
|
6796
|
-
"valueType": "number"
|
|
6797
|
-
}
|
|
6798
|
-
],
|
|
6817
|
+
"temperature-sensor": [{
|
|
6818
|
+
"path": "celsius",
|
|
6819
|
+
"valueType": "number"
|
|
6820
|
+
}],
|
|
6799
6821
|
"update": [
|
|
6800
6822
|
{
|
|
6801
6823
|
"path": "currentVersion",
|
|
@@ -6906,10 +6928,6 @@ Object.freeze({
|
|
|
6906
6928
|
"path": "temperature",
|
|
6907
6929
|
"valueType": "number"
|
|
6908
6930
|
},
|
|
6909
|
-
{
|
|
6910
|
-
"path": "temperatureUnit",
|
|
6911
|
-
"valueType": "string"
|
|
6912
|
-
},
|
|
6913
6931
|
{
|
|
6914
6932
|
"path": "humidity",
|
|
6915
6933
|
"valueType": "number"
|
|
@@ -6918,18 +6936,10 @@ Object.freeze({
|
|
|
6918
6936
|
"path": "pressure",
|
|
6919
6937
|
"valueType": "number"
|
|
6920
6938
|
},
|
|
6921
|
-
{
|
|
6922
|
-
"path": "pressureUnit",
|
|
6923
|
-
"valueType": "string"
|
|
6924
|
-
},
|
|
6925
6939
|
{
|
|
6926
6940
|
"path": "windSpeed",
|
|
6927
6941
|
"valueType": "number"
|
|
6928
6942
|
},
|
|
6929
|
-
{
|
|
6930
|
-
"path": "windSpeedUnit",
|
|
6931
|
-
"valueType": "string"
|
|
6932
|
-
},
|
|
6933
6943
|
{
|
|
6934
6944
|
"path": "windBearing",
|
|
6935
6945
|
"valueType": "number"
|
|
@@ -17134,6 +17144,17 @@ function unwrapSchema(schema) {
|
|
|
17134
17144
|
while (s instanceof zod.z.ZodNullable || s instanceof zod.z.ZodOptional || s instanceof zod.z.ZodDefault) s = s.unwrap();
|
|
17135
17145
|
return s;
|
|
17136
17146
|
}
|
|
17147
|
+
function isMetaBag(value) {
|
|
17148
|
+
return typeof value === "object" && value !== null;
|
|
17149
|
+
}
|
|
17150
|
+
function metaQuantity(schema) {
|
|
17151
|
+
const bag = zod.z.globalRegistry.get(schema);
|
|
17152
|
+
if (isMetaBag(bag) && isReadingQuantity(bag.quantity)) return bag.quantity;
|
|
17153
|
+
}
|
|
17154
|
+
/** Quantity declared with `readingMeta` on the field or on the unwrapped leaf. */
|
|
17155
|
+
function quantityOfField(schema) {
|
|
17156
|
+
return metaQuantity(schema) ?? metaQuantity(unwrapSchema(schema));
|
|
17157
|
+
}
|
|
17137
17158
|
function leafKind(schema) {
|
|
17138
17159
|
const s = unwrapSchema(schema);
|
|
17139
17160
|
if (s instanceof zod.z.ZodEnum) return {
|
|
@@ -17162,11 +17183,15 @@ function enumerateSchemaFields(schema, prefix = "") {
|
|
|
17162
17183
|
continue;
|
|
17163
17184
|
}
|
|
17164
17185
|
const leaf = leafKind(field);
|
|
17165
|
-
if (leaf)
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
|
|
17169
|
-
|
|
17186
|
+
if (leaf) {
|
|
17187
|
+
const quantity = quantityOfField(field);
|
|
17188
|
+
out.push({
|
|
17189
|
+
path,
|
|
17190
|
+
kind: leaf.kind,
|
|
17191
|
+
...leaf.enumValues ? { enumValues: leaf.enumValues } : {},
|
|
17192
|
+
...quantity !== void 0 ? { quantity } : {}
|
|
17193
|
+
});
|
|
17194
|
+
}
|
|
17170
17195
|
}
|
|
17171
17196
|
return out;
|
|
17172
17197
|
}
|
|
@@ -17225,7 +17250,7 @@ function requiredTopLevelKeys(schema) {
|
|
|
17225
17250
|
/**
|
|
17226
17251
|
* The proper prefixes of `path` whose schema accepts `undefined`: a required
|
|
17227
17252
|
* leaf under one of them is required only once something writes that parent
|
|
17228
|
-
* (`remaining.
|
|
17253
|
+
* (`remaining.kind` is required only when `remaining` is present).
|
|
17229
17254
|
*/
|
|
17230
17255
|
function optionalAncestors(schema, path) {
|
|
17231
17256
|
const segments = path.split(".");
|
|
@@ -17337,7 +17362,8 @@ var CompositionProblemCodeSchema = zod.z.enum([
|
|
|
17337
17362
|
"item-field-reserved",
|
|
17338
17363
|
"target-missing",
|
|
17339
17364
|
"target-unreadable",
|
|
17340
|
-
"not-replaceable"
|
|
17365
|
+
"not-replaceable",
|
|
17366
|
+
"native-capability-replace"
|
|
17341
17367
|
]);
|
|
17342
17368
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
17343
17369
|
var CompositionProblemSchema = zod.z.object({
|
|
@@ -17403,9 +17429,11 @@ function compositionFieldKey(plan) {
|
|
|
17403
17429
|
return `${plan.cap}.${path}`;
|
|
17404
17430
|
}
|
|
17405
17431
|
/**
|
|
17406
|
-
* What a feature does to its target (D663): `new` builds a capability on a
|
|
17407
|
-
* device; on an existing device it `add`s a capability the device lacks
|
|
17408
|
-
*
|
|
17432
|
+
* What a feature does to its target (D663, D944): `new` builds a capability on a
|
|
17433
|
+
* new device; on an existing device it `add`s a capability the device lacks.
|
|
17434
|
+
* Replacing a capability the device already serves is refused
|
|
17435
|
+
* (`native-capability-replace`), not planned. `replace` remains on the claim
|
|
17436
|
+
* wire for a claim the hub already holds.
|
|
17409
17437
|
*/
|
|
17410
17438
|
var CompositionFeatureModeSchema = zod.z.enum([
|
|
17411
17439
|
"new",
|
|
@@ -18202,6 +18230,9 @@ function isNativeCap(target, cap) {
|
|
|
18202
18230
|
const owner = target.nativeCaps.get(cap);
|
|
18203
18231
|
return owner !== void 0 && owner !== "composer";
|
|
18204
18232
|
}
|
|
18233
|
+
function isPlanProblem(value) {
|
|
18234
|
+
return "code" in value;
|
|
18235
|
+
}
|
|
18205
18236
|
/** The target read, or the refusal that replaces the whole plan when it could not be (D391). */
|
|
18206
18237
|
function planTargetOf(composition, target) {
|
|
18207
18238
|
if (composition.target.kind === "new") return {
|
|
@@ -18217,26 +18248,59 @@ function planTargetOf(composition, target) {
|
|
|
18217
18248
|
found: target
|
|
18218
18249
|
};
|
|
18219
18250
|
}
|
|
18220
|
-
|
|
18251
|
+
var NATIVE_REPLACE_KEPT = new Set([
|
|
18252
|
+
"not-composable",
|
|
18253
|
+
"unknown-capability",
|
|
18254
|
+
"reserved-variant"
|
|
18255
|
+
]);
|
|
18256
|
+
/** A native override is refused, unless the cap cannot be composed at all — that reason stays. */
|
|
18257
|
+
function nativeReplaceOrBlock(refusal, probed) {
|
|
18258
|
+
const kept = probed.problems.filter((item) => NATIVE_REPLACE_KEPT.has(item.code));
|
|
18259
|
+
if (kept.length > 0) return {
|
|
18260
|
+
problems: kept,
|
|
18261
|
+
fields: [],
|
|
18262
|
+
features: [],
|
|
18263
|
+
events: []
|
|
18264
|
+
};
|
|
18265
|
+
return refused(refusal);
|
|
18266
|
+
}
|
|
18267
|
+
function featureTargetOf(target, cap, at) {
|
|
18221
18268
|
if (target.kind === "new") return {
|
|
18222
18269
|
mode: "new",
|
|
18223
18270
|
deviceType: target.type
|
|
18224
18271
|
};
|
|
18272
|
+
if (isNativeCap(target.found, cap)) return problem("native-capability-replace", at, `native-capability-replace: stored override replaces native capability \`${cap}\` on device ${target.found.deviceId} — refused (D944)`);
|
|
18225
18273
|
return {
|
|
18226
|
-
mode:
|
|
18274
|
+
mode: "add",
|
|
18227
18275
|
deviceType: target.found.type
|
|
18228
18276
|
};
|
|
18229
18277
|
}
|
|
18230
18278
|
/**
|
|
18231
18279
|
* The static plan. `target` describes an EXISTING target device (one read);
|
|
18232
|
-
* it is ignored for a new one. On an existing target each feature
|
|
18233
|
-
*
|
|
18280
|
+
* it is ignored for a new one. On an existing target each feature ADDS a cap
|
|
18281
|
+
* the device lacks. A feature that would replace a native capability is
|
|
18282
|
+
* refused by name (D944). A new device is unchanged.
|
|
18234
18283
|
*/
|
|
18235
18284
|
function planComposition(composition, lookupCap, target) {
|
|
18236
18285
|
const planTarget = planTargetOf(composition, target);
|
|
18237
18286
|
if ("code" in planTarget) return refused(planTarget);
|
|
18238
18287
|
const results = composition.features.map((feature, index) => {
|
|
18239
|
-
const
|
|
18288
|
+
const at = `features[${index}]`;
|
|
18289
|
+
if (feature.kind === "passthrough") return refused(problem("reserved-variant", at, `whole-capability passthrough of \`${feature.cap}\` arrives in slice 3`));
|
|
18290
|
+
const featureTarget = featureTargetOf(planTarget, feature.cap, at);
|
|
18291
|
+
if (isPlanProblem(featureTarget)) {
|
|
18292
|
+
if (!compositionFeatureEnabled(feature) || planTarget.kind !== "existing") return {
|
|
18293
|
+
problems: [],
|
|
18294
|
+
fields: [],
|
|
18295
|
+
features: [],
|
|
18296
|
+
events: []
|
|
18297
|
+
};
|
|
18298
|
+
return nativeReplaceOrBlock(featureTarget, planFeature(feature, index, {
|
|
18299
|
+
mode: "add",
|
|
18300
|
+
deviceType: planTarget.found.type
|
|
18301
|
+
}, lookupCap));
|
|
18302
|
+
}
|
|
18303
|
+
const result = planFeature(feature, index, featureTarget, lookupCap);
|
|
18240
18304
|
return compositionFeatureEnabled(feature) ? result : {
|
|
18241
18305
|
problems: result.problems,
|
|
18242
18306
|
fields: [],
|
|
@@ -18377,7 +18441,11 @@ function cycleProblems(composition, ctx, fields, self) {
|
|
|
18377
18441
|
function validateComposition(composition, ctx) {
|
|
18378
18442
|
const plan = planComposition(composition, ctx.lookupCap, ctx.target ?? void 0);
|
|
18379
18443
|
const self = candidateSelf(composition, ctx, plan);
|
|
18380
|
-
const
|
|
18444
|
+
const refusedFeatures = plan.problems.filter((item) => item.code === "native-capability-replace").map((item) => item.path);
|
|
18445
|
+
const cycles = cycleProblems(composition, ctx, plan.fields, self).filter((item) => {
|
|
18446
|
+
if (refusedFeatures.some((at) => item.path === at || item.path.startsWith(`${at}.`))) return false;
|
|
18447
|
+
return refusedFeatures.length === 0 || item.path !== "features";
|
|
18448
|
+
});
|
|
18381
18449
|
const problems = [
|
|
18382
18450
|
...plan.problems,
|
|
18383
18451
|
...sourceProblems(plan.fields, ctx, self),
|
|
@@ -20894,12 +20962,12 @@ getAdminLink: method(zod.z.object({ deviceId: zod.z.number().int().nonnegative()
|
|
|
20894
20962
|
* providers detect renames by matching `uniqueId` and patch `id`
|
|
20895
20963
|
* in-place so dispatch keeps working.
|
|
20896
20964
|
*
|
|
20897
|
-
* **
|
|
20898
|
-
*
|
|
20899
|
-
*
|
|
20900
|
-
*
|
|
20901
|
-
* (`ha-domain-mapping`)
|
|
20902
|
-
* stored after that point.
|
|
20965
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
20966
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
20967
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
20968
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
20969
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
20970
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
20903
20971
|
*
|
|
20904
20972
|
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
20905
20973
|
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
@@ -20913,6 +20981,14 @@ var SourceInfoSchema = zod.z.object({
|
|
|
20913
20981
|
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
20914
20982
|
* Used to detect rename when `id` changes. */
|
|
20915
20983
|
uniqueId: zod.z.string().optional(),
|
|
20984
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
20985
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
20986
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
20987
|
+
dateTimeShape: zod.z.enum([
|
|
20988
|
+
"date",
|
|
20989
|
+
"time",
|
|
20990
|
+
"datetime"
|
|
20991
|
+
]).optional(),
|
|
20916
20992
|
/** Provider-specific extras that don't fit the structured slots.
|
|
20917
20993
|
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
20918
20994
|
* attribute blobs (would explode the meta JSON column). */
|
|
@@ -20997,9 +21073,38 @@ function normalizeUnit(raw) {
|
|
|
20997
21073
|
if (lower === "mph") return "mph";
|
|
20998
21074
|
if (lower === "m/s") return "m/s";
|
|
20999
21075
|
if (lower === "m") return "m";
|
|
21076
|
+
if (lower === "m²" || lower === "m2") return "m²";
|
|
21077
|
+
if (lower === "mm") return "mm";
|
|
21078
|
+
if (lower === "cm") return "cm";
|
|
21000
21079
|
if (lower === "km") return "km";
|
|
21080
|
+
if (lower === "in" || lower === "inch" || lower === "inches") return "in";
|
|
21081
|
+
if (lower === "ft" || lower === "foot" || lower === "feet") return "ft";
|
|
21001
21082
|
if (lower === "kg") return "kg";
|
|
21002
21083
|
if (lower === "g") return "g";
|
|
21084
|
+
if (lower === "l" || lower === "liter" || lower === "litre" || lower === "liters" || lower === "litres") return "L";
|
|
21085
|
+
if (lower === "ml") return "mL";
|
|
21086
|
+
if (lower === "gal" || lower === "gallon" || lower === "gallons") return "gal";
|
|
21087
|
+
if (lower === "s" || lower === "sec" || lower === "second" || lower === "seconds") return "s";
|
|
21088
|
+
if (lower === "ms") return "ms";
|
|
21089
|
+
if (lower === "min" || lower === "minute" || lower === "minutes") return "min";
|
|
21090
|
+
if (lower === "h" || lower === "hr" || lower === "hour" || lower === "hours") return "h";
|
|
21091
|
+
if (lower === "d" || lower === "day" || lower === "days") return "d";
|
|
21092
|
+
if (lower === "b" || lower === "byte" || lower === "bytes") return "B";
|
|
21093
|
+
if (lower === "kib") return "KiB";
|
|
21094
|
+
if (lower === "mib") return "MiB";
|
|
21095
|
+
if (lower === "gib") return "GiB";
|
|
21096
|
+
if (lower === "tib") return "TiB";
|
|
21097
|
+
if (lower === "kb") return "kB";
|
|
21098
|
+
if (lower === "mb") return "MB";
|
|
21099
|
+
if (lower === "gb") return "GB";
|
|
21100
|
+
if (lower === "dbm") return "dBm";
|
|
21101
|
+
if (lower === "dbfs") return "dBFS";
|
|
21102
|
+
if (lower === "inhg") return "inHg";
|
|
21103
|
+
if (lower === "mm/h") return "mm/h";
|
|
21104
|
+
if (lower === "w/m²" || lower === "w/m2") return "W/m²";
|
|
21105
|
+
if (lower === "°" || lower === "deg" || lower === "degree" || lower === "degrees") return "°";
|
|
21106
|
+
if (lower === "kbps") return "kbps";
|
|
21107
|
+
if (lower === "fps") return "fps";
|
|
21003
21108
|
return trimmed;
|
|
21004
21109
|
}
|
|
21005
21110
|
/**
|
|
@@ -42261,7 +42366,8 @@ var deviceManagerCapability = {
|
|
|
42261
42366
|
"enum"
|
|
42262
42367
|
]),
|
|
42263
42368
|
enumValues: zod.z.array(zod.z.string()).optional(),
|
|
42264
|
-
item: zod.z.boolean().optional()
|
|
42369
|
+
item: zod.z.boolean().optional(),
|
|
42370
|
+
quantity: ReadingQuantitySchema.optional()
|
|
42265
42371
|
})).readonly(),
|
|
42266
42372
|
itemArray: zod.z.object({
|
|
42267
42373
|
path: zod.z.string(),
|
|
@@ -47526,8 +47632,8 @@ var MaskPolygonShapeSchema = zod.z.object({
|
|
|
47526
47632
|
/** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
|
|
47527
47633
|
var MaskGridShapeSchema = zod.z.object({
|
|
47528
47634
|
kind: zod.z.literal("grid"),
|
|
47529
|
-
gridWidth: zod.z.number(),
|
|
47530
|
-
gridHeight: zod.z.number(),
|
|
47635
|
+
gridWidth: zod.z.number().meta(readingMeta("none")),
|
|
47636
|
+
gridHeight: zod.z.number().meta(readingMeta("none")),
|
|
47531
47637
|
cells: zod.z.array(zod.z.boolean())
|
|
47532
47638
|
});
|
|
47533
47639
|
/** Directed line / tripwire — an ordered list of normalized points (≥2). */
|
|
@@ -62076,27 +62182,17 @@ var addonsCapability = {
|
|
|
62076
62182
|
*/
|
|
62077
62183
|
var AirQualitySensorStatusSchema = zod.z.object({
|
|
62078
62184
|
/** Carbon dioxide concentration in ppm. */
|
|
62079
|
-
co2Ppm: zod.z.number().min(0).optional(),
|
|
62185
|
+
co2Ppm: zod.z.number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
62080
62186
|
/** Total volatile organic compounds in ppb. */
|
|
62081
|
-
vocPpb: zod.z.number().min(0).optional(),
|
|
62187
|
+
vocPpb: zod.z.number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
62082
62188
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
62083
|
-
pm25: zod.z.number().min(0).optional(),
|
|
62189
|
+
pm25: zod.z.number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
62084
62190
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
62085
|
-
pm10: zod.z.number().min(0).optional(),
|
|
62191
|
+
pm10: zod.z.number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
62086
62192
|
/** Composite AQI value (typically 0..500). */
|
|
62087
|
-
aqi: zod.z.number().optional(),
|
|
62193
|
+
aqi: zod.z.number().optional().meta(readingMeta("index")),
|
|
62088
62194
|
/** Ms epoch when the slice was last updated. */
|
|
62089
|
-
lastFetchedAt: zod.z.number()
|
|
62090
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
62091
|
-
* `attributes.unit_of_measurement` → 'ppm' / 'ppb' / 'µg/m³'). Each
|
|
62092
|
-
* upstream `sensor.*` entity surfaces ONE device_class, so one unit
|
|
62093
|
-
* per slice is unambiguous. */
|
|
62094
|
-
unit: zod.z.string().optional(),
|
|
62095
|
-
/** Suggested decimal places for numeric display.
|
|
62096
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
62097
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
62098
|
-
* auto-formatting when absent. */
|
|
62099
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
62195
|
+
lastFetchedAt: zod.z.number()
|
|
62100
62196
|
});
|
|
62101
62197
|
var airQualitySensorCapability = {
|
|
62102
62198
|
name: "air-quality-sensor",
|
|
@@ -62133,12 +62229,12 @@ var airQualitySensorCapability = {
|
|
|
62133
62229
|
},
|
|
62134
62230
|
pm25: {
|
|
62135
62231
|
kind: "gauge",
|
|
62136
|
-
unit: "
|
|
62232
|
+
unit: "µg/m³",
|
|
62137
62233
|
deadband: 1
|
|
62138
62234
|
},
|
|
62139
62235
|
pm10: {
|
|
62140
62236
|
kind: "gauge",
|
|
62141
|
-
unit: "
|
|
62237
|
+
unit: "µg/m³",
|
|
62142
62238
|
deadband: 1
|
|
62143
62239
|
},
|
|
62144
62240
|
aqi: {
|
|
@@ -62156,22 +62252,13 @@ var airQualitySensorCapability = {
|
|
|
62156
62252
|
* entries with `device_class: illuminance`.
|
|
62157
62253
|
*/
|
|
62158
62254
|
var AmbientLightSensorStatusSchema = zod.z.object({
|
|
62159
|
-
/** Current illuminance in lux (lx). */
|
|
62160
|
-
lux: zod.z.number().min(0).meta({
|
|
62161
|
-
|
|
62255
|
+
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
62256
|
+
lux: zod.z.number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
62257
|
+
precision: 0,
|
|
62162
62258
|
label: "Illuminance"
|
|
62163
|
-
}),
|
|
62259
|
+
})),
|
|
62164
62260
|
/** Ms epoch when the slice was last updated. */
|
|
62165
|
-
lastFetchedAt: zod.z.number()
|
|
62166
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
62167
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
62168
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
62169
|
-
unit: zod.z.string().optional(),
|
|
62170
|
-
/** Suggested decimal places for numeric display.
|
|
62171
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
62172
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
62173
|
-
* auto-formatting when absent. */
|
|
62174
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
62261
|
+
lastFetchedAt: zod.z.number()
|
|
62175
62262
|
});
|
|
62176
62263
|
var ambientLightSensorCapability = {
|
|
62177
62264
|
name: "ambient-light-sensor",
|
|
@@ -62203,12 +62290,7 @@ var ambientLightSensorCapability = {
|
|
|
62203
62290
|
} } },
|
|
62204
62291
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62205
62292
|
* whether persisting is worth a SQLite commit. */
|
|
62206
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
62207
|
-
customize: {
|
|
62208
|
-
version: 1,
|
|
62209
|
-
advanced: "derive",
|
|
62210
|
-
targets: []
|
|
62211
|
-
}
|
|
62293
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
62212
62294
|
};
|
|
62213
62295
|
/**
|
|
62214
62296
|
* Per-class audio metrics aggregated over a sliding window.
|
|
@@ -62444,10 +62526,7 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
62444
62526
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
62445
62527
|
* declines to band a non-finite reading, which is the correct shape.
|
|
62446
62528
|
*/
|
|
62447
|
-
percentage: zod.z.number().min(0).max(100).nullable().meta({
|
|
62448
|
-
unit: "%",
|
|
62449
|
-
label: "Charge"
|
|
62450
|
-
}),
|
|
62529
|
+
percentage: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
62451
62530
|
/**
|
|
62452
62531
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
62453
62532
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -62474,7 +62553,14 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
62474
62553
|
*/
|
|
62475
62554
|
sleeping: zod.z.boolean().meta({ label: "Sleeping" }),
|
|
62476
62555
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
62477
|
-
lastUpdated: zod.z.number(),
|
|
62556
|
+
lastUpdated: zod.z.number().meta(readingMeta("none")),
|
|
62557
|
+
/**
|
|
62558
|
+
* Battery voltage in volts, for a cell the firmware reports as voltage
|
|
62559
|
+
* rather than a percentage (Ecowitt capacitor packs). Absent on cameras
|
|
62560
|
+
* that only report charge. A second reading on this cap, not a second
|
|
62561
|
+
* `numeric-sensor` on the same device.
|
|
62562
|
+
*/
|
|
62563
|
+
volts: zod.z.number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
62478
62564
|
/**
|
|
62479
62565
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
62480
62566
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -62526,7 +62612,6 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
62526
62612
|
/** Generic Customize target for the percentage reading (D936). */
|
|
62527
62613
|
var batteryCustomize = {
|
|
62528
62614
|
version: 1,
|
|
62529
|
-
advanced: "derive",
|
|
62530
62615
|
targets: [{
|
|
62531
62616
|
id: "percentage",
|
|
62532
62617
|
cardinality: "scalar",
|
|
@@ -62535,7 +62620,7 @@ var batteryCustomize = {
|
|
|
62535
62620
|
stateField: "percentage"
|
|
62536
62621
|
},
|
|
62537
62622
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
62538
|
-
apply: "add
|
|
62623
|
+
apply: "add",
|
|
62539
62624
|
path: "percentage",
|
|
62540
62625
|
sources: [{
|
|
62541
62626
|
kind: "field",
|
|
@@ -62656,10 +62741,16 @@ onStatusChanged: { data: zod.z.object({
|
|
|
62656
62741
|
/**
|
|
62657
62742
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
62658
62743
|
*/
|
|
62659
|
-
history: { fields: {
|
|
62660
|
-
|
|
62661
|
-
|
|
62662
|
-
|
|
62744
|
+
history: { fields: {
|
|
62745
|
+
percentage: {
|
|
62746
|
+
kind: "gauge",
|
|
62747
|
+
unit: "%"
|
|
62748
|
+
},
|
|
62749
|
+
volts: {
|
|
62750
|
+
kind: "gauge",
|
|
62751
|
+
unit: "V"
|
|
62752
|
+
}
|
|
62753
|
+
} },
|
|
62663
62754
|
customize: batteryCustomize,
|
|
62664
62755
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62665
62756
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -62706,12 +62797,7 @@ var binaryCapability = {
|
|
|
62706
62797
|
history: { fields: { on: { kind: "boolean" } } },
|
|
62707
62798
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62708
62799
|
* whether persisting is worth a SQLite commit. */
|
|
62709
|
-
volatileStateFields: ["lastChangedAt"]
|
|
62710
|
-
customize: {
|
|
62711
|
-
version: 1,
|
|
62712
|
-
advanced: "derive",
|
|
62713
|
-
targets: []
|
|
62714
|
-
}
|
|
62800
|
+
volatileStateFields: ["lastChangedAt"]
|
|
62715
62801
|
};
|
|
62716
62802
|
/**
|
|
62717
62803
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
@@ -62727,7 +62813,7 @@ var binaryCapability = {
|
|
|
62727
62813
|
*/
|
|
62728
62814
|
var BrightnessStatusSchema = zod.z.object({
|
|
62729
62815
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
62730
|
-
percentage: zod.z.number().min(0).max(100),
|
|
62816
|
+
percentage: zod.z.number().min(0).max(100).meta(readingMeta("percentage")),
|
|
62731
62817
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
62732
62818
|
lastChangedAt: zod.z.number()
|
|
62733
62819
|
});
|
|
@@ -63278,21 +63364,21 @@ var ClimateControlStatusSchema = zod.z.object({
|
|
|
63278
63364
|
/** Single setpoint in Celsius. Used by single-target modes
|
|
63279
63365
|
* (heat / cool / dry). Null when the device is in a range mode
|
|
63280
63366
|
* (`heat_cool`) or has no setpoint at all (`fan_only`/`off`). */
|
|
63281
|
-
target: zod.z.number().nullable(),
|
|
63367
|
+
target: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
63282
63368
|
/** Upper bound of the dual setpoint in Celsius. Populated only
|
|
63283
63369
|
* in `heat_cool` mode. */
|
|
63284
|
-
targetHigh: zod.z.number().nullable(),
|
|
63370
|
+
targetHigh: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
63285
63371
|
/** Lower bound of the dual setpoint in Celsius. Populated only
|
|
63286
63372
|
* in `heat_cool` mode. */
|
|
63287
|
-
targetLow: zod.z.number().nullable(),
|
|
63373
|
+
targetLow: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
63288
63374
|
/** Target relative humidity (0..100). Null when the device has no
|
|
63289
63375
|
* humidity control. */
|
|
63290
|
-
targetHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
63376
|
+
targetHumidity: zod.z.number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63291
63377
|
/** Current measured temperature in Celsius. Read-only — pushed by
|
|
63292
63378
|
* the device's internal sensor. */
|
|
63293
|
-
currentTemp: zod.z.number().nullable(),
|
|
63379
|
+
currentTemp: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
63294
63380
|
/** Current measured relative humidity (0..100). Read-only. */
|
|
63295
|
-
currentHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
63381
|
+
currentHumidity: zod.z.number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
63296
63382
|
/** Vertical louver swing on/off. Null when the device has no vertical
|
|
63297
63383
|
* swing surface (gate with `DeviceFeature.ClimateSwingVertical`). */
|
|
63298
63384
|
swingVertical: zod.z.boolean().nullable(),
|
|
@@ -63300,11 +63386,11 @@ var ClimateControlStatusSchema = zod.z.object({
|
|
|
63300
63386
|
* horizontal swing surface (gate with `DeviceFeature.ClimateSwingHorizontal`). */
|
|
63301
63387
|
swingHorizontal: zod.z.boolean().nullable(),
|
|
63302
63388
|
/** Lowest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
63303
|
-
minTemp: zod.z.number().nullable().optional(),
|
|
63389
|
+
minTemp: zod.z.number().nullable().optional().meta(readingMeta("temperature")),
|
|
63304
63390
|
/** Highest setpoint the device accepts, Celsius. Absent / null = not reported. */
|
|
63305
|
-
maxTemp: zod.z.number().nullable().optional(),
|
|
63391
|
+
maxTemp: zod.z.number().nullable().optional().meta(readingMeta("temperature")),
|
|
63306
63392
|
/** Setpoint granularity, Celsius (0.5, 1). Absent / null = not reported. */
|
|
63307
|
-
tempStep: zod.z.number().positive().nullable().optional(),
|
|
63393
|
+
tempStep: zod.z.number().positive().nullable().optional().meta(readingMeta("temperature")),
|
|
63308
63394
|
/** Ms epoch when the slice was last updated (push or command). */
|
|
63309
63395
|
lastFetchedAt: zod.z.number()
|
|
63310
63396
|
});
|
|
@@ -63446,17 +63532,17 @@ var climateControlCapability = {
|
|
|
63446
63532
|
* modes to expose in the picker without a slice fetch.
|
|
63447
63533
|
*/
|
|
63448
63534
|
var RgbTripletSchema = zod.z.object({
|
|
63449
|
-
r: zod.z.number().int().min(0).max(255),
|
|
63450
|
-
g: zod.z.number().int().min(0).max(255),
|
|
63451
|
-
b: zod.z.number().int().min(0).max(255)
|
|
63535
|
+
r: zod.z.number().int().min(0).max(255).meta(readingMeta("none")),
|
|
63536
|
+
g: zod.z.number().int().min(0).max(255).meta(readingMeta("none")),
|
|
63537
|
+
b: zod.z.number().int().min(0).max(255).meta(readingMeta("none"))
|
|
63452
63538
|
});
|
|
63453
63539
|
var HsvTripletSchema = zod.z.object({
|
|
63454
63540
|
/** Hue in degrees, 0..360. */
|
|
63455
|
-
h: zod.z.number().min(0).max(360),
|
|
63541
|
+
h: zod.z.number().min(0).max(360).meta(readingMeta("none")),
|
|
63456
63542
|
/** Saturation as 0..100 inclusive. */
|
|
63457
|
-
s: zod.z.number().min(0).max(100),
|
|
63543
|
+
s: zod.z.number().min(0).max(100).meta(readingMeta("none")),
|
|
63458
63544
|
/** Value/brightness as 0..100 inclusive. */
|
|
63459
|
-
v: zod.z.number().min(0).max(100)
|
|
63545
|
+
v: zod.z.number().min(0).max(100).meta(readingMeta("none"))
|
|
63460
63546
|
});
|
|
63461
63547
|
var ColorInputSchema = zod.z.discriminatedUnion("mode", [
|
|
63462
63548
|
zod.z.object({
|
|
@@ -63485,7 +63571,7 @@ var ColorStatusSchema = zod.z.object({
|
|
|
63485
63571
|
/** Populated when `mode === 'hsv'`. */
|
|
63486
63572
|
hsv: HsvTripletSchema.optional(),
|
|
63487
63573
|
/** Populated when `mode === 'mired'`. */
|
|
63488
|
-
mireds: zod.z.number().int().optional(),
|
|
63574
|
+
mireds: zod.z.number().int().optional().meta(readingMeta("colour-temperature")),
|
|
63489
63575
|
/** Ms epoch of the last operator-driven change. */
|
|
63490
63576
|
lastChangedAt: zod.z.number()
|
|
63491
63577
|
});
|
|
@@ -63688,18 +63774,12 @@ zod.z.enum([
|
|
|
63688
63774
|
"empty",
|
|
63689
63775
|
"full"
|
|
63690
63776
|
]);
|
|
63691
|
-
/**
|
|
63692
|
-
|
|
63693
|
-
|
|
63694
|
-
"days",
|
|
63695
|
-
"hours",
|
|
63696
|
-
"cycles"
|
|
63697
|
-
]);
|
|
63698
|
-
/** Remaining life as a COUNT, not a percentage (the PetKit desiccant reports
|
|
63699
|
-
* days). `value` null = unknown (D393). */
|
|
63777
|
+
/** Whether `remaining.value` is a duration in seconds or a dimensionless count. */
|
|
63778
|
+
var ConsumableRemainingKindSchema = zod.z.enum(["duration", "count"]);
|
|
63779
|
+
/** Remaining life. `value` null = unknown (D393). Duration is seconds. */
|
|
63700
63780
|
var ConsumableRemainingSchema = zod.z.object({
|
|
63701
|
-
value: zod.z.number().min(0).nullable(),
|
|
63702
|
-
|
|
63781
|
+
value: zod.z.number().min(0).nullable().meta(readingMeta("device")),
|
|
63782
|
+
kind: ConsumableRemainingKindSchema
|
|
63703
63783
|
});
|
|
63704
63784
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
63705
63785
|
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
@@ -63712,7 +63792,7 @@ var ConsumableItemSchema = zod.z.object({
|
|
|
63712
63792
|
/** Display name. */
|
|
63713
63793
|
label: zod.z.string().min(1),
|
|
63714
63794
|
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
63715
|
-
level: zod.z.number().min(0).max(100).nullable(),
|
|
63795
|
+
level: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63716
63796
|
/** The provider's discrete verdict when known (binary mode). */
|
|
63717
63797
|
status: ConsumableStatusSchema.nullable(),
|
|
63718
63798
|
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
@@ -63794,8 +63874,8 @@ var consumablesCustomize = {
|
|
|
63794
63874
|
transforms: [{ kind: "identity" }]
|
|
63795
63875
|
}],
|
|
63796
63876
|
literals: [{
|
|
63797
|
-
path: "remaining.
|
|
63798
|
-
values: [...
|
|
63877
|
+
path: "remaining.kind",
|
|
63878
|
+
values: [...ConsumableRemainingKindSchema.options]
|
|
63799
63879
|
}]
|
|
63800
63880
|
},
|
|
63801
63881
|
{
|
|
@@ -63924,7 +64004,6 @@ reset: method(zod.z.object({
|
|
|
63924
64004
|
},
|
|
63925
64005
|
"remaining.value": {
|
|
63926
64006
|
kind: "gauge",
|
|
63927
|
-
unitFrom: "remaining.unit",
|
|
63928
64007
|
deadband: 1,
|
|
63929
64008
|
displayName: "Remaining"
|
|
63930
64009
|
}
|
|
@@ -64023,49 +64102,26 @@ var ControlKindSchema = zod.z.enum([
|
|
|
64023
64102
|
* (empty array for the other kinds). It lives in the slice because
|
|
64024
64103
|
* HA `select.*` entities may update their options at runtime.
|
|
64025
64104
|
*
|
|
64026
|
-
*
|
|
64027
|
-
*
|
|
64028
|
-
*
|
|
64029
|
-
* push — consistent with `options` and the sensor-unit approach.
|
|
64105
|
+
* Numeric `min` / `max` / `step` live in the slice and share the device
|
|
64106
|
+
* quantity (`SourceInfo.quantity`, D944). Display precision is a read-time
|
|
64107
|
+
* preference. A datetime control's shape is `SourceInfo.dateTimeShape`.
|
|
64030
64108
|
*/
|
|
64031
64109
|
var ControlStatusSchema = zod.z.object({
|
|
64032
64110
|
kind: ControlKindSchema,
|
|
64033
64111
|
/** Current value. Numeric kind → number; select/text/datetime → string.
|
|
64034
64112
|
* Datetime values are ISO 8601 strings (full timestamp, date-only,
|
|
64035
64113
|
* or time-only — HA accepts all three forms). */
|
|
64036
|
-
value: zod.z.union([zod.z.number(), zod.z.string()]),
|
|
64114
|
+
value: zod.z.union([zod.z.number().meta(readingMeta("device")), zod.z.string()]),
|
|
64037
64115
|
/** Acceptable values when `kind === 'select'`. Empty for other kinds. */
|
|
64038
64116
|
options: zod.z.array(zod.z.string()),
|
|
64039
64117
|
/** Ms epoch when the slice was last updated. */
|
|
64040
64118
|
lastChangedAt: zod.z.number(),
|
|
64041
|
-
/**
|
|
64042
|
-
|
|
64043
|
-
|
|
64044
|
-
|
|
64045
|
-
/**
|
|
64046
|
-
|
|
64047
|
-
min: zod.z.number().optional(),
|
|
64048
|
-
/** Maximum allowed value. Populated live from HA `attributes.max`.
|
|
64049
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
64050
|
-
max: zod.z.number().optional(),
|
|
64051
|
-
/** Step increment. Populated live from HA `attributes.step`.
|
|
64052
|
-
* Meaningful for `kind === 'numeric'`; absent for other kinds. */
|
|
64053
|
-
step: zod.z.number().optional(),
|
|
64054
|
-
/** Suggested decimal places for numeric display. Populated live from HA
|
|
64055
|
-
* `attributes.suggested_display_precision`, or derived from `step` when the
|
|
64056
|
-
* HA attribute is absent. Meaningful for `kind === 'numeric'`; absent for
|
|
64057
|
-
* other kinds. Falls back to auto-formatting when absent. */
|
|
64058
|
-
precision: zod.z.number().int().min(0).max(10).optional(),
|
|
64059
|
-
/** Date-picker granularity for `kind === 'datetime'`. 'date' → date-only,
|
|
64060
|
-
* 'time' → time-only, 'datetime' → full timestamp. Absent for other kinds
|
|
64061
|
-
* (UI defaults to 'datetime'). Derived live from the device's HA domain
|
|
64062
|
-
* (date.* / time.* / datetime.*) or, for input_datetime, from the entity's
|
|
64063
|
-
* `has_date`/`has_time` attributes on each push. */
|
|
64064
|
-
format: zod.z.enum([
|
|
64065
|
-
"date",
|
|
64066
|
-
"time",
|
|
64067
|
-
"datetime"
|
|
64068
|
-
]).optional()
|
|
64119
|
+
/** Minimum allowed value, in the device quantity's base unit. */
|
|
64120
|
+
min: zod.z.number().optional().meta(readingMeta("device")),
|
|
64121
|
+
/** Maximum allowed value, in the device quantity's base unit. */
|
|
64122
|
+
max: zod.z.number().optional().meta(readingMeta("device")),
|
|
64123
|
+
/** Step increment, in the device quantity's base unit. */
|
|
64124
|
+
step: zod.z.number().optional().meta(readingMeta("device"))
|
|
64069
64125
|
});
|
|
64070
64126
|
var ControlSetValueInputSchema = zod.z.discriminatedUnion("kind", [
|
|
64071
64127
|
zod.z.object({
|
|
@@ -64153,9 +64209,9 @@ var CoverStatusSchema = zod.z.object({
|
|
|
64153
64209
|
state: CoverStateSchema,
|
|
64154
64210
|
/** 0 = fully closed, 100 = fully open. Null when the device has
|
|
64155
64211
|
* no intermediate position surface. */
|
|
64156
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
64212
|
+
position: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64157
64213
|
/** 0 = closed slats, 100 = open slats. Null when no tilt support. */
|
|
64158
|
-
tiltPosition: zod.z.number().min(0).max(100).nullable(),
|
|
64214
|
+
tiltPosition: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64159
64215
|
/** Ms epoch when the slice was last updated. */
|
|
64160
64216
|
lastChangedAt: zod.z.number()
|
|
64161
64217
|
});
|
|
@@ -64258,9 +64314,9 @@ var NormalizedRangeSchema$1 = zod.z.object({
|
|
|
64258
64314
|
var DayNightStatusSchema = zod.z.object({
|
|
64259
64315
|
mode: DayNightModeSchema,
|
|
64260
64316
|
/** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
|
|
64261
|
-
sensitivity: zod.z.number().optional(),
|
|
64317
|
+
sensitivity: zod.z.number().optional().meta(readingMeta("none")),
|
|
64262
64318
|
/** Delay before the IR-cut filter flips, in seconds. */
|
|
64263
|
-
switchDelaySec: zod.z.number().optional(),
|
|
64319
|
+
switchDelaySec: zod.z.number().optional().meta(readingMeta("duration")),
|
|
64264
64320
|
lastFetchedAt: zod.z.number()
|
|
64265
64321
|
});
|
|
64266
64322
|
/**
|
|
@@ -64487,11 +64543,11 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
64487
64543
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
64488
64544
|
availablePrograms: zod.z.array(zod.z.string()),
|
|
64489
64545
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
64490
|
-
remainingSeconds: zod.z.number().int().nonnegative().nullable(),
|
|
64546
|
+
remainingSeconds: zod.z.number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
64491
64547
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
64492
|
-
delayedStartSeconds: zod.z.number().int().nonnegative().nullable(),
|
|
64548
|
+
delayedStartSeconds: zod.z.number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
64493
64549
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
64494
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
64550
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64495
64551
|
/** True when the door is reported open; null when the door state is not known. */
|
|
64496
64552
|
doorOpen: zod.z.boolean().nullable(),
|
|
64497
64553
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -64515,7 +64571,7 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
64515
64571
|
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
64516
64572
|
machineCareDue: zod.z.boolean().nullable(),
|
|
64517
64573
|
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
64518
|
-
machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable(),
|
|
64574
|
+
machineCareRemainingRuns: zod.z.number().int().nonnegative().nullable().meta(readingMeta("count")),
|
|
64519
64575
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
64520
64576
|
halfLoad: zod.z.boolean().nullable(),
|
|
64521
64577
|
hygienePlus: zod.z.boolean().nullable(),
|
|
@@ -64530,7 +64586,7 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
64530
64586
|
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
64531
64587
|
activeEvents: zod.z.array(zod.z.string()),
|
|
64532
64588
|
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
64533
|
-
errorCode: zod.z.number().nullable(),
|
|
64589
|
+
errorCode: zod.z.number().nullable().meta(readingMeta("none")),
|
|
64534
64590
|
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
64535
64591
|
errorLabel: zod.z.string().nullable(),
|
|
64536
64592
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
@@ -64761,7 +64817,7 @@ var DoorbellStatusSchema = zod.z.object({
|
|
|
64761
64817
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
64762
64818
|
lastPressedAt: zod.z.number().nullable(),
|
|
64763
64819
|
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
64764
|
-
pressCountSinceStart: zod.z.number()
|
|
64820
|
+
pressCountSinceStart: zod.z.number().meta(readingMeta("count"))
|
|
64765
64821
|
});
|
|
64766
64822
|
var DoorbellPressEventSchema = zod.z.object({
|
|
64767
64823
|
deviceId: zod.z.number(),
|
|
@@ -64826,17 +64882,7 @@ onPressed: {
|
|
|
64826
64882
|
history: "none",
|
|
64827
64883
|
customize: doorbellCustomize
|
|
64828
64884
|
};
|
|
64829
|
-
|
|
64830
|
-
* Enum-state sensor — a string value picked from a finite option set.
|
|
64831
|
-
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
64832
|
-
* states, weather conditions, contact-source channels, mode strings).
|
|
64833
|
-
* The option set is stable across observations; it is persisted in the
|
|
64834
|
-
* device config blob (via the control slice at adoption) and is NOT
|
|
64835
|
-
* stored in `sourceInfo`.
|
|
64836
|
-
*/
|
|
64837
|
-
/** Locale-render shape for an ISO `value` carried by a `DateTimeSensor`-role
|
|
64838
|
-
* enum sensor: `date` (date-only), `time` (time-only), `datetime` (both). */
|
|
64839
|
-
var EnumSensorDateTimeFormatSchema = zod.z.enum([
|
|
64885
|
+
zod.z.enum([
|
|
64840
64886
|
"date",
|
|
64841
64887
|
"time",
|
|
64842
64888
|
"datetime"
|
|
@@ -64844,12 +64890,11 @@ var EnumSensorDateTimeFormatSchema = zod.z.enum([
|
|
|
64844
64890
|
var EnumSensorStatusSchema = zod.z.object({
|
|
64845
64891
|
value: zod.z.string(),
|
|
64846
64892
|
/**
|
|
64847
|
-
* Set
|
|
64848
|
-
* as
|
|
64849
|
-
*
|
|
64850
|
-
* a time-only sensor → `'time'`.
|
|
64893
|
+
* Set when `value` is a timestamp rather than an enum state, so history
|
|
64894
|
+
* does not learn ISO strings as states. The display shape (date / time /
|
|
64895
|
+
* datetime) lives on `SourceInfo.dateTimeShape`, written once at adopt.
|
|
64851
64896
|
*/
|
|
64852
|
-
|
|
64897
|
+
timestamp: zod.z.boolean().optional(),
|
|
64853
64898
|
/** Ms epoch when the slice was last updated. */
|
|
64854
64899
|
lastFetchedAt: zod.z.number()
|
|
64855
64900
|
});
|
|
@@ -64876,11 +64921,11 @@ var enumSensorCapability = {
|
|
|
64876
64921
|
* History (D850): the value as an `enum` series (an appliance's program or
|
|
64877
64922
|
* operation state, an HVAC action). The option set is per device, so the
|
|
64878
64923
|
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
64879
|
-
* `
|
|
64924
|
+
* `timestamp` carries a clock, not a state, and is not recorded.
|
|
64880
64925
|
*/
|
|
64881
64926
|
history: { fields: { value: {
|
|
64882
64927
|
kind: "enum",
|
|
64883
|
-
skipWhenSet: "
|
|
64928
|
+
skipWhenSet: "timestamp"
|
|
64884
64929
|
} } },
|
|
64885
64930
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64886
64931
|
* whether persisting is worth a SQLite commit. */
|
|
@@ -64900,13 +64945,13 @@ var EventFireSchema = zod.z.object({
|
|
|
64900
64945
|
deviceId: zod.z.number(),
|
|
64901
64946
|
eventType: zod.z.string(),
|
|
64902
64947
|
data: zod.z.record(zod.z.string(), zod.z.unknown()).nullable(),
|
|
64903
|
-
timestamp: zod.z.number(),
|
|
64904
|
-
seq: zod.z.number()
|
|
64948
|
+
timestamp: zod.z.number().meta(readingMeta("none")),
|
|
64949
|
+
seq: zod.z.number().meta(readingMeta("count"))
|
|
64905
64950
|
});
|
|
64906
64951
|
var EventEmitterStatusSchema = zod.z.object({
|
|
64907
64952
|
eventTypes: zod.z.array(zod.z.string()),
|
|
64908
64953
|
lastEvent: EventFireSchema.nullable(),
|
|
64909
|
-
eventCountSinceStart: zod.z.number()
|
|
64954
|
+
eventCountSinceStart: zod.z.number().meta(readingMeta("count"))
|
|
64910
64955
|
});
|
|
64911
64956
|
var eventEmitterCapability = {
|
|
64912
64957
|
name: "event-emitter",
|
|
@@ -65359,10 +65404,10 @@ var FanDirectionSchema = zod.z.enum(["forward", "reverse"]);
|
|
|
65359
65404
|
var FanControlStatusSchema = zod.z.object({
|
|
65360
65405
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
65361
65406
|
* speed surface (single-speed fan). */
|
|
65362
|
-
percentage: zod.z.number().min(0).max(100).nullable(),
|
|
65407
|
+
percentage: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65363
65408
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
65364
65409
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
65365
|
-
percentageStep: zod.z.number().positive().optional(),
|
|
65410
|
+
percentageStep: zod.z.number().positive().optional().meta(readingMeta("percentage")),
|
|
65366
65411
|
/** Active preset mode (`auto` / `quiet` / `turbo` / vendor-specific)
|
|
65367
65412
|
* — empty string when no preset is active or supported. */
|
|
65368
65413
|
preset: zod.z.string(),
|
|
@@ -65483,7 +65528,7 @@ var FeatureProbeStatusSchema = zod.z.object({
|
|
|
65483
65528
|
/** Camera/firmware model string. `null` when the firmware doesn't expose it. */
|
|
65484
65529
|
model: zod.z.string().nullable(),
|
|
65485
65530
|
/** Channel count for NVR/Hub devices; `1` for standalone cameras; `null` pre-probe. */
|
|
65486
|
-
channelCount: zod.z.number().nullable(),
|
|
65531
|
+
channelCount: zod.z.number().nullable().meta(readingMeta("count")),
|
|
65487
65532
|
/**
|
|
65488
65533
|
* Ms epoch of the last SUCCESSFUL probe. `0` before the first probe
|
|
65489
65534
|
* completes — drivers' `getAccessoryChildren()` should treat zero as
|
|
@@ -65608,7 +65653,7 @@ var gasCapability = {
|
|
|
65608
65653
|
};
|
|
65609
65654
|
var HeatingValveStatusSchema = zod.z.object({
|
|
65610
65655
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
65611
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
65656
|
+
position: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65612
65657
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
65613
65658
|
lastFetchedAt: zod.z.number()
|
|
65614
65659
|
});
|
|
@@ -65651,9 +65696,9 @@ var HumidifierStatusSchema = zod.z.object({
|
|
|
65651
65696
|
/** Whether the humidifier is currently on. */
|
|
65652
65697
|
on: zod.z.boolean(),
|
|
65653
65698
|
/** Current measured relative humidity (0..100). Null when not reported. */
|
|
65654
|
-
currentHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
65699
|
+
currentHumidity: zod.z.number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
65655
65700
|
/** Target relative humidity (0..100). Null when no setpoint surface. */
|
|
65656
|
-
targetHumidity: zod.z.number().min(0).max(100).nullable(),
|
|
65701
|
+
targetHumidity: zod.z.number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
65657
65702
|
/** Active mode (`auto` / `normal` / `baby` / vendor). Null when the
|
|
65658
65703
|
* device has no mode surface. */
|
|
65659
65704
|
mode: zod.z.string().nullable(),
|
|
@@ -65663,9 +65708,9 @@ var HumidifierStatusSchema = zod.z.object({
|
|
|
65663
65708
|
* `idle` / `off`). Null when the device doesn't report it. */
|
|
65664
65709
|
action: zod.z.string().nullable(),
|
|
65665
65710
|
/** HA `min_humidity` attribute. Null → UI uses 0. */
|
|
65666
|
-
minHumidity: zod.z.number().nullable(),
|
|
65711
|
+
minHumidity: zod.z.number().nullable().meta(readingMeta("humidity")),
|
|
65667
65712
|
/** HA `max_humidity` attribute. Null → UI uses 100. */
|
|
65668
|
-
maxHumidity: zod.z.number().nullable(),
|
|
65713
|
+
maxHumidity: zod.z.number().nullable().meta(readingMeta("humidity")),
|
|
65669
65714
|
/** Ms epoch when the slice was last updated. */
|
|
65670
65715
|
lastChangedAt: zod.z.number()
|
|
65671
65716
|
});
|
|
@@ -65735,22 +65780,13 @@ var humidifierCapability = {
|
|
|
65735
65780
|
* `sourceInfo`.
|
|
65736
65781
|
*/
|
|
65737
65782
|
var HumiditySensorStatusSchema = zod.z.object({
|
|
65738
|
-
/** Current relative humidity, 0..100. */
|
|
65739
|
-
percent: zod.z.number().min(0).max(100).meta({
|
|
65740
|
-
|
|
65783
|
+
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
65784
|
+
percent: zod.z.number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
65785
|
+
precision: 0,
|
|
65741
65786
|
label: "Humidity"
|
|
65742
|
-
}),
|
|
65787
|
+
})),
|
|
65743
65788
|
/** Ms epoch when the slice was last updated. */
|
|
65744
|
-
lastFetchedAt: zod.z.number()
|
|
65745
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
65746
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
65747
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
65748
|
-
unit: zod.z.string().optional(),
|
|
65749
|
-
/** Suggested decimal places for numeric display.
|
|
65750
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
65751
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
65752
|
-
* auto-formatting when absent. */
|
|
65753
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
65789
|
+
lastFetchedAt: zod.z.number()
|
|
65754
65790
|
});
|
|
65755
65791
|
var humiditySensorCapability = {
|
|
65756
65792
|
name: "humidity-sensor",
|
|
@@ -65781,12 +65817,7 @@ var humiditySensorCapability = {
|
|
|
65781
65817
|
} } },
|
|
65782
65818
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65783
65819
|
* whether persisting is worth a SQLite commit. */
|
|
65784
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
65785
|
-
customize: {
|
|
65786
|
-
version: 1,
|
|
65787
|
-
advanced: "derive",
|
|
65788
|
-
targets: []
|
|
65789
|
-
}
|
|
65820
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
65790
65821
|
};
|
|
65791
65822
|
/**
|
|
65792
65823
|
* Image display cap. Models a single still image exposed by an integration —
|
|
@@ -65807,7 +65838,7 @@ var ImageStatusSchema = zod.z.object({
|
|
|
65807
65838
|
* entity exposes no `entity_picture` (yet). */
|
|
65808
65839
|
url: zod.z.string().nullable(),
|
|
65809
65840
|
/** Ms epoch of the upstream last-updated timestamp. Null at cold-start. */
|
|
65810
|
-
lastUpdated: zod.z.number().nullable()
|
|
65841
|
+
lastUpdated: zod.z.number().nullable().meta(readingMeta("none"))
|
|
65811
65842
|
});
|
|
65812
65843
|
var imageCapability = {
|
|
65813
65844
|
name: "image",
|
|
@@ -65895,19 +65926,19 @@ var NormalizedRangeSchema = zod.z.object({
|
|
|
65895
65926
|
*/
|
|
65896
65927
|
var ImageSettingsStatusSchema = zod.z.object({
|
|
65897
65928
|
/** Normalized 0–100. */
|
|
65898
|
-
brightness: zod.z.number().optional(),
|
|
65929
|
+
brightness: zod.z.number().optional().meta(readingMeta("none")),
|
|
65899
65930
|
/** Normalized 0–100. */
|
|
65900
|
-
contrast: zod.z.number().optional(),
|
|
65931
|
+
contrast: zod.z.number().optional().meta(readingMeta("none")),
|
|
65901
65932
|
/** Normalized 0–100. */
|
|
65902
|
-
saturation: zod.z.number().optional(),
|
|
65933
|
+
saturation: zod.z.number().optional().meta(readingMeta("none")),
|
|
65903
65934
|
/** Normalized 0–100. */
|
|
65904
|
-
sharpness: zod.z.number().optional(),
|
|
65935
|
+
sharpness: zod.z.number().optional().meta(readingMeta("none")),
|
|
65905
65936
|
mirror: zod.z.boolean().optional(),
|
|
65906
65937
|
flip: zod.z.boolean().optional(),
|
|
65907
65938
|
rotate: ImageRotateSchema.optional(),
|
|
65908
65939
|
whiteBalance: WhiteBalanceModeSchema.optional(),
|
|
65909
65940
|
/** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
|
|
65910
|
-
warmth: zod.z.number().optional(),
|
|
65941
|
+
warmth: zod.z.number().optional().meta(readingMeta("none")),
|
|
65911
65942
|
exposureMode: ExposureModeSchema.optional(),
|
|
65912
65943
|
backlightMode: BacklightModeSchema.optional(),
|
|
65913
65944
|
lastFetchedAt: zod.z.number()
|
|
@@ -66204,10 +66235,10 @@ var IntercomAbilitySchema = zod.z.object({
|
|
|
66204
66235
|
/** Codecs accepted by firmware, in preference order. Driver-authored strings. */
|
|
66205
66236
|
codecs: zod.z.array(zod.z.string()),
|
|
66206
66237
|
/** Sample rate (Hz) the firmware expects. Reolink typical: 16000. */
|
|
66207
|
-
sampleRate: zod.z.number(),
|
|
66238
|
+
sampleRate: zod.z.number().meta(readingMeta("none")),
|
|
66208
66239
|
duplex: zod.z.enum(["half", "full"]),
|
|
66209
66240
|
/** Max in-flight audio backlog before drop (ms). Server uses this to bound latency. */
|
|
66210
|
-
maxBacklogMs: zod.z.number()
|
|
66241
|
+
maxBacklogMs: zod.z.number().meta(readingMeta("duration-ms"))
|
|
66211
66242
|
});
|
|
66212
66243
|
var IntercomStatusSchema = zod.z.object({
|
|
66213
66244
|
/** True while a talk session is open. */
|
|
@@ -66434,13 +66465,13 @@ var LawnMowerControlStatusSchema = zod.z.object({
|
|
|
66434
66465
|
activity: LawnMowerActivitySchema,
|
|
66435
66466
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
66436
66467
|
* reading. */
|
|
66437
|
-
batteryLevel: zod.z.number().min(0).max(100).nullable(),
|
|
66468
|
+
batteryLevel: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
66438
66469
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
66439
66470
|
* task is active / progress is unavailable. */
|
|
66440
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
66471
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
66441
66472
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
66442
66473
|
* or null when unknown. */
|
|
66443
|
-
currentCode: zod.z.number().nullable(),
|
|
66474
|
+
currentCode: zod.z.number().nullable().meta(readingMeta("none")),
|
|
66444
66475
|
/** Human label for {@link currentCode}, or null when undecodable. */
|
|
66445
66476
|
currentCodeLabel: zod.z.string().nullable(),
|
|
66446
66477
|
/** Severity of {@link currentCode}. `error` (and often `warning`) warrants UI
|
|
@@ -67164,7 +67195,7 @@ var MediaPlayerStatusSchema = zod.z.object({
|
|
|
67164
67195
|
state: MediaPlayerStateSchema,
|
|
67165
67196
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
67166
67197
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
67167
|
-
volumeLevel: zod.z.number().min(0).max(100).nullable(),
|
|
67198
|
+
volumeLevel: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
67168
67199
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
67169
67200
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
67170
67201
|
isMuted: zod.z.boolean().nullable(),
|
|
@@ -67177,10 +67208,10 @@ var MediaPlayerStatusSchema = zod.z.object({
|
|
|
67177
67208
|
currentMedia: MediaInfoSchema.nullable(),
|
|
67178
67209
|
/** Current playback position in ms. Null when not seekable or
|
|
67179
67210
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
67180
|
-
positionMs: zod.z.number().int().nonnegative().nullable(),
|
|
67211
|
+
positionMs: zod.z.number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
67181
67212
|
/** Total duration of the current media in ms. Null when unknown
|
|
67182
67213
|
* (live stream) or nothing is playing. */
|
|
67183
|
-
durationMs: zod.z.number().int().nonnegative().nullable(),
|
|
67214
|
+
durationMs: zod.z.number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
67184
67215
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
67185
67216
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
67186
67217
|
shuffle: zod.z.boolean().nullable(),
|
|
@@ -67550,7 +67581,7 @@ var motionCustomize = {
|
|
|
67550
67581
|
eventName: "onMotionChanged"
|
|
67551
67582
|
},
|
|
67552
67583
|
deviceTypes: [DeviceType.Camera],
|
|
67553
|
-
apply: "
|
|
67584
|
+
apply: "add",
|
|
67554
67585
|
applyAuthority: {
|
|
67555
67586
|
kind: "camera-sensors",
|
|
67556
67587
|
timeoutField: "motionCooldownMs"
|
|
@@ -67647,7 +67678,7 @@ var MotionStatusSchema = zod.z.object({
|
|
|
67647
67678
|
* it, every provider seeded it at boot, and every session left it
|
|
67648
67679
|
* `detected: true` after its detach.
|
|
67649
67680
|
*/
|
|
67650
|
-
autoClearAfterMs: zod.z.number().nullable()
|
|
67681
|
+
autoClearAfterMs: zod.z.number().nullable().meta(readingMeta("duration-ms"))
|
|
67651
67682
|
});
|
|
67652
67683
|
/**
|
|
67653
67684
|
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
@@ -67829,7 +67860,7 @@ var MotionZoneRegionSchema = zod.z.object({
|
|
|
67829
67860
|
* the grid region(s). */
|
|
67830
67861
|
var MotionZoneStatusSchema = zod.z.object({
|
|
67831
67862
|
enabled: zod.z.boolean(),
|
|
67832
|
-
sensitivity: zod.z.number(),
|
|
67863
|
+
sensitivity: zod.z.number().meta(readingMeta("none")),
|
|
67833
67864
|
/** Grid region(s). Today exactly one `grid` shape. */
|
|
67834
67865
|
regions: zod.z.array(MotionZoneRegionSchema),
|
|
67835
67866
|
lastFetchedAt: zod.z.number()
|
|
@@ -68201,7 +68232,7 @@ var NavigationStatusSchema = zod.z.object({
|
|
|
68201
68232
|
following: zod.z.boolean(),
|
|
68202
68233
|
flash: zod.z.boolean(),
|
|
68203
68234
|
lightMode: NavigationLightModeSchema,
|
|
68204
|
-
lightLevel: zod.z.number().min(40).max(100),
|
|
68235
|
+
lightLevel: zod.z.number().min(40).max(100).meta(readingMeta("none")),
|
|
68205
68236
|
/** Ms epoch when the slice was last updated. */
|
|
68206
68237
|
lastChangedAt: zod.z.number()
|
|
68207
68238
|
});
|
|
@@ -68335,13 +68366,13 @@ var NetworkLinkStatusSchema = zod.z.object({
|
|
|
68335
68366
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
68336
68367
|
* SKIP a null rather than coerce it.
|
|
68337
68368
|
*/
|
|
68338
|
-
signalPercent: zod.z.number().min(0).max(100).nullable(),
|
|
68369
|
+
signalPercent: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68339
68370
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
68340
|
-
rssiDbm: zod.z.number().optional(),
|
|
68371
|
+
rssiDbm: zod.z.number().optional().meta(readingMeta("signal-level")),
|
|
68341
68372
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
68342
68373
|
ssid: zod.z.string().optional(),
|
|
68343
68374
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
68344
|
-
lastUpdated: zod.z.number()
|
|
68375
|
+
lastUpdated: zod.z.number().meta(readingMeta("none"))
|
|
68345
68376
|
});
|
|
68346
68377
|
var networkLinkCapability = {
|
|
68347
68378
|
name: "network-link",
|
|
@@ -68791,7 +68822,7 @@ var NotifierStatusSchema = zod.z.object({
|
|
|
68791
68822
|
lastError: zod.z.string().nullable(),
|
|
68792
68823
|
/** Number of deliveries currently buffered server-side (rate-limited
|
|
68793
68824
|
* notifiers may queue). 0 when the provider sends synchronously. */
|
|
68794
|
-
queueDepth: zod.z.number().int().nonnegative(),
|
|
68825
|
+
queueDepth: zod.z.number().int().nonnegative().meta(readingMeta("count")),
|
|
68795
68826
|
/** Per-feature capability matrix — authoritative source for the
|
|
68796
68827
|
* compose-form field gating. */
|
|
68797
68828
|
supports: NotifierSupportsSchema
|
|
@@ -68883,11 +68914,9 @@ onSent: { data: zod.z.object({
|
|
|
68883
68914
|
* cap fits (HA `sensor` whose `device_class` we don't have a typed cap
|
|
68884
68915
|
* for: water flow, distance, weight, frequency, signal strength, …).
|
|
68885
68916
|
*
|
|
68886
|
-
* The
|
|
68887
|
-
*
|
|
68888
|
-
*
|
|
68889
|
-
* The UI reads them directly from the slice — they are the single source
|
|
68890
|
-
* of truth for generic numeric rendering and do NOT live on `sourceInfo`.
|
|
68917
|
+
* The quantity is not on this slice. It is chosen when the device is
|
|
68918
|
+
* adopted and stored once on `SourceInfo.quantity` (D944). `value` is in
|
|
68919
|
+
* that quantity's base unit. `null` is a refused sample (D393).
|
|
68891
68920
|
*
|
|
68892
68921
|
* Prefer the typed alternatives (`temperature-sensor`, `humidity-sensor`,
|
|
68893
68922
|
* `ambient-light-sensor`, `pressure-sensor`, `power-meter`,
|
|
@@ -68896,15 +68925,8 @@ onSent: { data: zod.z.object({
|
|
|
68896
68925
|
* numeric values land here.
|
|
68897
68926
|
*/
|
|
68898
68927
|
var NumericSensorStatusSchema = zod.z.object({
|
|
68899
|
-
|
|
68900
|
-
|
|
68901
|
-
* Populated live from the upstream source on each state push.
|
|
68902
|
-
* Absent for unitless sensors. */
|
|
68903
|
-
unit: zod.z.string().optional(),
|
|
68904
|
-
/** Suggested decimal places for numeric display.
|
|
68905
|
-
* Populated live from the upstream source when provided.
|
|
68906
|
-
* Falls back to auto-formatting when absent. */
|
|
68907
|
-
precision: zod.z.number().int().min(0).max(10).optional(),
|
|
68928
|
+
/** Reading in the device quantity's base unit. `null` when refused (D393). */
|
|
68929
|
+
value: zod.z.number().nullable().meta(readingMeta("device")),
|
|
68908
68930
|
/** Ms epoch when the slice was last updated. */
|
|
68909
68931
|
lastFetchedAt: zod.z.number()
|
|
68910
68932
|
});
|
|
@@ -68928,11 +68950,11 @@ var numericSensorCapability = {
|
|
|
68928
68950
|
*/
|
|
68929
68951
|
durability: "restored",
|
|
68930
68952
|
/**
|
|
68931
|
-
* History (D850): recorded series. The unit is
|
|
68953
|
+
* History (D850): recorded series. The unit is the device quantity's base,
|
|
68954
|
+
* resolved when the series is read — the cap has no single unit.
|
|
68932
68955
|
*/
|
|
68933
68956
|
history: { fields: { value: {
|
|
68934
68957
|
kind: "gauge",
|
|
68935
|
-
unitFrom: "unit",
|
|
68936
68958
|
minIntervalMs: 3e4
|
|
68937
68959
|
} } },
|
|
68938
68960
|
/** Clock fields: written, but excluded from the compare that decides
|
|
@@ -69333,23 +69355,26 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
69333
69355
|
/** Food currently in the bowl (grams). Null when the device has not
|
|
69334
69356
|
* reported a reading yet. On dual-hopper models this is the combined
|
|
69335
69357
|
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
69336
|
-
foodLevel: zod.z.number().nullable(),
|
|
69358
|
+
foodLevel: zod.z.number().nullable().meta(readingMeta("none")),
|
|
69337
69359
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
69338
69360
|
* single-hopper models. */
|
|
69339
|
-
food1: zod.z.number().nullable(),
|
|
69361
|
+
food1: zod.z.number().nullable().meta(readingMeta("none")),
|
|
69340
69362
|
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
69341
69363
|
* single-hopper models. */
|
|
69342
|
-
food2: zod.z.number().nullable(),
|
|
69364
|
+
food2: zod.z.number().nullable().meta(readingMeta("none")),
|
|
69343
69365
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
69344
69366
|
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
69345
69367
|
* below the feeder's low threshold. */
|
|
69346
69368
|
lowFood: zod.z.boolean(),
|
|
69347
69369
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
69348
69370
|
* device has no battery reading. */
|
|
69349
|
-
batteryPower: zod.z.number().min(0).max(100).nullable(),
|
|
69350
|
-
/**
|
|
69351
|
-
*
|
|
69352
|
-
|
|
69371
|
+
batteryPower: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69372
|
+
/**
|
|
69373
|
+
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
69374
|
+
* Providers convert from the days the feeder reports. Null when the
|
|
69375
|
+
* model has no desiccant sensor.
|
|
69376
|
+
*/
|
|
69377
|
+
desiccantLeftDays: zod.z.number().nullable().meta(readingMeta("duration")),
|
|
69353
69378
|
/** True while a feed is in progress. */
|
|
69354
69379
|
feeding: zod.z.boolean(),
|
|
69355
69380
|
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
@@ -69360,7 +69385,7 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
69360
69385
|
* with `errorCode` for consumers that want the raw integer. */
|
|
69361
69386
|
error: zod.z.string().nullable(),
|
|
69362
69387
|
/** Raw device error code (0 / null = no error). */
|
|
69363
|
-
errorCode: zod.z.number().nullable(),
|
|
69388
|
+
errorCode: zod.z.number().nullable().meta(readingMeta("none")),
|
|
69364
69389
|
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
69365
69390
|
isDualHopper: zod.z.boolean(),
|
|
69366
69391
|
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
@@ -69370,7 +69395,7 @@ var PetFeederStatusSchema = zod.z.object({
|
|
|
69370
69395
|
/** Play a chime when dispensing. */
|
|
69371
69396
|
feedSound: zod.z.boolean(),
|
|
69372
69397
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
69373
|
-
volume: zod.z.number(),
|
|
69398
|
+
volume: zod.z.number().meta(readingMeta("none")),
|
|
69374
69399
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
69375
69400
|
lastFetchedAt: zod.z.number()
|
|
69376
69401
|
});
|
|
@@ -69489,7 +69514,7 @@ var petFeederCapability = {
|
|
|
69489
69514
|
},
|
|
69490
69515
|
desiccantLeftDays: {
|
|
69491
69516
|
kind: "gauge",
|
|
69492
|
-
unit: "
|
|
69517
|
+
unit: "s"
|
|
69493
69518
|
}
|
|
69494
69519
|
} }
|
|
69495
69520
|
};
|
|
@@ -69950,36 +69975,19 @@ var platformProbeCapability = {
|
|
|
69950
69975
|
*/
|
|
69951
69976
|
var PowerMeterStatusSchema = zod.z.object({
|
|
69952
69977
|
/** Instantaneous power draw in watts. */
|
|
69953
|
-
watts: zod.z.number().optional().meta({
|
|
69954
|
-
unit: "W",
|
|
69955
|
-
label: "Power"
|
|
69956
|
-
}),
|
|
69978
|
+
watts: zod.z.number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
69957
69979
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
69958
|
-
kwhTotal: zod.z.number().optional().meta({
|
|
69959
|
-
unit: "kWh",
|
|
69960
|
-
label: "Energy"
|
|
69961
|
-
}),
|
|
69980
|
+
kwhTotal: zod.z.number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
69962
69981
|
/** Voltage in volts. */
|
|
69963
|
-
volts: zod.z.number().optional(),
|
|
69982
|
+
volts: zod.z.number().optional().meta(readingMeta("voltage")),
|
|
69964
69983
|
/** Current in amperes. */
|
|
69965
|
-
amps: zod.z.number().optional(),
|
|
69966
|
-
/** Apparent power in volt-amperes
|
|
69967
|
-
va: zod.z.number().optional(),
|
|
69984
|
+
amps: zod.z.number().optional().meta(readingMeta("current")),
|
|
69985
|
+
/** Apparent power in volt-amperes. */
|
|
69986
|
+
va: zod.z.number().optional().meta(readingMeta("apparent-power")),
|
|
69968
69987
|
/** Power factor (0..1) if reported. */
|
|
69969
|
-
powerFactor: zod.z.number().min(0).max(1).optional(),
|
|
69988
|
+
powerFactor: zod.z.number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
69970
69989
|
/** Ms epoch when the slice was last updated. */
|
|
69971
|
-
lastFetchedAt: zod.z.number()
|
|
69972
|
-
/** Live display unit of the single metric this slice carries (e.g. HA
|
|
69973
|
-
* `attributes.unit_of_measurement` → 'V' / 'A' / 'W' / 'kW' / 'kWh').
|
|
69974
|
-
* Each upstream `sensor.*` entity surfaces ONE device_class, so one
|
|
69975
|
-
* unit per slice is unambiguous. The UI prefers this over the role's
|
|
69976
|
-
* canonical unit so a 'kW' / 'Wh' feed renders verbatim. */
|
|
69977
|
-
unit: zod.z.string().optional(),
|
|
69978
|
-
/** Suggested decimal places for numeric display.
|
|
69979
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
69980
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
69981
|
-
* auto-formatting when absent. */
|
|
69982
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
69990
|
+
lastFetchedAt: zod.z.number()
|
|
69983
69991
|
});
|
|
69984
69992
|
var powerMeterCapability = {
|
|
69985
69993
|
name: "power-meter",
|
|
@@ -70043,12 +70051,7 @@ var powerMeterCapability = {
|
|
|
70043
70051
|
} },
|
|
70044
70052
|
/** Clock fields: written, but excluded from the compare that decides
|
|
70045
70053
|
* whether persisting is worth a SQLite commit. */
|
|
70046
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
70047
|
-
customize: {
|
|
70048
|
-
version: 1,
|
|
70049
|
-
advanced: "derive",
|
|
70050
|
-
targets: []
|
|
70051
|
-
}
|
|
70054
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
70052
70055
|
};
|
|
70053
70056
|
/**
|
|
70054
70057
|
* Presence cap. Models HA `person.*` and `device_tracker.*` entities
|
|
@@ -70068,11 +70071,11 @@ var powerMeterCapability = {
|
|
|
70068
70071
|
*/
|
|
70069
70072
|
var GpsLocationSchema = zod.z.object({
|
|
70070
70073
|
/** Latitude in decimal degrees, -90..90. */
|
|
70071
|
-
latitude: zod.z.number().min(-90).max(90),
|
|
70074
|
+
latitude: zod.z.number().min(-90).max(90).meta(readingMeta("angle")),
|
|
70072
70075
|
/** Longitude in decimal degrees, -180..180. */
|
|
70073
|
-
longitude: zod.z.number().min(-180).max(180),
|
|
70076
|
+
longitude: zod.z.number().min(-180).max(180).meta(readingMeta("angle")),
|
|
70074
70077
|
/** Reported accuracy in meters (lower = better). */
|
|
70075
|
-
accuracyMeters: zod.z.number().nonnegative()
|
|
70078
|
+
accuracyMeters: zod.z.number().nonnegative().meta(readingMeta("length"))
|
|
70076
70079
|
});
|
|
70077
70080
|
var PresenceStatusSchema = zod.z.object({
|
|
70078
70081
|
/** `home` / `not_home` / any user-defined zone name. */
|
|
@@ -70084,7 +70087,7 @@ var PresenceStatusSchema = zod.z.object({
|
|
|
70084
70087
|
gps: GpsLocationSchema.nullable(),
|
|
70085
70088
|
/** Optional battery level of the tracking device (0..100). Null
|
|
70086
70089
|
* when not reported. */
|
|
70087
|
-
batteryPercent: zod.z.number().min(0).max(100).nullable(),
|
|
70090
|
+
batteryPercent: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
70088
70091
|
/** Ms epoch when the slice was last updated. */
|
|
70089
70092
|
lastChangedAt: zod.z.number()
|
|
70090
70093
|
});
|
|
@@ -70134,19 +70137,10 @@ var presenceCapability = {
|
|
|
70134
70137
|
* `sourceInfo`.
|
|
70135
70138
|
*/
|
|
70136
70139
|
var PressureSensorStatusSchema = zod.z.object({
|
|
70137
|
-
/** Current pressure in hPa. */
|
|
70138
|
-
hpa: zod.z.number(),
|
|
70140
|
+
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
70141
|
+
hpa: zod.z.number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
70139
70142
|
/** Ms epoch when the slice was last updated. */
|
|
70140
|
-
lastFetchedAt: zod.z.number()
|
|
70141
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
70142
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
70143
|
-
* role's canonical unit. Absent → fall back to the canonical unit. */
|
|
70144
|
-
unit: zod.z.string().optional(),
|
|
70145
|
-
/** Suggested decimal places for numeric display.
|
|
70146
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
70147
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
70148
|
-
* auto-formatting when absent. */
|
|
70149
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
70143
|
+
lastFetchedAt: zod.z.number()
|
|
70150
70144
|
});
|
|
70151
70145
|
var pressureSensorCapability = {
|
|
70152
70146
|
name: "pressure-sensor",
|
|
@@ -70687,8 +70681,8 @@ var ptzCapability = {
|
|
|
70687
70681
|
var AutotrackTargetTypeSchema = zod.z.string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
70688
70682
|
var PtzAutotrackSettingsSchema = zod.z.object({
|
|
70689
70683
|
targetType: AutotrackTargetTypeSchema,
|
|
70690
|
-
stopDelaySeconds: zod.z.number().int().min(0).max(300),
|
|
70691
|
-
disappearDelaySeconds: zod.z.number().int().min(0).max(300)
|
|
70684
|
+
stopDelaySeconds: zod.z.number().int().min(0).max(300).meta(readingMeta("duration")),
|
|
70685
|
+
disappearDelaySeconds: zod.z.number().int().min(0).max(300).meta(readingMeta("duration"))
|
|
70692
70686
|
});
|
|
70693
70687
|
/**
|
|
70694
70688
|
* One option the camera advertises as a valid `targetType`. Drivers
|
|
@@ -70842,7 +70836,7 @@ var RunningStateStatusSchema = zod.z.object({
|
|
|
70842
70836
|
/** null = unknown — never coerced to false (D393). */
|
|
70843
70837
|
running: zod.z.boolean().nullable(),
|
|
70844
70838
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
70845
|
-
since: zod.z.number().nullable(),
|
|
70839
|
+
since: zod.z.number().nullable().meta(readingMeta("none")),
|
|
70846
70840
|
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
70847
70841
|
phase: zod.z.string().nullable(),
|
|
70848
70842
|
/** null until a reading has been published (D393). */
|
|
@@ -70857,7 +70851,6 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
|
70857
70851
|
/** Generic Customize target for the running boolean (D936). */
|
|
70858
70852
|
var runningCustomize = {
|
|
70859
70853
|
version: 1,
|
|
70860
|
-
advanced: "derive",
|
|
70861
70854
|
targets: [{
|
|
70862
70855
|
id: "running",
|
|
70863
70856
|
cardinality: "scalar",
|
|
@@ -70877,7 +70870,7 @@ var runningCustomize = {
|
|
|
70877
70870
|
DeviceType.Thermostat,
|
|
70878
70871
|
DeviceType.PetFeeder
|
|
70879
70872
|
],
|
|
70880
|
-
apply: "add
|
|
70873
|
+
apply: "add",
|
|
70881
70874
|
path: "running",
|
|
70882
70875
|
sources: [
|
|
70883
70876
|
{
|
|
@@ -72516,9 +72509,9 @@ var RecordTriggerSchema = zod.z.enum([
|
|
|
72516
72509
|
*/
|
|
72517
72510
|
var RecordWindowSchema = zod.z.object({
|
|
72518
72511
|
trigger: RecordTriggerSchema,
|
|
72519
|
-
day: zod.z.number().int().min(0).max(6),
|
|
72520
|
-
startMinute: zod.z.number().int().min(0).max(1439),
|
|
72521
|
-
endMinute: zod.z.number().int().min(1).max(1440)
|
|
72512
|
+
day: zod.z.number().int().min(0).max(6).meta(readingMeta("none")),
|
|
72513
|
+
startMinute: zod.z.number().int().min(0).max(1439).meta(readingMeta("none")),
|
|
72514
|
+
endMinute: zod.z.number().int().min(1).max(1440).meta(readingMeta("none"))
|
|
72522
72515
|
});
|
|
72523
72516
|
/** Status of one physical volume, as the camera itself describes it. */
|
|
72524
72517
|
var OnboardStorageVolumeSchema = zod.z.object({
|
|
@@ -72617,10 +72610,10 @@ var RecordingOnboardStatusSchema = zod.z.object({
|
|
|
72617
72610
|
/** Master "record to the card at all" switch. */
|
|
72618
72611
|
enabled: zod.z.boolean().nullable(),
|
|
72619
72612
|
overwriteWhenFull: zod.z.boolean().nullable(),
|
|
72620
|
-
preRecordSec: zod.z.number().nullable(),
|
|
72621
|
-
postRecordSec: zod.z.number().nullable(),
|
|
72613
|
+
preRecordSec: zod.z.number().nullable().meta(readingMeta("duration")),
|
|
72614
|
+
postRecordSec: zod.z.number().nullable().meta(readingMeta("duration")),
|
|
72622
72615
|
/** Length of one recorded file, in minutes. */
|
|
72623
|
-
segmentMinutes: zod.z.number().nullable(),
|
|
72616
|
+
segmentMinutes: zod.z.number().nullable().meta(readingMeta("none")),
|
|
72624
72617
|
/** The primary track's weekly windows, flattened. */
|
|
72625
72618
|
windows: zod.z.array(RecordWindowSchema),
|
|
72626
72619
|
/**
|
|
@@ -72636,7 +72629,7 @@ var RecordingOnboardStatusSchema = zod.z.object({
|
|
|
72636
72629
|
* provider reporting a non-zero count also reports the schedule as not
|
|
72637
72630
|
* writable.
|
|
72638
72631
|
*/
|
|
72639
|
-
unreadableWindows: zod.z.number(),
|
|
72632
|
+
unreadableWindows: zod.z.number().meta(readingMeta("count")),
|
|
72640
72633
|
/**
|
|
72641
72634
|
* The camera is scheduled to record and has NO usable storage.
|
|
72642
72635
|
*
|
|
@@ -73502,7 +73495,7 @@ var CamStreamDescriptorSchema = zod.z.object({
|
|
|
73502
73495
|
url: zod.z.string().optional(),
|
|
73503
73496
|
codec: zod.z.string().optional(),
|
|
73504
73497
|
resolution: CamStreamResolutionSchema.optional(),
|
|
73505
|
-
fps: zod.z.number().positive().optional(),
|
|
73498
|
+
fps: zod.z.number().positive().optional().meta(readingMeta("rate")),
|
|
73506
73499
|
label: zod.z.string().optional(),
|
|
73507
73500
|
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
73508
73501
|
deviceFeatures: zod.z.array(zod.z.string()).optional(),
|
|
@@ -73589,18 +73582,18 @@ var StreamProfileSchema = zod.z.enum([
|
|
|
73589
73582
|
]);
|
|
73590
73583
|
/** The current encoding config of one stream profile. */
|
|
73591
73584
|
var StreamProfileConfigSchema = zod.z.object({
|
|
73592
|
-
width: zod.z.number(),
|
|
73593
|
-
height: zod.z.number(),
|
|
73585
|
+
width: zod.z.number().meta(readingMeta("none")),
|
|
73586
|
+
height: zod.z.number().meta(readingMeta("none")),
|
|
73594
73587
|
codec: zod.z.enum(["h264", "h265"]),
|
|
73595
|
-
framerate: zod.z.number(),
|
|
73596
|
-
bitrate: zod.z.number(),
|
|
73588
|
+
framerate: zod.z.number().meta(readingMeta("rate")),
|
|
73589
|
+
bitrate: zod.z.number().meta(readingMeta("bitrate")),
|
|
73597
73590
|
bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
|
|
73598
73591
|
encoderProfile: zod.z.enum([
|
|
73599
73592
|
"high",
|
|
73600
73593
|
"main",
|
|
73601
73594
|
"baseline"
|
|
73602
73595
|
]).optional(),
|
|
73603
|
-
gop: zod.z.number().optional(),
|
|
73596
|
+
gop: zod.z.number().optional().meta(readingMeta("none")),
|
|
73604
73597
|
/**
|
|
73605
73598
|
* Whether THIS profile currently carries an audio track. READ-ONLY here.
|
|
73606
73599
|
*
|
|
@@ -74078,12 +74071,7 @@ var switchCapability = {
|
|
|
74078
74071
|
label: "On",
|
|
74079
74072
|
kind: "boolean"
|
|
74080
74073
|
}
|
|
74081
|
-
}] }
|
|
74082
|
-
customize: {
|
|
74083
|
-
version: 1,
|
|
74084
|
-
advanced: "derive",
|
|
74085
|
-
targets: []
|
|
74086
|
-
}
|
|
74074
|
+
}] }
|
|
74087
74075
|
};
|
|
74088
74076
|
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
74089
74077
|
function hasControlCharacter(value) {
|
|
@@ -74793,35 +74781,21 @@ var tamperCapability = {
|
|
|
74793
74781
|
* entries with `device_class: temperature` and any future native
|
|
74794
74782
|
* thermometer.
|
|
74795
74783
|
*
|
|
74796
|
-
*
|
|
74797
|
-
*
|
|
74798
|
-
* (climate-control's `currentTemp`, energy analytics) can compose
|
|
74799
|
-
* without per-source unit fixups. The canonical display unit (`°C`) is
|
|
74800
|
-
* a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
|
|
74801
|
-
* `sourceInfo`.
|
|
74784
|
+
* The number is Celsius (D944). Providers convert on ingest. A failed
|
|
74785
|
+
* conversion is `null`, never a guess. Display unit is a read-time preference.
|
|
74802
74786
|
*
|
|
74803
74787
|
* Status `lastFetchedAt` lets staleness-aware consumers detect a
|
|
74804
74788
|
* frozen feed (provider hung) distinct from a "temperature hasn't
|
|
74805
74789
|
* changed" steady state.
|
|
74806
74790
|
*/
|
|
74807
74791
|
var TemperatureSensorStatusSchema = zod.z.object({
|
|
74808
|
-
/** Current temperature in Celsius. */
|
|
74809
|
-
celsius: zod.z.number().meta({
|
|
74810
|
-
|
|
74792
|
+
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
74793
|
+
celsius: zod.z.number().nullable().meta(readingMeta("temperature", {
|
|
74794
|
+
precision: 1,
|
|
74811
74795
|
label: "Temperature"
|
|
74812
|
-
}),
|
|
74796
|
+
})),
|
|
74813
74797
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
74814
|
-
lastFetchedAt: zod.z.number()
|
|
74815
|
-
/** Live display unit from the upstream source (e.g. HA
|
|
74816
|
-
* `attributes.unit_of_measurement`). The UI prefers this over the
|
|
74817
|
-
* role's canonical unit, so a Fahrenheit feed renders '°F' not '°C'.
|
|
74818
|
-
* Absent → the UI falls back to the role's canonical unit. */
|
|
74819
|
-
unit: zod.z.string().optional(),
|
|
74820
|
-
/** Suggested decimal places for numeric display.
|
|
74821
|
-
* Populated live from the upstream source when provided (e.g. HA
|
|
74822
|
-
* `attributes.suggested_display_precision`). Falls back to
|
|
74823
|
-
* auto-formatting when absent. */
|
|
74824
|
-
precision: zod.z.number().int().min(0).max(10).optional()
|
|
74798
|
+
lastFetchedAt: zod.z.number()
|
|
74825
74799
|
});
|
|
74826
74800
|
var temperatureSensorCapability = {
|
|
74827
74801
|
name: "temperature-sensor",
|
|
@@ -74852,12 +74826,7 @@ var temperatureSensorCapability = {
|
|
|
74852
74826
|
} } },
|
|
74853
74827
|
/** Clock fields: written, but excluded from the compare that decides
|
|
74854
74828
|
* whether persisting is worth a SQLite commit. */
|
|
74855
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
74856
|
-
customize: {
|
|
74857
|
-
version: 1,
|
|
74858
|
-
advanced: "derive",
|
|
74859
|
-
targets: []
|
|
74860
|
-
}
|
|
74829
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
74861
74830
|
};
|
|
74862
74831
|
/**
|
|
74863
74832
|
* toast — system-scoped singleton capability that streams toast
|
|
@@ -75203,16 +75172,16 @@ var VacuumControlStatusSchema = zod.z.object({
|
|
|
75203
75172
|
state: VacuumStateSchema,
|
|
75204
75173
|
/** 0..100 battery percentage. Null when the device has no battery
|
|
75205
75174
|
* reading. */
|
|
75206
|
-
batteryLevel: zod.z.number().min(0).max(100).nullable(),
|
|
75175
|
+
batteryLevel: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
75207
75176
|
/** Current fan-speed token (provider-verbatim). Null when unknown or
|
|
75208
75177
|
* the vacuum has no speed control. */
|
|
75209
75178
|
fanSpeed: zod.z.string().nullable(),
|
|
75210
75179
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
75211
75180
|
availableFanSpeeds: zod.z.array(zod.z.string()),
|
|
75212
75181
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
75213
|
-
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
75182
|
+
progressPercent: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
75214
75183
|
/** Current error code (0 / null = no error). */
|
|
75215
|
-
errorCode: zod.z.number().nullable(),
|
|
75184
|
+
errorCode: zod.z.number().nullable().meta(readingMeta("none")),
|
|
75216
75185
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
75217
75186
|
errorLabel: zod.z.string().nullable(),
|
|
75218
75187
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -75308,7 +75277,7 @@ var ValveStatusSchema = zod.z.object({
|
|
|
75308
75277
|
state: ValveStateSchema,
|
|
75309
75278
|
/** 0 = fully closed, 100 = fully open. Null when the device has no
|
|
75310
75279
|
* intermediate position surface. */
|
|
75311
|
-
position: zod.z.number().min(0).max(100).nullable(),
|
|
75280
|
+
position: zod.z.number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
75312
75281
|
/** Ms epoch when the slice was last updated. */
|
|
75313
75282
|
lastChangedAt: zod.z.number()
|
|
75314
75283
|
});
|
|
@@ -75416,9 +75385,9 @@ var vibrationCapability = {
|
|
|
75416
75385
|
*/
|
|
75417
75386
|
var WaterHeaterStatusSchema = zod.z.object({
|
|
75418
75387
|
/** Current measured temperature. Null when not reported. */
|
|
75419
|
-
currentTemp: zod.z.number().nullable(),
|
|
75388
|
+
currentTemp: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
75420
75389
|
/** Target temperature setpoint. Null when no setpoint surface. */
|
|
75421
|
-
targetTemp: zod.z.number().nullable(),
|
|
75390
|
+
targetTemp: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
75422
75391
|
/** Active operation mode = HA `state` (`eco` / `electric` / `gas` /
|
|
75423
75392
|
* `heat_pump` / `high_demand` / `performance` / `off`). Null when the
|
|
75424
75393
|
* device reports an unknown state. */
|
|
@@ -75429,9 +75398,9 @@ var WaterHeaterStatusSchema = zod.z.object({
|
|
|
75429
75398
|
* has no away surface. */
|
|
75430
75399
|
away: zod.z.boolean().nullable(),
|
|
75431
75400
|
/** HA `min_temp` attribute. Null when not reported. */
|
|
75432
|
-
minTemp: zod.z.number().nullable(),
|
|
75401
|
+
minTemp: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
75433
75402
|
/** HA `max_temp` attribute. Null when not reported. */
|
|
75434
|
-
maxTemp: zod.z.number().nullable(),
|
|
75403
|
+
maxTemp: zod.z.number().nullable().meta(readingMeta("temperature")),
|
|
75435
75404
|
/** Ms epoch when the slice was last updated. */
|
|
75436
75405
|
lastChangedAt: zod.z.number()
|
|
75437
75406
|
});
|
|
@@ -75516,25 +75485,18 @@ var waterHeaterCapability = {
|
|
|
75516
75485
|
* Forecast deferred — current conditions only for v1.
|
|
75517
75486
|
*/
|
|
75518
75487
|
var WeatherStatusSchema = zod.z.object({
|
|
75519
|
-
/** Verbatim
|
|
75520
|
-
* when no condition has been reported yet. */
|
|
75488
|
+
/** Verbatim condition state (`sunny`, `cloudy`, `rainy`, …). Null when none yet. */
|
|
75521
75489
|
condition: zod.z.string().nullable(),
|
|
75522
|
-
/** Current temperature in
|
|
75523
|
-
temperature: zod.z.number().nullable(),
|
|
75524
|
-
/** Temperature unit string (e.g. `°C` / `°F`). Null when not provided. */
|
|
75525
|
-
temperatureUnit: zod.z.string().nullable(),
|
|
75490
|
+
/** Current temperature in Celsius. Null when not provided or refused. */
|
|
75491
|
+
temperature: zod.z.number().nullable().meta(readingMeta("temperature", { precision: 1 })),
|
|
75526
75492
|
/** Relative humidity (0..100). Null when not provided. */
|
|
75527
|
-
humidity: zod.z.number().min(0).max(100).nullable(),
|
|
75528
|
-
/** Barometric pressure in
|
|
75529
|
-
pressure: zod.z.number().nullable(),
|
|
75530
|
-
/**
|
|
75531
|
-
|
|
75532
|
-
/** Wind speed in the reported unit. Null when not provided. */
|
|
75533
|
-
windSpeed: zod.z.number().nullable(),
|
|
75534
|
-
/** Wind-speed unit string (e.g. `km/h` / `mph`). Null when not provided. */
|
|
75535
|
-
windSpeedUnit: zod.z.string().nullable(),
|
|
75493
|
+
humidity: zod.z.number().min(0).max(100).nullable().meta(readingMeta("humidity")),
|
|
75494
|
+
/** Barometric pressure in hPa. Null when not provided or refused. */
|
|
75495
|
+
pressure: zod.z.number().nullable().meta(readingMeta("pressure")),
|
|
75496
|
+
/** Wind speed in metres per second. Null when not provided or refused. */
|
|
75497
|
+
windSpeed: zod.z.number().nullable().meta(readingMeta("speed")),
|
|
75536
75498
|
/** Wind bearing in degrees (0..360, meteorological). Null when not provided. */
|
|
75537
|
-
windBearing: zod.z.number().nullable(),
|
|
75499
|
+
windBearing: zod.z.number().nullable().meta(readingMeta("angle")),
|
|
75538
75500
|
/** Ms epoch when the slice was last updated. */
|
|
75539
75501
|
lastFetchedAt: zod.z.number()
|
|
75540
75502
|
});
|
|
@@ -75562,12 +75524,12 @@ var weatherCapability = {
|
|
|
75562
75524
|
*/
|
|
75563
75525
|
durability: "session",
|
|
75564
75526
|
/**
|
|
75565
|
-
* History (D850): recorded series.
|
|
75527
|
+
* History (D850): recorded series. Numbers are the quantity base (D944).
|
|
75566
75528
|
*/
|
|
75567
75529
|
history: { fields: {
|
|
75568
75530
|
temperature: {
|
|
75569
75531
|
kind: "gauge",
|
|
75570
|
-
|
|
75532
|
+
unit: "°C",
|
|
75571
75533
|
deadband: .2
|
|
75572
75534
|
},
|
|
75573
75535
|
humidity: {
|
|
@@ -75577,12 +75539,12 @@ var weatherCapability = {
|
|
|
75577
75539
|
},
|
|
75578
75540
|
pressure: {
|
|
75579
75541
|
kind: "gauge",
|
|
75580
|
-
|
|
75542
|
+
unit: "hPa",
|
|
75581
75543
|
deadband: .5
|
|
75582
75544
|
},
|
|
75583
75545
|
windSpeed: {
|
|
75584
75546
|
kind: "gauge",
|
|
75585
|
-
|
|
75547
|
+
unit: "m/s",
|
|
75586
75548
|
deadband: .5
|
|
75587
75549
|
}
|
|
75588
75550
|
} }
|
|
@@ -76793,6 +76755,11 @@ var UNIT_TABLE = {
|
|
|
76793
76755
|
factor: 1609.344,
|
|
76794
76756
|
offset: 0
|
|
76795
76757
|
},
|
|
76758
|
+
"m²": {
|
|
76759
|
+
dimension: "area",
|
|
76760
|
+
factor: 1,
|
|
76761
|
+
offset: 0
|
|
76762
|
+
},
|
|
76796
76763
|
lx: {
|
|
76797
76764
|
dimension: "illuminance",
|
|
76798
76765
|
factor: 1,
|
|
@@ -76897,6 +76864,121 @@ var UNIT_TABLE = {
|
|
|
76897
76864
|
dimension: "percentage",
|
|
76898
76865
|
factor: 1,
|
|
76899
76866
|
offset: 0
|
|
76867
|
+
},
|
|
76868
|
+
L: {
|
|
76869
|
+
dimension: "volume",
|
|
76870
|
+
factor: 1,
|
|
76871
|
+
offset: 0
|
|
76872
|
+
},
|
|
76873
|
+
mL: {
|
|
76874
|
+
dimension: "volume",
|
|
76875
|
+
factor: .001,
|
|
76876
|
+
offset: 0
|
|
76877
|
+
},
|
|
76878
|
+
gal: {
|
|
76879
|
+
dimension: "volume",
|
|
76880
|
+
factor: 3.785411784,
|
|
76881
|
+
offset: 0
|
|
76882
|
+
},
|
|
76883
|
+
s: {
|
|
76884
|
+
dimension: "duration",
|
|
76885
|
+
factor: 1,
|
|
76886
|
+
offset: 0
|
|
76887
|
+
},
|
|
76888
|
+
ms: {
|
|
76889
|
+
dimension: "duration",
|
|
76890
|
+
factor: .001,
|
|
76891
|
+
offset: 0
|
|
76892
|
+
},
|
|
76893
|
+
min: {
|
|
76894
|
+
dimension: "duration",
|
|
76895
|
+
factor: 60,
|
|
76896
|
+
offset: 0
|
|
76897
|
+
},
|
|
76898
|
+
h: {
|
|
76899
|
+
dimension: "duration",
|
|
76900
|
+
factor: 3600,
|
|
76901
|
+
offset: 0
|
|
76902
|
+
},
|
|
76903
|
+
d: {
|
|
76904
|
+
dimension: "duration",
|
|
76905
|
+
factor: 86400,
|
|
76906
|
+
offset: 0
|
|
76907
|
+
},
|
|
76908
|
+
B: {
|
|
76909
|
+
dimension: "information",
|
|
76910
|
+
factor: 1,
|
|
76911
|
+
offset: 0
|
|
76912
|
+
},
|
|
76913
|
+
KiB: {
|
|
76914
|
+
dimension: "information",
|
|
76915
|
+
factor: 1024,
|
|
76916
|
+
offset: 0
|
|
76917
|
+
},
|
|
76918
|
+
MiB: {
|
|
76919
|
+
dimension: "information",
|
|
76920
|
+
factor: 1024 ** 2,
|
|
76921
|
+
offset: 0
|
|
76922
|
+
},
|
|
76923
|
+
GiB: {
|
|
76924
|
+
dimension: "information",
|
|
76925
|
+
factor: 1024 ** 3,
|
|
76926
|
+
offset: 0
|
|
76927
|
+
},
|
|
76928
|
+
TiB: {
|
|
76929
|
+
dimension: "information",
|
|
76930
|
+
factor: 1024 ** 4,
|
|
76931
|
+
offset: 0
|
|
76932
|
+
},
|
|
76933
|
+
kB: {
|
|
76934
|
+
dimension: "information",
|
|
76935
|
+
factor: 1e3,
|
|
76936
|
+
offset: 0
|
|
76937
|
+
},
|
|
76938
|
+
MB: {
|
|
76939
|
+
dimension: "information",
|
|
76940
|
+
factor: 1e6,
|
|
76941
|
+
offset: 0
|
|
76942
|
+
},
|
|
76943
|
+
GB: {
|
|
76944
|
+
dimension: "information",
|
|
76945
|
+
factor: 1e9,
|
|
76946
|
+
offset: 0
|
|
76947
|
+
},
|
|
76948
|
+
"°": {
|
|
76949
|
+
dimension: "angle",
|
|
76950
|
+
factor: 1,
|
|
76951
|
+
offset: 0
|
|
76952
|
+
},
|
|
76953
|
+
dBFS: {
|
|
76954
|
+
dimension: "sound-level",
|
|
76955
|
+
factor: 1,
|
|
76956
|
+
offset: 0
|
|
76957
|
+
},
|
|
76958
|
+
dBm: {
|
|
76959
|
+
dimension: "signal-level",
|
|
76960
|
+
factor: 1,
|
|
76961
|
+
offset: 0
|
|
76962
|
+
},
|
|
76963
|
+
mired: {
|
|
76964
|
+
dimension: "colour-temperature",
|
|
76965
|
+
factor: 1,
|
|
76966
|
+
offset: 0
|
|
76967
|
+
},
|
|
76968
|
+
kbps: {
|
|
76969
|
+
dimension: "bitrate",
|
|
76970
|
+
factor: 1,
|
|
76971
|
+
offset: 0
|
|
76972
|
+
},
|
|
76973
|
+
Mbps: {
|
|
76974
|
+
dimension: "bitrate",
|
|
76975
|
+
factor: 1e3,
|
|
76976
|
+
offset: 0
|
|
76977
|
+
},
|
|
76978
|
+
fps: {
|
|
76979
|
+
dimension: "rate",
|
|
76980
|
+
factor: 1,
|
|
76981
|
+
offset: 0
|
|
76900
76982
|
}
|
|
76901
76983
|
};
|
|
76902
76984
|
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
@@ -91519,7 +91601,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
91519
91601
|
field: "value",
|
|
91520
91602
|
quantity: t("the reading", "il valore"),
|
|
91521
91603
|
label: t("Reading", "Valore"),
|
|
91522
|
-
unitField: "unit",
|
|
91523
91604
|
icon: "gauge"
|
|
91524
91605
|
}]
|
|
91525
91606
|
},
|
|
@@ -91655,7 +91736,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
91655
91736
|
field: "temperature",
|
|
91656
91737
|
quantity: t("the outdoor temperature", "la temperatura esterna"),
|
|
91657
91738
|
label: t("Temperature", "Temperatura"),
|
|
91658
|
-
|
|
91739
|
+
unit: "°C",
|
|
91659
91740
|
icon: "thermometer"
|
|
91660
91741
|
},
|
|
91661
91742
|
{
|
|
@@ -91671,7 +91752,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
91671
91752
|
field: "windSpeed",
|
|
91672
91753
|
quantity: t("the wind speed", "la velocità del vento"),
|
|
91673
91754
|
label: t("Wind", "Vento"),
|
|
91674
|
-
|
|
91755
|
+
unit: "m/s",
|
|
91675
91756
|
icon: "wind"
|
|
91676
91757
|
},
|
|
91677
91758
|
{
|
|
@@ -91679,7 +91760,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
91679
91760
|
field: "pressure",
|
|
91680
91761
|
quantity: t("the air pressure", "la pressione atmosferica"),
|
|
91681
91762
|
label: t("Pressure", "Pressione"),
|
|
91682
|
-
|
|
91763
|
+
unit: "hPa",
|
|
91683
91764
|
icon: "gauge"
|
|
91684
91765
|
}
|
|
91685
91766
|
]
|
|
@@ -95347,7 +95428,7 @@ var SESSION_ONLY_POLICY = {
|
|
|
95347
95428
|
};
|
|
95348
95429
|
/**
|
|
95349
95430
|
* Cap history catalog, projected from every `*.cap.ts` `history` block.
|
|
95350
|
-
* 41 caps with series (
|
|
95431
|
+
* 41 caps with series (75 series), 30 caps answered `'none'`.
|
|
95351
95432
|
* Field keys are `runtimeState` paths (`a.b` into fixed objects only).
|
|
95352
95433
|
*/
|
|
95353
95434
|
var HISTORY_CATALOG = {
|
|
@@ -95364,12 +95445,12 @@ var HISTORY_CATALOG = {
|
|
|
95364
95445
|
},
|
|
95365
95446
|
"pm25": {
|
|
95366
95447
|
kind: "gauge",
|
|
95367
|
-
unit: "
|
|
95448
|
+
unit: "µg/m³",
|
|
95368
95449
|
deadband: 1
|
|
95369
95450
|
},
|
|
95370
95451
|
"pm10": {
|
|
95371
95452
|
kind: "gauge",
|
|
95372
|
-
unit: "
|
|
95453
|
+
unit: "µg/m³",
|
|
95373
95454
|
deadband: 1
|
|
95374
95455
|
},
|
|
95375
95456
|
"aqi": {
|
|
@@ -95399,10 +95480,16 @@ var HISTORY_CATALOG = {
|
|
|
95399
95480
|
deadbandPct: 10,
|
|
95400
95481
|
minIntervalMs: 6e4
|
|
95401
95482
|
} },
|
|
95402
|
-
"battery": {
|
|
95403
|
-
|
|
95404
|
-
|
|
95405
|
-
|
|
95483
|
+
"battery": {
|
|
95484
|
+
"percentage": {
|
|
95485
|
+
kind: "gauge",
|
|
95486
|
+
unit: "%"
|
|
95487
|
+
},
|
|
95488
|
+
"volts": {
|
|
95489
|
+
kind: "gauge",
|
|
95490
|
+
unit: "V"
|
|
95491
|
+
}
|
|
95492
|
+
},
|
|
95406
95493
|
"binary": { "on": { kind: "boolean" } },
|
|
95407
95494
|
"brightness": { "percentage": {
|
|
95408
95495
|
kind: "gauge",
|
|
@@ -95486,7 +95573,7 @@ var HISTORY_CATALOG = {
|
|
|
95486
95573
|
},
|
|
95487
95574
|
"enum-sensor": { "value": {
|
|
95488
95575
|
kind: "enum",
|
|
95489
|
-
skipWhenSet: "
|
|
95576
|
+
skipWhenSet: "timestamp"
|
|
95490
95577
|
} },
|
|
95491
95578
|
"fan-control": {
|
|
95492
95579
|
"percentage": {
|
|
@@ -95559,7 +95646,6 @@ var HISTORY_CATALOG = {
|
|
|
95559
95646
|
},
|
|
95560
95647
|
"numeric-sensor": { "value": {
|
|
95561
95648
|
kind: "gauge",
|
|
95562
|
-
unitFrom: "unit",
|
|
95563
95649
|
minIntervalMs: 3e4
|
|
95564
95650
|
} },
|
|
95565
95651
|
"pet-feeder": {
|
|
@@ -95573,7 +95659,7 @@ var HISTORY_CATALOG = {
|
|
|
95573
95659
|
},
|
|
95574
95660
|
"desiccantLeftDays": {
|
|
95575
95661
|
kind: "gauge",
|
|
95576
|
-
unit: "
|
|
95662
|
+
unit: "s"
|
|
95577
95663
|
}
|
|
95578
95664
|
},
|
|
95579
95665
|
"power-meter": {
|
|
@@ -95677,7 +95763,7 @@ var HISTORY_CATALOG = {
|
|
|
95677
95763
|
"weather": {
|
|
95678
95764
|
"temperature": {
|
|
95679
95765
|
kind: "gauge",
|
|
95680
|
-
|
|
95766
|
+
unit: "°C",
|
|
95681
95767
|
deadband: .2
|
|
95682
95768
|
},
|
|
95683
95769
|
"humidity": {
|
|
@@ -95687,12 +95773,12 @@ var HISTORY_CATALOG = {
|
|
|
95687
95773
|
},
|
|
95688
95774
|
"pressure": {
|
|
95689
95775
|
kind: "gauge",
|
|
95690
|
-
|
|
95776
|
+
unit: "hPa",
|
|
95691
95777
|
deadband: .5
|
|
95692
95778
|
},
|
|
95693
95779
|
"windSpeed": {
|
|
95694
95780
|
kind: "gauge",
|
|
95695
|
-
|
|
95781
|
+
unit: "m/s",
|
|
95696
95782
|
deadband: .5
|
|
95697
95783
|
}
|
|
95698
95784
|
}
|
|
@@ -95726,7 +95812,6 @@ var HISTORY_ITEM_CATALOG = { "consumables": {
|
|
|
95726
95812
|
},
|
|
95727
95813
|
"remaining.value": {
|
|
95728
95814
|
kind: "gauge",
|
|
95729
|
-
unitFrom: "remaining.unit",
|
|
95730
95815
|
deadband: 1,
|
|
95731
95816
|
displayName: "Remaining"
|
|
95732
95817
|
}
|
|
@@ -98620,6 +98705,12 @@ Object.defineProperty(exports, "historyItemFieldPath", {
|
|
|
98620
98705
|
return historyItemFieldPath;
|
|
98621
98706
|
}
|
|
98622
98707
|
});
|
|
98708
|
+
Object.defineProperty(exports, "historyUnitFor", {
|
|
98709
|
+
enumerable: true,
|
|
98710
|
+
get: function() {
|
|
98711
|
+
return historyUnitFor;
|
|
98712
|
+
}
|
|
98713
|
+
});
|
|
98623
98714
|
Object.defineProperty(exports, "hydrateSchema", {
|
|
98624
98715
|
enumerable: true,
|
|
98625
98716
|
get: function() {
|
|
@@ -98704,6 +98795,12 @@ Object.defineProperty(exports, "isObjectInput", {
|
|
|
98704
98795
|
return isObjectInput;
|
|
98705
98796
|
}
|
|
98706
98797
|
});
|
|
98798
|
+
Object.defineProperty(exports, "isReadingQuantity", {
|
|
98799
|
+
enumerable: true,
|
|
98800
|
+
get: function() {
|
|
98801
|
+
return isReadingQuantity;
|
|
98802
|
+
}
|
|
98803
|
+
});
|
|
98707
98804
|
Object.defineProperty(exports, "isSecretClear", {
|
|
98708
98805
|
enumerable: true,
|
|
98709
98806
|
get: function() {
|