Reuse Blockly function

  • Platform information:

    • Hardware: RPi 3b
    • OS: openhabian
    • openHAB version:3.3
  • Issue of the topic: I begin to define rules with blocky . I have multiple cases where I have a push button toggling some light
    So I created a function to check the state and send command ON or OFF depending on it.

Is there a an easy way to just reuse a function in another rule?

The only way I found is to copy the entire rule containing the function and then edit it.
In that case, the function is define multiple times and I cannot edit the code globally.

I saw the possibility to define a block library but from scratch… but no way to save a bloclky function in a library

Thanks for any help.

Regarding the toggle function, i finally found it already done on marketplace among other nice functions, Collection of common blocks , bu my quetion is still pending for other function I would like to create and share

There is no way to save and reuse a Blockly function across multiple rules right now.

In OH 4 it might be possible to save a function to the new sharedCache and it would be accessible to multiple rules that way. But today there’s no way short of creating the new blocks from scratch that you already found.

Thanks for the feedback

Alternatively you can also create your blockly code as script and then call this script (inclusive custom parameters) from your rule

Thanks for the tip

Has the reuse of functions via “sharedCache” mentioned for the OH4 version been implemented (I haven’t found a document on this subject)?

If you are looking for documentation specific to this question you won’t find it because the implementation is more generic than that. OH 4 now has access to the shared and private caches. So you’ll just need to assign your function to a variable and then put that variable into the shared cache.

You have to be careful though as you are likely to see “Multi-threaded access is not allowed” exceptions if two rules attempt to call the shared function at the same time. So this is not a very goo solution.

Your best bet is to create a Blockly Library (Developer Toole → Block Library).

I’m in the process of discovering OpenHab, and you’ll have to excuse my errors in understanding this beautiful but sprawling application…
I’ve looked at the Blockly Library option, but I find it a bit complicated. In an ideal world, I’d just like to take an existing function and share it with several scripts. With Blockly Library, you have to rewrite everything in another language (unless I haven’t understood how Blockly Library works).
There seems to be another solution via a call script, but I find that rather inelegant and what’s more it doesn’t seem possible to return a value.
Thanks again for your answer

Blockly isn’t actually a language itself. It’s a visual representation of some other standard text based programming language. In OH’s case, that programming language is JavaScript ECMAScript 11 using the openHAB helper library.

So yes, in order to create a new set of Blocks, you’d need to write the code that that Block “compiles” into.

Unfortunately this isn’t an ideal world. It’s a highly complicated environment full with compromises. In the Blockly case, there is really no mechanism to create and share a library of functions like you want.

By “call script” I’m assuming you are referring to having a rule call another rule and not the callScript rule Action which is specific to Rules DSL.

Frankly, short of creating a new Block using the Block Library, any other mechanism to share functions in Blockly across rules is going to be equally “inelegant”.

But in either the callScript Action or the “run rule or script with context” block there is no return value.

If you want a library of reusable functions that may be a sign you’ve outgrown Blockly as a rules language. You might be happier with JS Scripting or jRuby which have the those languages normal mechanisms for importing libraries.

Finally, in an openHAB rules context, sometimes the need for reusable functions can be a code smell. It highly depends on context of course, but if you’ve a lot of duplicate code which pushes you to want to create a reusable function that could be a sign that those separate rules could be merged into one.

Thanks for this insight,
I’m going to look at the JS Scripting or jRuby solutions
Best regards

I’ve tried to create a JS Scripting library using information from JavaScript Scripting - Automation | openHAB,
I used npn (npm init --yes ; npm pack ; npm install) to create my library in \conf\automation\js which now contains a myjs directory with the two files index.js and package.json
When executing a script containing var myLibrary= require(‘myjs’); I get an error loading the library (Script execution of rule with UID ‘TestMyJS’ failed: org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: ‘myjs’).
I’m using openHAB 4.0.3: does the Third Party Libraries still supported in the same way?
Thanks in advance for your help

myjs was created is under \openhab4\conf\automation\js\node_modules

That’s a pretty generic error.

It needs to be /conf/automation/js/node_modules (that - might need to be an underscore). That’s the only folder libraries are picked up from.

Make sure the permissions are such that openhab can read it.

Also note that you have to export the parts of your library you want to be callable and you have to save that to a variable. Do you have your module.exports configured properly in your library?

Thank you very much for your help, you’re right, it is indeed a permission problem (when the directory is created by npm, conf\automation\js permission are not inherited).
Another little beginner’s question: During the debugging phase, changes to the index.js file don’t seem to be detected by openHAB. How can I force a reload of the library without restarting openHAB completely? Is there a “reload library” function?

Changes are supposed to be picked up as they are made. I’ve never had to do anything special to pick up changes, though I almost never update index.js. Reloading the rule (e.g. by disabling and reenabling it or by saving it) will cause it to reload the library.

Error on my part, the scripts are indeed reloaded as soon as a change is made to the file (I probably wasn’t awake when I did my first tests).