[SOLVED] Simple exec binding scenario: call shell script on Linux and have a switch item to toggle ON/OFF

  • Platform information:
    • Hardware: raspi
    • OS: stretch
    • Java Runtime Environment: JDK 8
    • openHAB version: 2.4
  • Issue of the topic: Simple exec use case: Have 1 button to trigger a script

Hi to the community.
After 2 years working with fhem, i also started looking into openhab 2 yesterday and started with Paper UI.

I have installed OH2 and configured a Shelly 1 with MQTT within the Paper UI => worked fine

Now i want to execute a script to switch a Gembird USB connected poweroutlet.
On Linux there is a nice tool, that does the trick, called sispmctl, so i just need to call that tool.
IHMO the scenario is very simple but searching the web and reading the docu doesn’t help me. Either the info is outdated about older versions of openhab or people do a lot of fancy stuff and assume the user is an openhab expert already.
All i need is a switch item, that switches ON / OFF and is connected to an EXEC binding / thing

Somebody able to help me here?

I tried starting with:

  • EXEC binding
  • defining switch thing configfile under $OPENHAB_CONF/things
  • defining items configfile under $OPENHAB_CONF/items

I also tried witin the visual Paper UI but it is not clear what to fill for a newbie

Hi Andreas,

Welcome to the community!

The most up to date documentation about the exec binding can be found here. Unfortunately, it seems that the rule example contains an error and as a result the sample does not work (the trigger execution should be before the while-loop).

I have stripped down the demo example to the bare minimum:

Content of exec.things (you can name it anything you like, as long as it has the things file extension):

Thing exec:command:yourcommand [ command="/tmp/exec-test.sh %2$s", interval=0, autorun=false ]

Here you define what command needs to be run, in this case a the /tmp/exec-test.sh shell script. The %2%s will be replaced by the (optional) command line arguments.

Content of exec.items (you can name it anything you like, as long as it has the items file extension):

Switch YourTrigger

// state of the execution, is running or finished
Switch yourcommand {channel="exec:command:yourcommand:run"}
// Arguments to be placed for '%2$s' in command line
String yourcommand_Args {channel="exec:command:yourcommand:input"}

Here we have defined the YourTrigger switch. By toggling this switch, you will trigger a rule which will then trigger the execution of your shell script.

The yourcommand and yourcommand_Args items are used in the rule. You don’t use them yourself to manually control the thing.

Content of exec.sitemap (you can name it anything you like, as long as it has the sitemap file extension AND the sitemap keyword is followed by the name of the sitemap file without the file extension):

sitemap exec label="Your Value"
{
        Frame {
            Switch item=YourTrigger
        }
}

You can display the sitemap in your browser by opening the following URL: http://<your openhab server ip>:8080/basicui/app?sitemap=exec
(If you’ve named your sitemap differently, then replace exec by the name of your sitemap)

The sitemap file is also used to determine the layout of the mobile apps.

Content of exec.rules (you can name it anything you like, as long as it has the rules file extension):

rule "Your Execution"
  when
     Item YourTrigger changed
  then
      if(YourTrigger.state == ON){
          yourcommand_Args.sendCommand("ON")
      }else{
          yourcommand_Args.sendCommand("OFF")
      }
      // Optional: give the event bus time to update the item
      // Thread.sleep(250)

      // Trigger execution
      yourcommand.sendCommand(ON)
end

When the YourTrigger item is changed by toggling the switch, the rule is triggered. When the state is ON then the yourcommand_Args item is set to ON. Since yourcommand_Args is an Item, we need to use sendCommand to update its state. The new state is then sent to the openHAB eventbus from where it is picked up again and assigned to the item. Note that this is asynchronous so you may need to slow down the rule a bit by adding a Thread.sleep(...).

So you cannot do the following in openHAB to assign a state to an item: yourcommand_Args = "ON".

The youcommand_Args will contain the command arguments. So in this case when you switch the switch on, then the command line argument will be be ON and when you switch the switch off then the command line argument will be OFF.

To demonstrate this, I have created a little shell script which will save the command line argument to the /tmp/exec-test.out file.

Content of the /tmp/exec-test.sh script that will be executed by the exec binding. Note that the openhab user will execute this script so it must be executable by the openhab user.

#!/bin/sh
echo $* > /tmp/exec-test.out

When you toggle the switch, the command line argument will be stored in the /tmp/exec-test.out file.

Hope this helps!

Hi Marcel ,

Thanks a lot for the nice welcome and the detailed answer.
I will go through it in more detail.
After a short superficial reading, please allow me one more question: is there a way to define a variable in the thing config, to get the ON / OFF command coming from a switch item?

So instead of " %2$s" is there some variable i can use and get the value ON or OFF?

Cheers
Andreas

The %2$s will be replaced by the state of the yourcommand_Args item when the script is triggered. So yourcommand_Args.state equals the state (ON or OFF) that was used when the script was triggered. However, until the rule (and as such also your script) is triggered for the first time, its state will be NULL.

If you would like to query the current state of your Gembird USB connected poweroutlet e.g. on openHAB startup so that it can display the correct state (I don’t know if the poweroutlet supports this functionality), then you would need to execute a script when openHAB starts up. This can be done with a rule that executes based on the System started trigger.
The script would then need to query the device and output the state. The state will then be stored in the yourcommand_out Item (see the demo.items example - note that I skipped this item in the exec.items file in my example).

Instead of using the while-loop to wait for the result of the script (as shown in the demo example) I would simply add another rule which would trigger when yourcommand_out gets changed. Due to the limited (from the top of my head 5) rule threads that can run at the same time you will want to avoid blocking rule threads as much as possible (and Thread.sleep() blocks the thread).

Thanks to @rossko57 an update of the documentation is already on the way.

Searching for hours today :frowning: and the help from here (Thanks a lot ! :slight_smile: ) finally helped me to understand what’s my wrong assumption. There seems to be no real Switch kind of channel for the EXEC binding.

Actually this EXEC binding is able to trigger execution of some script (via a channel) and it also has another channel to provide some input to the script.

Unfortunately the most important part is missing: I want to have some Switch to switch a socket or some light on or off via some script. It is obviously not so sexy to manually write ON or OFF into the input channel and trigger the script execution.
For the MQTT device (i configured as my first device) i could choose a channel of type ON/OFF switch. Is there anything like that for the EXEC binding / thing ?

I don’t understand what you mean with “I want to have some Switch to switch a socket or some light on or off via some script”.
The sitemap example contains a switch. When you toggle the switch, the rule is triggered which then will set the correct command line parameter and triggers the exec binding to execute the script.

Nope, you saw the docs.

Having to run an external script is a necessary kludge here to begin with; a little rule to control that isn’t a huge burden.
Define a Switch type Item, unlinked to anything, so that you have a Switch to be handled in UI etc. like any other.
A rule to listen for commands to that Switch and carry out the exec triggering.
Done.

For a openhab newbie it is quite strange to understand why the switch works correct in basicui but does not work in Paper UI.

All what Marcel wrote works OK in basicui but not in Paper UI.
Once more Thanks for that :+1:

Not really sure what you are talking about here.

Just background, BasicUI is for you to build your day to day user interface.
PaperUI is an administrator’s interface presenting raw Items. No fancy icons or neat ordering, everything exposed.

In PaperUI only the yourcommand (or as you renamed it in the documentation PR yourcommand_Run) switch is shown. This switch is readonly. By default it is off. While the script is running it is on but since the example script finishes so quickly this can hardly be seen.

The YourTrigger switch shown in BasicUI is not shown in PaperUI. I agree that that is confusing. The YourTrigger switch probably needs to be defined using PaperUI instead of an items file to make it appear in PaperUI.

2 Likes

Thanks once more, so quite many learnings :slight_smile: