class DataReader(IDataReader, IErrorMessage, IStartableObject, Publisher): def __init__(self, dataTransfer): if (isinstance(dataTransfer, IDataTransfer) != True): raise ValueError( "@DataReader : expecting parameter one to be IDataTransfer object" ) self.__dataTransfer = dataTransfer self.__rxQueue = ByteBuffer() self.__rxThread = threading.Thread(target=self.__RunInBackground, name="mxDataReader", args=(self.__rxQueue, )) self.__rxThread.daemon = True self.__waitEvent = threading.Event() self.__waitTaskCompleted = threading.Event() self.__isAlive = False self.__mutex = threading.Lock() def IsRunning(self): return ((self.__dataTransfer != None) and (self.__dataTransfer.IsConnected()) and self.__isAlive) def __del__(self): if (self.__rxThread != None): self.__rxThread.join(READ_THREAD_DELAY_TIMEOUT) pass self.__rxThread = None self.__waitEvent = None def GetLastError(self): return self.__errorCode def Start(self): if (self.IsRunning() != True): if (self.__rxThread.isAlive() != True): self.__rxThread.daemon = True self.__waitTaskCompleted.clear() self.__waitEvent.clear() self.__rxThread.start() def __RunInBackground(self, SeqQueue): if (self.__isAlive != True): self.__error = None if (self.__waitEvent.is_set != True): self.__waitEvent.set() self.__isAlive = True while (self.IsRunning()): time.sleep( 0.003 ) #put a delay on the read thread, lets not blow the pi up try: if (self.__error != None): break if ((self.__dataTransfer != None) and (self.__dataTransfer.IsDataAvailable())): self.__rxQueue.put(self.__dataTransfer.Read()) except Exception as err: self.__error = err print(self.__error) self.__isAlive = False self.__waitTaskCompleted.set() def IsDataAvailable(self): return (self.__rxQueue.empty() != True) def __isStartByte(self, byte): sbyte = ord(byte) return ((sbyte == ACK) or (sbyte == SOH)) """ The function will handle an event packet errors. """ def _GetInvalidBytes(self, argbytes): bytes = bytearray() for byte in argbytes: bytes.append(byte) while (self.__rxQueue.empty() != True): byte = self.__rxQueue.peek(0) if (byte != None): if (self.__isStartByte(byte)): break byte = self.__rxQueue.get() bytes.append(byte) return bytes def Stop(self): if (self.IsRunning()): try: self.__isAlive = False if (self.__waitTaskCompleted != None): self.__waitTaskCompleted.wait() if (self.__rxThread != None): self.__rxThread.join(READ_THREAD_DELAY_TIMEOUT) except Exception as err: print(err) finally: self.__rxThread = None return (self.__rxThread == True) """********************************************* *@brief * The function will read the current packet bytes from * The queue , return ACK if * throw an exception if invalid packet is read. * throw an exception for incompleted bytes. *********************************************""" def Read(self): bytes = bytearray() with self.__mutex: if (self.IsDataAvailable()): continueWith = True try: if (self.IsRunning() == True): byte = self.__rxQueue.get() #if(self.__isStartByte(byte)): bytes.append(byte) if (ord(byte) == SOH): byte = self.__rxQueue.get( True, READ_THREAD_DELAY_TIMEOUT) bytes.append(byte) byte = self.__rxQueue.get( True, READ_THREAD_DELAY_TIMEOUT) pLength = ord(byte) bytes.append(byte) for index in range(0, pLength): byte = self.__rxQueue.get( True, READ_THREAD_DELAY_TIMEOUT) bytes.append(byte) #else: # bytes = self._GetInvalidBytes(byte); # raise (BadPacketReadError("Invalid start byte read.",bytes,INVALID_PACKET_START_BYTE)); except Exception as err: bytes = self._GetInvalidBytes(bytes) raise BadPacketReadError(err.message, bytes, TRANSPORT_READ_TIMEOUT) return bytes