345 lines
14 KiB
Markdown
345 lines
14 KiB
Markdown
---
|
|
layout: documentation
|
|
title: JSR223 Scripting
|
|
---
|
|
|
|
# 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.core.config.core.Configuration
|
|
|
|
scriptExtension.importPreset("RuleSupport")
|
|
scriptExtension.importPreset("RuleSimple")
|
|
|
|
def sRule = new SimpleRule() {
|
|
Object execute(Action module, Map<String, ?> 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 are loaded at start level 40 by default (in no particular order).
|
|
The start level for each script can be overriden by specifying a start level either in the filename (`./my_script.sl50.py`) or containing directory (`./sl50/my_script.py`).
|
|
The runtime provides no explicit dependency mechanism or ordering, yet scripts are loaded one at a time so can be ordered via start level if desired.
|
|
For example, with the following scripts and directory structure...
|
|
|
|
```text
|
|
├── automation/jsr223
|
|
│ ├── dir1
|
|
│ │ ├── script_a.py
|
|
│ │ └── script_b.py
|
|
│ ├── script.sl38.py
|
|
│ ├── sl30
|
|
│ │ ├── script_x.py
|
|
│ │ └── script_y.py
|
|
│ └── script.py
|
|
```
|
|
|
|
... the load order will be: (`sl30/script_x.py` & `sl30/script_y.py`) at start level 30, `script.sl38.py` at start level 38, then (`/dir1/script_a.py`, `/dir1/script_b.py`, `script.py`) at start level 40.
|
|
The script file watching mechanism itself is activated at start level 20, so scripts cannot be executed earlier than this.
|
|
|
|
Note that prior to openHAB 3, script ordering was performed alphanumerically based on file path. This is no longer supported as of openHAB 3.
|
|
|
|
### `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<Item, State>)`
|
|
|
|
#### 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.core.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.core.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.
|
|
|
|
::: details timer.GenericCronTrigger
|
|
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `cronExpression` | The cron expression |
|
|
:::
|
|
|
|
::: details timer.TimeOfDayTrigger
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `time` | The time in "hh:mm" format |
|
|
:::
|
|
|
|
::: details core.ItemCommandTrigger
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `itemName` | The name of the `Item` |
|
|
| `command` | The `Command` (optional) |
|
|
:::
|
|
|
|
::: details core.ItemStateUpdateTrigger
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `itemName` | The name of the `Item` |
|
|
| `state` | The `State` (optional) |
|
|
:::
|
|
|
|
::: details core.ItemStateChangeTrigger
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `itemName` | The name of the `Item` |
|
|
| `previousState` | The previous `State` (optional) |
|
|
| `state` | The `State` (optional) |
|
|
:::
|
|
|
|
::: details core.ChannelEventTrigger
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `channelUID` | The `ChannelUID` of the `Channel` |
|
|
| `event` | The `Channel` trigger `Event` (optional) |
|
|
:::
|
|
|
|
::: details core.GenericEventTrigger
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `eventTopic` | Default: "openhab/\*"<br><br>Events can also be filtered, e.g.<br>Item events: "openhab/items/\*/"<br>Channel events: "openhab/channels/\*/triggered"<br>Thing events: "openhab/things/\*/" |
|
|
| `eventSource` | `Item` name, `ChannelUID`, `ThingUID`, etc. |
|
|
| `eventTypes` | `ItemCommandEvent`, `ItemStateEvent`, `ItemStateChangedEvent`, `GroupItemStateChangedEvent`, `ItemAddedEvent`, `ItemRemovedEvent`, `ThingAddedEvent`, `ThingRemovedEvent`, `ThingStatusInfoChangedEvent`, `ThingStatusInfoEvent`, `ThingUpdatedEvent`, etc. |
|
|
:::
|