@camstack/addon-model-studio 1.1.317 → 1.1.319
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-Dc4Kv4_B.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-wx9DyDgK.mjs → PrivacyMaskSettings-QuXzMphU.mjs} +4 -4
- package/dist/{SceneMonitorEditor-jDNxVNGw.mjs → SceneMonitorEditor-DTMWWxoE.mjs} +3 -3
- package/dist/_stub.js +1649 -1585
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CsVbgmDJ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BEwAo6V7.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-COf25W99.mjs +26 -0
- package/dist/addon-model-studio.css +1 -1
- package/dist/{hostInit-l8UwwnTV.mjs → hostInit-C5q4H84T.mjs} +2 -2
- package/dist/model-studio.addon.js +490 -11
- package/dist/model-studio.addon.mjs +490 -11
- package/dist/{player-overlays-B0MiJ5R6.mjs → player-overlays-CGbBkJ3j.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-BHzVDMt-.mjs → responsive-Cw4YAdTr.mjs} +1 -1
- package/dist/{scene-monitor-copy-CBNkkNvs.mjs → scene-monitor-copy-Dz9xLx8-.mjs} +1 -1
- package/dist/{square-SIMvtgyo.mjs → square-Dyvwj3m5.mjs} +1 -1
- package/dist/{trash-2-CTpwDufe.mjs → trash-2-CPAMsWG5.mjs} +1 -1
- 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-DWDyoPcG.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.443",
|
|
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.349",
|
|
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-C_u6cEAJ.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).
|
|
@@ -9086,6 +9086,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9086
9086
|
"network-link",
|
|
9087
9087
|
"network-quality",
|
|
9088
9088
|
"node-certificates",
|
|
9089
|
+
"node-removal-hook",
|
|
9089
9090
|
"nodes",
|
|
9090
9091
|
"notification-output",
|
|
9091
9092
|
"notification-rules",
|
|
@@ -9116,6 +9117,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9116
9117
|
"recording-onboard",
|
|
9117
9118
|
"recording-signal",
|
|
9118
9119
|
"records",
|
|
9120
|
+
"remote",
|
|
9119
9121
|
"running-state",
|
|
9120
9122
|
"scene-monitor",
|
|
9121
9123
|
"script-runner",
|
|
@@ -9139,6 +9141,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9139
9141
|
"system",
|
|
9140
9142
|
"tamper",
|
|
9141
9143
|
"temperature-sensor",
|
|
9144
|
+
"template",
|
|
9142
9145
|
"terminal-session",
|
|
9143
9146
|
"toast",
|
|
9144
9147
|
"training",
|
|
@@ -10079,6 +10082,11 @@ Object.freeze({
|
|
|
10079
10082
|
"standby"
|
|
10080
10083
|
]
|
|
10081
10084
|
},
|
|
10085
|
+
{
|
|
10086
|
+
"path": "stateSource",
|
|
10087
|
+
"valueType": "enum",
|
|
10088
|
+
"enumValues": ["reported", "assumed"]
|
|
10089
|
+
},
|
|
10082
10090
|
{
|
|
10083
10091
|
"path": "volumeLevel",
|
|
10084
10092
|
"valueType": "number"
|
|
@@ -10354,6 +10362,18 @@ Object.freeze({
|
|
|
10354
10362
|
{
|
|
10355
10363
|
"path": "volume",
|
|
10356
10364
|
"valueType": "number"
|
|
10365
|
+
},
|
|
10366
|
+
{
|
|
10367
|
+
"path": "lastFeedGrams",
|
|
10368
|
+
"valueType": "number"
|
|
10369
|
+
},
|
|
10370
|
+
{
|
|
10371
|
+
"path": "lastFeedHopper1",
|
|
10372
|
+
"valueType": "number"
|
|
10373
|
+
},
|
|
10374
|
+
{
|
|
10375
|
+
"path": "lastFeedHopper2",
|
|
10376
|
+
"valueType": "number"
|
|
10357
10377
|
}
|
|
10358
10378
|
],
|
|
10359
10379
|
"power-meter": [
|
|
@@ -11245,7 +11265,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11245
11265
|
return DeviceRole;
|
|
11246
11266
|
}({});
|
|
11247
11267
|
//#endregion
|
|
11248
|
-
//#region ../types/dist/composition-
|
|
11268
|
+
//#region ../types/dist/composition-bIBW5_13.mjs
|
|
11249
11269
|
/**
|
|
11250
11270
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11251
11271
|
*
|
|
@@ -42992,6 +43012,14 @@ method(object({
|
|
|
42992
43012
|
kind: "mutation",
|
|
42993
43013
|
auth: "admin"
|
|
42994
43014
|
});
|
|
43015
|
+
method(object({
|
|
43016
|
+
nodeId: string().min(1),
|
|
43017
|
+
/** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
|
|
43018
|
+
removedAt: number()
|
|
43019
|
+
}), object({ counts: record(string(), number().int().nonnegative()) }), {
|
|
43020
|
+
kind: "mutation",
|
|
43021
|
+
auth: "admin"
|
|
43022
|
+
});
|
|
42995
43023
|
/**
|
|
42996
43024
|
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
42997
43025
|
* so it can delete what it keeps for that device (D865).
|
|
@@ -58010,6 +58038,318 @@ DeviceType.Light, method(object({
|
|
|
58010
58038
|
level: number().min(0).max(100),
|
|
58011
58039
|
lastChangedAt: number()
|
|
58012
58040
|
});
|
|
58041
|
+
/**
|
|
58042
|
+
* The role vocabulary of a remote (D963): what a button MEANS, independent of
|
|
58043
|
+
* how it is wired. A layout template places buttons by role; a device binds a
|
|
58044
|
+
* role to an action; an exporter asks for a role by name. Roles are shared so
|
|
58045
|
+
* one layout fits every appliance and one voice command fits every binding.
|
|
58046
|
+
*
|
|
58047
|
+
* A role outside this list is `custom:<key>` — the operator's own button (a
|
|
58048
|
+
* SmartIR source, a channel preset). The key is a lowercase slug.
|
|
58049
|
+
*/
|
|
58050
|
+
var REMOTE_KNOWN_ROLES = [
|
|
58051
|
+
"power",
|
|
58052
|
+
"power_on",
|
|
58053
|
+
"power_off",
|
|
58054
|
+
"volume_up",
|
|
58055
|
+
"volume_down",
|
|
58056
|
+
"mute",
|
|
58057
|
+
"channel_up",
|
|
58058
|
+
"channel_down",
|
|
58059
|
+
"up",
|
|
58060
|
+
"down",
|
|
58061
|
+
"left",
|
|
58062
|
+
"right",
|
|
58063
|
+
"ok",
|
|
58064
|
+
"back",
|
|
58065
|
+
"home",
|
|
58066
|
+
"menu",
|
|
58067
|
+
"info",
|
|
58068
|
+
"guide",
|
|
58069
|
+
"exit",
|
|
58070
|
+
"input",
|
|
58071
|
+
"play",
|
|
58072
|
+
"pause",
|
|
58073
|
+
"play_pause",
|
|
58074
|
+
"stop",
|
|
58075
|
+
"next",
|
|
58076
|
+
"previous",
|
|
58077
|
+
"fast_forward",
|
|
58078
|
+
"rewind",
|
|
58079
|
+
"digit_0",
|
|
58080
|
+
"digit_1",
|
|
58081
|
+
"digit_2",
|
|
58082
|
+
"digit_3",
|
|
58083
|
+
"digit_4",
|
|
58084
|
+
"digit_5",
|
|
58085
|
+
"digit_6",
|
|
58086
|
+
"digit_7",
|
|
58087
|
+
"digit_8",
|
|
58088
|
+
"digit_9"
|
|
58089
|
+
];
|
|
58090
|
+
var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
|
|
58091
|
+
var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
|
|
58092
|
+
function isRemoteKnownRole(value) {
|
|
58093
|
+
return KNOWN_ROLES.has(value);
|
|
58094
|
+
}
|
|
58095
|
+
function isRemoteCustomKey(key) {
|
|
58096
|
+
return CUSTOM_KEY_RE.test(key);
|
|
58097
|
+
}
|
|
58098
|
+
/** The key of a `custom:<key>` role, or null for any other string. */
|
|
58099
|
+
function customKeyOfRole(role) {
|
|
58100
|
+
if (!role.startsWith("custom:")) return null;
|
|
58101
|
+
const key = role.slice(7);
|
|
58102
|
+
return isRemoteCustomKey(key) ? key : null;
|
|
58103
|
+
}
|
|
58104
|
+
function isRemoteRole(value) {
|
|
58105
|
+
return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
|
|
58106
|
+
}
|
|
58107
|
+
var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
|
|
58108
|
+
var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
|
|
58109
|
+
var RemoteCustomButtonSchema = object({
|
|
58110
|
+
/** The slug after `custom:` in the role. */
|
|
58111
|
+
key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
|
|
58112
|
+
/** What the operator calls it, and what a voice command may name. */
|
|
58113
|
+
name: string().min(1).max(60)
|
|
58114
|
+
});
|
|
58115
|
+
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
58116
|
+
var RemoteConfigSchema = object({
|
|
58117
|
+
layoutTemplateId: string().min(1).nullable(),
|
|
58118
|
+
/**
|
|
58119
|
+
* The transmitter device new bindings and an import send through. A binding
|
|
58120
|
+
* names its own device, so one command may override it.
|
|
58121
|
+
*/
|
|
58122
|
+
defaultTransmitterId: number().int().nonnegative().nullable().default(null),
|
|
58123
|
+
/** Keyed by role. A role with no entry falls back to the native cap. */
|
|
58124
|
+
bindings: record(string(), RemoteBindingSchema),
|
|
58125
|
+
customButtons: array(RemoteCustomButtonSchema).max(100),
|
|
58126
|
+
power: object({ mode: RemotePowerModeSchema })
|
|
58127
|
+
}).superRefine((config, ctx) => {
|
|
58128
|
+
const roles = Object.keys(config.bindings);
|
|
58129
|
+
if (roles.length > 200) ctx.addIssue({
|
|
58130
|
+
code: "custom",
|
|
58131
|
+
message: "too many bindings",
|
|
58132
|
+
path: ["bindings"]
|
|
58133
|
+
});
|
|
58134
|
+
for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
|
|
58135
|
+
code: "custom",
|
|
58136
|
+
message: `"${role}" is not a role`,
|
|
58137
|
+
path: ["bindings", role]
|
|
58138
|
+
});
|
|
58139
|
+
const keys = /* @__PURE__ */ new Set();
|
|
58140
|
+
config.customButtons.forEach((button, index) => {
|
|
58141
|
+
if (keys.has(button.key)) ctx.addIssue({
|
|
58142
|
+
code: "custom",
|
|
58143
|
+
message: `custom button "${button.key}" is listed twice`,
|
|
58144
|
+
path: [
|
|
58145
|
+
"customButtons",
|
|
58146
|
+
index,
|
|
58147
|
+
"key"
|
|
58148
|
+
]
|
|
58149
|
+
});
|
|
58150
|
+
keys.add(button.key);
|
|
58151
|
+
});
|
|
58152
|
+
for (const role of roles) {
|
|
58153
|
+
const key = customKeyOfRole(role);
|
|
58154
|
+
if (key !== null && !keys.has(key)) ctx.addIssue({
|
|
58155
|
+
code: "custom",
|
|
58156
|
+
message: `${role} is bound but has no entry in customButtons`,
|
|
58157
|
+
path: ["bindings", role]
|
|
58158
|
+
});
|
|
58159
|
+
}
|
|
58160
|
+
});
|
|
58161
|
+
object({
|
|
58162
|
+
power: object({
|
|
58163
|
+
state: _enum(["on", "off"]),
|
|
58164
|
+
at: number()
|
|
58165
|
+
}).nullable(),
|
|
58166
|
+
muted: object({
|
|
58167
|
+
value: boolean(),
|
|
58168
|
+
at: number()
|
|
58169
|
+
}).nullable()
|
|
58170
|
+
});
|
|
58171
|
+
var RemoteLayoutButtonSchema = object({
|
|
58172
|
+
id: string().min(1).max(40),
|
|
58173
|
+
/** 0-based grid position. */
|
|
58174
|
+
row: number().int().min(0).max(24),
|
|
58175
|
+
col: number().int().min(0).max(24),
|
|
58176
|
+
rowSpan: number().int().min(1).max(24),
|
|
58177
|
+
colSpan: number().int().min(1).max(24),
|
|
58178
|
+
icon: string().min(1).max(60).optional(),
|
|
58179
|
+
label: string().min(1).max(40).optional(),
|
|
58180
|
+
role: RemoteRoleSchema
|
|
58181
|
+
});
|
|
58182
|
+
object({
|
|
58183
|
+
columns: number().int().min(1).max(24),
|
|
58184
|
+
rows: number().int().min(1).max(24),
|
|
58185
|
+
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
58186
|
+
}).superRefine((grid, ctx) => {
|
|
58187
|
+
const ids = /* @__PURE__ */ new Set();
|
|
58188
|
+
const taken = /* @__PURE__ */ new Map();
|
|
58189
|
+
grid.buttons.forEach((button, index) => {
|
|
58190
|
+
if (ids.has(button.id)) ctx.addIssue({
|
|
58191
|
+
code: "custom",
|
|
58192
|
+
message: `button id "${button.id}" is used twice`,
|
|
58193
|
+
path: [
|
|
58194
|
+
"buttons",
|
|
58195
|
+
index,
|
|
58196
|
+
"id"
|
|
58197
|
+
]
|
|
58198
|
+
});
|
|
58199
|
+
ids.add(button.id);
|
|
58200
|
+
if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
|
|
58201
|
+
ctx.addIssue({
|
|
58202
|
+
code: "custom",
|
|
58203
|
+
message: `button "${button.id}" leaves the grid`,
|
|
58204
|
+
path: ["buttons", index]
|
|
58205
|
+
});
|
|
58206
|
+
return;
|
|
58207
|
+
}
|
|
58208
|
+
for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
|
|
58209
|
+
const cell = `${r}:${c}`;
|
|
58210
|
+
const other = taken.get(cell);
|
|
58211
|
+
if (other !== void 0) {
|
|
58212
|
+
ctx.addIssue({
|
|
58213
|
+
code: "custom",
|
|
58214
|
+
message: `buttons "${other}" and "${button.id}" overlap`,
|
|
58215
|
+
path: ["buttons", index]
|
|
58216
|
+
});
|
|
58217
|
+
return;
|
|
58218
|
+
}
|
|
58219
|
+
taken.set(cell, button.id);
|
|
58220
|
+
}
|
|
58221
|
+
});
|
|
58222
|
+
});
|
|
58223
|
+
var RemoteBoundCommandSchema = object({
|
|
58224
|
+
role: RemoteRoleSchema,
|
|
58225
|
+
/** The operator's name for a custom button; absent for a known role. */
|
|
58226
|
+
label: string().optional(),
|
|
58227
|
+
custom: boolean()
|
|
58228
|
+
});
|
|
58229
|
+
var RemoteCommandListSchema = object({
|
|
58230
|
+
layoutTemplateId: string().nullable(),
|
|
58231
|
+
power: object({ mode: RemotePowerModeSchema }),
|
|
58232
|
+
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
58233
|
+
commands: array(RemoteBoundCommandSchema)
|
|
58234
|
+
});
|
|
58235
|
+
var RemoteRefusalReasonSchema = _enum([
|
|
58236
|
+
"no-remote",
|
|
58237
|
+
"unbound-role",
|
|
58238
|
+
"action-failed"
|
|
58239
|
+
]);
|
|
58240
|
+
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
58241
|
+
object({
|
|
58242
|
+
status: literal("sent"),
|
|
58243
|
+
/** How many times the action ran. */
|
|
58244
|
+
sends: number().int().min(1)
|
|
58245
|
+
}),
|
|
58246
|
+
object({
|
|
58247
|
+
status: literal("skipped"),
|
|
58248
|
+
reason: literal("already-in-state")
|
|
58249
|
+
}),
|
|
58250
|
+
object({
|
|
58251
|
+
status: literal("refused"),
|
|
58252
|
+
reason: RemoteRefusalReasonSchema,
|
|
58253
|
+
detail: string().optional()
|
|
58254
|
+
})
|
|
58255
|
+
]);
|
|
58256
|
+
var RemoteMediaCommandSchema = _enum([
|
|
58257
|
+
"play",
|
|
58258
|
+
"pause",
|
|
58259
|
+
"stop",
|
|
58260
|
+
"next",
|
|
58261
|
+
"previous",
|
|
58262
|
+
"setMute",
|
|
58263
|
+
"selectSource"
|
|
58264
|
+
]);
|
|
58265
|
+
/** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
|
|
58266
|
+
var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
|
|
58267
|
+
var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
|
|
58268
|
+
status: literal("refused"),
|
|
58269
|
+
reason: _enum(["unknown-template", "not-a-media-player"]),
|
|
58270
|
+
detail: string()
|
|
58271
|
+
})]);
|
|
58272
|
+
var deviceInput = object({ deviceId: number().int().nonnegative() });
|
|
58273
|
+
DeviceType.MediaPlayer;
|
|
58274
|
+
method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
|
|
58275
|
+
kind: "mutation",
|
|
58276
|
+
auth: "admin"
|
|
58277
|
+
}), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
|
|
58278
|
+
role: RemoteRoleSchema,
|
|
58279
|
+
/** Sends in a row (volume steps). */
|
|
58280
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
58281
|
+
}), RemoteSendResultSchema, {
|
|
58282
|
+
kind: "mutation",
|
|
58283
|
+
auth: "protected"
|
|
58284
|
+
}), method(deviceInput.extend({
|
|
58285
|
+
command: RemoteMediaCommandSchema,
|
|
58286
|
+
muted: boolean().optional(),
|
|
58287
|
+
source: string().optional(),
|
|
58288
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
58289
|
+
}), RemoteMediaCommandResultSchema, {
|
|
58290
|
+
kind: "mutation",
|
|
58291
|
+
auth: "protected"
|
|
58292
|
+
});
|
|
58293
|
+
var TemplateKindSchema = _enum(["remote"]);
|
|
58294
|
+
/**
|
|
58295
|
+
* template — the generic store of reusable, named operator data (D963). A
|
|
58296
|
+
* record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
|
|
58297
|
+
* button grid of a remote) and the schema each payload must satisfy are
|
|
58298
|
+
* declared by the system in `template-kinds.ts`. Nothing here is specific to a
|
|
58299
|
+
* kind: the engine validates a payload against its kind's schema and, on a
|
|
58300
|
+
* delete, asks the kind's owner whether anything still points at the record.
|
|
58301
|
+
*
|
|
58302
|
+
* Every refusal is a typed result — a UI says "unknown kind" or names the
|
|
58303
|
+
* devices that still use a template, without parsing text.
|
|
58304
|
+
*/
|
|
58305
|
+
var TemplateRecordSchema = object({
|
|
58306
|
+
id: string().min(1),
|
|
58307
|
+
kind: TemplateKindSchema,
|
|
58308
|
+
name: string().min(1).max(120),
|
|
58309
|
+
/** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
|
|
58310
|
+
payload: unknown(),
|
|
58311
|
+
createdAt: number(),
|
|
58312
|
+
updatedAt: number()
|
|
58313
|
+
});
|
|
58314
|
+
var TemplateWriteResultSchema = discriminatedUnion("status", [object({
|
|
58315
|
+
status: literal("saved"),
|
|
58316
|
+
template: TemplateRecordSchema
|
|
58317
|
+
}), object({
|
|
58318
|
+
status: literal("refused"),
|
|
58319
|
+
reason: _enum(["invalid-payload", "not-found"]),
|
|
58320
|
+
detail: string()
|
|
58321
|
+
})]);
|
|
58322
|
+
/** A device still pointing at a template. */
|
|
58323
|
+
var TemplateUserSchema = object({
|
|
58324
|
+
deviceId: number().int().nonnegative(),
|
|
58325
|
+
name: string()
|
|
58326
|
+
});
|
|
58327
|
+
var TemplateDeleteResultSchema = discriminatedUnion("status", [
|
|
58328
|
+
object({ status: literal("deleted") }),
|
|
58329
|
+
object({ status: literal("not-found") }),
|
|
58330
|
+
object({
|
|
58331
|
+
status: literal("in-use"),
|
|
58332
|
+
devices: array(TemplateUserSchema).min(1)
|
|
58333
|
+
})
|
|
58334
|
+
]);
|
|
58335
|
+
method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
|
|
58336
|
+
kind: TemplateKindSchema,
|
|
58337
|
+
name: string().min(1).max(120),
|
|
58338
|
+
payload: unknown()
|
|
58339
|
+
}), TemplateWriteResultSchema, {
|
|
58340
|
+
kind: "mutation",
|
|
58341
|
+
auth: "admin"
|
|
58342
|
+
}), method(object({
|
|
58343
|
+
id: string().min(1),
|
|
58344
|
+
name: string().min(1).max(120).optional(),
|
|
58345
|
+
payload: unknown().optional()
|
|
58346
|
+
}), TemplateWriteResultSchema, {
|
|
58347
|
+
kind: "mutation",
|
|
58348
|
+
auth: "admin"
|
|
58349
|
+
}), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
|
|
58350
|
+
kind: "mutation",
|
|
58351
|
+
auth: "admin"
|
|
58352
|
+
});
|
|
58013
58353
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
58014
58354
|
kind: "mutation",
|
|
58015
58355
|
auth: "protected"
|
|
@@ -60759,9 +61099,35 @@ var MediaInfoSchema = object({
|
|
|
60759
61099
|
/** Optional cover-art / thumbnail URL. */
|
|
60760
61100
|
imageUrl: string().optional()
|
|
60761
61101
|
});
|
|
61102
|
+
/**
|
|
61103
|
+
* Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
|
|
61104
|
+
* the device said so. `assumed`: the driver has no feedback (infrared) and
|
|
61105
|
+
* tracks what it last SENT; it moves only after a send was accepted, and a
|
|
61106
|
+
* human at the real remote makes it wrong. A UI shows an assumed value as a
|
|
61107
|
+
* guess, never as a reading.
|
|
61108
|
+
*/
|
|
61109
|
+
var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
|
|
61110
|
+
/** The fields of a media-player status a driver can only guess. */
|
|
61111
|
+
var MediaPlayerAssumedFieldSchema = _enum([
|
|
61112
|
+
"state",
|
|
61113
|
+
"volumeLevel",
|
|
61114
|
+
"isMuted",
|
|
61115
|
+
"source"
|
|
61116
|
+
]);
|
|
60762
61117
|
object({
|
|
60763
61118
|
/** Playback lifecycle state. */
|
|
60764
61119
|
state: MediaPlayerStateSchema,
|
|
61120
|
+
/**
|
|
61121
|
+
* Whether the state fields are readings or the driver's own bookkeeping.
|
|
61122
|
+
* A slice written before this field existed parses as `reported`.
|
|
61123
|
+
*/
|
|
61124
|
+
stateSource: MediaPlayerStateSourceSchema.default("reported"),
|
|
61125
|
+
/**
|
|
61126
|
+
* Which fields are the driver's own guess. `stateSource` is `assumed` when
|
|
61127
|
+
* this is not empty; a field not listed here is a reading even then (power
|
|
61128
|
+
* from a running-state source, mute guessed from the last send).
|
|
61129
|
+
*/
|
|
61130
|
+
assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
|
|
60765
61131
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
60766
61132
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
60767
61133
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -62202,6 +62568,14 @@ object({
|
|
|
62202
62568
|
feedSound: boolean(),
|
|
62203
62569
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
62204
62570
|
volume: number().meta(readingMeta("none")),
|
|
62571
|
+
/** Portion (grams) of the last manual feed sent from a single-hopper
|
|
62572
|
+
* stepper — the default the next manual feed starts from. Persisted per
|
|
62573
|
+
* device by the provider; null until a manual feed has been sent. */
|
|
62574
|
+
lastFeedGrams: gramsPortion.nullable(),
|
|
62575
|
+
/** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
|
|
62576
|
+
lastFeedHopper1: gramsPortion.nullable(),
|
|
62577
|
+
/** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
|
|
62578
|
+
lastFeedHopper2: gramsPortion.nullable(),
|
|
62205
62579
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
62206
62580
|
lastFetchedAt: number()
|
|
62207
62581
|
});
|
|
@@ -66843,9 +67217,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
66843
67217
|
kind: "mutation",
|
|
66844
67218
|
auth: "admin"
|
|
66845
67219
|
});
|
|
67220
|
+
discriminatedUnion("kind", [object({
|
|
67221
|
+
kind: literal("raw"),
|
|
67222
|
+
timings: array(number().int()),
|
|
67223
|
+
settings: TransmitSettingsSchema.optional()
|
|
67224
|
+
}), object({
|
|
67225
|
+
kind: literal("pronto"),
|
|
67226
|
+
code: string()
|
|
67227
|
+
})]);
|
|
66846
67228
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
66847
67229
|
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;
|
|
67230
|
+
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
67231
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
66850
67232
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
66851
67233
|
new Set(CAP_NAMES);
|
|
@@ -71794,6 +72176,13 @@ Object.freeze({
|
|
|
71794
72176
|
access: "create",
|
|
71795
72177
|
role: "admin"
|
|
71796
72178
|
},
|
|
72179
|
+
"nodeRemovalHook.onNodeRemoved": {
|
|
72180
|
+
capName: "node-removal-hook",
|
|
72181
|
+
capScope: "system",
|
|
72182
|
+
addonId: null,
|
|
72183
|
+
access: "create",
|
|
72184
|
+
role: "admin"
|
|
72185
|
+
},
|
|
71797
72186
|
"nodes.clusterAddonStatus": {
|
|
71798
72187
|
capName: "nodes",
|
|
71799
72188
|
capScope: "system",
|
|
@@ -74685,6 +75074,41 @@ Object.freeze({
|
|
|
74685
75074
|
access: "create",
|
|
74686
75075
|
role: "admin"
|
|
74687
75076
|
},
|
|
75077
|
+
"remote.getConfig": {
|
|
75078
|
+
capName: "remote",
|
|
75079
|
+
capScope: "system",
|
|
75080
|
+
addonId: null,
|
|
75081
|
+
access: "view",
|
|
75082
|
+
role: "admin"
|
|
75083
|
+
},
|
|
75084
|
+
"remote.listCommands": {
|
|
75085
|
+
capName: "remote",
|
|
75086
|
+
capScope: "system",
|
|
75087
|
+
addonId: null,
|
|
75088
|
+
access: "view",
|
|
75089
|
+
role: "admin"
|
|
75090
|
+
},
|
|
75091
|
+
"remote.sendCommand": {
|
|
75092
|
+
capName: "remote",
|
|
75093
|
+
capScope: "system",
|
|
75094
|
+
addonId: null,
|
|
75095
|
+
access: "create",
|
|
75096
|
+
role: "admin"
|
|
75097
|
+
},
|
|
75098
|
+
"remote.sendMediaCommand": {
|
|
75099
|
+
capName: "remote",
|
|
75100
|
+
capScope: "system",
|
|
75101
|
+
addonId: null,
|
|
75102
|
+
access: "create",
|
|
75103
|
+
role: "admin"
|
|
75104
|
+
},
|
|
75105
|
+
"remote.setConfig": {
|
|
75106
|
+
capName: "remote",
|
|
75107
|
+
capScope: "system",
|
|
75108
|
+
addonId: null,
|
|
75109
|
+
access: "create",
|
|
75110
|
+
role: "admin"
|
|
75111
|
+
},
|
|
74688
75112
|
"runningState.getStatus": {
|
|
74689
75113
|
capName: "running-state",
|
|
74690
75114
|
capScope: "device",
|
|
@@ -75875,6 +76299,41 @@ Object.freeze({
|
|
|
75875
76299
|
access: "view",
|
|
75876
76300
|
role: "viewer"
|
|
75877
76301
|
},
|
|
76302
|
+
"template.create": {
|
|
76303
|
+
capName: "template",
|
|
76304
|
+
capScope: "system",
|
|
76305
|
+
addonId: null,
|
|
76306
|
+
access: "create",
|
|
76307
|
+
role: "admin"
|
|
76308
|
+
},
|
|
76309
|
+
"template.delete": {
|
|
76310
|
+
capName: "template",
|
|
76311
|
+
capScope: "system",
|
|
76312
|
+
addonId: null,
|
|
76313
|
+
access: "delete",
|
|
76314
|
+
role: "admin"
|
|
76315
|
+
},
|
|
76316
|
+
"template.get": {
|
|
76317
|
+
capName: "template",
|
|
76318
|
+
capScope: "system",
|
|
76319
|
+
addonId: null,
|
|
76320
|
+
access: "view",
|
|
76321
|
+
role: "admin"
|
|
76322
|
+
},
|
|
76323
|
+
"template.list": {
|
|
76324
|
+
capName: "template",
|
|
76325
|
+
capScope: "system",
|
|
76326
|
+
addonId: null,
|
|
76327
|
+
access: "view",
|
|
76328
|
+
role: "admin"
|
|
76329
|
+
},
|
|
76330
|
+
"template.update": {
|
|
76331
|
+
capName: "template",
|
|
76332
|
+
capScope: "system",
|
|
76333
|
+
addonId: null,
|
|
76334
|
+
access: "create",
|
|
76335
|
+
role: "admin"
|
|
76336
|
+
},
|
|
75878
76337
|
"terminalSession.adoptLegacyMonitor": {
|
|
75879
76338
|
capName: "terminal-session",
|
|
75880
76339
|
capScope: "system",
|
|
@@ -80667,6 +81126,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80667
81126
|
"device-manager": system("the device registry itself — rename, move and remove are administration"),
|
|
80668
81127
|
"device-provider": system(INTERNAL),
|
|
80669
81128
|
"device-removal-hook": system(INTERNAL),
|
|
81129
|
+
"node-removal-hook": system(INTERNAL),
|
|
80670
81130
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
80671
81131
|
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
80672
81132
|
"embedding-encoder": system(ML),
|
|
@@ -80706,6 +81166,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80706
81166
|
"recording-archive": system(STORAGE),
|
|
80707
81167
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
80708
81168
|
records: system(INTERNAL),
|
|
81169
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
80709
81170
|
"server-management": system(CLUSTER),
|
|
80710
81171
|
"settings-store": system(INTERNAL),
|
|
80711
81172
|
"smtp-provider": system(INTERNAL),
|
|
@@ -80718,6 +81179,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80718
81179
|
"storage-provider": system(STORAGE),
|
|
80719
81180
|
"stream-broker": system(PIPELINE),
|
|
80720
81181
|
system: system(CLUSTER),
|
|
81182
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
80721
81183
|
"terminal-session": system(CLUSTER),
|
|
80722
81184
|
toast: system(UI_PLUMBING),
|
|
80723
81185
|
training: system(ML),
|
|
@@ -83144,6 +83606,31 @@ Object.freeze({
|
|
|
83144
83606
|
form: "single",
|
|
83145
83607
|
optional: true
|
|
83146
83608
|
}],
|
|
83609
|
+
"remote.getConfig": [{
|
|
83610
|
+
name: "deviceId",
|
|
83611
|
+
form: "single",
|
|
83612
|
+
optional: false
|
|
83613
|
+
}],
|
|
83614
|
+
"remote.listCommands": [{
|
|
83615
|
+
name: "deviceId",
|
|
83616
|
+
form: "single",
|
|
83617
|
+
optional: false
|
|
83618
|
+
}],
|
|
83619
|
+
"remote.sendCommand": [{
|
|
83620
|
+
name: "deviceId",
|
|
83621
|
+
form: "single",
|
|
83622
|
+
optional: false
|
|
83623
|
+
}],
|
|
83624
|
+
"remote.sendMediaCommand": [{
|
|
83625
|
+
name: "deviceId",
|
|
83626
|
+
form: "single",
|
|
83627
|
+
optional: false
|
|
83628
|
+
}],
|
|
83629
|
+
"remote.setConfig": [{
|
|
83630
|
+
name: "deviceId",
|
|
83631
|
+
form: "single",
|
|
83632
|
+
optional: false
|
|
83633
|
+
}],
|
|
83147
83634
|
"runningState.getStatus": [{
|
|
83148
83635
|
name: "deviceId",
|
|
83149
83636
|
form: "single",
|
|
@@ -84952,14 +85439,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
84952
85439
|
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
84953
85440
|
var MB = 1024 * 1024;
|
|
84954
85441
|
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
85442
|
object({
|
|
84964
85443
|
manufacturer: string().optional(),
|
|
84965
85444
|
supportedModels: array(string()).optional(),
|