Problem extracting numbers from executeCommandLine script

I need to extract the value for Free memory (MemFree) on my system, which used to work, but seems not to anymore.

cat /proc/meminfo
MemTotal:        3981600 kB
MemFree:         2126632 kB
MemAvailable:    2926732 kB
Buffers:           56716 kB
Cached:           862928 kB

I had a bash script, getFreeMem.sh that is used to do the job with extracting the value:

#!/bin/bash
var=$(cat /proc/meminfo | grep -oP '(?<=MemFree:).*')
echo $var

That is used in my OH-script:

val value = executeCommandLine(Duration.ofSeconds(5), "/home/openhabian/getFreeMem.sh")
var Number newValue = Integer::parseInt(transform("REGEX", ".*([0-9]+).*", value))
newValue = (newValue / 1000).intValue
logInfo("MemTest","value of initial command is: {}" + value)
logInfo("MemTest","value of command is: {}" + newValue)
OH_RPi_Memory_Free.postUpdate(newValue)

However now this gives a response with a “null” in front which I don’t understand, and I am unable to remove it.

2023-03-06 17:24:37.902 [INFO ] [rg.openhab.core.model.script.MemTest] - value of initial command is: null2122356 kB
2023-03-06 17:24:37.904 [INFO ] [rg.openhab.core.model.script.MemTest] - value of command is: null0

I have tried extracting the values using a different command, which didn’t work:

awk '/MemFree/ { print $2 }' /proc/meminfo

This removes the “KB” which is in the initial command, so I don’t need the REGEX, but still I have a “null” in front of the value, like with the first command.
The aim is to get a number that I can update my OH_RPi_Memory_Free (number) item with.

What is the formatting I am missing here??

Note, does the SystemInfo binding not provide the information you need? A bunch of system status info is also available at http://<openhab ip or host>:8080/rest/systeminfo which could be got using an HTTP request.

{
  "systemInfo": {
    "configFolder": "/openhab/conf",
    "userdataFolder": "/openhab/userdata",
    "logFolder": "/openhab/userdata/logs",
    "javaVersion": "17.0.6",
    "javaVendor": "Eclipse Adoptium",
    "javaVendorVersion": "Temurin-17.0.6+10",
    "osName": "Linux",
    "osVersion": "5.15.0-60-generic",
    "osArchitecture": "amd64",
    "availableProcessors": 4,
    "freeMemory": 140794528,
    "totalMemory": 713031680,
    "startLevel": 100
  }
}

You do a whole lot of stuff even before your first log statement. Break it up and log out each and every step. The first thing to see is what is coming back from the script by logging value. Maybe it’s an error. Next log the result of the transform. Then the result of the parse. and so on and so on.

I have the SystemInfo binding, which does not provide the data I need, neither does the http request unfortunately, although I was not aware that was available - so always good to learn new stuff!

In my script I do log the raw value that my bash script returns which is “null2122356 kB”:

2023-03-06 17:24:37.902 [INFO ] [rg.openhab.core.model.script.MemTest] - value of initial command is: null2122356 kB

But when I run my script in a bash console I don’t get the “null”.

image

I made the initial post so that the commands should apply to everyone running OH on a debian base system, they should be able to replicate what I have…

Your logging is the problem

It needs to be comma instead of plus.

{} is a place holder for an argument which never is passed as an argument.
+ adds a string to the previous string.
{} then is replace with null.

The logs and the results don’t make sense.

The null is coming from mixing argument substitution and string concatenation in your log statements. Either use: logInfo("MemTest", "value of initial command is: {}", value) or logInfo("MemTest", value of command is: " + value)

Again, what’s the REGEX transformation returning. All we know at this point is that (newValue / 1000) < 1 (hence the 0).

One additional note. You probably don’t need this rule at all. You can define the OH_RPi_Memory_Free as a Number:DataAmount, set it’s State Description Pattern to mB and postUpdate the result of the script as is. OH will convert it to mB as it updates the Item.

should be:

logInfo("MemTest, value of command is: " + value)

We both got it wrong. :rofl:

logInfo("MemTest", "value of command is: " + value)

Indeed gentlemen, the logging was a problem.
So the script does seem to return what I need:

2023-03-06 20:05:39.257 [INFO ] [rg.openhab.core.model.script.MemTest] - value of initial command is: 2039132 kB
2023-03-06 20:05:39.258 [INFO ] [rg.openhab.core.model.script.MemTest] - value of command is: 2

which seems to suggest that the REGEX is the problem, in not fetching all the numbers, only the last digit :neutral_face:

Yes. The first .* is “greedy” which in regex terms means it’s going to match as many characters as it can until it is forced to stop in order to fulfill the match pattern. In this case that means it will continue to match all the numbers until only 1 number remains because 1 number is all that is required to satisfy ([0-9]+). The two easy solutions are:

  1. Use the “non-greedy” general match of .*? at the beginning of your regex: .*?([0-9]+).*
  2. Force the “greedy” match to stop when there’s whitespace in front of a number .*\s([0-9]+).*

Awesome - that was the last piece of the puzzle.

Thanks for all your wisdom gentlemen. Its always a pleasure learning the intricacies of the digital realm. I appreciate your help!

This site is good for testing regex.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.