Serial Binding + String Parsing +Regexpr

My GPRS shield generates multi line response like:

I would like to parse it, but have troubles.


+CMGR: "REC READ","+380683577253","","16/12/26,23:39:52+08"

Lalala



OK

Item def:

String GPRS_Shield "GPRS [%s]" {serial="/dev/ttyAMA0@19200"}

Rules def:

rule "SMS Protocol"
when 
	Item GPRS_Shield received update
then

	var String data = GPRS_Shield.state.toString
	logInfo("[SERIAL GPRS]" + data) // generate error 1
	
	//var Pattern pattern = Pattern::compile("\+CMGR:.*\r*\n*.*")
	//var Matcher matcher = pattern.matcher(data)
	//var count = 0
	//if(matcher.find()) {
		//count++
		//logInfo("found: " + count + " : " + matcher.start() + " - " + matcher.end())
	//}
end

sitemap shows response correctly…

Text item=GPRS_Shield label "GPRS"

  1. Why toString method doesn’t work, generates error:
2017-01-09 13:14:05.364 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'SMS Protocol': Index: 1, Size: 1
  1. Why regexpr parsing doesn’t work at all?

The built-in logging actions take two arguments. Not sure, but that might be the source of the error log.

Thanks, that’s it.

But what about second question?

After executing this line from my rule file,

var Pattern pattern = Pattern::compile("\+CMGR:.*\r*\n*.*")

I stop to see ANY logging activity, looks like silent exception occurs,
besides that UI stop to receive updates.

Do you have this

import java.util.regex.Pattern
import java.util.regex.Matcher

near the top of your .rules file?

yes, I do


import org.openhab.core.library.types.*
import java.util.Date
import java.text.SimpleDateFormat
import org.openhab.io.gpio.*
import org.openhab.binding.gpio.*
import org.openhab.binding.exec.*
import java.util.regex.Pattern
import java.util.regex.Matcher

Under openHAB 2, this is not required

These are never required and should not be imported.

Are you certain that

var Pattern pattern = Pattern::compile("\+CMGR:.*\r*\n*.*")

is the line that is causing the problem? Are you certain that your regular expression is valid and is not throwing a PatternCompileException? Maybe there is an asterisk that is incorrect?

YEs, definitely problem with regular expression.

Is there easiest way to split multiline in something like String[] and iterate over each item.

I’ ve tried this and that but nothing works.

Here is what I’ ve already tried:

var String data = GPRS_Shield.state.toString
logInfo("[SERIAL GPRS1]", data)
logInfo("[SERIAL GPRS2]", data.split("\r\n"))
2017-01-09 15:49:23.257 [INFO ] [.o.model.script.[SERIAL GPRS1]] - AT+CMGR=4
+CMGR: "REC READ","+380683577253","","16/12/26,23:39:52+08"
Lalala

OK

2017-01-09 15:49:23.428 [INFO ] [.o.model.script.[SERIAL GPRS1]] - AT+CMGR=4
2017-01-09 15:49:23.684 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'SMS Protocol': Could not invoke method: org.openhab.model.script.actions.LogAction.logInfo(java.lang.String,java.lang.String,java.lang.Object[]) on instance: null
2017-01-09 15:49:23.768 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'SMS Protocol': Could not invoke method: org.openhab.model.script.actions.LogAction.logInfo(java.lang.String,java.lang.String,java.lang.Object[]) on instance: null

I think it would make more sense to invest the effort in perfecting your regular expression with captures for the bits you want to extract. The regex should be able to match everything up to the OK and capture the regions you want to isolate.

You need to append a \g I think to get your regular expression to work “globally” rather than on single lines of text.

sorry where exactly should I append this flag?

i still can’t overcome regexp for my task!!!

Does OpenHAB compliant with regexpr specification???

Why after executing of this code I see nothing in log window???

	try {
		var String patternString = "CMGR.*\s*(.*)\s*OK"
		var Pattern pattern2 = Pattern::compile(patternString)
	} catch(...) {
		logInfo("[SERIAL GPRS4]", "EXCEPTION!")
	} finally {
		logInfo("[SERIAL GPRS4]", "FINALLY!")
	}	

Looks like it traps into infinity loop somewhere inside.

Regexpr is absolutely correct, it was verified here:

http://regexr.com/3f3qt

At the end of the pattern string.

"CMGR.*\s*(.*)\s*OK\g"

Without the \g flag Java’s regex engine will not match across multiple lines if I remember correctly.

But i has been years since I’ve done Java regex so things may have changed.

Does the \ need to be escaped in this context, so given as \\?

It didn’t used to be but my knowledge is really old

Actually with this string script do nothing at all. IT doesn’t print to log.
Behaviour highly depend on regexpr string.
But looks like openhab engine cann’t digest more less complex regexpr.

It can eat

CMGR

or

CMGR.*

but when I add complexity to regexpr this particular rule stops to response,
it doesn’t log any error messages from inside catch neither from inside finally.

Since the regex pattern string is being specified in the script language, which is Java-like, I thought that string literals like “\n” mean newline (ASCII 10), but if you wanted the two literal characters “\n” to appear in the string, you needed to escape the meaning of the backslash character with “\\n”. Does this part of the Xtend language apply here?

Is there any docs or examples of regexp support?

I found that interpreter doesn’t recognize

regex modifier \s

How should I insert \s modifier to string literal , so that openhab treat it correctly?

Have you yet tried my suggestion to use two backslashes instead of one when specifying it via the rule language? Java does indeed understand \s as shown here. I have to think that the rule language handles string literals similarly to the Java language, where this paragraph is given:

Backslashes within string literals in Java source code are interpreted as required by The Java™ Language Specification as either Unicode escapes (section 3.3) or other character escapes (section 3.10.6) It is therefore necessary to double backslashes in string literals that represent regular expressions to protect them from interpretation by the Java bytecode compiler. The string literal “\b”, for example, matches a single backspace character when interpreted as a regular expression, while “\\b” matches a word boundary. The string literal “\(hello\)” is illegal and leads to a compile-time error; in order to match the string (hello) the string literal “\(hello\)” must be used.