[SOLVED] Rule to append a text file

I need a little help, I am trying to export some data from my power monitor to a text file by appending a date stamp and the item value to it. I have tried using the exec binding to accomplish this, but cannot seem to get it to work properly. Here is my rule so far:

rule "Total Daily Energy Usage"
when
	Time cron "	0 59 23 1/1 * ? *"
then
	var String Usage = ElectricMeterKWh.state.toString
	var Message = (now.toString ("dd-MMM-yyyy") + Usage2)
	executeCommandLine = ("echo "+ Message + ( ">> /etc/openhab2/html/totalusage.txt" ))
end

My issue using the exec binding is getting the quotes around the variable value for the command. I have tried:

	executeCommandLine = ("echo "+ Message + ( ">> /etc/openhab2/html/totalusage.txt" ))

and

	executeCommandLine = ("echo "+ '"Message"' + ( ">> /etc/openhab2/html/totalusage.txt" ))

and

	executeCommandLine = ("echo "+ 'Message' + ( ">> /etc/openhab2/html/totalusage.txt" ))

all to no avail. Any help or guidance would be appreciated.

~John

UPDATE - I should say, this is how it is showing in my log:

2018-08-13 14:42:10.708 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'echo "13-Aug-2018" "3.553" >> /etc/openhab2/html/totalusage.txt'

So, when I checked the file totalusage.txt, there is nothing int the file except for the data I manually typed in (header). So I typed the above into the command line and it does append the file. So, I guess now my question is what would cause this not to work?

Try capturing the output from the command line and logging it. I can’t remember if it logs the output without the timeout.

logInfo("TEST", executeCommandLine = ("echo "+ Message +  ">> /etc/openhab2/html/totalusage.txt", 5000))

NOTE: the extra set of parens are not needed.

Most of the time it is a problem with permissions or file path.

Try using this…

executeCommandLine("/bin/sh@@-c@@/usr/bin/echo " + Message + " >> /etc/openhab2/html/totalusage.txt",1000)

… and make sure the account running OH has write permissions to the directory you are writing the file to.

@rlkoshak, I tried capturing the output, but am getting an error from VS:

Type mismatch: cannot convert from void to String

but I got this in the log:

2018-08-13 21:07:46.664 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'echo "13-Aug-2018" "5.866">> /etc/openhab2/html/totalusage.txt'
2018-08-13 21:07:46.671 [INFO ] [.eclipse.smarthome.model.script.TEST] - null

@5iver,
I tried your command (and also modifying my command with the “@@” but that did not seem to work, this is how the permissions are set for the file:

-rw-rw-r--   1 openhabian openhabian     89 Aug 13 12:38 totalusage.txt

Is it possible, or a better idea to write a script to accomplish this?

Thanks for the help so far… still plugging away at trying to find a solution.

~John

  1. Did you added the 5000 as the second argument? You have to give it a timeout so the executeCommandLine will wait at least that long (5 seconds in this case) for the script to complete. Without the timeout executeCommandLine doesn’t return anything.

  2. The permissions are wrong. The file is owned by openhabian:openhabian and only that user and group had permission to write to the file. OH runs as the openhab user. It doesn’t have permission to wit to the file. Either give everyone write permission or change the ownership of the file to openhab:openhab.

I’ve set this up to test, and it is working. Rich got to it first… your permissions won’t work for the openhab account, which OH runs under, even on openHABian. You could just give everyone rw (chmod o=rw /etc/openhab2/html/totalusage.txt).

@rlkoshak & @5iver: My mistake, thought on Openhabian, openhabian that was the user for OpenHAB… permissions changed (chmod 766 /etc/openhab2/html/totalusage.txt, I am use to using the numbers)…

@rlkoshak, I did put the 5000 in, but the log keeps giving me:

2018-08-14 07:25:45.861 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'powerdraw.rules' has errors, therefore ignoring it: [21,83]: mismatched input ',' expecting ')'
[21,84]: extraneous input '5000' expecting ')'
[21,90]: mismatched input ')' expecting 'end'

Testing it now with the changed permissions…

Ok, with the ‘5000’, I am getting the above errors and the command does not run. If I take the ‘5000’ out, I get:

2018-08-14 07:09:31.029 [INFO ] [.eclipse.smarthome.model.script.TEST] - null

The formatting of that line is incorrect. If you’d like to log the return code, use something like this (works for me without the full path to echo)…

val String echoResult = executeCommandLine("/bin/sh@@-c@@echo " + Message + " >> /etc/openhab2/html/totalusage.txt; echo $?", 5000)
logInfo("Rules","Test: echoResult=[{}]",echoResult)

or more like Rich was going for to get a human readable error…

logInfo("Test",executeCommandLine("/bin/sh@@-c@@echo " + Message + " >> /etc/openhab2/html/totalusage.txt", 5000))

Ok, made the changes to my rule file and this is what I am getting now:

2018-08-14 09:00:31.533 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'powerdraw.rules'
2018-08-14 09:00:37.514 [INFO ] [eclipse.smarthome.model.script.Rules] - Test: echoResult=[0]
2018-08-14 09:00:37.524 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'echo "14-Aug-2018" "3.205" >> /etc/openhab2/html/totalusage.txt'

Does that mean it’s working? :slightly_smiling_face:

Just checked the file and YES finally, thank you guys for all the help.

Cool! I just noticed something though… the example I gave will also return stderr. This will be better, if you just want the error code…

val String echoResult = executeCommandLine("/bin/sh@@-c@@(echo " + Message + " >> /etc/openhab2/html/totalusage.txt) >/dev/null 2>&1; echo $?", 5000)

Stupid typo. Thanks for catching it. That = between executeCommandLine and the "(“echo…” shouldn’t be there.

I was really after the stdout and stderr in the first place. That is where you will see the most useful information such as:

rich@huginn:~   cat /etc/shadow
cat: /etc/shadow: Permission denied
1 Like

That makes human sense :slightly_smiling_face: for debugging, but the magic shell return code is a bit easier to programatically respond to an error.

Agreed, but in this case the human OP needed to learn why his script wasn’t running, not figure out how to detect and programmatically deal with the script failing.

Seeing -1 would have told OP nothing useful. “Permission denied” tells him exactly where to look for the problem.

1 Like