Custom java script functions or objects

  • Platform information:
    • Hardware: XEON
    • OS: Windows 10 under Hyper-V
    • Java Runtime Environment: OpenJDK 11
    • openHAB version: >= 3.1
  • Issue of the topic:

Hello, everyone,

I would like to write java scripts or transfer existing scripts that I would like to use several times, that’s the point.

Simple example: Staircase light switching, which is switched off again after a time x. I have to control several stair lights and I would like to do this with a function or an object.
To do this, I would have to be able to define the function globally in a kind of library and call the function in a rule with one or more parameters of the ITEMS.
Is there a way to do this?

Later I need the programming technology to control two heating systems and a sauna. :wink:

Humm.
OpenHAB itself as a rule engine. I believe that’s what you want to take a look at. What you describe is easily made though. I like to make my life simpler (from my perspective) so I use node red.
Feel free to hit YouTube and search for it :slight_smile:

General:
You can create a script and call it from a rule/other script and pass some arguments.
However there is no option to return a value, therefore it will more behave like a procedure.

Another option is to think recursive and work with groups. E.g. your rule will trigger by a change of a group member, but the rule itself will also issue a command to the same group.

If your time duration is fixed for each starlight, than you don’t need a function at all, as this feature is inbuilt into OH as part of the expire metadata.
Only if you want to have the timer dynamically, e.g. 5 minutes in the morning, but only 3 minutes in the night, than you need to build it by yourself.

Instead of thinking within functions have a look into groups: several items building a group and if any of a group member will change, than you can run a rule on it (and only need to define it once).

Heating systems might be the most common usercase (after lightning) for home automation. You might find several examples and topics around this in the forum.

Look to see if Open Reminder and/or Threshold Alert which might be useful to you. Why code anything at all if you can just instantiate and configure. And in fact, for a simple “switched off again after a time x” the Expire feature built into OH would do the trick, assuming x is a static amount of time.

If you don’t want to use the rule templates themselves, at least look at them for ways to structure your rules so one rule can handle the behavior for all your Items. You may not need a function at all.

But to answer your question, yes, in Java Script you can write your own reusable function that you can import and use in multiple rules. But where you put them, how you “install” them, and the syntax you use to import them into your rule is different if you are using ECMAScript 5.1 or ECMAScript 11 (through the installed JS Scripting addon).

I’d need to know which one you are using to tell you what to do. However, assuming the JS Scripting add-on, which I’d encourage you to use anyway since it’s about a five year or more recent version of ECMAScript and the helper library comes with it and is very well documented:

  1. The JS Scripting add-on supports Node.js. In fact, most third party node libraries you can install via npm are supported (there’s a limitation in the underlying GraalVM that means no one rule can have more than one thread at a time which might make some libraries unsuitable). So, in a subfolder under $OH_CONF/automation/js/node_modules you would place your personal libraries. Structure your library in the “node” way with exports and such (see GitHub - rkoshak/openhab-rules-tools: Library functions, classes, and examples to reuse in the development of new Rules. or GitHub - openhab/openhab-js: openHAB JavaScript Library which is the helper library for examples, or review any of the many many npm tutorials out there).
  2. Once developed and tested, you’ll want to tar it up, remove it, and then install the tar file using npm. If you do not do this, when you go to install third party libraries using npm, npm will remove your personal library.
  3. You then import the library using standard ECMAScript requires(). For example, I have a personal library rlk_personal that includes an alerting namespace so I import that with let {alerting} = requires('rlk_personal');. To use it I call alerting.sendAlert(''This is an alert!);.

Of course, if you never intent to install any other third party libraries you can skip step 2. But I recommend against that.

I’m certain there are other more npm appropriate ways to manage a personal library but the above works for me.

This is true but outside of Rules DSL, the other rules languages also support writing your own personal libraries of reusable functions.