diff --git a/OBSW_UdpClient.py b/OBSW_UdpClient.py index 0e39ad773afdf61822cb61f76571dc5339735d93..e895eb51454db0172df19d1d537da97d50713fca 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 8bfc0ebe54aae8973044450e11d4c4f29b8fbe5b..b76ea093e52b70c38f2ae9f0be00959f6301552c 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 7edae715874be62c5a65eaa1ed6c22699731e113..c7becb3f9b3f90bf4d4e35116903c94dfbedfe83 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 434757814dc746fd965430e7062c7aa978dfa746..0eea44f609f1ef8e2d006ec1aac05648237f38b0 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 baea7fe87d97d3c084748588e289e6e077e80661..968e1647fb3331549dac20599c9c3b3d6669973f 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 ee0def12935a1460cbcec48472b75391c52d332c..312830e8920b92c2e206023c9a3d48f5d1742d0f 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 20a46f70f2290710f239bbb919959ec975118697..3dc54d7ba2ec7f47aeef83fd6c066284dfa59616 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 669eebd35ad72f73dee5a1aab578aeeeb4e4d52d..68f7fb51b719ea27d7a7490209c2889f697e7f52 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 ac318bea197ab1aa7ee812b0a50b0b6fe82e2fe3..919ff6fac994ad5bfa2d12226a82e0b836264a11 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"]) \