@camstack/addon-pipeline 1.2.631 → 1.2.633
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 +12 -0
- package/dist/audio-analyzer/index.js +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/{custom-model-catalog-DLv2FLul.mjs → custom-model-catalog-BcYQkMoD.mjs} +2 -2
- package/dist/{custom-model-catalog-5IT-gwL2.js → custom-model-catalog-Bsfg7BkC.js} +2 -2
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-CVvwej3J.js → dist-DQcSGwGp.js} +1602 -916
- package/dist/{dist-DV6W_qKY.mjs → dist-rqX8QLAU.mjs} +1602 -916
- package/dist/{model-catalogs-lWWyJZqw.js → model-catalogs-BIQmZA1O.js} +1 -1
- package/dist/{model-catalogs-CI9KoY4D.mjs → model-catalogs-C3fsKl2H.mjs} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-BQ7P2No5.js → node-Bq2OdtOJ.js} +1 -1
- package/dist/{node-KEh_tmT2.mjs → node-CxeIzhfZ.mjs} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-ChQO96Xb.mjs → process-memory-BJ4dGThE.mjs} +1 -1
- package/dist/{process-memory-C-3bSKF5.js → process-memory-DscuOZuW.js} +1 -1
- package/dist/recorder/index.js +3 -2
- package/dist/recorder/index.mjs +3 -2
- package/dist/{segment-demux-js-Dy75tkrR.mjs → segment-demux-js-CTN4M0L6.mjs} +1 -1
- package/dist/{segment-demux-js-8YepQCG3.js → segment-demux-js-CUvevVpm.js} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CKN6MEA_.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-ypdxRUwS.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BOIc62S5.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CY6cGkjo.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-BqjKmOsK.mjs → hostInit-DskyymXn.mjs} +2 -2
- package/dist/stream-broker/index.js +42 -11
- package/dist/stream-broker/index.mjs +42 -11
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BPnizAbp.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BL5-HIQd.mjs +0 -26
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
//#region ../types/dist/event-category-
|
|
2
|
+
//#region ../types/dist/event-category-DmZDPDf_.mjs
|
|
3
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
5
5
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -626,7 +626,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
626
626
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
627
627
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
628
628
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
629
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
629
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
630
630
|
*/
|
|
631
631
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
632
632
|
/**
|
|
@@ -764,6 +764,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
764
764
|
*/
|
|
765
765
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
766
766
|
/**
|
|
767
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
768
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
769
|
+
*/
|
|
770
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
771
|
+
/**
|
|
767
772
|
* Progress update from a running model conversion job.
|
|
768
773
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
769
774
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -5575,7 +5580,7 @@ var ZodIssueCode = {
|
|
|
5575
5580
|
var ZodFirstPartyTypeKind;
|
|
5576
5581
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5577
5582
|
//#endregion
|
|
5578
|
-
//#region ../types/dist/sleep
|
|
5583
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
5579
5584
|
/**
|
|
5580
5585
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5581
5586
|
* window to float samples (D455).
|
|
@@ -9034,6 +9039,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
9034
9039
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
9035
9040
|
var CAP_NAMES = Object.freeze([
|
|
9036
9041
|
"accessories",
|
|
9042
|
+
"action-source",
|
|
9043
|
+
"actions",
|
|
9037
9044
|
"addon-pages",
|
|
9038
9045
|
"addon-pages-source",
|
|
9039
9046
|
"addon-routes",
|
|
@@ -9222,11 +9229,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
9222
9229
|
Object.freeze({
|
|
9223
9230
|
"air-quality-sensor": [
|
|
9224
9231
|
{
|
|
9225
|
-
"path": "
|
|
9232
|
+
"path": "co2",
|
|
9226
9233
|
"valueType": "number"
|
|
9227
9234
|
},
|
|
9228
9235
|
{
|
|
9229
|
-
"path": "
|
|
9236
|
+
"path": "voc",
|
|
9230
9237
|
"valueType": "number"
|
|
9231
9238
|
},
|
|
9232
9239
|
{
|
|
@@ -9276,7 +9283,7 @@ Object.freeze({
|
|
|
9276
9283
|
}
|
|
9277
9284
|
],
|
|
9278
9285
|
"ambient-light-sensor": [{
|
|
9279
|
-
"path": "
|
|
9286
|
+
"path": "illuminance",
|
|
9280
9287
|
"valueType": "number"
|
|
9281
9288
|
}],
|
|
9282
9289
|
"audio-metrics": [
|
|
@@ -9337,7 +9344,7 @@ Object.freeze({
|
|
|
9337
9344
|
],
|
|
9338
9345
|
"battery": [
|
|
9339
9346
|
{
|
|
9340
|
-
"path": "
|
|
9347
|
+
"path": "level",
|
|
9341
9348
|
"valueType": "number"
|
|
9342
9349
|
},
|
|
9343
9350
|
{
|
|
@@ -9359,7 +9366,7 @@ Object.freeze({
|
|
|
9359
9366
|
"valueType": "number"
|
|
9360
9367
|
},
|
|
9361
9368
|
{
|
|
9362
|
-
"path": "
|
|
9369
|
+
"path": "voltage",
|
|
9363
9370
|
"valueType": "number"
|
|
9364
9371
|
},
|
|
9365
9372
|
{
|
|
@@ -9380,7 +9387,7 @@ Object.freeze({
|
|
|
9380
9387
|
"valueType": "boolean"
|
|
9381
9388
|
}],
|
|
9382
9389
|
"brightness": [{
|
|
9383
|
-
"path": "
|
|
9390
|
+
"path": "level",
|
|
9384
9391
|
"valueType": "number"
|
|
9385
9392
|
}],
|
|
9386
9393
|
"broker": [{
|
|
@@ -9581,7 +9588,7 @@ Object.freeze({
|
|
|
9581
9588
|
"valueType": "number"
|
|
9582
9589
|
},
|
|
9583
9590
|
{
|
|
9584
|
-
"path": "
|
|
9591
|
+
"path": "colorTemperature",
|
|
9585
9592
|
"valueType": "number"
|
|
9586
9593
|
}
|
|
9587
9594
|
],
|
|
@@ -9760,15 +9767,15 @@ Object.freeze({
|
|
|
9760
9767
|
"valueType": "string"
|
|
9761
9768
|
},
|
|
9762
9769
|
{
|
|
9763
|
-
"path": "
|
|
9770
|
+
"path": "remaining",
|
|
9764
9771
|
"valueType": "number"
|
|
9765
9772
|
},
|
|
9766
9773
|
{
|
|
9767
|
-
"path": "
|
|
9774
|
+
"path": "delayedStart",
|
|
9768
9775
|
"valueType": "number"
|
|
9769
9776
|
},
|
|
9770
9777
|
{
|
|
9771
|
-
"path": "
|
|
9778
|
+
"path": "progress",
|
|
9772
9779
|
"valueType": "number"
|
|
9773
9780
|
},
|
|
9774
9781
|
{
|
|
@@ -9882,7 +9889,7 @@ Object.freeze({
|
|
|
9882
9889
|
],
|
|
9883
9890
|
"fan-control": [
|
|
9884
9891
|
{
|
|
9885
|
-
"path": "
|
|
9892
|
+
"path": "speed",
|
|
9886
9893
|
"valueType": "number"
|
|
9887
9894
|
},
|
|
9888
9895
|
{
|
|
@@ -9982,7 +9989,7 @@ Object.freeze({
|
|
|
9982
9989
|
}
|
|
9983
9990
|
],
|
|
9984
9991
|
"humidity-sensor": [{
|
|
9985
|
-
"path": "
|
|
9992
|
+
"path": "humidity",
|
|
9986
9993
|
"valueType": "number"
|
|
9987
9994
|
}],
|
|
9988
9995
|
"image": [{
|
|
@@ -10092,7 +10099,7 @@ Object.freeze({
|
|
|
10092
10099
|
"valueType": "number"
|
|
10093
10100
|
},
|
|
10094
10101
|
{
|
|
10095
|
-
"path": "
|
|
10102
|
+
"path": "progress",
|
|
10096
10103
|
"valueType": "number"
|
|
10097
10104
|
},
|
|
10098
10105
|
{
|
|
@@ -10171,11 +10178,11 @@ Object.freeze({
|
|
|
10171
10178
|
"valueType": "string"
|
|
10172
10179
|
},
|
|
10173
10180
|
{
|
|
10174
|
-
"path": "
|
|
10181
|
+
"path": "position",
|
|
10175
10182
|
"valueType": "number"
|
|
10176
10183
|
},
|
|
10177
10184
|
{
|
|
10178
|
-
"path": "
|
|
10185
|
+
"path": "duration",
|
|
10179
10186
|
"valueType": "number"
|
|
10180
10187
|
},
|
|
10181
10188
|
{
|
|
@@ -10277,11 +10284,11 @@ Object.freeze({
|
|
|
10277
10284
|
]
|
|
10278
10285
|
},
|
|
10279
10286
|
{
|
|
10280
|
-
"path": "
|
|
10287
|
+
"path": "signal",
|
|
10281
10288
|
"valueType": "number"
|
|
10282
10289
|
},
|
|
10283
10290
|
{
|
|
10284
|
-
"path": "
|
|
10291
|
+
"path": "rssi",
|
|
10285
10292
|
"valueType": "number"
|
|
10286
10293
|
},
|
|
10287
10294
|
{
|
|
@@ -10336,6 +10343,18 @@ Object.freeze({
|
|
|
10336
10343
|
"path": "foodLevel",
|
|
10337
10344
|
"valueType": "number"
|
|
10338
10345
|
},
|
|
10346
|
+
{
|
|
10347
|
+
"path": "bowlFood",
|
|
10348
|
+
"valueType": "number"
|
|
10349
|
+
},
|
|
10350
|
+
{
|
|
10351
|
+
"path": "eating",
|
|
10352
|
+
"valueType": "boolean"
|
|
10353
|
+
},
|
|
10354
|
+
{
|
|
10355
|
+
"path": "supportsMarkRefilled",
|
|
10356
|
+
"valueType": "boolean"
|
|
10357
|
+
},
|
|
10339
10358
|
{
|
|
10340
10359
|
"path": "food1",
|
|
10341
10360
|
"valueType": "number"
|
|
@@ -10400,23 +10419,23 @@ Object.freeze({
|
|
|
10400
10419
|
],
|
|
10401
10420
|
"power-meter": [
|
|
10402
10421
|
{
|
|
10403
|
-
"path": "
|
|
10422
|
+
"path": "power",
|
|
10404
10423
|
"valueType": "number"
|
|
10405
10424
|
},
|
|
10406
10425
|
{
|
|
10407
|
-
"path": "
|
|
10426
|
+
"path": "energy",
|
|
10408
10427
|
"valueType": "number"
|
|
10409
10428
|
},
|
|
10410
10429
|
{
|
|
10411
|
-
"path": "
|
|
10430
|
+
"path": "voltage",
|
|
10412
10431
|
"valueType": "number"
|
|
10413
10432
|
},
|
|
10414
10433
|
{
|
|
10415
|
-
"path": "
|
|
10434
|
+
"path": "current",
|
|
10416
10435
|
"valueType": "number"
|
|
10417
10436
|
},
|
|
10418
10437
|
{
|
|
10419
|
-
"path": "
|
|
10438
|
+
"path": "apparentPower",
|
|
10420
10439
|
"valueType": "number"
|
|
10421
10440
|
},
|
|
10422
10441
|
{
|
|
@@ -10444,14 +10463,10 @@ Object.freeze({
|
|
|
10444
10463
|
{
|
|
10445
10464
|
"path": "gps.accuracyMeters",
|
|
10446
10465
|
"valueType": "number"
|
|
10447
|
-
},
|
|
10448
|
-
{
|
|
10449
|
-
"path": "batteryPercent",
|
|
10450
|
-
"valueType": "number"
|
|
10451
10466
|
}
|
|
10452
10467
|
],
|
|
10453
10468
|
"pressure-sensor": [{
|
|
10454
|
-
"path": "
|
|
10469
|
+
"path": "pressure",
|
|
10455
10470
|
"valueType": "number"
|
|
10456
10471
|
}],
|
|
10457
10472
|
"privacy-mask": [{
|
|
@@ -10765,7 +10780,7 @@ Object.freeze({
|
|
|
10765
10780
|
"valueType": "boolean"
|
|
10766
10781
|
}],
|
|
10767
10782
|
"temperature-sensor": [{
|
|
10768
|
-
"path": "
|
|
10783
|
+
"path": "temperature",
|
|
10769
10784
|
"valueType": "number"
|
|
10770
10785
|
}],
|
|
10771
10786
|
"update": [
|
|
@@ -10813,7 +10828,7 @@ Object.freeze({
|
|
|
10813
10828
|
"valueType": "string"
|
|
10814
10829
|
},
|
|
10815
10830
|
{
|
|
10816
|
-
"path": "
|
|
10831
|
+
"path": "progress",
|
|
10817
10832
|
"valueType": "number"
|
|
10818
10833
|
},
|
|
10819
10834
|
{
|
|
@@ -11450,7 +11465,7 @@ function errMsg(err) {
|
|
|
11450
11465
|
return String(err);
|
|
11451
11466
|
}
|
|
11452
11467
|
//#endregion
|
|
11453
|
-
//#region ../types/dist/composition-
|
|
11468
|
+
//#region ../types/dist/composition-DwA0uVW5.mjs
|
|
11454
11469
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
11455
11470
|
opus: "libopus",
|
|
11456
11471
|
aac: "aac",
|
|
@@ -18162,6 +18177,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
18162
18177
|
array(union$1([string(), number()]))
|
|
18163
18178
|
])
|
|
18164
18179
|
});
|
|
18180
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
18181
|
+
kind: literal("stationary-present"),
|
|
18182
|
+
deviceId: number().int().nonnegative(),
|
|
18183
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
18184
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
18185
|
+
/** The parked object must be in at least one of these zones. */
|
|
18186
|
+
zones: array(string().min(1)).min(1).optional()
|
|
18187
|
+
});
|
|
18165
18188
|
/**
|
|
18166
18189
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
18167
18190
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -18195,7 +18218,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
18195
18218
|
child: AutomationConditionSchema
|
|
18196
18219
|
}),
|
|
18197
18220
|
AutomationConditionLeafSchema,
|
|
18198
|
-
AutomationConditionExpressionSchema
|
|
18221
|
+
AutomationConditionExpressionSchema,
|
|
18222
|
+
AutomationConditionStationaryPresentSchema
|
|
18199
18223
|
]));
|
|
18200
18224
|
/**
|
|
18201
18225
|
* What starts a run.
|
|
@@ -18236,7 +18260,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
18236
18260
|
kind: literal("schedule"),
|
|
18237
18261
|
cron: string().min(1).max(120)
|
|
18238
18262
|
}),
|
|
18239
|
-
object({ kind: literal("manual") })
|
|
18263
|
+
object({ kind: literal("manual") }),
|
|
18264
|
+
object({
|
|
18265
|
+
kind: literal("detection"),
|
|
18266
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
18267
|
+
* matches every raw class that maps to it; any other name matches
|
|
18268
|
+
* exactly. */
|
|
18269
|
+
classes: array(string().min(1)).min(1),
|
|
18270
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
18271
|
+
/** The track must have visited at least one of these zones. */
|
|
18272
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
18273
|
+
/** Best-so-far confidence the track must reach. */
|
|
18274
|
+
minScore: number().min(0).max(1).optional()
|
|
18275
|
+
}),
|
|
18276
|
+
object({
|
|
18277
|
+
kind: literal("stationary"),
|
|
18278
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
18279
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
18280
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
18281
|
+
/** The parked object must be in at least one of these zones. */
|
|
18282
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
18283
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
18284
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
18285
|
+
phase: _enum(["appeared", "departed"])
|
|
18286
|
+
}),
|
|
18287
|
+
object({
|
|
18288
|
+
kind: literal("interval"),
|
|
18289
|
+
minutes: number().int().min(1).max(1440)
|
|
18290
|
+
})
|
|
18240
18291
|
]);
|
|
18241
18292
|
/**
|
|
18242
18293
|
* One action step.
|
|
@@ -18256,28 +18307,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
18256
18307
|
* is called. The runner still receives a number and is untouched; the
|
|
18257
18308
|
* resolution is the recipe's job, not the runner's.
|
|
18258
18309
|
*/
|
|
18310
|
+
var AutomationWaitStepSchema = object({
|
|
18311
|
+
kind: literal("wait"),
|
|
18312
|
+
seconds: number().min(0).max(300)
|
|
18313
|
+
});
|
|
18314
|
+
var AutomationCapStepSchema = object({
|
|
18315
|
+
kind: literal("cap"),
|
|
18316
|
+
/**
|
|
18317
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
18318
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
18319
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
18320
|
+
*/
|
|
18321
|
+
deviceId: union$1([
|
|
18322
|
+
number().int(),
|
|
18323
|
+
array(number().int()).min(1),
|
|
18324
|
+
object({ $var: string().min(1) })
|
|
18325
|
+
]),
|
|
18326
|
+
cap: string().min(1),
|
|
18327
|
+
method: string().min(1),
|
|
18328
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
18329
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
18330
|
+
* the expression leaf. */
|
|
18331
|
+
args: record(string(), unknown()).optional()
|
|
18332
|
+
});
|
|
18333
|
+
/**
|
|
18334
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
18335
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
18336
|
+
*/
|
|
18337
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
18259
18338
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
18339
|
+
AutomationWaitStepSchema,
|
|
18340
|
+
AutomationCapStepSchema,
|
|
18260
18341
|
object({
|
|
18261
|
-
kind: literal("
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
|
|
18270
|
-
*/
|
|
18271
|
-
deviceId: union$1([
|
|
18272
|
-
number().int(),
|
|
18273
|
-
array(number().int()).min(1),
|
|
18274
|
-
object({ $var: string().min(1) })
|
|
18275
|
-
]),
|
|
18276
|
-
cap: string().min(1),
|
|
18277
|
-
method: string().min(1),
|
|
18278
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
18279
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
18280
|
-
args: record(string(), unknown()).optional()
|
|
18342
|
+
kind: literal("action"),
|
|
18343
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
18344
|
+
actionId: string().min(1),
|
|
18345
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
18346
|
+
variables: record(string(), union$1([
|
|
18347
|
+
string(),
|
|
18348
|
+
number(),
|
|
18349
|
+
boolean()
|
|
18350
|
+
])).optional()
|
|
18281
18351
|
}),
|
|
18282
18352
|
object({
|
|
18283
18353
|
kind: literal("code"),
|
|
@@ -18286,74 +18356,743 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
18286
18356
|
code: string().min(1).max(2e4)
|
|
18287
18357
|
})
|
|
18288
18358
|
]);
|
|
18359
|
+
/**
|
|
18360
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
18361
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
18362
|
+
* actions. Absent means `single`.
|
|
18363
|
+
*
|
|
18364
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
18365
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
18366
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
18367
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
18368
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
18369
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
18370
|
+
* wait, never the single/queued limits.
|
|
18371
|
+
*/
|
|
18372
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
18373
|
+
object({ mode: literal("single") }),
|
|
18374
|
+
object({ mode: literal("restart") }),
|
|
18375
|
+
object({
|
|
18376
|
+
mode: literal("queued"),
|
|
18377
|
+
max: number().int().min(1).max(10)
|
|
18378
|
+
}),
|
|
18379
|
+
object({
|
|
18380
|
+
mode: literal("parallel"),
|
|
18381
|
+
max: number().int().min(1).max(10)
|
|
18382
|
+
}),
|
|
18383
|
+
object({
|
|
18384
|
+
mode: literal("cooldown"),
|
|
18385
|
+
minutes: number().int().min(1).max(1440)
|
|
18386
|
+
})
|
|
18387
|
+
]);
|
|
18289
18388
|
var AutomationRecipeSchema = object({
|
|
18290
18389
|
triggers: array(AutomationTriggerSchema),
|
|
18291
18390
|
conditions: AutomationConditionSchema.optional(),
|
|
18292
|
-
actions: array(AutomationActionSchema)
|
|
18391
|
+
actions: array(AutomationActionSchema),
|
|
18392
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
18393
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
18394
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
18293
18395
|
});
|
|
18396
|
+
var COCO_80_LABELS = [
|
|
18397
|
+
{
|
|
18398
|
+
id: "person",
|
|
18399
|
+
name: "Person"
|
|
18400
|
+
},
|
|
18401
|
+
{
|
|
18402
|
+
id: "bicycle",
|
|
18403
|
+
name: "Bicycle"
|
|
18404
|
+
},
|
|
18405
|
+
{
|
|
18406
|
+
id: "car",
|
|
18407
|
+
name: "Car"
|
|
18408
|
+
},
|
|
18409
|
+
{
|
|
18410
|
+
id: "motorcycle",
|
|
18411
|
+
name: "Motorcycle"
|
|
18412
|
+
},
|
|
18413
|
+
{
|
|
18414
|
+
id: "airplane",
|
|
18415
|
+
name: "Airplane"
|
|
18416
|
+
},
|
|
18417
|
+
{
|
|
18418
|
+
id: "bus",
|
|
18419
|
+
name: "Bus"
|
|
18420
|
+
},
|
|
18421
|
+
{
|
|
18422
|
+
id: "train",
|
|
18423
|
+
name: "Train"
|
|
18424
|
+
},
|
|
18425
|
+
{
|
|
18426
|
+
id: "truck",
|
|
18427
|
+
name: "Truck"
|
|
18428
|
+
},
|
|
18429
|
+
{
|
|
18430
|
+
id: "boat",
|
|
18431
|
+
name: "Boat"
|
|
18432
|
+
},
|
|
18433
|
+
{
|
|
18434
|
+
id: "traffic light",
|
|
18435
|
+
name: "Traffic Light"
|
|
18436
|
+
},
|
|
18437
|
+
{
|
|
18438
|
+
id: "fire hydrant",
|
|
18439
|
+
name: "Fire Hydrant"
|
|
18440
|
+
},
|
|
18441
|
+
{
|
|
18442
|
+
id: "stop sign",
|
|
18443
|
+
name: "Stop Sign"
|
|
18444
|
+
},
|
|
18445
|
+
{
|
|
18446
|
+
id: "parking meter",
|
|
18447
|
+
name: "Parking Meter"
|
|
18448
|
+
},
|
|
18449
|
+
{
|
|
18450
|
+
id: "bench",
|
|
18451
|
+
name: "Bench"
|
|
18452
|
+
},
|
|
18453
|
+
{
|
|
18454
|
+
id: "bird",
|
|
18455
|
+
name: "Bird"
|
|
18456
|
+
},
|
|
18457
|
+
{
|
|
18458
|
+
id: "cat",
|
|
18459
|
+
name: "Cat"
|
|
18460
|
+
},
|
|
18461
|
+
{
|
|
18462
|
+
id: "dog",
|
|
18463
|
+
name: "Dog"
|
|
18464
|
+
},
|
|
18465
|
+
{
|
|
18466
|
+
id: "horse",
|
|
18467
|
+
name: "Horse"
|
|
18468
|
+
},
|
|
18469
|
+
{
|
|
18470
|
+
id: "sheep",
|
|
18471
|
+
name: "Sheep"
|
|
18472
|
+
},
|
|
18473
|
+
{
|
|
18474
|
+
id: "cow",
|
|
18475
|
+
name: "Cow"
|
|
18476
|
+
},
|
|
18477
|
+
{
|
|
18478
|
+
id: "elephant",
|
|
18479
|
+
name: "Elephant"
|
|
18480
|
+
},
|
|
18481
|
+
{
|
|
18482
|
+
id: "bear",
|
|
18483
|
+
name: "Bear"
|
|
18484
|
+
},
|
|
18485
|
+
{
|
|
18486
|
+
id: "zebra",
|
|
18487
|
+
name: "Zebra"
|
|
18488
|
+
},
|
|
18489
|
+
{
|
|
18490
|
+
id: "giraffe",
|
|
18491
|
+
name: "Giraffe"
|
|
18492
|
+
},
|
|
18493
|
+
{
|
|
18494
|
+
id: "backpack",
|
|
18495
|
+
name: "Backpack"
|
|
18496
|
+
},
|
|
18497
|
+
{
|
|
18498
|
+
id: "umbrella",
|
|
18499
|
+
name: "Umbrella"
|
|
18500
|
+
},
|
|
18501
|
+
{
|
|
18502
|
+
id: "handbag",
|
|
18503
|
+
name: "Handbag"
|
|
18504
|
+
},
|
|
18505
|
+
{
|
|
18506
|
+
id: "tie",
|
|
18507
|
+
name: "Tie"
|
|
18508
|
+
},
|
|
18509
|
+
{
|
|
18510
|
+
id: "suitcase",
|
|
18511
|
+
name: "Suitcase"
|
|
18512
|
+
},
|
|
18513
|
+
{
|
|
18514
|
+
id: "frisbee",
|
|
18515
|
+
name: "Frisbee"
|
|
18516
|
+
},
|
|
18517
|
+
{
|
|
18518
|
+
id: "skis",
|
|
18519
|
+
name: "Skis"
|
|
18520
|
+
},
|
|
18521
|
+
{
|
|
18522
|
+
id: "snowboard",
|
|
18523
|
+
name: "Snowboard"
|
|
18524
|
+
},
|
|
18525
|
+
{
|
|
18526
|
+
id: "sports ball",
|
|
18527
|
+
name: "Sports Ball"
|
|
18528
|
+
},
|
|
18529
|
+
{
|
|
18530
|
+
id: "kite",
|
|
18531
|
+
name: "Kite"
|
|
18532
|
+
},
|
|
18533
|
+
{
|
|
18534
|
+
id: "baseball bat",
|
|
18535
|
+
name: "Baseball Bat"
|
|
18536
|
+
},
|
|
18537
|
+
{
|
|
18538
|
+
id: "baseball glove",
|
|
18539
|
+
name: "Baseball Glove"
|
|
18540
|
+
},
|
|
18541
|
+
{
|
|
18542
|
+
id: "skateboard",
|
|
18543
|
+
name: "Skateboard"
|
|
18544
|
+
},
|
|
18545
|
+
{
|
|
18546
|
+
id: "surfboard",
|
|
18547
|
+
name: "Surfboard"
|
|
18548
|
+
},
|
|
18549
|
+
{
|
|
18550
|
+
id: "tennis racket",
|
|
18551
|
+
name: "Tennis Racket"
|
|
18552
|
+
},
|
|
18553
|
+
{
|
|
18554
|
+
id: "bottle",
|
|
18555
|
+
name: "Bottle"
|
|
18556
|
+
},
|
|
18557
|
+
{
|
|
18558
|
+
id: "wine glass",
|
|
18559
|
+
name: "Wine Glass"
|
|
18560
|
+
},
|
|
18561
|
+
{
|
|
18562
|
+
id: "cup",
|
|
18563
|
+
name: "Cup"
|
|
18564
|
+
},
|
|
18565
|
+
{
|
|
18566
|
+
id: "fork",
|
|
18567
|
+
name: "Fork"
|
|
18568
|
+
},
|
|
18569
|
+
{
|
|
18570
|
+
id: "knife",
|
|
18571
|
+
name: "Knife"
|
|
18572
|
+
},
|
|
18573
|
+
{
|
|
18574
|
+
id: "spoon",
|
|
18575
|
+
name: "Spoon"
|
|
18576
|
+
},
|
|
18577
|
+
{
|
|
18578
|
+
id: "bowl",
|
|
18579
|
+
name: "Bowl"
|
|
18580
|
+
},
|
|
18581
|
+
{
|
|
18582
|
+
id: "banana",
|
|
18583
|
+
name: "Banana"
|
|
18584
|
+
},
|
|
18585
|
+
{
|
|
18586
|
+
id: "apple",
|
|
18587
|
+
name: "Apple"
|
|
18588
|
+
},
|
|
18589
|
+
{
|
|
18590
|
+
id: "sandwich",
|
|
18591
|
+
name: "Sandwich"
|
|
18592
|
+
},
|
|
18593
|
+
{
|
|
18594
|
+
id: "orange",
|
|
18595
|
+
name: "Orange"
|
|
18596
|
+
},
|
|
18597
|
+
{
|
|
18598
|
+
id: "broccoli",
|
|
18599
|
+
name: "Broccoli"
|
|
18600
|
+
},
|
|
18601
|
+
{
|
|
18602
|
+
id: "carrot",
|
|
18603
|
+
name: "Carrot"
|
|
18604
|
+
},
|
|
18605
|
+
{
|
|
18606
|
+
id: "hot dog",
|
|
18607
|
+
name: "Hot Dog"
|
|
18608
|
+
},
|
|
18609
|
+
{
|
|
18610
|
+
id: "pizza",
|
|
18611
|
+
name: "Pizza"
|
|
18612
|
+
},
|
|
18613
|
+
{
|
|
18614
|
+
id: "donut",
|
|
18615
|
+
name: "Donut"
|
|
18616
|
+
},
|
|
18617
|
+
{
|
|
18618
|
+
id: "cake",
|
|
18619
|
+
name: "Cake"
|
|
18620
|
+
},
|
|
18621
|
+
{
|
|
18622
|
+
id: "chair",
|
|
18623
|
+
name: "Chair"
|
|
18624
|
+
},
|
|
18625
|
+
{
|
|
18626
|
+
id: "couch",
|
|
18627
|
+
name: "Couch"
|
|
18628
|
+
},
|
|
18629
|
+
{
|
|
18630
|
+
id: "potted plant",
|
|
18631
|
+
name: "Potted Plant"
|
|
18632
|
+
},
|
|
18633
|
+
{
|
|
18634
|
+
id: "bed",
|
|
18635
|
+
name: "Bed"
|
|
18636
|
+
},
|
|
18637
|
+
{
|
|
18638
|
+
id: "dining table",
|
|
18639
|
+
name: "Dining Table"
|
|
18640
|
+
},
|
|
18641
|
+
{
|
|
18642
|
+
id: "toilet",
|
|
18643
|
+
name: "Toilet"
|
|
18644
|
+
},
|
|
18645
|
+
{
|
|
18646
|
+
id: "tv",
|
|
18647
|
+
name: "TV"
|
|
18648
|
+
},
|
|
18649
|
+
{
|
|
18650
|
+
id: "laptop",
|
|
18651
|
+
name: "Laptop"
|
|
18652
|
+
},
|
|
18653
|
+
{
|
|
18654
|
+
id: "mouse",
|
|
18655
|
+
name: "Mouse"
|
|
18656
|
+
},
|
|
18657
|
+
{
|
|
18658
|
+
id: "remote",
|
|
18659
|
+
name: "Remote"
|
|
18660
|
+
},
|
|
18661
|
+
{
|
|
18662
|
+
id: "keyboard",
|
|
18663
|
+
name: "Keyboard"
|
|
18664
|
+
},
|
|
18665
|
+
{
|
|
18666
|
+
id: "cell phone",
|
|
18667
|
+
name: "Cell Phone"
|
|
18668
|
+
},
|
|
18669
|
+
{
|
|
18670
|
+
id: "microwave",
|
|
18671
|
+
name: "Microwave"
|
|
18672
|
+
},
|
|
18673
|
+
{
|
|
18674
|
+
id: "oven",
|
|
18675
|
+
name: "Oven"
|
|
18676
|
+
},
|
|
18677
|
+
{
|
|
18678
|
+
id: "toaster",
|
|
18679
|
+
name: "Toaster"
|
|
18680
|
+
},
|
|
18681
|
+
{
|
|
18682
|
+
id: "sink",
|
|
18683
|
+
name: "Sink"
|
|
18684
|
+
},
|
|
18685
|
+
{
|
|
18686
|
+
id: "refrigerator",
|
|
18687
|
+
name: "Refrigerator"
|
|
18688
|
+
},
|
|
18689
|
+
{
|
|
18690
|
+
id: "book",
|
|
18691
|
+
name: "Book"
|
|
18692
|
+
},
|
|
18693
|
+
{
|
|
18694
|
+
id: "clock",
|
|
18695
|
+
name: "Clock"
|
|
18696
|
+
},
|
|
18697
|
+
{
|
|
18698
|
+
id: "vase",
|
|
18699
|
+
name: "Vase"
|
|
18700
|
+
},
|
|
18701
|
+
{
|
|
18702
|
+
id: "scissors",
|
|
18703
|
+
name: "Scissors"
|
|
18704
|
+
},
|
|
18705
|
+
{
|
|
18706
|
+
id: "teddy bear",
|
|
18707
|
+
name: "Teddy Bear"
|
|
18708
|
+
},
|
|
18709
|
+
{
|
|
18710
|
+
id: "hair drier",
|
|
18711
|
+
name: "Hair Drier"
|
|
18712
|
+
},
|
|
18713
|
+
{
|
|
18714
|
+
id: "toothbrush",
|
|
18715
|
+
name: "Toothbrush"
|
|
18716
|
+
}
|
|
18717
|
+
];
|
|
18718
|
+
new Set([
|
|
18719
|
+
{
|
|
18720
|
+
id: "person",
|
|
18721
|
+
name: "Person"
|
|
18722
|
+
},
|
|
18723
|
+
{
|
|
18724
|
+
id: "vehicle",
|
|
18725
|
+
name: "Vehicle"
|
|
18726
|
+
},
|
|
18727
|
+
{
|
|
18728
|
+
id: "animal",
|
|
18729
|
+
name: "Animal"
|
|
18730
|
+
},
|
|
18731
|
+
{
|
|
18732
|
+
id: "package",
|
|
18733
|
+
name: "Package"
|
|
18734
|
+
}
|
|
18735
|
+
].map((l) => l.id));
|
|
18736
|
+
var COCO_TO_MACRO = {
|
|
18737
|
+
mapping: {
|
|
18738
|
+
person: "person",
|
|
18739
|
+
bicycle: "vehicle",
|
|
18740
|
+
car: "vehicle",
|
|
18741
|
+
motorcycle: "vehicle",
|
|
18742
|
+
airplane: "vehicle",
|
|
18743
|
+
bus: "vehicle",
|
|
18744
|
+
train: "vehicle",
|
|
18745
|
+
truck: "vehicle",
|
|
18746
|
+
boat: "vehicle",
|
|
18747
|
+
bird: "animal",
|
|
18748
|
+
cat: "animal",
|
|
18749
|
+
dog: "animal",
|
|
18750
|
+
horse: "animal",
|
|
18751
|
+
sheep: "animal",
|
|
18752
|
+
cow: "animal",
|
|
18753
|
+
elephant: "animal",
|
|
18754
|
+
bear: "animal",
|
|
18755
|
+
zebra: "animal",
|
|
18756
|
+
giraffe: "animal",
|
|
18757
|
+
suitcase: "package",
|
|
18758
|
+
backpack: "package",
|
|
18759
|
+
handbag: "package"
|
|
18760
|
+
},
|
|
18761
|
+
preserveOriginal: false
|
|
18762
|
+
};
|
|
18763
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
18294
18764
|
/**
|
|
18295
|
-
*
|
|
18296
|
-
*
|
|
18765
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
18766
|
+
* so the editor can paint every block green or red with its reason.
|
|
18297
18767
|
*
|
|
18298
|
-
*
|
|
18299
|
-
*
|
|
18300
|
-
*
|
|
18301
|
-
*
|
|
18302
|
-
*
|
|
18768
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
18769
|
+
* every condition node (containers and leaves, including the ones a
|
|
18770
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
18771
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
18772
|
+
* for an Action run). Skipped
|
|
18773
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
18774
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
18303
18775
|
*
|
|
18304
|
-
*
|
|
18305
|
-
*
|
|
18306
|
-
* provider. Splitting the public aggregator from the raw collection
|
|
18307
|
-
* keeps both ends in codegen — there's no hand-written
|
|
18308
|
-
* `addon-pages.router.ts` wrapper anymore.
|
|
18776
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
18777
|
+
* vocabulary so an Action run records the same step shape.
|
|
18309
18778
|
*/
|
|
18310
|
-
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18779
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
18780
|
+
var TraceValueSchema = union$1([
|
|
18781
|
+
string(),
|
|
18782
|
+
number(),
|
|
18783
|
+
boolean(),
|
|
18784
|
+
_null(),
|
|
18785
|
+
array(union$1([string(), number()]))
|
|
18786
|
+
]);
|
|
18787
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
18788
|
+
"ran",
|
|
18789
|
+
"skipped-trigger",
|
|
18790
|
+
"skipped-conditions",
|
|
18791
|
+
"skipped-cooldown",
|
|
18792
|
+
"skipped-overlap",
|
|
18793
|
+
"failed",
|
|
18794
|
+
"aborted"
|
|
18795
|
+
]);
|
|
18796
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
18797
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
18798
|
+
"pass",
|
|
18799
|
+
"fail",
|
|
18800
|
+
"not-evaluated"
|
|
18801
|
+
]);
|
|
18802
|
+
var AutomationTriggerTraceSchema = object({
|
|
18803
|
+
kind: string().min(1),
|
|
18804
|
+
outcome: _enum(["pass", "fail"]),
|
|
18805
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
18806
|
+
reason: string(),
|
|
18807
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
18808
|
+
vars: record(string(), TraceValueSchema)
|
|
18319
18809
|
});
|
|
18320
|
-
var
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18810
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
18811
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
18812
|
+
path: string().min(1),
|
|
18813
|
+
kind: _enum([
|
|
18814
|
+
"all",
|
|
18815
|
+
"any",
|
|
18816
|
+
"not",
|
|
18817
|
+
"condition",
|
|
18818
|
+
"expression",
|
|
18819
|
+
"stationary-present"
|
|
18820
|
+
]),
|
|
18821
|
+
outcome: TraceNodeOutcomeSchema,
|
|
18822
|
+
reason: string(),
|
|
18823
|
+
deviceId: number().int().optional(),
|
|
18824
|
+
cap: string().optional(),
|
|
18825
|
+
fieldPath: string().optional(),
|
|
18826
|
+
operator: string().optional(),
|
|
18827
|
+
expected: TraceValueSchema.optional(),
|
|
18828
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
18829
|
+
observed: TraceValueSchema.optional()
|
|
18830
|
+
});
|
|
18831
|
+
var AutomationRunVerdictSchema = object({
|
|
18832
|
+
mode: AutomationRunModeSchema,
|
|
18833
|
+
decision: _enum([
|
|
18834
|
+
"run",
|
|
18835
|
+
"queued",
|
|
18836
|
+
"restart",
|
|
18837
|
+
"drop",
|
|
18838
|
+
"cooldown",
|
|
18839
|
+
"bypass"
|
|
18840
|
+
]),
|
|
18841
|
+
reason: string()
|
|
18842
|
+
});
|
|
18843
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
18844
|
+
var AutomationStepTraceSchema = object({
|
|
18845
|
+
/** `actions.<i>` */
|
|
18846
|
+
path: string().min(1),
|
|
18847
|
+
kind: string().min(1),
|
|
18848
|
+
cap: string().optional(),
|
|
18849
|
+
method: string().optional(),
|
|
18850
|
+
deviceId: number().int().optional(),
|
|
18851
|
+
startedAt: number().optional(),
|
|
18852
|
+
endedAt: number().optional(),
|
|
18853
|
+
outcome: _enum([
|
|
18854
|
+
"ok",
|
|
18855
|
+
"error",
|
|
18856
|
+
"not-run"
|
|
18857
|
+
]),
|
|
18858
|
+
message: string().optional()
|
|
18859
|
+
});
|
|
18860
|
+
var AutomationRunTraceSchema = object({
|
|
18861
|
+
runId: string().min(1),
|
|
18862
|
+
startedAt: number(),
|
|
18863
|
+
endedAt: number(),
|
|
18864
|
+
trigger: AutomationTriggerTraceSchema,
|
|
18865
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
18866
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
18867
|
+
steps: array(AutomationStepTraceSchema),
|
|
18868
|
+
outcome: AutomationRunOutcomeSchema,
|
|
18869
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
18870
|
+
repeat: number().int().min(1),
|
|
18871
|
+
/** When the latest of those repeats happened. */
|
|
18872
|
+
lastAt: number()
|
|
18324
18873
|
});
|
|
18325
|
-
method(_void(), array(AddonPageInfoSchema).readonly());
|
|
18326
18874
|
/**
|
|
18327
|
-
* `
|
|
18328
|
-
*
|
|
18329
|
-
|
|
18330
|
-
|
|
18331
|
-
|
|
18332
|
-
|
|
18875
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
18876
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
18877
|
+
*/
|
|
18878
|
+
var AutomationStateDocSchema = object({
|
|
18879
|
+
version: literal(1),
|
|
18880
|
+
lastRunStartedAt: number().nullable(),
|
|
18881
|
+
traces: array(AutomationRunTraceSchema)
|
|
18882
|
+
});
|
|
18883
|
+
/**
|
|
18884
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
18885
|
+
* declared as LIST ENTRIES, never as devices.
|
|
18333
18886
|
*
|
|
18334
|
-
*
|
|
18335
|
-
*
|
|
18336
|
-
*
|
|
18887
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
18888
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
18889
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
18890
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
18891
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
18892
|
+
*
|
|
18893
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
18894
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
18895
|
+
* runtime.
|
|
18337
18896
|
*/
|
|
18338
|
-
|
|
18339
|
-
|
|
18340
|
-
|
|
18341
|
-
|
|
18342
|
-
|
|
18343
|
-
|
|
18344
|
-
|
|
18345
|
-
|
|
18346
|
-
|
|
18347
|
-
|
|
18348
|
-
|
|
18349
|
-
|
|
18350
|
-
|
|
18351
|
-
|
|
18352
|
-
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
|
|
18356
|
-
|
|
18897
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
18898
|
+
var ActionVariableTypeSchema = _enum([
|
|
18899
|
+
"string",
|
|
18900
|
+
"number",
|
|
18901
|
+
"boolean",
|
|
18902
|
+
"select"
|
|
18903
|
+
]);
|
|
18904
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
18905
|
+
var ActionVariableValueSchema = union$1([
|
|
18906
|
+
string(),
|
|
18907
|
+
number(),
|
|
18908
|
+
boolean()
|
|
18909
|
+
]);
|
|
18910
|
+
/**
|
|
18911
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
18912
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
18913
|
+
*/
|
|
18914
|
+
var ActionVariableSchema = object({
|
|
18915
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
18916
|
+
label: string().min(1).max(120).optional(),
|
|
18917
|
+
type: ActionVariableTypeSchema,
|
|
18918
|
+
required: boolean().optional(),
|
|
18919
|
+
default: ActionVariableValueSchema.optional(),
|
|
18920
|
+
/** The allowed values of a `select`. */
|
|
18921
|
+
options: array(string().min(1)).min(1).optional()
|
|
18922
|
+
}).superRefine((v, ctx) => {
|
|
18923
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
18924
|
+
code: "custom",
|
|
18925
|
+
message: "a select variable needs options",
|
|
18926
|
+
path: ["options"]
|
|
18927
|
+
});
|
|
18928
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
18929
|
+
code: "custom",
|
|
18930
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
18931
|
+
path: ["default"]
|
|
18932
|
+
});
|
|
18933
|
+
});
|
|
18934
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
18935
|
+
function variableValueError(variable, value) {
|
|
18936
|
+
switch (variable.type) {
|
|
18937
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
18938
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
18939
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
18940
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
18941
|
+
}
|
|
18942
|
+
}
|
|
18943
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
18944
|
+
function isInternalActionId(actionId) {
|
|
18945
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
18946
|
+
}
|
|
18947
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
18948
|
+
function addonIdOfActionId(actionId) {
|
|
18949
|
+
if (isInternalActionId(actionId)) return null;
|
|
18950
|
+
const at = actionId.indexOf(":");
|
|
18951
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
18952
|
+
}
|
|
18953
|
+
var ActionStatusSchema = object({
|
|
18954
|
+
isRunning: boolean(),
|
|
18955
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
18956
|
+
lastRunAt: number().nullable(),
|
|
18957
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
18958
|
+
lastError: string().nullable()
|
|
18959
|
+
});
|
|
18960
|
+
var ActionEntrySchema = object({
|
|
18961
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
18962
|
+
id: string().min(3),
|
|
18963
|
+
name: string().min(1).max(120),
|
|
18964
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
18965
|
+
addonId: string().min(1),
|
|
18966
|
+
source: ActionSourceKindSchema,
|
|
18967
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
18968
|
+
readOnly: boolean(),
|
|
18969
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
18970
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
18971
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
18972
|
+
status: ActionStatusSchema
|
|
18973
|
+
}).superRefine((entry, ctx) => {
|
|
18974
|
+
if (entry.source === "internal") {
|
|
18975
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
18976
|
+
code: "custom",
|
|
18977
|
+
message: "an internal action id is internal:<uuid>",
|
|
18978
|
+
path: ["id"]
|
|
18979
|
+
});
|
|
18980
|
+
return;
|
|
18981
|
+
}
|
|
18982
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
18983
|
+
code: "custom",
|
|
18984
|
+
message: "only an internal action carries steps",
|
|
18985
|
+
path: ["steps"]
|
|
18986
|
+
});
|
|
18987
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
18988
|
+
code: "custom",
|
|
18989
|
+
message: "an addon action is read-only here",
|
|
18990
|
+
path: ["readOnly"]
|
|
18991
|
+
});
|
|
18992
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
18993
|
+
code: "custom",
|
|
18994
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
18995
|
+
path: ["id"]
|
|
18996
|
+
});
|
|
18997
|
+
});
|
|
18998
|
+
/** What an operator writes for an internal action. */
|
|
18999
|
+
var ActionInputSchema = object({
|
|
19000
|
+
name: string().min(1).max(120),
|
|
19001
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
19002
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
19003
|
+
});
|
|
19004
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
19005
|
+
var ActionRunOriginSchema = object({
|
|
19006
|
+
/** The automation block whose step started it. */
|
|
19007
|
+
blockId: string().min(1).optional() });
|
|
19008
|
+
/** `started` = the caller did not ask to wait. */
|
|
19009
|
+
var ActionRunOutcomeSchema = union$1([AutomationRunOutcomeSchema, literal("started")]);
|
|
19010
|
+
var ActionRunResultSchema = object({
|
|
19011
|
+
runId: string().min(1),
|
|
19012
|
+
outcome: ActionRunOutcomeSchema,
|
|
19013
|
+
/** Why it did not run, or what failed. */
|
|
19014
|
+
message: string().optional()
|
|
19015
|
+
});
|
|
19016
|
+
_enum([
|
|
19017
|
+
"not-found",
|
|
19018
|
+
"read-only",
|
|
19019
|
+
"invalid-variables",
|
|
19020
|
+
"invalid-steps",
|
|
19021
|
+
"not-linked",
|
|
19022
|
+
"busy"
|
|
19023
|
+
]);
|
|
19024
|
+
object({
|
|
19025
|
+
actionId: string(),
|
|
19026
|
+
runId: string(),
|
|
19027
|
+
isRunning: boolean(),
|
|
19028
|
+
/** Set when the run ended. */
|
|
19029
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
19030
|
+
lastRunAt: number().nullable(),
|
|
19031
|
+
lastError: string().nullable()
|
|
19032
|
+
});
|
|
19033
|
+
/**
|
|
19034
|
+
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
19035
|
+
* surface that admin-ui consumes through `useAddonPagesListPages()`.
|
|
19036
|
+
*
|
|
19037
|
+
* The provider iterates every `addon-pages-source` (collection) provider
|
|
19038
|
+
* and emits `AddonPageInfo[]` enriched with versioned `bundleUrl` strings
|
|
19039
|
+
* pointing at `/api/addon-pages/<addonId>/<bundle>?v=<mtime>`. The
|
|
19040
|
+
* filesystem `mtime` cache-buster lets the browser pick up addon
|
|
19041
|
+
* rebuilds without manual reload.
|
|
19042
|
+
*
|
|
19043
|
+
* The hub-local builtin `addon-pages-aggregator` (see
|
|
19044
|
+
* `@camstack/system/builtins/addon-pages-aggregator`) registers the
|
|
19045
|
+
* provider. Splitting the public aggregator from the raw collection
|
|
19046
|
+
* keeps both ends in codegen — there's no hand-written
|
|
19047
|
+
* `addon-pages.router.ts` wrapper anymore.
|
|
19048
|
+
*/
|
|
19049
|
+
var AddonPageDeclarationSchema$1 = object({
|
|
19050
|
+
id: string(),
|
|
19051
|
+
label: string(),
|
|
19052
|
+
icon: string(),
|
|
19053
|
+
path: string(),
|
|
19054
|
+
remoteName: string(),
|
|
19055
|
+
bundle: string(),
|
|
19056
|
+
section: string().optional(),
|
|
19057
|
+
sectionLabel: string().optional()
|
|
19058
|
+
});
|
|
19059
|
+
var AddonPageInfoSchema = object({
|
|
19060
|
+
addonId: string(),
|
|
19061
|
+
page: AddonPageDeclarationSchema$1,
|
|
19062
|
+
bundleUrl: string()
|
|
19063
|
+
});
|
|
19064
|
+
method(_void(), array(AddonPageInfoSchema).readonly());
|
|
19065
|
+
/**
|
|
19066
|
+
* `addon-pages-source` — collection cap exposing per-provider raw page
|
|
19067
|
+
* declarations. Every addon that contributes a UI page registers a
|
|
19068
|
+
* provider here. The hub-side singleton aggregator (`addon-pages` cap,
|
|
19069
|
+
* see `addon-pages.cap.ts`) walks this collection, stamps versioned
|
|
19070
|
+
* `bundleUrl` values, and returns the enriched `AddonPageInfo[]` list
|
|
19071
|
+
* that admin-ui consumes.
|
|
19072
|
+
*
|
|
19073
|
+
* The split exists because the public listing has a different output
|
|
19074
|
+
* shape than the per-provider raw declarations, and we want both ends
|
|
19075
|
+
* to flow through codegen instead of relying on a hand-written wrapper.
|
|
19076
|
+
*/
|
|
19077
|
+
var AddonPageDeclarationSchema = object({
|
|
19078
|
+
id: string(),
|
|
19079
|
+
label: string(),
|
|
19080
|
+
icon: string(),
|
|
19081
|
+
path: string(),
|
|
19082
|
+
/**
|
|
19083
|
+
* Module Federation remote name — must match the `name` field on the
|
|
19084
|
+
* page addon's `federation()` plugin config. Used by admin-ui's
|
|
19085
|
+
* `<AddonPageLoader>` to call `loadRemote('<remoteName>/page')`.
|
|
19086
|
+
* Conventionally `addon_<id>_page` (snake_case; MF names cannot
|
|
19087
|
+
* contain hyphens).
|
|
19088
|
+
*/
|
|
19089
|
+
remoteName: string(),
|
|
19090
|
+
/**
|
|
19091
|
+
* Bundle filename inside the addon's `dist/` dir served at
|
|
19092
|
+
* `/api/addon-pages/<addonId>/<bundle>`. With Module Federation this
|
|
19093
|
+
* is always `'remoteEntry.js'`; the value is kept on the metadata so
|
|
19094
|
+
* the static-file route can compute an mtime-based cache-buster URL
|
|
19095
|
+
* without a separate filesystem stat.
|
|
18357
19096
|
*/
|
|
18358
19097
|
bundle: string(),
|
|
18359
19098
|
/**
|
|
@@ -21342,7 +22081,7 @@ var CompositionEventPlanSchema = object({
|
|
|
21342
22081
|
stateField: string(),
|
|
21343
22082
|
fieldKey: string()
|
|
21344
22083
|
});
|
|
21345
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
22084
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
21346
22085
|
var CompositionProblemSchema = object({
|
|
21347
22086
|
code: _enum([
|
|
21348
22087
|
"reserved-variant",
|
|
@@ -21624,12 +22363,13 @@ var CHANGED = {
|
|
|
21624
22363
|
expr: "now"
|
|
21625
22364
|
};
|
|
21626
22365
|
function numeric(input) {
|
|
22366
|
+
const { alsoFrom, ...base } = input;
|
|
21627
22367
|
return {
|
|
21628
|
-
...
|
|
22368
|
+
...base,
|
|
21629
22369
|
family: "numeric",
|
|
21630
22370
|
deviceType: DeviceType.Sensor,
|
|
21631
22371
|
memberDeviceType: DeviceType.Sensor,
|
|
21632
|
-
memberDeviceTypes: [DeviceType.Sensor],
|
|
22372
|
+
memberDeviceTypes: [DeviceType.Sensor, ...alsoFrom?.deviceTypes ?? []],
|
|
21633
22373
|
activeWhen: void 0,
|
|
21634
22374
|
commandCaps: [],
|
|
21635
22375
|
baseUnit: baseUnitOf(input.quantity),
|
|
@@ -21637,9 +22377,10 @@ function numeric(input) {
|
|
|
21637
22377
|
accept: [{
|
|
21638
22378
|
cap: input.outputCap,
|
|
21639
22379
|
fieldPath: input.outputField
|
|
21640
|
-
}]
|
|
22380
|
+
}, ...alsoFrom === void 0 ? [] : [alsoFrom.accept]]
|
|
21641
22381
|
};
|
|
21642
22382
|
}
|
|
22383
|
+
var CLIMATE_DEVICES = [DeviceType.Thermostat, DeviceType.Climate];
|
|
21643
22384
|
function binary(input) {
|
|
21644
22385
|
return {
|
|
21645
22386
|
...input,
|
|
@@ -21661,29 +22402,43 @@ var GROUP_TEMPLATES = [
|
|
|
21661
22402
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
21662
22403
|
role: DeviceRole.TemperatureSensor,
|
|
21663
22404
|
outputCap: "temperature-sensor",
|
|
21664
|
-
outputField: "
|
|
22405
|
+
outputField: "temperature",
|
|
21665
22406
|
quantity: "temperature",
|
|
21666
22407
|
defaultAggregate: "mean",
|
|
21667
22408
|
empty: "null",
|
|
21668
|
-
companions: [NOW$2]
|
|
22409
|
+
companions: [NOW$2],
|
|
22410
|
+
alsoFrom: {
|
|
22411
|
+
deviceTypes: CLIMATE_DEVICES,
|
|
22412
|
+
accept: {
|
|
22413
|
+
cap: "climate-control",
|
|
22414
|
+
fieldPath: "currentTemp"
|
|
22415
|
+
}
|
|
22416
|
+
}
|
|
21669
22417
|
}),
|
|
21670
22418
|
numeric({
|
|
21671
22419
|
id: "humidity",
|
|
21672
22420
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
21673
22421
|
role: DeviceRole.HumiditySensor,
|
|
21674
22422
|
outputCap: "humidity-sensor",
|
|
21675
|
-
outputField: "
|
|
22423
|
+
outputField: "humidity",
|
|
21676
22424
|
quantity: "humidity",
|
|
21677
22425
|
defaultAggregate: "mean",
|
|
21678
22426
|
empty: "null",
|
|
21679
|
-
companions: [NOW$2]
|
|
22427
|
+
companions: [NOW$2],
|
|
22428
|
+
alsoFrom: {
|
|
22429
|
+
deviceTypes: CLIMATE_DEVICES,
|
|
22430
|
+
accept: {
|
|
22431
|
+
cap: "climate-control",
|
|
22432
|
+
fieldPath: "currentHumidity"
|
|
22433
|
+
}
|
|
22434
|
+
}
|
|
21680
22435
|
}),
|
|
21681
22436
|
numeric({
|
|
21682
22437
|
id: "pressure",
|
|
21683
22438
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
21684
22439
|
role: DeviceRole.PressureSensor,
|
|
21685
22440
|
outputCap: "pressure-sensor",
|
|
21686
|
-
outputField: "
|
|
22441
|
+
outputField: "pressure",
|
|
21687
22442
|
quantity: "pressure",
|
|
21688
22443
|
defaultAggregate: "mean",
|
|
21689
22444
|
empty: "null",
|
|
@@ -21694,7 +22449,7 @@ var GROUP_TEMPLATES = [
|
|
|
21694
22449
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
21695
22450
|
role: DeviceRole.AmbientLightSensor,
|
|
21696
22451
|
outputCap: "ambient-light-sensor",
|
|
21697
|
-
outputField: "
|
|
22452
|
+
outputField: "illuminance",
|
|
21698
22453
|
quantity: "illuminance",
|
|
21699
22454
|
defaultAggregate: "mean",
|
|
21700
22455
|
empty: "null",
|
|
@@ -21705,7 +22460,7 @@ var GROUP_TEMPLATES = [
|
|
|
21705
22460
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
21706
22461
|
role: DeviceRole.PowerSensor,
|
|
21707
22462
|
outputCap: "power-meter",
|
|
21708
|
-
outputField: "
|
|
22463
|
+
outputField: "power",
|
|
21709
22464
|
quantity: "power",
|
|
21710
22465
|
defaultAggregate: "sum",
|
|
21711
22466
|
empty: "omit",
|
|
@@ -21716,7 +22471,7 @@ var GROUP_TEMPLATES = [
|
|
|
21716
22471
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
21717
22472
|
role: DeviceRole.EnergySensor,
|
|
21718
22473
|
outputCap: "power-meter",
|
|
21719
|
-
outputField: "
|
|
22474
|
+
outputField: "energy",
|
|
21720
22475
|
quantity: "energy",
|
|
21721
22476
|
defaultAggregate: "sum",
|
|
21722
22477
|
empty: "omit",
|
|
@@ -21727,7 +22482,7 @@ var GROUP_TEMPLATES = [
|
|
|
21727
22482
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
21728
22483
|
role: DeviceRole.BatterySensor,
|
|
21729
22484
|
outputCap: "battery",
|
|
21730
|
-
outputField: "
|
|
22485
|
+
outputField: "level",
|
|
21731
22486
|
quantity: "percentage",
|
|
21732
22487
|
defaultAggregate: "mean",
|
|
21733
22488
|
empty: "null",
|
|
@@ -22305,7 +23060,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
22305
23060
|
kind: "mutation",
|
|
22306
23061
|
auth: "admin",
|
|
22307
23062
|
access: "view"
|
|
22308
|
-
})
|
|
23063
|
+
}), method(object({
|
|
23064
|
+
blockId: string().min(1),
|
|
23065
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
23066
|
+
runStartedAt: number().optional(),
|
|
23067
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
23068
|
+
}), _void(), {
|
|
23069
|
+
kind: "mutation",
|
|
23070
|
+
auth: "admin"
|
|
23071
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
23072
|
+
traces: array(AutomationRunTraceSchema),
|
|
23073
|
+
lastError: string().nullable()
|
|
23074
|
+
}), { auth: "admin" });
|
|
22309
23075
|
/**
|
|
22310
23076
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
22311
23077
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -45950,6 +46716,17 @@ var LlmProfileSchema = object({
|
|
|
45950
46716
|
* field in its editor only when its descriptor lists it in `profileFields`. */
|
|
45951
46717
|
topK: number().int().positive().optional(),
|
|
45952
46718
|
maxTokens: number().int().positive().optional(),
|
|
46719
|
+
/** How hard the model "thinks" before it answers. Omitted = the model's own
|
|
46720
|
+
* default. `off` matters for structured output: a thinking model can spend
|
|
46721
|
+
* the whole completion on reasoning and return an empty `content`. Carried
|
|
46722
|
+
* only by the wires that have it — a kind offers the field in its editor
|
|
46723
|
+
* only when its descriptor lists it in `profileFields`. */
|
|
46724
|
+
reasoningEffort: _enum([
|
|
46725
|
+
"off",
|
|
46726
|
+
"low",
|
|
46727
|
+
"medium",
|
|
46728
|
+
"high"
|
|
46729
|
+
]).optional(),
|
|
45953
46730
|
/** Prompt context window. Advisory for cloud kinds (they enforce their own). */
|
|
45954
46731
|
contextLength: number().int().positive().optional(),
|
|
45955
46732
|
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
@@ -45988,6 +46765,7 @@ var LlmProfileFieldSchema = _enum([
|
|
|
45988
46765
|
"topP",
|
|
45989
46766
|
"topK",
|
|
45990
46767
|
"maxTokens",
|
|
46768
|
+
"reasoningEffort",
|
|
45991
46769
|
"contextLength",
|
|
45992
46770
|
"systemPrompt",
|
|
45993
46771
|
"timeoutMs",
|
|
@@ -47180,710 +47958,391 @@ method(_void(), NetworkEndpointSchema, { kind: "mutation" }), method(_void(), _v
|
|
|
47180
47958
|
* adapter picks what it supports and the degrade engine filters the rest.
|
|
47181
47959
|
*/
|
|
47182
47960
|
var AttachmentMediaTypeSchema = _enum([
|
|
47183
|
-
"image",
|
|
47184
|
-
"video",
|
|
47185
|
-
"gif",
|
|
47186
|
-
"audio",
|
|
47187
|
-
"icon"
|
|
47188
|
-
]);
|
|
47189
|
-
/**
|
|
47190
|
-
* A single attachment. Exactly one of `url` (remote source, most adapters
|
|
47191
|
-
* prefer this) or `bytes` (inline source; required for Pushover-style
|
|
47192
|
-
* bytes-only kinds) MUST be present — the degrade engine expresses a
|
|
47193
|
-
* url→bytes fetch as a `needsFetch` directive the adapter executes.
|
|
47194
|
-
*/
|
|
47195
|
-
var AttachmentSchema = object({
|
|
47196
|
-
mediaType: AttachmentMediaTypeSchema,
|
|
47197
|
-
url: string().optional(),
|
|
47198
|
-
bytes: _instanceof(Uint8Array).optional(),
|
|
47199
|
-
mime: string().optional(),
|
|
47200
|
-
name: string().optional()
|
|
47201
|
-
}).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
|
|
47202
|
-
var NotificationFormatSchema = _enum([
|
|
47203
|
-
"text",
|
|
47204
|
-
"markdown",
|
|
47205
|
-
"html"
|
|
47206
|
-
]);
|
|
47207
|
-
/**
|
|
47208
|
-
* The CLOSED icon vocabulary an action button may use.
|
|
47209
|
-
*
|
|
47210
|
-
* A closed set, not a free string, and that is the whole point: an arbitrary
|
|
47211
|
-
* icon name is one that ntfy renders, zentik silently drops, and nobody
|
|
47212
|
-
* notices — the same class of gap as a zone vocabulary nothing produced
|
|
47213
|
-
* ([D35](../../../docs/decisions/adr-0035.md)). Every adapter maps this set or
|
|
47214
|
-
* declares `actionIcons: false` and the degrade engine strips the field.
|
|
47215
|
-
*
|
|
47216
|
-
* Named by INTENT, never by glyph. "check" would tie the vocabulary to one
|
|
47217
|
-
* renderer's icon set; "acknowledge" survives an adapter that draws it
|
|
47218
|
-
* differently.
|
|
47219
|
-
*
|
|
47220
|
-
* ── A TOKEN IS NOT A WIRE VALUE ─────────────────────────────────────
|
|
47221
|
-
*
|
|
47222
|
-
* These names are for US. **No adapter may forward one verbatim.** Each maps
|
|
47223
|
-
* the whole set onto its own renderer's vocabulary through a
|
|
47224
|
-
* `Record<NotificationActionIcon, string>` — a Record, never a lookup with a
|
|
47225
|
-
* fallback, so adding a member here fails every adapter's build until someone
|
|
47226
|
-
* decides its glyph, which is the only place that decision can be made
|
|
47227
|
-
* honestly.
|
|
47228
|
-
*
|
|
47229
|
-
* This paragraph is the bug. Zentik declared `actionIcons: true` and passed
|
|
47230
|
-
* `disarm` straight through; iOS feeds that string to
|
|
47231
|
-
* `UNNotificationActionIcon(systemImageName:)`, `disarm` is not an SF Symbol,
|
|
47232
|
-
* and every snooze and alarm button arrived BLANK. A pass-through is not a
|
|
47233
|
-
* mapping, and "the field is documented" is not "the value renders".
|
|
47234
|
-
*
|
|
47235
|
-
* Adding a member is TRAIN-BOUND. The enum lives in the published
|
|
47236
|
-
* `@camstack/server` closure and the cap seam validates against the HUB's copy,
|
|
47237
|
-
* so an addon that emits a token the running hub does not know does not lose an
|
|
47238
|
-
* icon — its whole `send` fails Zod validation and the notification never
|
|
47239
|
-
* arrives. Never emit a new token from an addon before the train carrying it.
|
|
47240
|
-
*/
|
|
47241
|
-
var NotificationActionIconSchema = _enum([
|
|
47242
|
-
"acknowledge",
|
|
47243
|
-
"dismiss",
|
|
47244
|
-
"silence",
|
|
47245
|
-
"snooze",
|
|
47246
|
-
"view",
|
|
47247
|
-
"play",
|
|
47248
|
-
"open",
|
|
47249
|
-
"close",
|
|
47250
|
-
"lock",
|
|
47251
|
-
"unlock",
|
|
47252
|
-
"arm",
|
|
47253
|
-
"arm-home",
|
|
47254
|
-
"arm-away",
|
|
47255
|
-
"arm-night",
|
|
47256
|
-
"disarm",
|
|
47257
|
-
"light",
|
|
47258
|
-
"alert",
|
|
47259
|
-
"camera"
|
|
47260
|
-
]);
|
|
47261
|
-
/** A single tap-through action button. */
|
|
47262
|
-
var NotificationActionSchema = object({
|
|
47263
|
-
id: string(),
|
|
47264
|
-
label: string(),
|
|
47265
|
-
url: string().optional(),
|
|
47266
|
-
/** Dropped by the degrade engine for a kind with `caps.actionIcons: false`. */
|
|
47267
|
-
icon: NotificationActionIconSchema.optional(),
|
|
47268
|
-
/**
|
|
47269
|
-
* Renders in a warning style where the notifier supports it.
|
|
47270
|
-
*
|
|
47271
|
-
* A HINT, never a gate. The callback's authority is its token and nothing
|
|
47272
|
-
* else — see `notification-center/action-token.ts` for what that does and
|
|
47273
|
-
* does not buy.
|
|
47274
|
-
*/
|
|
47275
|
-
destructive: boolean().optional(),
|
|
47276
|
-
/**
|
|
47277
|
-
* How the tap should REACH the url.
|
|
47278
|
-
*
|
|
47279
|
-
* `navigate` (absent, and every button authored before this field) opens it:
|
|
47280
|
-
* the phone leaves the notification and shows whatever the callback returns.
|
|
47281
|
-
* That is right for a button whose answer the operator wants to read.
|
|
47282
|
-
*
|
|
47283
|
-
* `background` fires it as a POST and stays put. It exists for the buttons
|
|
47284
|
-
* whose whole point is not to interrupt — "silence this for 30 minutes" is
|
|
47285
|
-
* an answer to the notification, and being thrown into a browser tab to
|
|
47286
|
-
* confirm it costs more attention than the notification did. A backend that
|
|
47287
|
-
* cannot do a background call renders it as an ordinary link (the adapters
|
|
47288
|
-
* fall back rather than dropping the button), so this is a preference, never
|
|
47289
|
-
* a requirement.
|
|
47290
|
-
*/
|
|
47291
|
-
mode: _enum(["navigate", "background"]).optional()
|
|
47292
|
-
});
|
|
47293
|
-
/**
|
|
47294
|
-
|
|
47295
|
-
|
|
47296
|
-
|
|
47297
|
-
|
|
47298
|
-
|
|
47299
|
-
|
|
47300
|
-
|
|
47301
|
-
|
|
47302
|
-
|
|
47303
|
-
|
|
47304
|
-
|
|
47305
|
-
|
|
47306
|
-
|
|
47307
|
-
|
|
47308
|
-
|
|
47309
|
-
|
|
47310
|
-
|
|
47311
|
-
|
|
47312
|
-
|
|
47313
|
-
|
|
47314
|
-
|
|
47315
|
-
|
|
47316
|
-
|
|
47317
|
-
|
|
47318
|
-
|
|
47319
|
-
|
|
47320
|
-
|
|
47321
|
-
|
|
47322
|
-
|
|
47323
|
-
|
|
47324
|
-
|
|
47325
|
-
|
|
47326
|
-
|
|
47327
|
-
|
|
47328
|
-
|
|
47329
|
-
|
|
47330
|
-
|
|
47331
|
-
|
|
47332
|
-
|
|
47333
|
-
|
|
47334
|
-
|
|
47335
|
-
|
|
47336
|
-
|
|
47337
|
-
|
|
47338
|
-
|
|
47339
|
-
|
|
47340
|
-
|
|
47341
|
-
|
|
47342
|
-
|
|
47343
|
-
|
|
47344
|
-
|
|
47345
|
-
|
|
47346
|
-
|
|
47347
|
-
|
|
47348
|
-
|
|
47349
|
-
|
|
47350
|
-
|
|
47351
|
-
|
|
47352
|
-
|
|
47353
|
-
|
|
47354
|
-
|
|
47355
|
-
|
|
47356
|
-
|
|
47357
|
-
|
|
47358
|
-
|
|
47359
|
-
|
|
47360
|
-
|
|
47361
|
-
|
|
47362
|
-
|
|
47363
|
-
|
|
47364
|
-
|
|
47365
|
-
|
|
47366
|
-
|
|
47367
|
-
|
|
47368
|
-
|
|
47369
|
-
|
|
47370
|
-
|
|
47371
|
-
|
|
47372
|
-
|
|
47373
|
-
|
|
47374
|
-
|
|
47375
|
-
|
|
47376
|
-
|
|
47377
|
-
|
|
47378
|
-
|
|
47379
|
-
|
|
47380
|
-
|
|
47381
|
-
|
|
47382
|
-
|
|
47383
|
-
|
|
47384
|
-
|
|
47385
|
-
|
|
47386
|
-
|
|
47387
|
-
|
|
47388
|
-
|
|
47389
|
-
|
|
47390
|
-
*
|
|
47391
|
-
|
|
47392
|
-
|
|
47393
|
-
|
|
47394
|
-
*
|
|
47395
|
-
*
|
|
47396
|
-
*
|
|
47397
|
-
|
|
47398
|
-
|
|
47399
|
-
|
|
47400
|
-
|
|
47401
|
-
|
|
47402
|
-
|
|
47403
|
-
|
|
47404
|
-
|
|
47405
|
-
|
|
47406
|
-
|
|
47407
|
-
|
|
47408
|
-
|
|
47409
|
-
|
|
47410
|
-
|
|
47411
|
-
|
|
47412
|
-
|
|
47413
|
-
|
|
47414
|
-
|
|
47415
|
-
|
|
47416
|
-
|
|
47417
|
-
|
|
47418
|
-
*/
|
|
47419
|
-
|
|
47420
|
-
|
|
47421
|
-
|
|
47422
|
-
|
|
47423
|
-
|
|
47424
|
-
*
|
|
47425
|
-
*
|
|
47426
|
-
*
|
|
47427
|
-
|
|
47428
|
-
|
|
47429
|
-
|
|
47430
|
-
|
|
47431
|
-
|
|
47432
|
-
|
|
47433
|
-
|
|
47434
|
-
|
|
47435
|
-
|
|
47436
|
-
/**
|
|
47437
|
-
|
|
47438
|
-
|
|
47439
|
-
|
|
47440
|
-
|
|
47441
|
-
|
|
47442
|
-
|
|
47443
|
-
|
|
47444
|
-
|
|
47445
|
-
|
|
47446
|
-
|
|
47447
|
-
|
|
47448
|
-
|
|
47449
|
-
|
|
47450
|
-
|
|
47451
|
-
|
|
47452
|
-
|
|
47453
|
-
|
|
47454
|
-
|
|
47455
|
-
|
|
47456
|
-
|
|
47457
|
-
|
|
47458
|
-
|
|
47459
|
-
*
|
|
47460
|
-
*
|
|
47461
|
-
*/
|
|
47462
|
-
|
|
47463
|
-
|
|
47464
|
-
|
|
47465
|
-
|
|
47466
|
-
|
|
47467
|
-
|
|
47468
|
-
|
|
47469
|
-
|
|
47470
|
-
|
|
47471
|
-
|
|
47472
|
-
|
|
47473
|
-
|
|
47474
|
-
|
|
47475
|
-
|
|
47476
|
-
|
|
47477
|
-
|
|
47478
|
-
|
|
47479
|
-
kind: string(),
|
|
47480
|
-
|
|
47481
|
-
|
|
47482
|
-
|
|
47483
|
-
})
|
|
47484
|
-
|
|
47485
|
-
|
|
47486
|
-
|
|
47487
|
-
|
|
47488
|
-
|
|
47489
|
-
})
|
|
47490
|
-
|
|
47491
|
-
|
|
47492
|
-
|
|
47493
|
-
|
|
47494
|
-
|
|
47495
|
-
|
|
47496
|
-
|
|
47497
|
-
|
|
47498
|
-
})
|
|
47499
|
-
|
|
47500
|
-
|
|
47501
|
-
|
|
47502
|
-
|
|
47503
|
-
|
|
47504
|
-
|
|
47505
|
-
|
|
47506
|
-
|
|
47507
|
-
|
|
47508
|
-
|
|
47509
|
-
|
|
47510
|
-
|
|
47511
|
-
|
|
47512
|
-
|
|
47513
|
-
|
|
47514
|
-
|
|
47515
|
-
|
|
47516
|
-
})
|
|
47517
|
-
|
|
47518
|
-
|
|
47519
|
-
|
|
47520
|
-
|
|
47521
|
-
|
|
47522
|
-
|
|
47523
|
-
|
|
47524
|
-
|
|
47525
|
-
|
|
47526
|
-
|
|
47527
|
-
|
|
47528
|
-
|
|
47529
|
-
|
|
47530
|
-
|
|
47531
|
-
|
|
47532
|
-
|
|
47533
|
-
|
|
47534
|
-
|
|
47535
|
-
|
|
47536
|
-
|
|
47537
|
-
|
|
47538
|
-
|
|
47539
|
-
|
|
47540
|
-
|
|
47541
|
-
|
|
47542
|
-
|
|
47543
|
-
|
|
47544
|
-
|
|
47545
|
-
|
|
47546
|
-
|
|
47547
|
-
|
|
47548
|
-
|
|
47549
|
-
|
|
47550
|
-
|
|
47551
|
-
|
|
47552
|
-
|
|
47553
|
-
|
|
47554
|
-
|
|
47555
|
-
|
|
47556
|
-
|
|
47557
|
-
|
|
47558
|
-
|
|
47559
|
-
|
|
47560
|
-
|
|
47561
|
-
|
|
47562
|
-
|
|
47563
|
-
|
|
47564
|
-
|
|
47565
|
-
|
|
47566
|
-
|
|
47567
|
-
|
|
47568
|
-
},
|
|
47569
|
-
{
|
|
47570
|
-
id: "parking meter",
|
|
47571
|
-
name: "Parking Meter"
|
|
47572
|
-
},
|
|
47573
|
-
{
|
|
47574
|
-
id: "bench",
|
|
47575
|
-
name: "Bench"
|
|
47576
|
-
},
|
|
47577
|
-
{
|
|
47578
|
-
id: "bird",
|
|
47579
|
-
name: "Bird"
|
|
47580
|
-
},
|
|
47581
|
-
{
|
|
47582
|
-
id: "cat",
|
|
47583
|
-
name: "Cat"
|
|
47584
|
-
},
|
|
47585
|
-
{
|
|
47586
|
-
id: "dog",
|
|
47587
|
-
name: "Dog"
|
|
47588
|
-
},
|
|
47589
|
-
{
|
|
47590
|
-
id: "horse",
|
|
47591
|
-
name: "Horse"
|
|
47592
|
-
},
|
|
47593
|
-
{
|
|
47594
|
-
id: "sheep",
|
|
47595
|
-
name: "Sheep"
|
|
47596
|
-
},
|
|
47597
|
-
{
|
|
47598
|
-
id: "cow",
|
|
47599
|
-
name: "Cow"
|
|
47600
|
-
},
|
|
47601
|
-
{
|
|
47602
|
-
id: "elephant",
|
|
47603
|
-
name: "Elephant"
|
|
47604
|
-
},
|
|
47605
|
-
{
|
|
47606
|
-
id: "bear",
|
|
47607
|
-
name: "Bear"
|
|
47608
|
-
},
|
|
47609
|
-
{
|
|
47610
|
-
id: "zebra",
|
|
47611
|
-
name: "Zebra"
|
|
47612
|
-
},
|
|
47613
|
-
{
|
|
47614
|
-
id: "giraffe",
|
|
47615
|
-
name: "Giraffe"
|
|
47616
|
-
},
|
|
47617
|
-
{
|
|
47618
|
-
id: "backpack",
|
|
47619
|
-
name: "Backpack"
|
|
47620
|
-
},
|
|
47621
|
-
{
|
|
47622
|
-
id: "umbrella",
|
|
47623
|
-
name: "Umbrella"
|
|
47624
|
-
},
|
|
47625
|
-
{
|
|
47626
|
-
id: "handbag",
|
|
47627
|
-
name: "Handbag"
|
|
47628
|
-
},
|
|
47629
|
-
{
|
|
47630
|
-
id: "tie",
|
|
47631
|
-
name: "Tie"
|
|
47632
|
-
},
|
|
47633
|
-
{
|
|
47634
|
-
id: "suitcase",
|
|
47635
|
-
name: "Suitcase"
|
|
47636
|
-
},
|
|
47637
|
-
{
|
|
47638
|
-
id: "frisbee",
|
|
47639
|
-
name: "Frisbee"
|
|
47640
|
-
},
|
|
47641
|
-
{
|
|
47642
|
-
id: "skis",
|
|
47643
|
-
name: "Skis"
|
|
47644
|
-
},
|
|
47645
|
-
{
|
|
47646
|
-
id: "snowboard",
|
|
47647
|
-
name: "Snowboard"
|
|
47648
|
-
},
|
|
47649
|
-
{
|
|
47650
|
-
id: "sports ball",
|
|
47651
|
-
name: "Sports Ball"
|
|
47652
|
-
},
|
|
47653
|
-
{
|
|
47654
|
-
id: "kite",
|
|
47655
|
-
name: "Kite"
|
|
47656
|
-
},
|
|
47657
|
-
{
|
|
47658
|
-
id: "baseball bat",
|
|
47659
|
-
name: "Baseball Bat"
|
|
47660
|
-
},
|
|
47661
|
-
{
|
|
47662
|
-
id: "baseball glove",
|
|
47663
|
-
name: "Baseball Glove"
|
|
47664
|
-
},
|
|
47665
|
-
{
|
|
47666
|
-
id: "skateboard",
|
|
47667
|
-
name: "Skateboard"
|
|
47668
|
-
},
|
|
47669
|
-
{
|
|
47670
|
-
id: "surfboard",
|
|
47671
|
-
name: "Surfboard"
|
|
47672
|
-
},
|
|
47673
|
-
{
|
|
47674
|
-
id: "tennis racket",
|
|
47675
|
-
name: "Tennis Racket"
|
|
47676
|
-
},
|
|
47677
|
-
{
|
|
47678
|
-
id: "bottle",
|
|
47679
|
-
name: "Bottle"
|
|
47680
|
-
},
|
|
47681
|
-
{
|
|
47682
|
-
id: "wine glass",
|
|
47683
|
-
name: "Wine Glass"
|
|
47684
|
-
},
|
|
47685
|
-
{
|
|
47686
|
-
id: "cup",
|
|
47687
|
-
name: "Cup"
|
|
47688
|
-
},
|
|
47689
|
-
{
|
|
47690
|
-
id: "fork",
|
|
47691
|
-
name: "Fork"
|
|
47692
|
-
},
|
|
47693
|
-
{
|
|
47694
|
-
id: "knife",
|
|
47695
|
-
name: "Knife"
|
|
47696
|
-
},
|
|
47697
|
-
{
|
|
47698
|
-
id: "spoon",
|
|
47699
|
-
name: "Spoon"
|
|
47700
|
-
},
|
|
47701
|
-
{
|
|
47702
|
-
id: "bowl",
|
|
47703
|
-
name: "Bowl"
|
|
47704
|
-
},
|
|
47705
|
-
{
|
|
47706
|
-
id: "banana",
|
|
47707
|
-
name: "Banana"
|
|
47708
|
-
},
|
|
47709
|
-
{
|
|
47710
|
-
id: "apple",
|
|
47711
|
-
name: "Apple"
|
|
47712
|
-
},
|
|
47713
|
-
{
|
|
47714
|
-
id: "sandwich",
|
|
47715
|
-
name: "Sandwich"
|
|
47716
|
-
},
|
|
47717
|
-
{
|
|
47718
|
-
id: "orange",
|
|
47719
|
-
name: "Orange"
|
|
47720
|
-
},
|
|
47721
|
-
{
|
|
47722
|
-
id: "broccoli",
|
|
47723
|
-
name: "Broccoli"
|
|
47724
|
-
},
|
|
47725
|
-
{
|
|
47726
|
-
id: "carrot",
|
|
47727
|
-
name: "Carrot"
|
|
47728
|
-
},
|
|
47729
|
-
{
|
|
47730
|
-
id: "hot dog",
|
|
47731
|
-
name: "Hot Dog"
|
|
47732
|
-
},
|
|
47733
|
-
{
|
|
47734
|
-
id: "pizza",
|
|
47735
|
-
name: "Pizza"
|
|
47736
|
-
},
|
|
47737
|
-
{
|
|
47738
|
-
id: "donut",
|
|
47739
|
-
name: "Donut"
|
|
47740
|
-
},
|
|
47741
|
-
{
|
|
47742
|
-
id: "cake",
|
|
47743
|
-
name: "Cake"
|
|
47744
|
-
},
|
|
47745
|
-
{
|
|
47746
|
-
id: "chair",
|
|
47747
|
-
name: "Chair"
|
|
47748
|
-
},
|
|
47749
|
-
{
|
|
47750
|
-
id: "couch",
|
|
47751
|
-
name: "Couch"
|
|
47752
|
-
},
|
|
47753
|
-
{
|
|
47754
|
-
id: "potted plant",
|
|
47755
|
-
name: "Potted Plant"
|
|
47756
|
-
},
|
|
47757
|
-
{
|
|
47758
|
-
id: "bed",
|
|
47759
|
-
name: "Bed"
|
|
47760
|
-
},
|
|
47761
|
-
{
|
|
47762
|
-
id: "dining table",
|
|
47763
|
-
name: "Dining Table"
|
|
47764
|
-
},
|
|
47765
|
-
{
|
|
47766
|
-
id: "toilet",
|
|
47767
|
-
name: "Toilet"
|
|
47768
|
-
},
|
|
47769
|
-
{
|
|
47770
|
-
id: "tv",
|
|
47771
|
-
name: "TV"
|
|
47772
|
-
},
|
|
47773
|
-
{
|
|
47774
|
-
id: "laptop",
|
|
47775
|
-
name: "Laptop"
|
|
47776
|
-
},
|
|
47777
|
-
{
|
|
47778
|
-
id: "mouse",
|
|
47779
|
-
name: "Mouse"
|
|
47780
|
-
},
|
|
47781
|
-
{
|
|
47782
|
-
id: "remote",
|
|
47783
|
-
name: "Remote"
|
|
47784
|
-
},
|
|
47785
|
-
{
|
|
47786
|
-
id: "keyboard",
|
|
47787
|
-
name: "Keyboard"
|
|
47788
|
-
},
|
|
47789
|
-
{
|
|
47790
|
-
id: "cell phone",
|
|
47791
|
-
name: "Cell Phone"
|
|
47792
|
-
},
|
|
47793
|
-
{
|
|
47794
|
-
id: "microwave",
|
|
47795
|
-
name: "Microwave"
|
|
47796
|
-
},
|
|
47797
|
-
{
|
|
47798
|
-
id: "oven",
|
|
47799
|
-
name: "Oven"
|
|
47800
|
-
},
|
|
47801
|
-
{
|
|
47802
|
-
id: "toaster",
|
|
47803
|
-
name: "Toaster"
|
|
47804
|
-
},
|
|
47805
|
-
{
|
|
47806
|
-
id: "sink",
|
|
47807
|
-
name: "Sink"
|
|
47808
|
-
},
|
|
47809
|
-
{
|
|
47810
|
-
id: "refrigerator",
|
|
47811
|
-
name: "Refrigerator"
|
|
47812
|
-
},
|
|
47813
|
-
{
|
|
47814
|
-
id: "book",
|
|
47815
|
-
name: "Book"
|
|
47816
|
-
},
|
|
47817
|
-
{
|
|
47818
|
-
id: "clock",
|
|
47819
|
-
name: "Clock"
|
|
47820
|
-
},
|
|
47821
|
-
{
|
|
47822
|
-
id: "vase",
|
|
47823
|
-
name: "Vase"
|
|
47824
|
-
},
|
|
47825
|
-
{
|
|
47826
|
-
id: "scissors",
|
|
47827
|
-
name: "Scissors"
|
|
47828
|
-
},
|
|
47829
|
-
{
|
|
47830
|
-
id: "teddy bear",
|
|
47831
|
-
name: "Teddy Bear"
|
|
47832
|
-
},
|
|
47833
|
-
{
|
|
47834
|
-
id: "hair drier",
|
|
47835
|
-
name: "Hair Drier"
|
|
47836
|
-
},
|
|
47837
|
-
{
|
|
47838
|
-
id: "toothbrush",
|
|
47839
|
-
name: "Toothbrush"
|
|
47840
|
-
}
|
|
47841
|
-
];
|
|
47842
|
-
new Set([
|
|
47843
|
-
{
|
|
47844
|
-
id: "person",
|
|
47845
|
-
name: "Person"
|
|
47846
|
-
},
|
|
47847
|
-
{
|
|
47848
|
-
id: "vehicle",
|
|
47849
|
-
name: "Vehicle"
|
|
47850
|
-
},
|
|
47851
|
-
{
|
|
47852
|
-
id: "animal",
|
|
47853
|
-
name: "Animal"
|
|
47854
|
-
},
|
|
47855
|
-
{
|
|
47856
|
-
id: "package",
|
|
47857
|
-
name: "Package"
|
|
47858
|
-
}
|
|
47859
|
-
].map((l) => l.id));
|
|
47860
|
-
var COCO_TO_MACRO = {
|
|
47861
|
-
mapping: {
|
|
47862
|
-
person: "person",
|
|
47863
|
-
bicycle: "vehicle",
|
|
47864
|
-
car: "vehicle",
|
|
47865
|
-
motorcycle: "vehicle",
|
|
47866
|
-
airplane: "vehicle",
|
|
47867
|
-
bus: "vehicle",
|
|
47868
|
-
train: "vehicle",
|
|
47869
|
-
truck: "vehicle",
|
|
47870
|
-
boat: "vehicle",
|
|
47871
|
-
bird: "animal",
|
|
47872
|
-
cat: "animal",
|
|
47873
|
-
dog: "animal",
|
|
47874
|
-
horse: "animal",
|
|
47875
|
-
sheep: "animal",
|
|
47876
|
-
cow: "animal",
|
|
47877
|
-
elephant: "animal",
|
|
47878
|
-
bear: "animal",
|
|
47879
|
-
zebra: "animal",
|
|
47880
|
-
giraffe: "animal",
|
|
47881
|
-
suitcase: "package",
|
|
47882
|
-
backpack: "package",
|
|
47883
|
-
handbag: "package"
|
|
47884
|
-
},
|
|
47885
|
-
preserveOriginal: false
|
|
47886
|
-
};
|
|
47961
|
+
"image",
|
|
47962
|
+
"video",
|
|
47963
|
+
"gif",
|
|
47964
|
+
"audio",
|
|
47965
|
+
"icon"
|
|
47966
|
+
]);
|
|
47967
|
+
/**
|
|
47968
|
+
* A single attachment. Exactly one of `url` (remote source, most adapters
|
|
47969
|
+
* prefer this) or `bytes` (inline source; required for Pushover-style
|
|
47970
|
+
* bytes-only kinds) MUST be present — the degrade engine expresses a
|
|
47971
|
+
* url→bytes fetch as a `needsFetch` directive the adapter executes.
|
|
47972
|
+
*/
|
|
47973
|
+
var AttachmentSchema = object({
|
|
47974
|
+
mediaType: AttachmentMediaTypeSchema,
|
|
47975
|
+
url: string().optional(),
|
|
47976
|
+
bytes: _instanceof(Uint8Array).optional(),
|
|
47977
|
+
mime: string().optional(),
|
|
47978
|
+
name: string().optional()
|
|
47979
|
+
}).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
|
|
47980
|
+
var NotificationFormatSchema = _enum([
|
|
47981
|
+
"text",
|
|
47982
|
+
"markdown",
|
|
47983
|
+
"html"
|
|
47984
|
+
]);
|
|
47985
|
+
/**
|
|
47986
|
+
* The CLOSED icon vocabulary an action button may use.
|
|
47987
|
+
*
|
|
47988
|
+
* A closed set, not a free string, and that is the whole point: an arbitrary
|
|
47989
|
+
* icon name is one that ntfy renders, zentik silently drops, and nobody
|
|
47990
|
+
* notices — the same class of gap as a zone vocabulary nothing produced
|
|
47991
|
+
* ([D35](../../../docs/decisions/adr-0035.md)). Every adapter maps this set or
|
|
47992
|
+
* declares `actionIcons: false` and the degrade engine strips the field.
|
|
47993
|
+
*
|
|
47994
|
+
* Named by INTENT, never by glyph. "check" would tie the vocabulary to one
|
|
47995
|
+
* renderer's icon set; "acknowledge" survives an adapter that draws it
|
|
47996
|
+
* differently.
|
|
47997
|
+
*
|
|
47998
|
+
* ── A TOKEN IS NOT A WIRE VALUE ─────────────────────────────────────
|
|
47999
|
+
*
|
|
48000
|
+
* These names are for US. **No adapter may forward one verbatim.** Each maps
|
|
48001
|
+
* the whole set onto its own renderer's vocabulary through a
|
|
48002
|
+
* `Record<NotificationActionIcon, string>` — a Record, never a lookup with a
|
|
48003
|
+
* fallback, so adding a member here fails every adapter's build until someone
|
|
48004
|
+
* decides its glyph, which is the only place that decision can be made
|
|
48005
|
+
* honestly.
|
|
48006
|
+
*
|
|
48007
|
+
* This paragraph is the bug. Zentik declared `actionIcons: true` and passed
|
|
48008
|
+
* `disarm` straight through; iOS feeds that string to
|
|
48009
|
+
* `UNNotificationActionIcon(systemImageName:)`, `disarm` is not an SF Symbol,
|
|
48010
|
+
* and every snooze and alarm button arrived BLANK. A pass-through is not a
|
|
48011
|
+
* mapping, and "the field is documented" is not "the value renders".
|
|
48012
|
+
*
|
|
48013
|
+
* Adding a member is TRAIN-BOUND. The enum lives in the published
|
|
48014
|
+
* `@camstack/server` closure and the cap seam validates against the HUB's copy,
|
|
48015
|
+
* so an addon that emits a token the running hub does not know does not lose an
|
|
48016
|
+
* icon — its whole `send` fails Zod validation and the notification never
|
|
48017
|
+
* arrives. Never emit a new token from an addon before the train carrying it.
|
|
48018
|
+
*/
|
|
48019
|
+
var NotificationActionIconSchema = _enum([
|
|
48020
|
+
"acknowledge",
|
|
48021
|
+
"dismiss",
|
|
48022
|
+
"silence",
|
|
48023
|
+
"snooze",
|
|
48024
|
+
"view",
|
|
48025
|
+
"play",
|
|
48026
|
+
"open",
|
|
48027
|
+
"close",
|
|
48028
|
+
"lock",
|
|
48029
|
+
"unlock",
|
|
48030
|
+
"arm",
|
|
48031
|
+
"arm-home",
|
|
48032
|
+
"arm-away",
|
|
48033
|
+
"arm-night",
|
|
48034
|
+
"disarm",
|
|
48035
|
+
"light",
|
|
48036
|
+
"alert",
|
|
48037
|
+
"camera"
|
|
48038
|
+
]);
|
|
48039
|
+
/** A single tap-through action button. */
|
|
48040
|
+
var NotificationActionSchema = object({
|
|
48041
|
+
id: string(),
|
|
48042
|
+
label: string(),
|
|
48043
|
+
url: string().optional(),
|
|
48044
|
+
/** Dropped by the degrade engine for a kind with `caps.actionIcons: false`. */
|
|
48045
|
+
icon: NotificationActionIconSchema.optional(),
|
|
48046
|
+
/**
|
|
48047
|
+
* Renders in a warning style where the notifier supports it.
|
|
48048
|
+
*
|
|
48049
|
+
* A HINT, never a gate. The callback's authority is its token and nothing
|
|
48050
|
+
* else — see `notification-center/action-token.ts` for what that does and
|
|
48051
|
+
* does not buy.
|
|
48052
|
+
*/
|
|
48053
|
+
destructive: boolean().optional(),
|
|
48054
|
+
/**
|
|
48055
|
+
* How the tap should REACH the url.
|
|
48056
|
+
*
|
|
48057
|
+
* `navigate` (absent, and every button authored before this field) opens it:
|
|
48058
|
+
* the phone leaves the notification and shows whatever the callback returns.
|
|
48059
|
+
* That is right for a button whose answer the operator wants to read.
|
|
48060
|
+
*
|
|
48061
|
+
* `background` fires it as a POST and stays put. It exists for the buttons
|
|
48062
|
+
* whose whole point is not to interrupt — "silence this for 30 minutes" is
|
|
48063
|
+
* an answer to the notification, and being thrown into a browser tab to
|
|
48064
|
+
* confirm it costs more attention than the notification did. A backend that
|
|
48065
|
+
* cannot do a background call renders it as an ordinary link (the adapters
|
|
48066
|
+
* fall back rather than dropping the button), so this is a preference, never
|
|
48067
|
+
* a requirement.
|
|
48068
|
+
*/
|
|
48069
|
+
mode: _enum(["navigate", "background"]).optional()
|
|
48070
|
+
});
|
|
48071
|
+
/** A delivery parameter value: what a notifier declared it takes. */
|
|
48072
|
+
var DeliveryParamValueSchema = union$1([
|
|
48073
|
+
string(),
|
|
48074
|
+
number(),
|
|
48075
|
+
boolean()
|
|
48076
|
+
]);
|
|
48077
|
+
/**
|
|
48078
|
+
* One extra delivery parameter a notifier KIND declares (D938). A rule that
|
|
48079
|
+
* addresses a target of that kind may set it; a kind that declares nothing is
|
|
48080
|
+
* never handed one. The admin UI derives its control from this descriptor —
|
|
48081
|
+
* no editor knows a service by name.
|
|
48082
|
+
*
|
|
48083
|
+
* Optional fields are `.optional()`, never `.default()` (a Zod default does not
|
|
48084
|
+
* run on the addon cap path).
|
|
48085
|
+
*/
|
|
48086
|
+
var DeliveryParamSchema = object({
|
|
48087
|
+
key: string().min(1),
|
|
48088
|
+
label: string(),
|
|
48089
|
+
/** i18n key of the label, resolved by the declaring addon's namespace. */
|
|
48090
|
+
labelKey: string().optional(),
|
|
48091
|
+
type: _enum([
|
|
48092
|
+
"enum",
|
|
48093
|
+
"number",
|
|
48094
|
+
"boolean",
|
|
48095
|
+
"string"
|
|
48096
|
+
]),
|
|
48097
|
+
/** `enum` only: the closed set of accepted values. */
|
|
48098
|
+
options: array(object({
|
|
48099
|
+
value: string(),
|
|
48100
|
+
label: string()
|
|
48101
|
+
})).optional(),
|
|
48102
|
+
/** `number` only. */
|
|
48103
|
+
min: number().optional(),
|
|
48104
|
+
max: number().optional(),
|
|
48105
|
+
/** What the notifier does when the rule sets nothing; shown as the placeholder. */
|
|
48106
|
+
default: DeliveryParamValueSchema.optional()
|
|
48107
|
+
});
|
|
48108
|
+
/**
|
|
48109
|
+
* The canonical notification. `body` is the only hard field (Apprise model).
|
|
48110
|
+
* `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
|
|
48111
|
+
* NOT a fixed severity enum — each kind declares its own `caps.levels` and
|
|
48112
|
+
* the adapter maps this ordinal onto its native level. `level?` is an
|
|
48113
|
+
* optional kind-native level id (`emergency`, `silent`, …) that overrides
|
|
48114
|
+
* `priority` for that one target.
|
|
48115
|
+
*/
|
|
48116
|
+
var NotificationSchema = object({
|
|
48117
|
+
body: string(),
|
|
48118
|
+
title: string().optional(),
|
|
48119
|
+
format: NotificationFormatSchema.default("text"),
|
|
48120
|
+
priority: number().int().min(1).max(5).default(3),
|
|
48121
|
+
level: string().optional(),
|
|
48122
|
+
attachments: array(AttachmentSchema).optional(),
|
|
48123
|
+
clickUrl: string().optional(),
|
|
48124
|
+
actions: array(NotificationActionSchema).optional(),
|
|
48125
|
+
sound: string().optional(),
|
|
48126
|
+
ttl: number().optional(),
|
|
48127
|
+
tag: string().optional(),
|
|
48128
|
+
deviceId: number().optional(),
|
|
48129
|
+
eventId: string().optional(),
|
|
48130
|
+
metadata: record(string(), unknown()).optional(),
|
|
48131
|
+
/**
|
|
48132
|
+
* Values for the parameters the target's kind DECLARES in
|
|
48133
|
+
* {@link TargetKindSchema} `deliveryParams`. Already validated against the
|
|
48134
|
+
* declaration by the sender; a notifier reads only the keys it declared.
|
|
48135
|
+
*/
|
|
48136
|
+
delivery: record(string(), DeliveryParamValueSchema).optional()
|
|
48137
|
+
});
|
|
48138
|
+
/** One declared native severity/priority level for a kind. */
|
|
48139
|
+
var TargetKindLevelSchema = object({
|
|
48140
|
+
id: string(),
|
|
48141
|
+
label: string(),
|
|
48142
|
+
/** Which canonical priority (1..5) this level maps to. `null` = qualitative-only. */
|
|
48143
|
+
ordinal: number().int().min(1).max(5).nullable(),
|
|
48144
|
+
flags: object({
|
|
48145
|
+
critical: boolean().optional(),
|
|
48146
|
+
silent: boolean().optional(),
|
|
48147
|
+
noPush: boolean().optional()
|
|
48148
|
+
}).optional(),
|
|
48149
|
+
/** e.g. Pushover `emergency` requires `retry` / `expire`. */
|
|
48150
|
+
requires: array(string()).optional(),
|
|
48151
|
+
description: string().optional()
|
|
48152
|
+
});
|
|
48153
|
+
/** The full capability block consulted before dispatch. */
|
|
48154
|
+
var TargetKindCapsSchema = object({
|
|
48155
|
+
attachments: object({
|
|
48156
|
+
mediaTypes: array(AttachmentMediaTypeSchema),
|
|
48157
|
+
mode: _enum([
|
|
48158
|
+
"url",
|
|
48159
|
+
"bytes",
|
|
48160
|
+
"both"
|
|
48161
|
+
]),
|
|
48162
|
+
max: number().int().nonnegative(),
|
|
48163
|
+
maxBytes: number().int().positive().optional()
|
|
48164
|
+
}),
|
|
48165
|
+
/** Max action buttons (0 = none). */
|
|
48166
|
+
actions: number().int().nonnegative(),
|
|
48167
|
+
/**
|
|
48168
|
+
* Whether this kind renders a per-action ICON.
|
|
48169
|
+
*
|
|
48170
|
+
* `.optional()`, deliberately NOT `.default(false)`: a Zod default does not
|
|
48171
|
+
* run on the addon cap path — three production failures in one day taught
|
|
48172
|
+
* this repo that once. Absent is read as false by the degrade engine, which
|
|
48173
|
+
* is the safe direction: an icon that is not rendered costs nothing, an icon
|
|
48174
|
+
* assumed and dropped costs the operator's trust in the field.
|
|
48175
|
+
*/
|
|
48176
|
+
actionIcons: boolean().optional(),
|
|
48177
|
+
levels: array(TargetKindLevelSchema),
|
|
48178
|
+
format: array(NotificationFormatSchema),
|
|
48179
|
+
clickUrl: boolean(),
|
|
48180
|
+
sound: boolean(),
|
|
48181
|
+
ttl: boolean(),
|
|
48182
|
+
bodyMaxLen: number().int().positive()
|
|
48183
|
+
});
|
|
48184
|
+
/**
|
|
48185
|
+
* `configSchema` is a `ConfigUISchema` tree passed through to the admin
|
|
48186
|
+
* FormBuilder. Stored as `z.unknown()` at the cap seam (mirrors
|
|
48187
|
+
* `device-provider.getChildCreationSchema` `CreationSchemaOutputSchema`) —
|
|
48188
|
+
* the union is large and not meant for runtime validation here; the exported
|
|
48189
|
+
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
48190
|
+
*/
|
|
48191
|
+
var ConfigSchemaPassthrough$2 = unknown();
|
|
48192
|
+
var TargetKindSchema = object({
|
|
48193
|
+
kind: string(),
|
|
48194
|
+
label: string(),
|
|
48195
|
+
icon: string(),
|
|
48196
|
+
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
48197
|
+
addonId: string(),
|
|
48198
|
+
/**
|
|
48199
|
+
* URL of the kind's bundled BRAND icon, served by the providing addon over
|
|
48200
|
+
* its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
|
|
48201
|
+
* when the addon bundles no icon for that kind — the client then falls back
|
|
48202
|
+
* to a neutral glyph rather than rendering the raw `icon` NAME as text.
|
|
48203
|
+
*
|
|
48204
|
+
* Root-relative on purpose: it resolves against whatever origin serves a web
|
|
48205
|
+
* client, and a native client joins it onto its own hub base.
|
|
48206
|
+
*
|
|
48207
|
+
* DECLARED here deliberately. It used to travel as an undeclared passthrough
|
|
48208
|
+
* field that survived only because the runtime cap-router forwards provider
|
|
48209
|
+
* output verbatim — so every consumer had to re-declare it by hand to stop
|
|
48210
|
+
* its own Zod parse from stripping it, and the whole arrangement would have
|
|
48211
|
+
* broken silently the moment output validation was tightened anywhere.
|
|
48212
|
+
*/
|
|
48213
|
+
iconUrl: string().optional(),
|
|
48214
|
+
/**
|
|
48215
|
+
* Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
|
|
48216
|
+
*
|
|
48217
|
+
* The server knows this and therefore says it, because the client cannot
|
|
48218
|
+
* safely guess: a React-Native client renders SVG and raster through two
|
|
48219
|
+
* DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
|
|
48220
|
+
* not decode SVG on iOS/Android), so without this it silently fell back to a
|
|
48221
|
+
* placeholder glyph for every vector icon while the web build looked fine.
|
|
48222
|
+
*
|
|
48223
|
+
* Absent when {@link iconUrl} is absent, or for a legacy provider that has
|
|
48224
|
+
* not been updated — a client that cannot determine the type should prefer
|
|
48225
|
+
* its raster path, which is the safe default for an unknown image.
|
|
48226
|
+
*/
|
|
48227
|
+
iconMediaType: string().optional(),
|
|
48228
|
+
configSchema: ConfigSchemaPassthrough$2,
|
|
48229
|
+
/**
|
|
48230
|
+
* The config keys that decide WHERE this kind's secrets are sent (server,
|
|
48231
|
+
* base URL, instance, chat, recipient). A save that changes any of them
|
|
48232
|
+
* while leaving a secret redacted is refused by the provider (D634), so an
|
|
48233
|
+
* editor uses this to ask for the secret on exactly those edits instead of
|
|
48234
|
+
* on every edit.
|
|
48235
|
+
*
|
|
48236
|
+
* Optional: absent from a provider that holds no secret (the Home Assistant
|
|
48237
|
+
* kinds) and from a provider older than this field — an editor that finds
|
|
48238
|
+
* it absent must assume ANY edit may need the secret.
|
|
48239
|
+
*/
|
|
48240
|
+
destinationKeys: array(string()).optional(),
|
|
48241
|
+
supportsDiscovery: boolean(),
|
|
48242
|
+
/**
|
|
48243
|
+
* Extra delivery parameters a rule may set for a target of this kind (D938).
|
|
48244
|
+
* Absent = none; the rule editor then offers nothing.
|
|
48245
|
+
*/
|
|
48246
|
+
deliveryParams: array(DeliveryParamSchema).optional(),
|
|
48247
|
+
caps: TargetKindCapsSchema
|
|
48248
|
+
});
|
|
48249
|
+
/**
|
|
48250
|
+
* A persisted target. `config` holds secrets; providers REDACT secret fields
|
|
48251
|
+
* (return a presence marker only) when serving `listTargets` — never
|
|
48252
|
+
* round-trip a stored secret to the UI.
|
|
48253
|
+
*/
|
|
48254
|
+
var TargetSchema = object({
|
|
48255
|
+
id: string(),
|
|
48256
|
+
name: string(),
|
|
48257
|
+
kind: string(),
|
|
48258
|
+
addonId: string(),
|
|
48259
|
+
enabled: boolean(),
|
|
48260
|
+
config: record(string(), unknown())
|
|
48261
|
+
});
|
|
48262
|
+
/** A discovery-surfaced candidate (config is partial + non-secret). */
|
|
48263
|
+
var DiscoveredTargetSchema = object({
|
|
48264
|
+
kind: string(),
|
|
48265
|
+
suggestedName: string(),
|
|
48266
|
+
config: record(string(), unknown())
|
|
48267
|
+
});
|
|
48268
|
+
/** The degrade engine's report — what was resolved / dropped / degraded. */
|
|
48269
|
+
var RenderedAsSchema = object({
|
|
48270
|
+
level: string(),
|
|
48271
|
+
format: NotificationFormatSchema,
|
|
48272
|
+
attachmentsSent: number().int().nonnegative(),
|
|
48273
|
+
actionsSent: number().int().nonnegative(),
|
|
48274
|
+
truncated: boolean(),
|
|
48275
|
+
dropped: array(string())
|
|
48276
|
+
});
|
|
48277
|
+
var SendResultSchema = object({
|
|
48278
|
+
success: boolean(),
|
|
48279
|
+
error: string().optional(),
|
|
48280
|
+
renderedAs: RenderedAsSchema.optional()
|
|
48281
|
+
});
|
|
48282
|
+
/** Same shape as SendResult — kept as a distinct name for the test panel. */
|
|
48283
|
+
var TestResultSchema = SendResultSchema;
|
|
48284
|
+
/**
|
|
48285
|
+
* Pre-save credential probe against a partial (unsaved) target config.
|
|
48286
|
+
* `resolvedUrl` never includes secrets (token stripped from path).
|
|
48287
|
+
*/
|
|
48288
|
+
var ProbeTargetConfigResultSchema = object({
|
|
48289
|
+
ok: boolean(),
|
|
48290
|
+
resolvedUrl: string(),
|
|
48291
|
+
httpStatus: number().int().optional(),
|
|
48292
|
+
stateInstance: string().optional(),
|
|
48293
|
+
error: string().optional()
|
|
48294
|
+
});
|
|
48295
|
+
method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSchema), { auth: "admin" }), method(object({ targetId: string() }), TargetSchema, { auth: "admin" }), method(object({
|
|
48296
|
+
kind: string(),
|
|
48297
|
+
config: record(string(), unknown()).optional(),
|
|
48298
|
+
/**
|
|
48299
|
+
* When editing / duplicating, the blank password field never round-trips
|
|
48300
|
+
* the stored token. Pass the source target id so the provider can restore
|
|
48301
|
+
* secrets server-side before dialling (same merge as upsert).
|
|
48302
|
+
*/
|
|
48303
|
+
targetId: string().optional()
|
|
48304
|
+
}), array(DiscoveredTargetSchema), { auth: "admin" }), method(object({
|
|
48305
|
+
kind: string(),
|
|
48306
|
+
config: record(string(), unknown()),
|
|
48307
|
+
/** See `discoverTargets.targetId` — restore stored secrets for a blank password. */
|
|
48308
|
+
targetId: string().optional()
|
|
48309
|
+
}), ProbeTargetConfigResultSchema, {
|
|
48310
|
+
kind: "mutation",
|
|
48311
|
+
auth: "admin"
|
|
48312
|
+
}), method(object({
|
|
48313
|
+
targetId: string(),
|
|
48314
|
+
notification: NotificationSchema
|
|
48315
|
+
}), SendResultSchema, {
|
|
48316
|
+
kind: "mutation",
|
|
48317
|
+
auth: "admin"
|
|
48318
|
+
}), method(object({
|
|
48319
|
+
targetId: string(),
|
|
48320
|
+
sample: NotificationSchema.optional()
|
|
48321
|
+
}), TestResultSchema, {
|
|
48322
|
+
kind: "mutation",
|
|
48323
|
+
auth: "admin"
|
|
48324
|
+
}), method(object({
|
|
48325
|
+
target: TargetSchema,
|
|
48326
|
+
/**
|
|
48327
|
+
* Duplicate flow: create a NEW target id while copying secrets from an
|
|
48328
|
+
* existing row. The UI never holds the stored token; blank / redacted
|
|
48329
|
+
* password fields are restored from this source (D634 still applies if
|
|
48330
|
+
* destinations diverge without a re-typed secret).
|
|
48331
|
+
*/
|
|
48332
|
+
cloneSecretsFrom: string().optional()
|
|
48333
|
+
}), TargetSchema, {
|
|
48334
|
+
kind: "mutation",
|
|
48335
|
+
auth: "admin"
|
|
48336
|
+
}), method(object({ targetId: string() }), _void(), {
|
|
48337
|
+
kind: "mutation",
|
|
48338
|
+
auth: "admin"
|
|
48339
|
+
}), method(object({
|
|
48340
|
+
targetId: string(),
|
|
48341
|
+
enabled: boolean()
|
|
48342
|
+
}), _void(), {
|
|
48343
|
+
kind: "mutation",
|
|
48344
|
+
auth: "admin"
|
|
48345
|
+
});
|
|
47887
48346
|
var AUDIO_MACRO_LABELS = [
|
|
47888
48347
|
{
|
|
47889
48348
|
id: "speech",
|
|
@@ -60799,7 +61258,9 @@ var ManifestShapeSchema = object({
|
|
|
60799
61258
|
icon: string().optional()
|
|
60800
61259
|
}).optional(),
|
|
60801
61260
|
protected: boolean().optional(),
|
|
60802
|
-
removable: boolean().optional()
|
|
61261
|
+
removable: boolean().optional(),
|
|
61262
|
+
/** Declared Integrations-page block (mirror of `AddonDeclaration.integrationSection`). */
|
|
61263
|
+
integrationSection: _enum(["system", "providers"]).optional()
|
|
60803
61264
|
});
|
|
60804
61265
|
var AddonProcessSchema = object({
|
|
60805
61266
|
pid: number().optional(),
|
|
@@ -61164,9 +61625,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
61164
61625
|
}), LogStreamEntrySchema, { kind: "subscription" });
|
|
61165
61626
|
object({
|
|
61166
61627
|
/** Carbon dioxide concentration in ppm. */
|
|
61167
|
-
|
|
61628
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
61168
61629
|
/** Total volatile organic compounds in ppb. */
|
|
61169
|
-
|
|
61630
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
61170
61631
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
61171
61632
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
61172
61633
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -61179,7 +61640,7 @@ object({
|
|
|
61179
61640
|
DeviceType.Sensor;
|
|
61180
61641
|
object({
|
|
61181
61642
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
61182
|
-
|
|
61643
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
61183
61644
|
precision: 0,
|
|
61184
61645
|
label: "Illuminance"
|
|
61185
61646
|
})),
|
|
@@ -61276,6 +61737,84 @@ DeviceType.Camera, method(object({ deviceId: number() }), AudioMetricsSnapshotSc
|
|
|
61276
61737
|
* would produce more than `maxPoints` samples. */
|
|
61277
61738
|
sampleEveryMs: number().int().positive().optional()
|
|
61278
61739
|
}), AudioMetricsHistorySchema);
|
|
61740
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
61741
|
+
actionId: string().min(1),
|
|
61742
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
61743
|
+
}), _void(), {
|
|
61744
|
+
kind: "mutation",
|
|
61745
|
+
auth: "admin"
|
|
61746
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
61747
|
+
kind: "mutation",
|
|
61748
|
+
auth: "admin"
|
|
61749
|
+
});
|
|
61750
|
+
/**
|
|
61751
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
61752
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
61753
|
+
*
|
|
61754
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
61755
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
61756
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
61757
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
61758
|
+
* drift (D3).
|
|
61759
|
+
*
|
|
61760
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
61761
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
61762
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
61763
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
61764
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
61765
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
61766
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
61767
|
+
*
|
|
61768
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
61769
|
+
* logged — never queued.
|
|
61770
|
+
*/
|
|
61771
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
61772
|
+
var ActionLinksSchema = object({
|
|
61773
|
+
deviceId: number().int().nonnegative(),
|
|
61774
|
+
actionIds: array(string().min(1)).max(100)
|
|
61775
|
+
});
|
|
61776
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
61777
|
+
actionId: string().min(1),
|
|
61778
|
+
deviceId: number().int().nonnegative().optional()
|
|
61779
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
61780
|
+
role: "viewer",
|
|
61781
|
+
auth: "protected",
|
|
61782
|
+
kind: "query",
|
|
61783
|
+
caller: "required"
|
|
61784
|
+
}), method(object({
|
|
61785
|
+
actionId: string().min(1),
|
|
61786
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
61787
|
+
wait: boolean().optional(),
|
|
61788
|
+
origin: ActionRunOriginSchema.optional(),
|
|
61789
|
+
deviceId: number().int().nonnegative().optional()
|
|
61790
|
+
}), ActionRunResultSchema, {
|
|
61791
|
+
role: "viewer",
|
|
61792
|
+
auth: "protected",
|
|
61793
|
+
kind: "mutation",
|
|
61794
|
+
caller: "required"
|
|
61795
|
+
}), method(ActionIdInput, _void(), {
|
|
61796
|
+
kind: "mutation",
|
|
61797
|
+
auth: "admin"
|
|
61798
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
61799
|
+
kind: "mutation",
|
|
61800
|
+
auth: "admin"
|
|
61801
|
+
}), method(object({
|
|
61802
|
+
actionId: string().min(1),
|
|
61803
|
+
action: ActionInputSchema.partial()
|
|
61804
|
+
}), object({ action: ActionEntrySchema }), {
|
|
61805
|
+
kind: "mutation",
|
|
61806
|
+
auth: "admin"
|
|
61807
|
+
}), method(ActionIdInput, _void(), {
|
|
61808
|
+
kind: "mutation",
|
|
61809
|
+
auth: "admin"
|
|
61810
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
61811
|
+
role: "viewer",
|
|
61812
|
+
auth: "protected",
|
|
61813
|
+
kind: "query"
|
|
61814
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
61815
|
+
kind: "mutation",
|
|
61816
|
+
auth: "admin"
|
|
61817
|
+
});
|
|
61279
61818
|
object({
|
|
61280
61819
|
/** Whether the automation is currently enabled. Disabled automations
|
|
61281
61820
|
* ignore their trigger block — manual `trigger` still works. */
|
|
@@ -61329,7 +61868,7 @@ var BatteryStatusSchema = object({
|
|
|
61329
61868
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
61330
61869
|
* declines to band a non-finite reading, which is the correct shape.
|
|
61331
61870
|
*/
|
|
61332
|
-
|
|
61871
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
61333
61872
|
/**
|
|
61334
61873
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
61335
61874
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -61339,7 +61878,7 @@ var BatteryStatusSchema = object({
|
|
|
61339
61878
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
61340
61879
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
61341
61880
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
61342
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
61881
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
61343
61882
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
61344
61883
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
61345
61884
|
*/
|
|
@@ -61363,7 +61902,7 @@ var BatteryStatusSchema = object({
|
|
|
61363
61902
|
* that only report charge. A second reading on this cap, not a second
|
|
61364
61903
|
* `numeric-sensor` on the same device.
|
|
61365
61904
|
*/
|
|
61366
|
-
|
|
61905
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
61367
61906
|
/**
|
|
61368
61907
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
61369
61908
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -61397,7 +61936,7 @@ var BatteryStatusSchema = object({
|
|
|
61397
61936
|
/**
|
|
61398
61937
|
* True when the source is a BINARY low-battery indicator (HA
|
|
61399
61938
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
61400
|
-
* charge level — `
|
|
61939
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
61401
61940
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
61402
61941
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
61403
61942
|
*/
|
|
@@ -61417,15 +61956,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
61417
61956
|
var batteryCustomize = {
|
|
61418
61957
|
version: 1,
|
|
61419
61958
|
targets: [{
|
|
61420
|
-
id: "
|
|
61959
|
+
id: "level",
|
|
61421
61960
|
cardinality: "scalar",
|
|
61422
61961
|
vocabulary: {
|
|
61423
61962
|
cap: "battery",
|
|
61424
|
-
stateField: "
|
|
61963
|
+
stateField: "level"
|
|
61425
61964
|
},
|
|
61426
61965
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
61427
61966
|
apply: "add",
|
|
61428
|
-
path: "
|
|
61967
|
+
path: "level",
|
|
61429
61968
|
sources: [{
|
|
61430
61969
|
kind: "field",
|
|
61431
61970
|
valueKinds: ["number", "string"],
|
|
@@ -61519,7 +62058,7 @@ onStatusChanged: { data: object({
|
|
|
61519
62058
|
schema: BatteryStatusSchema,
|
|
61520
62059
|
kind: "push",
|
|
61521
62060
|
empty: {
|
|
61522
|
-
|
|
62061
|
+
level: null,
|
|
61523
62062
|
charging: "unknown",
|
|
61524
62063
|
sleeping: false,
|
|
61525
62064
|
lastUpdated: 0
|
|
@@ -61546,11 +62085,11 @@ onStatusChanged: { data: object({
|
|
|
61546
62085
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
61547
62086
|
*/
|
|
61548
62087
|
history: { fields: {
|
|
61549
|
-
|
|
62088
|
+
level: {
|
|
61550
62089
|
kind: "gauge",
|
|
61551
62090
|
unit: "%"
|
|
61552
62091
|
},
|
|
61553
|
-
|
|
62092
|
+
voltage: {
|
|
61554
62093
|
kind: "gauge",
|
|
61555
62094
|
unit: "V"
|
|
61556
62095
|
}
|
|
@@ -61568,19 +62107,19 @@ object({
|
|
|
61568
62107
|
DeviceType.Sensor;
|
|
61569
62108
|
object({
|
|
61570
62109
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
61571
|
-
|
|
62110
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
61572
62111
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
61573
62112
|
lastChangedAt: number()
|
|
61574
62113
|
});
|
|
61575
62114
|
DeviceType.Light, method(object({
|
|
61576
62115
|
deviceId: number().int().nonnegative(),
|
|
61577
|
-
|
|
62116
|
+
level: number().min(0).max(100)
|
|
61578
62117
|
}), _void(), {
|
|
61579
62118
|
kind: "mutation",
|
|
61580
62119
|
auth: "protected"
|
|
61581
62120
|
}), object({
|
|
61582
62121
|
deviceId: number(),
|
|
61583
|
-
|
|
62122
|
+
level: number().min(0).max(100),
|
|
61584
62123
|
lastChangedAt: number()
|
|
61585
62124
|
});
|
|
61586
62125
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
@@ -62081,11 +62620,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
62081
62620
|
}),
|
|
62082
62621
|
object({
|
|
62083
62622
|
mode: literal("mired"),
|
|
62084
|
-
|
|
62623
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
62085
62624
|
})
|
|
62086
62625
|
]);
|
|
62087
62626
|
object({
|
|
62088
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
62627
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
62089
62628
|
* the bulb's current state. */
|
|
62090
62629
|
mode: _enum([
|
|
62091
62630
|
"rgb",
|
|
@@ -62097,7 +62636,7 @@ object({
|
|
|
62097
62636
|
/** Populated when `mode === 'hsv'`. */
|
|
62098
62637
|
hsv: HsvTripletSchema.optional(),
|
|
62099
62638
|
/** Populated when `mode === 'mired'`. */
|
|
62100
|
-
|
|
62639
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
62101
62640
|
/** Ms epoch of the last operator-driven change. */
|
|
62102
62641
|
lastChangedAt: number()
|
|
62103
62642
|
});
|
|
@@ -62116,7 +62655,7 @@ DeviceType.Light, method(object({
|
|
|
62116
62655
|
]),
|
|
62117
62656
|
rgb: RgbTripletSchema.optional(),
|
|
62118
62657
|
hsv: HsvTripletSchema.optional(),
|
|
62119
|
-
|
|
62658
|
+
colorTemperature: number().int().optional(),
|
|
62120
62659
|
lastChangedAt: number()
|
|
62121
62660
|
});
|
|
62122
62661
|
var ConnectionTestOutcomeSchema = discriminatedUnion("outcome", [
|
|
@@ -62542,11 +63081,11 @@ object({
|
|
|
62542
63081
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
62543
63082
|
availablePrograms: array(string()),
|
|
62544
63083
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
62545
|
-
|
|
63084
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
62546
63085
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
62547
|
-
|
|
63086
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
62548
63087
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
62549
|
-
|
|
63088
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62550
63089
|
/** True when the door is reported open; null when the door state is not known. */
|
|
62551
63090
|
doorOpen: boolean().nullable(),
|
|
62552
63091
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -63164,7 +63703,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
63164
63703
|
object({
|
|
63165
63704
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
63166
63705
|
* speed surface (single-speed fan). */
|
|
63167
|
-
|
|
63706
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63168
63707
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
63169
63708
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
63170
63709
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -63184,7 +63723,7 @@ object({
|
|
|
63184
63723
|
});
|
|
63185
63724
|
DeviceType.Fan, method(object({
|
|
63186
63725
|
deviceId: number().int().nonnegative(),
|
|
63187
|
-
|
|
63726
|
+
speed: number().min(0).max(100)
|
|
63188
63727
|
}), _void(), {
|
|
63189
63728
|
kind: "mutation",
|
|
63190
63729
|
auth: "protected"
|
|
@@ -63367,7 +63906,7 @@ DeviceType.Humidifier, method(object({
|
|
|
63367
63906
|
});
|
|
63368
63907
|
object({
|
|
63369
63908
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
63370
|
-
|
|
63909
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
63371
63910
|
precision: 0,
|
|
63372
63911
|
label: "Humidity"
|
|
63373
63912
|
})),
|
|
@@ -63810,7 +64349,7 @@ object({
|
|
|
63810
64349
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63811
64350
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
63812
64351
|
* task is active / progress is unavailable. */
|
|
63813
|
-
|
|
64352
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63814
64353
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
63815
64354
|
* or null when unknown. */
|
|
63816
64355
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -64300,10 +64839,10 @@ object({
|
|
|
64300
64839
|
currentMedia: MediaInfoSchema.nullable(),
|
|
64301
64840
|
/** Current playback position in ms. Null when not seekable or
|
|
64302
64841
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
64303
|
-
|
|
64842
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64304
64843
|
/** Total duration of the current media in ms. Null when unknown
|
|
64305
64844
|
* (live stream) or nothing is playing. */
|
|
64306
|
-
|
|
64845
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
64307
64846
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
64308
64847
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
64309
64848
|
shuffle: boolean().nullable(),
|
|
@@ -64330,7 +64869,7 @@ DeviceType.MediaPlayer, method(object({ deviceId: number().int().nonnegative() }
|
|
|
64330
64869
|
auth: "protected"
|
|
64331
64870
|
}), method(object({
|
|
64332
64871
|
deviceId: number().int().nonnegative(),
|
|
64333
|
-
|
|
64872
|
+
position: number().int().nonnegative()
|
|
64334
64873
|
}), _void(), {
|
|
64335
64874
|
kind: "mutation",
|
|
64336
64875
|
auth: "protected"
|
|
@@ -65003,9 +65542,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
65003
65542
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
65004
65543
|
* SKIP a null rather than coerce it.
|
|
65005
65544
|
*/
|
|
65006
|
-
|
|
65545
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65007
65546
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
65008
|
-
|
|
65547
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
65009
65548
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
65010
65549
|
ssid: string().optional(),
|
|
65011
65550
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -65666,10 +66205,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
65666
66205
|
]);
|
|
65667
66206
|
var gramsPortion = number().int().min(4).max(200);
|
|
65668
66207
|
object({
|
|
65669
|
-
/** Food
|
|
65670
|
-
*
|
|
65671
|
-
* bowl
|
|
66208
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
66209
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
66210
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
66211
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
66212
|
+
* the device has not reported yet. */
|
|
65672
66213
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
66214
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
66215
|
+
* feeder's own units. Null when the model reports none. */
|
|
66216
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
66217
|
+
/** True while the pet is eating (`state.eating`). */
|
|
66218
|
+
eating: boolean(),
|
|
66219
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
66220
|
+
* the client must not offer it. */
|
|
66221
|
+
supportsMarkRefilled: boolean(),
|
|
65673
66222
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
65674
66223
|
* single-hopper models. */
|
|
65675
66224
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -65677,8 +66226,8 @@ object({
|
|
|
65677
66226
|
* single-hopper models. */
|
|
65678
66227
|
food2: number().nullable().meta(readingMeta("none")),
|
|
65679
66228
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
65680
|
-
* (`device_class: problem`, on = low). True when the
|
|
65681
|
-
*
|
|
66229
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
66230
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
65682
66231
|
lowFood: boolean(),
|
|
65683
66232
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
65684
66233
|
* device has no battery reading. */
|
|
@@ -66145,16 +66694,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
66145
66694
|
auth: "admin"
|
|
66146
66695
|
});
|
|
66147
66696
|
object({
|
|
66148
|
-
/** Instantaneous power draw
|
|
66149
|
-
|
|
66697
|
+
/** Instantaneous power draw (watts). */
|
|
66698
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
66150
66699
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
66151
|
-
|
|
66152
|
-
/** Voltage
|
|
66153
|
-
|
|
66700
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
66701
|
+
/** Voltage (volts). */
|
|
66702
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
66154
66703
|
/** Current in amperes. */
|
|
66155
|
-
|
|
66704
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
66156
66705
|
/** Apparent power in volt-amperes. */
|
|
66157
|
-
|
|
66706
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
66158
66707
|
/** Power factor (0..1) if reported. */
|
|
66159
66708
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
66160
66709
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -66209,16 +66758,13 @@ object({
|
|
|
66209
66758
|
location: string().nullable(),
|
|
66210
66759
|
/** GPS coordinates when available. Null otherwise. */
|
|
66211
66760
|
gps: GpsLocationSchema.nullable(),
|
|
66212
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
66213
|
-
* when not reported. */
|
|
66214
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
66215
66761
|
/** Ms epoch when the slice was last updated. */
|
|
66216
66762
|
lastChangedAt: number()
|
|
66217
66763
|
});
|
|
66218
66764
|
DeviceType.Presence;
|
|
66219
66765
|
object({
|
|
66220
66766
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
66221
|
-
|
|
66767
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
66222
66768
|
/** Ms epoch when the slice was last updated. */
|
|
66223
66769
|
lastFetchedAt: number()
|
|
66224
66770
|
});
|
|
@@ -69745,7 +70291,7 @@ object({
|
|
|
69745
70291
|
DeviceType.Sensor;
|
|
69746
70292
|
object({
|
|
69747
70293
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
69748
|
-
|
|
70294
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
69749
70295
|
precision: 1,
|
|
69750
70296
|
label: "Temperature"
|
|
69751
70297
|
})),
|
|
@@ -70009,7 +70555,7 @@ object({
|
|
|
70009
70555
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
70010
70556
|
availableFanSpeeds: array(string()),
|
|
70011
70557
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
70012
|
-
|
|
70558
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
70013
70559
|
/** Current error code (0 / null = no error). */
|
|
70014
70560
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
70015
70561
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -71008,6 +71554,104 @@ Object.freeze({
|
|
|
71008
71554
|
access: "create",
|
|
71009
71555
|
role: "admin"
|
|
71010
71556
|
},
|
|
71557
|
+
"actions.create": {
|
|
71558
|
+
capName: "actions",
|
|
71559
|
+
capScope: "system",
|
|
71560
|
+
addonId: null,
|
|
71561
|
+
access: "create",
|
|
71562
|
+
role: "admin"
|
|
71563
|
+
},
|
|
71564
|
+
"actions.delete": {
|
|
71565
|
+
capName: "actions",
|
|
71566
|
+
capScope: "system",
|
|
71567
|
+
addonId: null,
|
|
71568
|
+
access: "delete",
|
|
71569
|
+
role: "admin"
|
|
71570
|
+
},
|
|
71571
|
+
"actions.get": {
|
|
71572
|
+
capName: "actions",
|
|
71573
|
+
capScope: "system",
|
|
71574
|
+
addonId: null,
|
|
71575
|
+
access: "view",
|
|
71576
|
+
role: "viewer"
|
|
71577
|
+
},
|
|
71578
|
+
"actions.getLinks": {
|
|
71579
|
+
capName: "actions",
|
|
71580
|
+
capScope: "system",
|
|
71581
|
+
addonId: null,
|
|
71582
|
+
access: "view",
|
|
71583
|
+
role: "admin"
|
|
71584
|
+
},
|
|
71585
|
+
"actions.getTraces": {
|
|
71586
|
+
capName: "actions",
|
|
71587
|
+
capScope: "system",
|
|
71588
|
+
addonId: null,
|
|
71589
|
+
access: "view",
|
|
71590
|
+
role: "admin"
|
|
71591
|
+
},
|
|
71592
|
+
"actions.list": {
|
|
71593
|
+
capName: "actions",
|
|
71594
|
+
capScope: "system",
|
|
71595
|
+
addonId: null,
|
|
71596
|
+
access: "view",
|
|
71597
|
+
role: "admin"
|
|
71598
|
+
},
|
|
71599
|
+
"actions.listForCamera": {
|
|
71600
|
+
capName: "actions",
|
|
71601
|
+
capScope: "system",
|
|
71602
|
+
addonId: null,
|
|
71603
|
+
access: "view",
|
|
71604
|
+
role: "viewer"
|
|
71605
|
+
},
|
|
71606
|
+
"actions.run": {
|
|
71607
|
+
capName: "actions",
|
|
71608
|
+
capScope: "system",
|
|
71609
|
+
addonId: null,
|
|
71610
|
+
access: "create",
|
|
71611
|
+
role: "viewer"
|
|
71612
|
+
},
|
|
71613
|
+
"actions.setLinks": {
|
|
71614
|
+
capName: "actions",
|
|
71615
|
+
capScope: "system",
|
|
71616
|
+
addonId: null,
|
|
71617
|
+
access: "create",
|
|
71618
|
+
role: "admin"
|
|
71619
|
+
},
|
|
71620
|
+
"actions.stop": {
|
|
71621
|
+
capName: "actions",
|
|
71622
|
+
capScope: "system",
|
|
71623
|
+
addonId: null,
|
|
71624
|
+
access: "create",
|
|
71625
|
+
role: "admin"
|
|
71626
|
+
},
|
|
71627
|
+
"actions.update": {
|
|
71628
|
+
capName: "actions",
|
|
71629
|
+
capScope: "system",
|
|
71630
|
+
addonId: null,
|
|
71631
|
+
access: "create",
|
|
71632
|
+
role: "admin"
|
|
71633
|
+
},
|
|
71634
|
+
"actionSource.listActions": {
|
|
71635
|
+
capName: "action-source",
|
|
71636
|
+
capScope: "system",
|
|
71637
|
+
addonId: null,
|
|
71638
|
+
access: "view",
|
|
71639
|
+
role: "admin"
|
|
71640
|
+
},
|
|
71641
|
+
"actionSource.runAction": {
|
|
71642
|
+
capName: "action-source",
|
|
71643
|
+
capScope: "system",
|
|
71644
|
+
addonId: null,
|
|
71645
|
+
access: "create",
|
|
71646
|
+
role: "admin"
|
|
71647
|
+
},
|
|
71648
|
+
"actionSource.stopAction": {
|
|
71649
|
+
capName: "action-source",
|
|
71650
|
+
capScope: "system",
|
|
71651
|
+
addonId: null,
|
|
71652
|
+
access: "create",
|
|
71653
|
+
role: "admin"
|
|
71654
|
+
},
|
|
71011
71655
|
"addonPages.listPages": {
|
|
71012
71656
|
capName: "addon-pages",
|
|
71013
71657
|
capScope: "system",
|
|
@@ -72289,6 +72933,13 @@ Object.freeze({
|
|
|
72289
72933
|
access: "view",
|
|
72290
72934
|
role: "admin"
|
|
72291
72935
|
},
|
|
72936
|
+
"coreBlocks.getAutomationRunState": {
|
|
72937
|
+
capName: "core-blocks",
|
|
72938
|
+
capScope: "system",
|
|
72939
|
+
addonId: null,
|
|
72940
|
+
access: "view",
|
|
72941
|
+
role: "admin"
|
|
72942
|
+
},
|
|
72292
72943
|
"coreBlocks.getBlockSettings": {
|
|
72293
72944
|
capName: "core-blocks",
|
|
72294
72945
|
capScope: "system",
|
|
@@ -72310,6 +72961,13 @@ Object.freeze({
|
|
|
72310
72961
|
access: "view",
|
|
72311
72962
|
role: "admin"
|
|
72312
72963
|
},
|
|
72964
|
+
"coreBlocks.getTraces": {
|
|
72965
|
+
capName: "core-blocks",
|
|
72966
|
+
capScope: "system",
|
|
72967
|
+
addonId: null,
|
|
72968
|
+
access: "view",
|
|
72969
|
+
role: "admin"
|
|
72970
|
+
},
|
|
72313
72971
|
"coreBlocks.getTypeDefs": {
|
|
72314
72972
|
capName: "core-blocks",
|
|
72315
72973
|
capScope: "system",
|
|
@@ -72345,6 +73003,13 @@ Object.freeze({
|
|
|
72345
73003
|
access: "create",
|
|
72346
73004
|
role: "admin"
|
|
72347
73005
|
},
|
|
73006
|
+
"coreBlocks.reportAutomationRun": {
|
|
73007
|
+
capName: "core-blocks",
|
|
73008
|
+
capScope: "system",
|
|
73009
|
+
addonId: null,
|
|
73010
|
+
access: "create",
|
|
73011
|
+
role: "admin"
|
|
73012
|
+
},
|
|
72348
73013
|
"coreBlocks.restart": {
|
|
72349
73014
|
capName: "core-blocks",
|
|
72350
73015
|
capScope: "system",
|
|
@@ -80918,7 +81583,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
80918
81583
|
label: t("Full brightness", "Luminosità massima"),
|
|
80919
81584
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
80920
81585
|
icon: "sun",
|
|
80921
|
-
args: {
|
|
81586
|
+
args: { level: 100 }
|
|
80922
81587
|
},
|
|
80923
81588
|
{
|
|
80924
81589
|
id: "brightness.half",
|
|
@@ -80926,7 +81591,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
80926
81591
|
label: t("Half brightness", "Luminosità a metà"),
|
|
80927
81592
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
80928
81593
|
icon: "sun-dim",
|
|
80929
|
-
args: {
|
|
81594
|
+
args: { level: 50 }
|
|
80930
81595
|
},
|
|
80931
81596
|
{
|
|
80932
81597
|
id: "brightness.off",
|
|
@@ -80934,16 +81599,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
80934
81599
|
label: t("Brightness off", "Luminosità a zero"),
|
|
80935
81600
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
80936
81601
|
icon: "lightbulb-off",
|
|
80937
|
-
args: {
|
|
81602
|
+
args: { level: 0 }
|
|
80938
81603
|
},
|
|
80939
81604
|
{
|
|
80940
81605
|
id: "brightness.set",
|
|
80941
81606
|
method: "setBrightness",
|
|
80942
81607
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
80943
|
-
phrase: t("Set the brightness of {device} to {
|
|
81608
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
80944
81609
|
icon: "sun-medium",
|
|
80945
81610
|
openArgs: [{
|
|
80946
|
-
key: "
|
|
81611
|
+
key: "level",
|
|
80947
81612
|
label: PERCENT,
|
|
80948
81613
|
offer: {
|
|
80949
81614
|
kind: "number",
|
|
@@ -80957,13 +81622,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
80957
81622
|
],
|
|
80958
81623
|
state: [{
|
|
80959
81624
|
kind: "numeric",
|
|
80960
|
-
field: "
|
|
81625
|
+
field: "level",
|
|
80961
81626
|
quantity: t("the brightness", "la luminosità"),
|
|
80962
81627
|
label: t("Brightness", "Luminosità"),
|
|
80963
81628
|
unit: "%",
|
|
80964
81629
|
icon: "sun"
|
|
80965
81630
|
}],
|
|
80966
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
81631
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
80967
81632
|
},
|
|
80968
81633
|
color: {
|
|
80969
81634
|
scope: "device",
|
|
@@ -80977,7 +81642,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
80977
81642
|
icon: "sun",
|
|
80978
81643
|
args: { color: {
|
|
80979
81644
|
mode: "mired",
|
|
80980
|
-
|
|
81645
|
+
colorTemperature: 370
|
|
80981
81646
|
} }
|
|
80982
81647
|
},
|
|
80983
81648
|
{
|
|
@@ -80988,7 +81653,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
80988
81653
|
icon: "snowflake",
|
|
80989
81654
|
args: { color: {
|
|
80990
81655
|
mode: "mired",
|
|
80991
|
-
|
|
81656
|
+
colorTemperature: 200
|
|
80992
81657
|
} }
|
|
80993
81658
|
},
|
|
80994
81659
|
{
|
|
@@ -81602,7 +82267,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81602
82267
|
label: t("Fan off", "Ventilatore spento"),
|
|
81603
82268
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
81604
82269
|
icon: "power-off",
|
|
81605
|
-
args: {
|
|
82270
|
+
args: { speed: 0 }
|
|
81606
82271
|
},
|
|
81607
82272
|
{
|
|
81608
82273
|
id: "fan.full",
|
|
@@ -81610,16 +82275,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81610
82275
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
81611
82276
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
81612
82277
|
icon: "fan",
|
|
81613
|
-
args: {
|
|
82278
|
+
args: { speed: 100 }
|
|
81614
82279
|
},
|
|
81615
82280
|
{
|
|
81616
82281
|
id: "fan.speed",
|
|
81617
82282
|
method: "setPercentage",
|
|
81618
82283
|
label: t("Set speed", "Imposta la velocità"),
|
|
81619
|
-
phrase: t("Set the speed of {device} to {
|
|
82284
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
81620
82285
|
icon: "fan",
|
|
81621
82286
|
openArgs: [{
|
|
81622
|
-
key: "
|
|
82287
|
+
key: "speed",
|
|
81623
82288
|
label: t("Speed", "Velocità"),
|
|
81624
82289
|
offer: {
|
|
81625
82290
|
kind: "number",
|
|
@@ -81681,7 +82346,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
81681
82346
|
],
|
|
81682
82347
|
state: [{
|
|
81683
82348
|
kind: "numeric",
|
|
81684
|
-
field: "
|
|
82349
|
+
field: "speed",
|
|
81685
82350
|
quantity: t("the speed", "la velocità"),
|
|
81686
82351
|
label: t("Speed", "Velocità"),
|
|
81687
82352
|
unit: "%",
|
|
@@ -82479,7 +83144,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
82479
83144
|
},
|
|
82480
83145
|
{
|
|
82481
83146
|
kind: "numeric",
|
|
82482
|
-
field: "
|
|
83147
|
+
field: "progress",
|
|
82483
83148
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
82484
83149
|
label: t("Progress", "Avanzamento"),
|
|
82485
83150
|
unit: "%",
|
|
@@ -82837,10 +83502,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
82837
83502
|
id: "media.seek",
|
|
82838
83503
|
method: "seek",
|
|
82839
83504
|
label: t("Seek", "Vai al punto"),
|
|
82840
|
-
phrase: t("Move {device} to {
|
|
83505
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
82841
83506
|
icon: "fast-forward",
|
|
82842
83507
|
openArgs: [{
|
|
82843
|
-
key: "
|
|
83508
|
+
key: "position",
|
|
82844
83509
|
label: t("Position", "Posizione"),
|
|
82845
83510
|
offer: {
|
|
82846
83511
|
kind: "number",
|
|
@@ -83889,7 +84554,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83889
84554
|
state: [
|
|
83890
84555
|
{
|
|
83891
84556
|
kind: "numeric",
|
|
83892
|
-
field: "
|
|
84557
|
+
field: "co2",
|
|
83893
84558
|
quantity: t("the CO₂", "la CO₂"),
|
|
83894
84559
|
label: t("CO₂", "CO₂"),
|
|
83895
84560
|
unit: "ppm",
|
|
@@ -83897,7 +84562,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83897
84562
|
},
|
|
83898
84563
|
{
|
|
83899
84564
|
kind: "numeric",
|
|
83900
|
-
field: "
|
|
84565
|
+
field: "voc",
|
|
83901
84566
|
quantity: t("the VOC level", "il livello di COV"),
|
|
83902
84567
|
label: t("VOC", "COV"),
|
|
83903
84568
|
unit: "ppb",
|
|
@@ -83933,7 +84598,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83933
84598
|
noun: t("Light level", "Luminosità ambiente"),
|
|
83934
84599
|
state: [{
|
|
83935
84600
|
kind: "numeric",
|
|
83936
|
-
field: "
|
|
84601
|
+
field: "illuminance",
|
|
83937
84602
|
quantity: t("the light level", "la luminosità"),
|
|
83938
84603
|
label: t("Illuminance", "Illuminamento"),
|
|
83939
84604
|
unit: "lx",
|
|
@@ -84136,7 +84801,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84136
84801
|
noun: t("Humidity", "Umidità"),
|
|
84137
84802
|
state: [{
|
|
84138
84803
|
kind: "numeric",
|
|
84139
|
-
field: "
|
|
84804
|
+
field: "humidity",
|
|
84140
84805
|
quantity: t("the humidity", "l’umidità"),
|
|
84141
84806
|
label: t("Humidity", "Umidità"),
|
|
84142
84807
|
unit: "%",
|
|
@@ -84184,7 +84849,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84184
84849
|
state: [
|
|
84185
84850
|
{
|
|
84186
84851
|
kind: "numeric",
|
|
84187
|
-
field: "
|
|
84852
|
+
field: "power",
|
|
84188
84853
|
quantity: t("the power draw", "il consumo"),
|
|
84189
84854
|
label: t("Power", "Potenza"),
|
|
84190
84855
|
unit: "W",
|
|
@@ -84192,7 +84857,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84192
84857
|
},
|
|
84193
84858
|
{
|
|
84194
84859
|
kind: "numeric",
|
|
84195
|
-
field: "
|
|
84860
|
+
field: "energy",
|
|
84196
84861
|
quantity: t("the energy used", "l’energia consumata"),
|
|
84197
84862
|
label: t("Energy", "Energia"),
|
|
84198
84863
|
unit: "kWh",
|
|
@@ -84200,7 +84865,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84200
84865
|
},
|
|
84201
84866
|
{
|
|
84202
84867
|
kind: "numeric",
|
|
84203
|
-
field: "
|
|
84868
|
+
field: "voltage",
|
|
84204
84869
|
quantity: t("the voltage", "la tensione"),
|
|
84205
84870
|
label: t("Voltage", "Tensione"),
|
|
84206
84871
|
unit: "V",
|
|
@@ -84208,7 +84873,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84208
84873
|
},
|
|
84209
84874
|
{
|
|
84210
84875
|
kind: "numeric",
|
|
84211
|
-
field: "
|
|
84876
|
+
field: "current",
|
|
84212
84877
|
quantity: t("the current", "la corrente"),
|
|
84213
84878
|
label: t("Current", "Corrente"),
|
|
84214
84879
|
unit: "A",
|
|
@@ -84225,13 +84890,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84225
84890
|
label: t("Where", "Posizione"),
|
|
84226
84891
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
84227
84892
|
icon: "map-pin"
|
|
84228
|
-
}, {
|
|
84229
|
-
kind: "numeric",
|
|
84230
|
-
field: "batteryPercent",
|
|
84231
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
84232
|
-
label: t("Battery", "Batteria"),
|
|
84233
|
-
unit: "%",
|
|
84234
|
-
icon: "battery"
|
|
84235
84893
|
}]
|
|
84236
84894
|
},
|
|
84237
84895
|
"pressure-sensor": {
|
|
@@ -84239,7 +84897,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84239
84897
|
noun: t("Pressure", "Pressione"),
|
|
84240
84898
|
state: [{
|
|
84241
84899
|
kind: "numeric",
|
|
84242
|
-
field: "
|
|
84900
|
+
field: "pressure",
|
|
84243
84901
|
quantity: t("the pressure", "la pressione"),
|
|
84244
84902
|
label: t("Pressure", "Pressione"),
|
|
84245
84903
|
unit: "hPa",
|
|
@@ -84275,7 +84933,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84275
84933
|
noun: t("Temperature", "Temperatura"),
|
|
84276
84934
|
state: [{
|
|
84277
84935
|
kind: "numeric",
|
|
84278
|
-
field: "
|
|
84936
|
+
field: "temperature",
|
|
84279
84937
|
quantity: t("the temperature", "la temperatura"),
|
|
84280
84938
|
label: t("Temperature", "Temperatura"),
|
|
84281
84939
|
unit: "°C",
|
|
@@ -84346,7 +85004,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84346
85004
|
state: [
|
|
84347
85005
|
{
|
|
84348
85006
|
kind: "numeric",
|
|
84349
|
-
field: "
|
|
85007
|
+
field: "level",
|
|
84350
85008
|
quantity: t("the battery level", "il livello della batteria"),
|
|
84351
85009
|
label: t("Battery", "Batteria"),
|
|
84352
85010
|
unit: "%",
|
|
@@ -84388,7 +85046,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84388
85046
|
icon: "battery-charging"
|
|
84389
85047
|
}
|
|
84390
85048
|
],
|
|
84391
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
85049
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
84392
85050
|
extraEvents: [{
|
|
84393
85051
|
category: EventCategory.DeviceAwake,
|
|
84394
85052
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -84406,7 +85064,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84406
85064
|
noun: t("Network link", "Collegamento di rete"),
|
|
84407
85065
|
state: [{
|
|
84408
85066
|
kind: "numeric",
|
|
84409
|
-
field: "
|
|
85067
|
+
field: "signal",
|
|
84410
85068
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
84411
85069
|
label: t("Signal", "Segnale"),
|
|
84412
85070
|
unit: "%",
|
|
@@ -84499,6 +85157,8 @@ var ML = "model and training machinery — no device action";
|
|
|
84499
85157
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
84500
85158
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
84501
85159
|
var SYSTEM_CAP_VOCABULARY = {
|
|
85160
|
+
"action-source": system(INTERNAL),
|
|
85161
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
84502
85162
|
"addon-pages": system(UI_PLUMBING),
|
|
84503
85163
|
"addon-pages-source": system(UI_PLUMBING),
|
|
84504
85164
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -84695,6 +85355,31 @@ Object.freeze({
|
|
|
84695
85355
|
form: "single",
|
|
84696
85356
|
optional: false
|
|
84697
85357
|
}],
|
|
85358
|
+
"actions.get": [{
|
|
85359
|
+
name: "deviceId",
|
|
85360
|
+
form: "single",
|
|
85361
|
+
optional: true
|
|
85362
|
+
}],
|
|
85363
|
+
"actions.getLinks": [{
|
|
85364
|
+
name: "deviceId",
|
|
85365
|
+
form: "single",
|
|
85366
|
+
optional: false
|
|
85367
|
+
}],
|
|
85368
|
+
"actions.listForCamera": [{
|
|
85369
|
+
name: "deviceId",
|
|
85370
|
+
form: "single",
|
|
85371
|
+
optional: false
|
|
85372
|
+
}],
|
|
85373
|
+
"actions.run": [{
|
|
85374
|
+
name: "deviceId",
|
|
85375
|
+
form: "single",
|
|
85376
|
+
optional: true
|
|
85377
|
+
}],
|
|
85378
|
+
"actions.setLinks": [{
|
|
85379
|
+
name: "deviceId",
|
|
85380
|
+
form: "single",
|
|
85381
|
+
optional: false
|
|
85382
|
+
}],
|
|
84698
85383
|
"addonSettings.getDeviceSettings": [{
|
|
84699
85384
|
name: "deviceId",
|
|
84700
85385
|
form: "single",
|
|
@@ -89738,6 +90423,7 @@ var BackgroundRunRegistry = class {
|
|
|
89738
90423
|
}
|
|
89739
90424
|
}
|
|
89740
90425
|
};
|
|
90426
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
89741
90427
|
var MB = 1024 * 1024;
|
|
89742
90428
|
var DEFAULT_POOL_MEMORY_POLICY = {
|
|
89743
90429
|
sampleIntervalMs: 6e4,
|