@camstack/addon-provider-homeassistant 1.2.633 → 1.2.635
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/CHANGELOG.md +12 -0
- package/dist/addon.js +83 -60
- package/dist/addon.mjs +83 -60
- package/dist/{dist-BVojc0hA.mjs → dist-CYl0u8cF.mjs} +1038 -247
- package/dist/{dist-DVkAN1CW.js → dist-C_PMvyYa.js} +1038 -247
- package/dist/ha-export/ha-export.addon.js +28 -24
- package/dist/ha-export/ha-export.addon.mjs +28 -24
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region ../types/dist/event-category-
|
|
1
|
+
//#region ../types/dist/event-category-DmZDPDf_.mjs
|
|
2
2
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
3
3
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4
4
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -625,7 +625,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
625
625
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
626
626
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
627
627
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
628
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
628
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
629
629
|
*/
|
|
630
630
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
631
631
|
/**
|
|
@@ -763,6 +763,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
763
763
|
*/
|
|
764
764
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
765
765
|
/**
|
|
766
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
767
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
768
|
+
*/
|
|
769
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
770
|
+
/**
|
|
766
771
|
* Progress update from a running model conversion job.
|
|
767
772
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
768
773
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -5574,7 +5579,7 @@ var ZodIssueCode = {
|
|
|
5574
5579
|
var ZodFirstPartyTypeKind;
|
|
5575
5580
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5576
5581
|
//#endregion
|
|
5577
|
-
//#region ../types/dist/sleep
|
|
5582
|
+
//#region ../types/dist/sleep-BAvUCi_2.mjs
|
|
5578
5583
|
/**
|
|
5579
5584
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5580
5585
|
* window to float samples (D455).
|
|
@@ -8944,6 +8949,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8944
8949
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8945
8950
|
var CAP_NAMES = Object.freeze([
|
|
8946
8951
|
"accessories",
|
|
8952
|
+
"action-source",
|
|
8953
|
+
"actions",
|
|
8947
8954
|
"addon-pages",
|
|
8948
8955
|
"addon-pages-source",
|
|
8949
8956
|
"addon-routes",
|
|
@@ -9027,6 +9034,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9027
9034
|
"image-settings",
|
|
9028
9035
|
"integrations",
|
|
9029
9036
|
"intercom",
|
|
9037
|
+
"ir-transmitter",
|
|
9030
9038
|
"keychain",
|
|
9031
9039
|
"keychain-admin",
|
|
9032
9040
|
"lawn-mower-control",
|
|
@@ -9132,11 +9140,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
9132
9140
|
Object.freeze({
|
|
9133
9141
|
"air-quality-sensor": [
|
|
9134
9142
|
{
|
|
9135
|
-
"path": "
|
|
9143
|
+
"path": "co2",
|
|
9136
9144
|
"valueType": "number"
|
|
9137
9145
|
},
|
|
9138
9146
|
{
|
|
9139
|
-
"path": "
|
|
9147
|
+
"path": "voc",
|
|
9140
9148
|
"valueType": "number"
|
|
9141
9149
|
},
|
|
9142
9150
|
{
|
|
@@ -9186,7 +9194,7 @@ Object.freeze({
|
|
|
9186
9194
|
}
|
|
9187
9195
|
],
|
|
9188
9196
|
"ambient-light-sensor": [{
|
|
9189
|
-
"path": "
|
|
9197
|
+
"path": "illuminance",
|
|
9190
9198
|
"valueType": "number"
|
|
9191
9199
|
}],
|
|
9192
9200
|
"audio-metrics": [
|
|
@@ -9247,7 +9255,7 @@ Object.freeze({
|
|
|
9247
9255
|
],
|
|
9248
9256
|
"battery": [
|
|
9249
9257
|
{
|
|
9250
|
-
"path": "
|
|
9258
|
+
"path": "level",
|
|
9251
9259
|
"valueType": "number"
|
|
9252
9260
|
},
|
|
9253
9261
|
{
|
|
@@ -9269,7 +9277,7 @@ Object.freeze({
|
|
|
9269
9277
|
"valueType": "number"
|
|
9270
9278
|
},
|
|
9271
9279
|
{
|
|
9272
|
-
"path": "
|
|
9280
|
+
"path": "voltage",
|
|
9273
9281
|
"valueType": "number"
|
|
9274
9282
|
},
|
|
9275
9283
|
{
|
|
@@ -9290,7 +9298,7 @@ Object.freeze({
|
|
|
9290
9298
|
"valueType": "boolean"
|
|
9291
9299
|
}],
|
|
9292
9300
|
"brightness": [{
|
|
9293
|
-
"path": "
|
|
9301
|
+
"path": "level",
|
|
9294
9302
|
"valueType": "number"
|
|
9295
9303
|
}],
|
|
9296
9304
|
"broker": [{
|
|
@@ -9491,7 +9499,7 @@ Object.freeze({
|
|
|
9491
9499
|
"valueType": "number"
|
|
9492
9500
|
},
|
|
9493
9501
|
{
|
|
9494
|
-
"path": "
|
|
9502
|
+
"path": "colorTemperature",
|
|
9495
9503
|
"valueType": "number"
|
|
9496
9504
|
}
|
|
9497
9505
|
],
|
|
@@ -9670,15 +9678,15 @@ Object.freeze({
|
|
|
9670
9678
|
"valueType": "string"
|
|
9671
9679
|
},
|
|
9672
9680
|
{
|
|
9673
|
-
"path": "
|
|
9681
|
+
"path": "remaining",
|
|
9674
9682
|
"valueType": "number"
|
|
9675
9683
|
},
|
|
9676
9684
|
{
|
|
9677
|
-
"path": "
|
|
9685
|
+
"path": "delayedStart",
|
|
9678
9686
|
"valueType": "number"
|
|
9679
9687
|
},
|
|
9680
9688
|
{
|
|
9681
|
-
"path": "
|
|
9689
|
+
"path": "progress",
|
|
9682
9690
|
"valueType": "number"
|
|
9683
9691
|
},
|
|
9684
9692
|
{
|
|
@@ -9792,7 +9800,7 @@ Object.freeze({
|
|
|
9792
9800
|
],
|
|
9793
9801
|
"fan-control": [
|
|
9794
9802
|
{
|
|
9795
|
-
"path": "
|
|
9803
|
+
"path": "speed",
|
|
9796
9804
|
"valueType": "number"
|
|
9797
9805
|
},
|
|
9798
9806
|
{
|
|
@@ -9892,7 +9900,7 @@ Object.freeze({
|
|
|
9892
9900
|
}
|
|
9893
9901
|
],
|
|
9894
9902
|
"humidity-sensor": [{
|
|
9895
|
-
"path": "
|
|
9903
|
+
"path": "humidity",
|
|
9896
9904
|
"valueType": "number"
|
|
9897
9905
|
}],
|
|
9898
9906
|
"image": [{
|
|
@@ -10002,7 +10010,7 @@ Object.freeze({
|
|
|
10002
10010
|
"valueType": "number"
|
|
10003
10011
|
},
|
|
10004
10012
|
{
|
|
10005
|
-
"path": "
|
|
10013
|
+
"path": "progress",
|
|
10006
10014
|
"valueType": "number"
|
|
10007
10015
|
},
|
|
10008
10016
|
{
|
|
@@ -10081,11 +10089,11 @@ Object.freeze({
|
|
|
10081
10089
|
"valueType": "string"
|
|
10082
10090
|
},
|
|
10083
10091
|
{
|
|
10084
|
-
"path": "
|
|
10092
|
+
"path": "position",
|
|
10085
10093
|
"valueType": "number"
|
|
10086
10094
|
},
|
|
10087
10095
|
{
|
|
10088
|
-
"path": "
|
|
10096
|
+
"path": "duration",
|
|
10089
10097
|
"valueType": "number"
|
|
10090
10098
|
},
|
|
10091
10099
|
{
|
|
@@ -10187,11 +10195,11 @@ Object.freeze({
|
|
|
10187
10195
|
]
|
|
10188
10196
|
},
|
|
10189
10197
|
{
|
|
10190
|
-
"path": "
|
|
10198
|
+
"path": "signal",
|
|
10191
10199
|
"valueType": "number"
|
|
10192
10200
|
},
|
|
10193
10201
|
{
|
|
10194
|
-
"path": "
|
|
10202
|
+
"path": "rssi",
|
|
10195
10203
|
"valueType": "number"
|
|
10196
10204
|
},
|
|
10197
10205
|
{
|
|
@@ -10246,6 +10254,18 @@ Object.freeze({
|
|
|
10246
10254
|
"path": "foodLevel",
|
|
10247
10255
|
"valueType": "number"
|
|
10248
10256
|
},
|
|
10257
|
+
{
|
|
10258
|
+
"path": "bowlFood",
|
|
10259
|
+
"valueType": "number"
|
|
10260
|
+
},
|
|
10261
|
+
{
|
|
10262
|
+
"path": "eating",
|
|
10263
|
+
"valueType": "boolean"
|
|
10264
|
+
},
|
|
10265
|
+
{
|
|
10266
|
+
"path": "supportsMarkRefilled",
|
|
10267
|
+
"valueType": "boolean"
|
|
10268
|
+
},
|
|
10249
10269
|
{
|
|
10250
10270
|
"path": "food1",
|
|
10251
10271
|
"valueType": "number"
|
|
@@ -10262,6 +10282,11 @@ Object.freeze({
|
|
|
10262
10282
|
"path": "batteryPower",
|
|
10263
10283
|
"valueType": "number"
|
|
10264
10284
|
},
|
|
10285
|
+
{
|
|
10286
|
+
"path": "powerSource",
|
|
10287
|
+
"valueType": "enum",
|
|
10288
|
+
"enumValues": ["mains", "battery"]
|
|
10289
|
+
},
|
|
10265
10290
|
{
|
|
10266
10291
|
"path": "desiccantLeftDays",
|
|
10267
10292
|
"valueType": "number"
|
|
@@ -10310,23 +10335,23 @@ Object.freeze({
|
|
|
10310
10335
|
],
|
|
10311
10336
|
"power-meter": [
|
|
10312
10337
|
{
|
|
10313
|
-
"path": "
|
|
10338
|
+
"path": "power",
|
|
10314
10339
|
"valueType": "number"
|
|
10315
10340
|
},
|
|
10316
10341
|
{
|
|
10317
|
-
"path": "
|
|
10342
|
+
"path": "energy",
|
|
10318
10343
|
"valueType": "number"
|
|
10319
10344
|
},
|
|
10320
10345
|
{
|
|
10321
|
-
"path": "
|
|
10346
|
+
"path": "voltage",
|
|
10322
10347
|
"valueType": "number"
|
|
10323
10348
|
},
|
|
10324
10349
|
{
|
|
10325
|
-
"path": "
|
|
10350
|
+
"path": "current",
|
|
10326
10351
|
"valueType": "number"
|
|
10327
10352
|
},
|
|
10328
10353
|
{
|
|
10329
|
-
"path": "
|
|
10354
|
+
"path": "apparentPower",
|
|
10330
10355
|
"valueType": "number"
|
|
10331
10356
|
},
|
|
10332
10357
|
{
|
|
@@ -10354,14 +10379,10 @@ Object.freeze({
|
|
|
10354
10379
|
{
|
|
10355
10380
|
"path": "gps.accuracyMeters",
|
|
10356
10381
|
"valueType": "number"
|
|
10357
|
-
},
|
|
10358
|
-
{
|
|
10359
|
-
"path": "batteryPercent",
|
|
10360
|
-
"valueType": "number"
|
|
10361
10382
|
}
|
|
10362
10383
|
],
|
|
10363
10384
|
"pressure-sensor": [{
|
|
10364
|
-
"path": "
|
|
10385
|
+
"path": "pressure",
|
|
10365
10386
|
"valueType": "number"
|
|
10366
10387
|
}],
|
|
10367
10388
|
"privacy-mask": [{
|
|
@@ -10675,7 +10696,7 @@ Object.freeze({
|
|
|
10675
10696
|
"valueType": "boolean"
|
|
10676
10697
|
}],
|
|
10677
10698
|
"temperature-sensor": [{
|
|
10678
|
-
"path": "
|
|
10699
|
+
"path": "temperature",
|
|
10679
10700
|
"valueType": "number"
|
|
10680
10701
|
}],
|
|
10681
10702
|
"update": [
|
|
@@ -10723,7 +10744,7 @@ Object.freeze({
|
|
|
10723
10744
|
"valueType": "string"
|
|
10724
10745
|
},
|
|
10725
10746
|
{
|
|
10726
|
-
"path": "
|
|
10747
|
+
"path": "progress",
|
|
10727
10748
|
"valueType": "number"
|
|
10728
10749
|
},
|
|
10729
10750
|
{
|
|
@@ -10849,7 +10870,7 @@ object({
|
|
|
10849
10870
|
params: record(string(), union([string(), number()])).optional()
|
|
10850
10871
|
});
|
|
10851
10872
|
//#endregion
|
|
10852
|
-
//#region ../types/dist/err-msg-
|
|
10873
|
+
//#region ../types/dist/err-msg-BCdlR2Li.mjs
|
|
10853
10874
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
10854
10875
|
DeviceType["Camera"] = "camera";
|
|
10855
10876
|
DeviceType["Hub"] = "hub";
|
|
@@ -11195,6 +11216,9 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11195
11216
|
/** Fallback when the notifier service name doesn't match a known
|
|
11196
11217
|
* pattern. */
|
|
11197
11218
|
DeviceRole["GenericNotifier"] = "generic-notifier";
|
|
11219
|
+
/** Emits a pulse train (infrared or RF) on request — the `ir-transmitter`
|
|
11220
|
+
* cap. A `DeviceType.Generic` device. */
|
|
11221
|
+
DeviceRole["IrTransmitter"] = "ir-transmitter";
|
|
11198
11222
|
return DeviceRole;
|
|
11199
11223
|
}({});
|
|
11200
11224
|
/**
|
|
@@ -11208,7 +11232,7 @@ function errMsg(err) {
|
|
|
11208
11232
|
return String(err);
|
|
11209
11233
|
}
|
|
11210
11234
|
//#endregion
|
|
11211
|
-
//#region ../types/dist/composition-
|
|
11235
|
+
//#region ../types/dist/composition-DpFv_J6D.mjs
|
|
11212
11236
|
/**
|
|
11213
11237
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11214
11238
|
*
|
|
@@ -15872,6 +15896,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
15872
15896
|
array(union([string(), number()]))
|
|
15873
15897
|
])
|
|
15874
15898
|
});
|
|
15899
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
15900
|
+
kind: literal("stationary-present"),
|
|
15901
|
+
deviceId: number().int().nonnegative(),
|
|
15902
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
15903
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15904
|
+
/** The parked object must be in at least one of these zones. */
|
|
15905
|
+
zones: array(string().min(1)).min(1).optional()
|
|
15906
|
+
});
|
|
15875
15907
|
/**
|
|
15876
15908
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
15877
15909
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -15905,7 +15937,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
15905
15937
|
child: AutomationConditionSchema
|
|
15906
15938
|
}),
|
|
15907
15939
|
AutomationConditionLeafSchema,
|
|
15908
|
-
AutomationConditionExpressionSchema
|
|
15940
|
+
AutomationConditionExpressionSchema,
|
|
15941
|
+
AutomationConditionStationaryPresentSchema
|
|
15909
15942
|
]));
|
|
15910
15943
|
/**
|
|
15911
15944
|
* What starts a run.
|
|
@@ -15946,7 +15979,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15946
15979
|
kind: literal("schedule"),
|
|
15947
15980
|
cron: string().min(1).max(120)
|
|
15948
15981
|
}),
|
|
15949
|
-
object({ kind: literal("manual") })
|
|
15982
|
+
object({ kind: literal("manual") }),
|
|
15983
|
+
object({
|
|
15984
|
+
kind: literal("detection"),
|
|
15985
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
15986
|
+
* matches every raw class that maps to it; any other name matches
|
|
15987
|
+
* exactly. */
|
|
15988
|
+
classes: array(string().min(1)).min(1),
|
|
15989
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15990
|
+
/** The track must have visited at least one of these zones. */
|
|
15991
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15992
|
+
/** Best-so-far confidence the track must reach. */
|
|
15993
|
+
minScore: number().min(0).max(1).optional()
|
|
15994
|
+
}),
|
|
15995
|
+
object({
|
|
15996
|
+
kind: literal("stationary"),
|
|
15997
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15998
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
15999
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16000
|
+
/** The parked object must be in at least one of these zones. */
|
|
16001
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16002
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
16003
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
16004
|
+
phase: _enum(["appeared", "departed"])
|
|
16005
|
+
}),
|
|
16006
|
+
object({
|
|
16007
|
+
kind: literal("interval"),
|
|
16008
|
+
minutes: number().int().min(1).max(1440)
|
|
16009
|
+
})
|
|
15950
16010
|
]);
|
|
15951
16011
|
/**
|
|
15952
16012
|
* One action step.
|
|
@@ -15966,28 +16026,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15966
16026
|
* is called. The runner still receives a number and is untouched; the
|
|
15967
16027
|
* resolution is the recipe's job, not the runner's.
|
|
15968
16028
|
*/
|
|
16029
|
+
var AutomationWaitStepSchema = object({
|
|
16030
|
+
kind: literal("wait"),
|
|
16031
|
+
seconds: number().min(0).max(300)
|
|
16032
|
+
});
|
|
16033
|
+
var AutomationCapStepSchema = object({
|
|
16034
|
+
kind: literal("cap"),
|
|
16035
|
+
/**
|
|
16036
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
16037
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
16038
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
16039
|
+
*/
|
|
16040
|
+
deviceId: union([
|
|
16041
|
+
number().int(),
|
|
16042
|
+
array(number().int()).min(1),
|
|
16043
|
+
object({ $var: string().min(1) })
|
|
16044
|
+
]),
|
|
16045
|
+
cap: string().min(1),
|
|
16046
|
+
method: string().min(1),
|
|
16047
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16048
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16049
|
+
* the expression leaf. */
|
|
16050
|
+
args: record(string(), unknown()).optional()
|
|
16051
|
+
});
|
|
16052
|
+
/**
|
|
16053
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
16054
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
16055
|
+
*/
|
|
16056
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
15969
16057
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
16058
|
+
AutomationWaitStepSchema,
|
|
16059
|
+
AutomationCapStepSchema,
|
|
15970
16060
|
object({
|
|
15971
|
-
kind: literal("
|
|
15972
|
-
|
|
15973
|
-
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
*/
|
|
15981
|
-
deviceId: union([
|
|
15982
|
-
number().int(),
|
|
15983
|
-
array(number().int()).min(1),
|
|
15984
|
-
object({ $var: string().min(1) })
|
|
15985
|
-
]),
|
|
15986
|
-
cap: string().min(1),
|
|
15987
|
-
method: string().min(1),
|
|
15988
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
15989
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
15990
|
-
args: record(string(), unknown()).optional()
|
|
16061
|
+
kind: literal("action"),
|
|
16062
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
16063
|
+
actionId: string().min(1),
|
|
16064
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
16065
|
+
variables: record(string(), union([
|
|
16066
|
+
string(),
|
|
16067
|
+
number(),
|
|
16068
|
+
boolean()
|
|
16069
|
+
])).optional()
|
|
15991
16070
|
}),
|
|
15992
16071
|
object({
|
|
15993
16072
|
kind: literal("code"),
|
|
@@ -15996,10 +16075,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
15996
16075
|
code: string().min(1).max(2e4)
|
|
15997
16076
|
})
|
|
15998
16077
|
]);
|
|
16078
|
+
/**
|
|
16079
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
16080
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
16081
|
+
* actions. Absent means `single`.
|
|
16082
|
+
*
|
|
16083
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
16084
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
16085
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
16086
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
16087
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
16088
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
16089
|
+
* wait, never the single/queued limits.
|
|
16090
|
+
*/
|
|
16091
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
16092
|
+
object({ mode: literal("single") }),
|
|
16093
|
+
object({ mode: literal("restart") }),
|
|
16094
|
+
object({
|
|
16095
|
+
mode: literal("queued"),
|
|
16096
|
+
max: number().int().min(1).max(10)
|
|
16097
|
+
}),
|
|
16098
|
+
object({
|
|
16099
|
+
mode: literal("parallel"),
|
|
16100
|
+
max: number().int().min(1).max(10)
|
|
16101
|
+
}),
|
|
16102
|
+
object({
|
|
16103
|
+
mode: literal("cooldown"),
|
|
16104
|
+
minutes: number().int().min(1).max(1440)
|
|
16105
|
+
})
|
|
16106
|
+
]);
|
|
15999
16107
|
var AutomationRecipeSchema = object({
|
|
16000
16108
|
triggers: array(AutomationTriggerSchema),
|
|
16001
16109
|
conditions: AutomationConditionSchema.optional(),
|
|
16002
|
-
actions: array(AutomationActionSchema)
|
|
16110
|
+
actions: array(AutomationActionSchema),
|
|
16111
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
16112
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
16113
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
16114
|
+
});
|
|
16115
|
+
new Set([
|
|
16116
|
+
{
|
|
16117
|
+
id: "person",
|
|
16118
|
+
name: "Person"
|
|
16119
|
+
},
|
|
16120
|
+
{
|
|
16121
|
+
id: "vehicle",
|
|
16122
|
+
name: "Vehicle"
|
|
16123
|
+
},
|
|
16124
|
+
{
|
|
16125
|
+
id: "animal",
|
|
16126
|
+
name: "Animal"
|
|
16127
|
+
},
|
|
16128
|
+
{
|
|
16129
|
+
id: "package",
|
|
16130
|
+
name: "Package"
|
|
16131
|
+
}
|
|
16132
|
+
].map((l) => l.id));
|
|
16133
|
+
var COCO_TO_MACRO = {
|
|
16134
|
+
mapping: {
|
|
16135
|
+
person: "person",
|
|
16136
|
+
bicycle: "vehicle",
|
|
16137
|
+
car: "vehicle",
|
|
16138
|
+
motorcycle: "vehicle",
|
|
16139
|
+
airplane: "vehicle",
|
|
16140
|
+
bus: "vehicle",
|
|
16141
|
+
train: "vehicle",
|
|
16142
|
+
truck: "vehicle",
|
|
16143
|
+
boat: "vehicle",
|
|
16144
|
+
bird: "animal",
|
|
16145
|
+
cat: "animal",
|
|
16146
|
+
dog: "animal",
|
|
16147
|
+
horse: "animal",
|
|
16148
|
+
sheep: "animal",
|
|
16149
|
+
cow: "animal",
|
|
16150
|
+
elephant: "animal",
|
|
16151
|
+
bear: "animal",
|
|
16152
|
+
zebra: "animal",
|
|
16153
|
+
giraffe: "animal",
|
|
16154
|
+
suitcase: "package",
|
|
16155
|
+
backpack: "package",
|
|
16156
|
+
handbag: "package"
|
|
16157
|
+
},
|
|
16158
|
+
preserveOriginal: false
|
|
16159
|
+
};
|
|
16160
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
16161
|
+
/**
|
|
16162
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
16163
|
+
* so the editor can paint every block green or red with its reason.
|
|
16164
|
+
*
|
|
16165
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
16166
|
+
* every condition node (containers and leaves, including the ones a
|
|
16167
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
16168
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
16169
|
+
* for an Action run). Skipped
|
|
16170
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
16171
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
16172
|
+
*
|
|
16173
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
16174
|
+
* vocabulary so an Action run records the same step shape.
|
|
16175
|
+
*/
|
|
16176
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
16177
|
+
var TraceValueSchema = union([
|
|
16178
|
+
string(),
|
|
16179
|
+
number(),
|
|
16180
|
+
boolean(),
|
|
16181
|
+
_null(),
|
|
16182
|
+
array(union([string(), number()]))
|
|
16183
|
+
]);
|
|
16184
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
16185
|
+
"ran",
|
|
16186
|
+
"skipped-trigger",
|
|
16187
|
+
"skipped-conditions",
|
|
16188
|
+
"skipped-cooldown",
|
|
16189
|
+
"skipped-overlap",
|
|
16190
|
+
"failed",
|
|
16191
|
+
"aborted"
|
|
16192
|
+
]);
|
|
16193
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
16194
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
16195
|
+
"pass",
|
|
16196
|
+
"fail",
|
|
16197
|
+
"not-evaluated"
|
|
16198
|
+
]);
|
|
16199
|
+
var AutomationTriggerTraceSchema = object({
|
|
16200
|
+
kind: string().min(1),
|
|
16201
|
+
outcome: _enum(["pass", "fail"]),
|
|
16202
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
16203
|
+
reason: string(),
|
|
16204
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
16205
|
+
vars: record(string(), TraceValueSchema)
|
|
16206
|
+
});
|
|
16207
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
16208
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
16209
|
+
path: string().min(1),
|
|
16210
|
+
kind: _enum([
|
|
16211
|
+
"all",
|
|
16212
|
+
"any",
|
|
16213
|
+
"not",
|
|
16214
|
+
"condition",
|
|
16215
|
+
"expression",
|
|
16216
|
+
"stationary-present"
|
|
16217
|
+
]),
|
|
16218
|
+
outcome: TraceNodeOutcomeSchema,
|
|
16219
|
+
reason: string(),
|
|
16220
|
+
deviceId: number().int().optional(),
|
|
16221
|
+
cap: string().optional(),
|
|
16222
|
+
fieldPath: string().optional(),
|
|
16223
|
+
operator: string().optional(),
|
|
16224
|
+
expected: TraceValueSchema.optional(),
|
|
16225
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
16226
|
+
observed: TraceValueSchema.optional()
|
|
16227
|
+
});
|
|
16228
|
+
var AutomationRunVerdictSchema = object({
|
|
16229
|
+
mode: AutomationRunModeSchema,
|
|
16230
|
+
decision: _enum([
|
|
16231
|
+
"run",
|
|
16232
|
+
"queued",
|
|
16233
|
+
"restart",
|
|
16234
|
+
"drop",
|
|
16235
|
+
"cooldown",
|
|
16236
|
+
"bypass"
|
|
16237
|
+
]),
|
|
16238
|
+
reason: string()
|
|
16239
|
+
});
|
|
16240
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
16241
|
+
var AutomationStepTraceSchema = object({
|
|
16242
|
+
/** `actions.<i>` */
|
|
16243
|
+
path: string().min(1),
|
|
16244
|
+
kind: string().min(1),
|
|
16245
|
+
cap: string().optional(),
|
|
16246
|
+
method: string().optional(),
|
|
16247
|
+
deviceId: number().int().optional(),
|
|
16248
|
+
startedAt: number().optional(),
|
|
16249
|
+
endedAt: number().optional(),
|
|
16250
|
+
outcome: _enum([
|
|
16251
|
+
"ok",
|
|
16252
|
+
"error",
|
|
16253
|
+
"not-run"
|
|
16254
|
+
]),
|
|
16255
|
+
message: string().optional()
|
|
16256
|
+
});
|
|
16257
|
+
var AutomationRunTraceSchema = object({
|
|
16258
|
+
runId: string().min(1),
|
|
16259
|
+
startedAt: number(),
|
|
16260
|
+
endedAt: number(),
|
|
16261
|
+
trigger: AutomationTriggerTraceSchema,
|
|
16262
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
16263
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
16264
|
+
steps: array(AutomationStepTraceSchema),
|
|
16265
|
+
outcome: AutomationRunOutcomeSchema,
|
|
16266
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
16267
|
+
repeat: number().int().min(1),
|
|
16268
|
+
/** When the latest of those repeats happened. */
|
|
16269
|
+
lastAt: number()
|
|
16270
|
+
});
|
|
16271
|
+
/**
|
|
16272
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
16273
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
16274
|
+
*/
|
|
16275
|
+
var AutomationStateDocSchema = object({
|
|
16276
|
+
version: literal(1),
|
|
16277
|
+
lastRunStartedAt: number().nullable(),
|
|
16278
|
+
traces: array(AutomationRunTraceSchema)
|
|
16279
|
+
});
|
|
16280
|
+
/**
|
|
16281
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
16282
|
+
* declared as LIST ENTRIES, never as devices.
|
|
16283
|
+
*
|
|
16284
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
16285
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
16286
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
16287
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
16288
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
16289
|
+
*
|
|
16290
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
16291
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
16292
|
+
* runtime.
|
|
16293
|
+
*/
|
|
16294
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
16295
|
+
var ActionVariableTypeSchema = _enum([
|
|
16296
|
+
"string",
|
|
16297
|
+
"number",
|
|
16298
|
+
"boolean",
|
|
16299
|
+
"select"
|
|
16300
|
+
]);
|
|
16301
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16302
|
+
var ActionVariableValueSchema = union([
|
|
16303
|
+
string(),
|
|
16304
|
+
number(),
|
|
16305
|
+
boolean()
|
|
16306
|
+
]);
|
|
16307
|
+
/**
|
|
16308
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
16309
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
16310
|
+
*/
|
|
16311
|
+
var ActionVariableSchema = object({
|
|
16312
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
16313
|
+
label: string().min(1).max(120).optional(),
|
|
16314
|
+
type: ActionVariableTypeSchema,
|
|
16315
|
+
required: boolean().optional(),
|
|
16316
|
+
default: ActionVariableValueSchema.optional(),
|
|
16317
|
+
/** The allowed values of a `select`. */
|
|
16318
|
+
options: array(string().min(1)).min(1).optional()
|
|
16319
|
+
}).superRefine((v, ctx) => {
|
|
16320
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
16321
|
+
code: "custom",
|
|
16322
|
+
message: "a select variable needs options",
|
|
16323
|
+
path: ["options"]
|
|
16324
|
+
});
|
|
16325
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
16326
|
+
code: "custom",
|
|
16327
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
16328
|
+
path: ["default"]
|
|
16329
|
+
});
|
|
16330
|
+
});
|
|
16331
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
16332
|
+
function variableValueError(variable, value) {
|
|
16333
|
+
switch (variable.type) {
|
|
16334
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
16335
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
16336
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
16337
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
16338
|
+
}
|
|
16339
|
+
}
|
|
16340
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
16341
|
+
function isInternalActionId(actionId) {
|
|
16342
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
16343
|
+
}
|
|
16344
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
16345
|
+
function addonIdOfActionId(actionId) {
|
|
16346
|
+
if (isInternalActionId(actionId)) return null;
|
|
16347
|
+
const at = actionId.indexOf(":");
|
|
16348
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
16349
|
+
}
|
|
16350
|
+
var ActionStatusSchema = object({
|
|
16351
|
+
isRunning: boolean(),
|
|
16352
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
16353
|
+
lastRunAt: number().nullable(),
|
|
16354
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
16355
|
+
lastError: string().nullable()
|
|
16356
|
+
});
|
|
16357
|
+
var ActionEntrySchema = object({
|
|
16358
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
16359
|
+
id: string().min(3),
|
|
16360
|
+
name: string().min(1).max(120),
|
|
16361
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
16362
|
+
addonId: string().min(1),
|
|
16363
|
+
source: ActionSourceKindSchema,
|
|
16364
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
16365
|
+
readOnly: boolean(),
|
|
16366
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
16367
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
16368
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
16369
|
+
status: ActionStatusSchema
|
|
16370
|
+
}).superRefine((entry, ctx) => {
|
|
16371
|
+
if (entry.source === "internal") {
|
|
16372
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
16373
|
+
code: "custom",
|
|
16374
|
+
message: "an internal action id is internal:<uuid>",
|
|
16375
|
+
path: ["id"]
|
|
16376
|
+
});
|
|
16377
|
+
return;
|
|
16378
|
+
}
|
|
16379
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
16380
|
+
code: "custom",
|
|
16381
|
+
message: "only an internal action carries steps",
|
|
16382
|
+
path: ["steps"]
|
|
16383
|
+
});
|
|
16384
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
16385
|
+
code: "custom",
|
|
16386
|
+
message: "an addon action is read-only here",
|
|
16387
|
+
path: ["readOnly"]
|
|
16388
|
+
});
|
|
16389
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
16390
|
+
code: "custom",
|
|
16391
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
16392
|
+
path: ["id"]
|
|
16393
|
+
});
|
|
16394
|
+
});
|
|
16395
|
+
/** What an operator writes for an internal action. */
|
|
16396
|
+
var ActionInputSchema = object({
|
|
16397
|
+
name: string().min(1).max(120),
|
|
16398
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
16399
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
16400
|
+
});
|
|
16401
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
16402
|
+
var ActionRunOriginSchema = object({
|
|
16403
|
+
/** The automation block whose step started it. */
|
|
16404
|
+
blockId: string().min(1).optional() });
|
|
16405
|
+
/** `started` = the caller did not ask to wait. */
|
|
16406
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
16407
|
+
var ActionRunResultSchema = object({
|
|
16408
|
+
runId: string().min(1),
|
|
16409
|
+
outcome: ActionRunOutcomeSchema,
|
|
16410
|
+
/** Why it did not run, or what failed. */
|
|
16411
|
+
message: string().optional()
|
|
16412
|
+
});
|
|
16413
|
+
_enum([
|
|
16414
|
+
"not-found",
|
|
16415
|
+
"read-only",
|
|
16416
|
+
"invalid-variables",
|
|
16417
|
+
"invalid-steps",
|
|
16418
|
+
"not-linked",
|
|
16419
|
+
"busy"
|
|
16420
|
+
]);
|
|
16421
|
+
object({
|
|
16422
|
+
actionId: string(),
|
|
16423
|
+
runId: string(),
|
|
16424
|
+
isRunning: boolean(),
|
|
16425
|
+
/** Set when the run ended. */
|
|
16426
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
16427
|
+
lastRunAt: number().nullable(),
|
|
16428
|
+
lastError: string().nullable()
|
|
16003
16429
|
});
|
|
16004
16430
|
/**
|
|
16005
16431
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18754,7 +19180,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18754
19180
|
stateField: string(),
|
|
18755
19181
|
fieldKey: string()
|
|
18756
19182
|
});
|
|
18757
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
19183
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18758
19184
|
var CompositionProblemSchema = object({
|
|
18759
19185
|
code: _enum([
|
|
18760
19186
|
"reserved-variant",
|
|
@@ -19036,12 +19462,13 @@ var CHANGED = {
|
|
|
19036
19462
|
expr: "now"
|
|
19037
19463
|
};
|
|
19038
19464
|
function numeric(input) {
|
|
19465
|
+
const { alsoFrom, ...base } = input;
|
|
19039
19466
|
return {
|
|
19040
|
-
...
|
|
19467
|
+
...base,
|
|
19041
19468
|
family: "numeric",
|
|
19042
19469
|
deviceType: DeviceType.Sensor,
|
|
19043
19470
|
memberDeviceType: DeviceType.Sensor,
|
|
19044
|
-
memberDeviceTypes: [DeviceType.Sensor],
|
|
19471
|
+
memberDeviceTypes: [DeviceType.Sensor, ...alsoFrom?.deviceTypes ?? []],
|
|
19045
19472
|
activeWhen: void 0,
|
|
19046
19473
|
commandCaps: [],
|
|
19047
19474
|
baseUnit: baseUnitOf(input.quantity),
|
|
@@ -19049,9 +19476,10 @@ function numeric(input) {
|
|
|
19049
19476
|
accept: [{
|
|
19050
19477
|
cap: input.outputCap,
|
|
19051
19478
|
fieldPath: input.outputField
|
|
19052
|
-
}]
|
|
19479
|
+
}, ...alsoFrom === void 0 ? [] : [alsoFrom.accept]]
|
|
19053
19480
|
};
|
|
19054
19481
|
}
|
|
19482
|
+
var CLIMATE_DEVICES = [DeviceType.Thermostat, DeviceType.Climate];
|
|
19055
19483
|
function binary(input) {
|
|
19056
19484
|
return {
|
|
19057
19485
|
...input,
|
|
@@ -19073,29 +19501,43 @@ var GROUP_TEMPLATES = [
|
|
|
19073
19501
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
19074
19502
|
role: DeviceRole.TemperatureSensor,
|
|
19075
19503
|
outputCap: "temperature-sensor",
|
|
19076
|
-
outputField: "
|
|
19504
|
+
outputField: "temperature",
|
|
19077
19505
|
quantity: "temperature",
|
|
19078
19506
|
defaultAggregate: "mean",
|
|
19079
19507
|
empty: "null",
|
|
19080
|
-
companions: [NOW$2]
|
|
19508
|
+
companions: [NOW$2],
|
|
19509
|
+
alsoFrom: {
|
|
19510
|
+
deviceTypes: CLIMATE_DEVICES,
|
|
19511
|
+
accept: {
|
|
19512
|
+
cap: "climate-control",
|
|
19513
|
+
fieldPath: "currentTemp"
|
|
19514
|
+
}
|
|
19515
|
+
}
|
|
19081
19516
|
}),
|
|
19082
19517
|
numeric({
|
|
19083
19518
|
id: "humidity",
|
|
19084
19519
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19085
19520
|
role: DeviceRole.HumiditySensor,
|
|
19086
19521
|
outputCap: "humidity-sensor",
|
|
19087
|
-
outputField: "
|
|
19522
|
+
outputField: "humidity",
|
|
19088
19523
|
quantity: "humidity",
|
|
19089
19524
|
defaultAggregate: "mean",
|
|
19090
19525
|
empty: "null",
|
|
19091
|
-
companions: [NOW$2]
|
|
19526
|
+
companions: [NOW$2],
|
|
19527
|
+
alsoFrom: {
|
|
19528
|
+
deviceTypes: CLIMATE_DEVICES,
|
|
19529
|
+
accept: {
|
|
19530
|
+
cap: "climate-control",
|
|
19531
|
+
fieldPath: "currentHumidity"
|
|
19532
|
+
}
|
|
19533
|
+
}
|
|
19092
19534
|
}),
|
|
19093
19535
|
numeric({
|
|
19094
19536
|
id: "pressure",
|
|
19095
19537
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
19096
19538
|
role: DeviceRole.PressureSensor,
|
|
19097
19539
|
outputCap: "pressure-sensor",
|
|
19098
|
-
outputField: "
|
|
19540
|
+
outputField: "pressure",
|
|
19099
19541
|
quantity: "pressure",
|
|
19100
19542
|
defaultAggregate: "mean",
|
|
19101
19543
|
empty: "null",
|
|
@@ -19106,7 +19548,7 @@ var GROUP_TEMPLATES = [
|
|
|
19106
19548
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
19107
19549
|
role: DeviceRole.AmbientLightSensor,
|
|
19108
19550
|
outputCap: "ambient-light-sensor",
|
|
19109
|
-
outputField: "
|
|
19551
|
+
outputField: "illuminance",
|
|
19110
19552
|
quantity: "illuminance",
|
|
19111
19553
|
defaultAggregate: "mean",
|
|
19112
19554
|
empty: "null",
|
|
@@ -19117,7 +19559,7 @@ var GROUP_TEMPLATES = [
|
|
|
19117
19559
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
19118
19560
|
role: DeviceRole.PowerSensor,
|
|
19119
19561
|
outputCap: "power-meter",
|
|
19120
|
-
outputField: "
|
|
19562
|
+
outputField: "power",
|
|
19121
19563
|
quantity: "power",
|
|
19122
19564
|
defaultAggregate: "sum",
|
|
19123
19565
|
empty: "omit",
|
|
@@ -19128,7 +19570,7 @@ var GROUP_TEMPLATES = [
|
|
|
19128
19570
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
19129
19571
|
role: DeviceRole.EnergySensor,
|
|
19130
19572
|
outputCap: "power-meter",
|
|
19131
|
-
outputField: "
|
|
19573
|
+
outputField: "energy",
|
|
19132
19574
|
quantity: "energy",
|
|
19133
19575
|
defaultAggregate: "sum",
|
|
19134
19576
|
empty: "omit",
|
|
@@ -19139,7 +19581,7 @@ var GROUP_TEMPLATES = [
|
|
|
19139
19581
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19140
19582
|
role: DeviceRole.BatterySensor,
|
|
19141
19583
|
outputCap: "battery",
|
|
19142
|
-
outputField: "
|
|
19584
|
+
outputField: "level",
|
|
19143
19585
|
quantity: "percentage",
|
|
19144
19586
|
defaultAggregate: "mean",
|
|
19145
19587
|
empty: "null",
|
|
@@ -19717,7 +20159,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19717
20159
|
kind: "mutation",
|
|
19718
20160
|
auth: "admin",
|
|
19719
20161
|
access: "view"
|
|
19720
|
-
})
|
|
20162
|
+
}), method(object({
|
|
20163
|
+
blockId: string().min(1),
|
|
20164
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
20165
|
+
runStartedAt: number().optional(),
|
|
20166
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
20167
|
+
}), _void(), {
|
|
20168
|
+
kind: "mutation",
|
|
20169
|
+
auth: "admin"
|
|
20170
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
20171
|
+
traces: array(AutomationRunTraceSchema),
|
|
20172
|
+
lastError: string().nullable()
|
|
20173
|
+
}), { auth: "admin" });
|
|
19721
20174
|
/**
|
|
19722
20175
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19723
20176
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -43750,6 +44203,17 @@ var LlmProfileSchema = object({
|
|
|
43750
44203
|
* field in its editor only when its descriptor lists it in `profileFields`. */
|
|
43751
44204
|
topK: number().int().positive().optional(),
|
|
43752
44205
|
maxTokens: number().int().positive().optional(),
|
|
44206
|
+
/** How hard the model "thinks" before it answers. Omitted = the model's own
|
|
44207
|
+
* default. `off` matters for structured output: a thinking model can spend
|
|
44208
|
+
* the whole completion on reasoning and return an empty `content`. Carried
|
|
44209
|
+
* only by the wires that have it — a kind offers the field in its editor
|
|
44210
|
+
* only when its descriptor lists it in `profileFields`. */
|
|
44211
|
+
reasoningEffort: _enum([
|
|
44212
|
+
"off",
|
|
44213
|
+
"low",
|
|
44214
|
+
"medium",
|
|
44215
|
+
"high"
|
|
44216
|
+
]).optional(),
|
|
43753
44217
|
/** Prompt context window. Advisory for cloud kinds (they enforce their own). */
|
|
43754
44218
|
contextLength: number().int().positive().optional(),
|
|
43755
44219
|
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
@@ -43788,6 +44252,7 @@ var LlmProfileFieldSchema = _enum([
|
|
|
43788
44252
|
"topP",
|
|
43789
44253
|
"topK",
|
|
43790
44254
|
"maxTokens",
|
|
44255
|
+
"reasoningEffort",
|
|
43791
44256
|
"contextLength",
|
|
43792
44257
|
"systemPrompt",
|
|
43793
44258
|
"timeoutMs",
|
|
@@ -45038,6 +45503,43 @@ var NotificationActionSchema = object({
|
|
|
45038
45503
|
*/
|
|
45039
45504
|
mode: _enum(["navigate", "background"]).optional()
|
|
45040
45505
|
});
|
|
45506
|
+
/** A delivery parameter value: what a notifier declared it takes. */
|
|
45507
|
+
var DeliveryParamValueSchema = union([
|
|
45508
|
+
string(),
|
|
45509
|
+
number(),
|
|
45510
|
+
boolean()
|
|
45511
|
+
]);
|
|
45512
|
+
/**
|
|
45513
|
+
* One extra delivery parameter a notifier KIND declares (D938). A rule that
|
|
45514
|
+
* addresses a target of that kind may set it; a kind that declares nothing is
|
|
45515
|
+
* never handed one. The admin UI derives its control from this descriptor —
|
|
45516
|
+
* no editor knows a service by name.
|
|
45517
|
+
*
|
|
45518
|
+
* Optional fields are `.optional()`, never `.default()` (a Zod default does not
|
|
45519
|
+
* run on the addon cap path).
|
|
45520
|
+
*/
|
|
45521
|
+
var DeliveryParamSchema = object({
|
|
45522
|
+
key: string().min(1),
|
|
45523
|
+
label: string(),
|
|
45524
|
+
/** i18n key of the label, resolved by the declaring addon's namespace. */
|
|
45525
|
+
labelKey: string().optional(),
|
|
45526
|
+
type: _enum([
|
|
45527
|
+
"enum",
|
|
45528
|
+
"number",
|
|
45529
|
+
"boolean",
|
|
45530
|
+
"string"
|
|
45531
|
+
]),
|
|
45532
|
+
/** `enum` only: the closed set of accepted values. */
|
|
45533
|
+
options: array(object({
|
|
45534
|
+
value: string(),
|
|
45535
|
+
label: string()
|
|
45536
|
+
})).optional(),
|
|
45537
|
+
/** `number` only. */
|
|
45538
|
+
min: number().optional(),
|
|
45539
|
+
max: number().optional(),
|
|
45540
|
+
/** What the notifier does when the rule sets nothing; shown as the placeholder. */
|
|
45541
|
+
default: DeliveryParamValueSchema.optional()
|
|
45542
|
+
});
|
|
45041
45543
|
/**
|
|
45042
45544
|
* The canonical notification. `body` is the only hard field (Apprise model).
|
|
45043
45545
|
* `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
|
|
@@ -45060,7 +45562,13 @@ var NotificationSchema = object({
|
|
|
45060
45562
|
tag: string().optional(),
|
|
45061
45563
|
deviceId: number().optional(),
|
|
45062
45564
|
eventId: string().optional(),
|
|
45063
|
-
metadata: record(string(), unknown()).optional()
|
|
45565
|
+
metadata: record(string(), unknown()).optional(),
|
|
45566
|
+
/**
|
|
45567
|
+
* Values for the parameters the target's kind DECLARES in
|
|
45568
|
+
* {@link TargetKindSchema} `deliveryParams`. Already validated against the
|
|
45569
|
+
* declaration by the sender; a notifier reads only the keys it declared.
|
|
45570
|
+
*/
|
|
45571
|
+
delivery: record(string(), DeliveryParamValueSchema).optional()
|
|
45064
45572
|
});
|
|
45065
45573
|
/** One declared native severity/priority level for a kind. */
|
|
45066
45574
|
var TargetKindLevelSchema = object({
|
|
@@ -45166,6 +45674,11 @@ var TargetKindSchema = object({
|
|
|
45166
45674
|
*/
|
|
45167
45675
|
destinationKeys: array(string()).optional(),
|
|
45168
45676
|
supportsDiscovery: boolean(),
|
|
45677
|
+
/**
|
|
45678
|
+
* Extra delivery parameters a rule may set for a target of this kind (D938).
|
|
45679
|
+
* Absent = none; the rule editor then offers nothing.
|
|
45680
|
+
*/
|
|
45681
|
+
deliveryParams: array(DeliveryParamSchema).optional(),
|
|
45169
45682
|
caps: TargetKindCapsSchema
|
|
45170
45683
|
});
|
|
45171
45684
|
/**
|
|
@@ -45287,51 +45800,6 @@ var notificationOutputCapability = {
|
|
|
45287
45800
|
})
|
|
45288
45801
|
}
|
|
45289
45802
|
};
|
|
45290
|
-
new Set([
|
|
45291
|
-
{
|
|
45292
|
-
id: "person",
|
|
45293
|
-
name: "Person"
|
|
45294
|
-
},
|
|
45295
|
-
{
|
|
45296
|
-
id: "vehicle",
|
|
45297
|
-
name: "Vehicle"
|
|
45298
|
-
},
|
|
45299
|
-
{
|
|
45300
|
-
id: "animal",
|
|
45301
|
-
name: "Animal"
|
|
45302
|
-
},
|
|
45303
|
-
{
|
|
45304
|
-
id: "package",
|
|
45305
|
-
name: "Package"
|
|
45306
|
-
}
|
|
45307
|
-
].map((l) => l.id));
|
|
45308
|
-
var COCO_TO_MACRO = {
|
|
45309
|
-
mapping: {
|
|
45310
|
-
person: "person",
|
|
45311
|
-
bicycle: "vehicle",
|
|
45312
|
-
car: "vehicle",
|
|
45313
|
-
motorcycle: "vehicle",
|
|
45314
|
-
airplane: "vehicle",
|
|
45315
|
-
bus: "vehicle",
|
|
45316
|
-
train: "vehicle",
|
|
45317
|
-
truck: "vehicle",
|
|
45318
|
-
boat: "vehicle",
|
|
45319
|
-
bird: "animal",
|
|
45320
|
-
cat: "animal",
|
|
45321
|
-
dog: "animal",
|
|
45322
|
-
horse: "animal",
|
|
45323
|
-
sheep: "animal",
|
|
45324
|
-
cow: "animal",
|
|
45325
|
-
elephant: "animal",
|
|
45326
|
-
bear: "animal",
|
|
45327
|
-
zebra: "animal",
|
|
45328
|
-
giraffe: "animal",
|
|
45329
|
-
suitcase: "package",
|
|
45330
|
-
backpack: "package",
|
|
45331
|
-
handbag: "package"
|
|
45332
|
-
},
|
|
45333
|
-
preserveOriginal: false
|
|
45334
|
-
};
|
|
45335
45803
|
var AUDIO_MACRO_LABELS = [
|
|
45336
45804
|
{
|
|
45337
45805
|
id: "speech",
|
|
@@ -57612,7 +58080,9 @@ var ManifestShapeSchema = object({
|
|
|
57612
58080
|
icon: string().optional()
|
|
57613
58081
|
}).optional(),
|
|
57614
58082
|
protected: boolean().optional(),
|
|
57615
|
-
removable: boolean().optional()
|
|
58083
|
+
removable: boolean().optional(),
|
|
58084
|
+
/** Declared Integrations-page block (mirror of `AddonDeclaration.integrationSection`). */
|
|
58085
|
+
integrationSection: _enum(["system", "providers"]).optional()
|
|
57616
58086
|
});
|
|
57617
58087
|
var AddonProcessSchema = object({
|
|
57618
58088
|
pid: number().optional(),
|
|
@@ -57986,9 +58456,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57986
58456
|
*/
|
|
57987
58457
|
var AirQualitySensorStatusSchema = object({
|
|
57988
58458
|
/** Carbon dioxide concentration in ppm. */
|
|
57989
|
-
|
|
58459
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57990
58460
|
/** Total volatile organic compounds in ppb. */
|
|
57991
|
-
|
|
58461
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57992
58462
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57993
58463
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57994
58464
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -58021,12 +58491,12 @@ var airQualitySensorCapability = {
|
|
|
58021
58491
|
* History (D850): recorded series.
|
|
58022
58492
|
*/
|
|
58023
58493
|
history: { fields: {
|
|
58024
|
-
|
|
58494
|
+
co2: {
|
|
58025
58495
|
kind: "gauge",
|
|
58026
58496
|
unit: "ppm",
|
|
58027
58497
|
deadband: 5
|
|
58028
58498
|
},
|
|
58029
|
-
|
|
58499
|
+
voc: {
|
|
58030
58500
|
kind: "gauge",
|
|
58031
58501
|
unit: "ppb",
|
|
58032
58502
|
deadband: 5
|
|
@@ -58057,7 +58527,7 @@ var airQualitySensorCapability = {
|
|
|
58057
58527
|
*/
|
|
58058
58528
|
var AmbientLightSensorStatusSchema = object({
|
|
58059
58529
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
58060
|
-
|
|
58530
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
58061
58531
|
precision: 0,
|
|
58062
58532
|
label: "Illuminance"
|
|
58063
58533
|
})),
|
|
@@ -58086,7 +58556,7 @@ var ambientLightSensorCapability = {
|
|
|
58086
58556
|
/**
|
|
58087
58557
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
58088
58558
|
*/
|
|
58089
|
-
history: { fields: {
|
|
58559
|
+
history: { fields: { illuminance: {
|
|
58090
58560
|
kind: "gauge",
|
|
58091
58561
|
unit: "lx",
|
|
58092
58562
|
deadbandPct: 10,
|
|
@@ -58225,6 +58695,84 @@ var audioMetricsCapability = {
|
|
|
58225
58695
|
*/
|
|
58226
58696
|
history: "none"
|
|
58227
58697
|
};
|
|
58698
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58699
|
+
actionId: string().min(1),
|
|
58700
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
58701
|
+
}), _void(), {
|
|
58702
|
+
kind: "mutation",
|
|
58703
|
+
auth: "admin"
|
|
58704
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
58705
|
+
kind: "mutation",
|
|
58706
|
+
auth: "admin"
|
|
58707
|
+
});
|
|
58708
|
+
/**
|
|
58709
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
58710
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
58711
|
+
*
|
|
58712
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
58713
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
58714
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
58715
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
58716
|
+
* drift (D3).
|
|
58717
|
+
*
|
|
58718
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
58719
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
58720
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
58721
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
58722
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
58723
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
58724
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
58725
|
+
*
|
|
58726
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
58727
|
+
* logged — never queued.
|
|
58728
|
+
*/
|
|
58729
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
58730
|
+
var ActionLinksSchema = object({
|
|
58731
|
+
deviceId: number().int().nonnegative(),
|
|
58732
|
+
actionIds: array(string().min(1)).max(100)
|
|
58733
|
+
});
|
|
58734
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58735
|
+
actionId: string().min(1),
|
|
58736
|
+
deviceId: number().int().nonnegative().optional()
|
|
58737
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
58738
|
+
role: "viewer",
|
|
58739
|
+
auth: "protected",
|
|
58740
|
+
kind: "query",
|
|
58741
|
+
caller: "required"
|
|
58742
|
+
}), method(object({
|
|
58743
|
+
actionId: string().min(1),
|
|
58744
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
58745
|
+
wait: boolean().optional(),
|
|
58746
|
+
origin: ActionRunOriginSchema.optional(),
|
|
58747
|
+
deviceId: number().int().nonnegative().optional()
|
|
58748
|
+
}), ActionRunResultSchema, {
|
|
58749
|
+
role: "viewer",
|
|
58750
|
+
auth: "protected",
|
|
58751
|
+
kind: "mutation",
|
|
58752
|
+
caller: "required"
|
|
58753
|
+
}), method(ActionIdInput, _void(), {
|
|
58754
|
+
kind: "mutation",
|
|
58755
|
+
auth: "admin"
|
|
58756
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
58757
|
+
kind: "mutation",
|
|
58758
|
+
auth: "admin"
|
|
58759
|
+
}), method(object({
|
|
58760
|
+
actionId: string().min(1),
|
|
58761
|
+
action: ActionInputSchema.partial()
|
|
58762
|
+
}), object({ action: ActionEntrySchema }), {
|
|
58763
|
+
kind: "mutation",
|
|
58764
|
+
auth: "admin"
|
|
58765
|
+
}), method(ActionIdInput, _void(), {
|
|
58766
|
+
kind: "mutation",
|
|
58767
|
+
auth: "admin"
|
|
58768
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
58769
|
+
role: "viewer",
|
|
58770
|
+
auth: "protected",
|
|
58771
|
+
kind: "query"
|
|
58772
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
58773
|
+
kind: "mutation",
|
|
58774
|
+
auth: "admin"
|
|
58775
|
+
});
|
|
58228
58776
|
/**
|
|
58229
58777
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
58230
58778
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -58321,7 +58869,7 @@ var BatteryStatusSchema = object({
|
|
|
58321
58869
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
58322
58870
|
* declines to band a non-finite reading, which is the correct shape.
|
|
58323
58871
|
*/
|
|
58324
|
-
|
|
58872
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
58325
58873
|
/**
|
|
58326
58874
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
58327
58875
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -58331,7 +58879,7 @@ var BatteryStatusSchema = object({
|
|
|
58331
58879
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
58332
58880
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
58333
58881
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
58334
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
58882
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
58335
58883
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
58336
58884
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
58337
58885
|
*/
|
|
@@ -58355,7 +58903,7 @@ var BatteryStatusSchema = object({
|
|
|
58355
58903
|
* that only report charge. A second reading on this cap, not a second
|
|
58356
58904
|
* `numeric-sensor` on the same device.
|
|
58357
58905
|
*/
|
|
58358
|
-
|
|
58906
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
58359
58907
|
/**
|
|
58360
58908
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
58361
58909
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58389,7 +58937,7 @@ var BatteryStatusSchema = object({
|
|
|
58389
58937
|
/**
|
|
58390
58938
|
* True when the source is a BINARY low-battery indicator (HA
|
|
58391
58939
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
58392
|
-
* charge level — `
|
|
58940
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
58393
58941
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
58394
58942
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
58395
58943
|
*/
|
|
@@ -58409,15 +58957,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58409
58957
|
var batteryCustomize = {
|
|
58410
58958
|
version: 1,
|
|
58411
58959
|
targets: [{
|
|
58412
|
-
id: "
|
|
58960
|
+
id: "level",
|
|
58413
58961
|
cardinality: "scalar",
|
|
58414
58962
|
vocabulary: {
|
|
58415
58963
|
cap: "battery",
|
|
58416
|
-
stateField: "
|
|
58964
|
+
stateField: "level"
|
|
58417
58965
|
},
|
|
58418
58966
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58419
58967
|
apply: "add",
|
|
58420
|
-
path: "
|
|
58968
|
+
path: "level",
|
|
58421
58969
|
sources: [{
|
|
58422
58970
|
kind: "field",
|
|
58423
58971
|
valueKinds: ["number", "string"],
|
|
@@ -58511,7 +59059,7 @@ onStatusChanged: { data: object({
|
|
|
58511
59059
|
schema: BatteryStatusSchema,
|
|
58512
59060
|
kind: "push",
|
|
58513
59061
|
empty: {
|
|
58514
|
-
|
|
59062
|
+
level: null,
|
|
58515
59063
|
charging: "unknown",
|
|
58516
59064
|
sleeping: false,
|
|
58517
59065
|
lastUpdated: 0
|
|
@@ -58538,11 +59086,11 @@ onStatusChanged: { data: object({
|
|
|
58538
59086
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58539
59087
|
*/
|
|
58540
59088
|
history: { fields: {
|
|
58541
|
-
|
|
59089
|
+
level: {
|
|
58542
59090
|
kind: "gauge",
|
|
58543
59091
|
unit: "%"
|
|
58544
59092
|
},
|
|
58545
|
-
|
|
59093
|
+
voltage: {
|
|
58546
59094
|
kind: "gauge",
|
|
58547
59095
|
unit: "V"
|
|
58548
59096
|
}
|
|
@@ -58602,14 +59150,14 @@ var binaryCapability = {
|
|
|
58602
59150
|
* controls to this single-method surface.
|
|
58603
59151
|
*
|
|
58604
59152
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
58605
|
-
*
|
|
59153
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
58606
59154
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
58607
59155
|
* should surface those via the device's `getSettingsUISchema()`
|
|
58608
59156
|
* instead of bloating this cap.
|
|
58609
59157
|
*/
|
|
58610
59158
|
var BrightnessStatusSchema = object({
|
|
58611
59159
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58612
|
-
|
|
59160
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58613
59161
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58614
59162
|
lastChangedAt: number()
|
|
58615
59163
|
});
|
|
@@ -58621,7 +59169,7 @@ var brightnessCapability = {
|
|
|
58621
59169
|
deviceTypes: [DeviceType.Light],
|
|
58622
59170
|
methods: { setBrightness: method(object({
|
|
58623
59171
|
deviceId: number().int().nonnegative(),
|
|
58624
|
-
|
|
59172
|
+
level: number().min(0).max(100)
|
|
58625
59173
|
}), _void(), {
|
|
58626
59174
|
kind: "mutation",
|
|
58627
59175
|
auth: "protected"
|
|
@@ -58634,7 +59182,7 @@ var brightnessCapability = {
|
|
|
58634
59182
|
*/
|
|
58635
59183
|
onBrightnessChanged: { data: object({
|
|
58636
59184
|
deviceId: number(),
|
|
58637
|
-
|
|
59185
|
+
level: number().min(0).max(100),
|
|
58638
59186
|
lastChangedAt: number()
|
|
58639
59187
|
}) } },
|
|
58640
59188
|
status: {
|
|
@@ -58657,7 +59205,7 @@ onBrightnessChanged: { data: object({
|
|
|
58657
59205
|
/**
|
|
58658
59206
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
58659
59207
|
*/
|
|
58660
|
-
history: { fields: {
|
|
59208
|
+
history: { fields: { level: {
|
|
58661
59209
|
kind: "gauge",
|
|
58662
59210
|
unit: "%",
|
|
58663
59211
|
minIntervalMs: 0
|
|
@@ -58685,6 +59233,56 @@ var buttonCapability = {
|
|
|
58685
59233
|
}) }
|
|
58686
59234
|
};
|
|
58687
59235
|
/**
|
|
59236
|
+
* A pulse train in signed microseconds: mark (+) first, then space (-), strictly
|
|
59237
|
+
* alternating, no zeros, 2..1024 entries.
|
|
59238
|
+
*/
|
|
59239
|
+
var IrTimingsSchema = array(number().int()).min(2).max(1024).superRefine((timings, ctx) => {
|
|
59240
|
+
timings.forEach((value, index) => {
|
|
59241
|
+
const expectMark = index % 2 === 0;
|
|
59242
|
+
if (value === 0 || value > 0 !== expectMark) ctx.addIssue({
|
|
59243
|
+
code: "custom",
|
|
59244
|
+
message: `timing ${index} must be a non-zero ${expectMark ? "mark (positive)" : "space (negative)"}`,
|
|
59245
|
+
path: [index]
|
|
59246
|
+
});
|
|
59247
|
+
});
|
|
59248
|
+
});
|
|
59249
|
+
/** Per-command transmit options. Every key is optional; a transmitter applies what it can. */
|
|
59250
|
+
var TransmitSettingsSchema = object({
|
|
59251
|
+
carrierHz: number().int().positive().optional(),
|
|
59252
|
+
dutyCyclePercent: number().int().min(1).max(100).optional(),
|
|
59253
|
+
repeat: number().int().min(0).max(20).optional(),
|
|
59254
|
+
repeatDelayMs: number().int().min(0).optional()
|
|
59255
|
+
});
|
|
59256
|
+
/** The setting keys a transmitter may declare as settable (`getInfo.settable`). */
|
|
59257
|
+
var TransmitSettingKeySchema = _enum([
|
|
59258
|
+
"carrierHz",
|
|
59259
|
+
"dutyCyclePercent",
|
|
59260
|
+
"repeat",
|
|
59261
|
+
"repeatDelayMs"
|
|
59262
|
+
]);
|
|
59263
|
+
var IrMediumSchema = _enum(["ir", "rf"]);
|
|
59264
|
+
var IrSendResultSchema = object({
|
|
59265
|
+
ok: literal(true),
|
|
59266
|
+
/** Settings the transmitter could not apply; the train was still sent. */
|
|
59267
|
+
ignoredSettings: array(string())
|
|
59268
|
+
});
|
|
59269
|
+
var IrTransmitterInfoSchema = object({
|
|
59270
|
+
media: array(IrMediumSchema),
|
|
59271
|
+
settable: array(TransmitSettingKeySchema),
|
|
59272
|
+
maxTimings: number().int().positive()
|
|
59273
|
+
});
|
|
59274
|
+
DeviceType.Generic, method(object({
|
|
59275
|
+
deviceId: number().int().nonnegative(),
|
|
59276
|
+
timings: IrTimingsSchema,
|
|
59277
|
+
settings: TransmitSettingsSchema.optional()
|
|
59278
|
+
}), IrSendResultSchema, {
|
|
59279
|
+
kind: "mutation",
|
|
59280
|
+
auth: "protected"
|
|
59281
|
+
}), method(object({ deviceId: number().int().nonnegative() }), IrTransmitterInfoSchema, {
|
|
59282
|
+
kind: "query",
|
|
59283
|
+
auth: "protected"
|
|
59284
|
+
});
|
|
59285
|
+
/**
|
|
58688
59286
|
* `calendar-source` — collection cap exposing per-provider calendars and
|
|
58689
59287
|
* their events. Every addon that contributes calendars (Home Assistant,
|
|
58690
59288
|
* a future Google Calendar addon, …) registers a provider here. The hub
|
|
@@ -59281,11 +59879,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
59281
59879
|
}),
|
|
59282
59880
|
object({
|
|
59283
59881
|
mode: literal("mired"),
|
|
59284
|
-
|
|
59882
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
59285
59883
|
})
|
|
59286
59884
|
]);
|
|
59287
59885
|
var ColorStatusSchema = object({
|
|
59288
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
59886
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
59289
59887
|
* the bulb's current state. */
|
|
59290
59888
|
mode: _enum([
|
|
59291
59889
|
"rgb",
|
|
@@ -59297,7 +59895,7 @@ var ColorStatusSchema = object({
|
|
|
59297
59895
|
/** Populated when `mode === 'hsv'`. */
|
|
59298
59896
|
hsv: HsvTripletSchema.optional(),
|
|
59299
59897
|
/** Populated when `mode === 'mired'`. */
|
|
59300
|
-
|
|
59898
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
59301
59899
|
/** Ms epoch of the last operator-driven change. */
|
|
59302
59900
|
lastChangedAt: number()
|
|
59303
59901
|
});
|
|
@@ -59329,7 +59927,7 @@ onColorChanged: { data: object({
|
|
|
59329
59927
|
]),
|
|
59330
59928
|
rgb: RgbTripletSchema.optional(),
|
|
59331
59929
|
hsv: HsvTripletSchema.optional(),
|
|
59332
|
-
|
|
59930
|
+
colorTemperature: number().int().optional(),
|
|
59333
59931
|
lastChangedAt: number()
|
|
59334
59932
|
}) } },
|
|
59335
59933
|
status: {
|
|
@@ -60220,11 +60818,11 @@ var DishwasherStatusSchema = object({
|
|
|
60220
60818
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
60221
60819
|
availablePrograms: array(string()),
|
|
60222
60820
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
60223
|
-
|
|
60821
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60224
60822
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
60225
|
-
|
|
60823
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60226
60824
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
60227
|
-
|
|
60825
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60228
60826
|
/** True when the door is reported open; null when the door state is not known. */
|
|
60229
60827
|
doorOpen: boolean().nullable(),
|
|
60230
60828
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -60443,14 +61041,14 @@ var dishwasherCapability = {
|
|
|
60443
61041
|
runtimeState: DishwasherStatusSchema,
|
|
60444
61042
|
durability: "session",
|
|
60445
61043
|
history: { fields: {
|
|
60446
|
-
|
|
61044
|
+
progress: {
|
|
60447
61045
|
kind: "gauge",
|
|
60448
61046
|
unit: "%",
|
|
60449
61047
|
deadband: 2
|
|
60450
61048
|
},
|
|
60451
61049
|
state: { kind: "enum" },
|
|
60452
61050
|
operationState: { kind: "enum" },
|
|
60453
|
-
|
|
61051
|
+
remaining: {
|
|
60454
61052
|
kind: "gauge",
|
|
60455
61053
|
unit: "s",
|
|
60456
61054
|
minIntervalMs: 6e4
|
|
@@ -61051,7 +61649,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
61051
61649
|
var FanControlStatusSchema = object({
|
|
61052
61650
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
61053
61651
|
* speed surface (single-speed fan). */
|
|
61054
|
-
|
|
61652
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61055
61653
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
61056
61654
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
61057
61655
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -61078,7 +61676,7 @@ var fanControlCapability = {
|
|
|
61078
61676
|
methods: {
|
|
61079
61677
|
setPercentage: method(object({
|
|
61080
61678
|
deviceId: number().int().nonnegative(),
|
|
61081
|
-
|
|
61679
|
+
speed: number().min(0).max(100)
|
|
61082
61680
|
}), _void(), {
|
|
61083
61681
|
kind: "mutation",
|
|
61084
61682
|
auth: "protected"
|
|
@@ -61111,7 +61709,7 @@ var fanControlCapability = {
|
|
|
61111
61709
|
},
|
|
61112
61710
|
/**
|
|
61113
61711
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
61114
|
-
* sliders read `
|
|
61712
|
+
* sliders read `speed` for live updates.
|
|
61115
61713
|
*/
|
|
61116
61714
|
runtimeState: FanControlStatusSchema,
|
|
61117
61715
|
/**
|
|
@@ -61125,7 +61723,7 @@ var fanControlCapability = {
|
|
|
61125
61723
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
61126
61724
|
*/
|
|
61127
61725
|
history: { fields: {
|
|
61128
|
-
|
|
61726
|
+
speed: {
|
|
61129
61727
|
kind: "gauge",
|
|
61130
61728
|
unit: "%",
|
|
61131
61729
|
minIntervalMs: 0
|
|
@@ -61570,7 +62168,7 @@ var humidifierCapability = {
|
|
|
61570
62168
|
*/
|
|
61571
62169
|
var HumiditySensorStatusSchema = object({
|
|
61572
62170
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61573
|
-
|
|
62171
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61574
62172
|
precision: 0,
|
|
61575
62173
|
label: "Humidity"
|
|
61576
62174
|
})),
|
|
@@ -61599,7 +62197,7 @@ var humiditySensorCapability = {
|
|
|
61599
62197
|
/**
|
|
61600
62198
|
* History (D850): recorded series.
|
|
61601
62199
|
*/
|
|
61602
|
-
history: { fields: {
|
|
62200
|
+
history: { fields: { humidity: {
|
|
61603
62201
|
kind: "gauge",
|
|
61604
62202
|
unit: "%",
|
|
61605
62203
|
deadband: .5
|
|
@@ -62239,7 +62837,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
62239
62837
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62240
62838
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
62241
62839
|
* task is active / progress is unavailable. */
|
|
62242
|
-
|
|
62840
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62243
62841
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
62244
62842
|
* or null when unknown. */
|
|
62245
62843
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -62739,7 +63337,7 @@ var lockControlCapability = {
|
|
|
62739
63337
|
volatileStateFields: ["lastChangedAt"]
|
|
62740
63338
|
};
|
|
62741
63339
|
/**
|
|
62742
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
63340
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
62743
63341
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
62744
63342
|
* `value` is the time integral in the source quantity's accumulated base
|
|
62745
63343
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -62833,10 +63431,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62833
63431
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62834
63432
|
/** Current playback position in ms. Null when not seekable or
|
|
62835
63433
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62836
|
-
|
|
63434
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62837
63435
|
/** Total duration of the current media in ms. Null when unknown
|
|
62838
63436
|
* (live stream) or nothing is playing. */
|
|
62839
|
-
|
|
63437
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62840
63438
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62841
63439
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62842
63440
|
shuffle: boolean().nullable(),
|
|
@@ -62875,7 +63473,7 @@ var mediaPlayerCapability = {
|
|
|
62875
63473
|
}),
|
|
62876
63474
|
seek: method(object({
|
|
62877
63475
|
deviceId: number().int().nonnegative(),
|
|
62878
|
-
|
|
63476
|
+
position: number().int().nonnegative()
|
|
62879
63477
|
}), _void(), {
|
|
62880
63478
|
kind: "mutation",
|
|
62881
63479
|
auth: "protected"
|
|
@@ -62947,7 +63545,7 @@ var mediaPlayerCapability = {
|
|
|
62947
63545
|
/**
|
|
62948
63546
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62949
63547
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62950
|
-
* `
|
|
63548
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62951
63549
|
*/
|
|
62952
63550
|
history: { fields: {
|
|
62953
63551
|
volumeLevel: {
|
|
@@ -63909,9 +64507,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
63909
64507
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63910
64508
|
* SKIP a null rather than coerce it.
|
|
63911
64509
|
*/
|
|
63912
|
-
|
|
64510
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63913
64511
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63914
|
-
|
|
64512
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
63915
64513
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63916
64514
|
ssid: string().optional(),
|
|
63917
64515
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63947,7 +64545,7 @@ onStatusChanged: { data: object({
|
|
|
63947
64545
|
kind: "push",
|
|
63948
64546
|
empty: {
|
|
63949
64547
|
type: "unknown",
|
|
63950
|
-
|
|
64548
|
+
signal: null,
|
|
63951
64549
|
lastUpdated: 0
|
|
63952
64550
|
}
|
|
63953
64551
|
},
|
|
@@ -63970,13 +64568,13 @@ onStatusChanged: { data: object({
|
|
|
63970
64568
|
* History (D850): recorded series.
|
|
63971
64569
|
*/
|
|
63972
64570
|
history: { fields: {
|
|
63973
|
-
|
|
64571
|
+
signal: {
|
|
63974
64572
|
kind: "gauge",
|
|
63975
64573
|
unit: "%",
|
|
63976
64574
|
deadband: 3,
|
|
63977
64575
|
minIntervalMs: 6e4
|
|
63978
64576
|
},
|
|
63979
|
-
|
|
64577
|
+
rssi: {
|
|
63980
64578
|
kind: "gauge",
|
|
63981
64579
|
unit: "dBm",
|
|
63982
64580
|
deadband: 2,
|
|
@@ -64721,10 +65319,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
64721
65319
|
]);
|
|
64722
65320
|
var gramsPortion = number().int().min(4).max(200);
|
|
64723
65321
|
var PetFeederStatusSchema = object({
|
|
64724
|
-
/** Food
|
|
64725
|
-
*
|
|
64726
|
-
* bowl
|
|
65322
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
65323
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
65324
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
65325
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
65326
|
+
* the device has not reported yet. */
|
|
64727
65327
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
65328
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
65329
|
+
* feeder's own units. Null when the model reports none. */
|
|
65330
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
65331
|
+
/** True while the pet is eating (`state.eating`). */
|
|
65332
|
+
eating: boolean(),
|
|
65333
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
65334
|
+
* the client must not offer it. */
|
|
65335
|
+
supportsMarkRefilled: boolean(),
|
|
64728
65336
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64729
65337
|
* single-hopper models. */
|
|
64730
65338
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -64732,12 +65340,17 @@ var PetFeederStatusSchema = object({
|
|
|
64732
65340
|
* single-hopper models. */
|
|
64733
65341
|
food2: number().nullable().meta(readingMeta("none")),
|
|
64734
65342
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64735
|
-
* (`device_class: problem`, on = low). True when the
|
|
64736
|
-
*
|
|
65343
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
65344
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
64737
65345
|
lowFood: boolean(),
|
|
64738
|
-
/** Battery charge 0..100 (%).
|
|
64739
|
-
*
|
|
65346
|
+
/** Battery charge 0..100 (%). On a feeder running on `mains` this is the
|
|
65347
|
+
* BACKUP battery's charge, not the power source. Null when the device has
|
|
65348
|
+
* no battery reading. */
|
|
64740
65349
|
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65350
|
+
/** What the feeder is powered from right now: `mains` (plugged in, the
|
|
65351
|
+
* battery is only a backup) or `battery`. Null when the device does not
|
|
65352
|
+
* report it. */
|
|
65353
|
+
powerSource: _enum(["mains", "battery"]).nullable(),
|
|
64741
65354
|
/**
|
|
64742
65355
|
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
64743
65356
|
* Providers convert from the days the feeder reports. Null when the
|
|
@@ -64801,7 +65414,9 @@ var petFeederCapability = {
|
|
|
64801
65414
|
kind: "mutation",
|
|
64802
65415
|
auth: "protected"
|
|
64803
65416
|
}),
|
|
64804
|
-
/**
|
|
65417
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
65418
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
65419
|
+
* change any sensor reading. */
|
|
64805
65420
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
64806
65421
|
kind: "mutation",
|
|
64807
65422
|
auth: "protected"
|
|
@@ -64874,6 +65489,7 @@ var petFeederCapability = {
|
|
|
64874
65489
|
*/
|
|
64875
65490
|
history: { fields: {
|
|
64876
65491
|
foodLevel: { kind: "gauge" },
|
|
65492
|
+
bowlFood: { kind: "gauge" },
|
|
64877
65493
|
food1: { kind: "gauge" },
|
|
64878
65494
|
food2: { kind: "gauge" },
|
|
64879
65495
|
batteryPower: {
|
|
@@ -65283,16 +65899,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
65283
65899
|
* in real-world devices.
|
|
65284
65900
|
*/
|
|
65285
65901
|
var PowerMeterStatusSchema = object({
|
|
65286
|
-
/** Instantaneous power draw
|
|
65287
|
-
|
|
65902
|
+
/** Instantaneous power draw (watts). */
|
|
65903
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
65288
65904
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65289
|
-
|
|
65290
|
-
/** Voltage
|
|
65291
|
-
|
|
65905
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65906
|
+
/** Voltage (volts). */
|
|
65907
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65292
65908
|
/** Current in amperes. */
|
|
65293
|
-
|
|
65909
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65294
65910
|
/** Apparent power in volt-amperes. */
|
|
65295
|
-
|
|
65911
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
65296
65912
|
/** Power factor (0..1) if reported. */
|
|
65297
65913
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
65298
65914
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -65350,14 +65966,14 @@ function powerTarget(id, unit) {
|
|
|
65350
65966
|
advancedExpression: true
|
|
65351
65967
|
};
|
|
65352
65968
|
}
|
|
65353
|
-
/** "Power and energy" extension:
|
|
65969
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
65354
65970
|
var powerMeterCustomize = {
|
|
65355
65971
|
version: 1,
|
|
65356
65972
|
targets: [
|
|
65357
|
-
powerTarget("
|
|
65358
|
-
powerTarget("
|
|
65359
|
-
powerTarget("
|
|
65360
|
-
powerTarget("
|
|
65973
|
+
powerTarget("power", "W"),
|
|
65974
|
+
powerTarget("energy", "kWh"),
|
|
65975
|
+
powerTarget("voltage", "V"),
|
|
65976
|
+
powerTarget("current", "A")
|
|
65361
65977
|
]
|
|
65362
65978
|
};
|
|
65363
65979
|
var powerMeterCapability = {
|
|
@@ -65373,41 +65989,41 @@ var powerMeterCapability = {
|
|
|
65373
65989
|
},
|
|
65374
65990
|
runtimeState: PowerMeterStatusSchema,
|
|
65375
65991
|
/**
|
|
65376
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
65992
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
65377
65993
|
*
|
|
65378
65994
|
* See `RuntimeStateDurability`. Enforced by
|
|
65379
65995
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65380
65996
|
*/
|
|
65381
65997
|
durability: "restored",
|
|
65382
65998
|
/**
|
|
65383
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
65999
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
65384
66000
|
*/
|
|
65385
66001
|
history: { fields: {
|
|
65386
|
-
|
|
66002
|
+
power: {
|
|
65387
66003
|
kind: "gauge",
|
|
65388
66004
|
unit: "W",
|
|
65389
66005
|
deadband: 1,
|
|
65390
66006
|
minIntervalMs: 3e4
|
|
65391
66007
|
},
|
|
65392
|
-
|
|
66008
|
+
energy: {
|
|
65393
66009
|
kind: "counter",
|
|
65394
66010
|
unit: "kWh",
|
|
65395
66011
|
deadband: .01,
|
|
65396
66012
|
minIntervalMs: 6e4
|
|
65397
66013
|
},
|
|
65398
|
-
|
|
66014
|
+
voltage: {
|
|
65399
66015
|
kind: "gauge",
|
|
65400
66016
|
unit: "V",
|
|
65401
66017
|
deadband: 1,
|
|
65402
66018
|
minIntervalMs: 3e4
|
|
65403
66019
|
},
|
|
65404
|
-
|
|
66020
|
+
current: {
|
|
65405
66021
|
kind: "gauge",
|
|
65406
66022
|
unit: "A",
|
|
65407
66023
|
deadband: .05,
|
|
65408
66024
|
minIntervalMs: 3e4
|
|
65409
66025
|
},
|
|
65410
|
-
|
|
66026
|
+
apparentPower: {
|
|
65411
66027
|
kind: "gauge",
|
|
65412
66028
|
unit: "VA",
|
|
65413
66029
|
deadband: 1,
|
|
@@ -65457,9 +66073,6 @@ var PresenceStatusSchema = object({
|
|
|
65457
66073
|
location: string().nullable(),
|
|
65458
66074
|
/** GPS coordinates when available. Null otherwise. */
|
|
65459
66075
|
gps: GpsLocationSchema.nullable(),
|
|
65460
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
65461
|
-
* when not reported. */
|
|
65462
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65463
66076
|
/** Ms epoch when the slice was last updated. */
|
|
65464
66077
|
lastChangedAt: number()
|
|
65465
66078
|
});
|
|
@@ -65488,14 +66101,7 @@ var presenceCapability = {
|
|
|
65488
66101
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65489
66102
|
*/
|
|
65490
66103
|
durability: "restored",
|
|
65491
|
-
|
|
65492
|
-
* History (D850): recorded series.
|
|
65493
|
-
*/
|
|
65494
|
-
history: { fields: { batteryPercent: {
|
|
65495
|
-
kind: "gauge",
|
|
65496
|
-
unit: "%",
|
|
65497
|
-
deadband: 1
|
|
65498
|
-
} } },
|
|
66104
|
+
history: "none",
|
|
65499
66105
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65500
66106
|
* whether persisting is worth a SQLite commit. */
|
|
65501
66107
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65510,7 +66116,7 @@ var presenceCapability = {
|
|
|
65510
66116
|
*/
|
|
65511
66117
|
var PressureSensorStatusSchema = object({
|
|
65512
66118
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65513
|
-
|
|
66119
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
65514
66120
|
/** Ms epoch when the slice was last updated. */
|
|
65515
66121
|
lastFetchedAt: number()
|
|
65516
66122
|
});
|
|
@@ -65536,7 +66142,7 @@ var pressureSensorCapability = {
|
|
|
65536
66142
|
/**
|
|
65537
66143
|
* History (D850): recorded series.
|
|
65538
66144
|
*/
|
|
65539
|
-
history: { fields: {
|
|
66145
|
+
history: { fields: { pressure: {
|
|
65540
66146
|
kind: "gauge",
|
|
65541
66147
|
unit: "hPa",
|
|
65542
66148
|
deadband: .1
|
|
@@ -69243,7 +69849,7 @@ var tamperCapability = {
|
|
|
69243
69849
|
*/
|
|
69244
69850
|
var TemperatureSensorStatusSchema = object({
|
|
69245
69851
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69246
|
-
|
|
69852
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
69247
69853
|
precision: 1,
|
|
69248
69854
|
label: "Temperature"
|
|
69249
69855
|
})),
|
|
@@ -69272,7 +69878,7 @@ var temperatureSensorCapability = {
|
|
|
69272
69878
|
/**
|
|
69273
69879
|
* History (D850): recorded series.
|
|
69274
69880
|
*/
|
|
69275
|
-
history: { fields: {
|
|
69881
|
+
history: { fields: { temperature: {
|
|
69276
69882
|
kind: "gauge",
|
|
69277
69883
|
unit: "°C",
|
|
69278
69884
|
deadband: .1
|
|
@@ -69569,7 +70175,7 @@ var VacuumControlStatusSchema = object({
|
|
|
69569
70175
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69570
70176
|
availableFanSpeeds: array(string()),
|
|
69571
70177
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69572
|
-
|
|
70178
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69573
70179
|
/** Current error code (0 / null = no error). */
|
|
69574
70180
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69575
70181
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -71658,7 +72264,7 @@ var BaseDevice = class {
|
|
|
71658
72264
|
* `device-local-state.ts`. Drivers access via:
|
|
71659
72265
|
*
|
|
71660
72266
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
71661
|
-
* `const pct = this.state.battery.
|
|
72267
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
71662
72268
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
71663
72269
|
*
|
|
71664
72270
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -71698,7 +72304,7 @@ var BaseDevice = class {
|
|
|
71698
72304
|
* shape; drivers don't redeclare it, they just write through.
|
|
71699
72305
|
*
|
|
71700
72306
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
71701
|
-
* `{
|
|
72307
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
71702
72308
|
* provider that registers `batteryCapability`.
|
|
71703
72309
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
71704
72310
|
*
|
|
@@ -72872,6 +73478,104 @@ Object.freeze({
|
|
|
72872
73478
|
access: "create",
|
|
72873
73479
|
role: "admin"
|
|
72874
73480
|
},
|
|
73481
|
+
"actions.create": {
|
|
73482
|
+
capName: "actions",
|
|
73483
|
+
capScope: "system",
|
|
73484
|
+
addonId: null,
|
|
73485
|
+
access: "create",
|
|
73486
|
+
role: "admin"
|
|
73487
|
+
},
|
|
73488
|
+
"actions.delete": {
|
|
73489
|
+
capName: "actions",
|
|
73490
|
+
capScope: "system",
|
|
73491
|
+
addonId: null,
|
|
73492
|
+
access: "delete",
|
|
73493
|
+
role: "admin"
|
|
73494
|
+
},
|
|
73495
|
+
"actions.get": {
|
|
73496
|
+
capName: "actions",
|
|
73497
|
+
capScope: "system",
|
|
73498
|
+
addonId: null,
|
|
73499
|
+
access: "view",
|
|
73500
|
+
role: "viewer"
|
|
73501
|
+
},
|
|
73502
|
+
"actions.getLinks": {
|
|
73503
|
+
capName: "actions",
|
|
73504
|
+
capScope: "system",
|
|
73505
|
+
addonId: null,
|
|
73506
|
+
access: "view",
|
|
73507
|
+
role: "admin"
|
|
73508
|
+
},
|
|
73509
|
+
"actions.getTraces": {
|
|
73510
|
+
capName: "actions",
|
|
73511
|
+
capScope: "system",
|
|
73512
|
+
addonId: null,
|
|
73513
|
+
access: "view",
|
|
73514
|
+
role: "admin"
|
|
73515
|
+
},
|
|
73516
|
+
"actions.list": {
|
|
73517
|
+
capName: "actions",
|
|
73518
|
+
capScope: "system",
|
|
73519
|
+
addonId: null,
|
|
73520
|
+
access: "view",
|
|
73521
|
+
role: "admin"
|
|
73522
|
+
},
|
|
73523
|
+
"actions.listForCamera": {
|
|
73524
|
+
capName: "actions",
|
|
73525
|
+
capScope: "system",
|
|
73526
|
+
addonId: null,
|
|
73527
|
+
access: "view",
|
|
73528
|
+
role: "viewer"
|
|
73529
|
+
},
|
|
73530
|
+
"actions.run": {
|
|
73531
|
+
capName: "actions",
|
|
73532
|
+
capScope: "system",
|
|
73533
|
+
addonId: null,
|
|
73534
|
+
access: "create",
|
|
73535
|
+
role: "viewer"
|
|
73536
|
+
},
|
|
73537
|
+
"actions.setLinks": {
|
|
73538
|
+
capName: "actions",
|
|
73539
|
+
capScope: "system",
|
|
73540
|
+
addonId: null,
|
|
73541
|
+
access: "create",
|
|
73542
|
+
role: "admin"
|
|
73543
|
+
},
|
|
73544
|
+
"actions.stop": {
|
|
73545
|
+
capName: "actions",
|
|
73546
|
+
capScope: "system",
|
|
73547
|
+
addonId: null,
|
|
73548
|
+
access: "create",
|
|
73549
|
+
role: "admin"
|
|
73550
|
+
},
|
|
73551
|
+
"actions.update": {
|
|
73552
|
+
capName: "actions",
|
|
73553
|
+
capScope: "system",
|
|
73554
|
+
addonId: null,
|
|
73555
|
+
access: "create",
|
|
73556
|
+
role: "admin"
|
|
73557
|
+
},
|
|
73558
|
+
"actionSource.listActions": {
|
|
73559
|
+
capName: "action-source",
|
|
73560
|
+
capScope: "system",
|
|
73561
|
+
addonId: null,
|
|
73562
|
+
access: "view",
|
|
73563
|
+
role: "admin"
|
|
73564
|
+
},
|
|
73565
|
+
"actionSource.runAction": {
|
|
73566
|
+
capName: "action-source",
|
|
73567
|
+
capScope: "system",
|
|
73568
|
+
addonId: null,
|
|
73569
|
+
access: "create",
|
|
73570
|
+
role: "admin"
|
|
73571
|
+
},
|
|
73572
|
+
"actionSource.stopAction": {
|
|
73573
|
+
capName: "action-source",
|
|
73574
|
+
capScope: "system",
|
|
73575
|
+
addonId: null,
|
|
73576
|
+
access: "create",
|
|
73577
|
+
role: "admin"
|
|
73578
|
+
},
|
|
72875
73579
|
"addonPages.listPages": {
|
|
72876
73580
|
capName: "addon-pages",
|
|
72877
73581
|
capScope: "system",
|
|
@@ -74153,6 +74857,13 @@ Object.freeze({
|
|
|
74153
74857
|
access: "view",
|
|
74154
74858
|
role: "admin"
|
|
74155
74859
|
},
|
|
74860
|
+
"coreBlocks.getAutomationRunState": {
|
|
74861
|
+
capName: "core-blocks",
|
|
74862
|
+
capScope: "system",
|
|
74863
|
+
addonId: null,
|
|
74864
|
+
access: "view",
|
|
74865
|
+
role: "admin"
|
|
74866
|
+
},
|
|
74156
74867
|
"coreBlocks.getBlockSettings": {
|
|
74157
74868
|
capName: "core-blocks",
|
|
74158
74869
|
capScope: "system",
|
|
@@ -74174,6 +74885,13 @@ Object.freeze({
|
|
|
74174
74885
|
access: "view",
|
|
74175
74886
|
role: "admin"
|
|
74176
74887
|
},
|
|
74888
|
+
"coreBlocks.getTraces": {
|
|
74889
|
+
capName: "core-blocks",
|
|
74890
|
+
capScope: "system",
|
|
74891
|
+
addonId: null,
|
|
74892
|
+
access: "view",
|
|
74893
|
+
role: "admin"
|
|
74894
|
+
},
|
|
74177
74895
|
"coreBlocks.getTypeDefs": {
|
|
74178
74896
|
capName: "core-blocks",
|
|
74179
74897
|
capScope: "system",
|
|
@@ -74209,6 +74927,13 @@ Object.freeze({
|
|
|
74209
74927
|
access: "create",
|
|
74210
74928
|
role: "admin"
|
|
74211
74929
|
},
|
|
74930
|
+
"coreBlocks.reportAutomationRun": {
|
|
74931
|
+
capName: "core-blocks",
|
|
74932
|
+
capScope: "system",
|
|
74933
|
+
addonId: null,
|
|
74934
|
+
access: "create",
|
|
74935
|
+
role: "admin"
|
|
74936
|
+
},
|
|
74212
74937
|
"coreBlocks.restart": {
|
|
74213
74938
|
capName: "core-blocks",
|
|
74214
74939
|
capScope: "system",
|
|
@@ -76288,6 +77013,20 @@ Object.freeze({
|
|
|
76288
77013
|
access: "create",
|
|
76289
77014
|
role: "viewer"
|
|
76290
77015
|
},
|
|
77016
|
+
"irTransmitter.getInfo": {
|
|
77017
|
+
capName: "ir-transmitter",
|
|
77018
|
+
capScope: "device",
|
|
77019
|
+
addonId: null,
|
|
77020
|
+
access: "view",
|
|
77021
|
+
role: "viewer"
|
|
77022
|
+
},
|
|
77023
|
+
"irTransmitter.send": {
|
|
77024
|
+
capName: "ir-transmitter",
|
|
77025
|
+
capScope: "device",
|
|
77026
|
+
addonId: null,
|
|
77027
|
+
access: "create",
|
|
77028
|
+
role: "viewer"
|
|
77029
|
+
},
|
|
76291
77030
|
"keychain.delete": {
|
|
76292
77031
|
capName: "keychain",
|
|
76293
77032
|
capScope: "system",
|
|
@@ -82782,7 +83521,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82782
83521
|
label: t("Full brightness", "Luminosità massima"),
|
|
82783
83522
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
82784
83523
|
icon: "sun",
|
|
82785
|
-
args: {
|
|
83524
|
+
args: { level: 100 }
|
|
82786
83525
|
},
|
|
82787
83526
|
{
|
|
82788
83527
|
id: "brightness.half",
|
|
@@ -82790,7 +83529,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82790
83529
|
label: t("Half brightness", "Luminosità a metà"),
|
|
82791
83530
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
82792
83531
|
icon: "sun-dim",
|
|
82793
|
-
args: {
|
|
83532
|
+
args: { level: 50 }
|
|
82794
83533
|
},
|
|
82795
83534
|
{
|
|
82796
83535
|
id: "brightness.off",
|
|
@@ -82798,16 +83537,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82798
83537
|
label: t("Brightness off", "Luminosità a zero"),
|
|
82799
83538
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
82800
83539
|
icon: "lightbulb-off",
|
|
82801
|
-
args: {
|
|
83540
|
+
args: { level: 0 }
|
|
82802
83541
|
},
|
|
82803
83542
|
{
|
|
82804
83543
|
id: "brightness.set",
|
|
82805
83544
|
method: "setBrightness",
|
|
82806
83545
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
82807
|
-
phrase: t("Set the brightness of {device} to {
|
|
83546
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
82808
83547
|
icon: "sun-medium",
|
|
82809
83548
|
openArgs: [{
|
|
82810
|
-
key: "
|
|
83549
|
+
key: "level",
|
|
82811
83550
|
label: PERCENT,
|
|
82812
83551
|
offer: {
|
|
82813
83552
|
kind: "number",
|
|
@@ -82821,13 +83560,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82821
83560
|
],
|
|
82822
83561
|
state: [{
|
|
82823
83562
|
kind: "numeric",
|
|
82824
|
-
field: "
|
|
83563
|
+
field: "level",
|
|
82825
83564
|
quantity: t("the brightness", "la luminosità"),
|
|
82826
83565
|
label: t("Brightness", "Luminosità"),
|
|
82827
83566
|
unit: "%",
|
|
82828
83567
|
icon: "sun"
|
|
82829
83568
|
}],
|
|
82830
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
83569
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
82831
83570
|
},
|
|
82832
83571
|
color: {
|
|
82833
83572
|
scope: "device",
|
|
@@ -82841,7 +83580,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82841
83580
|
icon: "sun",
|
|
82842
83581
|
args: { color: {
|
|
82843
83582
|
mode: "mired",
|
|
82844
|
-
|
|
83583
|
+
colorTemperature: 370
|
|
82845
83584
|
} }
|
|
82846
83585
|
},
|
|
82847
83586
|
{
|
|
@@ -82852,7 +83591,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82852
83591
|
icon: "snowflake",
|
|
82853
83592
|
args: { color: {
|
|
82854
83593
|
mode: "mired",
|
|
82855
|
-
|
|
83594
|
+
colorTemperature: 200
|
|
82856
83595
|
} }
|
|
82857
83596
|
},
|
|
82858
83597
|
{
|
|
@@ -83466,7 +84205,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83466
84205
|
label: t("Fan off", "Ventilatore spento"),
|
|
83467
84206
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
83468
84207
|
icon: "power-off",
|
|
83469
|
-
args: {
|
|
84208
|
+
args: { speed: 0 }
|
|
83470
84209
|
},
|
|
83471
84210
|
{
|
|
83472
84211
|
id: "fan.full",
|
|
@@ -83474,16 +84213,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83474
84213
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
83475
84214
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
83476
84215
|
icon: "fan",
|
|
83477
|
-
args: {
|
|
84216
|
+
args: { speed: 100 }
|
|
83478
84217
|
},
|
|
83479
84218
|
{
|
|
83480
84219
|
id: "fan.speed",
|
|
83481
84220
|
method: "setPercentage",
|
|
83482
84221
|
label: t("Set speed", "Imposta la velocità"),
|
|
83483
|
-
phrase: t("Set the speed of {device} to {
|
|
84222
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
83484
84223
|
icon: "fan",
|
|
83485
84224
|
openArgs: [{
|
|
83486
|
-
key: "
|
|
84225
|
+
key: "speed",
|
|
83487
84226
|
label: t("Speed", "Velocità"),
|
|
83488
84227
|
offer: {
|
|
83489
84228
|
kind: "number",
|
|
@@ -83545,7 +84284,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83545
84284
|
],
|
|
83546
84285
|
state: [{
|
|
83547
84286
|
kind: "numeric",
|
|
83548
|
-
field: "
|
|
84287
|
+
field: "speed",
|
|
83549
84288
|
quantity: t("the speed", "la velocità"),
|
|
83550
84289
|
label: t("Speed", "Velocità"),
|
|
83551
84290
|
unit: "%",
|
|
@@ -83911,6 +84650,11 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83911
84650
|
icon: "circle-dot"
|
|
83912
84651
|
}]
|
|
83913
84652
|
},
|
|
84653
|
+
"ir-transmitter": {
|
|
84654
|
+
scope: "device",
|
|
84655
|
+
noun: t("IR / RF transmitter", "Trasmettitore IR / RF"),
|
|
84656
|
+
notOperatorFacing: { send: "a raw pulse train is not something an operator composes in an automation; the remote that owns the command table sends it" }
|
|
84657
|
+
},
|
|
83914
84658
|
control: {
|
|
83915
84659
|
scope: "device",
|
|
83916
84660
|
noun: t("Control", "Controllo"),
|
|
@@ -84343,7 +85087,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84343
85087
|
},
|
|
84344
85088
|
{
|
|
84345
85089
|
kind: "numeric",
|
|
84346
|
-
field: "
|
|
85090
|
+
field: "progress",
|
|
84347
85091
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
84348
85092
|
label: t("Progress", "Avanzamento"),
|
|
84349
85093
|
unit: "%",
|
|
@@ -84701,10 +85445,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84701
85445
|
id: "media.seek",
|
|
84702
85446
|
method: "seek",
|
|
84703
85447
|
label: t("Seek", "Vai al punto"),
|
|
84704
|
-
phrase: t("Move {device} to {
|
|
85448
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
84705
85449
|
icon: "fast-forward",
|
|
84706
85450
|
openArgs: [{
|
|
84707
|
-
key: "
|
|
85451
|
+
key: "position",
|
|
84708
85452
|
label: t("Position", "Posizione"),
|
|
84709
85453
|
offer: {
|
|
84710
85454
|
kind: "number",
|
|
@@ -85753,7 +86497,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85753
86497
|
state: [
|
|
85754
86498
|
{
|
|
85755
86499
|
kind: "numeric",
|
|
85756
|
-
field: "
|
|
86500
|
+
field: "co2",
|
|
85757
86501
|
quantity: t("the CO₂", "la CO₂"),
|
|
85758
86502
|
label: t("CO₂", "CO₂"),
|
|
85759
86503
|
unit: "ppm",
|
|
@@ -85761,7 +86505,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85761
86505
|
},
|
|
85762
86506
|
{
|
|
85763
86507
|
kind: "numeric",
|
|
85764
|
-
field: "
|
|
86508
|
+
field: "voc",
|
|
85765
86509
|
quantity: t("the VOC level", "il livello di COV"),
|
|
85766
86510
|
label: t("VOC", "COV"),
|
|
85767
86511
|
unit: "ppb",
|
|
@@ -85797,7 +86541,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85797
86541
|
noun: t("Light level", "Luminosità ambiente"),
|
|
85798
86542
|
state: [{
|
|
85799
86543
|
kind: "numeric",
|
|
85800
|
-
field: "
|
|
86544
|
+
field: "illuminance",
|
|
85801
86545
|
quantity: t("the light level", "la luminosità"),
|
|
85802
86546
|
label: t("Illuminance", "Illuminamento"),
|
|
85803
86547
|
unit: "lx",
|
|
@@ -86000,7 +86744,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86000
86744
|
noun: t("Humidity", "Umidità"),
|
|
86001
86745
|
state: [{
|
|
86002
86746
|
kind: "numeric",
|
|
86003
|
-
field: "
|
|
86747
|
+
field: "humidity",
|
|
86004
86748
|
quantity: t("the humidity", "l’umidità"),
|
|
86005
86749
|
label: t("Humidity", "Umidità"),
|
|
86006
86750
|
unit: "%",
|
|
@@ -86048,7 +86792,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86048
86792
|
state: [
|
|
86049
86793
|
{
|
|
86050
86794
|
kind: "numeric",
|
|
86051
|
-
field: "
|
|
86795
|
+
field: "power",
|
|
86052
86796
|
quantity: t("the power draw", "il consumo"),
|
|
86053
86797
|
label: t("Power", "Potenza"),
|
|
86054
86798
|
unit: "W",
|
|
@@ -86056,7 +86800,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86056
86800
|
},
|
|
86057
86801
|
{
|
|
86058
86802
|
kind: "numeric",
|
|
86059
|
-
field: "
|
|
86803
|
+
field: "energy",
|
|
86060
86804
|
quantity: t("the energy used", "l’energia consumata"),
|
|
86061
86805
|
label: t("Energy", "Energia"),
|
|
86062
86806
|
unit: "kWh",
|
|
@@ -86064,7 +86808,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86064
86808
|
},
|
|
86065
86809
|
{
|
|
86066
86810
|
kind: "numeric",
|
|
86067
|
-
field: "
|
|
86811
|
+
field: "voltage",
|
|
86068
86812
|
quantity: t("the voltage", "la tensione"),
|
|
86069
86813
|
label: t("Voltage", "Tensione"),
|
|
86070
86814
|
unit: "V",
|
|
@@ -86072,7 +86816,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86072
86816
|
},
|
|
86073
86817
|
{
|
|
86074
86818
|
kind: "numeric",
|
|
86075
|
-
field: "
|
|
86819
|
+
field: "current",
|
|
86076
86820
|
quantity: t("the current", "la corrente"),
|
|
86077
86821
|
label: t("Current", "Corrente"),
|
|
86078
86822
|
unit: "A",
|
|
@@ -86089,13 +86833,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86089
86833
|
label: t("Where", "Posizione"),
|
|
86090
86834
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
86091
86835
|
icon: "map-pin"
|
|
86092
|
-
}, {
|
|
86093
|
-
kind: "numeric",
|
|
86094
|
-
field: "batteryPercent",
|
|
86095
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
86096
|
-
label: t("Battery", "Batteria"),
|
|
86097
|
-
unit: "%",
|
|
86098
|
-
icon: "battery"
|
|
86099
86836
|
}]
|
|
86100
86837
|
},
|
|
86101
86838
|
"pressure-sensor": {
|
|
@@ -86103,7 +86840,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86103
86840
|
noun: t("Pressure", "Pressione"),
|
|
86104
86841
|
state: [{
|
|
86105
86842
|
kind: "numeric",
|
|
86106
|
-
field: "
|
|
86843
|
+
field: "pressure",
|
|
86107
86844
|
quantity: t("the pressure", "la pressione"),
|
|
86108
86845
|
label: t("Pressure", "Pressione"),
|
|
86109
86846
|
unit: "hPa",
|
|
@@ -86139,7 +86876,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86139
86876
|
noun: t("Temperature", "Temperatura"),
|
|
86140
86877
|
state: [{
|
|
86141
86878
|
kind: "numeric",
|
|
86142
|
-
field: "
|
|
86879
|
+
field: "temperature",
|
|
86143
86880
|
quantity: t("the temperature", "la temperatura"),
|
|
86144
86881
|
label: t("Temperature", "Temperatura"),
|
|
86145
86882
|
unit: "°C",
|
|
@@ -86210,7 +86947,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86210
86947
|
state: [
|
|
86211
86948
|
{
|
|
86212
86949
|
kind: "numeric",
|
|
86213
|
-
field: "
|
|
86950
|
+
field: "level",
|
|
86214
86951
|
quantity: t("the battery level", "il livello della batteria"),
|
|
86215
86952
|
label: t("Battery", "Batteria"),
|
|
86216
86953
|
unit: "%",
|
|
@@ -86252,7 +86989,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86252
86989
|
icon: "battery-charging"
|
|
86253
86990
|
}
|
|
86254
86991
|
],
|
|
86255
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
86992
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
86256
86993
|
extraEvents: [{
|
|
86257
86994
|
category: EventCategory.DeviceAwake,
|
|
86258
86995
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -86270,7 +87007,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86270
87007
|
noun: t("Network link", "Collegamento di rete"),
|
|
86271
87008
|
state: [{
|
|
86272
87009
|
kind: "numeric",
|
|
86273
|
-
field: "
|
|
87010
|
+
field: "signal",
|
|
86274
87011
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
86275
87012
|
label: t("Signal", "Segnale"),
|
|
86276
87013
|
unit: "%",
|
|
@@ -86363,6 +87100,8 @@ var ML = "model and training machinery — no device action";
|
|
|
86363
87100
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
86364
87101
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
86365
87102
|
var SYSTEM_CAP_VOCABULARY = {
|
|
87103
|
+
"action-source": system(INTERNAL),
|
|
87104
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
86366
87105
|
"addon-pages": system(UI_PLUMBING),
|
|
86367
87106
|
"addon-pages-source": system(UI_PLUMBING),
|
|
86368
87107
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -86570,6 +87309,31 @@ Object.freeze({
|
|
|
86570
87309
|
form: "single",
|
|
86571
87310
|
optional: false
|
|
86572
87311
|
}],
|
|
87312
|
+
"actions.get": [{
|
|
87313
|
+
name: "deviceId",
|
|
87314
|
+
form: "single",
|
|
87315
|
+
optional: true
|
|
87316
|
+
}],
|
|
87317
|
+
"actions.getLinks": [{
|
|
87318
|
+
name: "deviceId",
|
|
87319
|
+
form: "single",
|
|
87320
|
+
optional: false
|
|
87321
|
+
}],
|
|
87322
|
+
"actions.listForCamera": [{
|
|
87323
|
+
name: "deviceId",
|
|
87324
|
+
form: "single",
|
|
87325
|
+
optional: false
|
|
87326
|
+
}],
|
|
87327
|
+
"actions.run": [{
|
|
87328
|
+
name: "deviceId",
|
|
87329
|
+
form: "single",
|
|
87330
|
+
optional: true
|
|
87331
|
+
}],
|
|
87332
|
+
"actions.setLinks": [{
|
|
87333
|
+
name: "deviceId",
|
|
87334
|
+
form: "single",
|
|
87335
|
+
optional: false
|
|
87336
|
+
}],
|
|
86573
87337
|
"addonSettings.getDeviceSettings": [{
|
|
86574
87338
|
name: "deviceId",
|
|
86575
87339
|
form: "single",
|
|
@@ -87621,6 +88385,16 @@ Object.freeze({
|
|
|
87621
88385
|
form: "single",
|
|
87622
88386
|
optional: false
|
|
87623
88387
|
}],
|
|
88388
|
+
"irTransmitter.getInfo": [{
|
|
88389
|
+
name: "deviceId",
|
|
88390
|
+
form: "single",
|
|
88391
|
+
optional: false
|
|
88392
|
+
}],
|
|
88393
|
+
"irTransmitter.send": [{
|
|
88394
|
+
name: "deviceId",
|
|
88395
|
+
form: "single",
|
|
88396
|
+
optional: false
|
|
88397
|
+
}],
|
|
87624
88398
|
"keychain.deleteDeviceScope": [{
|
|
87625
88399
|
name: "deviceId",
|
|
87626
88400
|
form: "single",
|
|
@@ -91000,7 +91774,24 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
|
|
|
91000
91774
|
}
|
|
91001
91775
|
return best;
|
|
91002
91776
|
}
|
|
91777
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
91003
91778
|
var MB = 1024 * 1024;
|
|
91004
91779
|
1024 * MB, 3072 * MB;
|
|
91780
|
+
discriminatedUnion("kind", [object({
|
|
91781
|
+
kind: literal("raw"),
|
|
91782
|
+
timings: array(number().int()),
|
|
91783
|
+
settings: TransmitSettingsSchema.optional()
|
|
91784
|
+
}), object({
|
|
91785
|
+
kind: literal("pronto"),
|
|
91786
|
+
code: string()
|
|
91787
|
+
})]);
|
|
91788
|
+
object({
|
|
91789
|
+
manufacturer: string().optional(),
|
|
91790
|
+
supportedModels: array(string()).optional(),
|
|
91791
|
+
supportedController: string().optional(),
|
|
91792
|
+
commandsEncoding: string(),
|
|
91793
|
+
delay: number().nonnegative().optional(),
|
|
91794
|
+
commands: record(string(), unknown())
|
|
91795
|
+
});
|
|
91005
91796
|
//#endregion
|
|
91006
91797
|
export { lawnMowerControlCapability as $, union as $t, buttonCapability as A, weatherCapability as At, coverCapability as B, defineRecordKinds as Bt, batteryCapability as C, tryConvertDelta as Ct, brokerCapability as D, valveCapability as Dt, brightnessCapability as E, vacuumControlCapability as Et, connectivityCapability as F, BaseAddon as Ft, eventEmitterCapability as G, array as Gt, deviceAdoptionCapability as H, isReadingQuantity as Ht, consumableFormOf as I, RecordSecretUnavailableError as It, gasCapability as J, literal as Jt, fanControlCapability as K, boolean as Kt, consumableKindOf as L, baseUnitOf as Lt, carbonMonoxideCapability as M, DeviceRole as Mt, climateControlCapability as N, DeviceType as Nt, buildAddonRouteProvider as O, vibrationCapability as Ot, colorCapability as P, errMsg as Pt, ingestReading as Q, string as Qt, contactCapability as R, createEvent as Rt, automationControlCapability as S, temperatureSensorCapability as St, binaryCapability as T, updateCapability as Tt, deviceExportCapability as U, nodePin as Ut, deviceAdminLinkCapability as V, entryBody as Vt, enumSensorCapability as W, _enum as Wt, humiditySensorCapability as X, object as Xt, humidifierCapability as Y, number as Yt, imageCapability as Z, record as Zt, accessoriesCapability as _, runningStateCapability as _t, COCO_TO_MACRO as a, notifierCapability as at, alarmPanelCapability as b, switchCapability as bt, ConsumableItemSchema as c, parseAdminBase as ct, FanDirectionSchema as d, presenceCapability as dt, unknown as en, lockControlCapability as et, HvacModeSchema as f, pressureSensorCapability as ft, TargetSchema as g, runningFromVacuumState as gt, RUNNING_STATE_COLD as h, runningFromMediaPlayer as ht, CAMERA_SWITCH_ORDER as i, notificationOutputCapability as it, calendarSourceCapability as j, DeviceFeature as jt, buildDeviceAdminUrl as k, waterHeaterCapability as kt, ConsumableStatusSchema as l, powerMeterCapability as lt, PLUG_APPLIANCE_TYPES as m, runningFromLawnMower as mt, BaseDevice as n, EventCategory as nn, motionCapability as nt, CameraSwitchIdSchema as o, numericSensorCapability as ot, MediaPlayerRepeatSchema as p, quantityFromUnit as pt, floodCapability as q, discriminatedUnion as qt, BaseDeviceProvider as r, normalizeUnit as rt, ConsumableFormSchema as s, oauthIntegrationCapability as st, AlarmArmModeSchema as t, url as tn, mediaPlayerCapability as tt, EnumSensorDateTimeFormatSchema as u, prepareNotification as ut, addonRoutesCapability as v, scriptRunnerCapability as vt, bestLocationMatch as w, tryConvertUnit as wt, ambientLightSensorCapability as x, tamperCapability as xt, airQualitySensorCapability as y, smokeCapability as yt, controlCapability as z, defineEntryKind as zt };
|