Rule to execute command line

  • Platform information:
    • Rocky Linux 8.8
    • Java 17
    • openHAB version: 4.0.2
rule "Steve's Nanomote"
when
    Item NanoMoteS_SceneNumber changed to 1.0
//    Item NanoMoteS_SceneNumber changed to 2.0 or
//    Item NanoMoteS_SceneNumber changed to 3.0 or
//    Item NanoMoteS_SceneNumber changed to 4.0
then
    executeCommandLine(Duration.ofSeconds(0), "/usr/bin/echo -e '306|on+30|255|Triggered from nanomote|WOPR' > /dev/tcp/10.10.100.100/6802")
end

Testing a rule to send a signal to a zoneminder instance on another computer to start an alert to record 30 seconds of video. The echo command works by itself when run by root or by the openhab user. But when I trigger the rule via the nanomote it fails to run.

Anyone see what I’m missing?

You have to split the command at each space, so it should look like this:

executeCommandLine(Duration.ofSeconds(0), "/usr/bin/echo","-e","'306|on+30|255|Triggered","from","nanomote|WOPR'",">","/dev/tcp/10.10.100.100/6802")

Usually, if it’s a static command, use a shell script instead and simply execute the shell script.

The correct syntax should be:

executeCommandLine(Duration.ofSeconds(0), "/usr/bin/echo","-e","306|on+30|255|Triggered from nanomote|WOPR",">","/dev/tcp/10.10.100.100/6802")

BUT, I am not sure that will work because you have a redirection there.

What will work is if you write a shell script with that command, and call the shell script. Basically trying to avoid invoking redirection from executeCommandLine. The shell script can take a parameter of the data you want to send

Note the single quote is needed by the shell interpreter in the same way that executeCommandLine needs a separate argument for each argument. In other words, executeCommandLine doesn’t need the single quote. The TCP data doesn’t contain the single quote.

Anyway, you should figure out a way to either:

  • Actually send TCP data directly, not using the /dev/tcp, or failing that,
  • Open / write to /dev/tcp using file i/o from java, not using shell / executeCommandLine

Got it working by putting the command in a separate script and then calling that.

I’m gonna look into doing things a bit more directly with the zoneminder binding but haven’t gotten all that magic worked out yet. This effort was a workaround just to see if it was possible while I work on the other methods.

Thanks.

That’s mostly correct but it’s a little more subtle than that.

You need to split it on the arguments which is usually on the spaces but not always. For example, if I had the command

ssh -P 8101 localhost bundle:restart zwave

The arguments are for the ssh command so the “bundle:restart zwave” should be treated like one argument, not two, even though there’s a space.

That’s basically a zero timeout meaning the command has no time to run before timing out. you have to give some time for the command to run. That first argument is the maximum amount of time allowed for the command to run before giving up and generating an error.

Indeed, that’s a problem too because when OH executes a command it doesn’t have a shell (e.g. bash) and pipes (|), io redirection, and other similar features are implemented by the shell.

I believe there’s a tcp/udp binding in the smarthome/j marketplace.