How do I call an OH3 UI script from a rule

Hi,

Apologies if this has been covered before. I did search and couldn’t find it.

I have a common piece of JS code that needs to be called from a number of rules, that I have tested and working in the OH3 UI Scripts interface. I just can’t work out how to actually call the script from a rule.

I’ve tried using the org.openhab.core.model.script.actions.callScript​ method, but the documentation clearly says it expects a file based script, where this one is UI only. The result is that it can’t find the script to execute.

I’ve also tried the RuleManager.runNow method (below) that @rlkoshak suggested on another post, but again it can’t find the script UID and I suspect this is because it’s a script, not a rule and the RuleManager.runNow is only able to call other rules.

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> 

I’ve spent a couple of hours trawling through the community with no luck. Does anyone have any helpful pointers?

A library or a Script (as shown in the Script page in MainUI). If the latter, you can’t find the ID because it’s not a Rule so it doesn’t have an ID. If the latter, why not the former? See OH 3 Examples: Writing and using JavaScript Libraries in MainUI created Rules.

If you have a Script (i.e. it’s defined through the UI and appears in the list on the Script page, I don’t know how much I can help without more information.

I’ve circled the UID of the Create Rule Example in the screen shot above. That’s the ID you need to use.

Hi Rich,

I can only apologise. I was using the correct UID and so I tried your rule manager example again and this time it worked perfectly. I must have had fat fingers and introduced a typo somewhere.

I can see how much you already contribute to the community and so the fact that you’d take the time to respond is really appreciated.

To answer your question, the piece of code is a script (not a rule) defined in the scripts section within the main UI. I absolutely could move it to a library insead without any real issues.

The reason why I was looking to keep it within the UI is that my son is interested in getting involved with me in the smart home project and whilst I have a reasonably solid background in Unix/Linux and the file structures etc., he has none. He does have a bit of programming experience though and so by keeping everything within the Main UI, it is easier to get him involved. Not necessarily a good reason, but a reason :slight_smile:

Again thanks and apologies for taking up your time.

Ah, but a Script is a Rule. It’s just a special type of rule that only as a single Script Action and no triggers or conditions. And really the only difference is a Script has the Script tag.

It’s as good a reason as any. Keep in mind though that you will have to pass any “arguments” to the Script by adding them to a Map and passing that Map to runNow as demonstrated in the last three lines of the example code you have above.

Ideally you will want to adopt the Helper Libraries or put all the Framework stuff into a library though so you can just import it and just call “runRule(“uid”, true, map);” without littering all your scripts and Rules with the same seven lines of code over and over. You can’t do that through a Script though.

That’s good to know. It would be helpful if this was referenced on the Scripts page in the UI, and would also be helpful if you could copy and paste the ID somehow.

1 Like

You can copy and paste the id and for that matter items etc.
Here is how I do it.

This is in the scripts
image

The id is 8e1e6893d6 so to copy and paste it I just click on the script to open it.

If you look in the url bar of your browser you will see the url link. I just click twice on the id and it highlights just that part of the url and then I just ctrl-c and ctrl-v to paste it where ever I want.

You can do the same to copy and paste item names.

Enjoy.

Just had the same Problem: I have created a Blockly Script in the Script Section an then wanted to execute it in a Rule.
Expected behavior was, that in the Rule I click „Run script“ then select my Script in a List of all my Scripts, click OK and be ready. Should be definitly made more easy.

Took me a while to understand how to use the example from the First Post in this thread.

So just for anyone you whant to do the same.
Click „Run Script“ → than „ECMA Script“ than past the following:

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(„XOXOXOXOXO");

replace XOXOXOXOXO with the ID of your Script, which you see under the Script Name in the Script List (as shown in @rlkoshak ´s Post of Jan 07.)

1 Like

It is that easy. You just looked in the wrong place.

  • Add Action
  • Other Rules
  • run these rules(s)
  • Select your Blockly Script from the list.

Oh thats great, didn’t saw that, because i just looked for script. Maybe add a „…/script(s)“ in the GUI at this place.

There is a typo the, should be "
RuleManager.runNow(“XOXOXOXOXO”);

Yeah, thats the annoying auto-correct in Safari. Don’t have that in my Rule.

Hi,

i am trying to get a script running that worked finr in 2.5
The script is executable over SSH login and starting it in the directory.
I cant get it to start in a rule. This is the old line:

executeCommandLine("/etc/openhab/scripts/openhablogs.sh", 10000)

I read a few posts about executing scripts but none got me to get it working. As i am a visual learner, i mostly get the curve when i see code that works.
The owner of the Script is openhabian:openhab
rights on the script are -rwxrwxrwx
Members of the group openhab are openhab, openhabian so it shouldnt be any right issue as far as i can see as a windows user.

I would like to try the Blockly part for that but have no idea where to start.
Pointing me in the right direction with either a codeline or any other ideas is highly appreciated. Helping me building a blockly rule for this would be brilliant :slight_smile:

Thnx a lot
M.

During the upgrade you didn’t review or missed the list of breaking changes. The way to use executeCommandLine has changed between OH 2 and OH 3. See Actions | openHAB

Blockly does not yet support Actions.

This topic is about running rules/scripts from within other rules, so won’t help you.

Having said that, this link should point you in the right direction ExecuteCommandLine and the following code is working in my implementation to run a command line executable -

'use strict';

var log = (context.logger === undefined) ? Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.core.model.script.actions") : context.logger
var Exec = (context.Exec === undefined) ? Java.type('org.openhab.core.model.script.actions.Exec') : context.Exec
var Transformation = (context.Transformation === undefined) ? Java.type('org.openhab.core.transform.actions.Transformation') : context.Transformation
var Duration = (context.Duration === undefined) ? Java.type("java.time.Duration") : context.Duration;

var SpeedtestOutput = Exec.executeCommandLine(Duration.ofSeconds(120),"/usr/bin/speedtest","-f","json");

Most of this was gained by getting help from @rlkoshak Thanks again Rich.

Trev

Thnx a lot i will review tomorrow
Cheers M.

Hi,

just tried what i read in the Link you posted under OH3 Actions.
It looks nearly the same as the old line so i am a bit confused…
Reading the example the line should look liek this: executeCommandLine("path/to/my/script.sh")
what in my case would be “executeCommandLine(”/etc/openhab/scripts/openhablogs.sh")"
It works when connected through SSH but it wont fire the rule with a trigger.

rule "executecommandLine Test"
when
       Item Dummy received update
then

                  executeCommandLine("/etc/openhab/scripts/openhablogs.sh")

     

end

I just dont see the trick yet…
Cheers M.

What is the script returning? Add the Duration argument and log what is returned by executeCommandLine.

Its really hard to help when you don’t give us any details. What does this script do? How do you know it’s not working? what is the output when you run it through ssh? What user are you when it runs through ssh?

In general, the Exec binding is one of the most challenging bindings to get to work right because you must be proficient in both openHAB and the operating system that OH is running on.

Hi,

sorry i didnt give the purpose of the script. its clean simple:
“tac /mnt/ext-storage/oh3/mirhome.log | head -n 10 > /etc/openhab/html/mirhome10.log”
It just takes the logfile mirhome.log, takes info out of it and writes it to a new mirhome10.log
It just creates a new file.

I just want to show the last 10 log entries on the BasicUI. If you got a better idea for doing this i am more than willing to do it different.

Thnx M.

And the answer to the rest of the questions?

How do you know it’s not working? what is the output when you run it through ssh? What user are you when it runs through ssh?

The mirhome10.log is not written or created. Im on the openhabian user on SSH. the funny thing when i try to change user to openhab it pops back to openhabian user.
Changing to other users works. The rights on the Script are free for all. rwxrwxrwx and owner is openhab:openhab. The group mebers of openhab are openhabian and openhab.