Subtract two dates from java now.toInstant().toEpochMilli() minus command line stat -c %Y file

Hello all,

I am finalizing the migration from OH2 to OH3, and I am stuck with the following command update:

if (now.millis/1000 - Integer.valueOf(executeCommandLine(“stat -c %Y /dev/shm/teleinfo.txt”,2000)) > 300)

The purpose of this command is to make sure that a file is updated regularly ( 5 minutes / 300 seconds )

This is a try with OH3:

if (now.toInstant().toEpochMilli()/1000 - executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt") > 300)

which return tris error :

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘sam-5’ failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,byte) on instance: null in sam

I also tried to transform the second byte value into long, I get the same error message, only byte is replaced by long…

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘sam-5’ failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,long) on instance: null in sam

I spent two evenings trying various things in java without succeeding, if anyone has an idea I am more than willing. :pray:

Thanks a lot

Sam

Either the result of now.toInstant().toEpochMilli()/1000 isn’t a number or the result of executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt") isn’t a number. And looking at the docs for executeCommandLine indeed, it shows that it returns a String, not a Number.

In your original you used Integer.valueOf(exec... to parse the String to an Integer (which is a Number). Why did you drop that? I’m pretty sure that’s the problem.

In general, when you see an error like that complaining about not being able to execute a mathematical operation on null it’s almost always because one of the operands isn’t a Number.

Hello Rich,
Ok but if I try with that :

if (now.toInstant().toEpochMilli()/1000-Integer.valueOf(executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt")) > 300)

I got this error :

2022-05-28 00:54:36.001 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘sam-5’ failed: For input string: “1653692073” in sam

So I try this :

if (Integer.valueOf(now.toInstant().toEpochMilli()/1000)-Integer.valueOf(executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt")) > 300)

and then I get this error :

2022-05-28 00:57:11.488 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘sam-5’ failed: An error occurred during the script execution: Could not invoke method: java.lang.Integer.valueOf(java.lang.String) on instance: null in sam

It seems to me that the first part of the command does not support the integer transformation. Do you have an idea about that?

Thanks again

Sam

I think I see what is my issue…

I think it’s a CR issue, the command executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt") does not return
“1653858095”
but
"1653858095
"

This kind of error that was just in front of me

2022-05-29 23:01:35.610 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘sam-5’ failed: For input string: "1653858095

" in sam

To be more accurate the following commands works :

logInfo(“SAM”,“test1 : {}”, now.toInstant().toEpochMilli()/1000)

return → test1 : 1653859735

logInfo(“SAM”,“test1-1 : {}”, (now.toInstant().toEpochMilli()/1000)-1)

return → test1-1 : 1653859734

logInfo(“SAM”,“test1-test1 : {}”, (now.toInstant().toEpochMilli()/1000) - (now.toInstant().toEpochMilli()/1000))

return → test1-test1 : 0

logInfo(“SAM”,“test2 : {}”, executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt"))
logInfo(“SAM”,“Only text”)

return :

2022-05-29 23:40:53.427 [INFO ] [org.openhab.core.model.script.SAM ] - test2 : 1653860451

2022-05-29 23:40:53.429 [INFO ] [org.openhab.core.model.script.SAM ] - Only text

In this last test we can see that a space exist betwteen the two lines! :exploding_head:

So now I search a command to replace the carryage return by nothing, like this try that not work :

executeCommandLine(Duration.ofSeconds(2),“stat”,"-c","%Y","/dev/shm/teleinfo.txt").replace("@CR","")

I’m almost there!!!

Sam

Found!
Here is the result :

var StringBuffer sb = new StringBuffer(executeCommandLine(Duration.ofSeconds(2),stat,-c,%Y,/dev/shm/teleinfo.txt))
sb.deleteCharAt(sb.length()-1)
if (Integer::parseInt((now.toInstant().toEpochMilli()/1000).toString) - Integer::parseInt(sb.toString) > 300)

We need to use StringBuffer class to call deleteChar(). More information here

I don’t know if this is the most direct and elegant method but it works! :innocent:

Thank again Rich for pointing me what the issue was.