From b83ff9ebf52e4bf497f28db070198d2d434d8e19 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" <robin.mueller.m@gmail.com> Date: Sun, 15 Dec 2019 20:53:21 +0100 Subject: [PATCH] comIF continued, serial implemented --- OBSW_UdpClient.py | 14 +++- comIF/OBSW_ComInterface.py | 29 +++++-- comIF/OBSW_Ethernet_ComIF.py | 56 ++++++-------- comIF/OBSW_Serial_ComIF.py | 75 +++++++++++++++---- sendreceive/OBSW_CommandSenderReceiver.py | 19 ++++- .../OBSW_MultipleCommandsSenderReceiver.py | 2 - sendreceive/OBSW_SequentialSenderReceiver.py | 4 +- 7 files changed, 135 insertions(+), 64 deletions(-) diff --git a/OBSW_UdpClient.py b/OBSW_UdpClient.py index e895eb5..5e6862d 100644 --- a/OBSW_UdpClient.py +++ b/OBSW_UdpClient.py @@ -68,6 +68,7 @@ from sendreceive.OBSW_SingleCommandSenderReceiver import SingleCommandSenderRece from sendreceive.OBSW_SequentialSenderReceiver import SequentialCommandSenderReceiver from utility.OBSW_TmTcPrinter import TmtcPrinter from comIF.OBSW_Ethernet_ComIF import EthernetComIF +from comIF.OBSW_Serial_ComIF import SerialComIF # Mode options, set by args parser modeList = { @@ -92,8 +93,13 @@ def main(): atexit.register(g.keyboardInterruptHandler) print("Attempting to connect") tmtcPrinter = TmtcPrinter(g.displayMode, g.printToFile, True) - communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, - g.sockSend, g.sockReceive, g.sendAddress) + if g.comIF == 0: + communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, + g.sockSend, g.sockReceive, g.sendAddress) + else: + comPort = 'COM8' + baudRate = 9600 + communicationInterface = SerialComIF(tmtcPrinter, comPort, baudRate, 0.2) connectToBoard() if g.modeId == "ListenerMode": @@ -147,9 +153,9 @@ def parseInputArguments(): '2: Single Command Mode, 3: Service Test Mode, ' '4: Software Test Mode, 5: Unit Test Mode ', default=0) argParser.add_argument('-c', '--comIF', type=int, help='Communication Interface. 0 for Ethernet, 1 for Serial', - default=1) + default=0) argParser.add_argument('--clientIP', help='Client(Computer) IP. Default:\'\'', default='') - argParser.add_argument('-b', '--boardIP', help='Board IP. Default: 169.254.1.38', default='169.254.1.38') + argParser.add_argument('--boardIP', help='Board IP. Default: 169.254.1.38', default='169.254.1.38') argParser.add_argument('-s', '--service', help='Service to test. Default: 17', default=17) argParser.add_argument('-t', '--tmTimeout', type=float, help='TM Timeout. Default: 10)', default=10.0) argParser.add_argument('-p', '--printFile', help='Supply -p to print output to file. Default: False', diff --git a/comIF/OBSW_ComInterface.py b/comIF/OBSW_ComInterface.py index 571fc8d..a113c44 100644 --- a/comIF/OBSW_ComInterface.py +++ b/comIF/OBSW_ComInterface.py @@ -11,28 +11,41 @@ from abc import abstractmethod class CommunicationInterface: - def __init__(self): - pass + def __init__(self, tmtcPrinter): + self.tmtcPrinter = tmtcPrinter + # Send Telecommand @abstractmethod def sendTelecommand(self, tcPacket, tcPacketInfo=""): pass + # Receive telemetry and process it @abstractmethod - def performListenerMode(self): + def receiveTelemetry(self, parameters): pass + # Poll the interface for data @abstractmethod - def receiveTelemetry(self): + def pollInterface(self, parameters): pass - def receiveTelemetryDeserializeAndStore(self, tmQueue): + # Check whether data is available + @abstractmethod + def dataAvailable(self, parameters): pass + # Listen for packets @abstractmethod - def receiveTelemetryAndStoreTuple(self, tmTupleQueue): + def performListenerMode(self): pass - @abstractmethod - def pollInterface(self, parameter): + # Receive Telemetry and store it into a queue + def receiveTelemetryAndStoreIntoQueue(self, tmQueue): pass + + # Receive Telemetry and store a tuple consisting of TM information and TM packet into queue + def receiveTelemetryAndStoreTuple(self, tmTupleQueue): + pass + + + diff --git a/comIF/OBSW_Ethernet_ComIF.py b/comIF/OBSW_Ethernet_ComIF.py index c7becb3..b2095bb 100644 --- a/comIF/OBSW_Ethernet_ComIF.py +++ b/comIF/OBSW_Ethernet_ComIF.py @@ -14,9 +14,9 @@ import select class EthernetComIF(CommunicationInterface): + def __init__(self, tmtcPrinter, tmTimeout, tcTimeoutFactor, sendSocket, recvSocket, sendAddress): - super().__init__() - self.tmtcPrinter = tmtcPrinter + super().__init__(tmtcPrinter) self.tmTimeout = tmTimeout self.tcTimeoutFactor = tcTimeoutFactor self.sendSocket = sendSocket @@ -31,50 +31,40 @@ class EthernetComIF(CommunicationInterface): pollTimeout = 10 while True: print("Listening for packages ...") - ready = self.pollInterface(pollTimeout) - if ready is None: - pass - elif ready[0]: - packet = self.receiveTelemetry() - self.tmtcPrinter.printTelemetry(packet) + self.pollInterface(pollTimeout) - # check for one sequence of replies for a telecommand (e.g. TM[1,1] , TM[1,7] ...) - # returns true on success - def checkForOneTelemetrySequence(self): - tmReady = self.pollInterface(self.tmTimeout * self.tcTimeoutFactor) - if tmReady is None: + def dataAvailable(self, timeout): + ready = select.select([self.recvSocket], [], [], timeout) + if ready is None: return False - elif tmReady[0]: - while tmReady[0]: - packet = self.receiveTelemetry() - self.tmtcPrinter.printTelemetry(packet) - tmReady = self.pollInterface(self.tmTimeout / 1.5) - if tmReady is None: - return False - else: - return True + elif ready[0]: + return ready + + def pollInterface(self, pollTimeout): + ready = self.dataAvailable(pollTimeout) + if ready is False: + pass + elif ready[0]: + packet = self.receiveTelemetry() + self.tmtcPrinter.printTelemetry(packet) - def receiveTelemetry(self): + def receiveTelemetry(self, parameters=0): data = self.recvSocket.recvfrom(1024)[0] packet = PUSTelemetryFactory(data) + self.tmtcPrinter.printTelemetry(packet) return packet - def receiveTelemetryDeserializeAndStore(self, tmQueue): - data = self.recvSocket.recvfrom(1024)[0] - packet = PUSTelemetryFactory(data) + def receiveTelemetryAndStoreIntoQueue(self, tmQueue): + packet = self.receiveTelemetry() tmQueue.put(packet) return tmQueue def receiveTelemetryAndStoreTuple(self, tmTupleQueue): data = self.recvSocket.recvfrom(1024)[0] tmInfo = PUSTelemetryFactory(data).packTmInformation() - tmTuple = (data, tmInfo) + packet = PUSTelemetryFactory(data) + self.tmtcPrinter.printTelemetry(packet) + tmTuple = (packet, tmInfo) tmTupleQueue.put(tmTuple) return tmTuple - def pollInterface(self, timeout): - ready = select.select([self.recvSocket], [], [], timeout) - if ready is None: - return None - elif ready[0]: - return ready diff --git a/comIF/OBSW_Serial_ComIF.py b/comIF/OBSW_Serial_ComIF.py index b706c26..f8883a6 100644 --- a/comIF/OBSW_Serial_ComIF.py +++ b/comIF/OBSW_Serial_ComIF.py @@ -1,24 +1,73 @@ +import time + from comIF.OBSW_ComInterface import CommunicationInterface +import serial + +from tm.OBSW_TmPacket import PUSTelemetryFactory class SerialComIF(CommunicationInterface): - def __init__(self): - super().__init__() + def __init__(self, tmtcPrinter, comPort, baudRate, serialTimeout): + super().__init__(tmtcPrinter) + self.comPort = comPort + self.baudRate = baudRate + self.tmtcPrinter = tmtcPrinter + # timeout in seconds + serialTimeout = 0.2 + self.serial = serial.Serial(port=comPort, baudrate=self.baudRate, timeout=serialTimeout) + # self.serial.open() - def sendTelecommand(self, tcPacket): - pass + def sendTelecommand(self, tcPacket, tcPacketInfo=""): + self.tmtcPrinter.printTelecommand(tcPacket, tcPacketInfo) + print("im here !") + self.serial.write(tcPacket) - def receiveTelemetry(self): - pass + def receiveTelemetry(self, data): + packet = self.pollInterface() + return packet - def receiveTelemetryDeserializeAndStore(self, tmQueue): - pass + def pollInterface(self, parameter=0): + if self.dataAvailable(): + data = self.pollPusPacket() + packet = PUSTelemetryFactory(data) + return packet - def receiveTelemetryAndStoreTuple(self, tmTupleQueue): - pass + def dataAvailable(self, timeout=0): + if timeout > 0: + start_time = time.time() + elapsed_time = 0 + while elapsed_time < timeout: + if self.serial.in_waiting > 0: + print("data available!") + print(self.serial.in_waiting) + return True + elapsed_time = time.time() - start_time + return False + elif self.serial.in_waiting > 0: + print("data available!") + print(self.serial.in_waiting) + return True - def pollInterface(self, parameter): - pass + def pollPusPacket(self): + data = bytearray() + pusHeader = self.serial.read(6) + dataFieldSize = data[5] << 8 | data[6] - 1 + pusData = self.serial.read(dataFieldSize) + data = data + pusHeader + data = data + pusData + if len(data) < 6 + dataFieldSize: + print("Serial Com IF: Size missmatch when polling PUS packet") + return data def performListenerMode(self): - pass + while True: + self.pollInterface() + + def receiveTelemetryAndStoreIntoQueue(self, tmQueue): + packet = self.pollInterface() + tmQueue.put(packet) + + def receiveTelemetryAndStoreTuple(self, tmTupleQueue): + packet = self.pollInterface() + tmInfo = packet.packTmInformation() + tmTupleQueue.put(packet, tmInfo) diff --git a/sendreceive/OBSW_CommandSenderReceiver.py b/sendreceive/OBSW_CommandSenderReceiver.py index 0eea44f..41afdaa 100644 --- a/sendreceive/OBSW_CommandSenderReceiver.py +++ b/sendreceive/OBSW_CommandSenderReceiver.py @@ -39,8 +39,8 @@ class CommandSenderReceiver: # checks for replies. if no reply is received, send telecommand again def checkForFirstReply(self): - tmSequenceCheckSuccess = self.comInterface.checkForOneTelemetrySequence() - if tmSequenceCheckSuccess: + success = self.checkForOneTelemetrySequence() + if success: self.replyReceived = True else: if len(self.pusPacket) == 0: @@ -78,6 +78,21 @@ class CommandSenderReceiver: self.start_time = time.time() time.sleep(3) + # check for one sequence of replies for a telecommand (e.g. TM[1,1] , TM[1,7] ...) + # returns True on success + def checkForOneTelemetrySequence(self): + tmReady = self.comInterface.dataAvailable(self.tmTimeout * self.tcSendTimeoutFactor) + if tmReady is False: + return False + else: + while tmReady: + self.comInterface.receiveTelemetry() + tmReady = self.comInterface.dataAvailable(self.tmTimeout / 1.5) + if tmReady is None: + return False + else: + return True + def connectToBoard(): # Maybe there is a cleaner way to start comm with udp server diff --git a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py index 20af3ed..7e4f382 100644 --- a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py +++ b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py @@ -85,8 +85,6 @@ class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver): def receiveTelemetryAndStoreInformation(self): packet = self.comInterface.receiveTelemetry() - if self.printTm: - self.tmtcPrinter.printTelemetry(packet) tmInfo = packet.packTmInformation() self.tmInfoQueue.put(tmInfo) diff --git a/sendreceive/OBSW_SequentialSenderReceiver.py b/sendreceive/OBSW_SequentialSenderReceiver.py index 312830e..65025e5 100644 --- a/sendreceive/OBSW_SequentialSenderReceiver.py +++ b/sendreceive/OBSW_SequentialSenderReceiver.py @@ -93,7 +93,7 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def handleReplyListening(self): if self.firstReplyReceived: - tmReady = self.comInterface.pollInterface(2.0) + tmReady = self.comInterface.dataAvailable(2.0) if tmReady is not None: if tmReady[0]: self.handleTelemetrySequence() @@ -102,7 +102,7 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def handleTelemetrySequence(self): if self.run_event.is_set(): - success = self.comInterface.checkForOneTelemetrySequence() + success = self.checkForOneTelemetrySequence() if success: # set this flag so the other thread can send the next telecommand self.replyReceived = True -- GitLab