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