Software documentation

Development tools


Techniques and Standards

How To

Functional Info

Background Info

JMRI: Names and Naming

This page discusses how JMRI objects are named, how those names are used to reference the objects (hardware and software), and how user-readable names are used. As of February 2017, we are considering a change to the allowable user names: They can't have leading or trailing spaces. If this change is made, the names will be "trimmed" whenever entered. If you have a copy of the code checked out, you can test this by modifying the jmri.NamedBean class following the instructions in the normalizeUserName(..) routine, rebuilding and running

What's in a name?

Why do we need names at all, rather than just references within the code? There are several important uses:
  1. When working with user input, e.g. typing a number in a field, the code will need to know how to map the user-provided info onto objects. Sometimes the user will want to name objects with arbitrary user names, e.g. "East Lockport Turnout". These can't be known until their mapping to hardware has been made. But other times these will be de-novo identifications that the code must understand, e.g. something that means "LocoNet Turnout 23".
  2. We imagine that configurations will be stored in XML files, in a symbolic form. Names are a convenient way to connect objects and object references in that kind of configuration.

Items with names

There are lots of things that might need names: Some of these are associated with a specific hardware device, e.g. a particular turnout. Others are more virtual, e.g. a route, which is a collection on control information within the program.

System and User Names

JMRI users both "system names" and "user names" to reference things.

We want users to be able to call things what they want. Names like "p(24,23)*" are not useful. Every named item will therefore have a "user name", which is an entirely free-form string. You can put whatever you want in there, so long as it's not a duplicate of the name given to something else. For example, you might call a Turnout "West Yard Lead" or "Turnout 32" or "Green Wire from Controller" or whatever.

At the same time, we need a shorthand name, really a unique identifier, to talk about specific objects. This doesn't have to be convenient, but does have to have a clear mapping from name to object and back. For example, we need a very specific way to identify "LocoNet Turnout 23". We call these "system names". JMRI code will map these to and from whatever information the hardware may need.

System Name Format

A system name is formed from a short prefix representing the hardware system, followed by a single upper case letter indicating the type, followed by system- and type-specific string identifying a specific object. The string is meant to be related to the hardware addressing, but is otherwise unconstrained.


Note that there is no assumption of pattern to the names; they don't have to be assigned monotonically, nor are they restricted to a single system.

Hardware Prefix

Originally, the "hardware prefix" was a single uppercase letter identifying a single system connection: L for LocoNet, N for NCE, etc. The default letters for those are listed below. This is still by far the most common use: Most model railroads have a single connection, and just use the default letter.

The JMRI code is much more flexible than that, however. This allows it to deal with multiple system connections and overlaps of letters (such as the multiple possibilities defined for "M" below). You change the letter associated with a system connection in the preferences to any other uppercase letter. You can call your NCE connection "P" if you want to. If you have two of them, you can call one "X" and the other "Y". You can also use an upper case letter followed by digits, e.g. "N1" and "N2".

Default System Letters

Note that some of these are placeholders, and have no underlying implementation. (Links are to JMRI pages with more information)

Device type letters

Note that some of these are placeholders, and have no underlying implementation. Also, there is no guarantee that any given hardware system will ever implement all of them.

System-specific info

Each different hardware system can specify the "string" that follows the system and type letters. Generally, these are small numbers, but their exact meaning is very system-specific. For more information, please see the specific pages for (If you find any missing, please add a reference)

"Internal" objects can also be addressed and manipulated, but they don't have a strict correspondence with some hardware on the layout. For example, if a signal head is implemented as three different outputs, LT1, LT2 and LT3, the signal head object might be called IH3.

Naming Conventions For Automated Use

Some higher-level constructs create their own items. For example, a "Sensor Group" is really just a collection of Routes that implements the sensor group logic; there is no specific object in the program that implements the sensor group. Instead, when the user creates sensor group "my group", a series of routes with system names like:


are created which implements the group. The sensor group tool knows to look for routes of this name.

To make this possible, two informal rules are used:

The list of tools currently working this way is:


For Programmers

The code to make sure that names are in normal form has been localized to a single routine for user names:

          String userName = NamedBean.normalizeUserName(input);

Because system names may vary from type to type and manager to manager, this is manager-specific for them:

          String systemName = manager.normalizeSystemName(input);

For more information, see the Javadoc for normalizeUserName and normalizeSystemName

In general, it's better to use an input method that already handles all this. Two are available now: