@camstack/addon-provider-enpal 0.1.3 → 0.1.4
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 +875 -271
- package/dist/addon.mjs +875 -271
- 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).
|
|
@@ -8566,6 +8571,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8566
8571
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8567
8572
|
var CAP_NAMES = Object.freeze([
|
|
8568
8573
|
"accessories",
|
|
8574
|
+
"action-source",
|
|
8575
|
+
"actions",
|
|
8569
8576
|
"addon-pages",
|
|
8570
8577
|
"addon-pages-source",
|
|
8571
8578
|
"addon-routes",
|
|
@@ -8754,11 +8761,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
8754
8761
|
Object.freeze({
|
|
8755
8762
|
"air-quality-sensor": [
|
|
8756
8763
|
{
|
|
8757
|
-
"path": "
|
|
8764
|
+
"path": "co2",
|
|
8758
8765
|
"valueType": "number"
|
|
8759
8766
|
},
|
|
8760
8767
|
{
|
|
8761
|
-
"path": "
|
|
8768
|
+
"path": "voc",
|
|
8762
8769
|
"valueType": "number"
|
|
8763
8770
|
},
|
|
8764
8771
|
{
|
|
@@ -8808,7 +8815,7 @@ Object.freeze({
|
|
|
8808
8815
|
}
|
|
8809
8816
|
],
|
|
8810
8817
|
"ambient-light-sensor": [{
|
|
8811
|
-
"path": "
|
|
8818
|
+
"path": "illuminance",
|
|
8812
8819
|
"valueType": "number"
|
|
8813
8820
|
}],
|
|
8814
8821
|
"audio-metrics": [
|
|
@@ -8869,7 +8876,7 @@ Object.freeze({
|
|
|
8869
8876
|
],
|
|
8870
8877
|
"battery": [
|
|
8871
8878
|
{
|
|
8872
|
-
"path": "
|
|
8879
|
+
"path": "level",
|
|
8873
8880
|
"valueType": "number"
|
|
8874
8881
|
},
|
|
8875
8882
|
{
|
|
@@ -8891,7 +8898,7 @@ Object.freeze({
|
|
|
8891
8898
|
"valueType": "number"
|
|
8892
8899
|
},
|
|
8893
8900
|
{
|
|
8894
|
-
"path": "
|
|
8901
|
+
"path": "voltage",
|
|
8895
8902
|
"valueType": "number"
|
|
8896
8903
|
},
|
|
8897
8904
|
{
|
|
@@ -8912,7 +8919,7 @@ Object.freeze({
|
|
|
8912
8919
|
"valueType": "boolean"
|
|
8913
8920
|
}],
|
|
8914
8921
|
"brightness": [{
|
|
8915
|
-
"path": "
|
|
8922
|
+
"path": "level",
|
|
8916
8923
|
"valueType": "number"
|
|
8917
8924
|
}],
|
|
8918
8925
|
"broker": [{
|
|
@@ -9113,7 +9120,7 @@ Object.freeze({
|
|
|
9113
9120
|
"valueType": "number"
|
|
9114
9121
|
},
|
|
9115
9122
|
{
|
|
9116
|
-
"path": "
|
|
9123
|
+
"path": "colorTemperature",
|
|
9117
9124
|
"valueType": "number"
|
|
9118
9125
|
}
|
|
9119
9126
|
],
|
|
@@ -9292,15 +9299,15 @@ Object.freeze({
|
|
|
9292
9299
|
"valueType": "string"
|
|
9293
9300
|
},
|
|
9294
9301
|
{
|
|
9295
|
-
"path": "
|
|
9302
|
+
"path": "remaining",
|
|
9296
9303
|
"valueType": "number"
|
|
9297
9304
|
},
|
|
9298
9305
|
{
|
|
9299
|
-
"path": "
|
|
9306
|
+
"path": "delayedStart",
|
|
9300
9307
|
"valueType": "number"
|
|
9301
9308
|
},
|
|
9302
9309
|
{
|
|
9303
|
-
"path": "
|
|
9310
|
+
"path": "progress",
|
|
9304
9311
|
"valueType": "number"
|
|
9305
9312
|
},
|
|
9306
9313
|
{
|
|
@@ -9414,7 +9421,7 @@ Object.freeze({
|
|
|
9414
9421
|
],
|
|
9415
9422
|
"fan-control": [
|
|
9416
9423
|
{
|
|
9417
|
-
"path": "
|
|
9424
|
+
"path": "speed",
|
|
9418
9425
|
"valueType": "number"
|
|
9419
9426
|
},
|
|
9420
9427
|
{
|
|
@@ -9514,7 +9521,7 @@ Object.freeze({
|
|
|
9514
9521
|
}
|
|
9515
9522
|
],
|
|
9516
9523
|
"humidity-sensor": [{
|
|
9517
|
-
"path": "
|
|
9524
|
+
"path": "humidity",
|
|
9518
9525
|
"valueType": "number"
|
|
9519
9526
|
}],
|
|
9520
9527
|
"image": [{
|
|
@@ -9624,7 +9631,7 @@ Object.freeze({
|
|
|
9624
9631
|
"valueType": "number"
|
|
9625
9632
|
},
|
|
9626
9633
|
{
|
|
9627
|
-
"path": "
|
|
9634
|
+
"path": "progress",
|
|
9628
9635
|
"valueType": "number"
|
|
9629
9636
|
},
|
|
9630
9637
|
{
|
|
@@ -9703,11 +9710,11 @@ Object.freeze({
|
|
|
9703
9710
|
"valueType": "string"
|
|
9704
9711
|
},
|
|
9705
9712
|
{
|
|
9706
|
-
"path": "
|
|
9713
|
+
"path": "position",
|
|
9707
9714
|
"valueType": "number"
|
|
9708
9715
|
},
|
|
9709
9716
|
{
|
|
9710
|
-
"path": "
|
|
9717
|
+
"path": "duration",
|
|
9711
9718
|
"valueType": "number"
|
|
9712
9719
|
},
|
|
9713
9720
|
{
|
|
@@ -9809,11 +9816,11 @@ Object.freeze({
|
|
|
9809
9816
|
]
|
|
9810
9817
|
},
|
|
9811
9818
|
{
|
|
9812
|
-
"path": "
|
|
9819
|
+
"path": "signal",
|
|
9813
9820
|
"valueType": "number"
|
|
9814
9821
|
},
|
|
9815
9822
|
{
|
|
9816
|
-
"path": "
|
|
9823
|
+
"path": "rssi",
|
|
9817
9824
|
"valueType": "number"
|
|
9818
9825
|
},
|
|
9819
9826
|
{
|
|
@@ -9868,6 +9875,18 @@ Object.freeze({
|
|
|
9868
9875
|
"path": "foodLevel",
|
|
9869
9876
|
"valueType": "number"
|
|
9870
9877
|
},
|
|
9878
|
+
{
|
|
9879
|
+
"path": "bowlFood",
|
|
9880
|
+
"valueType": "number"
|
|
9881
|
+
},
|
|
9882
|
+
{
|
|
9883
|
+
"path": "eating",
|
|
9884
|
+
"valueType": "boolean"
|
|
9885
|
+
},
|
|
9886
|
+
{
|
|
9887
|
+
"path": "supportsMarkRefilled",
|
|
9888
|
+
"valueType": "boolean"
|
|
9889
|
+
},
|
|
9871
9890
|
{
|
|
9872
9891
|
"path": "food1",
|
|
9873
9892
|
"valueType": "number"
|
|
@@ -9932,23 +9951,23 @@ Object.freeze({
|
|
|
9932
9951
|
],
|
|
9933
9952
|
"power-meter": [
|
|
9934
9953
|
{
|
|
9935
|
-
"path": "
|
|
9954
|
+
"path": "power",
|
|
9936
9955
|
"valueType": "number"
|
|
9937
9956
|
},
|
|
9938
9957
|
{
|
|
9939
|
-
"path": "
|
|
9958
|
+
"path": "energy",
|
|
9940
9959
|
"valueType": "number"
|
|
9941
9960
|
},
|
|
9942
9961
|
{
|
|
9943
|
-
"path": "
|
|
9962
|
+
"path": "voltage",
|
|
9944
9963
|
"valueType": "number"
|
|
9945
9964
|
},
|
|
9946
9965
|
{
|
|
9947
|
-
"path": "
|
|
9966
|
+
"path": "current",
|
|
9948
9967
|
"valueType": "number"
|
|
9949
9968
|
},
|
|
9950
9969
|
{
|
|
9951
|
-
"path": "
|
|
9970
|
+
"path": "apparentPower",
|
|
9952
9971
|
"valueType": "number"
|
|
9953
9972
|
},
|
|
9954
9973
|
{
|
|
@@ -9976,14 +9995,10 @@ Object.freeze({
|
|
|
9976
9995
|
{
|
|
9977
9996
|
"path": "gps.accuracyMeters",
|
|
9978
9997
|
"valueType": "number"
|
|
9979
|
-
},
|
|
9980
|
-
{
|
|
9981
|
-
"path": "batteryPercent",
|
|
9982
|
-
"valueType": "number"
|
|
9983
9998
|
}
|
|
9984
9999
|
],
|
|
9985
10000
|
"pressure-sensor": [{
|
|
9986
|
-
"path": "
|
|
10001
|
+
"path": "pressure",
|
|
9987
10002
|
"valueType": "number"
|
|
9988
10003
|
}],
|
|
9989
10004
|
"privacy-mask": [{
|
|
@@ -10297,7 +10312,7 @@ Object.freeze({
|
|
|
10297
10312
|
"valueType": "boolean"
|
|
10298
10313
|
}],
|
|
10299
10314
|
"temperature-sensor": [{
|
|
10300
|
-
"path": "
|
|
10315
|
+
"path": "temperature",
|
|
10301
10316
|
"valueType": "number"
|
|
10302
10317
|
}],
|
|
10303
10318
|
"update": [
|
|
@@ -10345,7 +10360,7 @@ Object.freeze({
|
|
|
10345
10360
|
"valueType": "string"
|
|
10346
10361
|
},
|
|
10347
10362
|
{
|
|
10348
|
-
"path": "
|
|
10363
|
+
"path": "progress",
|
|
10349
10364
|
"valueType": "number"
|
|
10350
10365
|
},
|
|
10351
10366
|
{
|
|
@@ -10830,7 +10845,7 @@ function errMsg(err) {
|
|
|
10830
10845
|
return String(err);
|
|
10831
10846
|
}
|
|
10832
10847
|
//#endregion
|
|
10833
|
-
//#region ../types/dist/composition-
|
|
10848
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
10834
10849
|
/**
|
|
10835
10850
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10836
10851
|
*
|
|
@@ -15350,6 +15365,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
15350
15365
|
array(union([string(), number()]))
|
|
15351
15366
|
])
|
|
15352
15367
|
});
|
|
15368
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
15369
|
+
kind: literal("stationary-present"),
|
|
15370
|
+
deviceId: number().int().nonnegative(),
|
|
15371
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
15372
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15373
|
+
/** The parked object must be in at least one of these zones. */
|
|
15374
|
+
zones: array(string().min(1)).min(1).optional()
|
|
15375
|
+
});
|
|
15353
15376
|
/**
|
|
15354
15377
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
15355
15378
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -15383,7 +15406,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
15383
15406
|
child: AutomationConditionSchema
|
|
15384
15407
|
}),
|
|
15385
15408
|
AutomationConditionLeafSchema,
|
|
15386
|
-
AutomationConditionExpressionSchema
|
|
15409
|
+
AutomationConditionExpressionSchema,
|
|
15410
|
+
AutomationConditionStationaryPresentSchema
|
|
15387
15411
|
]));
|
|
15388
15412
|
/**
|
|
15389
15413
|
* What starts a run.
|
|
@@ -15424,7 +15448,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15424
15448
|
kind: literal("schedule"),
|
|
15425
15449
|
cron: string().min(1).max(120)
|
|
15426
15450
|
}),
|
|
15427
|
-
object({ kind: literal("manual") })
|
|
15451
|
+
object({ kind: literal("manual") }),
|
|
15452
|
+
object({
|
|
15453
|
+
kind: literal("detection"),
|
|
15454
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
15455
|
+
* matches every raw class that maps to it; any other name matches
|
|
15456
|
+
* exactly. */
|
|
15457
|
+
classes: array(string().min(1)).min(1),
|
|
15458
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15459
|
+
/** The track must have visited at least one of these zones. */
|
|
15460
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15461
|
+
/** Best-so-far confidence the track must reach. */
|
|
15462
|
+
minScore: number().min(0).max(1).optional()
|
|
15463
|
+
}),
|
|
15464
|
+
object({
|
|
15465
|
+
kind: literal("stationary"),
|
|
15466
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15467
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
15468
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15469
|
+
/** The parked object must be in at least one of these zones. */
|
|
15470
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15471
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
15472
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
15473
|
+
phase: _enum(["appeared", "departed"])
|
|
15474
|
+
}),
|
|
15475
|
+
object({
|
|
15476
|
+
kind: literal("interval"),
|
|
15477
|
+
minutes: number().int().min(1).max(1440)
|
|
15478
|
+
})
|
|
15428
15479
|
]);
|
|
15429
15480
|
/**
|
|
15430
15481
|
* One action step.
|
|
@@ -15444,28 +15495,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15444
15495
|
* is called. The runner still receives a number and is untouched; the
|
|
15445
15496
|
* resolution is the recipe's job, not the runner's.
|
|
15446
15497
|
*/
|
|
15498
|
+
var AutomationWaitStepSchema = object({
|
|
15499
|
+
kind: literal("wait"),
|
|
15500
|
+
seconds: number().min(0).max(300)
|
|
15501
|
+
});
|
|
15502
|
+
var AutomationCapStepSchema = object({
|
|
15503
|
+
kind: literal("cap"),
|
|
15504
|
+
/**
|
|
15505
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
15506
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
15507
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
15508
|
+
*/
|
|
15509
|
+
deviceId: union([
|
|
15510
|
+
number().int(),
|
|
15511
|
+
array(number().int()).min(1),
|
|
15512
|
+
object({ $var: string().min(1) })
|
|
15513
|
+
]),
|
|
15514
|
+
cap: string().min(1),
|
|
15515
|
+
method: string().min(1),
|
|
15516
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
15517
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
15518
|
+
* the expression leaf. */
|
|
15519
|
+
args: record(string(), unknown()).optional()
|
|
15520
|
+
});
|
|
15521
|
+
/**
|
|
15522
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
15523
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
15524
|
+
*/
|
|
15525
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
15447
15526
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
15527
|
+
AutomationWaitStepSchema,
|
|
15528
|
+
AutomationCapStepSchema,
|
|
15448
15529
|
object({
|
|
15449
|
-
kind: literal("
|
|
15450
|
-
|
|
15451
|
-
|
|
15452
|
-
|
|
15453
|
-
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
|
|
15457
|
-
|
|
15458
|
-
*/
|
|
15459
|
-
deviceId: union([
|
|
15460
|
-
number().int(),
|
|
15461
|
-
array(number().int()).min(1),
|
|
15462
|
-
object({ $var: string().min(1) })
|
|
15463
|
-
]),
|
|
15464
|
-
cap: string().min(1),
|
|
15465
|
-
method: string().min(1),
|
|
15466
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
15467
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
15468
|
-
args: record(string(), unknown()).optional()
|
|
15530
|
+
kind: literal("action"),
|
|
15531
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
15532
|
+
actionId: string().min(1),
|
|
15533
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
15534
|
+
variables: record(string(), union([
|
|
15535
|
+
string(),
|
|
15536
|
+
number(),
|
|
15537
|
+
boolean()
|
|
15538
|
+
])).optional()
|
|
15469
15539
|
}),
|
|
15470
15540
|
object({
|
|
15471
15541
|
kind: literal("code"),
|
|
@@ -15474,10 +15544,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
15474
15544
|
code: string().min(1).max(2e4)
|
|
15475
15545
|
})
|
|
15476
15546
|
]);
|
|
15547
|
+
/**
|
|
15548
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
15549
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
15550
|
+
* actions. Absent means `single`.
|
|
15551
|
+
*
|
|
15552
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
15553
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
15554
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
15555
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
15556
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
15557
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
15558
|
+
* wait, never the single/queued limits.
|
|
15559
|
+
*/
|
|
15560
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
15561
|
+
object({ mode: literal("single") }),
|
|
15562
|
+
object({ mode: literal("restart") }),
|
|
15563
|
+
object({
|
|
15564
|
+
mode: literal("queued"),
|
|
15565
|
+
max: number().int().min(1).max(10)
|
|
15566
|
+
}),
|
|
15567
|
+
object({
|
|
15568
|
+
mode: literal("parallel"),
|
|
15569
|
+
max: number().int().min(1).max(10)
|
|
15570
|
+
}),
|
|
15571
|
+
object({
|
|
15572
|
+
mode: literal("cooldown"),
|
|
15573
|
+
minutes: number().int().min(1).max(1440)
|
|
15574
|
+
})
|
|
15575
|
+
]);
|
|
15477
15576
|
var AutomationRecipeSchema = object({
|
|
15478
15577
|
triggers: array(AutomationTriggerSchema),
|
|
15479
15578
|
conditions: AutomationConditionSchema.optional(),
|
|
15480
|
-
actions: array(AutomationActionSchema)
|
|
15579
|
+
actions: array(AutomationActionSchema),
|
|
15580
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
15581
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
15582
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
15583
|
+
});
|
|
15584
|
+
new Set([
|
|
15585
|
+
{
|
|
15586
|
+
id: "person",
|
|
15587
|
+
name: "Person"
|
|
15588
|
+
},
|
|
15589
|
+
{
|
|
15590
|
+
id: "vehicle",
|
|
15591
|
+
name: "Vehicle"
|
|
15592
|
+
},
|
|
15593
|
+
{
|
|
15594
|
+
id: "animal",
|
|
15595
|
+
name: "Animal"
|
|
15596
|
+
},
|
|
15597
|
+
{
|
|
15598
|
+
id: "package",
|
|
15599
|
+
name: "Package"
|
|
15600
|
+
}
|
|
15601
|
+
].map((l) => l.id));
|
|
15602
|
+
var COCO_TO_MACRO = {
|
|
15603
|
+
mapping: {
|
|
15604
|
+
person: "person",
|
|
15605
|
+
bicycle: "vehicle",
|
|
15606
|
+
car: "vehicle",
|
|
15607
|
+
motorcycle: "vehicle",
|
|
15608
|
+
airplane: "vehicle",
|
|
15609
|
+
bus: "vehicle",
|
|
15610
|
+
train: "vehicle",
|
|
15611
|
+
truck: "vehicle",
|
|
15612
|
+
boat: "vehicle",
|
|
15613
|
+
bird: "animal",
|
|
15614
|
+
cat: "animal",
|
|
15615
|
+
dog: "animal",
|
|
15616
|
+
horse: "animal",
|
|
15617
|
+
sheep: "animal",
|
|
15618
|
+
cow: "animal",
|
|
15619
|
+
elephant: "animal",
|
|
15620
|
+
bear: "animal",
|
|
15621
|
+
zebra: "animal",
|
|
15622
|
+
giraffe: "animal",
|
|
15623
|
+
suitcase: "package",
|
|
15624
|
+
backpack: "package",
|
|
15625
|
+
handbag: "package"
|
|
15626
|
+
},
|
|
15627
|
+
preserveOriginal: false
|
|
15628
|
+
};
|
|
15629
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
15630
|
+
/**
|
|
15631
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
15632
|
+
* so the editor can paint every block green or red with its reason.
|
|
15633
|
+
*
|
|
15634
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
15635
|
+
* every condition node (containers and leaves, including the ones a
|
|
15636
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
15637
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
15638
|
+
* for an Action run). Skipped
|
|
15639
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
15640
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
15641
|
+
*
|
|
15642
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
15643
|
+
* vocabulary so an Action run records the same step shape.
|
|
15644
|
+
*/
|
|
15645
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
15646
|
+
var TraceValueSchema = union([
|
|
15647
|
+
string(),
|
|
15648
|
+
number(),
|
|
15649
|
+
boolean(),
|
|
15650
|
+
_null(),
|
|
15651
|
+
array(union([string(), number()]))
|
|
15652
|
+
]);
|
|
15653
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
15654
|
+
"ran",
|
|
15655
|
+
"skipped-trigger",
|
|
15656
|
+
"skipped-conditions",
|
|
15657
|
+
"skipped-cooldown",
|
|
15658
|
+
"skipped-overlap",
|
|
15659
|
+
"failed",
|
|
15660
|
+
"aborted"
|
|
15661
|
+
]);
|
|
15662
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
15663
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
15664
|
+
"pass",
|
|
15665
|
+
"fail",
|
|
15666
|
+
"not-evaluated"
|
|
15667
|
+
]);
|
|
15668
|
+
var AutomationTriggerTraceSchema = object({
|
|
15669
|
+
kind: string().min(1),
|
|
15670
|
+
outcome: _enum(["pass", "fail"]),
|
|
15671
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
15672
|
+
reason: string(),
|
|
15673
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
15674
|
+
vars: record(string(), TraceValueSchema)
|
|
15675
|
+
});
|
|
15676
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
15677
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
15678
|
+
path: string().min(1),
|
|
15679
|
+
kind: _enum([
|
|
15680
|
+
"all",
|
|
15681
|
+
"any",
|
|
15682
|
+
"not",
|
|
15683
|
+
"condition",
|
|
15684
|
+
"expression",
|
|
15685
|
+
"stationary-present"
|
|
15686
|
+
]),
|
|
15687
|
+
outcome: TraceNodeOutcomeSchema,
|
|
15688
|
+
reason: string(),
|
|
15689
|
+
deviceId: number().int().optional(),
|
|
15690
|
+
cap: string().optional(),
|
|
15691
|
+
fieldPath: string().optional(),
|
|
15692
|
+
operator: string().optional(),
|
|
15693
|
+
expected: TraceValueSchema.optional(),
|
|
15694
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
15695
|
+
observed: TraceValueSchema.optional()
|
|
15696
|
+
});
|
|
15697
|
+
var AutomationRunVerdictSchema = object({
|
|
15698
|
+
mode: AutomationRunModeSchema,
|
|
15699
|
+
decision: _enum([
|
|
15700
|
+
"run",
|
|
15701
|
+
"queued",
|
|
15702
|
+
"restart",
|
|
15703
|
+
"drop",
|
|
15704
|
+
"cooldown",
|
|
15705
|
+
"bypass"
|
|
15706
|
+
]),
|
|
15707
|
+
reason: string()
|
|
15708
|
+
});
|
|
15709
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
15710
|
+
var AutomationStepTraceSchema = object({
|
|
15711
|
+
/** `actions.<i>` */
|
|
15712
|
+
path: string().min(1),
|
|
15713
|
+
kind: string().min(1),
|
|
15714
|
+
cap: string().optional(),
|
|
15715
|
+
method: string().optional(),
|
|
15716
|
+
deviceId: number().int().optional(),
|
|
15717
|
+
startedAt: number().optional(),
|
|
15718
|
+
endedAt: number().optional(),
|
|
15719
|
+
outcome: _enum([
|
|
15720
|
+
"ok",
|
|
15721
|
+
"error",
|
|
15722
|
+
"not-run"
|
|
15723
|
+
]),
|
|
15724
|
+
message: string().optional()
|
|
15725
|
+
});
|
|
15726
|
+
var AutomationRunTraceSchema = object({
|
|
15727
|
+
runId: string().min(1),
|
|
15728
|
+
startedAt: number(),
|
|
15729
|
+
endedAt: number(),
|
|
15730
|
+
trigger: AutomationTriggerTraceSchema,
|
|
15731
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
15732
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
15733
|
+
steps: array(AutomationStepTraceSchema),
|
|
15734
|
+
outcome: AutomationRunOutcomeSchema,
|
|
15735
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
15736
|
+
repeat: number().int().min(1),
|
|
15737
|
+
/** When the latest of those repeats happened. */
|
|
15738
|
+
lastAt: number()
|
|
15739
|
+
});
|
|
15740
|
+
/**
|
|
15741
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
15742
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
15743
|
+
*/
|
|
15744
|
+
var AutomationStateDocSchema = object({
|
|
15745
|
+
version: literal(1),
|
|
15746
|
+
lastRunStartedAt: number().nullable(),
|
|
15747
|
+
traces: array(AutomationRunTraceSchema)
|
|
15748
|
+
});
|
|
15749
|
+
/**
|
|
15750
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
15751
|
+
* declared as LIST ENTRIES, never as devices.
|
|
15752
|
+
*
|
|
15753
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
15754
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
15755
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
15756
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
15757
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
15758
|
+
*
|
|
15759
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
15760
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
15761
|
+
* runtime.
|
|
15762
|
+
*/
|
|
15763
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
15764
|
+
var ActionVariableTypeSchema = _enum([
|
|
15765
|
+
"string",
|
|
15766
|
+
"number",
|
|
15767
|
+
"boolean",
|
|
15768
|
+
"select"
|
|
15769
|
+
]);
|
|
15770
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
15771
|
+
var ActionVariableValueSchema = union([
|
|
15772
|
+
string(),
|
|
15773
|
+
number(),
|
|
15774
|
+
boolean()
|
|
15775
|
+
]);
|
|
15776
|
+
/**
|
|
15777
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
15778
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
15779
|
+
*/
|
|
15780
|
+
var ActionVariableSchema = object({
|
|
15781
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
15782
|
+
label: string().min(1).max(120).optional(),
|
|
15783
|
+
type: ActionVariableTypeSchema,
|
|
15784
|
+
required: boolean().optional(),
|
|
15785
|
+
default: ActionVariableValueSchema.optional(),
|
|
15786
|
+
/** The allowed values of a `select`. */
|
|
15787
|
+
options: array(string().min(1)).min(1).optional()
|
|
15788
|
+
}).superRefine((v, ctx) => {
|
|
15789
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
15790
|
+
code: "custom",
|
|
15791
|
+
message: "a select variable needs options",
|
|
15792
|
+
path: ["options"]
|
|
15793
|
+
});
|
|
15794
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
15795
|
+
code: "custom",
|
|
15796
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
15797
|
+
path: ["default"]
|
|
15798
|
+
});
|
|
15799
|
+
});
|
|
15800
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
15801
|
+
function variableValueError(variable, value) {
|
|
15802
|
+
switch (variable.type) {
|
|
15803
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
15804
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
15805
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
15806
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
15807
|
+
}
|
|
15808
|
+
}
|
|
15809
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
15810
|
+
function isInternalActionId(actionId) {
|
|
15811
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
15812
|
+
}
|
|
15813
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
15814
|
+
function addonIdOfActionId(actionId) {
|
|
15815
|
+
if (isInternalActionId(actionId)) return null;
|
|
15816
|
+
const at = actionId.indexOf(":");
|
|
15817
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
15818
|
+
}
|
|
15819
|
+
var ActionStatusSchema = object({
|
|
15820
|
+
isRunning: boolean(),
|
|
15821
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
15822
|
+
lastRunAt: number().nullable(),
|
|
15823
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
15824
|
+
lastError: string().nullable()
|
|
15825
|
+
});
|
|
15826
|
+
var ActionEntrySchema = object({
|
|
15827
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
15828
|
+
id: string().min(3),
|
|
15829
|
+
name: string().min(1).max(120),
|
|
15830
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
15831
|
+
addonId: string().min(1),
|
|
15832
|
+
source: ActionSourceKindSchema,
|
|
15833
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
15834
|
+
readOnly: boolean(),
|
|
15835
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
15836
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
15837
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
15838
|
+
status: ActionStatusSchema
|
|
15839
|
+
}).superRefine((entry, ctx) => {
|
|
15840
|
+
if (entry.source === "internal") {
|
|
15841
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
15842
|
+
code: "custom",
|
|
15843
|
+
message: "an internal action id is internal:<uuid>",
|
|
15844
|
+
path: ["id"]
|
|
15845
|
+
});
|
|
15846
|
+
return;
|
|
15847
|
+
}
|
|
15848
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
15849
|
+
code: "custom",
|
|
15850
|
+
message: "only an internal action carries steps",
|
|
15851
|
+
path: ["steps"]
|
|
15852
|
+
});
|
|
15853
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
15854
|
+
code: "custom",
|
|
15855
|
+
message: "an addon action is read-only here",
|
|
15856
|
+
path: ["readOnly"]
|
|
15857
|
+
});
|
|
15858
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
15859
|
+
code: "custom",
|
|
15860
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
15861
|
+
path: ["id"]
|
|
15862
|
+
});
|
|
15863
|
+
});
|
|
15864
|
+
/** What an operator writes for an internal action. */
|
|
15865
|
+
var ActionInputSchema = object({
|
|
15866
|
+
name: string().min(1).max(120),
|
|
15867
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
15868
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
15869
|
+
});
|
|
15870
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
15871
|
+
var ActionRunOriginSchema = object({
|
|
15872
|
+
/** The automation block whose step started it. */
|
|
15873
|
+
blockId: string().min(1).optional() });
|
|
15874
|
+
/** `started` = the caller did not ask to wait. */
|
|
15875
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
15876
|
+
var ActionRunResultSchema = object({
|
|
15877
|
+
runId: string().min(1),
|
|
15878
|
+
outcome: ActionRunOutcomeSchema,
|
|
15879
|
+
/** Why it did not run, or what failed. */
|
|
15880
|
+
message: string().optional()
|
|
15881
|
+
});
|
|
15882
|
+
_enum([
|
|
15883
|
+
"not-found",
|
|
15884
|
+
"read-only",
|
|
15885
|
+
"invalid-variables",
|
|
15886
|
+
"invalid-steps",
|
|
15887
|
+
"not-linked",
|
|
15888
|
+
"busy"
|
|
15889
|
+
]);
|
|
15890
|
+
object({
|
|
15891
|
+
actionId: string(),
|
|
15892
|
+
runId: string(),
|
|
15893
|
+
isRunning: boolean(),
|
|
15894
|
+
/** Set when the run ended. */
|
|
15895
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
15896
|
+
lastRunAt: number().nullable(),
|
|
15897
|
+
lastError: string().nullable()
|
|
15481
15898
|
});
|
|
15482
15899
|
/**
|
|
15483
15900
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18164,7 +18581,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18164
18581
|
stateField: string(),
|
|
18165
18582
|
fieldKey: string()
|
|
18166
18583
|
});
|
|
18167
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
18584
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18168
18585
|
var CompositionProblemSchema = object({
|
|
18169
18586
|
code: _enum([
|
|
18170
18587
|
"reserved-variant",
|
|
@@ -18483,7 +18900,7 @@ var GROUP_TEMPLATES = [
|
|
|
18483
18900
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18484
18901
|
role: DeviceRole.TemperatureSensor,
|
|
18485
18902
|
outputCap: "temperature-sensor",
|
|
18486
|
-
outputField: "
|
|
18903
|
+
outputField: "temperature",
|
|
18487
18904
|
quantity: "temperature",
|
|
18488
18905
|
defaultAggregate: "mean",
|
|
18489
18906
|
empty: "null",
|
|
@@ -18494,7 +18911,7 @@ var GROUP_TEMPLATES = [
|
|
|
18494
18911
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18495
18912
|
role: DeviceRole.HumiditySensor,
|
|
18496
18913
|
outputCap: "humidity-sensor",
|
|
18497
|
-
outputField: "
|
|
18914
|
+
outputField: "humidity",
|
|
18498
18915
|
quantity: "humidity",
|
|
18499
18916
|
defaultAggregate: "mean",
|
|
18500
18917
|
empty: "null",
|
|
@@ -18505,7 +18922,7 @@ var GROUP_TEMPLATES = [
|
|
|
18505
18922
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18506
18923
|
role: DeviceRole.PressureSensor,
|
|
18507
18924
|
outputCap: "pressure-sensor",
|
|
18508
|
-
outputField: "
|
|
18925
|
+
outputField: "pressure",
|
|
18509
18926
|
quantity: "pressure",
|
|
18510
18927
|
defaultAggregate: "mean",
|
|
18511
18928
|
empty: "null",
|
|
@@ -18516,7 +18933,7 @@ var GROUP_TEMPLATES = [
|
|
|
18516
18933
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18517
18934
|
role: DeviceRole.AmbientLightSensor,
|
|
18518
18935
|
outputCap: "ambient-light-sensor",
|
|
18519
|
-
outputField: "
|
|
18936
|
+
outputField: "illuminance",
|
|
18520
18937
|
quantity: "illuminance",
|
|
18521
18938
|
defaultAggregate: "mean",
|
|
18522
18939
|
empty: "null",
|
|
@@ -18527,7 +18944,7 @@ var GROUP_TEMPLATES = [
|
|
|
18527
18944
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18528
18945
|
role: DeviceRole.PowerSensor,
|
|
18529
18946
|
outputCap: "power-meter",
|
|
18530
|
-
outputField: "
|
|
18947
|
+
outputField: "power",
|
|
18531
18948
|
quantity: "power",
|
|
18532
18949
|
defaultAggregate: "sum",
|
|
18533
18950
|
empty: "omit",
|
|
@@ -18538,7 +18955,7 @@ var GROUP_TEMPLATES = [
|
|
|
18538
18955
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18539
18956
|
role: DeviceRole.EnergySensor,
|
|
18540
18957
|
outputCap: "power-meter",
|
|
18541
|
-
outputField: "
|
|
18958
|
+
outputField: "energy",
|
|
18542
18959
|
quantity: "energy",
|
|
18543
18960
|
defaultAggregate: "sum",
|
|
18544
18961
|
empty: "omit",
|
|
@@ -18549,7 +18966,7 @@ var GROUP_TEMPLATES = [
|
|
|
18549
18966
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18550
18967
|
role: DeviceRole.BatterySensor,
|
|
18551
18968
|
outputCap: "battery",
|
|
18552
|
-
outputField: "
|
|
18969
|
+
outputField: "level",
|
|
18553
18970
|
quantity: "percentage",
|
|
18554
18971
|
defaultAggregate: "mean",
|
|
18555
18972
|
empty: "null",
|
|
@@ -19127,7 +19544,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19127
19544
|
kind: "mutation",
|
|
19128
19545
|
auth: "admin",
|
|
19129
19546
|
access: "view"
|
|
19130
|
-
})
|
|
19547
|
+
}), method(object({
|
|
19548
|
+
blockId: string().min(1),
|
|
19549
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
19550
|
+
runStartedAt: number().optional(),
|
|
19551
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
19552
|
+
}), _void(), {
|
|
19553
|
+
kind: "mutation",
|
|
19554
|
+
auth: "admin"
|
|
19555
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
19556
|
+
traces: array(AutomationRunTraceSchema),
|
|
19557
|
+
lastError: string().nullable()
|
|
19558
|
+
}), { auth: "admin" });
|
|
19131
19559
|
/**
|
|
19132
19560
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19133
19561
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -44503,51 +44931,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
44503
44931
|
kind: "mutation",
|
|
44504
44932
|
auth: "admin"
|
|
44505
44933
|
});
|
|
44506
|
-
new Set([
|
|
44507
|
-
{
|
|
44508
|
-
id: "person",
|
|
44509
|
-
name: "Person"
|
|
44510
|
-
},
|
|
44511
|
-
{
|
|
44512
|
-
id: "vehicle",
|
|
44513
|
-
name: "Vehicle"
|
|
44514
|
-
},
|
|
44515
|
-
{
|
|
44516
|
-
id: "animal",
|
|
44517
|
-
name: "Animal"
|
|
44518
|
-
},
|
|
44519
|
-
{
|
|
44520
|
-
id: "package",
|
|
44521
|
-
name: "Package"
|
|
44522
|
-
}
|
|
44523
|
-
].map((l) => l.id));
|
|
44524
|
-
var COCO_TO_MACRO = {
|
|
44525
|
-
mapping: {
|
|
44526
|
-
person: "person",
|
|
44527
|
-
bicycle: "vehicle",
|
|
44528
|
-
car: "vehicle",
|
|
44529
|
-
motorcycle: "vehicle",
|
|
44530
|
-
airplane: "vehicle",
|
|
44531
|
-
bus: "vehicle",
|
|
44532
|
-
train: "vehicle",
|
|
44533
|
-
truck: "vehicle",
|
|
44534
|
-
boat: "vehicle",
|
|
44535
|
-
bird: "animal",
|
|
44536
|
-
cat: "animal",
|
|
44537
|
-
dog: "animal",
|
|
44538
|
-
horse: "animal",
|
|
44539
|
-
sheep: "animal",
|
|
44540
|
-
cow: "animal",
|
|
44541
|
-
elephant: "animal",
|
|
44542
|
-
bear: "animal",
|
|
44543
|
-
zebra: "animal",
|
|
44544
|
-
giraffe: "animal",
|
|
44545
|
-
suitcase: "package",
|
|
44546
|
-
backpack: "package",
|
|
44547
|
-
handbag: "package"
|
|
44548
|
-
},
|
|
44549
|
-
preserveOriginal: false
|
|
44550
|
-
};
|
|
44551
44934
|
var AUDIO_MACRO_LABELS = [
|
|
44552
44935
|
{
|
|
44553
44936
|
id: "speech",
|
|
@@ -57114,9 +57497,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57114
57497
|
*/
|
|
57115
57498
|
var AirQualitySensorStatusSchema = object({
|
|
57116
57499
|
/** Carbon dioxide concentration in ppm. */
|
|
57117
|
-
|
|
57500
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57118
57501
|
/** Total volatile organic compounds in ppb. */
|
|
57119
|
-
|
|
57502
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57120
57503
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57121
57504
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57122
57505
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -57149,12 +57532,12 @@ var airQualitySensorCapability = {
|
|
|
57149
57532
|
* History (D850): recorded series.
|
|
57150
57533
|
*/
|
|
57151
57534
|
history: { fields: {
|
|
57152
|
-
|
|
57535
|
+
co2: {
|
|
57153
57536
|
kind: "gauge",
|
|
57154
57537
|
unit: "ppm",
|
|
57155
57538
|
deadband: 5
|
|
57156
57539
|
},
|
|
57157
|
-
|
|
57540
|
+
voc: {
|
|
57158
57541
|
kind: "gauge",
|
|
57159
57542
|
unit: "ppb",
|
|
57160
57543
|
deadband: 5
|
|
@@ -57185,7 +57568,7 @@ var airQualitySensorCapability = {
|
|
|
57185
57568
|
*/
|
|
57186
57569
|
var AmbientLightSensorStatusSchema = object({
|
|
57187
57570
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57188
|
-
|
|
57571
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57189
57572
|
precision: 0,
|
|
57190
57573
|
label: "Illuminance"
|
|
57191
57574
|
})),
|
|
@@ -57214,7 +57597,7 @@ var ambientLightSensorCapability = {
|
|
|
57214
57597
|
/**
|
|
57215
57598
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
57216
57599
|
*/
|
|
57217
|
-
history: { fields: {
|
|
57600
|
+
history: { fields: { illuminance: {
|
|
57218
57601
|
kind: "gauge",
|
|
57219
57602
|
unit: "lx",
|
|
57220
57603
|
deadbandPct: 10,
|
|
@@ -57353,6 +57736,84 @@ var audioMetricsCapability = {
|
|
|
57353
57736
|
*/
|
|
57354
57737
|
history: "none"
|
|
57355
57738
|
};
|
|
57739
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
57740
|
+
actionId: string().min(1),
|
|
57741
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
57742
|
+
}), _void(), {
|
|
57743
|
+
kind: "mutation",
|
|
57744
|
+
auth: "admin"
|
|
57745
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
57746
|
+
kind: "mutation",
|
|
57747
|
+
auth: "admin"
|
|
57748
|
+
});
|
|
57749
|
+
/**
|
|
57750
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
57751
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
57752
|
+
*
|
|
57753
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
57754
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
57755
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
57756
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
57757
|
+
* drift (D3).
|
|
57758
|
+
*
|
|
57759
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
57760
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
57761
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
57762
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
57763
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
57764
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
57765
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
57766
|
+
*
|
|
57767
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
57768
|
+
* logged — never queued.
|
|
57769
|
+
*/
|
|
57770
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
57771
|
+
var ActionLinksSchema = object({
|
|
57772
|
+
deviceId: number().int().nonnegative(),
|
|
57773
|
+
actionIds: array(string().min(1)).max(100)
|
|
57774
|
+
});
|
|
57775
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
57776
|
+
actionId: string().min(1),
|
|
57777
|
+
deviceId: number().int().nonnegative().optional()
|
|
57778
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
57779
|
+
role: "viewer",
|
|
57780
|
+
auth: "protected",
|
|
57781
|
+
kind: "query",
|
|
57782
|
+
caller: "required"
|
|
57783
|
+
}), method(object({
|
|
57784
|
+
actionId: string().min(1),
|
|
57785
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
57786
|
+
wait: boolean().optional(),
|
|
57787
|
+
origin: ActionRunOriginSchema.optional(),
|
|
57788
|
+
deviceId: number().int().nonnegative().optional()
|
|
57789
|
+
}), ActionRunResultSchema, {
|
|
57790
|
+
role: "viewer",
|
|
57791
|
+
auth: "protected",
|
|
57792
|
+
kind: "mutation",
|
|
57793
|
+
caller: "required"
|
|
57794
|
+
}), method(ActionIdInput, _void(), {
|
|
57795
|
+
kind: "mutation",
|
|
57796
|
+
auth: "admin"
|
|
57797
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
57798
|
+
kind: "mutation",
|
|
57799
|
+
auth: "admin"
|
|
57800
|
+
}), method(object({
|
|
57801
|
+
actionId: string().min(1),
|
|
57802
|
+
action: ActionInputSchema.partial()
|
|
57803
|
+
}), object({ action: ActionEntrySchema }), {
|
|
57804
|
+
kind: "mutation",
|
|
57805
|
+
auth: "admin"
|
|
57806
|
+
}), method(ActionIdInput, _void(), {
|
|
57807
|
+
kind: "mutation",
|
|
57808
|
+
auth: "admin"
|
|
57809
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
57810
|
+
role: "viewer",
|
|
57811
|
+
auth: "protected",
|
|
57812
|
+
kind: "query"
|
|
57813
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
57814
|
+
kind: "mutation",
|
|
57815
|
+
auth: "admin"
|
|
57816
|
+
});
|
|
57356
57817
|
/**
|
|
57357
57818
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
57358
57819
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -57449,7 +57910,7 @@ var BatteryStatusSchema = object({
|
|
|
57449
57910
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57450
57911
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57451
57912
|
*/
|
|
57452
|
-
|
|
57913
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57453
57914
|
/**
|
|
57454
57915
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57455
57916
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57459,7 +57920,7 @@ var BatteryStatusSchema = object({
|
|
|
57459
57920
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
57460
57921
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
57461
57922
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
57462
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
57923
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
57463
57924
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
57464
57925
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
57465
57926
|
*/
|
|
@@ -57483,7 +57944,7 @@ var BatteryStatusSchema = object({
|
|
|
57483
57944
|
* that only report charge. A second reading on this cap, not a second
|
|
57484
57945
|
* `numeric-sensor` on the same device.
|
|
57485
57946
|
*/
|
|
57486
|
-
|
|
57947
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57487
57948
|
/**
|
|
57488
57949
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57489
57950
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57517,7 +57978,7 @@ var BatteryStatusSchema = object({
|
|
|
57517
57978
|
/**
|
|
57518
57979
|
* True when the source is a BINARY low-battery indicator (HA
|
|
57519
57980
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
57520
|
-
* charge level — `
|
|
57981
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
57521
57982
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
57522
57983
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
57523
57984
|
*/
|
|
@@ -57537,15 +57998,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57537
57998
|
var batteryCustomize = {
|
|
57538
57999
|
version: 1,
|
|
57539
58000
|
targets: [{
|
|
57540
|
-
id: "
|
|
58001
|
+
id: "level",
|
|
57541
58002
|
cardinality: "scalar",
|
|
57542
58003
|
vocabulary: {
|
|
57543
58004
|
cap: "battery",
|
|
57544
|
-
stateField: "
|
|
58005
|
+
stateField: "level"
|
|
57545
58006
|
},
|
|
57546
58007
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57547
58008
|
apply: "add",
|
|
57548
|
-
path: "
|
|
58009
|
+
path: "level",
|
|
57549
58010
|
sources: [{
|
|
57550
58011
|
kind: "field",
|
|
57551
58012
|
valueKinds: ["number", "string"],
|
|
@@ -57639,7 +58100,7 @@ onStatusChanged: { data: object({
|
|
|
57639
58100
|
schema: BatteryStatusSchema,
|
|
57640
58101
|
kind: "push",
|
|
57641
58102
|
empty: {
|
|
57642
|
-
|
|
58103
|
+
level: null,
|
|
57643
58104
|
charging: "unknown",
|
|
57644
58105
|
sleeping: false,
|
|
57645
58106
|
lastUpdated: 0
|
|
@@ -57666,11 +58127,11 @@ onStatusChanged: { data: object({
|
|
|
57666
58127
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57667
58128
|
*/
|
|
57668
58129
|
history: { fields: {
|
|
57669
|
-
|
|
58130
|
+
level: {
|
|
57670
58131
|
kind: "gauge",
|
|
57671
58132
|
unit: "%"
|
|
57672
58133
|
},
|
|
57673
|
-
|
|
58134
|
+
voltage: {
|
|
57674
58135
|
kind: "gauge",
|
|
57675
58136
|
unit: "V"
|
|
57676
58137
|
}
|
|
@@ -57730,14 +58191,14 @@ var binaryCapability = {
|
|
|
57730
58191
|
* controls to this single-method surface.
|
|
57731
58192
|
*
|
|
57732
58193
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
57733
|
-
*
|
|
58194
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
57734
58195
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
57735
58196
|
* should surface those via the device's `getSettingsUISchema()`
|
|
57736
58197
|
* instead of bloating this cap.
|
|
57737
58198
|
*/
|
|
57738
58199
|
var BrightnessStatusSchema = object({
|
|
57739
58200
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57740
|
-
|
|
58201
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57741
58202
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57742
58203
|
lastChangedAt: number()
|
|
57743
58204
|
});
|
|
@@ -57749,7 +58210,7 @@ var brightnessCapability = {
|
|
|
57749
58210
|
deviceTypes: [DeviceType.Light],
|
|
57750
58211
|
methods: { setBrightness: method(object({
|
|
57751
58212
|
deviceId: number().int().nonnegative(),
|
|
57752
|
-
|
|
58213
|
+
level: number().min(0).max(100)
|
|
57753
58214
|
}), _void(), {
|
|
57754
58215
|
kind: "mutation",
|
|
57755
58216
|
auth: "protected"
|
|
@@ -57762,7 +58223,7 @@ var brightnessCapability = {
|
|
|
57762
58223
|
*/
|
|
57763
58224
|
onBrightnessChanged: { data: object({
|
|
57764
58225
|
deviceId: number(),
|
|
57765
|
-
|
|
58226
|
+
level: number().min(0).max(100),
|
|
57766
58227
|
lastChangedAt: number()
|
|
57767
58228
|
}) } },
|
|
57768
58229
|
status: {
|
|
@@ -57785,7 +58246,7 @@ onBrightnessChanged: { data: object({
|
|
|
57785
58246
|
/**
|
|
57786
58247
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
57787
58248
|
*/
|
|
57788
|
-
history: { fields: {
|
|
58249
|
+
history: { fields: { level: {
|
|
57789
58250
|
kind: "gauge",
|
|
57790
58251
|
unit: "%",
|
|
57791
58252
|
minIntervalMs: 0
|
|
@@ -58382,11 +58843,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
58382
58843
|
}),
|
|
58383
58844
|
object({
|
|
58384
58845
|
mode: literal("mired"),
|
|
58385
|
-
|
|
58846
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
58386
58847
|
})
|
|
58387
58848
|
]);
|
|
58388
58849
|
var ColorStatusSchema = object({
|
|
58389
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
58850
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
58390
58851
|
* the bulb's current state. */
|
|
58391
58852
|
mode: _enum([
|
|
58392
58853
|
"rgb",
|
|
@@ -58398,7 +58859,7 @@ var ColorStatusSchema = object({
|
|
|
58398
58859
|
/** Populated when `mode === 'hsv'`. */
|
|
58399
58860
|
hsv: HsvTripletSchema.optional(),
|
|
58400
58861
|
/** Populated when `mode === 'mired'`. */
|
|
58401
|
-
|
|
58862
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58402
58863
|
/** Ms epoch of the last operator-driven change. */
|
|
58403
58864
|
lastChangedAt: number()
|
|
58404
58865
|
});
|
|
@@ -58430,7 +58891,7 @@ onColorChanged: { data: object({
|
|
|
58430
58891
|
]),
|
|
58431
58892
|
rgb: RgbTripletSchema.optional(),
|
|
58432
58893
|
hsv: HsvTripletSchema.optional(),
|
|
58433
|
-
|
|
58894
|
+
colorTemperature: number().int().optional(),
|
|
58434
58895
|
lastChangedAt: number()
|
|
58435
58896
|
}) } },
|
|
58436
58897
|
status: {
|
|
@@ -59307,11 +59768,11 @@ var DishwasherStatusSchema = object({
|
|
|
59307
59768
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59308
59769
|
availablePrograms: array(string()),
|
|
59309
59770
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59310
|
-
|
|
59771
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59311
59772
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59312
|
-
|
|
59773
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59313
59774
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59314
|
-
|
|
59775
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59315
59776
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59316
59777
|
doorOpen: boolean().nullable(),
|
|
59317
59778
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59530,14 +59991,14 @@ var dishwasherCapability = {
|
|
|
59530
59991
|
runtimeState: DishwasherStatusSchema,
|
|
59531
59992
|
durability: "session",
|
|
59532
59993
|
history: { fields: {
|
|
59533
|
-
|
|
59994
|
+
progress: {
|
|
59534
59995
|
kind: "gauge",
|
|
59535
59996
|
unit: "%",
|
|
59536
59997
|
deadband: 2
|
|
59537
59998
|
},
|
|
59538
59999
|
state: { kind: "enum" },
|
|
59539
60000
|
operationState: { kind: "enum" },
|
|
59540
|
-
|
|
60001
|
+
remaining: {
|
|
59541
60002
|
kind: "gauge",
|
|
59542
60003
|
unit: "s",
|
|
59543
60004
|
minIntervalMs: 6e4
|
|
@@ -60128,7 +60589,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60128
60589
|
var FanControlStatusSchema = object({
|
|
60129
60590
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60130
60591
|
* speed surface (single-speed fan). */
|
|
60131
|
-
|
|
60592
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60132
60593
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60133
60594
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60134
60595
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -60155,7 +60616,7 @@ var fanControlCapability = {
|
|
|
60155
60616
|
methods: {
|
|
60156
60617
|
setPercentage: method(object({
|
|
60157
60618
|
deviceId: number().int().nonnegative(),
|
|
60158
|
-
|
|
60619
|
+
speed: number().min(0).max(100)
|
|
60159
60620
|
}), _void(), {
|
|
60160
60621
|
kind: "mutation",
|
|
60161
60622
|
auth: "protected"
|
|
@@ -60188,7 +60649,7 @@ var fanControlCapability = {
|
|
|
60188
60649
|
},
|
|
60189
60650
|
/**
|
|
60190
60651
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
60191
|
-
* sliders read `
|
|
60652
|
+
* sliders read `speed` for live updates.
|
|
60192
60653
|
*/
|
|
60193
60654
|
runtimeState: FanControlStatusSchema,
|
|
60194
60655
|
/**
|
|
@@ -60202,7 +60663,7 @@ var fanControlCapability = {
|
|
|
60202
60663
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
60203
60664
|
*/
|
|
60204
60665
|
history: { fields: {
|
|
60205
|
-
|
|
60666
|
+
speed: {
|
|
60206
60667
|
kind: "gauge",
|
|
60207
60668
|
unit: "%",
|
|
60208
60669
|
minIntervalMs: 0
|
|
@@ -60647,7 +61108,7 @@ var humidifierCapability = {
|
|
|
60647
61108
|
*/
|
|
60648
61109
|
var HumiditySensorStatusSchema = object({
|
|
60649
61110
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60650
|
-
|
|
61111
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60651
61112
|
precision: 0,
|
|
60652
61113
|
label: "Humidity"
|
|
60653
61114
|
})),
|
|
@@ -60676,7 +61137,7 @@ var humiditySensorCapability = {
|
|
|
60676
61137
|
/**
|
|
60677
61138
|
* History (D850): recorded series.
|
|
60678
61139
|
*/
|
|
60679
|
-
history: { fields: {
|
|
61140
|
+
history: { fields: { humidity: {
|
|
60680
61141
|
kind: "gauge",
|
|
60681
61142
|
unit: "%",
|
|
60682
61143
|
deadband: .5
|
|
@@ -61316,7 +61777,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61316
61777
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61317
61778
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61318
61779
|
* task is active / progress is unavailable. */
|
|
61319
|
-
|
|
61780
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61320
61781
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61321
61782
|
* or null when unknown. */
|
|
61322
61783
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -61816,7 +62277,7 @@ var lockControlCapability = {
|
|
|
61816
62277
|
volatileStateFields: ["lastChangedAt"]
|
|
61817
62278
|
};
|
|
61818
62279
|
/**
|
|
61819
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
62280
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
61820
62281
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
61821
62282
|
* `value` is the time integral in the source quantity's accumulated base
|
|
61822
62283
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -61910,10 +62371,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
61910
62371
|
currentMedia: MediaInfoSchema.nullable(),
|
|
61911
62372
|
/** Current playback position in ms. Null when not seekable or
|
|
61912
62373
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
61913
|
-
|
|
62374
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61914
62375
|
/** Total duration of the current media in ms. Null when unknown
|
|
61915
62376
|
* (live stream) or nothing is playing. */
|
|
61916
|
-
|
|
62377
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
61917
62378
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
61918
62379
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
61919
62380
|
shuffle: boolean().nullable(),
|
|
@@ -61952,7 +62413,7 @@ var mediaPlayerCapability = {
|
|
|
61952
62413
|
}),
|
|
61953
62414
|
seek: method(object({
|
|
61954
62415
|
deviceId: number().int().nonnegative(),
|
|
61955
|
-
|
|
62416
|
+
position: number().int().nonnegative()
|
|
61956
62417
|
}), _void(), {
|
|
61957
62418
|
kind: "mutation",
|
|
61958
62419
|
auth: "protected"
|
|
@@ -62024,7 +62485,7 @@ var mediaPlayerCapability = {
|
|
|
62024
62485
|
/**
|
|
62025
62486
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62026
62487
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62027
|
-
* `
|
|
62488
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62028
62489
|
*/
|
|
62029
62490
|
history: { fields: {
|
|
62030
62491
|
volumeLevel: {
|
|
@@ -62986,9 +63447,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
62986
63447
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
62987
63448
|
* SKIP a null rather than coerce it.
|
|
62988
63449
|
*/
|
|
62989
|
-
|
|
63450
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62990
63451
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
62991
|
-
|
|
63452
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
62992
63453
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
62993
63454
|
ssid: string().optional(),
|
|
62994
63455
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63024,7 +63485,7 @@ onStatusChanged: { data: object({
|
|
|
63024
63485
|
kind: "push",
|
|
63025
63486
|
empty: {
|
|
63026
63487
|
type: "unknown",
|
|
63027
|
-
|
|
63488
|
+
signal: null,
|
|
63028
63489
|
lastUpdated: 0
|
|
63029
63490
|
}
|
|
63030
63491
|
},
|
|
@@ -63047,13 +63508,13 @@ onStatusChanged: { data: object({
|
|
|
63047
63508
|
* History (D850): recorded series.
|
|
63048
63509
|
*/
|
|
63049
63510
|
history: { fields: {
|
|
63050
|
-
|
|
63511
|
+
signal: {
|
|
63051
63512
|
kind: "gauge",
|
|
63052
63513
|
unit: "%",
|
|
63053
63514
|
deadband: 3,
|
|
63054
63515
|
minIntervalMs: 6e4
|
|
63055
63516
|
},
|
|
63056
|
-
|
|
63517
|
+
rssi: {
|
|
63057
63518
|
kind: "gauge",
|
|
63058
63519
|
unit: "dBm",
|
|
63059
63520
|
deadband: 2,
|
|
@@ -63798,10 +64259,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
63798
64259
|
]);
|
|
63799
64260
|
var gramsPortion = number().int().min(4).max(200);
|
|
63800
64261
|
var PetFeederStatusSchema = object({
|
|
63801
|
-
/** Food
|
|
63802
|
-
*
|
|
63803
|
-
* bowl
|
|
64262
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
64263
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
64264
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
64265
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
64266
|
+
* the device has not reported yet. */
|
|
63804
64267
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64268
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
64269
|
+
* feeder's own units. Null when the model reports none. */
|
|
64270
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
64271
|
+
/** True while the pet is eating (`state.eating`). */
|
|
64272
|
+
eating: boolean(),
|
|
64273
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
64274
|
+
* the client must not offer it. */
|
|
64275
|
+
supportsMarkRefilled: boolean(),
|
|
63805
64276
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63806
64277
|
* single-hopper models. */
|
|
63807
64278
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -63809,8 +64280,8 @@ var PetFeederStatusSchema = object({
|
|
|
63809
64280
|
* single-hopper models. */
|
|
63810
64281
|
food2: number().nullable().meta(readingMeta("none")),
|
|
63811
64282
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63812
|
-
* (`device_class: problem`, on = low). True when the
|
|
63813
|
-
*
|
|
64283
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
64284
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
63814
64285
|
lowFood: boolean(),
|
|
63815
64286
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63816
64287
|
* device has no battery reading. */
|
|
@@ -63878,7 +64349,9 @@ var petFeederCapability = {
|
|
|
63878
64349
|
kind: "mutation",
|
|
63879
64350
|
auth: "protected"
|
|
63880
64351
|
}),
|
|
63881
|
-
/**
|
|
64352
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
64353
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
64354
|
+
* change any sensor reading. */
|
|
63882
64355
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
63883
64356
|
kind: "mutation",
|
|
63884
64357
|
auth: "protected"
|
|
@@ -63951,6 +64424,7 @@ var petFeederCapability = {
|
|
|
63951
64424
|
*/
|
|
63952
64425
|
history: { fields: {
|
|
63953
64426
|
foodLevel: { kind: "gauge" },
|
|
64427
|
+
bowlFood: { kind: "gauge" },
|
|
63954
64428
|
food1: { kind: "gauge" },
|
|
63955
64429
|
food2: { kind: "gauge" },
|
|
63956
64430
|
batteryPower: {
|
|
@@ -64360,16 +64834,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64360
64834
|
* in real-world devices.
|
|
64361
64835
|
*/
|
|
64362
64836
|
var PowerMeterStatusSchema = object({
|
|
64363
|
-
/** Instantaneous power draw
|
|
64364
|
-
|
|
64837
|
+
/** Instantaneous power draw (watts). */
|
|
64838
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64365
64839
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64366
|
-
|
|
64367
|
-
/** Voltage
|
|
64368
|
-
|
|
64840
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64841
|
+
/** Voltage (volts). */
|
|
64842
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64369
64843
|
/** Current in amperes. */
|
|
64370
|
-
|
|
64844
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64371
64845
|
/** Apparent power in volt-amperes. */
|
|
64372
|
-
|
|
64846
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
64373
64847
|
/** Power factor (0..1) if reported. */
|
|
64374
64848
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64375
64849
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64427,14 +64901,14 @@ function powerTarget(id, unit) {
|
|
|
64427
64901
|
advancedExpression: true
|
|
64428
64902
|
};
|
|
64429
64903
|
}
|
|
64430
|
-
/** "Power and energy" extension:
|
|
64904
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
64431
64905
|
var powerMeterCustomize = {
|
|
64432
64906
|
version: 1,
|
|
64433
64907
|
targets: [
|
|
64434
|
-
powerTarget("
|
|
64435
|
-
powerTarget("
|
|
64436
|
-
powerTarget("
|
|
64437
|
-
powerTarget("
|
|
64908
|
+
powerTarget("power", "W"),
|
|
64909
|
+
powerTarget("energy", "kWh"),
|
|
64910
|
+
powerTarget("voltage", "V"),
|
|
64911
|
+
powerTarget("current", "A")
|
|
64438
64912
|
]
|
|
64439
64913
|
};
|
|
64440
64914
|
var powerMeterCapability = {
|
|
@@ -64450,41 +64924,41 @@ var powerMeterCapability = {
|
|
|
64450
64924
|
},
|
|
64451
64925
|
runtimeState: PowerMeterStatusSchema,
|
|
64452
64926
|
/**
|
|
64453
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
64927
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
64454
64928
|
*
|
|
64455
64929
|
* See `RuntimeStateDurability`. Enforced by
|
|
64456
64930
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64457
64931
|
*/
|
|
64458
64932
|
durability: "restored",
|
|
64459
64933
|
/**
|
|
64460
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
64934
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
64461
64935
|
*/
|
|
64462
64936
|
history: { fields: {
|
|
64463
|
-
|
|
64937
|
+
power: {
|
|
64464
64938
|
kind: "gauge",
|
|
64465
64939
|
unit: "W",
|
|
64466
64940
|
deadband: 1,
|
|
64467
64941
|
minIntervalMs: 3e4
|
|
64468
64942
|
},
|
|
64469
|
-
|
|
64943
|
+
energy: {
|
|
64470
64944
|
kind: "counter",
|
|
64471
64945
|
unit: "kWh",
|
|
64472
64946
|
deadband: .01,
|
|
64473
64947
|
minIntervalMs: 6e4
|
|
64474
64948
|
},
|
|
64475
|
-
|
|
64949
|
+
voltage: {
|
|
64476
64950
|
kind: "gauge",
|
|
64477
64951
|
unit: "V",
|
|
64478
64952
|
deadband: 1,
|
|
64479
64953
|
minIntervalMs: 3e4
|
|
64480
64954
|
},
|
|
64481
|
-
|
|
64955
|
+
current: {
|
|
64482
64956
|
kind: "gauge",
|
|
64483
64957
|
unit: "A",
|
|
64484
64958
|
deadband: .05,
|
|
64485
64959
|
minIntervalMs: 3e4
|
|
64486
64960
|
},
|
|
64487
|
-
|
|
64961
|
+
apparentPower: {
|
|
64488
64962
|
kind: "gauge",
|
|
64489
64963
|
unit: "VA",
|
|
64490
64964
|
deadband: 1,
|
|
@@ -64534,9 +65008,6 @@ var PresenceStatusSchema = object({
|
|
|
64534
65008
|
location: string().nullable(),
|
|
64535
65009
|
/** GPS coordinates when available. Null otherwise. */
|
|
64536
65010
|
gps: GpsLocationSchema.nullable(),
|
|
64537
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
64538
|
-
* when not reported. */
|
|
64539
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64540
65011
|
/** Ms epoch when the slice was last updated. */
|
|
64541
65012
|
lastChangedAt: number()
|
|
64542
65013
|
});
|
|
@@ -64565,14 +65036,7 @@ var presenceCapability = {
|
|
|
64565
65036
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64566
65037
|
*/
|
|
64567
65038
|
durability: "restored",
|
|
64568
|
-
|
|
64569
|
-
* History (D850): recorded series.
|
|
64570
|
-
*/
|
|
64571
|
-
history: { fields: { batteryPercent: {
|
|
64572
|
-
kind: "gauge",
|
|
64573
|
-
unit: "%",
|
|
64574
|
-
deadband: 1
|
|
64575
|
-
} } },
|
|
65039
|
+
history: "none",
|
|
64576
65040
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64577
65041
|
* whether persisting is worth a SQLite commit. */
|
|
64578
65042
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -64587,7 +65051,7 @@ var presenceCapability = {
|
|
|
64587
65051
|
*/
|
|
64588
65052
|
var PressureSensorStatusSchema = object({
|
|
64589
65053
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64590
|
-
|
|
65054
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64591
65055
|
/** Ms epoch when the slice was last updated. */
|
|
64592
65056
|
lastFetchedAt: number()
|
|
64593
65057
|
});
|
|
@@ -64613,7 +65077,7 @@ var pressureSensorCapability = {
|
|
|
64613
65077
|
/**
|
|
64614
65078
|
* History (D850): recorded series.
|
|
64615
65079
|
*/
|
|
64616
|
-
history: { fields: {
|
|
65080
|
+
history: { fields: { pressure: {
|
|
64617
65081
|
kind: "gauge",
|
|
64618
65082
|
unit: "hPa",
|
|
64619
65083
|
deadband: .1
|
|
@@ -68312,7 +68776,7 @@ var tamperCapability = {
|
|
|
68312
68776
|
*/
|
|
68313
68777
|
var TemperatureSensorStatusSchema = object({
|
|
68314
68778
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68315
|
-
|
|
68779
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
68316
68780
|
precision: 1,
|
|
68317
68781
|
label: "Temperature"
|
|
68318
68782
|
})),
|
|
@@ -68341,7 +68805,7 @@ var temperatureSensorCapability = {
|
|
|
68341
68805
|
/**
|
|
68342
68806
|
* History (D850): recorded series.
|
|
68343
68807
|
*/
|
|
68344
|
-
history: { fields: {
|
|
68808
|
+
history: { fields: { temperature: {
|
|
68345
68809
|
kind: "gauge",
|
|
68346
68810
|
unit: "°C",
|
|
68347
68811
|
deadband: .1
|
|
@@ -68638,7 +69102,7 @@ var VacuumControlStatusSchema = object({
|
|
|
68638
69102
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68639
69103
|
availableFanSpeeds: array(string()),
|
|
68640
69104
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68641
|
-
|
|
69105
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68642
69106
|
/** Current error code (0 / null = no error). */
|
|
68643
69107
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68644
69108
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -70675,7 +71139,7 @@ var BaseDevice = class {
|
|
|
70675
71139
|
* `device-local-state.ts`. Drivers access via:
|
|
70676
71140
|
*
|
|
70677
71141
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
70678
|
-
* `const pct = this.state.battery.
|
|
71142
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
70679
71143
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
70680
71144
|
*
|
|
70681
71145
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -70715,7 +71179,7 @@ var BaseDevice = class {
|
|
|
70715
71179
|
* shape; drivers don't redeclare it, they just write through.
|
|
70716
71180
|
*
|
|
70717
71181
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
70718
|
-
* `{
|
|
71182
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
70719
71183
|
* provider that registers `batteryCapability`.
|
|
70720
71184
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
70721
71185
|
*
|
|
@@ -71889,6 +72353,104 @@ Object.freeze({
|
|
|
71889
72353
|
access: "create",
|
|
71890
72354
|
role: "admin"
|
|
71891
72355
|
},
|
|
72356
|
+
"actions.create": {
|
|
72357
|
+
capName: "actions",
|
|
72358
|
+
capScope: "system",
|
|
72359
|
+
addonId: null,
|
|
72360
|
+
access: "create",
|
|
72361
|
+
role: "admin"
|
|
72362
|
+
},
|
|
72363
|
+
"actions.delete": {
|
|
72364
|
+
capName: "actions",
|
|
72365
|
+
capScope: "system",
|
|
72366
|
+
addonId: null,
|
|
72367
|
+
access: "delete",
|
|
72368
|
+
role: "admin"
|
|
72369
|
+
},
|
|
72370
|
+
"actions.get": {
|
|
72371
|
+
capName: "actions",
|
|
72372
|
+
capScope: "system",
|
|
72373
|
+
addonId: null,
|
|
72374
|
+
access: "view",
|
|
72375
|
+
role: "viewer"
|
|
72376
|
+
},
|
|
72377
|
+
"actions.getLinks": {
|
|
72378
|
+
capName: "actions",
|
|
72379
|
+
capScope: "system",
|
|
72380
|
+
addonId: null,
|
|
72381
|
+
access: "view",
|
|
72382
|
+
role: "admin"
|
|
72383
|
+
},
|
|
72384
|
+
"actions.getTraces": {
|
|
72385
|
+
capName: "actions",
|
|
72386
|
+
capScope: "system",
|
|
72387
|
+
addonId: null,
|
|
72388
|
+
access: "view",
|
|
72389
|
+
role: "admin"
|
|
72390
|
+
},
|
|
72391
|
+
"actions.list": {
|
|
72392
|
+
capName: "actions",
|
|
72393
|
+
capScope: "system",
|
|
72394
|
+
addonId: null,
|
|
72395
|
+
access: "view",
|
|
72396
|
+
role: "admin"
|
|
72397
|
+
},
|
|
72398
|
+
"actions.listForCamera": {
|
|
72399
|
+
capName: "actions",
|
|
72400
|
+
capScope: "system",
|
|
72401
|
+
addonId: null,
|
|
72402
|
+
access: "view",
|
|
72403
|
+
role: "viewer"
|
|
72404
|
+
},
|
|
72405
|
+
"actions.run": {
|
|
72406
|
+
capName: "actions",
|
|
72407
|
+
capScope: "system",
|
|
72408
|
+
addonId: null,
|
|
72409
|
+
access: "create",
|
|
72410
|
+
role: "viewer"
|
|
72411
|
+
},
|
|
72412
|
+
"actions.setLinks": {
|
|
72413
|
+
capName: "actions",
|
|
72414
|
+
capScope: "system",
|
|
72415
|
+
addonId: null,
|
|
72416
|
+
access: "create",
|
|
72417
|
+
role: "admin"
|
|
72418
|
+
},
|
|
72419
|
+
"actions.stop": {
|
|
72420
|
+
capName: "actions",
|
|
72421
|
+
capScope: "system",
|
|
72422
|
+
addonId: null,
|
|
72423
|
+
access: "create",
|
|
72424
|
+
role: "admin"
|
|
72425
|
+
},
|
|
72426
|
+
"actions.update": {
|
|
72427
|
+
capName: "actions",
|
|
72428
|
+
capScope: "system",
|
|
72429
|
+
addonId: null,
|
|
72430
|
+
access: "create",
|
|
72431
|
+
role: "admin"
|
|
72432
|
+
},
|
|
72433
|
+
"actionSource.listActions": {
|
|
72434
|
+
capName: "action-source",
|
|
72435
|
+
capScope: "system",
|
|
72436
|
+
addonId: null,
|
|
72437
|
+
access: "view",
|
|
72438
|
+
role: "admin"
|
|
72439
|
+
},
|
|
72440
|
+
"actionSource.runAction": {
|
|
72441
|
+
capName: "action-source",
|
|
72442
|
+
capScope: "system",
|
|
72443
|
+
addonId: null,
|
|
72444
|
+
access: "create",
|
|
72445
|
+
role: "admin"
|
|
72446
|
+
},
|
|
72447
|
+
"actionSource.stopAction": {
|
|
72448
|
+
capName: "action-source",
|
|
72449
|
+
capScope: "system",
|
|
72450
|
+
addonId: null,
|
|
72451
|
+
access: "create",
|
|
72452
|
+
role: "admin"
|
|
72453
|
+
},
|
|
71892
72454
|
"addonPages.listPages": {
|
|
71893
72455
|
capName: "addon-pages",
|
|
71894
72456
|
capScope: "system",
|
|
@@ -73170,6 +73732,13 @@ Object.freeze({
|
|
|
73170
73732
|
access: "view",
|
|
73171
73733
|
role: "admin"
|
|
73172
73734
|
},
|
|
73735
|
+
"coreBlocks.getAutomationRunState": {
|
|
73736
|
+
capName: "core-blocks",
|
|
73737
|
+
capScope: "system",
|
|
73738
|
+
addonId: null,
|
|
73739
|
+
access: "view",
|
|
73740
|
+
role: "admin"
|
|
73741
|
+
},
|
|
73173
73742
|
"coreBlocks.getBlockSettings": {
|
|
73174
73743
|
capName: "core-blocks",
|
|
73175
73744
|
capScope: "system",
|
|
@@ -73191,6 +73760,13 @@ Object.freeze({
|
|
|
73191
73760
|
access: "view",
|
|
73192
73761
|
role: "admin"
|
|
73193
73762
|
},
|
|
73763
|
+
"coreBlocks.getTraces": {
|
|
73764
|
+
capName: "core-blocks",
|
|
73765
|
+
capScope: "system",
|
|
73766
|
+
addonId: null,
|
|
73767
|
+
access: "view",
|
|
73768
|
+
role: "admin"
|
|
73769
|
+
},
|
|
73194
73770
|
"coreBlocks.getTypeDefs": {
|
|
73195
73771
|
capName: "core-blocks",
|
|
73196
73772
|
capScope: "system",
|
|
@@ -73226,6 +73802,13 @@ Object.freeze({
|
|
|
73226
73802
|
access: "create",
|
|
73227
73803
|
role: "admin"
|
|
73228
73804
|
},
|
|
73805
|
+
"coreBlocks.reportAutomationRun": {
|
|
73806
|
+
capName: "core-blocks",
|
|
73807
|
+
capScope: "system",
|
|
73808
|
+
addonId: null,
|
|
73809
|
+
access: "create",
|
|
73810
|
+
role: "admin"
|
|
73811
|
+
},
|
|
73229
73812
|
"coreBlocks.restart": {
|
|
73230
73813
|
capName: "core-blocks",
|
|
73231
73814
|
capScope: "system",
|
|
@@ -81799,7 +82382,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81799
82382
|
label: t("Full brightness", "Luminosità massima"),
|
|
81800
82383
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
81801
82384
|
icon: "sun",
|
|
81802
|
-
args: {
|
|
82385
|
+
args: { level: 100 }
|
|
81803
82386
|
},
|
|
81804
82387
|
{
|
|
81805
82388
|
id: "brightness.half",
|
|
@@ -81807,7 +82390,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81807
82390
|
label: t("Half brightness", "Luminosità a metà"),
|
|
81808
82391
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
81809
82392
|
icon: "sun-dim",
|
|
81810
|
-
args: {
|
|
82393
|
+
args: { level: 50 }
|
|
81811
82394
|
},
|
|
81812
82395
|
{
|
|
81813
82396
|
id: "brightness.off",
|
|
@@ -81815,16 +82398,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81815
82398
|
label: t("Brightness off", "Luminosità a zero"),
|
|
81816
82399
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
81817
82400
|
icon: "lightbulb-off",
|
|
81818
|
-
args: {
|
|
82401
|
+
args: { level: 0 }
|
|
81819
82402
|
},
|
|
81820
82403
|
{
|
|
81821
82404
|
id: "brightness.set",
|
|
81822
82405
|
method: "setBrightness",
|
|
81823
82406
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
81824
|
-
phrase: t("Set the brightness of {device} to {
|
|
82407
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
81825
82408
|
icon: "sun-medium",
|
|
81826
82409
|
openArgs: [{
|
|
81827
|
-
key: "
|
|
82410
|
+
key: "level",
|
|
81828
82411
|
label: PERCENT,
|
|
81829
82412
|
offer: {
|
|
81830
82413
|
kind: "number",
|
|
@@ -81838,13 +82421,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81838
82421
|
],
|
|
81839
82422
|
state: [{
|
|
81840
82423
|
kind: "numeric",
|
|
81841
|
-
field: "
|
|
82424
|
+
field: "level",
|
|
81842
82425
|
quantity: t("the brightness", "la luminosità"),
|
|
81843
82426
|
label: t("Brightness", "Luminosità"),
|
|
81844
82427
|
unit: "%",
|
|
81845
82428
|
icon: "sun"
|
|
81846
82429
|
}],
|
|
81847
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
82430
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
81848
82431
|
},
|
|
81849
82432
|
color: {
|
|
81850
82433
|
scope: "device",
|
|
@@ -81858,7 +82441,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81858
82441
|
icon: "sun",
|
|
81859
82442
|
args: { color: {
|
|
81860
82443
|
mode: "mired",
|
|
81861
|
-
|
|
82444
|
+
colorTemperature: 370
|
|
81862
82445
|
} }
|
|
81863
82446
|
},
|
|
81864
82447
|
{
|
|
@@ -81869,7 +82452,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81869
82452
|
icon: "snowflake",
|
|
81870
82453
|
args: { color: {
|
|
81871
82454
|
mode: "mired",
|
|
81872
|
-
|
|
82455
|
+
colorTemperature: 200
|
|
81873
82456
|
} }
|
|
81874
82457
|
},
|
|
81875
82458
|
{
|
|
@@ -82483,7 +83066,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82483
83066
|
label: t("Fan off", "Ventilatore spento"),
|
|
82484
83067
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
82485
83068
|
icon: "power-off",
|
|
82486
|
-
args: {
|
|
83069
|
+
args: { speed: 0 }
|
|
82487
83070
|
},
|
|
82488
83071
|
{
|
|
82489
83072
|
id: "fan.full",
|
|
@@ -82491,16 +83074,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82491
83074
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
82492
83075
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
82493
83076
|
icon: "fan",
|
|
82494
|
-
args: {
|
|
83077
|
+
args: { speed: 100 }
|
|
82495
83078
|
},
|
|
82496
83079
|
{
|
|
82497
83080
|
id: "fan.speed",
|
|
82498
83081
|
method: "setPercentage",
|
|
82499
83082
|
label: t("Set speed", "Imposta la velocità"),
|
|
82500
|
-
phrase: t("Set the speed of {device} to {
|
|
83083
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
82501
83084
|
icon: "fan",
|
|
82502
83085
|
openArgs: [{
|
|
82503
|
-
key: "
|
|
83086
|
+
key: "speed",
|
|
82504
83087
|
label: t("Speed", "Velocità"),
|
|
82505
83088
|
offer: {
|
|
82506
83089
|
kind: "number",
|
|
@@ -82562,7 +83145,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82562
83145
|
],
|
|
82563
83146
|
state: [{
|
|
82564
83147
|
kind: "numeric",
|
|
82565
|
-
field: "
|
|
83148
|
+
field: "speed",
|
|
82566
83149
|
quantity: t("the speed", "la velocità"),
|
|
82567
83150
|
label: t("Speed", "Velocità"),
|
|
82568
83151
|
unit: "%",
|
|
@@ -83360,7 +83943,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83360
83943
|
},
|
|
83361
83944
|
{
|
|
83362
83945
|
kind: "numeric",
|
|
83363
|
-
field: "
|
|
83946
|
+
field: "progress",
|
|
83364
83947
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
83365
83948
|
label: t("Progress", "Avanzamento"),
|
|
83366
83949
|
unit: "%",
|
|
@@ -83718,10 +84301,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83718
84301
|
id: "media.seek",
|
|
83719
84302
|
method: "seek",
|
|
83720
84303
|
label: t("Seek", "Vai al punto"),
|
|
83721
|
-
phrase: t("Move {device} to {
|
|
84304
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
83722
84305
|
icon: "fast-forward",
|
|
83723
84306
|
openArgs: [{
|
|
83724
|
-
key: "
|
|
84307
|
+
key: "position",
|
|
83725
84308
|
label: t("Position", "Posizione"),
|
|
83726
84309
|
offer: {
|
|
83727
84310
|
kind: "number",
|
|
@@ -84770,7 +85353,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84770
85353
|
state: [
|
|
84771
85354
|
{
|
|
84772
85355
|
kind: "numeric",
|
|
84773
|
-
field: "
|
|
85356
|
+
field: "co2",
|
|
84774
85357
|
quantity: t("the CO₂", "la CO₂"),
|
|
84775
85358
|
label: t("CO₂", "CO₂"),
|
|
84776
85359
|
unit: "ppm",
|
|
@@ -84778,7 +85361,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84778
85361
|
},
|
|
84779
85362
|
{
|
|
84780
85363
|
kind: "numeric",
|
|
84781
|
-
field: "
|
|
85364
|
+
field: "voc",
|
|
84782
85365
|
quantity: t("the VOC level", "il livello di COV"),
|
|
84783
85366
|
label: t("VOC", "COV"),
|
|
84784
85367
|
unit: "ppb",
|
|
@@ -84814,7 +85397,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84814
85397
|
noun: t("Light level", "Luminosità ambiente"),
|
|
84815
85398
|
state: [{
|
|
84816
85399
|
kind: "numeric",
|
|
84817
|
-
field: "
|
|
85400
|
+
field: "illuminance",
|
|
84818
85401
|
quantity: t("the light level", "la luminosità"),
|
|
84819
85402
|
label: t("Illuminance", "Illuminamento"),
|
|
84820
85403
|
unit: "lx",
|
|
@@ -85017,7 +85600,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85017
85600
|
noun: t("Humidity", "Umidità"),
|
|
85018
85601
|
state: [{
|
|
85019
85602
|
kind: "numeric",
|
|
85020
|
-
field: "
|
|
85603
|
+
field: "humidity",
|
|
85021
85604
|
quantity: t("the humidity", "l’umidità"),
|
|
85022
85605
|
label: t("Humidity", "Umidità"),
|
|
85023
85606
|
unit: "%",
|
|
@@ -85065,7 +85648,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85065
85648
|
state: [
|
|
85066
85649
|
{
|
|
85067
85650
|
kind: "numeric",
|
|
85068
|
-
field: "
|
|
85651
|
+
field: "power",
|
|
85069
85652
|
quantity: t("the power draw", "il consumo"),
|
|
85070
85653
|
label: t("Power", "Potenza"),
|
|
85071
85654
|
unit: "W",
|
|
@@ -85073,7 +85656,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85073
85656
|
},
|
|
85074
85657
|
{
|
|
85075
85658
|
kind: "numeric",
|
|
85076
|
-
field: "
|
|
85659
|
+
field: "energy",
|
|
85077
85660
|
quantity: t("the energy used", "l’energia consumata"),
|
|
85078
85661
|
label: t("Energy", "Energia"),
|
|
85079
85662
|
unit: "kWh",
|
|
@@ -85081,7 +85664,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85081
85664
|
},
|
|
85082
85665
|
{
|
|
85083
85666
|
kind: "numeric",
|
|
85084
|
-
field: "
|
|
85667
|
+
field: "voltage",
|
|
85085
85668
|
quantity: t("the voltage", "la tensione"),
|
|
85086
85669
|
label: t("Voltage", "Tensione"),
|
|
85087
85670
|
unit: "V",
|
|
@@ -85089,7 +85672,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85089
85672
|
},
|
|
85090
85673
|
{
|
|
85091
85674
|
kind: "numeric",
|
|
85092
|
-
field: "
|
|
85675
|
+
field: "current",
|
|
85093
85676
|
quantity: t("the current", "la corrente"),
|
|
85094
85677
|
label: t("Current", "Corrente"),
|
|
85095
85678
|
unit: "A",
|
|
@@ -85106,13 +85689,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85106
85689
|
label: t("Where", "Posizione"),
|
|
85107
85690
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
85108
85691
|
icon: "map-pin"
|
|
85109
|
-
}, {
|
|
85110
|
-
kind: "numeric",
|
|
85111
|
-
field: "batteryPercent",
|
|
85112
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
85113
|
-
label: t("Battery", "Batteria"),
|
|
85114
|
-
unit: "%",
|
|
85115
|
-
icon: "battery"
|
|
85116
85692
|
}]
|
|
85117
85693
|
},
|
|
85118
85694
|
"pressure-sensor": {
|
|
@@ -85120,7 +85696,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85120
85696
|
noun: t("Pressure", "Pressione"),
|
|
85121
85697
|
state: [{
|
|
85122
85698
|
kind: "numeric",
|
|
85123
|
-
field: "
|
|
85699
|
+
field: "pressure",
|
|
85124
85700
|
quantity: t("the pressure", "la pressione"),
|
|
85125
85701
|
label: t("Pressure", "Pressione"),
|
|
85126
85702
|
unit: "hPa",
|
|
@@ -85156,7 +85732,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85156
85732
|
noun: t("Temperature", "Temperatura"),
|
|
85157
85733
|
state: [{
|
|
85158
85734
|
kind: "numeric",
|
|
85159
|
-
field: "
|
|
85735
|
+
field: "temperature",
|
|
85160
85736
|
quantity: t("the temperature", "la temperatura"),
|
|
85161
85737
|
label: t("Temperature", "Temperatura"),
|
|
85162
85738
|
unit: "°C",
|
|
@@ -85227,7 +85803,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85227
85803
|
state: [
|
|
85228
85804
|
{
|
|
85229
85805
|
kind: "numeric",
|
|
85230
|
-
field: "
|
|
85806
|
+
field: "level",
|
|
85231
85807
|
quantity: t("the battery level", "il livello della batteria"),
|
|
85232
85808
|
label: t("Battery", "Batteria"),
|
|
85233
85809
|
unit: "%",
|
|
@@ -85269,7 +85845,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85269
85845
|
icon: "battery-charging"
|
|
85270
85846
|
}
|
|
85271
85847
|
],
|
|
85272
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
85848
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
85273
85849
|
extraEvents: [{
|
|
85274
85850
|
category: EventCategory.DeviceAwake,
|
|
85275
85851
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -85287,7 +85863,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85287
85863
|
noun: t("Network link", "Collegamento di rete"),
|
|
85288
85864
|
state: [{
|
|
85289
85865
|
kind: "numeric",
|
|
85290
|
-
field: "
|
|
85866
|
+
field: "signal",
|
|
85291
85867
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
85292
85868
|
label: t("Signal", "Segnale"),
|
|
85293
85869
|
unit: "%",
|
|
@@ -85380,6 +85956,8 @@ var ML = "model and training machinery — no device action";
|
|
|
85380
85956
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
85381
85957
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
85382
85958
|
var SYSTEM_CAP_VOCABULARY = {
|
|
85959
|
+
"action-source": system(INTERNAL),
|
|
85960
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
85383
85961
|
"addon-pages": system(UI_PLUMBING),
|
|
85384
85962
|
"addon-pages-source": system(UI_PLUMBING),
|
|
85385
85963
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -85576,6 +86154,31 @@ Object.freeze({
|
|
|
85576
86154
|
form: "single",
|
|
85577
86155
|
optional: false
|
|
85578
86156
|
}],
|
|
86157
|
+
"actions.get": [{
|
|
86158
|
+
name: "deviceId",
|
|
86159
|
+
form: "single",
|
|
86160
|
+
optional: true
|
|
86161
|
+
}],
|
|
86162
|
+
"actions.getLinks": [{
|
|
86163
|
+
name: "deviceId",
|
|
86164
|
+
form: "single",
|
|
86165
|
+
optional: false
|
|
86166
|
+
}],
|
|
86167
|
+
"actions.listForCamera": [{
|
|
86168
|
+
name: "deviceId",
|
|
86169
|
+
form: "single",
|
|
86170
|
+
optional: false
|
|
86171
|
+
}],
|
|
86172
|
+
"actions.run": [{
|
|
86173
|
+
name: "deviceId",
|
|
86174
|
+
form: "single",
|
|
86175
|
+
optional: true
|
|
86176
|
+
}],
|
|
86177
|
+
"actions.setLinks": [{
|
|
86178
|
+
name: "deviceId",
|
|
86179
|
+
form: "single",
|
|
86180
|
+
optional: false
|
|
86181
|
+
}],
|
|
85579
86182
|
"addonSettings.getDeviceSettings": [{
|
|
85580
86183
|
name: "deviceId",
|
|
85581
86184
|
form: "single",
|
|
@@ -89700,6 +90303,7 @@ function ingestReading(input) {
|
|
|
89700
90303
|
value: converted
|
|
89701
90304
|
};
|
|
89702
90305
|
}
|
|
90306
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
89703
90307
|
var MB = 1024 * 1024;
|
|
89704
90308
|
1024 * MB, 3072 * MB;
|
|
89705
90309
|
//#endregion
|
|
@@ -89934,7 +90538,7 @@ var point = (quantity, ...sources) => ({
|
|
|
89934
90538
|
* What an Enpal box can show, by the dotted keys its InfluxDB and device page use (the
|
|
89935
90539
|
* names follow the Home Assistant component's key table). A device is offered only when the
|
|
89936
90540
|
* box reported at least one of its points, so a box without a heat pump has no heat-pump
|
|
89937
|
-
* devices. Lifetime energy rides `power-meter.
|
|
90541
|
+
* devices. Lifetime energy rides `power-meter.energy` where a power reading sits beside it
|
|
89938
90542
|
* and the `meter` cap where it does not (D944).
|
|
89939
90543
|
*/
|
|
89940
90544
|
var ENPAL_SPECS = [
|
|
@@ -89943,7 +90547,7 @@ var ENPAL_SPECS = [
|
|
|
89943
90547
|
id: "pv",
|
|
89944
90548
|
name: "Production",
|
|
89945
90549
|
role: DeviceRole.PowerSensor,
|
|
89946
|
-
|
|
90550
|
+
power: point("power", "Power.DC.Total", "Power.DC.Total.Calculated", "Power.DC.Total.Huawei", "Power.Production.Total"),
|
|
89947
90551
|
kwh: point("energy", "Energy.Production.Total.Lifetime")
|
|
89948
90552
|
},
|
|
89949
90553
|
{
|
|
@@ -89953,9 +90557,9 @@ var ENPAL_SPECS = [
|
|
|
89953
90557
|
role: DeviceRole.BatterySensor,
|
|
89954
90558
|
level: point("percentage", "Energy.Battery.Charge.Level"),
|
|
89955
90559
|
capacity: point("energy", "Energy.Battery.Capacity"),
|
|
89956
|
-
|
|
89957
|
-
|
|
89958
|
-
|
|
90560
|
+
power: point("power", "Power.Battery.Charge.Discharge"),
|
|
90561
|
+
voltage: point("voltage", "Voltage.Battery"),
|
|
90562
|
+
current: point("current", "Current.Battery")
|
|
89959
90563
|
},
|
|
89960
90564
|
{
|
|
89961
90565
|
kind: "meter",
|
|
@@ -89978,7 +90582,7 @@ var ENPAL_SPECS = [
|
|
|
89978
90582
|
id: "grid-import",
|
|
89979
90583
|
name: "Import",
|
|
89980
90584
|
role: DeviceRole.PowerSensor,
|
|
89981
|
-
|
|
90585
|
+
power: point("power", "Grid.Import.Power.Total.Calculated", {
|
|
89982
90586
|
key: "Power.Grid.Export",
|
|
89983
90587
|
part: "negative"
|
|
89984
90588
|
}, {
|
|
@@ -89995,7 +90599,7 @@ var ENPAL_SPECS = [
|
|
|
89995
90599
|
id: "grid-export",
|
|
89996
90600
|
name: "Export",
|
|
89997
90601
|
role: DeviceRole.PowerSensor,
|
|
89998
|
-
|
|
90602
|
+
power: point("power", {
|
|
89999
90603
|
key: "Power.Grid.Export",
|
|
90000
90604
|
part: "positive"
|
|
90001
90605
|
}, {
|
|
@@ -90012,7 +90616,7 @@ var ENPAL_SPECS = [
|
|
|
90012
90616
|
id: "house",
|
|
90013
90617
|
name: "Consumption",
|
|
90014
90618
|
role: DeviceRole.PowerSensor,
|
|
90015
|
-
|
|
90619
|
+
power: point("power", "Power.Consumption.Total", "Power.Consumption.AC"),
|
|
90016
90620
|
kwh: point("energy", "Energy.Consumption.Total.Lifetime")
|
|
90017
90621
|
},
|
|
90018
90622
|
{
|
|
@@ -90020,7 +90624,7 @@ var ENPAL_SPECS = [
|
|
|
90020
90624
|
id: "heatpump",
|
|
90021
90625
|
name: "Consumption",
|
|
90022
90626
|
role: DeviceRole.PowerSensor,
|
|
90023
|
-
|
|
90627
|
+
power: point("power", "Heatpump.Power.Consumption.Total"),
|
|
90024
90628
|
kwh: point("energy", "Heatpump.Energy.Consumption.Total.Lifetime")
|
|
90025
90629
|
},
|
|
90026
90630
|
{
|
|
@@ -90078,12 +90682,12 @@ function capsOfSpec(spec) {
|
|
|
90078
90682
|
}
|
|
90079
90683
|
function pointsOf(spec) {
|
|
90080
90684
|
switch (spec.kind) {
|
|
90081
|
-
case "power-meter": return spec.kwh !== void 0 ? [spec.
|
|
90685
|
+
case "power-meter": return spec.kwh !== void 0 ? [spec.power, spec.kwh] : [spec.power];
|
|
90082
90686
|
case "battery": return [
|
|
90083
90687
|
spec.level,
|
|
90084
|
-
spec.
|
|
90085
|
-
spec.
|
|
90086
|
-
spec.
|
|
90688
|
+
spec.power,
|
|
90689
|
+
spec.voltage,
|
|
90690
|
+
spec.current
|
|
90087
90691
|
];
|
|
90088
90692
|
case "meter":
|
|
90089
90693
|
case "numeric": return [spec.value];
|
|
@@ -90149,46 +90753,46 @@ function stateOfCharge(spec, snapshot) {
|
|
|
90149
90753
|
function computeSlices(spec, snapshot, options, now) {
|
|
90150
90754
|
switch (spec.kind) {
|
|
90151
90755
|
case "power-meter": {
|
|
90152
|
-
const
|
|
90756
|
+
const power = resolve(spec.power, snapshot);
|
|
90153
90757
|
const kwh = spec.kwh !== void 0 ? resolve(spec.kwh, snapshot) : { state: "absent" };
|
|
90154
|
-
const w = numberOf(
|
|
90758
|
+
const w = numberOf(power);
|
|
90155
90759
|
const e = numberOf(kwh);
|
|
90156
90760
|
return {
|
|
90157
90761
|
...w !== void 0 || e !== void 0 ? { powerMeter: {
|
|
90158
|
-
...w !== void 0 ? {
|
|
90159
|
-
...e !== void 0 ? {
|
|
90762
|
+
...w !== void 0 ? { power: w } : {},
|
|
90763
|
+
...e !== void 0 ? { energy: e } : {},
|
|
90160
90764
|
lastFetchedAt: now
|
|
90161
90765
|
} } : {},
|
|
90162
|
-
refusals: [...refusalOf(
|
|
90766
|
+
refusals: [...refusalOf(power), ...refusalOf(kwh)]
|
|
90163
90767
|
};
|
|
90164
90768
|
}
|
|
90165
90769
|
case "battery": {
|
|
90166
90770
|
const soc = stateOfCharge(spec, snapshot);
|
|
90167
|
-
const
|
|
90168
|
-
const
|
|
90169
|
-
const
|
|
90771
|
+
const power = resolve(spec.power, snapshot);
|
|
90772
|
+
const voltage = resolve(spec.voltage, snapshot);
|
|
90773
|
+
const current = resolve(spec.current, snapshot);
|
|
90170
90774
|
const sign = options.invertBatteryPower ? -1 : 1;
|
|
90171
|
-
const w = numberOf(
|
|
90172
|
-
const v = numberOf(
|
|
90173
|
-
const a = numberOf(
|
|
90775
|
+
const w = numberOf(power);
|
|
90776
|
+
const v = numberOf(voltage);
|
|
90777
|
+
const a = numberOf(current);
|
|
90174
90778
|
return {
|
|
90175
90779
|
battery: {
|
|
90176
|
-
|
|
90780
|
+
level: nullableOf(soc),
|
|
90177
90781
|
charging: "unknown",
|
|
90178
90782
|
sleeping: false,
|
|
90179
90783
|
lastUpdated: now
|
|
90180
90784
|
},
|
|
90181
90785
|
...w !== void 0 || v !== void 0 || a !== void 0 ? { powerMeter: {
|
|
90182
|
-
...w !== void 0 ? {
|
|
90183
|
-
...v !== void 0 ? {
|
|
90184
|
-
...a !== void 0 ? {
|
|
90786
|
+
...w !== void 0 ? { power: w * sign || 0 } : {},
|
|
90787
|
+
...v !== void 0 ? { voltage: v } : {},
|
|
90788
|
+
...a !== void 0 ? { current: a * sign || 0 } : {},
|
|
90185
90789
|
lastFetchedAt: now
|
|
90186
90790
|
} } : {},
|
|
90187
90791
|
refusals: [
|
|
90188
90792
|
...refusalOf(soc),
|
|
90189
|
-
...refusalOf(
|
|
90190
|
-
...refusalOf(
|
|
90191
|
-
...refusalOf(
|
|
90793
|
+
...refusalOf(power),
|
|
90794
|
+
...refusalOf(voltage),
|
|
90795
|
+
...refusalOf(current)
|
|
90192
90796
|
]
|
|
90193
90797
|
};
|
|
90194
90798
|
}
|
|
@@ -90311,7 +90915,7 @@ var METER_CAP = meterCapability.name;
|
|
|
90311
90915
|
var NUMERIC_CAP = numericSensorCapability.name;
|
|
90312
90916
|
var POWER_COLD = { lastFetchedAt: 0 };
|
|
90313
90917
|
var BATTERY_COLD = {
|
|
90314
|
-
|
|
90918
|
+
level: null,
|
|
90315
90919
|
charging: "unknown",
|
|
90316
90920
|
sleeping: false,
|
|
90317
90921
|
lastUpdated: 0
|
|
@@ -90400,10 +91004,10 @@ var EnpalSensorDevice = class extends BaseDevice {
|
|
|
90400
91004
|
}
|
|
90401
91005
|
publish(slices) {
|
|
90402
91006
|
if (slices.powerMeter !== void 0) {
|
|
90403
|
-
const kwh = slices.powerMeter.
|
|
91007
|
+
const kwh = slices.powerMeter.energy;
|
|
90404
91008
|
this.runtimeState.setCapState(POWER_CAP, kwh === void 0 ? slices.powerMeter : {
|
|
90405
91009
|
...slices.powerMeter,
|
|
90406
|
-
|
|
91010
|
+
energy: this.energyGuard.accept(kwh)
|
|
90407
91011
|
});
|
|
90408
91012
|
}
|
|
90409
91013
|
if (slices.battery !== void 0) this.runtimeState.setCapState(BATTERY_CAP, slices.battery);
|