Skip to content

Commit

Permalink
Merge pull request #162 from robamu-org/prep-v8.1.0
Browse files Browse the repository at this point in the history
prep next version 8.1.0
  • Loading branch information
robamu authored Jan 15, 2025
2 parents a243257 + 69ec450 commit da2fb82
Show file tree
Hide file tree
Showing 121 changed files with 244 additions and 620 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Starting from v4.0.0, this project adheres to [Semantic Versioning](http://semve

# [unreleased]

# [v8.1.0] 2025-01-15

- Drop support for EOL Python 3.8. Minimum supported Python version is now 3.9

# [v8.0.3] 2024-11-08
Expand Down
6 changes: 3 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
from tmtccmd.version import get_version
from importlib.metadata import version

# -- Project information -----------------------------------------------------

project = "tmtccmd"
copyright = "2021-2023, Robin Mueller"
copyright = "2021-2024, Robin Mueller"
author = "Robin Mueller"

# The full version, including alpha/beta/rc tags
version = release = get_version()
release = version = version("tmtccmd")

# -- General configuration ---------------------------------------------------

Expand Down
56 changes: 15 additions & 41 deletions examples/app/tmtcc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
"""Example application for the TMTC Commander"""

import logging
import sys
import time
Expand Down Expand Up @@ -80,9 +81,7 @@ def get_command_definitions(self) -> CmdTreeNode:
root_node = CmdTreeNode.root_node()
root_node.add_child(CmdTreeNode("ping", "Send PUS ping command"))
root_node.add_child(CmdTreeNode("test", "Test Node"))
root_node.children["test"].add_child(
CmdTreeNode("event", "Send PUS event test command")
)
root_node.children["test"].add_child(CmdTreeNode("event", "Send PUS event test command"))
return self.build_more_complex_tree(root_node)

def build_more_complex_tree(self, root_node: CmdTreeNode) -> CmdTreeNode:
Expand All @@ -105,13 +104,9 @@ def build_more_complex_tree(self, root_node: CmdTreeNode) -> CmdTreeNode:
root_node.add_child(CmdTreeNode("eps", "EPS Subsystem"))
root_node["eps"].add_child(CmdTreeNode("pcdu", "PCDU"))
root_node["eps"]["pcdu"].add_child(CmdTreeNode("channel_0_on", "Channel 0 on"))
root_node["eps"]["pcdu"].add_child(
CmdTreeNode("channel_0_off", "Channel 0 off")
)
root_node["eps"]["pcdu"].add_child(CmdTreeNode("channel_0_off", "Channel 0 off"))
root_node["eps"]["pcdu"].add_child(CmdTreeNode("channel_1_on", "Channel 1 on"))
root_node["eps"]["pcdu"].add_child(
CmdTreeNode("channel_1_off", "Channel 1 off")
)
root_node["eps"]["pcdu"].add_child(CmdTreeNode("channel_1_off", "Channel 1 off"))
return root_node

def get_cmd_history(self) -> Optional[History]:
Expand All @@ -137,9 +132,7 @@ def __init__(

def handle_tm(self, packet: bytes, _user_args: Any):
try:
tm_packet = PusTelemetry.unpack(
packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
)
tm_packet = PusTelemetry.unpack(packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
except ValueError as e:
_LOGGER.warning("Could not generate PUS TM object from raw data")
_LOGGER.warning(f"Raw Packet: [{packet.hex(sep=',')}], REPR: {packet!r}")
Expand All @@ -157,39 +150,26 @@ def handle_tm(self, packet: bytes, _user_args: Any):
f" {tm_packet.subservice}] with Request ID"
f" {verif_tm.tc_req_id.as_u32():#08x}"
)
_LOGGER.warning(
f"No matching telecommand found for {verif_tm.tc_req_id}"
)
_LOGGER.warning(f"No matching telecommand found for {verif_tm.tc_req_id}")
else:
self.verif_wrapper.log_to_console(verif_tm, res)
self.verif_wrapper.log_to_file(verif_tm, res)
dedicated_handler = True
if service == 5:
event_tm = Service5Tm.unpack(
packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
)
_LOGGER.info(
f"Received event packet TM [{event_tm.service}, {event_tm.subservice}]"
)
event_tm = Service5Tm.unpack(packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
_LOGGER.info(f"Received event packet TM [{event_tm.service}, {event_tm.subservice}]")
if service == 17:
ping_tm = Service17Tm.unpack(
packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
)
ping_tm = Service17Tm.unpack(packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
dedicated_handler = True
if ping_tm.subservice == 2:
_LOGGER.info("Received Ping Reply TM[17,2]")
else:
_LOGGER.info(
"Received Test Packet with unknown subservice"
f" {tm_packet.subservice}"
"Received Test Packet with unknown subservice" f" {tm_packet.subservice}"
)
if tm_packet is None:
_LOGGER.info(
f"The service {service} is not implemented in Telemetry Factory"
)
tm_packet = PusTelemetry.unpack(
packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
)
_LOGGER.info(f"The service {service} is not implemented in Telemetry Factory")
tm_packet = PusTelemetry.unpack(packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
# TODO: Insert this into a DB instead. Maybe use sqlite for first variant.
# self.raw_logger.log_tm(tm_packet)
if not dedicated_handler:
Expand Down Expand Up @@ -221,9 +201,7 @@ def send_cb(self, send_params: SendCbParams):
if entry_helper.is_tc:
if entry_helper.entry_type == TcQueueEntryType.PUS_TC:
pus_tc_wrapper = entry_helper.to_pus_tc_entry()
pus_tc_wrapper.pus_tc.seq_count = (
self.seq_count_provider.get_and_increment()
)
pus_tc_wrapper.pus_tc.seq_count = self.seq_count_provider.get_and_increment()
self.verif_wrapper.add_tc(pus_tc_wrapper.pus_tc)
raw_tc = pus_tc_wrapper.pus_tc.pack()
_LOGGER.info(f"Sending {pus_tc_wrapper.pus_tc}")
Expand Down Expand Up @@ -253,9 +231,7 @@ def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
elif cmd_path_list[0] == "test":
if cmd_path_list[1] == "event":
return self.queue_helper.add_pus_tc(
PusTelecommand(
apid=EXAMPLE_PUS_APID, service=17, subservice=128
)
PusTelecommand(apid=EXAMPLE_PUS_APID, service=17, subservice=128)
)


Expand Down Expand Up @@ -289,9 +265,7 @@ def main(): # noqa: C901
tmtc_logger = RegularTmtcLogWrapper()
printer = FsfwTmTcPrinter(tmtc_logger.logger)
verificator = PusVerificator()
verification_wrapper = VerificationWrapper(
verificator, _LOGGER, printer.file_logger
)
verification_wrapper = VerificationWrapper(verificator, _LOGGER, printer.file_logger)
# Create primary TM handler and add it to the CCSDS Packet Handler
tm_handler = PusTmHandler(verification_wrapper, printer)
ccsds_handler = CcsdsTmHandler(generic_handler=None)
Expand Down
12 changes: 7 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ dependencies = [
"dle-encoder~=0.2.3",
"spacepackets>=0.24.0, <=0.25",
"cfdp-py>=0.1.1, <=0.4",
# "cfdp-py @ git+https://github.com/us-irs/cfdp-py.git@main"
]

[project.optional-dependencies]
Expand All @@ -53,10 +52,13 @@ test = [
[project.urls]
"Homepage" = "https://github.com/robamu-org/tmtccmd"

# Auto-Discovery is problematic for some reason, so use custom-discovery
[tool.setuptools.packages]
find = {}

[tool.ruff]
exclude = [
".git",
"venv",
"docs"
]
line-length = 100
[tool.ruff.lint]
ignore = ["E501"]
[tool.ruff.lint.extend-per-file-ignores]
Expand Down
7 changes: 3 additions & 4 deletions release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ The steps shown here are for Ubuntu/MacOS.
3. Update `CHANGELOG.md`: Convert `unreleased` section into version section
with date and new `unreleased`section.
4. Run tests with `pytest .`
5. Run auto-formatter with `black .`
5. Run auto-formatter with `ruff format .`
6. Run linter with `ruff check .`
7. Wait for CI/CD results. This also runs the tests on different
operating systems
7. Wait for CI/CD results. This also runs the tests on different operating systems

# Release

1. Delete existing distributions: `rm dist/*`
2. Build the package. Requires the `build` package: `python3 -m build`
2. Build the package. Requires the `build` package: `python3 -m build .` or `pyproject-build .`
3. Upload the source and build distribution: `python3 -m twine upload dist/*`. You might require
a PyPI upload token to do this.

Expand Down
24 changes: 6 additions & 18 deletions tmtccmd/__init__.py → src/tmtccmd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ def __start_tmtc_commander_qt_gui(
from PyQt6.QtWidgets import QApplication

if not __SETUP_WAS_CALLED:
__TMTCCMD_LOGGER.warning(
"setup_tmtccmd was not called first. Call it first"
)
__TMTCCMD_LOGGER.warning("setup_tmtccmd was not called first. Call it first")
sys.exit(1)
app = QApplication([app_name])
if tmtc_frontend is None:
Expand Down Expand Up @@ -199,19 +197,13 @@ def create_default_tmtc_backend(
tm_handler = cast(CcsdsTmHandler, tm_handler)
com_if = setup_wrapper.params.com_if
if com_if is None:
com_if = setup_wrapper.hook_obj.get_communication_interface(
setup_wrapper.params.com_if_id
)
com_if = setup_wrapper.hook_obj.get_communication_interface(setup_wrapper.params.com_if_id)
tm_listener = CcsdsTmListener(tm_handler)
mode_wrapper = ModeWrapper()
backend_mode_conversion(setup_wrapper.params.mode, mode_wrapper)
if setup_wrapper.params.mode == CoreModeConverter.get_str(
CoreModeList.LISTENER_MODE
):
if setup_wrapper.params.mode == CoreModeConverter.get_str(CoreModeList.LISTENER_MODE):
print("-- Backend Listener Mode --")
elif setup_wrapper.params.mode == CoreModeConverter.get_str(
CoreModeList.ONE_QUEUE_MODE
):
elif setup_wrapper.params.mode == CoreModeConverter.get_str(CoreModeList.ONE_QUEUE_MODE):
print("-- One Queue Mode --")
elif setup_wrapper.params.mode == CoreModeConverter.get_str(
CoreModeList.MULTI_INTERACTIVE_QUEUE_MODE
Expand All @@ -228,16 +220,12 @@ def create_default_tmtc_backend(
)
if setup_wrapper.params.backend_params.listener:
tmtc_backend.keep_listener_mode = True
tmtc_backend.inter_cmd_delay = timedelta(
seconds=setup_wrapper.params.cmd_params.delay
)
tmtc_backend.inter_cmd_delay = timedelta(seconds=setup_wrapper.params.cmd_params.delay)
if init_procedure is not None:
tmtc_backend.current_procedure = init_procedure.procedure
return tmtc_backend


def setup_backend_def_procedure(
backend: CcsdsTmtcBackend, tmtc_params: TreeCommandingProcedure
):
def setup_backend_def_procedure(backend: CcsdsTmtcBackend, tmtc_params: TreeCommandingProcedure):
assert tmtc_params.cmd_path is not None
backend.current_procedure = TreeCommandingProcedure(tmtc_params.cmd_path)
File renamed without changes.
4 changes: 1 addition & 3 deletions tmtccmd/cfdp/request.py → src/tmtccmd/cfdp/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,5 @@ def request(self) -> CfdpRequestType:

def to_put_request(self) -> PutRequestCfgWrapper:
if self.base.req_type != CfdpRequestType.PUT:
raise TypeError(
f"Request is not a {PutRequestCfgWrapper.__name__}: {self.base!r}"
)
raise TypeError(f"Request is not a {PutRequestCfgWrapper.__name__}: {self.base!r}")
return cast(PutRequestCfgWrapper, self.base)
1 change: 1 addition & 0 deletions tmtccmd/com/__init__.py → src/tmtccmd/com/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
"""Communication module. Provides generic abstraction for communication and commonly used
concrete implementations."""

from abc import abstractmethod, ABC
from typing import Any, List, Optional

Expand Down
12 changes: 3 additions & 9 deletions tmtccmd/com/dummy.py → src/tmtccmd/com/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ def generate_reply_package(self):
apid=self.last_tc.apid,
seq_count=self.current_ssc,
verif_params=VerificationParams(
req_id=RequestId(
self.last_tc.packet_id, self.last_tc.packet_seq_control
)
req_id=RequestId(self.last_tc.packet_id, self.last_tc.packet_seq_control)
),
timestamp=current_time_stamp.pack(),
)
Expand All @@ -67,9 +65,7 @@ def generate_reply_package(self):
apid=self.last_tc.apid,
seq_count=self.current_ssc,
verif_params=VerificationParams(
req_id=RequestId(
self.last_tc.packet_id, self.last_tc.packet_seq_control
)
req_id=RequestId(self.last_tc.packet_id, self.last_tc.packet_seq_control)
),
timestamp=current_time_stamp.pack(),
)
Expand All @@ -91,9 +87,7 @@ def generate_reply_package(self):
apid=self.last_tc.apid,
seq_count=self.current_ssc,
verif_params=VerificationParams(
req_id=RequestId(
self.last_tc.packet_id, self.last_tc.packet_seq_control
)
req_id=RequestId(self.last_tc.packet_id, self.last_tc.packet_seq_control)
),
timestamp=current_time_stamp.pack(),
)
Expand Down
8 changes: 2 additions & 6 deletions tmtccmd/com/qemu.py → src/tmtccmd/com/qemu.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@ def id(self) -> str:
def set_fixed_frame_settings(self, serial_frame_size: int):
self.serial_frame_size = serial_frame_size

def set_dle_settings(
self, dle_queue_len: int, dle_max_frame: int, dle_timeout: float
):
def set_dle_settings(self, dle_queue_len: int, dle_max_frame: int, dle_timeout: float):
self.dle_queue_len = dle_queue_len
self.dle_max_frame = dle_max_frame
self.dle_timeout = dle_timeout
Expand Down Expand Up @@ -240,9 +238,7 @@ async def poll_dle_packets(self):
# handle erroneous data
print(data)
# It is assumed that all packets are DLE encoded, so throw it away for now.
_LOGGER.info(
"Non DLE-Encoded data with length " + str(len(data) + 1) + " found.."
)
_LOGGER.info("Non DLE-Encoded data with length " + str(len(data) + 1) + " found..")


class QmpException(Exception):
Expand Down
9 changes: 2 additions & 7 deletions tmtccmd/com/ser_utils.py → src/tmtccmd/com/ser_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ def __try_com_port_load(json_obj) -> Tuple[bool, str]:
return try_hint, com_port


def __try_hint_handling(
json_cfg_path: str, reconfig_com_port: bool, json_obj
) -> Tuple[bool, str]:
def __try_hint_handling(json_cfg_path: str, reconfig_com_port: bool, json_obj) -> Tuple[bool, str]:
reconfig_hint = False
try:
hint = json_obj[JsonKeyNames.SERIAL_HINT.value]
Expand Down Expand Up @@ -191,10 +189,7 @@ def prompt_com_port() -> str:
print("{}: {} [{}]".format(port, desc, hwid))
else:
if not check_port_validity(com_port):
print(
"Serial port not in list of available serial ports. Try again?"
" ([Y]/n)"
)
print("Serial port not in list of available serial ports. Try again?" " ([Y]/n)")
try_again = input()
if try_again.lower() in ["y", "yes", ""]:
continue
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ def open(self, args: any = None) -> None:
"""Spins up a receiver thread to permanently check for new COBS encoded packets."""
super().open_port()
self.__polling_shutdown.clear()
self.__reception_thread = threading.Thread(
target=self.__poll_cobs_packets, daemon=True
)
self.__reception_thread = threading.Thread(target=self.__poll_cobs_packets, daemon=True)
self.__reception_thread.start()

def is_open(self) -> bool:
Expand Down
8 changes: 2 additions & 6 deletions tmtccmd/com/serial_dle.py → src/tmtccmd/com/serial_dle.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ def open(self, args: any = None) -> None:
"""Spins up a receiver thread to permanently check for new DLE encoded packets."""
super().open_port()
self.__polling_shutdown.clear()
self.__reception_thread = threading.Thread(
target=self.__poll_dle_packets, daemon=True
)
self.__reception_thread = threading.Thread(target=self.__poll_dle_packets, daemon=True)
self.__reception_thread.start()

def __poll_dle_packets(self):
Expand Down Expand Up @@ -97,9 +95,7 @@ def receive(self, parameters: any = 0) -> List[bytes]:
packet_list = []
while self.__reception_buffer:
data = self.__reception_buffer.pop()
dle_retval, decoded_packet, read_len = self.__encoder.decode(
source_packet=data
)
dle_retval, decoded_packet, read_len = self.__encoder.decode(source_packet=data)
if dle_retval == DleErrorCodes.OK:
packet_list.append(decoded_packet)
else:
Expand Down
Loading

0 comments on commit da2fb82

Please sign in to comment.