JavaScript examples that have worked for you. Put them here for others to use

Normally you should just use the cron-based Trigger for triggering rules in an interval.
From my understanding even in OH3, you should avoid (longer) sleeps and minimize the use for timers within a rule. It makes the rule logic not only more complicated, but also uses more memory as needed…

The cron-based trigger is what I want. I just want an example of a rule triggered by a timer in OH3. It appears that the triggers from OH2 are now completely broken.

To clarify: this is the sort of thing I had working in OH2.

JSRule
(
  {
    name: "Run every 10 minutes",
    description: "Do stuff",
    triggers: 
    [
        TimerTrigger("0 0/10 * * * ?")
    ],
    execute: function( module, input)
	{
          // Do stuff
	}
  }
);

What would the equivalent in OH3 be?

triggers:
  - id: "1"
    configuration:
      cronExpression: 0 0/10 * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >-
        var logger =
        Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Rules.Examples");


        logger.info("log some stuff");
    type: script.ScriptAction

this would trigger a log-entry every 10mins.
You can invoke a script/rule/execCommand/… within that script of course… but I don’t get your use case of using cron within a rule?

That goes in a .js file? What syntax is that?
I’m totally lost at this point.

@LordLiverpool how many places are we having this conversation lol.

Your example in this post is the correct syntax and should be working.

Haha. The “My first steps” post is really a kind of running blog of my attempt to get my openHab system working. When I have a specific problem I can’t solve, I open a thread. This seemed like a good place to find examples, but I get the impression that “Javascript” has fragmented into several different implementations and syntaxs, including the one generated by the new UI in OH3. So it’s difficult to keep track of.

I’m going to try it, and if it works, I’ll post it here.

  1. read through the intros for OH3
    Getting Started - Introduction | openHAB
    especially the part about “rules”
    Rules | openHAB
  2. in OH3 goto “Settings” - “Rules”
    grafik
  3. click on the plus in the down-right corner
  4. click on “code” and insert said code

I’m not using the UI, I’m using .js files. I’m not sure the two methods can be combined.

I think we’re talking about two completely different things.

in a way - yes. You want to start JavaScript with a cron - usually that’s where Rules (with ECMA-Script) come into place. That’s why I started this.

…if you need - for some reason or the other - the .js script: you can start a .js script from a Rule (as described above).

I’m coming from an OH2 setup where all my rules are in .js files. I prefer not to get involved with the UI if possible.

Pro-Tipp: use the UI, it saves A SH%TLOAD of trouble[1]. (and that’s coming from a guy, who’s file-based thinking is decades old)

nonetheless: you could create rules outside the UI, but then again: why bother? text files are error-loaden, non-referential and mostly impractible. - the only upside is: you can git and backup them more easily than the OH3 UI. But then again: I backup my OH3 daily and you can git and backup your JSON-DB also…

[1] first of all: you get more and better support here in the forum using the UI.
Second: you can’t get errors in referencing with typos and stuff, as you the UI takes care of the references
Third: you don’t have the hassle with naming conventions and loading of item-files and referencing the correct things and having to dig deep to get the right thing-syntax - that does the UI and the binding for you.

I don’t know how to use cron-timer in .js files and that’s I imagine not the recommended way - so you’re probably on your own with this approach. :man_shrugging:

I prefer to edit my files on the PC in Visual Code and then copy them over as needed. Much easier to backup, easier to edit, easier in every way.

Yes, it looks like I’m on my own with the file-based approach. Oh well.

I’ve already figured out how to set up the timer trigger.

No, that’s the representation of a Rule created in the UI with a JavaScript Script Action.

There are three syntaxes:

  1. ECMAScript 5.1 in .js files; the Helper Libraries help make this easier but is not required (though it’d be foolish not to use them).
  2. ECMAScript 5.1 in the UI for Script Actions and Script Conditions
  3. GraalVM ECMAScript 9 (i think) which is a separate add-on to install, note as of this writing installing it will break the build in ECMAScript 5.1 stuff.

In OH 3 almost everyone who is using JS is doing so through the UI. Those who are using file based rules are doing so using Jython or Rules DSL or one of the other rules languages.

Rules development in OH 3 is in my opinion hopelessly fragmented right now and I see no path forward. So I’m focusing on preparing myself for when we have a marketplace (OH 3.2 is the target for it right now) so I can make libraries installable like an add-on.

1 Like

Yep, it seems to be getting worse rather than better.

I’m going to plow on with my files.

I’m going to post some complete examples of simple functions here that I could have done with myself. All this is OH3 - a lot doesn’t work in OH2.5, works badly, or requires modifications.

function DoHttpGetRequest(sURL, sDesc, headers)
{
  //logInfo("DoHttpGetRequest " + sDesc + ": URL: " + sURL);

  var bAPICallOK = true;
  var response;
  var parsedResponse;

  try 
  {
    var HTTP = Java.type("org.openhab.core.model.script.actions.HTTP");    
    response = HTTP.sendHttpGetRequest(sURL, headers, 1000);      
    parsedResponse = JSON.parse(response);

    //logInfo("DoHttpGetRequest: " + sDesc + ": result: " + parsedResponse + "; unparsed result: " + response);
  } 

  catch(exception) 
  { 
    HandleHTTPException("DoHttpGetRequest", sDesc, exception, response);
    bAPICallOK = false;
  }     

  if (bAPICallOK)
  {
    return parsedResponse;
  }
  else
  {
    return null;
  }
}

POST is similar:

    var HTTP = Java.type("org.openhab.core.model.script.actions.HTTP");
    var result = HTTP.sendHttpPostRequest(sURL, sContentType, "", 10*1000);
    var objResult = JSON.parse(result);

HandleHTTPException is just a generic error-handling function I use to write a log entry.

This wait function is probably identical to one posted in another thread somewhere, possibly by Rich (which is where I got it from), but for completeness I’ll include it:

function Wait(fSeconds) 
{
  var ZonedDateTime = Java.type("java.time.ZonedDateTime");
  var ChronoUnit = Java.type("java.time.temporal.ChronoUnit");
  var CompletableFuture = Java.type("java.util.concurrent.CompletableFuture");
  var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");  

  var future = new CompletableFuture();
  var timer = ScriptExecution.createTimer(ZonedDateTime.now().plus(fSeconds*1000, ChronoUnit.MILLIS), function() 

  {
    future.complete(null);
  });

  future.get();
}

This tests whether a thing is online or not:

OpenHabHelpers.prototype.IsThingOnline =

function IsThingOnline(sThingUID)
{
  var Things = Java.type("org.openhab.core.model.script.actions.Things");
  var statusInfo = Things.getThingStatusInfo(sThingUID);

  if (statusInfo != null)
  {
    var status = statusInfo.getStatus();

    if (status != null && status == "ONLINE" || statusInfo == "ONLINE") 
    {
      return true;
    }
    else 
    {
      return false;
    }
  }
}

And these are rules in the format required by Crazy Ivan’s helper libraries:

On item update:

function Rule_OnAlexaVentilationOff(event) 
{
  alexaControl.OnVentilationOff();
}
when("Item AlxTrgOH_VentilationOff received update")(Rule_OnAlexaVentilationOff);
rule
(
    "Rule_OnAlexaVentilationOff",
    "Turn ventilation off via Alexa"
)(Rule_OnAlexaVentilationOff);

An on item change rule with multiple triggers:

function Rule_LastUpdate(event) 
{
  // Do stuff
}
when("Item SecondBedroomAeotecZW100Multisensor6_SensorLuminance changed")(Rule_LastUpdate);
when("Item SecondBedroomAeotecZW100Multisensor6_SensorRelativeHumidity changed")(Rule_LastUpdate);
rule
(
    "Rule_LastUpdate",
    "Does stuff"
)(Rule_LastUpdate);

And a rule with a 10-minute timer trigger:

function OnTimer_EveryTenMinutes(event) 
{
	// Do stuff
}
// @ts-ignore
when("Time cron 0 0/10 * * * ?")(OnTimer_EveryTenMinutes);
// @ts-ignore
rule
(
    "On timer:  (every 10 minutes)",
    "Does stuff"
)(OnTimer_EveryTenMinutes);

That’s not one of mine. When I wait and block while waiting I just call

java.lang.Thread.sleep(<number of milliseconds to wait>);

Using a CompletableFuture and a Timer just to wait a certain number of seconds seems like a lot of bother just to block a rule for a given amount of time. Maybe there is some reason I don’t see why one would want to do it this way.

If I don’t want to block while waiting I create Timers, and I do have a lot of timer management libraries.