import serial import os import time import random import string import argparse chunksize=4096 #LOG0002 #32 = 124 kbps #128 = 263 kbps #4096 = 416 kbps #32768 = 427 kbps #65536 = failed serialport = serial.Serial(port='/dev/ttyACM0', baudrate=115200, timeout=1) def establish_connection(): serialport.write("\n".encode()) serialport.write("echo off\n".encode()) while len(serialport.readline())>0: continue serialport.write("test\n".encode()) response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if hrresponse != "OK": print("Unexpected test response:"+str(response)) exit() def get_filenames(): filenames=[] serialport.write("ls\n".encode()) while True: response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if(len(response))>0: #print(hrresponse) filenames.append(hrresponse) else: break return filenames def get_filesize(filename): filesize=0 serialport.write(("sizeof "+str(filename)+"\n").encode()) response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if(len(response))>0: filesize=int(hrresponse) return filesize def copy_file(source,destination,expectedsize): os.makedirs(os.path.dirname(writefilename), exist_ok=True) transferstarttime=time.time() chunkstarttime=time.time() last_print=time.time() with open(writefilename, 'wb') as writer: serialport.write(("chunksize "+str(chunksize)+"\n").encode()) serialport.write(("get "+filename+"\n").encode()) acc_datalen=0 while True: ''' response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if(len(response))>0: #print(hrresponse) writer.write(response) else: break ''' data=serialport.read(chunksize) if(len(data))>0: #data received #print("received "+str(len(data))+" bytes") #hrresponse=data.rstrip().decode('ascii') #print(hrresponse) acc_datalen+=len(data) checksum=(sum(data) & 0xFF) checksumarray=bytearray([checksum]) writer.write(data) serialport.write(checksumarray) #request next chunk by sending checksum of last chunk else: break if (time.time()-last_print>0.5): last_print=time.time() chunkduration=time.time()-chunkstarttime chunkstarttime=time.time() progress=acc_datalen/expectedsize print(str(round(progress*100,0))+"% \t"+str(round(chunkduration*1000,3))+" ms for "+str(len(data))+" Byte \t = "+str(round((len(data)/chunkduration)/1000,3))+" kB/s") fileduration=time.time()-transferstarttime file_stats=os.stat(writefilename) print("Finished transfer of "+str(acc_datalen)+" B or "+str(file_stats.st_size)+" (os) Byte in "+str(fileduration)+" s \t = "+str(round(file_stats.st_size/fileduration/1000,3))+" kB/s") return acc_datalen def log_off(): serialport.write(("log off\n").encode()) response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if (not hrresponse.startswith("Log disabled")): print("Unexpected response:"+str(response)) exit() def delete_file(filename): serialport.write(("rm "+filename+"\n").encode()) response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if hrresponse != "OK": print("Unexpected response:"+str(response)) exit() if __name__ == "__main__": parser = argparse.ArgumentParser(description='Transfers log files from bobbycar over serial') parser.add_argument('-o', '--output', nargs='?', help="output directory") parser.add_argument('-d','--delete', action="store_true", help="delete files after transfer") args = parser.parse_args() outputfolder="sdcard" if (args.output is not None): outputfolder = args.output if(outputfolder[-1]=='/'): outputfolder=outputfolder[:-1] #remove last slash print("Outputfolder:"+outputfolder) if serialport.isOpen(): establish_connection() #Get File List filenames=get_filenames() #Copy all Files failed=0 for filename in filenames: print("Reading file "+filename) expectedsize=get_filesize(filename) print("Expecting "+str(expectedsize)+" Byte") writefilename=outputfolder+'/'+filename receivedsize=copy_file(filename,writefilename,expectedsize) if (expectedsize!=receivedsize): print("Warning: Filesize does not match!") failed+=1 print("") print(str(len(filenames))+" Files copied with "+str(failed)+" failed") #Delete all files if (args.delete): if (failed>0): print("Copy not successful. Files won't be deleted!") exit() deletecheckstring=''.join(random.choices(string.ascii_lowercase, k=3)) deletecheck=input("Enter "+deletecheckstring+" to confirm deletion of "+str(len(filenames))+" files on bobbycar:") if (deletecheck==deletecheckstring): log_off() for filename in filenames: print("Deleting "+filename) delete_file(filename) else: print("Verification failed!") serialport.write("echo on\n".encode()) serialport.close()