Making OH Rules Easier for Everyone

Don’t let that stop you.

For the most part one of the big problems with all the JSR223 libraries is lack of examples and lack of documentation. If you start sharing I guarantee you will get some followers and end up on the same page with a few users at least.

Please share your ideas and code! It all helps. :smiley: And you clearly have a lot of good ideas and if the sample code is any indication your code is clear and concise.

2 Likes

Let’s move the name calling to PMs or off the forum. Sarcasm and joking around is too easy to misunderstand, particularly on an international forum where the bulk of users are not native English speakers. and nuance is lost.

JSR223 has several advantages.

We have it now. (first to market)

There is more than one person using it/pushing it on OH. (better support in OH)

It supports two top ten most used languages now. (networking effects)

It seems to be lost now but a long time ago an essay from Neil Stephenson’s In the Beginning there Was the Command Line entitles “MGB, Tanks and Batmobiles” that circled the Internet. In it he used an extended metaphor comparing operating systems to cars. Windows was a massive station wagon, Mac OS (this was well before OSX) was a hermetically sealed sports car, Linux was a tank and BeOS was the Batmobile.

I used Be in its day. It was phenomenal. Damn I loved working in Be. And that statement definitely ages me.

But today we still have the station wagon and the tank and a new sports car rebuilt from the ground up. The Batmobile is all but gone and frankly has been long since surpassed in capability and features by even the station wagon.

Java looks like the station wagon. Python looks like the tank. I don’t know what the sports car would be, maybe Ruby. Right now, Kotlin looks a whole lot like the Batmobile to me. It may be the most awesome thing ever but that isn’t enough. Superior technologies die out to “good enough” all the time.

And to be fair, Rules DSL is a moped.

1 Like

So true! :slight_smile:

1 Like

I agree, when Amazon echo first can out. I developed a few “Alexa skills” using javascript. Without tons of internet support and tutorials I would still be working on the first skill. I did learn a few things, at the time, through trial and error but I’m no programmer. This was several years ago, I wished I would have kept developing and learning but I ran out of idea’s for new skills.

If JSR223 is similar to javascript, I’ll have to read up on JSR223, I’m willing to give it a try. Worst case, I fall flat on my face and revert back to Rules DSL.

Can I use both Rules DSL and JSR223 with my OH set up (installed via openhabian image on RPI), or would a fresh install on a test server be the better route?

Thanks

It is a way to write Rules in Jython, JavaScript, or Groovy.

You can use them in parallel.

JavaScript will be easier to set up and started initially. There are more users on the forum working with Jython though so there will be more support with that language. I’d like to see more docs and support for JavaScript and Groovy though.

Just a FTR. Please review below syntax, comment, criticize on improving readability.

You need to trade “a little readability” compared to ESH rules DSL but you get full IDE support, first class Java integration, ESH/OH community no longer has to maintain/improve/promote a rules VM, and robustness+goodies of Kotlin and of course tones of examples/tutors/support from Android and Kotlin community.

https://github.com/diyhomeauto/smarthome/blob/master/Kotlin-ESH-openHAB-draft.txt

FYI this is working! Need to polish certain things and of course adapt as per community feedback.

Since this a generic thread, I would prefer main Kotlin discussion be maintained in below thread, just to spare the Kotlin noise from those who ain’t interested here :slight_smile:

Rules DSL has that

Rules DSL has that

I don’t really see how this integration is much different from using Xtend as the base of the Rules DSL. We don’t maintain/improve/promote that. All the work done is on the interface between OH and these Rules which would still be there for Kotlin.

My point isn’t to somehow claim that Rules DSL is good or as good. Just point out these features are not a differentiator. Clearly it is possible to meet all of these criteria and have an unsatisfactory result.

Anyway, I’ll preface this with I like what I see.

Observations:

  • I would like to have something to differentiate rules a bit more clearly. the fact they both start with “config {” and except for positioning it is not clear that “actions” goes with config or the config before. As it is currently written it is not obvious that the config and actions are a unit. Can I have more than one config per actions? Can I have more than one actions per config?

  • I’ve some issues with the triggers. The OH architecture is event driven. As things occur the fact of the event goes on the Item Event Bus. These events are Item changes, updates, commands and a smattering of Thing events (ONLINE/OFFLINE), trigger events (Sunrise/Sunset/Dash button). So, when I see item["BedroomLight"].is(ON) it raises a bunch of questions. Does this mean that these Rules can be triggered by state as well as events? I see the equivalent of the changed trigger. What about received command or received update? I have some concerns if you are mixing state based triggering and event based triggering. This is one area where I like the Experimental Rules DSL. There are two clauses, a “When” clause where the event triggers are listed and an “But only if” clause where we check the states of Items to determine whether the Rule should run given the states of various Items. If .is(ON) truly is an event based trigger then I have major concerns about this nomenclature because there is nothing about .is(ON) that implies it is anything but the state, not the event that is triggering the Rule.

  • I’m very much not in favor of sending commands to Thing’s Channels directly from Rules. The purpose of Items is to “model” your home automation. OH revolves around Items. Items are intended to represent all the pieces of information and actuators in your home automation. Rules should operate on the model. Bypassing the Items means that Rules are bypassing the model and now there are two different ways to interact with your devices instead of just one which will just cause confusion. Furthermore, what happens if I have an Item connected to “Radio1.station” and I send a command to the Channel directly instead of to the Item? Does the Item get that command to? Does it get it as a command or as an update? Or is the Item now out of sync with it’s Channel? I was very much not in favor of Thing triggers in Rules as well but we see they exist. But I only see a mass of confusion and questions like “what are Items even for? when should I use an Item and when should I use the Thing? I sent a command to Foo but it doesn’t show the change in my UI, why?” and so on. It further breaks down the layered architecture OH has. If Things are at the bottom and Rules are at the top, Items are the layer between. This causes all sorts of intrusions from the Things layer into the Rules layer.

  • What is SUNRISE? Something built in or something defined elsewhere? Does it use Astro or something else?

  • Is there some sort of builder of full documentation for the scheduling engine? I’ve never been all that much of a fan of cron but at least there are tons of tools to help build them. This looks slightly more intuitive but it isn’t clear how I would do something like “the first monday after the first sunday of the month” or “every minute”.

  • So this enabled-when/forbidden-when looks a whole lot like the “But only if” clause in the Experimental Rules Engine. This is where checking of Items states or online status of Things and the like should be placed. Oh wait, I see you have a should-not-trigger-when clause. I see no reason to have two separate clauses for this unless there is a very compelling technical reason. Put them in the same clause.

  • I don’t know what I think about the optional alias-* fields. It’s optional so it probably doesn’t hurt anything, though I’m still against interacting directly with Channels and Things from Rules. I probably wouldn’t include it in any thing I posted because I find that the longer the chain of things to remember the harder it is for non-technical users to manage. Changing the name of the Item for this Rule and this Rule only adds a whole new level of redirection and abstraction that I think many will find confusing. Regardless of whether I agree with having Channels and Things here, there shouldn’t be separate clauses for the three, there should be just one alias clause and the engine should infer from the context what the alias is for. Fewer optional clauses is better than more clauses that do the same thing only with a different type of data. The new non-technical users shouldn’t have to worry too much about type. One of the problems with the Rules DSL is the users must worry too much about type.

  • Can I put any arbitrary code in the should-not-trigger-when clause so long as it returns a boolean? Like a whole function? Because there may be cases where some significant calculations need to be made to determine if the rule should run that won’t fit on a single line.

  • Can you explain what an emergency theme is?

  • Another cool feature of the Experimental Rule Engine is the ability for Rules to disable/enable other Rules. Have you thought about something like that?

  • val msg = "Intrusion alert, suspicious activity near ${device["Door1"].label}"; Why the ; here? Is ; always optional, sometimes optional?

  • sendUiNotification(msg) How is scope managed? Where is this function defined?

  • “device means ESH Item or Channel, thing means ESH Thing” Is there no way to be able to just refer to the Items by name? This is one of my complaints about a lot of the alternatives. They all have indirect access to the Items.

  • systemConfig.emergencyPersonal.filter(it.name == "Jack" || it.name == "Kim").sendSMS(msg) Does this assume there is only one it with the name Jack? What if there is more than one? What other collection actions are available?

  • lookup and use OSGI service, with special systemService helper If I’m understanding correctly, this will create a separate JSONDB file under /lib/openhab2/userdata/jsondb. That is really cool, so long as there is no risk of corrupting the other JSONDB files. What other OSGI services are available? I’d prefer this were just available and not something that we would have to look up and extract from the system services.

  • Will third party Actions be supported?

  • Are all of the methods on the Item classes available? In particular the persistence methods and group methods?

  • (How) Can I trigger a Rule based on an update, command, or change to one of its members? How can I determine which member triggered the Rule in the actions section? Or do you have some other approach that makes more sense in a Kotlin context, though it would ease migration if this were more directly supported.

That’s all I have for now.

On paper yes, but Xtend language has annoying quirks that Kotlin doesn’t. Its like having same looking cars but engines are different.

Below reply is not yet complete. More to come.

Right now its one config and one actions per file. Re-usable code will go in global functions, libs, classes etc. More on that later.

User will be free to combine conditions. The ones shown are not exhaustive at all. There is also a filtering/pruning in between to avoid lockups/infinite recursions. And the ones who do want to depend on only states vs “change in state” or trigger, will be evaluated regularly (at specified intervals). Imagine a stubborn theme, that must ensure regularly that all devices are in given state, if theme conditions are met.

Items / Things / Channels are all optional. You can use whichever you like. I don’t want to push one paradigm here. Because I got most scenarios covered without using the concept of Item.

Its goodies available from standard kotlin-esh extension libs. They help majority of beginners. If people prefer a more verbose Java approach like TimeUtil.SUNRISE then we can do that.

Yes. There will be a type safe builder available soon for scheduling engine. I have to work hard. :slight_smile:

There could be multiple contributors, and it allows experimental new conditions separate from those already working. Same reason most Linux /etc/package.conf are now /etc/package.d/xyz.conf. All those conditions eventually get combined by AND / OR. Its optional anyway.

They are soft referencing mechanism. They make rules re-usable across sites, where exact device names and technologies are different. Like I said earlier, I am no fan of Item concept, its a baggage in my personal opinion. I got a complex system working without even have to deal with single Item. Rule engine should be able to work directly with Thinghs and Channels.

Yes. Where ever you see { // code } , it is a lamda that eventually returns something.

More on that later. Rabbit hole goes deep. :slight_smile: You need to take Blue pill first. :wink:

There will be Karaf/Rest commands to do that. I am no UI expert, otherwise I would have created nice Enable/Disable UI for installed Kotlin rules.

Its optional so that we can have endless debates about whether to have it or not. :slight_smile:

There is an explicit way for those who know Items and Channels are different. item[“MyItem”] or channel[“MyChannelUID”]. But you can’t have MyItem as variable unless you declare it with

val myItem = items["MyItem"]
// Now myItem is org.eclipse.smarthome.core.Item Java object
// You can do anything with it as you would do in Java, plus Kotin extensions if any on that type.e.g method flagForMyCustomInspection below
if(myItem.getState()==OnOffType.ON) { myItem.flagForMyCustomInspection() }

Its a pipeline. A typical language feature in modern langs. You pipe things, filter, map, convert and then take actions available for those types. You can tailor above to your need using many many ways. I will document as much as possible. And IDE also shows possible actions in auto-complete.

There is a security risk here. We need not expose all core services to Kotlin Rule/App unless user has explicitly approved it somehow. Some conscious decisions we can make based on our knowledge and experience, on behalf of our users.

To be contnd…

Sounds great for technical users. This is almost a deal killer IMHO for non-technical users.

Great for experienced users. This massively increases the mental load on the new users.

And that is one of the main complaints of new users to Linux. More fields like this increases the mental load on the inexperienced users. It also increases the opportunities for those users to do what they think is intuitive and fail.

Unilaterally deciding that one of THE KEY concepts in OH is “baggage” is not going to endear you or win you any converts among the maintainers.

You misunderstand. I mean I have a Rule that runs and because of something it detects/decides that Rule is able to disable/enable some other Rules. No UI involved.

If its optional

I’d recommending never showing it. It just raises questions and confuses the new users who don’t know how to tell what’s important and what isn’t.

One more thing the new user needs to know that they should have to to write their first Rule.

I’m not totally ignorant of all these new fangled programming languages that all the young whipper snappers are using. Rules DSL/Xtend has this as well. I just wanted to know the parameters about how it works here since in my experience every language handles them slightly differently. In particular, is there an implicit for each on the collection returned by filter or does the filter assume only one result?

So far it would seem that you are rejecting any advise/criticism I might have to offer so I’m not very hopeful this will become something I can recommend for new and non-technical users.

FTR aside from some other improvements, I have added offline-test and offline-test-assert sections for easy testing at build time without having to connect to live instance.

Rich, you are primarily interested in newbie adaptation. In your opinion Rules DSL has already done everything that should have been done and no new language/ enhancements could significantly improve the current situation that we have. I have noted that and I am working hard to make the Kotlin equally good and hopefully better for newbies.

My goal is also to attract dev community. I have already stated that. Title says make rules good for everyone, isn’t it?

Bashing a concept only based on one goal (newbie compliance), is not fair.

Every new minute is an event. People should be able to write conditions against that.
To make things clear I have made explicit expression

retrigger-delay { 23.hours } 

in the rule-config section. Above criteria introduces a fixed minimum delay for “My Wakeup” rule while re-triggering. We know sun doesn’t rise again within 23 hours. Or is it 22? You can tune it for your location.

Now you agree its really Xtend behind the scenes. The rules DSL is basically a custom “when” clause and its OH-specific trigger specification combined with Xtend statements in “then”.
Kotlin is much better than Xtend. If your are hung up on beauty of when clause and its semantics then continue using and promoting it.
Xtend and rules DSL IDE support, its VSCode I believe, you guys discontinued Eclipse IDE based support because Xtend is not something even Eclipse folks want to pursue? That VSCode extension is maintained by ESH/OH community members. How many are they anyway? Kotlin’s JetBrains team will obviously surpass them.
How may Xtend examples/tutors/videos are available on internet today compared to Kotlin? Users should do their own math.

Yes, I have rule priorities. Not publicly documented yet. In my model, a rule cannot override a system’s core rule or emergency rule. Allowing any rule to disable any other rule is a rudimentary model in Experimental Engine.

The code installed and available in the osgi container is assumed to be authenticated already with jar signing or osgi installers. The Kotlin rule will be able to execute any installed code. But like I said, we need a user consent on what rule can call what system services, and there are rule priorities as mentioned earlier.

There will be some thin layer between important core classes like Item, Thing, ThingHandler etc. , that layer will ensure non-relevant methods are hidden for clarity. This layer will be different for Kotlin Rules, Kotlin Bindings and Kotlin Apps. The Apps will have least restriction. An App could include Bindings, Rules and UI extensions, although that part is not yet implemented. We have to get there.

In fact, the concept of Thing and Channel is more visible to a newbie than the concept of Item. If you put OH in Item linking simple mode, you see no item concept throughout all the UIs. The Item concept is for experienced users like you, who know OH for a long time. On this point, I am actually making things better for newbies by allowing Channels and Things in rules.

That is not accurate. I see enough reasons to support multiple triggers-when and should-not-trigger-when clauses. Imagine your /etc/sudoers is maintained by 10 different packages, it was a nightmare, that is why there is modularity introduced these days. No one entity contributes everything. Support for multiple when clauses comes from same experience.

Like I mentioned earlier, Item concept is not relevant to a beginner on any of our UIs if item linking is put in simple mode. It was the default mode in 2.1, 2.2, I believe, you guys changed it to off. But I always liked simple mode. I don’t care about items and I have gone so far. So can any other user. Just that he needs a rule language which allows it to express what he already sees on UI.
Items make you write config files, which is OH1 philosophy I believe. Its a newbie barrier.
Who is being unilateral / totalitarian here? The maintainers and hard core users like Rich or new users like me? I wonder.

Like I said earlier, if Items are optional, things will be simpler for newbie. For advanced users may Items make sense, but wait, the group concept can be eloquently expressed in Kotlin based infrastructure, and the group averaging functions can be changed by user easily.

filter produces multiple output items. And map converts them to different objects. Its actually not difficult to understand, you might already know Unix pipelines. Its similar thing but statically type safe. Like in Microsoft Powershell.

Like I said already, we shouldn’t be unfair when evaluating different paths, especially when they can lead us to a common destination. In this this case, making our platform better than it is today.

I dunno personally, the more options for us devs, the better. I don’t really care about non-technical users, unless i get paid for it, so better don’t listen to me.

OH2 sure deserves something better than Rules DSL but Kotlin probably isn’t it. They need something like a dumbed down Node Red with a lot of fancy colors and buttons. Kotlin sounds more like something that comes up your throat in the morning after a night on coke with a lot of cigarettes and beer idk. J/k, i bet it’s pretty cool, i’m just not java-nerd enough.

And yeah i try to avoid talking about my smart home fetish too much with co-workers and such, only the wife knows about all my dark secrets. Kai and me should invite some of you regulars over to some german beers, then we can audit each other’s rule code and talk about your kotlin boner.

A statement like this does not belong in a thread titled as such. I do admire your humor and honesty though.

Hey, by the way, what JavaScript IDE you use? Is there any other way to create a bidirectional bridge from JavaScript to Java?
I used Rhino JS engine with JSR223 like integration 8 years ago, at that time it was the only option, we did build a nice product on top of it.
I am not sure about latest JS/Java integration for the back-end purposes.
I do agree with you that JS has the most extensive collection of UI centric libs and the node-JS backend libs.
I am trying to figure out how we leverage that.

What i’m trying to say is, i rarely work on code i don’t need personally and i’m the kind of dev who stops coding if something works “good enough”, i (mostly) don’t go out of my way to make it fool proof, i don’t really have the patience to explain things like that to non-techies either, i don’t like writing docs. I work as project manager / lead dev though so i guess i have some valuable input

I’m just using VS Code, Visual Studio, PHPStorm at work, sometimes. I’m not doing any Java stuff at all though, i have been successfully avoiding Java since school. :nerd_face:

1 Like

Yes, your input is valuable and appreciated.
Thanks

That’s not true. I’d love to see something better for new users come along. But I have definite opinions on what would be as easy to use or easier to use for non-technical users.

I’m of the opinion that there really can’t be a programming environment that has the training wheels necessary to help these new users and have the flexibility an experienced programmer desires. But I’m willing to be pleasantly surprised. That’s the main reason I’m even pasting here, besides the fact that the not-technical users need an advocate moreso than developers do.

These training wheels included

  • fewer options, not more
  • fewer ways to do something, not more
  • self descriptive syntax
  • clear delineation of scope and what goes with what
  • intuitiveness and consistency

Based on those criteria Rules DSL and Experimental Rules are better than what is proposed so far (I’ve not yet reviewed your most recent changes).

Perhaps it’s a fools errand to try to target both audiences with the same language. I’m perfectly willing to accept that. But that also means that Kotlin can’t be and won’t be a replacement for the Rules DSL which is what you are proposing, because it is worse than Rules DSL on these criteria.

You might have to choose between targets. And if you choose to focus on devs, that’s fine and appreciated and will probably be an improvement. But don’t advertise it as the language to use for new users and I really won’t have any useful opinions to offer so will happily bow out of the discussion.

Why? You are presenting this as a better replacement for Rules DSL. One area where Rules DSL is good is in its relative simplicity to learn for non-technical users. If you want to replace Rules DSL with this it needs to be at least as easy to learn and use for non-technical users. Otherwise it is just an addition for developers. That’s perfectly fine but it means it’s not a replacement for Rules DSL.

And if you are not trying to build an environment for non-technical users, I don’t have anything to add. You are a better Kotlin developer than I am. You know better what makes sense to be available to other Kotlin developers. I have nothing useful to add.

I guess my tl;Dr is if you want to target both types of users, I’ll continue to push back on anything that violates the criteria above. If you want to only target developers, I have no opinion. If you want to target only new users I’ll push back even harder.

I only speak for the non-technical users. I’ve said it before. It’s unfair to expect me to provide any opinions from any other perspective. I’ve already made clear what my role would be in this discussion. And it is unfair to expect me to be ok with compromises in favor of developers with no apparent immediate benefit to the non-technical users. My job is to advocate for the non-technical users and I’d be a poor advocate if I did.

Yep, you caught me in a typo.

No, because there were changes to rules dsl from oh 1 to oh 2 that broke the syntax checking and VSCode came along before anyone could fix ESH Designer. I’ve no idea if there is an IDE for Xtend but ESHD wasn’t it. ESHD was an IDE for OH. VSCode with the oh extension is an ide for OH. The vast majority of the syntax for rules is custom Rules DSL. The sorts of things both checked, and whether they provided the most benefit are:

  • syntax checking for Rules, Items, Things, and Sitemaps, not just Rules.
  • Item aware meaning if you refer to an Item that doesn’t exist they tell you.

A generic Kotlin idea isn’t going to do that.

As was Designer.

That is something I can get fully behind.

At the end of the day, if you want this to replace Rules DSL for non-technical users then my comments here are useful. If you want this to target other developers then my comments are not. I’ve already said me peace in that end (I’d like to see Python since it is known by far more developers and there are far far more scripts and libraries that imminent ha relevant APIs than in any other languages).

I just don’t think this is productive.

1 Like

Would not something like Flows Builder be better suited to meet the needs of non-technical users?

Assuming it became the new face of the Experimental Rules Engine (and was built-in and not requiring the added effort of setup and configuration like Node-Red), it seems to handle the basic needs of “when this happens, do that” using a clean visual presentation. Someone said it reminds them of Node-Red but, from appearances (I haven’t actually tried it), it appears to do more hand-holding than Node-Red. A quick look at this image shows lots of basic triggers/conditions/actions in the left-hand menu.

Apparently the developer has suspended developing it because of alleged instabilities in the Experimental Rules Engine and, I assume, is waiting for it to stabilize before continuing.

1 Like

Reminds me of the Girder 3/4 type of interface for building actions based off events with conditions. The treeview was a great way to build automation tasks easily.