# JSR223 Jython Scripting

# Configuration

Download the Jython 2.7.0 standalone or installer package, or install through a package repository. Newer versions are not yet supported. Install Jython on the local filesystem and make note of the installation directory location.

The Jython implementation will need to be added to openHAB's Java classpath. How this is done depends on the specific installation technique and operating system.

# Linux Package Installers

Modify the EXTRA_JAVA_OPTS environment variable in /etc/default/openhab2 to:

EXTRA_JAVA_OPTS="-Xbootclasspath/a:/etc/openhab2/automation/jython/jython-standalone-2.7.0.jar -Dpython.home=/etc/openhab2/automation/jython -Dpython.path=/etc/openhab2/automation/lib/python"

This will add the Jython library to the Java classpath, set the Jython home directory and specify the initial Python path for the Jython runtime. Python modules and packages can be installed into the python.path locations and imported from scripts. Note that library modules and packages are not automatically reloaded when they change.

# Mac and Windows or Manual Installation

Set the EXTRA_JAVA_OPTS environment variable to the value described in the Linux configuration. Note that on Windows the environment variable value should be set as a single line (without backslashes to combine the line fragments).

# Configuration Testing

In the automation/jsr223 directory create an empty file called test.py.

Watch the openHAB log file carefully (Karaf logging or viewing the openhab.log file directly). You should see a log line with information similar to:

    ... [INFO ] [s.i.GenericScriptEngineFactory:28   ] - Activated scripting support for ECMAScript
    ... [INFO ] [s.i.GenericScriptEngineFactory:28   ] - Activated scripting support for python
        ...
    ... [INFO ] [.a.m.s.r.i.l.ScriptFileWatcher:150  ] - Loading script 'test.py'

Note

ECMAScript is Javascript

Look for any potentially related error messages.

To enable debug logging, use the Karaf logging commands to enable debug logging for the automation functionality:

log:set DEBUG org.openhab.core.automation

# Script Examples

Jython scripts provide access to almost all the functionality in an openHAB runtime environment. As a simple example, the following script logs "Hello, World!" into the openhab.log file. Note that print will usually not work since the output has no terminal to display the text. One exception is when the openHAB server is running from the Eclipse IDE. The openHAB server uses the SLFJ library for logging.

from org.slf4j import LoggerFactory

LoggerFactory.getLogger("org.openhab.core.automation.examples").info("Hello world!")

Jython can import Java classes. Depending on the openHAB logging configuration, you may need to prefix logger names with org.openhab.core.automation for them to show up in the log file (or you modify the logging configuration).

Note

Be careful with using wildcards when importing Java packages (e.g., import org.sl4j.*). This will work in some cases, but it might not work in some situations. It's best to use explicit imports with Java packages. For more details, see the Jython documentation on Java package scanning.

The script then uses the LoggerFactory to obtain a named logger and then logs a message like:

    ... [INFO ] [.openhab.core.automation.examples:-2   ] - Hello world!

Notice that no rules were required for this simple script. This can be a useful way to experiment with simple Jython code before defining rules or other more advanced functionality.

If you want to respond to openHAB events you can create rules in the scripts. The following script requires two string items, TestString1 and TestString2. The rule created in the script is triggered by an update to TestString1 and, when triggered, the rule updates TestString2.

scriptExtension.importPreset("RuleSupport")
scriptExtension.importPreset("RuleSimple")

class MyRule(SimpleRule):
    def __init__(self):
        self.triggers = [
            TriggerBuilder.create()
                    .withId("MyTrigger")
                    .withTypeUID("core.ItemStateUpdateTrigger")
                    .withConfiguration(
                        Configuration({
                            "itemName": "TestString1"
                        })).build()
        ]

    def execute(self, module, input):
        events.postUpdate("TestString2", "some data")
automationManager.addRule(MyRule())

When a script is loaded, some names are already defined in the script scope (the local Jython namespace). To define rules, you must include some additional script extensions (implemented as "presets") that add more names to the script scope for specific purposes. In this case, the RuleSimple extension is used to import the SimpleRule base class. The RuleSupport extensions provides the automationManager that allows you to register rule instances with openHAB.

The Jython rule class uses the SimpleRule subclass to simplify some aspects of the openHAB interface for use with JSR223. n the constructor, the triggers atribute is set to a list of triggers. In this example, the trigger is a state update trigger. The trigger name identifies the trigger and the configuration direction provides trigger-specific options. For the item update trigger, the configuration provides the item name of the monitored item.

The execute method is invoked when the rule is triggered. The module and input arguments can be used in advanced rules. The information provided varies by the trigger type.

# Resources

  • Scripted Rule Support

    Early documentation on JSR223 usage in openHAB 2. Includes IDE setup instructions.

  • openhab2-jython (github)

    Provides information and examples related to advanced, exploratory openHAB JSR223 Jython usage.

    • Wrappers to simplify Trigger usage in rules.
    • Python decorators to define simple time-triggered and item-triggered functions
    • Python logging bridge to openHAB logger
    • Custom Trigger Implementations: StartupTrigger, OsgiEventTrigger, ...
    • OSGI console command implemented in Jython
    • OH2 Module Implementations in Jython (things, item providers, ...)
    • Jython-based ScriptExtension (preset) provider support.
    • Example of using Pykka Actor library.
    • Unit-testing support