Blockly "contextual info" "previous state of item" as String fails

I am seeing unexpected behavior from the “contextual info” block with “previous state of item” as String selected.

2023-07-31 09:52:35.643 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "toString"
	at <js>.:program(<eval>:8) ~[?:?]
	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 javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262) ~[java.scripting:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:78) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:78) ~[?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:71) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:68) ~[?:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1188) ~[?:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:997) ~[?:?]
	at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:87) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
2023-07-31 09:52:35.651 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Set_Device_Virtual_Presence' failed: org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "toString"

Here is an image of the blocks (part of a list for debugging a rule):

And the code:

console.info((['Rule', ctx.ruleUID, 'Triggered by', event.itemName, 'Change to', String(event.itemState.toString()), 'From', String(event.oldItemState.toString()), 'User', User, 'Device Type', Device, 'Detection Type', Detection_Type].join(' : ')));

With the previous state of item block disabled, it works:

2023-07-31 10:01:52.945 [INFO ] [cript.ui.Set_Device_Virtual_Presence] - Rule : Set_Device_Virtual_Presence : Triggered by : GMH_iPhone_Network_Detection_Presence_Is_At_Ossineke_Debounced : Change to : OFF : From :  : User : GMH : Device Type : iPhone : Detection Type : Network

In the first sample, I had added a “create text from” block to both new and previous item state blocks. It isn’t needed for the “new” and didn’t help the “previous.”

Here is the info on my install

runtimeInfo:
  version: 4.0.1
  buildString: Release Build
locale: en-US
systemInfo:
  configFolder: /etc/openhab
  userdataFolder: /var/lib/openhab
  logFolder: /var/log/openhab
  javaVersion: 17.0.7
  javaVendor: Raspbian
  osName: Linux
  osVersion: 6.1.21-v8+
  osArchitecture: arm
  availableProcessors: 4
  freeMemory: 282247456
  totalMemory: 778567680
  startLevel: 100
bindings: null
clientInfo:
  device:
    ios: false
    android: false
    androidChrome: false
    desktop: true
    iphone: false
    ipod: false
    ipad: false
    edge: false
    ie: false
    firefox: false
    macos: false
    windows: true
    cordova: false
    phonegap: false
    electron: false
    nwjs: false
    webView: false
    webview: false
    standalone: false
    os: windows
    pixelRatio: 1.5
    prefersColorScheme: light
  isSecureContext: false
  locationbarVisible: true
  menubarVisible: true
  navigator:
    cookieEnabled: true
    deviceMemory: N/A
    hardwareConcurrency: 8
    language: en-US
    languages:
      - en-US
      - en
    onLine: true
    platform: Win32
  screen:
    width: 1707
    height: 1067
    colorDepth: 24
  support:
    touch: false
    pointerEvents: true
    observer: true
    passiveListener: true
    gestures: false
    intersectionObserver: true
  themeOptions:
    dark: light
    filled: true
    pageTransitionAnimation: default
    bars: filled
    homeNavbar: default
    homeBackground: default
    expandableCardAnimation: default
  userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
    like Gecko) Chrome/114.0.0.0 Safari/537.36
timestamp: 2023-07-31T15:05:26.202Z

How is this rule triggered? “previous state of item” only exists if the rule is triggered by an update or changed event. Maybe only for a changed event.

Thanks. That is probably it. While in production it will be triggered by changed, while developing it, I had it on Update so that it would trigger more frequently.

That was it. Thanks for the help.

It would be much more user-friendly if it returned UNDEF or NULL rather than a fatal error.

You can test for undefined. NULL and UNDEF are specific Item states and are not intended to indicate whether or not a variable exists or not.

1 Like

Coming back on this one. I’m on OH 4.1.

I’m trying to work with the block “contextual info”-block.

Here’s my test case:
image

The rule is triggered in this test case by a change of a switch:

While the first block runs through like it should…
2023-12-26 14:08:52.372 [ERROR] [ab.automation.script.ui.test_blockly] - OFF

… the second block always throws an error:

2023-12-26 14:08:52.372 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "toString"
	at <js>.:program(<eval>:2) ~[?:?]
	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 javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262) ~[java.scripting:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:78) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:78) ~[?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:71) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:178) [?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:68) [bundleFile:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1188) [bundleFile:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:997) [bundleFile:?]
	at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:87) [bundleFile:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
	at java.lang.Thread.run(Thread.java:840) [?:?]
2023-12-26 14:08:52.373 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test_blockly' failed: org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "toString"

The rule is definitely triggered by a change or update event, as suggested by @rlkoshak, so I believe this is not the root cause for failure.

I wonder whether this is a bug (I read this one here)? Or am I missing something really obvious?

Anyone having an idea?

No, that trigger is for an update to a Switch, assuming the description is correct in the screen shot. It’s almost always better to paste the contents of the “Code” tab over screen shots.

And newState only exists for a rule triggered with a changed events, not for updates even if the update resulted in a change.

1 Like

D’uh, thanks for the hint.

You were right: The blockly-element “previous state of item” works perfectly well for the trigger “when item changed”…

configuration: {}
triggers:
  - id: "2"
    configuration:
      itemName: echo_dummy_switch_fernseher
    type: core.ItemStateChangeTrigger
conditions: []
actions:
...

but not for “when item was updated”

configuration: {}
triggers:
  - id: "2"
    configuration:
      itemName: echo_dummy_switch_fernseher
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
...

Thanks!