Serial input string rule errors

Hi,
This is my first post so hopefully I am posting to the forum correctly. I am having issues trying to implement what I thought was a fairly simple concept, receiving a serial string to update the state of OH items using the serial binding and rules. I am currently using OH v1.8. My setup consists of Arduino Nodes using GPIO to monitor contact closures. I am using RF links to another Arduino acting as a gateway that outputs a string on the UART to OH running on an RPI. I have the Arduino’s and links working well and the protocol I implemented works well. It is basically a CSV string of device type, node id, payload. I have the UART connection working as I can see the received string in the log file. I have detailed the error below and would appreciate some advice on how to resolve the errors and get this working. I should point out that this is my first time at working with java and my coding experience is limited to that I have gained working with Arduinos, so I could be way out of my depth here.

Here is the relevant item config:

String Arduino          "Arduino [%s]"  (Arduino_Grp)    { serial="/dev/ttyAMA0", autoupdate="false" }
Contact Window_PU_ArduinoTEST   "Arduino Test Input" <pump> (gPU, Windows)

I can update the test contact from the console with the expected result in the gui:
osgi> openhab update Window_PU_ArduinoTEST OPEN
Update has been sent successfully.

Here is the openhab.log inclusive of the error:
[DEBUG] [b.serial.internal.SerialDevice:225 ] - Received message ‘1,2,0’ on serial port /dev/ttyAMA0
[DEBUG] [o.o.i.m.i.MyOpenHABServiceImpl:282 ] - store(Arduino_Grp), state = 1,2,0
[DEBUG] [o.o.i.m.i.MyOpenHABServiceImpl:282 ] - store(Arduino), state = 1,2,0
[DEBUG] [m.r.internal.engine.RuleEngine:305 ] - Executing rule ‘Arduino UART RX Received’
[DEBUG] [o.m.s.Arduino UART RX Packet =:38 ] - 1,2,0
[ERROR] [o.o.c.s.ScriptExecutionThread :50 ] - Error during the execution of rule ‘Arduino UART RX Received’: For input string: “0”

This is the rule that I am using:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.joda.time.*
import java.util.*
import org.eclipse.xtext.xbase.lib.*
import org.openhab.core.items.*
import java.util.ArrayList.*

var String[] rxbuffer

rule "Arduino UART RX Received"

        when
                Item Arduino received update
                //Item Arduino changed
        then
                logDebug("Arduino UART RX Packet =", Arduino.state.toString)
                rxbuffer = Arduino.state.toString.split(",")

                var int devid = new Integer(rxbuffer.get(1))
                var int nodeid = new Integer(rxbuffer.get(2))
                var int rxdata = new Integer(rxbuffer.get(3))

                logDebug("devid =",+ devid)     //generates error
        //      logDebug("nodeid =", nodeid)    //generates error
        //      logInfo("rxdata =", rxdata)     //generates error

                        if (nodeid == 2) {
                        //      logDebug("Node ID Confirmed =", nodeid)

                                if (rxdata == 0) {
                        //              logInfo ("Arduino RX String Confirmed")
                                        postUpdate(Window_PU_ArduinoTEST OPEN)
                                }
                                        else if (rxdata == 1) {
                                                postUpdate(Windows_PU_ArduinoTEST CLOSED)
                                        }
                        }
end

So I suspect that the rule fails whilst trying to split the 3rd char from the string. I have tried using different variable type such as var Number rxdata = new Integer(rxbuffer.get(3)) to no avail and I am at a loss as to what is going on here.

Thanks for any assistance the community provides.

Just a note, while OH is written in Java, the Rules programming language and configuration are not Java. They are a Domain Specific Language that resembles the Xtend programming language. You can access Java stuff from within then but the language itself is not Java.

Do you happen to have white space after the “0”? If so it will fail to parse it into an Integer. Try adding a call to trim.

var int rxdata = new Integer(rxbuffer.get(3).trim)

However, I will say this much. I find that unless you need to do math with these numbers, you will probably find coding easier and will get fewer errors if you just keep them as Strings.

Also, the syntax of your logDebug calls are incorrect. Remove the comma. The ‘+’ operator is the string concatenation operator so what happens is it combines “devid =” with devid before calling logDebug.

But, as I’m sure you saw, logDebug requires two arguments. The first argument is a name that lets you more easily find and control your rules logging. So the call to the logging actions should be something like:

logDebug("Arduino", "devid = " + devid)

And you will see something in openhab.log that looks like:

2016-11-21 14:00:08.153 [INFO ] [lipse.smarthome.model.script.Arduino] - devid = " + 1

Finally, your calls to postUpdate require commas between the arguments.

postUpdate(Window_PU_ArduinoTEST, OPEN)

Personally I always recommend calling the method on the Item instead as that way is a bit better at converting between types.

Window_PU_ArduinoTEST.postUpdate(OPEN)

From a readability perspective, you should not indent the else if clause. Indentation is used to visually denote context and the else if defines a context at the same level as the if(rsdata == 0) so it should be indendted to the same level.

I cannot recommend strongly enough that you use Designer. Almost all of these errors would have been caught and pointed out to you in Designer as you type the code.

Hi Rich,

Thanks for you assistance. I have followed your suggestions and the rule is now working.

I have posted the working rule below.

Cheers.

rule "Arduino UART RX Received"

when
                Item Arduino received update
                
        then
                logDebug("Arduino UART RX Packet =", Arduino.state.toString)
                rxbuffer = Arduino.state.toString.split(",")

                var devid = new String(rxbuffer.get(0).trim)
                var nodeid = new String(rxbuffer.get(1).trim)
                var rxdata = new String(rxbuffer.get(2).trim)

              	logDebug("UART RX","devid =" + devid)     
              	logDebug("UART RX","nodeid =" + nodeid)    
              	logDebug("UART RX","rxdata =" + rxdata)    

                        if (nodeid == 2) {
                              logDebug("Node ID Confirmed", "Node ID =" + nodeid)

                                if (rxdata == 0) {
                                      logDebug ("RX Open String Confirmed","OK")
                                        Window_PU_ArduinoTEST.postUpdate("OPEN")
                                }
                                 else if (rxdata == 1) {
                                        Window_PU_ArduinoTEST.postUpdate("CLOSED")
                                        logDebug ("RX Closed String Confirmed","OK")
                                }
                        }
end
1 Like