@camstack/addon-provider-bosch 0.1.47 → 0.1.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/{account-integration-offline-C6tzFB-H.js → account-integration-offline-CQ7UB6U_.js} +1 -1
- package/dist/{account-integration-offline-Bie4aS5e.mjs → account-integration-offline-DLCUxCxS.mjs} +1 -1
- package/dist/{bosch-instances-D0eF-Jjy.js → bosch-instances-CRvxRbDk.js} +276 -317
- package/dist/{bosch-instances-DAqkAsRO.mjs → bosch-instances-t9x1fGVW.mjs} +276 -317
- package/dist/home-connect/addon.js +2 -2
- package/dist/home-connect/addon.mjs +2 -2
- package/dist/homecom/addon.js +2 -2
- package/dist/homecom/addon.mjs +2 -2
- package/dist/shc/addon.js +1 -1
- package/dist/shc/addon.mjs +1 -1
- package/package.json +2 -2
|
@@ -802,7 +802,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
802
802
|
return EventCategory;
|
|
803
803
|
}({});
|
|
804
804
|
//#endregion
|
|
805
|
-
//#region ../types/dist/composed-stable-id-
|
|
805
|
+
//#region ../types/dist/composed-stable-id-jnvhwGoH.mjs
|
|
806
806
|
/**
|
|
807
807
|
import { errMsg } from '@camstack/types'
|
|
808
808
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -1090,6 +1090,10 @@ var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
|
1090
1090
|
/** Robot mower exposes targeted mowing (all-area / zones / edges /
|
|
1091
1091
|
* spots) — gates the Mow action + map selectors. */
|
|
1092
1092
|
DeviceFeature["MowerHasTargetedMowing"] = "mower-has-targeted-mowing";
|
|
1093
|
+
/** The device has a drive/navigation surface (`navigation` cap): a robot camera. */
|
|
1094
|
+
DeviceFeature["Navigation"] = "navigation";
|
|
1095
|
+
/** The device has a network-link reading (`network-link` cap). */
|
|
1096
|
+
DeviceFeature["NetworkLink"] = "network-link";
|
|
1093
1097
|
return DeviceFeature;
|
|
1094
1098
|
}({});
|
|
1095
1099
|
/**
|
|
@@ -6022,7 +6026,7 @@ var ZodIssueCode = {
|
|
|
6022
6026
|
var ZodFirstPartyTypeKind;
|
|
6023
6027
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6024
6028
|
//#endregion
|
|
6025
|
-
//#region ../types/dist/sleep-
|
|
6029
|
+
//#region ../types/dist/sleep-Dz1P6--1.mjs
|
|
6026
6030
|
/**
|
|
6027
6031
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6028
6032
|
* window to float samples (D455).
|
|
@@ -10109,15 +10113,52 @@ var PeerBytesTicketSchema = object({
|
|
|
10109
10113
|
*/
|
|
10110
10114
|
declaredBytes: number$1().int().nonnegative().nullable()
|
|
10111
10115
|
});
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10116
|
+
/**
|
|
10117
|
+
* The match a notification rule fired on (D705). Carried as a command origin so an
|
|
10118
|
+
* Action the rule starts can press `alarm-panel.trigger` as that match, not as an
|
|
10119
|
+
* anonymous press (D735). The same fields a rule fire ref freezes.
|
|
10120
|
+
*/
|
|
10121
|
+
var RuleFireOriginSchema = object({
|
|
10122
|
+
ruleId: string(),
|
|
10123
|
+
ruleName: string(),
|
|
10124
|
+
deviceId: number$1().int(),
|
|
10125
|
+
sourceDeviceId: number$1().int().optional(),
|
|
10126
|
+
recordId: string(),
|
|
10127
|
+
timestamp: number$1(),
|
|
10128
|
+
trackId: string().optional(),
|
|
10129
|
+
eventId: string().optional(),
|
|
10130
|
+
className: string().optional(),
|
|
10131
|
+
label: string().optional(),
|
|
10132
|
+
zones: array(string()).optional(),
|
|
10133
|
+
confidence: number$1().optional(),
|
|
10134
|
+
sensorChange: object({
|
|
10135
|
+
name: string(),
|
|
10136
|
+
kind: string(),
|
|
10137
|
+
state: string()
|
|
10138
|
+
}).optional(),
|
|
10139
|
+
extraStills: array(object({
|
|
10140
|
+
ownerId: string(),
|
|
10141
|
+
cameraId: number$1().int()
|
|
10142
|
+
})).optional()
|
|
10143
|
+
});
|
|
10144
|
+
discriminatedUnion("kind", [
|
|
10145
|
+
object({
|
|
10146
|
+
kind: literal("action"),
|
|
10147
|
+
actionId: string(),
|
|
10148
|
+
runId: string(),
|
|
10149
|
+
automationId: string().optional(),
|
|
10150
|
+
/** The rule fire that started this run, when one did (D705). */
|
|
10151
|
+
ruleFire: RuleFireOriginSchema.optional()
|
|
10152
|
+
}),
|
|
10153
|
+
object({
|
|
10154
|
+
kind: literal("scheduler"),
|
|
10155
|
+
schedulerId: string()
|
|
10156
|
+
}),
|
|
10157
|
+
object({
|
|
10158
|
+
kind: literal("rule"),
|
|
10159
|
+
fire: RuleFireOriginSchema
|
|
10160
|
+
})
|
|
10161
|
+
]);
|
|
10121
10162
|
/**
|
|
10122
10163
|
* One recorded device transition (D1022): a status field of a device went from
|
|
10123
10164
|
* one value to another, with who or what asked for it.
|
|
@@ -17412,7 +17453,7 @@ Object.freeze({
|
|
|
17412
17453
|
}
|
|
17413
17454
|
});
|
|
17414
17455
|
//#endregion
|
|
17415
|
-
//#region ../types/dist/
|
|
17456
|
+
//#region ../types/dist/implemented-methods-OitwyO1Y.mjs
|
|
17416
17457
|
/**
|
|
17417
17458
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
17418
17459
|
*
|
|
@@ -19352,18 +19393,43 @@ var TargetKindLevelSchema = object({
|
|
|
19352
19393
|
requires: array(string()).optional(),
|
|
19353
19394
|
description: string().optional()
|
|
19354
19395
|
});
|
|
19396
|
+
/** Attachment capabilities for a kind (drives the degrade engine + test panel). */
|
|
19397
|
+
var TargetKindAttachmentsCapsSchema = object({
|
|
19398
|
+
mediaTypes: array(AttachmentMediaTypeSchema),
|
|
19399
|
+
mode: _enum([
|
|
19400
|
+
"url",
|
|
19401
|
+
"bytes",
|
|
19402
|
+
"both"
|
|
19403
|
+
]),
|
|
19404
|
+
max: number$1().int().nonnegative(),
|
|
19405
|
+
maxBytes: number$1().int().positive().optional()
|
|
19406
|
+
});
|
|
19407
|
+
/**
|
|
19408
|
+
* Which TEXT fields a kind delivers (#483). Alexa speaks a title and nothing
|
|
19409
|
+
* else; a push service shows both.
|
|
19410
|
+
*
|
|
19411
|
+
* `.optional()` on the caps block, never defaulted: absent = both, which is
|
|
19412
|
+
* what every kind declared before this field meant (D938's rule for a Zod
|
|
19413
|
+
* default on the addon cap path).
|
|
19414
|
+
*/
|
|
19415
|
+
var TargetKindTextCapsSchema = object({
|
|
19416
|
+
title: boolean(),
|
|
19417
|
+
body: boolean()
|
|
19418
|
+
});
|
|
19419
|
+
_enum([
|
|
19420
|
+
"title",
|
|
19421
|
+
"body",
|
|
19422
|
+
"attachments",
|
|
19423
|
+
"actions",
|
|
19424
|
+
"priority",
|
|
19425
|
+
"sound",
|
|
19426
|
+
"clickUrl"
|
|
19427
|
+
]);
|
|
19355
19428
|
/** The full capability block consulted before dispatch. */
|
|
19356
19429
|
var TargetKindCapsSchema = object({
|
|
19357
|
-
|
|
19358
|
-
|
|
19359
|
-
|
|
19360
|
-
"url",
|
|
19361
|
-
"bytes",
|
|
19362
|
-
"both"
|
|
19363
|
-
]),
|
|
19364
|
-
max: number$1().int().nonnegative(),
|
|
19365
|
-
maxBytes: number$1().int().positive().optional()
|
|
19366
|
-
}),
|
|
19430
|
+
/** Text fields this kind delivers (#483). Absent = title AND body. */
|
|
19431
|
+
text: TargetKindTextCapsSchema.optional(),
|
|
19432
|
+
attachments: TargetKindAttachmentsCapsSchema,
|
|
19367
19433
|
/** Max action buttons (0 = none). */
|
|
19368
19434
|
actions: number$1().int().nonnegative(),
|
|
19369
19435
|
/**
|
|
@@ -44487,30 +44553,21 @@ function convertLegacyWhen(half) {
|
|
|
44487
44553
|
* (instants) and state leaves (durations). It replaces the flat trigger list
|
|
44488
44554
|
* plus the separate condition tree; the firing rule is in that file and in
|
|
44489
44555
|
* ADR "one tree".
|
|
44490
|
-
* - **Actions** — `
|
|
44491
|
-
* fragment of §3.2.2. See {@link AutomationActionSchema}
|
|
44492
|
-
* this had to diverge from "verbatim", and why.
|
|
44556
|
+
* - **Actions** — the `wait` and `cap` steps, plus the `{kind:'code'}`
|
|
44557
|
+
* fragment of §3.2.2. See {@link AutomationActionSchema}.
|
|
44493
44558
|
*
|
|
44494
44559
|
* A recipe stored in the old shape (`triggers` + `conditions`) still LOADS:
|
|
44495
44560
|
* {@link AutomationRecipeSchema} (the parse-anywhere schema) converts it on parse. Nothing writes it.
|
|
44496
44561
|
*/
|
|
44497
44562
|
/**
|
|
44498
|
-
* One action step.
|
|
44499
|
-
*
|
|
44500
|
-
* `wait` and `cap` are `NcRuleActionSchema`'s two members, kept structurally
|
|
44501
|
-
* identical so `NcRuleActionRunner` runs them unchanged — its device-scope
|
|
44502
|
-
* check, stop-at-first-failure and per-sequence throttle are the whole reason
|
|
44503
|
-
* to reuse it, and none of them are re-implemented here.
|
|
44563
|
+
* One action step: `wait`, or a `cap` call.
|
|
44504
44564
|
*
|
|
44505
|
-
*
|
|
44506
|
-
*
|
|
44507
|
-
*
|
|
44508
|
-
*
|
|
44509
|
-
*
|
|
44510
|
-
*
|
|
44511
|
-
* also accepts `{ $var }`, resolved from the run's `vars` bag BEFORE the runner
|
|
44512
|
-
* is called. The runner still receives a number and is untouched; the
|
|
44513
|
-
* resolution is the recipe's job, not the runner's.
|
|
44565
|
+
* A cap step's target is who it acts on (D983: `devices`, a `domain`, or a
|
|
44566
|
+
* `{ $var }` resolved from the run's variables); the legacy `deviceId` is still
|
|
44567
|
+
* READ, never written. The step runner (`runSteps`) owns the device-scope
|
|
44568
|
+
* check, the stop-at-first-failure and the variable substitution, once, for
|
|
44569
|
+
* every caller — automations, Actions, and the notification centre, which runs
|
|
44570
|
+
* only Actions (planning#473).
|
|
44514
44571
|
*/
|
|
44515
44572
|
var AutomationWaitStepSchema = object({
|
|
44516
44573
|
kind: literal("wait"),
|
|
@@ -45128,6 +45185,8 @@ var ActionStatusSchema = object({
|
|
|
45128
45185
|
/** The latest run's failure; null on success or when it never ran. */
|
|
45129
45186
|
lastError: string().nullable()
|
|
45130
45187
|
});
|
|
45188
|
+
/** The throttle window of an action, in seconds; absent or 0 = no throttle. */
|
|
45189
|
+
var ActionMinDelaySecSchema = number$1().int().min(0).max(86400);
|
|
45131
45190
|
var ActionEntrySchema = object({
|
|
45132
45191
|
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
45133
45192
|
id: string().min(3),
|
|
@@ -45140,6 +45199,14 @@ var ActionEntrySchema = object({
|
|
|
45140
45199
|
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
45141
45200
|
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
45142
45201
|
variables: array(ActionVariableSchema).max(20).optional(),
|
|
45202
|
+
/**
|
|
45203
|
+
* Internal only: the least time between two run STARTS. A run that begins
|
|
45204
|
+
* inside the window is skipped (`skipped-cooldown`), traced and logged. It
|
|
45205
|
+
* is an actuator's budget — "how often may this gate physically open" —
|
|
45206
|
+
* not a notification cooldown, and it is shared by every caller of the
|
|
45207
|
+
* action (two rules, a button, an automation).
|
|
45208
|
+
*/
|
|
45209
|
+
minDelaySec: ActionMinDelaySecSchema.optional(),
|
|
45143
45210
|
status: ActionStatusSchema
|
|
45144
45211
|
}).superRefine((entry, ctx) => {
|
|
45145
45212
|
if (entry.source === "internal") {
|
|
@@ -45170,7 +45237,8 @@ var ActionEntrySchema = object({
|
|
|
45170
45237
|
var ActionInputSchema = object({
|
|
45171
45238
|
name: string().min(1).max(120),
|
|
45172
45239
|
steps: array(ActionStepSchema).min(1).max(50),
|
|
45173
|
-
variables: array(ActionVariableSchema).max(20).optional()
|
|
45240
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
45241
|
+
minDelaySec: ActionMinDelaySecSchema.optional()
|
|
45174
45242
|
});
|
|
45175
45243
|
/** Who started a run. Absent = the operator pressed it. */
|
|
45176
45244
|
var ActionRunOriginSchema = object({
|
|
@@ -49330,14 +49398,14 @@ var climateControlCapability = {
|
|
|
49330
49398
|
kind: "mutation",
|
|
49331
49399
|
auth: "protected"
|
|
49332
49400
|
}),
|
|
49333
|
-
setFanMode:
|
|
49401
|
+
setFanMode: optionalMethod(object({
|
|
49334
49402
|
deviceId: number$1().int().nonnegative(),
|
|
49335
49403
|
fanMode: string().min(1)
|
|
49336
49404
|
}), _void(), {
|
|
49337
49405
|
kind: "mutation",
|
|
49338
49406
|
auth: "protected"
|
|
49339
49407
|
}),
|
|
49340
|
-
setPreset:
|
|
49408
|
+
setPreset: optionalMethod(object({
|
|
49341
49409
|
deviceId: number$1().int().nonnegative(),
|
|
49342
49410
|
preset: string().min(1)
|
|
49343
49411
|
}), _void(), {
|
|
@@ -49351,7 +49419,7 @@ var climateControlCapability = {
|
|
|
49351
49419
|
kind: "mutation",
|
|
49352
49420
|
auth: "protected"
|
|
49353
49421
|
}),
|
|
49354
|
-
setTargetRange:
|
|
49422
|
+
setTargetRange: optionalMethod(object({
|
|
49355
49423
|
deviceId: number$1().int().nonnegative(),
|
|
49356
49424
|
targetLow: number$1(),
|
|
49357
49425
|
targetHigh: number$1()
|
|
@@ -49359,21 +49427,21 @@ var climateControlCapability = {
|
|
|
49359
49427
|
kind: "mutation",
|
|
49360
49428
|
auth: "protected"
|
|
49361
49429
|
}),
|
|
49362
|
-
setTargetHumidity:
|
|
49430
|
+
setTargetHumidity: optionalMethod(object({
|
|
49363
49431
|
deviceId: number$1().int().nonnegative(),
|
|
49364
49432
|
targetHumidity: number$1().min(0).max(100)
|
|
49365
49433
|
}), _void(), {
|
|
49366
49434
|
kind: "mutation",
|
|
49367
49435
|
auth: "protected"
|
|
49368
49436
|
}),
|
|
49369
|
-
setSwingVertical:
|
|
49437
|
+
setSwingVertical: optionalMethod(object({
|
|
49370
49438
|
deviceId: number$1().int().nonnegative(),
|
|
49371
49439
|
on: boolean()
|
|
49372
49440
|
}), _void(), {
|
|
49373
49441
|
kind: "mutation",
|
|
49374
49442
|
auth: "protected"
|
|
49375
49443
|
}),
|
|
49376
|
-
setSwingHorizontal:
|
|
49444
|
+
setSwingHorizontal: optionalMethod(object({
|
|
49377
49445
|
deviceId: number$1().int().nonnegative(),
|
|
49378
49446
|
on: boolean()
|
|
49379
49447
|
}), _void(), {
|
|
@@ -50632,27 +50700,27 @@ var mediaPlayerCapability = {
|
|
|
50632
50700
|
mode: "singleton",
|
|
50633
50701
|
deviceTypes: [DeviceType.MediaPlayer],
|
|
50634
50702
|
methods: {
|
|
50635
|
-
turnOn:
|
|
50703
|
+
turnOn: optionalMethod(deviceOnly, _void(), {
|
|
50636
50704
|
kind: "mutation",
|
|
50637
50705
|
auth: "protected"
|
|
50638
50706
|
}),
|
|
50639
|
-
turnOff:
|
|
50707
|
+
turnOff: optionalMethod(deviceOnly, _void(), {
|
|
50640
50708
|
kind: "mutation",
|
|
50641
50709
|
auth: "protected"
|
|
50642
50710
|
}),
|
|
50643
|
-
volumeUp:
|
|
50711
|
+
volumeUp: optionalMethod(stepInput, _void(), {
|
|
50644
50712
|
kind: "mutation",
|
|
50645
50713
|
auth: "protected"
|
|
50646
50714
|
}),
|
|
50647
|
-
volumeDown:
|
|
50715
|
+
volumeDown: optionalMethod(stepInput, _void(), {
|
|
50648
50716
|
kind: "mutation",
|
|
50649
50717
|
auth: "protected"
|
|
50650
50718
|
}),
|
|
50651
|
-
channelUp:
|
|
50719
|
+
channelUp: optionalMethod(stepInput, _void(), {
|
|
50652
50720
|
kind: "mutation",
|
|
50653
50721
|
auth: "protected"
|
|
50654
50722
|
}),
|
|
50655
|
-
channelDown:
|
|
50723
|
+
channelDown: optionalMethod(stepInput, _void(), {
|
|
50656
50724
|
kind: "mutation",
|
|
50657
50725
|
auth: "protected"
|
|
50658
50726
|
}),
|
|
@@ -50664,61 +50732,61 @@ var mediaPlayerCapability = {
|
|
|
50664
50732
|
kind: "mutation",
|
|
50665
50733
|
auth: "protected"
|
|
50666
50734
|
}),
|
|
50667
|
-
stop:
|
|
50735
|
+
stop: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
50668
50736
|
kind: "mutation",
|
|
50669
50737
|
auth: "protected"
|
|
50670
50738
|
}),
|
|
50671
|
-
next:
|
|
50739
|
+
next: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
50672
50740
|
kind: "mutation",
|
|
50673
50741
|
auth: "protected"
|
|
50674
50742
|
}),
|
|
50675
|
-
previous:
|
|
50743
|
+
previous: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
50676
50744
|
kind: "mutation",
|
|
50677
50745
|
auth: "protected"
|
|
50678
50746
|
}),
|
|
50679
|
-
seek:
|
|
50747
|
+
seek: optionalMethod(object({
|
|
50680
50748
|
deviceId: number$1().int().nonnegative(),
|
|
50681
50749
|
position: number$1().int().nonnegative()
|
|
50682
50750
|
}), _void(), {
|
|
50683
50751
|
kind: "mutation",
|
|
50684
50752
|
auth: "protected"
|
|
50685
50753
|
}),
|
|
50686
|
-
setVolume:
|
|
50754
|
+
setVolume: optionalMethod(object({
|
|
50687
50755
|
deviceId: number$1().int().nonnegative(),
|
|
50688
50756
|
volumeLevel: number$1().min(0).max(100)
|
|
50689
50757
|
}), _void(), {
|
|
50690
50758
|
kind: "mutation",
|
|
50691
50759
|
auth: "protected"
|
|
50692
50760
|
}),
|
|
50693
|
-
setMute:
|
|
50761
|
+
setMute: optionalMethod(object({
|
|
50694
50762
|
deviceId: number$1().int().nonnegative(),
|
|
50695
50763
|
muted: boolean()
|
|
50696
50764
|
}), _void(), {
|
|
50697
50765
|
kind: "mutation",
|
|
50698
50766
|
auth: "protected"
|
|
50699
50767
|
}),
|
|
50700
|
-
setShuffle:
|
|
50768
|
+
setShuffle: optionalMethod(object({
|
|
50701
50769
|
deviceId: number$1().int().nonnegative(),
|
|
50702
50770
|
shuffle: boolean()
|
|
50703
50771
|
}), _void(), {
|
|
50704
50772
|
kind: "mutation",
|
|
50705
50773
|
auth: "protected"
|
|
50706
50774
|
}),
|
|
50707
|
-
setRepeat:
|
|
50775
|
+
setRepeat: optionalMethod(object({
|
|
50708
50776
|
deviceId: number$1().int().nonnegative(),
|
|
50709
50777
|
repeat: MediaPlayerRepeatSchema
|
|
50710
50778
|
}), _void(), {
|
|
50711
50779
|
kind: "mutation",
|
|
50712
50780
|
auth: "protected"
|
|
50713
50781
|
}),
|
|
50714
|
-
selectSource:
|
|
50782
|
+
selectSource: optionalMethod(object({
|
|
50715
50783
|
deviceId: number$1().int().nonnegative(),
|
|
50716
50784
|
source: string().min(1)
|
|
50717
50785
|
}), _void(), {
|
|
50718
50786
|
kind: "mutation",
|
|
50719
50787
|
auth: "protected"
|
|
50720
50788
|
}),
|
|
50721
|
-
playMedia:
|
|
50789
|
+
playMedia: optionalMethod(object({
|
|
50722
50790
|
deviceId: number$1().int().nonnegative(),
|
|
50723
50791
|
/** Media identifier / URL. */
|
|
50724
50792
|
mediaId: string().min(1),
|
|
@@ -51740,18 +51808,18 @@ var coverCapability = {
|
|
|
51740
51808
|
kind: "mutation",
|
|
51741
51809
|
auth: "protected"
|
|
51742
51810
|
}),
|
|
51743
|
-
stop:
|
|
51811
|
+
stop: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
51744
51812
|
kind: "mutation",
|
|
51745
51813
|
auth: "protected"
|
|
51746
51814
|
}),
|
|
51747
|
-
setPosition:
|
|
51815
|
+
setPosition: optionalMethod(object({
|
|
51748
51816
|
deviceId: number$1().int().nonnegative(),
|
|
51749
51817
|
position: number$1().min(0).max(100)
|
|
51750
51818
|
}), _void(), {
|
|
51751
51819
|
kind: "mutation",
|
|
51752
51820
|
auth: "protected"
|
|
51753
51821
|
}),
|
|
51754
|
-
setTiltPosition:
|
|
51822
|
+
setTiltPosition: optionalMethod(object({
|
|
51755
51823
|
deviceId: number$1().int().nonnegative(),
|
|
51756
51824
|
tiltPosition: number$1().min(0).max(100)
|
|
51757
51825
|
}), _void(), {
|
|
@@ -52781,6 +52849,22 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
52781
52849
|
});
|
|
52782
52850
|
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
52783
52851
|
var DeviceTemplateSchema = string().min(1).max(4096);
|
|
52852
|
+
/** One value a caller hands the renderer for `thisDevice`. */
|
|
52853
|
+
var DeviceTemplateValueSchema = union([
|
|
52854
|
+
string(),
|
|
52855
|
+
number$1(),
|
|
52856
|
+
boolean()
|
|
52857
|
+
]);
|
|
52858
|
+
/**
|
|
52859
|
+
* The device a render is FOR (`camera` in the text) and the values the caller
|
|
52860
|
+
* knows about it that no capability carries, for example `lastPerson` and
|
|
52861
|
+
* `lastPlate`. `values` read as `camera.<name>`; a name a capability also carries
|
|
52862
|
+
* is `ambiguous` and is written `camera.values.<name>`.
|
|
52863
|
+
*/
|
|
52864
|
+
var DeviceTemplateThisDeviceSchema = object({
|
|
52865
|
+
deviceId: number$1().int(),
|
|
52866
|
+
values: record(string().min(1).max(64), DeviceTemplateValueSchema).optional()
|
|
52867
|
+
});
|
|
52784
52868
|
var DeviceTemplateRefusalSchema = object({
|
|
52785
52869
|
reason: _enum([
|
|
52786
52870
|
"too-long",
|
|
@@ -53412,7 +53496,9 @@ var DeviceBindingsForDeviceSchema = object({
|
|
|
53412
53496
|
kind: _enum(["native", "wrapped"]),
|
|
53413
53497
|
providerAddonId: string(),
|
|
53414
53498
|
providerNodeId: string(),
|
|
53415
|
-
nativeAddonId: string()
|
|
53499
|
+
nativeAddonId: string(),
|
|
53500
|
+
/** The cap's methods the native provider implements; absent = all. */
|
|
53501
|
+
implementedMethods: array(string()).optional()
|
|
53416
53502
|
}))
|
|
53417
53503
|
});
|
|
53418
53504
|
/**
|
|
@@ -53655,17 +53741,24 @@ method(object({
|
|
|
53655
53741
|
auth: "admin"
|
|
53656
53742
|
}), method(object({
|
|
53657
53743
|
templates: array(DeviceTemplateSchema).max(64),
|
|
53658
|
-
allowedDeviceIds: array(number$1().int()).optional()
|
|
53744
|
+
allowedDeviceIds: array(number$1().int()).optional(),
|
|
53745
|
+
/** The device `camera` names in the texts, and the values the caller knows of it. */
|
|
53746
|
+
thisDevice: DeviceTemplateThisDeviceSchema.optional()
|
|
53659
53747
|
}), object({ results: array(DeviceTemplateRenderSchema) }), { auth: "admin" }), method(object({
|
|
53660
53748
|
templates: array(string()).max(64),
|
|
53661
|
-
allowedDeviceIds: array(number$1().int()).optional()
|
|
53749
|
+
allowedDeviceIds: array(number$1().int()).optional(),
|
|
53750
|
+
thisDevice: DeviceTemplateThisDeviceSchema.optional()
|
|
53662
53751
|
}), object({ results: array(discriminatedUnion("ok", [object({
|
|
53663
53752
|
ok: literal(true),
|
|
53664
53753
|
aliases: array(object({
|
|
53665
53754
|
alias: string(),
|
|
53666
53755
|
deviceId: number$1().int().nullable(),
|
|
53667
|
-
allowed: boolean()
|
|
53668
|
-
|
|
53756
|
+
allowed: boolean(),
|
|
53757
|
+
/** The fields the text reads on this alias, as written (`temperature`, `cap.field`). */
|
|
53758
|
+
reads: array(string())
|
|
53759
|
+
})),
|
|
53760
|
+
/** Whether the text reads the clock (`now`): it changes every minute. */
|
|
53761
|
+
readsClock: boolean()
|
|
53669
53762
|
}), object({
|
|
53670
53763
|
ok: literal(false),
|
|
53671
53764
|
refusal: DeviceTemplateRefusalSchema
|
|
@@ -56387,28 +56480,28 @@ var fanControlCapability = {
|
|
|
56387
56480
|
mode: "singleton",
|
|
56388
56481
|
deviceTypes: [DeviceType.Fan],
|
|
56389
56482
|
methods: {
|
|
56390
|
-
setPercentage:
|
|
56483
|
+
setPercentage: optionalMethod(object({
|
|
56391
56484
|
deviceId: number$1().int().nonnegative(),
|
|
56392
56485
|
speed: number$1().min(0).max(100)
|
|
56393
56486
|
}), _void(), {
|
|
56394
56487
|
kind: "mutation",
|
|
56395
56488
|
auth: "protected"
|
|
56396
56489
|
}),
|
|
56397
|
-
setPreset:
|
|
56490
|
+
setPreset: optionalMethod(object({
|
|
56398
56491
|
deviceId: number$1().int().nonnegative(),
|
|
56399
56492
|
preset: string().min(1)
|
|
56400
56493
|
}), _void(), {
|
|
56401
56494
|
kind: "mutation",
|
|
56402
56495
|
auth: "protected"
|
|
56403
56496
|
}),
|
|
56404
|
-
setDirection:
|
|
56497
|
+
setDirection: optionalMethod(object({
|
|
56405
56498
|
deviceId: number$1().int().nonnegative(),
|
|
56406
56499
|
direction: FanDirectionSchema
|
|
56407
56500
|
}), _void(), {
|
|
56408
56501
|
kind: "mutation",
|
|
56409
56502
|
auth: "protected"
|
|
56410
56503
|
}),
|
|
56411
|
-
setOscillating:
|
|
56504
|
+
setOscillating: optionalMethod(object({
|
|
56412
56505
|
deviceId: number$1().int().nonnegative(),
|
|
56413
56506
|
oscillating: boolean()
|
|
56414
56507
|
}), _void(), {
|
|
@@ -60513,7 +60606,7 @@ var lockControlCapability = {
|
|
|
60513
60606
|
kind: "mutation",
|
|
60514
60607
|
auth: "protected"
|
|
60515
60608
|
}),
|
|
60516
|
-
open:
|
|
60609
|
+
open: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
60517
60610
|
kind: "mutation",
|
|
60518
60611
|
auth: "protected"
|
|
60519
60612
|
})
|
|
@@ -61710,7 +61803,7 @@ object({
|
|
|
61710
61803
|
deviceId: number$1().int().optional(),
|
|
61711
61804
|
atBefore: number$1().optional(),
|
|
61712
61805
|
where: RecordWhereSchema.optional()
|
|
61713
|
-
}), object({ count: number$1().int().nonnegative() }), object({}), object({ store: Rows }), object({ patch: Rows }), object({}), object({ keys: array(string().min(1)) }), object({ removed: array(string()) }), object({ refs: array(string()) }), object({ values: record(string(), string().nullable()) }), object({
|
|
61806
|
+
}), object({ count: number$1().int().nonnegative() }), object({}), object({ store: Rows }), object({ patch: Rows }), object({}), object({ keys: array(string().min(1)) }), object({ removed: array(string()) }), object({}), object({ deviceIds: array(number$1().int()) }), object({ deviceIds: array(number$1().int()) }), object({ blobs: record(string(), Rows) }), object({ refs: array(string()) }), object({ values: record(string(), string().nullable()) }), object({
|
|
61714
61807
|
ref: string().min(1),
|
|
61715
61808
|
value: string()
|
|
61716
61809
|
}), object({}), object({ refs: array(string()) }), object({ deleted: number$1().int().nonnegative() }), object({}), object({ integrations: array(MigrationIntegrationSchema) }), object({ id: string().min(1) }), MigrationIntegrationSchema.nullable(), object({
|
|
@@ -61721,7 +61814,7 @@ object({
|
|
|
61721
61814
|
integrationId: string().nullable(),
|
|
61722
61815
|
/** Whether the device carries any stored config; its content is not offered. */
|
|
61723
61816
|
hasConfig: boolean()
|
|
61724
|
-
}).nullable(), object({
|
|
61817
|
+
}).nullable(), object({ deviceIds: array(number$1().int()) }), object({ aliases: record(string(), string()) }), object({
|
|
61725
61818
|
deviceId: number$1().int(),
|
|
61726
61819
|
integrationId: string().min(1)
|
|
61727
61820
|
}), object({}), object({}), object({ nodeId: string() }), object({}), object({});
|
|
@@ -68999,92 +69092,21 @@ var NcZoneConditionSchema = object({
|
|
|
68999
69092
|
* membership lists are OR within the list (spec §2.3).
|
|
69000
69093
|
*/
|
|
69001
69094
|
/**
|
|
69002
|
-
* What a rule
|
|
69003
|
-
*
|
|
69004
|
-
* **No hand-maintained allowlist** (operator decision, and the right one — a
|
|
69005
|
-
* written list of methods is a third parallel map to keep aligned, and this
|
|
69006
|
-
* repo has paid for those). The boundary instead comes from a property the
|
|
69007
|
-
* capabilities already carry: an action may target only a **device-scoped**
|
|
69008
|
-
* capability method.
|
|
69009
|
-
*
|
|
69010
|
-
* That is not decoration. A rule can be authored by a NON-ADMIN — personal
|
|
69011
|
-
* rules are a supported flow — and the executor runs with the addon's
|
|
69012
|
-
* privileges, so an unbounded action is an arbitrary RPC channel with a
|
|
69013
|
-
* privilege escalation attached. Restricting to device scope excludes the
|
|
69014
|
-
* system caps (`device-manager.removeDevice` and friends) by construction,
|
|
69015
|
-
* costs nothing to maintain, and cannot rot: a cap that stops being
|
|
69016
|
-
* device-scoped stops being actuatable in the same change.
|
|
69017
|
-
*
|
|
69018
|
-
* The executor enforces it; {@link NcRuleActionSchema} carries the intent.
|
|
69019
|
-
*/
|
|
69020
|
-
/**
|
|
69021
|
-
* One step of a sequence.
|
|
69095
|
+
* What a rule or a button runs: an **Action** of the `actions` surface
|
|
69096
|
+
* (`internal:<uuid>` or an addon's), by id, and nothing else (planning#473).
|
|
69022
69097
|
*
|
|
69023
|
-
*
|
|
69024
|
-
*
|
|
69025
|
-
*
|
|
69098
|
+
* The notification centre has no step vocabulary of its own. The steps, the
|
|
69099
|
+
* device-scope boundary, the stop-at-first-failure, the throttle
|
|
69100
|
+
* (`minDelaySec`), the variables and the runs ledger all belong to the Action;
|
|
69101
|
+
* an operator edits them in ONE place (the Actions page) and a rule points at
|
|
69102
|
+
* the result. A rule can be authored by a non-admin (personal rules), which is
|
|
69103
|
+
* safe for the same reason: it can only name an Action an admin already wrote.
|
|
69026
69104
|
*/
|
|
69027
|
-
var
|
|
69028
|
-
|
|
69029
|
-
|
|
69030
|
-
}), object({
|
|
69031
|
-
kind: literal("cap"),
|
|
69032
|
-
/**
|
|
69033
|
-
* WHO the step acts on (D983) — the only shape that is written. A sequence
|
|
69034
|
-
* stored before D983 carries `deviceId`; the sequence store reads it as a
|
|
69035
|
-
* `devices` target.
|
|
69036
|
-
*/
|
|
69037
|
-
target: ActionTargetSchema.optional(),
|
|
69038
|
-
/** The vocabulary action the step performs; required for a `domain` target. */
|
|
69039
|
-
actionId: string().min(1).optional(),
|
|
69040
|
-
/** @deprecated The pre-D983 single device. Read, never written. */
|
|
69041
|
-
deviceId: number$1().int().optional(),
|
|
69042
|
-
/** Capability name, e.g. `alarm-panel`. */
|
|
69043
|
-
cap: string().min(1),
|
|
69044
|
-
/** Method on it. The executor refuses a non-device-scoped cap. */
|
|
69045
|
-
method: string().min(1),
|
|
69046
|
-
/** Method arguments, minus `deviceId` (the executor injects it). */
|
|
69047
|
-
args: record(string(), unknown()).optional()
|
|
69048
|
-
}).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
69049
|
-
message: "a cap step needs a target",
|
|
69050
|
-
path: ["target"]
|
|
69051
|
-
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
69052
|
-
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
69053
|
-
path: ["actionId"]
|
|
69054
|
-
})]);
|
|
69055
|
-
/**
|
|
69056
|
-
* A named, ordered run of steps shared across rules, with its own throttle.
|
|
69057
|
-
*
|
|
69058
|
-
* Sequences live in the notification centre's sequence store — never inline on
|
|
69059
|
-
* a rule. A rule binds to one by id ({@link NcActionBindingSchema}), and a
|
|
69060
|
-
* button names one the same way. `minDelaySec` exists because a noisy rule
|
|
69061
|
-
* otherwise hammers a physical actuator — the rule's own cooldown governs
|
|
69062
|
-
* NOTIFICATIONS, which is a different budget from "how often may this gate
|
|
69063
|
-
* actually open". The throttle key is the sequence id, so two rules sharing
|
|
69064
|
-
* one sequence share its budget.
|
|
69065
|
-
*/
|
|
69066
|
-
var NcSharedSequenceSchema = object({
|
|
69067
|
-
id: string().min(1),
|
|
69068
|
-
name: string().min(1).max(120),
|
|
69069
|
-
minDelaySec: number$1().int().min(0).max(86400).optional(),
|
|
69070
|
-
actions: array(NcRuleActionSchema).min(1)
|
|
69071
|
-
});
|
|
69072
|
-
/** Create / update body — the id is minted by the provider. */
|
|
69073
|
-
var NcSharedSequenceInputSchema = object({
|
|
69074
|
-
name: string().min(1).max(120),
|
|
69075
|
-
minDelaySec: number$1().int().min(0).max(86400).optional(),
|
|
69076
|
-
actions: array(NcRuleActionSchema).min(1)
|
|
69077
|
-
});
|
|
69078
|
-
/** Bindings on one hook edge. Cap keeps a slot from becoming a second sequence editor. */
|
|
69079
|
-
var NcHookBindingsSchema = array(discriminatedUnion("kind", [object({
|
|
69080
|
-
kind: literal("sequence"),
|
|
69081
|
-
sequenceId: string().min(1)
|
|
69082
|
-
}), object({
|
|
69083
|
-
kind: literal("do"),
|
|
69084
|
-
action: NcRuleActionSchema
|
|
69085
|
-
})])).max(4);
|
|
69105
|
+
var NcActionIdSchema = string().min(1);
|
|
69106
|
+
/** Action ids one hook edge runs, in order. Capped so a slot never becomes a second editor. */
|
|
69107
|
+
var NcHookActionIdsSchema = array(NcActionIdSchema).max(4);
|
|
69086
69108
|
/**
|
|
69087
|
-
* One button carried by the notification, running
|
|
69109
|
+
* One button carried by the notification, running an Action on tap.
|
|
69088
69110
|
*
|
|
69089
69111
|
* **Read this before adding a button that does something physical.** The tap
|
|
69090
69112
|
* arrives over a link that travelled through third-party infrastructure — ntfy,
|
|
@@ -69099,9 +69121,9 @@ var NcRuleNotificationButtonSchema = object({
|
|
|
69099
69121
|
/** Stable id — travels in the callback and identifies the button in logs. */
|
|
69100
69122
|
id: string().min(1).max(64),
|
|
69101
69123
|
label: string().min(1).max(40),
|
|
69102
|
-
/**
|
|
69103
|
-
*
|
|
69104
|
-
|
|
69124
|
+
/** The Action the tap runs. The dispatcher drops a button whose Action does
|
|
69125
|
+
* not exist rather than minting a token for nothing. */
|
|
69126
|
+
actionId: NcActionIdSchema,
|
|
69105
69127
|
icon: NotificationActionIconSchema.optional(),
|
|
69106
69128
|
destructive: boolean().optional()
|
|
69107
69129
|
});
|
|
@@ -69116,25 +69138,19 @@ var NcRuleNotificationButtonSchema = object({
|
|
|
69116
69138
|
* leave). A delivery with no clear edge never produces this hook.
|
|
69117
69139
|
*/
|
|
69118
69140
|
var NcRuleActionsSchema = object({
|
|
69119
|
-
onActivation:
|
|
69120
|
-
onDeactivation:
|
|
69141
|
+
onActivation: NcHookActionIdsSchema.optional(),
|
|
69142
|
+
onDeactivation: NcHookActionIdsSchema.optional(),
|
|
69121
69143
|
/** Runs on a positive / raised match. */
|
|
69122
|
-
onTrigger:
|
|
69144
|
+
onTrigger: NcHookActionIdsSchema.optional(),
|
|
69123
69145
|
/** Runs on a clear / leave match, when the subject carries one. */
|
|
69124
|
-
onTriggerOff:
|
|
69146
|
+
onTriggerOff: NcHookActionIdsSchema.optional(),
|
|
69125
69147
|
/**
|
|
69126
|
-
* Buttons the NOTIFICATION carries, each running one
|
|
69127
|
-
*
|
|
69128
|
-
*
|
|
69148
|
+
* Buttons the NOTIFICATION carries, each running one Action when tapped.
|
|
69149
|
+
* Deliberately a REFERENCE — a button that could define its own steps would
|
|
69150
|
+
* be a parallel actuation vocabulary.
|
|
69129
69151
|
*/
|
|
69130
69152
|
buttons: array(NcRuleNotificationButtonSchema).max(8).optional()
|
|
69131
69153
|
});
|
|
69132
|
-
object({
|
|
69133
|
-
name: string().min(1).max(120),
|
|
69134
|
-
enabled: boolean(),
|
|
69135
|
-
minDelaySec: number$1().int().min(0).max(86400).optional(),
|
|
69136
|
-
actions: array(NcRuleActionSchema).min(1)
|
|
69137
|
-
});
|
|
69138
69154
|
/**
|
|
69139
69155
|
* "This rule applies only while `deviceId` is in one of `states`."
|
|
69140
69156
|
*
|
|
@@ -69433,6 +69449,16 @@ var NcRuleTargetSchema = object({
|
|
|
69433
69449
|
*/
|
|
69434
69450
|
params: record(string(), unknown()).optional()
|
|
69435
69451
|
});
|
|
69452
|
+
var NcTargetOverrideSchema = object({
|
|
69453
|
+
template: object({
|
|
69454
|
+
title: string().max(500).optional(),
|
|
69455
|
+
body: string().max(2e3).optional()
|
|
69456
|
+
}).optional(),
|
|
69457
|
+
schedule: NcScheduleSchema.optional(),
|
|
69458
|
+
priority: number$1().int().min(1).max(5).optional()
|
|
69459
|
+
});
|
|
69460
|
+
/** Per-target settings keyed by target id (#487). */
|
|
69461
|
+
var NcTargetOverridesSchema = record(string(), NcTargetOverrideSchema);
|
|
69436
69462
|
/**
|
|
69437
69463
|
* WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
|
|
69438
69464
|
*
|
|
@@ -69714,6 +69740,13 @@ var NcRuleInputSchema = object({
|
|
|
69714
69740
|
* targets.
|
|
69715
69741
|
*/
|
|
69716
69742
|
targetUsers: array(string()).optional(),
|
|
69743
|
+
/**
|
|
69744
|
+
* Per-target settings keyed by target id (#487): texts, schedule, priority.
|
|
69745
|
+
* Absent (and an absent entry) = the rule's own values. A patch that omits
|
|
69746
|
+
* the key keeps the stored map; a patch that names it REPLACES it whole —
|
|
69747
|
+
* `{}` empties it.
|
|
69748
|
+
*/
|
|
69749
|
+
targetOverrides: NcTargetOverridesSchema.optional(),
|
|
69717
69750
|
/** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
|
|
69718
69751
|
* detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
|
|
69719
69752
|
media: NcMediaPolicySchema.default({}),
|
|
@@ -70815,18 +70848,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
70815
70848
|
}), object({ success: literal(true) }), {
|
|
70816
70849
|
kind: "mutation",
|
|
70817
70850
|
auth: "admin"
|
|
70818
|
-
}), method(object({}), object({ sequences: array(NcSharedSequenceSchema) }), { auth: "admin" }), method(object({ sequenceId: string().min(1) }), object({ sequence: NcSharedSequenceSchema.nullable() }), { auth: "admin" }), method(object({ sequence: NcSharedSequenceInputSchema }), object({ sequence: NcSharedSequenceSchema }), {
|
|
70819
|
-
kind: "mutation",
|
|
70820
|
-
auth: "admin"
|
|
70821
|
-
}), method(object({
|
|
70822
|
-
sequenceId: string().min(1),
|
|
70823
|
-
sequence: NcSharedSequenceInputSchema
|
|
70824
|
-
}), object({ sequence: NcSharedSequenceSchema }), {
|
|
70825
|
-
kind: "mutation",
|
|
70826
|
-
auth: "admin"
|
|
70827
|
-
}), method(object({ sequenceId: string().min(1) }), object({ success: literal(true) }), {
|
|
70828
|
-
kind: "mutation",
|
|
70829
|
-
auth: "admin"
|
|
70830
70851
|
}), method(object({}), NcClipRetentionPlanSchema, { auth: "admin" }), method(object({}), object({ mutedDeviceIds: array(number$1().int()).readonly() }), { auth: "admin" }), method(object({
|
|
70831
70852
|
deviceId: number$1().int(),
|
|
70832
70853
|
muted: boolean()
|
|
@@ -71265,53 +71286,41 @@ DeviceType.Camera, method(object({
|
|
|
71265
71286
|
deviceId: number$1(),
|
|
71266
71287
|
status: OsdStatusSchema
|
|
71267
71288
|
});
|
|
71268
|
-
_enum([
|
|
71269
|
-
"value",
|
|
71270
|
-
"unit",
|
|
71271
|
-
"full"
|
|
71272
|
-
]);
|
|
71273
|
-
_enum([
|
|
71274
|
-
"value+unit",
|
|
71275
|
-
"value",
|
|
71276
|
-
"unit"
|
|
71277
|
-
]);
|
|
71278
71289
|
/**
|
|
71279
|
-
*
|
|
71280
|
-
*
|
|
71281
|
-
*
|
|
71290
|
+
* `osd-manager` — the ORCHESTRATOR over the device-scope `osd` cap.
|
|
71291
|
+
*
|
|
71292
|
+
* The `osd` cap is the firmware contract: it probes a camera's overlay
|
|
71293
|
+
* SLOTS and writes literal text into one. It has no idea WHERE that text
|
|
71294
|
+
* comes from, and it must not — a driver that grew a "show the temperature
|
|
71295
|
+
* here" feature would grow it once per vendor.
|
|
71296
|
+
*
|
|
71297
|
+
* This cap owns the other half: a per-(camera, slot) BINDING that says
|
|
71298
|
+
* which value feeds the slot, how it is formatted, and under which
|
|
71299
|
+
* conditions it is shown at all. Named TEMPLATES combine many device
|
|
71300
|
+
* fields into one overlay string (plugin catalog OSD Manager parity).
|
|
71282
71301
|
*/
|
|
71283
|
-
var OsdTemplatePickSchema = object({
|
|
71284
|
-
containerId: number$1().int().optional(),
|
|
71285
|
-
deviceId: number$1().int()
|
|
71286
|
-
});
|
|
71287
71302
|
/**
|
|
71288
|
-
*
|
|
71289
|
-
*
|
|
71290
|
-
* `{
|
|
71291
|
-
*
|
|
71303
|
+
* The text of a named template: a device template (D1021) —
|
|
71304
|
+
* `{{ camera.temperature | round(1) }}`, `{{ now | time('HH:mm') }}`,
|
|
71305
|
+
* `{% if camera.motion %}MOTION{% endif %}` — rendered by the ONE hub renderer
|
|
71306
|
+
* (`device-manager.renderDeviceTemplates`), never by this addon.
|
|
71307
|
+
*
|
|
71308
|
+
* Two names belong to the render rather than to a device:
|
|
71309
|
+
* - `now` is the clock; `time('HH:mm')` prints it in the server's zone.
|
|
71310
|
+
* - `camera` is the camera the overlay is on, so one template serves every
|
|
71311
|
+
* camera. `camera.lastPerson` and `camera.lastPlate` are the most recent
|
|
71312
|
+
* recognition persisted for it (empty text until there is one, with
|
|
71313
|
+
* `| default('')`).
|
|
71292
71314
|
*/
|
|
71293
|
-
var
|
|
71294
|
-
/** Token stem in the parser, e.g. `t` → `{t}` / `{t.value}`. Unique within the template. */
|
|
71295
|
-
alias: string().min(1).max(32).regex(/^[A-Za-z][A-Za-z0-9_-]*$/, "alias must start with a letter"),
|
|
71296
|
-
pick: OsdTemplatePickSchema,
|
|
71297
|
-
capName: string().min(1).max(64),
|
|
71298
|
-
valuePath: string().min(1).max(64),
|
|
71299
|
-
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
71300
|
-
displayUnit: string().max(16).optional(),
|
|
71301
|
-
maxDecimals: number$1().int().min(0).max(4).default(1),
|
|
71302
|
-
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
71303
|
-
valueMap: record(string(), string()).optional()
|
|
71304
|
-
});
|
|
71315
|
+
var OSD_TEMPLATE_TEXT_MAX = 1024;
|
|
71305
71316
|
/**
|
|
71306
|
-
* A named template:
|
|
71307
|
-
*
|
|
71317
|
+
* A named template: the unit of reuse. A slot points at one by id; editing it
|
|
71318
|
+
* changes every slot that points at it, on every camera.
|
|
71308
71319
|
*/
|
|
71309
71320
|
var OsdNamedTemplateSchema = object({
|
|
71310
71321
|
id: string().min(1).max(64),
|
|
71311
71322
|
name: string().min(1).max(64),
|
|
71312
|
-
|
|
71313
|
-
/** Parser with alias placeholders, e.g. `{t.value} {t.unit} / {h}`. */
|
|
71314
|
-
parser: string().max(256).default("")
|
|
71323
|
+
text: string().max(OSD_TEMPLATE_TEXT_MAX).default("")
|
|
71315
71324
|
});
|
|
71316
71325
|
/** Where a slot's value comes from. */
|
|
71317
71326
|
var OsdSourceSchema = discriminatedUnion("kind", [
|
|
@@ -71320,26 +71329,6 @@ var OsdSourceSchema = discriminatedUnion("kind", [
|
|
|
71320
71329
|
kind: literal("static"),
|
|
71321
71330
|
text: string().max(64)
|
|
71322
71331
|
}),
|
|
71323
|
-
object({
|
|
71324
|
-
kind: literal("clock"),
|
|
71325
|
-
/** Token pattern: `YYYY MM DD HH mm ss`. Everything else is literal. */
|
|
71326
|
-
pattern: string().min(1).max(32).default("HH:mm"),
|
|
71327
|
-
/** IANA zone. Omitted = the server's zone. */
|
|
71328
|
-
timezone: string().min(1).max(64).optional()
|
|
71329
|
-
}),
|
|
71330
|
-
object({
|
|
71331
|
-
kind: literal("device-state"),
|
|
71332
|
-
deviceId: number$1().int().optional(),
|
|
71333
|
-
capName: string().min(1).max(64),
|
|
71334
|
-
/** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
|
|
71335
|
-
valuePath: string().min(1).max(64),
|
|
71336
|
-
/** Convert TO this unit at render. Absent = no conversion. */
|
|
71337
|
-
displayUnit: string().max(16).optional()
|
|
71338
|
-
}),
|
|
71339
|
-
object({
|
|
71340
|
-
kind: literal("latest-recognition"),
|
|
71341
|
-
recognition: _enum(["person", "plate"])
|
|
71342
|
-
}),
|
|
71343
71332
|
object({
|
|
71344
71333
|
kind: literal("template"),
|
|
71345
71334
|
templateId: string().min(1).max(64)
|
|
@@ -71349,15 +71338,6 @@ var OsdSlotBindingSchema = object({
|
|
|
71349
71338
|
/** Off = the manager stops driving this slot. It does NOT clear it. */
|
|
71350
71339
|
enabled: boolean().default(true),
|
|
71351
71340
|
source: OsdSourceSchema,
|
|
71352
|
-
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
71353
|
-
template: string().max(96).default("${value}"),
|
|
71354
|
-
/**
|
|
71355
|
-
* Decimal places for a numeric value. `0` yields an integer — the
|
|
71356
|
-
* documented workaround for firmwares that reject `.` in overlay text.
|
|
71357
|
-
*/
|
|
71358
|
-
maxDecimals: number$1().int().min(0).max(4).default(1),
|
|
71359
|
-
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
71360
|
-
valueMap: record(string(), string()).optional(),
|
|
71361
71341
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
71362
71342
|
schedule: NcScheduleSchema.optional(),
|
|
71363
71343
|
/**
|
|
@@ -71399,31 +71379,21 @@ var OsdRenderResultSchema = object({
|
|
|
71399
71379
|
/** Why, whenever the outcome is not a plain write. Never silent. */
|
|
71400
71380
|
reason: string().optional()
|
|
71401
71381
|
});
|
|
71402
|
-
var OsdSourceValueTypeEnum = _enum([
|
|
71403
|
-
"number",
|
|
71404
|
-
"boolean",
|
|
71405
|
-
"string",
|
|
71406
|
-
"enum"
|
|
71407
|
-
]);
|
|
71408
71382
|
/**
|
|
71409
|
-
*
|
|
71410
|
-
*
|
|
71411
|
-
*
|
|
71383
|
+
* A template rendered for one camera without being saved: what the editor
|
|
71384
|
+
* previews. `text` is what the overlay would carry; a refused render has a
|
|
71385
|
+
* `reason` and an empty text.
|
|
71412
71386
|
*/
|
|
71413
|
-
var
|
|
71414
|
-
|
|
71415
|
-
|
|
71416
|
-
|
|
71417
|
-
|
|
71418
|
-
label: string(),
|
|
71419
|
-
valueType: OsdSourceValueTypeEnum,
|
|
71420
|
-
/** Present for `enum`; the editor offers these as `valueMap` keys. */
|
|
71421
|
-
enumValues: array(string()).readonly().optional()
|
|
71387
|
+
var OsdTemplatePreviewSchema = object({
|
|
71388
|
+
ok: boolean(),
|
|
71389
|
+
text: string(),
|
|
71390
|
+
/** The refusal, or `ref: reason` per value that printed `—`. */
|
|
71391
|
+
notes: array(string())
|
|
71422
71392
|
});
|
|
71423
71393
|
method(object({ deviceId: number$1().int() }), object({
|
|
71424
71394
|
supported: boolean(),
|
|
71425
71395
|
slots: array(OsdSlotViewSchema)
|
|
71426
|
-
}), { auth: "admin" }), method(object({
|
|
71396
|
+
}), { auth: "admin" }), method(object({}), object({
|
|
71427
71397
|
supported: array(string()),
|
|
71428
71398
|
catalog: array(NcConditionDescriptorSchema)
|
|
71429
71399
|
}), { auth: "admin" }), method(object({
|
|
@@ -71465,6 +71435,12 @@ method(object({ deviceId: number$1().int() }), object({
|
|
|
71465
71435
|
}), OsdRenderResultSchema, {
|
|
71466
71436
|
kind: "mutation",
|
|
71467
71437
|
auth: "admin"
|
|
71438
|
+
}), method(object({
|
|
71439
|
+
deviceId: number$1().int(),
|
|
71440
|
+
text: string().max(OSD_TEMPLATE_TEXT_MAX)
|
|
71441
|
+
}), OsdTemplatePreviewSchema, {
|
|
71442
|
+
kind: "mutation",
|
|
71443
|
+
auth: "admin"
|
|
71468
71444
|
}), method(object({ deviceId: number$1().int() }), object({ results: array(OsdRenderResultSchema) }), {
|
|
71469
71445
|
kind: "mutation",
|
|
71470
71446
|
auth: "admin"
|
|
@@ -81064,7 +81040,7 @@ var valveCapability = {
|
|
|
81064
81040
|
kind: "mutation",
|
|
81065
81041
|
auth: "protected"
|
|
81066
81042
|
}),
|
|
81067
|
-
setPosition:
|
|
81043
|
+
setPosition: optionalMethod(object({
|
|
81068
81044
|
deviceId: number$1().int().nonnegative(),
|
|
81069
81045
|
position: number$1().min(0).max(100)
|
|
81070
81046
|
}), _void(), {
|
|
@@ -92369,13 +92345,6 @@ Object.freeze({
|
|
|
92369
92345
|
access: "create",
|
|
92370
92346
|
role: "admin"
|
|
92371
92347
|
},
|
|
92372
|
-
"notificationRules.createSequence": {
|
|
92373
|
-
capName: "notification-rules",
|
|
92374
|
-
capScope: "system",
|
|
92375
|
-
addonId: null,
|
|
92376
|
-
access: "create",
|
|
92377
|
-
role: "admin"
|
|
92378
|
-
},
|
|
92379
92348
|
"notificationRules.createSnooze": {
|
|
92380
92349
|
capName: "notification-rules",
|
|
92381
92350
|
capScope: "system",
|
|
@@ -92397,13 +92366,6 @@ Object.freeze({
|
|
|
92397
92366
|
access: "delete",
|
|
92398
92367
|
role: "admin"
|
|
92399
92368
|
},
|
|
92400
|
-
"notificationRules.deleteSequence": {
|
|
92401
|
-
capName: "notification-rules",
|
|
92402
|
-
capScope: "system",
|
|
92403
|
-
addonId: null,
|
|
92404
|
-
access: "delete",
|
|
92405
|
-
role: "admin"
|
|
92406
|
-
},
|
|
92407
92369
|
"notificationRules.getAlarmConfig": {
|
|
92408
92370
|
capName: "notification-rules",
|
|
92409
92371
|
capScope: "system",
|
|
@@ -92453,13 +92415,6 @@ Object.freeze({
|
|
|
92453
92415
|
access: "view",
|
|
92454
92416
|
role: "admin"
|
|
92455
92417
|
},
|
|
92456
|
-
"notificationRules.getSequence": {
|
|
92457
|
-
capName: "notification-rules",
|
|
92458
|
-
capScope: "system",
|
|
92459
|
-
addonId: null,
|
|
92460
|
-
access: "view",
|
|
92461
|
-
role: "admin"
|
|
92462
|
-
},
|
|
92463
92418
|
"notificationRules.getTemplateCatalog": {
|
|
92464
92419
|
capName: "notification-rules",
|
|
92465
92420
|
capScope: "system",
|
|
@@ -92481,13 +92436,6 @@ Object.freeze({
|
|
|
92481
92436
|
access: "view",
|
|
92482
92437
|
role: "admin"
|
|
92483
92438
|
},
|
|
92484
|
-
"notificationRules.listSequences": {
|
|
92485
|
-
capName: "notification-rules",
|
|
92486
|
-
capScope: "system",
|
|
92487
|
-
addonId: null,
|
|
92488
|
-
access: "view",
|
|
92489
|
-
role: "admin"
|
|
92490
|
-
},
|
|
92491
92439
|
"notificationRules.listSnoozes": {
|
|
92492
92440
|
capName: "notification-rules",
|
|
92493
92441
|
capScope: "system",
|
|
@@ -92558,13 +92506,6 @@ Object.freeze({
|
|
|
92558
92506
|
access: "create",
|
|
92559
92507
|
role: "admin"
|
|
92560
92508
|
},
|
|
92561
|
-
"notificationRules.updateSequence": {
|
|
92562
|
-
capName: "notification-rules",
|
|
92563
|
-
capScope: "system",
|
|
92564
|
-
addonId: null,
|
|
92565
|
-
access: "create",
|
|
92566
|
-
role: "admin"
|
|
92567
|
-
},
|
|
92568
92509
|
"notifier.cancel": {
|
|
92569
92510
|
capName: "notifier",
|
|
92570
92511
|
capScope: "device",
|
|
@@ -92649,21 +92590,21 @@ Object.freeze({
|
|
|
92649
92590
|
access: "view",
|
|
92650
92591
|
role: "admin"
|
|
92651
92592
|
},
|
|
92652
|
-
"osdManager.
|
|
92593
|
+
"osdManager.listTemplates": {
|
|
92653
92594
|
capName: "osd-manager",
|
|
92654
92595
|
capScope: "system",
|
|
92655
92596
|
addonId: null,
|
|
92656
92597
|
access: "view",
|
|
92657
92598
|
role: "admin"
|
|
92658
92599
|
},
|
|
92659
|
-
"osdManager.
|
|
92600
|
+
"osdManager.previewSlot": {
|
|
92660
92601
|
capName: "osd-manager",
|
|
92661
92602
|
capScope: "system",
|
|
92662
92603
|
addonId: null,
|
|
92663
|
-
access: "
|
|
92604
|
+
access: "create",
|
|
92664
92605
|
role: "admin"
|
|
92665
92606
|
},
|
|
92666
|
-
"osdManager.
|
|
92607
|
+
"osdManager.previewTemplate": {
|
|
92667
92608
|
capName: "osd-manager",
|
|
92668
92609
|
capScope: "system",
|
|
92669
92610
|
addonId: null,
|
|
@@ -97453,6 +97394,24 @@ function projectAction(cap, action) {
|
|
|
97453
97394
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
97454
97395
|
DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.HeatPump, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Heater, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway;
|
|
97455
97396
|
DeviceFeature.BatteryOperated;
|
|
97397
|
+
function bound(cap, methods = [], authority = "reported") {
|
|
97398
|
+
return {
|
|
97399
|
+
kind: "cap",
|
|
97400
|
+
cap,
|
|
97401
|
+
methods,
|
|
97402
|
+
authority
|
|
97403
|
+
};
|
|
97404
|
+
}
|
|
97405
|
+
function derived(cap, methods = []) {
|
|
97406
|
+
return bound(cap, methods, "derived");
|
|
97407
|
+
}
|
|
97408
|
+
DeviceFeature.BatteryOperated, DeviceFeature.Rebootable, derived("reboot", ["reboot"]), DeviceFeature.Resyncable, DeviceFeature.NativeSnapshot, DeviceFeature.DoorbellButton, derived("doorbell"), DeviceFeature.TwoWayAudio, derived("intercom", [
|
|
97409
|
+
"startTalkSession",
|
|
97410
|
+
"pushTalkAudio",
|
|
97411
|
+
"endTalkSession"
|
|
97412
|
+
]), DeviceFeature.PanTiltZoom, derived("ptz"), DeviceFeature.PtzAutotrack, derived("ptz-autotrack"), DeviceFeature.MotionTrigger, derived("motion-trigger", ["setMotionTrigger"]), DeviceFeature.TimedRun, derived("timed-run", ["runFor"]), DeviceFeature.Switch, DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired, DeviceFeature.ClimateDualSetpoint, DeviceFeature.ClimateHumidity, DeviceFeature.ClimateFanMode, DeviceFeature.ClimatePreset, DeviceFeature.ClimateSwingVertical, DeviceFeature.ClimateSwingHorizontal, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.CoverStoppable, DeviceFeature.ValvePositionable, DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.LockPinRequired, DeviceFeature.LockOpen, DeviceFeature.MediaPlayerSeek, DeviceFeature.MediaPlayerVolume, DeviceFeature.MediaPlayerMute, DeviceFeature.MediaPlayerShuffle, DeviceFeature.MediaPlayerRepeat, DeviceFeature.MediaPlayerSelectSource, DeviceFeature.MediaPlayerPlayMedia, DeviceFeature.MediaPlayerNext, DeviceFeature.MediaPlayerPrevious, DeviceFeature.MediaPlayerStop, DeviceFeature.MediaPlayerVolumeStep, DeviceFeature.MediaPlayerChannelStep, DeviceFeature.MediaPlayerPower, DeviceFeature.AlarmPinRequired, DeviceFeature.PresenceGps, DeviceFeature.NotifierImage, DeviceFeature.NotifierPriority, DeviceFeature.NotifierData, DeviceFeature.NotifierActions, DeviceFeature.NotifierRecipients, DeviceFeature.ScriptVariables, DeviceFeature.AutomationSkipCondition, DeviceFeature.VacuumHasMap, DeviceFeature.VacuumHasAi, DeviceFeature.MowerHasMap, DeviceFeature.MowerHasTargetedMowing, DeviceFeature.Navigation, derived("navigation"), DeviceFeature.NetworkLink, derived("network-link");
|
|
97413
|
+
var ALL_FEATURES = Object.values(DeviceFeature);
|
|
97414
|
+
new Set(ALL_FEATURES);
|
|
97456
97415
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
97457
97416
|
var HA_AS = "a power sensor (device_class power). Home Assistant has no laundry domain. running-state stays unexported until a null reading can be published as unavailable.";
|
|
97458
97417
|
var HOMEKIT_REASON = "HomeKit has no laundry-appliance service. The export tab would pair an accessory with nothing on it: running-state is withheld until a null reading can be unavailable, and power is not a HomeKit service this export honours.";
|
|
@@ -99108,12 +99067,12 @@ Object.freeze({
|
|
|
99108
99067
|
form: "single",
|
|
99109
99068
|
optional: false
|
|
99110
99069
|
}],
|
|
99111
|
-
"osdManager.
|
|
99070
|
+
"osdManager.previewSlot": [{
|
|
99112
99071
|
name: "deviceId",
|
|
99113
99072
|
form: "single",
|
|
99114
99073
|
optional: false
|
|
99115
99074
|
}],
|
|
99116
|
-
"osdManager.
|
|
99075
|
+
"osdManager.previewTemplate": [{
|
|
99117
99076
|
name: "deviceId",
|
|
99118
99077
|
form: "single",
|
|
99119
99078
|
optional: false
|