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