ECMAScript shows error after 1 successfull run

  • Platform information:
    • Hardware: Synology with docker
    • OS: Linux/4.4.302+ (amd64)
    • Java Runtime Environment: debian 17.0.12
    • openHAB version: openHAB 4.2.2
  • Issue of the topic: I have a rule that triggers when a widget (heating) changes the setpoint of a thermostat (evohome). The script of the rule is based on the ecmascript (v11). It sends a stringified JSON message on the command topic of the mqtt broker . When triggered a first time, the script runs and publishes a message, and changes te setpoint. After that, the script is ‘broken’. It takes a while, and a reinitialize of the scriptengine makes it work again 1 time. I cannot get my head around why this is happening.

Code:

var item = items.Thermostaat_zone_temperature_setpoint;
var obj = new Object();
obj.command = "set_zone_setpoint";
obj.setpoint = item.state;
obj.zone_idx = 1;
obj.ctl_id = "id code";
var val = parseFloat (obj.setpoint);
obj.setpoint = val;
var message = JSON.stringify(obj);
var actions = actions.get("mqtt", "mqtt:broker:mqtt_master");
actions.publishMQTT("evohome/evogateway/_zone_independent/command", message);
console.log(message);

Logs when error occurs

2024-10-18 06:51:42.850 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'evo_zone' failed: org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (get) on org.openhab.binding.mqtt.internal.action.MQTTActions@27c6d6d2 failed due to: Unknown identifier: get
2024-10-18 06:54:44.350 [ERROR] [ation.script.javascript.evo_eetkamer] - Failed to execute script: TypeError: invokeMember (get) on org.openhab.binding.mqtt.internal.action.MQTTActions@27c6d6d2 failed due to: Unknown identifier: get
        at <js>.:program(<eval>:10)
        at org.graalvm.polyglot.Context.eval(Context.java:399)
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458)
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426)
        at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262)

Logs when script runs succesful:

2024-10-17 20:17:02.354 [DEBUG] [.internal.OpenhabGraalJSScriptEngine] - Initializing GraalJS script engine...
2024-10-17 20:17:02.360 [DEBUG] [.internal.OpenhabGraalJSScriptEngine] - Injecting ThreadsafeTimers into the JS runtime...
2024-10-17 20:17:02.361 [DEBUG] [.internal.OpenhabGraalJSScriptEngine] - Evaluating cached global script...
2024-10-17 20:17:02.362 [DEBUG] [.internal.OpenhabGraalJSScriptEngine] - Evaluating cached openhab-js injection...
2024-10-17 20:17:02.417 [DEBUG] [.internal.OpenhabGraalJSScriptEngine] - Successfully initialized GraalJS script engine.
2024-10-17 20:17:02.420 [INFO ] [ab.automation.script.ui.evo_zone] - {"command":"set_zone_setpoint","setpoint":20.5,"zone_idx":1,"ctl_id":"id code"}
2024-10-17 20:17:02.420 [DEBUG] [ing.mqtt.internal.action.MQTTActions] - MQTT publish to evohome/evogateway/_zone_independent/command performed

It looks like a bug in the code handlers, but i’m not sure. The script i build took some time because of the lack of examples specific on the evohome @ openhab system, so it’s also possible that i’m missing something…

You change the variable actions. This is a built in object to start with which does indeed give access to all available oh actions. But after the first run, you have modified that built in variable to now be a custom value and that new value is maintained in the rule context between runs.

The error tells you that the variable named actions doesn’t have a get function anymore, which is true because after the first run it is no longer the built in object.

Just use a different variable name than actions.

Also, you don’t need the parseFloat. Use item.numericState to get the state as a number instead of a String or a Quantity.

Because this is only working with the one Item, a more canonical approach would be to use a Generic MQTT Thing with an outgoing command transform to build the JSON.