@camstack/addon-training 0.1.103 → 0.1.105
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-HAJ6awj4.mjs → MotionZonesSettings-CTiGmTwm.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-BF0NUmVm.mjs → PrivacyMaskSettings-evTcHeEU.mjs} +2 -2
- package/dist/{SceneMonitorEditor-CeEWTp0p.mjs → SceneMonitorEditor-C03Xg6cM.mjs} +2 -2
- package/dist/_stub.js +6578 -6515
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-T_zCH7zZ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-1sr2B1A2.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-rMgUaeoj.mjs +26 -0
- package/dist/addon-training.css +1 -1
- package/dist/{dist-Cq0HT75H.js → dist-BhNuTgrA.js} +490 -11
- package/dist/{dist-BfxOw6-O.mjs → dist-CCRzGEk1.mjs} +490 -11
- package/dist/{hostInit-DRiiL3Ka.mjs → hostInit-Cxx4Eh3M.mjs} +2 -2
- package/dist/index.js +1 -1
- package/dist/orchestrator/training.addon.js +1 -1
- package/dist/orchestrator/training.addon.mjs +1 -1
- package/dist/{player-overlays-NVql0bBe.mjs → player-overlays-0haBt2oQ.mjs} +1 -1
- package/dist/providers/modal/training-modal.addon.js +1 -1
- package/dist/providers/modal/training-modal.addon.mjs +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-Cw10UV1G.mjs → responsive-BnXGZLBS.mjs} +1 -1
- package/dist/{scene-monitor-copy-BiaQA_PZ.mjs → scene-monitor-copy-Bh54RJt8.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-Bg8j40fX.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-X8CJUTYR.mjs} +399 -390
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CLeWJI6-.mjs +0 -26
|
@@ -5613,7 +5613,7 @@ var ZodIssueCode = {
|
|
|
5613
5613
|
var ZodFirstPartyTypeKind;
|
|
5614
5614
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5615
5615
|
//#endregion
|
|
5616
|
-
//#region ../types/dist/sleep-
|
|
5616
|
+
//#region ../types/dist/sleep-C_u6cEAJ.mjs
|
|
5617
5617
|
/**
|
|
5618
5618
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5619
5619
|
* window to float samples (D455).
|
|
@@ -9024,6 +9024,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9024
9024
|
"network-link",
|
|
9025
9025
|
"network-quality",
|
|
9026
9026
|
"node-certificates",
|
|
9027
|
+
"node-removal-hook",
|
|
9027
9028
|
"nodes",
|
|
9028
9029
|
"notification-output",
|
|
9029
9030
|
"notification-rules",
|
|
@@ -9054,6 +9055,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9054
9055
|
"recording-onboard",
|
|
9055
9056
|
"recording-signal",
|
|
9056
9057
|
"records",
|
|
9058
|
+
"remote",
|
|
9057
9059
|
"running-state",
|
|
9058
9060
|
"scene-monitor",
|
|
9059
9061
|
"script-runner",
|
|
@@ -9077,6 +9079,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9077
9079
|
"system",
|
|
9078
9080
|
"tamper",
|
|
9079
9081
|
"temperature-sensor",
|
|
9082
|
+
"template",
|
|
9080
9083
|
"terminal-session",
|
|
9081
9084
|
"toast",
|
|
9082
9085
|
"training",
|
|
@@ -10017,6 +10020,11 @@ Object.freeze({
|
|
|
10017
10020
|
"standby"
|
|
10018
10021
|
]
|
|
10019
10022
|
},
|
|
10023
|
+
{
|
|
10024
|
+
"path": "stateSource",
|
|
10025
|
+
"valueType": "enum",
|
|
10026
|
+
"enumValues": ["reported", "assumed"]
|
|
10027
|
+
},
|
|
10020
10028
|
{
|
|
10021
10029
|
"path": "volumeLevel",
|
|
10022
10030
|
"valueType": "number"
|
|
@@ -10292,6 +10300,18 @@ Object.freeze({
|
|
|
10292
10300
|
{
|
|
10293
10301
|
"path": "volume",
|
|
10294
10302
|
"valueType": "number"
|
|
10303
|
+
},
|
|
10304
|
+
{
|
|
10305
|
+
"path": "lastFeedGrams",
|
|
10306
|
+
"valueType": "number"
|
|
10307
|
+
},
|
|
10308
|
+
{
|
|
10309
|
+
"path": "lastFeedHopper1",
|
|
10310
|
+
"valueType": "number"
|
|
10311
|
+
},
|
|
10312
|
+
{
|
|
10313
|
+
"path": "lastFeedHopper2",
|
|
10314
|
+
"valueType": "number"
|
|
10295
10315
|
}
|
|
10296
10316
|
],
|
|
10297
10317
|
"power-meter": [
|
|
@@ -11183,7 +11203,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11183
11203
|
return DeviceRole;
|
|
11184
11204
|
}({});
|
|
11185
11205
|
//#endregion
|
|
11186
|
-
//#region ../types/dist/composition-
|
|
11206
|
+
//#region ../types/dist/composition-bIBW5_13.mjs
|
|
11187
11207
|
/**
|
|
11188
11208
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11189
11209
|
*
|
|
@@ -42781,6 +42801,14 @@ method(object({
|
|
|
42781
42801
|
kind: "mutation",
|
|
42782
42802
|
auth: "admin"
|
|
42783
42803
|
});
|
|
42804
|
+
method(object({
|
|
42805
|
+
nodeId: string().min(1),
|
|
42806
|
+
/** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
|
|
42807
|
+
removedAt: number()
|
|
42808
|
+
}), object({ counts: record(string(), number().int().nonnegative()) }), {
|
|
42809
|
+
kind: "mutation",
|
|
42810
|
+
auth: "admin"
|
|
42811
|
+
});
|
|
42784
42812
|
/**
|
|
42785
42813
|
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
42786
42814
|
* so it can delete what it keeps for that device (D865).
|
|
@@ -57793,6 +57821,318 @@ DeviceType.Light, method(object({
|
|
|
57793
57821
|
level: number().min(0).max(100),
|
|
57794
57822
|
lastChangedAt: number()
|
|
57795
57823
|
});
|
|
57824
|
+
/**
|
|
57825
|
+
* The role vocabulary of a remote (D963): what a button MEANS, independent of
|
|
57826
|
+
* how it is wired. A layout template places buttons by role; a device binds a
|
|
57827
|
+
* role to an action; an exporter asks for a role by name. Roles are shared so
|
|
57828
|
+
* one layout fits every appliance and one voice command fits every binding.
|
|
57829
|
+
*
|
|
57830
|
+
* A role outside this list is `custom:<key>` — the operator's own button (a
|
|
57831
|
+
* SmartIR source, a channel preset). The key is a lowercase slug.
|
|
57832
|
+
*/
|
|
57833
|
+
var REMOTE_KNOWN_ROLES = [
|
|
57834
|
+
"power",
|
|
57835
|
+
"power_on",
|
|
57836
|
+
"power_off",
|
|
57837
|
+
"volume_up",
|
|
57838
|
+
"volume_down",
|
|
57839
|
+
"mute",
|
|
57840
|
+
"channel_up",
|
|
57841
|
+
"channel_down",
|
|
57842
|
+
"up",
|
|
57843
|
+
"down",
|
|
57844
|
+
"left",
|
|
57845
|
+
"right",
|
|
57846
|
+
"ok",
|
|
57847
|
+
"back",
|
|
57848
|
+
"home",
|
|
57849
|
+
"menu",
|
|
57850
|
+
"info",
|
|
57851
|
+
"guide",
|
|
57852
|
+
"exit",
|
|
57853
|
+
"input",
|
|
57854
|
+
"play",
|
|
57855
|
+
"pause",
|
|
57856
|
+
"play_pause",
|
|
57857
|
+
"stop",
|
|
57858
|
+
"next",
|
|
57859
|
+
"previous",
|
|
57860
|
+
"fast_forward",
|
|
57861
|
+
"rewind",
|
|
57862
|
+
"digit_0",
|
|
57863
|
+
"digit_1",
|
|
57864
|
+
"digit_2",
|
|
57865
|
+
"digit_3",
|
|
57866
|
+
"digit_4",
|
|
57867
|
+
"digit_5",
|
|
57868
|
+
"digit_6",
|
|
57869
|
+
"digit_7",
|
|
57870
|
+
"digit_8",
|
|
57871
|
+
"digit_9"
|
|
57872
|
+
];
|
|
57873
|
+
var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
|
|
57874
|
+
var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
|
|
57875
|
+
function isRemoteKnownRole(value) {
|
|
57876
|
+
return KNOWN_ROLES.has(value);
|
|
57877
|
+
}
|
|
57878
|
+
function isRemoteCustomKey(key) {
|
|
57879
|
+
return CUSTOM_KEY_RE.test(key);
|
|
57880
|
+
}
|
|
57881
|
+
/** The key of a `custom:<key>` role, or null for any other string. */
|
|
57882
|
+
function customKeyOfRole(role) {
|
|
57883
|
+
if (!role.startsWith("custom:")) return null;
|
|
57884
|
+
const key = role.slice(7);
|
|
57885
|
+
return isRemoteCustomKey(key) ? key : null;
|
|
57886
|
+
}
|
|
57887
|
+
function isRemoteRole(value) {
|
|
57888
|
+
return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
|
|
57889
|
+
}
|
|
57890
|
+
var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
|
|
57891
|
+
var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
|
|
57892
|
+
var RemoteCustomButtonSchema = object({
|
|
57893
|
+
/** The slug after `custom:` in the role. */
|
|
57894
|
+
key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
|
|
57895
|
+
/** What the operator calls it, and what a voice command may name. */
|
|
57896
|
+
name: string().min(1).max(60)
|
|
57897
|
+
});
|
|
57898
|
+
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
57899
|
+
var RemoteConfigSchema = object({
|
|
57900
|
+
layoutTemplateId: string().min(1).nullable(),
|
|
57901
|
+
/**
|
|
57902
|
+
* The transmitter device new bindings and an import send through. A binding
|
|
57903
|
+
* names its own device, so one command may override it.
|
|
57904
|
+
*/
|
|
57905
|
+
defaultTransmitterId: number().int().nonnegative().nullable().default(null),
|
|
57906
|
+
/** Keyed by role. A role with no entry falls back to the native cap. */
|
|
57907
|
+
bindings: record(string(), RemoteBindingSchema),
|
|
57908
|
+
customButtons: array(RemoteCustomButtonSchema).max(100),
|
|
57909
|
+
power: object({ mode: RemotePowerModeSchema })
|
|
57910
|
+
}).superRefine((config, ctx) => {
|
|
57911
|
+
const roles = Object.keys(config.bindings);
|
|
57912
|
+
if (roles.length > 200) ctx.addIssue({
|
|
57913
|
+
code: "custom",
|
|
57914
|
+
message: "too many bindings",
|
|
57915
|
+
path: ["bindings"]
|
|
57916
|
+
});
|
|
57917
|
+
for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
|
|
57918
|
+
code: "custom",
|
|
57919
|
+
message: `"${role}" is not a role`,
|
|
57920
|
+
path: ["bindings", role]
|
|
57921
|
+
});
|
|
57922
|
+
const keys = /* @__PURE__ */ new Set();
|
|
57923
|
+
config.customButtons.forEach((button, index) => {
|
|
57924
|
+
if (keys.has(button.key)) ctx.addIssue({
|
|
57925
|
+
code: "custom",
|
|
57926
|
+
message: `custom button "${button.key}" is listed twice`,
|
|
57927
|
+
path: [
|
|
57928
|
+
"customButtons",
|
|
57929
|
+
index,
|
|
57930
|
+
"key"
|
|
57931
|
+
]
|
|
57932
|
+
});
|
|
57933
|
+
keys.add(button.key);
|
|
57934
|
+
});
|
|
57935
|
+
for (const role of roles) {
|
|
57936
|
+
const key = customKeyOfRole(role);
|
|
57937
|
+
if (key !== null && !keys.has(key)) ctx.addIssue({
|
|
57938
|
+
code: "custom",
|
|
57939
|
+
message: `${role} is bound but has no entry in customButtons`,
|
|
57940
|
+
path: ["bindings", role]
|
|
57941
|
+
});
|
|
57942
|
+
}
|
|
57943
|
+
});
|
|
57944
|
+
object({
|
|
57945
|
+
power: object({
|
|
57946
|
+
state: _enum(["on", "off"]),
|
|
57947
|
+
at: number()
|
|
57948
|
+
}).nullable(),
|
|
57949
|
+
muted: object({
|
|
57950
|
+
value: boolean(),
|
|
57951
|
+
at: number()
|
|
57952
|
+
}).nullable()
|
|
57953
|
+
});
|
|
57954
|
+
var RemoteLayoutButtonSchema = object({
|
|
57955
|
+
id: string().min(1).max(40),
|
|
57956
|
+
/** 0-based grid position. */
|
|
57957
|
+
row: number().int().min(0).max(24),
|
|
57958
|
+
col: number().int().min(0).max(24),
|
|
57959
|
+
rowSpan: number().int().min(1).max(24),
|
|
57960
|
+
colSpan: number().int().min(1).max(24),
|
|
57961
|
+
icon: string().min(1).max(60).optional(),
|
|
57962
|
+
label: string().min(1).max(40).optional(),
|
|
57963
|
+
role: RemoteRoleSchema
|
|
57964
|
+
});
|
|
57965
|
+
object({
|
|
57966
|
+
columns: number().int().min(1).max(24),
|
|
57967
|
+
rows: number().int().min(1).max(24),
|
|
57968
|
+
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
57969
|
+
}).superRefine((grid, ctx) => {
|
|
57970
|
+
const ids = /* @__PURE__ */ new Set();
|
|
57971
|
+
const taken = /* @__PURE__ */ new Map();
|
|
57972
|
+
grid.buttons.forEach((button, index) => {
|
|
57973
|
+
if (ids.has(button.id)) ctx.addIssue({
|
|
57974
|
+
code: "custom",
|
|
57975
|
+
message: `button id "${button.id}" is used twice`,
|
|
57976
|
+
path: [
|
|
57977
|
+
"buttons",
|
|
57978
|
+
index,
|
|
57979
|
+
"id"
|
|
57980
|
+
]
|
|
57981
|
+
});
|
|
57982
|
+
ids.add(button.id);
|
|
57983
|
+
if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
|
|
57984
|
+
ctx.addIssue({
|
|
57985
|
+
code: "custom",
|
|
57986
|
+
message: `button "${button.id}" leaves the grid`,
|
|
57987
|
+
path: ["buttons", index]
|
|
57988
|
+
});
|
|
57989
|
+
return;
|
|
57990
|
+
}
|
|
57991
|
+
for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
|
|
57992
|
+
const cell = `${r}:${c}`;
|
|
57993
|
+
const other = taken.get(cell);
|
|
57994
|
+
if (other !== void 0) {
|
|
57995
|
+
ctx.addIssue({
|
|
57996
|
+
code: "custom",
|
|
57997
|
+
message: `buttons "${other}" and "${button.id}" overlap`,
|
|
57998
|
+
path: ["buttons", index]
|
|
57999
|
+
});
|
|
58000
|
+
return;
|
|
58001
|
+
}
|
|
58002
|
+
taken.set(cell, button.id);
|
|
58003
|
+
}
|
|
58004
|
+
});
|
|
58005
|
+
});
|
|
58006
|
+
var RemoteBoundCommandSchema = object({
|
|
58007
|
+
role: RemoteRoleSchema,
|
|
58008
|
+
/** The operator's name for a custom button; absent for a known role. */
|
|
58009
|
+
label: string().optional(),
|
|
58010
|
+
custom: boolean()
|
|
58011
|
+
});
|
|
58012
|
+
var RemoteCommandListSchema = object({
|
|
58013
|
+
layoutTemplateId: string().nullable(),
|
|
58014
|
+
power: object({ mode: RemotePowerModeSchema }),
|
|
58015
|
+
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
58016
|
+
commands: array(RemoteBoundCommandSchema)
|
|
58017
|
+
});
|
|
58018
|
+
var RemoteRefusalReasonSchema = _enum([
|
|
58019
|
+
"no-remote",
|
|
58020
|
+
"unbound-role",
|
|
58021
|
+
"action-failed"
|
|
58022
|
+
]);
|
|
58023
|
+
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
58024
|
+
object({
|
|
58025
|
+
status: literal("sent"),
|
|
58026
|
+
/** How many times the action ran. */
|
|
58027
|
+
sends: number().int().min(1)
|
|
58028
|
+
}),
|
|
58029
|
+
object({
|
|
58030
|
+
status: literal("skipped"),
|
|
58031
|
+
reason: literal("already-in-state")
|
|
58032
|
+
}),
|
|
58033
|
+
object({
|
|
58034
|
+
status: literal("refused"),
|
|
58035
|
+
reason: RemoteRefusalReasonSchema,
|
|
58036
|
+
detail: string().optional()
|
|
58037
|
+
})
|
|
58038
|
+
]);
|
|
58039
|
+
var RemoteMediaCommandSchema = _enum([
|
|
58040
|
+
"play",
|
|
58041
|
+
"pause",
|
|
58042
|
+
"stop",
|
|
58043
|
+
"next",
|
|
58044
|
+
"previous",
|
|
58045
|
+
"setMute",
|
|
58046
|
+
"selectSource"
|
|
58047
|
+
]);
|
|
58048
|
+
/** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
|
|
58049
|
+
var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
|
|
58050
|
+
var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
|
|
58051
|
+
status: literal("refused"),
|
|
58052
|
+
reason: _enum(["unknown-template", "not-a-media-player"]),
|
|
58053
|
+
detail: string()
|
|
58054
|
+
})]);
|
|
58055
|
+
var deviceInput = object({ deviceId: number().int().nonnegative() });
|
|
58056
|
+
DeviceType.MediaPlayer;
|
|
58057
|
+
method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
|
|
58058
|
+
kind: "mutation",
|
|
58059
|
+
auth: "admin"
|
|
58060
|
+
}), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
|
|
58061
|
+
role: RemoteRoleSchema,
|
|
58062
|
+
/** Sends in a row (volume steps). */
|
|
58063
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
58064
|
+
}), RemoteSendResultSchema, {
|
|
58065
|
+
kind: "mutation",
|
|
58066
|
+
auth: "protected"
|
|
58067
|
+
}), method(deviceInput.extend({
|
|
58068
|
+
command: RemoteMediaCommandSchema,
|
|
58069
|
+
muted: boolean().optional(),
|
|
58070
|
+
source: string().optional(),
|
|
58071
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
58072
|
+
}), RemoteMediaCommandResultSchema, {
|
|
58073
|
+
kind: "mutation",
|
|
58074
|
+
auth: "protected"
|
|
58075
|
+
});
|
|
58076
|
+
var TemplateKindSchema = _enum(["remote"]);
|
|
58077
|
+
/**
|
|
58078
|
+
* template — the generic store of reusable, named operator data (D963). A
|
|
58079
|
+
* record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
|
|
58080
|
+
* button grid of a remote) and the schema each payload must satisfy are
|
|
58081
|
+
* declared by the system in `template-kinds.ts`. Nothing here is specific to a
|
|
58082
|
+
* kind: the engine validates a payload against its kind's schema and, on a
|
|
58083
|
+
* delete, asks the kind's owner whether anything still points at the record.
|
|
58084
|
+
*
|
|
58085
|
+
* Every refusal is a typed result — a UI says "unknown kind" or names the
|
|
58086
|
+
* devices that still use a template, without parsing text.
|
|
58087
|
+
*/
|
|
58088
|
+
var TemplateRecordSchema = object({
|
|
58089
|
+
id: string().min(1),
|
|
58090
|
+
kind: TemplateKindSchema,
|
|
58091
|
+
name: string().min(1).max(120),
|
|
58092
|
+
/** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
|
|
58093
|
+
payload: unknown(),
|
|
58094
|
+
createdAt: number(),
|
|
58095
|
+
updatedAt: number()
|
|
58096
|
+
});
|
|
58097
|
+
var TemplateWriteResultSchema = discriminatedUnion("status", [object({
|
|
58098
|
+
status: literal("saved"),
|
|
58099
|
+
template: TemplateRecordSchema
|
|
58100
|
+
}), object({
|
|
58101
|
+
status: literal("refused"),
|
|
58102
|
+
reason: _enum(["invalid-payload", "not-found"]),
|
|
58103
|
+
detail: string()
|
|
58104
|
+
})]);
|
|
58105
|
+
/** A device still pointing at a template. */
|
|
58106
|
+
var TemplateUserSchema = object({
|
|
58107
|
+
deviceId: number().int().nonnegative(),
|
|
58108
|
+
name: string()
|
|
58109
|
+
});
|
|
58110
|
+
var TemplateDeleteResultSchema = discriminatedUnion("status", [
|
|
58111
|
+
object({ status: literal("deleted") }),
|
|
58112
|
+
object({ status: literal("not-found") }),
|
|
58113
|
+
object({
|
|
58114
|
+
status: literal("in-use"),
|
|
58115
|
+
devices: array(TemplateUserSchema).min(1)
|
|
58116
|
+
})
|
|
58117
|
+
]);
|
|
58118
|
+
method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
|
|
58119
|
+
kind: TemplateKindSchema,
|
|
58120
|
+
name: string().min(1).max(120),
|
|
58121
|
+
payload: unknown()
|
|
58122
|
+
}), TemplateWriteResultSchema, {
|
|
58123
|
+
kind: "mutation",
|
|
58124
|
+
auth: "admin"
|
|
58125
|
+
}), method(object({
|
|
58126
|
+
id: string().min(1),
|
|
58127
|
+
name: string().min(1).max(120).optional(),
|
|
58128
|
+
payload: unknown().optional()
|
|
58129
|
+
}), TemplateWriteResultSchema, {
|
|
58130
|
+
kind: "mutation",
|
|
58131
|
+
auth: "admin"
|
|
58132
|
+
}), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
|
|
58133
|
+
kind: "mutation",
|
|
58134
|
+
auth: "admin"
|
|
58135
|
+
});
|
|
57796
58136
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
57797
58137
|
kind: "mutation",
|
|
57798
58138
|
auth: "protected"
|
|
@@ -60542,9 +60882,35 @@ var MediaInfoSchema = object({
|
|
|
60542
60882
|
/** Optional cover-art / thumbnail URL. */
|
|
60543
60883
|
imageUrl: string().optional()
|
|
60544
60884
|
});
|
|
60885
|
+
/**
|
|
60886
|
+
* Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
|
|
60887
|
+
* the device said so. `assumed`: the driver has no feedback (infrared) and
|
|
60888
|
+
* tracks what it last SENT; it moves only after a send was accepted, and a
|
|
60889
|
+
* human at the real remote makes it wrong. A UI shows an assumed value as a
|
|
60890
|
+
* guess, never as a reading.
|
|
60891
|
+
*/
|
|
60892
|
+
var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
|
|
60893
|
+
/** The fields of a media-player status a driver can only guess. */
|
|
60894
|
+
var MediaPlayerAssumedFieldSchema = _enum([
|
|
60895
|
+
"state",
|
|
60896
|
+
"volumeLevel",
|
|
60897
|
+
"isMuted",
|
|
60898
|
+
"source"
|
|
60899
|
+
]);
|
|
60545
60900
|
object({
|
|
60546
60901
|
/** Playback lifecycle state. */
|
|
60547
60902
|
state: MediaPlayerStateSchema,
|
|
60903
|
+
/**
|
|
60904
|
+
* Whether the state fields are readings or the driver's own bookkeeping.
|
|
60905
|
+
* A slice written before this field existed parses as `reported`.
|
|
60906
|
+
*/
|
|
60907
|
+
stateSource: MediaPlayerStateSourceSchema.default("reported"),
|
|
60908
|
+
/**
|
|
60909
|
+
* Which fields are the driver's own guess. `stateSource` is `assumed` when
|
|
60910
|
+
* this is not empty; a field not listed here is a reading even then (power
|
|
60911
|
+
* from a running-state source, mute guessed from the last send).
|
|
60912
|
+
*/
|
|
60913
|
+
assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
|
|
60548
60914
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
60549
60915
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
60550
60916
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61985,6 +62351,14 @@ object({
|
|
|
61985
62351
|
feedSound: boolean(),
|
|
61986
62352
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
61987
62353
|
volume: number().meta(readingMeta("none")),
|
|
62354
|
+
/** Portion (grams) of the last manual feed sent from a single-hopper
|
|
62355
|
+
* stepper — the default the next manual feed starts from. Persisted per
|
|
62356
|
+
* device by the provider; null until a manual feed has been sent. */
|
|
62357
|
+
lastFeedGrams: gramsPortion.nullable(),
|
|
62358
|
+
/** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
|
|
62359
|
+
lastFeedHopper1: gramsPortion.nullable(),
|
|
62360
|
+
/** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
|
|
62361
|
+
lastFeedHopper2: gramsPortion.nullable(),
|
|
61988
62362
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
61989
62363
|
lastFetchedAt: number()
|
|
61990
62364
|
});
|
|
@@ -66728,9 +67102,17 @@ var trainingCapability = {
|
|
|
66728
67102
|
})
|
|
66729
67103
|
}
|
|
66730
67104
|
};
|
|
67105
|
+
discriminatedUnion("kind", [object({
|
|
67106
|
+
kind: literal("raw"),
|
|
67107
|
+
timings: array(number().int()),
|
|
67108
|
+
settings: TransmitSettingsSchema.optional()
|
|
67109
|
+
}), object({
|
|
67110
|
+
kind: literal("pronto"),
|
|
67111
|
+
code: string()
|
|
67112
|
+
})]);
|
|
66731
67113
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
66732
67114
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
66733
|
-
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;
|
|
67115
|
+
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;
|
|
66734
67116
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
66735
67117
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
66736
67118
|
new Set(CAP_NAMES);
|
|
@@ -71581,6 +71963,13 @@ Object.freeze({
|
|
|
71581
71963
|
access: "create",
|
|
71582
71964
|
role: "admin"
|
|
71583
71965
|
},
|
|
71966
|
+
"nodeRemovalHook.onNodeRemoved": {
|
|
71967
|
+
capName: "node-removal-hook",
|
|
71968
|
+
capScope: "system",
|
|
71969
|
+
addonId: null,
|
|
71970
|
+
access: "create",
|
|
71971
|
+
role: "admin"
|
|
71972
|
+
},
|
|
71584
71973
|
"nodes.clusterAddonStatus": {
|
|
71585
71974
|
capName: "nodes",
|
|
71586
71975
|
capScope: "system",
|
|
@@ -74472,6 +74861,41 @@ Object.freeze({
|
|
|
74472
74861
|
access: "create",
|
|
74473
74862
|
role: "admin"
|
|
74474
74863
|
},
|
|
74864
|
+
"remote.getConfig": {
|
|
74865
|
+
capName: "remote",
|
|
74866
|
+
capScope: "system",
|
|
74867
|
+
addonId: null,
|
|
74868
|
+
access: "view",
|
|
74869
|
+
role: "admin"
|
|
74870
|
+
},
|
|
74871
|
+
"remote.listCommands": {
|
|
74872
|
+
capName: "remote",
|
|
74873
|
+
capScope: "system",
|
|
74874
|
+
addonId: null,
|
|
74875
|
+
access: "view",
|
|
74876
|
+
role: "admin"
|
|
74877
|
+
},
|
|
74878
|
+
"remote.sendCommand": {
|
|
74879
|
+
capName: "remote",
|
|
74880
|
+
capScope: "system",
|
|
74881
|
+
addonId: null,
|
|
74882
|
+
access: "create",
|
|
74883
|
+
role: "admin"
|
|
74884
|
+
},
|
|
74885
|
+
"remote.sendMediaCommand": {
|
|
74886
|
+
capName: "remote",
|
|
74887
|
+
capScope: "system",
|
|
74888
|
+
addonId: null,
|
|
74889
|
+
access: "create",
|
|
74890
|
+
role: "admin"
|
|
74891
|
+
},
|
|
74892
|
+
"remote.setConfig": {
|
|
74893
|
+
capName: "remote",
|
|
74894
|
+
capScope: "system",
|
|
74895
|
+
addonId: null,
|
|
74896
|
+
access: "create",
|
|
74897
|
+
role: "admin"
|
|
74898
|
+
},
|
|
74475
74899
|
"runningState.getStatus": {
|
|
74476
74900
|
capName: "running-state",
|
|
74477
74901
|
capScope: "device",
|
|
@@ -75662,6 +76086,41 @@ Object.freeze({
|
|
|
75662
76086
|
access: "view",
|
|
75663
76087
|
role: "viewer"
|
|
75664
76088
|
},
|
|
76089
|
+
"template.create": {
|
|
76090
|
+
capName: "template",
|
|
76091
|
+
capScope: "system",
|
|
76092
|
+
addonId: null,
|
|
76093
|
+
access: "create",
|
|
76094
|
+
role: "admin"
|
|
76095
|
+
},
|
|
76096
|
+
"template.delete": {
|
|
76097
|
+
capName: "template",
|
|
76098
|
+
capScope: "system",
|
|
76099
|
+
addonId: null,
|
|
76100
|
+
access: "delete",
|
|
76101
|
+
role: "admin"
|
|
76102
|
+
},
|
|
76103
|
+
"template.get": {
|
|
76104
|
+
capName: "template",
|
|
76105
|
+
capScope: "system",
|
|
76106
|
+
addonId: null,
|
|
76107
|
+
access: "view",
|
|
76108
|
+
role: "admin"
|
|
76109
|
+
},
|
|
76110
|
+
"template.list": {
|
|
76111
|
+
capName: "template",
|
|
76112
|
+
capScope: "system",
|
|
76113
|
+
addonId: null,
|
|
76114
|
+
access: "view",
|
|
76115
|
+
role: "admin"
|
|
76116
|
+
},
|
|
76117
|
+
"template.update": {
|
|
76118
|
+
capName: "template",
|
|
76119
|
+
capScope: "system",
|
|
76120
|
+
addonId: null,
|
|
76121
|
+
access: "create",
|
|
76122
|
+
role: "admin"
|
|
76123
|
+
},
|
|
75665
76124
|
"terminalSession.adoptLegacyMonitor": {
|
|
75666
76125
|
capName: "terminal-session",
|
|
75667
76126
|
capScope: "system",
|
|
@@ -80454,6 +80913,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80454
80913
|
"device-manager": system("the device registry itself — rename, move and remove are administration"),
|
|
80455
80914
|
"device-provider": system(INTERNAL),
|
|
80456
80915
|
"device-removal-hook": system(INTERNAL),
|
|
80916
|
+
"node-removal-hook": system(INTERNAL),
|
|
80457
80917
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
80458
80918
|
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
80459
80919
|
"embedding-encoder": system(ML),
|
|
@@ -80493,6 +80953,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80493
80953
|
"recording-archive": system(STORAGE),
|
|
80494
80954
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
80495
80955
|
records: system(INTERNAL),
|
|
80956
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
80496
80957
|
"server-management": system(CLUSTER),
|
|
80497
80958
|
"settings-store": system(INTERNAL),
|
|
80498
80959
|
"smtp-provider": system(INTERNAL),
|
|
@@ -80505,6 +80966,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
80505
80966
|
"storage-provider": system(STORAGE),
|
|
80506
80967
|
"stream-broker": system(PIPELINE),
|
|
80507
80968
|
system: system(CLUSTER),
|
|
80969
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
80508
80970
|
"terminal-session": system(CLUSTER),
|
|
80509
80971
|
toast: system(UI_PLUMBING),
|
|
80510
80972
|
training: system(ML),
|
|
@@ -82931,6 +83393,31 @@ Object.freeze({
|
|
|
82931
83393
|
form: "single",
|
|
82932
83394
|
optional: true
|
|
82933
83395
|
}],
|
|
83396
|
+
"remote.getConfig": [{
|
|
83397
|
+
name: "deviceId",
|
|
83398
|
+
form: "single",
|
|
83399
|
+
optional: false
|
|
83400
|
+
}],
|
|
83401
|
+
"remote.listCommands": [{
|
|
83402
|
+
name: "deviceId",
|
|
83403
|
+
form: "single",
|
|
83404
|
+
optional: false
|
|
83405
|
+
}],
|
|
83406
|
+
"remote.sendCommand": [{
|
|
83407
|
+
name: "deviceId",
|
|
83408
|
+
form: "single",
|
|
83409
|
+
optional: false
|
|
83410
|
+
}],
|
|
83411
|
+
"remote.sendMediaCommand": [{
|
|
83412
|
+
name: "deviceId",
|
|
83413
|
+
form: "single",
|
|
83414
|
+
optional: false
|
|
83415
|
+
}],
|
|
83416
|
+
"remote.setConfig": [{
|
|
83417
|
+
name: "deviceId",
|
|
83418
|
+
form: "single",
|
|
83419
|
+
optional: false
|
|
83420
|
+
}],
|
|
82934
83421
|
"runningState.getStatus": [{
|
|
82935
83422
|
name: "deviceId",
|
|
82936
83423
|
form: "single",
|
|
@@ -84739,14 +85226,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
84739
85226
|
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
84740
85227
|
var MB = 1024 * 1024;
|
|
84741
85228
|
1024 * MB, 3072 * MB;
|
|
84742
|
-
discriminatedUnion("kind", [object({
|
|
84743
|
-
kind: literal("raw"),
|
|
84744
|
-
timings: array(number().int()),
|
|
84745
|
-
settings: TransmitSettingsSchema.optional()
|
|
84746
|
-
}), object({
|
|
84747
|
-
kind: literal("pronto"),
|
|
84748
|
-
code: string()
|
|
84749
|
-
})]);
|
|
84750
85229
|
object({
|
|
84751
85230
|
manufacturer: string().optional(),
|
|
84752
85231
|
supportedModels: array(string()).optional(),
|