@camstack/addon-provider-unifi 0.2.149 → 0.2.150
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 +6 -0
- package/dist/addon.js +843 -241
- package/dist/addon.mjs +843 -241
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
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.
|
|
@@ -5442,7 +5447,7 @@ var ZodIssueCode = {
|
|
|
5442
5447
|
var ZodFirstPartyTypeKind;
|
|
5443
5448
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5444
5449
|
//#endregion
|
|
5445
|
-
//#region ../types/dist/sleep
|
|
5450
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
5446
5451
|
/**
|
|
5447
5452
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5448
5453
|
* window to float samples (D455).
|
|
@@ -8562,6 +8567,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8562
8567
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8563
8568
|
var CAP_NAMES = Object.freeze([
|
|
8564
8569
|
"accessories",
|
|
8570
|
+
"action-source",
|
|
8571
|
+
"actions",
|
|
8565
8572
|
"addon-pages",
|
|
8566
8573
|
"addon-pages-source",
|
|
8567
8574
|
"addon-routes",
|
|
@@ -8750,11 +8757,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
8750
8757
|
Object.freeze({
|
|
8751
8758
|
"air-quality-sensor": [
|
|
8752
8759
|
{
|
|
8753
|
-
"path": "
|
|
8760
|
+
"path": "co2",
|
|
8754
8761
|
"valueType": "number"
|
|
8755
8762
|
},
|
|
8756
8763
|
{
|
|
8757
|
-
"path": "
|
|
8764
|
+
"path": "voc",
|
|
8758
8765
|
"valueType": "number"
|
|
8759
8766
|
},
|
|
8760
8767
|
{
|
|
@@ -8804,7 +8811,7 @@ Object.freeze({
|
|
|
8804
8811
|
}
|
|
8805
8812
|
],
|
|
8806
8813
|
"ambient-light-sensor": [{
|
|
8807
|
-
"path": "
|
|
8814
|
+
"path": "illuminance",
|
|
8808
8815
|
"valueType": "number"
|
|
8809
8816
|
}],
|
|
8810
8817
|
"audio-metrics": [
|
|
@@ -8865,7 +8872,7 @@ Object.freeze({
|
|
|
8865
8872
|
],
|
|
8866
8873
|
"battery": [
|
|
8867
8874
|
{
|
|
8868
|
-
"path": "
|
|
8875
|
+
"path": "level",
|
|
8869
8876
|
"valueType": "number"
|
|
8870
8877
|
},
|
|
8871
8878
|
{
|
|
@@ -8887,7 +8894,7 @@ Object.freeze({
|
|
|
8887
8894
|
"valueType": "number"
|
|
8888
8895
|
},
|
|
8889
8896
|
{
|
|
8890
|
-
"path": "
|
|
8897
|
+
"path": "voltage",
|
|
8891
8898
|
"valueType": "number"
|
|
8892
8899
|
},
|
|
8893
8900
|
{
|
|
@@ -8908,7 +8915,7 @@ Object.freeze({
|
|
|
8908
8915
|
"valueType": "boolean"
|
|
8909
8916
|
}],
|
|
8910
8917
|
"brightness": [{
|
|
8911
|
-
"path": "
|
|
8918
|
+
"path": "level",
|
|
8912
8919
|
"valueType": "number"
|
|
8913
8920
|
}],
|
|
8914
8921
|
"broker": [{
|
|
@@ -9109,7 +9116,7 @@ Object.freeze({
|
|
|
9109
9116
|
"valueType": "number"
|
|
9110
9117
|
},
|
|
9111
9118
|
{
|
|
9112
|
-
"path": "
|
|
9119
|
+
"path": "colorTemperature",
|
|
9113
9120
|
"valueType": "number"
|
|
9114
9121
|
}
|
|
9115
9122
|
],
|
|
@@ -9288,15 +9295,15 @@ Object.freeze({
|
|
|
9288
9295
|
"valueType": "string"
|
|
9289
9296
|
},
|
|
9290
9297
|
{
|
|
9291
|
-
"path": "
|
|
9298
|
+
"path": "remaining",
|
|
9292
9299
|
"valueType": "number"
|
|
9293
9300
|
},
|
|
9294
9301
|
{
|
|
9295
|
-
"path": "
|
|
9302
|
+
"path": "delayedStart",
|
|
9296
9303
|
"valueType": "number"
|
|
9297
9304
|
},
|
|
9298
9305
|
{
|
|
9299
|
-
"path": "
|
|
9306
|
+
"path": "progress",
|
|
9300
9307
|
"valueType": "number"
|
|
9301
9308
|
},
|
|
9302
9309
|
{
|
|
@@ -9410,7 +9417,7 @@ Object.freeze({
|
|
|
9410
9417
|
],
|
|
9411
9418
|
"fan-control": [
|
|
9412
9419
|
{
|
|
9413
|
-
"path": "
|
|
9420
|
+
"path": "speed",
|
|
9414
9421
|
"valueType": "number"
|
|
9415
9422
|
},
|
|
9416
9423
|
{
|
|
@@ -9510,7 +9517,7 @@ Object.freeze({
|
|
|
9510
9517
|
}
|
|
9511
9518
|
],
|
|
9512
9519
|
"humidity-sensor": [{
|
|
9513
|
-
"path": "
|
|
9520
|
+
"path": "humidity",
|
|
9514
9521
|
"valueType": "number"
|
|
9515
9522
|
}],
|
|
9516
9523
|
"image": [{
|
|
@@ -9620,7 +9627,7 @@ Object.freeze({
|
|
|
9620
9627
|
"valueType": "number"
|
|
9621
9628
|
},
|
|
9622
9629
|
{
|
|
9623
|
-
"path": "
|
|
9630
|
+
"path": "progress",
|
|
9624
9631
|
"valueType": "number"
|
|
9625
9632
|
},
|
|
9626
9633
|
{
|
|
@@ -9699,11 +9706,11 @@ Object.freeze({
|
|
|
9699
9706
|
"valueType": "string"
|
|
9700
9707
|
},
|
|
9701
9708
|
{
|
|
9702
|
-
"path": "
|
|
9709
|
+
"path": "position",
|
|
9703
9710
|
"valueType": "number"
|
|
9704
9711
|
},
|
|
9705
9712
|
{
|
|
9706
|
-
"path": "
|
|
9713
|
+
"path": "duration",
|
|
9707
9714
|
"valueType": "number"
|
|
9708
9715
|
},
|
|
9709
9716
|
{
|
|
@@ -9805,11 +9812,11 @@ Object.freeze({
|
|
|
9805
9812
|
]
|
|
9806
9813
|
},
|
|
9807
9814
|
{
|
|
9808
|
-
"path": "
|
|
9815
|
+
"path": "signal",
|
|
9809
9816
|
"valueType": "number"
|
|
9810
9817
|
},
|
|
9811
9818
|
{
|
|
9812
|
-
"path": "
|
|
9819
|
+
"path": "rssi",
|
|
9813
9820
|
"valueType": "number"
|
|
9814
9821
|
},
|
|
9815
9822
|
{
|
|
@@ -9864,6 +9871,18 @@ Object.freeze({
|
|
|
9864
9871
|
"path": "foodLevel",
|
|
9865
9872
|
"valueType": "number"
|
|
9866
9873
|
},
|
|
9874
|
+
{
|
|
9875
|
+
"path": "bowlFood",
|
|
9876
|
+
"valueType": "number"
|
|
9877
|
+
},
|
|
9878
|
+
{
|
|
9879
|
+
"path": "eating",
|
|
9880
|
+
"valueType": "boolean"
|
|
9881
|
+
},
|
|
9882
|
+
{
|
|
9883
|
+
"path": "supportsMarkRefilled",
|
|
9884
|
+
"valueType": "boolean"
|
|
9885
|
+
},
|
|
9867
9886
|
{
|
|
9868
9887
|
"path": "food1",
|
|
9869
9888
|
"valueType": "number"
|
|
@@ -9928,23 +9947,23 @@ Object.freeze({
|
|
|
9928
9947
|
],
|
|
9929
9948
|
"power-meter": [
|
|
9930
9949
|
{
|
|
9931
|
-
"path": "
|
|
9950
|
+
"path": "power",
|
|
9932
9951
|
"valueType": "number"
|
|
9933
9952
|
},
|
|
9934
9953
|
{
|
|
9935
|
-
"path": "
|
|
9954
|
+
"path": "energy",
|
|
9936
9955
|
"valueType": "number"
|
|
9937
9956
|
},
|
|
9938
9957
|
{
|
|
9939
|
-
"path": "
|
|
9958
|
+
"path": "voltage",
|
|
9940
9959
|
"valueType": "number"
|
|
9941
9960
|
},
|
|
9942
9961
|
{
|
|
9943
|
-
"path": "
|
|
9962
|
+
"path": "current",
|
|
9944
9963
|
"valueType": "number"
|
|
9945
9964
|
},
|
|
9946
9965
|
{
|
|
9947
|
-
"path": "
|
|
9966
|
+
"path": "apparentPower",
|
|
9948
9967
|
"valueType": "number"
|
|
9949
9968
|
},
|
|
9950
9969
|
{
|
|
@@ -9972,14 +9991,10 @@ Object.freeze({
|
|
|
9972
9991
|
{
|
|
9973
9992
|
"path": "gps.accuracyMeters",
|
|
9974
9993
|
"valueType": "number"
|
|
9975
|
-
},
|
|
9976
|
-
{
|
|
9977
|
-
"path": "batteryPercent",
|
|
9978
|
-
"valueType": "number"
|
|
9979
9994
|
}
|
|
9980
9995
|
],
|
|
9981
9996
|
"pressure-sensor": [{
|
|
9982
|
-
"path": "
|
|
9997
|
+
"path": "pressure",
|
|
9983
9998
|
"valueType": "number"
|
|
9984
9999
|
}],
|
|
9985
10000
|
"privacy-mask": [{
|
|
@@ -10293,7 +10308,7 @@ Object.freeze({
|
|
|
10293
10308
|
"valueType": "boolean"
|
|
10294
10309
|
}],
|
|
10295
10310
|
"temperature-sensor": [{
|
|
10296
|
-
"path": "
|
|
10311
|
+
"path": "temperature",
|
|
10297
10312
|
"valueType": "number"
|
|
10298
10313
|
}],
|
|
10299
10314
|
"update": [
|
|
@@ -10341,7 +10356,7 @@ Object.freeze({
|
|
|
10341
10356
|
"valueType": "string"
|
|
10342
10357
|
},
|
|
10343
10358
|
{
|
|
10344
|
-
"path": "
|
|
10359
|
+
"path": "progress",
|
|
10345
10360
|
"valueType": "number"
|
|
10346
10361
|
},
|
|
10347
10362
|
{
|
|
@@ -10840,7 +10855,7 @@ function errMsg(err) {
|
|
|
10840
10855
|
return String(err);
|
|
10841
10856
|
}
|
|
10842
10857
|
//#endregion
|
|
10843
|
-
//#region ../types/dist/composition-
|
|
10858
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
10844
10859
|
/**
|
|
10845
10860
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10846
10861
|
*
|
|
@@ -15360,6 +15375,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
15360
15375
|
array(union([string(), number()]))
|
|
15361
15376
|
])
|
|
15362
15377
|
});
|
|
15378
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
15379
|
+
kind: literal("stationary-present"),
|
|
15380
|
+
deviceId: number().int().nonnegative(),
|
|
15381
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
15382
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15383
|
+
/** The parked object must be in at least one of these zones. */
|
|
15384
|
+
zones: array(string().min(1)).min(1).optional()
|
|
15385
|
+
});
|
|
15363
15386
|
/**
|
|
15364
15387
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
15365
15388
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -15393,7 +15416,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
15393
15416
|
child: AutomationConditionSchema
|
|
15394
15417
|
}),
|
|
15395
15418
|
AutomationConditionLeafSchema,
|
|
15396
|
-
AutomationConditionExpressionSchema
|
|
15419
|
+
AutomationConditionExpressionSchema,
|
|
15420
|
+
AutomationConditionStationaryPresentSchema
|
|
15397
15421
|
]));
|
|
15398
15422
|
/**
|
|
15399
15423
|
* What starts a run.
|
|
@@ -15434,7 +15458,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15434
15458
|
kind: literal("schedule"),
|
|
15435
15459
|
cron: string().min(1).max(120)
|
|
15436
15460
|
}),
|
|
15437
|
-
object({ kind: literal("manual") })
|
|
15461
|
+
object({ kind: literal("manual") }),
|
|
15462
|
+
object({
|
|
15463
|
+
kind: literal("detection"),
|
|
15464
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
15465
|
+
* matches every raw class that maps to it; any other name matches
|
|
15466
|
+
* exactly. */
|
|
15467
|
+
classes: array(string().min(1)).min(1),
|
|
15468
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15469
|
+
/** The track must have visited at least one of these zones. */
|
|
15470
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15471
|
+
/** Best-so-far confidence the track must reach. */
|
|
15472
|
+
minScore: number().min(0).max(1).optional()
|
|
15473
|
+
}),
|
|
15474
|
+
object({
|
|
15475
|
+
kind: literal("stationary"),
|
|
15476
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15477
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
15478
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15479
|
+
/** The parked object must be in at least one of these zones. */
|
|
15480
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15481
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
15482
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
15483
|
+
phase: _enum(["appeared", "departed"])
|
|
15484
|
+
}),
|
|
15485
|
+
object({
|
|
15486
|
+
kind: literal("interval"),
|
|
15487
|
+
minutes: number().int().min(1).max(1440)
|
|
15488
|
+
})
|
|
15438
15489
|
]);
|
|
15439
15490
|
/**
|
|
15440
15491
|
* One action step.
|
|
@@ -15454,28 +15505,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15454
15505
|
* is called. The runner still receives a number and is untouched; the
|
|
15455
15506
|
* resolution is the recipe's job, not the runner's.
|
|
15456
15507
|
*/
|
|
15508
|
+
var AutomationWaitStepSchema = object({
|
|
15509
|
+
kind: literal("wait"),
|
|
15510
|
+
seconds: number().min(0).max(300)
|
|
15511
|
+
});
|
|
15512
|
+
var AutomationCapStepSchema = object({
|
|
15513
|
+
kind: literal("cap"),
|
|
15514
|
+
/**
|
|
15515
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
15516
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
15517
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
15518
|
+
*/
|
|
15519
|
+
deviceId: union([
|
|
15520
|
+
number().int(),
|
|
15521
|
+
array(number().int()).min(1),
|
|
15522
|
+
object({ $var: string().min(1) })
|
|
15523
|
+
]),
|
|
15524
|
+
cap: string().min(1),
|
|
15525
|
+
method: string().min(1),
|
|
15526
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
15527
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
15528
|
+
* the expression leaf. */
|
|
15529
|
+
args: record(string(), unknown()).optional()
|
|
15530
|
+
});
|
|
15531
|
+
/**
|
|
15532
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
15533
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
15534
|
+
*/
|
|
15535
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
15457
15536
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
15537
|
+
AutomationWaitStepSchema,
|
|
15538
|
+
AutomationCapStepSchema,
|
|
15458
15539
|
object({
|
|
15459
|
-
kind: literal("
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
*/
|
|
15469
|
-
deviceId: union([
|
|
15470
|
-
number().int(),
|
|
15471
|
-
array(number().int()).min(1),
|
|
15472
|
-
object({ $var: string().min(1) })
|
|
15473
|
-
]),
|
|
15474
|
-
cap: string().min(1),
|
|
15475
|
-
method: string().min(1),
|
|
15476
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
15477
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
15478
|
-
args: record(string(), unknown()).optional()
|
|
15540
|
+
kind: literal("action"),
|
|
15541
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
15542
|
+
actionId: string().min(1),
|
|
15543
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
15544
|
+
variables: record(string(), union([
|
|
15545
|
+
string(),
|
|
15546
|
+
number(),
|
|
15547
|
+
boolean()
|
|
15548
|
+
])).optional()
|
|
15479
15549
|
}),
|
|
15480
15550
|
object({
|
|
15481
15551
|
kind: literal("code"),
|
|
@@ -15484,10 +15554,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
15484
15554
|
code: string().min(1).max(2e4)
|
|
15485
15555
|
})
|
|
15486
15556
|
]);
|
|
15557
|
+
/**
|
|
15558
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
15559
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
15560
|
+
* actions. Absent means `single`.
|
|
15561
|
+
*
|
|
15562
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
15563
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
15564
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
15565
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
15566
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
15567
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
15568
|
+
* wait, never the single/queued limits.
|
|
15569
|
+
*/
|
|
15570
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
15571
|
+
object({ mode: literal("single") }),
|
|
15572
|
+
object({ mode: literal("restart") }),
|
|
15573
|
+
object({
|
|
15574
|
+
mode: literal("queued"),
|
|
15575
|
+
max: number().int().min(1).max(10)
|
|
15576
|
+
}),
|
|
15577
|
+
object({
|
|
15578
|
+
mode: literal("parallel"),
|
|
15579
|
+
max: number().int().min(1).max(10)
|
|
15580
|
+
}),
|
|
15581
|
+
object({
|
|
15582
|
+
mode: literal("cooldown"),
|
|
15583
|
+
minutes: number().int().min(1).max(1440)
|
|
15584
|
+
})
|
|
15585
|
+
]);
|
|
15487
15586
|
var AutomationRecipeSchema = object({
|
|
15488
15587
|
triggers: array(AutomationTriggerSchema),
|
|
15489
15588
|
conditions: AutomationConditionSchema.optional(),
|
|
15490
|
-
actions: array(AutomationActionSchema)
|
|
15589
|
+
actions: array(AutomationActionSchema),
|
|
15590
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
15591
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
15592
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
15593
|
+
});
|
|
15594
|
+
new Set([
|
|
15595
|
+
{
|
|
15596
|
+
id: "person",
|
|
15597
|
+
name: "Person"
|
|
15598
|
+
},
|
|
15599
|
+
{
|
|
15600
|
+
id: "vehicle",
|
|
15601
|
+
name: "Vehicle"
|
|
15602
|
+
},
|
|
15603
|
+
{
|
|
15604
|
+
id: "animal",
|
|
15605
|
+
name: "Animal"
|
|
15606
|
+
},
|
|
15607
|
+
{
|
|
15608
|
+
id: "package",
|
|
15609
|
+
name: "Package"
|
|
15610
|
+
}
|
|
15611
|
+
].map((l) => l.id));
|
|
15612
|
+
var COCO_TO_MACRO = {
|
|
15613
|
+
mapping: {
|
|
15614
|
+
person: "person",
|
|
15615
|
+
bicycle: "vehicle",
|
|
15616
|
+
car: "vehicle",
|
|
15617
|
+
motorcycle: "vehicle",
|
|
15618
|
+
airplane: "vehicle",
|
|
15619
|
+
bus: "vehicle",
|
|
15620
|
+
train: "vehicle",
|
|
15621
|
+
truck: "vehicle",
|
|
15622
|
+
boat: "vehicle",
|
|
15623
|
+
bird: "animal",
|
|
15624
|
+
cat: "animal",
|
|
15625
|
+
dog: "animal",
|
|
15626
|
+
horse: "animal",
|
|
15627
|
+
sheep: "animal",
|
|
15628
|
+
cow: "animal",
|
|
15629
|
+
elephant: "animal",
|
|
15630
|
+
bear: "animal",
|
|
15631
|
+
zebra: "animal",
|
|
15632
|
+
giraffe: "animal",
|
|
15633
|
+
suitcase: "package",
|
|
15634
|
+
backpack: "package",
|
|
15635
|
+
handbag: "package"
|
|
15636
|
+
},
|
|
15637
|
+
preserveOriginal: false
|
|
15638
|
+
};
|
|
15639
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
15640
|
+
/**
|
|
15641
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
15642
|
+
* so the editor can paint every block green or red with its reason.
|
|
15643
|
+
*
|
|
15644
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
15645
|
+
* every condition node (containers and leaves, including the ones a
|
|
15646
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
15647
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
15648
|
+
* for an Action run). Skipped
|
|
15649
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
15650
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
15651
|
+
*
|
|
15652
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
15653
|
+
* vocabulary so an Action run records the same step shape.
|
|
15654
|
+
*/
|
|
15655
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
15656
|
+
var TraceValueSchema = union([
|
|
15657
|
+
string(),
|
|
15658
|
+
number(),
|
|
15659
|
+
boolean(),
|
|
15660
|
+
_null(),
|
|
15661
|
+
array(union([string(), number()]))
|
|
15662
|
+
]);
|
|
15663
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
15664
|
+
"ran",
|
|
15665
|
+
"skipped-trigger",
|
|
15666
|
+
"skipped-conditions",
|
|
15667
|
+
"skipped-cooldown",
|
|
15668
|
+
"skipped-overlap",
|
|
15669
|
+
"failed",
|
|
15670
|
+
"aborted"
|
|
15671
|
+
]);
|
|
15672
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
15673
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
15674
|
+
"pass",
|
|
15675
|
+
"fail",
|
|
15676
|
+
"not-evaluated"
|
|
15677
|
+
]);
|
|
15678
|
+
var AutomationTriggerTraceSchema = object({
|
|
15679
|
+
kind: string().min(1),
|
|
15680
|
+
outcome: _enum(["pass", "fail"]),
|
|
15681
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
15682
|
+
reason: string(),
|
|
15683
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
15684
|
+
vars: record(string(), TraceValueSchema)
|
|
15685
|
+
});
|
|
15686
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
15687
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
15688
|
+
path: string().min(1),
|
|
15689
|
+
kind: _enum([
|
|
15690
|
+
"all",
|
|
15691
|
+
"any",
|
|
15692
|
+
"not",
|
|
15693
|
+
"condition",
|
|
15694
|
+
"expression",
|
|
15695
|
+
"stationary-present"
|
|
15696
|
+
]),
|
|
15697
|
+
outcome: TraceNodeOutcomeSchema,
|
|
15698
|
+
reason: string(),
|
|
15699
|
+
deviceId: number().int().optional(),
|
|
15700
|
+
cap: string().optional(),
|
|
15701
|
+
fieldPath: string().optional(),
|
|
15702
|
+
operator: string().optional(),
|
|
15703
|
+
expected: TraceValueSchema.optional(),
|
|
15704
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
15705
|
+
observed: TraceValueSchema.optional()
|
|
15706
|
+
});
|
|
15707
|
+
var AutomationRunVerdictSchema = object({
|
|
15708
|
+
mode: AutomationRunModeSchema,
|
|
15709
|
+
decision: _enum([
|
|
15710
|
+
"run",
|
|
15711
|
+
"queued",
|
|
15712
|
+
"restart",
|
|
15713
|
+
"drop",
|
|
15714
|
+
"cooldown",
|
|
15715
|
+
"bypass"
|
|
15716
|
+
]),
|
|
15717
|
+
reason: string()
|
|
15718
|
+
});
|
|
15719
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
15720
|
+
var AutomationStepTraceSchema = object({
|
|
15721
|
+
/** `actions.<i>` */
|
|
15722
|
+
path: string().min(1),
|
|
15723
|
+
kind: string().min(1),
|
|
15724
|
+
cap: string().optional(),
|
|
15725
|
+
method: string().optional(),
|
|
15726
|
+
deviceId: number().int().optional(),
|
|
15727
|
+
startedAt: number().optional(),
|
|
15728
|
+
endedAt: number().optional(),
|
|
15729
|
+
outcome: _enum([
|
|
15730
|
+
"ok",
|
|
15731
|
+
"error",
|
|
15732
|
+
"not-run"
|
|
15733
|
+
]),
|
|
15734
|
+
message: string().optional()
|
|
15735
|
+
});
|
|
15736
|
+
var AutomationRunTraceSchema = object({
|
|
15737
|
+
runId: string().min(1),
|
|
15738
|
+
startedAt: number(),
|
|
15739
|
+
endedAt: number(),
|
|
15740
|
+
trigger: AutomationTriggerTraceSchema,
|
|
15741
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
15742
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
15743
|
+
steps: array(AutomationStepTraceSchema),
|
|
15744
|
+
outcome: AutomationRunOutcomeSchema,
|
|
15745
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
15746
|
+
repeat: number().int().min(1),
|
|
15747
|
+
/** When the latest of those repeats happened. */
|
|
15748
|
+
lastAt: number()
|
|
15749
|
+
});
|
|
15750
|
+
/**
|
|
15751
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
15752
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
15753
|
+
*/
|
|
15754
|
+
var AutomationStateDocSchema = object({
|
|
15755
|
+
version: literal(1),
|
|
15756
|
+
lastRunStartedAt: number().nullable(),
|
|
15757
|
+
traces: array(AutomationRunTraceSchema)
|
|
15758
|
+
});
|
|
15759
|
+
/**
|
|
15760
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
15761
|
+
* declared as LIST ENTRIES, never as devices.
|
|
15762
|
+
*
|
|
15763
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
15764
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
15765
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
15766
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
15767
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
15768
|
+
*
|
|
15769
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
15770
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
15771
|
+
* runtime.
|
|
15772
|
+
*/
|
|
15773
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
15774
|
+
var ActionVariableTypeSchema = _enum([
|
|
15775
|
+
"string",
|
|
15776
|
+
"number",
|
|
15777
|
+
"boolean",
|
|
15778
|
+
"select"
|
|
15779
|
+
]);
|
|
15780
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
15781
|
+
var ActionVariableValueSchema = union([
|
|
15782
|
+
string(),
|
|
15783
|
+
number(),
|
|
15784
|
+
boolean()
|
|
15785
|
+
]);
|
|
15786
|
+
/**
|
|
15787
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
15788
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
15789
|
+
*/
|
|
15790
|
+
var ActionVariableSchema = object({
|
|
15791
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
15792
|
+
label: string().min(1).max(120).optional(),
|
|
15793
|
+
type: ActionVariableTypeSchema,
|
|
15794
|
+
required: boolean().optional(),
|
|
15795
|
+
default: ActionVariableValueSchema.optional(),
|
|
15796
|
+
/** The allowed values of a `select`. */
|
|
15797
|
+
options: array(string().min(1)).min(1).optional()
|
|
15798
|
+
}).superRefine((v, ctx) => {
|
|
15799
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
15800
|
+
code: "custom",
|
|
15801
|
+
message: "a select variable needs options",
|
|
15802
|
+
path: ["options"]
|
|
15803
|
+
});
|
|
15804
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
15805
|
+
code: "custom",
|
|
15806
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
15807
|
+
path: ["default"]
|
|
15808
|
+
});
|
|
15809
|
+
});
|
|
15810
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
15811
|
+
function variableValueError(variable, value) {
|
|
15812
|
+
switch (variable.type) {
|
|
15813
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
15814
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
15815
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
15816
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
15817
|
+
}
|
|
15818
|
+
}
|
|
15819
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
15820
|
+
function isInternalActionId(actionId) {
|
|
15821
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
15822
|
+
}
|
|
15823
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
15824
|
+
function addonIdOfActionId(actionId) {
|
|
15825
|
+
if (isInternalActionId(actionId)) return null;
|
|
15826
|
+
const at = actionId.indexOf(":");
|
|
15827
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
15828
|
+
}
|
|
15829
|
+
var ActionStatusSchema = object({
|
|
15830
|
+
isRunning: boolean(),
|
|
15831
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
15832
|
+
lastRunAt: number().nullable(),
|
|
15833
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
15834
|
+
lastError: string().nullable()
|
|
15835
|
+
});
|
|
15836
|
+
var ActionEntrySchema = object({
|
|
15837
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
15838
|
+
id: string().min(3),
|
|
15839
|
+
name: string().min(1).max(120),
|
|
15840
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
15841
|
+
addonId: string().min(1),
|
|
15842
|
+
source: ActionSourceKindSchema,
|
|
15843
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
15844
|
+
readOnly: boolean(),
|
|
15845
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
15846
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
15847
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
15848
|
+
status: ActionStatusSchema
|
|
15849
|
+
}).superRefine((entry, ctx) => {
|
|
15850
|
+
if (entry.source === "internal") {
|
|
15851
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
15852
|
+
code: "custom",
|
|
15853
|
+
message: "an internal action id is internal:<uuid>",
|
|
15854
|
+
path: ["id"]
|
|
15855
|
+
});
|
|
15856
|
+
return;
|
|
15857
|
+
}
|
|
15858
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
15859
|
+
code: "custom",
|
|
15860
|
+
message: "only an internal action carries steps",
|
|
15861
|
+
path: ["steps"]
|
|
15862
|
+
});
|
|
15863
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
15864
|
+
code: "custom",
|
|
15865
|
+
message: "an addon action is read-only here",
|
|
15866
|
+
path: ["readOnly"]
|
|
15867
|
+
});
|
|
15868
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
15869
|
+
code: "custom",
|
|
15870
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
15871
|
+
path: ["id"]
|
|
15872
|
+
});
|
|
15873
|
+
});
|
|
15874
|
+
/** What an operator writes for an internal action. */
|
|
15875
|
+
var ActionInputSchema = object({
|
|
15876
|
+
name: string().min(1).max(120),
|
|
15877
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
15878
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
15879
|
+
});
|
|
15880
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
15881
|
+
var ActionRunOriginSchema = object({
|
|
15882
|
+
/** The automation block whose step started it. */
|
|
15883
|
+
blockId: string().min(1).optional() });
|
|
15884
|
+
/** `started` = the caller did not ask to wait. */
|
|
15885
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
15886
|
+
var ActionRunResultSchema = object({
|
|
15887
|
+
runId: string().min(1),
|
|
15888
|
+
outcome: ActionRunOutcomeSchema,
|
|
15889
|
+
/** Why it did not run, or what failed. */
|
|
15890
|
+
message: string().optional()
|
|
15891
|
+
});
|
|
15892
|
+
_enum([
|
|
15893
|
+
"not-found",
|
|
15894
|
+
"read-only",
|
|
15895
|
+
"invalid-variables",
|
|
15896
|
+
"invalid-steps",
|
|
15897
|
+
"not-linked",
|
|
15898
|
+
"busy"
|
|
15899
|
+
]);
|
|
15900
|
+
object({
|
|
15901
|
+
actionId: string(),
|
|
15902
|
+
runId: string(),
|
|
15903
|
+
isRunning: boolean(),
|
|
15904
|
+
/** Set when the run ended. */
|
|
15905
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
15906
|
+
lastRunAt: number().nullable(),
|
|
15907
|
+
lastError: string().nullable()
|
|
15491
15908
|
});
|
|
15492
15909
|
/**
|
|
15493
15910
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18174,7 +18591,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18174
18591
|
stateField: string(),
|
|
18175
18592
|
fieldKey: string()
|
|
18176
18593
|
});
|
|
18177
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
18594
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18178
18595
|
var CompositionProblemSchema = object({
|
|
18179
18596
|
code: _enum([
|
|
18180
18597
|
"reserved-variant",
|
|
@@ -18493,7 +18910,7 @@ var GROUP_TEMPLATES = [
|
|
|
18493
18910
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18494
18911
|
role: DeviceRole.TemperatureSensor,
|
|
18495
18912
|
outputCap: "temperature-sensor",
|
|
18496
|
-
outputField: "
|
|
18913
|
+
outputField: "temperature",
|
|
18497
18914
|
quantity: "temperature",
|
|
18498
18915
|
defaultAggregate: "mean",
|
|
18499
18916
|
empty: "null",
|
|
@@ -18504,7 +18921,7 @@ var GROUP_TEMPLATES = [
|
|
|
18504
18921
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18505
18922
|
role: DeviceRole.HumiditySensor,
|
|
18506
18923
|
outputCap: "humidity-sensor",
|
|
18507
|
-
outputField: "
|
|
18924
|
+
outputField: "humidity",
|
|
18508
18925
|
quantity: "humidity",
|
|
18509
18926
|
defaultAggregate: "mean",
|
|
18510
18927
|
empty: "null",
|
|
@@ -18515,7 +18932,7 @@ var GROUP_TEMPLATES = [
|
|
|
18515
18932
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18516
18933
|
role: DeviceRole.PressureSensor,
|
|
18517
18934
|
outputCap: "pressure-sensor",
|
|
18518
|
-
outputField: "
|
|
18935
|
+
outputField: "pressure",
|
|
18519
18936
|
quantity: "pressure",
|
|
18520
18937
|
defaultAggregate: "mean",
|
|
18521
18938
|
empty: "null",
|
|
@@ -18526,7 +18943,7 @@ var GROUP_TEMPLATES = [
|
|
|
18526
18943
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18527
18944
|
role: DeviceRole.AmbientLightSensor,
|
|
18528
18945
|
outputCap: "ambient-light-sensor",
|
|
18529
|
-
outputField: "
|
|
18946
|
+
outputField: "illuminance",
|
|
18530
18947
|
quantity: "illuminance",
|
|
18531
18948
|
defaultAggregate: "mean",
|
|
18532
18949
|
empty: "null",
|
|
@@ -18537,7 +18954,7 @@ var GROUP_TEMPLATES = [
|
|
|
18537
18954
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18538
18955
|
role: DeviceRole.PowerSensor,
|
|
18539
18956
|
outputCap: "power-meter",
|
|
18540
|
-
outputField: "
|
|
18957
|
+
outputField: "power",
|
|
18541
18958
|
quantity: "power",
|
|
18542
18959
|
defaultAggregate: "sum",
|
|
18543
18960
|
empty: "omit",
|
|
@@ -18548,7 +18965,7 @@ var GROUP_TEMPLATES = [
|
|
|
18548
18965
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18549
18966
|
role: DeviceRole.EnergySensor,
|
|
18550
18967
|
outputCap: "power-meter",
|
|
18551
|
-
outputField: "
|
|
18968
|
+
outputField: "energy",
|
|
18552
18969
|
quantity: "energy",
|
|
18553
18970
|
defaultAggregate: "sum",
|
|
18554
18971
|
empty: "omit",
|
|
@@ -18559,7 +18976,7 @@ var GROUP_TEMPLATES = [
|
|
|
18559
18976
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18560
18977
|
role: DeviceRole.BatterySensor,
|
|
18561
18978
|
outputCap: "battery",
|
|
18562
|
-
outputField: "
|
|
18979
|
+
outputField: "level",
|
|
18563
18980
|
quantity: "percentage",
|
|
18564
18981
|
defaultAggregate: "mean",
|
|
18565
18982
|
empty: "null",
|
|
@@ -19137,7 +19554,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19137
19554
|
kind: "mutation",
|
|
19138
19555
|
auth: "admin",
|
|
19139
19556
|
access: "view"
|
|
19140
|
-
})
|
|
19557
|
+
}), method(object({
|
|
19558
|
+
blockId: string().min(1),
|
|
19559
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
19560
|
+
runStartedAt: number().optional(),
|
|
19561
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
19562
|
+
}), _void(), {
|
|
19563
|
+
kind: "mutation",
|
|
19564
|
+
auth: "admin"
|
|
19565
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
19566
|
+
traces: array(AutomationRunTraceSchema),
|
|
19567
|
+
lastError: string().nullable()
|
|
19568
|
+
}), { auth: "admin" });
|
|
19141
19569
|
/**
|
|
19142
19570
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19143
19571
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -44535,51 +44963,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
44535
44963
|
kind: "mutation",
|
|
44536
44964
|
auth: "admin"
|
|
44537
44965
|
});
|
|
44538
|
-
new Set([
|
|
44539
|
-
{
|
|
44540
|
-
id: "person",
|
|
44541
|
-
name: "Person"
|
|
44542
|
-
},
|
|
44543
|
-
{
|
|
44544
|
-
id: "vehicle",
|
|
44545
|
-
name: "Vehicle"
|
|
44546
|
-
},
|
|
44547
|
-
{
|
|
44548
|
-
id: "animal",
|
|
44549
|
-
name: "Animal"
|
|
44550
|
-
},
|
|
44551
|
-
{
|
|
44552
|
-
id: "package",
|
|
44553
|
-
name: "Package"
|
|
44554
|
-
}
|
|
44555
|
-
].map((l) => l.id));
|
|
44556
|
-
var COCO_TO_MACRO = {
|
|
44557
|
-
mapping: {
|
|
44558
|
-
person: "person",
|
|
44559
|
-
bicycle: "vehicle",
|
|
44560
|
-
car: "vehicle",
|
|
44561
|
-
motorcycle: "vehicle",
|
|
44562
|
-
airplane: "vehicle",
|
|
44563
|
-
bus: "vehicle",
|
|
44564
|
-
train: "vehicle",
|
|
44565
|
-
truck: "vehicle",
|
|
44566
|
-
boat: "vehicle",
|
|
44567
|
-
bird: "animal",
|
|
44568
|
-
cat: "animal",
|
|
44569
|
-
dog: "animal",
|
|
44570
|
-
horse: "animal",
|
|
44571
|
-
sheep: "animal",
|
|
44572
|
-
cow: "animal",
|
|
44573
|
-
elephant: "animal",
|
|
44574
|
-
bear: "animal",
|
|
44575
|
-
zebra: "animal",
|
|
44576
|
-
giraffe: "animal",
|
|
44577
|
-
suitcase: "package",
|
|
44578
|
-
backpack: "package",
|
|
44579
|
-
handbag: "package"
|
|
44580
|
-
},
|
|
44581
|
-
preserveOriginal: false
|
|
44582
|
-
};
|
|
44583
44966
|
var AUDIO_MACRO_LABELS = [
|
|
44584
44967
|
{
|
|
44585
44968
|
id: "speech",
|
|
@@ -57146,9 +57529,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57146
57529
|
*/
|
|
57147
57530
|
var AirQualitySensorStatusSchema = object({
|
|
57148
57531
|
/** Carbon dioxide concentration in ppm. */
|
|
57149
|
-
|
|
57532
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57150
57533
|
/** Total volatile organic compounds in ppb. */
|
|
57151
|
-
|
|
57534
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57152
57535
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57153
57536
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57154
57537
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -57181,12 +57564,12 @@ var airQualitySensorCapability = {
|
|
|
57181
57564
|
* History (D850): recorded series.
|
|
57182
57565
|
*/
|
|
57183
57566
|
history: { fields: {
|
|
57184
|
-
|
|
57567
|
+
co2: {
|
|
57185
57568
|
kind: "gauge",
|
|
57186
57569
|
unit: "ppm",
|
|
57187
57570
|
deadband: 5
|
|
57188
57571
|
},
|
|
57189
|
-
|
|
57572
|
+
voc: {
|
|
57190
57573
|
kind: "gauge",
|
|
57191
57574
|
unit: "ppb",
|
|
57192
57575
|
deadband: 5
|
|
@@ -57217,7 +57600,7 @@ var airQualitySensorCapability = {
|
|
|
57217
57600
|
*/
|
|
57218
57601
|
var AmbientLightSensorStatusSchema = object({
|
|
57219
57602
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57220
|
-
|
|
57603
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57221
57604
|
precision: 0,
|
|
57222
57605
|
label: "Illuminance"
|
|
57223
57606
|
})),
|
|
@@ -57246,7 +57629,7 @@ var ambientLightSensorCapability = {
|
|
|
57246
57629
|
/**
|
|
57247
57630
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
57248
57631
|
*/
|
|
57249
|
-
history: { fields: {
|
|
57632
|
+
history: { fields: { illuminance: {
|
|
57250
57633
|
kind: "gauge",
|
|
57251
57634
|
unit: "lx",
|
|
57252
57635
|
deadbandPct: 10,
|
|
@@ -57385,6 +57768,84 @@ var audioMetricsCapability = {
|
|
|
57385
57768
|
*/
|
|
57386
57769
|
history: "none"
|
|
57387
57770
|
};
|
|
57771
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
57772
|
+
actionId: string().min(1),
|
|
57773
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
57774
|
+
}), _void(), {
|
|
57775
|
+
kind: "mutation",
|
|
57776
|
+
auth: "admin"
|
|
57777
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
57778
|
+
kind: "mutation",
|
|
57779
|
+
auth: "admin"
|
|
57780
|
+
});
|
|
57781
|
+
/**
|
|
57782
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
57783
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
57784
|
+
*
|
|
57785
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
57786
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
57787
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
57788
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
57789
|
+
* drift (D3).
|
|
57790
|
+
*
|
|
57791
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
57792
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
57793
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
57794
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
57795
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
57796
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
57797
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
57798
|
+
*
|
|
57799
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
57800
|
+
* logged — never queued.
|
|
57801
|
+
*/
|
|
57802
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
57803
|
+
var ActionLinksSchema = object({
|
|
57804
|
+
deviceId: number().int().nonnegative(),
|
|
57805
|
+
actionIds: array(string().min(1)).max(100)
|
|
57806
|
+
});
|
|
57807
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
57808
|
+
actionId: string().min(1),
|
|
57809
|
+
deviceId: number().int().nonnegative().optional()
|
|
57810
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
57811
|
+
role: "viewer",
|
|
57812
|
+
auth: "protected",
|
|
57813
|
+
kind: "query",
|
|
57814
|
+
caller: "required"
|
|
57815
|
+
}), method(object({
|
|
57816
|
+
actionId: string().min(1),
|
|
57817
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
57818
|
+
wait: boolean().optional(),
|
|
57819
|
+
origin: ActionRunOriginSchema.optional(),
|
|
57820
|
+
deviceId: number().int().nonnegative().optional()
|
|
57821
|
+
}), ActionRunResultSchema, {
|
|
57822
|
+
role: "viewer",
|
|
57823
|
+
auth: "protected",
|
|
57824
|
+
kind: "mutation",
|
|
57825
|
+
caller: "required"
|
|
57826
|
+
}), method(ActionIdInput, _void(), {
|
|
57827
|
+
kind: "mutation",
|
|
57828
|
+
auth: "admin"
|
|
57829
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
57830
|
+
kind: "mutation",
|
|
57831
|
+
auth: "admin"
|
|
57832
|
+
}), method(object({
|
|
57833
|
+
actionId: string().min(1),
|
|
57834
|
+
action: ActionInputSchema.partial()
|
|
57835
|
+
}), object({ action: ActionEntrySchema }), {
|
|
57836
|
+
kind: "mutation",
|
|
57837
|
+
auth: "admin"
|
|
57838
|
+
}), method(ActionIdInput, _void(), {
|
|
57839
|
+
kind: "mutation",
|
|
57840
|
+
auth: "admin"
|
|
57841
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
57842
|
+
role: "viewer",
|
|
57843
|
+
auth: "protected",
|
|
57844
|
+
kind: "query"
|
|
57845
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
57846
|
+
kind: "mutation",
|
|
57847
|
+
auth: "admin"
|
|
57848
|
+
});
|
|
57388
57849
|
/**
|
|
57389
57850
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
57390
57851
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -57481,7 +57942,7 @@ var BatteryStatusSchema = object({
|
|
|
57481
57942
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57482
57943
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57483
57944
|
*/
|
|
57484
|
-
|
|
57945
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57485
57946
|
/**
|
|
57486
57947
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57487
57948
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57491,7 +57952,7 @@ var BatteryStatusSchema = object({
|
|
|
57491
57952
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
57492
57953
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
57493
57954
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
57494
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
57955
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
57495
57956
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
57496
57957
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
57497
57958
|
*/
|
|
@@ -57515,7 +57976,7 @@ var BatteryStatusSchema = object({
|
|
|
57515
57976
|
* that only report charge. A second reading on this cap, not a second
|
|
57516
57977
|
* `numeric-sensor` on the same device.
|
|
57517
57978
|
*/
|
|
57518
|
-
|
|
57979
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57519
57980
|
/**
|
|
57520
57981
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57521
57982
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57549,7 +58010,7 @@ var BatteryStatusSchema = object({
|
|
|
57549
58010
|
/**
|
|
57550
58011
|
* True when the source is a BINARY low-battery indicator (HA
|
|
57551
58012
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
57552
|
-
* charge level — `
|
|
58013
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
57553
58014
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
57554
58015
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
57555
58016
|
*/
|
|
@@ -57569,15 +58030,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57569
58030
|
var batteryCustomize = {
|
|
57570
58031
|
version: 1,
|
|
57571
58032
|
targets: [{
|
|
57572
|
-
id: "
|
|
58033
|
+
id: "level",
|
|
57573
58034
|
cardinality: "scalar",
|
|
57574
58035
|
vocabulary: {
|
|
57575
58036
|
cap: "battery",
|
|
57576
|
-
stateField: "
|
|
58037
|
+
stateField: "level"
|
|
57577
58038
|
},
|
|
57578
58039
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57579
58040
|
apply: "add",
|
|
57580
|
-
path: "
|
|
58041
|
+
path: "level",
|
|
57581
58042
|
sources: [{
|
|
57582
58043
|
kind: "field",
|
|
57583
58044
|
valueKinds: ["number", "string"],
|
|
@@ -57671,7 +58132,7 @@ onStatusChanged: { data: object({
|
|
|
57671
58132
|
schema: BatteryStatusSchema,
|
|
57672
58133
|
kind: "push",
|
|
57673
58134
|
empty: {
|
|
57674
|
-
|
|
58135
|
+
level: null,
|
|
57675
58136
|
charging: "unknown",
|
|
57676
58137
|
sleeping: false,
|
|
57677
58138
|
lastUpdated: 0
|
|
@@ -57698,11 +58159,11 @@ onStatusChanged: { data: object({
|
|
|
57698
58159
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57699
58160
|
*/
|
|
57700
58161
|
history: { fields: {
|
|
57701
|
-
|
|
58162
|
+
level: {
|
|
57702
58163
|
kind: "gauge",
|
|
57703
58164
|
unit: "%"
|
|
57704
58165
|
},
|
|
57705
|
-
|
|
58166
|
+
voltage: {
|
|
57706
58167
|
kind: "gauge",
|
|
57707
58168
|
unit: "V"
|
|
57708
58169
|
}
|
|
@@ -57762,14 +58223,14 @@ var binaryCapability = {
|
|
|
57762
58223
|
* controls to this single-method surface.
|
|
57763
58224
|
*
|
|
57764
58225
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
57765
|
-
*
|
|
58226
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
57766
58227
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
57767
58228
|
* should surface those via the device's `getSettingsUISchema()`
|
|
57768
58229
|
* instead of bloating this cap.
|
|
57769
58230
|
*/
|
|
57770
58231
|
var BrightnessStatusSchema = object({
|
|
57771
58232
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57772
|
-
|
|
58233
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57773
58234
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57774
58235
|
lastChangedAt: number()
|
|
57775
58236
|
});
|
|
@@ -57781,7 +58242,7 @@ var brightnessCapability = {
|
|
|
57781
58242
|
deviceTypes: [DeviceType.Light],
|
|
57782
58243
|
methods: { setBrightness: method(object({
|
|
57783
58244
|
deviceId: number().int().nonnegative(),
|
|
57784
|
-
|
|
58245
|
+
level: number().min(0).max(100)
|
|
57785
58246
|
}), _void(), {
|
|
57786
58247
|
kind: "mutation",
|
|
57787
58248
|
auth: "protected"
|
|
@@ -57794,7 +58255,7 @@ var brightnessCapability = {
|
|
|
57794
58255
|
*/
|
|
57795
58256
|
onBrightnessChanged: { data: object({
|
|
57796
58257
|
deviceId: number(),
|
|
57797
|
-
|
|
58258
|
+
level: number().min(0).max(100),
|
|
57798
58259
|
lastChangedAt: number()
|
|
57799
58260
|
}) } },
|
|
57800
58261
|
status: {
|
|
@@ -57817,7 +58278,7 @@ onBrightnessChanged: { data: object({
|
|
|
57817
58278
|
/**
|
|
57818
58279
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
57819
58280
|
*/
|
|
57820
|
-
history: { fields: {
|
|
58281
|
+
history: { fields: { level: {
|
|
57821
58282
|
kind: "gauge",
|
|
57822
58283
|
unit: "%",
|
|
57823
58284
|
minIntervalMs: 0
|
|
@@ -58431,11 +58892,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
58431
58892
|
}),
|
|
58432
58893
|
object({
|
|
58433
58894
|
mode: literal("mired"),
|
|
58434
|
-
|
|
58895
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
58435
58896
|
})
|
|
58436
58897
|
]);
|
|
58437
58898
|
var ColorStatusSchema = object({
|
|
58438
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
58899
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
58439
58900
|
* the bulb's current state. */
|
|
58440
58901
|
mode: _enum([
|
|
58441
58902
|
"rgb",
|
|
@@ -58447,7 +58908,7 @@ var ColorStatusSchema = object({
|
|
|
58447
58908
|
/** Populated when `mode === 'hsv'`. */
|
|
58448
58909
|
hsv: HsvTripletSchema.optional(),
|
|
58449
58910
|
/** Populated when `mode === 'mired'`. */
|
|
58450
|
-
|
|
58911
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58451
58912
|
/** Ms epoch of the last operator-driven change. */
|
|
58452
58913
|
lastChangedAt: number()
|
|
58453
58914
|
});
|
|
@@ -58479,7 +58940,7 @@ onColorChanged: { data: object({
|
|
|
58479
58940
|
]),
|
|
58480
58941
|
rgb: RgbTripletSchema.optional(),
|
|
58481
58942
|
hsv: HsvTripletSchema.optional(),
|
|
58482
|
-
|
|
58943
|
+
colorTemperature: number().int().optional(),
|
|
58483
58944
|
lastChangedAt: number()
|
|
58484
58945
|
}) } },
|
|
58485
58946
|
status: {
|
|
@@ -59356,11 +59817,11 @@ var DishwasherStatusSchema = object({
|
|
|
59356
59817
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59357
59818
|
availablePrograms: array(string()),
|
|
59358
59819
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59359
|
-
|
|
59820
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59360
59821
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59361
|
-
|
|
59822
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59362
59823
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59363
|
-
|
|
59824
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59364
59825
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59365
59826
|
doorOpen: boolean().nullable(),
|
|
59366
59827
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59579,14 +60040,14 @@ var dishwasherCapability = {
|
|
|
59579
60040
|
runtimeState: DishwasherStatusSchema,
|
|
59580
60041
|
durability: "session",
|
|
59581
60042
|
history: { fields: {
|
|
59582
|
-
|
|
60043
|
+
progress: {
|
|
59583
60044
|
kind: "gauge",
|
|
59584
60045
|
unit: "%",
|
|
59585
60046
|
deadband: 2
|
|
59586
60047
|
},
|
|
59587
60048
|
state: { kind: "enum" },
|
|
59588
60049
|
operationState: { kind: "enum" },
|
|
59589
|
-
|
|
60050
|
+
remaining: {
|
|
59590
60051
|
kind: "gauge",
|
|
59591
60052
|
unit: "s",
|
|
59592
60053
|
minIntervalMs: 6e4
|
|
@@ -60177,7 +60638,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60177
60638
|
var FanControlStatusSchema = object({
|
|
60178
60639
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60179
60640
|
* speed surface (single-speed fan). */
|
|
60180
|
-
|
|
60641
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60181
60642
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60182
60643
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60183
60644
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -60204,7 +60665,7 @@ var fanControlCapability = {
|
|
|
60204
60665
|
methods: {
|
|
60205
60666
|
setPercentage: method(object({
|
|
60206
60667
|
deviceId: number().int().nonnegative(),
|
|
60207
|
-
|
|
60668
|
+
speed: number().min(0).max(100)
|
|
60208
60669
|
}), _void(), {
|
|
60209
60670
|
kind: "mutation",
|
|
60210
60671
|
auth: "protected"
|
|
@@ -60237,7 +60698,7 @@ var fanControlCapability = {
|
|
|
60237
60698
|
},
|
|
60238
60699
|
/**
|
|
60239
60700
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
60240
|
-
* sliders read `
|
|
60701
|
+
* sliders read `speed` for live updates.
|
|
60241
60702
|
*/
|
|
60242
60703
|
runtimeState: FanControlStatusSchema,
|
|
60243
60704
|
/**
|
|
@@ -60251,7 +60712,7 @@ var fanControlCapability = {
|
|
|
60251
60712
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
60252
60713
|
*/
|
|
60253
60714
|
history: { fields: {
|
|
60254
|
-
|
|
60715
|
+
speed: {
|
|
60255
60716
|
kind: "gauge",
|
|
60256
60717
|
unit: "%",
|
|
60257
60718
|
minIntervalMs: 0
|
|
@@ -60696,7 +61157,7 @@ var humidifierCapability = {
|
|
|
60696
61157
|
*/
|
|
60697
61158
|
var HumiditySensorStatusSchema = object({
|
|
60698
61159
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60699
|
-
|
|
61160
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60700
61161
|
precision: 0,
|
|
60701
61162
|
label: "Humidity"
|
|
60702
61163
|
})),
|
|
@@ -60725,7 +61186,7 @@ var humiditySensorCapability = {
|
|
|
60725
61186
|
/**
|
|
60726
61187
|
* History (D850): recorded series.
|
|
60727
61188
|
*/
|
|
60728
|
-
history: { fields: {
|
|
61189
|
+
history: { fields: { humidity: {
|
|
60729
61190
|
kind: "gauge",
|
|
60730
61191
|
unit: "%",
|
|
60731
61192
|
deadband: .5
|
|
@@ -61365,7 +61826,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61365
61826
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61366
61827
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61367
61828
|
* task is active / progress is unavailable. */
|
|
61368
|
-
|
|
61829
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61369
61830
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61370
61831
|
* or null when unknown. */
|
|
61371
61832
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -61865,7 +62326,7 @@ var lockControlCapability = {
|
|
|
61865
62326
|
volatileStateFields: ["lastChangedAt"]
|
|
61866
62327
|
};
|
|
61867
62328
|
/**
|
|
61868
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
62329
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
61869
62330
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
61870
62331
|
* `value` is the time integral in the source quantity's accumulated base
|
|
61871
62332
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -61959,10 +62420,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61959
62420
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61960
62421
|
/** Current playback position in ms. Null when not seekable or
|
|
61961
62422
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61962
|
-
|
|
62423
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61963
62424
|
/** Total duration of the current media in ms. Null when unknown
|
|
61964
62425
|
* (live stream) or nothing is playing. */
|
|
61965
|
-
|
|
62426
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61966
62427
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61967
62428
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61968
62429
|
shuffle: boolean().nullable(),
|
|
@@ -62001,7 +62462,7 @@ var mediaPlayerCapability = {
|
|
|
62001
62462
|
}),
|
|
62002
62463
|
seek: method(object({
|
|
62003
62464
|
deviceId: number().int().nonnegative(),
|
|
62004
|
-
|
|
62465
|
+
position: number().int().nonnegative()
|
|
62005
62466
|
}), _void(), {
|
|
62006
62467
|
kind: "mutation",
|
|
62007
62468
|
auth: "protected"
|
|
@@ -62073,7 +62534,7 @@ var mediaPlayerCapability = {
|
|
|
62073
62534
|
/**
|
|
62074
62535
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62075
62536
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62076
|
-
* `
|
|
62537
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62077
62538
|
*/
|
|
62078
62539
|
history: { fields: {
|
|
62079
62540
|
volumeLevel: {
|
|
@@ -63035,9 +63496,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
63035
63496
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63036
63497
|
* SKIP a null rather than coerce it.
|
|
63037
63498
|
*/
|
|
63038
|
-
|
|
63499
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63039
63500
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63040
|
-
|
|
63501
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
63041
63502
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63042
63503
|
ssid: string().optional(),
|
|
63043
63504
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63073,7 +63534,7 @@ onStatusChanged: { data: object({
|
|
|
63073
63534
|
kind: "push",
|
|
63074
63535
|
empty: {
|
|
63075
63536
|
type: "unknown",
|
|
63076
|
-
|
|
63537
|
+
signal: null,
|
|
63077
63538
|
lastUpdated: 0
|
|
63078
63539
|
}
|
|
63079
63540
|
},
|
|
@@ -63096,13 +63557,13 @@ onStatusChanged: { data: object({
|
|
|
63096
63557
|
* History (D850): recorded series.
|
|
63097
63558
|
*/
|
|
63098
63559
|
history: { fields: {
|
|
63099
|
-
|
|
63560
|
+
signal: {
|
|
63100
63561
|
kind: "gauge",
|
|
63101
63562
|
unit: "%",
|
|
63102
63563
|
deadband: 3,
|
|
63103
63564
|
minIntervalMs: 6e4
|
|
63104
63565
|
},
|
|
63105
|
-
|
|
63566
|
+
rssi: {
|
|
63106
63567
|
kind: "gauge",
|
|
63107
63568
|
unit: "dBm",
|
|
63108
63569
|
deadband: 2,
|
|
@@ -63847,10 +64308,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
63847
64308
|
]);
|
|
63848
64309
|
var gramsPortion = number().int().min(4).max(200);
|
|
63849
64310
|
var PetFeederStatusSchema = object({
|
|
63850
|
-
/** Food
|
|
63851
|
-
*
|
|
63852
|
-
* bowl
|
|
64311
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
64312
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
64313
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
64314
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
64315
|
+
* the device has not reported yet. */
|
|
63853
64316
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64317
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
64318
|
+
* feeder's own units. Null when the model reports none. */
|
|
64319
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
64320
|
+
/** True while the pet is eating (`state.eating`). */
|
|
64321
|
+
eating: boolean(),
|
|
64322
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
64323
|
+
* the client must not offer it. */
|
|
64324
|
+
supportsMarkRefilled: boolean(),
|
|
63854
64325
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63855
64326
|
* single-hopper models. */
|
|
63856
64327
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -63858,8 +64329,8 @@ var PetFeederStatusSchema = object({
|
|
|
63858
64329
|
* single-hopper models. */
|
|
63859
64330
|
food2: number().nullable().meta(readingMeta("none")),
|
|
63860
64331
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63861
|
-
* (`device_class: problem`, on = low). True when the
|
|
63862
|
-
*
|
|
64332
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
64333
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
63863
64334
|
lowFood: boolean(),
|
|
63864
64335
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63865
64336
|
* device has no battery reading. */
|
|
@@ -63927,7 +64398,9 @@ var petFeederCapability = {
|
|
|
63927
64398
|
kind: "mutation",
|
|
63928
64399
|
auth: "protected"
|
|
63929
64400
|
}),
|
|
63930
|
-
/**
|
|
64401
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
64402
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
64403
|
+
* change any sensor reading. */
|
|
63931
64404
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
63932
64405
|
kind: "mutation",
|
|
63933
64406
|
auth: "protected"
|
|
@@ -64000,6 +64473,7 @@ var petFeederCapability = {
|
|
|
64000
64473
|
*/
|
|
64001
64474
|
history: { fields: {
|
|
64002
64475
|
foodLevel: { kind: "gauge" },
|
|
64476
|
+
bowlFood: { kind: "gauge" },
|
|
64003
64477
|
food1: { kind: "gauge" },
|
|
64004
64478
|
food2: { kind: "gauge" },
|
|
64005
64479
|
batteryPower: {
|
|
@@ -64409,16 +64883,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64409
64883
|
* in real-world devices.
|
|
64410
64884
|
*/
|
|
64411
64885
|
var PowerMeterStatusSchema = object({
|
|
64412
|
-
/** Instantaneous power draw
|
|
64413
|
-
|
|
64886
|
+
/** Instantaneous power draw (watts). */
|
|
64887
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64414
64888
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64415
|
-
|
|
64416
|
-
/** Voltage
|
|
64417
|
-
|
|
64889
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64890
|
+
/** Voltage (volts). */
|
|
64891
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64418
64892
|
/** Current in amperes. */
|
|
64419
|
-
|
|
64893
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64420
64894
|
/** Apparent power in volt-amperes. */
|
|
64421
|
-
|
|
64895
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
64422
64896
|
/** Power factor (0..1) if reported. */
|
|
64423
64897
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64424
64898
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64476,14 +64950,14 @@ function powerTarget(id, unit) {
|
|
|
64476
64950
|
advancedExpression: true
|
|
64477
64951
|
};
|
|
64478
64952
|
}
|
|
64479
|
-
/** "Power and energy" extension:
|
|
64953
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
64480
64954
|
var powerMeterCustomize = {
|
|
64481
64955
|
version: 1,
|
|
64482
64956
|
targets: [
|
|
64483
|
-
powerTarget("
|
|
64484
|
-
powerTarget("
|
|
64485
|
-
powerTarget("
|
|
64486
|
-
powerTarget("
|
|
64957
|
+
powerTarget("power", "W"),
|
|
64958
|
+
powerTarget("energy", "kWh"),
|
|
64959
|
+
powerTarget("voltage", "V"),
|
|
64960
|
+
powerTarget("current", "A")
|
|
64487
64961
|
]
|
|
64488
64962
|
};
|
|
64489
64963
|
var powerMeterCapability = {
|
|
@@ -64499,41 +64973,41 @@ var powerMeterCapability = {
|
|
|
64499
64973
|
},
|
|
64500
64974
|
runtimeState: PowerMeterStatusSchema,
|
|
64501
64975
|
/**
|
|
64502
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
64976
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
64503
64977
|
*
|
|
64504
64978
|
* See `RuntimeStateDurability`. Enforced by
|
|
64505
64979
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64506
64980
|
*/
|
|
64507
64981
|
durability: "restored",
|
|
64508
64982
|
/**
|
|
64509
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
64983
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
64510
64984
|
*/
|
|
64511
64985
|
history: { fields: {
|
|
64512
|
-
|
|
64986
|
+
power: {
|
|
64513
64987
|
kind: "gauge",
|
|
64514
64988
|
unit: "W",
|
|
64515
64989
|
deadband: 1,
|
|
64516
64990
|
minIntervalMs: 3e4
|
|
64517
64991
|
},
|
|
64518
|
-
|
|
64992
|
+
energy: {
|
|
64519
64993
|
kind: "counter",
|
|
64520
64994
|
unit: "kWh",
|
|
64521
64995
|
deadband: .01,
|
|
64522
64996
|
minIntervalMs: 6e4
|
|
64523
64997
|
},
|
|
64524
|
-
|
|
64998
|
+
voltage: {
|
|
64525
64999
|
kind: "gauge",
|
|
64526
65000
|
unit: "V",
|
|
64527
65001
|
deadband: 1,
|
|
64528
65002
|
minIntervalMs: 3e4
|
|
64529
65003
|
},
|
|
64530
|
-
|
|
65004
|
+
current: {
|
|
64531
65005
|
kind: "gauge",
|
|
64532
65006
|
unit: "A",
|
|
64533
65007
|
deadband: .05,
|
|
64534
65008
|
minIntervalMs: 3e4
|
|
64535
65009
|
},
|
|
64536
|
-
|
|
65010
|
+
apparentPower: {
|
|
64537
65011
|
kind: "gauge",
|
|
64538
65012
|
unit: "VA",
|
|
64539
65013
|
deadband: 1,
|
|
@@ -64583,9 +65057,6 @@ var PresenceStatusSchema = object({
|
|
|
64583
65057
|
location: string().nullable(),
|
|
64584
65058
|
/** GPS coordinates when available. Null otherwise. */
|
|
64585
65059
|
gps: GpsLocationSchema.nullable(),
|
|
64586
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
64587
|
-
* when not reported. */
|
|
64588
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64589
65060
|
/** Ms epoch when the slice was last updated. */
|
|
64590
65061
|
lastChangedAt: number()
|
|
64591
65062
|
});
|
|
@@ -64614,14 +65085,7 @@ var presenceCapability = {
|
|
|
64614
65085
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64615
65086
|
*/
|
|
64616
65087
|
durability: "restored",
|
|
64617
|
-
|
|
64618
|
-
* History (D850): recorded series.
|
|
64619
|
-
*/
|
|
64620
|
-
history: { fields: { batteryPercent: {
|
|
64621
|
-
kind: "gauge",
|
|
64622
|
-
unit: "%",
|
|
64623
|
-
deadband: 1
|
|
64624
|
-
} } },
|
|
65088
|
+
history: "none",
|
|
64625
65089
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64626
65090
|
* whether persisting is worth a SQLite commit. */
|
|
64627
65091
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -64636,7 +65100,7 @@ var presenceCapability = {
|
|
|
64636
65100
|
*/
|
|
64637
65101
|
var PressureSensorStatusSchema = object({
|
|
64638
65102
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64639
|
-
|
|
65103
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64640
65104
|
/** Ms epoch when the slice was last updated. */
|
|
64641
65105
|
lastFetchedAt: number()
|
|
64642
65106
|
});
|
|
@@ -64662,7 +65126,7 @@ var pressureSensorCapability = {
|
|
|
64662
65126
|
/**
|
|
64663
65127
|
* History (D850): recorded series.
|
|
64664
65128
|
*/
|
|
64665
|
-
history: { fields: {
|
|
65129
|
+
history: { fields: { pressure: {
|
|
64666
65130
|
kind: "gauge",
|
|
64667
65131
|
unit: "hPa",
|
|
64668
65132
|
deadband: .1
|
|
@@ -68361,7 +68825,7 @@ var tamperCapability = {
|
|
|
68361
68825
|
*/
|
|
68362
68826
|
var TemperatureSensorStatusSchema = object({
|
|
68363
68827
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68364
|
-
|
|
68828
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
68365
68829
|
precision: 1,
|
|
68366
68830
|
label: "Temperature"
|
|
68367
68831
|
})),
|
|
@@ -68390,7 +68854,7 @@ var temperatureSensorCapability = {
|
|
|
68390
68854
|
/**
|
|
68391
68855
|
* History (D850): recorded series.
|
|
68392
68856
|
*/
|
|
68393
|
-
history: { fields: {
|
|
68857
|
+
history: { fields: { temperature: {
|
|
68394
68858
|
kind: "gauge",
|
|
68395
68859
|
unit: "°C",
|
|
68396
68860
|
deadband: .1
|
|
@@ -68687,7 +69151,7 @@ var VacuumControlStatusSchema = object({
|
|
|
68687
69151
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68688
69152
|
availableFanSpeeds: array(string()),
|
|
68689
69153
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68690
|
-
|
|
69154
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68691
69155
|
/** Current error code (0 / null = no error). */
|
|
68692
69156
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68693
69157
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -70341,7 +70805,7 @@ var BaseDevice = class {
|
|
|
70341
70805
|
* `device-local-state.ts`. Drivers access via:
|
|
70342
70806
|
*
|
|
70343
70807
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
70344
|
-
* `const pct = this.state.battery.
|
|
70808
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
70345
70809
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
70346
70810
|
*
|
|
70347
70811
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -70381,7 +70845,7 @@ var BaseDevice = class {
|
|
|
70381
70845
|
* shape; drivers don't redeclare it, they just write through.
|
|
70382
70846
|
*
|
|
70383
70847
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
70384
|
-
* `{
|
|
70848
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
70385
70849
|
* provider that registers `batteryCapability`.
|
|
70386
70850
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
70387
70851
|
*
|
|
@@ -71555,6 +72019,104 @@ Object.freeze({
|
|
|
71555
72019
|
access: "create",
|
|
71556
72020
|
role: "admin"
|
|
71557
72021
|
},
|
|
72022
|
+
"actions.create": {
|
|
72023
|
+
capName: "actions",
|
|
72024
|
+
capScope: "system",
|
|
72025
|
+
addonId: null,
|
|
72026
|
+
access: "create",
|
|
72027
|
+
role: "admin"
|
|
72028
|
+
},
|
|
72029
|
+
"actions.delete": {
|
|
72030
|
+
capName: "actions",
|
|
72031
|
+
capScope: "system",
|
|
72032
|
+
addonId: null,
|
|
72033
|
+
access: "delete",
|
|
72034
|
+
role: "admin"
|
|
72035
|
+
},
|
|
72036
|
+
"actions.get": {
|
|
72037
|
+
capName: "actions",
|
|
72038
|
+
capScope: "system",
|
|
72039
|
+
addonId: null,
|
|
72040
|
+
access: "view",
|
|
72041
|
+
role: "viewer"
|
|
72042
|
+
},
|
|
72043
|
+
"actions.getLinks": {
|
|
72044
|
+
capName: "actions",
|
|
72045
|
+
capScope: "system",
|
|
72046
|
+
addonId: null,
|
|
72047
|
+
access: "view",
|
|
72048
|
+
role: "admin"
|
|
72049
|
+
},
|
|
72050
|
+
"actions.getTraces": {
|
|
72051
|
+
capName: "actions",
|
|
72052
|
+
capScope: "system",
|
|
72053
|
+
addonId: null,
|
|
72054
|
+
access: "view",
|
|
72055
|
+
role: "admin"
|
|
72056
|
+
},
|
|
72057
|
+
"actions.list": {
|
|
72058
|
+
capName: "actions",
|
|
72059
|
+
capScope: "system",
|
|
72060
|
+
addonId: null,
|
|
72061
|
+
access: "view",
|
|
72062
|
+
role: "admin"
|
|
72063
|
+
},
|
|
72064
|
+
"actions.listForCamera": {
|
|
72065
|
+
capName: "actions",
|
|
72066
|
+
capScope: "system",
|
|
72067
|
+
addonId: null,
|
|
72068
|
+
access: "view",
|
|
72069
|
+
role: "viewer"
|
|
72070
|
+
},
|
|
72071
|
+
"actions.run": {
|
|
72072
|
+
capName: "actions",
|
|
72073
|
+
capScope: "system",
|
|
72074
|
+
addonId: null,
|
|
72075
|
+
access: "create",
|
|
72076
|
+
role: "viewer"
|
|
72077
|
+
},
|
|
72078
|
+
"actions.setLinks": {
|
|
72079
|
+
capName: "actions",
|
|
72080
|
+
capScope: "system",
|
|
72081
|
+
addonId: null,
|
|
72082
|
+
access: "create",
|
|
72083
|
+
role: "admin"
|
|
72084
|
+
},
|
|
72085
|
+
"actions.stop": {
|
|
72086
|
+
capName: "actions",
|
|
72087
|
+
capScope: "system",
|
|
72088
|
+
addonId: null,
|
|
72089
|
+
access: "create",
|
|
72090
|
+
role: "admin"
|
|
72091
|
+
},
|
|
72092
|
+
"actions.update": {
|
|
72093
|
+
capName: "actions",
|
|
72094
|
+
capScope: "system",
|
|
72095
|
+
addonId: null,
|
|
72096
|
+
access: "create",
|
|
72097
|
+
role: "admin"
|
|
72098
|
+
},
|
|
72099
|
+
"actionSource.listActions": {
|
|
72100
|
+
capName: "action-source",
|
|
72101
|
+
capScope: "system",
|
|
72102
|
+
addonId: null,
|
|
72103
|
+
access: "view",
|
|
72104
|
+
role: "admin"
|
|
72105
|
+
},
|
|
72106
|
+
"actionSource.runAction": {
|
|
72107
|
+
capName: "action-source",
|
|
72108
|
+
capScope: "system",
|
|
72109
|
+
addonId: null,
|
|
72110
|
+
access: "create",
|
|
72111
|
+
role: "admin"
|
|
72112
|
+
},
|
|
72113
|
+
"actionSource.stopAction": {
|
|
72114
|
+
capName: "action-source",
|
|
72115
|
+
capScope: "system",
|
|
72116
|
+
addonId: null,
|
|
72117
|
+
access: "create",
|
|
72118
|
+
role: "admin"
|
|
72119
|
+
},
|
|
71558
72120
|
"addonPages.listPages": {
|
|
71559
72121
|
capName: "addon-pages",
|
|
71560
72122
|
capScope: "system",
|
|
@@ -72836,6 +73398,13 @@ Object.freeze({
|
|
|
72836
73398
|
access: "view",
|
|
72837
73399
|
role: "admin"
|
|
72838
73400
|
},
|
|
73401
|
+
"coreBlocks.getAutomationRunState": {
|
|
73402
|
+
capName: "core-blocks",
|
|
73403
|
+
capScope: "system",
|
|
73404
|
+
addonId: null,
|
|
73405
|
+
access: "view",
|
|
73406
|
+
role: "admin"
|
|
73407
|
+
},
|
|
72839
73408
|
"coreBlocks.getBlockSettings": {
|
|
72840
73409
|
capName: "core-blocks",
|
|
72841
73410
|
capScope: "system",
|
|
@@ -72857,6 +73426,13 @@ Object.freeze({
|
|
|
72857
73426
|
access: "view",
|
|
72858
73427
|
role: "admin"
|
|
72859
73428
|
},
|
|
73429
|
+
"coreBlocks.getTraces": {
|
|
73430
|
+
capName: "core-blocks",
|
|
73431
|
+
capScope: "system",
|
|
73432
|
+
addonId: null,
|
|
73433
|
+
access: "view",
|
|
73434
|
+
role: "admin"
|
|
73435
|
+
},
|
|
72860
73436
|
"coreBlocks.getTypeDefs": {
|
|
72861
73437
|
capName: "core-blocks",
|
|
72862
73438
|
capScope: "system",
|
|
@@ -72892,6 +73468,13 @@ Object.freeze({
|
|
|
72892
73468
|
access: "create",
|
|
72893
73469
|
role: "admin"
|
|
72894
73470
|
},
|
|
73471
|
+
"coreBlocks.reportAutomationRun": {
|
|
73472
|
+
capName: "core-blocks",
|
|
73473
|
+
capScope: "system",
|
|
73474
|
+
addonId: null,
|
|
73475
|
+
access: "create",
|
|
73476
|
+
role: "admin"
|
|
73477
|
+
},
|
|
72895
73478
|
"coreBlocks.restart": {
|
|
72896
73479
|
capName: "core-blocks",
|
|
72897
73480
|
capScope: "system",
|
|
@@ -81465,7 +82048,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81465
82048
|
label: t("Full brightness", "Luminosità massima"),
|
|
81466
82049
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
81467
82050
|
icon: "sun",
|
|
81468
|
-
args: {
|
|
82051
|
+
args: { level: 100 }
|
|
81469
82052
|
},
|
|
81470
82053
|
{
|
|
81471
82054
|
id: "brightness.half",
|
|
@@ -81473,7 +82056,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81473
82056
|
label: t("Half brightness", "Luminosità a metà"),
|
|
81474
82057
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
81475
82058
|
icon: "sun-dim",
|
|
81476
|
-
args: {
|
|
82059
|
+
args: { level: 50 }
|
|
81477
82060
|
},
|
|
81478
82061
|
{
|
|
81479
82062
|
id: "brightness.off",
|
|
@@ -81481,16 +82064,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81481
82064
|
label: t("Brightness off", "Luminosità a zero"),
|
|
81482
82065
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
81483
82066
|
icon: "lightbulb-off",
|
|
81484
|
-
args: {
|
|
82067
|
+
args: { level: 0 }
|
|
81485
82068
|
},
|
|
81486
82069
|
{
|
|
81487
82070
|
id: "brightness.set",
|
|
81488
82071
|
method: "setBrightness",
|
|
81489
82072
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
81490
|
-
phrase: t("Set the brightness of {device} to {
|
|
82073
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
81491
82074
|
icon: "sun-medium",
|
|
81492
82075
|
openArgs: [{
|
|
81493
|
-
key: "
|
|
82076
|
+
key: "level",
|
|
81494
82077
|
label: PERCENT,
|
|
81495
82078
|
offer: {
|
|
81496
82079
|
kind: "number",
|
|
@@ -81504,13 +82087,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81504
82087
|
],
|
|
81505
82088
|
state: [{
|
|
81506
82089
|
kind: "numeric",
|
|
81507
|
-
field: "
|
|
82090
|
+
field: "level",
|
|
81508
82091
|
quantity: t("the brightness", "la luminosità"),
|
|
81509
82092
|
label: t("Brightness", "Luminosità"),
|
|
81510
82093
|
unit: "%",
|
|
81511
82094
|
icon: "sun"
|
|
81512
82095
|
}],
|
|
81513
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
82096
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
81514
82097
|
},
|
|
81515
82098
|
color: {
|
|
81516
82099
|
scope: "device",
|
|
@@ -81524,7 +82107,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81524
82107
|
icon: "sun",
|
|
81525
82108
|
args: { color: {
|
|
81526
82109
|
mode: "mired",
|
|
81527
|
-
|
|
82110
|
+
colorTemperature: 370
|
|
81528
82111
|
} }
|
|
81529
82112
|
},
|
|
81530
82113
|
{
|
|
@@ -81535,7 +82118,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81535
82118
|
icon: "snowflake",
|
|
81536
82119
|
args: { color: {
|
|
81537
82120
|
mode: "mired",
|
|
81538
|
-
|
|
82121
|
+
colorTemperature: 200
|
|
81539
82122
|
} }
|
|
81540
82123
|
},
|
|
81541
82124
|
{
|
|
@@ -82149,7 +82732,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82149
82732
|
label: t("Fan off", "Ventilatore spento"),
|
|
82150
82733
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
82151
82734
|
icon: "power-off",
|
|
82152
|
-
args: {
|
|
82735
|
+
args: { speed: 0 }
|
|
82153
82736
|
},
|
|
82154
82737
|
{
|
|
82155
82738
|
id: "fan.full",
|
|
@@ -82157,16 +82740,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82157
82740
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
82158
82741
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
82159
82742
|
icon: "fan",
|
|
82160
|
-
args: {
|
|
82743
|
+
args: { speed: 100 }
|
|
82161
82744
|
},
|
|
82162
82745
|
{
|
|
82163
82746
|
id: "fan.speed",
|
|
82164
82747
|
method: "setPercentage",
|
|
82165
82748
|
label: t("Set speed", "Imposta la velocità"),
|
|
82166
|
-
phrase: t("Set the speed of {device} to {
|
|
82749
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
82167
82750
|
icon: "fan",
|
|
82168
82751
|
openArgs: [{
|
|
82169
|
-
key: "
|
|
82752
|
+
key: "speed",
|
|
82170
82753
|
label: t("Speed", "Velocità"),
|
|
82171
82754
|
offer: {
|
|
82172
82755
|
kind: "number",
|
|
@@ -82228,7 +82811,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82228
82811
|
],
|
|
82229
82812
|
state: [{
|
|
82230
82813
|
kind: "numeric",
|
|
82231
|
-
field: "
|
|
82814
|
+
field: "speed",
|
|
82232
82815
|
quantity: t("the speed", "la velocità"),
|
|
82233
82816
|
label: t("Speed", "Velocità"),
|
|
82234
82817
|
unit: "%",
|
|
@@ -83026,7 +83609,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83026
83609
|
},
|
|
83027
83610
|
{
|
|
83028
83611
|
kind: "numeric",
|
|
83029
|
-
field: "
|
|
83612
|
+
field: "progress",
|
|
83030
83613
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
83031
83614
|
label: t("Progress", "Avanzamento"),
|
|
83032
83615
|
unit: "%",
|
|
@@ -83384,10 +83967,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83384
83967
|
id: "media.seek",
|
|
83385
83968
|
method: "seek",
|
|
83386
83969
|
label: t("Seek", "Vai al punto"),
|
|
83387
|
-
phrase: t("Move {device} to {
|
|
83970
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
83388
83971
|
icon: "fast-forward",
|
|
83389
83972
|
openArgs: [{
|
|
83390
|
-
key: "
|
|
83973
|
+
key: "position",
|
|
83391
83974
|
label: t("Position", "Posizione"),
|
|
83392
83975
|
offer: {
|
|
83393
83976
|
kind: "number",
|
|
@@ -84436,7 +85019,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84436
85019
|
state: [
|
|
84437
85020
|
{
|
|
84438
85021
|
kind: "numeric",
|
|
84439
|
-
field: "
|
|
85022
|
+
field: "co2",
|
|
84440
85023
|
quantity: t("the CO₂", "la CO₂"),
|
|
84441
85024
|
label: t("CO₂", "CO₂"),
|
|
84442
85025
|
unit: "ppm",
|
|
@@ -84444,7 +85027,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84444
85027
|
},
|
|
84445
85028
|
{
|
|
84446
85029
|
kind: "numeric",
|
|
84447
|
-
field: "
|
|
85030
|
+
field: "voc",
|
|
84448
85031
|
quantity: t("the VOC level", "il livello di COV"),
|
|
84449
85032
|
label: t("VOC", "COV"),
|
|
84450
85033
|
unit: "ppb",
|
|
@@ -84480,7 +85063,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84480
85063
|
noun: t("Light level", "Luminosità ambiente"),
|
|
84481
85064
|
state: [{
|
|
84482
85065
|
kind: "numeric",
|
|
84483
|
-
field: "
|
|
85066
|
+
field: "illuminance",
|
|
84484
85067
|
quantity: t("the light level", "la luminosità"),
|
|
84485
85068
|
label: t("Illuminance", "Illuminamento"),
|
|
84486
85069
|
unit: "lx",
|
|
@@ -84683,7 +85266,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84683
85266
|
noun: t("Humidity", "Umidità"),
|
|
84684
85267
|
state: [{
|
|
84685
85268
|
kind: "numeric",
|
|
84686
|
-
field: "
|
|
85269
|
+
field: "humidity",
|
|
84687
85270
|
quantity: t("the humidity", "l’umidità"),
|
|
84688
85271
|
label: t("Humidity", "Umidità"),
|
|
84689
85272
|
unit: "%",
|
|
@@ -84731,7 +85314,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84731
85314
|
state: [
|
|
84732
85315
|
{
|
|
84733
85316
|
kind: "numeric",
|
|
84734
|
-
field: "
|
|
85317
|
+
field: "power",
|
|
84735
85318
|
quantity: t("the power draw", "il consumo"),
|
|
84736
85319
|
label: t("Power", "Potenza"),
|
|
84737
85320
|
unit: "W",
|
|
@@ -84739,7 +85322,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84739
85322
|
},
|
|
84740
85323
|
{
|
|
84741
85324
|
kind: "numeric",
|
|
84742
|
-
field: "
|
|
85325
|
+
field: "energy",
|
|
84743
85326
|
quantity: t("the energy used", "l’energia consumata"),
|
|
84744
85327
|
label: t("Energy", "Energia"),
|
|
84745
85328
|
unit: "kWh",
|
|
@@ -84747,7 +85330,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84747
85330
|
},
|
|
84748
85331
|
{
|
|
84749
85332
|
kind: "numeric",
|
|
84750
|
-
field: "
|
|
85333
|
+
field: "voltage",
|
|
84751
85334
|
quantity: t("the voltage", "la tensione"),
|
|
84752
85335
|
label: t("Voltage", "Tensione"),
|
|
84753
85336
|
unit: "V",
|
|
@@ -84755,7 +85338,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84755
85338
|
},
|
|
84756
85339
|
{
|
|
84757
85340
|
kind: "numeric",
|
|
84758
|
-
field: "
|
|
85341
|
+
field: "current",
|
|
84759
85342
|
quantity: t("the current", "la corrente"),
|
|
84760
85343
|
label: t("Current", "Corrente"),
|
|
84761
85344
|
unit: "A",
|
|
@@ -84772,13 +85355,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84772
85355
|
label: t("Where", "Posizione"),
|
|
84773
85356
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
84774
85357
|
icon: "map-pin"
|
|
84775
|
-
}, {
|
|
84776
|
-
kind: "numeric",
|
|
84777
|
-
field: "batteryPercent",
|
|
84778
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
84779
|
-
label: t("Battery", "Batteria"),
|
|
84780
|
-
unit: "%",
|
|
84781
|
-
icon: "battery"
|
|
84782
85358
|
}]
|
|
84783
85359
|
},
|
|
84784
85360
|
"pressure-sensor": {
|
|
@@ -84786,7 +85362,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84786
85362
|
noun: t("Pressure", "Pressione"),
|
|
84787
85363
|
state: [{
|
|
84788
85364
|
kind: "numeric",
|
|
84789
|
-
field: "
|
|
85365
|
+
field: "pressure",
|
|
84790
85366
|
quantity: t("the pressure", "la pressione"),
|
|
84791
85367
|
label: t("Pressure", "Pressione"),
|
|
84792
85368
|
unit: "hPa",
|
|
@@ -84822,7 +85398,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84822
85398
|
noun: t("Temperature", "Temperatura"),
|
|
84823
85399
|
state: [{
|
|
84824
85400
|
kind: "numeric",
|
|
84825
|
-
field: "
|
|
85401
|
+
field: "temperature",
|
|
84826
85402
|
quantity: t("the temperature", "la temperatura"),
|
|
84827
85403
|
label: t("Temperature", "Temperatura"),
|
|
84828
85404
|
unit: "°C",
|
|
@@ -84893,7 +85469,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84893
85469
|
state: [
|
|
84894
85470
|
{
|
|
84895
85471
|
kind: "numeric",
|
|
84896
|
-
field: "
|
|
85472
|
+
field: "level",
|
|
84897
85473
|
quantity: t("the battery level", "il livello della batteria"),
|
|
84898
85474
|
label: t("Battery", "Batteria"),
|
|
84899
85475
|
unit: "%",
|
|
@@ -84935,7 +85511,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84935
85511
|
icon: "battery-charging"
|
|
84936
85512
|
}
|
|
84937
85513
|
],
|
|
84938
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
85514
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
84939
85515
|
extraEvents: [{
|
|
84940
85516
|
category: EventCategory.DeviceAwake,
|
|
84941
85517
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -84953,7 +85529,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84953
85529
|
noun: t("Network link", "Collegamento di rete"),
|
|
84954
85530
|
state: [{
|
|
84955
85531
|
kind: "numeric",
|
|
84956
|
-
field: "
|
|
85532
|
+
field: "signal",
|
|
84957
85533
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
84958
85534
|
label: t("Signal", "Segnale"),
|
|
84959
85535
|
unit: "%",
|
|
@@ -85046,6 +85622,8 @@ var ML = "model and training machinery — no device action";
|
|
|
85046
85622
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
85047
85623
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
85048
85624
|
var SYSTEM_CAP_VOCABULARY = {
|
|
85625
|
+
"action-source": system(INTERNAL),
|
|
85626
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
85049
85627
|
"addon-pages": system(UI_PLUMBING),
|
|
85050
85628
|
"addon-pages-source": system(UI_PLUMBING),
|
|
85051
85629
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -85242,6 +85820,31 @@ Object.freeze({
|
|
|
85242
85820
|
form: "single",
|
|
85243
85821
|
optional: false
|
|
85244
85822
|
}],
|
|
85823
|
+
"actions.get": [{
|
|
85824
|
+
name: "deviceId",
|
|
85825
|
+
form: "single",
|
|
85826
|
+
optional: true
|
|
85827
|
+
}],
|
|
85828
|
+
"actions.getLinks": [{
|
|
85829
|
+
name: "deviceId",
|
|
85830
|
+
form: "single",
|
|
85831
|
+
optional: false
|
|
85832
|
+
}],
|
|
85833
|
+
"actions.listForCamera": [{
|
|
85834
|
+
name: "deviceId",
|
|
85835
|
+
form: "single",
|
|
85836
|
+
optional: false
|
|
85837
|
+
}],
|
|
85838
|
+
"actions.run": [{
|
|
85839
|
+
name: "deviceId",
|
|
85840
|
+
form: "single",
|
|
85841
|
+
optional: true
|
|
85842
|
+
}],
|
|
85843
|
+
"actions.setLinks": [{
|
|
85844
|
+
name: "deviceId",
|
|
85845
|
+
form: "single",
|
|
85846
|
+
optional: false
|
|
85847
|
+
}],
|
|
85245
85848
|
"addonSettings.getDeviceSettings": [{
|
|
85246
85849
|
name: "deviceId",
|
|
85247
85850
|
form: "single",
|
|
@@ -89323,6 +89926,7 @@ DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
|
89323
89926
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
89324
89927
|
DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb;
|
|
89325
89928
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
89929
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
89326
89930
|
var MB = 1024 * 1024;
|
|
89327
89931
|
1024 * MB, 3072 * MB;
|
|
89328
89932
|
//#endregion
|
|
@@ -90086,7 +90690,6 @@ var COLD_PRESENCE = {
|
|
|
90086
90690
|
state: "not_home",
|
|
90087
90691
|
location: null,
|
|
90088
90692
|
gps: null,
|
|
90089
|
-
batteryPercent: null,
|
|
90090
90693
|
lastChangedAt: 0
|
|
90091
90694
|
};
|
|
90092
90695
|
/**
|
|
@@ -90217,7 +90820,7 @@ var UnifiFeatureDevice = class extends BaseDevice {
|
|
|
90217
90820
|
switch (capForMetric(this.metric)) {
|
|
90218
90821
|
case "temperature-sensor":
|
|
90219
90822
|
this.runtimeState.setCapState("temperature-sensor", {
|
|
90220
|
-
|
|
90823
|
+
temperature: infra.cpuTempC ?? 0,
|
|
90221
90824
|
lastFetchedAt: now
|
|
90222
90825
|
});
|
|
90223
90826
|
return;
|
|
@@ -90254,7 +90857,6 @@ var UnifiFeatureDevice = class extends BaseDevice {
|
|
|
90254
90857
|
state: client.connected ? "home" : "not_home",
|
|
90255
90858
|
location: client.ip,
|
|
90256
90859
|
gps: null,
|
|
90257
|
-
batteryPercent: null,
|
|
90258
90860
|
lastChangedAt: Date.now()
|
|
90259
90861
|
};
|
|
90260
90862
|
this.runtimeState.setCapState("presence", status);
|
|
@@ -90294,7 +90896,7 @@ var UnifiFeatureDevice = class extends BaseDevice {
|
|
|
90294
90896
|
switch (capForMetric(this.metric)) {
|
|
90295
90897
|
case "temperature-sensor": {
|
|
90296
90898
|
const COLD = {
|
|
90297
|
-
|
|
90899
|
+
temperature: 0,
|
|
90298
90900
|
lastFetchedAt: 0
|
|
90299
90901
|
};
|
|
90300
90902
|
this.ctx.registerNativeCap(temperatureSensorCapability, { getStatus: async () => this.runtimeState.getCapState("temperature-sensor") ?? COLD });
|