There are two ways to use the iPeng command.

XML File Configuration

The simple one is to just generate an XML file for the command.

You can add your own customized commands by creating a XML file that follows the specification described in the XML Interface Data Specification below. The XML file needs to have the extension .ipeng.xml and must be stored in the directory you have specified in the iPeng section of SqueezeCenter Settings.

Plugin Registration

The alternative way is to register the plugin directly

A plugin can register one or several commands, the attributes specified by the plugin is the same as those described in the XML Interface Data Specification section below. There are three different functions that can be used by a plugin when registering commands:

  • Plugins::iPeng::Plugin::addSubSection
    Registers a new sub section, this needs to be used if you like to set a name or sorting order of the plugin specific sub sections you are going to use when registering commands. If called twice for the same sub section, this function will update the existing sub section with new values.
  • Plugins::iPeng::Plugin::addCommand
    Registers a single command in the specificed section and sub section. If called twice for the same command this function will update the existing command with new values.
  • Plugins::iPeng::Plugin::deleteCommand
    Removes a previously registered command from the specified section and sub section.

A typical plugin would register its commands in the initPlugin function by calling addSubSection once for each sub section used by the plugin and addCommand once for each command that should be registered. Typically there is no reason to call the deleteCommand, the reason it exists is if a plugin likes to have dynamic commands that disapears due to some configuration or state change in the plugin, you don’t need to call deleteCommand when shutting down the plugin.

The following code shows an example how you register a new sub section and add command to it:

# Only perform the registration if the iPeng plugin is installed
if(UNIVERSAL::can("Plugins::iPeng::Plugin","addCommand") && UNIVERSAL::can("Plugins::iPeng::Plugin","addSubSection")) {
    # Prepare sub section registration data
    my %subsection = (
        'weight' => 10,
        'name' => 'CB Info',
    eval { Plugins::iPeng::Plugin::addSubSection('nowplaying','custombrowse',\%subsection) };
    if ($@) {
    $log->warn("Failed to register iPeng command:\n$@");
    # Prepare command registration data
    my %command = (
        'weight' => 10,
        'name' => 'Song Info',
        'icon' => 'html/images/infobutton.png',
        'url' => 'plugins/CustomBrowse/custombrowse_contextheader.html?hierarchy=group_track&contexttype=track',
        'type' => 'content',
        'parameters' => {
            'id' => 'contextid',
            'title' => 'contextname',
            'player' => 'player',
    # Register the new
    eval { Plugins::iPeng::Plugin::addCommand('nowplaying','custombrowse','custombrowse_songinfo',\%command) };
    if ($@) {
    # Something went wrong
    $log->warn("Failed to register iPeng command:\n$@");

Command Usage

The use of the ipeng command is not limited to iPeng itself. As long as the plugin is installed, any application can use it by calling

ipeng commands <section>

through CLI or JSON/RPC interfaces (please refer to the SqueezeCenter documentation if you don’t know what that is).

As a result, iPeng will deliver an array of interface data as described in the XML specification