My first steps with OpenHab

OK, wait, let’s see if I understand this.

var LOG = getLogger(LOG_PREFIX + ".core.rules");

equates to

var LOG = getLogger("jsr223.javascript.core.rules");

That would go to my JSR223.log as it stands. The output from “org.openhab.model.script” is what I’ve directed to rules.log, so if I just do:

var log = getLogger("org.openhab.model.script");"Hello");

I get what I want, correct? I could then define a logInfo function and avoid having to find/replace all my log entries.

createTimer is an Action so the library to load will be actions.js. createTimer lives in the ScriptExecution class.

Almost all the interactions with openHAB itself (calling actions, working with Items, etc.) is achieve through the same Java Classes and Objects no matter what language you are using. So for the most part, with a little practice, you should be able to look at a jython block of code and convert it to JavaScript without too much trouble. Rules after all are mainly about interacting with openHAB and the rest of the rule is either proforma or stringing together those interactions.

So using the Helper Library you’d create a Timer

var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Test");
var ZDT = Java.type("java.time.ZonedDateTime");

var OPENHAB_CONF = java.lang.System.getenv("OPENHAB_CONF");
load(OPENHAB_CONF + "/automation/lib/javascript/core/actions.js");

var runme = function(){"Timer expired...");'
  // timer code goes here
var timer = ScriptExecution.createTimer(, runme);

But you’re not asking about a Timer there but a cron triggered rule. As I only use UI created rules with JavaScript I don’t know what it should look like in .js files.

As with createTimer, logInfo is one of the core openHAB Actions. In this case it’s on the Log class. @CrazyIvan359, the Helper Library seems to be trying to import the wrong class for the logger Actions, using org.openhab.core.model.script.actions.LogAction which is what is was before OH 3. I thought someone submitted a PR for that. I can do so if you like. Only the first block need to be updated I think. However that will make it not work for OH 2.5 so I don’t know how you are handling that.

@LordLiverpool, this appears to be one of the places in that 20% not yet done. So you can either create the logger directly like I showed in the createTimer example above, or import the Log class manually.

var Log = Java.type("org.openhab.core.model.script.actions.Log");
Log.logError("Experiments", "This is an OH error log");
Log.logWarn("Experiments", "This is an OH warn log");
Log.logInfo("Experiments", "This is an OH info log");
Log.logDebug("Experiments", "This is an OH debug log");
// There is no trace

Not a file, but a logger name. The logger names are hierarchical. By default, there are configs in log3jk2.xml to log out everything under org.openhab.model.script to openhab.log. You’ve added some customizations to move those to another file. The openHAB Log actions create new loggers under that path. If you use slf4j directly instead, you have to specify the full path.

@rlkoshak I can’t remember if I did JS but the Jython libs are fully OH2/3 agnostic. You can use either Log or LogAction in both version and you’ll get the available object.

Which used to be called TimerTrigger :smirk:

I have that worked out now. As I get things fully working I’ll post them here and wherever else seems appropriate.


var Log = Java.type("org.openhab.core.model.script.actions.Log");


var Log = getLogger("org.openhab.core.model.script.actions.Log");

fully equivalent? Should I prefer one to the other?

For JS, yes they are the same.
For Jython, no. getLogger returns a Python logger class instance, though functionally they are almost identical.

getLogger makes your life easier so you don’t have to remember or know any of the Java, you just give it the log path you want and you get a logger back.

1 Like

getLogger it is.

It looks like the JS only refers to LogAction with no reference to Log anywhere in actions.js, at least in the ivans-updates branch. Should I be looking at a different brach?

Another thing: using the when syntax, how would I combine multiple triggers, like this:


Wait, got it

"Member of gRoomThermostat received update || Member of gRoomSetPoint received update "

Got to get used to this natural-language-combined-with-operators idea.

The old rules received the parameters

module, input

The new ones receive “event”. I don’t understand the Javascript well enough to work out how this maps to the code in the libraries.

Previously I was able to obtain the trigger item from “input”. You could extract an event string from input, split it and get at the various parts of the trigger condition:

  var ev = input.get("event")+"";
  // Splits into: 'gRecordLastUpdate,changed,from,7.96612745098039237,to,7.95362745098039237,through,BalconyAeotec_SensorTemperature' 
  var evArr = ev.split("'").join("").split("Item ").join("").split(" ");

What would be the equivalent of this now? What sort of object is event?

I have some sort of log output from my rules. It’s a decent start.

event encapsulates the event that triggered the rule. It sounds like event and input might be the same thing but it’s not clear.

The following table is not complete.

Value Purpose When Present
event.itemName Name of the Item that triggered the rule All Item event triggers
event.itemState The state of the Item that triggered the rule Item received update and Item changed triggers
event.oldItemState The previous state of the Item that triggered the rule Item changed triggers
event.itemCommand The command that triggered the rule Item received command triggers
event.event The trigger Channel event that triggered the rule Thing Channel triggers

event is undefined for cron, system startup/runlevel, and manually triggered rules.

But How Do I…? — openHAB Helper Libraries documentation is by far the best source for this sort of thing right now.

1 Like

You should look in the js-rewrite branch for any of my JS work. It’s still separate Becuase of how incomplete it is.

You don’t combine them, just use when once for each trigger you need. This is documented in the Jython docs.

This should not work…

input encapsulates event.

This unpacking is present in both the Jython and my updated JS libraries:

OK, that explains it. It looks right in that branch. I was looking at the wrong version.

I just found that page before I saw your reply. That deals with the triggering event problem.

Ok so I need a separate rule for each when case?

No - underneath your first when line, just add another. And another under that one if you want.


Ahh OK :+1:. I found the || syntax somewhere on the forum and assumed that would work.