Anytime Help Center

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  • Support
  • Guest
  • Log In
  • AKG
    Microphones Wireless Integrated Systems Automatic Mixers Headphones Discontinued Products (AKG) General AKG Inquiries Certifications (AKG) Video Manual Series (AKG)
  • AMX
    Networked A/V Distribution (AVoIP) Traditional A/V Distribution Video Signal Processing Architectural Connectivity User Interfaces Control Processing Power (AMX) Programming (AMX) Software (AMX) Discontinued Products (AMX) Video Manual Series (AMX) General AMX Inquiries Certifications (AMX)
  • BSS
    Soundweb™ Omni Soundweb™ London Soundweb™ Contrio™ Software (BSS) Discontinued Products (BSS) Video Manual Series (BSS) General BSS Inquiries Certifications (BSS)
  • Crown
    CDi DriveCore Series CDi Series Commercial Series ComTech Series DCi DriveCore Series I-Tech HD Series XLC series XLi Series XLS DriveCore 2 Series XTi 2 Series Discontinued Products (Crown) Software (Crown) General Crown Inquiries Certifications (Crown) Video Manual Series (Crown)
  • dbx
    CX Series 500 Series DriveRack Personal Monitor Control ZonePRO Zone Controllers FeedBack Suppression Microphone Preamps Dynamics Processors Crossovers Equalizers Software (dbx) Discontinued Products (dbx) General dbx Inquiries Certifications (dbx)
  • Flux::
    Immersive Processing Analysis Subscriptions General FLUX: Inquiries
  • JBL
    Cinema Sound Installed Live Portable Tour Sound Recording & Broadcast Software (JBL) Discontinued Products (JBL) Video Manual Series (JBL) General JBL Inquiries Certifications (JBL)
  • Lexicon
    Plugins Effects Processors Cinema Discontinued Products (Lexicon) Video Manual Series (Lexicon) General Lexicon Inquiries Certifications (Lexicon)
  • Martin
    Atomic ELP ERA Exterior MAC P3 VC VDO Tools Discontinued Products (Martin) General Martin Inquiries Certifications (Martin)
  • Soundcraft
    Digital Analog Connected Analog Only Discontinued Products (Soundcraft) Video Manual Series (Soundcraft) General Soundcraft Inquiries Certifications (Soundcraft)
  • General HARMAN Inquiries
    Dante
+ More
  • Home
  • AMX
  • Programming (AMX)
  • Muse

Device Descriptor Guide

Technical Support Guide


Written by Wesley Moore

Updated at August 27th, 2026

Table of Contents

Brand: Models: Download: Overview JSON File Descriptor Outline Building Blocks Paths Parameters .type .default .min .max .enums .access .enabled .flags Examples Boolean Parameter Floating Point Parameter Enumeration Parameter Objects  Driver Object Arrays Homogeneous Arrays Array of Parameters Heterogeneous Arrays Heterogeneous Array Commands Arguments Command with Arguments Command without Arguments Events Event with Arguments Metadata Header Block Metadata Header Driver Configuration Driver Configuration

Brand:

  • AMX

Models:

  • MU-1000
  • MU-1300
  • MU-2300
  • MU-3300

Download:

Device Descriptor Guide.pdf


Overview

This is a guide to writing descriptors for Mojo device drivers.  While much of this content is common with HControl descriptors contained in HControl native devices; a portion of this is specific to the Mojo driver system.

 

JSON File

A descriptor file is a JSON compliant text file assumed to be in UTF-8 format even though most just use ASCII.  The general rules and syntax of a JSON file can be found at https://www.json.org/.  A JSON schema has been written to help define the requirements of a driver descriptor and a link to it can be included in the descriptor itself.  When doing this, it allows many editors to download the schema and use it to help highlight any errors you may have as well as support autocomplete in some editors.

 

Descriptor Outline 

{
   "$schema": "https:// "https://developer.amx.com/schema/amx-mojo-program-1.0.json",

   ".metadata": {
       "$comment": "See Metadata Block section below"
   },

   ".kind": "obj",

   "configuration": {
       ".kind": "obj" {
       "driver": {
           ".kind": "obj",
           "$comment": "See Driver Configuration section below"
       }
   },

   "$comment": "Body of descriptor goes here"
}
 

The different sections will be described below but notice the "$schema" entry on the second line.  This is the magic that allows editors to become intelligent about the proper structure of a driver descriptor file.

The following editors have been tested with the descriptor schema.

Editor

Error Detection

Autocomplete

Comments

Eclipse

*

  Web Developer's plugin must be installed
VS Code

*

*

 
IntelliJ CE

*

*

 

 

Building Blocks

There are five main building blocks in a descriptor file:

Item

".kind" value

Definition
Object "obj" Objects (aka Components) provide additional nested children items for organizational purposes. Objects may contain parameters, commands, events, arrays and additional nested child objects.
Parameter "param" Parameters provide run-time access controlled (read-only/write-only/read-write) value information about a device state or device capability. Parameters are observable and provide state. Parameter examples may include things like a mute control (read-write) or a meter (read-only)
Array "array" Arrays provide the same functionality as Objects except that they are addressed by a numeric index instead of a string name.  In Mojo, arrays can be homogeneous or heterogeneous.  Meaning their entries can be all identical (like a traditional array) or each entry can be unique.  Heterogeneous arrays, while supported by Mojo may not be portable to all devices in the HControl ecosystem.  Arrays may contain parameters or objects.  Arrays of arrays, commands, and events are currently not supported.
Command "command" Commands provide run-time (control) functionality that can be invoked against a device entity. Commands do NOT provide state. Command examples may include things like "reboot".
Event "event" Events describe run-time unsolicited events raised by a device entity. Events do NOT provide state. Events are observable and include event hooks where event consumers can optionally subscribe to event triggers. Event examples may include events like “PRESET-SELECTED” where a device raises the event notification when a preset has been selected by the user.

 

Each building block can be annotated with attributes to provide information regarding the block. 

Not every attribute can be used in every ".kind" of descriptor item. Below is an overview of the possible fields within an item type.

Note also that only some attributes may be used in objects that are defined in an ".arguments" attribute value sequence of objects.

 

Object

Array

Parameter

Command

Event

Objects in 
".arguments"

Description

.metadata

*

*

*

*

*

*

A list of name/value pairs that are not well known
.kind

*

*

*

*

*

  The kind of the item - object, array, parameter, command, or event
.name

*

*

*

*

*

  Optional name for the item
.scope

*

*

*

      Either "configuration" or not
.class

*

 

*

      FQDN describing a well-known item type (e.g. com.harman.common.frequency)
.size  

*

        The size of an array
.prototype  

*

        The definition of the array entry if all are identical.
.items  

*

        A list of array entries definitions if all are not identical.
.type    

*

   

*

The type of a value (integer, float, string, enum, boolean, byte_array) 
.default    

*

   

*

The default value of a value
.min    

*

   

*

The minimum of a value
.max    

*

   

*

The maximum of a value
.enums    

*

   

*

A list of strings denoting the legal enumerations of an enum
.access    

*

      Read, Write, Read Write, Constant
.enabled    

*

      Whether the parameter is enabled, defaults to false 
.flags    

*

      A list of strings denoting flags that are true
.arguments      

*

*

  A list of arguments to a command or event
.optional          

*

Whether the argument to a command is optional.  Not applicable for events.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Paths

A descriptor is a tree structure made of these 5 building blocks.  The root of a descriptor is always an object.  Objects can contain other objects as well as parameters, arrays, commands and events.  Arrays are also container nodes that can contain objects and parameters.  Parameters, commands, and events are always leaf nodes.  For each node there is a "path" that defines its place in the tree.  The path is built using the names of the container nodes (objects and arrays) that are used to navigate to a leaf node separated by a forward slash ("/").  The leading slash in a path is optional.  Entries in an array are named after the array index. 

For example, if you had an object named "audio" that contains an array named "gain" which holds 10 parameters to control 10 gains; the third gain control would be called "/audio/gain/2".  Note that arrays are zero based, so the third parameter is named "2".


Parameters

Parameter nodes in a descriptor represent a single value that may change over the life of the system.  Parameters may be subscribed to and will automatically update watchers any time the parameter changes.  Also, parameters hold state and their value can be retrieved at any time.  At a minimum, all parameters should have at least ".kind" and ".type" defined, as well as '.enums' if the ".type" is "enum".  Other attributes will have defaults if they are not specified but the author should not depend on those defaults and specify all attributes.

 

 .type

The ".type" attribute defines the type of a parameter.  Valid types are:

.type

Comments

boolean A boolean value, represented by the Java boolean type.
integer An integer value, represented by the Java long type.
float A floating point value, represented by the Java double type.
enum An enumeration.  Enumerations are always presented to a driver as an integer but are represented to scripts as a String
string A string.  Mojo and HControl support UTF-8 encoding so a string may contain unicode characters
byte_array A binary blob, represented as an array of Java bytes.

 

.default

The ".default" attribute defines the default value of a parameter.  This is the value that will be shown to the world before the driver makes its first 'update' to the parameter.  If a parameter has an ".access" set to 'c' (i.e. constant) then it is assumed a driver will never update the value, and systems can rely on the ".default" value to always be the correct value.  An example of this would be "manufacturer" of the driver or "MAC Address" of the unit.

 

.min

The ".min" attribute has different meanings depending on the ".type" attribute.  For a type of boolean, it should be excluded.  For the numeric types, it specifies the minimum legal value of the parameter (inclusive).  If not specified, the minimum will be set to the minimum legal value in the native types.  For string, dstring, and byte_array, the minimum represents the minimum length of the parameter (defaults to zero).  And for enumerations, the minimum value is the starting index of the array of enumerations (defaults to zero).  For example, if you have an enumeration of COLD, WARM, HOT then a minimum of zero would cause their values to be COLD=0, WARM=1, HOT=2; however, if minimum was set to one the values would be COLD=1, WARM=2, HOT=3.

 

.max

The ".max" attribute has different meanings depending on the ".type" attribute.  For a type of boolean, it should be excluded.  For the numeric types, it specifies the maximum legal value of the parameter (inclusive).  If not specified, the maximum will be set to the maximum legal value in the Java native types.  For string, dstring, and byte_array, the maximum represents the maximum length of the parameter.  For enumerations, the maximum is calculated as the (.min + number of enums - 1) so it can be safely omitted.

 

.enums

The ".enums" attribute is an array of strings that represent the names of the legal enumeration values.  The attribute is mandatory if the ".type" attribute is "enum" and should be omitted otherwise.

Hint: Since enumerations can be accessed by either their index or name, it is often good to order them so that the index is intuitive.  For example, if you had an enumeration of ON and OFF, it would be better to order them OFF, ON so that OFF=0 and ON=1

 

.access

The ".access" attribute specifies the read/write access of the parameter.  It will default to "rw" (read/write) if not provided.  Valid values are:

.access

Comments

c The value is a constant and will never change.  The driver author will not need to code for this parameter since the driver system will always give back the “.default" value in the descriptor and never query the driver for its value.
ro The value is read only.  This differs from the constant in that ro values can change, they just can't set by the system.  Examples could be a audio meter, a button press/release, or the outdoor temperature.
rw The value is read/write.  This represents a value that can be set by system.
wo The value is write only.  Primarily support just for completeness but has been used for passwords.

 

.enabled

Enabled/disabled parameters are currently not supported and this attribute should be omitted.

 

.flags

Flags are currently not supported, and this attribute should be omitted.


Examples

A boolean parameter that is read/write and advertises as true prior to any updates.

Boolean Parameter 

"booleanParam" : {
   ".kind": "param",
   ".type": "boolean",
   ".default": true,
   ".access": "rw"
}
 

A floating point parameter describing a gain control.

Floating Point Parameter

"gain" : {
   ".kind": "param",
   ".type": "float",
   ".min": -90.0,
   ".max": 0.0,
   ".default": 0.0,
   ".access": "rw"
}
 

An enumeration for outdoor temperature.  Note that, while not considered good practice, the parameter name can contain spaces.

Enumeration Parameter 

"outdoor temp": {
   ".kind": "param",
   ".type": "enum",
   ".enums": [ "COLD", "WARM", "HOT" ],
   ".access": "ro"
}
 


Objects 

Objects are nodes that contain other nodes which can be accessed by name.  The top level of a descriptor is always an object.  An object can contain any node type: parameters, arrays, commands, events and other objects.

Hint: Objects assume children with names beginning with dot (".") are attributes, even if it doesn't recognize the attribute.  Therefore, node names cannot start with dot.

 

Example of a top driver object, with two sub-objects and each sub-object containing a single parameter.

Driver Object 

{
   ".metadata" : {
       See "Metadata Header Block" section below for details of driver's metadata header
   }
   ".kind": "obj",
   "weather": {
       ".kind": "obj",
       "outdoor temp": {
            ".kind": "param",
            ".type": "enum",
            ".enums": [ "COLD", "WARM", "HOT" ],
            ".access": "ro"
       },
   "audio": {
        "gain" : {
            ".kind": "param",
            ".type": "float",
            ".min": -90.0,
            ".max": 0.0,
            ".default": 0.0,
            ".access": "rw"
        }
   }
}
 


Arrays

Arrays are nodes that contain other nodes which can be accessed by index.  Mojo supports both heterogeneous and homogeneous arrays.  That is, an array can have all its elements identical, or the elements can change based on the index. 

 

Homogeneous Arrays

For a homogeneous array, there are two attributes that define the array: 

Attribute

Required

Comments

.prototype required An object or parameter that defines each entry of the array
.size required The size of the array

While Objects can contain any type of descriptor node, Mojo only supports the inclusion of Objects and Parameters in an array.  If an array of arrays is required, the driver author must create an array of objects and have the object contain the second array.  Arrays of commands and events are also not supported.

 

An array of 10 gain parameters.  The gain controls in this example would be accessed as gain[0] through gain[9].

Array of Parameters

"gain": {
  ".kind": "array",
  ".size": 10,
  ".prototype": {
      ".kind": "param",
      ".type": "float",
      ".min": -90.0,
      ".max": 0.0,
      ".default": 0.0,
      ".access": "rw"
   }
} 

 

Heterogeneous Arrays

It is sometime convenient to have different content in each array index.  This might be for something as simple as each index has a different ".default" value as would happen in an array of equalizer elements.  Or it could be an array of LEDs, some of which are multicolor and some are not.  To support the ".items" attribute is used:

Attribute

Required

Comments

.items required An array of objects or parameters that define each entry in the array
.size optional The Mojo driver system will use the length of .items to determine the size of the array, but .size may be included for completeness

The length of the array is defined by the length of the ".items" attribute and the ".size" attribute is not required and will be ignored.

 

Here is an array of 3 LEDs which don't have the same colors.

Heterogeneous Array 

"led": {
   ".kind" : "array",
   ".items": [
        {
            ".kind": "param",
            ".type": "enum",
            ".enums": [ "OFF", "ON", "GREEN", "RED", "ORANGE" ],
            ".min": 0,
            ".default": 0
        },
         {
            ".kind": "param",
            ".type": "enum",
            ".enums": [ "OFF", "ON", "GREEN", "RED", "ORANGE" ],
            ".min": 0,
            ".default": 0
        },
         {
            ".kind": "param",
            ".type": "enum",
            ".enums": [ "OFF", "ON", "GREEN", "RED", "ORANGE" ],
            ".min": 0,
            ".default": 0
        },
        {
            ".kind": "param",
            ".type": "enum",
            ".enums": [ "OFF", "ON" ],
            ".min": 0,
            ".default": "OFF"
        }
   ]
}
 

Note: The ".prototype" and ".items" attributes should never both be used in an array definition.  Any such definition is not supported and the results are undefined.


Commands

Commands represent a stateless message that has effect on the device.  Example could be "cycle mute" on a TV.  The TV could have a "mute" parameter that can be read and set but cycling the mute would be a command.  Another example would be sending data out a serial port.  The serial port wouldn't have any state but you could still command it to send data.  Commands can have arguments.  In the HControl protocol, command arguments are sent named; however, in scripting environments, they are often in an un-named list (function call arguments).  Commands have one attribute, which is optional:

Attribute

Comments

.arguments An object containing a description of each argument

 

Arguments

Arguments are similar (subset) to Parameters.  Arguments can have ".type", ".min", ".max" and ".enums" as attributes.  For each attribute the Argument attributes have the same behavior as described above for Parameter attributes.  In addition to these inherited Parameter attributes, arguments add two new attributes.

Attribute

Comments

.ordinal JSON does not honor the ordering of objects.  So, while it seems intuitive to define the arguments in the correct order this is not sufficient.   This attribute defines the order of the arguments. 
.optional This specifies that the argument is optional and can be omitted from the command.  To have this work well with scripting languages, optional arguments should always be at the end of the argument list.

 

An example of a command to switch an input to an outpoint on a 10 x 10 matrix switcher.  Notice that the arguments do not have a ".kind" attribute since it is known that they are Arguments.

Command with Arguments

"switch": {
   ".kind": "command",
   ".arguments": {
        "input": {
           ".type": integer,
           ".min": 0,
           ".max": 9,
           ".ordinal": 0,
           ".optional": false
       },         
       "output": {
           ".type": integer,
           ".min": 0,
           ".max": 9,
           ".ordinal": 1,
           ".optional": false
       }
   }
}


A simple "cycle mute" command with no arguments.

Command without Arguments

"cycleMute": {
   ".type": "command"
}
 


Events

Events are effectively the opposite of commands.  They are stateless messages that are emitted from the device instead of being sent to it.  Like Commands they have a single attribute named ".arguments".  The Event arguments, in turn, are the same as the Command arguments except that the ".optional" attribute doesn't apply since the device would always send all arguments.  The most common example of an event is receiving data from a serial port.

 

A serial port receive event.

Event with Arguments

"receive": {
   ".type": "event",
   ".arguments": {
       "data": {
           ".type": "byte_array",
           ".min": 1
       }
   }
}


Metadata Header Block

This is driver specific and not applicable to general descriptors

Metadata in descriptors isn't formally defined for all.  Instead, the metadata is designed to be only understood by certain systems while allowing other systems to ignore it.  The metadata at the root of a driver descriptor is such a case.  The Mojo driver system requires the following information to be in the metadata to properly handle the descriptor.  

Key

Required

Type

Value

id required string A fully qualified domain name (FQDN) that uniquely identifies this driver descriptor.  For example "com.amx.thing.denon"
description optional* string A human readable description of the driver for use in user interfaces
manufacturer optional* string The name of the manufacturer of the device(s) supported by the driver
models optional* array of strings An array of strings listing the model names of the devices that are supported by the driver

 * even though marked as optional, these fields are highly desired

 

Metadata Header 

{
   ".metadata": {
       "id": "com.smarthometek.thing.denon.3312CI",
       "description": "Denon A/V Receiver",
       "manufacturer": "Denon",
       "models": [
           "3312CI"
       ]
   }
}
 


Driver Configuration

This is driver specific and not applicable to general descriptors

The driver author can tell the system what types of configuration data it requires.  Any descriptor nodes below the path of "/configuration/driver" are taken to be configuration data required by the driver.  This information will be requested from the installer and passed to the driver on startup in its driver.config structure.

Below is an example of the configuration that might be needed by a driver that uses a serial port.  Note that the driver author might know that their device only supports certain settings on a serial port so some of the fields below could be removed for brevity.

 

Driver Configuration

{
   "configuration": {
       ".kind": "obj",
       "driver": {
           ".kind": "obj",
            ".scope": "configuration",
            "comm": {
                ".type": "string",
                ".metadata": {
                    "displayOrder": 0,
                    "title": "Serial Port",
                    "description": "Serial port device name"
                }
            },
            "baudrate": {
                ".type": "integer",
                ".default": 9600,
                ".metadata": {
                    "displayOrder": 1,
                    "title": "Baud Rate",
                    "description": "Serial communication baud rate"
                }
            },
            "parity": {
                ".type": "enum",
                ".enums": [ "NONE", "ODD", "EVEN", "MARK", "SPACE" ],
                ".default": "NONE",
                ".metadata": {
                    "displayOrder": 2,
                    "title": "Parity",
                    "description": "Serial communication parity"
                }
            },
            "databits": {
                ".type": "integer",
                ".min": 7,
                ".max": 8,
                ".default": 8,
                ".metadata": {
                    "displayOrder": 3,
                    "title": "Data Bits",
                    "description": "Serial communication data bits"
               }
            },
            "stopbits": {
                ".type": "integer",
                ".min": 1,
                ".max": 2,
                ".default": 1,
                ".metadata": {
                    "displayOrder": 4,
                    "title": "Stop Bits",
                    "description": "Serial communication stop bits"
                }
            }
       }
   }
}
 

There are several things to notice in this example.  First and most important, all the parameters are hanging off the "/configuration/driver" branch of the descriptor.  When the system reads in this descriptor, it will remove this branch so that script writers or HControl clients will not confuse it with controls of the product.  It will then take these items and store them as configuration requirements.  This will cause the system to query the installer for the information during system configuration.

The ".scope" attribute is effectively legacy and not currently used by the system but should be included for safety.

The ".default" value for each configuration item will be pre-filled in the configuration GUI saving time and frustration for the installer and any input to the configuration GUI will be type and range checked against ".type", ".min", and ".max".

Finally, we have some new fields in the ".metadata" section.  The configuration GUI will use these to decorate the dialog.  "title" will be used for the field label and "description" will be used as a tool-tip.  If not included, the system will use the node id for both.  "displayOrder will force the order of the entry fields on the dialog.  Without "displayOrder" the order will be semi-random.

 

All .metadata for the configuration blocks are optional.

Key

Value

Comments

displayOrder integer Places the field in order of value.  Order values can be zero or one based
title String Human readable label for the field
description String Human readable description for the field to be used for tooltips, etc.
password boolean Forces the user interface to use "*" characters instead of echoing typed characters.  Defaults to false.
optional boolean Allows the field to be uninitialized.  Defaults to false.

 

 


 

Related Videos

Was this article helpful?

Yes
No
Give feedback about this article

Table of Contents

Brand: Models: Download: Overview JSON File Descriptor Outline Building Blocks Paths Parameters .type .default .min .max .enums .access .enabled .flags Examples Boolean Parameter Floating Point Parameter Enumeration Parameter Objects  Driver Object Arrays Homogeneous Arrays Array of Parameters Heterogeneous Arrays Heterogeneous Array Commands Arguments Command with Arguments Command without Arguments Events Event with Arguments Metadata Header Block Metadata Header Driver Configuration Driver Configuration

Related Articles

  • Muse Mutually Exclusive helper
  • File Read Write with MUSE
  • MUSE Controller-to-Controller Programming with Python
  • Controlling CE-REL8 Relay Ports with Python Code
  • Controlling MUSE Relay Ports with Python Code

Related Articles

  • Muse Mutually Exclusive helper
  • File Read Write with MUSE
  • MUSE Controller-to-Controller Programming with Python
  • Controlling CE-REL8 Relay Ports with Python Code
  • Controlling MUSE Relay Ports with Python Code
Copyright © HARMAN Professional. All rights reserved. Privacy Policy | Terms of Use
Expand