8.1.2 TCP driver Binary Data

In 8.1.2, the new MessageBytes and WritableBytes tags were added, to allow binary data to be sent/received from a TCP device. I’m trying to do a socket stream to a device on port 4001, where I send it 0x020x000x010x01 followed by a \r\lf, and look for a message in response. I believe I should be able to do this via system.tag.write(WriteableBytesTag.value), but it doesn’t seem to work. The device does show as connected, writeback is enabled. I’ve also tried the generic driver that has been posted, but it does not seem to run under 8.x, and I’ve tried some of the scripting methods mentioned as well but have not had luck.
Thanks for any help!

How are you trying to write to it? Have you looked at Wireshark to see if the data is being written and what it looks like?

I haven’t tried wireshark (yet) as this is on production network, and I haven’t cleared that with my friends in IT.
My device is an andon board, it needs a binary command sent to it, then will respond with another message.
I’ve tried configuring the tcp driver with writeback and writing to the tag, but it does not seem to get the data, and I’ve tried doing a direct socket via script. I’m suspicious I have a byte order issue, but I can’t rule out other issues either.
Script to write/read tags below; note the two different strings to play with big endian/little endian.
string=‘0x020x000x010x01’+‘0x0d’+‘0x0a’
string=‘0x010x010x000x02’+‘0x0d’+‘0x0a’
response=[]
system.tag.write(’[default]vorneBytes’,string)
response=system.tag.read(’[default]vorneresponse’)
print(response.value)

You shouldn’t be writing String data to the binary tags. The whole point of these was to avoid the loss that happens when you try to round-trip binary data through UTF-8 encoding.

Try something like this:

tagPath = "[default]TCP/5000/WritableBytes"
val = [65, 66, 67, 68, 69, 70]
system.tag.writeBlocking([tagPath], [val])

(with the appropriate payload and tag path)

Also you’ve written your script to read the message bytes immediately after writing and there’s absolutely no reason to assume this will work and that the driver will already have received any kind of response and updated the tag, especially since you’re using the old system.tag.write which is async.

Ok, still testing;
my response tag does change, but my device isn’t reacting as expected, which makes me think I’ve got an issue with the message format;
I need to send it little endian byte packed messages.
The first byte is 02, second byte 00, then 01, 01, and finally the appended CR and LF. I have asked IT if I can install wireshark, will see what they say. Very hard to do this working blind.
packet=[01,01,00,02,00,00,‘0d’,‘0a’] #reversed order
#packet=[02,00,01,01,‘0d’,‘0a’,00,00]#normal byte order
path=’[default]vorneBytes’
response=[]
system.tag.writeBlocking([path],[packet])
time.sleep(1)
response=system.tag.read(’[default]vorneresponse’)
print(response)

Why are you putting hex codes in quotes? That isn’t going to do what you think. Just deliver individual byte values as integers in a list. Python does permit integer constants of the form 0xNN, but not in quotes.

Confusion!

Dig some digging into the protocol “documentation”. I don’t appear to need the CR and LF at all, the other software we use uses that as its trigger to send the message and strips them from the message.
I have my device configured as packetbased, with writeback enabled. Delimiters are both blank, as are the field count and field delimiter.
My two tags are both configured as byte arrays, but I’m not clear on how/where i set the number of elements in the array.
I have installed wireshark, but haven’t really dug into that yet.

current script
import time
packet=[0,2,1,1]#normal byte order
path=’[default]vorneBytes’
response=[]
system.tag.writeBlocking([path],[packet])
time.sleep(1)
response=system.tag.read(’[default]vorneresponse’)
print(response)

my response value does change each time i do a write.

At risk of digging up a dead topic, I’m back on this.
Does the integer value in my packet need to be in two’s complement format, IE -127-127?
If I build a message with the value 213, i get an error as follows:
Error_TypeConversion(“Value 213 can not be coerced to byte due to overflow.”)
when I attempt to write the tag. I’m guessing that the driver is looking for a two’s complement number, vs a 0-255 number, correct?

Do I need to put in an if value>127: value=value-255 or similar statement?
(just off top of my head, have not validated that statement)
Thanks!

Yeah you’ll have to do that conversion, annoyingly.

if packet3>127:
packet3=packet3-256
handles that, for anyone trying the same.
for a fuller explanation, my equipment wants a 4 byte code. Byte 0 is control code, byte 1 is 0, and bytes 2/3 are the message.
Of course it is made more challenging because the integer value of say 1237 must be converted to hex, then the byte order is changed, then converted to decimal and then twos complement is done.
value=1237
hexcode=hex(value)
bytea=hexcode[2]
byteb=hexcode[3]+hexcode[4]
packet3=int(byteb,16)
if packet3>127:
packet3=packet3-256
packet4=int(bytea,16)
packet=[65,0,packet3,packet4]
Note that I have a constained set of values I’m dealing with, 1000-1999. This breaks with a value that does not have a second hex pair due to the string conversion.