Run a script by UID from within another script (ECMA OH3)

In the OH3 main UI ECMA script editor, what is the syntax for triggering another script by UID? The documentation appears to be incomplete on the matter (https://openhab-scripters.github.io/openhab-helper-libraries/Examples/Rule%20Registry%20Example.html)

I believe the helper libraries have not yet been updated for OH3.

// Run another rule
var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
var _bundle = FrameworkUtil.getBundle(scriptExtension.class);
var bundle_context = _bundle.getBundleContext()
var classname = "org.openhab.core.automation.RuleManager"
var RuleManager_Ref = bundle_context.getServiceReference(classname);
var RuleManager = bundle_context.getService(RuleManager_Ref);
RuleManager.runNow("tocall");
var map = new java.util.HashMap();
map.put("test_data", "Passed data to called function!")
RuleManager.runNow("tocall", true, map); // second argument is whether to consider the conditions, third is a Map<String, Object> 

Notice how you can pass data to the called rule too.

With the Helper Libraries all the above is really just one function call to the library.

“tocall” is the ID of the other rule to run.

2 Likes

First, thank you for that. Seems like the long way in for now but it will get the job done until it’s baked into the cake later I guess.

Second, whoa, you can pass arguments into scripts and rules now?? I’ve been craving that for a LONG time. How are those parameters defined in the script/rule now? Or is it by the name of the variable and you can pass in any of them??

This isn’t something new. And I can’t say for certain if rules loaded from files work differently from thsoe created through the UI.

You pass that map which has the name/value pairs for the data you are passing to the other rule. Then in the other rule, if I recall correctly, all those name/value pairs will have been added to this so you can just reference is using this.test_data. You can test if it exists using if(this.test_data !== undefined) to be safe.

I’ve no idea if this works in Groovy or Python. It’s built into the scripting engine so it should, but I’m sure they are referenced in different ways.

I don’t think this can be done using Rules DSL.

2 Likes

Until now, I’ve never used anything but the DSL rules. So this is new to me. Makes me happy.

It might be worth an experiement in Rules DSL. I would expect you to be able to just reference test_data directly if it works.

@rlkoshak thank you once again for this information. I just finished implementing the one thing I’ve wanted but couldn’t have with DSL in OH2.5. A single script that handles all notification communication, taking required data through arguments by other calling scripts.

So my notifier script has all the code needed to send emails, pushover messages, myopenhab cloud broadcasts, and logging. Including all the common stuff I want in any message. Arguments feed it the topic specific subject, body, and priority. Then in my various scripts that handle environmental and alarm systems, I just call the notifier script and send it those needed arguments.

In DSL, where this isn’t possible, every rule for every little thing has to have a mile of rambling crap doing the same thing over and over. It was such a mess and difficult to maintain. This is the cleanest and most consistent notification messaging I’ve ever been able to produce.

There are approaches to achieve this in Rules DSL. Even in Rules DSL you shouldn’t have duplicative. Design Pattern: DRY, How Not to Repeat Yourself in Rules DSL

And for code like this that us dealing with notifications, it’s probably best to create a library instead of calling a separate rule, but the specifics are in the details. See OH 3 Examples: Writing and using JavaScript Libraries in MainUI created Rules. Centralized alert notifications are one of the examples there as well.

Hi Rick!

Wonderful example (like always)! :slight_smile:

But I have a question: How can I use the map in another js rule (to use the parameters). I tried it with map.get(), but this seems not right. Do I have to include “var newHashMap = Java.type(“java.util.HashMap”);”. To use the the same var (“map”) was not right, too.

Thanks a lot!
HFM

That is an important bit of detail that I’ve not posted.

The data is passed to the new rule under a variable called context which is a SimpleScriptContext Object: SimpleScriptContext (Java SE 11 & JDK 11 ). You need to use getAttribute to pull the data passed.

var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Run From");
logger.info("Passed data is: " + context.getAttribute("test_data"));
1 Like

Thanks for the details!
Helped me. :grin:

HFM