I personally haven’t done much with Serial devices on OH, but maybe these links would help. My thought would be to use a regex in the serial binding config to extract the values you are after…
The serial binding receives the data as a String. And given this is a pretty specific binary encoded message I think your best bet will be to create one Item to receive the messages from your devices and a rule to pick out the values and apply them to your Items.
2016-04-05 08:19:16.335 [INFO ] [runtime.busevents ] - Air_Quality state updated to Qk0AHAABAAEAAwABAAEAAwR6AO+/vQAQAAIAAgAAcQACSA==
2016-04-05 08:19:16.336 [INFO ] [g.openhab.model.script.Testing] - Air Quality: [B@2a4a201
I also tried:
var String air = new DatatypeConverter::parseBase64Binary(Air_Quality.state.toString)
loginfo("testing", "Air Quality: " + air)
And got:
2016-04-05 08:30:35.294 [INFO ] [runtime.busevents ] - Air_Quality state updated to Qk0AHAABAAEAAQABAAEAAQTvv70AfAALAAAAAAAAcQACPA==
2016-04-05 08:30:35.405 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Testing': The name 'parseBase64Binary(<XMemberFeatureCallImplCustom>)' cannot be resolved to an item or type.
getBytes returns an array of byte primitives so what you are seeing when you print it is the memory address of the start of that array. You probably want something along the lines of:
val StringBuilder bts = new StringBuilder
bts.append("Air Quality:")
Air_Quality.state.toString.getBytes.forEach[b | bts.append(Integer.toHexString(b)]
logInfo("Testing", bts.toString)
Neither Java nor the Rules DSL makes dealing with raw binary data obvious nor easy.
Usual disclaimer, I just typed in the above, there may be typos.
2016-04-05 10:16:01.631 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Testing’: The name ‘Integer’ cannot be resolved to an item or type.
Actually, this may be what I want, how do I access that array and pull two 1 byte values and then combine them in a 16 bit number? As an example if byte 1 is 42 and byte 2 is 4d I have valid data. I then need to update item1 with 5th and 6th bytes and item 2 with 7th and 8th bytes and so on. The first byte is the high eight bits and the 2nd byte is the low eight bits.
val ByteBuffer bb = ByteBuffer::wrap(Air_Quality.state.toString.getBytes)
bb.order(ByteOrder.LITTLE_ENDIAN)
val short first = bb.getShort
logInfo("Testing", "1st Bytes: " + first)
val short second = bb.getShort
logInfo("Testing", "2nd Bytes: " + second)
It does not like the ByteOrder:
2016-04-05 13:04:58.726 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Testing': The name 'ByteOrder' cannot be resolved to an item or type.
If I take that out I get my two vars, but they don’t look right (I am not 100% tho). I also want to run DatatypeConverter::parseBase64Binary on it. How can I do that as part of this code?
But unless you know that the incoming data is indeed Base-64 encoded (from your description and example I would say the answer is “no”) it is not going to do much for you. “�u q�” is not a Base-64 encoded string. There are no special characters in Base-64, only "0-1, a-z, A-Z, and ‘+’ and “/” are valid characters in a Base-64 encoded string.
Ya, I figured that part out, I have import java.nio.*, but its still giving me:
2016-04-05 14:14:53.534 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Testing': The name 'ByteOrder' cannot be resolved to an item or type.
Code so far:
DatatypeConverter::parseBase64Binary(Air_Quality.state.toString)
val ByteBuffer bb = ByteBuffer::wrap(Air_Quality.state.toString.getBytes)
bb.order(ByteOrder.LITTLE_ENDIAN)
val short first = bb.getShort
logInfo("Testing", "1st Bytes: " + first)
val short second = bb.getShort
logInfo("Testing", "2nd Bytes: " + second)
val short third = bb.getShort
logInfo("Testing", "3rd Bytes: " + third)
val short forth = bb.getShort
logInfo("Testing", "4th Bytes: " + forth)
val short fith = bb.getShort
P.S. Your right on Base64, I am changing the item tho to BASE64 so I don’t get junk in my log.
Try ByteOrder::LITTLE_ENDIAN or java.nio.ByteOrder::LITTLE_ENDIAN. Reference to something that is static needs to use “::” instead of “.”.
Though I looked it up and “first byte is the high eight bits and second byte the low eight bits” is big endian which is the default so you probably don’t need it anyway.
2016-04-05 16:57:44.861 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Testing': The name 'potUpdate(<XFeatureCallImplCustom>,<XMemberFeatureCallImplCustom>)' cannot be resolved to an item or type.
Then tried to just use pm1 var:
val short pm1 = bb.getShort
logInfo("Testing", "PM 1.0 : " + pm1)
potUpdate(Outside_PM1, pm1)