From 20108699775c56a05bf17d7cdfa68614d017261c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" <robin.mueller.m@gmail.com> Date: Sun, 15 Dec 2019 02:19:43 +0100 Subject: [PATCH] comIF continued --- OBSW_Config.py | 5 +- OBSW_UdpClient.py | 22 ++++-- comIF/OBSW_ComInterface.py | 25 ++++++- comIF/OBSW_Ethernet_ComIF.py | 71 ++++++++++++++++++- comIF/OBSW_Serial_ComIF.py | 12 ++++ gui/OBSW_TmtcGUI.py | 1 - sendreceive/OBSW_CommandSenderReceiver.py | 60 +++------------- .../OBSW_MultipleCommandsSenderReceiver.py | 1 - sendreceive/OBSW_SequentialSenderReceiver.py | 10 +-- .../OBSW_SingleCommandSenderReceiver.py | 10 +-- test/OBSW_UnitTest.py | 11 ++- utility/OBSW_TmTcPrinter.py | 4 +- 12 files changed, 152 insertions(+), 80 deletions(-) diff --git a/OBSW_Config.py b/OBSW_Config.py index e555f56..c9712dc 100644 --- a/OBSW_Config.py +++ b/OBSW_Config.py @@ -17,16 +17,17 @@ modeId = 0 service = 17 displayMode = "long" +comIF = 0 # Time related tmTimeout = 10 tcSendTimeoutFactor = 2.0 # Ethernet connection settings recAddress = 0 -sendAddress = 0 +sendAddress = (0, 0) sockSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sockReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -sockSend.setblocking(0) + # Print Settings printToFile = False printRawTmData = False diff --git a/OBSW_UdpClient.py b/OBSW_UdpClient.py index 63fa2a2..0e39ad7 100644 --- a/OBSW_UdpClient.py +++ b/OBSW_UdpClient.py @@ -57,7 +57,6 @@ import atexit import signal import queue import socket -import time import unittest import argparse @@ -67,6 +66,8 @@ from tc.OBSW_TcPacker import PUSTelecommand, createTotalTcQueue, serviceTestSele from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver, connectToBoard from sendreceive.OBSW_SingleCommandSenderReceiver import SingleCommandSenderReceiver from sendreceive.OBSW_SequentialSenderReceiver import SequentialCommandSenderReceiver +from utility.OBSW_TmTcPrinter import TmtcPrinter +from comIF.OBSW_Ethernet_ComIF import EthernetComIF # Mode options, set by args parser modeList = { @@ -79,6 +80,7 @@ modeList = { } +# noinspection PyTypeChecker def main(): args = parseInputArguments() setGlobals(args) @@ -89,28 +91,31 @@ def main(): setUpSocket() atexit.register(g.keyboardInterruptHandler) print("Attempting to connect") + tmtcPrinter = TmtcPrinter(g.displayMode, g.printToFile) + communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor) connectToBoard() if g.modeId == "ListenerMode": - Receiver = CommandSenderReceiver(g.displayMode, g.tmTimeout, g.tcSendTimeoutFactor, g.printToFile) + Receiver = CommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, + True, g.printToFile) Receiver.performListenerMode() elif g.modeId == "SingleCommandMode": pusPacketTuple = commandPreparation() - SenderAndReceiver = SingleCommandSenderReceiver(g.displayMode, pusPacketTuple, g.tmTimeout, - g.tcSendTimeoutFactor, True, g.printToFile) + SenderAndReceiver = SingleCommandSenderReceiver(communicationInterface, tmtcPrinter, pusPacketTuple, + g.tmTimeout, g.tcSendTimeoutFactor, True, g.printToFile) SenderAndReceiver.sendSingleTcAndReceiveTm() elif g.modeId == "ServiceTestMode": serviceQueue = queue.Queue() - SenderAndReceiver = SequentialCommandSenderReceiver(g.displayMode, g.tmTimeout, + SenderAndReceiver = SequentialCommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, serviceTestSelect(g.service, serviceQueue), g.tcSendTimeoutFactor, True, g.printToFile) SenderAndReceiver.sendQueueTcAndReceiveTmSequentially() elif g.modeId == "SoftwareTestMode": allTcQueue = createTotalTcQueue() - SenderAndReceiver = SequentialCommandSenderReceiver(g.displayMode, g.tmTimeout, + SenderAndReceiver = SequentialCommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, allTcQueue, g.tcSendTimeoutFactor, True, g.printToFile) SenderAndReceiver.sendQueueTcAndReceiveTmSequentially() @@ -140,7 +145,9 @@ def parseInputArguments(): '0: GUI Mode, 1:Listener Mode, ' '2: Single Command Mode, 3: Service Test Mode, ' '4: Software Test Mode, 5: Unit Test Mode ', default=0) - argParser.add_argument('-c', '--clientIP', help='Client(Computer) IP. Default:\'\'', default='') + argParser.add_argument('-c', '--comIF', type=int, help='Communication Interface. 0 for Ethernet, 1 for Serial', + default=1) + 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('-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) @@ -182,6 +189,7 @@ def setGlobals(args): service = args.service g.recAddress = recAddress g.sendAddress = sendAddress + g.comIF = args.comIF g.sockReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) g.sockSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) g.modeId = modeId diff --git a/comIF/OBSW_ComInterface.py b/comIF/OBSW_ComInterface.py index 5b3ca25..8bfc0eb 100644 --- a/comIF/OBSW_ComInterface.py +++ b/comIF/OBSW_ComInterface.py @@ -1,10 +1,31 @@ -class CommunicationInterface(): +# -*- coding: utf-8 -*- +""" +Program: OBSW_UnitTest.py +Date: 01.11.2019 +Description: Generic Communication Interface. Defines the syntax of the communication functions + +@author: R. Mueller +""" + + +class CommunicationInterface: def __init__(self): pass def sendTelecommand(self, tcPacket): pass - def receiveTelemetry(self, tmPacket): + def performListenerMode(self): + pass + + def receiveTelemetry(self): pass + def receiveTelemetryDeserializeAndStore(self, tmQueue): + pass + + def receiveTelemetryAndStoreTuple(self, tmTupleQueue): + pass + + def pollInterface(self, parameter): + pass diff --git a/comIF/OBSW_Ethernet_ComIF.py b/comIF/OBSW_Ethernet_ComIF.py index f15ec6e..7edae71 100644 --- a/comIF/OBSW_Ethernet_ComIF.py +++ b/comIF/OBSW_Ethernet_ComIF.py @@ -1,6 +1,73 @@ +# -*- coding: utf-8 -*- +""" +Program: OBSW_UnitTest.py +Date: 01.11.2019 +Description: Ethernet Communication Interface + +@author: R. Mueller +""" + + 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): - pass + def __init__(self, tmtcPrinter, tmTimeout, tcTimeoutFactor): + super().__init__() + self.tmtcPrinter = tmtcPrinter + self.tmTimeout = tmTimeout + self.tcTimeoutFactor = tcTimeoutFactor + + def sendTelecommand(self, tcPacket): + g.sockSend.sendto(tcPacket, g.sendAddress) + + def performListenerMode(self): + 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) + + # 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[0]: + while tmReady[0]: + packet = self.receiveTelemetry() + self.tmtcPrinter.printTelemetry(packet) + tmReady = self.pollInterface(self.tmTimeout / 1.5) + if tmReady is None: + return True + + def receiveTelemetry(self): + data = g.sockReceive.recvfrom(1024)[0] + packet = PUSTelemetryFactory(data) + return packet + + def receiveTelemetryDeserializeAndStore(self, tmQueue): + data = g.sockReceive.recvfrom(1024)[0] + packet = PUSTelemetryFactory(data) + tmQueue.put(packet) + return tmQueue + + def receiveTelemetryAndStoreTuple(self, tmTupleQueue): + data = g.sockReceive.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) + if ready is None: + pass + elif ready[0]: + return ready diff --git a/comIF/OBSW_Serial_ComIF.py b/comIF/OBSW_Serial_ComIF.py index 2aaa369..55f2738 100644 --- a/comIF/OBSW_Serial_ComIF.py +++ b/comIF/OBSW_Serial_ComIF.py @@ -3,5 +3,17 @@ from comIF.OBSW_ComInterface import CommunicationInterface class SerialComIF(CommunicationInterface): def __init__(self): + super().__init__() + + def sendTelecommand(self, tcPacket): + pass + + def receiveTelemetry(self): + pass + + def receiveTelemetryDeserializeAndStore(self, tmQueue): + pass + + def receiveTelemetryAndStoreTuple(self, tmTupleQueue): pass diff --git a/gui/OBSW_TmtcGUI.py b/gui/OBSW_TmtcGUI.py index 09599a9..a64eca3 100644 --- a/gui/OBSW_TmtcGUI.py +++ b/gui/OBSW_TmtcGUI.py @@ -14,7 +14,6 @@ R. Mueller """ from tkinter import * -import OBSW_Config as g # A first simple version has drop down menus to chose all necessary options # which are normally handled by the args parser. diff --git a/sendreceive/OBSW_CommandSenderReceiver.py b/sendreceive/OBSW_CommandSenderReceiver.py index e9c6844..bc18169 100644 --- a/sendreceive/OBSW_CommandSenderReceiver.py +++ b/sendreceive/OBSW_CommandSenderReceiver.py @@ -15,24 +15,23 @@ This is still experimental. import OBSW_Config as g import select import time -import atexit -from utility.OBSW_TmTcPrinter import TmtcPrinter -from tm.OBSW_TmPacket import PUSTelemetryFactory # Generic TMTC SendReceive class which is implemented # by specific implementations (e.g. SingleCommandSenderReceiver) class CommandSenderReceiver: - def __init__(self, comInterface, displayMode, tmTimeout, tcSendTimeoutFactor, printTc, doPrintToFile): - self.displayMode = displayMode + def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcSendTimeoutFactor, printTc, doPrintToFile): self.tmTimeout = tmTimeout self.printTc = printTc + self.comInterface = comInterface + self.tmtcPrinter = tmtcPrinter + self.replyReceived = False self.tmReady = False self.pusPacketInfo = [] self.pusPacket = [] - self.tmtcPrinter = TmtcPrinter(self.displayMode, doPrintToFile) + self.start_time = 0 self.elapsed_time = 0 self.timeoutCounter = 0 @@ -42,22 +41,14 @@ class CommandSenderReceiver: # checks for replies. if no reply is received, send telecommand again def checkForFirstReply(self): - self.tmReady = select.select([g.sockReceive], [], [], self.tmTimeout * self.tcSendTimeoutFactor) - if self.tmReady[0]: - self.checkForOneTelemetrySequence() + tmSequenceCheckSuccess = self.comInterface.checkForOneTelemetrySequence() + if tmSequenceCheckSuccess: self.replyReceived = True else: if len(self.pusPacket) == 0: print("No command has been sent yet") else: - self.sendTelecommand() - - # check for one sequence of replies for a telecommand (e.g. TM[1,1] , TM[1,7] ...) - def checkForOneTelemetrySequence(self): - while self.tmReady[0]: - packet = self.receiveTelemetry() - self.tmtcPrinter.printTelemetry(packet) - self.tmReady = select.select([g.sockReceive], [], [], self.tmTimeout / 1.5) + self.comInterface.sendTelecommand(self.pusPacket) # Check for special queue entries. def checkQueueEntry(self, tcQueueEntry): @@ -76,20 +67,6 @@ class CommandSenderReceiver: else: self.queueEntryIsTelecommand = True - def sendTelecommand(self): - if self.printTc: - self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket, self.displayMode) - g.sockSend.sendto(self.pusPacket, g.sendAddress) - - def performListenerMode(self): - timeoutInSeconds = 10 - while True: - print("Listening for packages ...") - ready = select.select([g.sockReceive], [], [], timeoutInSeconds) - if ready[0]: - packet = self.receiveTelemetry() - self.tmtcPrinter.printTelemetry(packet) - def checkForTimeout(self): if self.timeoutCounter == 5: print("No response from command !") @@ -103,27 +80,6 @@ class CommandSenderReceiver: self.start_time = time.time() time.sleep(3) - @staticmethod - def receiveTelemetry(): - data = g.sockReceive.recvfrom(1024)[0] - packet = PUSTelemetryFactory(data) - return packet - - @staticmethod - def receiveTelemetryDeserializeAndStore(tmQueue): - data = g.sockReceive.recvfrom(1024)[0] - packet = PUSTelemetryFactory(data) - tmQueue.put(packet) - return tmQueue - - @staticmethod - def receiveTelemetryAndStoreTuple(tmTupleQueue): - data = g.sockReceive.recvfrom(1024)[0] - tmInfo = PUSTelemetryFactory(data).packTmInformation() - tmTuple = (data, tmInfo) - tmTupleQueue.put(tmTuple) - return tmTuple - 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 47f28f5..baea7fe 100644 --- a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py +++ b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py @@ -39,7 +39,6 @@ class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver): time.sleep(1) # self.handleTcResending() Turned off for now, not needed if self.doPrintToFile: - print("HELLOOOO !") self.tmtcPrinter.printToFile() except (KeyboardInterrupt, SystemExit): super().handleInterrupt(receiverThread) diff --git a/sendreceive/OBSW_SequentialSenderReceiver.py b/sendreceive/OBSW_SequentialSenderReceiver.py index 91135a4..ead1f3a 100644 --- a/sendreceive/OBSW_SequentialSenderReceiver.py +++ b/sendreceive/OBSW_SequentialSenderReceiver.py @@ -8,7 +8,7 @@ @brief Used to send multiple TCs in sequence and listen for replies after each sent tc """ -from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver, connectToBoard +from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver import threading import OBSW_Config as g import time @@ -69,7 +69,9 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def sendAndReceiveFirstPacket(self): self.checkQueueEntry(self.tcQueue.get()) if self.queueEntryIsTelecommand: - self.sendTelecommand() + if self.printTc: + self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket, self.displayMode) + self.sendTelecommand(self.pusPacket) else: self.sendAndReceiveFirstPacket() @@ -95,7 +97,7 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def handleReplyListening(self): if self.firstReplyReceived: - self.tmReady = select.select([g.sockReceive], [], [], 2.0) + self.comInterface.pollInterface(2.0) if self.tmReady[0]: self.handleTelemetrySequence() else: @@ -103,7 +105,7 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver): def handleTelemetrySequence(self): if self.run_event.is_set(): - self.checkForOneTelemetrySequence() + self.comInterface.checkForOneTelemetrySequence() # set this flag so the other thread can send the next telecommand self.replyReceived = True if self.tcQueue.empty(): diff --git a/sendreceive/OBSW_SingleCommandSenderReceiver.py b/sendreceive/OBSW_SingleCommandSenderReceiver.py index 4964cb3..20a46f7 100644 --- a/sendreceive/OBSW_SingleCommandSenderReceiver.py +++ b/sendreceive/OBSW_SingleCommandSenderReceiver.py @@ -16,21 +16,21 @@ import time # Specific implementation of CommandSenderReceiver to send a single telecommand class SingleCommandSenderReceiver(CommandSenderReceiver): - def __init__(self, comInterface, displayMode, pusPacketTuple, tmTimeout, tcTimeoutFactor, doPrintToFile): - super().__init__(comInterface, displayMode, tmTimeout, tcTimeoutFactor, doPrintToFile) + def __init__(self, comInterface, displayMode, pusPacketTuple, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile): + super().__init__(comInterface, displayMode, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile) self.pusPacketTuple = pusPacketTuple (self.pusPacketInfo, self.pusPacket) = self.pusPacketTuple def sendSingleTcAndReceiveTm(self): - self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket, self.displayMode) + self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket) print("Starting listener thread") threading.Thread(target=self.receiveReply).start() - g.sockSend.sendto(self.pusPacket, g.sendAddress) + self.comInterface.sendTelecommand(self.pusPacket) while not self.replyReceived: # wait until reply is received time.sleep(3) if self.replyReceived: - self.performListenerMode() + self.comInterface.performListenerMode() # runs in separate thread. sends TC again if no TM is received after timeout def receiveReply(self): diff --git a/test/OBSW_UnitTest.py b/test/OBSW_UnitTest.py index 531a2aa..669eebd 100644 --- a/test/OBSW_UnitTest.py +++ b/test/OBSW_UnitTest.py @@ -27,12 +27,17 @@ import queue from tc.OBSW_TcPacker import packService17TestInto, packService5TestInto, packDummyDeviceTestInto from sendreceive.OBSW_MultipleCommandsSenderReceiver import MultipleCommandSenderReceiver from OBSW_UdpClient import connectToBoard +from utility.OBSW_TmTcPrinter import TmtcPrinter +from comIF.OBSW_Ethernet_ComIF import EthernetComIF class TestService(unittest.TestCase): + testQueue = queue.Queue() + @classmethod def setUpClass(cls): cls.displayMode = "long" + # default timeout for receiving TM, set in subclass manually cls.tmTimeout = 3 # wait intervals between tc send bursts. @@ -45,11 +50,13 @@ 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) connectToBoard() def performTestingAndGenerateAssertionDict(self): - UnitTester = MultipleCommandSenderReceiver(self.displayMode, self.testQueue, self.tmTimeout, - self.waitIntervals, self.waitTime, self.printTm, + UnitTester = MultipleCommandSenderReceiver(self.communicationInterface, self.tmtcPrinter, self.testQueue, + self.tmTimeout, self.waitIntervals, self.waitTime, self.printTm, self.printTc, self.tcTimeoutFactor, self.printFile) (tcInfoQueue, tmInfoQueue) = UnitTester.sendTcQueueAndReturnTcInfo() assertionDict = self.analyseTmTcInfo(tmInfoQueue, tcInfoQueue) diff --git a/utility/OBSW_TmTcPrinter.py b/utility/OBSW_TmTcPrinter.py index 4c7af73..ac318be 100644 --- a/utility/OBSW_TmTcPrinter.py +++ b/utility/OBSW_TmTcPrinter.py @@ -74,11 +74,11 @@ class TmtcPrinter: print(self.printBuffer) # This function handles the printing of Telecommands - def displaySentCommand(self, pusPacketInfo, pusPacket, displayMode): + def displaySentCommand(self, pusPacketInfo, pusPacket): if len(pusPacket) == 0: print("Empty packet was sent, configuration error") exit() - if displayMode == "short": + if self.displayMode == "short": self.handleShortTcPrint(pusPacketInfo) else: self.handleLongTcPrint(pusPacketInfo) -- GitLab