@camstack/addon-provider-bosch 0.1.46 → 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 +12 -0
- package/dist/{account-integration-offline-BfsMnlJo.js → account-integration-offline-CQ7UB6U_.js} +1 -1
- package/dist/{account-integration-offline-BGH1q3tj.mjs → account-integration-offline-DLCUxCxS.mjs} +1 -1
- package/dist/{bosch-instances-BD-Valeo.js → bosch-instances-CRvxRbDk.js} +306 -330
- package/dist/{bosch-instances-DkUo6BfT.mjs → bosch-instances-t9x1fGVW.mjs} +306 -330
- package/dist/home-connect/addon.js +2 -2
- package/dist/home-connect/addon.mjs +2 -2
- package/dist/homecom/addon.js +210 -92
- package/dist/homecom/addon.mjs +210 -92
- 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/
|
|
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
|
/**
|
|
@@ -1204,6 +1208,12 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
1204
1208
|
DeviceRole["IrTransmitter"] = "ir-transmitter";
|
|
1205
1209
|
return DeviceRole;
|
|
1206
1210
|
}({});
|
|
1211
|
+
/**
|
|
1212
|
+
* A composed device's stableId is this prefix plus the block id. Its own module,
|
|
1213
|
+
* free of zod, so the addon runner can read it through `@camstack/types/addon`
|
|
1214
|
+
* without loading the schema barrel (D28).
|
|
1215
|
+
*/
|
|
1216
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
1207
1217
|
//#endregion
|
|
1208
1218
|
//#region ../../node_modules/zod/v4/core/core.js
|
|
1209
1219
|
var _a$1;
|
|
@@ -6016,7 +6026,7 @@ var ZodIssueCode = {
|
|
|
6016
6026
|
var ZodFirstPartyTypeKind;
|
|
6017
6027
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6018
6028
|
//#endregion
|
|
6019
|
-
//#region ../types/dist/sleep-
|
|
6029
|
+
//#region ../types/dist/sleep-Dz1P6--1.mjs
|
|
6020
6030
|
/**
|
|
6021
6031
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6022
6032
|
* window to float samples (D455).
|
|
@@ -10103,15 +10113,52 @@ var PeerBytesTicketSchema = object({
|
|
|
10103
10113
|
*/
|
|
10104
10114
|
declaredBytes: number$1().int().nonnegative().nullable()
|
|
10105
10115
|
});
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
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
|
+
]);
|
|
10115
10162
|
/**
|
|
10116
10163
|
* One recorded device transition (D1022): a status field of a device went from
|
|
10117
10164
|
* one value to another, with who or what asked for it.
|
|
@@ -17406,7 +17453,7 @@ Object.freeze({
|
|
|
17406
17453
|
}
|
|
17407
17454
|
});
|
|
17408
17455
|
//#endregion
|
|
17409
|
-
//#region ../types/dist/
|
|
17456
|
+
//#region ../types/dist/implemented-methods-OitwyO1Y.mjs
|
|
17410
17457
|
/**
|
|
17411
17458
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
17412
17459
|
*
|
|
@@ -18361,8 +18408,6 @@ var HelperSpecSchema = discriminatedUnion("kind", [
|
|
|
18361
18408
|
source: HelperMemberSchema
|
|
18362
18409
|
})
|
|
18363
18410
|
]);
|
|
18364
|
-
/** A composed device's stableId is this prefix plus the block id. */
|
|
18365
|
-
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
18366
18411
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
18367
18412
|
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
18368
18413
|
/** One field of one capability of one source device. */
|
|
@@ -19348,18 +19393,43 @@ var TargetKindLevelSchema = object({
|
|
|
19348
19393
|
requires: array(string()).optional(),
|
|
19349
19394
|
description: string().optional()
|
|
19350
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
|
+
]);
|
|
19351
19428
|
/** The full capability block consulted before dispatch. */
|
|
19352
19429
|
var TargetKindCapsSchema = object({
|
|
19353
|
-
|
|
19354
|
-
|
|
19355
|
-
|
|
19356
|
-
"url",
|
|
19357
|
-
"bytes",
|
|
19358
|
-
"both"
|
|
19359
|
-
]),
|
|
19360
|
-
max: number$1().int().nonnegative(),
|
|
19361
|
-
maxBytes: number$1().int().positive().optional()
|
|
19362
|
-
}),
|
|
19430
|
+
/** Text fields this kind delivers (#483). Absent = title AND body. */
|
|
19431
|
+
text: TargetKindTextCapsSchema.optional(),
|
|
19432
|
+
attachments: TargetKindAttachmentsCapsSchema,
|
|
19363
19433
|
/** Max action buttons (0 = none). */
|
|
19364
19434
|
actions: number$1().int().nonnegative(),
|
|
19365
19435
|
/**
|
|
@@ -44483,30 +44553,21 @@ function convertLegacyWhen(half) {
|
|
|
44483
44553
|
* (instants) and state leaves (durations). It replaces the flat trigger list
|
|
44484
44554
|
* plus the separate condition tree; the firing rule is in that file and in
|
|
44485
44555
|
* ADR "one tree".
|
|
44486
|
-
* - **Actions** — `
|
|
44487
|
-
* fragment of §3.2.2. See {@link AutomationActionSchema}
|
|
44488
|
-
* 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}.
|
|
44489
44558
|
*
|
|
44490
44559
|
* A recipe stored in the old shape (`triggers` + `conditions`) still LOADS:
|
|
44491
44560
|
* {@link AutomationRecipeSchema} (the parse-anywhere schema) converts it on parse. Nothing writes it.
|
|
44492
44561
|
*/
|
|
44493
44562
|
/**
|
|
44494
|
-
* One action step.
|
|
44495
|
-
*
|
|
44496
|
-
* `wait` and `cap` are `NcRuleActionSchema`'s two members, kept structurally
|
|
44497
|
-
* identical so `NcRuleActionRunner` runs them unchanged — its device-scope
|
|
44498
|
-
* check, stop-at-first-failure and per-sequence throttle are the whole reason
|
|
44499
|
-
* to reuse it, and none of them are re-implemented here.
|
|
44563
|
+
* One action step: `wait`, or a `cap` call.
|
|
44500
44564
|
*
|
|
44501
|
-
*
|
|
44502
|
-
*
|
|
44503
|
-
*
|
|
44504
|
-
*
|
|
44505
|
-
*
|
|
44506
|
-
*
|
|
44507
|
-
* also accepts `{ $var }`, resolved from the run's `vars` bag BEFORE the runner
|
|
44508
|
-
* is called. The runner still receives a number and is untouched; the
|
|
44509
|
-
* 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).
|
|
44510
44571
|
*/
|
|
44511
44572
|
var AutomationWaitStepSchema = object({
|
|
44512
44573
|
kind: literal("wait"),
|
|
@@ -45124,6 +45185,8 @@ var ActionStatusSchema = object({
|
|
|
45124
45185
|
/** The latest run's failure; null on success or when it never ran. */
|
|
45125
45186
|
lastError: string().nullable()
|
|
45126
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);
|
|
45127
45190
|
var ActionEntrySchema = object({
|
|
45128
45191
|
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
45129
45192
|
id: string().min(3),
|
|
@@ -45136,6 +45199,14 @@ var ActionEntrySchema = object({
|
|
|
45136
45199
|
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
45137
45200
|
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
45138
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(),
|
|
45139
45210
|
status: ActionStatusSchema
|
|
45140
45211
|
}).superRefine((entry, ctx) => {
|
|
45141
45212
|
if (entry.source === "internal") {
|
|
@@ -45166,7 +45237,8 @@ var ActionEntrySchema = object({
|
|
|
45166
45237
|
var ActionInputSchema = object({
|
|
45167
45238
|
name: string().min(1).max(120),
|
|
45168
45239
|
steps: array(ActionStepSchema).min(1).max(50),
|
|
45169
|
-
variables: array(ActionVariableSchema).max(20).optional()
|
|
45240
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
45241
|
+
minDelaySec: ActionMinDelaySecSchema.optional()
|
|
45170
45242
|
});
|
|
45171
45243
|
/** Who started a run. Absent = the operator pressed it. */
|
|
45172
45244
|
var ActionRunOriginSchema = object({
|
|
@@ -49326,14 +49398,14 @@ var climateControlCapability = {
|
|
|
49326
49398
|
kind: "mutation",
|
|
49327
49399
|
auth: "protected"
|
|
49328
49400
|
}),
|
|
49329
|
-
setFanMode:
|
|
49401
|
+
setFanMode: optionalMethod(object({
|
|
49330
49402
|
deviceId: number$1().int().nonnegative(),
|
|
49331
49403
|
fanMode: string().min(1)
|
|
49332
49404
|
}), _void(), {
|
|
49333
49405
|
kind: "mutation",
|
|
49334
49406
|
auth: "protected"
|
|
49335
49407
|
}),
|
|
49336
|
-
setPreset:
|
|
49408
|
+
setPreset: optionalMethod(object({
|
|
49337
49409
|
deviceId: number$1().int().nonnegative(),
|
|
49338
49410
|
preset: string().min(1)
|
|
49339
49411
|
}), _void(), {
|
|
@@ -49347,7 +49419,7 @@ var climateControlCapability = {
|
|
|
49347
49419
|
kind: "mutation",
|
|
49348
49420
|
auth: "protected"
|
|
49349
49421
|
}),
|
|
49350
|
-
setTargetRange:
|
|
49422
|
+
setTargetRange: optionalMethod(object({
|
|
49351
49423
|
deviceId: number$1().int().nonnegative(),
|
|
49352
49424
|
targetLow: number$1(),
|
|
49353
49425
|
targetHigh: number$1()
|
|
@@ -49355,21 +49427,21 @@ var climateControlCapability = {
|
|
|
49355
49427
|
kind: "mutation",
|
|
49356
49428
|
auth: "protected"
|
|
49357
49429
|
}),
|
|
49358
|
-
setTargetHumidity:
|
|
49430
|
+
setTargetHumidity: optionalMethod(object({
|
|
49359
49431
|
deviceId: number$1().int().nonnegative(),
|
|
49360
49432
|
targetHumidity: number$1().min(0).max(100)
|
|
49361
49433
|
}), _void(), {
|
|
49362
49434
|
kind: "mutation",
|
|
49363
49435
|
auth: "protected"
|
|
49364
49436
|
}),
|
|
49365
|
-
setSwingVertical:
|
|
49437
|
+
setSwingVertical: optionalMethod(object({
|
|
49366
49438
|
deviceId: number$1().int().nonnegative(),
|
|
49367
49439
|
on: boolean()
|
|
49368
49440
|
}), _void(), {
|
|
49369
49441
|
kind: "mutation",
|
|
49370
49442
|
auth: "protected"
|
|
49371
49443
|
}),
|
|
49372
|
-
setSwingHorizontal:
|
|
49444
|
+
setSwingHorizontal: optionalMethod(object({
|
|
49373
49445
|
deviceId: number$1().int().nonnegative(),
|
|
49374
49446
|
on: boolean()
|
|
49375
49447
|
}), _void(), {
|
|
@@ -50628,27 +50700,27 @@ var mediaPlayerCapability = {
|
|
|
50628
50700
|
mode: "singleton",
|
|
50629
50701
|
deviceTypes: [DeviceType.MediaPlayer],
|
|
50630
50702
|
methods: {
|
|
50631
|
-
turnOn:
|
|
50703
|
+
turnOn: optionalMethod(deviceOnly, _void(), {
|
|
50632
50704
|
kind: "mutation",
|
|
50633
50705
|
auth: "protected"
|
|
50634
50706
|
}),
|
|
50635
|
-
turnOff:
|
|
50707
|
+
turnOff: optionalMethod(deviceOnly, _void(), {
|
|
50636
50708
|
kind: "mutation",
|
|
50637
50709
|
auth: "protected"
|
|
50638
50710
|
}),
|
|
50639
|
-
volumeUp:
|
|
50711
|
+
volumeUp: optionalMethod(stepInput, _void(), {
|
|
50640
50712
|
kind: "mutation",
|
|
50641
50713
|
auth: "protected"
|
|
50642
50714
|
}),
|
|
50643
|
-
volumeDown:
|
|
50715
|
+
volumeDown: optionalMethod(stepInput, _void(), {
|
|
50644
50716
|
kind: "mutation",
|
|
50645
50717
|
auth: "protected"
|
|
50646
50718
|
}),
|
|
50647
|
-
channelUp:
|
|
50719
|
+
channelUp: optionalMethod(stepInput, _void(), {
|
|
50648
50720
|
kind: "mutation",
|
|
50649
50721
|
auth: "protected"
|
|
50650
50722
|
}),
|
|
50651
|
-
channelDown:
|
|
50723
|
+
channelDown: optionalMethod(stepInput, _void(), {
|
|
50652
50724
|
kind: "mutation",
|
|
50653
50725
|
auth: "protected"
|
|
50654
50726
|
}),
|
|
@@ -50660,61 +50732,61 @@ var mediaPlayerCapability = {
|
|
|
50660
50732
|
kind: "mutation",
|
|
50661
50733
|
auth: "protected"
|
|
50662
50734
|
}),
|
|
50663
|
-
stop:
|
|
50735
|
+
stop: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
50664
50736
|
kind: "mutation",
|
|
50665
50737
|
auth: "protected"
|
|
50666
50738
|
}),
|
|
50667
|
-
next:
|
|
50739
|
+
next: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
50668
50740
|
kind: "mutation",
|
|
50669
50741
|
auth: "protected"
|
|
50670
50742
|
}),
|
|
50671
|
-
previous:
|
|
50743
|
+
previous: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
50672
50744
|
kind: "mutation",
|
|
50673
50745
|
auth: "protected"
|
|
50674
50746
|
}),
|
|
50675
|
-
seek:
|
|
50747
|
+
seek: optionalMethod(object({
|
|
50676
50748
|
deviceId: number$1().int().nonnegative(),
|
|
50677
50749
|
position: number$1().int().nonnegative()
|
|
50678
50750
|
}), _void(), {
|
|
50679
50751
|
kind: "mutation",
|
|
50680
50752
|
auth: "protected"
|
|
50681
50753
|
}),
|
|
50682
|
-
setVolume:
|
|
50754
|
+
setVolume: optionalMethod(object({
|
|
50683
50755
|
deviceId: number$1().int().nonnegative(),
|
|
50684
50756
|
volumeLevel: number$1().min(0).max(100)
|
|
50685
50757
|
}), _void(), {
|
|
50686
50758
|
kind: "mutation",
|
|
50687
50759
|
auth: "protected"
|
|
50688
50760
|
}),
|
|
50689
|
-
setMute:
|
|
50761
|
+
setMute: optionalMethod(object({
|
|
50690
50762
|
deviceId: number$1().int().nonnegative(),
|
|
50691
50763
|
muted: boolean()
|
|
50692
50764
|
}), _void(), {
|
|
50693
50765
|
kind: "mutation",
|
|
50694
50766
|
auth: "protected"
|
|
50695
50767
|
}),
|
|
50696
|
-
setShuffle:
|
|
50768
|
+
setShuffle: optionalMethod(object({
|
|
50697
50769
|
deviceId: number$1().int().nonnegative(),
|
|
50698
50770
|
shuffle: boolean()
|
|
50699
50771
|
}), _void(), {
|
|
50700
50772
|
kind: "mutation",
|
|
50701
50773
|
auth: "protected"
|
|
50702
50774
|
}),
|
|
50703
|
-
setRepeat:
|
|
50775
|
+
setRepeat: optionalMethod(object({
|
|
50704
50776
|
deviceId: number$1().int().nonnegative(),
|
|
50705
50777
|
repeat: MediaPlayerRepeatSchema
|
|
50706
50778
|
}), _void(), {
|
|
50707
50779
|
kind: "mutation",
|
|
50708
50780
|
auth: "protected"
|
|
50709
50781
|
}),
|
|
50710
|
-
selectSource:
|
|
50782
|
+
selectSource: optionalMethod(object({
|
|
50711
50783
|
deviceId: number$1().int().nonnegative(),
|
|
50712
50784
|
source: string().min(1)
|
|
50713
50785
|
}), _void(), {
|
|
50714
50786
|
kind: "mutation",
|
|
50715
50787
|
auth: "protected"
|
|
50716
50788
|
}),
|
|
50717
|
-
playMedia:
|
|
50789
|
+
playMedia: optionalMethod(object({
|
|
50718
50790
|
deviceId: number$1().int().nonnegative(),
|
|
50719
50791
|
/** Media identifier / URL. */
|
|
50720
50792
|
mediaId: string().min(1),
|
|
@@ -51736,18 +51808,18 @@ var coverCapability = {
|
|
|
51736
51808
|
kind: "mutation",
|
|
51737
51809
|
auth: "protected"
|
|
51738
51810
|
}),
|
|
51739
|
-
stop:
|
|
51811
|
+
stop: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
51740
51812
|
kind: "mutation",
|
|
51741
51813
|
auth: "protected"
|
|
51742
51814
|
}),
|
|
51743
|
-
setPosition:
|
|
51815
|
+
setPosition: optionalMethod(object({
|
|
51744
51816
|
deviceId: number$1().int().nonnegative(),
|
|
51745
51817
|
position: number$1().min(0).max(100)
|
|
51746
51818
|
}), _void(), {
|
|
51747
51819
|
kind: "mutation",
|
|
51748
51820
|
auth: "protected"
|
|
51749
51821
|
}),
|
|
51750
|
-
setTiltPosition:
|
|
51822
|
+
setTiltPosition: optionalMethod(object({
|
|
51751
51823
|
deviceId: number$1().int().nonnegative(),
|
|
51752
51824
|
tiltPosition: number$1().min(0).max(100)
|
|
51753
51825
|
}), _void(), {
|
|
@@ -52777,6 +52849,22 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
52777
52849
|
});
|
|
52778
52850
|
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
52779
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
|
+
});
|
|
52780
52868
|
var DeviceTemplateRefusalSchema = object({
|
|
52781
52869
|
reason: _enum([
|
|
52782
52870
|
"too-long",
|
|
@@ -53408,7 +53496,9 @@ var DeviceBindingsForDeviceSchema = object({
|
|
|
53408
53496
|
kind: _enum(["native", "wrapped"]),
|
|
53409
53497
|
providerAddonId: string(),
|
|
53410
53498
|
providerNodeId: string(),
|
|
53411
|
-
nativeAddonId: string()
|
|
53499
|
+
nativeAddonId: string(),
|
|
53500
|
+
/** The cap's methods the native provider implements; absent = all. */
|
|
53501
|
+
implementedMethods: array(string()).optional()
|
|
53412
53502
|
}))
|
|
53413
53503
|
});
|
|
53414
53504
|
/**
|
|
@@ -53620,7 +53710,13 @@ method(object({
|
|
|
53620
53710
|
auth: "admin"
|
|
53621
53711
|
}), method(object({ deviceId: number$1() }), record(string(), unknown()), { auth: "admin" }), method(object({ deviceId: number$1() }), record(string(), unknown()), { auth: "admin" }), method(object({ deviceId: number$1() }), DeviceMetaSchema.nullable()), method(object({
|
|
53622
53712
|
deviceId: number$1(),
|
|
53623
|
-
name: string()
|
|
53713
|
+
name: string(),
|
|
53714
|
+
/**
|
|
53715
|
+
* Absent or true: an operator rename, which stamps `userNamed`.
|
|
53716
|
+
* False: the system copying a block name onto the device. That write
|
|
53717
|
+
* must not look like the operator's, or the next reconcile freezes it.
|
|
53718
|
+
*/
|
|
53719
|
+
stampUserNamed: boolean().optional()
|
|
53624
53720
|
}), _void(), {
|
|
53625
53721
|
kind: "mutation",
|
|
53626
53722
|
auth: "admin"
|
|
@@ -53645,17 +53741,24 @@ method(object({
|
|
|
53645
53741
|
auth: "admin"
|
|
53646
53742
|
}), method(object({
|
|
53647
53743
|
templates: array(DeviceTemplateSchema).max(64),
|
|
53648
|
-
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()
|
|
53649
53747
|
}), object({ results: array(DeviceTemplateRenderSchema) }), { auth: "admin" }), method(object({
|
|
53650
53748
|
templates: array(string()).max(64),
|
|
53651
|
-
allowedDeviceIds: array(number$1().int()).optional()
|
|
53749
|
+
allowedDeviceIds: array(number$1().int()).optional(),
|
|
53750
|
+
thisDevice: DeviceTemplateThisDeviceSchema.optional()
|
|
53652
53751
|
}), object({ results: array(discriminatedUnion("ok", [object({
|
|
53653
53752
|
ok: literal(true),
|
|
53654
53753
|
aliases: array(object({
|
|
53655
53754
|
alias: string(),
|
|
53656
53755
|
deviceId: number$1().int().nullable(),
|
|
53657
|
-
allowed: boolean()
|
|
53658
|
-
|
|
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()
|
|
53659
53762
|
}), object({
|
|
53660
53763
|
ok: literal(false),
|
|
53661
53764
|
refusal: DeviceTemplateRefusalSchema
|
|
@@ -56377,28 +56480,28 @@ var fanControlCapability = {
|
|
|
56377
56480
|
mode: "singleton",
|
|
56378
56481
|
deviceTypes: [DeviceType.Fan],
|
|
56379
56482
|
methods: {
|
|
56380
|
-
setPercentage:
|
|
56483
|
+
setPercentage: optionalMethod(object({
|
|
56381
56484
|
deviceId: number$1().int().nonnegative(),
|
|
56382
56485
|
speed: number$1().min(0).max(100)
|
|
56383
56486
|
}), _void(), {
|
|
56384
56487
|
kind: "mutation",
|
|
56385
56488
|
auth: "protected"
|
|
56386
56489
|
}),
|
|
56387
|
-
setPreset:
|
|
56490
|
+
setPreset: optionalMethod(object({
|
|
56388
56491
|
deviceId: number$1().int().nonnegative(),
|
|
56389
56492
|
preset: string().min(1)
|
|
56390
56493
|
}), _void(), {
|
|
56391
56494
|
kind: "mutation",
|
|
56392
56495
|
auth: "protected"
|
|
56393
56496
|
}),
|
|
56394
|
-
setDirection:
|
|
56497
|
+
setDirection: optionalMethod(object({
|
|
56395
56498
|
deviceId: number$1().int().nonnegative(),
|
|
56396
56499
|
direction: FanDirectionSchema
|
|
56397
56500
|
}), _void(), {
|
|
56398
56501
|
kind: "mutation",
|
|
56399
56502
|
auth: "protected"
|
|
56400
56503
|
}),
|
|
56401
|
-
setOscillating:
|
|
56504
|
+
setOscillating: optionalMethod(object({
|
|
56402
56505
|
deviceId: number$1().int().nonnegative(),
|
|
56403
56506
|
oscillating: boolean()
|
|
56404
56507
|
}), _void(), {
|
|
@@ -60503,7 +60606,7 @@ var lockControlCapability = {
|
|
|
60503
60606
|
kind: "mutation",
|
|
60504
60607
|
auth: "protected"
|
|
60505
60608
|
}),
|
|
60506
|
-
open:
|
|
60609
|
+
open: optionalMethod(object({ deviceId: number$1().int().nonnegative() }), _void(), {
|
|
60507
60610
|
kind: "mutation",
|
|
60508
60611
|
auth: "protected"
|
|
60509
60612
|
})
|
|
@@ -61700,7 +61803,7 @@ object({
|
|
|
61700
61803
|
deviceId: number$1().int().optional(),
|
|
61701
61804
|
atBefore: number$1().optional(),
|
|
61702
61805
|
where: RecordWhereSchema.optional()
|
|
61703
|
-
}), 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({
|
|
61704
61807
|
ref: string().min(1),
|
|
61705
61808
|
value: string()
|
|
61706
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({
|
|
@@ -61711,7 +61814,7 @@ object({
|
|
|
61711
61814
|
integrationId: string().nullable(),
|
|
61712
61815
|
/** Whether the device carries any stored config; its content is not offered. */
|
|
61713
61816
|
hasConfig: boolean()
|
|
61714
|
-
}).nullable(), object({
|
|
61817
|
+
}).nullable(), object({ deviceIds: array(number$1().int()) }), object({ aliases: record(string(), string()) }), object({
|
|
61715
61818
|
deviceId: number$1().int(),
|
|
61716
61819
|
integrationId: string().min(1)
|
|
61717
61820
|
}), object({}), object({}), object({ nodeId: string() }), object({}), object({});
|
|
@@ -68989,92 +69092,21 @@ var NcZoneConditionSchema = object({
|
|
|
68989
69092
|
* membership lists are OR within the list (spec §2.3).
|
|
68990
69093
|
*/
|
|
68991
69094
|
/**
|
|
68992
|
-
* What a rule
|
|
68993
|
-
*
|
|
68994
|
-
* **No hand-maintained allowlist** (operator decision, and the right one — a
|
|
68995
|
-
* written list of methods is a third parallel map to keep aligned, and this
|
|
68996
|
-
* repo has paid for those). The boundary instead comes from a property the
|
|
68997
|
-
* capabilities already carry: an action may target only a **device-scoped**
|
|
68998
|
-
* capability method.
|
|
68999
|
-
*
|
|
69000
|
-
* That is not decoration. A rule can be authored by a NON-ADMIN — personal
|
|
69001
|
-
* rules are a supported flow — and the executor runs with the addon's
|
|
69002
|
-
* privileges, so an unbounded action is an arbitrary RPC channel with a
|
|
69003
|
-
* privilege escalation attached. Restricting to device scope excludes the
|
|
69004
|
-
* system caps (`device-manager.removeDevice` and friends) by construction,
|
|
69005
|
-
* costs nothing to maintain, and cannot rot: a cap that stops being
|
|
69006
|
-
* device-scoped stops being actuatable in the same change.
|
|
69007
|
-
*
|
|
69008
|
-
* The executor enforces it; {@link NcRuleActionSchema} carries the intent.
|
|
69009
|
-
*/
|
|
69010
|
-
/**
|
|
69011
|
-
* 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).
|
|
69012
69097
|
*
|
|
69013
|
-
*
|
|
69014
|
-
*
|
|
69015
|
-
*
|
|
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.
|
|
69016
69104
|
*/
|
|
69017
|
-
var
|
|
69018
|
-
|
|
69019
|
-
|
|
69020
|
-
}), object({
|
|
69021
|
-
kind: literal("cap"),
|
|
69022
|
-
/**
|
|
69023
|
-
* WHO the step acts on (D983) — the only shape that is written. A sequence
|
|
69024
|
-
* stored before D983 carries `deviceId`; the sequence store reads it as a
|
|
69025
|
-
* `devices` target.
|
|
69026
|
-
*/
|
|
69027
|
-
target: ActionTargetSchema.optional(),
|
|
69028
|
-
/** The vocabulary action the step performs; required for a `domain` target. */
|
|
69029
|
-
actionId: string().min(1).optional(),
|
|
69030
|
-
/** @deprecated The pre-D983 single device. Read, never written. */
|
|
69031
|
-
deviceId: number$1().int().optional(),
|
|
69032
|
-
/** Capability name, e.g. `alarm-panel`. */
|
|
69033
|
-
cap: string().min(1),
|
|
69034
|
-
/** Method on it. The executor refuses a non-device-scoped cap. */
|
|
69035
|
-
method: string().min(1),
|
|
69036
|
-
/** Method arguments, minus `deviceId` (the executor injects it). */
|
|
69037
|
-
args: record(string(), unknown()).optional()
|
|
69038
|
-
}).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
69039
|
-
message: "a cap step needs a target",
|
|
69040
|
-
path: ["target"]
|
|
69041
|
-
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
69042
|
-
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
69043
|
-
path: ["actionId"]
|
|
69044
|
-
})]);
|
|
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);
|
|
69045
69108
|
/**
|
|
69046
|
-
*
|
|
69047
|
-
*
|
|
69048
|
-
* Sequences live in the notification centre's sequence store — never inline on
|
|
69049
|
-
* a rule. A rule binds to one by id ({@link NcActionBindingSchema}), and a
|
|
69050
|
-
* button names one the same way. `minDelaySec` exists because a noisy rule
|
|
69051
|
-
* otherwise hammers a physical actuator — the rule's own cooldown governs
|
|
69052
|
-
* NOTIFICATIONS, which is a different budget from "how often may this gate
|
|
69053
|
-
* actually open". The throttle key is the sequence id, so two rules sharing
|
|
69054
|
-
* one sequence share its budget.
|
|
69055
|
-
*/
|
|
69056
|
-
var NcSharedSequenceSchema = object({
|
|
69057
|
-
id: string().min(1),
|
|
69058
|
-
name: string().min(1).max(120),
|
|
69059
|
-
minDelaySec: number$1().int().min(0).max(86400).optional(),
|
|
69060
|
-
actions: array(NcRuleActionSchema).min(1)
|
|
69061
|
-
});
|
|
69062
|
-
/** Create / update body — the id is minted by the provider. */
|
|
69063
|
-
var NcSharedSequenceInputSchema = object({
|
|
69064
|
-
name: string().min(1).max(120),
|
|
69065
|
-
minDelaySec: number$1().int().min(0).max(86400).optional(),
|
|
69066
|
-
actions: array(NcRuleActionSchema).min(1)
|
|
69067
|
-
});
|
|
69068
|
-
/** Bindings on one hook edge. Cap keeps a slot from becoming a second sequence editor. */
|
|
69069
|
-
var NcHookBindingsSchema = array(discriminatedUnion("kind", [object({
|
|
69070
|
-
kind: literal("sequence"),
|
|
69071
|
-
sequenceId: string().min(1)
|
|
69072
|
-
}), object({
|
|
69073
|
-
kind: literal("do"),
|
|
69074
|
-
action: NcRuleActionSchema
|
|
69075
|
-
})])).max(4);
|
|
69076
|
-
/**
|
|
69077
|
-
* One button carried by the notification, running a shared sequence on tap.
|
|
69109
|
+
* One button carried by the notification, running an Action on tap.
|
|
69078
69110
|
*
|
|
69079
69111
|
* **Read this before adding a button that does something physical.** The tap
|
|
69080
69112
|
* arrives over a link that travelled through third-party infrastructure — ntfy,
|
|
@@ -69089,9 +69121,9 @@ var NcRuleNotificationButtonSchema = object({
|
|
|
69089
69121
|
/** Stable id — travels in the callback and identifies the button in logs. */
|
|
69090
69122
|
id: string().min(1).max(64),
|
|
69091
69123
|
label: string().min(1).max(40),
|
|
69092
|
-
/**
|
|
69093
|
-
*
|
|
69094
|
-
|
|
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,
|
|
69095
69127
|
icon: NotificationActionIconSchema.optional(),
|
|
69096
69128
|
destructive: boolean().optional()
|
|
69097
69129
|
});
|
|
@@ -69106,25 +69138,19 @@ var NcRuleNotificationButtonSchema = object({
|
|
|
69106
69138
|
* leave). A delivery with no clear edge never produces this hook.
|
|
69107
69139
|
*/
|
|
69108
69140
|
var NcRuleActionsSchema = object({
|
|
69109
|
-
onActivation:
|
|
69110
|
-
onDeactivation:
|
|
69141
|
+
onActivation: NcHookActionIdsSchema.optional(),
|
|
69142
|
+
onDeactivation: NcHookActionIdsSchema.optional(),
|
|
69111
69143
|
/** Runs on a positive / raised match. */
|
|
69112
|
-
onTrigger:
|
|
69144
|
+
onTrigger: NcHookActionIdsSchema.optional(),
|
|
69113
69145
|
/** Runs on a clear / leave match, when the subject carries one. */
|
|
69114
|
-
onTriggerOff:
|
|
69146
|
+
onTriggerOff: NcHookActionIdsSchema.optional(),
|
|
69115
69147
|
/**
|
|
69116
|
-
* Buttons the NOTIFICATION carries, each running one
|
|
69117
|
-
*
|
|
69118
|
-
*
|
|
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.
|
|
69119
69151
|
*/
|
|
69120
69152
|
buttons: array(NcRuleNotificationButtonSchema).max(8).optional()
|
|
69121
69153
|
});
|
|
69122
|
-
object({
|
|
69123
|
-
name: string().min(1).max(120),
|
|
69124
|
-
enabled: boolean(),
|
|
69125
|
-
minDelaySec: number$1().int().min(0).max(86400).optional(),
|
|
69126
|
-
actions: array(NcRuleActionSchema).min(1)
|
|
69127
|
-
});
|
|
69128
69154
|
/**
|
|
69129
69155
|
* "This rule applies only while `deviceId` is in one of `states`."
|
|
69130
69156
|
*
|
|
@@ -69423,6 +69449,16 @@ var NcRuleTargetSchema = object({
|
|
|
69423
69449
|
*/
|
|
69424
69450
|
params: record(string(), unknown()).optional()
|
|
69425
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);
|
|
69426
69462
|
/**
|
|
69427
69463
|
* WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
|
|
69428
69464
|
*
|
|
@@ -69704,6 +69740,13 @@ var NcRuleInputSchema = object({
|
|
|
69704
69740
|
* targets.
|
|
69705
69741
|
*/
|
|
69706
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(),
|
|
69707
69750
|
/** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
|
|
69708
69751
|
* detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
|
|
69709
69752
|
media: NcMediaPolicySchema.default({}),
|
|
@@ -70805,18 +70848,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
70805
70848
|
}), object({ success: literal(true) }), {
|
|
70806
70849
|
kind: "mutation",
|
|
70807
70850
|
auth: "admin"
|
|
70808
|
-
}), 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 }), {
|
|
70809
|
-
kind: "mutation",
|
|
70810
|
-
auth: "admin"
|
|
70811
|
-
}), method(object({
|
|
70812
|
-
sequenceId: string().min(1),
|
|
70813
|
-
sequence: NcSharedSequenceInputSchema
|
|
70814
|
-
}), object({ sequence: NcSharedSequenceSchema }), {
|
|
70815
|
-
kind: "mutation",
|
|
70816
|
-
auth: "admin"
|
|
70817
|
-
}), method(object({ sequenceId: string().min(1) }), object({ success: literal(true) }), {
|
|
70818
|
-
kind: "mutation",
|
|
70819
|
-
auth: "admin"
|
|
70820
70851
|
}), method(object({}), NcClipRetentionPlanSchema, { auth: "admin" }), method(object({}), object({ mutedDeviceIds: array(number$1().int()).readonly() }), { auth: "admin" }), method(object({
|
|
70821
70852
|
deviceId: number$1().int(),
|
|
70822
70853
|
muted: boolean()
|
|
@@ -71255,53 +71286,41 @@ DeviceType.Camera, method(object({
|
|
|
71255
71286
|
deviceId: number$1(),
|
|
71256
71287
|
status: OsdStatusSchema
|
|
71257
71288
|
});
|
|
71258
|
-
_enum([
|
|
71259
|
-
"value",
|
|
71260
|
-
"unit",
|
|
71261
|
-
"full"
|
|
71262
|
-
]);
|
|
71263
|
-
_enum([
|
|
71264
|
-
"value+unit",
|
|
71265
|
-
"value",
|
|
71266
|
-
"unit"
|
|
71267
|
-
]);
|
|
71268
71289
|
/**
|
|
71269
|
-
*
|
|
71270
|
-
*
|
|
71271
|
-
*
|
|
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).
|
|
71272
71301
|
*/
|
|
71273
|
-
var OsdTemplatePickSchema = object({
|
|
71274
|
-
containerId: number$1().int().optional(),
|
|
71275
|
-
deviceId: number$1().int()
|
|
71276
|
-
});
|
|
71277
71302
|
/**
|
|
71278
|
-
*
|
|
71279
|
-
*
|
|
71280
|
-
* `{
|
|
71281
|
-
*
|
|
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('')`).
|
|
71282
71314
|
*/
|
|
71283
|
-
var
|
|
71284
|
-
/** Token stem in the parser, e.g. `t` → `{t}` / `{t.value}`. Unique within the template. */
|
|
71285
|
-
alias: string().min(1).max(32).regex(/^[A-Za-z][A-Za-z0-9_-]*$/, "alias must start with a letter"),
|
|
71286
|
-
pick: OsdTemplatePickSchema,
|
|
71287
|
-
capName: string().min(1).max(64),
|
|
71288
|
-
valuePath: string().min(1).max(64),
|
|
71289
|
-
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
71290
|
-
displayUnit: string().max(16).optional(),
|
|
71291
|
-
maxDecimals: number$1().int().min(0).max(4).default(1),
|
|
71292
|
-
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
71293
|
-
valueMap: record(string(), string()).optional()
|
|
71294
|
-
});
|
|
71315
|
+
var OSD_TEMPLATE_TEXT_MAX = 1024;
|
|
71295
71316
|
/**
|
|
71296
|
-
* A named template:
|
|
71297
|
-
*
|
|
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.
|
|
71298
71319
|
*/
|
|
71299
71320
|
var OsdNamedTemplateSchema = object({
|
|
71300
71321
|
id: string().min(1).max(64),
|
|
71301
71322
|
name: string().min(1).max(64),
|
|
71302
|
-
|
|
71303
|
-
/** Parser with alias placeholders, e.g. `{t.value} {t.unit} / {h}`. */
|
|
71304
|
-
parser: string().max(256).default("")
|
|
71323
|
+
text: string().max(OSD_TEMPLATE_TEXT_MAX).default("")
|
|
71305
71324
|
});
|
|
71306
71325
|
/** Where a slot's value comes from. */
|
|
71307
71326
|
var OsdSourceSchema = discriminatedUnion("kind", [
|
|
@@ -71310,26 +71329,6 @@ var OsdSourceSchema = discriminatedUnion("kind", [
|
|
|
71310
71329
|
kind: literal("static"),
|
|
71311
71330
|
text: string().max(64)
|
|
71312
71331
|
}),
|
|
71313
|
-
object({
|
|
71314
|
-
kind: literal("clock"),
|
|
71315
|
-
/** Token pattern: `YYYY MM DD HH mm ss`. Everything else is literal. */
|
|
71316
|
-
pattern: string().min(1).max(32).default("HH:mm"),
|
|
71317
|
-
/** IANA zone. Omitted = the server's zone. */
|
|
71318
|
-
timezone: string().min(1).max(64).optional()
|
|
71319
|
-
}),
|
|
71320
|
-
object({
|
|
71321
|
-
kind: literal("device-state"),
|
|
71322
|
-
deviceId: number$1().int().optional(),
|
|
71323
|
-
capName: string().min(1).max(64),
|
|
71324
|
-
/** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
|
|
71325
|
-
valuePath: string().min(1).max(64),
|
|
71326
|
-
/** Convert TO this unit at render. Absent = no conversion. */
|
|
71327
|
-
displayUnit: string().max(16).optional()
|
|
71328
|
-
}),
|
|
71329
|
-
object({
|
|
71330
|
-
kind: literal("latest-recognition"),
|
|
71331
|
-
recognition: _enum(["person", "plate"])
|
|
71332
|
-
}),
|
|
71333
71332
|
object({
|
|
71334
71333
|
kind: literal("template"),
|
|
71335
71334
|
templateId: string().min(1).max(64)
|
|
@@ -71339,15 +71338,6 @@ var OsdSlotBindingSchema = object({
|
|
|
71339
71338
|
/** Off = the manager stops driving this slot. It does NOT clear it. */
|
|
71340
71339
|
enabled: boolean().default(true),
|
|
71341
71340
|
source: OsdSourceSchema,
|
|
71342
|
-
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
71343
|
-
template: string().max(96).default("${value}"),
|
|
71344
|
-
/**
|
|
71345
|
-
* Decimal places for a numeric value. `0` yields an integer — the
|
|
71346
|
-
* documented workaround for firmwares that reject `.` in overlay text.
|
|
71347
|
-
*/
|
|
71348
|
-
maxDecimals: number$1().int().min(0).max(4).default(1),
|
|
71349
|
-
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
71350
|
-
valueMap: record(string(), string()).optional(),
|
|
71351
71341
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
71352
71342
|
schedule: NcScheduleSchema.optional(),
|
|
71353
71343
|
/**
|
|
@@ -71389,31 +71379,21 @@ var OsdRenderResultSchema = object({
|
|
|
71389
71379
|
/** Why, whenever the outcome is not a plain write. Never silent. */
|
|
71390
71380
|
reason: string().optional()
|
|
71391
71381
|
});
|
|
71392
|
-
var OsdSourceValueTypeEnum = _enum([
|
|
71393
|
-
"number",
|
|
71394
|
-
"boolean",
|
|
71395
|
-
"string",
|
|
71396
|
-
"enum"
|
|
71397
|
-
]);
|
|
71398
71382
|
/**
|
|
71399
|
-
*
|
|
71400
|
-
*
|
|
71401
|
-
*
|
|
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.
|
|
71402
71386
|
*/
|
|
71403
|
-
var
|
|
71404
|
-
|
|
71405
|
-
|
|
71406
|
-
|
|
71407
|
-
|
|
71408
|
-
label: string(),
|
|
71409
|
-
valueType: OsdSourceValueTypeEnum,
|
|
71410
|
-
/** Present for `enum`; the editor offers these as `valueMap` keys. */
|
|
71411
|
-
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())
|
|
71412
71392
|
});
|
|
71413
71393
|
method(object({ deviceId: number$1().int() }), object({
|
|
71414
71394
|
supported: boolean(),
|
|
71415
71395
|
slots: array(OsdSlotViewSchema)
|
|
71416
|
-
}), { auth: "admin" }), method(object({
|
|
71396
|
+
}), { auth: "admin" }), method(object({}), object({
|
|
71417
71397
|
supported: array(string()),
|
|
71418
71398
|
catalog: array(NcConditionDescriptorSchema)
|
|
71419
71399
|
}), { auth: "admin" }), method(object({
|
|
@@ -71455,6 +71435,12 @@ method(object({ deviceId: number$1().int() }), object({
|
|
|
71455
71435
|
}), OsdRenderResultSchema, {
|
|
71456
71436
|
kind: "mutation",
|
|
71457
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"
|
|
71458
71444
|
}), method(object({ deviceId: number$1().int() }), object({ results: array(OsdRenderResultSchema) }), {
|
|
71459
71445
|
kind: "mutation",
|
|
71460
71446
|
auth: "admin"
|
|
@@ -81054,7 +81040,7 @@ var valveCapability = {
|
|
|
81054
81040
|
kind: "mutation",
|
|
81055
81041
|
auth: "protected"
|
|
81056
81042
|
}),
|
|
81057
|
-
setPosition:
|
|
81043
|
+
setPosition: optionalMethod(object({
|
|
81058
81044
|
deviceId: number$1().int().nonnegative(),
|
|
81059
81045
|
position: number$1().min(0).max(100)
|
|
81060
81046
|
}), _void(), {
|
|
@@ -84335,6 +84321,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
84335
84321
|
return toDeviceSummary(device, this.addonId);
|
|
84336
84322
|
}
|
|
84337
84323
|
};
|
|
84324
|
+
DeviceType.HeatPump;
|
|
84338
84325
|
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.HeatPump, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, 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;
|
|
84339
84326
|
new Set(Object.values(DeviceType));
|
|
84340
84327
|
/** Parses the raw slice with the cap's own schema; `undefined` when it does not parse. */
|
|
@@ -86081,7 +86068,7 @@ var CLIMATE_FAMILY_CONTRIBUTIONS = {
|
|
|
86081
86068
|
/**
|
|
86082
86069
|
* The heat pump's contribution to a hero (D1026): the compressor scene, every
|
|
86083
86070
|
* circuit as a row with its own label and icon, the powers as pills (the
|
|
86084
|
-
* instantaneous COP
|
|
86071
|
+
* instantaneous COP is "—" when it cannot be computed) and a "System" group with
|
|
86085
86072
|
* one selector per mode. Values and their limits come from the slice, which the
|
|
86086
86073
|
* gateway filled: a selector with no allowed value is not drawn, a missing
|
|
86087
86074
|
* reading is never a 0 (D393).
|
|
@@ -86153,9 +86140,22 @@ function circuitRow(circuit) {
|
|
|
86153
86140
|
};
|
|
86154
86141
|
}
|
|
86155
86142
|
var kilowatts = (watts) => `${Number((watts / 1e3).toFixed(2))} kW`;
|
|
86143
|
+
/** A COP that cannot be computed is still the pill: "—", never an absent reading (D393). */
|
|
86144
|
+
function copPill(cop) {
|
|
86145
|
+
if (cop === null) return {
|
|
86146
|
+
icon: "gauge",
|
|
86147
|
+
text: t("Instantaneous COP —", "COP istantaneo —"),
|
|
86148
|
+
tone: "muted"
|
|
86149
|
+
};
|
|
86150
|
+
const text = String(Number(cop.toFixed(1)));
|
|
86151
|
+
return {
|
|
86152
|
+
icon: "gauge",
|
|
86153
|
+
text: t(`Instantaneous COP ${text}`, `COP istantaneo ${text}`),
|
|
86154
|
+
tone: "success"
|
|
86155
|
+
};
|
|
86156
|
+
}
|
|
86156
86157
|
function powerPills(status) {
|
|
86157
86158
|
const { thermalW, electricalW } = status.power;
|
|
86158
|
-
const cop = heatPumpInstantCop(status.power);
|
|
86159
86159
|
const pills = [];
|
|
86160
86160
|
if (thermalW !== null) pills.push({
|
|
86161
86161
|
icon: "flame",
|
|
@@ -86167,14 +86167,7 @@ function powerPills(status) {
|
|
|
86167
86167
|
text: t(`Electrical ${kilowatts(electricalW)}`, `Elettrica ${kilowatts(electricalW)}`),
|
|
86168
86168
|
tone: "muted"
|
|
86169
86169
|
});
|
|
86170
|
-
|
|
86171
|
-
const text = String(Number(cop.toFixed(1)));
|
|
86172
|
-
pills.push({
|
|
86173
|
-
icon: "gauge",
|
|
86174
|
-
text: t(`Instantaneous COP ${text}`, `COP istantaneo ${text}`),
|
|
86175
|
-
tone: "success"
|
|
86176
|
-
});
|
|
86177
|
-
}
|
|
86170
|
+
pills.push(copPill(heatPumpInstantCop(status.power)));
|
|
86178
86171
|
return pills;
|
|
86179
86172
|
}
|
|
86180
86173
|
/** The independent system modes, in the order the card draws them. */
|
|
@@ -92352,13 +92345,6 @@ Object.freeze({
|
|
|
92352
92345
|
access: "create",
|
|
92353
92346
|
role: "admin"
|
|
92354
92347
|
},
|
|
92355
|
-
"notificationRules.createSequence": {
|
|
92356
|
-
capName: "notification-rules",
|
|
92357
|
-
capScope: "system",
|
|
92358
|
-
addonId: null,
|
|
92359
|
-
access: "create",
|
|
92360
|
-
role: "admin"
|
|
92361
|
-
},
|
|
92362
92348
|
"notificationRules.createSnooze": {
|
|
92363
92349
|
capName: "notification-rules",
|
|
92364
92350
|
capScope: "system",
|
|
@@ -92380,13 +92366,6 @@ Object.freeze({
|
|
|
92380
92366
|
access: "delete",
|
|
92381
92367
|
role: "admin"
|
|
92382
92368
|
},
|
|
92383
|
-
"notificationRules.deleteSequence": {
|
|
92384
|
-
capName: "notification-rules",
|
|
92385
|
-
capScope: "system",
|
|
92386
|
-
addonId: null,
|
|
92387
|
-
access: "delete",
|
|
92388
|
-
role: "admin"
|
|
92389
|
-
},
|
|
92390
92369
|
"notificationRules.getAlarmConfig": {
|
|
92391
92370
|
capName: "notification-rules",
|
|
92392
92371
|
capScope: "system",
|
|
@@ -92436,13 +92415,6 @@ Object.freeze({
|
|
|
92436
92415
|
access: "view",
|
|
92437
92416
|
role: "admin"
|
|
92438
92417
|
},
|
|
92439
|
-
"notificationRules.getSequence": {
|
|
92440
|
-
capName: "notification-rules",
|
|
92441
|
-
capScope: "system",
|
|
92442
|
-
addonId: null,
|
|
92443
|
-
access: "view",
|
|
92444
|
-
role: "admin"
|
|
92445
|
-
},
|
|
92446
92418
|
"notificationRules.getTemplateCatalog": {
|
|
92447
92419
|
capName: "notification-rules",
|
|
92448
92420
|
capScope: "system",
|
|
@@ -92464,13 +92436,6 @@ Object.freeze({
|
|
|
92464
92436
|
access: "view",
|
|
92465
92437
|
role: "admin"
|
|
92466
92438
|
},
|
|
92467
|
-
"notificationRules.listSequences": {
|
|
92468
|
-
capName: "notification-rules",
|
|
92469
|
-
capScope: "system",
|
|
92470
|
-
addonId: null,
|
|
92471
|
-
access: "view",
|
|
92472
|
-
role: "admin"
|
|
92473
|
-
},
|
|
92474
92439
|
"notificationRules.listSnoozes": {
|
|
92475
92440
|
capName: "notification-rules",
|
|
92476
92441
|
capScope: "system",
|
|
@@ -92541,13 +92506,6 @@ Object.freeze({
|
|
|
92541
92506
|
access: "create",
|
|
92542
92507
|
role: "admin"
|
|
92543
92508
|
},
|
|
92544
|
-
"notificationRules.updateSequence": {
|
|
92545
|
-
capName: "notification-rules",
|
|
92546
|
-
capScope: "system",
|
|
92547
|
-
addonId: null,
|
|
92548
|
-
access: "create",
|
|
92549
|
-
role: "admin"
|
|
92550
|
-
},
|
|
92551
92509
|
"notifier.cancel": {
|
|
92552
92510
|
capName: "notifier",
|
|
92553
92511
|
capScope: "device",
|
|
@@ -92632,21 +92590,21 @@ Object.freeze({
|
|
|
92632
92590
|
access: "view",
|
|
92633
92591
|
role: "admin"
|
|
92634
92592
|
},
|
|
92635
|
-
"osdManager.
|
|
92593
|
+
"osdManager.listTemplates": {
|
|
92636
92594
|
capName: "osd-manager",
|
|
92637
92595
|
capScope: "system",
|
|
92638
92596
|
addonId: null,
|
|
92639
92597
|
access: "view",
|
|
92640
92598
|
role: "admin"
|
|
92641
92599
|
},
|
|
92642
|
-
"osdManager.
|
|
92600
|
+
"osdManager.previewSlot": {
|
|
92643
92601
|
capName: "osd-manager",
|
|
92644
92602
|
capScope: "system",
|
|
92645
92603
|
addonId: null,
|
|
92646
|
-
access: "
|
|
92604
|
+
access: "create",
|
|
92647
92605
|
role: "admin"
|
|
92648
92606
|
},
|
|
92649
|
-
"osdManager.
|
|
92607
|
+
"osdManager.previewTemplate": {
|
|
92650
92608
|
capName: "osd-manager",
|
|
92651
92609
|
capScope: "system",
|
|
92652
92610
|
addonId: null,
|
|
@@ -97436,6 +97394,24 @@ function projectAction(cap, action) {
|
|
|
97436
97394
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
97437
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;
|
|
97438
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);
|
|
97439
97415
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
97440
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.";
|
|
97441
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.";
|
|
@@ -99091,12 +99067,12 @@ Object.freeze({
|
|
|
99091
99067
|
form: "single",
|
|
99092
99068
|
optional: false
|
|
99093
99069
|
}],
|
|
99094
|
-
"osdManager.
|
|
99070
|
+
"osdManager.previewSlot": [{
|
|
99095
99071
|
name: "deviceId",
|
|
99096
99072
|
form: "single",
|
|
99097
99073
|
optional: false
|
|
99098
99074
|
}],
|
|
99099
|
-
"osdManager.
|
|
99075
|
+
"osdManager.previewTemplate": [{
|
|
99100
99076
|
name: "deviceId",
|
|
99101
99077
|
form: "single",
|
|
99102
99078
|
optional: false
|