--- layout: documentation title: JSR223 Scripting --- {% include base.html %} # JSR223 Scripting ::: tip Note This feature is for users who have or are willing to learn some programming skills and are comfortable working with the command line prompt of the operating system hosting openHAB. ::: ## Overview [JSR223](https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/) ([spec](https://jcp.org/aboutJava/communityprocess/pr/jsr223/index.html)) is a standard scripting API for Java Virtual Machine (JVM) [languages](https://en.wikipedia.org/wiki/List_of_JVM_languages). The JVM languages provide varying levels of support for the JSR223 API and interoperability with the Java runtime. Currently the following languages are known to work well for openHAB scripting: [**Jython**](https://jython.github.io/) (Python on the JVM), and [**Apache Groovy**](https://www.groovy-lang.org/) (JVM scripting language). (At the time of writing a **JavaScript** reimplementation is under development.) Although JSR223 scripts can be used as a general-purpose extension language for openHAB, it is most commonly used for the creation of rules, and within scripted Actions or Conditions. Currently, openHAB allows JSR223 scripting to access all packages, which may not be included in the official APIs. This provides great flexibility for the users of JSR223, but is also *use at your own risk*, since changes outside of the offical APIs occur frequently, and are not considered to be *breaking changes*. New APIs are planned to be implemented in the future, which will provide standardized interfaces for interacting with openHAB through scripted automation. ### Example rules for a first impression :::: tabs ::: tab JavaScript ```js 'use strict'; scriptExtension.importPreset("RuleSupport"); scriptExtension.importPreset("RuleSimple"); var sRule = new SimpleRule() { execute: function( module, input) { print("This is a 'hello world!' from a Javascript rule."); } }; sRule.setTriggers([ TriggerBuilder.create() .withId("aTimerTrigger") .withTypeUID("timer.GenericCronTrigger") .withConfiguration( new Configuration({ "cronExpression": "0 * * * * ?" })).build() ]); automationManager.addRule(sRule); ``` ::: ::: tab Jython ```python scriptExtension.importPreset("RuleSupport") scriptExtension.importPreset("RuleSimple") class myRule(SimpleRule): def execute(self, module, inputs): print "This is a 'hello world!' from Jython rule." sRule = myRule() sRule.setTriggers([ TriggerBuilder.create() .withId("aTimerTrigger") .withTypeUID("timer.GenericCronTrigger") .withConfiguration( Configuration({ "cronExpression": "0 * * * * ?" })).build() ]) automationManager.addRule(sRule) ``` ::: ::: tab Groovy ```groovy import org.openhab.core.automation.* import org.openhab.core.automation.module.script.rulesupport.shared.simple.* import org.openhab.config.core.Configuration scriptExtension.importPreset("RuleSupport") scriptExtension.importPreset("RuleSimple") def sRule = new SimpleRule() { Object execute(Action module, Map inputs) { println("Hello World from Groovy") } } sRule.setTriggers([ TriggerBuilder.create() .withId("aTimerTrigger") .withTypeUID("timer.GenericCronTrigger") .withConfiguration(new Configuration([cronExpression: "0 * * * * ?"])) .build() ]) automationManager.addRule(sRule) ``` ::: :::: ### Script Locations Scripts should be placed in the `${OPENHAB_CONF}/automation/jsr223/` directory. This directory will vary, [based on the type of openHAB installation used](https://www.openhab.org/docs/installation/linux.html#installation). For example, Linux installations created with a package installer will use `/etc/openhab/automation/jsr223/`, and manual installations will use `/opt/openhab/conf/automation/jsr223/`. When openHAB starts, scripts will be loaded in an order based on their file name. If the scripts have the same name, which should rarely happen, the parent directories will be considered in the sort. For example, with the following scripts and directory structure... ```text ├── automation/jsr223 │   ├── dir1 │   │   ├── 001_script.py │   │   └── script.py │   ├── 001_script.py │   ├── dir2 │   │   ├── 002_script.py │   │   └── script.py │   └── script.py ``` ... the load order will be: `/001_script.py`, `/dir1/001_script.py`, `/dir2/002_script.py`, `/script.py`, `/dir1/script.py`, `/dir2/script.py`. ### `ScriptExtension` Objects (all JSR223 languages) To faciliate JSR223 scripting, several openHAB-related variables are automatically predefined within `ScriptExtension` presets. They can be loaded into the script context using `scriptExtension.importPreset(String preset)`, e.g. `scriptExtension.importPreset("RuleSimple")`. The `default` preset is preloaded, so it does not require importing. - [`Default`](#default_presets) - [`RuleSimple`](#rulesimple_presets) - [`RuleSupport`](#rulesupport_presets) - [`RuleFactories`](#rulefactories_presets) #### Default Preset (`importPreset` not required) | Variable | Description | |----------|-------------| | `State` | `org.openhab.core.types.State` | | `Command` | `org.openhab.core.types.State` | | `URLEncoder` | `java.net.URLEncoder` | | `File` | `java.io.File` | | `Files` | `java.nio.file.Files` | | `Path` | `java.nio.file.Path` | | `Paths` | `java.nio.file.Paths` | | `IncreaseDecreaseType` | `org.openhab.core.library.types.IncreaseDecreaseType` | | `DECREASE` | `IncreaseDecreaseType` enum item | | `INCREASE` | `IncreaseDecreaseType` enum item | | `OnOffType` | `org.openhab.core.library.types.OnOffType` | | `ON` | `OnOffType` enum item | | `OFF` | `OnOffType` enum item | | `OpenClosedType` | `org.openhab.core.library.types.OpenClosedType` | | `OPEN` | `OpenClosedType` enum item | | `CLOSED` | `OpenClosedType` enum item | | `StopMoveType` | `org.openhab.core.library.types.StopMoveType` | | `STOP` | `StopMoveType` enum item | | `MOVE` | `StopMoveType` enum item | | `UpDownType` | `org.openhab.core.library.types.UpDownType` | | `UP` | `UpDownType` enum item | | `DOWN` | `UpDownType` enum item | | `UnDefType` | `org.openhab.core.library.types.UnDefType` | | `NULL` | `UnDefType` enum item | | `UNDEF` | `UnDefType` enum item | | `RefreshType` | `org.openhab.core.library.types.RefreshType` | | `REFRESH` | `RefreshType` enum item | | `NextPreviousType` | `org.openhab.core.library.types.NextPreviusType` | | `NEXT` | `NextPreviousType` enum item | | `PREVIOUS` | `NextPreviousType` enum item | | `PlayPauseType` | `org.openhab.core.library.types.PlayPauseType` | | `PLAY` | `PlayPauseType` enum item | | `PAUSE` | `PlayPauseType` enum item | | `RewindFastforwardType` | `org.openhab.core.library.types.RewindFastforwardType` | | `REWIND` | `RewindFastforwardType` enum item | | `FASTFORWARD` | `RewindFastforwardType` enum item | | `QuantityType` | `org.openhab.core.library.types.QuantityType` | | `StringListType` | `org.openhab.core.library.types.StringListType` | | `RawType` | `org.openhab.core.library.types.RawType` | | `DateTimeType` | `org.openhab.core.library.types.DateTimeType` | | `DecimalType` | `org.openhab.core.library.types.DecimalType` | | `HSBType` | `org.openhab.core.library.types.HSBType` | | `PercentType` | `org.openhab.core.library.types.PercentType` | | `PointType` | `org.openhab.core.library.types.PointType` | | `StringType` | `org.openhab.core.library.types.StringType` | | `SIUnits` | `org.openhab.core.library.unit.SIUnits` | | `ImperialUnits` | `org.openhab.core.library.unit.ImperialUnits` | | `MetricPrefix` | `org.openhab.core.library.unit.MetricPrefix` | | `Units` | `org.openhab.core.library.unit.Units` | | `BinaryPrefix` | `org.openhab.core.library.unit.BinaryPrefix` | | `items` | Instance of `java.util.Map<String, State>` | | `ir` | Alias for `itemRegistry` | | `itemRegistry` | Instance of `org.openhab.core.items.ItemRegistry` | | `things` | Instance of `org.openhab.core.thing.ThingRegistry` | | `rules` | Instance of `org.openhab.core.automation.RuleRegistry` | | `events` | (internal) Used to send events, post commands, etc. [Details](#event_operations) below] | | `actions` | Instance of `org.openhab.core.thing.binding.ThingActions` | | `scriptExtension` | (internal) For loading script presets. | | `se` | Alias for `scriptExtension` | ##### `events` operations - `events.postUpdate(String, String)` - `events.postUpdate(Item, Number)` - `events.postUpdate(Item, String)` - `events.postUpdate(Item, State)` - `events.sendCommand(String, String)` - `events.sendCommand(Item, Number)` - `events.sendCommand(Item, String)` - `events.sendCommand(Item, Command)` - `events.storeStates(Item...)` - `events.restoreStates(Map)` #### RuleSimple Preset These variables and classes are loaded using: ```python scriptExtension.importPreset("RuleSimple") ``` The primary usage of this preset is for defining rule (`SimpleRule`) subclasses. See language-specific documentation for examples. | Variable | Description | |----------|-------------| | ActionType | `org.openhab.core.automation.type.ActionType` | | ConfigDescriptionParameter | `org.openhab.config.core.ConfigDescriptionParameter` | | ModuleType | `org.openhab.core.automation.type.ModuleType` | | SimpleActionHandler | `org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleActionHandler` | | SimpleConditionHandler | `org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleConditionHandler` | | SimpleRule | Base class for Jython Rules `org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRule` | | SimpleTriggerHandler | `org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleTriggerHandler` | | TriggerType | `org.openhab.core.automation.type.TriggerType` | | Visibility | `org.openhab.core.automation.Visibility` enum | #### `RuleSupport` Preset These variables and classes are loaded using: ```python scriptExtension.importPreset("RuleSupport") ``` | Variable | Description | |----------|-------------| | Action | `org.openhab.core.automation.Action` | | ActionBuilder | `org.openhab.core.automation.ActionBuilder` | | Condition | `org.openhab.core.automation.Condition` | | ConditionBuilder | `org.openhab.core.automation.ConditionBuilder` | | Configuration | `org.openhab.config.core.Configuration` | | ModuleBuilder | `org.openhab.core.automation.ModuleBuilder` | | Rule | `org.openhab.core.automation.Rule` (use `SimpleRule` for defining rules) | | Trigger | `org.openhab.core.automation.Trigger` | | TriggerBuilder | `org.openhab.core.automation.TriggerBuilder` | | automationManager | Instance for managing rules and other openHAB module instances. (e.g., `addRule`) | | ruleRegistry | `org.openhab.core.automation.Rule` | #### `RuleFactories` Preset >Note: Advanced usage ```python scriptExtension.importPreset("RuleFactories") ``` | Variable | Description | |----------|-------------| | `ActionHandlerFactory` | `org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedActionHandlerFactory` | | `ConditionHandlerFactory` | `org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedConditionHandlerFactory` | | `TriggerHandlerFactory` | `org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory` | ### `TriggerType` Objects (all JSR223 languages) The following trigger types are defined by openHAB (custom triggers can also be defined) and take the specified configuration parameters. All parameters are Strings. Read the JSR223 language specific documentation for examples of using these `TriggerType` objects.
timer.GenericCronTrigger | Parameter | Description | |-----------|-------------| | `cronExpression` | The cron expression |
timer.TimeOfDayTrigger | Parameter | Description | |-----------|-------------| | `time` | The time in "hh:mm" format |
core.ItemCommandTrigger | Parameter | Description | |-----------|-------------| | `itemName` | The name of the `Item` | | `command` | The `Command` (optional) |
core.ItemStateUpdateTrigger | Parameter | Description | |-----------|-------------| | `itemName` | The name of the `Item` | | `state` | The `State` (optional) |
core.ItemStateChangeTrigger | Parameter | Description | |-----------|-------------| | `itemName` | The name of the `Item` | | `previousState` | The previous `State` (optional) | | `state` | The `State` (optional) |
core.ChannelEventTrigger | Parameter | Description | |-----------|-------------| | `channelUID` | The `ChannelUID` of the `Channel` | | `event` | The `Channel` trigger `Event` (optional) |
core.GenericEventTrigger | Parameter | Description | |-----------|-------------| | `eventTopic` | Default: "openhab/\*"

Events can also be filtered, e.g.
Item events: "openhab/items/\*/"
Channel events: "openhab/channels/\*/triggered"
Thing events: "openhab/things/\*/" | | `eventSource` | `Item` name, `ChannelUID`, `ThingUID`, etc. | | `eventTypes` | `ItemCommandEvent`, `ItemStateEvent`, `ItemStateChangedEvent`, `GroupItemStateChangedEvent`, `ItemAddedEvent`, `ItemRemovedEvent`, `ThingAddedEvent`, `ThingRemovedEvent`, `ThingStatusInfoChangedEvent`, `ThingStatusInfoEvent`, `ThingUpdatedEvent`, etc. |