JavaScript rules in OH3

  • Platform information:
    • Hardware: Raspberry Pi 4 Model B Rev 1.1
    • OS: Linux/5.10.17-v7l+ (arm)
    • Java Runtime Environment: 11.0.9 (Zulu11.43+88-CA)
    • openHAB version: 3.0.1 (Docker)

Hello,
I’m trying to manage my openhab configuration only with the texfiles in the /openhab/conf/ folder. So I can use git, which makes it easier to test different configurations. But I’m struggling with the rules. I like to write my rules in JavaScripts as it is made in the UI. For example:

triggers:
  - id: "1"
    configuration:
      itemName: FF_LightHallway
    type: core.ItemStateChangeTrigger
  - id: "3"
    configuration:
      thingUID: shelly:shelly1pm:xyz
    type: core.ThingStatusChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "4"
    configuration:
      type: application/javascript
      script: >-
        var Things = Java.type("org.openhab.core.model.script.actions.Things");
...

But how do I save them in the conf folder?
The files in /openhab/conf/rules/*.rules seem to have a different syntax and you can’t use JavaScript in them, am I right?
After some research I found the openHAB Helper Libraries but they do not support OH3.

Is there a documentation how to setup rules in OH3 which are files and writen in JavaScript?
Thank you.

Just to be clear, the configs made through the UI are themselves stored as text files. Many, including myself check even these into git.

You don’t have to use text based config to use git.

You don’t really. That YAML representation only exists in the MainUI and nowhere else.

What you can do is use the REST API docs to query for and extract the JSON format for the rule and save that as a .json file in $OH_CONF/automation but JSON doesn’t allow newlines in an element so all your code gets munged together onto one line with \n. It’s pretty much useless to hand edit.

For example, here’s the Action from the Smart Doorbell rule template

  "actions": [
    {
      "inputs": {},
      "id": "2",
      "label": "ring doorbell or bark",
      "description": "Plays a doorbell sound and flashes the light if at home.\nPlays a dog barking sound if not at home.",
      "configuration": {
        "type": "application/javascript",
        "script": "var presence = states.get('${presence}') == ON\nif(presence) {\n  var startTime = new Date().getMilliseconds()\n  var oldLightState = states.get('${light}').toString()\n  if(oldLightState != '') {\n    var onState = ON\n    if(oldLightState.toString().contains(',')) onState = '0,100,100' // red as HSB\n    if(oldLightState != '') events.sendCommand('${light}', onState)\n  }\n  audio.playFile('doorbell.mp3')\n  var endTime = new Date().getMilliseconds()\n  if(endTime < startTime + 1000) {\n    java.lang.Thread.sleep(startTime + 1000 - endTime)\n  }\n  events.sendCommand('${light}', oldLightState)\n} else {\n  audio.playFile('barking.mp3')\n}"
      },
      "type": "script.ScriptAction"
    }

Indeed Rules DSL is it’s own language and not JavaScript and those are saved to .rules files.

A somewhat complete rewrite of the JavaScript Helper Libraries for OH 3 can be found here. There are not too many docs for writing rules in .js files but if you search the forum you’ll find a number of posts about it.

There is also the GraalVM JavaScript add-on which has it’s own helper libraries but making those libraries be a part of the add-on is a work in progress.

If you want to stick to the UI format, you may as well just check in $OH_USERDATA/jsondb because all you’ll get is a whole lot of extra work with absolutely no benefit. If you want to use .js files for rules, you’ll have to learn how to do it from the forum and trial and error.

NOTE: There will be many configuration things you will make in OH that are not and cannot be defined in $OH_CONF such as custom widgets, installed rule templates from the marketplace, etc. If you are only checking $OH_CONF into git you are missing a lot. Since you need to check in most of $OH_USERDATA anyway you need to decide if having .js files is worth all the extra work.

1 Like

So what does your workflow look like, if you are editing your OH3 configuration?:

  • Your repository contains the whole openhab folder:
    openhab/
    ├── addons
    ├── conf
    └── userdata
    (What does your .gitignore file look like? Is there anything more I don’t need except the logfiles?)
  • If you edit something, you only do it via UI?
  • After editing you ssh on your machine and commit your changes?

So $OH_USERDATA is transferable to any other OH instance on other hardware or docker image?

I run in Docker so all three of those folders are in the same parent folder, but they don’t have to be. For awhile before I started using Docker I had a root folder (/opt/openhab if I recall) and created a symlink to of conf to /etc/openhab and of userdata to /var/lib/openhab and addons to where ever that folder was at the time.

My .gitignore is:

userdata/*
!userdata/secrets
!userdata/etc
!userdata/jsondb
!userdata/config
!userdata/habot
!userdata/openhabcloud
!userdata/uuid
!userdata/zigbee
!userdata/zwave
userdata/jsondb/backup
userdata/backup
.Trash-1000
conf/html/hum.jpg
conf/html/light.jpg
conf/html/power.jpg
conf/html/temp.jpg
*py.class
*.swp
*~
*.old

Some of the stuff in there is old and no longer relevant but the key takeaway is that I exclude all of userdata and then add back in those parts that contain config or data saved by bindings that I care about. I might decide to include the rrd4j files at some point too though git isn’t great for storing binary data.

Yes. Unless it’s something that cannot be edited through the UI like logging configs or .persist files or the like.

When I’m ready to. Most changes take multiple days to complete and I often won’t commit and push the changes until I’ve finished and tested it.

Yes if you are doing like to like. There are some paths encoded in the configs so moving a userdata from an apt installed OH to a Docker (which is manually installed) might have a few problems.

Thx, I also use docker, so I can copy your .gitignore (except the checkin of the cloud keys).
And I will try to use the UI more often :slight_smile: