Using Java code in openhab2

Tags: #<Tag:0x00007fe051dd4288>

(Joseph F. Karnicky) #1

I am slowly coming up to speed on openhab2 and would appreciate some advice.
I have defined a couple of Things, a few Items, and a single simple rule that works.

I have been studying the online documentation but I am still unclear as to how I would use standard Java methods within rules.
For example, suppose I want to take an action when a certain String appears as the 1st line in a text file.
In pure Java, I would write something like this:


try {
FileInputStream fis = new FileInputStream(“myfile.txt”);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader in = new BufferedReader(isr);
String input=“myfile.txt”);
if(input.contains(“lights”) {
} catch (IOException e) {

where adjustLights is a static method I have defined in

what would the equivalent openhab2 rule look like?

Also, in a previous thread, someone said I should be using code fences. I assume this is some form of text demarcation that applies code-smart formatting. How do I do this? Will the code fences also format Java code such as above or only openhab rules?
Thanks in advance,

(namraccr) #2

A code fence is two sets of backticks:


Code between them is rendered in more readable fashion.

(namraccr) #3

I’m not clear on how much you can do in a rule. I’m guessing you can’t do file I/O. You certainly can’t use your own POJOs.

(Rich Koshak) #4

It is hard to find a thread where someone hasn’t given an example. But I wrote this up so I don’t have to type it any more.

You need to look at the Xtend Documentation which is linked to from the Rules Documentation along side the Rules Documentation since the Rules Domain Specific Language (DSL) is a subset of Xtend. In particular, the Rules DSL does not support user defined classes, arrays, or other data structures. The Rules DSL is also NOT Java. It is its own separate language that can run embedded within Java.

But because the Rules DSL is running within a Java application, it has access to SOME Java classes. These are namely the core Java classes, the Joda DateTime library, and core openHAB and Eclipse SmartHome classes. You cannot write your own classes and call them from a Rule. You cannot (as far as I know) import an external library and make its classes available in a Rule.

So for your specific example/question, part of your struggles may come from not yet understanding how OH works fully. Don’t worry, it takes everyone a good deal of time and lots of programmers struggle particularly with the Rules DSL because of the limitations outlined above (more on that below).

Taking the first sentence of the Rules docs let’s break it down a bit.

“Rules” are used for automating processes: Each rule can be triggered, which invokes a script that performs any kinds of tasks, e.g. turn on lights by modifying your items, do mathematical calculations, start timers etcetera.

So to trigger a Rule one needs an Event. Events come from the Event Bus or from a small set of internal triggers. See the Trigger’s section of the Rules docs for details. Rules do not directly trigger each other. So from a Rule’s perspective “I want to take an action when a certain String appears as the 1st line in a text file” doesn’t really make sense. You need something external to the Rules to watch that file and generate an event to cause a Rule to trigger. (This isn’t entirely true as you will see shortly, but as a concept, typically one would have a Binding that interacts with the API or hardware which in this case is your text file and the Binding creates events as commands or updates to Items and the Rules trigger based on those commands and events. And Bindings ARE written in Java.) If a binding doesn’t exist, often people can resort to externally called scripts, quick little services that publish data into OH, or manage to construct something using Rules to make it work.

So, if someone where to want to watch a file and cause something to occur when the top of the file contains “lights” they might approach it something like this in Rules DSL.

Switch AdjustLights
rule "Check File"
    Time cron "0 1 * * ? *" // don't know if I got this right, lets just say once a minute
    val topLine = executeCommandLine("head -n 1 /path/to/myfile.txt", 1000) // get the top line
    if(topLine.contains"lights") AdjustLights.sendCommand(ON)

rule "Adjust lights"
    Item AdjustLights received command ON
    // do whatever you have in your AdjustLights java file here
    // However, this wouldn't be Java code, this would typically be doing calculations and postUpdate or sendCommand to change
    // the state of one or more Items. For AdjustLights, I would presume the Items would be connected to Lights.

Finally, I’m going to predict you will likely be very unhappy with the Rules DSL. Because of the decision to base it on a subset of Xtext and some deliberate design decisions the language is limited in many ways that give experienced programmers many problems when they try to program in the Rules DSL as if it were their language of choice. By design it is not a general purpose langauge; it is designed to be constrained to give non-programmers less rope to hang themselves with. So I will recommend looking at the JSR223 Rules which will let you write your Rules using a full programming language, your choice of Jython, JavaScript, or Groovy. The Experimental Rules Engine also has alot of promise but I don’t think it is feature complete enough to be used by most.

(Joseph F. Karnicky) #5

Thanks for the extensive reply. Your promptness and detail are extremely valuable.
I will see if I can get this to work. I have a number of networked computers running programs written in different languages and I frequently use text files to communicate between them. So if I can implement your example it will be big-time progress for me.
In any case, I’m sure I’ll be back with more questions.
PS I do realize how difficult it is for you to create a software system that is usable quickly and yet can be extended almost indefinitely.
PPS just so you don’t think I’m a total doofus, I DID search for “code fences” in the search box on the beginners tutorial page and it came up with “no results”. Anyway, I believe I have it down now.

executeCommandLine on a Windows machine