@camstack/addon-provider-tuya 0.2.147 → 0.2.148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/addon.js +843 -239
- package/dist/addon.mjs +843 -239
- package/package.json +1 -1
package/dist/addon.mjs
CHANGED
|
@@ -818,7 +818,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
|
|
|
818
818
|
return [...byId.values()];
|
|
819
819
|
}
|
|
820
820
|
//#endregion
|
|
821
|
-
//#region ../types/dist/event-category-
|
|
821
|
+
//#region ../types/dist/event-category-DmZDPDf_.mjs
|
|
822
822
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
823
823
|
EventCategory["SystemBoot"] = "system.boot";
|
|
824
824
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1445,7 +1445,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1445
1445
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
1446
1446
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
1447
1447
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
1448
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
1448
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
1449
1449
|
*/
|
|
1450
1450
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
1451
1451
|
/**
|
|
@@ -1583,6 +1583,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1583
1583
|
*/
|
|
1584
1584
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
1585
1585
|
/**
|
|
1586
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
1587
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
1588
|
+
*/
|
|
1589
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
1590
|
+
/**
|
|
1586
1591
|
* Progress update from a running model conversion job.
|
|
1587
1592
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
1588
1593
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -6261,7 +6266,7 @@ var ZodIssueCode = {
|
|
|
6261
6266
|
var ZodFirstPartyTypeKind;
|
|
6262
6267
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6263
6268
|
//#endregion
|
|
6264
|
-
//#region ../types/dist/sleep
|
|
6269
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
6265
6270
|
/**
|
|
6266
6271
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6267
6272
|
* window to float samples (D455).
|
|
@@ -9381,6 +9386,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
9381
9386
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
9382
9387
|
var CAP_NAMES = Object.freeze([
|
|
9383
9388
|
"accessories",
|
|
9389
|
+
"action-source",
|
|
9390
|
+
"actions",
|
|
9384
9391
|
"addon-pages",
|
|
9385
9392
|
"addon-pages-source",
|
|
9386
9393
|
"addon-routes",
|
|
@@ -9569,11 +9576,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
9569
9576
|
Object.freeze({
|
|
9570
9577
|
"air-quality-sensor": [
|
|
9571
9578
|
{
|
|
9572
|
-
"path": "
|
|
9579
|
+
"path": "co2",
|
|
9573
9580
|
"valueType": "number"
|
|
9574
9581
|
},
|
|
9575
9582
|
{
|
|
9576
|
-
"path": "
|
|
9583
|
+
"path": "voc",
|
|
9577
9584
|
"valueType": "number"
|
|
9578
9585
|
},
|
|
9579
9586
|
{
|
|
@@ -9623,7 +9630,7 @@ Object.freeze({
|
|
|
9623
9630
|
}
|
|
9624
9631
|
],
|
|
9625
9632
|
"ambient-light-sensor": [{
|
|
9626
|
-
"path": "
|
|
9633
|
+
"path": "illuminance",
|
|
9627
9634
|
"valueType": "number"
|
|
9628
9635
|
}],
|
|
9629
9636
|
"audio-metrics": [
|
|
@@ -9684,7 +9691,7 @@ Object.freeze({
|
|
|
9684
9691
|
],
|
|
9685
9692
|
"battery": [
|
|
9686
9693
|
{
|
|
9687
|
-
"path": "
|
|
9694
|
+
"path": "level",
|
|
9688
9695
|
"valueType": "number"
|
|
9689
9696
|
},
|
|
9690
9697
|
{
|
|
@@ -9706,7 +9713,7 @@ Object.freeze({
|
|
|
9706
9713
|
"valueType": "number"
|
|
9707
9714
|
},
|
|
9708
9715
|
{
|
|
9709
|
-
"path": "
|
|
9716
|
+
"path": "voltage",
|
|
9710
9717
|
"valueType": "number"
|
|
9711
9718
|
},
|
|
9712
9719
|
{
|
|
@@ -9727,7 +9734,7 @@ Object.freeze({
|
|
|
9727
9734
|
"valueType": "boolean"
|
|
9728
9735
|
}],
|
|
9729
9736
|
"brightness": [{
|
|
9730
|
-
"path": "
|
|
9737
|
+
"path": "level",
|
|
9731
9738
|
"valueType": "number"
|
|
9732
9739
|
}],
|
|
9733
9740
|
"broker": [{
|
|
@@ -9928,7 +9935,7 @@ Object.freeze({
|
|
|
9928
9935
|
"valueType": "number"
|
|
9929
9936
|
},
|
|
9930
9937
|
{
|
|
9931
|
-
"path": "
|
|
9938
|
+
"path": "colorTemperature",
|
|
9932
9939
|
"valueType": "number"
|
|
9933
9940
|
}
|
|
9934
9941
|
],
|
|
@@ -10107,15 +10114,15 @@ Object.freeze({
|
|
|
10107
10114
|
"valueType": "string"
|
|
10108
10115
|
},
|
|
10109
10116
|
{
|
|
10110
|
-
"path": "
|
|
10117
|
+
"path": "remaining",
|
|
10111
10118
|
"valueType": "number"
|
|
10112
10119
|
},
|
|
10113
10120
|
{
|
|
10114
|
-
"path": "
|
|
10121
|
+
"path": "delayedStart",
|
|
10115
10122
|
"valueType": "number"
|
|
10116
10123
|
},
|
|
10117
10124
|
{
|
|
10118
|
-
"path": "
|
|
10125
|
+
"path": "progress",
|
|
10119
10126
|
"valueType": "number"
|
|
10120
10127
|
},
|
|
10121
10128
|
{
|
|
@@ -10229,7 +10236,7 @@ Object.freeze({
|
|
|
10229
10236
|
],
|
|
10230
10237
|
"fan-control": [
|
|
10231
10238
|
{
|
|
10232
|
-
"path": "
|
|
10239
|
+
"path": "speed",
|
|
10233
10240
|
"valueType": "number"
|
|
10234
10241
|
},
|
|
10235
10242
|
{
|
|
@@ -10329,7 +10336,7 @@ Object.freeze({
|
|
|
10329
10336
|
}
|
|
10330
10337
|
],
|
|
10331
10338
|
"humidity-sensor": [{
|
|
10332
|
-
"path": "
|
|
10339
|
+
"path": "humidity",
|
|
10333
10340
|
"valueType": "number"
|
|
10334
10341
|
}],
|
|
10335
10342
|
"image": [{
|
|
@@ -10439,7 +10446,7 @@ Object.freeze({
|
|
|
10439
10446
|
"valueType": "number"
|
|
10440
10447
|
},
|
|
10441
10448
|
{
|
|
10442
|
-
"path": "
|
|
10449
|
+
"path": "progress",
|
|
10443
10450
|
"valueType": "number"
|
|
10444
10451
|
},
|
|
10445
10452
|
{
|
|
@@ -10518,11 +10525,11 @@ Object.freeze({
|
|
|
10518
10525
|
"valueType": "string"
|
|
10519
10526
|
},
|
|
10520
10527
|
{
|
|
10521
|
-
"path": "
|
|
10528
|
+
"path": "position",
|
|
10522
10529
|
"valueType": "number"
|
|
10523
10530
|
},
|
|
10524
10531
|
{
|
|
10525
|
-
"path": "
|
|
10532
|
+
"path": "duration",
|
|
10526
10533
|
"valueType": "number"
|
|
10527
10534
|
},
|
|
10528
10535
|
{
|
|
@@ -10624,11 +10631,11 @@ Object.freeze({
|
|
|
10624
10631
|
]
|
|
10625
10632
|
},
|
|
10626
10633
|
{
|
|
10627
|
-
"path": "
|
|
10634
|
+
"path": "signal",
|
|
10628
10635
|
"valueType": "number"
|
|
10629
10636
|
},
|
|
10630
10637
|
{
|
|
10631
|
-
"path": "
|
|
10638
|
+
"path": "rssi",
|
|
10632
10639
|
"valueType": "number"
|
|
10633
10640
|
},
|
|
10634
10641
|
{
|
|
@@ -10683,6 +10690,18 @@ Object.freeze({
|
|
|
10683
10690
|
"path": "foodLevel",
|
|
10684
10691
|
"valueType": "number"
|
|
10685
10692
|
},
|
|
10693
|
+
{
|
|
10694
|
+
"path": "bowlFood",
|
|
10695
|
+
"valueType": "number"
|
|
10696
|
+
},
|
|
10697
|
+
{
|
|
10698
|
+
"path": "eating",
|
|
10699
|
+
"valueType": "boolean"
|
|
10700
|
+
},
|
|
10701
|
+
{
|
|
10702
|
+
"path": "supportsMarkRefilled",
|
|
10703
|
+
"valueType": "boolean"
|
|
10704
|
+
},
|
|
10686
10705
|
{
|
|
10687
10706
|
"path": "food1",
|
|
10688
10707
|
"valueType": "number"
|
|
@@ -10747,23 +10766,23 @@ Object.freeze({
|
|
|
10747
10766
|
],
|
|
10748
10767
|
"power-meter": [
|
|
10749
10768
|
{
|
|
10750
|
-
"path": "
|
|
10769
|
+
"path": "power",
|
|
10751
10770
|
"valueType": "number"
|
|
10752
10771
|
},
|
|
10753
10772
|
{
|
|
10754
|
-
"path": "
|
|
10773
|
+
"path": "energy",
|
|
10755
10774
|
"valueType": "number"
|
|
10756
10775
|
},
|
|
10757
10776
|
{
|
|
10758
|
-
"path": "
|
|
10777
|
+
"path": "voltage",
|
|
10759
10778
|
"valueType": "number"
|
|
10760
10779
|
},
|
|
10761
10780
|
{
|
|
10762
|
-
"path": "
|
|
10781
|
+
"path": "current",
|
|
10763
10782
|
"valueType": "number"
|
|
10764
10783
|
},
|
|
10765
10784
|
{
|
|
10766
|
-
"path": "
|
|
10785
|
+
"path": "apparentPower",
|
|
10767
10786
|
"valueType": "number"
|
|
10768
10787
|
},
|
|
10769
10788
|
{
|
|
@@ -10791,14 +10810,10 @@ Object.freeze({
|
|
|
10791
10810
|
{
|
|
10792
10811
|
"path": "gps.accuracyMeters",
|
|
10793
10812
|
"valueType": "number"
|
|
10794
|
-
},
|
|
10795
|
-
{
|
|
10796
|
-
"path": "batteryPercent",
|
|
10797
|
-
"valueType": "number"
|
|
10798
10813
|
}
|
|
10799
10814
|
],
|
|
10800
10815
|
"pressure-sensor": [{
|
|
10801
|
-
"path": "
|
|
10816
|
+
"path": "pressure",
|
|
10802
10817
|
"valueType": "number"
|
|
10803
10818
|
}],
|
|
10804
10819
|
"privacy-mask": [{
|
|
@@ -11112,7 +11127,7 @@ Object.freeze({
|
|
|
11112
11127
|
"valueType": "boolean"
|
|
11113
11128
|
}],
|
|
11114
11129
|
"temperature-sensor": [{
|
|
11115
|
-
"path": "
|
|
11130
|
+
"path": "temperature",
|
|
11116
11131
|
"valueType": "number"
|
|
11117
11132
|
}],
|
|
11118
11133
|
"update": [
|
|
@@ -11160,7 +11175,7 @@ Object.freeze({
|
|
|
11160
11175
|
"valueType": "string"
|
|
11161
11176
|
},
|
|
11162
11177
|
{
|
|
11163
|
-
"path": "
|
|
11178
|
+
"path": "progress",
|
|
11164
11179
|
"valueType": "number"
|
|
11165
11180
|
},
|
|
11166
11181
|
{
|
|
@@ -11645,7 +11660,7 @@ function errMsg(err) {
|
|
|
11645
11660
|
return String(err);
|
|
11646
11661
|
}
|
|
11647
11662
|
//#endregion
|
|
11648
|
-
//#region ../types/dist/composition-
|
|
11663
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
11649
11664
|
/**
|
|
11650
11665
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11651
11666
|
*
|
|
@@ -16165,6 +16180,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
16165
16180
|
array(union([string(), number()]))
|
|
16166
16181
|
])
|
|
16167
16182
|
});
|
|
16183
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
16184
|
+
kind: literal("stationary-present"),
|
|
16185
|
+
deviceId: number().int().nonnegative(),
|
|
16186
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
16187
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16188
|
+
/** The parked object must be in at least one of these zones. */
|
|
16189
|
+
zones: array(string().min(1)).min(1).optional()
|
|
16190
|
+
});
|
|
16168
16191
|
/**
|
|
16169
16192
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
16170
16193
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -16198,7 +16221,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
16198
16221
|
child: AutomationConditionSchema
|
|
16199
16222
|
}),
|
|
16200
16223
|
AutomationConditionLeafSchema,
|
|
16201
|
-
AutomationConditionExpressionSchema
|
|
16224
|
+
AutomationConditionExpressionSchema,
|
|
16225
|
+
AutomationConditionStationaryPresentSchema
|
|
16202
16226
|
]));
|
|
16203
16227
|
/**
|
|
16204
16228
|
* What starts a run.
|
|
@@ -16239,7 +16263,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
16239
16263
|
kind: literal("schedule"),
|
|
16240
16264
|
cron: string().min(1).max(120)
|
|
16241
16265
|
}),
|
|
16242
|
-
object({ kind: literal("manual") })
|
|
16266
|
+
object({ kind: literal("manual") }),
|
|
16267
|
+
object({
|
|
16268
|
+
kind: literal("detection"),
|
|
16269
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
16270
|
+
* matches every raw class that maps to it; any other name matches
|
|
16271
|
+
* exactly. */
|
|
16272
|
+
classes: array(string().min(1)).min(1),
|
|
16273
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
16274
|
+
/** The track must have visited at least one of these zones. */
|
|
16275
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16276
|
+
/** Best-so-far confidence the track must reach. */
|
|
16277
|
+
minScore: number().min(0).max(1).optional()
|
|
16278
|
+
}),
|
|
16279
|
+
object({
|
|
16280
|
+
kind: literal("stationary"),
|
|
16281
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
16282
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
16283
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16284
|
+
/** The parked object must be in at least one of these zones. */
|
|
16285
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16286
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
16287
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
16288
|
+
phase: _enum(["appeared", "departed"])
|
|
16289
|
+
}),
|
|
16290
|
+
object({
|
|
16291
|
+
kind: literal("interval"),
|
|
16292
|
+
minutes: number().int().min(1).max(1440)
|
|
16293
|
+
})
|
|
16243
16294
|
]);
|
|
16244
16295
|
/**
|
|
16245
16296
|
* One action step.
|
|
@@ -16259,28 +16310,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
16259
16310
|
* is called. The runner still receives a number and is untouched; the
|
|
16260
16311
|
* resolution is the recipe's job, not the runner's.
|
|
16261
16312
|
*/
|
|
16313
|
+
var AutomationWaitStepSchema = object({
|
|
16314
|
+
kind: literal("wait"),
|
|
16315
|
+
seconds: number().min(0).max(300)
|
|
16316
|
+
});
|
|
16317
|
+
var AutomationCapStepSchema = object({
|
|
16318
|
+
kind: literal("cap"),
|
|
16319
|
+
/**
|
|
16320
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
16321
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
16322
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
16323
|
+
*/
|
|
16324
|
+
deviceId: union([
|
|
16325
|
+
number().int(),
|
|
16326
|
+
array(number().int()).min(1),
|
|
16327
|
+
object({ $var: string().min(1) })
|
|
16328
|
+
]),
|
|
16329
|
+
cap: string().min(1),
|
|
16330
|
+
method: string().min(1),
|
|
16331
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16332
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16333
|
+
* the expression leaf. */
|
|
16334
|
+
args: record(string(), unknown()).optional()
|
|
16335
|
+
});
|
|
16336
|
+
/**
|
|
16337
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
16338
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
16339
|
+
*/
|
|
16340
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
16262
16341
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
16342
|
+
AutomationWaitStepSchema,
|
|
16343
|
+
AutomationCapStepSchema,
|
|
16263
16344
|
object({
|
|
16264
|
-
kind: literal("
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
*/
|
|
16274
|
-
deviceId: union([
|
|
16275
|
-
number().int(),
|
|
16276
|
-
array(number().int()).min(1),
|
|
16277
|
-
object({ $var: string().min(1) })
|
|
16278
|
-
]),
|
|
16279
|
-
cap: string().min(1),
|
|
16280
|
-
method: string().min(1),
|
|
16281
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
16282
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
16283
|
-
args: record(string(), unknown()).optional()
|
|
16345
|
+
kind: literal("action"),
|
|
16346
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
16347
|
+
actionId: string().min(1),
|
|
16348
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
16349
|
+
variables: record(string(), union([
|
|
16350
|
+
string(),
|
|
16351
|
+
number(),
|
|
16352
|
+
boolean()
|
|
16353
|
+
])).optional()
|
|
16284
16354
|
}),
|
|
16285
16355
|
object({
|
|
16286
16356
|
kind: literal("code"),
|
|
@@ -16289,10 +16359,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
16289
16359
|
code: string().min(1).max(2e4)
|
|
16290
16360
|
})
|
|
16291
16361
|
]);
|
|
16362
|
+
/**
|
|
16363
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
16364
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
16365
|
+
* actions. Absent means `single`.
|
|
16366
|
+
*
|
|
16367
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
16368
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
16369
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
16370
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
16371
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
16372
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
16373
|
+
* wait, never the single/queued limits.
|
|
16374
|
+
*/
|
|
16375
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
16376
|
+
object({ mode: literal("single") }),
|
|
16377
|
+
object({ mode: literal("restart") }),
|
|
16378
|
+
object({
|
|
16379
|
+
mode: literal("queued"),
|
|
16380
|
+
max: number().int().min(1).max(10)
|
|
16381
|
+
}),
|
|
16382
|
+
object({
|
|
16383
|
+
mode: literal("parallel"),
|
|
16384
|
+
max: number().int().min(1).max(10)
|
|
16385
|
+
}),
|
|
16386
|
+
object({
|
|
16387
|
+
mode: literal("cooldown"),
|
|
16388
|
+
minutes: number().int().min(1).max(1440)
|
|
16389
|
+
})
|
|
16390
|
+
]);
|
|
16292
16391
|
var AutomationRecipeSchema = object({
|
|
16293
16392
|
triggers: array(AutomationTriggerSchema),
|
|
16294
16393
|
conditions: AutomationConditionSchema.optional(),
|
|
16295
|
-
actions: array(AutomationActionSchema)
|
|
16394
|
+
actions: array(AutomationActionSchema),
|
|
16395
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
16396
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
16397
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
16398
|
+
});
|
|
16399
|
+
new Set([
|
|
16400
|
+
{
|
|
16401
|
+
id: "person",
|
|
16402
|
+
name: "Person"
|
|
16403
|
+
},
|
|
16404
|
+
{
|
|
16405
|
+
id: "vehicle",
|
|
16406
|
+
name: "Vehicle"
|
|
16407
|
+
},
|
|
16408
|
+
{
|
|
16409
|
+
id: "animal",
|
|
16410
|
+
name: "Animal"
|
|
16411
|
+
},
|
|
16412
|
+
{
|
|
16413
|
+
id: "package",
|
|
16414
|
+
name: "Package"
|
|
16415
|
+
}
|
|
16416
|
+
].map((l) => l.id));
|
|
16417
|
+
var COCO_TO_MACRO = {
|
|
16418
|
+
mapping: {
|
|
16419
|
+
person: "person",
|
|
16420
|
+
bicycle: "vehicle",
|
|
16421
|
+
car: "vehicle",
|
|
16422
|
+
motorcycle: "vehicle",
|
|
16423
|
+
airplane: "vehicle",
|
|
16424
|
+
bus: "vehicle",
|
|
16425
|
+
train: "vehicle",
|
|
16426
|
+
truck: "vehicle",
|
|
16427
|
+
boat: "vehicle",
|
|
16428
|
+
bird: "animal",
|
|
16429
|
+
cat: "animal",
|
|
16430
|
+
dog: "animal",
|
|
16431
|
+
horse: "animal",
|
|
16432
|
+
sheep: "animal",
|
|
16433
|
+
cow: "animal",
|
|
16434
|
+
elephant: "animal",
|
|
16435
|
+
bear: "animal",
|
|
16436
|
+
zebra: "animal",
|
|
16437
|
+
giraffe: "animal",
|
|
16438
|
+
suitcase: "package",
|
|
16439
|
+
backpack: "package",
|
|
16440
|
+
handbag: "package"
|
|
16441
|
+
},
|
|
16442
|
+
preserveOriginal: false
|
|
16443
|
+
};
|
|
16444
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
16445
|
+
/**
|
|
16446
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
16447
|
+
* so the editor can paint every block green or red with its reason.
|
|
16448
|
+
*
|
|
16449
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
16450
|
+
* every condition node (containers and leaves, including the ones a
|
|
16451
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
16452
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
16453
|
+
* for an Action run). Skipped
|
|
16454
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
16455
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
16456
|
+
*
|
|
16457
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
16458
|
+
* vocabulary so an Action run records the same step shape.
|
|
16459
|
+
*/
|
|
16460
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
16461
|
+
var TraceValueSchema = union([
|
|
16462
|
+
string(),
|
|
16463
|
+
number(),
|
|
16464
|
+
boolean(),
|
|
16465
|
+
_null(),
|
|
16466
|
+
array(union([string(), number()]))
|
|
16467
|
+
]);
|
|
16468
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
16469
|
+
"ran",
|
|
16470
|
+
"skipped-trigger",
|
|
16471
|
+
"skipped-conditions",
|
|
16472
|
+
"skipped-cooldown",
|
|
16473
|
+
"skipped-overlap",
|
|
16474
|
+
"failed",
|
|
16475
|
+
"aborted"
|
|
16476
|
+
]);
|
|
16477
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
16478
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
16479
|
+
"pass",
|
|
16480
|
+
"fail",
|
|
16481
|
+
"not-evaluated"
|
|
16482
|
+
]);
|
|
16483
|
+
var AutomationTriggerTraceSchema = object({
|
|
16484
|
+
kind: string().min(1),
|
|
16485
|
+
outcome: _enum(["pass", "fail"]),
|
|
16486
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
16487
|
+
reason: string(),
|
|
16488
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
16489
|
+
vars: record(string(), TraceValueSchema)
|
|
16490
|
+
});
|
|
16491
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
16492
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
16493
|
+
path: string().min(1),
|
|
16494
|
+
kind: _enum([
|
|
16495
|
+
"all",
|
|
16496
|
+
"any",
|
|
16497
|
+
"not",
|
|
16498
|
+
"condition",
|
|
16499
|
+
"expression",
|
|
16500
|
+
"stationary-present"
|
|
16501
|
+
]),
|
|
16502
|
+
outcome: TraceNodeOutcomeSchema,
|
|
16503
|
+
reason: string(),
|
|
16504
|
+
deviceId: number().int().optional(),
|
|
16505
|
+
cap: string().optional(),
|
|
16506
|
+
fieldPath: string().optional(),
|
|
16507
|
+
operator: string().optional(),
|
|
16508
|
+
expected: TraceValueSchema.optional(),
|
|
16509
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
16510
|
+
observed: TraceValueSchema.optional()
|
|
16511
|
+
});
|
|
16512
|
+
var AutomationRunVerdictSchema = object({
|
|
16513
|
+
mode: AutomationRunModeSchema,
|
|
16514
|
+
decision: _enum([
|
|
16515
|
+
"run",
|
|
16516
|
+
"queued",
|
|
16517
|
+
"restart",
|
|
16518
|
+
"drop",
|
|
16519
|
+
"cooldown",
|
|
16520
|
+
"bypass"
|
|
16521
|
+
]),
|
|
16522
|
+
reason: string()
|
|
16523
|
+
});
|
|
16524
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
16525
|
+
var AutomationStepTraceSchema = object({
|
|
16526
|
+
/** `actions.<i>` */
|
|
16527
|
+
path: string().min(1),
|
|
16528
|
+
kind: string().min(1),
|
|
16529
|
+
cap: string().optional(),
|
|
16530
|
+
method: string().optional(),
|
|
16531
|
+
deviceId: number().int().optional(),
|
|
16532
|
+
startedAt: number().optional(),
|
|
16533
|
+
endedAt: number().optional(),
|
|
16534
|
+
outcome: _enum([
|
|
16535
|
+
"ok",
|
|
16536
|
+
"error",
|
|
16537
|
+
"not-run"
|
|
16538
|
+
]),
|
|
16539
|
+
message: string().optional()
|
|
16540
|
+
});
|
|
16541
|
+
var AutomationRunTraceSchema = object({
|
|
16542
|
+
runId: string().min(1),
|
|
16543
|
+
startedAt: number(),
|
|
16544
|
+
endedAt: number(),
|
|
16545
|
+
trigger: AutomationTriggerTraceSchema,
|
|
16546
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
16547
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
16548
|
+
steps: array(AutomationStepTraceSchema),
|
|
16549
|
+
outcome: AutomationRunOutcomeSchema,
|
|
16550
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
16551
|
+
repeat: number().int().min(1),
|
|
16552
|
+
/** When the latest of those repeats happened. */
|
|
16553
|
+
lastAt: number()
|
|
16554
|
+
});
|
|
16555
|
+
/**
|
|
16556
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
16557
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
16558
|
+
*/
|
|
16559
|
+
var AutomationStateDocSchema = object({
|
|
16560
|
+
version: literal(1),
|
|
16561
|
+
lastRunStartedAt: number().nullable(),
|
|
16562
|
+
traces: array(AutomationRunTraceSchema)
|
|
16563
|
+
});
|
|
16564
|
+
/**
|
|
16565
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
16566
|
+
* declared as LIST ENTRIES, never as devices.
|
|
16567
|
+
*
|
|
16568
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
16569
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
16570
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
16571
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
16572
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
16573
|
+
*
|
|
16574
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
16575
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
16576
|
+
* runtime.
|
|
16577
|
+
*/
|
|
16578
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
16579
|
+
var ActionVariableTypeSchema = _enum([
|
|
16580
|
+
"string",
|
|
16581
|
+
"number",
|
|
16582
|
+
"boolean",
|
|
16583
|
+
"select"
|
|
16584
|
+
]);
|
|
16585
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16586
|
+
var ActionVariableValueSchema = union([
|
|
16587
|
+
string(),
|
|
16588
|
+
number(),
|
|
16589
|
+
boolean()
|
|
16590
|
+
]);
|
|
16591
|
+
/**
|
|
16592
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
16593
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
16594
|
+
*/
|
|
16595
|
+
var ActionVariableSchema = object({
|
|
16596
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
16597
|
+
label: string().min(1).max(120).optional(),
|
|
16598
|
+
type: ActionVariableTypeSchema,
|
|
16599
|
+
required: boolean().optional(),
|
|
16600
|
+
default: ActionVariableValueSchema.optional(),
|
|
16601
|
+
/** The allowed values of a `select`. */
|
|
16602
|
+
options: array(string().min(1)).min(1).optional()
|
|
16603
|
+
}).superRefine((v, ctx) => {
|
|
16604
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
16605
|
+
code: "custom",
|
|
16606
|
+
message: "a select variable needs options",
|
|
16607
|
+
path: ["options"]
|
|
16608
|
+
});
|
|
16609
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
16610
|
+
code: "custom",
|
|
16611
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
16612
|
+
path: ["default"]
|
|
16613
|
+
});
|
|
16614
|
+
});
|
|
16615
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
16616
|
+
function variableValueError(variable, value) {
|
|
16617
|
+
switch (variable.type) {
|
|
16618
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
16619
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
16620
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
16621
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
16622
|
+
}
|
|
16623
|
+
}
|
|
16624
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
16625
|
+
function isInternalActionId(actionId) {
|
|
16626
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
16627
|
+
}
|
|
16628
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
16629
|
+
function addonIdOfActionId(actionId) {
|
|
16630
|
+
if (isInternalActionId(actionId)) return null;
|
|
16631
|
+
const at = actionId.indexOf(":");
|
|
16632
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
16633
|
+
}
|
|
16634
|
+
var ActionStatusSchema = object({
|
|
16635
|
+
isRunning: boolean(),
|
|
16636
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
16637
|
+
lastRunAt: number().nullable(),
|
|
16638
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
16639
|
+
lastError: string().nullable()
|
|
16640
|
+
});
|
|
16641
|
+
var ActionEntrySchema = object({
|
|
16642
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
16643
|
+
id: string().min(3),
|
|
16644
|
+
name: string().min(1).max(120),
|
|
16645
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
16646
|
+
addonId: string().min(1),
|
|
16647
|
+
source: ActionSourceKindSchema,
|
|
16648
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
16649
|
+
readOnly: boolean(),
|
|
16650
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
16651
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
16652
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
16653
|
+
status: ActionStatusSchema
|
|
16654
|
+
}).superRefine((entry, ctx) => {
|
|
16655
|
+
if (entry.source === "internal") {
|
|
16656
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
16657
|
+
code: "custom",
|
|
16658
|
+
message: "an internal action id is internal:<uuid>",
|
|
16659
|
+
path: ["id"]
|
|
16660
|
+
});
|
|
16661
|
+
return;
|
|
16662
|
+
}
|
|
16663
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
16664
|
+
code: "custom",
|
|
16665
|
+
message: "only an internal action carries steps",
|
|
16666
|
+
path: ["steps"]
|
|
16667
|
+
});
|
|
16668
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
16669
|
+
code: "custom",
|
|
16670
|
+
message: "an addon action is read-only here",
|
|
16671
|
+
path: ["readOnly"]
|
|
16672
|
+
});
|
|
16673
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
16674
|
+
code: "custom",
|
|
16675
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
16676
|
+
path: ["id"]
|
|
16677
|
+
});
|
|
16678
|
+
});
|
|
16679
|
+
/** What an operator writes for an internal action. */
|
|
16680
|
+
var ActionInputSchema = object({
|
|
16681
|
+
name: string().min(1).max(120),
|
|
16682
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
16683
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
16684
|
+
});
|
|
16685
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
16686
|
+
var ActionRunOriginSchema = object({
|
|
16687
|
+
/** The automation block whose step started it. */
|
|
16688
|
+
blockId: string().min(1).optional() });
|
|
16689
|
+
/** `started` = the caller did not ask to wait. */
|
|
16690
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
16691
|
+
var ActionRunResultSchema = object({
|
|
16692
|
+
runId: string().min(1),
|
|
16693
|
+
outcome: ActionRunOutcomeSchema,
|
|
16694
|
+
/** Why it did not run, or what failed. */
|
|
16695
|
+
message: string().optional()
|
|
16696
|
+
});
|
|
16697
|
+
_enum([
|
|
16698
|
+
"not-found",
|
|
16699
|
+
"read-only",
|
|
16700
|
+
"invalid-variables",
|
|
16701
|
+
"invalid-steps",
|
|
16702
|
+
"not-linked",
|
|
16703
|
+
"busy"
|
|
16704
|
+
]);
|
|
16705
|
+
object({
|
|
16706
|
+
actionId: string(),
|
|
16707
|
+
runId: string(),
|
|
16708
|
+
isRunning: boolean(),
|
|
16709
|
+
/** Set when the run ended. */
|
|
16710
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
16711
|
+
lastRunAt: number().nullable(),
|
|
16712
|
+
lastError: string().nullable()
|
|
16296
16713
|
});
|
|
16297
16714
|
/**
|
|
16298
16715
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18979,7 +19396,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18979
19396
|
stateField: string(),
|
|
18980
19397
|
fieldKey: string()
|
|
18981
19398
|
});
|
|
18982
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
19399
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18983
19400
|
var CompositionProblemSchema = object({
|
|
18984
19401
|
code: _enum([
|
|
18985
19402
|
"reserved-variant",
|
|
@@ -19298,7 +19715,7 @@ var GROUP_TEMPLATES = [
|
|
|
19298
19715
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
19299
19716
|
role: DeviceRole.TemperatureSensor,
|
|
19300
19717
|
outputCap: "temperature-sensor",
|
|
19301
|
-
outputField: "
|
|
19718
|
+
outputField: "temperature",
|
|
19302
19719
|
quantity: "temperature",
|
|
19303
19720
|
defaultAggregate: "mean",
|
|
19304
19721
|
empty: "null",
|
|
@@ -19309,7 +19726,7 @@ var GROUP_TEMPLATES = [
|
|
|
19309
19726
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19310
19727
|
role: DeviceRole.HumiditySensor,
|
|
19311
19728
|
outputCap: "humidity-sensor",
|
|
19312
|
-
outputField: "
|
|
19729
|
+
outputField: "humidity",
|
|
19313
19730
|
quantity: "humidity",
|
|
19314
19731
|
defaultAggregate: "mean",
|
|
19315
19732
|
empty: "null",
|
|
@@ -19320,7 +19737,7 @@ var GROUP_TEMPLATES = [
|
|
|
19320
19737
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
19321
19738
|
role: DeviceRole.PressureSensor,
|
|
19322
19739
|
outputCap: "pressure-sensor",
|
|
19323
|
-
outputField: "
|
|
19740
|
+
outputField: "pressure",
|
|
19324
19741
|
quantity: "pressure",
|
|
19325
19742
|
defaultAggregate: "mean",
|
|
19326
19743
|
empty: "null",
|
|
@@ -19331,7 +19748,7 @@ var GROUP_TEMPLATES = [
|
|
|
19331
19748
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
19332
19749
|
role: DeviceRole.AmbientLightSensor,
|
|
19333
19750
|
outputCap: "ambient-light-sensor",
|
|
19334
|
-
outputField: "
|
|
19751
|
+
outputField: "illuminance",
|
|
19335
19752
|
quantity: "illuminance",
|
|
19336
19753
|
defaultAggregate: "mean",
|
|
19337
19754
|
empty: "null",
|
|
@@ -19342,7 +19759,7 @@ var GROUP_TEMPLATES = [
|
|
|
19342
19759
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
19343
19760
|
role: DeviceRole.PowerSensor,
|
|
19344
19761
|
outputCap: "power-meter",
|
|
19345
|
-
outputField: "
|
|
19762
|
+
outputField: "power",
|
|
19346
19763
|
quantity: "power",
|
|
19347
19764
|
defaultAggregate: "sum",
|
|
19348
19765
|
empty: "omit",
|
|
@@ -19353,7 +19770,7 @@ var GROUP_TEMPLATES = [
|
|
|
19353
19770
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
19354
19771
|
role: DeviceRole.EnergySensor,
|
|
19355
19772
|
outputCap: "power-meter",
|
|
19356
|
-
outputField: "
|
|
19773
|
+
outputField: "energy",
|
|
19357
19774
|
quantity: "energy",
|
|
19358
19775
|
defaultAggregate: "sum",
|
|
19359
19776
|
empty: "omit",
|
|
@@ -19364,7 +19781,7 @@ var GROUP_TEMPLATES = [
|
|
|
19364
19781
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19365
19782
|
role: DeviceRole.BatterySensor,
|
|
19366
19783
|
outputCap: "battery",
|
|
19367
|
-
outputField: "
|
|
19784
|
+
outputField: "level",
|
|
19368
19785
|
quantity: "percentage",
|
|
19369
19786
|
defaultAggregate: "mean",
|
|
19370
19787
|
empty: "null",
|
|
@@ -19942,7 +20359,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19942
20359
|
kind: "mutation",
|
|
19943
20360
|
auth: "admin",
|
|
19944
20361
|
access: "view"
|
|
19945
|
-
})
|
|
20362
|
+
}), method(object({
|
|
20363
|
+
blockId: string().min(1),
|
|
20364
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
20365
|
+
runStartedAt: number().optional(),
|
|
20366
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
20367
|
+
}), _void(), {
|
|
20368
|
+
kind: "mutation",
|
|
20369
|
+
auth: "admin"
|
|
20370
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
20371
|
+
traces: array(AutomationRunTraceSchema),
|
|
20372
|
+
lastError: string().nullable()
|
|
20373
|
+
}), { auth: "admin" });
|
|
19946
20374
|
/**
|
|
19947
20375
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19948
20376
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -45244,51 +45672,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
45244
45672
|
kind: "mutation",
|
|
45245
45673
|
auth: "admin"
|
|
45246
45674
|
});
|
|
45247
|
-
new Set([
|
|
45248
|
-
{
|
|
45249
|
-
id: "person",
|
|
45250
|
-
name: "Person"
|
|
45251
|
-
},
|
|
45252
|
-
{
|
|
45253
|
-
id: "vehicle",
|
|
45254
|
-
name: "Vehicle"
|
|
45255
|
-
},
|
|
45256
|
-
{
|
|
45257
|
-
id: "animal",
|
|
45258
|
-
name: "Animal"
|
|
45259
|
-
},
|
|
45260
|
-
{
|
|
45261
|
-
id: "package",
|
|
45262
|
-
name: "Package"
|
|
45263
|
-
}
|
|
45264
|
-
].map((l) => l.id));
|
|
45265
|
-
var COCO_TO_MACRO = {
|
|
45266
|
-
mapping: {
|
|
45267
|
-
person: "person",
|
|
45268
|
-
bicycle: "vehicle",
|
|
45269
|
-
car: "vehicle",
|
|
45270
|
-
motorcycle: "vehicle",
|
|
45271
|
-
airplane: "vehicle",
|
|
45272
|
-
bus: "vehicle",
|
|
45273
|
-
train: "vehicle",
|
|
45274
|
-
truck: "vehicle",
|
|
45275
|
-
boat: "vehicle",
|
|
45276
|
-
bird: "animal",
|
|
45277
|
-
cat: "animal",
|
|
45278
|
-
dog: "animal",
|
|
45279
|
-
horse: "animal",
|
|
45280
|
-
sheep: "animal",
|
|
45281
|
-
cow: "animal",
|
|
45282
|
-
elephant: "animal",
|
|
45283
|
-
bear: "animal",
|
|
45284
|
-
zebra: "animal",
|
|
45285
|
-
giraffe: "animal",
|
|
45286
|
-
suitcase: "package",
|
|
45287
|
-
backpack: "package",
|
|
45288
|
-
handbag: "package"
|
|
45289
|
-
},
|
|
45290
|
-
preserveOriginal: false
|
|
45291
|
-
};
|
|
45292
45675
|
var AUDIO_MACRO_LABELS = [
|
|
45293
45676
|
{
|
|
45294
45677
|
id: "speech",
|
|
@@ -57855,9 +58238,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57855
58238
|
*/
|
|
57856
58239
|
var AirQualitySensorStatusSchema = object({
|
|
57857
58240
|
/** Carbon dioxide concentration in ppm. */
|
|
57858
|
-
|
|
58241
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57859
58242
|
/** Total volatile organic compounds in ppb. */
|
|
57860
|
-
|
|
58243
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57861
58244
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57862
58245
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57863
58246
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -57890,12 +58273,12 @@ var airQualitySensorCapability = {
|
|
|
57890
58273
|
* History (D850): recorded series.
|
|
57891
58274
|
*/
|
|
57892
58275
|
history: { fields: {
|
|
57893
|
-
|
|
58276
|
+
co2: {
|
|
57894
58277
|
kind: "gauge",
|
|
57895
58278
|
unit: "ppm",
|
|
57896
58279
|
deadband: 5
|
|
57897
58280
|
},
|
|
57898
|
-
|
|
58281
|
+
voc: {
|
|
57899
58282
|
kind: "gauge",
|
|
57900
58283
|
unit: "ppb",
|
|
57901
58284
|
deadband: 5
|
|
@@ -57926,7 +58309,7 @@ var airQualitySensorCapability = {
|
|
|
57926
58309
|
*/
|
|
57927
58310
|
var AmbientLightSensorStatusSchema = object({
|
|
57928
58311
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57929
|
-
|
|
58312
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57930
58313
|
precision: 0,
|
|
57931
58314
|
label: "Illuminance"
|
|
57932
58315
|
})),
|
|
@@ -57955,7 +58338,7 @@ var ambientLightSensorCapability = {
|
|
|
57955
58338
|
/**
|
|
57956
58339
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
57957
58340
|
*/
|
|
57958
|
-
history: { fields: {
|
|
58341
|
+
history: { fields: { illuminance: {
|
|
57959
58342
|
kind: "gauge",
|
|
57960
58343
|
unit: "lx",
|
|
57961
58344
|
deadbandPct: 10,
|
|
@@ -58094,6 +58477,84 @@ var audioMetricsCapability = {
|
|
|
58094
58477
|
*/
|
|
58095
58478
|
history: "none"
|
|
58096
58479
|
};
|
|
58480
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58481
|
+
actionId: string().min(1),
|
|
58482
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
58483
|
+
}), _void(), {
|
|
58484
|
+
kind: "mutation",
|
|
58485
|
+
auth: "admin"
|
|
58486
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
58487
|
+
kind: "mutation",
|
|
58488
|
+
auth: "admin"
|
|
58489
|
+
});
|
|
58490
|
+
/**
|
|
58491
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
58492
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
58493
|
+
*
|
|
58494
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
58495
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
58496
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
58497
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
58498
|
+
* drift (D3).
|
|
58499
|
+
*
|
|
58500
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
58501
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
58502
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
58503
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
58504
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
58505
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
58506
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
58507
|
+
*
|
|
58508
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
58509
|
+
* logged — never queued.
|
|
58510
|
+
*/
|
|
58511
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
58512
|
+
var ActionLinksSchema = object({
|
|
58513
|
+
deviceId: number().int().nonnegative(),
|
|
58514
|
+
actionIds: array(string().min(1)).max(100)
|
|
58515
|
+
});
|
|
58516
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58517
|
+
actionId: string().min(1),
|
|
58518
|
+
deviceId: number().int().nonnegative().optional()
|
|
58519
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
58520
|
+
role: "viewer",
|
|
58521
|
+
auth: "protected",
|
|
58522
|
+
kind: "query",
|
|
58523
|
+
caller: "required"
|
|
58524
|
+
}), method(object({
|
|
58525
|
+
actionId: string().min(1),
|
|
58526
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
58527
|
+
wait: boolean().optional(),
|
|
58528
|
+
origin: ActionRunOriginSchema.optional(),
|
|
58529
|
+
deviceId: number().int().nonnegative().optional()
|
|
58530
|
+
}), ActionRunResultSchema, {
|
|
58531
|
+
role: "viewer",
|
|
58532
|
+
auth: "protected",
|
|
58533
|
+
kind: "mutation",
|
|
58534
|
+
caller: "required"
|
|
58535
|
+
}), method(ActionIdInput, _void(), {
|
|
58536
|
+
kind: "mutation",
|
|
58537
|
+
auth: "admin"
|
|
58538
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
58539
|
+
kind: "mutation",
|
|
58540
|
+
auth: "admin"
|
|
58541
|
+
}), method(object({
|
|
58542
|
+
actionId: string().min(1),
|
|
58543
|
+
action: ActionInputSchema.partial()
|
|
58544
|
+
}), object({ action: ActionEntrySchema }), {
|
|
58545
|
+
kind: "mutation",
|
|
58546
|
+
auth: "admin"
|
|
58547
|
+
}), method(ActionIdInput, _void(), {
|
|
58548
|
+
kind: "mutation",
|
|
58549
|
+
auth: "admin"
|
|
58550
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
58551
|
+
role: "viewer",
|
|
58552
|
+
auth: "protected",
|
|
58553
|
+
kind: "query"
|
|
58554
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
58555
|
+
kind: "mutation",
|
|
58556
|
+
auth: "admin"
|
|
58557
|
+
});
|
|
58097
58558
|
/**
|
|
58098
58559
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
58099
58560
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -58190,7 +58651,7 @@ var BatteryStatusSchema = object({
|
|
|
58190
58651
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
58191
58652
|
* declines to band a non-finite reading, which is the correct shape.
|
|
58192
58653
|
*/
|
|
58193
|
-
|
|
58654
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
58194
58655
|
/**
|
|
58195
58656
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
58196
58657
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -58200,7 +58661,7 @@ var BatteryStatusSchema = object({
|
|
|
58200
58661
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
58201
58662
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
58202
58663
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
58203
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
58664
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
58204
58665
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
58205
58666
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
58206
58667
|
*/
|
|
@@ -58224,7 +58685,7 @@ var BatteryStatusSchema = object({
|
|
|
58224
58685
|
* that only report charge. A second reading on this cap, not a second
|
|
58225
58686
|
* `numeric-sensor` on the same device.
|
|
58226
58687
|
*/
|
|
58227
|
-
|
|
58688
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
58228
58689
|
/**
|
|
58229
58690
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
58230
58691
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58258,7 +58719,7 @@ var BatteryStatusSchema = object({
|
|
|
58258
58719
|
/**
|
|
58259
58720
|
* True when the source is a BINARY low-battery indicator (HA
|
|
58260
58721
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
58261
|
-
* charge level — `
|
|
58722
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
58262
58723
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
58263
58724
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
58264
58725
|
*/
|
|
@@ -58278,15 +58739,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58278
58739
|
var batteryCustomize = {
|
|
58279
58740
|
version: 1,
|
|
58280
58741
|
targets: [{
|
|
58281
|
-
id: "
|
|
58742
|
+
id: "level",
|
|
58282
58743
|
cardinality: "scalar",
|
|
58283
58744
|
vocabulary: {
|
|
58284
58745
|
cap: "battery",
|
|
58285
|
-
stateField: "
|
|
58746
|
+
stateField: "level"
|
|
58286
58747
|
},
|
|
58287
58748
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58288
58749
|
apply: "add",
|
|
58289
|
-
path: "
|
|
58750
|
+
path: "level",
|
|
58290
58751
|
sources: [{
|
|
58291
58752
|
kind: "field",
|
|
58292
58753
|
valueKinds: ["number", "string"],
|
|
@@ -58380,7 +58841,7 @@ onStatusChanged: { data: object({
|
|
|
58380
58841
|
schema: BatteryStatusSchema,
|
|
58381
58842
|
kind: "push",
|
|
58382
58843
|
empty: {
|
|
58383
|
-
|
|
58844
|
+
level: null,
|
|
58384
58845
|
charging: "unknown",
|
|
58385
58846
|
sleeping: false,
|
|
58386
58847
|
lastUpdated: 0
|
|
@@ -58407,11 +58868,11 @@ onStatusChanged: { data: object({
|
|
|
58407
58868
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58408
58869
|
*/
|
|
58409
58870
|
history: { fields: {
|
|
58410
|
-
|
|
58871
|
+
level: {
|
|
58411
58872
|
kind: "gauge",
|
|
58412
58873
|
unit: "%"
|
|
58413
58874
|
},
|
|
58414
|
-
|
|
58875
|
+
voltage: {
|
|
58415
58876
|
kind: "gauge",
|
|
58416
58877
|
unit: "V"
|
|
58417
58878
|
}
|
|
@@ -58471,14 +58932,14 @@ var binaryCapability = {
|
|
|
58471
58932
|
* controls to this single-method surface.
|
|
58472
58933
|
*
|
|
58473
58934
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
58474
|
-
*
|
|
58935
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
58475
58936
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
58476
58937
|
* should surface those via the device's `getSettingsUISchema()`
|
|
58477
58938
|
* instead of bloating this cap.
|
|
58478
58939
|
*/
|
|
58479
58940
|
var BrightnessStatusSchema = object({
|
|
58480
58941
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58481
|
-
|
|
58942
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58482
58943
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58483
58944
|
lastChangedAt: number()
|
|
58484
58945
|
});
|
|
@@ -58490,7 +58951,7 @@ var brightnessCapability = {
|
|
|
58490
58951
|
deviceTypes: [DeviceType.Light],
|
|
58491
58952
|
methods: { setBrightness: method(object({
|
|
58492
58953
|
deviceId: number().int().nonnegative(),
|
|
58493
|
-
|
|
58954
|
+
level: number().min(0).max(100)
|
|
58494
58955
|
}), _void(), {
|
|
58495
58956
|
kind: "mutation",
|
|
58496
58957
|
auth: "protected"
|
|
@@ -58503,7 +58964,7 @@ var brightnessCapability = {
|
|
|
58503
58964
|
*/
|
|
58504
58965
|
onBrightnessChanged: { data: object({
|
|
58505
58966
|
deviceId: number(),
|
|
58506
|
-
|
|
58967
|
+
level: number().min(0).max(100),
|
|
58507
58968
|
lastChangedAt: number()
|
|
58508
58969
|
}) } },
|
|
58509
58970
|
status: {
|
|
@@ -58526,7 +58987,7 @@ onBrightnessChanged: { data: object({
|
|
|
58526
58987
|
/**
|
|
58527
58988
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
58528
58989
|
*/
|
|
58529
|
-
history: { fields: {
|
|
58990
|
+
history: { fields: { level: {
|
|
58530
58991
|
kind: "gauge",
|
|
58531
58992
|
unit: "%",
|
|
58532
58993
|
minIntervalMs: 0
|
|
@@ -59123,11 +59584,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
59123
59584
|
}),
|
|
59124
59585
|
object({
|
|
59125
59586
|
mode: literal("mired"),
|
|
59126
|
-
|
|
59587
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
59127
59588
|
})
|
|
59128
59589
|
]);
|
|
59129
59590
|
var ColorStatusSchema = object({
|
|
59130
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
59591
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
59131
59592
|
* the bulb's current state. */
|
|
59132
59593
|
mode: _enum([
|
|
59133
59594
|
"rgb",
|
|
@@ -59139,7 +59600,7 @@ var ColorStatusSchema = object({
|
|
|
59139
59600
|
/** Populated when `mode === 'hsv'`. */
|
|
59140
59601
|
hsv: HsvTripletSchema.optional(),
|
|
59141
59602
|
/** Populated when `mode === 'mired'`. */
|
|
59142
|
-
|
|
59603
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
59143
59604
|
/** Ms epoch of the last operator-driven change. */
|
|
59144
59605
|
lastChangedAt: number()
|
|
59145
59606
|
});
|
|
@@ -59171,7 +59632,7 @@ onColorChanged: { data: object({
|
|
|
59171
59632
|
]),
|
|
59172
59633
|
rgb: RgbTripletSchema.optional(),
|
|
59173
59634
|
hsv: HsvTripletSchema.optional(),
|
|
59174
|
-
|
|
59635
|
+
colorTemperature: number().int().optional(),
|
|
59175
59636
|
lastChangedAt: number()
|
|
59176
59637
|
}) } },
|
|
59177
59638
|
status: {
|
|
@@ -60056,11 +60517,11 @@ var DishwasherStatusSchema = object({
|
|
|
60056
60517
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
60057
60518
|
availablePrograms: array(string()),
|
|
60058
60519
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
60059
|
-
|
|
60520
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60060
60521
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
60061
|
-
|
|
60522
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60062
60523
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
60063
|
-
|
|
60524
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60064
60525
|
/** True when the door is reported open; null when the door state is not known. */
|
|
60065
60526
|
doorOpen: boolean().nullable(),
|
|
60066
60527
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -60279,14 +60740,14 @@ var dishwasherCapability = {
|
|
|
60279
60740
|
runtimeState: DishwasherStatusSchema,
|
|
60280
60741
|
durability: "session",
|
|
60281
60742
|
history: { fields: {
|
|
60282
|
-
|
|
60743
|
+
progress: {
|
|
60283
60744
|
kind: "gauge",
|
|
60284
60745
|
unit: "%",
|
|
60285
60746
|
deadband: 2
|
|
60286
60747
|
},
|
|
60287
60748
|
state: { kind: "enum" },
|
|
60288
60749
|
operationState: { kind: "enum" },
|
|
60289
|
-
|
|
60750
|
+
remaining: {
|
|
60290
60751
|
kind: "gauge",
|
|
60291
60752
|
unit: "s",
|
|
60292
60753
|
minIntervalMs: 6e4
|
|
@@ -60877,7 +61338,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60877
61338
|
var FanControlStatusSchema = object({
|
|
60878
61339
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60879
61340
|
* speed surface (single-speed fan). */
|
|
60880
|
-
|
|
61341
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60881
61342
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60882
61343
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60883
61344
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -60904,7 +61365,7 @@ var fanControlCapability = {
|
|
|
60904
61365
|
methods: {
|
|
60905
61366
|
setPercentage: method(object({
|
|
60906
61367
|
deviceId: number().int().nonnegative(),
|
|
60907
|
-
|
|
61368
|
+
speed: number().min(0).max(100)
|
|
60908
61369
|
}), _void(), {
|
|
60909
61370
|
kind: "mutation",
|
|
60910
61371
|
auth: "protected"
|
|
@@ -60937,7 +61398,7 @@ var fanControlCapability = {
|
|
|
60937
61398
|
},
|
|
60938
61399
|
/**
|
|
60939
61400
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
60940
|
-
* sliders read `
|
|
61401
|
+
* sliders read `speed` for live updates.
|
|
60941
61402
|
*/
|
|
60942
61403
|
runtimeState: FanControlStatusSchema,
|
|
60943
61404
|
/**
|
|
@@ -60951,7 +61412,7 @@ var fanControlCapability = {
|
|
|
60951
61412
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
60952
61413
|
*/
|
|
60953
61414
|
history: { fields: {
|
|
60954
|
-
|
|
61415
|
+
speed: {
|
|
60955
61416
|
kind: "gauge",
|
|
60956
61417
|
unit: "%",
|
|
60957
61418
|
minIntervalMs: 0
|
|
@@ -61396,7 +61857,7 @@ var humidifierCapability = {
|
|
|
61396
61857
|
*/
|
|
61397
61858
|
var HumiditySensorStatusSchema = object({
|
|
61398
61859
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61399
|
-
|
|
61860
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61400
61861
|
precision: 0,
|
|
61401
61862
|
label: "Humidity"
|
|
61402
61863
|
})),
|
|
@@ -61425,7 +61886,7 @@ var humiditySensorCapability = {
|
|
|
61425
61886
|
/**
|
|
61426
61887
|
* History (D850): recorded series.
|
|
61427
61888
|
*/
|
|
61428
|
-
history: { fields: {
|
|
61889
|
+
history: { fields: { humidity: {
|
|
61429
61890
|
kind: "gauge",
|
|
61430
61891
|
unit: "%",
|
|
61431
61892
|
deadband: .5
|
|
@@ -62065,7 +62526,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
62065
62526
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62066
62527
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
62067
62528
|
* task is active / progress is unavailable. */
|
|
62068
|
-
|
|
62529
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62069
62530
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
62070
62531
|
* or null when unknown. */
|
|
62071
62532
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -62565,7 +63026,7 @@ var lockControlCapability = {
|
|
|
62565
63026
|
volatileStateFields: ["lastChangedAt"]
|
|
62566
63027
|
};
|
|
62567
63028
|
/**
|
|
62568
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
63029
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
62569
63030
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
62570
63031
|
* `value` is the time integral in the source quantity's accumulated base
|
|
62571
63032
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -62659,10 +63120,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62659
63120
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62660
63121
|
/** Current playback position in ms. Null when not seekable or
|
|
62661
63122
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62662
|
-
|
|
63123
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62663
63124
|
/** Total duration of the current media in ms. Null when unknown
|
|
62664
63125
|
* (live stream) or nothing is playing. */
|
|
62665
|
-
|
|
63126
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62666
63127
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62667
63128
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62668
63129
|
shuffle: boolean().nullable(),
|
|
@@ -62701,7 +63162,7 @@ var mediaPlayerCapability = {
|
|
|
62701
63162
|
}),
|
|
62702
63163
|
seek: method(object({
|
|
62703
63164
|
deviceId: number().int().nonnegative(),
|
|
62704
|
-
|
|
63165
|
+
position: number().int().nonnegative()
|
|
62705
63166
|
}), _void(), {
|
|
62706
63167
|
kind: "mutation",
|
|
62707
63168
|
auth: "protected"
|
|
@@ -62773,7 +63234,7 @@ var mediaPlayerCapability = {
|
|
|
62773
63234
|
/**
|
|
62774
63235
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62775
63236
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62776
|
-
* `
|
|
63237
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62777
63238
|
*/
|
|
62778
63239
|
history: { fields: {
|
|
62779
63240
|
volumeLevel: {
|
|
@@ -63735,9 +64196,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
63735
64196
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63736
64197
|
* SKIP a null rather than coerce it.
|
|
63737
64198
|
*/
|
|
63738
|
-
|
|
64199
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63739
64200
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63740
|
-
|
|
64201
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
63741
64202
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63742
64203
|
ssid: string().optional(),
|
|
63743
64204
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63773,7 +64234,7 @@ onStatusChanged: { data: object({
|
|
|
63773
64234
|
kind: "push",
|
|
63774
64235
|
empty: {
|
|
63775
64236
|
type: "unknown",
|
|
63776
|
-
|
|
64237
|
+
signal: null,
|
|
63777
64238
|
lastUpdated: 0
|
|
63778
64239
|
}
|
|
63779
64240
|
},
|
|
@@ -63796,13 +64257,13 @@ onStatusChanged: { data: object({
|
|
|
63796
64257
|
* History (D850): recorded series.
|
|
63797
64258
|
*/
|
|
63798
64259
|
history: { fields: {
|
|
63799
|
-
|
|
64260
|
+
signal: {
|
|
63800
64261
|
kind: "gauge",
|
|
63801
64262
|
unit: "%",
|
|
63802
64263
|
deadband: 3,
|
|
63803
64264
|
minIntervalMs: 6e4
|
|
63804
64265
|
},
|
|
63805
|
-
|
|
64266
|
+
rssi: {
|
|
63806
64267
|
kind: "gauge",
|
|
63807
64268
|
unit: "dBm",
|
|
63808
64269
|
deadband: 2,
|
|
@@ -64547,10 +65008,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
64547
65008
|
]);
|
|
64548
65009
|
var gramsPortion = number().int().min(4).max(200);
|
|
64549
65010
|
var PetFeederStatusSchema = object({
|
|
64550
|
-
/** Food
|
|
64551
|
-
*
|
|
64552
|
-
* bowl
|
|
65011
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
65012
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
65013
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
65014
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
65015
|
+
* the device has not reported yet. */
|
|
64553
65016
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
65017
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
65018
|
+
* feeder's own units. Null when the model reports none. */
|
|
65019
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
65020
|
+
/** True while the pet is eating (`state.eating`). */
|
|
65021
|
+
eating: boolean(),
|
|
65022
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
65023
|
+
* the client must not offer it. */
|
|
65024
|
+
supportsMarkRefilled: boolean(),
|
|
64554
65025
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64555
65026
|
* single-hopper models. */
|
|
64556
65027
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -64558,8 +65029,8 @@ var PetFeederStatusSchema = object({
|
|
|
64558
65029
|
* single-hopper models. */
|
|
64559
65030
|
food2: number().nullable().meta(readingMeta("none")),
|
|
64560
65031
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64561
|
-
* (`device_class: problem`, on = low). True when the
|
|
64562
|
-
*
|
|
65032
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
65033
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
64563
65034
|
lowFood: boolean(),
|
|
64564
65035
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
64565
65036
|
* device has no battery reading. */
|
|
@@ -64627,7 +65098,9 @@ var petFeederCapability = {
|
|
|
64627
65098
|
kind: "mutation",
|
|
64628
65099
|
auth: "protected"
|
|
64629
65100
|
}),
|
|
64630
|
-
/**
|
|
65101
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
65102
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
65103
|
+
* change any sensor reading. */
|
|
64631
65104
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
64632
65105
|
kind: "mutation",
|
|
64633
65106
|
auth: "protected"
|
|
@@ -64700,6 +65173,7 @@ var petFeederCapability = {
|
|
|
64700
65173
|
*/
|
|
64701
65174
|
history: { fields: {
|
|
64702
65175
|
foodLevel: { kind: "gauge" },
|
|
65176
|
+
bowlFood: { kind: "gauge" },
|
|
64703
65177
|
food1: { kind: "gauge" },
|
|
64704
65178
|
food2: { kind: "gauge" },
|
|
64705
65179
|
batteryPower: {
|
|
@@ -65109,16 +65583,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
65109
65583
|
* in real-world devices.
|
|
65110
65584
|
*/
|
|
65111
65585
|
var PowerMeterStatusSchema = object({
|
|
65112
|
-
/** Instantaneous power draw
|
|
65113
|
-
|
|
65586
|
+
/** Instantaneous power draw (watts). */
|
|
65587
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
65114
65588
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65115
|
-
|
|
65116
|
-
/** Voltage
|
|
65117
|
-
|
|
65589
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65590
|
+
/** Voltage (volts). */
|
|
65591
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65118
65592
|
/** Current in amperes. */
|
|
65119
|
-
|
|
65593
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65120
65594
|
/** Apparent power in volt-amperes. */
|
|
65121
|
-
|
|
65595
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
65122
65596
|
/** Power factor (0..1) if reported. */
|
|
65123
65597
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
65124
65598
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -65176,14 +65650,14 @@ function powerTarget(id, unit) {
|
|
|
65176
65650
|
advancedExpression: true
|
|
65177
65651
|
};
|
|
65178
65652
|
}
|
|
65179
|
-
/** "Power and energy" extension:
|
|
65653
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
65180
65654
|
var powerMeterCustomize = {
|
|
65181
65655
|
version: 1,
|
|
65182
65656
|
targets: [
|
|
65183
|
-
powerTarget("
|
|
65184
|
-
powerTarget("
|
|
65185
|
-
powerTarget("
|
|
65186
|
-
powerTarget("
|
|
65657
|
+
powerTarget("power", "W"),
|
|
65658
|
+
powerTarget("energy", "kWh"),
|
|
65659
|
+
powerTarget("voltage", "V"),
|
|
65660
|
+
powerTarget("current", "A")
|
|
65187
65661
|
]
|
|
65188
65662
|
};
|
|
65189
65663
|
var powerMeterCapability = {
|
|
@@ -65199,41 +65673,41 @@ var powerMeterCapability = {
|
|
|
65199
65673
|
},
|
|
65200
65674
|
runtimeState: PowerMeterStatusSchema,
|
|
65201
65675
|
/**
|
|
65202
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
65676
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
65203
65677
|
*
|
|
65204
65678
|
* See `RuntimeStateDurability`. Enforced by
|
|
65205
65679
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65206
65680
|
*/
|
|
65207
65681
|
durability: "restored",
|
|
65208
65682
|
/**
|
|
65209
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
65683
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
65210
65684
|
*/
|
|
65211
65685
|
history: { fields: {
|
|
65212
|
-
|
|
65686
|
+
power: {
|
|
65213
65687
|
kind: "gauge",
|
|
65214
65688
|
unit: "W",
|
|
65215
65689
|
deadband: 1,
|
|
65216
65690
|
minIntervalMs: 3e4
|
|
65217
65691
|
},
|
|
65218
|
-
|
|
65692
|
+
energy: {
|
|
65219
65693
|
kind: "counter",
|
|
65220
65694
|
unit: "kWh",
|
|
65221
65695
|
deadband: .01,
|
|
65222
65696
|
minIntervalMs: 6e4
|
|
65223
65697
|
},
|
|
65224
|
-
|
|
65698
|
+
voltage: {
|
|
65225
65699
|
kind: "gauge",
|
|
65226
65700
|
unit: "V",
|
|
65227
65701
|
deadband: 1,
|
|
65228
65702
|
minIntervalMs: 3e4
|
|
65229
65703
|
},
|
|
65230
|
-
|
|
65704
|
+
current: {
|
|
65231
65705
|
kind: "gauge",
|
|
65232
65706
|
unit: "A",
|
|
65233
65707
|
deadband: .05,
|
|
65234
65708
|
minIntervalMs: 3e4
|
|
65235
65709
|
},
|
|
65236
|
-
|
|
65710
|
+
apparentPower: {
|
|
65237
65711
|
kind: "gauge",
|
|
65238
65712
|
unit: "VA",
|
|
65239
65713
|
deadband: 1,
|
|
@@ -65283,9 +65757,6 @@ var PresenceStatusSchema = object({
|
|
|
65283
65757
|
location: string().nullable(),
|
|
65284
65758
|
/** GPS coordinates when available. Null otherwise. */
|
|
65285
65759
|
gps: GpsLocationSchema.nullable(),
|
|
65286
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
65287
|
-
* when not reported. */
|
|
65288
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65289
65760
|
/** Ms epoch when the slice was last updated. */
|
|
65290
65761
|
lastChangedAt: number()
|
|
65291
65762
|
});
|
|
@@ -65314,14 +65785,7 @@ var presenceCapability = {
|
|
|
65314
65785
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65315
65786
|
*/
|
|
65316
65787
|
durability: "restored",
|
|
65317
|
-
|
|
65318
|
-
* History (D850): recorded series.
|
|
65319
|
-
*/
|
|
65320
|
-
history: { fields: { batteryPercent: {
|
|
65321
|
-
kind: "gauge",
|
|
65322
|
-
unit: "%",
|
|
65323
|
-
deadband: 1
|
|
65324
|
-
} } },
|
|
65788
|
+
history: "none",
|
|
65325
65789
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65326
65790
|
* whether persisting is worth a SQLite commit. */
|
|
65327
65791
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65336,7 +65800,7 @@ var presenceCapability = {
|
|
|
65336
65800
|
*/
|
|
65337
65801
|
var PressureSensorStatusSchema = object({
|
|
65338
65802
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65339
|
-
|
|
65803
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
65340
65804
|
/** Ms epoch when the slice was last updated. */
|
|
65341
65805
|
lastFetchedAt: number()
|
|
65342
65806
|
});
|
|
@@ -65362,7 +65826,7 @@ var pressureSensorCapability = {
|
|
|
65362
65826
|
/**
|
|
65363
65827
|
* History (D850): recorded series.
|
|
65364
65828
|
*/
|
|
65365
|
-
history: { fields: {
|
|
65829
|
+
history: { fields: { pressure: {
|
|
65366
65830
|
kind: "gauge",
|
|
65367
65831
|
unit: "hPa",
|
|
65368
65832
|
deadband: .1
|
|
@@ -69061,7 +69525,7 @@ var tamperCapability = {
|
|
|
69061
69525
|
*/
|
|
69062
69526
|
var TemperatureSensorStatusSchema = object({
|
|
69063
69527
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69064
|
-
|
|
69528
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
69065
69529
|
precision: 1,
|
|
69066
69530
|
label: "Temperature"
|
|
69067
69531
|
})),
|
|
@@ -69090,7 +69554,7 @@ var temperatureSensorCapability = {
|
|
|
69090
69554
|
/**
|
|
69091
69555
|
* History (D850): recorded series.
|
|
69092
69556
|
*/
|
|
69093
|
-
history: { fields: {
|
|
69557
|
+
history: { fields: { temperature: {
|
|
69094
69558
|
kind: "gauge",
|
|
69095
69559
|
unit: "°C",
|
|
69096
69560
|
deadband: .1
|
|
@@ -69387,7 +69851,7 @@ var VacuumControlStatusSchema = object({
|
|
|
69387
69851
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69388
69852
|
availableFanSpeeds: array(string()),
|
|
69389
69853
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69390
|
-
|
|
69854
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69391
69855
|
/** Current error code (0 / null = no error). */
|
|
69392
69856
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69393
69857
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -71041,7 +71505,7 @@ var BaseDevice = class {
|
|
|
71041
71505
|
* `device-local-state.ts`. Drivers access via:
|
|
71042
71506
|
*
|
|
71043
71507
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
71044
|
-
* `const pct = this.state.battery.
|
|
71508
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
71045
71509
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
71046
71510
|
*
|
|
71047
71511
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -71081,7 +71545,7 @@ var BaseDevice = class {
|
|
|
71081
71545
|
* shape; drivers don't redeclare it, they just write through.
|
|
71082
71546
|
*
|
|
71083
71547
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
71084
|
-
* `{
|
|
71548
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
71085
71549
|
* provider that registers `batteryCapability`.
|
|
71086
71550
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
71087
71551
|
*
|
|
@@ -72255,6 +72719,104 @@ Object.freeze({
|
|
|
72255
72719
|
access: "create",
|
|
72256
72720
|
role: "admin"
|
|
72257
72721
|
},
|
|
72722
|
+
"actions.create": {
|
|
72723
|
+
capName: "actions",
|
|
72724
|
+
capScope: "system",
|
|
72725
|
+
addonId: null,
|
|
72726
|
+
access: "create",
|
|
72727
|
+
role: "admin"
|
|
72728
|
+
},
|
|
72729
|
+
"actions.delete": {
|
|
72730
|
+
capName: "actions",
|
|
72731
|
+
capScope: "system",
|
|
72732
|
+
addonId: null,
|
|
72733
|
+
access: "delete",
|
|
72734
|
+
role: "admin"
|
|
72735
|
+
},
|
|
72736
|
+
"actions.get": {
|
|
72737
|
+
capName: "actions",
|
|
72738
|
+
capScope: "system",
|
|
72739
|
+
addonId: null,
|
|
72740
|
+
access: "view",
|
|
72741
|
+
role: "viewer"
|
|
72742
|
+
},
|
|
72743
|
+
"actions.getLinks": {
|
|
72744
|
+
capName: "actions",
|
|
72745
|
+
capScope: "system",
|
|
72746
|
+
addonId: null,
|
|
72747
|
+
access: "view",
|
|
72748
|
+
role: "admin"
|
|
72749
|
+
},
|
|
72750
|
+
"actions.getTraces": {
|
|
72751
|
+
capName: "actions",
|
|
72752
|
+
capScope: "system",
|
|
72753
|
+
addonId: null,
|
|
72754
|
+
access: "view",
|
|
72755
|
+
role: "admin"
|
|
72756
|
+
},
|
|
72757
|
+
"actions.list": {
|
|
72758
|
+
capName: "actions",
|
|
72759
|
+
capScope: "system",
|
|
72760
|
+
addonId: null,
|
|
72761
|
+
access: "view",
|
|
72762
|
+
role: "admin"
|
|
72763
|
+
},
|
|
72764
|
+
"actions.listForCamera": {
|
|
72765
|
+
capName: "actions",
|
|
72766
|
+
capScope: "system",
|
|
72767
|
+
addonId: null,
|
|
72768
|
+
access: "view",
|
|
72769
|
+
role: "viewer"
|
|
72770
|
+
},
|
|
72771
|
+
"actions.run": {
|
|
72772
|
+
capName: "actions",
|
|
72773
|
+
capScope: "system",
|
|
72774
|
+
addonId: null,
|
|
72775
|
+
access: "create",
|
|
72776
|
+
role: "viewer"
|
|
72777
|
+
},
|
|
72778
|
+
"actions.setLinks": {
|
|
72779
|
+
capName: "actions",
|
|
72780
|
+
capScope: "system",
|
|
72781
|
+
addonId: null,
|
|
72782
|
+
access: "create",
|
|
72783
|
+
role: "admin"
|
|
72784
|
+
},
|
|
72785
|
+
"actions.stop": {
|
|
72786
|
+
capName: "actions",
|
|
72787
|
+
capScope: "system",
|
|
72788
|
+
addonId: null,
|
|
72789
|
+
access: "create",
|
|
72790
|
+
role: "admin"
|
|
72791
|
+
},
|
|
72792
|
+
"actions.update": {
|
|
72793
|
+
capName: "actions",
|
|
72794
|
+
capScope: "system",
|
|
72795
|
+
addonId: null,
|
|
72796
|
+
access: "create",
|
|
72797
|
+
role: "admin"
|
|
72798
|
+
},
|
|
72799
|
+
"actionSource.listActions": {
|
|
72800
|
+
capName: "action-source",
|
|
72801
|
+
capScope: "system",
|
|
72802
|
+
addonId: null,
|
|
72803
|
+
access: "view",
|
|
72804
|
+
role: "admin"
|
|
72805
|
+
},
|
|
72806
|
+
"actionSource.runAction": {
|
|
72807
|
+
capName: "action-source",
|
|
72808
|
+
capScope: "system",
|
|
72809
|
+
addonId: null,
|
|
72810
|
+
access: "create",
|
|
72811
|
+
role: "admin"
|
|
72812
|
+
},
|
|
72813
|
+
"actionSource.stopAction": {
|
|
72814
|
+
capName: "action-source",
|
|
72815
|
+
capScope: "system",
|
|
72816
|
+
addonId: null,
|
|
72817
|
+
access: "create",
|
|
72818
|
+
role: "admin"
|
|
72819
|
+
},
|
|
72258
72820
|
"addonPages.listPages": {
|
|
72259
72821
|
capName: "addon-pages",
|
|
72260
72822
|
capScope: "system",
|
|
@@ -73536,6 +74098,13 @@ Object.freeze({
|
|
|
73536
74098
|
access: "view",
|
|
73537
74099
|
role: "admin"
|
|
73538
74100
|
},
|
|
74101
|
+
"coreBlocks.getAutomationRunState": {
|
|
74102
|
+
capName: "core-blocks",
|
|
74103
|
+
capScope: "system",
|
|
74104
|
+
addonId: null,
|
|
74105
|
+
access: "view",
|
|
74106
|
+
role: "admin"
|
|
74107
|
+
},
|
|
73539
74108
|
"coreBlocks.getBlockSettings": {
|
|
73540
74109
|
capName: "core-blocks",
|
|
73541
74110
|
capScope: "system",
|
|
@@ -73557,6 +74126,13 @@ Object.freeze({
|
|
|
73557
74126
|
access: "view",
|
|
73558
74127
|
role: "admin"
|
|
73559
74128
|
},
|
|
74129
|
+
"coreBlocks.getTraces": {
|
|
74130
|
+
capName: "core-blocks",
|
|
74131
|
+
capScope: "system",
|
|
74132
|
+
addonId: null,
|
|
74133
|
+
access: "view",
|
|
74134
|
+
role: "admin"
|
|
74135
|
+
},
|
|
73560
74136
|
"coreBlocks.getTypeDefs": {
|
|
73561
74137
|
capName: "core-blocks",
|
|
73562
74138
|
capScope: "system",
|
|
@@ -73592,6 +74168,13 @@ Object.freeze({
|
|
|
73592
74168
|
access: "create",
|
|
73593
74169
|
role: "admin"
|
|
73594
74170
|
},
|
|
74171
|
+
"coreBlocks.reportAutomationRun": {
|
|
74172
|
+
capName: "core-blocks",
|
|
74173
|
+
capScope: "system",
|
|
74174
|
+
addonId: null,
|
|
74175
|
+
access: "create",
|
|
74176
|
+
role: "admin"
|
|
74177
|
+
},
|
|
73595
74178
|
"coreBlocks.restart": {
|
|
73596
74179
|
capName: "core-blocks",
|
|
73597
74180
|
capScope: "system",
|
|
@@ -82165,7 +82748,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82165
82748
|
label: t("Full brightness", "Luminosità massima"),
|
|
82166
82749
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
82167
82750
|
icon: "sun",
|
|
82168
|
-
args: {
|
|
82751
|
+
args: { level: 100 }
|
|
82169
82752
|
},
|
|
82170
82753
|
{
|
|
82171
82754
|
id: "brightness.half",
|
|
@@ -82173,7 +82756,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82173
82756
|
label: t("Half brightness", "Luminosità a metà"),
|
|
82174
82757
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
82175
82758
|
icon: "sun-dim",
|
|
82176
|
-
args: {
|
|
82759
|
+
args: { level: 50 }
|
|
82177
82760
|
},
|
|
82178
82761
|
{
|
|
82179
82762
|
id: "brightness.off",
|
|
@@ -82181,16 +82764,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82181
82764
|
label: t("Brightness off", "Luminosità a zero"),
|
|
82182
82765
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
82183
82766
|
icon: "lightbulb-off",
|
|
82184
|
-
args: {
|
|
82767
|
+
args: { level: 0 }
|
|
82185
82768
|
},
|
|
82186
82769
|
{
|
|
82187
82770
|
id: "brightness.set",
|
|
82188
82771
|
method: "setBrightness",
|
|
82189
82772
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
82190
|
-
phrase: t("Set the brightness of {device} to {
|
|
82773
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
82191
82774
|
icon: "sun-medium",
|
|
82192
82775
|
openArgs: [{
|
|
82193
|
-
key: "
|
|
82776
|
+
key: "level",
|
|
82194
82777
|
label: PERCENT,
|
|
82195
82778
|
offer: {
|
|
82196
82779
|
kind: "number",
|
|
@@ -82204,13 +82787,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82204
82787
|
],
|
|
82205
82788
|
state: [{
|
|
82206
82789
|
kind: "numeric",
|
|
82207
|
-
field: "
|
|
82790
|
+
field: "level",
|
|
82208
82791
|
quantity: t("the brightness", "la luminosità"),
|
|
82209
82792
|
label: t("Brightness", "Luminosità"),
|
|
82210
82793
|
unit: "%",
|
|
82211
82794
|
icon: "sun"
|
|
82212
82795
|
}],
|
|
82213
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
82796
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
82214
82797
|
},
|
|
82215
82798
|
color: {
|
|
82216
82799
|
scope: "device",
|
|
@@ -82224,7 +82807,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82224
82807
|
icon: "sun",
|
|
82225
82808
|
args: { color: {
|
|
82226
82809
|
mode: "mired",
|
|
82227
|
-
|
|
82810
|
+
colorTemperature: 370
|
|
82228
82811
|
} }
|
|
82229
82812
|
},
|
|
82230
82813
|
{
|
|
@@ -82235,7 +82818,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82235
82818
|
icon: "snowflake",
|
|
82236
82819
|
args: { color: {
|
|
82237
82820
|
mode: "mired",
|
|
82238
|
-
|
|
82821
|
+
colorTemperature: 200
|
|
82239
82822
|
} }
|
|
82240
82823
|
},
|
|
82241
82824
|
{
|
|
@@ -82849,7 +83432,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82849
83432
|
label: t("Fan off", "Ventilatore spento"),
|
|
82850
83433
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
82851
83434
|
icon: "power-off",
|
|
82852
|
-
args: {
|
|
83435
|
+
args: { speed: 0 }
|
|
82853
83436
|
},
|
|
82854
83437
|
{
|
|
82855
83438
|
id: "fan.full",
|
|
@@ -82857,16 +83440,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82857
83440
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
82858
83441
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
82859
83442
|
icon: "fan",
|
|
82860
|
-
args: {
|
|
83443
|
+
args: { speed: 100 }
|
|
82861
83444
|
},
|
|
82862
83445
|
{
|
|
82863
83446
|
id: "fan.speed",
|
|
82864
83447
|
method: "setPercentage",
|
|
82865
83448
|
label: t("Set speed", "Imposta la velocità"),
|
|
82866
|
-
phrase: t("Set the speed of {device} to {
|
|
83449
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
82867
83450
|
icon: "fan",
|
|
82868
83451
|
openArgs: [{
|
|
82869
|
-
key: "
|
|
83452
|
+
key: "speed",
|
|
82870
83453
|
label: t("Speed", "Velocità"),
|
|
82871
83454
|
offer: {
|
|
82872
83455
|
kind: "number",
|
|
@@ -82928,7 +83511,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82928
83511
|
],
|
|
82929
83512
|
state: [{
|
|
82930
83513
|
kind: "numeric",
|
|
82931
|
-
field: "
|
|
83514
|
+
field: "speed",
|
|
82932
83515
|
quantity: t("the speed", "la velocità"),
|
|
82933
83516
|
label: t("Speed", "Velocità"),
|
|
82934
83517
|
unit: "%",
|
|
@@ -83726,7 +84309,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83726
84309
|
},
|
|
83727
84310
|
{
|
|
83728
84311
|
kind: "numeric",
|
|
83729
|
-
field: "
|
|
84312
|
+
field: "progress",
|
|
83730
84313
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
83731
84314
|
label: t("Progress", "Avanzamento"),
|
|
83732
84315
|
unit: "%",
|
|
@@ -84084,10 +84667,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84084
84667
|
id: "media.seek",
|
|
84085
84668
|
method: "seek",
|
|
84086
84669
|
label: t("Seek", "Vai al punto"),
|
|
84087
|
-
phrase: t("Move {device} to {
|
|
84670
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
84088
84671
|
icon: "fast-forward",
|
|
84089
84672
|
openArgs: [{
|
|
84090
|
-
key: "
|
|
84673
|
+
key: "position",
|
|
84091
84674
|
label: t("Position", "Posizione"),
|
|
84092
84675
|
offer: {
|
|
84093
84676
|
kind: "number",
|
|
@@ -85136,7 +85719,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85136
85719
|
state: [
|
|
85137
85720
|
{
|
|
85138
85721
|
kind: "numeric",
|
|
85139
|
-
field: "
|
|
85722
|
+
field: "co2",
|
|
85140
85723
|
quantity: t("the CO₂", "la CO₂"),
|
|
85141
85724
|
label: t("CO₂", "CO₂"),
|
|
85142
85725
|
unit: "ppm",
|
|
@@ -85144,7 +85727,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85144
85727
|
},
|
|
85145
85728
|
{
|
|
85146
85729
|
kind: "numeric",
|
|
85147
|
-
field: "
|
|
85730
|
+
field: "voc",
|
|
85148
85731
|
quantity: t("the VOC level", "il livello di COV"),
|
|
85149
85732
|
label: t("VOC", "COV"),
|
|
85150
85733
|
unit: "ppb",
|
|
@@ -85180,7 +85763,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85180
85763
|
noun: t("Light level", "Luminosità ambiente"),
|
|
85181
85764
|
state: [{
|
|
85182
85765
|
kind: "numeric",
|
|
85183
|
-
field: "
|
|
85766
|
+
field: "illuminance",
|
|
85184
85767
|
quantity: t("the light level", "la luminosità"),
|
|
85185
85768
|
label: t("Illuminance", "Illuminamento"),
|
|
85186
85769
|
unit: "lx",
|
|
@@ -85383,7 +85966,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85383
85966
|
noun: t("Humidity", "Umidità"),
|
|
85384
85967
|
state: [{
|
|
85385
85968
|
kind: "numeric",
|
|
85386
|
-
field: "
|
|
85969
|
+
field: "humidity",
|
|
85387
85970
|
quantity: t("the humidity", "l’umidità"),
|
|
85388
85971
|
label: t("Humidity", "Umidità"),
|
|
85389
85972
|
unit: "%",
|
|
@@ -85431,7 +86014,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85431
86014
|
state: [
|
|
85432
86015
|
{
|
|
85433
86016
|
kind: "numeric",
|
|
85434
|
-
field: "
|
|
86017
|
+
field: "power",
|
|
85435
86018
|
quantity: t("the power draw", "il consumo"),
|
|
85436
86019
|
label: t("Power", "Potenza"),
|
|
85437
86020
|
unit: "W",
|
|
@@ -85439,7 +86022,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85439
86022
|
},
|
|
85440
86023
|
{
|
|
85441
86024
|
kind: "numeric",
|
|
85442
|
-
field: "
|
|
86025
|
+
field: "energy",
|
|
85443
86026
|
quantity: t("the energy used", "l’energia consumata"),
|
|
85444
86027
|
label: t("Energy", "Energia"),
|
|
85445
86028
|
unit: "kWh",
|
|
@@ -85447,7 +86030,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85447
86030
|
},
|
|
85448
86031
|
{
|
|
85449
86032
|
kind: "numeric",
|
|
85450
|
-
field: "
|
|
86033
|
+
field: "voltage",
|
|
85451
86034
|
quantity: t("the voltage", "la tensione"),
|
|
85452
86035
|
label: t("Voltage", "Tensione"),
|
|
85453
86036
|
unit: "V",
|
|
@@ -85455,7 +86038,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85455
86038
|
},
|
|
85456
86039
|
{
|
|
85457
86040
|
kind: "numeric",
|
|
85458
|
-
field: "
|
|
86041
|
+
field: "current",
|
|
85459
86042
|
quantity: t("the current", "la corrente"),
|
|
85460
86043
|
label: t("Current", "Corrente"),
|
|
85461
86044
|
unit: "A",
|
|
@@ -85472,13 +86055,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85472
86055
|
label: t("Where", "Posizione"),
|
|
85473
86056
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
85474
86057
|
icon: "map-pin"
|
|
85475
|
-
}, {
|
|
85476
|
-
kind: "numeric",
|
|
85477
|
-
field: "batteryPercent",
|
|
85478
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
85479
|
-
label: t("Battery", "Batteria"),
|
|
85480
|
-
unit: "%",
|
|
85481
|
-
icon: "battery"
|
|
85482
86058
|
}]
|
|
85483
86059
|
},
|
|
85484
86060
|
"pressure-sensor": {
|
|
@@ -85486,7 +86062,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85486
86062
|
noun: t("Pressure", "Pressione"),
|
|
85487
86063
|
state: [{
|
|
85488
86064
|
kind: "numeric",
|
|
85489
|
-
field: "
|
|
86065
|
+
field: "pressure",
|
|
85490
86066
|
quantity: t("the pressure", "la pressione"),
|
|
85491
86067
|
label: t("Pressure", "Pressione"),
|
|
85492
86068
|
unit: "hPa",
|
|
@@ -85522,7 +86098,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85522
86098
|
noun: t("Temperature", "Temperatura"),
|
|
85523
86099
|
state: [{
|
|
85524
86100
|
kind: "numeric",
|
|
85525
|
-
field: "
|
|
86101
|
+
field: "temperature",
|
|
85526
86102
|
quantity: t("the temperature", "la temperatura"),
|
|
85527
86103
|
label: t("Temperature", "Temperatura"),
|
|
85528
86104
|
unit: "°C",
|
|
@@ -85593,7 +86169,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85593
86169
|
state: [
|
|
85594
86170
|
{
|
|
85595
86171
|
kind: "numeric",
|
|
85596
|
-
field: "
|
|
86172
|
+
field: "level",
|
|
85597
86173
|
quantity: t("the battery level", "il livello della batteria"),
|
|
85598
86174
|
label: t("Battery", "Batteria"),
|
|
85599
86175
|
unit: "%",
|
|
@@ -85635,7 +86211,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85635
86211
|
icon: "battery-charging"
|
|
85636
86212
|
}
|
|
85637
86213
|
],
|
|
85638
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
86214
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
85639
86215
|
extraEvents: [{
|
|
85640
86216
|
category: EventCategory.DeviceAwake,
|
|
85641
86217
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -85653,7 +86229,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85653
86229
|
noun: t("Network link", "Collegamento di rete"),
|
|
85654
86230
|
state: [{
|
|
85655
86231
|
kind: "numeric",
|
|
85656
|
-
field: "
|
|
86232
|
+
field: "signal",
|
|
85657
86233
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
85658
86234
|
label: t("Signal", "Segnale"),
|
|
85659
86235
|
unit: "%",
|
|
@@ -85746,6 +86322,8 @@ var ML = "model and training machinery — no device action";
|
|
|
85746
86322
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
85747
86323
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
85748
86324
|
var SYSTEM_CAP_VOCABULARY = {
|
|
86325
|
+
"action-source": system(INTERNAL),
|
|
86326
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
85749
86327
|
"addon-pages": system(UI_PLUMBING),
|
|
85750
86328
|
"addon-pages-source": system(UI_PLUMBING),
|
|
85751
86329
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -85942,6 +86520,31 @@ Object.freeze({
|
|
|
85942
86520
|
form: "single",
|
|
85943
86521
|
optional: false
|
|
85944
86522
|
}],
|
|
86523
|
+
"actions.get": [{
|
|
86524
|
+
name: "deviceId",
|
|
86525
|
+
form: "single",
|
|
86526
|
+
optional: true
|
|
86527
|
+
}],
|
|
86528
|
+
"actions.getLinks": [{
|
|
86529
|
+
name: "deviceId",
|
|
86530
|
+
form: "single",
|
|
86531
|
+
optional: false
|
|
86532
|
+
}],
|
|
86533
|
+
"actions.listForCamera": [{
|
|
86534
|
+
name: "deviceId",
|
|
86535
|
+
form: "single",
|
|
86536
|
+
optional: false
|
|
86537
|
+
}],
|
|
86538
|
+
"actions.run": [{
|
|
86539
|
+
name: "deviceId",
|
|
86540
|
+
form: "single",
|
|
86541
|
+
optional: true
|
|
86542
|
+
}],
|
|
86543
|
+
"actions.setLinks": [{
|
|
86544
|
+
name: "deviceId",
|
|
86545
|
+
form: "single",
|
|
86546
|
+
optional: false
|
|
86547
|
+
}],
|
|
85945
86548
|
"addonSettings.getDeviceSettings": [{
|
|
85946
86549
|
name: "deviceId",
|
|
85947
86550
|
form: "single",
|
|
@@ -90023,6 +90626,7 @@ DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
|
90023
90626
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
90024
90627
|
DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb;
|
|
90025
90628
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
90629
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
90026
90630
|
var MB = 1024 * 1024;
|
|
90027
90631
|
1024 * MB, 3072 * MB;
|
|
90028
90632
|
//#endregion
|
|
@@ -90734,7 +91338,7 @@ var TuyaTemperatureSensorDevice = class extends TuyaChildDevice {
|
|
|
90734
91338
|
}
|
|
90735
91339
|
#slice(celsius) {
|
|
90736
91340
|
return {
|
|
90737
|
-
celsius,
|
|
91341
|
+
temperature: celsius,
|
|
90738
91342
|
lastFetchedAt: Date.now()
|
|
90739
91343
|
};
|
|
90740
91344
|
}
|
|
@@ -90746,7 +91350,7 @@ var TuyaTemperatureSensorDevice = class extends TuyaChildDevice {
|
|
|
90746
91350
|
recomputeSlice() {
|
|
90747
91351
|
const celsius = this.#read();
|
|
90748
91352
|
if (celsius === null) return;
|
|
90749
|
-
if (this.runtimeState.getCapState(CAP_NAME$1)?.
|
|
91353
|
+
if (this.runtimeState.getCapState(CAP_NAME$1)?.temperature === celsius) return;
|
|
90750
91354
|
this.runtimeState.setCapState(CAP_NAME$1, this.#slice(celsius));
|
|
90751
91355
|
}
|
|
90752
91356
|
};
|