@camstack/addon-provider-homeassistant 1.2.632 → 1.2.634
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 +16 -1
- package/README.md +31 -11
- package/dist/addon.js +83 -60
- package/dist/addon.mjs +83 -60
- package/dist/{dist-CPkvghX8.mjs → dist-6sCUdAUD.mjs} +845 -240
- package/dist/{dist-D0ZiJUPy.js → dist-DSRitvmZ.js} +845 -240
- package/dist/ha-export/ha-export.addon.js +24 -24
- package/dist/ha-export/ha-export.addon.mjs +24 -24
- package/package.json +2 -2
|
@@ -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-Crlmu_tO.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",
|
|
@@ -9133,11 +9140,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
9133
9140
|
Object.freeze({
|
|
9134
9141
|
"air-quality-sensor": [
|
|
9135
9142
|
{
|
|
9136
|
-
"path": "
|
|
9143
|
+
"path": "co2",
|
|
9137
9144
|
"valueType": "number"
|
|
9138
9145
|
},
|
|
9139
9146
|
{
|
|
9140
|
-
"path": "
|
|
9147
|
+
"path": "voc",
|
|
9141
9148
|
"valueType": "number"
|
|
9142
9149
|
},
|
|
9143
9150
|
{
|
|
@@ -9187,7 +9194,7 @@ Object.freeze({
|
|
|
9187
9194
|
}
|
|
9188
9195
|
],
|
|
9189
9196
|
"ambient-light-sensor": [{
|
|
9190
|
-
"path": "
|
|
9197
|
+
"path": "illuminance",
|
|
9191
9198
|
"valueType": "number"
|
|
9192
9199
|
}],
|
|
9193
9200
|
"audio-metrics": [
|
|
@@ -9248,7 +9255,7 @@ Object.freeze({
|
|
|
9248
9255
|
],
|
|
9249
9256
|
"battery": [
|
|
9250
9257
|
{
|
|
9251
|
-
"path": "
|
|
9258
|
+
"path": "level",
|
|
9252
9259
|
"valueType": "number"
|
|
9253
9260
|
},
|
|
9254
9261
|
{
|
|
@@ -9270,7 +9277,7 @@ Object.freeze({
|
|
|
9270
9277
|
"valueType": "number"
|
|
9271
9278
|
},
|
|
9272
9279
|
{
|
|
9273
|
-
"path": "
|
|
9280
|
+
"path": "voltage",
|
|
9274
9281
|
"valueType": "number"
|
|
9275
9282
|
},
|
|
9276
9283
|
{
|
|
@@ -9291,7 +9298,7 @@ Object.freeze({
|
|
|
9291
9298
|
"valueType": "boolean"
|
|
9292
9299
|
}],
|
|
9293
9300
|
"brightness": [{
|
|
9294
|
-
"path": "
|
|
9301
|
+
"path": "level",
|
|
9295
9302
|
"valueType": "number"
|
|
9296
9303
|
}],
|
|
9297
9304
|
"broker": [{
|
|
@@ -9492,7 +9499,7 @@ Object.freeze({
|
|
|
9492
9499
|
"valueType": "number"
|
|
9493
9500
|
},
|
|
9494
9501
|
{
|
|
9495
|
-
"path": "
|
|
9502
|
+
"path": "colorTemperature",
|
|
9496
9503
|
"valueType": "number"
|
|
9497
9504
|
}
|
|
9498
9505
|
],
|
|
@@ -9671,15 +9678,15 @@ Object.freeze({
|
|
|
9671
9678
|
"valueType": "string"
|
|
9672
9679
|
},
|
|
9673
9680
|
{
|
|
9674
|
-
"path": "
|
|
9681
|
+
"path": "remaining",
|
|
9675
9682
|
"valueType": "number"
|
|
9676
9683
|
},
|
|
9677
9684
|
{
|
|
9678
|
-
"path": "
|
|
9685
|
+
"path": "delayedStart",
|
|
9679
9686
|
"valueType": "number"
|
|
9680
9687
|
},
|
|
9681
9688
|
{
|
|
9682
|
-
"path": "
|
|
9689
|
+
"path": "progress",
|
|
9683
9690
|
"valueType": "number"
|
|
9684
9691
|
},
|
|
9685
9692
|
{
|
|
@@ -9793,7 +9800,7 @@ Object.freeze({
|
|
|
9793
9800
|
],
|
|
9794
9801
|
"fan-control": [
|
|
9795
9802
|
{
|
|
9796
|
-
"path": "
|
|
9803
|
+
"path": "speed",
|
|
9797
9804
|
"valueType": "number"
|
|
9798
9805
|
},
|
|
9799
9806
|
{
|
|
@@ -9893,7 +9900,7 @@ Object.freeze({
|
|
|
9893
9900
|
}
|
|
9894
9901
|
],
|
|
9895
9902
|
"humidity-sensor": [{
|
|
9896
|
-
"path": "
|
|
9903
|
+
"path": "humidity",
|
|
9897
9904
|
"valueType": "number"
|
|
9898
9905
|
}],
|
|
9899
9906
|
"image": [{
|
|
@@ -10003,7 +10010,7 @@ Object.freeze({
|
|
|
10003
10010
|
"valueType": "number"
|
|
10004
10011
|
},
|
|
10005
10012
|
{
|
|
10006
|
-
"path": "
|
|
10013
|
+
"path": "progress",
|
|
10007
10014
|
"valueType": "number"
|
|
10008
10015
|
},
|
|
10009
10016
|
{
|
|
@@ -10082,11 +10089,11 @@ Object.freeze({
|
|
|
10082
10089
|
"valueType": "string"
|
|
10083
10090
|
},
|
|
10084
10091
|
{
|
|
10085
|
-
"path": "
|
|
10092
|
+
"path": "position",
|
|
10086
10093
|
"valueType": "number"
|
|
10087
10094
|
},
|
|
10088
10095
|
{
|
|
10089
|
-
"path": "
|
|
10096
|
+
"path": "duration",
|
|
10090
10097
|
"valueType": "number"
|
|
10091
10098
|
},
|
|
10092
10099
|
{
|
|
@@ -10188,11 +10195,11 @@ Object.freeze({
|
|
|
10188
10195
|
]
|
|
10189
10196
|
},
|
|
10190
10197
|
{
|
|
10191
|
-
"path": "
|
|
10198
|
+
"path": "signal",
|
|
10192
10199
|
"valueType": "number"
|
|
10193
10200
|
},
|
|
10194
10201
|
{
|
|
10195
|
-
"path": "
|
|
10202
|
+
"path": "rssi",
|
|
10196
10203
|
"valueType": "number"
|
|
10197
10204
|
},
|
|
10198
10205
|
{
|
|
@@ -10247,6 +10254,18 @@ Object.freeze({
|
|
|
10247
10254
|
"path": "foodLevel",
|
|
10248
10255
|
"valueType": "number"
|
|
10249
10256
|
},
|
|
10257
|
+
{
|
|
10258
|
+
"path": "bowlFood",
|
|
10259
|
+
"valueType": "number"
|
|
10260
|
+
},
|
|
10261
|
+
{
|
|
10262
|
+
"path": "eating",
|
|
10263
|
+
"valueType": "boolean"
|
|
10264
|
+
},
|
|
10265
|
+
{
|
|
10266
|
+
"path": "supportsMarkRefilled",
|
|
10267
|
+
"valueType": "boolean"
|
|
10268
|
+
},
|
|
10250
10269
|
{
|
|
10251
10270
|
"path": "food1",
|
|
10252
10271
|
"valueType": "number"
|
|
@@ -10311,23 +10330,23 @@ Object.freeze({
|
|
|
10311
10330
|
],
|
|
10312
10331
|
"power-meter": [
|
|
10313
10332
|
{
|
|
10314
|
-
"path": "
|
|
10333
|
+
"path": "power",
|
|
10315
10334
|
"valueType": "number"
|
|
10316
10335
|
},
|
|
10317
10336
|
{
|
|
10318
|
-
"path": "
|
|
10337
|
+
"path": "energy",
|
|
10319
10338
|
"valueType": "number"
|
|
10320
10339
|
},
|
|
10321
10340
|
{
|
|
10322
|
-
"path": "
|
|
10341
|
+
"path": "voltage",
|
|
10323
10342
|
"valueType": "number"
|
|
10324
10343
|
},
|
|
10325
10344
|
{
|
|
10326
|
-
"path": "
|
|
10345
|
+
"path": "current",
|
|
10327
10346
|
"valueType": "number"
|
|
10328
10347
|
},
|
|
10329
10348
|
{
|
|
10330
|
-
"path": "
|
|
10349
|
+
"path": "apparentPower",
|
|
10331
10350
|
"valueType": "number"
|
|
10332
10351
|
},
|
|
10333
10352
|
{
|
|
@@ -10355,14 +10374,10 @@ Object.freeze({
|
|
|
10355
10374
|
{
|
|
10356
10375
|
"path": "gps.accuracyMeters",
|
|
10357
10376
|
"valueType": "number"
|
|
10358
|
-
},
|
|
10359
|
-
{
|
|
10360
|
-
"path": "batteryPercent",
|
|
10361
|
-
"valueType": "number"
|
|
10362
10377
|
}
|
|
10363
10378
|
],
|
|
10364
10379
|
"pressure-sensor": [{
|
|
10365
|
-
"path": "
|
|
10380
|
+
"path": "pressure",
|
|
10366
10381
|
"valueType": "number"
|
|
10367
10382
|
}],
|
|
10368
10383
|
"privacy-mask": [{
|
|
@@ -10676,7 +10691,7 @@ Object.freeze({
|
|
|
10676
10691
|
"valueType": "boolean"
|
|
10677
10692
|
}],
|
|
10678
10693
|
"temperature-sensor": [{
|
|
10679
|
-
"path": "
|
|
10694
|
+
"path": "temperature",
|
|
10680
10695
|
"valueType": "number"
|
|
10681
10696
|
}],
|
|
10682
10697
|
"update": [
|
|
@@ -10724,7 +10739,7 @@ Object.freeze({
|
|
|
10724
10739
|
"valueType": "string"
|
|
10725
10740
|
},
|
|
10726
10741
|
{
|
|
10727
|
-
"path": "
|
|
10742
|
+
"path": "progress",
|
|
10728
10743
|
"valueType": "number"
|
|
10729
10744
|
},
|
|
10730
10745
|
{
|
|
@@ -11209,7 +11224,7 @@ function errMsg(err) {
|
|
|
11209
11224
|
return String(err);
|
|
11210
11225
|
}
|
|
11211
11226
|
//#endregion
|
|
11212
|
-
//#region ../types/dist/composition-
|
|
11227
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
11213
11228
|
/**
|
|
11214
11229
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11215
11230
|
*
|
|
@@ -15873,6 +15888,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
15873
15888
|
array(union([string(), number()]))
|
|
15874
15889
|
])
|
|
15875
15890
|
});
|
|
15891
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
15892
|
+
kind: literal("stationary-present"),
|
|
15893
|
+
deviceId: number().int().nonnegative(),
|
|
15894
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
15895
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15896
|
+
/** The parked object must be in at least one of these zones. */
|
|
15897
|
+
zones: array(string().min(1)).min(1).optional()
|
|
15898
|
+
});
|
|
15876
15899
|
/**
|
|
15877
15900
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
15878
15901
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -15906,7 +15929,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
15906
15929
|
child: AutomationConditionSchema
|
|
15907
15930
|
}),
|
|
15908
15931
|
AutomationConditionLeafSchema,
|
|
15909
|
-
AutomationConditionExpressionSchema
|
|
15932
|
+
AutomationConditionExpressionSchema,
|
|
15933
|
+
AutomationConditionStationaryPresentSchema
|
|
15910
15934
|
]));
|
|
15911
15935
|
/**
|
|
15912
15936
|
* What starts a run.
|
|
@@ -15947,7 +15971,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15947
15971
|
kind: literal("schedule"),
|
|
15948
15972
|
cron: string().min(1).max(120)
|
|
15949
15973
|
}),
|
|
15950
|
-
object({ kind: literal("manual") })
|
|
15974
|
+
object({ kind: literal("manual") }),
|
|
15975
|
+
object({
|
|
15976
|
+
kind: literal("detection"),
|
|
15977
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
15978
|
+
* matches every raw class that maps to it; any other name matches
|
|
15979
|
+
* exactly. */
|
|
15980
|
+
classes: array(string().min(1)).min(1),
|
|
15981
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15982
|
+
/** The track must have visited at least one of these zones. */
|
|
15983
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15984
|
+
/** Best-so-far confidence the track must reach. */
|
|
15985
|
+
minScore: number().min(0).max(1).optional()
|
|
15986
|
+
}),
|
|
15987
|
+
object({
|
|
15988
|
+
kind: literal("stationary"),
|
|
15989
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15990
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
15991
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15992
|
+
/** The parked object must be in at least one of these zones. */
|
|
15993
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15994
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
15995
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
15996
|
+
phase: _enum(["appeared", "departed"])
|
|
15997
|
+
}),
|
|
15998
|
+
object({
|
|
15999
|
+
kind: literal("interval"),
|
|
16000
|
+
minutes: number().int().min(1).max(1440)
|
|
16001
|
+
})
|
|
15951
16002
|
]);
|
|
15952
16003
|
/**
|
|
15953
16004
|
* One action step.
|
|
@@ -15967,28 +16018,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15967
16018
|
* is called. The runner still receives a number and is untouched; the
|
|
15968
16019
|
* resolution is the recipe's job, not the runner's.
|
|
15969
16020
|
*/
|
|
16021
|
+
var AutomationWaitStepSchema = object({
|
|
16022
|
+
kind: literal("wait"),
|
|
16023
|
+
seconds: number().min(0).max(300)
|
|
16024
|
+
});
|
|
16025
|
+
var AutomationCapStepSchema = object({
|
|
16026
|
+
kind: literal("cap"),
|
|
16027
|
+
/**
|
|
16028
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
16029
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
16030
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
16031
|
+
*/
|
|
16032
|
+
deviceId: union([
|
|
16033
|
+
number().int(),
|
|
16034
|
+
array(number().int()).min(1),
|
|
16035
|
+
object({ $var: string().min(1) })
|
|
16036
|
+
]),
|
|
16037
|
+
cap: string().min(1),
|
|
16038
|
+
method: string().min(1),
|
|
16039
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16040
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16041
|
+
* the expression leaf. */
|
|
16042
|
+
args: record(string(), unknown()).optional()
|
|
16043
|
+
});
|
|
16044
|
+
/**
|
|
16045
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
16046
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
16047
|
+
*/
|
|
16048
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
15970
16049
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
16050
|
+
AutomationWaitStepSchema,
|
|
16051
|
+
AutomationCapStepSchema,
|
|
15971
16052
|
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()
|
|
16053
|
+
kind: literal("action"),
|
|
16054
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
16055
|
+
actionId: string().min(1),
|
|
16056
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
16057
|
+
variables: record(string(), union([
|
|
16058
|
+
string(),
|
|
16059
|
+
number(),
|
|
16060
|
+
boolean()
|
|
16061
|
+
])).optional()
|
|
15992
16062
|
}),
|
|
15993
16063
|
object({
|
|
15994
16064
|
kind: literal("code"),
|
|
@@ -15997,10 +16067,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
15997
16067
|
code: string().min(1).max(2e4)
|
|
15998
16068
|
})
|
|
15999
16069
|
]);
|
|
16070
|
+
/**
|
|
16071
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
16072
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
16073
|
+
* actions. Absent means `single`.
|
|
16074
|
+
*
|
|
16075
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
16076
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
16077
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
16078
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
16079
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
16080
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
16081
|
+
* wait, never the single/queued limits.
|
|
16082
|
+
*/
|
|
16083
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
16084
|
+
object({ mode: literal("single") }),
|
|
16085
|
+
object({ mode: literal("restart") }),
|
|
16086
|
+
object({
|
|
16087
|
+
mode: literal("queued"),
|
|
16088
|
+
max: number().int().min(1).max(10)
|
|
16089
|
+
}),
|
|
16090
|
+
object({
|
|
16091
|
+
mode: literal("parallel"),
|
|
16092
|
+
max: number().int().min(1).max(10)
|
|
16093
|
+
}),
|
|
16094
|
+
object({
|
|
16095
|
+
mode: literal("cooldown"),
|
|
16096
|
+
minutes: number().int().min(1).max(1440)
|
|
16097
|
+
})
|
|
16098
|
+
]);
|
|
16000
16099
|
var AutomationRecipeSchema = object({
|
|
16001
16100
|
triggers: array(AutomationTriggerSchema),
|
|
16002
16101
|
conditions: AutomationConditionSchema.optional(),
|
|
16003
|
-
actions: array(AutomationActionSchema)
|
|
16102
|
+
actions: array(AutomationActionSchema),
|
|
16103
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
16104
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
16105
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
16106
|
+
});
|
|
16107
|
+
new Set([
|
|
16108
|
+
{
|
|
16109
|
+
id: "person",
|
|
16110
|
+
name: "Person"
|
|
16111
|
+
},
|
|
16112
|
+
{
|
|
16113
|
+
id: "vehicle",
|
|
16114
|
+
name: "Vehicle"
|
|
16115
|
+
},
|
|
16116
|
+
{
|
|
16117
|
+
id: "animal",
|
|
16118
|
+
name: "Animal"
|
|
16119
|
+
},
|
|
16120
|
+
{
|
|
16121
|
+
id: "package",
|
|
16122
|
+
name: "Package"
|
|
16123
|
+
}
|
|
16124
|
+
].map((l) => l.id));
|
|
16125
|
+
var COCO_TO_MACRO = {
|
|
16126
|
+
mapping: {
|
|
16127
|
+
person: "person",
|
|
16128
|
+
bicycle: "vehicle",
|
|
16129
|
+
car: "vehicle",
|
|
16130
|
+
motorcycle: "vehicle",
|
|
16131
|
+
airplane: "vehicle",
|
|
16132
|
+
bus: "vehicle",
|
|
16133
|
+
train: "vehicle",
|
|
16134
|
+
truck: "vehicle",
|
|
16135
|
+
boat: "vehicle",
|
|
16136
|
+
bird: "animal",
|
|
16137
|
+
cat: "animal",
|
|
16138
|
+
dog: "animal",
|
|
16139
|
+
horse: "animal",
|
|
16140
|
+
sheep: "animal",
|
|
16141
|
+
cow: "animal",
|
|
16142
|
+
elephant: "animal",
|
|
16143
|
+
bear: "animal",
|
|
16144
|
+
zebra: "animal",
|
|
16145
|
+
giraffe: "animal",
|
|
16146
|
+
suitcase: "package",
|
|
16147
|
+
backpack: "package",
|
|
16148
|
+
handbag: "package"
|
|
16149
|
+
},
|
|
16150
|
+
preserveOriginal: false
|
|
16151
|
+
};
|
|
16152
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
16153
|
+
/**
|
|
16154
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
16155
|
+
* so the editor can paint every block green or red with its reason.
|
|
16156
|
+
*
|
|
16157
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
16158
|
+
* every condition node (containers and leaves, including the ones a
|
|
16159
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
16160
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
16161
|
+
* for an Action run). Skipped
|
|
16162
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
16163
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
16164
|
+
*
|
|
16165
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
16166
|
+
* vocabulary so an Action run records the same step shape.
|
|
16167
|
+
*/
|
|
16168
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
16169
|
+
var TraceValueSchema = union([
|
|
16170
|
+
string(),
|
|
16171
|
+
number(),
|
|
16172
|
+
boolean(),
|
|
16173
|
+
_null(),
|
|
16174
|
+
array(union([string(), number()]))
|
|
16175
|
+
]);
|
|
16176
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
16177
|
+
"ran",
|
|
16178
|
+
"skipped-trigger",
|
|
16179
|
+
"skipped-conditions",
|
|
16180
|
+
"skipped-cooldown",
|
|
16181
|
+
"skipped-overlap",
|
|
16182
|
+
"failed",
|
|
16183
|
+
"aborted"
|
|
16184
|
+
]);
|
|
16185
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
16186
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
16187
|
+
"pass",
|
|
16188
|
+
"fail",
|
|
16189
|
+
"not-evaluated"
|
|
16190
|
+
]);
|
|
16191
|
+
var AutomationTriggerTraceSchema = object({
|
|
16192
|
+
kind: string().min(1),
|
|
16193
|
+
outcome: _enum(["pass", "fail"]),
|
|
16194
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
16195
|
+
reason: string(),
|
|
16196
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
16197
|
+
vars: record(string(), TraceValueSchema)
|
|
16198
|
+
});
|
|
16199
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
16200
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
16201
|
+
path: string().min(1),
|
|
16202
|
+
kind: _enum([
|
|
16203
|
+
"all",
|
|
16204
|
+
"any",
|
|
16205
|
+
"not",
|
|
16206
|
+
"condition",
|
|
16207
|
+
"expression",
|
|
16208
|
+
"stationary-present"
|
|
16209
|
+
]),
|
|
16210
|
+
outcome: TraceNodeOutcomeSchema,
|
|
16211
|
+
reason: string(),
|
|
16212
|
+
deviceId: number().int().optional(),
|
|
16213
|
+
cap: string().optional(),
|
|
16214
|
+
fieldPath: string().optional(),
|
|
16215
|
+
operator: string().optional(),
|
|
16216
|
+
expected: TraceValueSchema.optional(),
|
|
16217
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
16218
|
+
observed: TraceValueSchema.optional()
|
|
16219
|
+
});
|
|
16220
|
+
var AutomationRunVerdictSchema = object({
|
|
16221
|
+
mode: AutomationRunModeSchema,
|
|
16222
|
+
decision: _enum([
|
|
16223
|
+
"run",
|
|
16224
|
+
"queued",
|
|
16225
|
+
"restart",
|
|
16226
|
+
"drop",
|
|
16227
|
+
"cooldown",
|
|
16228
|
+
"bypass"
|
|
16229
|
+
]),
|
|
16230
|
+
reason: string()
|
|
16231
|
+
});
|
|
16232
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
16233
|
+
var AutomationStepTraceSchema = object({
|
|
16234
|
+
/** `actions.<i>` */
|
|
16235
|
+
path: string().min(1),
|
|
16236
|
+
kind: string().min(1),
|
|
16237
|
+
cap: string().optional(),
|
|
16238
|
+
method: string().optional(),
|
|
16239
|
+
deviceId: number().int().optional(),
|
|
16240
|
+
startedAt: number().optional(),
|
|
16241
|
+
endedAt: number().optional(),
|
|
16242
|
+
outcome: _enum([
|
|
16243
|
+
"ok",
|
|
16244
|
+
"error",
|
|
16245
|
+
"not-run"
|
|
16246
|
+
]),
|
|
16247
|
+
message: string().optional()
|
|
16248
|
+
});
|
|
16249
|
+
var AutomationRunTraceSchema = object({
|
|
16250
|
+
runId: string().min(1),
|
|
16251
|
+
startedAt: number(),
|
|
16252
|
+
endedAt: number(),
|
|
16253
|
+
trigger: AutomationTriggerTraceSchema,
|
|
16254
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
16255
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
16256
|
+
steps: array(AutomationStepTraceSchema),
|
|
16257
|
+
outcome: AutomationRunOutcomeSchema,
|
|
16258
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
16259
|
+
repeat: number().int().min(1),
|
|
16260
|
+
/** When the latest of those repeats happened. */
|
|
16261
|
+
lastAt: number()
|
|
16262
|
+
});
|
|
16263
|
+
/**
|
|
16264
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
16265
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
16266
|
+
*/
|
|
16267
|
+
var AutomationStateDocSchema = object({
|
|
16268
|
+
version: literal(1),
|
|
16269
|
+
lastRunStartedAt: number().nullable(),
|
|
16270
|
+
traces: array(AutomationRunTraceSchema)
|
|
16271
|
+
});
|
|
16272
|
+
/**
|
|
16273
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
16274
|
+
* declared as LIST ENTRIES, never as devices.
|
|
16275
|
+
*
|
|
16276
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
16277
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
16278
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
16279
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
16280
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
16281
|
+
*
|
|
16282
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
16283
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
16284
|
+
* runtime.
|
|
16285
|
+
*/
|
|
16286
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
16287
|
+
var ActionVariableTypeSchema = _enum([
|
|
16288
|
+
"string",
|
|
16289
|
+
"number",
|
|
16290
|
+
"boolean",
|
|
16291
|
+
"select"
|
|
16292
|
+
]);
|
|
16293
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16294
|
+
var ActionVariableValueSchema = union([
|
|
16295
|
+
string(),
|
|
16296
|
+
number(),
|
|
16297
|
+
boolean()
|
|
16298
|
+
]);
|
|
16299
|
+
/**
|
|
16300
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
16301
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
16302
|
+
*/
|
|
16303
|
+
var ActionVariableSchema = object({
|
|
16304
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
16305
|
+
label: string().min(1).max(120).optional(),
|
|
16306
|
+
type: ActionVariableTypeSchema,
|
|
16307
|
+
required: boolean().optional(),
|
|
16308
|
+
default: ActionVariableValueSchema.optional(),
|
|
16309
|
+
/** The allowed values of a `select`. */
|
|
16310
|
+
options: array(string().min(1)).min(1).optional()
|
|
16311
|
+
}).superRefine((v, ctx) => {
|
|
16312
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
16313
|
+
code: "custom",
|
|
16314
|
+
message: "a select variable needs options",
|
|
16315
|
+
path: ["options"]
|
|
16316
|
+
});
|
|
16317
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
16318
|
+
code: "custom",
|
|
16319
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
16320
|
+
path: ["default"]
|
|
16321
|
+
});
|
|
16322
|
+
});
|
|
16323
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
16324
|
+
function variableValueError(variable, value) {
|
|
16325
|
+
switch (variable.type) {
|
|
16326
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
16327
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
16328
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
16329
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
16330
|
+
}
|
|
16331
|
+
}
|
|
16332
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
16333
|
+
function isInternalActionId(actionId) {
|
|
16334
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
16335
|
+
}
|
|
16336
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
16337
|
+
function addonIdOfActionId(actionId) {
|
|
16338
|
+
if (isInternalActionId(actionId)) return null;
|
|
16339
|
+
const at = actionId.indexOf(":");
|
|
16340
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
16341
|
+
}
|
|
16342
|
+
var ActionStatusSchema = object({
|
|
16343
|
+
isRunning: boolean(),
|
|
16344
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
16345
|
+
lastRunAt: number().nullable(),
|
|
16346
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
16347
|
+
lastError: string().nullable()
|
|
16348
|
+
});
|
|
16349
|
+
var ActionEntrySchema = object({
|
|
16350
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
16351
|
+
id: string().min(3),
|
|
16352
|
+
name: string().min(1).max(120),
|
|
16353
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
16354
|
+
addonId: string().min(1),
|
|
16355
|
+
source: ActionSourceKindSchema,
|
|
16356
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
16357
|
+
readOnly: boolean(),
|
|
16358
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
16359
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
16360
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
16361
|
+
status: ActionStatusSchema
|
|
16362
|
+
}).superRefine((entry, ctx) => {
|
|
16363
|
+
if (entry.source === "internal") {
|
|
16364
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
16365
|
+
code: "custom",
|
|
16366
|
+
message: "an internal action id is internal:<uuid>",
|
|
16367
|
+
path: ["id"]
|
|
16368
|
+
});
|
|
16369
|
+
return;
|
|
16370
|
+
}
|
|
16371
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
16372
|
+
code: "custom",
|
|
16373
|
+
message: "only an internal action carries steps",
|
|
16374
|
+
path: ["steps"]
|
|
16375
|
+
});
|
|
16376
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
16377
|
+
code: "custom",
|
|
16378
|
+
message: "an addon action is read-only here",
|
|
16379
|
+
path: ["readOnly"]
|
|
16380
|
+
});
|
|
16381
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
16382
|
+
code: "custom",
|
|
16383
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
16384
|
+
path: ["id"]
|
|
16385
|
+
});
|
|
16386
|
+
});
|
|
16387
|
+
/** What an operator writes for an internal action. */
|
|
16388
|
+
var ActionInputSchema = object({
|
|
16389
|
+
name: string().min(1).max(120),
|
|
16390
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
16391
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
16392
|
+
});
|
|
16393
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
16394
|
+
var ActionRunOriginSchema = object({
|
|
16395
|
+
/** The automation block whose step started it. */
|
|
16396
|
+
blockId: string().min(1).optional() });
|
|
16397
|
+
/** `started` = the caller did not ask to wait. */
|
|
16398
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
16399
|
+
var ActionRunResultSchema = object({
|
|
16400
|
+
runId: string().min(1),
|
|
16401
|
+
outcome: ActionRunOutcomeSchema,
|
|
16402
|
+
/** Why it did not run, or what failed. */
|
|
16403
|
+
message: string().optional()
|
|
16404
|
+
});
|
|
16405
|
+
_enum([
|
|
16406
|
+
"not-found",
|
|
16407
|
+
"read-only",
|
|
16408
|
+
"invalid-variables",
|
|
16409
|
+
"invalid-steps",
|
|
16410
|
+
"not-linked",
|
|
16411
|
+
"busy"
|
|
16412
|
+
]);
|
|
16413
|
+
object({
|
|
16414
|
+
actionId: string(),
|
|
16415
|
+
runId: string(),
|
|
16416
|
+
isRunning: boolean(),
|
|
16417
|
+
/** Set when the run ended. */
|
|
16418
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
16419
|
+
lastRunAt: number().nullable(),
|
|
16420
|
+
lastError: string().nullable()
|
|
16004
16421
|
});
|
|
16005
16422
|
/**
|
|
16006
16423
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18755,7 +19172,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18755
19172
|
stateField: string(),
|
|
18756
19173
|
fieldKey: string()
|
|
18757
19174
|
});
|
|
18758
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
19175
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18759
19176
|
var CompositionProblemSchema = object({
|
|
18760
19177
|
code: _enum([
|
|
18761
19178
|
"reserved-variant",
|
|
@@ -19074,7 +19491,7 @@ var GROUP_TEMPLATES = [
|
|
|
19074
19491
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
19075
19492
|
role: DeviceRole.TemperatureSensor,
|
|
19076
19493
|
outputCap: "temperature-sensor",
|
|
19077
|
-
outputField: "
|
|
19494
|
+
outputField: "temperature",
|
|
19078
19495
|
quantity: "temperature",
|
|
19079
19496
|
defaultAggregate: "mean",
|
|
19080
19497
|
empty: "null",
|
|
@@ -19085,7 +19502,7 @@ var GROUP_TEMPLATES = [
|
|
|
19085
19502
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19086
19503
|
role: DeviceRole.HumiditySensor,
|
|
19087
19504
|
outputCap: "humidity-sensor",
|
|
19088
|
-
outputField: "
|
|
19505
|
+
outputField: "humidity",
|
|
19089
19506
|
quantity: "humidity",
|
|
19090
19507
|
defaultAggregate: "mean",
|
|
19091
19508
|
empty: "null",
|
|
@@ -19096,7 +19513,7 @@ var GROUP_TEMPLATES = [
|
|
|
19096
19513
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
19097
19514
|
role: DeviceRole.PressureSensor,
|
|
19098
19515
|
outputCap: "pressure-sensor",
|
|
19099
|
-
outputField: "
|
|
19516
|
+
outputField: "pressure",
|
|
19100
19517
|
quantity: "pressure",
|
|
19101
19518
|
defaultAggregate: "mean",
|
|
19102
19519
|
empty: "null",
|
|
@@ -19107,7 +19524,7 @@ var GROUP_TEMPLATES = [
|
|
|
19107
19524
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
19108
19525
|
role: DeviceRole.AmbientLightSensor,
|
|
19109
19526
|
outputCap: "ambient-light-sensor",
|
|
19110
|
-
outputField: "
|
|
19527
|
+
outputField: "illuminance",
|
|
19111
19528
|
quantity: "illuminance",
|
|
19112
19529
|
defaultAggregate: "mean",
|
|
19113
19530
|
empty: "null",
|
|
@@ -19118,7 +19535,7 @@ var GROUP_TEMPLATES = [
|
|
|
19118
19535
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
19119
19536
|
role: DeviceRole.PowerSensor,
|
|
19120
19537
|
outputCap: "power-meter",
|
|
19121
|
-
outputField: "
|
|
19538
|
+
outputField: "power",
|
|
19122
19539
|
quantity: "power",
|
|
19123
19540
|
defaultAggregate: "sum",
|
|
19124
19541
|
empty: "omit",
|
|
@@ -19129,7 +19546,7 @@ var GROUP_TEMPLATES = [
|
|
|
19129
19546
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
19130
19547
|
role: DeviceRole.EnergySensor,
|
|
19131
19548
|
outputCap: "power-meter",
|
|
19132
|
-
outputField: "
|
|
19549
|
+
outputField: "energy",
|
|
19133
19550
|
quantity: "energy",
|
|
19134
19551
|
defaultAggregate: "sum",
|
|
19135
19552
|
empty: "omit",
|
|
@@ -19140,7 +19557,7 @@ var GROUP_TEMPLATES = [
|
|
|
19140
19557
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19141
19558
|
role: DeviceRole.BatterySensor,
|
|
19142
19559
|
outputCap: "battery",
|
|
19143
|
-
outputField: "
|
|
19560
|
+
outputField: "level",
|
|
19144
19561
|
quantity: "percentage",
|
|
19145
19562
|
defaultAggregate: "mean",
|
|
19146
19563
|
empty: "null",
|
|
@@ -19718,7 +20135,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19718
20135
|
kind: "mutation",
|
|
19719
20136
|
auth: "admin",
|
|
19720
20137
|
access: "view"
|
|
19721
|
-
})
|
|
20138
|
+
}), method(object({
|
|
20139
|
+
blockId: string().min(1),
|
|
20140
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
20141
|
+
runStartedAt: number().optional(),
|
|
20142
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
20143
|
+
}), _void(), {
|
|
20144
|
+
kind: "mutation",
|
|
20145
|
+
auth: "admin"
|
|
20146
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
20147
|
+
traces: array(AutomationRunTraceSchema),
|
|
20148
|
+
lastError: string().nullable()
|
|
20149
|
+
}), { auth: "admin" });
|
|
19722
20150
|
/**
|
|
19723
20151
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19724
20152
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -44873,7 +45301,7 @@ var NetworkAccessStatusSchema = object({
|
|
|
44873
45301
|
});
|
|
44874
45302
|
/**
|
|
44875
45303
|
* Optional, richer endpoint shape returned by providers that expose
|
|
44876
|
-
* MORE than one ingress concurrently (Tailscale
|
|
45304
|
+
* MORE than one ingress concurrently (Tailscale Funnel with mixed
|
|
44877
45305
|
* serve+funnel rules, future ngrok multi-tunnel, …). Each entry carries
|
|
44878
45306
|
* the originating provider config (mode + sourcePort) so the
|
|
44879
45307
|
* orchestrator UI can label rows distinctly. Providers that expose only
|
|
@@ -45288,51 +45716,6 @@ var notificationOutputCapability = {
|
|
|
45288
45716
|
})
|
|
45289
45717
|
}
|
|
45290
45718
|
};
|
|
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
45719
|
var AUDIO_MACRO_LABELS = [
|
|
45337
45720
|
{
|
|
45338
45721
|
id: "speech",
|
|
@@ -57987,9 +58370,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57987
58370
|
*/
|
|
57988
58371
|
var AirQualitySensorStatusSchema = object({
|
|
57989
58372
|
/** Carbon dioxide concentration in ppm. */
|
|
57990
|
-
|
|
58373
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57991
58374
|
/** Total volatile organic compounds in ppb. */
|
|
57992
|
-
|
|
58375
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57993
58376
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57994
58377
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57995
58378
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -58022,12 +58405,12 @@ var airQualitySensorCapability = {
|
|
|
58022
58405
|
* History (D850): recorded series.
|
|
58023
58406
|
*/
|
|
58024
58407
|
history: { fields: {
|
|
58025
|
-
|
|
58408
|
+
co2: {
|
|
58026
58409
|
kind: "gauge",
|
|
58027
58410
|
unit: "ppm",
|
|
58028
58411
|
deadband: 5
|
|
58029
58412
|
},
|
|
58030
|
-
|
|
58413
|
+
voc: {
|
|
58031
58414
|
kind: "gauge",
|
|
58032
58415
|
unit: "ppb",
|
|
58033
58416
|
deadband: 5
|
|
@@ -58058,7 +58441,7 @@ var airQualitySensorCapability = {
|
|
|
58058
58441
|
*/
|
|
58059
58442
|
var AmbientLightSensorStatusSchema = object({
|
|
58060
58443
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
58061
|
-
|
|
58444
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
58062
58445
|
precision: 0,
|
|
58063
58446
|
label: "Illuminance"
|
|
58064
58447
|
})),
|
|
@@ -58087,7 +58470,7 @@ var ambientLightSensorCapability = {
|
|
|
58087
58470
|
/**
|
|
58088
58471
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
58089
58472
|
*/
|
|
58090
|
-
history: { fields: {
|
|
58473
|
+
history: { fields: { illuminance: {
|
|
58091
58474
|
kind: "gauge",
|
|
58092
58475
|
unit: "lx",
|
|
58093
58476
|
deadbandPct: 10,
|
|
@@ -58226,6 +58609,84 @@ var audioMetricsCapability = {
|
|
|
58226
58609
|
*/
|
|
58227
58610
|
history: "none"
|
|
58228
58611
|
};
|
|
58612
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58613
|
+
actionId: string().min(1),
|
|
58614
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
58615
|
+
}), _void(), {
|
|
58616
|
+
kind: "mutation",
|
|
58617
|
+
auth: "admin"
|
|
58618
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
58619
|
+
kind: "mutation",
|
|
58620
|
+
auth: "admin"
|
|
58621
|
+
});
|
|
58622
|
+
/**
|
|
58623
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
58624
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
58625
|
+
*
|
|
58626
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
58627
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
58628
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
58629
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
58630
|
+
* drift (D3).
|
|
58631
|
+
*
|
|
58632
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
58633
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
58634
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
58635
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
58636
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
58637
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
58638
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
58639
|
+
*
|
|
58640
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
58641
|
+
* logged — never queued.
|
|
58642
|
+
*/
|
|
58643
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
58644
|
+
var ActionLinksSchema = object({
|
|
58645
|
+
deviceId: number().int().nonnegative(),
|
|
58646
|
+
actionIds: array(string().min(1)).max(100)
|
|
58647
|
+
});
|
|
58648
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58649
|
+
actionId: string().min(1),
|
|
58650
|
+
deviceId: number().int().nonnegative().optional()
|
|
58651
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
58652
|
+
role: "viewer",
|
|
58653
|
+
auth: "protected",
|
|
58654
|
+
kind: "query",
|
|
58655
|
+
caller: "required"
|
|
58656
|
+
}), method(object({
|
|
58657
|
+
actionId: string().min(1),
|
|
58658
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
58659
|
+
wait: boolean().optional(),
|
|
58660
|
+
origin: ActionRunOriginSchema.optional(),
|
|
58661
|
+
deviceId: number().int().nonnegative().optional()
|
|
58662
|
+
}), ActionRunResultSchema, {
|
|
58663
|
+
role: "viewer",
|
|
58664
|
+
auth: "protected",
|
|
58665
|
+
kind: "mutation",
|
|
58666
|
+
caller: "required"
|
|
58667
|
+
}), method(ActionIdInput, _void(), {
|
|
58668
|
+
kind: "mutation",
|
|
58669
|
+
auth: "admin"
|
|
58670
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
58671
|
+
kind: "mutation",
|
|
58672
|
+
auth: "admin"
|
|
58673
|
+
}), method(object({
|
|
58674
|
+
actionId: string().min(1),
|
|
58675
|
+
action: ActionInputSchema.partial()
|
|
58676
|
+
}), object({ action: ActionEntrySchema }), {
|
|
58677
|
+
kind: "mutation",
|
|
58678
|
+
auth: "admin"
|
|
58679
|
+
}), method(ActionIdInput, _void(), {
|
|
58680
|
+
kind: "mutation",
|
|
58681
|
+
auth: "admin"
|
|
58682
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
58683
|
+
role: "viewer",
|
|
58684
|
+
auth: "protected",
|
|
58685
|
+
kind: "query"
|
|
58686
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
58687
|
+
kind: "mutation",
|
|
58688
|
+
auth: "admin"
|
|
58689
|
+
});
|
|
58229
58690
|
/**
|
|
58230
58691
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
58231
58692
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -58322,7 +58783,7 @@ var BatteryStatusSchema = object({
|
|
|
58322
58783
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
58323
58784
|
* declines to band a non-finite reading, which is the correct shape.
|
|
58324
58785
|
*/
|
|
58325
|
-
|
|
58786
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
58326
58787
|
/**
|
|
58327
58788
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
58328
58789
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -58332,7 +58793,7 @@ var BatteryStatusSchema = object({
|
|
|
58332
58793
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
58333
58794
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
58334
58795
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
58335
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
58796
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
58336
58797
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
58337
58798
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
58338
58799
|
*/
|
|
@@ -58356,7 +58817,7 @@ var BatteryStatusSchema = object({
|
|
|
58356
58817
|
* that only report charge. A second reading on this cap, not a second
|
|
58357
58818
|
* `numeric-sensor` on the same device.
|
|
58358
58819
|
*/
|
|
58359
|
-
|
|
58820
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
58360
58821
|
/**
|
|
58361
58822
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
58362
58823
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58390,7 +58851,7 @@ var BatteryStatusSchema = object({
|
|
|
58390
58851
|
/**
|
|
58391
58852
|
* True when the source is a BINARY low-battery indicator (HA
|
|
58392
58853
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
58393
|
-
* charge level — `
|
|
58854
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
58394
58855
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
58395
58856
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
58396
58857
|
*/
|
|
@@ -58403,21 +58864,22 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58403
58864
|
DeviceType.Switch,
|
|
58404
58865
|
DeviceType.PetFeeder,
|
|
58405
58866
|
DeviceType.Container,
|
|
58406
|
-
DeviceType.Thermostat
|
|
58867
|
+
DeviceType.Thermostat,
|
|
58868
|
+
DeviceType.EventEmitter
|
|
58407
58869
|
];
|
|
58408
58870
|
/** Generic Customize target for the percentage reading (D936). */
|
|
58409
58871
|
var batteryCustomize = {
|
|
58410
58872
|
version: 1,
|
|
58411
58873
|
targets: [{
|
|
58412
|
-
id: "
|
|
58874
|
+
id: "level",
|
|
58413
58875
|
cardinality: "scalar",
|
|
58414
58876
|
vocabulary: {
|
|
58415
58877
|
cap: "battery",
|
|
58416
|
-
stateField: "
|
|
58878
|
+
stateField: "level"
|
|
58417
58879
|
},
|
|
58418
58880
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58419
58881
|
apply: "add",
|
|
58420
|
-
path: "
|
|
58882
|
+
path: "level",
|
|
58421
58883
|
sources: [{
|
|
58422
58884
|
kind: "field",
|
|
58423
58885
|
valueKinds: ["number", "string"],
|
|
@@ -58511,7 +58973,7 @@ onStatusChanged: { data: object({
|
|
|
58511
58973
|
schema: BatteryStatusSchema,
|
|
58512
58974
|
kind: "push",
|
|
58513
58975
|
empty: {
|
|
58514
|
-
|
|
58976
|
+
level: null,
|
|
58515
58977
|
charging: "unknown",
|
|
58516
58978
|
sleeping: false,
|
|
58517
58979
|
lastUpdated: 0
|
|
@@ -58538,11 +59000,11 @@ onStatusChanged: { data: object({
|
|
|
58538
59000
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58539
59001
|
*/
|
|
58540
59002
|
history: { fields: {
|
|
58541
|
-
|
|
59003
|
+
level: {
|
|
58542
59004
|
kind: "gauge",
|
|
58543
59005
|
unit: "%"
|
|
58544
59006
|
},
|
|
58545
|
-
|
|
59007
|
+
voltage: {
|
|
58546
59008
|
kind: "gauge",
|
|
58547
59009
|
unit: "V"
|
|
58548
59010
|
}
|
|
@@ -58602,14 +59064,14 @@ var binaryCapability = {
|
|
|
58602
59064
|
* controls to this single-method surface.
|
|
58603
59065
|
*
|
|
58604
59066
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
58605
|
-
*
|
|
59067
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
58606
59068
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
58607
59069
|
* should surface those via the device's `getSettingsUISchema()`
|
|
58608
59070
|
* instead of bloating this cap.
|
|
58609
59071
|
*/
|
|
58610
59072
|
var BrightnessStatusSchema = object({
|
|
58611
59073
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58612
|
-
|
|
59074
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58613
59075
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58614
59076
|
lastChangedAt: number()
|
|
58615
59077
|
});
|
|
@@ -58621,7 +59083,7 @@ var brightnessCapability = {
|
|
|
58621
59083
|
deviceTypes: [DeviceType.Light],
|
|
58622
59084
|
methods: { setBrightness: method(object({
|
|
58623
59085
|
deviceId: number().int().nonnegative(),
|
|
58624
|
-
|
|
59086
|
+
level: number().min(0).max(100)
|
|
58625
59087
|
}), _void(), {
|
|
58626
59088
|
kind: "mutation",
|
|
58627
59089
|
auth: "protected"
|
|
@@ -58634,7 +59096,7 @@ var brightnessCapability = {
|
|
|
58634
59096
|
*/
|
|
58635
59097
|
onBrightnessChanged: { data: object({
|
|
58636
59098
|
deviceId: number(),
|
|
58637
|
-
|
|
59099
|
+
level: number().min(0).max(100),
|
|
58638
59100
|
lastChangedAt: number()
|
|
58639
59101
|
}) } },
|
|
58640
59102
|
status: {
|
|
@@ -58657,7 +59119,7 @@ onBrightnessChanged: { data: object({
|
|
|
58657
59119
|
/**
|
|
58658
59120
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
58659
59121
|
*/
|
|
58660
|
-
history: { fields: {
|
|
59122
|
+
history: { fields: { level: {
|
|
58661
59123
|
kind: "gauge",
|
|
58662
59124
|
unit: "%",
|
|
58663
59125
|
minIntervalMs: 0
|
|
@@ -59281,11 +59743,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
59281
59743
|
}),
|
|
59282
59744
|
object({
|
|
59283
59745
|
mode: literal("mired"),
|
|
59284
|
-
|
|
59746
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
59285
59747
|
})
|
|
59286
59748
|
]);
|
|
59287
59749
|
var ColorStatusSchema = object({
|
|
59288
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
59750
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
59289
59751
|
* the bulb's current state. */
|
|
59290
59752
|
mode: _enum([
|
|
59291
59753
|
"rgb",
|
|
@@ -59297,7 +59759,7 @@ var ColorStatusSchema = object({
|
|
|
59297
59759
|
/** Populated when `mode === 'hsv'`. */
|
|
59298
59760
|
hsv: HsvTripletSchema.optional(),
|
|
59299
59761
|
/** Populated when `mode === 'mired'`. */
|
|
59300
|
-
|
|
59762
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
59301
59763
|
/** Ms epoch of the last operator-driven change. */
|
|
59302
59764
|
lastChangedAt: number()
|
|
59303
59765
|
});
|
|
@@ -59329,7 +59791,7 @@ onColorChanged: { data: object({
|
|
|
59329
59791
|
]),
|
|
59330
59792
|
rgb: RgbTripletSchema.optional(),
|
|
59331
59793
|
hsv: HsvTripletSchema.optional(),
|
|
59332
|
-
|
|
59794
|
+
colorTemperature: number().int().optional(),
|
|
59333
59795
|
lastChangedAt: number()
|
|
59334
59796
|
}) } },
|
|
59335
59797
|
status: {
|
|
@@ -60220,11 +60682,11 @@ var DishwasherStatusSchema = object({
|
|
|
60220
60682
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
60221
60683
|
availablePrograms: array(string()),
|
|
60222
60684
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
60223
|
-
|
|
60685
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60224
60686
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
60225
|
-
|
|
60687
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60226
60688
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
60227
|
-
|
|
60689
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60228
60690
|
/** True when the door is reported open; null when the door state is not known. */
|
|
60229
60691
|
doorOpen: boolean().nullable(),
|
|
60230
60692
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -60443,14 +60905,14 @@ var dishwasherCapability = {
|
|
|
60443
60905
|
runtimeState: DishwasherStatusSchema,
|
|
60444
60906
|
durability: "session",
|
|
60445
60907
|
history: { fields: {
|
|
60446
|
-
|
|
60908
|
+
progress: {
|
|
60447
60909
|
kind: "gauge",
|
|
60448
60910
|
unit: "%",
|
|
60449
60911
|
deadband: 2
|
|
60450
60912
|
},
|
|
60451
60913
|
state: { kind: "enum" },
|
|
60452
60914
|
operationState: { kind: "enum" },
|
|
60453
|
-
|
|
60915
|
+
remaining: {
|
|
60454
60916
|
kind: "gauge",
|
|
60455
60917
|
unit: "s",
|
|
60456
60918
|
minIntervalMs: 6e4
|
|
@@ -61051,7 +61513,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
61051
61513
|
var FanControlStatusSchema = object({
|
|
61052
61514
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
61053
61515
|
* speed surface (single-speed fan). */
|
|
61054
|
-
|
|
61516
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61055
61517
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
61056
61518
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
61057
61519
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -61078,7 +61540,7 @@ var fanControlCapability = {
|
|
|
61078
61540
|
methods: {
|
|
61079
61541
|
setPercentage: method(object({
|
|
61080
61542
|
deviceId: number().int().nonnegative(),
|
|
61081
|
-
|
|
61543
|
+
speed: number().min(0).max(100)
|
|
61082
61544
|
}), _void(), {
|
|
61083
61545
|
kind: "mutation",
|
|
61084
61546
|
auth: "protected"
|
|
@@ -61111,7 +61573,7 @@ var fanControlCapability = {
|
|
|
61111
61573
|
},
|
|
61112
61574
|
/**
|
|
61113
61575
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
61114
|
-
* sliders read `
|
|
61576
|
+
* sliders read `speed` for live updates.
|
|
61115
61577
|
*/
|
|
61116
61578
|
runtimeState: FanControlStatusSchema,
|
|
61117
61579
|
/**
|
|
@@ -61125,7 +61587,7 @@ var fanControlCapability = {
|
|
|
61125
61587
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
61126
61588
|
*/
|
|
61127
61589
|
history: { fields: {
|
|
61128
|
-
|
|
61590
|
+
speed: {
|
|
61129
61591
|
kind: "gauge",
|
|
61130
61592
|
unit: "%",
|
|
61131
61593
|
minIntervalMs: 0
|
|
@@ -61570,7 +62032,7 @@ var humidifierCapability = {
|
|
|
61570
62032
|
*/
|
|
61571
62033
|
var HumiditySensorStatusSchema = object({
|
|
61572
62034
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61573
|
-
|
|
62035
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61574
62036
|
precision: 0,
|
|
61575
62037
|
label: "Humidity"
|
|
61576
62038
|
})),
|
|
@@ -61599,7 +62061,7 @@ var humiditySensorCapability = {
|
|
|
61599
62061
|
/**
|
|
61600
62062
|
* History (D850): recorded series.
|
|
61601
62063
|
*/
|
|
61602
|
-
history: { fields: {
|
|
62064
|
+
history: { fields: { humidity: {
|
|
61603
62065
|
kind: "gauge",
|
|
61604
62066
|
unit: "%",
|
|
61605
62067
|
deadband: .5
|
|
@@ -62239,7 +62701,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
62239
62701
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62240
62702
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
62241
62703
|
* task is active / progress is unavailable. */
|
|
62242
|
-
|
|
62704
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62243
62705
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
62244
62706
|
* or null when unknown. */
|
|
62245
62707
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -62739,7 +63201,7 @@ var lockControlCapability = {
|
|
|
62739
63201
|
volatileStateFields: ["lastChangedAt"]
|
|
62740
63202
|
};
|
|
62741
63203
|
/**
|
|
62742
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
63204
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
62743
63205
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
62744
63206
|
* `value` is the time integral in the source quantity's accumulated base
|
|
62745
63207
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -62833,10 +63295,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62833
63295
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62834
63296
|
/** Current playback position in ms. Null when not seekable or
|
|
62835
63297
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62836
|
-
|
|
63298
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62837
63299
|
/** Total duration of the current media in ms. Null when unknown
|
|
62838
63300
|
* (live stream) or nothing is playing. */
|
|
62839
|
-
|
|
63301
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62840
63302
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62841
63303
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62842
63304
|
shuffle: boolean().nullable(),
|
|
@@ -62875,7 +63337,7 @@ var mediaPlayerCapability = {
|
|
|
62875
63337
|
}),
|
|
62876
63338
|
seek: method(object({
|
|
62877
63339
|
deviceId: number().int().nonnegative(),
|
|
62878
|
-
|
|
63340
|
+
position: number().int().nonnegative()
|
|
62879
63341
|
}), _void(), {
|
|
62880
63342
|
kind: "mutation",
|
|
62881
63343
|
auth: "protected"
|
|
@@ -62947,7 +63409,7 @@ var mediaPlayerCapability = {
|
|
|
62947
63409
|
/**
|
|
62948
63410
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62949
63411
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62950
|
-
* `
|
|
63412
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62951
63413
|
*/
|
|
62952
63414
|
history: { fields: {
|
|
62953
63415
|
volumeLevel: {
|
|
@@ -63909,9 +64371,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
63909
64371
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63910
64372
|
* SKIP a null rather than coerce it.
|
|
63911
64373
|
*/
|
|
63912
|
-
|
|
64374
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63913
64375
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63914
|
-
|
|
64376
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
63915
64377
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63916
64378
|
ssid: string().optional(),
|
|
63917
64379
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63947,7 +64409,7 @@ onStatusChanged: { data: object({
|
|
|
63947
64409
|
kind: "push",
|
|
63948
64410
|
empty: {
|
|
63949
64411
|
type: "unknown",
|
|
63950
|
-
|
|
64412
|
+
signal: null,
|
|
63951
64413
|
lastUpdated: 0
|
|
63952
64414
|
}
|
|
63953
64415
|
},
|
|
@@ -63970,13 +64432,13 @@ onStatusChanged: { data: object({
|
|
|
63970
64432
|
* History (D850): recorded series.
|
|
63971
64433
|
*/
|
|
63972
64434
|
history: { fields: {
|
|
63973
|
-
|
|
64435
|
+
signal: {
|
|
63974
64436
|
kind: "gauge",
|
|
63975
64437
|
unit: "%",
|
|
63976
64438
|
deadband: 3,
|
|
63977
64439
|
minIntervalMs: 6e4
|
|
63978
64440
|
},
|
|
63979
|
-
|
|
64441
|
+
rssi: {
|
|
63980
64442
|
kind: "gauge",
|
|
63981
64443
|
unit: "dBm",
|
|
63982
64444
|
deadband: 2,
|
|
@@ -64721,10 +65183,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
64721
65183
|
]);
|
|
64722
65184
|
var gramsPortion = number().int().min(4).max(200);
|
|
64723
65185
|
var PetFeederStatusSchema = object({
|
|
64724
|
-
/** Food
|
|
64725
|
-
*
|
|
64726
|
-
* bowl
|
|
65186
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
65187
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
65188
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
65189
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
65190
|
+
* the device has not reported yet. */
|
|
64727
65191
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
65192
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
65193
|
+
* feeder's own units. Null when the model reports none. */
|
|
65194
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
65195
|
+
/** True while the pet is eating (`state.eating`). */
|
|
65196
|
+
eating: boolean(),
|
|
65197
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
65198
|
+
* the client must not offer it. */
|
|
65199
|
+
supportsMarkRefilled: boolean(),
|
|
64728
65200
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64729
65201
|
* single-hopper models. */
|
|
64730
65202
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -64732,8 +65204,8 @@ var PetFeederStatusSchema = object({
|
|
|
64732
65204
|
* single-hopper models. */
|
|
64733
65205
|
food2: number().nullable().meta(readingMeta("none")),
|
|
64734
65206
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64735
|
-
* (`device_class: problem`, on = low). True when the
|
|
64736
|
-
*
|
|
65207
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
65208
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
64737
65209
|
lowFood: boolean(),
|
|
64738
65210
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
64739
65211
|
* device has no battery reading. */
|
|
@@ -64801,7 +65273,9 @@ var petFeederCapability = {
|
|
|
64801
65273
|
kind: "mutation",
|
|
64802
65274
|
auth: "protected"
|
|
64803
65275
|
}),
|
|
64804
|
-
/**
|
|
65276
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
65277
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
65278
|
+
* change any sensor reading. */
|
|
64805
65279
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
64806
65280
|
kind: "mutation",
|
|
64807
65281
|
auth: "protected"
|
|
@@ -64874,6 +65348,7 @@ var petFeederCapability = {
|
|
|
64874
65348
|
*/
|
|
64875
65349
|
history: { fields: {
|
|
64876
65350
|
foodLevel: { kind: "gauge" },
|
|
65351
|
+
bowlFood: { kind: "gauge" },
|
|
64877
65352
|
food1: { kind: "gauge" },
|
|
64878
65353
|
food2: { kind: "gauge" },
|
|
64879
65354
|
batteryPower: {
|
|
@@ -65283,16 +65758,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
65283
65758
|
* in real-world devices.
|
|
65284
65759
|
*/
|
|
65285
65760
|
var PowerMeterStatusSchema = object({
|
|
65286
|
-
/** Instantaneous power draw
|
|
65287
|
-
|
|
65761
|
+
/** Instantaneous power draw (watts). */
|
|
65762
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
65288
65763
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65289
|
-
|
|
65290
|
-
/** Voltage
|
|
65291
|
-
|
|
65764
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65765
|
+
/** Voltage (volts). */
|
|
65766
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65292
65767
|
/** Current in amperes. */
|
|
65293
|
-
|
|
65768
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65294
65769
|
/** Apparent power in volt-amperes. */
|
|
65295
|
-
|
|
65770
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
65296
65771
|
/** Power factor (0..1) if reported. */
|
|
65297
65772
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
65298
65773
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -65350,14 +65825,14 @@ function powerTarget(id, unit) {
|
|
|
65350
65825
|
advancedExpression: true
|
|
65351
65826
|
};
|
|
65352
65827
|
}
|
|
65353
|
-
/** "Power and energy" extension:
|
|
65828
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
65354
65829
|
var powerMeterCustomize = {
|
|
65355
65830
|
version: 1,
|
|
65356
65831
|
targets: [
|
|
65357
|
-
powerTarget("
|
|
65358
|
-
powerTarget("
|
|
65359
|
-
powerTarget("
|
|
65360
|
-
powerTarget("
|
|
65832
|
+
powerTarget("power", "W"),
|
|
65833
|
+
powerTarget("energy", "kWh"),
|
|
65834
|
+
powerTarget("voltage", "V"),
|
|
65835
|
+
powerTarget("current", "A")
|
|
65361
65836
|
]
|
|
65362
65837
|
};
|
|
65363
65838
|
var powerMeterCapability = {
|
|
@@ -65373,41 +65848,41 @@ var powerMeterCapability = {
|
|
|
65373
65848
|
},
|
|
65374
65849
|
runtimeState: PowerMeterStatusSchema,
|
|
65375
65850
|
/**
|
|
65376
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
65851
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
65377
65852
|
*
|
|
65378
65853
|
* See `RuntimeStateDurability`. Enforced by
|
|
65379
65854
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65380
65855
|
*/
|
|
65381
65856
|
durability: "restored",
|
|
65382
65857
|
/**
|
|
65383
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
65858
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
65384
65859
|
*/
|
|
65385
65860
|
history: { fields: {
|
|
65386
|
-
|
|
65861
|
+
power: {
|
|
65387
65862
|
kind: "gauge",
|
|
65388
65863
|
unit: "W",
|
|
65389
65864
|
deadband: 1,
|
|
65390
65865
|
minIntervalMs: 3e4
|
|
65391
65866
|
},
|
|
65392
|
-
|
|
65867
|
+
energy: {
|
|
65393
65868
|
kind: "counter",
|
|
65394
65869
|
unit: "kWh",
|
|
65395
65870
|
deadband: .01,
|
|
65396
65871
|
minIntervalMs: 6e4
|
|
65397
65872
|
},
|
|
65398
|
-
|
|
65873
|
+
voltage: {
|
|
65399
65874
|
kind: "gauge",
|
|
65400
65875
|
unit: "V",
|
|
65401
65876
|
deadband: 1,
|
|
65402
65877
|
minIntervalMs: 3e4
|
|
65403
65878
|
},
|
|
65404
|
-
|
|
65879
|
+
current: {
|
|
65405
65880
|
kind: "gauge",
|
|
65406
65881
|
unit: "A",
|
|
65407
65882
|
deadband: .05,
|
|
65408
65883
|
minIntervalMs: 3e4
|
|
65409
65884
|
},
|
|
65410
|
-
|
|
65885
|
+
apparentPower: {
|
|
65411
65886
|
kind: "gauge",
|
|
65412
65887
|
unit: "VA",
|
|
65413
65888
|
deadband: 1,
|
|
@@ -65457,9 +65932,6 @@ var PresenceStatusSchema = object({
|
|
|
65457
65932
|
location: string().nullable(),
|
|
65458
65933
|
/** GPS coordinates when available. Null otherwise. */
|
|
65459
65934
|
gps: GpsLocationSchema.nullable(),
|
|
65460
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
65461
|
-
* when not reported. */
|
|
65462
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65463
65935
|
/** Ms epoch when the slice was last updated. */
|
|
65464
65936
|
lastChangedAt: number()
|
|
65465
65937
|
});
|
|
@@ -65488,14 +65960,7 @@ var presenceCapability = {
|
|
|
65488
65960
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65489
65961
|
*/
|
|
65490
65962
|
durability: "restored",
|
|
65491
|
-
|
|
65492
|
-
* History (D850): recorded series.
|
|
65493
|
-
*/
|
|
65494
|
-
history: { fields: { batteryPercent: {
|
|
65495
|
-
kind: "gauge",
|
|
65496
|
-
unit: "%",
|
|
65497
|
-
deadband: 1
|
|
65498
|
-
} } },
|
|
65963
|
+
history: "none",
|
|
65499
65964
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65500
65965
|
* whether persisting is worth a SQLite commit. */
|
|
65501
65966
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65510,7 +65975,7 @@ var presenceCapability = {
|
|
|
65510
65975
|
*/
|
|
65511
65976
|
var PressureSensorStatusSchema = object({
|
|
65512
65977
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65513
|
-
|
|
65978
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
65514
65979
|
/** Ms epoch when the slice was last updated. */
|
|
65515
65980
|
lastFetchedAt: number()
|
|
65516
65981
|
});
|
|
@@ -65536,7 +66001,7 @@ var pressureSensorCapability = {
|
|
|
65536
66001
|
/**
|
|
65537
66002
|
* History (D850): recorded series.
|
|
65538
66003
|
*/
|
|
65539
|
-
history: { fields: {
|
|
66004
|
+
history: { fields: { pressure: {
|
|
65540
66005
|
kind: "gauge",
|
|
65541
66006
|
unit: "hPa",
|
|
65542
66007
|
deadband: .1
|
|
@@ -69243,7 +69708,7 @@ var tamperCapability = {
|
|
|
69243
69708
|
*/
|
|
69244
69709
|
var TemperatureSensorStatusSchema = object({
|
|
69245
69710
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69246
|
-
|
|
69711
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
69247
69712
|
precision: 1,
|
|
69248
69713
|
label: "Temperature"
|
|
69249
69714
|
})),
|
|
@@ -69272,7 +69737,7 @@ var temperatureSensorCapability = {
|
|
|
69272
69737
|
/**
|
|
69273
69738
|
* History (D850): recorded series.
|
|
69274
69739
|
*/
|
|
69275
|
-
history: { fields: {
|
|
69740
|
+
history: { fields: { temperature: {
|
|
69276
69741
|
kind: "gauge",
|
|
69277
69742
|
unit: "°C",
|
|
69278
69743
|
deadband: .1
|
|
@@ -69569,7 +70034,7 @@ var VacuumControlStatusSchema = object({
|
|
|
69569
70034
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69570
70035
|
availableFanSpeeds: array(string()),
|
|
69571
70036
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69572
|
-
|
|
70037
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69573
70038
|
/** Current error code (0 / null = no error). */
|
|
69574
70039
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69575
70040
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -71254,7 +71719,7 @@ function tryConvertDelta(value, from, to) {
|
|
|
71254
71719
|
return shifted - origin;
|
|
71255
71720
|
}
|
|
71256
71721
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
71257
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
71722
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
71258
71723
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
71259
71724
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
71260
71725
|
new Set(CAP_NAMES);
|
|
@@ -71658,7 +72123,7 @@ var BaseDevice = class {
|
|
|
71658
72123
|
* `device-local-state.ts`. Drivers access via:
|
|
71659
72124
|
*
|
|
71660
72125
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
71661
|
-
* `const pct = this.state.battery.
|
|
72126
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
71662
72127
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
71663
72128
|
*
|
|
71664
72129
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -71698,7 +72163,7 @@ var BaseDevice = class {
|
|
|
71698
72163
|
* shape; drivers don't redeclare it, they just write through.
|
|
71699
72164
|
*
|
|
71700
72165
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
71701
|
-
* `{
|
|
72166
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
71702
72167
|
* provider that registers `batteryCapability`.
|
|
71703
72168
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
71704
72169
|
*
|
|
@@ -72872,6 +73337,104 @@ Object.freeze({
|
|
|
72872
73337
|
access: "create",
|
|
72873
73338
|
role: "admin"
|
|
72874
73339
|
},
|
|
73340
|
+
"actions.create": {
|
|
73341
|
+
capName: "actions",
|
|
73342
|
+
capScope: "system",
|
|
73343
|
+
addonId: null,
|
|
73344
|
+
access: "create",
|
|
73345
|
+
role: "admin"
|
|
73346
|
+
},
|
|
73347
|
+
"actions.delete": {
|
|
73348
|
+
capName: "actions",
|
|
73349
|
+
capScope: "system",
|
|
73350
|
+
addonId: null,
|
|
73351
|
+
access: "delete",
|
|
73352
|
+
role: "admin"
|
|
73353
|
+
},
|
|
73354
|
+
"actions.get": {
|
|
73355
|
+
capName: "actions",
|
|
73356
|
+
capScope: "system",
|
|
73357
|
+
addonId: null,
|
|
73358
|
+
access: "view",
|
|
73359
|
+
role: "viewer"
|
|
73360
|
+
},
|
|
73361
|
+
"actions.getLinks": {
|
|
73362
|
+
capName: "actions",
|
|
73363
|
+
capScope: "system",
|
|
73364
|
+
addonId: null,
|
|
73365
|
+
access: "view",
|
|
73366
|
+
role: "admin"
|
|
73367
|
+
},
|
|
73368
|
+
"actions.getTraces": {
|
|
73369
|
+
capName: "actions",
|
|
73370
|
+
capScope: "system",
|
|
73371
|
+
addonId: null,
|
|
73372
|
+
access: "view",
|
|
73373
|
+
role: "admin"
|
|
73374
|
+
},
|
|
73375
|
+
"actions.list": {
|
|
73376
|
+
capName: "actions",
|
|
73377
|
+
capScope: "system",
|
|
73378
|
+
addonId: null,
|
|
73379
|
+
access: "view",
|
|
73380
|
+
role: "admin"
|
|
73381
|
+
},
|
|
73382
|
+
"actions.listForCamera": {
|
|
73383
|
+
capName: "actions",
|
|
73384
|
+
capScope: "system",
|
|
73385
|
+
addonId: null,
|
|
73386
|
+
access: "view",
|
|
73387
|
+
role: "viewer"
|
|
73388
|
+
},
|
|
73389
|
+
"actions.run": {
|
|
73390
|
+
capName: "actions",
|
|
73391
|
+
capScope: "system",
|
|
73392
|
+
addonId: null,
|
|
73393
|
+
access: "create",
|
|
73394
|
+
role: "viewer"
|
|
73395
|
+
},
|
|
73396
|
+
"actions.setLinks": {
|
|
73397
|
+
capName: "actions",
|
|
73398
|
+
capScope: "system",
|
|
73399
|
+
addonId: null,
|
|
73400
|
+
access: "create",
|
|
73401
|
+
role: "admin"
|
|
73402
|
+
},
|
|
73403
|
+
"actions.stop": {
|
|
73404
|
+
capName: "actions",
|
|
73405
|
+
capScope: "system",
|
|
73406
|
+
addonId: null,
|
|
73407
|
+
access: "create",
|
|
73408
|
+
role: "admin"
|
|
73409
|
+
},
|
|
73410
|
+
"actions.update": {
|
|
73411
|
+
capName: "actions",
|
|
73412
|
+
capScope: "system",
|
|
73413
|
+
addonId: null,
|
|
73414
|
+
access: "create",
|
|
73415
|
+
role: "admin"
|
|
73416
|
+
},
|
|
73417
|
+
"actionSource.listActions": {
|
|
73418
|
+
capName: "action-source",
|
|
73419
|
+
capScope: "system",
|
|
73420
|
+
addonId: null,
|
|
73421
|
+
access: "view",
|
|
73422
|
+
role: "admin"
|
|
73423
|
+
},
|
|
73424
|
+
"actionSource.runAction": {
|
|
73425
|
+
capName: "action-source",
|
|
73426
|
+
capScope: "system",
|
|
73427
|
+
addonId: null,
|
|
73428
|
+
access: "create",
|
|
73429
|
+
role: "admin"
|
|
73430
|
+
},
|
|
73431
|
+
"actionSource.stopAction": {
|
|
73432
|
+
capName: "action-source",
|
|
73433
|
+
capScope: "system",
|
|
73434
|
+
addonId: null,
|
|
73435
|
+
access: "create",
|
|
73436
|
+
role: "admin"
|
|
73437
|
+
},
|
|
72875
73438
|
"addonPages.listPages": {
|
|
72876
73439
|
capName: "addon-pages",
|
|
72877
73440
|
capScope: "system",
|
|
@@ -74153,6 +74716,13 @@ Object.freeze({
|
|
|
74153
74716
|
access: "view",
|
|
74154
74717
|
role: "admin"
|
|
74155
74718
|
},
|
|
74719
|
+
"coreBlocks.getAutomationRunState": {
|
|
74720
|
+
capName: "core-blocks",
|
|
74721
|
+
capScope: "system",
|
|
74722
|
+
addonId: null,
|
|
74723
|
+
access: "view",
|
|
74724
|
+
role: "admin"
|
|
74725
|
+
},
|
|
74156
74726
|
"coreBlocks.getBlockSettings": {
|
|
74157
74727
|
capName: "core-blocks",
|
|
74158
74728
|
capScope: "system",
|
|
@@ -74174,6 +74744,13 @@ Object.freeze({
|
|
|
74174
74744
|
access: "view",
|
|
74175
74745
|
role: "admin"
|
|
74176
74746
|
},
|
|
74747
|
+
"coreBlocks.getTraces": {
|
|
74748
|
+
capName: "core-blocks",
|
|
74749
|
+
capScope: "system",
|
|
74750
|
+
addonId: null,
|
|
74751
|
+
access: "view",
|
|
74752
|
+
role: "admin"
|
|
74753
|
+
},
|
|
74177
74754
|
"coreBlocks.getTypeDefs": {
|
|
74178
74755
|
capName: "core-blocks",
|
|
74179
74756
|
capScope: "system",
|
|
@@ -74209,6 +74786,13 @@ Object.freeze({
|
|
|
74209
74786
|
access: "create",
|
|
74210
74787
|
role: "admin"
|
|
74211
74788
|
},
|
|
74789
|
+
"coreBlocks.reportAutomationRun": {
|
|
74790
|
+
capName: "core-blocks",
|
|
74791
|
+
capScope: "system",
|
|
74792
|
+
addonId: null,
|
|
74793
|
+
access: "create",
|
|
74794
|
+
role: "admin"
|
|
74795
|
+
},
|
|
74212
74796
|
"coreBlocks.restart": {
|
|
74213
74797
|
capName: "core-blocks",
|
|
74214
74798
|
capScope: "system",
|
|
@@ -82782,7 +83366,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82782
83366
|
label: t("Full brightness", "Luminosità massima"),
|
|
82783
83367
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
82784
83368
|
icon: "sun",
|
|
82785
|
-
args: {
|
|
83369
|
+
args: { level: 100 }
|
|
82786
83370
|
},
|
|
82787
83371
|
{
|
|
82788
83372
|
id: "brightness.half",
|
|
@@ -82790,7 +83374,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82790
83374
|
label: t("Half brightness", "Luminosità a metà"),
|
|
82791
83375
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
82792
83376
|
icon: "sun-dim",
|
|
82793
|
-
args: {
|
|
83377
|
+
args: { level: 50 }
|
|
82794
83378
|
},
|
|
82795
83379
|
{
|
|
82796
83380
|
id: "brightness.off",
|
|
@@ -82798,16 +83382,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82798
83382
|
label: t("Brightness off", "Luminosità a zero"),
|
|
82799
83383
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
82800
83384
|
icon: "lightbulb-off",
|
|
82801
|
-
args: {
|
|
83385
|
+
args: { level: 0 }
|
|
82802
83386
|
},
|
|
82803
83387
|
{
|
|
82804
83388
|
id: "brightness.set",
|
|
82805
83389
|
method: "setBrightness",
|
|
82806
83390
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
82807
|
-
phrase: t("Set the brightness of {device} to {
|
|
83391
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
82808
83392
|
icon: "sun-medium",
|
|
82809
83393
|
openArgs: [{
|
|
82810
|
-
key: "
|
|
83394
|
+
key: "level",
|
|
82811
83395
|
label: PERCENT,
|
|
82812
83396
|
offer: {
|
|
82813
83397
|
kind: "number",
|
|
@@ -82821,13 +83405,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82821
83405
|
],
|
|
82822
83406
|
state: [{
|
|
82823
83407
|
kind: "numeric",
|
|
82824
|
-
field: "
|
|
83408
|
+
field: "level",
|
|
82825
83409
|
quantity: t("the brightness", "la luminosità"),
|
|
82826
83410
|
label: t("Brightness", "Luminosità"),
|
|
82827
83411
|
unit: "%",
|
|
82828
83412
|
icon: "sun"
|
|
82829
83413
|
}],
|
|
82830
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
83414
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
82831
83415
|
},
|
|
82832
83416
|
color: {
|
|
82833
83417
|
scope: "device",
|
|
@@ -82841,7 +83425,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82841
83425
|
icon: "sun",
|
|
82842
83426
|
args: { color: {
|
|
82843
83427
|
mode: "mired",
|
|
82844
|
-
|
|
83428
|
+
colorTemperature: 370
|
|
82845
83429
|
} }
|
|
82846
83430
|
},
|
|
82847
83431
|
{
|
|
@@ -82852,7 +83436,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82852
83436
|
icon: "snowflake",
|
|
82853
83437
|
args: { color: {
|
|
82854
83438
|
mode: "mired",
|
|
82855
|
-
|
|
83439
|
+
colorTemperature: 200
|
|
82856
83440
|
} }
|
|
82857
83441
|
},
|
|
82858
83442
|
{
|
|
@@ -83466,7 +84050,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83466
84050
|
label: t("Fan off", "Ventilatore spento"),
|
|
83467
84051
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
83468
84052
|
icon: "power-off",
|
|
83469
|
-
args: {
|
|
84053
|
+
args: { speed: 0 }
|
|
83470
84054
|
},
|
|
83471
84055
|
{
|
|
83472
84056
|
id: "fan.full",
|
|
@@ -83474,16 +84058,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83474
84058
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
83475
84059
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
83476
84060
|
icon: "fan",
|
|
83477
|
-
args: {
|
|
84061
|
+
args: { speed: 100 }
|
|
83478
84062
|
},
|
|
83479
84063
|
{
|
|
83480
84064
|
id: "fan.speed",
|
|
83481
84065
|
method: "setPercentage",
|
|
83482
84066
|
label: t("Set speed", "Imposta la velocità"),
|
|
83483
|
-
phrase: t("Set the speed of {device} to {
|
|
84067
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
83484
84068
|
icon: "fan",
|
|
83485
84069
|
openArgs: [{
|
|
83486
|
-
key: "
|
|
84070
|
+
key: "speed",
|
|
83487
84071
|
label: t("Speed", "Velocità"),
|
|
83488
84072
|
offer: {
|
|
83489
84073
|
kind: "number",
|
|
@@ -83545,7 +84129,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83545
84129
|
],
|
|
83546
84130
|
state: [{
|
|
83547
84131
|
kind: "numeric",
|
|
83548
|
-
field: "
|
|
84132
|
+
field: "speed",
|
|
83549
84133
|
quantity: t("the speed", "la velocità"),
|
|
83550
84134
|
label: t("Speed", "Velocità"),
|
|
83551
84135
|
unit: "%",
|
|
@@ -84343,7 +84927,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84343
84927
|
},
|
|
84344
84928
|
{
|
|
84345
84929
|
kind: "numeric",
|
|
84346
|
-
field: "
|
|
84930
|
+
field: "progress",
|
|
84347
84931
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
84348
84932
|
label: t("Progress", "Avanzamento"),
|
|
84349
84933
|
unit: "%",
|
|
@@ -84701,10 +85285,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84701
85285
|
id: "media.seek",
|
|
84702
85286
|
method: "seek",
|
|
84703
85287
|
label: t("Seek", "Vai al punto"),
|
|
84704
|
-
phrase: t("Move {device} to {
|
|
85288
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
84705
85289
|
icon: "fast-forward",
|
|
84706
85290
|
openArgs: [{
|
|
84707
|
-
key: "
|
|
85291
|
+
key: "position",
|
|
84708
85292
|
label: t("Position", "Posizione"),
|
|
84709
85293
|
offer: {
|
|
84710
85294
|
kind: "number",
|
|
@@ -85753,7 +86337,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85753
86337
|
state: [
|
|
85754
86338
|
{
|
|
85755
86339
|
kind: "numeric",
|
|
85756
|
-
field: "
|
|
86340
|
+
field: "co2",
|
|
85757
86341
|
quantity: t("the CO₂", "la CO₂"),
|
|
85758
86342
|
label: t("CO₂", "CO₂"),
|
|
85759
86343
|
unit: "ppm",
|
|
@@ -85761,7 +86345,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85761
86345
|
},
|
|
85762
86346
|
{
|
|
85763
86347
|
kind: "numeric",
|
|
85764
|
-
field: "
|
|
86348
|
+
field: "voc",
|
|
85765
86349
|
quantity: t("the VOC level", "il livello di COV"),
|
|
85766
86350
|
label: t("VOC", "COV"),
|
|
85767
86351
|
unit: "ppb",
|
|
@@ -85797,7 +86381,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85797
86381
|
noun: t("Light level", "Luminosità ambiente"),
|
|
85798
86382
|
state: [{
|
|
85799
86383
|
kind: "numeric",
|
|
85800
|
-
field: "
|
|
86384
|
+
field: "illuminance",
|
|
85801
86385
|
quantity: t("the light level", "la luminosità"),
|
|
85802
86386
|
label: t("Illuminance", "Illuminamento"),
|
|
85803
86387
|
unit: "lx",
|
|
@@ -86000,7 +86584,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86000
86584
|
noun: t("Humidity", "Umidità"),
|
|
86001
86585
|
state: [{
|
|
86002
86586
|
kind: "numeric",
|
|
86003
|
-
field: "
|
|
86587
|
+
field: "humidity",
|
|
86004
86588
|
quantity: t("the humidity", "l’umidità"),
|
|
86005
86589
|
label: t("Humidity", "Umidità"),
|
|
86006
86590
|
unit: "%",
|
|
@@ -86048,7 +86632,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86048
86632
|
state: [
|
|
86049
86633
|
{
|
|
86050
86634
|
kind: "numeric",
|
|
86051
|
-
field: "
|
|
86635
|
+
field: "power",
|
|
86052
86636
|
quantity: t("the power draw", "il consumo"),
|
|
86053
86637
|
label: t("Power", "Potenza"),
|
|
86054
86638
|
unit: "W",
|
|
@@ -86056,7 +86640,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86056
86640
|
},
|
|
86057
86641
|
{
|
|
86058
86642
|
kind: "numeric",
|
|
86059
|
-
field: "
|
|
86643
|
+
field: "energy",
|
|
86060
86644
|
quantity: t("the energy used", "l’energia consumata"),
|
|
86061
86645
|
label: t("Energy", "Energia"),
|
|
86062
86646
|
unit: "kWh",
|
|
@@ -86064,7 +86648,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86064
86648
|
},
|
|
86065
86649
|
{
|
|
86066
86650
|
kind: "numeric",
|
|
86067
|
-
field: "
|
|
86651
|
+
field: "voltage",
|
|
86068
86652
|
quantity: t("the voltage", "la tensione"),
|
|
86069
86653
|
label: t("Voltage", "Tensione"),
|
|
86070
86654
|
unit: "V",
|
|
@@ -86072,7 +86656,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86072
86656
|
},
|
|
86073
86657
|
{
|
|
86074
86658
|
kind: "numeric",
|
|
86075
|
-
field: "
|
|
86659
|
+
field: "current",
|
|
86076
86660
|
quantity: t("the current", "la corrente"),
|
|
86077
86661
|
label: t("Current", "Corrente"),
|
|
86078
86662
|
unit: "A",
|
|
@@ -86089,13 +86673,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86089
86673
|
label: t("Where", "Posizione"),
|
|
86090
86674
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
86091
86675
|
icon: "map-pin"
|
|
86092
|
-
}, {
|
|
86093
|
-
kind: "numeric",
|
|
86094
|
-
field: "batteryPercent",
|
|
86095
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
86096
|
-
label: t("Battery", "Batteria"),
|
|
86097
|
-
unit: "%",
|
|
86098
|
-
icon: "battery"
|
|
86099
86676
|
}]
|
|
86100
86677
|
},
|
|
86101
86678
|
"pressure-sensor": {
|
|
@@ -86103,7 +86680,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86103
86680
|
noun: t("Pressure", "Pressione"),
|
|
86104
86681
|
state: [{
|
|
86105
86682
|
kind: "numeric",
|
|
86106
|
-
field: "
|
|
86683
|
+
field: "pressure",
|
|
86107
86684
|
quantity: t("the pressure", "la pressione"),
|
|
86108
86685
|
label: t("Pressure", "Pressione"),
|
|
86109
86686
|
unit: "hPa",
|
|
@@ -86139,7 +86716,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86139
86716
|
noun: t("Temperature", "Temperatura"),
|
|
86140
86717
|
state: [{
|
|
86141
86718
|
kind: "numeric",
|
|
86142
|
-
field: "
|
|
86719
|
+
field: "temperature",
|
|
86143
86720
|
quantity: t("the temperature", "la temperatura"),
|
|
86144
86721
|
label: t("Temperature", "Temperatura"),
|
|
86145
86722
|
unit: "°C",
|
|
@@ -86210,7 +86787,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86210
86787
|
state: [
|
|
86211
86788
|
{
|
|
86212
86789
|
kind: "numeric",
|
|
86213
|
-
field: "
|
|
86790
|
+
field: "level",
|
|
86214
86791
|
quantity: t("the battery level", "il livello della batteria"),
|
|
86215
86792
|
label: t("Battery", "Batteria"),
|
|
86216
86793
|
unit: "%",
|
|
@@ -86252,7 +86829,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86252
86829
|
icon: "battery-charging"
|
|
86253
86830
|
}
|
|
86254
86831
|
],
|
|
86255
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
86832
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
86256
86833
|
extraEvents: [{
|
|
86257
86834
|
category: EventCategory.DeviceAwake,
|
|
86258
86835
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -86270,7 +86847,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86270
86847
|
noun: t("Network link", "Collegamento di rete"),
|
|
86271
86848
|
state: [{
|
|
86272
86849
|
kind: "numeric",
|
|
86273
|
-
field: "
|
|
86850
|
+
field: "signal",
|
|
86274
86851
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
86275
86852
|
label: t("Signal", "Segnale"),
|
|
86276
86853
|
unit: "%",
|
|
@@ -86363,6 +86940,8 @@ var ML = "model and training machinery — no device action";
|
|
|
86363
86940
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
86364
86941
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
86365
86942
|
var SYSTEM_CAP_VOCABULARY = {
|
|
86943
|
+
"action-source": system(INTERNAL),
|
|
86944
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
86366
86945
|
"addon-pages": system(UI_PLUMBING),
|
|
86367
86946
|
"addon-pages-source": system(UI_PLUMBING),
|
|
86368
86947
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -86570,6 +87149,31 @@ Object.freeze({
|
|
|
86570
87149
|
form: "single",
|
|
86571
87150
|
optional: false
|
|
86572
87151
|
}],
|
|
87152
|
+
"actions.get": [{
|
|
87153
|
+
name: "deviceId",
|
|
87154
|
+
form: "single",
|
|
87155
|
+
optional: true
|
|
87156
|
+
}],
|
|
87157
|
+
"actions.getLinks": [{
|
|
87158
|
+
name: "deviceId",
|
|
87159
|
+
form: "single",
|
|
87160
|
+
optional: false
|
|
87161
|
+
}],
|
|
87162
|
+
"actions.listForCamera": [{
|
|
87163
|
+
name: "deviceId",
|
|
87164
|
+
form: "single",
|
|
87165
|
+
optional: false
|
|
87166
|
+
}],
|
|
87167
|
+
"actions.run": [{
|
|
87168
|
+
name: "deviceId",
|
|
87169
|
+
form: "single",
|
|
87170
|
+
optional: true
|
|
87171
|
+
}],
|
|
87172
|
+
"actions.setLinks": [{
|
|
87173
|
+
name: "deviceId",
|
|
87174
|
+
form: "single",
|
|
87175
|
+
optional: false
|
|
87176
|
+
}],
|
|
86573
87177
|
"addonSettings.getDeviceSettings": [{
|
|
86574
87178
|
name: "deviceId",
|
|
86575
87179
|
form: "single",
|
|
@@ -91000,6 +91604,7 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
|
|
|
91000
91604
|
}
|
|
91001
91605
|
return best;
|
|
91002
91606
|
}
|
|
91607
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
91003
91608
|
var MB = 1024 * 1024;
|
|
91004
91609
|
1024 * MB, 3072 * MB;
|
|
91005
91610
|
//#endregion
|