@camstack/addon-provider-ecowitt 0.2.149 → 0.2.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/addon.js +860 -256
- package/dist/addon.mjs +860 -256
- package/package.json +1 -1
package/dist/addon.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createServer } from "http";
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
3
|
import { createSocket } from "dgram";
|
|
4
|
-
//#region ../types/dist/event-category-
|
|
4
|
+
//#region ../types/dist/event-category-DmZDPDf_.mjs
|
|
5
5
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
6
6
|
EventCategory["SystemBoot"] = "system.boot";
|
|
7
7
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -628,7 +628,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
628
628
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
629
629
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
630
630
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
631
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
631
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
632
632
|
*/
|
|
633
633
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
634
634
|
/**
|
|
@@ -766,6 +766,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
766
766
|
*/
|
|
767
767
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
768
768
|
/**
|
|
769
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
770
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
771
|
+
*/
|
|
772
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
773
|
+
/**
|
|
769
774
|
* Progress update from a running model conversion job.
|
|
770
775
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
771
776
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -5444,7 +5449,7 @@ var ZodIssueCode$1 = {
|
|
|
5444
5449
|
var ZodFirstPartyTypeKind$1;
|
|
5445
5450
|
ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
|
|
5446
5451
|
//#endregion
|
|
5447
|
-
//#region ../types/dist/sleep
|
|
5452
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
5448
5453
|
/**
|
|
5449
5454
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5450
5455
|
* window to float samples (D455).
|
|
@@ -8564,6 +8569,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8564
8569
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8565
8570
|
var CAP_NAMES = Object.freeze([
|
|
8566
8571
|
"accessories",
|
|
8572
|
+
"action-source",
|
|
8573
|
+
"actions",
|
|
8567
8574
|
"addon-pages",
|
|
8568
8575
|
"addon-pages-source",
|
|
8569
8576
|
"addon-routes",
|
|
@@ -8752,11 +8759,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
8752
8759
|
Object.freeze({
|
|
8753
8760
|
"air-quality-sensor": [
|
|
8754
8761
|
{
|
|
8755
|
-
"path": "
|
|
8762
|
+
"path": "co2",
|
|
8756
8763
|
"valueType": "number"
|
|
8757
8764
|
},
|
|
8758
8765
|
{
|
|
8759
|
-
"path": "
|
|
8766
|
+
"path": "voc",
|
|
8760
8767
|
"valueType": "number"
|
|
8761
8768
|
},
|
|
8762
8769
|
{
|
|
@@ -8806,7 +8813,7 @@ Object.freeze({
|
|
|
8806
8813
|
}
|
|
8807
8814
|
],
|
|
8808
8815
|
"ambient-light-sensor": [{
|
|
8809
|
-
"path": "
|
|
8816
|
+
"path": "illuminance",
|
|
8810
8817
|
"valueType": "number"
|
|
8811
8818
|
}],
|
|
8812
8819
|
"audio-metrics": [
|
|
@@ -8867,7 +8874,7 @@ Object.freeze({
|
|
|
8867
8874
|
],
|
|
8868
8875
|
"battery": [
|
|
8869
8876
|
{
|
|
8870
|
-
"path": "
|
|
8877
|
+
"path": "level",
|
|
8871
8878
|
"valueType": "number"
|
|
8872
8879
|
},
|
|
8873
8880
|
{
|
|
@@ -8889,7 +8896,7 @@ Object.freeze({
|
|
|
8889
8896
|
"valueType": "number"
|
|
8890
8897
|
},
|
|
8891
8898
|
{
|
|
8892
|
-
"path": "
|
|
8899
|
+
"path": "voltage",
|
|
8893
8900
|
"valueType": "number"
|
|
8894
8901
|
},
|
|
8895
8902
|
{
|
|
@@ -8910,7 +8917,7 @@ Object.freeze({
|
|
|
8910
8917
|
"valueType": "boolean"
|
|
8911
8918
|
}],
|
|
8912
8919
|
"brightness": [{
|
|
8913
|
-
"path": "
|
|
8920
|
+
"path": "level",
|
|
8914
8921
|
"valueType": "number"
|
|
8915
8922
|
}],
|
|
8916
8923
|
"broker": [{
|
|
@@ -9111,7 +9118,7 @@ Object.freeze({
|
|
|
9111
9118
|
"valueType": "number"
|
|
9112
9119
|
},
|
|
9113
9120
|
{
|
|
9114
|
-
"path": "
|
|
9121
|
+
"path": "colorTemperature",
|
|
9115
9122
|
"valueType": "number"
|
|
9116
9123
|
}
|
|
9117
9124
|
],
|
|
@@ -9290,15 +9297,15 @@ Object.freeze({
|
|
|
9290
9297
|
"valueType": "string"
|
|
9291
9298
|
},
|
|
9292
9299
|
{
|
|
9293
|
-
"path": "
|
|
9300
|
+
"path": "remaining",
|
|
9294
9301
|
"valueType": "number"
|
|
9295
9302
|
},
|
|
9296
9303
|
{
|
|
9297
|
-
"path": "
|
|
9304
|
+
"path": "delayedStart",
|
|
9298
9305
|
"valueType": "number"
|
|
9299
9306
|
},
|
|
9300
9307
|
{
|
|
9301
|
-
"path": "
|
|
9308
|
+
"path": "progress",
|
|
9302
9309
|
"valueType": "number"
|
|
9303
9310
|
},
|
|
9304
9311
|
{
|
|
@@ -9412,7 +9419,7 @@ Object.freeze({
|
|
|
9412
9419
|
],
|
|
9413
9420
|
"fan-control": [
|
|
9414
9421
|
{
|
|
9415
|
-
"path": "
|
|
9422
|
+
"path": "speed",
|
|
9416
9423
|
"valueType": "number"
|
|
9417
9424
|
},
|
|
9418
9425
|
{
|
|
@@ -9512,7 +9519,7 @@ Object.freeze({
|
|
|
9512
9519
|
}
|
|
9513
9520
|
],
|
|
9514
9521
|
"humidity-sensor": [{
|
|
9515
|
-
"path": "
|
|
9522
|
+
"path": "humidity",
|
|
9516
9523
|
"valueType": "number"
|
|
9517
9524
|
}],
|
|
9518
9525
|
"image": [{
|
|
@@ -9622,7 +9629,7 @@ Object.freeze({
|
|
|
9622
9629
|
"valueType": "number"
|
|
9623
9630
|
},
|
|
9624
9631
|
{
|
|
9625
|
-
"path": "
|
|
9632
|
+
"path": "progress",
|
|
9626
9633
|
"valueType": "number"
|
|
9627
9634
|
},
|
|
9628
9635
|
{
|
|
@@ -9701,11 +9708,11 @@ Object.freeze({
|
|
|
9701
9708
|
"valueType": "string"
|
|
9702
9709
|
},
|
|
9703
9710
|
{
|
|
9704
|
-
"path": "
|
|
9711
|
+
"path": "position",
|
|
9705
9712
|
"valueType": "number"
|
|
9706
9713
|
},
|
|
9707
9714
|
{
|
|
9708
|
-
"path": "
|
|
9715
|
+
"path": "duration",
|
|
9709
9716
|
"valueType": "number"
|
|
9710
9717
|
},
|
|
9711
9718
|
{
|
|
@@ -9807,11 +9814,11 @@ Object.freeze({
|
|
|
9807
9814
|
]
|
|
9808
9815
|
},
|
|
9809
9816
|
{
|
|
9810
|
-
"path": "
|
|
9817
|
+
"path": "signal",
|
|
9811
9818
|
"valueType": "number"
|
|
9812
9819
|
},
|
|
9813
9820
|
{
|
|
9814
|
-
"path": "
|
|
9821
|
+
"path": "rssi",
|
|
9815
9822
|
"valueType": "number"
|
|
9816
9823
|
},
|
|
9817
9824
|
{
|
|
@@ -9866,6 +9873,18 @@ Object.freeze({
|
|
|
9866
9873
|
"path": "foodLevel",
|
|
9867
9874
|
"valueType": "number"
|
|
9868
9875
|
},
|
|
9876
|
+
{
|
|
9877
|
+
"path": "bowlFood",
|
|
9878
|
+
"valueType": "number"
|
|
9879
|
+
},
|
|
9880
|
+
{
|
|
9881
|
+
"path": "eating",
|
|
9882
|
+
"valueType": "boolean"
|
|
9883
|
+
},
|
|
9884
|
+
{
|
|
9885
|
+
"path": "supportsMarkRefilled",
|
|
9886
|
+
"valueType": "boolean"
|
|
9887
|
+
},
|
|
9869
9888
|
{
|
|
9870
9889
|
"path": "food1",
|
|
9871
9890
|
"valueType": "number"
|
|
@@ -9930,23 +9949,23 @@ Object.freeze({
|
|
|
9930
9949
|
],
|
|
9931
9950
|
"power-meter": [
|
|
9932
9951
|
{
|
|
9933
|
-
"path": "
|
|
9952
|
+
"path": "power",
|
|
9934
9953
|
"valueType": "number"
|
|
9935
9954
|
},
|
|
9936
9955
|
{
|
|
9937
|
-
"path": "
|
|
9956
|
+
"path": "energy",
|
|
9938
9957
|
"valueType": "number"
|
|
9939
9958
|
},
|
|
9940
9959
|
{
|
|
9941
|
-
"path": "
|
|
9960
|
+
"path": "voltage",
|
|
9942
9961
|
"valueType": "number"
|
|
9943
9962
|
},
|
|
9944
9963
|
{
|
|
9945
|
-
"path": "
|
|
9964
|
+
"path": "current",
|
|
9946
9965
|
"valueType": "number"
|
|
9947
9966
|
},
|
|
9948
9967
|
{
|
|
9949
|
-
"path": "
|
|
9968
|
+
"path": "apparentPower",
|
|
9950
9969
|
"valueType": "number"
|
|
9951
9970
|
},
|
|
9952
9971
|
{
|
|
@@ -9974,14 +9993,10 @@ Object.freeze({
|
|
|
9974
9993
|
{
|
|
9975
9994
|
"path": "gps.accuracyMeters",
|
|
9976
9995
|
"valueType": "number"
|
|
9977
|
-
},
|
|
9978
|
-
{
|
|
9979
|
-
"path": "batteryPercent",
|
|
9980
|
-
"valueType": "number"
|
|
9981
9996
|
}
|
|
9982
9997
|
],
|
|
9983
9998
|
"pressure-sensor": [{
|
|
9984
|
-
"path": "
|
|
9999
|
+
"path": "pressure",
|
|
9985
10000
|
"valueType": "number"
|
|
9986
10001
|
}],
|
|
9987
10002
|
"privacy-mask": [{
|
|
@@ -10295,7 +10310,7 @@ Object.freeze({
|
|
|
10295
10310
|
"valueType": "boolean"
|
|
10296
10311
|
}],
|
|
10297
10312
|
"temperature-sensor": [{
|
|
10298
|
-
"path": "
|
|
10313
|
+
"path": "temperature",
|
|
10299
10314
|
"valueType": "number"
|
|
10300
10315
|
}],
|
|
10301
10316
|
"update": [
|
|
@@ -10343,7 +10358,7 @@ Object.freeze({
|
|
|
10343
10358
|
"valueType": "string"
|
|
10344
10359
|
},
|
|
10345
10360
|
{
|
|
10346
|
-
"path": "
|
|
10361
|
+
"path": "progress",
|
|
10347
10362
|
"valueType": "number"
|
|
10348
10363
|
},
|
|
10349
10364
|
{
|
|
@@ -10842,7 +10857,7 @@ function errMsg(err) {
|
|
|
10842
10857
|
return String(err);
|
|
10843
10858
|
}
|
|
10844
10859
|
//#endregion
|
|
10845
|
-
//#region ../types/dist/composition-
|
|
10860
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
10846
10861
|
/**
|
|
10847
10862
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10848
10863
|
*
|
|
@@ -15362,6 +15377,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
15362
15377
|
array(union([string(), number()]))
|
|
15363
15378
|
])
|
|
15364
15379
|
});
|
|
15380
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
15381
|
+
kind: literal("stationary-present"),
|
|
15382
|
+
deviceId: number().int().nonnegative(),
|
|
15383
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
15384
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15385
|
+
/** The parked object must be in at least one of these zones. */
|
|
15386
|
+
zones: array(string().min(1)).min(1).optional()
|
|
15387
|
+
});
|
|
15365
15388
|
/**
|
|
15366
15389
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
15367
15390
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -15395,7 +15418,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
15395
15418
|
child: AutomationConditionSchema
|
|
15396
15419
|
}),
|
|
15397
15420
|
AutomationConditionLeafSchema,
|
|
15398
|
-
AutomationConditionExpressionSchema
|
|
15421
|
+
AutomationConditionExpressionSchema,
|
|
15422
|
+
AutomationConditionStationaryPresentSchema
|
|
15399
15423
|
]));
|
|
15400
15424
|
/**
|
|
15401
15425
|
* What starts a run.
|
|
@@ -15436,7 +15460,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15436
15460
|
kind: literal("schedule"),
|
|
15437
15461
|
cron: string().min(1).max(120)
|
|
15438
15462
|
}),
|
|
15439
|
-
object({ kind: literal("manual") })
|
|
15463
|
+
object({ kind: literal("manual") }),
|
|
15464
|
+
object({
|
|
15465
|
+
kind: literal("detection"),
|
|
15466
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
15467
|
+
* matches every raw class that maps to it; any other name matches
|
|
15468
|
+
* exactly. */
|
|
15469
|
+
classes: array(string().min(1)).min(1),
|
|
15470
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15471
|
+
/** The track must have visited at least one of these zones. */
|
|
15472
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15473
|
+
/** Best-so-far confidence the track must reach. */
|
|
15474
|
+
minScore: number().min(0).max(1).optional()
|
|
15475
|
+
}),
|
|
15476
|
+
object({
|
|
15477
|
+
kind: literal("stationary"),
|
|
15478
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15479
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
15480
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15481
|
+
/** The parked object must be in at least one of these zones. */
|
|
15482
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15483
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
15484
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
15485
|
+
phase: _enum(["appeared", "departed"])
|
|
15486
|
+
}),
|
|
15487
|
+
object({
|
|
15488
|
+
kind: literal("interval"),
|
|
15489
|
+
minutes: number().int().min(1).max(1440)
|
|
15490
|
+
})
|
|
15440
15491
|
]);
|
|
15441
15492
|
/**
|
|
15442
15493
|
* One action step.
|
|
@@ -15456,28 +15507,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15456
15507
|
* is called. The runner still receives a number and is untouched; the
|
|
15457
15508
|
* resolution is the recipe's job, not the runner's.
|
|
15458
15509
|
*/
|
|
15510
|
+
var AutomationWaitStepSchema = object({
|
|
15511
|
+
kind: literal("wait"),
|
|
15512
|
+
seconds: number().min(0).max(300)
|
|
15513
|
+
});
|
|
15514
|
+
var AutomationCapStepSchema = object({
|
|
15515
|
+
kind: literal("cap"),
|
|
15516
|
+
/**
|
|
15517
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
15518
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
15519
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
15520
|
+
*/
|
|
15521
|
+
deviceId: union([
|
|
15522
|
+
number().int(),
|
|
15523
|
+
array(number().int()).min(1),
|
|
15524
|
+
object({ $var: string().min(1) })
|
|
15525
|
+
]),
|
|
15526
|
+
cap: string().min(1),
|
|
15527
|
+
method: string().min(1),
|
|
15528
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
15529
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
15530
|
+
* the expression leaf. */
|
|
15531
|
+
args: record(string(), unknown()).optional()
|
|
15532
|
+
});
|
|
15533
|
+
/**
|
|
15534
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
15535
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
15536
|
+
*/
|
|
15537
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
15459
15538
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
15539
|
+
AutomationWaitStepSchema,
|
|
15540
|
+
AutomationCapStepSchema,
|
|
15460
15541
|
object({
|
|
15461
|
-
kind: literal("
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
|
|
15469
|
-
|
|
15470
|
-
*/
|
|
15471
|
-
deviceId: union([
|
|
15472
|
-
number().int(),
|
|
15473
|
-
array(number().int()).min(1),
|
|
15474
|
-
object({ $var: string().min(1) })
|
|
15475
|
-
]),
|
|
15476
|
-
cap: string().min(1),
|
|
15477
|
-
method: string().min(1),
|
|
15478
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
15479
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
15480
|
-
args: record(string(), unknown()).optional()
|
|
15542
|
+
kind: literal("action"),
|
|
15543
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
15544
|
+
actionId: string().min(1),
|
|
15545
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
15546
|
+
variables: record(string(), union([
|
|
15547
|
+
string(),
|
|
15548
|
+
number(),
|
|
15549
|
+
boolean()
|
|
15550
|
+
])).optional()
|
|
15481
15551
|
}),
|
|
15482
15552
|
object({
|
|
15483
15553
|
kind: literal("code"),
|
|
@@ -15486,10 +15556,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
15486
15556
|
code: string().min(1).max(2e4)
|
|
15487
15557
|
})
|
|
15488
15558
|
]);
|
|
15559
|
+
/**
|
|
15560
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
15561
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
15562
|
+
* actions. Absent means `single`.
|
|
15563
|
+
*
|
|
15564
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
15565
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
15566
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
15567
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
15568
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
15569
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
15570
|
+
* wait, never the single/queued limits.
|
|
15571
|
+
*/
|
|
15572
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
15573
|
+
object({ mode: literal("single") }),
|
|
15574
|
+
object({ mode: literal("restart") }),
|
|
15575
|
+
object({
|
|
15576
|
+
mode: literal("queued"),
|
|
15577
|
+
max: number().int().min(1).max(10)
|
|
15578
|
+
}),
|
|
15579
|
+
object({
|
|
15580
|
+
mode: literal("parallel"),
|
|
15581
|
+
max: number().int().min(1).max(10)
|
|
15582
|
+
}),
|
|
15583
|
+
object({
|
|
15584
|
+
mode: literal("cooldown"),
|
|
15585
|
+
minutes: number().int().min(1).max(1440)
|
|
15586
|
+
})
|
|
15587
|
+
]);
|
|
15489
15588
|
var AutomationRecipeSchema = object({
|
|
15490
15589
|
triggers: array(AutomationTriggerSchema),
|
|
15491
15590
|
conditions: AutomationConditionSchema.optional(),
|
|
15492
|
-
actions: array(AutomationActionSchema)
|
|
15591
|
+
actions: array(AutomationActionSchema),
|
|
15592
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
15593
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
15594
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
15595
|
+
});
|
|
15596
|
+
new Set([
|
|
15597
|
+
{
|
|
15598
|
+
id: "person",
|
|
15599
|
+
name: "Person"
|
|
15600
|
+
},
|
|
15601
|
+
{
|
|
15602
|
+
id: "vehicle",
|
|
15603
|
+
name: "Vehicle"
|
|
15604
|
+
},
|
|
15605
|
+
{
|
|
15606
|
+
id: "animal",
|
|
15607
|
+
name: "Animal"
|
|
15608
|
+
},
|
|
15609
|
+
{
|
|
15610
|
+
id: "package",
|
|
15611
|
+
name: "Package"
|
|
15612
|
+
}
|
|
15613
|
+
].map((l) => l.id));
|
|
15614
|
+
var COCO_TO_MACRO = {
|
|
15615
|
+
mapping: {
|
|
15616
|
+
person: "person",
|
|
15617
|
+
bicycle: "vehicle",
|
|
15618
|
+
car: "vehicle",
|
|
15619
|
+
motorcycle: "vehicle",
|
|
15620
|
+
airplane: "vehicle",
|
|
15621
|
+
bus: "vehicle",
|
|
15622
|
+
train: "vehicle",
|
|
15623
|
+
truck: "vehicle",
|
|
15624
|
+
boat: "vehicle",
|
|
15625
|
+
bird: "animal",
|
|
15626
|
+
cat: "animal",
|
|
15627
|
+
dog: "animal",
|
|
15628
|
+
horse: "animal",
|
|
15629
|
+
sheep: "animal",
|
|
15630
|
+
cow: "animal",
|
|
15631
|
+
elephant: "animal",
|
|
15632
|
+
bear: "animal",
|
|
15633
|
+
zebra: "animal",
|
|
15634
|
+
giraffe: "animal",
|
|
15635
|
+
suitcase: "package",
|
|
15636
|
+
backpack: "package",
|
|
15637
|
+
handbag: "package"
|
|
15638
|
+
},
|
|
15639
|
+
preserveOriginal: false
|
|
15640
|
+
};
|
|
15641
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
15642
|
+
/**
|
|
15643
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
15644
|
+
* so the editor can paint every block green or red with its reason.
|
|
15645
|
+
*
|
|
15646
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
15647
|
+
* every condition node (containers and leaves, including the ones a
|
|
15648
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
15649
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
15650
|
+
* for an Action run). Skipped
|
|
15651
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
15652
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
15653
|
+
*
|
|
15654
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
15655
|
+
* vocabulary so an Action run records the same step shape.
|
|
15656
|
+
*/
|
|
15657
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
15658
|
+
var TraceValueSchema = union([
|
|
15659
|
+
string(),
|
|
15660
|
+
number(),
|
|
15661
|
+
boolean(),
|
|
15662
|
+
_null(),
|
|
15663
|
+
array(union([string(), number()]))
|
|
15664
|
+
]);
|
|
15665
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
15666
|
+
"ran",
|
|
15667
|
+
"skipped-trigger",
|
|
15668
|
+
"skipped-conditions",
|
|
15669
|
+
"skipped-cooldown",
|
|
15670
|
+
"skipped-overlap",
|
|
15671
|
+
"failed",
|
|
15672
|
+
"aborted"
|
|
15673
|
+
]);
|
|
15674
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
15675
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
15676
|
+
"pass",
|
|
15677
|
+
"fail",
|
|
15678
|
+
"not-evaluated"
|
|
15679
|
+
]);
|
|
15680
|
+
var AutomationTriggerTraceSchema = object({
|
|
15681
|
+
kind: string().min(1),
|
|
15682
|
+
outcome: _enum(["pass", "fail"]),
|
|
15683
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
15684
|
+
reason: string(),
|
|
15685
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
15686
|
+
vars: record(string(), TraceValueSchema)
|
|
15687
|
+
});
|
|
15688
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
15689
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
15690
|
+
path: string().min(1),
|
|
15691
|
+
kind: _enum([
|
|
15692
|
+
"all",
|
|
15693
|
+
"any",
|
|
15694
|
+
"not",
|
|
15695
|
+
"condition",
|
|
15696
|
+
"expression",
|
|
15697
|
+
"stationary-present"
|
|
15698
|
+
]),
|
|
15699
|
+
outcome: TraceNodeOutcomeSchema,
|
|
15700
|
+
reason: string(),
|
|
15701
|
+
deviceId: number().int().optional(),
|
|
15702
|
+
cap: string().optional(),
|
|
15703
|
+
fieldPath: string().optional(),
|
|
15704
|
+
operator: string().optional(),
|
|
15705
|
+
expected: TraceValueSchema.optional(),
|
|
15706
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
15707
|
+
observed: TraceValueSchema.optional()
|
|
15708
|
+
});
|
|
15709
|
+
var AutomationRunVerdictSchema = object({
|
|
15710
|
+
mode: AutomationRunModeSchema,
|
|
15711
|
+
decision: _enum([
|
|
15712
|
+
"run",
|
|
15713
|
+
"queued",
|
|
15714
|
+
"restart",
|
|
15715
|
+
"drop",
|
|
15716
|
+
"cooldown",
|
|
15717
|
+
"bypass"
|
|
15718
|
+
]),
|
|
15719
|
+
reason: string()
|
|
15720
|
+
});
|
|
15721
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
15722
|
+
var AutomationStepTraceSchema = object({
|
|
15723
|
+
/** `actions.<i>` */
|
|
15724
|
+
path: string().min(1),
|
|
15725
|
+
kind: string().min(1),
|
|
15726
|
+
cap: string().optional(),
|
|
15727
|
+
method: string().optional(),
|
|
15728
|
+
deviceId: number().int().optional(),
|
|
15729
|
+
startedAt: number().optional(),
|
|
15730
|
+
endedAt: number().optional(),
|
|
15731
|
+
outcome: _enum([
|
|
15732
|
+
"ok",
|
|
15733
|
+
"error",
|
|
15734
|
+
"not-run"
|
|
15735
|
+
]),
|
|
15736
|
+
message: string().optional()
|
|
15737
|
+
});
|
|
15738
|
+
var AutomationRunTraceSchema = object({
|
|
15739
|
+
runId: string().min(1),
|
|
15740
|
+
startedAt: number(),
|
|
15741
|
+
endedAt: number(),
|
|
15742
|
+
trigger: AutomationTriggerTraceSchema,
|
|
15743
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
15744
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
15745
|
+
steps: array(AutomationStepTraceSchema),
|
|
15746
|
+
outcome: AutomationRunOutcomeSchema,
|
|
15747
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
15748
|
+
repeat: number().int().min(1),
|
|
15749
|
+
/** When the latest of those repeats happened. */
|
|
15750
|
+
lastAt: number()
|
|
15751
|
+
});
|
|
15752
|
+
/**
|
|
15753
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
15754
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
15755
|
+
*/
|
|
15756
|
+
var AutomationStateDocSchema = object({
|
|
15757
|
+
version: literal(1),
|
|
15758
|
+
lastRunStartedAt: number().nullable(),
|
|
15759
|
+
traces: array(AutomationRunTraceSchema)
|
|
15760
|
+
});
|
|
15761
|
+
/**
|
|
15762
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
15763
|
+
* declared as LIST ENTRIES, never as devices.
|
|
15764
|
+
*
|
|
15765
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
15766
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
15767
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
15768
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
15769
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
15770
|
+
*
|
|
15771
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
15772
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
15773
|
+
* runtime.
|
|
15774
|
+
*/
|
|
15775
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
15776
|
+
var ActionVariableTypeSchema = _enum([
|
|
15777
|
+
"string",
|
|
15778
|
+
"number",
|
|
15779
|
+
"boolean",
|
|
15780
|
+
"select"
|
|
15781
|
+
]);
|
|
15782
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
15783
|
+
var ActionVariableValueSchema = union([
|
|
15784
|
+
string(),
|
|
15785
|
+
number(),
|
|
15786
|
+
boolean()
|
|
15787
|
+
]);
|
|
15788
|
+
/**
|
|
15789
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
15790
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
15791
|
+
*/
|
|
15792
|
+
var ActionVariableSchema = object({
|
|
15793
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
15794
|
+
label: string().min(1).max(120).optional(),
|
|
15795
|
+
type: ActionVariableTypeSchema,
|
|
15796
|
+
required: boolean().optional(),
|
|
15797
|
+
default: ActionVariableValueSchema.optional(),
|
|
15798
|
+
/** The allowed values of a `select`. */
|
|
15799
|
+
options: array(string().min(1)).min(1).optional()
|
|
15800
|
+
}).superRefine((v, ctx) => {
|
|
15801
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
15802
|
+
code: "custom",
|
|
15803
|
+
message: "a select variable needs options",
|
|
15804
|
+
path: ["options"]
|
|
15805
|
+
});
|
|
15806
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
15807
|
+
code: "custom",
|
|
15808
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
15809
|
+
path: ["default"]
|
|
15810
|
+
});
|
|
15811
|
+
});
|
|
15812
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
15813
|
+
function variableValueError(variable, value) {
|
|
15814
|
+
switch (variable.type) {
|
|
15815
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
15816
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
15817
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
15818
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
15819
|
+
}
|
|
15820
|
+
}
|
|
15821
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
15822
|
+
function isInternalActionId(actionId) {
|
|
15823
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
15824
|
+
}
|
|
15825
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
15826
|
+
function addonIdOfActionId(actionId) {
|
|
15827
|
+
if (isInternalActionId(actionId)) return null;
|
|
15828
|
+
const at = actionId.indexOf(":");
|
|
15829
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
15830
|
+
}
|
|
15831
|
+
var ActionStatusSchema = object({
|
|
15832
|
+
isRunning: boolean(),
|
|
15833
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
15834
|
+
lastRunAt: number().nullable(),
|
|
15835
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
15836
|
+
lastError: string().nullable()
|
|
15837
|
+
});
|
|
15838
|
+
var ActionEntrySchema = object({
|
|
15839
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
15840
|
+
id: string().min(3),
|
|
15841
|
+
name: string().min(1).max(120),
|
|
15842
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
15843
|
+
addonId: string().min(1),
|
|
15844
|
+
source: ActionSourceKindSchema,
|
|
15845
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
15846
|
+
readOnly: boolean(),
|
|
15847
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
15848
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
15849
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
15850
|
+
status: ActionStatusSchema
|
|
15851
|
+
}).superRefine((entry, ctx) => {
|
|
15852
|
+
if (entry.source === "internal") {
|
|
15853
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
15854
|
+
code: "custom",
|
|
15855
|
+
message: "an internal action id is internal:<uuid>",
|
|
15856
|
+
path: ["id"]
|
|
15857
|
+
});
|
|
15858
|
+
return;
|
|
15859
|
+
}
|
|
15860
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
15861
|
+
code: "custom",
|
|
15862
|
+
message: "only an internal action carries steps",
|
|
15863
|
+
path: ["steps"]
|
|
15864
|
+
});
|
|
15865
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
15866
|
+
code: "custom",
|
|
15867
|
+
message: "an addon action is read-only here",
|
|
15868
|
+
path: ["readOnly"]
|
|
15869
|
+
});
|
|
15870
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
15871
|
+
code: "custom",
|
|
15872
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
15873
|
+
path: ["id"]
|
|
15874
|
+
});
|
|
15875
|
+
});
|
|
15876
|
+
/** What an operator writes for an internal action. */
|
|
15877
|
+
var ActionInputSchema = object({
|
|
15878
|
+
name: string().min(1).max(120),
|
|
15879
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
15880
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
15881
|
+
});
|
|
15882
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
15883
|
+
var ActionRunOriginSchema = object({
|
|
15884
|
+
/** The automation block whose step started it. */
|
|
15885
|
+
blockId: string().min(1).optional() });
|
|
15886
|
+
/** `started` = the caller did not ask to wait. */
|
|
15887
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
15888
|
+
var ActionRunResultSchema = object({
|
|
15889
|
+
runId: string().min(1),
|
|
15890
|
+
outcome: ActionRunOutcomeSchema,
|
|
15891
|
+
/** Why it did not run, or what failed. */
|
|
15892
|
+
message: string().optional()
|
|
15893
|
+
});
|
|
15894
|
+
_enum([
|
|
15895
|
+
"not-found",
|
|
15896
|
+
"read-only",
|
|
15897
|
+
"invalid-variables",
|
|
15898
|
+
"invalid-steps",
|
|
15899
|
+
"not-linked",
|
|
15900
|
+
"busy"
|
|
15901
|
+
]);
|
|
15902
|
+
object({
|
|
15903
|
+
actionId: string(),
|
|
15904
|
+
runId: string(),
|
|
15905
|
+
isRunning: boolean(),
|
|
15906
|
+
/** Set when the run ended. */
|
|
15907
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
15908
|
+
lastRunAt: number().nullable(),
|
|
15909
|
+
lastError: string().nullable()
|
|
15493
15910
|
});
|
|
15494
15911
|
/**
|
|
15495
15912
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18176,7 +18593,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18176
18593
|
stateField: string(),
|
|
18177
18594
|
fieldKey: string()
|
|
18178
18595
|
});
|
|
18179
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
18596
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18180
18597
|
var CompositionProblemSchema = object({
|
|
18181
18598
|
code: _enum([
|
|
18182
18599
|
"reserved-variant",
|
|
@@ -18495,7 +18912,7 @@ var GROUP_TEMPLATES = [
|
|
|
18495
18912
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18496
18913
|
role: DeviceRole.TemperatureSensor,
|
|
18497
18914
|
outputCap: "temperature-sensor",
|
|
18498
|
-
outputField: "
|
|
18915
|
+
outputField: "temperature",
|
|
18499
18916
|
quantity: "temperature",
|
|
18500
18917
|
defaultAggregate: "mean",
|
|
18501
18918
|
empty: "null",
|
|
@@ -18506,7 +18923,7 @@ var GROUP_TEMPLATES = [
|
|
|
18506
18923
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18507
18924
|
role: DeviceRole.HumiditySensor,
|
|
18508
18925
|
outputCap: "humidity-sensor",
|
|
18509
|
-
outputField: "
|
|
18926
|
+
outputField: "humidity",
|
|
18510
18927
|
quantity: "humidity",
|
|
18511
18928
|
defaultAggregate: "mean",
|
|
18512
18929
|
empty: "null",
|
|
@@ -18517,7 +18934,7 @@ var GROUP_TEMPLATES = [
|
|
|
18517
18934
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18518
18935
|
role: DeviceRole.PressureSensor,
|
|
18519
18936
|
outputCap: "pressure-sensor",
|
|
18520
|
-
outputField: "
|
|
18937
|
+
outputField: "pressure",
|
|
18521
18938
|
quantity: "pressure",
|
|
18522
18939
|
defaultAggregate: "mean",
|
|
18523
18940
|
empty: "null",
|
|
@@ -18528,7 +18945,7 @@ var GROUP_TEMPLATES = [
|
|
|
18528
18945
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18529
18946
|
role: DeviceRole.AmbientLightSensor,
|
|
18530
18947
|
outputCap: "ambient-light-sensor",
|
|
18531
|
-
outputField: "
|
|
18948
|
+
outputField: "illuminance",
|
|
18532
18949
|
quantity: "illuminance",
|
|
18533
18950
|
defaultAggregate: "mean",
|
|
18534
18951
|
empty: "null",
|
|
@@ -18539,7 +18956,7 @@ var GROUP_TEMPLATES = [
|
|
|
18539
18956
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18540
18957
|
role: DeviceRole.PowerSensor,
|
|
18541
18958
|
outputCap: "power-meter",
|
|
18542
|
-
outputField: "
|
|
18959
|
+
outputField: "power",
|
|
18543
18960
|
quantity: "power",
|
|
18544
18961
|
defaultAggregate: "sum",
|
|
18545
18962
|
empty: "omit",
|
|
@@ -18550,7 +18967,7 @@ var GROUP_TEMPLATES = [
|
|
|
18550
18967
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18551
18968
|
role: DeviceRole.EnergySensor,
|
|
18552
18969
|
outputCap: "power-meter",
|
|
18553
|
-
outputField: "
|
|
18970
|
+
outputField: "energy",
|
|
18554
18971
|
quantity: "energy",
|
|
18555
18972
|
defaultAggregate: "sum",
|
|
18556
18973
|
empty: "omit",
|
|
@@ -18561,7 +18978,7 @@ var GROUP_TEMPLATES = [
|
|
|
18561
18978
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18562
18979
|
role: DeviceRole.BatterySensor,
|
|
18563
18980
|
outputCap: "battery",
|
|
18564
|
-
outputField: "
|
|
18981
|
+
outputField: "level",
|
|
18565
18982
|
quantity: "percentage",
|
|
18566
18983
|
defaultAggregate: "mean",
|
|
18567
18984
|
empty: "null",
|
|
@@ -19139,7 +19556,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19139
19556
|
kind: "mutation",
|
|
19140
19557
|
auth: "admin",
|
|
19141
19558
|
access: "view"
|
|
19142
|
-
})
|
|
19559
|
+
}), method(object({
|
|
19560
|
+
blockId: string().min(1),
|
|
19561
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
19562
|
+
runStartedAt: number().optional(),
|
|
19563
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
19564
|
+
}), _void(), {
|
|
19565
|
+
kind: "mutation",
|
|
19566
|
+
auth: "admin"
|
|
19567
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
19568
|
+
traces: array(AutomationRunTraceSchema),
|
|
19569
|
+
lastError: string().nullable()
|
|
19570
|
+
}), { auth: "admin" });
|
|
19143
19571
|
/**
|
|
19144
19572
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19145
19573
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -44611,51 +45039,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
44611
45039
|
kind: "mutation",
|
|
44612
45040
|
auth: "admin"
|
|
44613
45041
|
});
|
|
44614
|
-
new Set([
|
|
44615
|
-
{
|
|
44616
|
-
id: "person",
|
|
44617
|
-
name: "Person"
|
|
44618
|
-
},
|
|
44619
|
-
{
|
|
44620
|
-
id: "vehicle",
|
|
44621
|
-
name: "Vehicle"
|
|
44622
|
-
},
|
|
44623
|
-
{
|
|
44624
|
-
id: "animal",
|
|
44625
|
-
name: "Animal"
|
|
44626
|
-
},
|
|
44627
|
-
{
|
|
44628
|
-
id: "package",
|
|
44629
|
-
name: "Package"
|
|
44630
|
-
}
|
|
44631
|
-
].map((l) => l.id));
|
|
44632
|
-
var COCO_TO_MACRO = {
|
|
44633
|
-
mapping: {
|
|
44634
|
-
person: "person",
|
|
44635
|
-
bicycle: "vehicle",
|
|
44636
|
-
car: "vehicle",
|
|
44637
|
-
motorcycle: "vehicle",
|
|
44638
|
-
airplane: "vehicle",
|
|
44639
|
-
bus: "vehicle",
|
|
44640
|
-
train: "vehicle",
|
|
44641
|
-
truck: "vehicle",
|
|
44642
|
-
boat: "vehicle",
|
|
44643
|
-
bird: "animal",
|
|
44644
|
-
cat: "animal",
|
|
44645
|
-
dog: "animal",
|
|
44646
|
-
horse: "animal",
|
|
44647
|
-
sheep: "animal",
|
|
44648
|
-
cow: "animal",
|
|
44649
|
-
elephant: "animal",
|
|
44650
|
-
bear: "animal",
|
|
44651
|
-
zebra: "animal",
|
|
44652
|
-
giraffe: "animal",
|
|
44653
|
-
suitcase: "package",
|
|
44654
|
-
backpack: "package",
|
|
44655
|
-
handbag: "package"
|
|
44656
|
-
},
|
|
44657
|
-
preserveOriginal: false
|
|
44658
|
-
};
|
|
44659
45042
|
var AUDIO_MACRO_LABELS = [
|
|
44660
45043
|
{
|
|
44661
45044
|
id: "speech",
|
|
@@ -57222,9 +57605,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57222
57605
|
*/
|
|
57223
57606
|
var AirQualitySensorStatusSchema = object({
|
|
57224
57607
|
/** Carbon dioxide concentration in ppm. */
|
|
57225
|
-
|
|
57608
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57226
57609
|
/** Total volatile organic compounds in ppb. */
|
|
57227
|
-
|
|
57610
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57228
57611
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57229
57612
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57230
57613
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -57257,12 +57640,12 @@ var airQualitySensorCapability = {
|
|
|
57257
57640
|
* History (D850): recorded series.
|
|
57258
57641
|
*/
|
|
57259
57642
|
history: { fields: {
|
|
57260
|
-
|
|
57643
|
+
co2: {
|
|
57261
57644
|
kind: "gauge",
|
|
57262
57645
|
unit: "ppm",
|
|
57263
57646
|
deadband: 5
|
|
57264
57647
|
},
|
|
57265
|
-
|
|
57648
|
+
voc: {
|
|
57266
57649
|
kind: "gauge",
|
|
57267
57650
|
unit: "ppb",
|
|
57268
57651
|
deadband: 5
|
|
@@ -57293,7 +57676,7 @@ var airQualitySensorCapability = {
|
|
|
57293
57676
|
*/
|
|
57294
57677
|
var AmbientLightSensorStatusSchema = object({
|
|
57295
57678
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57296
|
-
|
|
57679
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57297
57680
|
precision: 0,
|
|
57298
57681
|
label: "Illuminance"
|
|
57299
57682
|
})),
|
|
@@ -57322,7 +57705,7 @@ var ambientLightSensorCapability = {
|
|
|
57322
57705
|
/**
|
|
57323
57706
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
57324
57707
|
*/
|
|
57325
|
-
history: { fields: {
|
|
57708
|
+
history: { fields: { illuminance: {
|
|
57326
57709
|
kind: "gauge",
|
|
57327
57710
|
unit: "lx",
|
|
57328
57711
|
deadbandPct: 10,
|
|
@@ -57461,6 +57844,84 @@ var audioMetricsCapability = {
|
|
|
57461
57844
|
*/
|
|
57462
57845
|
history: "none"
|
|
57463
57846
|
};
|
|
57847
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
57848
|
+
actionId: string().min(1),
|
|
57849
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
57850
|
+
}), _void(), {
|
|
57851
|
+
kind: "mutation",
|
|
57852
|
+
auth: "admin"
|
|
57853
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
57854
|
+
kind: "mutation",
|
|
57855
|
+
auth: "admin"
|
|
57856
|
+
});
|
|
57857
|
+
/**
|
|
57858
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
57859
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
57860
|
+
*
|
|
57861
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
57862
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
57863
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
57864
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
57865
|
+
* drift (D3).
|
|
57866
|
+
*
|
|
57867
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
57868
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
57869
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
57870
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
57871
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
57872
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
57873
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
57874
|
+
*
|
|
57875
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
57876
|
+
* logged — never queued.
|
|
57877
|
+
*/
|
|
57878
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
57879
|
+
var ActionLinksSchema = object({
|
|
57880
|
+
deviceId: number().int().nonnegative(),
|
|
57881
|
+
actionIds: array(string().min(1)).max(100)
|
|
57882
|
+
});
|
|
57883
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
57884
|
+
actionId: string().min(1),
|
|
57885
|
+
deviceId: number().int().nonnegative().optional()
|
|
57886
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
57887
|
+
role: "viewer",
|
|
57888
|
+
auth: "protected",
|
|
57889
|
+
kind: "query",
|
|
57890
|
+
caller: "required"
|
|
57891
|
+
}), method(object({
|
|
57892
|
+
actionId: string().min(1),
|
|
57893
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
57894
|
+
wait: boolean().optional(),
|
|
57895
|
+
origin: ActionRunOriginSchema.optional(),
|
|
57896
|
+
deviceId: number().int().nonnegative().optional()
|
|
57897
|
+
}), ActionRunResultSchema, {
|
|
57898
|
+
role: "viewer",
|
|
57899
|
+
auth: "protected",
|
|
57900
|
+
kind: "mutation",
|
|
57901
|
+
caller: "required"
|
|
57902
|
+
}), method(ActionIdInput, _void(), {
|
|
57903
|
+
kind: "mutation",
|
|
57904
|
+
auth: "admin"
|
|
57905
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
57906
|
+
kind: "mutation",
|
|
57907
|
+
auth: "admin"
|
|
57908
|
+
}), method(object({
|
|
57909
|
+
actionId: string().min(1),
|
|
57910
|
+
action: ActionInputSchema.partial()
|
|
57911
|
+
}), object({ action: ActionEntrySchema }), {
|
|
57912
|
+
kind: "mutation",
|
|
57913
|
+
auth: "admin"
|
|
57914
|
+
}), method(ActionIdInput, _void(), {
|
|
57915
|
+
kind: "mutation",
|
|
57916
|
+
auth: "admin"
|
|
57917
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
57918
|
+
role: "viewer",
|
|
57919
|
+
auth: "protected",
|
|
57920
|
+
kind: "query"
|
|
57921
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
57922
|
+
kind: "mutation",
|
|
57923
|
+
auth: "admin"
|
|
57924
|
+
});
|
|
57464
57925
|
/**
|
|
57465
57926
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
57466
57927
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -57557,7 +58018,7 @@ var BatteryStatusSchema = object({
|
|
|
57557
58018
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57558
58019
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57559
58020
|
*/
|
|
57560
|
-
|
|
58021
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57561
58022
|
/**
|
|
57562
58023
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57563
58024
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57567,7 +58028,7 @@ var BatteryStatusSchema = object({
|
|
|
57567
58028
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
57568
58029
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
57569
58030
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
57570
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
58031
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
57571
58032
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
57572
58033
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
57573
58034
|
*/
|
|
@@ -57591,7 +58052,7 @@ var BatteryStatusSchema = object({
|
|
|
57591
58052
|
* that only report charge. A second reading on this cap, not a second
|
|
57592
58053
|
* `numeric-sensor` on the same device.
|
|
57593
58054
|
*/
|
|
57594
|
-
|
|
58055
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57595
58056
|
/**
|
|
57596
58057
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57597
58058
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -57625,7 +58086,7 @@ var BatteryStatusSchema = object({
|
|
|
57625
58086
|
/**
|
|
57626
58087
|
* True when the source is a BINARY low-battery indicator (HA
|
|
57627
58088
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
57628
|
-
* charge level — `
|
|
58089
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
57629
58090
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
57630
58091
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
57631
58092
|
*/
|
|
@@ -57645,15 +58106,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
57645
58106
|
var batteryCustomize = {
|
|
57646
58107
|
version: 1,
|
|
57647
58108
|
targets: [{
|
|
57648
|
-
id: "
|
|
58109
|
+
id: "level",
|
|
57649
58110
|
cardinality: "scalar",
|
|
57650
58111
|
vocabulary: {
|
|
57651
58112
|
cap: "battery",
|
|
57652
|
-
stateField: "
|
|
58113
|
+
stateField: "level"
|
|
57653
58114
|
},
|
|
57654
58115
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
57655
58116
|
apply: "add",
|
|
57656
|
-
path: "
|
|
58117
|
+
path: "level",
|
|
57657
58118
|
sources: [{
|
|
57658
58119
|
kind: "field",
|
|
57659
58120
|
valueKinds: ["number", "string"],
|
|
@@ -57747,7 +58208,7 @@ onStatusChanged: { data: object({
|
|
|
57747
58208
|
schema: BatteryStatusSchema,
|
|
57748
58209
|
kind: "push",
|
|
57749
58210
|
empty: {
|
|
57750
|
-
|
|
58211
|
+
level: null,
|
|
57751
58212
|
charging: "unknown",
|
|
57752
58213
|
sleeping: false,
|
|
57753
58214
|
lastUpdated: 0
|
|
@@ -57774,11 +58235,11 @@ onStatusChanged: { data: object({
|
|
|
57774
58235
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
57775
58236
|
*/
|
|
57776
58237
|
history: { fields: {
|
|
57777
|
-
|
|
58238
|
+
level: {
|
|
57778
58239
|
kind: "gauge",
|
|
57779
58240
|
unit: "%"
|
|
57780
58241
|
},
|
|
57781
|
-
|
|
58242
|
+
voltage: {
|
|
57782
58243
|
kind: "gauge",
|
|
57783
58244
|
unit: "V"
|
|
57784
58245
|
}
|
|
@@ -57838,14 +58299,14 @@ var binaryCapability = {
|
|
|
57838
58299
|
* controls to this single-method surface.
|
|
57839
58300
|
*
|
|
57840
58301
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
57841
|
-
*
|
|
58302
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
57842
58303
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
57843
58304
|
* should surface those via the device's `getSettingsUISchema()`
|
|
57844
58305
|
* instead of bloating this cap.
|
|
57845
58306
|
*/
|
|
57846
58307
|
var BrightnessStatusSchema = object({
|
|
57847
58308
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
57848
|
-
|
|
58309
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
57849
58310
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
57850
58311
|
lastChangedAt: number()
|
|
57851
58312
|
});
|
|
@@ -57857,7 +58318,7 @@ var brightnessCapability = {
|
|
|
57857
58318
|
deviceTypes: [DeviceType.Light],
|
|
57858
58319
|
methods: { setBrightness: method(object({
|
|
57859
58320
|
deviceId: number().int().nonnegative(),
|
|
57860
|
-
|
|
58321
|
+
level: number().min(0).max(100)
|
|
57861
58322
|
}), _void(), {
|
|
57862
58323
|
kind: "mutation",
|
|
57863
58324
|
auth: "protected"
|
|
@@ -57870,7 +58331,7 @@ var brightnessCapability = {
|
|
|
57870
58331
|
*/
|
|
57871
58332
|
onBrightnessChanged: { data: object({
|
|
57872
58333
|
deviceId: number(),
|
|
57873
|
-
|
|
58334
|
+
level: number().min(0).max(100),
|
|
57874
58335
|
lastChangedAt: number()
|
|
57875
58336
|
}) } },
|
|
57876
58337
|
status: {
|
|
@@ -57893,7 +58354,7 @@ onBrightnessChanged: { data: object({
|
|
|
57893
58354
|
/**
|
|
57894
58355
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
57895
58356
|
*/
|
|
57896
|
-
history: { fields: {
|
|
58357
|
+
history: { fields: { level: {
|
|
57897
58358
|
kind: "gauge",
|
|
57898
58359
|
unit: "%",
|
|
57899
58360
|
minIntervalMs: 0
|
|
@@ -58490,11 +58951,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
58490
58951
|
}),
|
|
58491
58952
|
object({
|
|
58492
58953
|
mode: literal("mired"),
|
|
58493
|
-
|
|
58954
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
58494
58955
|
})
|
|
58495
58956
|
]);
|
|
58496
58957
|
var ColorStatusSchema = object({
|
|
58497
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
58958
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
58498
58959
|
* the bulb's current state. */
|
|
58499
58960
|
mode: _enum([
|
|
58500
58961
|
"rgb",
|
|
@@ -58506,7 +58967,7 @@ var ColorStatusSchema = object({
|
|
|
58506
58967
|
/** Populated when `mode === 'hsv'`. */
|
|
58507
58968
|
hsv: HsvTripletSchema.optional(),
|
|
58508
58969
|
/** Populated when `mode === 'mired'`. */
|
|
58509
|
-
|
|
58970
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58510
58971
|
/** Ms epoch of the last operator-driven change. */
|
|
58511
58972
|
lastChangedAt: number()
|
|
58512
58973
|
});
|
|
@@ -58538,7 +58999,7 @@ onColorChanged: { data: object({
|
|
|
58538
58999
|
]),
|
|
58539
59000
|
rgb: RgbTripletSchema.optional(),
|
|
58540
59001
|
hsv: HsvTripletSchema.optional(),
|
|
58541
|
-
|
|
59002
|
+
colorTemperature: number().int().optional(),
|
|
58542
59003
|
lastChangedAt: number()
|
|
58543
59004
|
}) } },
|
|
58544
59005
|
status: {
|
|
@@ -59415,11 +59876,11 @@ var DishwasherStatusSchema = object({
|
|
|
59415
59876
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59416
59877
|
availablePrograms: array(string()),
|
|
59417
59878
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59418
|
-
|
|
59879
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59419
59880
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59420
|
-
|
|
59881
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59421
59882
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59422
|
-
|
|
59883
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59423
59884
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59424
59885
|
doorOpen: boolean().nullable(),
|
|
59425
59886
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -59638,14 +60099,14 @@ var dishwasherCapability = {
|
|
|
59638
60099
|
runtimeState: DishwasherStatusSchema,
|
|
59639
60100
|
durability: "session",
|
|
59640
60101
|
history: { fields: {
|
|
59641
|
-
|
|
60102
|
+
progress: {
|
|
59642
60103
|
kind: "gauge",
|
|
59643
60104
|
unit: "%",
|
|
59644
60105
|
deadband: 2
|
|
59645
60106
|
},
|
|
59646
60107
|
state: { kind: "enum" },
|
|
59647
60108
|
operationState: { kind: "enum" },
|
|
59648
|
-
|
|
60109
|
+
remaining: {
|
|
59649
60110
|
kind: "gauge",
|
|
59650
60111
|
unit: "s",
|
|
59651
60112
|
minIntervalMs: 6e4
|
|
@@ -60236,7 +60697,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60236
60697
|
var FanControlStatusSchema = object({
|
|
60237
60698
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60238
60699
|
* speed surface (single-speed fan). */
|
|
60239
|
-
|
|
60700
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60240
60701
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60241
60702
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60242
60703
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -60263,7 +60724,7 @@ var fanControlCapability = {
|
|
|
60263
60724
|
methods: {
|
|
60264
60725
|
setPercentage: method(object({
|
|
60265
60726
|
deviceId: number().int().nonnegative(),
|
|
60266
|
-
|
|
60727
|
+
speed: number().min(0).max(100)
|
|
60267
60728
|
}), _void(), {
|
|
60268
60729
|
kind: "mutation",
|
|
60269
60730
|
auth: "protected"
|
|
@@ -60296,7 +60757,7 @@ var fanControlCapability = {
|
|
|
60296
60757
|
},
|
|
60297
60758
|
/**
|
|
60298
60759
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
60299
|
-
* sliders read `
|
|
60760
|
+
* sliders read `speed` for live updates.
|
|
60300
60761
|
*/
|
|
60301
60762
|
runtimeState: FanControlStatusSchema,
|
|
60302
60763
|
/**
|
|
@@ -60310,7 +60771,7 @@ var fanControlCapability = {
|
|
|
60310
60771
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
60311
60772
|
*/
|
|
60312
60773
|
history: { fields: {
|
|
60313
|
-
|
|
60774
|
+
speed: {
|
|
60314
60775
|
kind: "gauge",
|
|
60315
60776
|
unit: "%",
|
|
60316
60777
|
minIntervalMs: 0
|
|
@@ -60755,7 +61216,7 @@ var humidifierCapability = {
|
|
|
60755
61216
|
*/
|
|
60756
61217
|
var HumiditySensorStatusSchema = object({
|
|
60757
61218
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
60758
|
-
|
|
61219
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
60759
61220
|
precision: 0,
|
|
60760
61221
|
label: "Humidity"
|
|
60761
61222
|
})),
|
|
@@ -60784,7 +61245,7 @@ var humiditySensorCapability = {
|
|
|
60784
61245
|
/**
|
|
60785
61246
|
* History (D850): recorded series.
|
|
60786
61247
|
*/
|
|
60787
|
-
history: { fields: {
|
|
61248
|
+
history: { fields: { humidity: {
|
|
60788
61249
|
kind: "gauge",
|
|
60789
61250
|
unit: "%",
|
|
60790
61251
|
deadband: .5
|
|
@@ -61424,7 +61885,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61424
61885
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61425
61886
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61426
61887
|
* task is active / progress is unavailable. */
|
|
61427
|
-
|
|
61888
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61428
61889
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61429
61890
|
* or null when unknown. */
|
|
61430
61891
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -61924,7 +62385,7 @@ var lockControlCapability = {
|
|
|
61924
62385
|
volatileStateFields: ["lastChangedAt"]
|
|
61925
62386
|
};
|
|
61926
62387
|
/**
|
|
61927
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
62388
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
61928
62389
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
61929
62390
|
* `value` is the time integral in the source quantity's accumulated base
|
|
61930
62391
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -62018,10 +62479,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62018
62479
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62019
62480
|
/** Current playback position in ms. Null when not seekable or
|
|
62020
62481
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62021
|
-
|
|
62482
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62022
62483
|
/** Total duration of the current media in ms. Null when unknown
|
|
62023
62484
|
* (live stream) or nothing is playing. */
|
|
62024
|
-
|
|
62485
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62025
62486
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62026
62487
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62027
62488
|
shuffle: boolean().nullable(),
|
|
@@ -62060,7 +62521,7 @@ var mediaPlayerCapability = {
|
|
|
62060
62521
|
}),
|
|
62061
62522
|
seek: method(object({
|
|
62062
62523
|
deviceId: number().int().nonnegative(),
|
|
62063
|
-
|
|
62524
|
+
position: number().int().nonnegative()
|
|
62064
62525
|
}), _void(), {
|
|
62065
62526
|
kind: "mutation",
|
|
62066
62527
|
auth: "protected"
|
|
@@ -62132,7 +62593,7 @@ var mediaPlayerCapability = {
|
|
|
62132
62593
|
/**
|
|
62133
62594
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62134
62595
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62135
|
-
* `
|
|
62596
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62136
62597
|
*/
|
|
62137
62598
|
history: { fields: {
|
|
62138
62599
|
volumeLevel: {
|
|
@@ -63094,9 +63555,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
63094
63555
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63095
63556
|
* SKIP a null rather than coerce it.
|
|
63096
63557
|
*/
|
|
63097
|
-
|
|
63558
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63098
63559
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63099
|
-
|
|
63560
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
63100
63561
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63101
63562
|
ssid: string().optional(),
|
|
63102
63563
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63132,7 +63593,7 @@ onStatusChanged: { data: object({
|
|
|
63132
63593
|
kind: "push",
|
|
63133
63594
|
empty: {
|
|
63134
63595
|
type: "unknown",
|
|
63135
|
-
|
|
63596
|
+
signal: null,
|
|
63136
63597
|
lastUpdated: 0
|
|
63137
63598
|
}
|
|
63138
63599
|
},
|
|
@@ -63155,13 +63616,13 @@ onStatusChanged: { data: object({
|
|
|
63155
63616
|
* History (D850): recorded series.
|
|
63156
63617
|
*/
|
|
63157
63618
|
history: { fields: {
|
|
63158
|
-
|
|
63619
|
+
signal: {
|
|
63159
63620
|
kind: "gauge",
|
|
63160
63621
|
unit: "%",
|
|
63161
63622
|
deadband: 3,
|
|
63162
63623
|
minIntervalMs: 6e4
|
|
63163
63624
|
},
|
|
63164
|
-
|
|
63625
|
+
rssi: {
|
|
63165
63626
|
kind: "gauge",
|
|
63166
63627
|
unit: "dBm",
|
|
63167
63628
|
deadband: 2,
|
|
@@ -63906,10 +64367,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
63906
64367
|
]);
|
|
63907
64368
|
var gramsPortion = number().int().min(4).max(200);
|
|
63908
64369
|
var PetFeederStatusSchema = object({
|
|
63909
|
-
/** Food
|
|
63910
|
-
*
|
|
63911
|
-
* bowl
|
|
64370
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
64371
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
64372
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
64373
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
64374
|
+
* the device has not reported yet. */
|
|
63912
64375
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64376
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
64377
|
+
* feeder's own units. Null when the model reports none. */
|
|
64378
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
64379
|
+
/** True while the pet is eating (`state.eating`). */
|
|
64380
|
+
eating: boolean(),
|
|
64381
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
64382
|
+
* the client must not offer it. */
|
|
64383
|
+
supportsMarkRefilled: boolean(),
|
|
63913
64384
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
63914
64385
|
* single-hopper models. */
|
|
63915
64386
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -63917,8 +64388,8 @@ var PetFeederStatusSchema = object({
|
|
|
63917
64388
|
* single-hopper models. */
|
|
63918
64389
|
food2: number().nullable().meta(readingMeta("none")),
|
|
63919
64390
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
63920
|
-
* (`device_class: problem`, on = low). True when the
|
|
63921
|
-
*
|
|
64391
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
64392
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
63922
64393
|
lowFood: boolean(),
|
|
63923
64394
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
63924
64395
|
* device has no battery reading. */
|
|
@@ -63986,7 +64457,9 @@ var petFeederCapability = {
|
|
|
63986
64457
|
kind: "mutation",
|
|
63987
64458
|
auth: "protected"
|
|
63988
64459
|
}),
|
|
63989
|
-
/**
|
|
64460
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
64461
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
64462
|
+
* change any sensor reading. */
|
|
63990
64463
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
63991
64464
|
kind: "mutation",
|
|
63992
64465
|
auth: "protected"
|
|
@@ -64059,6 +64532,7 @@ var petFeederCapability = {
|
|
|
64059
64532
|
*/
|
|
64060
64533
|
history: { fields: {
|
|
64061
64534
|
foodLevel: { kind: "gauge" },
|
|
64535
|
+
bowlFood: { kind: "gauge" },
|
|
64062
64536
|
food1: { kind: "gauge" },
|
|
64063
64537
|
food2: { kind: "gauge" },
|
|
64064
64538
|
batteryPower: {
|
|
@@ -64468,16 +64942,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64468
64942
|
* in real-world devices.
|
|
64469
64943
|
*/
|
|
64470
64944
|
var PowerMeterStatusSchema = object({
|
|
64471
|
-
/** Instantaneous power draw
|
|
64472
|
-
|
|
64945
|
+
/** Instantaneous power draw (watts). */
|
|
64946
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64473
64947
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64474
|
-
|
|
64475
|
-
/** Voltage
|
|
64476
|
-
|
|
64948
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
64949
|
+
/** Voltage (volts). */
|
|
64950
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64477
64951
|
/** Current in amperes. */
|
|
64478
|
-
|
|
64952
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64479
64953
|
/** Apparent power in volt-amperes. */
|
|
64480
|
-
|
|
64954
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
64481
64955
|
/** Power factor (0..1) if reported. */
|
|
64482
64956
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64483
64957
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64535,14 +65009,14 @@ function powerTarget(id, unit) {
|
|
|
64535
65009
|
advancedExpression: true
|
|
64536
65010
|
};
|
|
64537
65011
|
}
|
|
64538
|
-
/** "Power and energy" extension:
|
|
65012
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
64539
65013
|
var powerMeterCustomize = {
|
|
64540
65014
|
version: 1,
|
|
64541
65015
|
targets: [
|
|
64542
|
-
powerTarget("
|
|
64543
|
-
powerTarget("
|
|
64544
|
-
powerTarget("
|
|
64545
|
-
powerTarget("
|
|
65016
|
+
powerTarget("power", "W"),
|
|
65017
|
+
powerTarget("energy", "kWh"),
|
|
65018
|
+
powerTarget("voltage", "V"),
|
|
65019
|
+
powerTarget("current", "A")
|
|
64546
65020
|
]
|
|
64547
65021
|
};
|
|
64548
65022
|
var powerMeterCapability = {
|
|
@@ -64558,41 +65032,41 @@ var powerMeterCapability = {
|
|
|
64558
65032
|
},
|
|
64559
65033
|
runtimeState: PowerMeterStatusSchema,
|
|
64560
65034
|
/**
|
|
64561
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
65035
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
64562
65036
|
*
|
|
64563
65037
|
* See `RuntimeStateDurability`. Enforced by
|
|
64564
65038
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64565
65039
|
*/
|
|
64566
65040
|
durability: "restored",
|
|
64567
65041
|
/**
|
|
64568
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
65042
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
64569
65043
|
*/
|
|
64570
65044
|
history: { fields: {
|
|
64571
|
-
|
|
65045
|
+
power: {
|
|
64572
65046
|
kind: "gauge",
|
|
64573
65047
|
unit: "W",
|
|
64574
65048
|
deadband: 1,
|
|
64575
65049
|
minIntervalMs: 3e4
|
|
64576
65050
|
},
|
|
64577
|
-
|
|
65051
|
+
energy: {
|
|
64578
65052
|
kind: "counter",
|
|
64579
65053
|
unit: "kWh",
|
|
64580
65054
|
deadband: .01,
|
|
64581
65055
|
minIntervalMs: 6e4
|
|
64582
65056
|
},
|
|
64583
|
-
|
|
65057
|
+
voltage: {
|
|
64584
65058
|
kind: "gauge",
|
|
64585
65059
|
unit: "V",
|
|
64586
65060
|
deadband: 1,
|
|
64587
65061
|
minIntervalMs: 3e4
|
|
64588
65062
|
},
|
|
64589
|
-
|
|
65063
|
+
current: {
|
|
64590
65064
|
kind: "gauge",
|
|
64591
65065
|
unit: "A",
|
|
64592
65066
|
deadband: .05,
|
|
64593
65067
|
minIntervalMs: 3e4
|
|
64594
65068
|
},
|
|
64595
|
-
|
|
65069
|
+
apparentPower: {
|
|
64596
65070
|
kind: "gauge",
|
|
64597
65071
|
unit: "VA",
|
|
64598
65072
|
deadband: 1,
|
|
@@ -64642,9 +65116,6 @@ var PresenceStatusSchema = object({
|
|
|
64642
65116
|
location: string().nullable(),
|
|
64643
65117
|
/** GPS coordinates when available. Null otherwise. */
|
|
64644
65118
|
gps: GpsLocationSchema.nullable(),
|
|
64645
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
64646
|
-
* when not reported. */
|
|
64647
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64648
65119
|
/** Ms epoch when the slice was last updated. */
|
|
64649
65120
|
lastChangedAt: number()
|
|
64650
65121
|
});
|
|
@@ -64673,14 +65144,7 @@ var presenceCapability = {
|
|
|
64673
65144
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64674
65145
|
*/
|
|
64675
65146
|
durability: "restored",
|
|
64676
|
-
|
|
64677
|
-
* History (D850): recorded series.
|
|
64678
|
-
*/
|
|
64679
|
-
history: { fields: { batteryPercent: {
|
|
64680
|
-
kind: "gauge",
|
|
64681
|
-
unit: "%",
|
|
64682
|
-
deadband: 1
|
|
64683
|
-
} } },
|
|
65147
|
+
history: "none",
|
|
64684
65148
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64685
65149
|
* whether persisting is worth a SQLite commit. */
|
|
64686
65150
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -64695,7 +65159,7 @@ var presenceCapability = {
|
|
|
64695
65159
|
*/
|
|
64696
65160
|
var PressureSensorStatusSchema = object({
|
|
64697
65161
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
64698
|
-
|
|
65162
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
64699
65163
|
/** Ms epoch when the slice was last updated. */
|
|
64700
65164
|
lastFetchedAt: number()
|
|
64701
65165
|
});
|
|
@@ -64721,7 +65185,7 @@ var pressureSensorCapability = {
|
|
|
64721
65185
|
/**
|
|
64722
65186
|
* History (D850): recorded series.
|
|
64723
65187
|
*/
|
|
64724
|
-
history: { fields: {
|
|
65188
|
+
history: { fields: { pressure: {
|
|
64725
65189
|
kind: "gauge",
|
|
64726
65190
|
unit: "hPa",
|
|
64727
65191
|
deadband: .1
|
|
@@ -68420,7 +68884,7 @@ var tamperCapability = {
|
|
|
68420
68884
|
*/
|
|
68421
68885
|
var TemperatureSensorStatusSchema = object({
|
|
68422
68886
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68423
|
-
|
|
68887
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
68424
68888
|
precision: 1,
|
|
68425
68889
|
label: "Temperature"
|
|
68426
68890
|
})),
|
|
@@ -68449,7 +68913,7 @@ var temperatureSensorCapability = {
|
|
|
68449
68913
|
/**
|
|
68450
68914
|
* History (D850): recorded series.
|
|
68451
68915
|
*/
|
|
68452
|
-
history: { fields: {
|
|
68916
|
+
history: { fields: { temperature: {
|
|
68453
68917
|
kind: "gauge",
|
|
68454
68918
|
unit: "°C",
|
|
68455
68919
|
deadband: .1
|
|
@@ -68746,7 +69210,7 @@ var VacuumControlStatusSchema = object({
|
|
|
68746
69210
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
68747
69211
|
availableFanSpeeds: array(string()),
|
|
68748
69212
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
68749
|
-
|
|
69213
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
68750
69214
|
/** Current error code (0 / null = no error). */
|
|
68751
69215
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
68752
69216
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -70783,7 +71247,7 @@ var BaseDevice = class {
|
|
|
70783
71247
|
* `device-local-state.ts`. Drivers access via:
|
|
70784
71248
|
*
|
|
70785
71249
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
70786
|
-
* `const pct = this.state.battery.
|
|
71250
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
70787
71251
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
70788
71252
|
*
|
|
70789
71253
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -70823,7 +71287,7 @@ var BaseDevice = class {
|
|
|
70823
71287
|
* shape; drivers don't redeclare it, they just write through.
|
|
70824
71288
|
*
|
|
70825
71289
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
70826
|
-
* `{
|
|
71290
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
70827
71291
|
* provider that registers `batteryCapability`.
|
|
70828
71292
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
70829
71293
|
*
|
|
@@ -71997,6 +72461,104 @@ Object.freeze({
|
|
|
71997
72461
|
access: "create",
|
|
71998
72462
|
role: "admin"
|
|
71999
72463
|
},
|
|
72464
|
+
"actions.create": {
|
|
72465
|
+
capName: "actions",
|
|
72466
|
+
capScope: "system",
|
|
72467
|
+
addonId: null,
|
|
72468
|
+
access: "create",
|
|
72469
|
+
role: "admin"
|
|
72470
|
+
},
|
|
72471
|
+
"actions.delete": {
|
|
72472
|
+
capName: "actions",
|
|
72473
|
+
capScope: "system",
|
|
72474
|
+
addonId: null,
|
|
72475
|
+
access: "delete",
|
|
72476
|
+
role: "admin"
|
|
72477
|
+
},
|
|
72478
|
+
"actions.get": {
|
|
72479
|
+
capName: "actions",
|
|
72480
|
+
capScope: "system",
|
|
72481
|
+
addonId: null,
|
|
72482
|
+
access: "view",
|
|
72483
|
+
role: "viewer"
|
|
72484
|
+
},
|
|
72485
|
+
"actions.getLinks": {
|
|
72486
|
+
capName: "actions",
|
|
72487
|
+
capScope: "system",
|
|
72488
|
+
addonId: null,
|
|
72489
|
+
access: "view",
|
|
72490
|
+
role: "admin"
|
|
72491
|
+
},
|
|
72492
|
+
"actions.getTraces": {
|
|
72493
|
+
capName: "actions",
|
|
72494
|
+
capScope: "system",
|
|
72495
|
+
addonId: null,
|
|
72496
|
+
access: "view",
|
|
72497
|
+
role: "admin"
|
|
72498
|
+
},
|
|
72499
|
+
"actions.list": {
|
|
72500
|
+
capName: "actions",
|
|
72501
|
+
capScope: "system",
|
|
72502
|
+
addonId: null,
|
|
72503
|
+
access: "view",
|
|
72504
|
+
role: "admin"
|
|
72505
|
+
},
|
|
72506
|
+
"actions.listForCamera": {
|
|
72507
|
+
capName: "actions",
|
|
72508
|
+
capScope: "system",
|
|
72509
|
+
addonId: null,
|
|
72510
|
+
access: "view",
|
|
72511
|
+
role: "viewer"
|
|
72512
|
+
},
|
|
72513
|
+
"actions.run": {
|
|
72514
|
+
capName: "actions",
|
|
72515
|
+
capScope: "system",
|
|
72516
|
+
addonId: null,
|
|
72517
|
+
access: "create",
|
|
72518
|
+
role: "viewer"
|
|
72519
|
+
},
|
|
72520
|
+
"actions.setLinks": {
|
|
72521
|
+
capName: "actions",
|
|
72522
|
+
capScope: "system",
|
|
72523
|
+
addonId: null,
|
|
72524
|
+
access: "create",
|
|
72525
|
+
role: "admin"
|
|
72526
|
+
},
|
|
72527
|
+
"actions.stop": {
|
|
72528
|
+
capName: "actions",
|
|
72529
|
+
capScope: "system",
|
|
72530
|
+
addonId: null,
|
|
72531
|
+
access: "create",
|
|
72532
|
+
role: "admin"
|
|
72533
|
+
},
|
|
72534
|
+
"actions.update": {
|
|
72535
|
+
capName: "actions",
|
|
72536
|
+
capScope: "system",
|
|
72537
|
+
addonId: null,
|
|
72538
|
+
access: "create",
|
|
72539
|
+
role: "admin"
|
|
72540
|
+
},
|
|
72541
|
+
"actionSource.listActions": {
|
|
72542
|
+
capName: "action-source",
|
|
72543
|
+
capScope: "system",
|
|
72544
|
+
addonId: null,
|
|
72545
|
+
access: "view",
|
|
72546
|
+
role: "admin"
|
|
72547
|
+
},
|
|
72548
|
+
"actionSource.runAction": {
|
|
72549
|
+
capName: "action-source",
|
|
72550
|
+
capScope: "system",
|
|
72551
|
+
addonId: null,
|
|
72552
|
+
access: "create",
|
|
72553
|
+
role: "admin"
|
|
72554
|
+
},
|
|
72555
|
+
"actionSource.stopAction": {
|
|
72556
|
+
capName: "action-source",
|
|
72557
|
+
capScope: "system",
|
|
72558
|
+
addonId: null,
|
|
72559
|
+
access: "create",
|
|
72560
|
+
role: "admin"
|
|
72561
|
+
},
|
|
72000
72562
|
"addonPages.listPages": {
|
|
72001
72563
|
capName: "addon-pages",
|
|
72002
72564
|
capScope: "system",
|
|
@@ -73278,6 +73840,13 @@ Object.freeze({
|
|
|
73278
73840
|
access: "view",
|
|
73279
73841
|
role: "admin"
|
|
73280
73842
|
},
|
|
73843
|
+
"coreBlocks.getAutomationRunState": {
|
|
73844
|
+
capName: "core-blocks",
|
|
73845
|
+
capScope: "system",
|
|
73846
|
+
addonId: null,
|
|
73847
|
+
access: "view",
|
|
73848
|
+
role: "admin"
|
|
73849
|
+
},
|
|
73281
73850
|
"coreBlocks.getBlockSettings": {
|
|
73282
73851
|
capName: "core-blocks",
|
|
73283
73852
|
capScope: "system",
|
|
@@ -73299,6 +73868,13 @@ Object.freeze({
|
|
|
73299
73868
|
access: "view",
|
|
73300
73869
|
role: "admin"
|
|
73301
73870
|
},
|
|
73871
|
+
"coreBlocks.getTraces": {
|
|
73872
|
+
capName: "core-blocks",
|
|
73873
|
+
capScope: "system",
|
|
73874
|
+
addonId: null,
|
|
73875
|
+
access: "view",
|
|
73876
|
+
role: "admin"
|
|
73877
|
+
},
|
|
73302
73878
|
"coreBlocks.getTypeDefs": {
|
|
73303
73879
|
capName: "core-blocks",
|
|
73304
73880
|
capScope: "system",
|
|
@@ -73334,6 +73910,13 @@ Object.freeze({
|
|
|
73334
73910
|
access: "create",
|
|
73335
73911
|
role: "admin"
|
|
73336
73912
|
},
|
|
73913
|
+
"coreBlocks.reportAutomationRun": {
|
|
73914
|
+
capName: "core-blocks",
|
|
73915
|
+
capScope: "system",
|
|
73916
|
+
addonId: null,
|
|
73917
|
+
access: "create",
|
|
73918
|
+
role: "admin"
|
|
73919
|
+
},
|
|
73337
73920
|
"coreBlocks.restart": {
|
|
73338
73921
|
capName: "core-blocks",
|
|
73339
73922
|
capScope: "system",
|
|
@@ -81907,7 +82490,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81907
82490
|
label: t("Full brightness", "Luminosità massima"),
|
|
81908
82491
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
81909
82492
|
icon: "sun",
|
|
81910
|
-
args: {
|
|
82493
|
+
args: { level: 100 }
|
|
81911
82494
|
},
|
|
81912
82495
|
{
|
|
81913
82496
|
id: "brightness.half",
|
|
@@ -81915,7 +82498,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81915
82498
|
label: t("Half brightness", "Luminosità a metà"),
|
|
81916
82499
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
81917
82500
|
icon: "sun-dim",
|
|
81918
|
-
args: {
|
|
82501
|
+
args: { level: 50 }
|
|
81919
82502
|
},
|
|
81920
82503
|
{
|
|
81921
82504
|
id: "brightness.off",
|
|
@@ -81923,16 +82506,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81923
82506
|
label: t("Brightness off", "Luminosità a zero"),
|
|
81924
82507
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
81925
82508
|
icon: "lightbulb-off",
|
|
81926
|
-
args: {
|
|
82509
|
+
args: { level: 0 }
|
|
81927
82510
|
},
|
|
81928
82511
|
{
|
|
81929
82512
|
id: "brightness.set",
|
|
81930
82513
|
method: "setBrightness",
|
|
81931
82514
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
81932
|
-
phrase: t("Set the brightness of {device} to {
|
|
82515
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
81933
82516
|
icon: "sun-medium",
|
|
81934
82517
|
openArgs: [{
|
|
81935
|
-
key: "
|
|
82518
|
+
key: "level",
|
|
81936
82519
|
label: PERCENT,
|
|
81937
82520
|
offer: {
|
|
81938
82521
|
kind: "number",
|
|
@@ -81946,13 +82529,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81946
82529
|
],
|
|
81947
82530
|
state: [{
|
|
81948
82531
|
kind: "numeric",
|
|
81949
|
-
field: "
|
|
82532
|
+
field: "level",
|
|
81950
82533
|
quantity: t("the brightness", "la luminosità"),
|
|
81951
82534
|
label: t("Brightness", "Luminosità"),
|
|
81952
82535
|
unit: "%",
|
|
81953
82536
|
icon: "sun"
|
|
81954
82537
|
}],
|
|
81955
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
82538
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
81956
82539
|
},
|
|
81957
82540
|
color: {
|
|
81958
82541
|
scope: "device",
|
|
@@ -81966,7 +82549,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81966
82549
|
icon: "sun",
|
|
81967
82550
|
args: { color: {
|
|
81968
82551
|
mode: "mired",
|
|
81969
|
-
|
|
82552
|
+
colorTemperature: 370
|
|
81970
82553
|
} }
|
|
81971
82554
|
},
|
|
81972
82555
|
{
|
|
@@ -81977,7 +82560,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81977
82560
|
icon: "snowflake",
|
|
81978
82561
|
args: { color: {
|
|
81979
82562
|
mode: "mired",
|
|
81980
|
-
|
|
82563
|
+
colorTemperature: 200
|
|
81981
82564
|
} }
|
|
81982
82565
|
},
|
|
81983
82566
|
{
|
|
@@ -82591,7 +83174,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82591
83174
|
label: t("Fan off", "Ventilatore spento"),
|
|
82592
83175
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
82593
83176
|
icon: "power-off",
|
|
82594
|
-
args: {
|
|
83177
|
+
args: { speed: 0 }
|
|
82595
83178
|
},
|
|
82596
83179
|
{
|
|
82597
83180
|
id: "fan.full",
|
|
@@ -82599,16 +83182,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82599
83182
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
82600
83183
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
82601
83184
|
icon: "fan",
|
|
82602
|
-
args: {
|
|
83185
|
+
args: { speed: 100 }
|
|
82603
83186
|
},
|
|
82604
83187
|
{
|
|
82605
83188
|
id: "fan.speed",
|
|
82606
83189
|
method: "setPercentage",
|
|
82607
83190
|
label: t("Set speed", "Imposta la velocità"),
|
|
82608
|
-
phrase: t("Set the speed of {device} to {
|
|
83191
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
82609
83192
|
icon: "fan",
|
|
82610
83193
|
openArgs: [{
|
|
82611
|
-
key: "
|
|
83194
|
+
key: "speed",
|
|
82612
83195
|
label: t("Speed", "Velocità"),
|
|
82613
83196
|
offer: {
|
|
82614
83197
|
kind: "number",
|
|
@@ -82670,7 +83253,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82670
83253
|
],
|
|
82671
83254
|
state: [{
|
|
82672
83255
|
kind: "numeric",
|
|
82673
|
-
field: "
|
|
83256
|
+
field: "speed",
|
|
82674
83257
|
quantity: t("the speed", "la velocità"),
|
|
82675
83258
|
label: t("Speed", "Velocità"),
|
|
82676
83259
|
unit: "%",
|
|
@@ -83468,7 +84051,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83468
84051
|
},
|
|
83469
84052
|
{
|
|
83470
84053
|
kind: "numeric",
|
|
83471
|
-
field: "
|
|
84054
|
+
field: "progress",
|
|
83472
84055
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
83473
84056
|
label: t("Progress", "Avanzamento"),
|
|
83474
84057
|
unit: "%",
|
|
@@ -83826,10 +84409,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83826
84409
|
id: "media.seek",
|
|
83827
84410
|
method: "seek",
|
|
83828
84411
|
label: t("Seek", "Vai al punto"),
|
|
83829
|
-
phrase: t("Move {device} to {
|
|
84412
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
83830
84413
|
icon: "fast-forward",
|
|
83831
84414
|
openArgs: [{
|
|
83832
|
-
key: "
|
|
84415
|
+
key: "position",
|
|
83833
84416
|
label: t("Position", "Posizione"),
|
|
83834
84417
|
offer: {
|
|
83835
84418
|
kind: "number",
|
|
@@ -84878,7 +85461,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84878
85461
|
state: [
|
|
84879
85462
|
{
|
|
84880
85463
|
kind: "numeric",
|
|
84881
|
-
field: "
|
|
85464
|
+
field: "co2",
|
|
84882
85465
|
quantity: t("the CO₂", "la CO₂"),
|
|
84883
85466
|
label: t("CO₂", "CO₂"),
|
|
84884
85467
|
unit: "ppm",
|
|
@@ -84886,7 +85469,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84886
85469
|
},
|
|
84887
85470
|
{
|
|
84888
85471
|
kind: "numeric",
|
|
84889
|
-
field: "
|
|
85472
|
+
field: "voc",
|
|
84890
85473
|
quantity: t("the VOC level", "il livello di COV"),
|
|
84891
85474
|
label: t("VOC", "COV"),
|
|
84892
85475
|
unit: "ppb",
|
|
@@ -84922,7 +85505,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84922
85505
|
noun: t("Light level", "Luminosità ambiente"),
|
|
84923
85506
|
state: [{
|
|
84924
85507
|
kind: "numeric",
|
|
84925
|
-
field: "
|
|
85508
|
+
field: "illuminance",
|
|
84926
85509
|
quantity: t("the light level", "la luminosità"),
|
|
84927
85510
|
label: t("Illuminance", "Illuminamento"),
|
|
84928
85511
|
unit: "lx",
|
|
@@ -85125,7 +85708,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85125
85708
|
noun: t("Humidity", "Umidità"),
|
|
85126
85709
|
state: [{
|
|
85127
85710
|
kind: "numeric",
|
|
85128
|
-
field: "
|
|
85711
|
+
field: "humidity",
|
|
85129
85712
|
quantity: t("the humidity", "l’umidità"),
|
|
85130
85713
|
label: t("Humidity", "Umidità"),
|
|
85131
85714
|
unit: "%",
|
|
@@ -85173,7 +85756,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85173
85756
|
state: [
|
|
85174
85757
|
{
|
|
85175
85758
|
kind: "numeric",
|
|
85176
|
-
field: "
|
|
85759
|
+
field: "power",
|
|
85177
85760
|
quantity: t("the power draw", "il consumo"),
|
|
85178
85761
|
label: t("Power", "Potenza"),
|
|
85179
85762
|
unit: "W",
|
|
@@ -85181,7 +85764,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85181
85764
|
},
|
|
85182
85765
|
{
|
|
85183
85766
|
kind: "numeric",
|
|
85184
|
-
field: "
|
|
85767
|
+
field: "energy",
|
|
85185
85768
|
quantity: t("the energy used", "l’energia consumata"),
|
|
85186
85769
|
label: t("Energy", "Energia"),
|
|
85187
85770
|
unit: "kWh",
|
|
@@ -85189,7 +85772,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85189
85772
|
},
|
|
85190
85773
|
{
|
|
85191
85774
|
kind: "numeric",
|
|
85192
|
-
field: "
|
|
85775
|
+
field: "voltage",
|
|
85193
85776
|
quantity: t("the voltage", "la tensione"),
|
|
85194
85777
|
label: t("Voltage", "Tensione"),
|
|
85195
85778
|
unit: "V",
|
|
@@ -85197,7 +85780,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85197
85780
|
},
|
|
85198
85781
|
{
|
|
85199
85782
|
kind: "numeric",
|
|
85200
|
-
field: "
|
|
85783
|
+
field: "current",
|
|
85201
85784
|
quantity: t("the current", "la corrente"),
|
|
85202
85785
|
label: t("Current", "Corrente"),
|
|
85203
85786
|
unit: "A",
|
|
@@ -85214,13 +85797,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85214
85797
|
label: t("Where", "Posizione"),
|
|
85215
85798
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
85216
85799
|
icon: "map-pin"
|
|
85217
|
-
}, {
|
|
85218
|
-
kind: "numeric",
|
|
85219
|
-
field: "batteryPercent",
|
|
85220
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
85221
|
-
label: t("Battery", "Batteria"),
|
|
85222
|
-
unit: "%",
|
|
85223
|
-
icon: "battery"
|
|
85224
85800
|
}]
|
|
85225
85801
|
},
|
|
85226
85802
|
"pressure-sensor": {
|
|
@@ -85228,7 +85804,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85228
85804
|
noun: t("Pressure", "Pressione"),
|
|
85229
85805
|
state: [{
|
|
85230
85806
|
kind: "numeric",
|
|
85231
|
-
field: "
|
|
85807
|
+
field: "pressure",
|
|
85232
85808
|
quantity: t("the pressure", "la pressione"),
|
|
85233
85809
|
label: t("Pressure", "Pressione"),
|
|
85234
85810
|
unit: "hPa",
|
|
@@ -85264,7 +85840,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85264
85840
|
noun: t("Temperature", "Temperatura"),
|
|
85265
85841
|
state: [{
|
|
85266
85842
|
kind: "numeric",
|
|
85267
|
-
field: "
|
|
85843
|
+
field: "temperature",
|
|
85268
85844
|
quantity: t("the temperature", "la temperatura"),
|
|
85269
85845
|
label: t("Temperature", "Temperatura"),
|
|
85270
85846
|
unit: "°C",
|
|
@@ -85335,7 +85911,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85335
85911
|
state: [
|
|
85336
85912
|
{
|
|
85337
85913
|
kind: "numeric",
|
|
85338
|
-
field: "
|
|
85914
|
+
field: "level",
|
|
85339
85915
|
quantity: t("the battery level", "il livello della batteria"),
|
|
85340
85916
|
label: t("Battery", "Batteria"),
|
|
85341
85917
|
unit: "%",
|
|
@@ -85377,7 +85953,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85377
85953
|
icon: "battery-charging"
|
|
85378
85954
|
}
|
|
85379
85955
|
],
|
|
85380
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
85956
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
85381
85957
|
extraEvents: [{
|
|
85382
85958
|
category: EventCategory.DeviceAwake,
|
|
85383
85959
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -85395,7 +85971,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85395
85971
|
noun: t("Network link", "Collegamento di rete"),
|
|
85396
85972
|
state: [{
|
|
85397
85973
|
kind: "numeric",
|
|
85398
|
-
field: "
|
|
85974
|
+
field: "signal",
|
|
85399
85975
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
85400
85976
|
label: t("Signal", "Segnale"),
|
|
85401
85977
|
unit: "%",
|
|
@@ -85488,6 +86064,8 @@ var ML = "model and training machinery — no device action";
|
|
|
85488
86064
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
85489
86065
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
85490
86066
|
var SYSTEM_CAP_VOCABULARY = {
|
|
86067
|
+
"action-source": system(INTERNAL),
|
|
86068
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
85491
86069
|
"addon-pages": system(UI_PLUMBING),
|
|
85492
86070
|
"addon-pages-source": system(UI_PLUMBING),
|
|
85493
86071
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -85684,6 +86262,31 @@ Object.freeze({
|
|
|
85684
86262
|
form: "single",
|
|
85685
86263
|
optional: false
|
|
85686
86264
|
}],
|
|
86265
|
+
"actions.get": [{
|
|
86266
|
+
name: "deviceId",
|
|
86267
|
+
form: "single",
|
|
86268
|
+
optional: true
|
|
86269
|
+
}],
|
|
86270
|
+
"actions.getLinks": [{
|
|
86271
|
+
name: "deviceId",
|
|
86272
|
+
form: "single",
|
|
86273
|
+
optional: false
|
|
86274
|
+
}],
|
|
86275
|
+
"actions.listForCamera": [{
|
|
86276
|
+
name: "deviceId",
|
|
86277
|
+
form: "single",
|
|
86278
|
+
optional: false
|
|
86279
|
+
}],
|
|
86280
|
+
"actions.run": [{
|
|
86281
|
+
name: "deviceId",
|
|
86282
|
+
form: "single",
|
|
86283
|
+
optional: true
|
|
86284
|
+
}],
|
|
86285
|
+
"actions.setLinks": [{
|
|
86286
|
+
name: "deviceId",
|
|
86287
|
+
form: "single",
|
|
86288
|
+
optional: false
|
|
86289
|
+
}],
|
|
85687
86290
|
"addonSettings.getDeviceSettings": [{
|
|
85688
86291
|
name: "deviceId",
|
|
85689
86292
|
form: "single",
|
|
@@ -89855,6 +90458,7 @@ function ingestReading(input) {
|
|
|
89855
90458
|
value: converted
|
|
89856
90459
|
};
|
|
89857
90460
|
}
|
|
90461
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
89858
90462
|
var MB = 1024 * 1024;
|
|
89859
90463
|
1024 * MB, 3072 * MB;
|
|
89860
90464
|
//#endregion
|
|
@@ -96287,10 +96891,10 @@ function batteryModeForUnit(unit) {
|
|
|
96287
96891
|
/** The canonical "value" field name for a typed sensor cap's slice. */
|
|
96288
96892
|
function valueFieldForCap(cap) {
|
|
96289
96893
|
switch (cap) {
|
|
96290
|
-
case "temperature-sensor": return "
|
|
96291
|
-
case "humidity-sensor": return "
|
|
96292
|
-
case "pressure-sensor": return "
|
|
96293
|
-
case "ambient-light-sensor": return "
|
|
96894
|
+
case "temperature-sensor": return "temperature";
|
|
96895
|
+
case "humidity-sensor": return "humidity";
|
|
96896
|
+
case "pressure-sensor": return "pressure";
|
|
96897
|
+
case "ambient-light-sensor": return "illuminance";
|
|
96294
96898
|
case "numeric-sensor": return "value";
|
|
96295
96899
|
}
|
|
96296
96900
|
}
|
|
@@ -96535,7 +97139,7 @@ var SUPPORTED_CAPS = new Set([
|
|
|
96535
97139
|
* - `'%'` (binary/bar batteries, already decoded to a percent) → the typed
|
|
96536
97140
|
* `battery` cap (which models a 0..100 percentage).
|
|
96537
97141
|
* - `'V'` (raw voltage, e.g. WS90/WH90/WS85 capacitor + soil/leaf push) →
|
|
96538
|
-
* `battery.
|
|
97142
|
+
* `battery.voltage`. A voltage has no honest percentage, so `level`
|
|
96539
97143
|
* stays null. The field lives on `battery`, so a numeric primary sensor
|
|
96540
97144
|
* and a voltage battery do not share a slice.
|
|
96541
97145
|
*/
|
|
@@ -96549,7 +97153,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96549
97153
|
/**
|
|
96550
97154
|
* Which battery cap (if any) was registered for this sensor:
|
|
96551
97155
|
* - `'percent'` → the typed `battery` cap (percentage),
|
|
96552
|
-
* - `'voltage'` → `battery.
|
|
97156
|
+
* - `'voltage'` → `battery.voltage` (level stays null),
|
|
96553
97157
|
* - `'none'` → no battery cap.
|
|
96554
97158
|
*/
|
|
96555
97159
|
batteryMode = "none";
|
|
@@ -96620,7 +97224,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96620
97224
|
this.runtimeState.setCapState(this.capName, slice);
|
|
96621
97225
|
if (this.batteryMode === "percent" && sensor.batteryUnit === "%" && typeof sensor.battery === "number") {
|
|
96622
97226
|
const next = {
|
|
96623
|
-
|
|
97227
|
+
level: Math.max(0, Math.min(100, sensor.battery)),
|
|
96624
97228
|
charging: "none",
|
|
96625
97229
|
sleeping: false,
|
|
96626
97230
|
lastUpdated: lastFetchedAt
|
|
@@ -96629,8 +97233,8 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96629
97233
|
}
|
|
96630
97234
|
if (this.batteryMode === "voltage" && sensor.batteryUnit === "V" && typeof sensor.battery === "number" && Number.isFinite(sensor.battery)) {
|
|
96631
97235
|
const next = {
|
|
96632
|
-
|
|
96633
|
-
|
|
97236
|
+
level: null,
|
|
97237
|
+
voltage: sensor.battery,
|
|
96634
97238
|
charging: "none",
|
|
96635
97239
|
sleeping: false,
|
|
96636
97240
|
lastUpdated: lastFetchedAt
|
|
@@ -96642,7 +97246,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96642
97246
|
switch (this.capName) {
|
|
96643
97247
|
case "temperature-sensor": {
|
|
96644
97248
|
const COLD = {
|
|
96645
|
-
|
|
97249
|
+
temperature: 0,
|
|
96646
97250
|
lastFetchedAt: 0
|
|
96647
97251
|
};
|
|
96648
97252
|
this.ctx.registerNativeCap(temperatureSensorCapability, { getStatus: async () => this.readSlice(COLD) });
|
|
@@ -96651,7 +97255,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96651
97255
|
}
|
|
96652
97256
|
case "humidity-sensor": {
|
|
96653
97257
|
const COLD = {
|
|
96654
|
-
|
|
97258
|
+
humidity: 0,
|
|
96655
97259
|
lastFetchedAt: 0
|
|
96656
97260
|
};
|
|
96657
97261
|
this.ctx.registerNativeCap(humiditySensorCapability, { getStatus: async () => this.readSlice(COLD) });
|
|
@@ -96660,7 +97264,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96660
97264
|
}
|
|
96661
97265
|
case "pressure-sensor": {
|
|
96662
97266
|
const COLD = {
|
|
96663
|
-
|
|
97267
|
+
pressure: 0,
|
|
96664
97268
|
lastFetchedAt: 0
|
|
96665
97269
|
};
|
|
96666
97270
|
this.ctx.registerNativeCap(pressureSensorCapability, { getStatus: async () => this.readSlice(COLD) });
|
|
@@ -96669,7 +97273,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96669
97273
|
}
|
|
96670
97274
|
case "ambient-light-sensor": {
|
|
96671
97275
|
const COLD = {
|
|
96672
|
-
|
|
97276
|
+
illuminance: 0,
|
|
96673
97277
|
lastFetchedAt: 0
|
|
96674
97278
|
};
|
|
96675
97279
|
this.ctx.registerNativeCap(ambientLightSensorCapability, { getStatus: async () => this.readSlice(COLD) });
|
|
@@ -96688,8 +97292,8 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96688
97292
|
}
|
|
96689
97293
|
}
|
|
96690
97294
|
/**
|
|
96691
|
-
* Register the `battery` cap. Percent batteries fill `
|
|
96692
|
-
* batteries fill `
|
|
97295
|
+
* Register the `battery` cap. Percent batteries fill `level`. Voltage
|
|
97296
|
+
* batteries fill `voltage` and leave `level` null.
|
|
96693
97297
|
*/
|
|
96694
97298
|
maybeRegisterBatteryCap() {
|
|
96695
97299
|
const sensor = this.resolveSensor();
|
|
@@ -96701,7 +97305,7 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96701
97305
|
/** Register the typed `battery` (percentage) cap for a `%`-unit battery. */
|
|
96702
97306
|
registerPercentBatteryCap() {
|
|
96703
97307
|
const COLD = {
|
|
96704
|
-
|
|
97308
|
+
level: 0,
|
|
96705
97309
|
charging: "none",
|
|
96706
97310
|
sleeping: false,
|
|
96707
97311
|
lastUpdated: 0
|
|
@@ -96716,11 +97320,11 @@ var EcowittSensorDevice = class extends BaseDevice {
|
|
|
96716
97320
|
this.runtimeState.setCapState("battery", COLD);
|
|
96717
97321
|
this.batteryMode = "percent";
|
|
96718
97322
|
}
|
|
96719
|
-
/** Voltage batteries share the `battery` cap. `
|
|
97323
|
+
/** Voltage batteries share the `battery` cap. `level` stays unknown. */
|
|
96720
97324
|
registerVoltageBatteryCap() {
|
|
96721
97325
|
const COLD = {
|
|
96722
|
-
|
|
96723
|
-
|
|
97326
|
+
level: null,
|
|
97327
|
+
voltage: null,
|
|
96724
97328
|
charging: "unknown",
|
|
96725
97329
|
sleeping: false,
|
|
96726
97330
|
lastUpdated: 0
|