Jsr223 helper for javascript

openhab jsr223 helper for javascript

First at this point special thanks @lewie for his work and share of helper librarays.
Now i have extended this one and want also share this. Perhaps someone will find it usefull.
This extension is only usefull for the older librarys. The new one from @5iver are much more powerfull

You can find all files on GitLab: https://gitlab.com/RNTs_3/openhab-jsr223-javascript-helper/tree/master
The relevant file is RNTs-trigger.js in the folder jslib.

Here is a complete example of all new helper:

'use strict';
var OPENHAB_CONF = Java.type("java.lang.System").getenv("OPENHAB_CONF")     // most this is /etc/openhab2
load(OPENHAB_CONF + '/automation/jsr223/jslib/JSRule.js')
load(OPENHAB_CONF + '/automation/jsr223/jslib/RNTs-trigger.js')

var timeOfDay_preset = {
  "morning_start": "6:00",          // morning_start is nessesary for time of day
  "night_start": "22:00",           // night_start is nessesary for time of day
  "bed_start": "00:00",             // bed_start is nessesary for time of day
  "astro_calc": "00:01",
} 

JSRule({
  name: "RNTs - example",
  description: "example",
  triggers: aggregateTrigger([
    TimerTrigger("0 0/15 * 1/1 * ? *"),               // single cron trigger
    ChangedEventTriggerGroup("gExampleGroup1"),       // trigger when single item in group changed
    ItemCommandTriggerGroup("gExampleGroup2"),        // trigger when single item in group received command
    generateCronTriggerSet(timeOfDay_preset),         // multiple cron trigger generated from var timeOfDay_preset
    ItemStateChangeTrigger("exampleSwitch","","ON")   // single item change trigger
  ]),
  execute:

aggregateTrigger(ArrayOfTriggers)
In the JSRule template the key trigger except a single array with various sort of triggers. But it’s not possible to use nested arrays with nested triggers.
Here the parameter is also an array. In difference one can hand over arrays of trigger or single trigger and the function will return a single array of triggers.

ItemCommandTriggerGroup(groupName)
param: group of item
return: single ItemCommandTrigger array of items what are member of group in param

ChangedEventTriggerGroup(groupName)
param: group of item
return: single ChangedEventTrigger array of items what are member of group in param

generateCronTriggerSet(triggerPreset)
param: dataset with trigger times in the follwoing format - hour:minute
return: array of single cron trigger

example of dataset: var example_timeSet = {
“trigger1”: “23:10”,
“nightStart”: “23:04”,
“bedTime”: “23:02”,
}

one can define as much as nessesary trigger times
the key is for human readability but it must be unique

In the example of time of day Migrating DSL Rules to JSR223/Javascript with a case example, @Confectrician thanks for sharing, one can see the benefit of this datastructure. It’s exist one place (var timeOfDay_preset) of relevant times.


var timeOfDay_preset = {
  "morning_start": "6:00",          // morning_start is nessesary for time of day
  "night_start": "22:00",           // night_start is nessesary for time of day
  "bed_start": "00:00",             // bed_start is nessesary for time of day
  "astro_calc": "00:01",
} 

JSRule({
  name: "Time of day",
  description: "Calculates the time of day, depending on several triggers",
  triggers: aggregateTrigger([
    ChannelEventTrigger("astro:sun:home:rise#event", "START", "astroSunriseTrigger"),
    ChannelEventTrigger("astro:sun:home:set#event", "START", "astroSunsetTrigger"),
    ChannelEventTrigger("astro:sun:minus90:set#event", "START", "astroSunsetDelayTrigger"),
    generateCronTriggerSet(timeOfDay_preset),
    ItemStateChangeTrigger("Helper_JSR223_SystemIsStarted","","ON")           // trigger for system startup witch helper
  ]),

...
    //logInfo("Calculating time of day...")

    // Calculate the times for the static times
    var tMorning = timeOfDay_preset["morning_start"].split(':')
    var tNight = timeOfDay_preset["night_start"].split(':')
    var tBed = timeOfDay_preset["bed_start"].split(':')
    var morning_start = new Date().setHours(tMorning[0], tMorning[1], 0, 0)   // .setHours(Hour, Minute, Second, Millisecond)
    var night_start = new Date().setHours(tNight[0], tNight[1], 0, 0)
    var bed_start = new Date().setHours(tBed[0], tBed[1], 0, 0)

hint: Abouve you see only the relevant part for generateCronTriggerSet not the complete rule.


checkItemExist(item.name)
param: item name
return: item then exist or null


context.checkItemExist = function(it) {
  try {
    //print("################## "+ir.getItem(it));
    return (typeof it === 'string' || it instanceof String) ? ir.getItem(it) : it;
  }catch(err) {
    return null;
  } 
};

This function is append in the file helper.js. It’s almost identical to getItem(item.name). The only difference is, you will not get an error in the log when the item not exist. So i find it a little bit cleaner to check if items exist.

@lewie’s libraries were moved into the openHAB Scripter’s repository back in May 2019 and have had several updates and new libraries added to them. There is more planned for the JS helper libraries, but that will require OH to be compatible with JDK9, which provides a newer version of Nashorn with ES6 compatibility. If you’d like to enhance these libraries, contributions are welcomed!

Your repository appears to contain enhancements to the older libraries and would not be compatible.

@5iver Yes your are right. I’m working with the older librarys. My running OH is 2.4 and i will stay on it, because it’s stable. My intention is to migrate rules to jsr223 yet. In comparison with the rule DSL the javascript rules are much more cleaner, structured and especially one can better work with objects. To wait on JDK9 (i think we talk about oh 3) is to late and so i must update the rules agin when available. But, at the moment the javascript librarays are up to date? Or is this assumption wrong. I will write a hint in the OP.

If you mean the libraries in your repo, they are very out of date. Off the top of my head, you are missing the osgi.js and metadata.js, which open a LOT of doors for your automations.

Oh :fearful: okay. I will look a little bit deeper in your repo.
If I see it correctly, the work is not meaningless. I will adapt the group trigger and now write a hint in the OP. Thanks for your quick response.

2 Likes

Hi @tose,

keep up the good work! I love the JavaScript implementation and I am migration all my old DSL rules to this modern language. I am not a good developer and do not know JAVA. But if you are a good enforcement help openHAB to be the best house automation system. :wink:

Have a Merry Christmas and Happy New Year!
HFM

1 Like

FYI if you are going for conciseness in your library, you could do away with the aggregateTrigger part entirely - if your trigger groups return arrays of triggers then if you ensure the JSRule flattens the array (of arrays). You could also modify the original triggers code to allow specifying an array of item names which would return an array of triggers, so that you don’t need custom trigger groups at all.

Also, regarding you being stuck on OH 2.4; I could probably get my ES9 support working on 2.4 as it was developed pre-2.5 and doesn’t depend on much being there. I’ve already had someone request this. Let me know if you’re interested.

Yes, the aggregate function was a way for me not to change the original helper.

That would be really great.
You mean with ES9: arrow function, spread operator, promises and asynchronus functions…
When you see the possibility and your time slots say yes i would interested. :grinning:

So I had a quick look, and due to package relocations it’s not as simple as I hoped. However I’ll still see if I can create a bundle for you. And yes, I am already using most of those features in my rules, except for async functions, although I see no reason why they wouldn’t work too.

Thanks a lot. I will wait and migrate my last basic rule. So i have the logic in javascript and later i can optimise.