From 78c6990670763e0c58745131aba033536b68b968 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Apr 2024 17:21:41 +0200 Subject: [PATCH 1/4] possible fix for print tree argument --- tmtccmd/config/args.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tmtccmd/config/args.py b/tmtccmd/config/args.py index 7ed4a33c..8b90f601 100644 --- a/tmtccmd/config/args.py +++ b/tmtccmd/config/args.py @@ -213,6 +213,7 @@ def add_default_procedure_arguments(parser_or_subparser: argparse.ArgumentParser "--print-tree", dest="print_tree", nargs="*", + default=False, help=( f"Optional arguments [b] [p] []. Print the command definition tree. You " f"can{os.linesep}optionally add b to omit descriptions, p to display hidden nodes, " From 5def7c7dfd6ed7771666b741bfaa02d89f1876d6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Apr 2024 18:28:49 +0200 Subject: [PATCH 2/4] this is the correct fix --- tmtccmd/config/args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtccmd/config/args.py b/tmtccmd/config/args.py index 8b90f601..12c59452 100644 --- a/tmtccmd/config/args.py +++ b/tmtccmd/config/args.py @@ -213,7 +213,7 @@ def add_default_procedure_arguments(parser_or_subparser: argparse.ArgumentParser "--print-tree", dest="print_tree", nargs="*", - default=False, + default=None, help=( f"Optional arguments [b] [p] []. Print the command definition tree. You " f"can{os.linesep}optionally add b to omit descriptions, p to display hidden nodes, " From 7f115c6e89576f87332ca4b9b2aec87d4120f009 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Apr 2024 23:54:01 +0200 Subject: [PATCH 3/4] Update for tree commanding types --- CHANGELOG.md | 25 ++++-- examples/app/tmtcc.py | 17 ++-- tests/config/test_args_conversion.py | 50 ++++++------ tests/config/test_args_parsing.py | 11 +-- tests/test_backend.py | 20 ++--- tests/test_queue.py | 12 +-- tests/test_seq_sender.py | 4 +- tmtccmd/__init__.py | 8 +- tmtccmd/config/__init__.py | 47 +++-------- tmtccmd/config/args.py | 116 ++++++++++----------------- tmtccmd/config/defs.py | 23 +----- tmtccmd/tmtc/__init__.py | 2 +- tmtccmd/tmtc/decorator.py | 4 +- tmtccmd/tmtc/procedure.py | 22 ++--- tmtccmd/tmtc/queue.py | 26 +++--- 15 files changed, 167 insertions(+), 220 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f47998ac..4b486158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,21 @@ Starting from v4.0.0, this project adheres to [Semantic Versioning](http://semve # [unreleased] +# [v8.0.0rc2] 2024-04-22 + +## Changed + +- Renamed `DefaultProcedureParams` to `TreeCommandingParams`. +- Renamed `TcParams` to `CommandingParams`. +- Renamed `DefaultProcedureInfo` to `TreeCommandingProcedure`. +- Renamed `add_default_procedure_arguments` to `add_tree_commanding_arguments`. +- Renamed `TcProcedureType.DEFAULT` to `TcProcedureType.TREE_COMMANDING`. + +## Removed + +- `CoreServiceList` enumeration. +- `DEFAULT_APID` and `DEBUG_MODE` globals. + # [v8.0.0rc1] 2024-01-24 ## Fixed @@ -254,7 +269,7 @@ spacepackets version: v0.15.0 - `config.args`: Assigning of the COM interface in the args to setup converters is now done in the `args_to_params_generic` function. Otherwise, this feature does not work for the conversion - of CFDP arguments. + of CFDP arguments. ## Changed @@ -276,7 +291,7 @@ The usage of the `logging` library now is a lot more pythonic and more aligned to the recommended way to use the logger. The `get_console_logger` has become deprecated. Users are encouraged to create custom application loggers using `logging.getLogger(__name__)`. It is also possible to apply the library log format to an application logger using -`tmtccmd.logging.add_colorlog_console_logger`. +`tmtccmd.logging.add_colorlog_console_logger`. - Mark `get_console_logger` as deprecated. - New `tmtccmd.init_logger` method to set up library logger. @@ -315,7 +330,7 @@ It is also possible to apply the library log format to an application logger usi caches it. All `set_*` methods now do not expect the `SetupParams` to be passed explicitely anymore. - (breaking): The `PreArgsParsingWrapper` now expects a `setup_params` parameter to be passed to the - `parse` method. The parameter helper will be cached in the created `PostArgsParsingWrapper`. + `parse` method. The parameter helper will be cached in the created `PostArgsParsingWrapper`. - `args_to_params_tmtc` now expects an `assign_com_if` method and can assign a COM interface when it is passed. It oftentimes makes sense to determine a valid COM interface (and prompt applicable parameters from the user) before prompting procedure parameters. @@ -342,7 +357,7 @@ It is also possible to apply the library log format to an application logger usi - (breaking): `DefaultPusQueueHelper`: `seq_cnt_provider`, `pus_verificator` and `default_pus_apid` (formerly `pus_apid`) do not have default values anymore - and need to be specified explicitely. + and need to be specified explicitely. - (breaking): Renamed `tmtccmd.config.com.ComIfCfgBase` to `ComCfgBase` - (breaking): `tmtccmd.com.ComInterface`: Change `get_id` to `id` property. - (breaking): TCP (`tmtccmd.com.TcpSpacePacketsComIF`) and `tmtccmd.com.UdpComIF`: @@ -472,7 +487,7 @@ It is also possible to apply the library log format to an application logger usi ## TmTcHandler - Added a cached `SequentialCommandSenderReceiver` -- Added `CONTINUOUS` mode which will start the receiver thread in the +- Added `CONTINUOUS` mode which will start the receiver thread in the `SequentialCommandSenderReceiver` instance and only send one TC ## Runner module diff --git a/examples/app/tmtcc.py b/examples/app/tmtcc.py index 57fb9dc7..1854cca6 100755 --- a/examples/app/tmtcc.py +++ b/examples/app/tmtcc.py @@ -44,7 +44,8 @@ TcProcedureType, TcQueueEntryType, ) -from tmtccmd.util import FileSeqCountProvider, ObjectIdDictT, PusFileSeqCountProvider +from tmtccmd.util import ObjectIdDictT +from spacepackets.seqcount import FileSeqCountProvider, PusFileSeqCountProvider _LOGGER = logging.getLogger() @@ -234,14 +235,14 @@ def send_cb(self, send_params: SendCbParams): _LOGGER.info(log_entry.log_str) def queue_finished_cb(self, helper: ProcedureWrapper): - if helper.proc_type == TcProcedureType.DEFAULT: - def_proc = helper.to_def_procedure() + if helper.proc_type == TcProcedureType.TREE_COMMANDING: + def_proc = helper.to_tree_commanding_procedure() _LOGGER.info(f"Queue handling finished for command {def_proc.cmd_path}") def feed_cb(self, helper: ProcedureWrapper, wrapper: FeedWrapper): self.queue_helper.queue_wrapper = wrapper.queue_wrapper - if helper.proc_type == TcProcedureType.DEFAULT: - def_proc = helper.to_def_procedure() + if helper.proc_type == TcProcedureType.TREE_COMMANDING: + def_proc = helper.to_tree_commanding_procedure() cmd_path = def_proc.cmd_path assert cmd_path is not None # Path starts with / so the first entry of the list will be an empty string. We cut @@ -278,8 +279,8 @@ def main(): # noqa: C901 else: post_args_wrapper.set_params_with_prompts(proc_wrapper) params.apid = EXAMPLE_PUS_APID - if params.app_params.print_tree: - perform_tree_printout(params.app_params, hook_obj.get_command_definitions()) + if params.tc_params.print_tree: + perform_tree_printout(params.tc_params, hook_obj.get_command_definitions()) sys.exit(0) setup_args = SetupWrapper( hook_obj=hook_obj, setup_params=params, proc_param_wrapper=proc_wrapper @@ -312,6 +313,7 @@ def main(): # noqa: C901 while True: state = tmtc_backend.periodic_op(None) if state.request == BackendRequest.TERMINATION_NO_ERROR: + tmtc_backend.close_com_if() sys.exit(0) elif state.request == BackendRequest.DELAY_IDLE: _LOGGER.info("TMTC Client in IDLE mode") @@ -326,6 +328,7 @@ def main(): # noqa: C901 elif state.request == BackendRequest.CALL_NEXT: pass except KeyboardInterrupt: + tmtc_backend.close_com_if() sys.exit(0) diff --git a/tests/config/test_args_conversion.py b/tests/config/test_args_conversion.py index ee02784e..d0c19027 100644 --- a/tests/config/test_args_conversion.py +++ b/tests/config/test_args_conversion.py @@ -9,8 +9,8 @@ from tmtccmd import CoreModeConverter, CoreModeList from tmtccmd.config import CfdpParams from tmtccmd.config.args import ( - AppParams, - DefaultProcedureParams, + CommandingParams, + TreeCommandingParams, SetupParams, args_to_all_params_tmtc, cfdp_args_to_cfdp_params, @@ -52,7 +52,7 @@ def test_basic(self): self.assertEqual(self.params.tc_params.delay, 0) self.assertEqual(self.params.backend_params.mode, "") self.assertEqual(self.params.backend_params.com_if_id, "") - def_params = DefaultProcedureParams(None) + def_params = TreeCommandingParams(None) args_to_all_params_tmtc( pargs=self.pargs, params=self.params, @@ -78,7 +78,7 @@ def test_basic(self): def test_delay_set(self): self.simple_pargs_cli_set() self.pargs.delay = 2.0 - def_params = DefaultProcedureParams(None) + def_params = TreeCommandingParams(None) args_to_all_params_tmtc( pargs=self.pargs, params=self.params, @@ -115,7 +115,7 @@ def test_cfdp_conversion_acked(self): def test_auto_listener_mode(self): self.auto_listener_cli_set() - def_params = DefaultProcedureParams(None) + def_params = TreeCommandingParams(None) args_to_all_params_tmtc( pargs=self.pargs, params=self.params, @@ -138,7 +138,7 @@ def test_auto_listener_mode(self): def test_tree_printout_conversion_default(self): self.base_cli_set() self.pargs.print_tree = [] - def_params = DefaultProcedureParams(None) + def_params = TreeCommandingParams(None) args_to_all_params_tmtc( pargs=self.pargs, params=self.params, @@ -147,14 +147,14 @@ def test_tree_printout_conversion_default(self): def_tmtc_params=def_params, assign_com_if=False, ) - self.assertTrue(self.params.app_params.print_tree) - self.assertTrue(self.params.app_params.tree_print_with_description) - self.assertIsNone(self.params.app_params.tree_print_max_depth) + self.assertTrue(self.params.tc_params.print_tree) + self.assertTrue(self.params.tc_params.tree_print_with_description) + self.assertIsNone(self.params.tc_params.tree_print_max_depth) def test_tree_printout_conversion_with_custom_args(self): self.base_cli_set() self.pargs.print_tree = ["b", "2"] - def_params = DefaultProcedureParams(None) + def_params = TreeCommandingParams(None) args_to_all_params_tmtc( pargs=self.pargs, params=self.params, @@ -163,16 +163,16 @@ def test_tree_printout_conversion_with_custom_args(self): def_tmtc_params=def_params, assign_com_if=False, ) - self.assertTrue(self.params.app_params.print_tree) - self.assertFalse(self.params.app_params.tree_print_with_description) - self.assertEqual(self.params.app_params.tree_print_max_depth, 2) + self.assertTrue(self.params.tc_params.print_tree) + self.assertFalse(self.params.tc_params.tree_print_with_description) + self.assertEqual(self.params.tc_params.tree_print_max_depth, 2) @patch("builtins.print") def test_tree_printout_0(self, print_mock: MagicMock): root_node_only = CmdTreeNode.root_node() - app_params = AppParams() - app_params.print_tree = True - perform_tree_printout(app_params, root_node_only) + tc_params = CommandingParams() + tc_params.print_tree = True + perform_tree_printout(tc_params, root_node_only) self.assertEqual(len(print_mock.call_args_list), 2) self.assertEqual( print_mock.call_args_list[0], @@ -185,10 +185,10 @@ def test_tree_printout_0(self, print_mock: MagicMock): @patch("builtins.print") def test_tree_printout_1(self, print_mock: MagicMock): root_node_only = CmdTreeNode.root_node() - app_params = AppParams() - app_params.print_tree = True - app_params.tree_print_with_description = False - perform_tree_printout(app_params, root_node_only) + tc_params = CommandingParams() + tc_params.print_tree = True + tc_params.tree_print_with_description = False + perform_tree_printout(tc_params, root_node_only) self.assertEqual(len(print_mock.call_args_list), 2) self.assertEqual( print_mock.call_args_list[0], @@ -200,11 +200,11 @@ def test_tree_printout_1(self, print_mock: MagicMock): def test_tree_printout_2(self, print_mock: MagicMock): root_node_only = CmdTreeNode.root_node() root_node_only.add_child(CmdTreeNode("acs", "ACS Subsystem")) - app_params = AppParams() - app_params.print_tree = True - app_params.tree_print_with_description = False - app_params.tree_print_max_depth = 0 - perform_tree_printout(app_params, root_node_only) + tc_params = CommandingParams() + tc_params.print_tree = True + tc_params.tree_print_with_description = False + tc_params.tree_print_max_depth = 0 + perform_tree_printout(tc_params, root_node_only) self.assertEqual(len(print_mock.call_args_list), 2) self.assertEqual( print_mock.call_args_list[0], diff --git a/tests/config/test_args_parsing.py b/tests/config/test_args_parsing.py index 39d1324d..ec6b432e 100644 --- a/tests/config/test_args_parsing.py +++ b/tests/config/test_args_parsing.py @@ -5,7 +5,7 @@ add_tmtc_mode_arguments, add_generic_arguments, add_default_com_if_arguments, - add_default_procedure_arguments, + add_tree_commanding_arguments, ) @@ -29,14 +29,15 @@ def test_valid_argument_1(self): self.assertEqual(args.mode, "one-q") def test_def_proc_argument_empty(self): - add_default_procedure_arguments(self.arg_parser) + add_tree_commanding_arguments(self.arg_parser) args = self.arg_parser.parse_args([]) self.assertIsNone(args.cmd_path) def test_def_proc_argument_valid(self): - add_default_procedure_arguments(self.arg_parser) + add_tree_commanding_arguments(self.arg_parser) args = self.arg_parser.parse_args(["-p", "/PING"]) self.assertEqual(args.cmd_path, "/PING") + self.assertEqual(args.print_tree, None) def test_generic_arguments_empty(self): add_generic_arguments(self.arg_parser) @@ -61,7 +62,7 @@ def test_com_if_arguments_valid(self): self.assertEqual(args.com_if, "udp") def test_tree_print_args_0(self): - add_default_procedure_arguments(self.arg_parser) + add_tree_commanding_arguments(self.arg_parser) args = self.arg_parser.parse_args(["-T"]) self.assertEqual(args.print_tree, []) args = self.arg_parser.parse_args(["--print-tree"]) @@ -70,6 +71,6 @@ def test_tree_print_args_0(self): self.assertEqual(args.print_tree, []) def test_tree_print_args_1(self): - add_default_procedure_arguments(self.arg_parser) + add_tree_commanding_arguments(self.arg_parser) args = self.arg_parser.parse_args(["-T", "b", "2"]) self.assertEqual(args.print_tree, ["b", "2"]) diff --git a/tests/test_backend.py b/tests/test_backend.py index 9c47482f..690d9ace 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -10,11 +10,11 @@ from tmtccmd.core.ccsds_backend import NoValidProcedureSet from tmtccmd.tmtc import ( TcProcedureBase, - DefaultProcedureInfo, TcProcedureType, ProcedureWrapper, ) from tmtccmd.tmtc.handler import FeedWrapper, SendCbParams +from tmtccmd.tmtc.procedure import TreeCommandingProcedure from tmtccmd.tmtc.queue import DefaultPusQueueHelper, QueueWrapper @@ -48,9 +48,9 @@ def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper): self.send_cb_cmd_path_arg = None self.send_cb_op_code_arg = None if info is not None: - if info.proc_type == TcProcedureType.DEFAULT: + if info.proc_type == TcProcedureType.TREE_COMMANDING: self.feed_cb_def_proc_count += 1 - def_info = info.to_def_procedure() + def_info = info.to_tree_commanding_procedure() if def_info.cmd_path != "/ping": self.is_feed_cb_valid = False self.send_cb_cmd_path_arg = def_info.cmd_path @@ -116,7 +116,7 @@ def test_basic_ops(self): self.backend.tc_mode = TcMode.ONE_QUEUE with self.assertRaises(NoValidProcedureSet): self.backend.periodic_op() - self.backend.current_procedure = DefaultProcedureInfo(cmd_path="/ping") + self.backend.current_procedure = TreeCommandingProcedure(cmd_path="/ping") res = self.backend.periodic_op() # Only one queue entry which is handled immediately @@ -137,7 +137,7 @@ def test_basic_ops(self): def test_one_queue_multi_entry_ops(self): self.backend.tm_mode = TmMode.IDLE self.backend.tc_mode = TcMode.ONE_QUEUE - self.backend.current_procedure = DefaultProcedureInfo(cmd_path="/event") + self.backend.current_procedure = TreeCommandingProcedure(cmd_path="/event") res = self.backend.periodic_op() self.assertEqual(res.request, BackendRequest.CALL_NEXT) self.assertEqual(self.tc_handler.feed_cb_def_proc_count, 1) @@ -154,7 +154,7 @@ def test_one_queue_multi_entry_ops(self): def test_multi_queue_ops(self): self.backend.tm_mode = TmMode.IDLE self.backend.tc_mode = TcMode.MULTI_QUEUE - self.backend.current_procedure = DefaultProcedureInfo(cmd_path="/ping") + self.backend.current_procedure = TreeCommandingProcedure(cmd_path="/ping") res = self.backend.periodic_op() self.assertEqual(res.request, BackendRequest.CALL_NEXT) self.assertEqual(self.backend.request, BackendRequest.CALL_NEXT) @@ -167,7 +167,7 @@ def test_multi_queue_ops(self): self.assertEqual(self.tc_handler.feed_cb_call_count, 1) self.assertEqual(res.request, BackendRequest.DELAY_IDLE) self.backend.tc_mode = TcMode.MULTI_QUEUE - self.backend.current_procedure = DefaultProcedureInfo(cmd_path="/ping") + self.backend.current_procedure = TreeCommandingProcedure(cmd_path="/ping") res = self.backend.periodic_op() self.assertEqual(res.request, BackendRequest.CALL_NEXT) self.assertEqual(self.backend.request, BackendRequest.CALL_NEXT) @@ -175,13 +175,13 @@ def test_multi_queue_ops(self): self.assertEqual(self.tc_handler.feed_cb_call_count, 2) def test_procedure_handling(self): - def_proc = DefaultProcedureInfo(cmd_path="/ping") + def_proc = TreeCommandingProcedure(cmd_path="/ping") self.backend.current_procedure = def_proc self.assertEqual( - self.backend.current_procedure.proc_type, TcProcedureType.DEFAULT + self.backend.current_procedure.proc_type, TcProcedureType.TREE_COMMANDING ) proc_helper = self.backend.current_procedure - def_proc = proc_helper.to_def_procedure() + def_proc = proc_helper.to_tree_commanding_procedure() self.assertIsNotNone(def_proc) self.assertEqual(def_proc.cmd_path, "/ping") diff --git a/tests/test_queue.py b/tests/test_queue.py index da51c6ac..bf73bbe2 100644 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -7,7 +7,6 @@ from spacepackets.ecss import PusTelecommand from spacepackets.seqcount import ProvidesSeqCount -from tmtccmd import DefaultProcedureInfo # Required for eval calls # noinspection PyUnresolvedReferences @@ -17,13 +16,14 @@ RawTcEntry, WaitEntry, ) +from tmtccmd.tmtc.procedure import TreeCommandingProcedure from tmtccmd.tmtc.queue import DefaultPusQueueHelper, QueueWrapper class TestTcQueue(TestCase): def setUp(self) -> None: self.queue_wrapper = QueueWrapper( - info=DefaultProcedureInfo.empty(), queue=deque() + info=TreeCommandingProcedure.empty(), queue=deque() ) self.assertEqual(self.queue_wrapper.queue, deque()) self.queue_helper = DefaultPusQueueHelper( @@ -86,7 +86,7 @@ def test_multi_entry(self): self.assertTrue(pus_entry) log_entry = self.queue_wrapper.queue.popleft() self.assertFalse(log_entry.is_tc()) - cast_wrapper.base = log_entry + cast_wrapper.entry = log_entry log_entry = cast_wrapper.to_log_entry() self.assertTrue(log_entry) with self.assertRaises(TypeError): @@ -97,7 +97,7 @@ def test_multi_entry(self): raw_entry = self.queue_wrapper.queue.popleft() self.assertTrue(raw_entry.is_tc()) - cast_wrapper.base = raw_entry + cast_wrapper.entry = raw_entry raw_entry = cast_wrapper.to_raw_tc_entry() self.assertTrue(raw_entry) self.assertEqual(raw_entry.tc, bytes([0, 1, 2])) @@ -106,13 +106,13 @@ def test_multi_entry(self): space_packet_entry = self.queue_wrapper.queue.popleft() self.assertTrue(space_packet_entry.is_tc()) - cast_wrapper.base = space_packet_entry + cast_wrapper.entry = space_packet_entry space_packet_entry = cast_wrapper.to_space_packet_entry() self.assertTrue(space_packet_entry) self.assertTrue(space_packet_entry.space_packet, pus_cmd.to_space_packet()) packet_delay = self.queue_wrapper.queue.pop() self.assertFalse(packet_delay.is_tc()) - cast_wrapper.base = packet_delay + cast_wrapper.entry = packet_delay packet_delay = cast_wrapper.to_packet_delay_entry() self.assertEqual(packet_delay.delay_time.total_seconds(), 3.0) diff --git a/tests/test_seq_sender.py b/tests/test_seq_sender.py index 616aa1f6..aa08c850 100644 --- a/tests/test_seq_sender.py +++ b/tests/test_seq_sender.py @@ -8,7 +8,7 @@ from tmtccmd.com import ComInterface from tmtccmd.tmtc.ccsds_seq_sender import SequentialCcsdsSender, SenderMode from tmtccmd.tmtc.handler import TcHandlerBase, SendCbParams -from tmtccmd.tmtc.procedure import DefaultProcedureInfo +from tmtccmd.tmtc.procedure import TreeCommandingProcedure from tmtccmd.tmtc.queue import QueueWrapper, DefaultPusQueueHelper @@ -45,7 +45,7 @@ def test_basic(self): self.tc_handler_mock.send_cb.assert_called_with(ANY) call_args = self.tc_handler_mock.send_cb.call_args send_cb_params = cast(SendCbParams, call_args.args[0]) - self.assertEqual(send_cb_params.info.procedure, DefaultProcedureInfo.empty()) + self.assertEqual(send_cb_params.info.procedure, TreeCommandingProcedure.empty()) raw_tc_entry = send_cb_params.entry.to_raw_tc_entry() self.assertEqual(raw_tc_entry.tc, bytes([0, 1, 2])) # Queue should be empty now diff --git a/tmtccmd/__init__.py b/tmtccmd/__init__.py index 5c9bc9d1..296667ca 100644 --- a/tmtccmd/__init__.py +++ b/tmtccmd/__init__.py @@ -19,13 +19,13 @@ PreArgsParsingWrapper, CoreModeConverter, CoreModeList, - DefaultProcedureParams, + TreeCommandingParams, ) from tmtccmd.core.ccsds_backend import BackendBase from tmtccmd.tmtc import TmTypes, TmHandlerBase, CcsdsTmHandler from tmtccmd.core import ModeWrapper from tmtccmd.tmtc import ( - DefaultProcedureInfo, + TreeCommandingProcedure, TcProcedureBase, ProcedureWrapper, TcHandlerBase, @@ -236,7 +236,7 @@ def create_default_tmtc_backend( def setup_backend_def_procedure( - backend: CcsdsTmtcBackend, tmtc_params: DefaultProcedureParams + backend: CcsdsTmtcBackend, tmtc_params: TreeCommandingProcedure ): assert tmtc_params.cmd_path is not None - backend.current_procedure = DefaultProcedureInfo(tmtc_params.cmd_path) + backend.current_procedure = TreeCommandingProcedure(tmtc_params.cmd_path) diff --git a/tmtccmd/config/__init__.py b/tmtccmd/config/__init__.py index 9bebab2e..5c775503 100644 --- a/tmtccmd/config/__init__.py +++ b/tmtccmd/config/__init__.py @@ -20,14 +20,14 @@ from tmtccmd.core import TcMode, TmMode from tmtccmd.core.base import ModeWrapper from tmtccmd.tmtc.procedure import ( - CfdpProcedureInfo, - DefaultProcedureInfo, + CfdpProcedure, + TreeCommandingProcedure, ProcedureWrapper, TcProcedureType, ) from .args import ( - DefaultProcedureParams, + TreeCommandingParams, PreArgsParsingWrapper, ProcedureParamsWrapper, SetupParams, @@ -42,15 +42,12 @@ CoreComInterfaces, CoreModeConverter, CoreModeList, - CoreServiceList, default_json_path, ) from .hook import HookBase from .prompt import prompt_op_code, prompt_service from .tmtc import CmdTreeNode, OpCodeEntry, OpCodeOptionBase, TmtcDefinitionWrapper -_LOGGER = logging.getLogger(__name__) - def backend_mode_conversion(mode: str, mode_wrapper: ModeWrapper): if mode == CoreModeConverter.get_str(CoreModeList.LISTENER_MODE): @@ -64,30 +61,6 @@ def backend_mode_conversion(mode: str, mode_wrapper: ModeWrapper): mode_wrapper.tm_mode = TmMode.LISTENER -def get_global_hook_obj() -> Optional[HookBase]: - """This function can be used to get the handle to the global hook object. - :return: - """ - - try: - from typing import cast - - from tmtccmd.config.definitions import CoreGlobalIds - from tmtccmd.core.globals_manager import get_global - - hook_obj_raw = get_global(CoreGlobalIds.TMTC_HOOK) - if hook_obj_raw is None: - _LOGGER.error("Hook object is invalid!") - return None - return cast(HookBase, hook_obj_raw) - except ImportError: - _LOGGER.exception("Issues importing modules to get global hook handle!") - return None - except AttributeError: - _LOGGER.exception("Attribute error when trying to get global hook handle!") - return None - - class SetupWrapper: """This class encapsulates various important setup parameters required by tmtccmd components""" @@ -115,12 +88,12 @@ def params(self): return self._params -def tmtc_params_to_procedure(params: DefaultProcedureParams) -> DefaultProcedureInfo: - return DefaultProcedureInfo(cmd_path=params.cmd_path) +def tmtc_params_to_procedure(params: TreeCommandingParams) -> TreeCommandingProcedure: + return TreeCommandingProcedure(cmd_path=params.cmd_path) -def cfdp_put_req_params_to_procedure(params: CfdpParams) -> CfdpProcedureInfo: - proc_info = CfdpProcedureInfo() +def cfdp_put_req_params_to_procedure(params: CfdpParams) -> CfdpProcedure: + proc_info = CfdpProcedure() proc_info.request_wrapper.base = PutRequestCfgWrapper(params) return proc_info @@ -129,8 +102,10 @@ def params_to_procedure_conversion( param_wrapper: ProcedureParamsWrapper, ) -> ProcedureWrapper: proc_wrapper = ProcedureWrapper(None) - if param_wrapper.ptype == TcProcedureType.DEFAULT: - proc_wrapper.procedure = tmtc_params_to_procedure(param_wrapper.def_params()) # type: ignore + if param_wrapper.ptype == TcProcedureType.TREE_COMMANDING: + tree_cmd_params = param_wrapper.tree_commanding_params() + assert tree_cmd_params is not None + proc_wrapper.procedure = tmtc_params_to_procedure(tree_cmd_params) elif param_wrapper.ptype == TcProcedureType.CFDP: proc_wrapper.procedure = cfdp_put_req_params_to_procedure( param_wrapper.cfdp_params() # type: ignore diff --git a/tmtccmd/config/args.py b/tmtccmd/config/args.py index 12c59452..92445a2a 100644 --- a/tmtccmd/config/args.py +++ b/tmtccmd/config/args.py @@ -8,13 +8,12 @@ from dataclasses import dataclass from typing import List, Optional, Sequence, Tuple, Union -from deprecated.sphinx import deprecated from prompt_toolkit.shortcuts import CompleteStyle from spacepackets.cfdp import TransmissionMode from tmtccmd.com import ComInterface from tmtccmd.com.utils import determine_com_if -from tmtccmd.config.prompt import prompt_cmd_path, prompt_op_code, prompt_service +from tmtccmd.config.prompt import prompt_cmd_path from tmtccmd.config.tmtc import CmdTreeNode from tmtccmd.tmtc.procedure import TcProcedureType @@ -23,7 +22,7 @@ CoreComInterfaces, CoreModeConverter, CoreModeList, - DefaultProcedureParams, + TreeCommandingParams, ) from .hook import HookBase @@ -62,16 +61,16 @@ def __init__(self): def ptype(self): return self._ptype - def set_params(self, params: Union[DefaultProcedureParams, CfdpParams]): - if isinstance(params, DefaultProcedureParams): + def set_params(self, params: Union[TreeCommandingParams, CfdpParams]): + if isinstance(params, TreeCommandingParams): self._params = params - self._ptype = TcProcedureType.DEFAULT + self._ptype = TcProcedureType.TREE_COMMANDING elif isinstance(params, CfdpParams): self._params = params self._ptype = TcProcedureType.CFDP - def def_params(self) -> Optional[DefaultProcedureParams]: - if self._ptype == TcProcedureType.DEFAULT: + def tree_commanding_params(self) -> Optional[TreeCommandingParams]: + if self._ptype == TcProcedureType.TREE_COMMANDING: return self._params return None @@ -82,9 +81,12 @@ def cfdp_params(self) -> Optional[CfdpParams]: @dataclass -class TcParams: +class CommandingParams: delay: float = 0.0 apid: int = 0 + print_tree: bool = False + tree_print_with_description: bool = True + tree_print_max_depth: Optional[int] = None @dataclass @@ -100,9 +102,6 @@ class AppParams: use_gui: bool = False reduced_printout: bool = False use_ansi_colors: bool = True - print_tree: bool = False - tree_print_with_description: bool = True - tree_print_max_depth: Optional[int] = None compl_style: CompleteStyle = CompleteStyle.READLINE_LIKE @@ -110,13 +109,13 @@ class SetupParams: def __init__( self, com_if: Optional[ComInterface] = None, - tc_params: Optional[TcParams] = None, + tc_params: Optional[CommandingParams] = None, backend_params: Optional[BackendParams] = None, app_params: Optional[AppParams] = None, ): self.com_if = com_if if tc_params is None: - self.tc_params = TcParams() + self.tc_params = CommandingParams() if backend_params is None: self.backend_params = BackendParams() if app_params is None: @@ -159,7 +158,7 @@ def add_default_tmtccmd_args(parser: argparse.ArgumentParser): add_tmtc_mode_arguments(parser) add_default_com_if_arguments(parser) add_generic_arguments(parser) - add_default_procedure_arguments(parser) + add_tree_commanding_arguments(parser) add_ethernet_arguments(parser) @@ -199,7 +198,7 @@ def parse_default_tmtccmd_input_arguments( return args, unknown -def add_default_procedure_arguments(parser_or_subparser: argparse.ArgumentParser): +def add_tree_commanding_arguments(parser_or_subparser: argparse.ArgumentParser): parser_or_subparser.add_argument( "-p", "--path", @@ -371,41 +370,9 @@ def add_ethernet_arguments(arg_parser: argparse.ArgumentParser): ) -@deprecated( - version="8.0.0", - reason="use determine_cmd_path instead", -) -def find_service_and_op_code( - params: SetupParams, - def_params: DefaultProcedureParams, - hook_obj: HookBase, - pargs: argparse.Namespace, - use_prompts: bool, -): - tmtc_defs = hook_obj.get_tmtc_definitions() - if pargs.service is None: - if use_prompts: - print("No service argument (-s) specified, prompting from user") - # Try to get the service list from the hook base and prompt service - # from user - def_params.service = prompt_service( - tmtc_defs, params.app_params.compl_style - ) - else: - def_params.service = pargs.service - if pargs.op_code is None: - current_service = def_params.service - if use_prompts: - def_params.op_code = prompt_op_code( - tmtc_defs, current_service, params.app_params.compl_style - ) - else: - def_params.op_code = pargs.op_code - - def determine_cmd_path( params: SetupParams, - def_params: DefaultProcedureParams, + def_params: TreeCommandingParams, hook_obj: HookBase, pargs: argparse.Namespace, use_prompts: bool, @@ -435,15 +402,6 @@ def args_to_params_generic( params.app_params.use_gui = False else: params.app_params.use_gui = pargs.gui - if pargs.print_tree is not None: - params.app_params.print_tree = True - for arg in pargs.print_tree: - if "b" in arg: - params.app_params.tree_print_with_description = False - if arg.isdigit(): - params.app_params.tree_print_max_depth = int(arg) - else: - params.app_params.print_tree = False if pargs.com_if is None or pargs.com_if == CoreComInterfaces.UNSPECIFIED.value: assert hook_obj.cfg_path is not None params.com_if_id = determine_com_if( @@ -507,7 +465,7 @@ def args_to_all_params_for_cfdp( def args_to_all_params_tmtc( pargs: argparse.Namespace, params: SetupParams, - def_tmtc_params: DefaultProcedureParams, + def_tmtc_params: TreeCommandingParams, hook_obj: HookBase, use_prompts: bool, assign_com_if: bool = True, @@ -537,6 +495,14 @@ def args_to_all_params_tmtc( use_prompts=use_prompts, assign_com_if=assign_com_if, ) + params.tc_params.print_tree = False + if pargs.print_tree is not None: + params.tc_params.print_tree = True + for arg in pargs.print_tree: + if "b" in arg: + params.tc_params.tree_print_with_description = False + if arg.isdigit(): + params.tc_params.tree_print_max_depth = int(arg) mode_set_explicitely = False if pargs.mode is None: params.mode = CoreModeConverter.get_str(CoreModeList.ONE_QUEUE_MODE) @@ -561,7 +527,7 @@ def args_to_all_params_tmtc( params.tc_params.delay = float(pargs.delay) if ( params.mode != CoreModeConverter.get_str(CoreModeList.LISTENER_MODE) - and not params.app_params.print_tree + and not params.tc_params.print_tree ): determine_cmd_path( params=params, @@ -572,18 +538,18 @@ def args_to_all_params_tmtc( ) -def perform_tree_printout(app_params: AppParams, cmd_def_tree: CmdTreeNode): - if app_params.tree_print_with_description: +def perform_tree_printout(tc_params: CommandingParams, cmd_def_tree: CmdTreeNode): + if tc_params.tree_print_with_description: info_str = "with full descriptions" else: info_str = "without descriptions" - if app_params.tree_print_max_depth is not None: - info_str += f" and maximum depth {app_params.tree_print_max_depth}" + if tc_params.tree_print_max_depth is not None: + info_str += f" and maximum depth {tc_params.tree_print_max_depth}" print(f"Printing command tree {info_str}:") print( cmd_def_tree.str_for_tree( - app_params.tree_print_with_description, - app_params.tree_print_max_depth, + tc_params.tree_print_with_description, + tc_params.tree_print_max_depth, ) ) @@ -679,7 +645,7 @@ def add_def_proc_args(self): the service and operation code flags.""" self._check_arg_parser() assert self.args_parser is not None - add_default_procedure_arguments(self.args_parser) + add_tree_commanding_arguments(self.args_parser) def add_cfdp_args(self): """Add the default CFDP procedure parameters to the default parser.""" @@ -713,7 +679,7 @@ def add_def_proc_and_cfdp_as_subparsers( formatter_class=argparse.RawTextHelpFormatter, parents=[self.parent_parser], ) - add_default_procedure_arguments(tmtc_parser) + add_tree_commanding_arguments(tmtc_parser) cfdp_descrip = "CCSDS CFDP File Transfer" cfdp_parser = subparser.add_parser( "cfdp", @@ -763,7 +729,7 @@ def use_gui(self): def request_type_from_args(self) -> TcProcedureType: if hasattr(self.args_raw, "proc_type"): if self.args_raw.proc_type == "tmtc": - return TcProcedureType.DEFAULT + return TcProcedureType.TREE_COMMANDING elif self.args_raw.proc_type == "cfdp": return TcProcedureType.CFDP else: @@ -772,7 +738,7 @@ def request_type_from_args(self) -> TcProcedureType: ' "cfdp"' ) else: - return TcProcedureType.DEFAULT + return TcProcedureType.TREE_COMMANDING def set_params_with_prompts(self, proc_base: ProcedureParamsWrapper): self._set_params(proc_base, True) @@ -782,8 +748,8 @@ def set_params_without_prompts(self, proc_wrapper: ProcedureParamsWrapper): def _set_params(self, proc_base: ProcedureParamsWrapper, with_prompts: bool): param_type = self.request_type_from_args() - if param_type == TcProcedureType.DEFAULT: - def_proc_params = DefaultProcedureParams(None) + if param_type == TcProcedureType.TREE_COMMANDING: + def_proc_params = TreeCommandingParams(None) if with_prompts: self.set_tmtc_params_with_prompts(def_proc_params) else: @@ -803,10 +769,10 @@ def set_cfdp_params_with_prompts(self, cfdp_params: CfdpParams): def set_cfdp_params_without_prompts(self, cfdp_params: CfdpParams): self._set_cfdp_params(cfdp_params, False) - def set_tmtc_params_with_prompts(self, tmtc_params: DefaultProcedureParams): + def set_tmtc_params_with_prompts(self, tmtc_params: TreeCommandingParams): self._set_tmtc_params(tmtc_params, True) - def set_tmtc_params_without_prompts(self, tmtc_params: DefaultProcedureParams): + def set_tmtc_params_without_prompts(self, tmtc_params: TreeCommandingParams): """Set up the parameter object from the parsed arguments. This call auto-determines whether prompts should be used depending on whether the GUI flag was passed or not. @@ -816,7 +782,7 @@ def set_tmtc_params_without_prompts(self, tmtc_params: DefaultProcedureParams): def _set_tmtc_params( self, - def_tmtc_params: DefaultProcedureParams, + def_tmtc_params: TreeCommandingParams, use_prompts: bool, ): try: diff --git a/tmtccmd/config/defs.py b/tmtccmd/config/defs.py index 8ebd0ae9..0c7658e3 100644 --- a/tmtccmd/config/defs.py +++ b/tmtccmd/config/defs.py @@ -10,7 +10,7 @@ @dataclass -class DefaultProcedureParams: +class TreeCommandingParams: cmd_path: Optional[str] @@ -31,8 +31,6 @@ def default_json_path() -> str: class CoreComInterfaces(str, enum.Enum): - value: str - DUMMY = "dummy" UDP = "udp" TCP = "tcp" @@ -89,22 +87,3 @@ def get_str(mode: Union[CoreModeList, int]) -> str: return "idle" else: return "" - - -class CoreServiceList(str, enum.Enum): - value: str - SERVICE_2 = "2" - SERVICE_3 = "3" - SERVICE_5 = "5" - SERVICE_8 = "8" - SERVICE_9 = "9" - SERVICE_11 = "11" - SERVICE_17 = "17" - SERVICE_17_ALT = "test" - SERVICE_20 = "20" - SERVICE_23 = "23" - SERVICE_200 = "200" - - -DEFAULT_APID = 0xEF -DEBUG_MODE = False diff --git a/tmtccmd/tmtc/__init__.py b/tmtccmd/tmtc/__init__.py index 377096e0..6d40942c 100644 --- a/tmtccmd/tmtc/__init__.py +++ b/tmtccmd/tmtc/__init__.py @@ -22,7 +22,7 @@ from .procedure import ( TcProcedureBase, TcProcedureType, - DefaultProcedureInfo, + TreeCommandingProcedure, CustomProcedureInfo, ProcedureWrapper, ) diff --git a/tmtccmd/tmtc/decorator.py b/tmtccmd/tmtc/decorator.py index 881bdcef..3253a8eb 100644 --- a/tmtccmd/tmtc/decorator.py +++ b/tmtccmd/tmtc/decorator.py @@ -2,7 +2,7 @@ import functools from tmtccmd.tmtc import TcHandlerBase -from tmtccmd.tmtc.procedure import DefaultProcedureInfo +from tmtccmd.tmtc.procedure import TreeCommandingProcedure from tmtccmd.tmtc.queue import DefaultPusQueueHelper SERVICE_HANDLER_DICT = dict() @@ -11,7 +11,7 @@ @dataclasses.dataclass class ServiceProviderParams: handler_base: TcHandlerBase - info: DefaultProcedureInfo + info: TreeCommandingProcedure queue_helper: DefaultPusQueueHelper op_code: str diff --git a/tmtccmd/tmtc/procedure.py b/tmtccmd/tmtc/procedure.py index c933ee92..504282f9 100644 --- a/tmtccmd/tmtc/procedure.py +++ b/tmtccmd/tmtc/procedure.py @@ -6,7 +6,7 @@ class TcProcedureType(enum.Enum): - DEFAULT = 0 + TREE_COMMANDING = 0 CFDP = 1 CUSTOM = 2 @@ -25,13 +25,13 @@ def __repr__(self): return f"{self.__class__.__name__}(info={self.procedure!r}" -class DefaultProcedureInfo(TcProcedureBase): +class TreeCommandingProcedure(TcProcedureBase): """Generic abstraction for procedures. A procedure can be a single command or a sequence of commands. Generally, one procedure is mapped to a specific TC queue which is packed during run-time""" def __init__(self, cmd_path: Optional[str]): - super().__init__(TcProcedureType.DEFAULT) + super().__init__(TcProcedureType.TREE_COMMANDING) self.cmd_path = cmd_path @classmethod @@ -41,11 +41,13 @@ def empty(cls): def __repr__(self): return f"CmdInfo(cmd_path={self.cmd_path!r})" - def __eq__(self, other: DefaultProcedureInfo) -> bool: - return self.cmd_path == other.cmd_path + def __eq__(self, other: object) -> bool: + if isinstance(other, TreeCommandingProcedure): + return self.cmd_path == other.cmd_path + return False -class CfdpProcedureInfo(TcProcedureBase): +class CfdpProcedure(TcProcedureBase): def __init__(self): super().__init__(TcProcedureType.CFDP) self.request_wrapper = CfdpRequestWrapper(None) @@ -81,16 +83,16 @@ def __cast_internally( raise TypeError(f"Invalid object {obj} for type {self.procedure.ptype}") return cast(obj_type, obj) - def to_def_procedure(self) -> DefaultProcedureInfo: + def to_tree_commanding_procedure(self) -> TreeCommandingProcedure: assert self.procedure is not None return self.__cast_internally( - DefaultProcedureInfo, self.procedure, TcProcedureType.DEFAULT + TreeCommandingProcedure, self.procedure, TcProcedureType.TREE_COMMANDING ) - def to_cfdp_procedure(self) -> CfdpProcedureInfo: + def to_cfdp_procedure(self) -> CfdpProcedure: assert self.procedure is not None return self.__cast_internally( - CfdpProcedureInfo, self.procedure, TcProcedureType.CFDP + CfdpProcedure, self.procedure, TcProcedureType.CFDP ) def to_custom_procedure(self) -> CustomProcedureInfo: diff --git a/tmtccmd/tmtc/queue.py b/tmtccmd/tmtc/queue.py index 4f36ec87..eca7ed94 100644 --- a/tmtccmd/tmtc/queue.py +++ b/tmtccmd/tmtc/queue.py @@ -13,7 +13,7 @@ from spacepackets.seqcount import ProvidesSeqCount from tmtccmd.pus.s11_tc_sched import Subservice as Pus11Subservice -from tmtccmd.tmtc.procedure import DefaultProcedureInfo, TcProcedureBase +from tmtccmd.tmtc.procedure import TreeCommandingProcedure, TcProcedureBase class TcQueueEntryType(Enum): @@ -110,24 +110,27 @@ def __repr__(self): class QueueEntryHelper: def __init__(self, base: Optional[TcQueueEntryBase]): - self.base = base + self.entry = base @property def is_tc(self) -> bool: - return self.base.is_tc() + assert self.entry is not None + return self.entry.is_tc() @property def entry_type(self) -> TcQueueEntryType: - return self.base.etype + assert self.entry is not None + return self.entry.etype def __cast_internally( self, obj_type: Type[TcQueueEntryBase], expected_type: TcQueueEntryType, ) -> Any: - if self.base.etype != expected_type: - raise TypeError(f"Invalid object {self.base} for type {expected_type}") - return cast(obj_type, self.base) + assert self.entry is not None + if self.entry.etype != expected_type: + raise TypeError(f"Invalid object {self.entry} for type {expected_type}") + return cast(obj_type, self.entry) def to_log_entry(self) -> LogQueueEntry: return self.__cast_internally(LogQueueEntry, TcQueueEntryType.LOG) @@ -161,7 +164,7 @@ def __init__( @classmethod def empty(cls): - return cls(DefaultProcedureInfo.empty(), deque()) + return cls(TreeCommandingProcedure.empty(), deque()) def __repr__(self): return ( @@ -251,14 +254,17 @@ def pre_add_cb(self, entry: TcQueueEntryBase): self._pus_packet_handler(pus_entry.pus_tc) def _handle_time_tagged_tc(self, pus_tc: PusTelecommand): - pus_tc_raw = pus_tc.app_data[self.tc_sched_timestamp_len :] + new_pus_tc_app_data = bytearray() + new_pus_tc_app_data.extend(pus_tc.app_data[: self.tc_sched_timestamp_len]) + pus_tc_raw = new_pus_tc_app_data[self.tc_sched_timestamp_len :] if not check_pus_crc(pus_tc_raw): raise ValueError( f"crc check on contained PUS TC with length {len(pus_tc_raw)} failed" ) time_tagged_tc = PusTelecommand.unpack(pus_tc_raw) self._pus_packet_handler(time_tagged_tc) - pus_tc.app_data[self.tc_sched_timestamp_len :] = time_tagged_tc.pack() + new_pus_tc_app_data.extend(time_tagged_tc.pack()) + pus_tc._app_data = new_pus_tc_app_data def _pus_packet_handler(self, pus_tc: PusTelecommand): recalc_crc = False From 4a88306ca929f2ba7fa90430c50a35d52a6fddc4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Apr 2024 11:09:09 +0200 Subject: [PATCH 4/4] spacepackets update --- CHANGELOG.md | 5 +++- pyproject.toml | 8 ++--- release-checklist.md | 2 +- tests/com/test_dummy.py | 2 +- tests/com/test_tcp.py | 2 +- tests/tc/test_srv20.py | 2 +- tests/test_backend.py | 19 +++++++----- tests/test_printer.py | 4 ++- tests/test_pus_verif_log.py | 51 +++++++++++++++++++++----------- tests/test_queue.py | 5 ++-- tests/test_seq_sender.py | 3 +- tests/test_tm_handler.py | 18 +++++++++-- tests/tm/test_srv1.py | 8 +++-- tests/tm/test_srv17.py | 13 ++++---- tests/tm/test_srv20.py | 6 ++-- tests/tm/test_srv200.py | 2 +- tests/tm/test_srv5.py | 6 ++-- tmtccmd/com/dummy.py | 10 +++---- tmtccmd/pus/tc/s20_fsfw_param.py | 17 ++++------- tmtccmd/pus/tm/s20_fsfw_param.py | 19 +++++------- tmtccmd/pus/tm/s5_fsfw_event.py | 21 ++++++------- 21 files changed, 125 insertions(+), 98 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d1aa26..285d227f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,10 @@ Starting from v4.0.0, this project adheres to [Semantic Versioning](http://semve # [unreleased] -# [v8.0.0rc2] 2024-04-22 +# [v8.0.0rc2] 2024-04-23 + +- Bumped `spacepackets` to release range >=0.24, <0.25. +- Bumped `cfdp-py` to v0.1.1. ## Changed diff --git a/pyproject.toml b/pyproject.toml index 43c726ad..b95db959 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,8 +36,8 @@ dependencies = [ "Deprecated~=1.2", "pyserial~=3.5", "dle-encoder~=0.2.3", - "spacepackets~=0.23.0", - "cfdp-py~=0.1.0" + "spacepackets>=0.24.0, <0.25", + "cfdp-py~=0.1.1", # "spacepackets @ git+https://github.com/us-irs/spacepackets-py@main" ] @@ -56,7 +56,7 @@ test = [ [tool.setuptools.packages] find = {} -[tool.ruff] +[tool.ruff.lint] ignore = ["E501"] -[tool.ruff.extend-per-file-ignores] +[tool.ruff.lint.extend-per-file-ignores] "__init__.py" = ["F401"] diff --git a/release-checklist.md b/release-checklist.md index 66392698..7bf388ba 100644 --- a/release-checklist.md +++ b/release-checklist.md @@ -12,7 +12,7 @@ The steps shown here are for Ubuntu/MacOS. with date and new `unreleased`section. 4. Run tests with `pytest .` 5. Run auto-formatter with `black .` -6. Run linter with `ruff .` +6. Run linter with `ruff check .` 7. Wait for CI/CD results. This also runs the tests on different operating systems diff --git a/tests/com/test_dummy.py b/tests/com/test_dummy.py index 26c67b27..b2fae4c3 100644 --- a/tests/com/test_dummy.py +++ b/tests/com/test_dummy.py @@ -14,7 +14,7 @@ def test_dummy_if(self): dummy_com_if.initialize() self.assertTrue(dummy_com_if.initialized) self.assertFalse(dummy_com_if.data_available()) - dummy_com_if.send(PusTelecommand(service=17, subservice=1).pack()) + dummy_com_if.send(PusTelecommand(apid=0x02, service=17, subservice=1).pack()) self.assertTrue(dummy_com_if.data_available()) replies = dummy_com_if.receive() # Full verification set (acceptance, start and completion) and ping reply diff --git a/tests/com/test_tcp.py b/tests/com/test_tcp.py index 4fd9ce2f..71d5f2cc 100644 --- a/tests/com/test_tcp.py +++ b/tests/com/test_tcp.py @@ -31,7 +31,7 @@ def setUp(self) -> None: self.base_data = bytes([0, 1, 2, 3]) self.ping_cmd = PusTelecommand(service=17, subservice=1, apid=0x22) self.ping_reply = PusTelemetry( - service=17, subservice=2, apid=0x22, time_provider=None + service=17, subservice=2, apid=0x22, timestamp=bytes() ) self.tcp_client = TcpSpacePacketsClient( "tcp", diff --git a/tests/tc/test_srv20.py b/tests/tc/test_srv20.py index 8eb3c497..91da95d9 100644 --- a/tests/tc/test_srv20.py +++ b/tests/tc/test_srv20.py @@ -14,7 +14,7 @@ def setUp(self): self.boolean_param = create_scalar_boolean_parameter( object_id=self.obj_id, domain_id=1, unique_id=5, parameter=True ) - self.tc = create_load_param_cmd(self.boolean_param) + self.tc = create_load_param_cmd(0x05, self.boolean_param) def test_basic(self): # 12 bytes of generic parameter header + 1 byte parameter itself diff --git a/tests/test_backend.py b/tests/test_backend.py index 690d9ace..0a7a8489 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -19,8 +19,9 @@ class TcHandlerMock(TcHandlerBase): - def __init__(self): + def __init__(self, apid: int): super().__init__() + self.apid = apid self.is_feed_cb_valid = False self.feed_cb_call_count = 0 self.feed_cb_def_proc_count = 0 @@ -56,14 +57,14 @@ def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper): self.send_cb_cmd_path_arg = def_info.cmd_path if def_info.cmd_path == "/ping": self.queue_helper.add_pus_tc( - PusTelecommand(service=17, subservice=1) + PusTelecommand(apid=self.apid, service=17, subservice=1) ) elif def_info.cmd_path == "/event": self.queue_helper.add_pus_tc( - PusTelecommand(service=17, subservice=1) + PusTelecommand(apid=self.apid, service=17, subservice=1) ) self.queue_helper.add_pus_tc( - PusTelecommand(service=5, subservice=1) + PusTelecommand(apid=self.apid, service=5, subservice=1) ) @@ -71,7 +72,8 @@ class TestBackend(TestCase): def setUp(self) -> None: self.com_if = DummyComIF() self.tm_listener = MagicMock(specs=CcsdsTmListener) - self.tc_handler = TcHandlerMock() + self.apid = 0x06 + self.tc_handler = TcHandlerMock(self.apid) self.backend = CcsdsTmtcBackend( tc_mode=TcMode.IDLE, tm_mode=TmMode.IDLE, @@ -130,7 +132,9 @@ def test_basic_ops(self): self.assertEqual(self.tc_handler.send_cb_call_args.com_if, self.com_if) cast_wrapper = self.tc_handler.send_cb_call_args.entry pus_entry = cast_wrapper.to_pus_tc_entry() - self.assertEqual(pus_entry.pus_tc, PusTelecommand(service=17, subservice=1)) + self.assertEqual( + pus_entry.pus_tc, PusTelecommand(apid=self.apid, service=17, subservice=1) + ) self.backend.close_com_if() self.assertFalse(self.com_if.is_open()) @@ -190,5 +194,6 @@ def _check_tc_req_recvd(self, service: int, subservice: int): cast_wrapper = self.tc_handler.send_cb_call_args.entry pus_entry = cast_wrapper.to_pus_tc_entry() self.assertEqual( - pus_entry.pus_tc, PusTelecommand(service=service, subservice=subservice) + pus_entry.pus_tc, + PusTelecommand(apid=self.apid, service=service, subservice=subservice), ) diff --git a/tests/test_printer.py b/tests/test_printer.py index d41eb2bd..812251c6 100644 --- a/tests/test_printer.py +++ b/tests/test_printer.py @@ -21,6 +21,7 @@ # TODO: Use temp files to test loggers? class TestPrintersLoggers(TestCase): def setUp(self): + self.apid = 0x07 self.log_path = Path(LOG_DIR) if not self.log_path.exists(): self.log_path.mkdir() @@ -34,8 +35,9 @@ def test_pus_loggers(self): pus_tc = create_service_17_ping_command() raw_tmtc_log.log_tc(pus_tc) pus_tm = Service1Tm( + apid=self.apid, subservice=Subservice.TM_START_SUCCESS, - time_provider=CdsShortTimestamp.from_now(), + timestamp=CdsShortTimestamp.now().pack(), verif_params=VerificationParams( req_id=RequestId(pus_tc.packet_id, pus_tc.packet_seq_control) ), diff --git a/tests/test_pus_verif_log.py b/tests/test_pus_verif_log.py index 72790270..7529c98d 100644 --- a/tests/test_pus_verif_log.py +++ b/tests/test_pus_verif_log.py @@ -24,6 +24,7 @@ class TestPusVerifLog(TestCase): def setUp(self) -> None: + self.apid = 0x02 self.log_file_name = RegularTmtcLogWrapper.get_current_tmtc_file_name() self.logger = logging.getLogger(__name__) add_colorlog_console_logger(self.logger) @@ -39,11 +40,12 @@ def test_console_log_success_without_colors(self): def _test_success(self, wrapper: VerificationWrapper): verificator = wrapper.verificator - tc = PusTelecommand(service=17, subservice=1, seq_count=0) + tc = PusTelecommand(apid=self.apid, service=17, subservice=1, seq_count=0) verificator.add_tc(tc) srv_1_tm = create_acceptance_success_tm( - tc, time_provider=CdsShortTimestamp.empty() + apid=self.apid, pus_tc=tc, timestamp=CdsShortTimestamp.empty().pack() ) + empty_stamp = CdsShortTimestamp.empty().pack() def generic_checks(): self.assertTrue("acc" in cm.output[0]) @@ -59,7 +61,9 @@ def generic_checks(): f"Request ID {srv_1_tm.tc_req_id.as_u32():#08x}" in cm.output[0] ) generic_checks() - srv_1_tm = create_start_success_tm(tc, time_provider=CdsShortTimestamp.empty()) + srv_1_tm = create_start_success_tm( + apid=self.apid, pus_tc=tc, timestamp=empty_stamp + ) res = verificator.add_tm(srv_1_tm) with self.assertLogs(self.logger) as cm: wrapper.log_to_console(srv_1_tm, res) @@ -69,7 +73,10 @@ def generic_checks(): ) generic_checks() srv_1_tm = create_step_success_tm( - tc, StepId.with_byte_size(1, 1), time_provider=CdsShortTimestamp.empty() + apid=self.apid, + pus_tc=tc, + step_id=StepId.with_byte_size(1, 1), + timestamp=empty_stamp, ) res = verificator.add_tm(srv_1_tm) with self.assertLogs(self.logger) as cm: @@ -80,7 +87,7 @@ def generic_checks(): ) generic_checks() srv_1_tm = create_completion_success_tm( - tc, time_provider=CdsShortTimestamp.empty() + apid=self.apid, pus_tc=tc, timestamp=empty_stamp ) res = verificator.add_tm(srv_1_tm) with self.assertLogs(self.logger) as cm: @@ -102,12 +109,13 @@ def test_console_log_acc_failure_without_colors(self): def _test_acc_failure(self, wrapper: VerificationWrapper): verificator = wrapper.verificator - tc = PusTelecommand(service=17, subservice=1, seq_count=1) + tc = PusTelecommand(apid=self.apid, service=17, subservice=1, seq_count=1) verificator.add_tc(tc) srv_1_tm = create_acceptance_failure_tm( - tc, + apid=self.apid, + pus_tc=tc, failure_notice=FailureNotice(code=ErrorCode(pfc=8, val=1), data=bytes()), - time_provider=CdsShortTimestamp.empty(), + timestamp=CdsShortTimestamp.empty().pack(), ) res = verificator.add_tm(srv_1_tm) # TODO: Use self.assertLogs here instead @@ -116,20 +124,22 @@ def _test_acc_failure(self, wrapper: VerificationWrapper): def test_console_log_start_failure(self): wrapper = VerificationWrapper(PusVerificator(), self.logger, None) verificator = wrapper.verificator - tc = PusTelecommand(service=17, subservice=1, seq_count=2) + tc = PusTelecommand(apid=self.apid, service=17, subservice=1, seq_count=2) verificator.add_tc(tc) srv_1_tm = create_acceptance_failure_tm( - tc, + apid=self.apid, + pus_tc=tc, failure_notice=FailureNotice(code=ErrorCode(pfc=8, val=1), data=bytes()), - time_provider=CdsShortTimestamp.empty(), + timestamp=CdsShortTimestamp.empty().pack(), ) res = verificator.add_tm(srv_1_tm) # TODO: Use self.assertLogs here instead wrapper.log_to_console(srv_1_tm, res) srv_1_tm = create_start_failure_tm( - tc, + apid=self.apid, + pus_tc=tc, failure_notice=FailureNotice(code=ErrorCode(pfc=8, val=1), data=bytes()), - time_provider=CdsShortTimestamp.empty(), + timestamp=CdsShortTimestamp.empty().pack(), ) res = verificator.add_tm(srv_1_tm) # TODO: Use self.assertLogs here instead @@ -139,23 +149,28 @@ def test_file_logger(self): tmtc_logger = RegularTmtcLogWrapper(file_name=self.log_file_name) wrapper = VerificationWrapper(PusVerificator(), None, tmtc_logger.logger) verificator = wrapper.verificator - tc = PusTelecommand(service=17, subservice=1, seq_count=0) + tc = PusTelecommand(apid=self.apid, service=17, subservice=1, seq_count=0) verificator.add_tc(tc) srv_1_tm = create_acceptance_success_tm( - tc, time_provider=CdsShortTimestamp.empty() + apid=self.apid, pus_tc=tc, timestamp=CdsShortTimestamp.empty().pack() ) res = verificator.add_tm(srv_1_tm) wrapper.log_to_file(srv_1_tm, res) - srv_1_tm = create_start_success_tm(tc, time_provider=CdsShortTimestamp.empty()) + srv_1_tm = create_start_success_tm( + apid=self.apid, pus_tc=tc, timestamp=CdsShortTimestamp.empty().pack() + ) res = verificator.add_tm(srv_1_tm) wrapper.log_to_file(srv_1_tm, res) srv_1_tm = create_step_success_tm( - tc, StepId.with_byte_size(1, 1), time_provider=CdsShortTimestamp.empty() + apid=self.apid, + pus_tc=tc, + step_id=StepId.with_byte_size(1, 1), + timestamp=CdsShortTimestamp.empty().pack(), ) res = verificator.add_tm(srv_1_tm) wrapper.log_to_file(srv_1_tm, res) srv_1_tm = create_completion_success_tm( - tc, time_provider=CdsShortTimestamp.empty() + apid=self.apid, pus_tc=tc, timestamp=CdsShortTimestamp.empty().pack() ) res = verificator.add_tm(srv_1_tm) wrapper.log_to_file(srv_1_tm, res) diff --git a/tests/test_queue.py b/tests/test_queue.py index bf73bbe2..efd92c8b 100644 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -22,6 +22,7 @@ class TestTcQueue(TestCase): def setUp(self) -> None: + self.apid = 0x11 self.queue_wrapper = QueueWrapper( info=TreeCommandingProcedure.empty(), queue=deque() ) @@ -33,7 +34,7 @@ def setUp(self) -> None: default_pus_apid=None, pus_verificator=None, ) - self.pus_cmd = PusTelecommand(service=17, subservice=1) + self.pus_cmd = PusTelecommand(apid=self.apid, service=17, subservice=1) def test_wait_entry(self): self.queue_helper.add_wait(timedelta(seconds=2)) @@ -71,7 +72,7 @@ def test_faulty_cast(self): cast_wrapper.to_wait_entry() def test_multi_entry(self): - pus_cmd = PusTelecommand(service=17, subservice=1) + pus_cmd = PusTelecommand(apid=self.apid, service=17, subservice=1) self.queue_helper.add_pus_tc(pus_cmd) self.assertEqual(len(self.queue_wrapper.queue), 1) self.queue_helper.add_log_cmd("Test String") diff --git a/tests/test_seq_sender.py b/tests/test_seq_sender.py index aa08c850..211615ed 100644 --- a/tests/test_seq_sender.py +++ b/tests/test_seq_sender.py @@ -14,6 +14,7 @@ class TestSendReceive(TestCase): def setUp(self) -> None: + self.apid = 0x22 self.queue_wrapper = QueueWrapper.empty() self.queue_helper = DefaultPusQueueHelper( self.queue_wrapper, @@ -110,7 +111,7 @@ def test_with_wait_entry(self): def test_interpacket_delay(self): delay_ms = 20 inter_packet_delay = timedelta(milliseconds=delay_ms) - ping_cmd = PusTelecommand(service=17, subservice=1) + ping_cmd = PusTelecommand(apid=self.apid, service=17, subservice=1) self.queue_helper.add_pus_tc(ping_cmd) self.queue_helper.add_packet_delay_ms(delay_ms) self.queue_helper.add_ccsds_tc(ping_cmd.to_space_packet()) diff --git a/tests/test_tm_handler.py b/tests/test_tm_handler.py index 37462438..778fc788 100644 --- a/tests/test_tm_handler.py +++ b/tests/test_tm_handler.py @@ -28,6 +28,9 @@ def handle_tm(self, packet: bytes, user_args: any): class TestTmHandler(TestCase): + def setUp(self) -> None: + self.apid = 0x33 + def test_basic(self): tm_handler = ApidHandler(0x01) com_if = MagicMock(specs=ComInterface) @@ -39,10 +42,16 @@ def test_basic(self): self.assertEqual(handled_packets, 0) self.assertTrue(ccsds_handler.has_apid(0x01)) tm0_raw = PusTelemetry( - service=1, subservice=12, apid=0x01, time_provider=CdsShortTimestamp.empty() + service=1, + subservice=12, + apid=0x01, + timestamp=CdsShortTimestamp.empty().pack(), ).pack() tm1_raw = PusTelemetry( - service=5, subservice=1, apid=0x01, time_provider=CdsShortTimestamp.empty() + service=5, + subservice=1, + apid=0x01, + timestamp=CdsShortTimestamp.empty().pack(), ).pack() com_if.receive.return_value = [tm0_raw] handled_packets = tm_listener.operation(com_if) @@ -58,7 +67,10 @@ def test_basic(self): self.assertEqual(tm_handler.packet_queue.pop(), tm0_raw) self.assertEqual(tm_handler.packet_queue.pop(), tm1_raw) unknown_apid = PusTelemetry( - service=1, subservice=12, apid=0x02, time_provider=CdsShortTimestamp.empty() + service=1, + subservice=12, + apid=0x02, + timestamp=CdsShortTimestamp.empty().pack(), ).pack() com_if.receive.return_value = [unknown_apid] handled_packets = tm_listener.operation(com_if) diff --git a/tests/tm/test_srv1.py b/tests/tm/test_srv1.py index 249ec4ce..8ca11ed8 100644 --- a/tests/tm/test_srv1.py +++ b/tests/tm/test_srv1.py @@ -1,7 +1,7 @@ import struct from unittest import TestCase -from spacepackets.ecss import RequestId, PusTelecommand, PacketFieldU8 +from spacepackets.ecss import RequestId, PusTc, PacketFieldU8 from spacepackets.ecss.pus_1_verification import ( Service1Tm, Subservice, @@ -13,7 +13,8 @@ class TestVerif1TmWrapper(TestCase): def setUp(self) -> None: - self.ping_tc = PusTelecommand(service=17, subservice=1) + self.apid = 0x01 + self.ping_tc = PusTc(apid=self.apid, service=17, subservice=1) pass def test_basic(self): @@ -25,8 +26,9 @@ def test_basic(self): code=PacketFieldU8(1), data=context_param_1 + context_param_2 ) service_1_tm = Service1Tm( + apid=self.apid, subservice=Subservice.TM_START_FAILURE, - time_provider=None, + timestamp=bytes(), verif_params=VerificationParams( step_id=None, req_id=RequestId.from_pus_tc(self.ping_tc), diff --git a/tests/tm/test_srv17.py b/tests/tm/test_srv17.py index 73d3995a..13741d37 100644 --- a/tests/tm/test_srv17.py +++ b/tests/tm/test_srv17.py @@ -7,27 +7,24 @@ class TestTelemetry(TestCase): def setUp(self) -> None: + self.apid = 0xEF self.pus_17_telemetry = Service17Tm( + apid=self.apid, subservice=1, ssc=36, - time_provider=CdsShortTimestamp.from_now(), - apid=0xEF, + timestamp=CdsShortTimestamp.now().pack(), ) self.pus_17_raw = self.pus_17_telemetry.pack() def test_generic_pus_c(self): def tm_func(raw_telemetry: bytearray): - return Service17Tm.unpack( - data=raw_telemetry, time_reader=CdsShortTimestamp.empty() - ) + return Service17Tm.unpack(data=raw_telemetry, timestamp_len=7) self.assertRaises(ValueError, tm_func, bytearray()) self.assertRaises(ValueError, tm_func, None) - pus_17_telemetry = Service17Tm.unpack( - data=self.pus_17_raw, time_reader=CdsShortTimestamp.empty() - ) + pus_17_telemetry = Service17Tm.unpack(data=self.pus_17_raw, timestamp_len=7) self.assertTrue(pus_17_telemetry.service == 17) self.assertTrue(pus_17_telemetry.apid == 0xEF) self.assertTrue(pus_17_telemetry.subservice == 1) diff --git a/tests/tm/test_srv20.py b/tests/tm/test_srv20.py index 17441052..e9f6e0bf 100644 --- a/tests/tm/test_srv20.py +++ b/tests/tm/test_srv20.py @@ -17,12 +17,12 @@ def setUp(self): ) self.tm = Service20FsfwTm( subservice=CustomSubservice.TM_DUMP_REPLY, - time_provider=None, + timestamp=bytes(), source_data=self.boolean_param.pack(), ) def test_state(self): - self.assertEqual(self.tm.time_provider, None) + self.assertEqual(self.tm.timestamp, bytes()) self.assertEqual(self.tm.service, PusService.S20_PARAMETER) self.assertEqual(self.tm.subservice, CustomSubservice.TM_DUMP_REPLY) self.assertEqual(self.tm.source_data, self.boolean_param.pack()) @@ -30,7 +30,7 @@ def test_state(self): def test_unpack(self): tm_raw = self.tm.pack() - tm_unpacked = Service20FsfwTm.unpack(raw_telemetry=tm_raw, time_reader=None) + tm_unpacked = Service20FsfwTm.unpack(raw_telemetry=tm_raw, timestamp_len=0) self.assertEqual(self.tm, tm_unpacked) param_unpacked = Parameter.unpack(tm_unpacked.source_data) self.assertEqual(param_unpacked, self.boolean_param) diff --git a/tests/tm/test_srv200.py b/tests/tm/test_srv200.py index b8e1b1b2..93959c4b 100644 --- a/tests/tm/test_srv200.py +++ b/tests/tm/test_srv200.py @@ -12,6 +12,6 @@ def setUp(self): self.srv_200_tm = PusTelemetry( service=200, subservice=Subservice.TM_MODE_REPLY, - time_provider=CdsShortTimestamp.empty(), + timestamp=CdsShortTimestamp.empty().pack(), apid=0x02, ) diff --git a/tests/tm/test_srv5.py b/tests/tm/test_srv5.py index a08da5b9..843f4b38 100644 --- a/tests/tm/test_srv5.py +++ b/tests/tm/test_srv5.py @@ -5,14 +5,16 @@ class TestSrv5Tm(TestCase): def setUp(self): + self.apid = 0x08 self.obj_id = bytes([0x00, 0x01, 0x02, 0x03]) self.event_def = EventDefinition( event_id=5, reporter_id=self.obj_id, param1=22, param2=942 ) self.srv5_tm = Service5Tm( + apid=self.apid, subservice=Subservice.TM_INFO_EVENT, event=self.event_def, - time_provider=None, + timestamp=bytes(), ) def test_basic(self): @@ -34,6 +36,6 @@ def test_packed(self): def test_unpack(self): raw_tm = self.srv5_tm.pack() - unpacked = Service5Tm.unpack(raw_tm, None) + unpacked = Service5Tm.unpack(raw_tm, 0) self.assertEqual(self.srv5_tm, unpacked) self.assertEqual(unpacked.event_definition, self.event_def) diff --git a/tmtccmd/com/dummy.py b/tmtccmd/com/dummy.py index a5091018..87c8f8c4 100644 --- a/tmtccmd/com/dummy.py +++ b/tmtccmd/com/dummy.py @@ -46,7 +46,7 @@ def generate_reply_package(self): assert self.last_tc is not None if self.last_tc.service == 17: if self.last_tc.subservice == 1: - current_time_stamp = CdsShortTimestamp.from_now() + current_time_stamp = CdsShortTimestamp.now() tm_packer = Service1Tm( subservice=Pus1Subservice.TM_ACCEPTANCE_SUCCESS, apid=self.last_tc.apid, @@ -56,7 +56,7 @@ def generate_reply_package(self): self.last_tc.packet_id, self.last_tc.packet_seq_control ) ), - time_provider=current_time_stamp, + timestamp=current_time_stamp.pack(), ) self.current_ssc += 1 @@ -71,7 +71,7 @@ def generate_reply_package(self): self.last_tc.packet_id, self.last_tc.packet_seq_control ) ), - time_provider=current_time_stamp, + timestamp=current_time_stamp.pack(), ) tm_packet_raw = tm_packer.pack() self.next_telemetry_package.append(tm_packet_raw) @@ -80,7 +80,7 @@ def generate_reply_package(self): tm_packer = Service17Tm( subservice=Pus17Subservice.TM_REPLY, apid=self.last_tc.apid, - time_provider=current_time_stamp, + timestamp=current_time_stamp.pack(), ) tm_packet_raw = tm_packer.pack() self.next_telemetry_package.append(tm_packet_raw) @@ -95,7 +95,7 @@ def generate_reply_package(self): self.last_tc.packet_id, self.last_tc.packet_seq_control ) ), - time_provider=current_time_stamp, + timestamp=current_time_stamp.pack(), ) tm_packet_raw = tm_packer.pack() self.next_telemetry_package.append(tm_packet_raw) diff --git a/tmtccmd/pus/tc/s20_fsfw_param.py b/tmtccmd/pus/tc/s20_fsfw_param.py index 9e249e4a..98326ebd 100644 --- a/tmtccmd/pus/tc/s20_fsfw_param.py +++ b/tmtccmd/pus/tc/s20_fsfw_param.py @@ -31,38 +31,33 @@ ) -def create_load_param_cmd(parameter: Parameter) -> PusTelecommand: +def create_load_param_cmd(apid: int, parameter: Parameter) -> PusTelecommand: return PusTelecommand( + apid=apid, service=PusService.S20_PARAMETER, subservice=CustomSubservice.TC_LOAD, app_data=parameter.pack(), ) -def create_dump_param_cmd(param_fsfw_id: FsfwParamId) -> PusTelecommand: +def create_dump_param_cmd(apid: int, param_fsfw_id: FsfwParamId) -> PusTelecommand: return PusTelecommand( + apid=apid, service=PusService.S20_PARAMETER, subservice=CustomSubservice.TC_LOAD, app_data=param_fsfw_id.pack(), ) -def create_load_param_cmd_from_raw(parameter_raw: bytes) -> PusTelecommand: +def create_load_param_cmd_from_raw(apid: int, parameter_raw: bytes) -> PusTelecommand: return PusTelecommand( + apid=apid, service=PusService.S20_PARAMETER, subservice=CustomSubservice.TC_LOAD, app_data=parameter_raw, ) -@deprecated( - version="4.0.0a3", - reason="use crate_fsfw_load_param_cmd instead", -) -def pack_fsfw_load_param_cmd(app_data: bytes) -> PusTelecommand: - return create_load_param_cmd(app_data) - - @deprecated( version="3.1.0", reason="use create_scalar_boolean_parameter instead", diff --git a/tmtccmd/pus/tm/s20_fsfw_param.py b/tmtccmd/pus/tm/s20_fsfw_param.py index 97c36ca7..8fcf956b 100644 --- a/tmtccmd/pus/tm/s20_fsfw_param.py +++ b/tmtccmd/pus/tm/s20_fsfw_param.py @@ -1,10 +1,7 @@ from __future__ import annotations -from typing import Optional - from spacepackets import SpacePacketHeader from spacepackets.ccsds.spacepacket import PacketId, PacketSeqCtrl -from spacepackets.ccsds.time import CdsShortTimestamp, CcsdsTimeProvider from spacepackets.ecss import ( Ptc, PusTelemetry, @@ -62,14 +59,14 @@ def __init__( self, subservice: int, source_data: bytes, - time_provider: Optional[CcsdsTimeProvider], + timestamp: bytes, apid: int = 0, ): self.pus_tm = PusTelemetry( service=PusService.S20_PARAMETER, subservice=subservice, source_data=source_data, - time_provider=time_provider, + timestamp=timestamp, apid=apid, ) @@ -83,12 +80,10 @@ def __common_checks(tm: PusTelemetry): ) @classmethod - def unpack( - cls, raw_telemetry: bytes, time_reader: Optional[CcsdsTimeProvider] - ) -> Service20FsfwTm: + def unpack(cls, raw_telemetry: bytes, timestamp_len: int) -> Service20FsfwTm: instance = cls.empty() instance.pus_tm = PusTelemetry.unpack( - data=raw_telemetry, time_reader=time_reader + data=raw_telemetry, timestamp_len=timestamp_len ) Service20FsfwTm.__common_checks(instance.pus_tm) return instance @@ -104,8 +99,8 @@ def pack(self) -> bytearray: return self.pus_tm.pack() @property - def time_provider(self) -> Optional[CcsdsTimeProvider]: - return self.pus_tm.time_provider + def timestamp(self) -> bytes: + return self.pus_tm.timestamp @property def object_id(self) -> bytes: @@ -127,9 +122,9 @@ def source_data(self) -> bytes: def empty(cls) -> Service20FsfwTm: return cls( subservice=0, - time_provider=CdsShortTimestamp.empty(), apid=0, source_data=bytes([0, 0, 0, 0]), + timestamp=bytes(), ) @property diff --git a/tmtccmd/pus/tm/s5_fsfw_event.py b/tmtccmd/pus/tm/s5_fsfw_event.py index cc8012cf..91956539 100644 --- a/tmtccmd/pus/tm/s5_fsfw_event.py +++ b/tmtccmd/pus/tm/s5_fsfw_event.py @@ -5,11 +5,9 @@ import dataclasses import struct -from typing import Optional from spacepackets import SpacePacketHeader from spacepackets.ccsds.spacepacket import PacketId, PacketSeqCtrl -from spacepackets.ccsds.time import CcsdsTimeProvider from spacepackets.ecss.defs import PusService from spacepackets.ecss.pus_5_event import Subservice from spacepackets.ecss.tm import CdsShortTimestamp, AbstractPusTm, PusTelemetry @@ -52,11 +50,11 @@ def from_bytes(cls, data: bytes) -> EventDefinition: class Service5Tm(AbstractPusTm): def __init__( self, + apid: int, subservice: Subservice, event: EventDefinition, - time_provider: Optional[CdsShortTimestamp], + timestamp: bytes, ssc: int = 0, - apid: int = -1, packet_version: int = 0b000, space_time_ref: int = 0b0000, destination_id: int = 0, @@ -68,7 +66,7 @@ def __init__( self.pus_tm = PusTelemetry( service=PusService.S5_EVENT, subservice=subservice, - time_provider=time_provider, + timestamp=timestamp, seq_count=ssc, source_data=event.pack(), apid=apid, @@ -82,8 +80,8 @@ def sp_header(self) -> SpacePacketHeader: return self.pus_tm.space_packet_header @property - def time_provider(self) -> Optional[CcsdsTimeProvider]: - return self.pus_tm.time_provider + def timestamp(self) -> bytes: + return self.pus_tm.timestamp def pack(self) -> bytearray: return self.pus_tm.pack() @@ -115,9 +113,10 @@ def source_data(self) -> bytes: @classmethod def __empty(cls) -> Service5Tm: return cls( + apid=0x0, subservice=Subservice.TM_INFO_EVENT, event=EventDefinition.empty(), - time_provider=CdsShortTimestamp.empty(), + timestamp=CdsShortTimestamp.empty().pack(), ) @classmethod @@ -127,11 +126,9 @@ def from_tm(cls, pus_tm: PusTelemetry) -> Service5Tm: return instance @classmethod - def unpack( - cls, data: bytes, time_reader: Optional[CcsdsTimeProvider] - ) -> Service5Tm: + def unpack(cls, data: bytes, timestamp_len: int) -> Service5Tm: instance = cls.__empty() - instance.pus_tm = PusTelemetry.unpack(data=data, time_reader=time_reader) + instance.pus_tm = PusTelemetry.unpack(data=data, timestamp_len=timestamp_len) return instance @property