Why is everything in JSON format in my OpenHAB installation

  • Platform information:
    • Hardware: Intel NUC i3
    • OS: Ubuntu 20.04
    • Java Runtime Environment: n/a
    • openHAB version: 3.2.0
  • Issue of the topic: Custom Rules and others

I assume this is a completely stupid question and I am doing something wrong. I set up OpenHAB 3.2.0 a couple of weeks ago and used the UI to add things. I recently bought a motion sensor and wanted to add rules based on it. The web UI allows me to set up rules, which are then in JSON format and are stored in the folder “jsondb”. This simply does not allow me to do what I want to do. When searching for specifics on how to set up my rules, I found that most everyone is writing the rules in a scripting language (like DSL). However, I don’t see how and where I would do so. Where do I add DSL rules (in the web UI)?

The same goes for setting up items, etc. All subfolders in “/etc/openhab” are empty. In “/var/lib/openhab/jsondb/” however, I find the JSON settings that the UI is creating for me.

I am totally lost and do not have any clue how to get along. :frowning:

If you want to not have it stored as JSON in $OH_USERDATA, you can not use the UI. You must use text files located in $OH_CONF/rules.

The same goes for Items. If you don’t want stuff in JSONDB, you can’t use the UI to create or manage them. Also true for Things, Links, and Item Metadata

It might help further to know exactly what it is that you want to do.

For MainUI widgets, there is no choice as there is no separate file based version that OH can load for those. They must be stored in the JSONDB.

I guess that I have two questions (at least) and find it a bit difficult to express them.

1.) While the UI is a neat and convenient thing to get started with OpenHAB, it is a bit limiting. I’d like to have full control, write my own rules without the corset of the UI (using times, etc.) and so on. Is this supported in the UI at all?

2.) If it’s not supported in the UI, what is the best way to proceed? I played around yesterday and put a rule into /etc/openhab/rules, which was then found by OpenHAB and shown under rules (as read-only). Is this the correct way to add custom rules? I find it a bit annoying, because my OpenHAB server has no display, keyboard, etc., so I have to work on it remotely (or set up a network share, which I don’t have the time for at the moment).

Regarding the thing I want to do, I am not sure if the result will satisfy me, but then I like playing around and I prefer programming over UI-clicking, so even if I don’t like my approach, I’d like to learn how to write rules myself.
I have a light and a motion detector in my living room. The light is switched on at sunset (via astro binding, works fine). The light should go off between 11pm and 1am, when there is no more motion (but latest at 1am). Since I am typically sitting on the sofa and move seldomly, I want a much larger delay of the motion sensor than it has (Ikea, not configurable, 1min). My take would be to activate a timer (say 15 min), if the motion sensor goes to motion state OFF, and stop the timer, if the motion sensor goes to motion state ON. At 1 am, the light is always switched off.

Besides the final aspect, I’ve made everything work by now by writing the rule and adding the file to “/etc/openhab/rules”. Unless there’s good reason to not write the rule myself in above way, the only thing missing is the final “switch off”. I have declared two global variables for the timespan (11pm and 1am) and use this to check the current time, when the motion sensor changes its motion state. I’d like to use these variables (1am, end of “interval”) to switch off the light eventually (e.g., when I am not at home), but don’t really know how to do this. I could add a cron trigger, but that means having the same info (end of interval) at two places (cron and variable), which adds redundancy and is hence not ideal. Can I somehow convert the time into a cron trigger event?

Cheers
Christian

What have you found limiting about it?

I’m not sure what that means. “The UI does not allow you to use the UI without using the UI”, seems to be the answer.

openHAB main parts are UI, Items modelling, Things mapping real devices/services, rules to give functionality.

Items, Things, rules can all be configured in flat files, a legacy method from earlier openHAB versions.
Using VSCode with openHAB extension as your file editor is recommended.

There are a few fiddly things -custom zwave configs etc. - that can’t be done from flat file.
I don’t think you can use Blockly rules from file, nor perhaps the newer language options.

Configuring MainUI for user-facing displays without using MainUI is quite a challenge, I don’t think you can.
But there are still legacy BasicUI and apps, configurable via sitemap flat file, and HABpanel for more advanced displays

Controlling openHAB itself configuration - add-ons, default settings - should be possible from flat file editing too, though you’ll probably have to scratch around in OH1 docs to find out how.

For your timing rule, search this forum for ‘Alarm Clock’ examples, old and new.

not sure, if this is what you are asking, but when you create a rule in the UI you click “Add Action”, then “Run Script” . Now you can choose, which Scripting Language you want to use. Click “Rule DSL” and you can enter your DSL script.

I tried this, but the rule was never executed. I did a test with a cron and logging → No entry in the log. When I used the exact same code in a rules-file, it worked. Not sure what I am doing wrong.

I find it limiting that I could not write my rules as DSL code (or Python, or whatnot). As in response to baeron25, this did not work. I would like to add rules in the way I can add scripts, no extra clicks. :slight_smile:

Apart from that, I like the UI, don’t get me wrong. It’s just that I am a bit old-fashioned computer science person using text editors quite a lot. The UI for rules is a nice thing and it helped me initially, but I wanted to achieve my very specific goal, I was lost and struggled for about an hour looking at log files with no success.

It works for everyone else. As with everyone else, if you’d like help with a non-working rule, click the ‘code’ tab and paste the result here so we can see what’s what.

Might be your problem. You only want the stuff between then-end in the GUI script section, not a direct copy of file rule. But we can’t see, and descriptions are open to interpretation.

Yeah, this was actually my problem. Thanks for pointing this out. I somehow assumed that I write the entire rule rather than only its body. So this is working now.

It think the problem is that when searching for rules, you find the entire rules and not only the body. So I put the entire rule and thought by selecting “script”, this would render the trigger portion obsolete in the UI.

However, how can I make use of global variables to be shared among different rules?

Is there a way to group rules? I expect that I’ll end up having a bunch of them at some point, so that I am curious how to structure them best (just by name?). In case of files I’d know what to do. :wink:

You can’t, in DSL in GUI. Key stuff can be shared via Items, of course, but that’s not always practical.

How would you deal with a timer then that’s shared between rules? Is there a different approach?

Always. Solutions intended for one environment are not always suitable in another.

The simplest shared timing needs can be fulfilled with expiring Items.

it’s worth reading because it goes on to further depth.

Bur as a generalism, design around the limitations that you have. Can’t share timer between rules? Then don’t design to do that. A mega-rule is the obvious answer.

Less obvious is that rules can call other rules,making the mega proposition more manageable. Except not in DSL, I think. Remember this is essentially a legacy rules language - don’t start out in DSL just because you want to use flat files and/or copy-paste old solutions. Remember also you can run mixed rules alongside each other.

Thanks for the explanation and sharing your thoughts. Which language would you suggest: ECMA, Python, …?
I will have another look at the expiring times; I found them yesterday night, but didn’t quite see a way to cancel them.

No. If you want to use file based configs you must write them yourself.

Yes, if you want to use file based configs, you must write files and place them in the right folders.

Nothing you describe is impossible to do in a UI rule. So your end goal is not a reason to not use the UI. Only your personal preferences will drive that decision. The UI rules are as fully capable as file based rules.

We’d have to see the code to really help. Typically, because openHAB is event driven, you would want to drive behavior like this using events. Alarm Clock Rule and Time Based State Machine might be useful to you.

Correct on Blockly. The newer language options all follow a files first, UI maybe someday approach, much to my chagrin. The only “modern” language with full UI support right now is JS Scripting. All the rest are files only, though there are reports that jRuby is at least working on UI support. JScript cannot work in the UI based on my understanding but there is a third party Java Scripting add-on that does.

Right now I can only recommend Blockly or JS Scripting if you want to write rules in the UI. If you want to use text files I can recommend JS Scripting or jRuby. If you are OK with running a separate rules service I can also recommend HABApp which is pure Python 3.

I cannot recommend Rules DSL for new users because of it’s limitations. I cannot recommend ECMAScript 5.1 because it’s going to go away as soon as OH moves to the next Java version. I cannot recommend Jython because it’s stuck on version 2.7.1 and is based on an all but abandoned upstream project so might break at any moment with no chance of being fixed.

With Blockly you can save a variable from one run of one script to the next, but not easily share variables between rules unless you have one rule call another.

With JS Scripting there is a cache which is map shared by all JS Scripting rules. You can share variables between scripts by putting it into the cache. There is talk of trying to get this into the core so all languages can benefit but I’m not sure how long that will take.

In all the rules languages, a variable defined at the top of the file can be accessed by all the rules defined in that file. These are often referred to as “global” variables, though they are only global to the one file.

Rules have the following metadata properties:

  • UID
  • Name
  • Description
  • tags

You can use any or all of these as a way to visually group (or group through search) a collection of rules.

You can create adhoc groups of rules, Items, and Things on the Developer Sidebar (alt-shift-d). For example, if working on heating, open the sidebar and search for all the Things, Items, and Rules that work with heating and pin them there. While the sidebar is open you have access to everything you are working on right there.

With files you can group rules into separate files. For some languages you can use subfolders too (not Rules DSL).

See Design Pattern: Expire Binding Based Timers and Design Pattern: Motion Sensor Timer. Both of these need to be rewritten but they include Rules DSL examples which should work. If nothing else they present the concept and approach.

But to answer the specific question, the timer will start as soon as the Item enters a state different from the expire state. To cancel the timer update the Item back to the expired state. The rule that triggers when the timer goes off triggers on commands so it won’t be run with the update.