OpenHAB中ECMAScript脚本首次运行成功后报错求助
平台信息
Hardware: Synology with docker OS: Linux/4.4.302+ (amd64) Java Runtime Environment: debian 17.0.12 openHAB version: openHAB 4.2.2
问题描述
配置了一条OpenHAB规则,当加热控件修改evohome恒温器的设定值时触发。规则采用ECMAScript(v11)编写,逻辑是将变量与项目值转换为JSON字符串,发布到MQTT代理的命令主题。首次触发时脚本运行正常,能成功发布消息并修改设定值,但之后脚本失效,必须重新初始化脚本引擎才能再次正常运行一次,无法定位问题原因。
已在多个论坛查找Javascript/JSON/MQTT/Graalvm/Openhab相关主题,但未找到针对OpenHAB 4中MQTT与evohome结合的相关讨论,确认代码可成功运行但仅能生效一次。
完整规则代码
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
运行日志
成功运行日志
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
失败运行日志
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)
问题解决
错误根源是脚本覆盖了全局的actions变量:
首次运行时,actions是OpenHAB提供的全局动作服务对象,调用actions.get()能获取到MQTT动作实例并赋值给同名变量actions。但第二次运行时,脚本里的actions已经是上一次保存的MQTT动作实例,这个实例并没有get方法,因此抛出Unknown identifier: get错误。
修改方法是将获取MQTT动作的变量名改为其他名称,避免覆盖全局变量,比如mqttActions:
修改后的脚本关键部分:
var message = JSON.stringify(obj); // 改用不同变量名,不覆盖全局actions var mqttActions = actions.get("mqtt", "mqtt:broker:master"); mqttActions.publishMQTT("evohome/evogateway/_zone_independent/command", message); console.log(message);
这样每次运行脚本时,都会通过全局的actions服务获取MQTT动作实例,不会出现变量覆盖导致的错误。
内容的提问来源于stack exchange,提问作者AlexanderR1987
相关产品推荐
相关产品推荐

