How to discover "Error during the execution of rule"

I have a simple rule that is kicking our an Error, but it looks like it is executing correctly to me.

2016-05-14 18:01:04.003 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Hydrogen_Peroxide_Sensor'

My rule:

import javax.xml.bind.DatatypeConverter
import java.nio.*
import java.lang.*
import org.openhab.core.library.types.*


rule "Ping Sensors"
when
	Time cron "0/2 * * * * ?"
then
	logInfo("Hydrogen", "Pinging Sensors")
	sendCommand(Hydrogen_Peroxide_Sensor, '\u0055')
end


rule "Hydrogen_Peroxide_Sensor"
when
	Item Hydrogen_Peroxide_Sensor received update
then
	val to64 = DatatypeConverter::parseBase64Binary(Hydrogen_Peroxide_Sensor.state.toString)
	val ByteBuffer bb = ByteBuffer::wrap(to64)
	val short distance = bb.getShort
	logInfo("Hydrogen", "Distance: " + distance)
end

Maybe you have to cast the val to String.

logInfo("Hydrogen", "Distance: " + distance.toString)
logInfo("Hydrogen", "Distance: {}", distance)

I think one of them should do the job.

Not sure that’s it, If I take out the loginfo I still get the error:

2016-05-16 09:10:45.004 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Hydrogen_Peroxide_Sensor'
java.nio.BufferUnderflowException: null
	at java.nio.Buffer.nextGetIndex(Buffer.java:506) ~[na:1.8.0_66]
	at java.nio.HeapByteBuffer.getShort(HeapByteBuffer.java:310) ~[na:1.8.0_66]
	at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:729) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._featureCallOperation(XbaseInterpreter.java:713) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor45.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.openhab.model.script.interpreter.ScriptInterpreter.internalFeatureCallDispatch(ScriptInterpreter.java:69) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateMemberFeatureCall(XbaseInterpreter.java:549) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateVariableDeclaration(XbaseInterpreter.java:601) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateBlockExpression(XbaseInterpreter.java:321) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:204) ~[na:na]
	at org.openhab.model.script.internal.engine.ScriptImpl.execute(ScriptImpl.java:59) ~[na:na]
	at org.openhab.core.scriptengine.ScriptExecutionThread.run(ScriptExecutionThread.java:44) ~[na:na]

Sadly the best way I’ve found is to just add a logging statement every other line and see which line in the rule immediately precedes the error.

The “BufferUnderflowException” points to the val short distance = bb.getShort line. A buffer underflow happens when there are not enough bytes to create the primitive asked for. In this case a short is two bytes so to64 must be one byte or less.

If you are only expecting one byte, you might need to use val byte distance = bb.getByte. I think you can treat a byte as a number so you should be able to print it and do math with it as if it were a short.

Was driving me crazy because I know the response from the sensor is two bytes. However, to ping the sensor you send 0x55 and that is just one byte that is also received by my rule.

import javax.xml.bind.DatatypeConverter
import java.nio.*
import java.lang.*
import org.openhab.core.library.types.*


rule "Ping Sensors"
when
        Time cron "0/5 * * * * ?"
then
        sendCommand(Hydrogen_Peroxide_Sensor, '\u0055')
end


rule "Hydrogen_Peroxide_Sensor"
when
        Item Hydrogen_Peroxide_Sensor received update
then
        val to64 = DatatypeConverter::parseBase64Binary(Hydrogen_Peroxide_Sensor.state.toString)
        val ByteBuffer bb = ByteBuffer::wrap(to64)
        logInfo("Hydrogen", "bb: " + bb)
        val short distance = bb.getShort
        logInfo("Hydrogen", "Distance: " + distance)
end

So I guess my questions are; first should I be using something other then “sendCommand” and “received update” so that I don’t see the 0x55 I am sending come into my rule as a single byte? If not, is there a clean way to execute “val short distance = bb.getShort” only if there are two bytes?

Log:

2016-05-16 12:43:10.002 [INFO ] [.openhab.model.script.Hydrogen] - bb: java.nio.HeapByteBuffer[pos=0 lim=0 cap=0]
2016-05-16 12:43:10.002 [INFO ] [runtime.busevents             ] - Hydrogen_Peroxide_Sensor received command U
2016-05-16 12:43:10.003 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Hydrogen_Peroxide_Sensor'
java.nio.BufferUnderflowException: null
	at java.nio.Buffer.nextGetIndex(Buffer.java:506) ~[na:1.8.0_66]
	at java.nio.HeapByteBuffer.getShort(HeapByteBuffer.java:310) ~[na:1.8.0_66]
	at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:729) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._featureCallOperation(XbaseInterpreter.java:713) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor45.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.openhab.model.script.interpreter.ScriptInterpreter.internalFeatureCallDispatch(ScriptInterpreter.java:69) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateMemberFeatureCall(XbaseInterpreter.java:549) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateVariableDeclaration(XbaseInterpreter.java:601) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateBlockExpression(XbaseInterpreter.java:321) ~[na:na]
	at sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
	at org.eclipse.xtext.util.PolymorphicDispatcher.invoke(PolymorphicDispatcher.java:291) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:218) ~[na:na]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:204) ~[na:na]
	at org.openhab.model.script.internal.engine.ScriptImpl.execute(ScriptImpl.java:59) ~[na:na]
	at org.openhab.core.scriptengine.ScriptExecutionThread.run(ScriptExecutionThread.java:44) ~[na:na]
2016-05-16 12:43:10.224 [INFO ] [runtime.busevents             ] - Hydrogen_Peroxide_Sensor state updated to CO+/vQ==

2016-05-16 12:43:10.226 [INFO ] [.openhab.model.script.Hydrogen] - bb: java.nio.HeapByteBuffer[pos=0 lim=4 cap=4]
2016-05-16 12:43:10.226 [INFO ] [.openhab.model.script.Hydrogen] - Distance: 2287

I think you have to use sendCommand or else the binding will never send your 0x55 at all.

But you can check to see if if the ByteBuffer has at least two bytes before calling getShort:

if(bb.array.size >= 2) {
    val short distance = bb.getShort
    logInfo("Hydrogen", "Distance: " + distance)
}