Hello, i have the following code that worked well in OH2
val String echoResult2 = executeCommandLine("cat@@/etc/openhab2/variables/valve.txt", 5000)
sendCommand(VALVE,(Integer::parseInt(echoResult2) as Number))
When i try to have this rule work in OH4
val String echoResult2 = executeCommandLine(Duration.ofSeconds(5),"/bin/bash", "-c", "cat /etc/openhab/variables/valve.txt");
sendCommand(VALVE,(Integer::parseInt(echoResult2) as Number))
I get
2024-01-06 22:06:16.438 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘RestoreSystemItems’ failed: For input string: "1
The valve.txt file has one character “1” and can be successfully printed in a log without quotes.
Can you help me to understand why Integer::parseInt does not like this string and looks like get it with quotes??
How does the error message exaclty look like ?
Is it
For input string: "1
"
or
For input string: "1"
I think the quotes are there just put around that what is returned. They are not really there.
If the error message looks like in the first case ( output over two lines ) then a newline is part of the txt file.
Add an other line of code that prints out the variable into the openhab.log file. Then you will be sure about what the content of the variable really is.
I had the same problem. If you convert the number to string and log out the length of the string you will notice that it does not match with the digits.
I worked around by multiplying by 1 to get rid of any “hidden” characters
First, when you save the number into the file with echo command it adds 0x0A (CR) after 1(0x31). And that does not help. While it was working well in OH2
Second, i tried to replace 0x0A with 0x00 and this error shows up showing only 1 in quotes
I could not find easy way to hexedit the file to make its length only 1 byte. Any idea what editor i can use? Please do not propose vi as i’m not really fan of it and do now want to spend time to learn it.
Anyway i’m confused why Integer;;parseInt does not work with well formatted string that consist only of numbers
// Restore values from the file
logInfo("Start","Variable initialization from file");
val String echoResult2 = executeCommandLine(Duration.ofSeconds(5),"/bin/bash","-c", "cat /etc/openhab/variables/valve.txt");
logInfo("Start",echoResult2);
val echoResult3 = (Integer::parseInt(echoResult2) as Number) * 1
sendCommand(VALVE,echoResult3)
No. sendCommand(item,state) definitely requires a string for state. sendCommand converts the value by itself into the correct type.
Could you please try as suggested and report back what the log says?
Ultimately everything you need to solve this has been said on this post so far but I want to summarize and consolidate.
Your call to execute command line is returning a newline after the output. So instead of 1, you are getting 1\n. Obviously, 1\n is not a number and you cannot parse it into one. But you can use trim to remove the newline (I recommend that over multiplying by 1 as suggested by @Oliver2, though that should work too.
val echoResult2 = executeCommandLine(Duration.ofSeconds(5),“/bin/cat”, “/etc/openhab/variables/valve.txt”).trim()
Also I suspect the carriage return is being added by cat so even if you managed to remove it from the file, you’ll still have to deal with it. So don’t bother, just trim the result in your rule.
The sendCommand() action indeed expects two Strings as arguments, doesn’t matter what type the Item is. Often it can be smart enough to call toString() on what’s passed to it but not always. This is why the docs and it’s always been recommended to use Item.sendCommand(newState) over sendCommand(ItemName, newState) as the Item method can accept more different types and convert as needed.
But given that it expects a String in the first place, you don’t need to parse it into an Integer in the first place. Just pass the String from executeCommandLine directly to the Item in the update. The error “for input string: 1” is telling you that it expects a String for the second argument but it’s not getting a String because you are parsing it into an Integer.
The line above avoids the assignment to final val by doing the trim on the same line. If you do two lines like @Baschtlwaschtl desmonstrates, you must use var instead of val so you can change the value of the variable.
Hi Rich, as always your comments and structured answers works best Thanks!
So both #1 and #2 from you worked well. #1 method .trim() used for executeCommandLine worked to remove \n from the string
However echoResult2=echoResult2.trim() didn’t worked. Though i didn’t try wit var #2 Using Item.sendCommand() worked well without additional type conversions
so in the end the working code looks like
// Restore values from the file
logInfo("Start","Variable initialization from file");
val String echoResult2 = executeCommandLine(Duration.ofSeconds(5),"/bin/bash","-c", "cat /etc/openhab/variables/valve.txt").trim();
logInfo("Start",echoResult2);
VALVE.sendCommand(echoResult2)