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 build on ecmascript (v11). It converts some variables + item value into a stringified JSON message on the command topic of the mqtt broker . When triggered a first time, the script runs and publishes a message on the broker, 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
Tried different things, depending on the various forums i checked on topics Javascript/JSON/MQTT/Graalvm/Openhab etc, but there isn't a specific forum that discusses mqtt with evohome on Openhab 4. Understand that the code works, and fires successfull, but only one time.
Code build up (complete rule):
configuration: {}
triggers:
- id: "1"
configuration:
itemName: Thermostaat_zone_temperature_setpoint
type: core.ItemStateUpdateTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >-
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";
var val = parseFloat (obj.setpoint);
obj.setpoint = val;
var message = JSON.stringify(obj);
var actions = actions.get("mqtt", "mqtt:broker:master");
actions.publishMQTT("evohome/evogateway/_zone_independent/command",
message);
console.log(message);
type: script.ScriptAction
Logging gives the following (Log when succesfull):
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
Logging gives the following (Log when failed):
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)
Writing this up as a full answer.
As determined from the comments, the problem is that you are overwriting the actions
object at the end of the first run, which means there is no get
function when it runs the second time.
A couple of extra things
The stack trace does actually contain something useful
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)
The second line is actually the place in the script it's failing, <js>
means it's in the JavaScript, <eval>:10
is the 10th line.
Which if you take all the blank lines out of the script: >-
sections get's you to:
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";
var val = parseFloat (obj.setpoint);
obj.setpoint = val;
var message = JSON.stringify(obj);
var actions = actions.get("mqtt", "mqtt:broker:master"); // << line 10
actions.publishMQTT("evohome/evogateway/_zone_independent/command", message);
console.log(message);
The quickest fix is to not reuse actions
as a variable name inside the script so line 10 and 11 become
var action = actions.get("mqtt", "mqtt:broker:master");
action.publishMQTT("evohome/evogateway/_zone_independent/command", message);