openhab / openhab-webui

Web UIs of openHAB
Eclipse Public License 2.0
215 stars 236 forks source link

Blockly-block "get thing status <variable name>" in a loop throws an error ("things.getThings is not a function") #2670

Closed Boldfor closed 3 weeks ago

Boldfor commented 1 month ago

The problem

In blockly, when using the new loop function for things, the block "get of " or "get of <variable name"" works as intended. The block "get thing status however throws an error. Also discussed here: https://github.com/openhab/openhab-webui/pull/2562#issuecomment-2223821057

image

2024-07-13 23:38:10.956 [ERROR] [script.javascript.thing_status_check] - Failed to execute script: TypeError: things.getThings is not a function
        at <js>.:program(<eval>:5)
        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)
        ... 75 more
2024-07-13 23:38:10.956 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'thing_status_check' failed: org.graalvm.polyglot.PolyglotException: TypeError: things.getThings is not a function

Expected behavior

The way I understood the "get things status " block, if used in a loop, it should produce the same result than the "get of <variable name"-block.

Steps to reproduce

On OH 4.2, execute the following rule:

configuration: {}
triggers:
  - id: "1"
    configuration:
      time: 08:00
    type: timer.TimeOfDayTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      blockSource: '<xml
        xmlns="https://developers.google.com/blockly/xml"><variables><variable
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</variable></variables><block
        type="oh_log" id="RAN^G0LsPP)aX6[`/[VF" x="110" y="238"><field
        name="severity">warn</field><value name="message"><shadow type="text"
        id="^NbDf]=lW!sJo$qyQ1y$"><field name="TEXT">abc</field></shadow><block
        type="text" id="9IK$86jhPEuB1b3Bgu-;"><field name="TEXT">Regeln zum
        Checken der Thing-Status wird
        ausgeführt.</field></block></value><next><block type="controls_forEach"
        id="Ho;{;9}~Hj8h%kXCM15s"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field><value name="LIST"><block
        type="oh_getthings" id="v{^kG.VUIOjcq!C(l]pT"></block></value><statement
        name="DO"><block type="controls_if" id="^I#jy!^OnNA?IeG2TWBJ"><value
        name="IF0"><block type="logic_operation"
        id="QyP$O4x36Y,d=qERtr|d"><field name="OP">AND</field><value
        name="A"><block type="logic_compare" id="1;yAN)@keU[f{G:91byP"><field
        name="OP">NEQ</field><value name="A"><block type="oh_getthing_attribute"
        id="^=|Ni#SmxviC5%.VS-7S"><mutation
        attributeName="status"></mutation><field
        name="attributeName">status</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="dxcIE?9E]O1kj$W^m^V|"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value><value
        name="B"><block type="text" id="et2yi,EX/ximM|LAuH3z"><field
        name="TEXT">ONLINE</field></block></value></block></value><value
        name="B"><block type="logic_compare" id="m}U.0PNfhvFiX:rDqx1d"><field
        name="OP">NEQ</field><value name="A"><block type="oh_getthing_attribute"
        id="?Q@hn3rvLrZDI5r;$`_K"><mutation
        attributeName="status"></mutation><field
        name="attributeName">status</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="2[uALj;vP)UKa,$~aWuR"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value><value
        name="B"><block type="text" id="IfF%R$TyEkvXZx([OJuR"><field
        name="TEXT">INITIALIZING</field></block></value></block></value></block></value><statement
        name="DO0"><block type="oh_log" id="-~noS7X6s44+,ZN#w+H,"
        disabled="true"><field name="severity">info</field><value
        name="message"><shadow type="text" id="{NC^DTc+=Um_juX~am;U"><field
        name="TEXT">abc</field></shadow><block type="text_join"
        id="Xr~8we~;VGy3M|~0aB*H"><mutation items="3"></mutation><value
        name="ADD0"><block type="oh_getthing_attribute"
        id="spjn;n?]PH5vVL=Uv!:Y"><mutation
        attributeName="label"></mutation><field
        name="attributeName">label</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="PS$!=pF(YLq`b5NAwl=8"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value><value
        name="ADD1"><block type="text" id="udRKTGz$1oi(}]/DgV@_"><field
        name="TEXT">: </field></block></value><value name="ADD2"><block
        type="oh_getthing_attribute" id="qRCwlH49$k=Xo?#}q9Uc"><mutation
        attributeName="statusInfo"></mutation><field
        name="attributeName">statusInfo</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="{l`FU#]G$nU.|lE`qgAW"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value></block></value><next><block
        type="oh_sendNotification" id="!I3OT}E4[qAMvl!fXvSk"
        disabled="true"><value name="message"><shadow type="text"
        id="VH4J#3b]$+$eFosK.Tj6"><field
        name="TEXT">message</field></shadow><block type="text_join"
        id="Bi^lOLQgd{Cpn|leB%io"><mutation items="3"></mutation><value
        name="ADD0"><block type="oh_getthing_attribute"
        id="%AaYf%Hxf~z56wnL4(2B"><mutation
        attributeName="label"></mutation><field
        name="attributeName">label</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="D{[,`l4sv{n2LD[bhMlE"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value><value
        name="ADD1"><block type="text" id="$/6$vlhL^Z*w1-,;NoGz"><field
        name="TEXT">: </field></block></value><value name="ADD2"><block
        type="oh_getthing_attribute" id="ah4[x)N42NevspQ[/+b,"><mutation
        attributeName="statusInfo"></mutation><field
        name="attributeName">statusInfo</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id=";h5wW}zv:Z|susAYrtKK"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value></block></value><value
        name="email"><shadow type="text" id="lRPuHm+F`CG!;.fIa3Z/"><field
        name="TEXT">test@example.org</field></shadow><block type="text"
        id="K7jISkTzQqh|1tyn?+vG"><field
        name="TEXT">x.x@x.de</field></block></value><next><block
        type="oh_log" id="4b]@n)u2/u`P+@PVbi:@"><field
        name="severity">info</field><value name="message"><shadow type="text"
        id="{NC^DTc+=Um_juX~am;U"><field name="TEXT">abc</field></shadow><block
        type="oh_getthing_attribute" id="DkX2_P;dhaYH}gXS)b3#"><mutation
        attributeName="statusInfo"></mutation><field
        name="attributeName">statusInfo</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="vHM9*gB}6dvSGjHX3tKY"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value><next><block
        type="oh_log" id="^~`%1A|JX1fn,)JW?[u~"><field
        name="severity">info</field><value name="message"><shadow type="text"
        id="{NC^DTc+=Um_juX~am;U"><field name="TEXT">abc</field></shadow><block
        type="oh_getthing_attribute" id="a*yMm,MPt;IJ*)tn9@e#"><mutation
        attributeName="status"></mutation><field
        name="attributeName">status</field><value name="thing"><shadow
        type="oh_getthing" id="hYle;l`qdnqD9!)2WG9l"><value
        name="thingUid"><shadow type="oh_thing" id="L;w=CqH5kwN[m#U0~[*V"><field
        name="thingUid">MyThing</field></shadow></value></shadow><block
        type="variables_get_dynamic" id="$2%Q7%ZDwdr1Op8QW}rp"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value><next><block
        type="oh_log" id="Nhfw1}@i]k/(^U_+Al+w"><field
        name="severity">info</field><value name="message"><shadow type="text"
        id="{NC^DTc+=Um_juX~am;U"><field name="TEXT">abc</field></shadow><block
        type="oh_getthing_state" id="svb.p/5-]WDM}gAM*w5m"><value
        name="thingUid"><shadow type="oh_thing" id="4B;(xH-BqmU_Mo|$H--Y"><field
        name="thingUid">MyThing</field></shadow><block
        type="variables_get_dynamic" id="67@Ee-9w!W4[j!4IUw+0"><field name="VAR"
        id="/Mmy(vM(a:WtW*@Gp~Lj">things</field></block></value></block></value></block></next></block></next></block></next></block></next></block></statement></block></statement></block></next></block></xml>'
      type: application/javascript
      script: |
        var things;

        console.warn('Regeln zum Checken der Thing-Status wird ausgeführt.');
        var things_list = things.getThings();
        for (var things_index in things_list) {
          things = things_list[things_index];
          if (things.status != 'ONLINE' && things.status != 'INITIALIZING') {
            console.info(things.statusInfo);
            console.info(things.status);
            console.info(things.getThing(things).status);
          }
        }
    type: script.ScriptAction

Your environment

runtimeInfo:
  version: 4.2.0
  buildString: Release Build
locale: en-DE
systemInfo:
  configFolder: /openhab/conf
  userdataFolder: /openhab/userdata
  logFolder: /openhab/userdata/logs
  javaVersion: 17.0.11
  javaVendor: Debian
  osName: Linux
  osVersion: 6.1.0-rpi8-rpi-2712
  osArchitecture: aarch64
  availableProcessors: 4
  freeMemory: 343055280
  totalMemory: 584056832
  uptime: 3022
  startLevel: 100
addons:
  - automation-jsscripting
  - binding-amazonechocontrol
  - binding-gardena
  - binding-homematic
  - binding-irobot
  - binding-mqtt
  - binding-systeminfo
  - binding-yamahamusiccast
  - binding-zigbee
  - binding-zwave
  - misc-openhabcloud
  - persistence-influxdb
  - persistence-rrd4j
  - transformation-jinja
  - transformation-jsonpath
  - transformation-regex
  - transformation-xpath
  - ui-basic
  - ui-habpanel
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
    prefersColorScheme: dark
  isSecureContext: false
  locationbarVisible: true
  menubarVisible: true
  navigator:
    cookieEnabled: true
    deviceMemory: N/A
    hardwareConcurrency: 16
    language: de
    languages:
      - de
      - de-DE
      - en
      - en-GB
      - en-US
    onLine: true
    platform: Win32
  screen:
    width: 1920
    height: 1200
    colorDepth: 24
  support:
    touch: false
    pointerEvents: true
    observer: true
    passiveListener: true
    gestures: false
    intersectionObserver: true
  themeOptions:
    dark: dark
    filled: true
    pageTransitionAnimation: default
    bars: light
    homeNavbar: default
    homeBackground: default
    expandableCardAnimation: default
    blocklyRenderer: null
  userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
    like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0
timestamp: 2024-07-13T21:47:35.570Z

Browser console

Browser network traffic

Additional information

florian-h05 commented 1 month ago

/cc @stefan-hoehn

stefan-hoehn commented 1 month ago

Before we go on, can you make sure you are using a typed variable like described here: https://www.openhab.org/docs/configuration/blockly/#using-variables

Boldfor commented 1 month ago

@stefan-hoehn, I just re-created the variable as a typed variable with the type "Thing name": image

The error is the same:

2024-07-15 20:41:13.033 [ERROR] [script.javascript.thing_status_check] - Failed to execute script: TypeError: things.getThing is not a function
        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 java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262)
        ... 75 more
2024-07-15 20:41:13.033 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'thing_status_check' failed: org.graalvm.polyglot.PolyglotException: TypeError: things.getThing is not a function

What's odd: When I check the generated code, I cannot see the type the variable was defined as (not sure if this should look differently):

var things;
console.warn('Regeln zum Checken der Thing-Status wird ausgeführt.');
var things_list = things.getThings();
for (var things_index in things_list) {
  things = things_list[things_index];
  if (things.getThing(things).status != 'ONLINE' && things.getThing(things).status != 'INITIALIZING') {
    console.info(things.getThing(things).statusInfo);
    console.info(things.getThing(things).status);
    console.info(things.getThing(things).status);
  }
}
stefan-hoehn commented 3 weeks ago

This works fine:

image

Your code breaks on the "get thing status" block. This block DOES NOT take a thing object! It is meant to be used with a thing-block. A thing block, though, similar to an item block, does hold the id which is uid of thing. See the two blocks at. the beginning of the above sample. So, if you really wanted to use it (though there is no good reason because get-status-of-thing does the same but with a thing object, you have to supply the uid of the thing to that block.

Boldfor commented 3 weeks ago

@stefan-hoehn , thanks a lot for the explanation.

So should I close this issue? Or is this one of the cases where restrictions can be applied in blockly, so that the user can't even put blocks together that won't work?

stefan-hoehn commented 3 weeks ago

You actually have a point here. I made that block smarter now:

See the related fix for that.

Boldfor commented 2 weeks ago

You actually have a point here. I made that block smarter now:

Nice. After almost three years of OH I could (indirectly via you) also make a contribution to the actual code. 😃