From 8a6a8b3f904f64961131d2a702bfc54e799e18f9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" <robin.mueller.m@gmail.com> Date: Sat, 7 Mar 2020 17:00:09 +0100 Subject: [PATCH] some minog bugfixes, multiprocessing test for gui --- .../runConfigurations/OBSW_TmTcClient_GUI.xml | 24 +++++++++ OBSW_TmTcClient.py | 49 +++++-------------- comIF/OBSW_ComInterface.py | 9 +--- comIF/OBSW_Ethernet_ComIF.py | 27 ++++++++-- comIF/OBSW_Serial_ComIF.py | 2 + config/OBSW_Config.py | 5 ++ gui/OBSW_ClientTest.py | 8 +++ gui/OBSW_ListenerTest.py | 14 ++++++ gui/OBSW_TmtcGUI.py | 6 ++- sendreceive/OBSW_CommandSenderReceiver.py | 7 +-- utility/OBSW_ExitHandler.py | 21 ++++++++ 11 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 .idea/runConfigurations/OBSW_TmTcClient_GUI.xml create mode 100644 gui/OBSW_ClientTest.py create mode 100644 gui/OBSW_ListenerTest.py create mode 100644 utility/OBSW_ExitHandler.py diff --git a/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml b/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml new file mode 100644 index 0000000..1e2ad1a --- /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 116dbe6..56bf0ce 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 6fcc7a4..050bcc3 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 dacb009..de7db0a 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 b428aff..4729b41 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 45a312a..9803577 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 0000000..70afa52 --- /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 0000000..b675d2c --- /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 23c13e8..6f89bd5 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 70f52d8..60bded9 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 0000000..19c082e --- /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])) -- GitLab