Contents

Javascript scripts in Openhab stopped working? Here is the fix

The problem

In my case it manifested itself by upgrading Openhab to Milestone 4.0 version. All my scripts in Javascript stopped working with errors like Reference error “event” is not defined. or Reference error “items” is not defined.

The situation

From version 3 of Openhab, the plugin in the Automation category that allowed scripts to be interpreted in Javascript was Javascript Scripting based on the Nashorn Engine. This engine, part of Java up to version 15, allows Javascript code to be used with ECMA Script 5.1 syntax. Starting with Milestone 4 of Openhab, the Java version of the entire project was updated, involving a modernization of the Javascript interpretation engine as well, which now supports ECMA Script 2022+ syntax. Unlike its predecessor, many objects such as items, events, itemRegistry, rules are no longer automatically called from the script execution environment.

This caused similar compatibility problems for scripts in Blocklies as well since they also use Javascript code.

Solution 1: choice of dialect.

The first solution that can be deployed without modifying existing scripts is to install the Automation plugins related to Javascript ECMA 5 and 2022+.
By going to open the script directly from the Openhab GUI, via the arrow in the lower right corner, you will be able to scroll down to the choice of interpreter to use (so in the case of the old ECMScript-5.1 scripts).

Choice of language for script

Choice of language for script

Afterwards, don’t forget to save your changes to the script!

Problems with scripts with different syntax
I have noticed that occasional errors occur in script execution in case a script with modern Javascript syntax calls one with obsolete version or vice versa. Therefore, consider making your scripts compatible with the new version of Javascript by continuing with Solution 2.

Solution 2: manual inclusion of missing dependencies.

How to make our scripts natively compatible with the new engine? Mainly by manually importing the dependencies that we used to find automatically available before. To do this we can add as the first part of the script:

1
2
var runtime = require("@runtime");
var itemRegistry =runtime.itemRegistry, events=runtime.events, HSBType=runtime.HSBType, rules=runtime.rules;

In this way most of the compatibility problems due to lack of dependencies should be solved. I noticed that, contrary to what is stated in the documentation, something in the handling classes for colors needs to be changed, in fact the static method HSBType.fromRGB() is no longer available. In my case I preferred to vary the logic of my scripts to natively use colors in HSB encoding, but in case an RGB->HSB conversion is needed a method will have to be defined manually.

Calling a script from another script?

I find it extremely convenient to call from a script another script. Through scripts the degrees of freedom are greater than through the use of rules, just think of the ability to handle timers or insert complex logic into the automaton. In addition, by adopting the practice of calling a script from other scripts, we are able to create a library of ready-to-use commands without too much repetition:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var callScriptById = function(id){
  var classname = "org.openhab.core.automation.RuleManager"
  var rulemanager = osgi.getService(classname);
  try {
    rulemanager.runNow(id);  
    //rulemanager.runNow(id, true, {something:1}); // in case you want to pass some parameters
  } catch (error) {
    console.error(error);
  }
}