Skip to main content

Commands

Commands are individual control instructions within a command set. Each command has a name, a template string, and optional arguments that allow dynamic value substitution at runtime.

Overview

The Commands page manages the individual commands within a command set. It is accessed by clicking Edit on a command set row in the Command Sets page, or via the commands icon on a device row in the Devices page.

Viewing Commands

The main grid displays all commands in the selected command set:

  • ID - Unique identifier
  • Name - Command name (lowercase_with_underscores)
  • Template - The command string or template
  • Args - Defined argument names
  • Source - DRIVER for driver-managed (system) commands, USER for ones you added
  • Command Set - Parent command set
  • Title - Shows the command set name
  • Test Device selector - Choose a device for testing commands
  • Reload button - Reload the selected test device

Grid Actions

  • Add - Create a new command
  • Edit - Open the command editor
  • Delete - Remove a command

Quick Actions

  • Test (remote icon) - Execute the command on the selected test device

Creating a Command

  1. Click Add in the grid toolbar
  2. Fill in the command details:

Command Fields

Name

  • Internal identifier (lowercase_with_underscores)
  • Auto-formatted on blur
  • Examples: power_on, set_volume, select_input

Template

  • Raw command string sent to the device
  • Use [arg_name] for argument placeholders (e.g., set_volume [level])
  • Can reference dynamic values: PWR [@zone.address]

Arguments

Arguments define named parameters that are substituted into the template at runtime:

  1. Type an argument name in the Arguments list editor and press Enter
  2. The argument appears as a selectable item
  3. Click an argument to configure its options

Argument Options

When an argument is selected, you can define the allowed values:

  1. Add static values (e.g., on, off, toggle)
  2. Add dynamic value placeholders that resolve at runtime using the buttons:
    • Zone Address - [@zone.address] - Resolved to the target zone's address
    • Device Address - [@device.address] - Resolved to the device's address
    • Device ID - [@device.id] - Resolved to the device's database ID
    • AV Zone - [@av_zone.address] - Resolved to the AV zone's address
    • AV Source - [@av_source.address] - Resolved to the AV source's address

Dynamic values are resolved at command execution time based on the target zone or device.

Testing Commands

To test a command:

  1. Select a Test Device from the dropdown in the header
  2. Click the Test icon (remote icon) on a command row
  3. If the command has arguments, a command tester dialog appears:
    • Fill in argument values
    • Click Send to execute
  4. If the command has no arguments, it executes immediately
  5. Results and responses appear as toast notifications

Prompt Attributes

Some commands may trigger a prompt attribute response from the device, asking for additional input (e.g., a PIN code or confirmation). The console will display a dialog for the user to provide the value.

Command Templates

Templates define what is sent to the device. They support several placeholder syntaxes:

Static Templates

POWER ON
VOL UP
INPUT HDMI1

Argument Placeholders

VOLUME [level] → VOLUME 50
INPUT [input_name] → INPUT HDMI1
PWR [state] → PWR ON

Dynamic Value Placeholders

ZONE[@zone.address] ON → ZONE03 ON
DEV[@device.id] STATUS → DEV5 STATUS

System Commands

Many device drivers define a built-in set of default commands via a static getCommands() method. When a device connects for the first time (or after a GEM update adds new commands to a driver), GEM automatically syncs these system commands into the device's command set.

How System Commands Work

  • Auto-created: When a device starts up, any commands defined by the driver that are missing from the command set are automatically inserted.
  • System flag: System-managed commands have the system field set to true and show a DRIVER badge in the Source column.
  • Driver is the source of truth: On every boot, GEM resyncs each field on the existing row from the driver definition. template, args, arg_options, and description all follow the same fill-empty stop-gap rule: if the driver supplies a value, the driver wins; if the driver leaves the field empty, your local edit is preserved (see below).
  • Orphan cleanup: If a driver removes a command in an update, the corresponding system command is automatically deleted from the database. User-created commands (where system is false) are never removed by the sync process.

Editing Driver-Managed Commands

The name field on a driver-managed command is owned by the driver and cannot be edited from the UI. Every other editable field — template, args, arg_options, description — follows the fill-empty stop-gap rule:

  • If the driver's getCommands() does not supply a value for the field, you can fill it in from the editor and your value is preserved across reboots.
  • If the driver does supply a value, the driver wins on every boot and overwrites whatever was in the row.

This lets integrators patch missing driver hints locally — adding a [@zone.address] arg option to surface a zone picker, filling in a missing template for a command the driver declared name-only, or writing a clearer description — without waiting for a driver release. As soon as the driver starts opining on the field, the driver takes over.

tip

If you need a permanent customization that conflicts with the driver, add a separate command with a different name. Custom commands (system = false) are preserved across updates and never overwritten by the sync process.

Identifying System Commands

In the commands grid, the Source column shows DRIVER for system-managed commands and USER for ones you've added. You can test driver-managed commands and use them in macros just like any other command. Deletion is blocked, and fields the driver opines on are reverted on the next boot — but any field the driver leaves empty stays editable as the fill-empty escape hatch.

Command Name Aliases

GEM maintains an internal alias system for common command names. When a command is executed and the exact name is not found in the device's command set, GEM tries alternative names from the same alias group. For example:

  • fast_forward → tries scan_forward, forward, ff
  • rewind → tries scan_back, reverse, scan_reverse, rw
  • next → tries skip_forward, skip_next
  • volumeset_volume
  • inputset_input
  • power_on → tries on, discrete_on
  • backreturn
  • select → tries ok, enter

This means macros and automation commands work across different drivers even when naming conventions differ slightly.

Database Schema

ColumnTypeDescription
idINTEGERPrimary key
nameSTRINGCommand name (required)
command_set_idINTEGERFK to parent command_set (required)
templateTEXTCommand template string
descriptionTEXTOptional description (no length limit)
argsJSONArray of argument names
arg_optionsJSONObject mapping argument names to arrays of allowed values
systemBOOLEANWhether this command is managed by the driver (default: false)

Import and Export

Exporting Commands

Use the grid Export button to save all commands to a JSON file. To export only specific commands, multi-select them first (click-and-drag or Ctrl+Click) and use Export Selected.

Importing Commands

  1. Click the Import button in the grid toolbar
  2. Select a JSON file containing an array of command objects
  3. A confirmation dialog appears with the number of commands to import
  4. Replace existing commands — check this option to delete all existing commands in the set before importing. This is useful when loading a complete replacement command set rather than merging.
  5. Click OK to proceed
warning

The replace option permanently deletes all existing commands in the command set before importing. Use this only when you want a full replacement, not a merge.

Best Practices

  1. Consistent Naming: Use descriptive command names matching the device protocol (e.g., power_on, volume_up)
  2. Document Templates: Use the description field to explain the template format
  3. Test After Creating: Always test new commands with a real device before deploying
  4. Use Dynamic Values: Prefer [@zone.address] over hardcoded addresses for reusable commands
  5. Group Related Args: Keep argument option lists focused and ordered logically