<commit_before># Jython scripting for openHAB 2.x

This is a repository of experimental Jython code that can be used 
with the [Eclipse SmartHome](https://www.eclipse.org/smarthome/) platform and [openHAB 2](http://docs.openhab.org/) Jython scripting. 
Also see the [openHAB 2 scripting documentation](http://docs.openhab.org/configuration/jsr223.html).

_NOTE: To use Jython for defining rules, the Experimental Rule Engine add-on must be installed in openHAB 2._

## Applications

The [JSR223 scripting extensions](https://www.jcp.org/en/jsr/detail?id=223) can be used for general scripting purposes, 
including defining rules and associated SmartHome rule "modules" (triggers, conditions, actions). 
Some possible applications include integration testing of complex rule behaviors or prototyping new OH2/ESH functionality.

(_JSR223_ refers to a Java specification request for adding scripting to the Java platform. 
That term will not be used in Java versions 9 and above. 
The previous JSR223 functionality will be provided by the Java `javax.script` package in the standard runtime libraries.)

The scripting can be used for other purposes like automated integration testing 
or to access the OSGI framework (using or creating services, for example).

## Jython Scripts and Modules

It's important to understand the distinction between Jython _scripts_ and Jython _modules_. 
In this repo, scripts are in the `scripts` directory and modules are in the `lib` directory.

A Jython script is loaded by the `javax.script` script engine manager (JSR223) integrated into openHAB 2. 
Each time the file is loaded, OH2 creates a execution context for that script.
When the file is modified, OH2 will destroy the old script context and create a new one.
This means any variables defined in the script will be lost when the script is reloaded.

A Jython module is loaded by Jython itself through the standard Python `import` directive and uses `sys.path`.
The normal Python module loading behavior applies.
This means the module is loaded once and is not reloaded when the module source code changes.

# File Locations

Scripts should be put into the `automation/jsr223` subdirectory hierarchy of your OH2 configuration directory.
For example, in a Linux apt installation this would be `/etc/openhab2/automation/jsr223`.

Some scripts should be loaded before others because of dependencies between the scripts. 
Scripts that implement OH2 components (like trigger types, item providers, etc.) are one example.
I recommend putting these scripts into a subdirectory called `000_Components`. 
The name prefix will cause the scripts in the directory to be loaded first.
I also recommend naming the component files with a "000_" prefix 
because there are currently bugs in the file loading behavior of OH2.

Example:

```text
/etc/openhab2/automation/jsr223
    /000_Components
       000_StartupTrigger.py
    myotherscript.py
```

Jython modules can be placed anywhere but the Python path must be configured to find them.
There are several ways to do this. 
You can add a `-Dpython.path=mypath1:mypath2` to the JVM command line by modifying the OH2 startup scripts.
You can also modify the `sys.path` list in a Jython script that loads early (like a component script).

I put my Jython modules in `/etc/openhab2/lib/python` (Linux apt installation).
Another option is to checkout the GitHub repo in some location and use a directory soft link (Linux) 
from `/etc/openhab2/lib/python/openhab` to the GitHub workspace `lib\openhab` directory.

## Defining Rules

One the primary use cases for the JSR223 scripting is to define rules 
for the [Eclipse SmartHome (ESH) rule engine](http://www.eclipse.org/smarthome/documentation/features/rules.html).

The ESH rule engine structures rules as _modules_ (triggers, conditions, actions). 
Jython rules can use rule modules that are already present in ESH and can define new modules that can be used outside of JSR223 scripting.

### Rules: Raw ESH API

Using the raw ESH API, the simplest rule definition would look something like:

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

class MyRule(SimpleRule):
    def __init__(self):
        self.triggers = [
             Trigger("MyTrigger", "core.ItemStateUpdateTrigger", 
                    Configuration({ "itemName": "TestString1"}))
        ]
        
    def execute(self, module, input):
        events.postUpdate("TestString2", "some data")

automationManager.addRule(MyRule())
```
<commit_msg>Documentation updates.<commit_after># Jython scripting for openHAB 2.x

This is a repository of experimental Jython code that can be used 
with the [Eclipse SmartHome](https://www.eclipse.org/smarthome/) platform and [openHAB 2](http://docs.openhab.org/) Jython scripting. 
Also see the [openHAB 2 scripting documentation](http://docs.openhab.org/configuration/jsr223.html).

_NOTE: To use Jython for defining rules, the Experimental Rule Engine add-on must be installed in openHAB 2._

## Applications

The [JSR223 scripting extensions](https://www.jcp.org/en/jsr/detail?id=223) can be used for general scripting purposes, 
including defining rules and associated SmartHome rule "modules" (triggers, conditions, actions). 
Some possible applications include integration testing of complex rule behaviors or prototyping new OH2/ESH functionality.

(_JSR223_ refers to a Java specification request for adding scripting to the Java platform. 
That term will not be used in Java versions 9 and above. 
The previous JSR223 functionality will be provided by the Java `javax.script` package in the standard runtime libraries.)

The scripting can be used for other purposes like automated integration testing 
or to access the OSGI framework (using or creating services, for example).

## Jython Scripts and Modules

It's important to understand the distinction between Jython _scripts_ and Jython _modules_. 
In this repo, scripts are in the `scripts` directory and modules are in the `lib` directory.

A Jython script is loaded by the `javax.script` script engine manager (JSR223) integrated into openHAB 2. 
Each time the file is loaded, OH2 creates a execution context for that script.
When the file is modified, OH2 will destroy the old script context and create a new one.
This means any variables defined in the script will be lost when the script is reloaded.

A Jython module is loaded by Jython itself through the standard Python `import` directive and uses `sys.path`.
The normal Python module loading behavior applies.
This means the module is loaded once and is not reloaded when the module source code changes.

# File Locations

Scripts should be put into the `automation/jsr223` subdirectory hierarchy of your OH2 configuration directory.
For example, in a Linux apt installation this would be `/etc/openhab2/automation/jsr223`.

Some scripts should be loaded before others because of dependencies between the scripts. 
Scripts that implement OH2 components (like trigger types, item providers, etc.) are one example.
I recommend putting these scripts into a subdirectory called `000_Components`. 
The name prefix will cause the scripts in the directory to be loaded first.
I also recommend naming the component files with a "000_" prefix 
because there are currently bugs in the file loading behavior of OH2.

Example:

```text
/etc/openhab2/automation/jsr223
    /000_Components
       000_StartupTrigger.py
    myotherscript.py
```

Jython modules can be placed anywhere but the Python path must be configured to find them.
There are several ways to do this. 
You can add a `-Dpython.path=mypath1:mypath2` to the JVM command line by modifying the OH2 startup scripts.
You can also modify the `sys.path` list in a Jython script that loads early (like a component script).

I put my Jython modules in `/etc/openhab2/lib/python` (Linux apt installation).
Another option is to checkout the GitHub repo in some location and use a directory soft link (Linux) 
from `/etc/openhab2/lib/python/openhab` to the GitHub workspace `lib\openhab` directory.

## Defining Rules

One the primary use cases for the JSR223 scripting is to define rules 
for the [Eclipse SmartHome (ESH) rule engine](http://www.eclipse.org/smarthome/documentation/features/rules.html).

The ESH rule engine structures rules as _modules_ (triggers, conditions, actions). 
Jython rules can use rule modules that are already present in ESH and can define new modules that can be used outside of JSR223 scripting.

### Rules: Raw ESH API

Using the raw ESH API, the simplest rule definition would look something like:

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

class MyRule(SimpleRule):
    def __init__(self):
        self.triggers = [
             Trigger("MyTrigger", "core.ItemStateUpdateTrigger", 
                    Configuration({ "itemName": "TestString1"}))
        ]
        
    def execute(self, module, input):
        events.postUpdate("TestString2", "some data")

automationManager.addRule(MyRule())
```

    Note: trigger names must be unique within the scope of a rule instance. 

{'fraction_non_alphanumeric': 0.061879297173414824, 'fraction_numerical': 0.014405762304921969, 'mean_word_length': 4.400117855038303, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '272730', 'n_tokens_mistral': 2524, 'n_tokens_neox': 2373, 'n_words': 1194}