@camstack/addon-model-studio 1.1.317 → 1.1.318

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.
Files changed (20) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{MotionZonesSettings-CMwAQd-Y.mjs → MotionZonesSettings-DNN9QEA3.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-wx9DyDgK.mjs → PrivacyMaskSettings-CwE32Qhm.mjs} +4 -4
  4. package/dist/{SceneMonitorEditor-jDNxVNGw.mjs → SceneMonitorEditor-SNXiXvXt.mjs} +3 -3
  5. package/dist/_stub.js +1647 -1583
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CsVbgmDJ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BaMcMPS8.mjs} +3 -3
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D_KssOQn.mjs +26 -0
  8. package/dist/addon-model-studio.css +1 -1
  9. package/dist/{hostInit-l8UwwnTV.mjs → hostInit-C6xHvsEb.mjs} +2 -2
  10. package/dist/model-studio.addon.js +472 -10
  11. package/dist/model-studio.addon.mjs +472 -10
  12. package/dist/{player-overlays-B0MiJ5R6.mjs → player-overlays-BmZ_qrdR.mjs} +1 -1
  13. package/dist/remoteEntry.js +1 -1
  14. package/dist/{responsive-BHzVDMt-.mjs → responsive-Dypi_Y-V.mjs} +1 -1
  15. package/dist/{scene-monitor-copy-CBNkkNvs.mjs → scene-monitor-copy-Bafz9ZMd.mjs} +1 -1
  16. package/dist/{square-SIMvtgyo.mjs → square-BhfFFjT7.mjs} +1 -1
  17. package/dist/{trash-2-CTpwDufe.mjs → trash-2-BAyfEZwH.mjs} +1 -1
  18. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CkwPjS5o.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DyWlwmuC.mjs} +1 -1
  19. package/package.json +1 -1
  20. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cxz43vtF.mjs +0 -26
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.440",
39
+ version: "1.2.441",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -81,7 +81,7 @@ async function r() {
81
81
  }
82
82
  },
83
83
  "@camstack/ui-library": {
84
- version: "1.2.347",
84
+ version: "1.2.348",
85
85
  scope: "default",
86
86
  shareConfig: {
87
87
  singleton: !0,
@@ -5842,7 +5842,7 @@ var ZodIssueCode = {
5842
5842
  var ZodFirstPartyTypeKind;
5843
5843
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5844
5844
  //#endregion
5845
- //#region ../types/dist/sleep-BAvUCi_2.mjs
5845
+ //#region ../types/dist/sleep-DJws6ho7.mjs
5846
5846
  /**
5847
5847
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5848
5848
  * window to float samples (D455).
@@ -9116,6 +9116,7 @@ var CAP_NAMES = Object.freeze([
9116
9116
  "recording-onboard",
9117
9117
  "recording-signal",
9118
9118
  "records",
9119
+ "remote",
9119
9120
  "running-state",
9120
9121
  "scene-monitor",
9121
9122
  "script-runner",
@@ -9139,6 +9140,7 @@ var CAP_NAMES = Object.freeze([
9139
9140
  "system",
9140
9141
  "tamper",
9141
9142
  "temperature-sensor",
9143
+ "template",
9142
9144
  "terminal-session",
9143
9145
  "toast",
9144
9146
  "training",
@@ -10079,6 +10081,11 @@ Object.freeze({
10079
10081
  "standby"
10080
10082
  ]
10081
10083
  },
10084
+ {
10085
+ "path": "stateSource",
10086
+ "valueType": "enum",
10087
+ "enumValues": ["reported", "assumed"]
10088
+ },
10082
10089
  {
10083
10090
  "path": "volumeLevel",
10084
10091
  "valueType": "number"
@@ -10354,6 +10361,18 @@ Object.freeze({
10354
10361
  {
10355
10362
  "path": "volume",
10356
10363
  "valueType": "number"
10364
+ },
10365
+ {
10366
+ "path": "lastFeedGrams",
10367
+ "valueType": "number"
10368
+ },
10369
+ {
10370
+ "path": "lastFeedHopper1",
10371
+ "valueType": "number"
10372
+ },
10373
+ {
10374
+ "path": "lastFeedHopper2",
10375
+ "valueType": "number"
10357
10376
  }
10358
10377
  ],
10359
10378
  "power-meter": [
@@ -58010,6 +58029,318 @@ DeviceType.Light, method(object({
58010
58029
  level: number().min(0).max(100),
58011
58030
  lastChangedAt: number()
58012
58031
  });
58032
+ /**
58033
+ * The role vocabulary of a remote (D963): what a button MEANS, independent of
58034
+ * how it is wired. A layout template places buttons by role; a device binds a
58035
+ * role to an action; an exporter asks for a role by name. Roles are shared so
58036
+ * one layout fits every appliance and one voice command fits every binding.
58037
+ *
58038
+ * A role outside this list is `custom:<key>` — the operator's own button (a
58039
+ * SmartIR source, a channel preset). The key is a lowercase slug.
58040
+ */
58041
+ var REMOTE_KNOWN_ROLES = [
58042
+ "power",
58043
+ "power_on",
58044
+ "power_off",
58045
+ "volume_up",
58046
+ "volume_down",
58047
+ "mute",
58048
+ "channel_up",
58049
+ "channel_down",
58050
+ "up",
58051
+ "down",
58052
+ "left",
58053
+ "right",
58054
+ "ok",
58055
+ "back",
58056
+ "home",
58057
+ "menu",
58058
+ "info",
58059
+ "guide",
58060
+ "exit",
58061
+ "input",
58062
+ "play",
58063
+ "pause",
58064
+ "play_pause",
58065
+ "stop",
58066
+ "next",
58067
+ "previous",
58068
+ "fast_forward",
58069
+ "rewind",
58070
+ "digit_0",
58071
+ "digit_1",
58072
+ "digit_2",
58073
+ "digit_3",
58074
+ "digit_4",
58075
+ "digit_5",
58076
+ "digit_6",
58077
+ "digit_7",
58078
+ "digit_8",
58079
+ "digit_9"
58080
+ ];
58081
+ var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
58082
+ var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
58083
+ function isRemoteKnownRole(value) {
58084
+ return KNOWN_ROLES.has(value);
58085
+ }
58086
+ function isRemoteCustomKey(key) {
58087
+ return CUSTOM_KEY_RE.test(key);
58088
+ }
58089
+ /** The key of a `custom:<key>` role, or null for any other string. */
58090
+ function customKeyOfRole(role) {
58091
+ if (!role.startsWith("custom:")) return null;
58092
+ const key = role.slice(7);
58093
+ return isRemoteCustomKey(key) ? key : null;
58094
+ }
58095
+ function isRemoteRole(value) {
58096
+ return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
58097
+ }
58098
+ var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
58099
+ var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
58100
+ var RemoteCustomButtonSchema = object({
58101
+ /** The slug after `custom:` in the role. */
58102
+ key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
58103
+ /** What the operator calls it, and what a voice command may name. */
58104
+ name: string().min(1).max(60)
58105
+ });
58106
+ var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
58107
+ var RemoteConfigSchema = object({
58108
+ layoutTemplateId: string().min(1).nullable(),
58109
+ /**
58110
+ * The transmitter device new bindings and an import send through. A binding
58111
+ * names its own device, so one command may override it.
58112
+ */
58113
+ defaultTransmitterId: number().int().nonnegative().nullable().default(null),
58114
+ /** Keyed by role. A role with no entry falls back to the native cap. */
58115
+ bindings: record(string(), RemoteBindingSchema),
58116
+ customButtons: array(RemoteCustomButtonSchema).max(100),
58117
+ power: object({ mode: RemotePowerModeSchema })
58118
+ }).superRefine((config, ctx) => {
58119
+ const roles = Object.keys(config.bindings);
58120
+ if (roles.length > 200) ctx.addIssue({
58121
+ code: "custom",
58122
+ message: "too many bindings",
58123
+ path: ["bindings"]
58124
+ });
58125
+ for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
58126
+ code: "custom",
58127
+ message: `"${role}" is not a role`,
58128
+ path: ["bindings", role]
58129
+ });
58130
+ const keys = /* @__PURE__ */ new Set();
58131
+ config.customButtons.forEach((button, index) => {
58132
+ if (keys.has(button.key)) ctx.addIssue({
58133
+ code: "custom",
58134
+ message: `custom button "${button.key}" is listed twice`,
58135
+ path: [
58136
+ "customButtons",
58137
+ index,
58138
+ "key"
58139
+ ]
58140
+ });
58141
+ keys.add(button.key);
58142
+ });
58143
+ for (const role of roles) {
58144
+ const key = customKeyOfRole(role);
58145
+ if (key !== null && !keys.has(key)) ctx.addIssue({
58146
+ code: "custom",
58147
+ message: `${role} is bound but has no entry in customButtons`,
58148
+ path: ["bindings", role]
58149
+ });
58150
+ }
58151
+ });
58152
+ object({
58153
+ power: object({
58154
+ state: _enum(["on", "off"]),
58155
+ at: number()
58156
+ }).nullable(),
58157
+ muted: object({
58158
+ value: boolean(),
58159
+ at: number()
58160
+ }).nullable()
58161
+ });
58162
+ var RemoteLayoutButtonSchema = object({
58163
+ id: string().min(1).max(40),
58164
+ /** 0-based grid position. */
58165
+ row: number().int().min(0).max(24),
58166
+ col: number().int().min(0).max(24),
58167
+ rowSpan: number().int().min(1).max(24),
58168
+ colSpan: number().int().min(1).max(24),
58169
+ icon: string().min(1).max(60).optional(),
58170
+ label: string().min(1).max(40).optional(),
58171
+ role: RemoteRoleSchema
58172
+ });
58173
+ object({
58174
+ columns: number().int().min(1).max(24),
58175
+ rows: number().int().min(1).max(24),
58176
+ buttons: array(RemoteLayoutButtonSchema).max(200)
58177
+ }).superRefine((grid, ctx) => {
58178
+ const ids = /* @__PURE__ */ new Set();
58179
+ const taken = /* @__PURE__ */ new Map();
58180
+ grid.buttons.forEach((button, index) => {
58181
+ if (ids.has(button.id)) ctx.addIssue({
58182
+ code: "custom",
58183
+ message: `button id "${button.id}" is used twice`,
58184
+ path: [
58185
+ "buttons",
58186
+ index,
58187
+ "id"
58188
+ ]
58189
+ });
58190
+ ids.add(button.id);
58191
+ if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
58192
+ ctx.addIssue({
58193
+ code: "custom",
58194
+ message: `button "${button.id}" leaves the grid`,
58195
+ path: ["buttons", index]
58196
+ });
58197
+ return;
58198
+ }
58199
+ for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
58200
+ const cell = `${r}:${c}`;
58201
+ const other = taken.get(cell);
58202
+ if (other !== void 0) {
58203
+ ctx.addIssue({
58204
+ code: "custom",
58205
+ message: `buttons "${other}" and "${button.id}" overlap`,
58206
+ path: ["buttons", index]
58207
+ });
58208
+ return;
58209
+ }
58210
+ taken.set(cell, button.id);
58211
+ }
58212
+ });
58213
+ });
58214
+ var RemoteBoundCommandSchema = object({
58215
+ role: RemoteRoleSchema,
58216
+ /** The operator's name for a custom button; absent for a known role. */
58217
+ label: string().optional(),
58218
+ custom: boolean()
58219
+ });
58220
+ var RemoteCommandListSchema = object({
58221
+ layoutTemplateId: string().nullable(),
58222
+ power: object({ mode: RemotePowerModeSchema }),
58223
+ /** Only the roles that are BOUND — the ones a press can reach. */
58224
+ commands: array(RemoteBoundCommandSchema)
58225
+ });
58226
+ var RemoteRefusalReasonSchema = _enum([
58227
+ "no-remote",
58228
+ "unbound-role",
58229
+ "action-failed"
58230
+ ]);
58231
+ var RemoteSendResultSchema = discriminatedUnion("status", [
58232
+ object({
58233
+ status: literal("sent"),
58234
+ /** How many times the action ran. */
58235
+ sends: number().int().min(1)
58236
+ }),
58237
+ object({
58238
+ status: literal("skipped"),
58239
+ reason: literal("already-in-state")
58240
+ }),
58241
+ object({
58242
+ status: literal("refused"),
58243
+ reason: RemoteRefusalReasonSchema,
58244
+ detail: string().optional()
58245
+ })
58246
+ ]);
58247
+ var RemoteMediaCommandSchema = _enum([
58248
+ "play",
58249
+ "pause",
58250
+ "stop",
58251
+ "next",
58252
+ "previous",
58253
+ "setMute",
58254
+ "selectSource"
58255
+ ]);
58256
+ /** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
58257
+ var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
58258
+ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
58259
+ status: literal("refused"),
58260
+ reason: _enum(["unknown-template", "not-a-media-player"]),
58261
+ detail: string()
58262
+ })]);
58263
+ var deviceInput = object({ deviceId: number().int().nonnegative() });
58264
+ DeviceType.MediaPlayer;
58265
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
58266
+ kind: "mutation",
58267
+ auth: "admin"
58268
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
58269
+ role: RemoteRoleSchema,
58270
+ /** Sends in a row (volume steps). */
58271
+ repeat: number().int().min(1).max(50).default(1)
58272
+ }), RemoteSendResultSchema, {
58273
+ kind: "mutation",
58274
+ auth: "protected"
58275
+ }), method(deviceInput.extend({
58276
+ command: RemoteMediaCommandSchema,
58277
+ muted: boolean().optional(),
58278
+ source: string().optional(),
58279
+ repeat: number().int().min(1).max(50).default(1)
58280
+ }), RemoteMediaCommandResultSchema, {
58281
+ kind: "mutation",
58282
+ auth: "protected"
58283
+ });
58284
+ var TemplateKindSchema = _enum(["remote"]);
58285
+ /**
58286
+ * template — the generic store of reusable, named operator data (D963). A
58287
+ * record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
58288
+ * button grid of a remote) and the schema each payload must satisfy are
58289
+ * declared by the system in `template-kinds.ts`. Nothing here is specific to a
58290
+ * kind: the engine validates a payload against its kind's schema and, on a
58291
+ * delete, asks the kind's owner whether anything still points at the record.
58292
+ *
58293
+ * Every refusal is a typed result — a UI says "unknown kind" or names the
58294
+ * devices that still use a template, without parsing text.
58295
+ */
58296
+ var TemplateRecordSchema = object({
58297
+ id: string().min(1),
58298
+ kind: TemplateKindSchema,
58299
+ name: string().min(1).max(120),
58300
+ /** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
58301
+ payload: unknown(),
58302
+ createdAt: number(),
58303
+ updatedAt: number()
58304
+ });
58305
+ var TemplateWriteResultSchema = discriminatedUnion("status", [object({
58306
+ status: literal("saved"),
58307
+ template: TemplateRecordSchema
58308
+ }), object({
58309
+ status: literal("refused"),
58310
+ reason: _enum(["invalid-payload", "not-found"]),
58311
+ detail: string()
58312
+ })]);
58313
+ /** A device still pointing at a template. */
58314
+ var TemplateUserSchema = object({
58315
+ deviceId: number().int().nonnegative(),
58316
+ name: string()
58317
+ });
58318
+ var TemplateDeleteResultSchema = discriminatedUnion("status", [
58319
+ object({ status: literal("deleted") }),
58320
+ object({ status: literal("not-found") }),
58321
+ object({
58322
+ status: literal("in-use"),
58323
+ devices: array(TemplateUserSchema).min(1)
58324
+ })
58325
+ ]);
58326
+ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
58327
+ kind: TemplateKindSchema,
58328
+ name: string().min(1).max(120),
58329
+ payload: unknown()
58330
+ }), TemplateWriteResultSchema, {
58331
+ kind: "mutation",
58332
+ auth: "admin"
58333
+ }), method(object({
58334
+ id: string().min(1),
58335
+ name: string().min(1).max(120).optional(),
58336
+ payload: unknown().optional()
58337
+ }), TemplateWriteResultSchema, {
58338
+ kind: "mutation",
58339
+ auth: "admin"
58340
+ }), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
58341
+ kind: "mutation",
58342
+ auth: "admin"
58343
+ });
58013
58344
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
58014
58345
  kind: "mutation",
58015
58346
  auth: "protected"
@@ -60759,9 +61090,35 @@ var MediaInfoSchema = object({
60759
61090
  /** Optional cover-art / thumbnail URL. */
60760
61091
  imageUrl: string().optional()
60761
61092
  });
61093
+ /**
61094
+ * Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
61095
+ * the device said so. `assumed`: the driver has no feedback (infrared) and
61096
+ * tracks what it last SENT; it moves only after a send was accepted, and a
61097
+ * human at the real remote makes it wrong. A UI shows an assumed value as a
61098
+ * guess, never as a reading.
61099
+ */
61100
+ var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
61101
+ /** The fields of a media-player status a driver can only guess. */
61102
+ var MediaPlayerAssumedFieldSchema = _enum([
61103
+ "state",
61104
+ "volumeLevel",
61105
+ "isMuted",
61106
+ "source"
61107
+ ]);
60762
61108
  object({
60763
61109
  /** Playback lifecycle state. */
60764
61110
  state: MediaPlayerStateSchema,
61111
+ /**
61112
+ * Whether the state fields are readings or the driver's own bookkeeping.
61113
+ * A slice written before this field existed parses as `reported`.
61114
+ */
61115
+ stateSource: MediaPlayerStateSourceSchema.default("reported"),
61116
+ /**
61117
+ * Which fields are the driver's own guess. `stateSource` is `assumed` when
61118
+ * this is not empty; a field not listed here is a reading even then (power
61119
+ * from a running-state source, mute guessed from the last send).
61120
+ */
61121
+ assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
60765
61122
  /** Volume as 0..100 inclusive. Null when the device has no volume
60766
61123
  * surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
60767
61124
  volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
@@ -62202,6 +62559,14 @@ object({
62202
62559
  feedSound: boolean(),
62203
62560
  /** Speaker / prompt volume level (device-scaled integer). */
62204
62561
  volume: number().meta(readingMeta("none")),
62562
+ /** Portion (grams) of the last manual feed sent from a single-hopper
62563
+ * stepper — the default the next manual feed starts from. Persisted per
62564
+ * device by the provider; null until a manual feed has been sent. */
62565
+ lastFeedGrams: gramsPortion.nullable(),
62566
+ /** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
62567
+ lastFeedHopper1: gramsPortion.nullable(),
62568
+ /** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
62569
+ lastFeedHopper2: gramsPortion.nullable(),
62205
62570
  /** Ms epoch when the slice was last refreshed from the cloud. */
62206
62571
  lastFetchedAt: number()
62207
62572
  });
@@ -66843,9 +67208,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
66843
67208
  kind: "mutation",
66844
67209
  auth: "admin"
66845
67210
  });
67211
+ discriminatedUnion("kind", [object({
67212
+ kind: literal("raw"),
67213
+ timings: array(number().int()),
67214
+ settings: TransmitSettingsSchema.optional()
67215
+ }), object({
67216
+ kind: literal("pronto"),
67217
+ code: string()
67218
+ })]);
66846
67219
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
66847
67220
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
66848
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
67221
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
66849
67222
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
66850
67223
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
66851
67224
  new Set(CAP_NAMES);
@@ -74685,6 +75058,41 @@ Object.freeze({
74685
75058
  access: "create",
74686
75059
  role: "admin"
74687
75060
  },
75061
+ "remote.getConfig": {
75062
+ capName: "remote",
75063
+ capScope: "system",
75064
+ addonId: null,
75065
+ access: "view",
75066
+ role: "admin"
75067
+ },
75068
+ "remote.listCommands": {
75069
+ capName: "remote",
75070
+ capScope: "system",
75071
+ addonId: null,
75072
+ access: "view",
75073
+ role: "admin"
75074
+ },
75075
+ "remote.sendCommand": {
75076
+ capName: "remote",
75077
+ capScope: "system",
75078
+ addonId: null,
75079
+ access: "create",
75080
+ role: "admin"
75081
+ },
75082
+ "remote.sendMediaCommand": {
75083
+ capName: "remote",
75084
+ capScope: "system",
75085
+ addonId: null,
75086
+ access: "create",
75087
+ role: "admin"
75088
+ },
75089
+ "remote.setConfig": {
75090
+ capName: "remote",
75091
+ capScope: "system",
75092
+ addonId: null,
75093
+ access: "create",
75094
+ role: "admin"
75095
+ },
74688
75096
  "runningState.getStatus": {
74689
75097
  capName: "running-state",
74690
75098
  capScope: "device",
@@ -75875,6 +76283,41 @@ Object.freeze({
75875
76283
  access: "view",
75876
76284
  role: "viewer"
75877
76285
  },
76286
+ "template.create": {
76287
+ capName: "template",
76288
+ capScope: "system",
76289
+ addonId: null,
76290
+ access: "create",
76291
+ role: "admin"
76292
+ },
76293
+ "template.delete": {
76294
+ capName: "template",
76295
+ capScope: "system",
76296
+ addonId: null,
76297
+ access: "delete",
76298
+ role: "admin"
76299
+ },
76300
+ "template.get": {
76301
+ capName: "template",
76302
+ capScope: "system",
76303
+ addonId: null,
76304
+ access: "view",
76305
+ role: "admin"
76306
+ },
76307
+ "template.list": {
76308
+ capName: "template",
76309
+ capScope: "system",
76310
+ addonId: null,
76311
+ access: "view",
76312
+ role: "admin"
76313
+ },
76314
+ "template.update": {
76315
+ capName: "template",
76316
+ capScope: "system",
76317
+ addonId: null,
76318
+ access: "create",
76319
+ role: "admin"
76320
+ },
75878
76321
  "terminalSession.adoptLegacyMonitor": {
75879
76322
  capName: "terminal-session",
75880
76323
  capScope: "system",
@@ -80706,6 +81149,7 @@ var SYSTEM_CAP_VOCABULARY = {
80706
81149
  "recording-archive": system(STORAGE),
80707
81150
  "recording-export": system("recording exports — requested from the timeline, not an automation step"),
80708
81151
  records: system(INTERNAL),
81152
+ remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
80709
81153
  "server-management": system(CLUSTER),
80710
81154
  "settings-store": system(INTERNAL),
80711
81155
  "smtp-provider": system(INTERNAL),
@@ -80718,6 +81162,7 @@ var SYSTEM_CAP_VOCABULARY = {
80718
81162
  "storage-provider": system(STORAGE),
80719
81163
  "stream-broker": system(PIPELINE),
80720
81164
  system: system(CLUSTER),
81165
+ template: system("operator-authored templates — edited in their own editor, never actuated"),
80721
81166
  "terminal-session": system(CLUSTER),
80722
81167
  toast: system(UI_PLUMBING),
80723
81168
  training: system(ML),
@@ -83144,6 +83589,31 @@ Object.freeze({
83144
83589
  form: "single",
83145
83590
  optional: true
83146
83591
  }],
83592
+ "remote.getConfig": [{
83593
+ name: "deviceId",
83594
+ form: "single",
83595
+ optional: false
83596
+ }],
83597
+ "remote.listCommands": [{
83598
+ name: "deviceId",
83599
+ form: "single",
83600
+ optional: false
83601
+ }],
83602
+ "remote.sendCommand": [{
83603
+ name: "deviceId",
83604
+ form: "single",
83605
+ optional: false
83606
+ }],
83607
+ "remote.sendMediaCommand": [{
83608
+ name: "deviceId",
83609
+ form: "single",
83610
+ optional: false
83611
+ }],
83612
+ "remote.setConfig": [{
83613
+ name: "deviceId",
83614
+ form: "single",
83615
+ optional: false
83616
+ }],
83147
83617
  "runningState.getStatus": [{
83148
83618
  name: "deviceId",
83149
83619
  form: "single",
@@ -84952,14 +85422,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
84952
85422
  String.raw`(?<=^|["'(\s>,\[{])`;
84953
85423
  var MB = 1024 * 1024;
84954
85424
  1024 * MB, 3072 * MB;
84955
- discriminatedUnion("kind", [object({
84956
- kind: literal("raw"),
84957
- timings: array(number().int()),
84958
- settings: TransmitSettingsSchema.optional()
84959
- }), object({
84960
- kind: literal("pronto"),
84961
- code: string()
84962
- })]);
84963
85425
  object({
84964
85426
  manufacturer: string().optional(),
84965
85427
  supportedModels: array(string()).optional(),