diff --git a/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml b/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml new file mode 100644 index 0000000000000000000000000000000000000000..1e2ad1a573a15dfe8f0b1f2b3fb2659a0ee2c51e --- /dev/null +++ b/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml @@ -0,0 +1,24 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="OBSW_TmTcClient GUI" type="PythonConfigurationType" factoryName="Python"> + <module name="tmtc" /> + <option name="INTERPRETER_OPTIONS" value="" /> + <option name="PARENT_ENVS" value="true" /> + <envs> + <env name="PYTHONUNBUFFERED" value="1" /> + </envs> + <option name="SDK_HOME" value="" /> + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> + <option name="IS_MODULE_SDK" value="true" /> + <option name="ADD_CONTENT_ROOTS" value="true" /> + <option name="ADD_SOURCE_ROOTS" value="true" /> + <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> + <option name="SCRIPT_NAME" value="$PROJECT_DIR$/OBSW_TmTcClient.py" /> + <option name="PARAMETERS" value="-m 0" /> + <option name="SHOW_COMMAND_LINE" value="false" /> + <option name="EMULATE_TERMINAL" value="false" /> + <option name="MODULE_MODE" value="false" /> + <option name="REDIRECT_INPUT" value="false" /> + <option name="INPUT_FILE" value="" /> + <method v="2" /> + </configuration> +</component> \ No newline at end of file diff --git a/OBSW_TmTcClient.py b/OBSW_TmTcClient.py index 116dbe63da6557905185ac200555b152cc2ec98a..56bf0ce7883bc9271003a720d85666cc0144b254 100644 --- a/OBSW_TmTcClient.py +++ b/OBSW_TmTcClient.py @@ -54,15 +54,15 @@ """ import atexit -import signal import queue import unittest +import logging from test import OBSW_PusServiceTest from config import OBSW_Config as g from config.OBSW_Config import setGlobals from tc.OBSW_TcPacker import PUSTelecommand, createTotalTcQueue, serviceTestSelect -from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver, connectToBoard +from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver from sendreceive.OBSW_SingleCommandSenderReceiver import SingleCommandSenderReceiver from sendreceive.OBSW_SequentialSenderReceiver import SequentialCommandSenderReceiver from utility.OBSW_ArgParser import parseInputArguments @@ -70,6 +70,7 @@ from utility.OBSW_TmTcPrinter import TmtcPrinter from comIF.OBSW_Ethernet_ComIF import EthernetComIF from comIF.OBSW_Serial_ComIF import SerialComIF from gui.OBSW_TmtcGUI import TmtcGUI +from utility.OBSW_ExitHandler import keyboardInterruptHandler def main(): @@ -82,7 +83,7 @@ def main(): GUI.open() else: communicationInterface = setCommunicationInterface(tmtcPrinter) - atexit.register(communicationInterface.keyboardInterruptHandler) + atexit.register(keyboardInterruptHandler, comInterface=communicationInterface) if g.modeId == "ListenerMode": Receiver = CommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, g.printToFile) @@ -108,8 +109,6 @@ def main(): SenderAndReceiver.sendQueueTcAndReceiveTmSequentially() elif g.modeId == "OBSWUnitTest": - if g.comIF == 1: - communicationInterface.serial.close() # Set up test suite and run it with runner # Verbosity specifies detail level # noinspection PyTypeChecker @@ -133,49 +132,25 @@ def commandPreparation(): return command.packCommandTuple() -def setUpSocket(): - try: - g.sockReceive.bind(g.recAddress) - g.sockReceive.setblocking(False) - except OSError: - print("Error setting up sockets.") - print("Socket Receive Address: " + str(g.recAddress)) - exit() - except TypeError: - print("Invalid Receive Address") - exit() - - def setCommunicationInterface(tmtcPrinter): try: - if g.comIF == 0: - setUpSocket() - connectToBoard() + if g.comIF == 0 and g.modeId != "OBSWUnitTest": communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor, - g.sockSend, g.sockReceive, g.sendAddress) - else: + g.sockSend, g.sockReceive, g.sendAddress) + elif g.modeId != "OBSWUnitTest": comPort = g.comPort baudRate = 115200 g.serialTimeout = 0.05 communicationInterface = SerialComIF(tmtcPrinter, comPort, baudRate, g.serialTimeout) + else: + communicationInterface = 0 return communicationInterface - except (IOError, OSError) as e: - print("Error setting up communication interface, Error: " + str(e)) + except (IOError, OSError): + print("Error setting up communication interface") + logging.exception("Error: ") return exit() -class GracefulKiller: - kill_now = False - - def __init__(self): - signal.signal(signal.SIGINT, self.exit_gracefully) - signal.signal(signal.SIGTERM, self.exit_gracefully) - - def exit_gracefully(self): - self.kill_now = True - print("I was killed") - - if __name__ == "__main__": main() diff --git a/comIF/OBSW_ComInterface.py b/comIF/OBSW_ComInterface.py index 6fcc7a4bf381e598985b3efdf5c85b0750002291..050bcc3b486a4b1dd81d4996ef07091bfa448b31 100644 --- a/comIF/OBSW_ComInterface.py +++ b/comIF/OBSW_ComInterface.py @@ -8,7 +8,7 @@ Description: Generic Communication Interface. Defines the syntax of the communic @author: R. Mueller """ from abc import abstractmethod -import config.OBSW_Config as g + class CommunicationInterface: def __init__(self, tmtcPrinter): @@ -48,12 +48,7 @@ class CommunicationInterface: def receiveTelemetryAndStoreTuple(self, tmTupleQueue): pass - def keyboardInterruptHandler(self): - print("Disconnect registered") - # Unit Test closes Serial Port at the end - if g.modeId != "OBSWUnitTest": - disconnect = bytearray([0, 0, 0, 0, 0]) - self.sendTelecommand(disconnect) + diff --git a/comIF/OBSW_Ethernet_ComIF.py b/comIF/OBSW_Ethernet_ComIF.py index dacb009b0ffd86449a1367ae6ad86bfe1701af4d..de7db0a5ad4793bf1c080d30798bcda4db54604d 100644 --- a/comIF/OBSW_Ethernet_ComIF.py +++ b/comIF/OBSW_Ethernet_ComIF.py @@ -6,15 +6,15 @@ Description: Ethernet Communication Interface @author: R. Mueller """ - +import select +import logging from comIF.OBSW_ComInterface import CommunicationInterface from tm.OBSW_TmPacket import PUSTelemetryFactory -import select +import config.OBSW_Config as g class EthernetComIF(CommunicationInterface): - def __init__(self, tmtcPrinter, tmTimeout, tcTimeoutFactor, sendSocket, recvSocket, sendAddress): super().__init__(tmtcPrinter) self.tmTimeout = tmTimeout @@ -22,6 +22,7 @@ class EthernetComIF(CommunicationInterface): self.sendSocket = sendSocket self.recvSocket = recvSocket self.sendAddress = sendAddress + self.setUpSocket() def sendTelecommand(self, tcPacket, tcPacketInfo=""): self.tmtcPrinter.printTelecommand(tcPacket, tcPacketInfo) @@ -69,3 +70,23 @@ class EthernetComIF(CommunicationInterface): tmTupleQueue.put(tmTuple) return tmTuple + def setUpSocket(self): + try: + self.recvSocket.bind(g.recAddress) + self.recvSocket.setblocking(False) + except OSError: + print("Socket already set-up.") + # print("Socket Receive Address: " + str(g.recAddress)) + # logging.exception("Error: ") + # exit() + except TypeError: + print("Invalid Receive Address") + exit() + + def connectToBoard(self): + # Maybe there is a cleaner way to start comm with udp server + # so that it knows the ip address? + test = bytearray([]) + self.sendTelecommand(test) + # send multiple times to get connection if there are problems + diff --git a/comIF/OBSW_Serial_ComIF.py b/comIF/OBSW_Serial_ComIF.py index b428aff2ceac4eccb126695a97fd8a4fd5aecd11..4729b41eee005c3ff52e65afbb9f1463ad5c10c5 100644 --- a/comIF/OBSW_Serial_ComIF.py +++ b/comIF/OBSW_Serial_ComIF.py @@ -2,6 +2,7 @@ import time from comIF.OBSW_ComInterface import CommunicationInterface import serial +import logging from tm.OBSW_TmPacket import PUSTelemetryFactory @@ -14,6 +15,7 @@ class SerialComIF(CommunicationInterface): self.serial = serial.Serial(port=comPort, baudrate=baudRate, timeout=serialTimeout) except serial.SerialException: print("Serial Port can not be opened") + logging.exception("Error: ") exit() self.data = bytearray() self.numberOfPackets = 0 diff --git a/config/OBSW_Config.py b/config/OBSW_Config.py index 45a312ac99faa5e20e513a9a45d09b6ddc5e6801..9803577ee2a3644e85045ada6fb723607ff32061 100644 --- a/config/OBSW_Config.py +++ b/config/OBSW_Config.py @@ -105,3 +105,8 @@ def setGlobals(args): displayMode = displayMode service = service printToFile = args.printFile + + +def setGlobalsUnitTest(): + global sockReceive + sockReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) diff --git a/gui/OBSW_ClientTest.py b/gui/OBSW_ClientTest.py new file mode 100644 index 0000000000000000000000000000000000000000..70afa529f8e6a049230f8cdeb6de08c49cf15a38 --- /dev/null +++ b/gui/OBSW_ClientTest.py @@ -0,0 +1,8 @@ +from multiprocessing.connection import Client + +address = ('localhost', 6000) +conn = Client(address, authkey=None) +conn.send('close') +# can also send arbitrary objects: +# conn.send(['a', 2.5, None, int, sum]) +conn.close() diff --git a/gui/OBSW_ListenerTest.py b/gui/OBSW_ListenerTest.py new file mode 100644 index 0000000000000000000000000000000000000000..b675d2ca43a3fb70d59fe4e29055af34500366e1 --- /dev/null +++ b/gui/OBSW_ListenerTest.py @@ -0,0 +1,14 @@ +from multiprocessing.connection import Listener + +address = ('localhost', 6000) # family is deduced to be 'AF_INET' +listener = Listener(address, authkey=None) +conn = listener.accept() +print('connection accepted from' + str(listener.last_accepted)) +while True: + msg = conn.recv() + # do something with msg + print("I received something") + if msg == 'close': + conn.close() + break +listener.close() diff --git a/gui/OBSW_TmtcGUI.py b/gui/OBSW_TmtcGUI.py index 23c13e8f44ab2c229d024bdcb4e7985ac55ff5eb..6f89bd55853da9256a033e05fa8e8a9e0745f195 100644 --- a/gui/OBSW_TmtcGUI.py +++ b/gui/OBSW_TmtcGUI.py @@ -13,7 +13,8 @@ @author: R. Mueller """ -from tkinter import * +from tkinter import Tk +from multiprocessing.connection import Client # A first simple version has drop down menus to chose all necessary options @@ -26,10 +27,13 @@ from tkinter import * class TmtcGUI: def __init__(self): self.window = Tk() + self.address = ('localhost', 6000) + self.conn = Client(self.address, authkey=None) def open(self): self.window.title("Hallo Welt") self.window.mainloop() + self.conn.send("close") def close(self): self.window.quit() diff --git a/sendreceive/OBSW_CommandSenderReceiver.py b/sendreceive/OBSW_CommandSenderReceiver.py index 70f52d8b2eb9414df2ff6a1dfdc43611360cd239..60bded93082bab975e59165fc6cceb444590ff00 100644 --- a/sendreceive/OBSW_CommandSenderReceiver.py +++ b/sendreceive/OBSW_CommandSenderReceiver.py @@ -111,11 +111,6 @@ class CommandSenderReceiver: return True -def connectToBoard(): - # Maybe there is a cleaner way to start comm with udp server - # so that it knows the ip address? - test = bytearray([]) - g.sockSend.sendto(test, g.sendAddress) - # send multiple times to get connection if there are problems + diff --git a/utility/OBSW_ExitHandler.py b/utility/OBSW_ExitHandler.py new file mode 100644 index 0000000000000000000000000000000000000000..19c082ebf6b5daaf4109e56d8d5e473650e815f8 --- /dev/null +++ b/utility/OBSW_ExitHandler.py @@ -0,0 +1,21 @@ +import signal + + +class GracefulKiller: + kill_now = False + + def __init__(self): + signal.signal(signal.SIGINT, self.exit_gracefully) + signal.signal(signal.SIGTERM, self.exit_gracefully) + + def exit_gracefully(self): + self.kill_now = True + print("I was killed") + + +def keyboardInterruptHandler(comInterface): + print("Disconnect registered") + # Unit Test closes Serial Port at the end + # We could do some optional stuff here + if comInterface != 0: + comInterface.sendTelecommand(bytearray([0, 0, 0, 0, 0]))