From f029d8120d1d9cbf78a705df30bbfcb013ad7ff6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" <robin.mueller.m@gmail.com> Date: Sun, 15 Dec 2019 14:21:03 +0100 Subject: [PATCH] more refactoring, bugfixed --- OBSW_UdpClient.py | 15 ++++---- comIF/OBSW_ComInterface.py | 2 +- comIF/OBSW_Ethernet_ComIF.py | 27 ++++++++------ sendreceive/OBSW_CommandSenderReceiver.py | 14 ++++---- .../OBSW_MultipleCommandsSenderReceiver.py | 35 ++++++++++--------- sendreceive/OBSW_SequentialSenderReceiver.py | 21 +++++------ .../OBSW_SingleCommandSenderReceiver.py | 8 ++--- test/OBSW_UnitTest.py | 13 ++++--- utility/OBSW_TmTcPrinter.py | 23 +++++++----- 9 files changed, 84 insertions(+), 74 deletions(-) diff --git a/OBSW_UdpClient.py b/OBSW_UdpClient.py index 0e39ad7..e895eb5 100644 --- a/OBSW_UdpClient.py +++ b/OBSW_UdpClient.py @@ -91,32 +91,33 @@ def main(): setUpSocket() atexit.register(g.keyboardInterruptHandler) print("Attempting to connect") - tmtcPrinter = TmtcPrinter(g.displayMode, g.printToFile) - communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor) + tmtcPrinter = TmtcPrinter(g.displayMode, g.printToFile, True) + communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, + g.sockSend, g.sockReceive, g.sendAddress) connectToBoard() if g.modeId == "ListenerMode": Receiver = CommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, - True, g.printToFile) - Receiver.performListenerMode() + g.printToFile) + Receiver.comInterface.performListenerMode() elif g.modeId == "SingleCommandMode": pusPacketTuple = commandPreparation() SenderAndReceiver = SingleCommandSenderReceiver(communicationInterface, tmtcPrinter, pusPacketTuple, - g.tmTimeout, g.tcSendTimeoutFactor, True, g.printToFile) + g.tmTimeout, g.tcSendTimeoutFactor, g.printToFile) SenderAndReceiver.sendSingleTcAndReceiveTm() elif g.modeId == "ServiceTestMode": serviceQueue = queue.Queue() SenderAndReceiver = SequentialCommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, serviceTestSelect(g.service, serviceQueue), - g.tcSendTimeoutFactor, True, g.printToFile) + g.tcSendTimeoutFactor, g.printToFile) SenderAndReceiver.sendQueueTcAndReceiveTmSequentially() elif g.modeId == "SoftwareTestMode": allTcQueue = createTotalTcQueue() SenderAndReceiver = SequentialCommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, - allTcQueue, g.tcSendTimeoutFactor, True, g.printToFile) + allTcQueue, g.tcSendTimeoutFactor, g.printToFile) SenderAndReceiver.sendQueueTcAndReceiveTmSequentially() elif g.modeId == "OBSWUnitTest": diff --git a/comIF/OBSW_ComInterface.py b/comIF/OBSW_ComInterface.py index 8bfc0eb..b76ea09 100644 --- a/comIF/OBSW_ComInterface.py +++ b/comIF/OBSW_ComInterface.py @@ -12,7 +12,7 @@ class CommunicationInterface: def __init__(self): pass - def sendTelecommand(self, tcPacket): + def sendTelecommand(self, tcPacket, tcPacketInfo=""): pass def performListenerMode(self): diff --git a/comIF/OBSW_Ethernet_ComIF.py b/comIF/OBSW_Ethernet_ComIF.py index 7edae71..c7becb3 100644 --- a/comIF/OBSW_Ethernet_ComIF.py +++ b/comIF/OBSW_Ethernet_ComIF.py @@ -9,20 +9,23 @@ Description: Ethernet Communication Interface from comIF.OBSW_ComInterface import CommunicationInterface -import OBSW_Config as g from tm.OBSW_TmPacket import PUSTelemetryFactory import select class EthernetComIF(CommunicationInterface): - def __init__(self, tmtcPrinter, tmTimeout, tcTimeoutFactor): + def __init__(self, tmtcPrinter, tmTimeout, tcTimeoutFactor, sendSocket, recvSocket, sendAddress): super().__init__() self.tmtcPrinter = tmtcPrinter self.tmTimeout = tmTimeout self.tcTimeoutFactor = tcTimeoutFactor + self.sendSocket = sendSocket + self.recvSocket = recvSocket + self.sendAddress = sendAddress - def sendTelecommand(self, tcPacket): - g.sockSend.sendto(tcPacket, g.sendAddress) + def sendTelecommand(self, tcPacket, tcPacketInfo=""): + self.tmtcPrinter.printTelecommand(tcPacket, tcPacketInfo) + self.sendSocket.sendto(tcPacket, self.sendAddress) def performListenerMode(self): pollTimeout = 10 @@ -39,35 +42,39 @@ class EthernetComIF(CommunicationInterface): # returns true on success def checkForOneTelemetrySequence(self): tmReady = self.pollInterface(self.tmTimeout * self.tcTimeoutFactor) - if tmReady[0]: + if tmReady 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 def receiveTelemetry(self): - data = g.sockReceive.recvfrom(1024)[0] + data = self.recvSocket.recvfrom(1024)[0] packet = PUSTelemetryFactory(data) return packet def receiveTelemetryDeserializeAndStore(self, tmQueue): - data = g.sockReceive.recvfrom(1024)[0] + data = self.recvSocket.recvfrom(1024)[0] packet = PUSTelemetryFactory(data) tmQueue.put(packet) return tmQueue def receiveTelemetryAndStoreTuple(self, tmTupleQueue): - data = g.sockReceive.recvfrom(1024)[0] + data = self.recvSocket.recvfrom(1024)[0] tmInfo = PUSTelemetryFactory(data).packTmInformation() tmTuple = (data, tmInfo) tmTupleQueue.put(tmTuple) return tmTuple def pollInterface(self, timeout): - ready = select.select([g.sockReceive], [], [], timeout) + ready = select.select([self.recvSocket], [], [], timeout) if ready is None: - pass + return None elif ready[0]: return ready diff --git a/sendreceive/OBSW_CommandSenderReceiver.py b/sendreceive/OBSW_CommandSenderReceiver.py index 4347578..0eea44f 100644 --- a/sendreceive/OBSW_CommandSenderReceiver.py +++ b/sendreceive/OBSW_CommandSenderReceiver.py @@ -13,16 +13,14 @@ This is still experimental. @author: R. Mueller """ import OBSW_Config as g -import select import time # Generic TMTC SendReceive class which is implemented # by specific implementations (e.g. SingleCommandSenderReceiver) class CommandSenderReceiver: - def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcSendTimeoutFactor, printTc, doPrintToFile): + def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcSendTimeoutFactor, doPrintToFile): self.tmTimeout = tmTimeout - self.printTc = printTc self.comInterface = comInterface self.tmtcPrinter = tmtcPrinter @@ -46,9 +44,9 @@ class CommandSenderReceiver: self.replyReceived = True else: if len(self.pusPacket) == 0: - print("No command has been sent yet") + print("Command Sender Receiver: No command has been sent yet") else: - self.comInterface.sendTelecommand(self.pusPacket) + self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo) # Check for special queue entries. def checkQueueEntry(self, tcQueueEntry): @@ -69,13 +67,13 @@ class CommandSenderReceiver: def checkForTimeout(self): if self.timeoutCounter == 5: - print("No response from command !") + print("Command Sender Receiver: No response from command !") exit() if self.start_time != 0: self.elapsed_time = time.time() - self.start_time if self.elapsed_time > self.tmTimeout * self.tcSendTimeoutFactor: - print("Timeout ! Sending Telecommand again") - self.comInterface.sendTelecommand() + print("Command Sender Receiver: Timeout, sending Telecommand again") + self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo) self.timeoutCounter = self.timeoutCounter + 1 self.start_time = time.time() time.sleep(3) diff --git a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py index baea7fe..968e164 100644 --- a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py +++ b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py @@ -17,26 +17,26 @@ import select # Difference to seqential sender: This class can send TCs in bursts. Wait intervals can be specified with # wait time between the send bursts. This is generally done in the separate test classes in UnitTest class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver): - def __init__(self, comInterface, displayMode, tcQueue, tmTimeout, waitIntervals, - waitTime, printTm, printTc, tcTimeoutFactor, doPrintToFile): - super().__init__(displayMode, comInterface, tmTimeout, tcQueue, tcTimeoutFactor, printTc, doPrintToFile) + def __init__(self, comInterface, tmtcPrinter, tcQueue, tmTimeout, waitIntervals, + waitTime, printTm, tcTimeoutFactor, doPrintToFile): + super().__init__(comInterface, tmtcPrinter, tmTimeout, tcQueue, tcTimeoutFactor, doPrintToFile) self.waitIntervals = waitIntervals self.waitTime = waitTime self.printTm = printTm - self.printTc = printTc self.tmInfoQueue = queue.Queue() self.tcInfoQueue = queue.Queue() self.pusPacketInfo = [] self.pusPacket = [] + self.waitCounter = 0 def sendTcQueueAndReturnTcInfo(self): receiverThread = threading.Thread(target=self.checkForMultipleReplies) receiverThread.start() - time.sleep(1) + time.sleep(0.5) try: self.sendAllQueue() while not self.allRepliesReceived: - time.sleep(1) + time.sleep(0.5) # self.handleTcResending() Turned off for now, not needed if self.doPrintToFile: self.tmtcPrinter.printToFile() @@ -52,23 +52,24 @@ class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver): self.checkForTimeout() def sendAllQueue(self): - waitCounter = 0 while not self.tcQueue.empty(): self.sendAndPrintTc() - waitCounter = self.handleWaiting(waitCounter) def sendAndPrintTc(self): self.checkQueueEntry(self.tcQueue.get()) if self.queueEntryIsTelecommand: self.tcInfoQueue.put(self.pusPacketInfo) - self.sendTelecommand() - - def handleWaiting(self, waitCounter): - time.sleep(0.5) - waitCounter = waitCounter + 1 - if waitCounter in self.waitIntervals: - time.sleep(self.waitTime) - return waitCounter + self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo) + self.handleWaiting() + + def handleWaiting(self): + self.waitCounter = self.waitCounter + 1 + print(self.waitCounter) + if self.waitCounter in self.waitIntervals: + if isinstance(self.waitTime, list): + time.sleep(self.waitTime[self.waitIntervals.index(self.waitCounter)]) + else: + time.sleep(self.waitTime) def checkForMultipleReplies(self): super().checkForMultipleReplies() @@ -84,7 +85,7 @@ class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver): self.allRepliesReceived = True def receiveTelemetryAndStoreInformation(self): - packet = self.receiveTelemetry() + packet = self.comInterface.receiveTelemetry() if self.printTm: self.tmtcPrinter.printTelemetry(packet) tmInfo = packet.packTmInformation() diff --git a/sendreceive/OBSW_SequentialSenderReceiver.py b/sendreceive/OBSW_SequentialSenderReceiver.py index ee0def1..312830e 100644 --- a/sendreceive/OBSW_SequentialSenderReceiver.py +++ b/sendreceive/OBSW_SequentialSenderReceiver.py @@ -10,15 +10,13 @@ """ from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver import threading -import OBSW_Config as g import time -import select # Specific implementation of CommandSenderReceiver to send multiple telecommands in sequence class SequentialCommandSenderReceiver(CommandSenderReceiver): - def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcQueue, tcTimeoutFactor, printTc, doPrintToFile): - super().__init__(comInterface, tmtcPrinter, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile) + def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcQueue, tcTimeoutFactor, doPrintToFile): + super().__init__(comInterface, tmtcPrinter, tmTimeout, tcTimeoutFactor, doPrintToFile) self.tcQueue = tcQueue self.firstReplyReceived = False self.allRepliesReceived = False @@ -59,7 +57,6 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def performNextTcSend(self): # this flag is set in the separate receiver thread too if self.replyReceived: - self.start_time = time.time() self.sendNextTelecommand() self.replyReceived = False # just calculate elapsed time if start time has already been set (= command has been sent) @@ -69,16 +66,15 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def sendAndReceiveFirstPacket(self): self.checkQueueEntry(self.tcQueue.get()) if self.queueEntryIsTelecommand: - if self.printTc: - self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket) - self.comInterface.sendTelecommand(self.pusPacket) + self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo) else: self.sendAndReceiveFirstPacket() def sendNextTelecommand(self): self.checkQueueEntry(self.tcQueue.get()) if self.queueEntryIsTelecommand: - self.comInterface.sendTelecommand(self.pusPacket) + self.start_time = time.time() + self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo) elif self.tcQueue.empty(): # Special case: Last queue entry is not a Telecommand self.allRepliesReceived = True @@ -106,9 +102,10 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def handleTelemetrySequence(self): if self.run_event.is_set(): - self.comInterface.checkForOneTelemetrySequence() - # set this flag so the other thread can send the next telecommand - self.replyReceived = True + success = self.comInterface.checkForOneTelemetrySequence() + if success: + # set this flag so the other thread can send the next telecommand + self.replyReceived = True if self.tcQueue.empty(): self.allRepliesReceived = True diff --git a/sendreceive/OBSW_SingleCommandSenderReceiver.py b/sendreceive/OBSW_SingleCommandSenderReceiver.py index 20a46f7..3dc54d7 100644 --- a/sendreceive/OBSW_SingleCommandSenderReceiver.py +++ b/sendreceive/OBSW_SingleCommandSenderReceiver.py @@ -9,23 +9,21 @@ Used to send single tcs and listen for replies after that """ from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver -import OBSW_Config as g import threading import time # Specific implementation of CommandSenderReceiver to send a single telecommand class SingleCommandSenderReceiver(CommandSenderReceiver): - def __init__(self, comInterface, displayMode, pusPacketTuple, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile): - super().__init__(comInterface, displayMode, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile) + def __init__(self, comInterface, displayMode, pusPacketTuple, tmTimeout, tcTimeoutFactor, doPrintToFile): + super().__init__(comInterface, displayMode, tmTimeout, tcTimeoutFactor, doPrintToFile) self.pusPacketTuple = pusPacketTuple (self.pusPacketInfo, self.pusPacket) = self.pusPacketTuple def sendSingleTcAndReceiveTm(self): - self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket) print("Starting listener thread") threading.Thread(target=self.receiveReply).start() - self.comInterface.sendTelecommand(self.pusPacket) + self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo) while not self.replyReceived: # wait until reply is received time.sleep(3) diff --git a/test/OBSW_UnitTest.py b/test/OBSW_UnitTest.py index 669eebd..68f7fb5 100644 --- a/test/OBSW_UnitTest.py +++ b/test/OBSW_UnitTest.py @@ -29,6 +29,7 @@ from sendreceive.OBSW_MultipleCommandsSenderReceiver import MultipleCommandSende from OBSW_UdpClient import connectToBoard from utility.OBSW_TmTcPrinter import TmtcPrinter from comIF.OBSW_Ethernet_ComIF import EthernetComIF +import OBSW_Config as g class TestService(unittest.TestCase): @@ -43,6 +44,7 @@ class TestService(unittest.TestCase): # wait intervals between tc send bursts. # Example: [2,4] sends to send 2 tc from queue and wait, then sends another 2 and wait again cls.waitIntervals = [] + cls.waitTime = 2 cls.printTm = True cls.printTc = True # default wait time between tc send bursts @@ -50,14 +52,15 @@ class TestService(unittest.TestCase): cls.testQueue = queue.Queue() cls.tcTimeoutFactor = 3.0 cls.printFile = True - cls.tmtcPrinter = TmtcPrinter(cls.displayMode, cls.printFile) - cls.communicationInterface = EthernetComIF(cls.tmtcPrinter) + cls.tmtcPrinter = TmtcPrinter(cls.displayMode, cls.printFile, True) + cls.communicationInterface = EthernetComIF(cls.tmtcPrinter, cls.tmTimeout, cls.tcTimeoutFactor, g.sockSend, + g.sockReceive, g.sendAddress) connectToBoard() def performTestingAndGenerateAssertionDict(self): UnitTester = MultipleCommandSenderReceiver(self.communicationInterface, self.tmtcPrinter, self.testQueue, self.tmTimeout, self.waitIntervals, self.waitTime, self.printTm, - self.printTc, self.tcTimeoutFactor, self.printFile) + self.tcTimeoutFactor, self.printFile) (tcInfoQueue, tmInfoQueue) = UnitTester.sendTcQueueAndReturnTcInfo() assertionDict = self.analyseTmTcInfo(tmInfoQueue, tcInfoQueue) return assertionDict @@ -166,8 +169,8 @@ class TestService5(TestService): def setUpClass(cls): super().setUpClass() print("Testing Service 5") - cls.waitIntervals = [2] - cls.waitTime = 7 + cls.waitIntervals = [1, 2, 3] + cls.waitTime = [1.2, 1.5, 1.2] packService5TestInto(cls.testQueue) def test_Service5(self): diff --git a/utility/OBSW_TmTcPrinter.py b/utility/OBSW_TmTcPrinter.py index ac318be..919ff6f 100644 --- a/utility/OBSW_TmTcPrinter.py +++ b/utility/OBSW_TmTcPrinter.py @@ -13,12 +13,13 @@ import OBSW_Config as g # TODO: Print everything in a file class TmtcPrinter: - def __init__(self, displayMode, doPrintToFile): + def __init__(self, displayMode, doPrintToFile, printTc): self.printBuffer = "" # global print buffer which will be useful to print something to file self.fileBuffer = "" self.displayMode = displayMode self.doPrintToFile = doPrintToFile + self.printTc = printTc def printTelemetry(self, packet): if self.displayMode == "short": @@ -74,14 +75,18 @@ class TmtcPrinter: print(self.printBuffer) # This function handles the printing of Telecommands - def displaySentCommand(self, pusPacketInfo, pusPacket): - if len(pusPacket) == 0: - print("Empty packet was sent, configuration error") - exit() - if self.displayMode == "short": - self.handleShortTcPrint(pusPacketInfo) - else: - self.handleLongTcPrint(pusPacketInfo) + def printTelecommand(self, pusPacket, pusPacketInfo=""): + if self.printTc: + if len(pusPacket) == 0: + print("TMTC Printer: Empty packet was sent, configuration error") + exit() + if pusPacketInfo == "": + print("TMTC Printer: No packet info supplied to print") + return + if self.displayMode == "short": + self.handleShortTcPrint(pusPacketInfo) + else: + self.handleLongTcPrint(pusPacketInfo) def handleShortTcPrint(self, pusPacketInfo): self.printBuffer = "Sent TC[" + str(pusPacketInfo["service"]) + "," + str(pusPacketInfo["subservice"]) \ -- GitLab