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