Skip to main content

kvm macro

A macro binds a key combination to an action. The combination is detected on the remote station's keyboard and never forwarded to the controlled PC. Macros are stored persistently and survive server restarts.

A macro lives inside a seat configuration, and is created, removed, enabled, and disabled there with kvm config macro. The kvm macro command itself is read-only: it reports what exists and what a given seat will actually fire.

Command TypeDisplayNet
Minimum Version5.0

Usage

kvm macro list [<remote_device>]

Authoring, in kvm config:

kvm config macro add <config> <name> <trigger> <builtin|command|script|sendkeys> <action...>
kvm config macro remove <config> <name>
kvm config macro enable <config> <name>
kvm config macro disable <config> <name>
Removed subcommands
5.0

They addressed a macro by a scope and a bare name rather than by its configuration, which made two things impossible to get right:

  • kvm macro define <name> <remote_device> created a configuration for that receiver and assigned it. Since a seat resolves to exactly one configuration and that configuration replaces the less specific one entirely, the new one, holding one macro and no buttons, took the seat's Stream Deck dark the instant it was created.
  • A macro name was a global handle, so kvm macro delete <name> searched every configuration. That in turn forced kvm config clone to rename the macros it copied, since two of them could not share a name.

defineconfig macro add, deleteconfig macro remove. Running an old verb returns an error naming its replacement.

Macro scope

Not on the macro, but on its configuration. A configuration assigned to global applies at every station; one assigned to an rx scope applies at that seat.

warning

Resolution is whole-configuration replacement, not a per-trigger merge Each seat resolves to exactly one configuration (rx > global), and that configuration supplies all of the seat's macros. The less-specific one is not layered underneath it. So the moment a seat has its own configuration assigned, none of the Global macros apply there anymore, not just the ones sharing a trigger. Give a seat its own configuration and it must carry the complete set that seat needs. kvm config clone is the quick way to start from the global set. See kvm config.

Names and triggers are unique within a configuration, not globally. Two configurations may each hold a macro called openrun, and cloning a configuration copies names verbatim.

Action types

TypeAction argumentEffect
builtinfocus_next, focus_prev, focus <window>, lock_toggle, lock_on, lock_off, fullscreen_toggle, fullscreen_on, fullscreen_offRuns the corresponding kvm focus / kvm lock / kvm fullscreen operation on the session that fired the macro
commandAny DisplayNet API commandRuns the command with the same validation and authority as a connected client
scriptThe name of an existing preset scriptRuns the script (see preset)
sendkeysA keystroke sequence, e.g. ctrl+alt+f1 or gui+r, type:notepad, enterTypes the sequence into the host the seat is currently controlling (see kvm sendkeys)

A script action must name a script that already exists; the add is rejected otherwise.

Arguments

ArgumentDescription
configThe configuration that will own the macro. kvm config list shows them; kvm workstation show <remote_device> shows which one a seat resolves.
nameThe macro name, unique within its configuration (case-insensitive).
remote_deviceA remote HID extender, used to filter kvm macro list to what that seat actually fires.
triggerA key combination string. See trigger.

trigger

A key combination string: one or more modifiers plus exactly one non-modifier key, joined with +. Matching is side-agnostic: left and right modifiers are equivalent (ctrl matches either Ctrl key, and lctrl/rctrl are accepted as aliases).

ElementAccepted names
Modifiersctrl, shift, alt, gui (aliases: control, win, cmd, and l/r side prefixes)
Letters / digitsa to z, 0 to 9
Function keysf1 to f12
Navigationup, down, left, right, home, end, pageup, pagedown, insert, delete
Otherenter, esc, tab, space, backspace, minus, equals, printscreen, scrolllock, pause, numlock, kp0 to kp9
Raw escape0xNN, any USB HID usage code in hex

Examples: ctrl+alt+1, ctrl+shift+f5, gui+0x52.

When a trigger fires, the controlled PC does not see the combination. The chord is swallowed and the modifier keys are released cleanly on the PC side.

Examples

Add a hotkey that every station gets
kvm config macro add Global wallcycle ctrl+alt+n builtin focus_next
Add one that runs a preset script
kvm config macro add Global camerascript ctrl+alt+c script CameraPreset1
Give one seat its own macros, starting from the global set
kvm config clone Global ControlRoom_seat
kvm config assign ControlRoom_seat rx ControlRoom
kvm config macro add ControlRoom_seat night ctrl+alt+f9 command preset apply NightShift
Turn a macro off without deleting it
kvm config macro disable Global wallcycle
List what a station will actually fire
kvm macro list ControlRoom
Writing a command action

Type the API command as plain words after command, as in the night example above. Do not wrap the whole command in quotes. A quoted command "preset apply NightShift" collapses to the single token preset_apply_NightShift; the macro is accepted and the break surfaces only when it fires. A multi-word name inside the command still needs its quotes so it stays one token: command connect HDMI "Front Lobby" ControlRoom.

Return value

kvm macro list

With no argument, every macro that exists, labelled with the configuration that owns it. With a <remote_device>, the seat's effective set, read from the same compiled result the engine fires from, so it cannot drift from behaviour.

kvm macro list
{
"status": "SUCCESS",
"request_id": null,
"result": {
"macro_list": [
{
"Name": "wallcycle",
"Config": "Global",
"TriggerDisplay": "ctrl+alt+n",
"ActionType": "builtin",
"ActionPayload": "focus_next",
"Enabled": true
}
]
},
"error": null
}

TriggerDisplay is the macro's trigger as the same human-readable string used to define it, such as ctrl+alt+n. It uses the exact vocabulary the trigger argument accepts, so what a macro reports is what recreates it.

Config replaced the former Scope / Source pair in 5.0. Those described a per-macro scope, but resolution has always been per-configuration, and once every macro is configuration-owned, every row would have reported global regardless of where its configuration was actually assigned.

Macro subcommands

add, remove, enable and disable all return the same envelope.

kvm config macro add Global wallcycle ctrl+alt+n builtin focus_next
{
"status": "SUCCESS",
"request_id": null,
"result": null,
"error": null
}

Errors

Error response
{
"status": "ERROR",
"request_id": null,
"result": null,
"error": {
"message": "<description>",
"reason": "KVM API ERROR"
}
}

Common error conditions:

  • Invalid trigger string, action type, or built-in name (config macro add)
  • Macro name already used in that configuration, or its trigger already bound there (config macro add)
  • Script not found (config macro add ... script)
  • Configuration not found, or no macro of that name in it (config macro remove / enable / disable)
  • Enabling a macro whose trigger is already bound by another enabled macro in the same configuration (config macro enable)
  • A removed kvm macro verb was used. The message names its kvm config macro replacement

Notifications

macro_update

Sent after every kvm config macro add, remove, enable, or disable, carrying the current macro names and enabled flags so clients can keep a macro editor live.

macro_update notification
{
"status": "DN_NOTIFICATION",
"request_id": null,
"error": null,
"result": {
"macro_update": [
{ "Name": "wallcycle", "Enabled": true },
{ "Name": "night", "Enabled": false }
]
}
}

macro_error

Sent when a fired macro fails to execute, for example a command macro whose target device is locked, or a fullscreen_toggle on a session that is not MultiView. A failing macro never disturbs keyboard/mouse forwarding.

macro_error notification
{
"status": "DN_NOTIFICATION",
"request_id": null,
"error": null,
"result": {
"macro_error": [
{
"Macro": "night",
"Remote": "6cdffb00387f",
"Action": "preset apply NightShift",
"Message": "Cannot apply preset: device DisplayWall-1 is locked"
}
]
}
}

REST API

Endpoint typeDisplayNet API command
AddressPOST /api/displaynet/<operation>, or name the operation in the body of a POST /api/displaynet. See Sending commands.
RoleUser
SubcommandOperationParameters
macrokvm_macroaction [args]*
macro_listkvm_macro_list[remote_id]

A parameter in brackets is optional. A parameter marked * takes the remainder of the command line as one string. Pass the text exactly as you would type it on the TCI interface.

kvm_macro_list takes remote_id as a named field for one seat's effective set, or no fields for every defined macro. Authoring runs through the kvm config typed operations.

kvm_macro takes a raw grammar line instead: action and args, spelled as under Usage above.

See also

  • kvm config: where macros are authored, and the configuration model they resolve through
  • kvm: core KVM session commands, including kvm sendkeys
  • preset: preset scripts runnable from script macros