Add Group and Aux master actions, feedbacks and preset sections

Groups were only reachable through the generic "Buss:" actions, whose
dropdown mixes all 25 busses, so users could not find group fader
control.

- New "Group:" and "Aux master:" mute, solo, set fader (with fade time)
  and adjust fader actions; their dropdowns list only busses of that
  type. Matching muted, solo, fader text/position, meter, signal and
  peak feedbacks.
- The old buss_* actions and feedbacks keep working for existing
  buttons and are now labelled "Any buss (aux or group)".
- Presets: "Busses" is split into "Groups" and "Aux masters", and the
  bus meters into "Group meters" and "Aux meters". A bus that changes
  type on the console moves section on the next rebuild.

npm test: 542 checks pass on Node 25 and on Companion's Node 22.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 12:57:01 -04:00
co-authored by Claude Opus 5.5
parent 205f91e7d2
commit f81d581bf2
6 changed files with 263 additions and 75 deletions
+40 -5
View File
@@ -23,7 +23,9 @@ export const opt = {
const choices = kind === 'aux' ? inst.state.choices.auxChoices() : kind === 'group' ? inst.state.choices.groupChoices() : inst.state.choices.busses()
return opt.dropdown(id, label || (kind === 'aux' ? 'Aux buss' : kind === 'group' ? 'Group buss' : 'Buss'), choices)
},
busses: (inst, id = 'busses', label = 'Busses') => opt.multi(id, label, inst.state.choices.busses()),
/** Several busses; `kind` 'aux' or 'group' lists only busses of that type (without the suffix), 'all' lists every buss. */
busses: (inst, id = 'busses', label = 'Busses', kind = 'all') =>
opt.multi(id, label, kind === 'aux' ? inst.state.choices.auxChoices() : kind === 'group' ? inst.state.choices.groupChoices() : inst.state.choices.busses()),
matrix: (inst, id = 'matrix', label = 'Matrix output') => opt.dropdown(id, label, inst.state.choices.matrix()),
matrixIn: (inst, id = 'matrixIn', label = 'Matrix input') => opt.dropdown(id, label, inst.state.choices.matrixInputs()),
cg: (inst, id = 'cg', label = 'Control group') => opt.dropdown(id, label, inst.state.choices.cgs()),
@@ -147,6 +149,36 @@ function quiet(inst, defs) {
export function getActionDefinitions(inst) {
const each = (list, fn) => Promise.all(numbers(list).map(fn))
const n = (v) => Number(v)
/**
* Mute, solo and fader actions for one type of buss (`prefix` 'group' or 'aux'). They are thin wrappers over the same
* buss operations as the buss_* actions (the address follows the buss's aux / group side), with the dropdowns
* filtered by type. The option ids are the same as the buss_* ones.
*/
const bussActions = (prefix, title, one, many) => ({
[`${prefix}_mute`]: {
name: `${title}: mute`,
description: 'Mute, unmute or toggle one or more.',
options: [opt.busses(inst, 'busses', many, prefix), opt.state()],
callback: async ({ options }) => void (await each(options.busses, (b) => inst.setSwitch('buss', 'mute', b, options.state))),
},
[`${prefix}_solo`]: {
name: `${title}: solo`,
options: [opt.busses(inst, 'busses', many, prefix), opt.state()],
callback: async ({ options }) => void (await each(options.busses, (b) => inst.setSwitch('buss', 'solo', b, options.state))),
},
[`${prefix}_fader_set`]: {
name: `${title}: set fader`,
description: FADE_NOTE,
options: [opt.buss(inst, prefix, 'buss', one), opt.level(), opt.duration(), opt.curve()],
callback: async ({ options }) => inst.setFader('buss', n(options.buss), n(options.level), ...fadeArgs(options)),
},
[`${prefix}_fader_adjust`]: {
name: `${title}: adjust fader (relative)`,
description: `For rotary encoders. ${ADJUST_NOTE}`,
options: [opt.buss(inst, prefix, 'buss', one), opt.delta()],
callback: async ({ options }) => inst.adjustFader('buss', n(options.buss), n(options.delta)),
},
})
return quiet(inst, {
...getParamActions(inst),
input_mute: {
@@ -221,24 +253,27 @@ export function getActionDefinitions(inst) {
callback: async ({ options }) => inst.setGroup(n(options.channel), n(options.buss), options.state),
},
...bussActions('group', 'Group', 'Group', 'Groups'),
...bussActions('aux', 'Aux master', 'Aux master', 'Aux masters'),
buss_mute: {
name: 'Buss: mute',
name: 'Any buss (aux or group): mute',
description: 'Mute, unmute or toggle one or more busses, aux and group alike (one list of all busses).',
options: [opt.busses(inst), opt.state()],
callback: async ({ options }) => void (await each(options.busses, (b) => inst.setSwitch('buss', 'mute', b, options.state))),
},
buss_solo: {
name: 'Buss: solo',
name: 'Any buss (aux or group): solo',
options: [opt.busses(inst), opt.state()],
callback: async ({ options }) => void (await each(options.busses, (b) => inst.setSwitch('buss', 'solo', b, options.state))),
},
buss_fader_set: {
name: 'Buss: set fader',
name: 'Any buss (aux or group): set fader',
description: FADE_NOTE,
options: [opt.buss(inst), opt.level(), opt.duration(), opt.curve()],
callback: async ({ options }) => inst.setFader('buss', n(options.buss), n(options.level), ...fadeArgs(options)),
},
buss_fader_adjust: {
name: 'Buss: adjust fader (relative)',
name: 'Any buss (aux or group): adjust fader (relative)',
description: `For rotary encoders. ${ADJUST_NOTE}`,
options: [opt.buss(inst), opt.delta()],
callback: async ({ options }) => inst.adjustFader('buss', n(options.buss), n(options.delta)),