Skip to content

Commit

Permalink
Merge branch 'main' into mohr/daemon
Browse files Browse the repository at this point in the history
  • Loading branch information
umohr-irs committed May 17, 2022
2 parents be75bee + 95336de commit 35f96d1
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 116 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).

## [unreleased]

- Improve `lint.py`: Add prefix and print out executed command
- Architectural improvements for the `TmListener` component
- Separate functions to set the internal mode
- Moved mode enum outside of class scope
- Call user send callback for both queue commands and regular telecommands

## [v2.1.0]

- API consolidation for PUS TCs and TMs. Unified the API and made it more consistent
Expand Down
2 changes: 2 additions & 0 deletions lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def main():
f"flake8 . {additional_flags_both_steps} "
f"{additional_flags_first_step} {exclude_dirs_flag}"
)
print(f"lint.py - Executing command: {flake8_first_step_cmd}")
status = os.system(flake8_first_step_cmd)
if os.name == "nt":
if status != 0:
Expand All @@ -32,6 +33,7 @@ def main():
f"flake8 . {additional_flags_both_steps} {additional_flags_second_step}"
f" {exclude_dirs_flag}"
)
print(f"lint.py - Executing command: {flake8_second_step_cmd}")
os.system(flake8_second_step_cmd)


Expand Down
2 changes: 1 addition & 1 deletion src/tests/backend_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def create_backend_mock(tm_handler: CcsdsTmHandler) -> TmTcHandler:
com_if_key=CoreComInterfaces.DUMMY.value,
json_cfg_path="tmtc_config.json",
)
tm_listener = TmListener(com_if=com_if, tm_timeout=3.0, tc_timeout_factor=3.0)
tm_listener = TmListener(com_if=com_if, seq_timeout=3.0)
# The global variables are set by the argument parser.
tmtc_backend = TmTcHandler(
com_if=com_if,
Expand Down
17 changes: 4 additions & 13 deletions src/tmtccmd/com_if/tcpip_tcp_com_if.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ class TcpCommunicationType(enum.Enum):
SPACE_PACKETS = 0


# pylint: disable=abstract-method
# pylint: disable=arguments-differ
# pylint: disable=too-many-arguments
class TcpIpTcpComIF(CommunicationInterface):
"""Communication interface for TCP communication."""

Expand All @@ -49,9 +46,7 @@ def __init__(
com_type: TcpCommunicationType,
space_packet_ids: Tuple[int],
tm_polling_freqency: float,
tm_timeout: float,
tc_timeout_factor: float,
send_address: EthernetAddressT,
target_address: EthernetAddressT,
max_recv_size: int,
max_packets_stored: int = 50,
init_mode: int = CoreModeList.LISTENER_MODE,
Expand All @@ -63,16 +58,12 @@ def __init__(
:param space_packet_ids: 16 bit packet header for space packet headers. Used to
detect the start of PUS packets
:param tm_polling_freqency: Polling frequency in seconds
:param tm_timeout: Timeout in seconds
:param tmtc_printer: Printer instance, can be passed optionally to allow packet debugging
"""
super().__init__(com_if_key=com_if_key)
self.tm_timeout = tm_timeout
self.com_type = com_type
self.space_packet_ids = space_packet_ids
self.tc_timeout_factor = tc_timeout_factor
self.tm_polling_frequency = tm_polling_freqency
self.send_address = send_address
self.target_address = target_address
self.max_recv_size = max_recv_size
self.max_packets_stored = max_packets_stored
self.init_mode = init_mode
Expand All @@ -99,7 +90,7 @@ def __del__(self):
def initialize(self, args: any = None) -> any:
self.__tm_thread_kill_signal.clear()
self.__tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__tcp_socket.connect(self.send_address)
self.__tcp_socket.connect(self.target_address)

def open(self, args: any = None):
self.__tcp_conn_thread.start()
Expand All @@ -116,7 +107,7 @@ def close(self, args: any = None) -> None:

def send(self, data: bytearray):
try:
self.__tcp_socket.sendto(data, self.send_address)
self.__tcp_socket.sendto(data, self.target_address)
except ConnectionRefusedError:
LOGGER.warning("TCP connection attempt failed..")

Expand Down
8 changes: 4 additions & 4 deletions src/tmtccmd/config/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Argument parser modules for the TMTC commander core
"""
import argparse
import pprint
import sys
from typing import Optional

Expand Down Expand Up @@ -96,7 +95,6 @@ def parse_default_input_arguments(
"""Parses all input arguments
:return: Input arguments contained in a special namespace and accessable by args.<variable>
"""
from tmtccmd.utility.conf_util import AnsiColors

if len(sys.argv) == 1:
LOGGER.info(
Expand Down Expand Up @@ -233,7 +231,8 @@ def args_post_processing(
args, unknown: list, service_op_code_dict: ServiceOpCodeDictT
) -> None:
"""Handles the parsed arguments.
:param args: Namespace objects (see https://docs.python.org/dev/library/argparse.html#argparse.Namespace)
:param args: Namespace objects
(see https://docs.python.org/dev/library/argparse.html#argparse.Namespace)
:param unknown: List of unknown parameters.
:return: None
"""
Expand All @@ -247,7 +246,8 @@ def args_post_processing(

def handle_unspecified_args(args, service_op_code_dict: ServiceOpCodeDictT) -> None:
"""If some arguments are unspecified, they are set here with (variable) default values.
:param args:
:param args: Arguments from calling parse method
:param service_op_code_dict:
:return: None
"""
from tmtccmd.config.definitions import CoreModeStrings
Expand Down
10 changes: 4 additions & 6 deletions src/tmtccmd/config/com_if.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ def create_communication_interface_default(
communication_interface.initialize()
return communication_interface
except ConnectionRefusedError:
LOGGER.exception(f"TCP/IP connection refused")
LOGGER.exception("TCP/IP connection refused")
if com_if_key == CoreComInterfaces.TCPIP_UDP.value:
LOGGER.warning("Make sure that a UDP server is running")
if com_if_key == CoreComInterfaces.TCPIP_TCP.value:
LOGGER.warning("Make sure that a TCP server is running")
sys.exit(1)
except (IOError, OSError):
LOGGER.exception(f"Error setting up communication interface")
LOGGER.exception("Error setting up communication interface")
sys.exit(1)


Expand All @@ -93,7 +93,7 @@ def default_tcpip_cfg_setup(
:func:`create_default_tcpip_interface`
:param tcpip_type:
:param json_cfg_path:
:param space_packet_id: Required if the TCP com interface needs to parse space packets
:param space_packet_ids: Required if the TCP com interface needs to parse space packets
:return:
"""
from tmtccmd.com_if.tcpip_utilities import (
Expand Down Expand Up @@ -185,10 +185,8 @@ def create_default_tcpip_interface(
com_if_key=com_if_key,
com_type=TcpCommunicationType.SPACE_PACKETS,
space_packet_ids=space_packet_ids,
tm_timeout=get_global(CoreGlobalIds.TM_TIMEOUT),
tc_timeout_factor=get_global(CoreGlobalIds.TC_SEND_TIMEOUT_FACTOR),
tm_polling_freqency=0.5,
send_address=send_addr,
target_address=send_addr,
max_recv_size=max_recv_size,
init_mode=init_mode,
)
Expand Down
7 changes: 6 additions & 1 deletion src/tmtccmd/config/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ class QueueCommands(enum.Enum):
SET_TIMEOUT = "set_timeout"


TcQueueEntryArg = Any
UserArg = Any
"""Third Argument: Second argument in TC queue tuple. Fouth Argument
"""
UsrSendCbT = Callable[
[Union[bytes, QueueCommands], CommunicationInterface, Any, Any], None
[Union[bytes, QueueCommands], CommunicationInterface, TcQueueEntryArg, UserArg],
None,
]


Expand Down
1 change: 0 additions & 1 deletion src/tmtccmd/pus/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@

5 changes: 1 addition & 4 deletions src/tmtccmd/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,8 @@ def create_default_tmtc_backend(setup_args: SetupArgs, tm_handler: TmHandler):
com_if = setup_args.hook_obj.assign_communication_interface(
com_if_key=get_global(CoreGlobalIds.COM_IF)
)
tc_send_timeout_factor = get_global(CoreGlobalIds.TC_SEND_TIMEOUT_FACTOR)
tm_timeout = get_global(CoreGlobalIds.TM_TIMEOUT)
tm_listener = TmListener(
com_if=com_if, tm_timeout=tm_timeout, tc_timeout_factor=tc_send_timeout_factor
)
tm_listener = TmListener(com_if=com_if, seq_timeout=tm_timeout)
# The global variables are set by the argument parser.
tmtc_backend = TmTcHandler(
com_if=com_if,
Expand Down
1 change: 1 addition & 0 deletions src/tmtccmd/sendreceive/cmd_sender_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ def check_queue_entry(self, tc_queue_entry: TcQueueEntryT) -> bool:
LOGGER.info(f"Raw command: {queue_entry_second.hex(sep=',')}")
elif queue_entry_first == QueueCommands.SET_TIMEOUT:
self._tm_timeout = queue_entry_second
self._tm_listener.seq_timeout = queue_entry_second
else:
self._last_tc, self._last_tc_obj = (queue_entry_first, queue_entry_second)
return True
Expand Down
47 changes: 19 additions & 28 deletions src/tmtccmd/sendreceive/multiple_cmds_sender_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
"""
import sys
import time
from typing import Union, Deque
from typing import Union, Deque, Optional, Tuple
from collections import deque

from tmtccmd.config.definitions import CoreGlobalIds
from tmtccmd.ccsds.handler import CcsdsTmHandler
from tmtccmd.config.definitions import UsrSendCbT
from tmtccmd.sendreceive.sequential_sender_receiver import (
SequentialCommandSenderReceiver,
)
from tmtccmd.com_if.com_interface_base import CommunicationInterface
from tmtccmd.utility.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.core.globals_manager import get_global
from tmtccmd.sendreceive.tm_listener import TmListener
from tmtccmd.utility.tmtc_printer import get_console_logger

Expand All @@ -20,26 +19,26 @@


class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver):
"""Difference to seqential sender: This class can send TCs in bursts.
"""Difference to sequential 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
"""

def __init__(
self,
com_if: CommunicationInterface,
tmtc_printer: FsfwTmTcPrinter,
tc_queue: Deque,
apid: int,
tm_handler: CcsdsTmHandler,
tm_listener: TmListener,
tc_queue: Deque,
wait_intervals: list,
wait_time: Union[float, list],
print_tm: bool,
usr_send_wrapper: Optional[Tuple[UsrSendCbT, any]] = None,
):
"""TCs are sent in burst when applicable. Wait intervals can be specified by supplying
respective arguments
:param com_if:
:param tmtc_printer:
:param tc_queue:
:param wait_intervals: List of pause intervals. For example [1,3] means that a wait_time
is applied after
Expand All @@ -49,9 +48,11 @@ def __init__(
"""
super().__init__(
com_if=com_if,
tmtc_printer=tmtc_printer,
tm_listener=tm_listener,
tc_queue=tc_queue,
apid=apid,
tm_handler=tm_handler,
usr_send_wrapper=usr_send_wrapper,
)
self.waitIntervals = wait_intervals
self.waitTime = wait_time
Expand All @@ -64,19 +65,17 @@ def __init__(

def send_tc_queue_and_return_info(self):
try:
self._tm_listener.set_listener_mode(TmListener.ListenerModes.MANUAL)
self._tm_listener.manual_mode()
self._tm_listener.event_mode_change.set()
time.sleep(0.1)
# TC info queue is set in this function
self.__send_all_queue()
time.sleep(self._tm_timeout / 1.4)
# Get a copy of the queue, otherwise we will lose the data.
tm_packet_queue_list = self._tm_listener.retrieve_tm_packet_queue().copy()
if get_global(CoreGlobalIds.PRINT_TM):
self.print_tm_queue(self._tm_listener.retrieve_tm_packet_queue())
self._tm_listener.clear_tm_packet_queue()
if get_global(CoreGlobalIds.PRINT_TO_FILE):
self._tmtc_printer.print_to_file()
tm_packet_queue_list = (
self._tm_listener.retrieve_ccsds_tm_packet_queue().copy()
)
self._tm_listener.clear_ccsds_tm_packet_queue(apid=self._apid)
return self.tc_info_queue, tm_packet_queue_list
except (KeyboardInterrupt, SystemExit):
LOGGER.info("Keyboard Interrupt.")
Expand All @@ -91,15 +90,7 @@ def __handle_tc_resending(self):

def __send_all_queue(self):
while not self._tc_queue.__len__() == 0:
self.__send_and_print_tc()

def __send_and_print_tc(self):
tc_queue_tuple = self._tc_queue.pop()
if self.check_queue_entry(tc_queue_tuple):
pus_packet, pus_packet_obj = tc_queue_tuple
self.tc_info_queue.append(pus_packet_obj)
self._com_if.send_telecommand(pus_packet, pus_packet_obj)
self.__handle_waiting()
self._send_next_telecommand()

def __handle_waiting(self):
self.waitCounter = self.waitCounter + 1
Expand All @@ -114,12 +105,12 @@ def __handle_waiting(self):

def __retrieve_listener_tm_packet_queue(self):
if self._tm_listener.reply_event():
return self._tm_listener.retrieve_tm_packet_queue()
return self._tm_listener.retrieve_ccsds_tm_packet_queue(apid=self._apid)
else:
LOGGER.error(
"Multiple Command SenderReceiver: Configuration error, "
"reply event not set in TM listener"
)

def __clear_listener_tm_info_queue(self):
self._tm_listener.clear_tm_packet_queue()
self._tm_listener.clear_tm_packet_queues(True)
8 changes: 4 additions & 4 deletions src/tmtccmd/sendreceive/sequential_sender_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def send_queue_tc_and_receive_tm_sequentially(self):
"""Primary function which is called for sequential transfer.
:return:
"""
self._tm_listener.set_listener_mode(TmListener.ListenerModes.SEQUENCE)
self._tm_listener.sequence_mode()
# tiny delay for pus_tm listener
time.sleep(0.05)
if self._tc_queue:
Expand All @@ -77,7 +77,7 @@ def send_queue_tc_and_receive_tm_sequentially(self):
LOGGER.warning("Supplied TC queue is empty!")

def send_queue_tc_and_return(self):
self._tm_listener.set_listener_mode(TmListener.ListenerModes.LISTENER)
self._tm_listener.listener_mode()
# tiny delay for pus_tm listener
time.sleep(0.05)
if self._tc_queue:
Expand Down Expand Up @@ -148,13 +148,13 @@ def __check_next_tc_send(self):
return
# this flag is set in the separate receiver thread too
if self._reply_received:
if self.__send_next_telecommand():
if self._send_next_telecommand():
self._reply_received = False
# just calculate elapsed time if start time has already been set (= command has been sent)
else:
self._check_for_timeout()

def __send_next_telecommand(self) -> bool:
def _send_next_telecommand(self) -> bool:
"""Sends the next telecommand and returns whether an actual telecommand was sent"""
tc_queue_tuple = self._tc_queue.pop()
if self.check_queue_entry(tc_queue_tuple):
Expand Down

0 comments on commit 35f96d1

Please sign in to comment.