LogixNG Reference - Chapter 7


The following discussion refers to {name}. This can be either a JMRI memory variable or a LogixNG Local Variable.

LogixNG can use references to access layout items like turnouts in an indirect way. It's done by entering the system name or user name in curly brackets. If a turnout action has the turnout IT1, it will access that turnout directly. But if the turnout action has the turnout {IM2}, it will read that memory and if that memory has a string as a value, it will use that string value to find the turnout. So if the memory IM2 has the value IT5, and the turnout action has the turnout {IM2}, the turnout action will read the memory IM2 and find out that it points to the turnout IT5 and therefore do it's action on turnout IT5. The benefit of this is that the Memory can be changed during execution and therefore the same turnout action can be used to access different turnouts at different times.

It's possible to use indirect access recursive. If a turnout action has the turnout {IM5}, and that Memory has the value {IM14}, and that the Memory IM14 has the value IT3, the turnout action will access IT3. The turnout action has an indirect turnout IM5 so it will read that Memory. And since that memory has the value {IM14} which also is an indirect access, it will read the memory IM14 and find out that it has the value IT3, and therefore use IT3. This is also true for tables. If the cell IQT1[5,3] has the value '{IM3}', and the memory IM3 has the value 'IT5', the cell IQT1[5,3] will point to IT5.

When the Reference tab is selected, the appropriate values are entered into the text field. References are the name of a local variable, memory or table cell, enclosed in curly brackets.

Chapter 7 reference tab

Some examples:

Reference Description Note
{MyLocalVariable} The value of the local variable MyLocalVariable The name is in the symbol table
{My memory} The value of the memory My memory
{{My other memory}} Double reference, the value of the value
{My table[North yard, Left turnout]} The value of the cell at the intersection of the row name and column name
{My table[{Yard}, Left turnout]} Same as above except the row name comes from a reference
{My table[North yard, {Turnout selection}]} Same as above except the column name comes from a reference
{{TableName}[North yard, Left turnout]} The table name comes from a reference, which becomes a reference
{{TableName}[{Yard}, {Turnout selection}]} Everything comes from a reference, which becomes a reference

Local variables are described in Chapter 8 - Local variables.

Tables are described in Chapter 11 - Tables.

Indirect adressing of NamedBeans

In some cases, it may be useful to use indirect addressing of NamedBeans.

This can be done in two ways:

Using a Memory that has the name of the NamedBean

Lets say we have a Turnout action that should throw a particulat turnout. But we wnat to be able to select which turnout to throw at a later time. We can solve that by storing the system name or user name in a Memory. We then tell the Turnout action to read the Memory and lookup the turnout on the fly.

Since LogixNG fully supports string manipulation and calculations of both integers and floating point values, where are plenty of possibilities here.

Listen on beans

There is one major drawback with this. Since LogixNG doesn't know in advance which NamedBeans (turnouts, sensors, etc.) will be accessed indirectly, it's not possible for LogixNG to automaticly register listeners to the named beans that should trigger on change. For example, a Turnout expression registers a listener on the turnout, if the name of the turnout is given, but if the Turnout expression is using indirect addressing of the turnout, it's not able to do that.

The solution is to use the Listen on beans action and tell this action which beans to listen on. Any time any property of any of the named beans this action listens to changes, the ConditionalNG will be executed.

LogixNG listen on beans dialog

The Add reference button is used to add beans to the the list. For each bean select the bean type, the bean name from the drop down list and whether the standard events for the selected bean should be monitored or if all of the events are monitored.

There are three optional fields for specifying local variables that will contain the name of the bean, the event type and the new value. For example, a sensor has a KnownState event with the new value being 2 (Active) or 4 (Inactive).

If the optional local variables are used and the Listen On Beans action is part of a copy/cut/paste, the local variable names will be included in the paste action. If the same names have not been defined in the target ConditionalNG, a LogixNG exception will occur. Make sure the paste destination has those local variables defined.


A ConditionalNG is using turnouts IT1, IT2, IT3, IT4 and IT5 in it's expressions and wants each of them to trigger on change. Turnouts IT1 and IT3 and IT4 are directly accessed in expressions and IT2 and IT5 are indirect accessed.

Each turnout that is directly addressed in an expression will have the ConditionalNG listen to automatically, so IT1, IT3 and IT4 will be listend to. But in order to listen on turnouts IT2 and IT5, the Listen on beans action needs to be used.

The Listen on beans action can be placed anythere in the ConditionalNG tree, as long as it and its parents are enabled. If you disable this action, or any of its parent actions, the Listen on beans action will not listen on its named beans.

Chapter 8 - Local Variables

Return to the Reference TOC