JRuby OpenHAB Rules System

Version 2.3.0 is now released with support for rule descriptions. @JimT wrote all the code and tests for this release. Thanks @JimT

Changelog
Latest Documentation

For simple binary cases you can use the otherwise block to execute an alternative.

Right now, maybe? For between I am monkey patching the Range class and how it handles strings. This would potentially be dangerous outside of the rule context. Right now the run/triggered/guard blocks operating within the rule context, but that is changing as I fix the variable scope problems mentioned above.

If we remove the implicit text parsing and require objects only, we should be able to make it work without modifying the range object.

Right now it would be messy, and look like this.

  TimeOfDay.parse('8:00')..TimeOfDay.parse('12:00') #Create a range.

I think what we really want is:

 tod('8:00')..tod('12:00') 

or something like that.

Could we do:

TimeOfDay.now.within('8:00'..'12:00') 

Maybe? the ‘
’ operator is the thing creating a range
 So you would end up with a range of strings and then your within method would need to take that range and convert it to a range of time of day objects.

Might be able to do the same thing with just between('8:00'..'12:00') which would convert the range and return a new range of the appropriate type. Having just said that, that is probably the better way to implement the between code we have, it would be less dangerous than monkey patching the Range class. And if we did that, then between could be available everywhere.

One of the reason you want the range is so that it can be used anywhere ranges make sense, for example you want to be able to do

case TimeOfDay.now
when between('8:00'...'12:00') then x
when between('12:00'..'16:00') then x
else then y

You could still support ‘within’ or maybe you also call it ‘between’ so it’s the same syntax everywhere. It is worth opening a GitHub issue to explore this.

I spent some time trying to accomplish this and I couldn’t. I am not sure it will be possible. They JRuby devs are going to take a look and provide some recommendations on what is possible within the various runtime/variable isolation settings.

Version 2.4.0 is now released with support for compaging TimeOfDay objects against strings and provided access to store and restore item states. Once again, @JimT wrote all the code for this release. Thanks @JimT

Changelog
Latest Documentation

Version 2.5.0 is now released with support for TimeOfDay (and thus between) parsing of AM/PM in times. In addition, as discussed above the between syntax is now available inside of rules with full support in case statements, etc.

Changelog
Latest Documentation

It is becoming so normal I forgot to add that @JimT wrote the AM/PM parsing code.

Version 2.5.1 is now released with fixed TimeOfDay parsing and removed a merge conflict that made it into the build.

Changelog
Latest Documentation

Version 2.6.0 is now released with two updates from @JimT. A fix introduced by a regressions in 2.5.0 and the ability to check if a time range is between a current time of day with:

TimeOfDay.now.between? '5am'..'7pm'

As usually, check changelog and latest documentation for details.

Changelog
Latest Documentation

Version 2.6.1 is now released with some minor fixes.

While the release cadence has slowed down, there has been a lot of work happening on the back end. Version 2.5.0 was released with several regressions, which was very disappointing given that we have good test coverage.

So, with good test coverage, why was there a release with several regressions??

Because I didn’t run the tests.

We have over 280 test scenarios that exercise the various parts of the rules language directly against OpenHAB. Running these tests take almost an hour and the release process was manual and didn’t require the tests to be run.

It was a lot of work, but that is now no longer the case. The testing and release process has been converted over to GitHub Actions and the testing process is now heavily cached and executed in parallel. This brings the testing and full release time down to under 10 minutes and fully automates it.

Going forward releases should be easier and released with less regressions.

Changelog
Latest Documentation

1 Like

A new searchable documentation site is now live and available here.

1 Like

Version 2.7.0 is released with one additional feature: SwitchItem.toggle which acts the same way as SwitchItem << !SwitchItem but it allows such usage:

SwitchItem1.toggle
Group1.each(&:toggle)
1 Like

Version 2.9 is now released (looks like I didn’t announce 2.8)

The big changes in 2.9 is the support for actions. The biggest difference compared to other libraries is that you can access actions as methods on things (since they are inherently attached to things).

For example:

 things['mail:smtp:local'].sendEmail('me@example.com', 'subject', 'message')

Can be used to send an email message. Additionally, there is an ‘actions’ method that works similar to
how it works in Jython or DSL. See the actions docs for more details.

Release 2.8 added metadata access. @JimT do you want to share the work you did there?

As usual, check changelog and latest documentation for details.

Changelog
Latest Documentation

1 Like

Metadata support was added in 2.8

Quick examples:

# Check namespace's existence
Item1.meta['namespace'].nil?
Item1.meta.key?('namespace')

# Access item's metadata value
Item1.meta['namespace1'].value

# Access namespace1's configuration
Item1.meta['namespace1']['config1']

Metadata can be added, deleted, cleared, merged, enumerated, updated, etc. More details can be found in the metadata docs

1 Like

Hi, first of all I want to say thank you for this impressive work.

I like the style of ruby and wanted to play a little bit but have some problems to load the rule.
For the installation I followed the steps on you site and created a test rule:

require 'openhab'

rule 'Simple' do
  every :minute
  run { logger.info "Rule #{name} executed" }
end

But I get following error while loading it:

2021-01-29 10:48:50.545 [INFO ] [ab.core.service.AbstractWatchService] - Loading script '/etc/openhab/automation/jsr223/ruby/personal/test_rule.rb'
2021-01-29 10:48:56.969 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/jsr223/ruby/personal/test_rule.rb': org.jruby.embed.EvalFailedException: (LoadError) no such file to load -- openhab

Somehow the path cannot be loaded although environment variables are added to start.sh.
I can fix it by adding the full path e.g.

require '/etc/openhab/automation/lib/ruby/lib/openhab'

but I want to avoid to do it manually for each ruby lib file.
Is there something missing?

Hi @olsim - Glad you like it.

The only reason I can think of is that either the variable is pointing to the wrong path (maybe a typo?).

However, the installation method just changed to make things easier.

Version 2.10 is now released!
I am excited about this one. This is a big internal change.
This library is now packaged as a Ruby gem.

For users this now means:

  1. No messing with start.sh or setting environment variables
  2. No having to download, unzip the files, move them to the right place, etc.
  3. Upgrades can be automated (with openhab restart) or manual

You should clear out all the files in your ruby_lib dir, as they will no longer be needed.

This requires a new version of the Openhab JRuby bundle which can install gems and sets the environment up appropriately. Details on how to perform the new setup are here.

I would appreciate any feedback on the setup process and let me know if you hit any snags.

1 Like

Hi @boconnor
The new installation method made it. Now everything works fine

I’ve finally come around to upgrading to OH3, and are planning to migrate my rules to jruby. When reading the installation instructions I noticed the paths specified:

  • <openhab_base_dir>/conf/automation/lib/ruby/gem_home
  • <openhab_base_dir>/conf/services/
  • <openhab_base_dir>/addons/
    seems to assume a windows installation. In linux (apt install) they are not under the same base dir, and the conf/ directory should be omitted. The correct paths are:
  • /etc/openhab/automation/lib/ruby/gem_home
  • /etc/openhab/services/
  • /usr/share/openhab/addons/

That aside, I must congratulate you @broconne and @JimT for your excellent work, looking forward to playing around with it!