@camstack/addon-model-studio 1.1.316 → 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.
- package/CHANGELOG.md +12 -0
- package/dist/{MotionZonesSettings-CMwAQd-Y.mjs → MotionZonesSettings-DNN9QEA3.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-wx9DyDgK.mjs → PrivacyMaskSettings-CwE32Qhm.mjs} +4 -4
- package/dist/{SceneMonitorEditor-jDNxVNGw.mjs → SceneMonitorEditor-SNXiXvXt.mjs} +3 -3
- package/dist/_stub.js +1647 -1583
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-P5JTQUjR.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BaMcMPS8.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D_KssOQn.mjs +26 -0
- package/dist/addon-model-studio.css +1 -1
- package/dist/{hostInit-DXaNbFAa.mjs → hostInit-C6xHvsEb.mjs} +2 -2
- package/dist/model-studio.addon.js +484 -10
- package/dist/model-studio.addon.mjs +484 -10
- package/dist/{player-overlays-B0MiJ5R6.mjs → player-overlays-BmZ_qrdR.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-BHzVDMt-.mjs → responsive-Dypi_Y-V.mjs} +1 -1
- package/dist/{scene-monitor-copy-CBNkkNvs.mjs → scene-monitor-copy-Bafz9ZMd.mjs} +1 -1
- package/dist/{square-SIMvtgyo.mjs → square-BhfFFjT7.mjs} +1 -1
- package/dist/{trash-2-CTpwDufe.mjs → trash-2-BAyfEZwH.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-D6DfHBUW.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DyWlwmuC.mjs} +1 -1
- package/package.json +1 -1
- 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.
|
|
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.
|
|
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-
|
|
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": [
|
|
@@ -16811,9 +16830,21 @@ var AlertSeveritySchema = _enum([
|
|
|
16811
16830
|
"error",
|
|
16812
16831
|
"critical"
|
|
16813
16832
|
]);
|
|
16833
|
+
/**
|
|
16834
|
+
* An action that RUNS something instead of going somewhere: the admin UI calls
|
|
16835
|
+
* the addon's custom action (`addons.custom`) with exactly these fields. The
|
|
16836
|
+
* producer owns the meaning; the UI knows nothing about the addon or the kind.
|
|
16837
|
+
*/
|
|
16838
|
+
var AlertActionInvokeSchema = object({
|
|
16839
|
+
addonId: string().min(1),
|
|
16840
|
+
action: string().min(1),
|
|
16841
|
+
input: record(string(), unknown()).optional()
|
|
16842
|
+
});
|
|
16843
|
+
/** An action has `href` (a link) OR `invoke` (a button that runs a custom action). */
|
|
16814
16844
|
var AlertActionSchema = object({
|
|
16815
16845
|
label: string(),
|
|
16816
16846
|
href: string().optional(),
|
|
16847
|
+
invoke: AlertActionInvokeSchema.optional(),
|
|
16817
16848
|
/**
|
|
16818
16849
|
* How `href` is followed. Absent / `app`: an admin-ui route (client-side).
|
|
16819
16850
|
* `server`: a route the HUB serves (an addon HTTP route such as an OAuth
|
|
@@ -57998,6 +58029,318 @@ DeviceType.Light, method(object({
|
|
|
57998
58029
|
level: number().min(0).max(100),
|
|
57999
58030
|
lastChangedAt: number()
|
|
58000
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
|
+
});
|
|
58001
58344
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
58002
58345
|
kind: "mutation",
|
|
58003
58346
|
auth: "protected"
|
|
@@ -60747,9 +61090,35 @@ var MediaInfoSchema = object({
|
|
|
60747
61090
|
/** Optional cover-art / thumbnail URL. */
|
|
60748
61091
|
imageUrl: string().optional()
|
|
60749
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
|
+
]);
|
|
60750
61108
|
object({
|
|
60751
61109
|
/** Playback lifecycle state. */
|
|
60752
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([]),
|
|
60753
61122
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
60754
61123
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
60755
61124
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -62190,6 +62559,14 @@ object({
|
|
|
62190
62559
|
feedSound: boolean(),
|
|
62191
62560
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
62192
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(),
|
|
62193
62570
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
62194
62571
|
lastFetchedAt: number()
|
|
62195
62572
|
});
|
|
@@ -66831,9 +67208,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
66831
67208
|
kind: "mutation",
|
|
66832
67209
|
auth: "admin"
|
|
66833
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
|
+
})]);
|
|
66834
67219
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
66835
67220
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
66836
|
-
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;
|
|
66837
67222
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
66838
67223
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
66839
67224
|
new Set(CAP_NAMES);
|
|
@@ -74673,6 +75058,41 @@ Object.freeze({
|
|
|
74673
75058
|
access: "create",
|
|
74674
75059
|
role: "admin"
|
|
74675
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
|
+
},
|
|
74676
75096
|
"runningState.getStatus": {
|
|
74677
75097
|
capName: "running-state",
|
|
74678
75098
|
capScope: "device",
|
|
@@ -75863,6 +76283,41 @@ Object.freeze({
|
|
|
75863
76283
|
access: "view",
|
|
75864
76284
|
role: "viewer"
|
|
75865
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
|
+
},
|
|
75866
76321
|
"terminalSession.adoptLegacyMonitor": {
|
|
75867
76322
|
capName: "terminal-session",
|
|
75868
76323
|
capScope: "system",
|
|
@@ -80694,6 +81149,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80694
81149
|
"recording-archive": system(STORAGE),
|
|
80695
81150
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
80696
81151
|
records: system(INTERNAL),
|
|
81152
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
80697
81153
|
"server-management": system(CLUSTER),
|
|
80698
81154
|
"settings-store": system(INTERNAL),
|
|
80699
81155
|
"smtp-provider": system(INTERNAL),
|
|
@@ -80706,6 +81162,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80706
81162
|
"storage-provider": system(STORAGE),
|
|
80707
81163
|
"stream-broker": system(PIPELINE),
|
|
80708
81164
|
system: system(CLUSTER),
|
|
81165
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
80709
81166
|
"terminal-session": system(CLUSTER),
|
|
80710
81167
|
toast: system(UI_PLUMBING),
|
|
80711
81168
|
training: system(ML),
|
|
@@ -83132,6 +83589,31 @@ Object.freeze({
|
|
|
83132
83589
|
form: "single",
|
|
83133
83590
|
optional: true
|
|
83134
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
|
+
}],
|
|
83135
83617
|
"runningState.getStatus": [{
|
|
83136
83618
|
name: "deviceId",
|
|
83137
83619
|
form: "single",
|
|
@@ -84940,14 +85422,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
84940
85422
|
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
84941
85423
|
var MB = 1024 * 1024;
|
|
84942
85424
|
1024 * MB, 3072 * MB;
|
|
84943
|
-
discriminatedUnion("kind", [object({
|
|
84944
|
-
kind: literal("raw"),
|
|
84945
|
-
timings: array(number().int()),
|
|
84946
|
-
settings: TransmitSettingsSchema.optional()
|
|
84947
|
-
}), object({
|
|
84948
|
-
kind: literal("pronto"),
|
|
84949
|
-
code: string()
|
|
84950
|
-
})]);
|
|
84951
85425
|
object({
|
|
84952
85426
|
manufacturer: string().optional(),
|
|
84953
85427
|
supportedModels: array(string()).optional(),
|