diff --git a/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml b/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml index 1c3f526ce8059aed5785a392d39b8ebae68931c0..ad057809e1194c668ac2d92a40e240ae4cc9077e 100644 --- a/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml +++ b/.idea/runConfigurations/OBSW_TmTcClient_GUI.xml @@ -12,7 +12,7 @@ <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="C:\Users\Robin\NoSyncDokumente\sourceobsw\tmtc\obsw_tmtc_client.py" /> + <option name="SCRIPT_NAME" value="C:/Users/Robin/NoSyncDokumente/sourceobsw/tmtc/obsw_tmtc_client.py" /> <option name="PARAMETERS" value="-m 0" /> <option name="SHOW_COMMAND_LINE" value="false" /> <option name="EMULATE_TERMINAL" value="false" /> diff --git a/.idea/runConfigurations/OBSW_UdpClient_Listener_Serial.xml b/.idea/runConfigurations/tmtcclient_Listener_Serial.xml similarity index 86% rename from .idea/runConfigurations/OBSW_UdpClient_Listener_Serial.xml rename to .idea/runConfigurations/tmtcclient_Listener_Serial.xml index 1d9915ed48d8dc6e38281082a1099384cbf24c3f..c59efdb836593429d3c211d1ed21f814c1a13177 100644 --- a/.idea/runConfigurations/OBSW_UdpClient_Listener_Serial.xml +++ b/.idea/runConfigurations/tmtcclient_Listener_Serial.xml @@ -1,5 +1,5 @@ <component name="ProjectRunConfigurationManager"> - <configuration default="false" name="OBSW_UdpClient Listener Serial" type="PythonConfigurationType" factoryName="Python" folderName="Serial Communication"> + <configuration default="false" name="tmtcclient Listener Serial" type="PythonConfigurationType" factoryName="Python" folderName="Serial Communication"> <module name="tmtc" /> <option name="INTERPRETER_OPTIONS" value="" /> <option name="PARENT_ENVS" value="true" /> diff --git a/.idea/runConfigurations/OBSW_UdpClient_Single_Command_Serial_.xml b/.idea/runConfigurations/tmtcclient_Single_Command_Serial_.xml similarity index 86% rename from .idea/runConfigurations/OBSW_UdpClient_Single_Command_Serial_.xml rename to .idea/runConfigurations/tmtcclient_Single_Command_Serial_.xml index 63420a0c91db797a78269aaa2efd27a1065c6c7b..c59814017c5419b0cfa0d262228897e93ae23e4f 100644 --- a/.idea/runConfigurations/OBSW_UdpClient_Single_Command_Serial_.xml +++ b/.idea/runConfigurations/tmtcclient_Single_Command_Serial_.xml @@ -1,5 +1,5 @@ <component name="ProjectRunConfigurationManager"> - <configuration default="false" name="OBSW_UdpClient Single Command Serial " type="PythonConfigurationType" factoryName="Python" folderName="Serial Communication"> + <configuration default="false" name="tmtcclient Single Command Serial " type="PythonConfigurationType" factoryName="Python" folderName="Serial Communication"> <module name="tmtc" /> <option name="INTERPRETER_OPTIONS" value="" /> <option name="PARENT_ENVS" value="true" /> diff --git a/comIF/obsw_com_interface.py b/comIF/obsw_com_interface.py index 2a9adfeb3a4f348969634fd3745a25849ee3ba8e..cf4447b544b8bd864932d159a22d37340aae765b 100644 --- a/comIF/obsw_com_interface.py +++ b/comIF/obsw_com_interface.py @@ -72,34 +72,34 @@ class CommunicationInterface: :return: """ - def receive_telemetry_and_store_info(self, tm_info_queue: PusTmInfoQueueT) -> \ - Union[None, PusTmInfoQueueT]: - """ - Receive telemetry and store wiretapping_packet information in dict format into a queue. - If no _tm_data is available, don't do anything. - :param tm_info_queue: - :return: - """ - print("No child implementation provided yet!") - return - - def receive_telemetry_and_store_tm(self, tm_queue: PusTmQueueT) -> Union[None, PusTmQueueT]: - """ - Receive telemetry packets and store TM object into a queue. - If no _tm_data is available, don't do anything. - :param tm_queue: - :return: - """ - print("No child implementation provided yet!") - return - - def receive_telemetry_and_store_tuple(self, tm_tuple_queue: PusTmTupleQueueT) -> \ - Union[None, PusTmTupleQueueT]: - """ - Poll telemetry and store a tuple consisting of TM information and the - TM wiretapping_packet into the queue. If no _tm_data is available, don't do anything. - :param tm_tuple_queue: - :return: - """ - print("No child implementation provided yet!") - return + # def receive_telemetry_and_store_info(self, tm_info_queue: PusTmInfoQueueT) -> \ + # Union[None, PusTmInfoQueueT]: + # """ + # Receive telemetry and store wiretapping_packet information in dict format into a queue. + # If no _tm_data is available, don't do anything. + # :param tm_info_queue: + # :return: + # """ + # print("No child implementation provided yet!") + # return + # + # def receive_telemetry_and_store_tm(self, tm_queue: PusTmQueueT) -> Union[None, PusTmQueueT]: + # """ + # Receive telemetry packets and store TM object into a queue. + # If no _tm_data is available, don't do anything. + # :param tm_queue: + # :return: + # """ + # print("No child implementation provided yet!") + # return + # + # def receive_telemetry_and_store_tuple(self, tm_tuple_queue: PusTmTupleQueueT) -> \ + # Union[None, PusTmTupleQueueT]: + # """ + # Poll telemetry and store a tuple consisting of TM information and the + # TM wiretapping_packet into the queue. If no _tm_data is available, don't do anything. + # :param tm_tuple_queue: + # :return: + # """ + # print("No child implementation provided yet!") + # return diff --git a/comIF/obsw_dummy_com_if.py b/comIF/obsw_dummy_com_if.py index ac20f17d11380fb9e675cb08de2e567358365f32..653b536f6782979e7ea06bd9f569c18253e20e4c 100644 --- a/comIF/obsw_dummy_com_if.py +++ b/comIF/obsw_dummy_com_if.py @@ -8,14 +8,19 @@ from typing import Tuple from comIF.obsw_com_interface import CommunicationInterface +from tc.obsw_pus_tc_base import PusTelecommand, PusTcInfoT, TcDictionaryKeys class DummyComIF(CommunicationInterface): + def __init__(self, tmtc_printer): + super().__init__(tmtc_printer) + self.service_sent = 0 + def close(self) -> None: pass def data_available(self, parameters): - pass + return False def poll_interface(self, parameters: any = 0) -> Tuple[bool, list]: pass @@ -23,5 +28,8 @@ class DummyComIF(CommunicationInterface): def receive_telemetry(self, parameters: any = 0): pass - def send_telecommand(self, tc_packet, tc_packet_info="") -> None: - pass + def send_telecommand(self, tc_packet: PusTelecommand, tc_packet_info: PusTcInfoT = None) -> None: + if isinstance(tc_packet_info, dict) and tc_packet_info.__len__() > 0: + self.service_sent = tc_packet_info[TcDictionaryKeys.SERVICE] + print("Send function accessed") + print(self.service_sent) diff --git a/comIF/obsw_ethernet_com_if.py b/comIF/obsw_ethernet_com_if.py index 35e14d0d715598ff4f8f215923b12af8820e47f0..97506753e01fbc62f577b7a78a97b0657dfb441e 100644 --- a/comIF/obsw_ethernet_com_if.py +++ b/comIF/obsw_ethernet_com_if.py @@ -65,32 +65,6 @@ class EthernetComIF(CommunicationInterface): return packet_list return [] - def receive_telemetry_and_store_info(self, tm_info_queue: PusTmInfoQueueT) -> \ - Union[None, PusTmInfoQueueT]: - packets = self.receive_telemetry() - for packet in packets: - packet_info = packet.pack_tm_information() - if g.G_PRINT_TM: - self.tmtc_printer.print_telemetry(packet) - tm_info_queue.append(packet_info) - return tm_info_queue - - def receive_telemetry_and_store_tm(self, tm_queue: PusTmQueueT) -> Union[None, PusTmQueueT]: - packets = self.receive_telemetry() - for packet in packets: - tm_queue.append(packet) - return tm_queue - - def receive_telemetry_and_store_tuple(self, tm_tuple_queue): - packet_list = self.receive_telemetry() - for packet in packet_list: - packet_info = packet.pack_tm_information() - tm_tuple = (packet_info, packet) - if g.G_PRINT_TM: - self.tmtc_printer.print_telemetry(packet) - tm_tuple_queue.append(tm_tuple) - return tm_tuple_queue - def set_up_socket(self): """ Sets up the sockets for the UDP communication. @@ -115,3 +89,29 @@ class EthernetComIF(CommunicationInterface): """ test = bytearray([]) self.send_telecommand(test) + + # def receive_telemetry_and_store_info(self, tm_info_queue: PusTmInfoQueueT) -> \ + # Union[None, PusTmInfoQueueT]: + # packets = self.receive_telemetry() + # for packet in packets: + # packet_info = packet.pack_tm_information() + # if g.G_PRINT_TM: + # self.tmtc_printer.print_telemetry(packet) + # tm_info_queue.append(packet_info) + # return tm_info_queue + # + # def receive_telemetry_and_store_tm(self, tm_queue: PusTmQueueT) -> Union[None, PusTmQueueT]: + # packets = self.receive_telemetry() + # for packet in packets: + # tm_queue.append(packet) + # return tm_queue + # + # def receive_telemetry_and_store_tuple(self, tm_tuple_queue): + # packet_list = self.receive_telemetry() + # for packet in packet_list: + # packet_info = packet.pack_tm_information() + # tm_tuple = (packet_info, packet) + # if g.G_PRINT_TM: + # self.tmtc_printer.print_telemetry(packet) + # tm_tuple_queue.append(tm_tuple) + # return tm_tuple_queue \ No newline at end of file diff --git a/comIF/obsw_serial_com_if.py b/comIF/obsw_serial_com_if.py index 9b59cb1167f2e05dff5679599dd03c7e1a5397f1..892a3431f25a05326a48394e2f3053df61feceb1 100644 --- a/comIF/obsw_serial_com_if.py +++ b/comIF/obsw_serial_com_if.py @@ -47,7 +47,7 @@ class SerialComIF(CommunicationInterface): sys.exit() def send_telecommand(self, tc_packet: bytearray, tc_packet_info: PusTcInfoT = None) -> None: - self.tmtc_printer.print_telecommand(tc_packet, tc_packet_info) + # self.tmtc_printer.print_telecommand(tc_packet, tc_packet_info) self.serial.write(tc_packet) def receive_telemetry(self, parameters: any = 0) -> list: diff --git a/config/obsw_config.py b/config/obsw_config.py index aab02521603c75ef78a89b2a8f8f31fe83ea869a..c76d2c5f81b37d9b5eaf00131fa5f66cfb952dce 100644 --- a/config/obsw_config.py +++ b/config/obsw_config.py @@ -29,6 +29,7 @@ class ModeList(enum.Enum): class ComIF(enum.Enum): Ethernet = 0 Serial = 1 + Dummy = 2 """ @@ -65,7 +66,7 @@ G_SERVICE = 17 G_DISPLAY_MODE = "long" -G_COM_IF = 0 +G_COM_IF = 2 # COM Port for serial communication G_COM_PORT = 'COM0' G_SERIAL_TIMEOUT = 0.01 @@ -105,11 +106,11 @@ def set_globals(args): # Board IP address and ethernet port IP address can be passed optionally # by passing line parameter In PyCharm: Set parameters in run configuration # Add IP address of Ethernet port. Use command ipconfig in windows console or ifconfig in Linux. - portReceive = 2008 - recAddressToSet = (args.clientIP, portReceive) + port_receive = 2008 + rec_address_to_set = (args.clientIP, port_receive) # Static IP of board - portSend = 7 - sendAddressToSet = (args.boardIP, portSend) + port_send = 7 + send_address_to_set = (args.boardIP, port_send) if 0 <= args.mode <= 5: if args.mode == 0: G_MODE_ID = ModeList.GUIMode @@ -126,22 +127,23 @@ def set_globals(args): else: print("Invalid mode argument, setting default mode (1)") G_MODE_ID = ModeList[1] - if args.comIF == 0: + print("Setting ethernet communication interface") G_COM_IF = ComIF.Ethernet elif args.comIF == 1: + print("Setting serial communication interface") G_COM_IF = ComIF.Serial else: - print("Invalid Communication Interface, setting serial (1)") - G_COM_IF = ComIF.Serial + print("Setting dummy communication interface") + G_COM_IF = ComIF.Dummy G_SERVICE = str(args.service) if G_SERVICE.isdigit(): G_SERVICE = int(args.service) else: G_SERVICE = args.service - G_REC_ADDRESS = recAddressToSet - G_SEND_ADDRESS = sendAddressToSet + G_REC_ADDRESS = rec_address_to_set + G_SEND_ADDRESS = send_address_to_set G_MODE_ID = G_MODE_ID G_PRINT_HK_DATA = args.print_hk G_PRINT_TM = args.print_tm diff --git a/obsw_tmtc_client.py b/obsw_tmtc_client.py index 0c5e73fecce298cbdb7b2967b12a11d107ad582a..3c549b8d3c11b6093554255217b319deeeae1bb8 100644 --- a/obsw_tmtc_client.py +++ b/obsw_tmtc_client.py @@ -74,6 +74,7 @@ from utility.obsw_exit_handler import keyboard_interrupt_handler from comIF.obsw_ethernet_com_if import EthernetComIF from comIF.obsw_serial_com_if import SerialComIF +from comIF.obsw_dummy_com_if import DummyComIF from comIF.obsw_com_interface import ComIfT from gui.obsw_tmtc_gui import TmTcGUI @@ -179,15 +180,15 @@ def set_communication_interface(tmtc_printer: TmTcPrinter) -> ComIfT: tmtc_printer=tmtc_printer, tm_timeout=g.G_TM_TIMEOUT, tc_timeout_factor=g.G_TC_SEND_TIMEOUT_FACTOR, send_address=g.G_SEND_ADDRESS, receive_address=g.G_REC_ADDRESS) - else: + elif g.G_COM_IF == g.ComIF.Serial: com_port = g.G_COM_PORT baud_rate = 250000 g.G_SERIAL_TIMEOUT = 1 communication_interface = SerialComIF( tmtc_printer=tmtc_printer, com_port=com_port, baud_rate=baud_rate, serial_timeout=g.G_SERIAL_TIMEOUT) - # else: - # pass + else: + communication_interface = DummyComIF(tmtc_printer=tmtc_printer) return communication_interface except (IOError, OSError): print("Error setting up communication interface") diff --git a/sendreceive/obsw_command_sender_receiver.py b/sendreceive/obsw_command_sender_receiver.py index 70448a02c890e3d9f0d2b20742cea3a706db93f3..2684765da460f9f3c2a5234e1a5cc127f2a5bb20 100644 --- a/sendreceive/obsw_command_sender_receiver.py +++ b/sendreceive/obsw_command_sender_receiver.py @@ -124,12 +124,14 @@ class CommandSenderReceiver: again. If resending reached certain counter, exit the program. :return: """ + if self._start_time == 0: + self._start_time = time.time() if self._timeout_counter == 5: print("Command Sender Receiver: No response from command !") sys.exit() if self._start_time != 0: self._elapsed_time = time.time() - self._start_time - if self._elapsed_time > self._tm_timeout * self._tc_send_timeout_factor: + if self._elapsed_time >= self._tm_timeout * self._tc_send_timeout_factor: print("Command Sender Receiver: Timeout, sending TC again !") self._com_interface.send_telecommand(self._last_tc, self._last_tc_info) self._timeout_counter = self._timeout_counter + 1 diff --git a/sendreceive/obsw_single_command_sender_receiver.py b/sendreceive/obsw_single_command_sender_receiver.py index d3e7fc297ee5f61a7718aaa5d90897d52d738b90..677e3893b17323d3420b11eadf12ee947b79ee0b 100644 --- a/sendreceive/obsw_single_command_sender_receiver.py +++ b/sendreceive/obsw_single_command_sender_receiver.py @@ -46,7 +46,10 @@ class SingleCommandSenderReceiver(CommandSenderReceiver): if not self.faulty_input: self._tm_listener.mode_id = g.ModeList.SingleCommandMode self._tm_listener.mode_change_event.set() + self._tmtc_printer.print_telecommand(self.pus_packet, self.pus_packet_info) self._com_interface.send_telecommand(self.pus_packet, self.pus_packet_info) + self._last_tc = self.pus_packet + self._last_tc_info = self.pus_packet_info while not self._reply_received: # wait until reply is received super()._check_for_first_reply() diff --git a/sendreceive/obsw_tm_listener.py b/sendreceive/obsw_tm_listener.py index 8501f4e8604e23ebe0f8ee9d209f8c2e88bb42d7..1be1a7125c815e3bfa00f80231f53e49768618f1 100644 --- a/sendreceive/obsw_tm_listener.py +++ b/sendreceive/obsw_tm_listener.py @@ -9,6 +9,7 @@ This Listener will propably have some kind of mode. In default configuration, it will just listen for packets """ +import sys import time import threading from collections import deque @@ -116,7 +117,7 @@ class TmListener: tm_ready = self.com_interface.data_available(self.tm_timeout * self.tc_timeout_factor) if tm_ready is False: return False - else: + elif tm_ready is True: self.__tm_packet_queue.append(self.com_interface.receive_telemetry()) start_time = time.time() elapsed_time = 0 @@ -130,6 +131,9 @@ class TmListener: if self.tm_timeout is not g.G_TM_TIMEOUT: self.tm_timeout = g.G_TM_TIMEOUT return True + else: + print("TM Listener: Configuration error in communication interface!") + sys.exit() def retrieve_tm_packet_queue(self): return self.__tm_packet_queue.copy() diff --git a/tc/obsw_pus_tc_base.py b/tc/obsw_pus_tc_base.py index 22061afc7c0328a2a9aec63a36d817c539a7a9b2..ba25669bda2be2ab821d751e222dd96fa081292a 100644 --- a/tc/obsw_pus_tc_base.py +++ b/tc/obsw_pus_tc_base.py @@ -10,8 +10,6 @@ import logging from enum import Enum from typing import TypeVar, Dict, Union, Tuple, Deque -PusTcT = TypeVar('PusTcT', bound='PUSTelecommand') - class TcDictionaryKeys(Enum): SERVICE = 1 @@ -115,7 +113,7 @@ class PusTelecommand: # Takes pusPackets, removes current Packet Error Control, # calculates new CRC (16 bits at wiretapping_packet end) and # adds it as correct Packet Error Control Code. Reference: ECSS-E70-41A p. 207-212 -def generate_packet_crc(tc_packet: PusTcT) -> PusTcT: +def generate_packet_crc(tc_packet: PusTelecommand) -> PusTelecommand: crc_func = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0xFFFF, xorOut=0x0000) crc = crc_func(bytearray(tc_packet[0:len(tc_packet) - 2])) tc_packet[len(tc_packet) - 2] = (crc & 0xFF00) >> 8 diff --git a/test/obsw_module_test.py b/test/obsw_module_test.py index 984091569f0c8a551b042fdbf530600e9497e885..3b4a985435754053330ffec3b4055a3227c819b9 100644 --- a/test/obsw_module_test.py +++ b/test/obsw_module_test.py @@ -43,7 +43,8 @@ from config import obsw_config as g from tc.obsw_pus_tc_packer import pack_dummy_device_test_into from tc.obsw_pus_tc_base import PusTcInfoQueueT, TcDictionaryKeys from tm.obsw_tm_service_1 import pusPacketInfoService1T -from tm.obsw_pus_tm_factory import PusTmInfoQueueT, PusTmInfoT, TmDictionaryKeys +from tm.obsw_pus_tm_base import TmDictionaryKeys +from tm.obsw_pus_tm_factory import PusTmInfoQueueT, PusTmInfoT from sendreceive.obsw_multiple_commands_sender_receiver import MultipleCommandSenderReceiver diff --git a/tm/obsw_pus_tm_base.py b/tm/obsw_pus_tm_base.py index fc5ea03bf2a632ce6badd9ce776a05a3401c56b2..f2b4666df0ab0d3e31930b197774e08fa30c3522 100644 --- a/tm/obsw_pus_tm_base.py +++ b/tm/obsw_pus_tm_base.py @@ -5,9 +5,8 @@ """ import datetime from enum import Enum, auto -from typing import Final +from typing import Final, Dict from crcmod import crcmod -from tm.obsw_pus_tm_factory import PusTmInfoT class TmDictionaryKeys(Enum): @@ -30,6 +29,9 @@ class TmDictionaryKeys(Enum): EVENT_PARAM_2 = auto() +PusTmInfoT = Dict[TmDictionaryKeys, any] + + class PusTelemetry: """ Generic PUS telemetry class. It is instantiated by passing the raw pus telemetry wiretapping_packet diff --git a/tm/obsw_pus_tm_factory.py b/tm/obsw_pus_tm_factory.py index 96945df7b33492d0c9e0d1fb9c0f1b19813d794f..b77ff9682bb65e64dea062fd0019de085de245f5 100644 --- a/tm/obsw_pus_tm_factory.py +++ b/tm/obsw_pus_tm_factory.py @@ -6,7 +6,7 @@ Description: Deserialize TM byte header_list into PUS TM Class Author: R.Mueller, S. Gaisser """ from typing import Deque, List, Dict, Tuple -from tm.obsw_pus_tm_base import PusTelemetry, TmDictionaryKeys +from tm.obsw_pus_tm_base import PusTelemetry, PusTmInfoT from tm.obsw_tm_service_1 import Service1TM from tm.obsw_tm_service_3 import Service3TM from tm.obsw_tm_service_5 import Service5TM @@ -15,7 +15,6 @@ import struct PusTmQueueT = Deque[PusTelemetry] PusTmListT = List[PusTelemetry] -PusTmInfoT = Dict[TmDictionaryKeys, any] PusTmTupleT = Tuple[PusTmInfoT, PusTelemetry] PusTmInfoQueueT = Deque[PusTmInfoT] PusTmTupleQueueT = Deque[PusTmTupleT] diff --git a/utility/obsw_args_parser.py b/utility/obsw_args_parser.py index 78210d54d91acdc428c8ca13406c7bbf53751d67..a98b306c7600cdea058ebf812696b918202e6793 100644 --- a/utility/obsw_args_parser.py +++ b/utility/obsw_args_parser.py @@ -24,8 +24,8 @@ def parse_input_arguments(): '0: GUI Mode, 1:Listener Mode, 2: Single Command Mode, 3: Service Test Mode, ' '4: Software Test Mode, 5: Unit Test Mode ', default=0) arg_parser.add_argument( - '-c', '--comIF', type=int, help='Communication Interface. 0 for Ethernet, 1 for Serial', - default=0) + '-c', '--comIF', type=int, help='Communication Interface. 0 for Ethernet, 1 for Serial, ' + '2 for virtual interface', default=2) arg_parser.add_argument('--clientIP', help='Client(Computer) IP. Default:\'\'', default='') arg_parser.add_argument( '--boardIP', help='Board IP. Default: 169.254.1.38', default='169.254.1.38') diff --git a/utility/obsw_tmtc_printer.py b/utility/obsw_tmtc_printer.py index 72e3a7ade6c6fb8a4762d1eace1c8d5721c91bc7..22381c1dd74a47dda13da72e6f483f8092477260 100644 --- a/utility/obsw_tmtc_printer.py +++ b/utility/obsw_tmtc_printer.py @@ -13,7 +13,7 @@ import sys from config import obsw_config as g from tm.obsw_pus_tm_base import PusTelemetry from tm.obsw_tm_service_3 import Service3TM -from tc.obsw_pus_tc_base import PusTcT, PusTcInfoT, TcDictionaryKeys +from tc.obsw_pus_tc_base import PusTelecommand, PusTcInfoT, TcDictionaryKeys class TmTcPrinter: @@ -255,7 +255,7 @@ class TmTcPrinter: shift_number = position + (6 - 2 * (position - 1)) return (byte >> shift_number) & 1 - def print_telecommand(self, tc_packet: PusTcT, tc_packet_info: PusTcInfoT = None): + def print_telecommand(self, tc_packet: bytes, tc_packet_info: PusTcInfoT = None): """ This function handles the printing of Telecommands :param tc_packet: