# JSR223 Scripting

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 (opens new window) (spec (opens new window)) is a standard scripting API for Java Virtual Machine (JVM) languages (opens new window). 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: Apache Groovy (JVM scripting language), JavaScript/ECMA - 262 Edition 5.1, JavaScript/ECMAScript 262 Edition 11, Ruby, and Jython (opens new window) (Python 2.7 on the JVM).

Please note that JavaScript/ECMA - 262 Edition 5.1 which is referenced here is using an older engine called NashornJS. This version of JavaScript/ECMAScript is end of life and lacks many important features that have been added to the language since 2009. If you plan to use JavaScript/ECMAScript as your scripting language, it is recommended to use JavaScript/ECMAScript 262 Edition 11, also known as JS Scripting, which includes the latest ES6 language features, supports third party node libraries (please keep in mind that not all NodeJS APIs are available in GraalJS), and comes with a well documented helper library (openhab-js (opens new window)) that makes interaction with the APIs documented on this page (and more) much simpler and straight forward in plain JavaScript.

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 official 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

'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);

# 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 (opens new window). 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 overridden 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...

├── 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 and later versions.

# ScriptExtension Objects (all JSR223 languages)

To facilitate 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. With scriptExtension.get("automationManager") the automationManager can be made available without loading a preset.

# Default Preset (importPreset not required)

Variable Description
State org.openhab.core.types.State (opens new window)
Command org.openhab.core.types.Command (opens new window)
URLEncoder java.net.URLEncoder (opens new window)
File java.io.File (opens new window)
Files java.nio.file.Files (opens new window)
Path java.nio.file.Path (opens new window)
Paths java.nio.file.Paths (opens new window)
IncreaseDecreaseType org.openhab.core.library.types.IncreaseDecreaseType (opens new window)
DECREASE IncreaseDecreaseType enum item
INCREASE IncreaseDecreaseType enum item
OnOffType org.openhab.core.library.types.OnOffType (opens new window)
ON OnOffType enum item
OFF OnOffType enum item
OpenClosedType org.openhab.core.library.types.OpenClosedType (opens new window)
OPEN OpenClosedType enum item
CLOSED OpenClosedType enum item
StopMoveType org.openhab.core.library.types.StopMoveType (opens new window)
STOP StopMoveType enum item
MOVE StopMoveType enum item
UpDownType org.openhab.core.library.types.UpDownType (opens new window)
UP UpDownType enum item
DOWN UpDownType enum item
UnDefType org.openhab.core.library.types.UnDefType (opens new window)
NULL UnDefType enum item
UNDEF UnDefType enum item
RefreshType org.openhab.core.library.types.RefreshType (opens new window)
REFRESH RefreshType enum item
NextPreviousType org.openhab.core.library.types.NextPreviusType (opens new window)
NEXT NextPreviousType enum item
PREVIOUS NextPreviousType enum item
PlayPauseType org.openhab.core.library.types.PlayPauseType (opens new window)
PLAY PlayPauseType enum item
PAUSE PlayPauseType enum item
RewindFastforwardType org.openhab.core.library.types.RewindFastforwardType (opens new window)
REWIND RewindFastforwardType enum item
FASTFORWARD RewindFastforwardType enum item
QuantityType org.openhab.core.library.types.QuantityType (opens new window)
StringListType org.openhab.core.library.types.StringListType (opens new window)
RawType org.openhab.core.library.types.RawType (opens new window)
DateTimeType org.openhab.core.library.types.DateTimeType (opens new window)
DecimalType org.openhab.core.library.types.DecimalType (opens new window)
HSBType org.openhab.core.library.types.HSBType (opens new window)
PercentType org.openhab.core.library.types.PercentType (opens new window)
PointType org.openhab.core.library.types.PointType (opens new window)
StringType org.openhab.core.library.types.StringType (opens new window)
SIUnits org.openhab.core.library.unit.SIUnits (opens new window)
ImperialUnits org.openhab.core.library.unit.ImperialUnits (opens new window)
MetricPrefix org.openhab.core.library.unit.MetricPrefix (opens new window)
Units org.openhab.core.library.unit.Units (opens new window)
BinaryPrefix org.openhab.core.library.unit.BinaryPrefix (opens new window)
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 below]
actions Instance of org.openhab.core.automation.module.script.defaultscope.ScriptThingActions (opens new window)
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:

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 (opens new window)
ConfigDescriptionParameter org.openhab.core.config.core.ConfigDescriptionParameter (opens new window)
ModuleType org.openhab.core.automation.type.ModuleType (opens new window)
SimpleActionHandler org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleActionHandler (opens new window)
SimpleConditionHandler org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleConditionHandler (opens new window)
SimpleRule Base class for Rules org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRule (opens new window)
SimpleTriggerHandler org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleTriggerHandler (opens new window)
TriggerType org.openhab.core.automation.type.TriggerType (opens new window)
Visibility org.openhab.core.automation.Visibility (opens new window) enum

# RuleSupport Preset

These variables and classes are loaded using:

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.util.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

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

# ScriptAction Preset

This preset can be useful for scheduling asynchronous code execution with org.openhab.core.automation.module.script.action.Timer.

Variable Description
scriptExecution org.openhab.core.automation.module.script.action.ScriptExecution
scriptExtension.importPreset("ScriptAction")
scriptExtension.importPreset("RuleSupport")
scriptExtension.importPreset("RuleSimple")

scriptExecution.createTimer(ZonedDateTime.now(), {
  org.slf4j.LoggerFactory.getLogger('Test logger').warn('Timer ran')
})

# cache Preset

The cache preset does not provide a default import and needs to be imported explicitly.

scriptExtension.importPreset("cache")

sharedCache.put("x", "y")

It provides two different caches:

  • sharedCache: This cache is shared over all languages and all scripts (file-based and UI). Usage of entries is tracked and entries will be removed if the last script that ever accessed an entry is removed.
  • privateCache: This cache is private to a script engine, usually that means it is private to a script or rule, depending on the implementation of the scripting language. It is cleared when the script engine is unloaded (i.e. usually when the script is unloaded).

In both cases values that are either a ScheduledFuture<?> or a Timer are cancelled by calling .cancel() on the object if the object is removed automatically.

Both caches implement the org.openhab.core.automation.module.script.rulesupport.shared.ValueCache interface and therefore can be accessed by

  • Object put(String key, Object value): Put a key/value pair to the cache. Returns old value if already set, otherwise null.
  • Object remove(String key): Remove the key/value pair from the cache. Returns old value if already set, otherwise null.
  • Object get(String key): Get the value for the given key from the cache. Non-existent keys return null.
  • Object get(String key, Supplier<Object> supplier: Get the value for the given key. If no value is present, add the value that is return from the supplier.

# 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.DateTimeTrigger
Parameter Description
itemName The name of the Item
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.GroupCommandTrigger
Parameter Description
groupName The name of the GroupItem
command The Command (optional)
core.GroupStateUpdateTrigger
Parameter Description
groupName The name of the GroupItem
state The State (optional)
core.GroupStateChangeTrigger
Parameter Description
groupName The name of the GroupItem
previousState The previous State (optional)
state The State (optional)
core.ThingStatusUpdateTrigger
Parameter Description
thingUID The thingUID
status The ThingStatus (optional)
core.ThingStatusChangeTrigger
Parameter Description
thingUID The thingUID
previousStatus The previous ThingStatus (optional)
status The ThingStatus (optional)
core.ChannelEventTrigger
Parameter Description
channelUID The ChannelUID of the Channel
event The Channel trigger Event (optional)
core.GenericEventTrigger
Parameter Description
topic The topic to match, as a file-system style glob (*, **, ?, and {} operators).

Example filters:
Item events: "openhab/items/*/"
Channel events: "openhab/channels/*/triggered"
Thing events: "openhab/things/**"
source The object that triggered the event, such as org.openhab.core.expire
types ItemCommandEvent, ItemStateEvent, ItemStateChangedEvent, GroupItemStateChangedEvent, ItemAddedEvent, ItemRemovedEvent, ThingAddedEvent, ThingRemovedEvent, ThingStatusInfoChangedEvent, ThingStatusInfoEvent, ThingUpdatedEvent, etc. A non-exhaustive list can be found in the Javadocs (opens new window).
payload Regex to match against the actual event data.
core.SystemStartlevelTrigger
Parameter Description
startlevel The system StartLevel