Author: Daniel Bergqvist
Keywords: jmri LogixNG jython

# LogixNG Reference - Chapter 13

## Jython Scripting Support

Jython is an important component provided by JMRI to make it possible to extend the JMRI features. LogixNG continues that ability to run scripts supporting JMRI using the same actions that were part of the original Logix. LogixNG extends that support to include the ability to extend LogixNG itself, by providing access to the LogixNG managers, access to global and local (since 5.7.6) variables and receiving results from a script, etc.

The following is a summary of the scripting options.

- The Script action in chapter 5 provides the basic ability to run Jython commands or call a script.
- The Script expression in chapter 6 provides the ability to run Jython commands or call a script that return true or false.
- Script options are available to initialize global and local variable values. See Variable Types for more details.
- LogixNG has functions that can be called by formula actions. Custom functions can be created using a script. See Jython Functions for details.

The LogixNG includes additional bindings to support LogixNG access.

- logixngs → LogixNG_Manager
- conditionalngs → ConditionalNG_Manager
- globalVariables → GlobalVariableManager
- logixngModules → ModuleManager
- logixngTables → NamedTableManager
- analogActions → AnalogActionManager
- analogExpressions → AnalogExpressionManager
- digitalActions → DigitalActionManager
- digitalBooleanActions → DigitalBooleanActionManager
- digitalExpressions → DigitalExpressionManager
- stringActions → StringActionManager
- stringExpressions → StringExpressionManager

These work like the standard bindings, such as `masts.getSignalMast('mastName')`. For example: `myTable = logixngTables.getNamedTable('tableName')`.

The LogixNG bindings only exist when the script or command is invoked by LogixNG. Other scripts, such as startup actions or scripts run using the script editor, need to create their own LogixNG bindings. Here is an example of creating a binding for the GlobalVariableManager.

    globalVarMgr = jmri.InstanceManager.getDefault(jmri.jmrit.logixng.GlobalVariableManager)

### since 5.7.6Symbol table support

The LogixNG symbol table contains a list of local and global variables. Global variables are also available using the GlobalVariableManager.

Local variables are only in the symbol table. They are also very transient. They only exist during the execution of a ConditionalNG or Module and when within the scope of the logic.

When a script or command is executed by LogixNG, the symbolTable is added to the Jython context as a Python variable. This variable can be used to read and write the content of global variables and current local variables. Note: If strict typing has been enabled for the variable type, that will be enforced.

### Sample script for accessing LogixNG content

A LogixNG ConditionalNG uses two local variables. The time-of-day variable contains a word representing the time of the day. The A1 if then else uses the System Clock function to get the current hour. The script is called to add the word Good to the time of day and update the greeting local variable. Then the current Local Variables are displayed on the JMRI system console. Note: This simple example does not require a script since LogixNG can do the whole process.

The script gets the value of the time-of-day local variable, adds the word Good and updates the greeting local variable

    import java
    import jmri

    greeting = 'Good {}'.format(symbolTable.getValue('time_of_day'))
    symbolTable.setValue('greeting', greeting)

The Log local variables action shows the local variable values.

    WARN  - Log local variables:
    WARN  -     Name: greeting, Value: Good morning
    WARN  -     Name: time_of_day, Value: morning
    WARN  - Log local variables done

### since 5.9.2Call Module Script

A LogixNG Digital Action Module can be called from other JMRI classes or a Jython script. Other LogixNG module types are not supported. There are two options for calling a module.

A single parameter
  When the single parameter option is used, the module must have only one input defined and no outputs.
Multiple parameters
  Multiple parameters are passed as a list of key/value pairs. The key is the name of a module input variable. The presence of other input or output variables is not an issue. An empty key/value list can be used for modules that have no inputs. For Jython, the Python Dictionary is used for the key/value pairs. For Java, use a Map, such as HashMap<String, Object>.

The module call returns immediately. The module is executed using the LogixNG thread. Even though the module might have output parameters, they are not returned to the caller. Notification of completion can be implemented using a property change listener for a standard JMRI object, such as a sensor state set by the module logic.

Simple Module Definitions

    Module: SingleModule ::: In: pinput,
        ! Root
            Log local variables

    Module: MultiModule ::: In: inputA, inputB,
        ! Root
            Log local variables

Jython Script

    import java
    import jmri

    # Get the LogixNG manager and Module manager
    lngmgr = jmri.InstanceManager.getDefault(jmri.jmrit.logixng.LogixNG_Manager)
    modmgr = jmri.InstanceManager.getDefault(jmri.jmrit.logixng.ModuleManager)

    # Get the modules using the LogixNG ModuleManager
    single = modmgr.getModule('SingleModule')
    multi = modmgr.getModule('MultiModule')

    # Create a single value to be passed to the module
    # Note:  The actual parameter input name is 'pinput'.  The single value is assigned to the single module input.
    param = 'abc'
    lngmgr.executeModule(single, param);

    # Define and populate a Python dictionary. The keys are the module parameter names.
    pmap = {}
    pmap['inputA'] = 'qrs'
    pmap['inputB'] = 'xyz'
    lngmgr.executeModule(multi, pmap);

Log Local Variables Output

    WARN  - Log local variables:
    WARN  -     Name: pinput, Value: abc, java.lang.String
    WARN  - Log local variables done

    WARN  - Log local variables:
    WARN  -     Name: inputB, Value: xyz, java.lang.String
    WARN  -     Name: inputA, Value: qrs, java.lang.String
    WARN  - Global variables:
    WARN  - Log local variables done

Jython access to LogixNGs and ConditionalNGs

The ability to invoke LogixNGs and ConditionalNGs can also be done using a Jython script. Instead of using `lngmgr` to get a module, a LogixNG can be accessed.

    lng = lngmgr.getNamedBean(<name>)    # User name or system name

Use the `execute()` method to process all of the enabled ConditionalNGs in the LogixNG.

    lng.execute()

To invoke a single ConditionalNG, get the ConditionalNG from the LogixNG and execute it.

    cng = lng.getConditionalNGByUserName(<user name>)   # or lng.getConditionalNG(<system name>)
    cng.execute()

Return to the Reference TOC