campbell-cr10-logging/async-stream-tutorial.py
2020-11-29 14:34:40 -08:00

187 lines
5.1 KiB
Python

import argparse
import csv
import asyncio
import serial_asyncio
parser = argparse.ArgumentParser()
parser.add_argument("-o", "--output", default="data.csv", help="output csv file name")
parser.add_argument("-d", "--device", help="serial communication port name", required=True)
parser.add_argument("-t", "--time", default=60, type=int, help="sampling time in seconds")
parser.add_argument("-g", "--debug", action='store_true')
args = parser.parse_args()
print (args)
is_debug = args.debug
device = args.device
ntc = 13
nreq = ntc + 3
tsample = args.time
period = 2. # sec, sampling period
nsample = (tsample/period)
eol = bytes.fromhex("2A")
q = asyncio.Queue()
output_file = open(args.output, 'w')
outputwriter = csv.writer(output_file, delimiter=',')
outputwriter.writerow(["time", "T_ref"] + ["T_{}".format(i) for i in range(ntc)])
output_file.flush()
def get_return_type (b):
l = len(b)
if b[0] == 0x0D :
l = -1
elif b[0] == 0x45 :
l = 3
elif b[0] == 0x43 :
l = -1
elif b[0] == 0x33 :
l = l + 2
elif b[0] == 0x4B :
l = 4 * nreq + 9 + 4
return l
def parse_time(msg):
minutes = int.from_bytes(msg[0:2], byteorder='big')
hh = minutes // 60
mm = minutes - hh * 60
ss = int.from_bytes(msg[2:4], byteorder='big') / 10.
return hh,mm,ss
def decode_campbell_float(m):
exponent = (m[0] & (128-1)) - 64
sign = -1 if m[0] & 128 > 0 else 1
mantissa = int.from_bytes(m[1:], byteorder='big')/16777216
val = sign * mantissa * (2**exponent)
return val
def parse_data(msg):
return ([decode_campbell_float(msg[i:i+4]) for i in range(0,len(msg),4)])
def parse_binary(msg):
time = parse_time(msg[3:7])
data = parse_data(msg[9:9+4*nreq])
return (time, data)
parse_data(bytes.fromhex("BF820C49"))
async def main(loop):
reader, writer = await serial_asyncio.open_serial_connection(url=device, baudrate=9600)
if is_debug: print('Reader created')
if is_debug: print('Writer created')
#writer.write(bytes.fromhex("0D"))
a = bytes.fromhex("430D")
input_loc_request = "".join(
["004000"]
+ ["{:02X}".format(i+1) for i in range(nreq)]
+ ["00"]
)
raw_messages = [
"430D",
"430D",
"333134324A0D",
input_loc_request,
#"0040000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C00",
] + [ "4B0D" for i in range(int(nsample)) ]
messages = list(map(bytes.fromhex, raw_messages))
'''
print(bytes.fromhex("0D0D"), get_return_type(bytes.fromhex("0D0D")))
for msg in messages:
print(msg, get_return_type(msg))
'''
# Begin Communication
msg = bytes.fromhex("0D")
await q.put(get_return_type(msg))
writer.write(msg)
await asyncio.sleep(1.0)
writer.write(msg)
await asyncio.sleep(1.0)
sent = send(writer, messages)
received = recv(reader)
await asyncio.wait([sent, received])
async def send(w, msgs):
# msg = msgs[0]
for msg in msgs:
# while True:
# print(msg, get_return_type(msg))
await q.put(get_return_type(msg))
w.write(msg)
if is_debug: print('DEBUG> message sent: ', msg)
# print(f'sent: {msg.decode().rstrip()}')
await asyncio.sleep(period)
await q.put(get_return_type((bytes.fromhex("450D"))))
w.write(bytes.fromhex("450D"))
if is_debug: print('DEBUG> Done sending')
async def recv(r):
while True:
rtype = await q.get()
if rtype < 0 :
msg = await r.readuntil(eol)
else:
if is_debug: print("DEBUG> Reading ", rtype, " bytes")
msg = await r.readexactly(rtype)
if is_debug: print('DEBUG> message received: ', msg[0], msg)
if msg[0] == 75:
time, data = parse_binary(msg)
hhmmss = "{0[0]}:{0[1]}:{0[2]}".format(time)
if is_debug: print ("DEBUG> time {0[0]}:{0[1]}:{0[2]}".format(time))
if is_debug: print ("DEBUG> data {}".format(data))
outputwriter.writerow([hhmmss] + data[2:])
output_file.flush()
if msg == b'E\r\n':
if is_debug: print('DEBUG> Done receiving')
break
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()
'''
41 0D A.
33 31 34 32 4A 0D 3142J.
00 40 00 00 .@..
4B 0D K.
33 31 34 32 4A 0D 3142J.
00 40 00 01 02 03 04 05 00 .@.......
4B 0D K.
4B 0D K.
4B 0D K.
4B 0D K.
4B 0D K.
'''