update common_tmtc
This commit is contained in:
parent
59a80fed91
commit
d308899920
@ -0,0 +1,6 @@
|
||||
SW_NAME = "fsfw-tmtc"
|
||||
SW_VERSION = 1
|
||||
SW_SUBVERSION = 4
|
||||
SW_SUBSUBVERSION = 0
|
||||
|
||||
__version__ = "1.4.0"
|
@ -1 +1,2 @@
|
||||
PUS_APID = 0xEF
|
||||
TM_SP_IDS = ((0x08 << 8) | PUS_APID,)
|
||||
|
@ -1,76 +1,34 @@
|
||||
import argparse
|
||||
from typing import Dict, Tuple, Optional
|
||||
from typing import Dict, Optional
|
||||
|
||||
from spacepackets.ecss.conf import PusVersion
|
||||
|
||||
from tmtccmd.com_if.com_interface_base import CommunicationInterface
|
||||
from tmtccmd.config.definitions import ServiceOpCodeDictT
|
||||
from tmtccmd.config.hook import TmTcHookBase
|
||||
from tmtccmd.core.backend import TmTcHandler
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.tm.service_3_base import Service3Base
|
||||
from tmtccmd.utility.tmtc_printer import TmTcPrinter
|
||||
|
||||
from common_tmtc.config.definitions import PUS_APID
|
||||
from tmtccmd.utility.retval import RetvalDictT
|
||||
|
||||
from common_tmtc.config.definitions import TM_SP_IDS
|
||||
from common_tmtc.pus_tc.cmd_definitions import get_fsfw_service_op_code_dict
|
||||
|
||||
|
||||
class FsfwHookBase(TmTcHookBase):
|
||||
def get_json_config_file_path(self) -> str:
|
||||
return "config/tmtc_config.json"
|
||||
def __init__(self, json_cfg_path: str):
|
||||
super().__init__(json_cfg_path=json_cfg_path)
|
||||
|
||||
def get_service_op_code_dictionary(self) -> ServiceOpCodeDictT:
|
||||
from tmtccmd.config.globals import (
|
||||
get_default_service_op_code_dict,
|
||||
add_service_op_code_entry,
|
||||
add_op_code_entry,
|
||||
OpCodeDictKeys,
|
||||
)
|
||||
|
||||
def_dict = get_default_service_op_code_dict()
|
||||
op_code = dict()
|
||||
add_op_code_entry(op_code_dict=op_code, keys="test", info="Mode CMD Test")
|
||||
add_op_code_entry(
|
||||
op_code_dict=op_code,
|
||||
keys=["0", "asm_to_normal"],
|
||||
info="Command test assembly to normal mode",
|
||||
options={OpCodeDictKeys.TIMEOUT: 6.0},
|
||||
)
|
||||
add_service_op_code_entry(
|
||||
srv_op_code_dict=def_dict,
|
||||
name="200",
|
||||
info="Mode MGMT",
|
||||
op_code_entry=op_code,
|
||||
)
|
||||
return def_dict
|
||||
|
||||
def add_globals_pre_args_parsing(self, gui: bool = False):
|
||||
from tmtccmd.config.globals import set_default_globals_pre_args_parsing
|
||||
|
||||
set_default_globals_pre_args_parsing(
|
||||
gui=gui,
|
||||
pus_tm_version=PusVersion.PUS_C,
|
||||
pus_tc_version=PusVersion.PUS_C,
|
||||
tc_apid=PUS_APID,
|
||||
tm_apid=PUS_APID,
|
||||
)
|
||||
|
||||
def add_globals_post_args_parsing(self, args: argparse.Namespace):
|
||||
from tmtccmd.config.globals import set_default_globals_post_args_parsing
|
||||
|
||||
set_default_globals_post_args_parsing(
|
||||
args=args, json_cfg_path=self.get_json_config_file_path()
|
||||
)
|
||||
return get_fsfw_service_op_code_dict()
|
||||
|
||||
def assign_communication_interface(
|
||||
self, com_if_key: str, tmtc_printer: TmTcPrinter
|
||||
self, com_if_key: str
|
||||
) -> Optional[CommunicationInterface]:
|
||||
from tmtccmd.config.com_if import create_communication_interface_default
|
||||
|
||||
return create_communication_interface_default(
|
||||
com_if_key=com_if_key,
|
||||
tmtc_printer=tmtc_printer,
|
||||
json_cfg_path=self.get_json_config_file_path(),
|
||||
space_packet_ids=(0x08EF,),
|
||||
json_cfg_path=self.json_cfg_path,
|
||||
space_packet_ids=TM_SP_IDS,
|
||||
)
|
||||
|
||||
def perform_mode_operation(self, tmtc_backend: TmTcHandler, mode: int):
|
||||
@ -88,25 +46,5 @@ class FsfwHookBase(TmTcHookBase):
|
||||
|
||||
return get_object_ids()
|
||||
|
||||
@staticmethod
|
||||
def handle_service_8_telemetry(
|
||||
object_id: int, action_id: int, custom_data: bytearray
|
||||
) -> Tuple[list, list]:
|
||||
from common_tmtc.pus_tm.service_8_handling import custom_service_8_handling
|
||||
|
||||
return custom_service_8_handling(
|
||||
object_id=object_id, action_id=action_id, custom_data=custom_data
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def handle_service_3_housekeeping(
|
||||
object_id: bytes, set_id: int, hk_data: bytearray, service3_packet: Service3Base
|
||||
) -> Tuple[list, list, bytearray, int]:
|
||||
from common_tmtc.pus_tm.service_3_hk_handling import service_3_hk_handling
|
||||
|
||||
return service_3_hk_handling(
|
||||
object_id=object_id,
|
||||
set_id=set_id,
|
||||
hk_data=hk_data,
|
||||
service3_packet=service3_packet,
|
||||
)
|
||||
def get_retval_dict(self) -> RetvalDictT:
|
||||
return self.get_retval_dict()
|
||||
|
@ -3,7 +3,15 @@
|
||||
@details Template configuration file. Copy this folder to the TMTC commander root and adapt
|
||||
it to your needs.
|
||||
"""
|
||||
from typing import Dict
|
||||
import os
|
||||
|
||||
from tmtccmd.fsfw import parse_fsfw_objects_csv
|
||||
from tmtccmd.logging import get_console_logger
|
||||
from tmtccmd.utility.obj_id import ObjectIdDictT
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
DEFAULT_OBJECTS_CSV_PATH = "config/objects.csv"
|
||||
__OBJECT_ID_DICT = None
|
||||
|
||||
PUS_SERVICE_17_ID = bytes([0x53, 0x00, 0x00, 0x17])
|
||||
TEST_DEVICE_0_ID = bytes([0x44, 0x01, 0xAF, 0xFE])
|
||||
@ -11,11 +19,13 @@ TEST_DEVICE_1_ID = bytes([0x44, 0x02, 0xAF, 0xFE])
|
||||
ASSEMBLY_ID = bytes([0x41, 0x00, 0xCA, 0xFE])
|
||||
|
||||
|
||||
def get_object_ids() -> Dict[bytes, list]:
|
||||
object_id_dict = {
|
||||
PUS_SERVICE_17_ID: ["PUS Service 17"],
|
||||
TEST_DEVICE_0_ID: ["Test Device 0"],
|
||||
TEST_DEVICE_1_ID: ["Test Device 1"],
|
||||
ASSEMBLY_ID: ["Assembly ID"],
|
||||
}
|
||||
return object_id_dict
|
||||
def get_object_ids() -> ObjectIdDictT:
|
||||
global __OBJECT_ID_DICT
|
||||
if not os.path.exists(DEFAULT_OBJECTS_CSV_PATH):
|
||||
LOGGER.warning(f"No Objects CSV file found at {DEFAULT_OBJECTS_CSV_PATH}")
|
||||
if __OBJECT_ID_DICT is None:
|
||||
if os.path.exists(DEFAULT_OBJECTS_CSV_PATH):
|
||||
__OBJECT_ID_DICT = parse_fsfw_objects_csv(csv_file=DEFAULT_OBJECTS_CSV_PATH)
|
||||
else:
|
||||
__OBJECT_ID_DICT = dict()
|
||||
return __OBJECT_ID_DICT
|
||||
|
22
config/retvals.py
Normal file
22
config/retvals.py
Normal file
@ -0,0 +1,22 @@
|
||||
import os
|
||||
from tmtccmd.fsfw import parse_fsfw_returnvalues_csv, RetvalDictT
|
||||
from tmtccmd.logging import get_console_logger
|
||||
|
||||
DEFAULT_RETVAL_CSV_NAME = "config/returnvalues.csv"
|
||||
__RETVAL_DICT = None
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
def get_retval_dict() -> RetvalDictT:
|
||||
global __RETVAL_DICT
|
||||
if __RETVAL_DICT is None:
|
||||
if os.path.exists(DEFAULT_RETVAL_CSV_NAME):
|
||||
__RETVAL_DICT = parse_fsfw_returnvalues_csv(
|
||||
csv_file=DEFAULT_RETVAL_CSV_NAME
|
||||
)
|
||||
else:
|
||||
LOGGER.warning(
|
||||
f"No Return Value CSV file found at {DEFAULT_RETVAL_CSV_NAME}"
|
||||
)
|
||||
__RETVAL_DICT = dict()
|
||||
return __RETVAL_DICT
|
@ -1,4 +0,0 @@
|
||||
SW_NAME = "fsfw-tmtc"
|
||||
SW_VERSION = 1
|
||||
SW_SUBVERSION = 4
|
||||
SW_SUBSUBVERSION = 0
|
26
pus_tc/cmd_definitions.py
Normal file
26
pus_tc/cmd_definitions.py
Normal file
@ -0,0 +1,26 @@
|
||||
from tmtccmd.config import (
|
||||
ServiceOpCodeDictT,
|
||||
add_op_code_entry,
|
||||
add_service_op_code_entry,
|
||||
OpCodeDictKeys,
|
||||
)
|
||||
from tmtccmd.config.globals import get_default_service_op_code_dict
|
||||
|
||||
|
||||
def get_fsfw_service_op_code_dict() -> ServiceOpCodeDictT:
|
||||
service_op_code_dict = get_default_service_op_code_dict()
|
||||
op_code = dict()
|
||||
add_op_code_entry(op_code_dict=op_code, keys="test", info="Mode CMD Test")
|
||||
add_op_code_entry(
|
||||
op_code_dict=op_code,
|
||||
keys=["0", "asm_to_normal"],
|
||||
info="Command test assembly to normal mode",
|
||||
options={OpCodeDictKeys.TIMEOUT: 6.0},
|
||||
)
|
||||
add_service_op_code_entry(
|
||||
srv_op_code_dict=service_op_code_dict,
|
||||
name="200",
|
||||
info="Mode MGMT",
|
||||
op_code_entry=op_code,
|
||||
)
|
||||
return service_op_code_dict
|
@ -1,5 +1,5 @@
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.pus.service_17_test import (
|
||||
from tmtccmd.pus.pus_17_test import (
|
||||
pack_service_17_ping_command,
|
||||
pack_generic_service17_test,
|
||||
)
|
||||
|
@ -1,15 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@file tmtcc_tc_service_200_mode.py
|
||||
@brief PUS Service 200: PUS custom service 200: Mode commanding
|
||||
@author R. Mueller
|
||||
@date 02.05.2020
|
||||
"""
|
||||
from spacepackets.ecss.tc import PusTelecommand
|
||||
|
||||
from tmtccmd.config.definitions import QueueCommands
|
||||
from tmtccmd.tc.packer import TcQueueT
|
||||
from tmtccmd.tc.service_200_mode import pack_mode_data, Modes
|
||||
from tmtccmd.tc.pus_200_fsfw_modes import pack_mode_data, Modes
|
||||
|
||||
from common_tmtc.config.object_ids import TEST_DEVICE_0_ID, ASSEMBLY_ID
|
||||
|
||||
@ -57,5 +51,4 @@ def pack_service_200_test_into(init_ssc: int, tc_queue: TcQueueT) -> int:
|
||||
command = PusTelecommand(service=200, subservice=1, ssc=new_ssc, app_data=mode_data)
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
new_ssc += 1
|
||||
tc_queue.appendleft((QueueCommands.EXPORT_LOG, "log/tmtc_log_service200.txt"))
|
||||
return new_ssc
|
||||
|
@ -4,9 +4,9 @@ from spacepackets.ecss.tc import PusTelecommand
|
||||
|
||||
from tmtccmd.config.definitions import QueueCommands
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.tc.service_20_parameter import pack_type_and_matrix_data, pack_parameter_id
|
||||
from tmtccmd.tc.service_200_mode import pack_mode_data
|
||||
from tmtccmd.utility.logger import get_console_logger
|
||||
from tmtccmd.tc.pus_20_params import pack_type_and_matrix_data, pack_parameter_id
|
||||
from tmtccmd.tc.pus_200_fsfw_modes import pack_mode_data, Modes
|
||||
from tmtccmd.logging import get_console_logger
|
||||
|
||||
from common_tmtc.config.object_ids import TEST_DEVICE_0_ID
|
||||
|
||||
@ -25,7 +25,7 @@ def pack_service20_test_into(tc_queue: TcQueueT, called_externally: bool = False
|
||||
|
||||
# set mode normal
|
||||
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 20: Set Normal Mode"))
|
||||
mode_data = pack_mode_data(object_id, 2, 0)
|
||||
mode_data = pack_mode_data(object_id, Modes.NORMAL, 0)
|
||||
command = PusTelecommand(service=200, subservice=1, ssc=2000, app_data=mode_data)
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
|
||||
@ -33,9 +33,6 @@ def pack_service20_test_into(tc_queue: TcQueueT, called_externally: bool = False
|
||||
load_param_1_simple_test_commands(tc_queue=tc_queue)
|
||||
load_param_2_simple_test_commands(tc_queue=tc_queue)
|
||||
|
||||
if called_externally is False:
|
||||
tc_queue.appendleft((QueueCommands.EXPORT_LOG, "log/tmtc_log_service20.txt"))
|
||||
|
||||
|
||||
def load_param_0_simple_test_commands(tc_queue: TcQueueT):
|
||||
object_id = TEST_DEVICE_0_ID
|
||||
|
@ -9,10 +9,9 @@ import struct
|
||||
|
||||
from spacepackets.ecss.tc import PusTelecommand
|
||||
|
||||
from tmtccmd.tc.service_200_mode import Modes
|
||||
from tmtccmd.tc.pus_200_fsfw_modes import Modes, pack_mode_data
|
||||
from tmtccmd.config.definitions import QueueCommands
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.tc.service_200_mode import pack_mode_data
|
||||
|
||||
from common_tmtc.pus_tc import command_data as cmd_data
|
||||
from common_tmtc.config.object_ids import TEST_DEVICE_0_ID
|
||||
@ -73,11 +72,10 @@ def pack_generic_service_2_test_into(init_ssc: int, tc_queue: TcQueueT) -> int:
|
||||
|
||||
# Set mode off
|
||||
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 2: Setting Off Mode"))
|
||||
mode_data = pack_mode_data(object_id, 0, 0)
|
||||
mode_data = pack_mode_data(object_id, Modes.OFF, 0)
|
||||
command = PusTelecommand(service=200, subservice=1, ssc=new_ssc, app_data=mode_data)
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
new_ssc += 1
|
||||
tc_queue.appendleft((QueueCommands.EXPORT_LOG, "log/tmtc_log_service_2.txt"))
|
||||
return new_ssc
|
||||
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
from spacepackets.ecss.tc import PusTelecommand
|
||||
|
||||
from tmtccmd.config.definitions import QueueCommands
|
||||
from tmtccmd.tc.service_200_mode import pack_mode_data, Modes
|
||||
from tmtccmd.tc.service_20_parameter import pack_boolean_parameter_command
|
||||
from tmtccmd.tc.service_3_housekeeping import (
|
||||
make_sid,
|
||||
generate_one_hk_command,
|
||||
Srv3Subservice,
|
||||
from tmtccmd.tc.pus_200_fsfw_modes import pack_mode_data, Modes
|
||||
from tmtccmd.tc.pus_20_params import (
|
||||
pack_boolean_parameter_app_data,
|
||||
pack_fsfw_load_param_cmd,
|
||||
)
|
||||
from tmtccmd.tc.pus_3_fsfw_hk import make_sid, generate_one_hk_command
|
||||
import tmtccmd.tc.pus_3_fsfw_hk as srv3
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.tc.service_8_functional_cmd import generate_action_command
|
||||
from tmtccmd.tc.pus_8_funccmd import generate_action_command
|
||||
|
||||
from common_tmtc.config.object_ids import TEST_DEVICE_0_ID, TEST_DEVICE_1_ID
|
||||
|
||||
@ -130,15 +130,16 @@ def pack_housekeeping_basic_test(
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
|
||||
tc_queue.appendleft((QueueCommands.PRINT, "Enabling changing datasets"))
|
||||
command = pack_boolean_parameter_command(
|
||||
app_data = pack_boolean_parameter_app_data(
|
||||
object_id=object_id,
|
||||
domain_id=0,
|
||||
unique_id=PARAM_ACTIVATE_CHANGING_DATASETS,
|
||||
parameter=True,
|
||||
ssc=current_ssc,
|
||||
)
|
||||
cmd = pack_fsfw_load_param_cmd(app_data=app_data, ssc=0)
|
||||
|
||||
current_ssc += 1
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
tc_queue.appendleft(cmd.pack_command_tuple())
|
||||
|
||||
# Enable periodic reporting
|
||||
tc_queue.appendleft(
|
||||
@ -146,7 +147,7 @@ def pack_housekeeping_basic_test(
|
||||
)
|
||||
command = PusTelecommand(
|
||||
service=3,
|
||||
subservice=Srv3Subservice.ENABLE_PERIODIC_HK_GEN.value,
|
||||
subservice=srv3.Subservices.TC_ENABLE_PERIODIC_HK_GEN,
|
||||
ssc=current_ssc,
|
||||
app_data=test_sid,
|
||||
)
|
||||
@ -161,7 +162,7 @@ def pack_housekeeping_basic_test(
|
||||
)
|
||||
command = PusTelecommand(
|
||||
service=3,
|
||||
subservice=Srv3Subservice.DISABLE_PERIODIC_HK_GEN.value,
|
||||
subservice=srv3.Subservices.TC_DISABLE_PERIODIC_HK_GEN,
|
||||
ssc=current_ssc,
|
||||
app_data=test_sid,
|
||||
)
|
||||
@ -170,15 +171,15 @@ def pack_housekeeping_basic_test(
|
||||
|
||||
# Disable changing datasets via parameter service (Service 20)
|
||||
tc_queue.appendleft((QueueCommands.PRINT, "Disabling changing datasets"))
|
||||
command = pack_boolean_parameter_command(
|
||||
app_data = pack_boolean_parameter_app_data(
|
||||
object_id=object_id,
|
||||
domain_id=0,
|
||||
unique_id=PARAM_ACTIVATE_CHANGING_DATASETS,
|
||||
parameter=False,
|
||||
ssc=current_ssc,
|
||||
)
|
||||
current_ssc += 1
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
cmd = pack_fsfw_load_param_cmd(app_data=app_data, ssc=0)
|
||||
tc_queue.appendleft(cmd.pack_command_tuple())
|
||||
return current_ssc
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ from spacepackets.ecss.tc import PusTelecommand
|
||||
|
||||
from tmtccmd.config.definitions import QueueCommands
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.tc.service_200_mode import pack_mode_data, Modes
|
||||
from tmtccmd.tc.pus_200_fsfw_modes import pack_mode_data, Modes
|
||||
|
||||
import common_tmtc.pus_tc.command_data as cmd_data
|
||||
|
||||
@ -57,8 +57,6 @@ def pack_generic_service_8_test_into(tc_queue: TcQueueT):
|
||||
|
||||
# Set mode off
|
||||
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 8: Set Off Mode"))
|
||||
mode_data = pack_mode_data(object_id, 0, 0)
|
||||
mode_data = pack_mode_data(object_id, Modes.OFF, 0)
|
||||
command = PusTelecommand(service=200, subservice=1, ssc=800, app_data=mode_data)
|
||||
tc_queue.appendleft(command.pack_command_tuple())
|
||||
|
||||
tc_queue.appendleft((QueueCommands.EXPORT_LOG, "log/tmtc_log_service_8.txt"))
|
||||
|
@ -3,26 +3,50 @@
|
||||
@details Template configuration file. Copy this folder to the TMTC commander root and adapt
|
||||
it to your needs.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from collections import deque
|
||||
from typing import Union
|
||||
|
||||
from spacepackets.ecss.tc import PusTelecommand
|
||||
from tmtccmd.com_if.com_interface_base import CommunicationInterface
|
||||
from tmtccmd.logging import get_console_logger, get_current_time_string
|
||||
from tmtccmd.logging.pus import log_raw_pus_tc
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.config.definitions import CoreServiceList, QueueCommands
|
||||
from tmtccmd.tc.pus_5_event import pack_generic_service5_test_into
|
||||
from tmtccmd.pus.pus_17_test import pack_generic_service17_test
|
||||
|
||||
from common_tmtc.pus_tc.service_20_parameters import pack_service20_commands_into
|
||||
from common_tmtc.pus_tc.service_2_raw_cmd import pack_service_2_commands_into
|
||||
from common_tmtc.pus_tc.service_3_housekeeping import pack_service_3_commands_into
|
||||
from common_tmtc.pus_tc.service_17_test import pack_service_17_commands
|
||||
from common_tmtc.pus_tc.service_8_func_cmd import pack_service_8_commands_into
|
||||
from tmtccmd.utility.logger import get_console_logger
|
||||
from tmtccmd.tc.definitions import TcQueueT
|
||||
from tmtccmd.config.definitions import CoreServiceList
|
||||
from tmtccmd.tc.service_5_event import pack_generic_service5_test_into
|
||||
from tmtccmd.pus.service_17_test import pack_generic_service17_test
|
||||
from common_tmtc.pus_tc.service_200_mode import pack_service_200_commands_into
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
def pre_tc_send_cb(
|
||||
queue_entry: Union[bytes, QueueCommands],
|
||||
com_if: CommunicationInterface,
|
||||
queue_info: Union[PusTelecommand, any],
|
||||
file_logger: logging.Logger,
|
||||
):
|
||||
if isinstance(queue_entry, bytes) or isinstance(queue_entry, bytearray):
|
||||
log_raw_pus_tc(
|
||||
packet=queue_entry,
|
||||
srv_subservice=(queue_info.service, queue_info.subservice),
|
||||
)
|
||||
tc_info_string = f"Sent {queue_info}"
|
||||
LOGGER.info(tc_info_string)
|
||||
file_logger.info(f"{get_current_time_string(True)}: {tc_info_string}")
|
||||
com_if.send(data=queue_entry)
|
||||
elif isinstance(queue_entry, QueueCommands):
|
||||
if queue_entry == QueueCommands.PRINT:
|
||||
file_logger.info(queue_info)
|
||||
|
||||
|
||||
def pack_service_queue_user(service: Union[str, int], op_code: str, tc_queue: TcQueueT):
|
||||
if service == CoreServiceList.SERVICE_2.value:
|
||||
return pack_service_2_commands_into(op_code=op_code, tc_queue=tc_queue)
|
||||
|
24
pus_tm/action_reply_handling.py
Normal file
24
pus_tm/action_reply_handling.py
Normal file
@ -0,0 +1,24 @@
|
||||
from tmtccmd.logging import get_console_logger
|
||||
from tmtccmd.tm import Service8FsfwTm
|
||||
from tmtccmd.utility.obj_id import ObjectIdDictT
|
||||
from tmtccmd.utility.tmtc_printer import FsfwTmTcPrinter
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
def handle_action_reply(
|
||||
raw_tm: bytes, printer: FsfwTmTcPrinter, obj_id_dict: ObjectIdDictT
|
||||
):
|
||||
"""Core Action reply handler
|
||||
:return:
|
||||
"""
|
||||
tm_packet = Service8FsfwTm.unpack(raw_telemetry=raw_tm)
|
||||
printer.handle_long_tm_print(packet_if=tm_packet, info_if=tm_packet)
|
||||
object_id = obj_id_dict.get(tm_packet.source_object_id_as_bytes)
|
||||
custom_data = tm_packet.custom_data
|
||||
action_id = tm_packet.action_id
|
||||
generic_print_str = printer.generic_action_packet_tm_print(
|
||||
packet=tm_packet, obj_id=object_id
|
||||
)
|
||||
print(generic_print_str)
|
||||
printer.file_logger.info(generic_print_str)
|
61
pus_tm/event_handler.py
Normal file
61
pus_tm/event_handler.py
Normal file
@ -0,0 +1,61 @@
|
||||
import logging
|
||||
import os.path
|
||||
from datetime import datetime
|
||||
from common_tmtc.config.object_ids import get_object_ids
|
||||
|
||||
from tmtccmd.tm import Service5Tm
|
||||
from tmtccmd.logging import get_console_logger
|
||||
from tmtccmd.utility.tmtc_printer import FsfwTmTcPrinter
|
||||
from tmtccmd.fsfw import parse_fsfw_events_csv, EventDictT, EventInfo
|
||||
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
DEFAULT_EVENTS_CSV_PATH = "config/events.csv"
|
||||
__EVENT_DICT = None
|
||||
|
||||
|
||||
def get_event_dict() -> EventDictT:
|
||||
global __EVENT_DICT
|
||||
if __EVENT_DICT is None:
|
||||
if os.path.exists(DEFAULT_EVENTS_CSV_PATH):
|
||||
__EVENT_DICT = parse_fsfw_events_csv(DEFAULT_EVENTS_CSV_PATH)
|
||||
else:
|
||||
LOGGER.warning(f"No Event CSV file found at {DEFAULT_EVENTS_CSV_PATH}")
|
||||
__EVENT_DICT = dict()
|
||||
return __EVENT_DICT
|
||||
|
||||
|
||||
def handle_event_packet(
|
||||
raw_tm: bytes, printer: FsfwTmTcPrinter, file_logger: logging.Logger
|
||||
) -> str:
|
||||
tm = Service5Tm.unpack(raw_telemetry=raw_tm)
|
||||
printer.handle_long_tm_print(packet_if=tm, info_if=tm)
|
||||
additional_event_info = ""
|
||||
event_dict = get_event_dict()
|
||||
info = event_dict.get(tm.event_id)
|
||||
if info is None:
|
||||
LOGGER.warning(f"Event ID {tm.event_id} has no information")
|
||||
info = EventInfo()
|
||||
info.name = "Unknown event"
|
||||
obj_ids = get_object_ids()
|
||||
obj_id_obj = obj_ids.get(tm.reporter_id.as_bytes)
|
||||
if obj_id_obj is None:
|
||||
LOGGER.warning(f"Object ID 0x{tm.reporter_id.as_string} has no name")
|
||||
obj_name = tm.reporter_id.as_string
|
||||
else:
|
||||
obj_name = obj_id_obj.name
|
||||
generic_event_string = (
|
||||
f"Object {obj_name} generated Event {tm.event_id} | {info.name}"
|
||||
)
|
||||
if info.info != "":
|
||||
additional_event_info = (
|
||||
f"Additional info: {info.info} | P1: {tm.param_1} | P2: {tm.param_2}"
|
||||
)
|
||||
file_logger.info(
|
||||
f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: {generic_event_string}"
|
||||
)
|
||||
LOGGER.info(generic_event_string)
|
||||
if additional_event_info != "":
|
||||
file_logger.info(additional_event_info)
|
||||
print(additional_event_info)
|
||||
return generic_event_string + " | " + additional_event_info
|
@ -4,55 +4,89 @@
|
||||
it to your needs.
|
||||
"""
|
||||
from spacepackets.ecss.tm import PusTelemetry
|
||||
from spacepackets.util import PrintFormats
|
||||
from spacepackets.ccsds.spacepacket import PacketTypes
|
||||
|
||||
from tmtccmd.utility.logger import get_console_logger
|
||||
from tmtccmd.pus.service_1_verification import Service1TMExtended
|
||||
from tmtccmd.tm.service_2_raw_cmd import Service2TM
|
||||
from tmtccmd.tm.service_3_housekeeping import Service3TM
|
||||
from tmtccmd.tm.service_5_event import Service5TM
|
||||
from tmtccmd.tm.service_8_functional_cmd import Service8TM
|
||||
from tmtccmd.pus.service_17_test import Service17TMExtended
|
||||
from tmtccmd.tm.service_20_parameters import Service20TM
|
||||
from tmtccmd.tm.service_200_mode import Service200TM
|
||||
from tmtccmd.utility.tmtc_printer import TmTcPrinter
|
||||
from tmtccmd.tm.pus_2_rawcmd import Service2Tm
|
||||
from tmtccmd.tm.pus_17_test import Service17TMExtended
|
||||
from tmtccmd.tm.pus_20_fsfw_parameters import Service20FsfwTm
|
||||
from tmtccmd.tm.pus_200_fsfw_modes import Service200FsfwTm
|
||||
from tmtccmd.utility.tmtc_printer import FsfwTmTcPrinter
|
||||
from tmtccmd.logging import get_console_logger
|
||||
from tmtccmd.logging.pus import (
|
||||
create_tmtc_logger,
|
||||
log_raw_pus_tm,
|
||||
log_raw_unknown_packet,
|
||||
)
|
||||
|
||||
from common_tmtc.config.object_ids import get_object_ids
|
||||
from common_tmtc.pus_tm.action_reply_handling import handle_action_reply
|
||||
from common_tmtc.pus_tm.event_handler import handle_event_packet
|
||||
from common_tmtc.pus_tm.verification_handler import handle_service_1_packet
|
||||
from common_tmtc.pus_tm.hk_handling import handle_hk_packet
|
||||
from common_tmtc.config.definitions import PUS_APID
|
||||
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
def ccsds_tm_handler(
|
||||
apid: int, raw_tm_packet: bytearray, tmtc_printer: TmTcPrinter
|
||||
) -> None:
|
||||
FSFW_PRINTER = FsfwTmTcPrinter(file_logger=create_tmtc_logger())
|
||||
|
||||
|
||||
def ccsds_tm_handler(apid: int, raw_tm_packet: bytes, _user_args: any) -> None:
|
||||
if apid == PUS_APID:
|
||||
pus_packet_factory(raw_tm_packet=raw_tm_packet, tmtc_printer=tmtc_printer)
|
||||
pus_factory_hook(raw_tm_packet=raw_tm_packet)
|
||||
|
||||
|
||||
def pus_packet_factory(raw_tm_packet: bytearray, tmtc_printer: TmTcPrinter):
|
||||
def pus_factory_hook(raw_tm_packet: bytes):
|
||||
if len(raw_tm_packet) < 8:
|
||||
LOGGER.warning("Detected packet shorter than 8 bytes!")
|
||||
return
|
||||
service_type = raw_tm_packet[7]
|
||||
tm_packet = None
|
||||
if service_type == 1:
|
||||
tm_packet = Service1TMExtended.unpack(raw_tm_packet)
|
||||
if service_type == 2:
|
||||
tm_packet = Service2TM.unpack(raw_tm_packet)
|
||||
if service_type == 3:
|
||||
tm_packet = Service3TM.unpack(raw_tm_packet, custom_hk_handling=False)
|
||||
if service_type == 8:
|
||||
tm_packet = Service8TM.unpack(raw_tm_packet)
|
||||
if service_type == 5:
|
||||
tm_packet = Service5TM.unpack(raw_tm_packet)
|
||||
if service_type == 17:
|
||||
tm_packet = Service17TMExtended.unpack(raw_tm_packet)
|
||||
if service_type == 20:
|
||||
tm_packet = Service20TM.unpack(raw_tm_packet)
|
||||
if service_type == 200:
|
||||
tm_packet = Service200TM.unpack(raw_tm_packet)
|
||||
if tm_packet is None:
|
||||
LOGGER.info(
|
||||
"The service "
|
||||
+ str(service_type)
|
||||
+ " is not implemented in Telemetry Factory"
|
||||
subservice_type = raw_tm_packet[8]
|
||||
file_logger = FSFW_PRINTER.file_logger
|
||||
obj_id_dict = get_object_ids()
|
||||
dedicated_handler = True
|
||||
try:
|
||||
tm_packet = None
|
||||
if service_type == 1:
|
||||
handle_service_1_packet(printer=FSFW_PRINTER, raw_tm=raw_tm_packet)
|
||||
if service_type == 2:
|
||||
tm_packet = Service2Tm.unpack(raw_tm_packet)
|
||||
dedicated_handler = False
|
||||
if service_type == 3:
|
||||
handle_hk_packet(
|
||||
printer=FSFW_PRINTER, raw_tm=raw_tm_packet, obj_id_dict=obj_id_dict
|
||||
)
|
||||
if service_type == 8:
|
||||
handle_action_reply(
|
||||
raw_tm=raw_tm_packet, printer=FSFW_PRINTER, obj_id_dict=obj_id_dict
|
||||
)
|
||||
if service_type == 5:
|
||||
handle_event_packet(
|
||||
raw_tm=raw_tm_packet, printer=FSFW_PRINTER, file_logger=file_logger
|
||||
)
|
||||
if service_type == 17:
|
||||
tm_packet = Service17TMExtended.unpack(raw_telemetry=raw_tm_packet)
|
||||
dedicated_handler = False
|
||||
if service_type == 20:
|
||||
tm_packet = Service20FsfwTm.unpack(raw_telemetry=raw_tm_packet)
|
||||
dedicated_handler = False
|
||||
if service_type == 200:
|
||||
tm_packet = Service200FsfwTm.unpack(raw_telemetry=raw_tm_packet)
|
||||
dedicated_handler = False
|
||||
else:
|
||||
LOGGER.info(
|
||||
f"The service {service_type} is not implemented in Telemetry Factory"
|
||||
)
|
||||
tm_packet = PusTelemetry.unpack(raw_telemetry=raw_tm_packet)
|
||||
tm_packet.print_source_data(PrintFormats.HEX)
|
||||
dedicated_handler = True
|
||||
if not dedicated_handler and tm_packet is not None:
|
||||
FSFW_PRINTER.handle_long_tm_print(packet_if=tm_packet, info_if=tm_packet)
|
||||
log_raw_pus_tm(
|
||||
packet=raw_tm_packet, srv_subservice=(service_type, subservice_type)
|
||||
)
|
||||
tm_packet = PusTelemetry.unpack(raw_tm_packet)
|
||||
tmtc_printer.print_telemetry(packet_if=tm_packet, info_if=tm_packet)
|
||||
except ValueError:
|
||||
LOGGER.warning("Invalid packet format detected")
|
||||
log_raw_unknown_packet(packet=raw_tm_packet, packet_type=PacketTypes.TM)
|
||||
|
@ -2,44 +2,57 @@
|
||||
"""
|
||||
import struct
|
||||
from typing import Tuple
|
||||
from tmtccmd.tm.service_3_housekeeping import Service3Base
|
||||
from tmtccmd.utility.logger import get_console_logger
|
||||
|
||||
from tmtccmd.tm import Service3FsfwTm
|
||||
from tmtccmd.tm.pus_3_hk_base import HkContentType, Service3Base
|
||||
from tmtccmd.utility.obj_id import ObjectIdDictT, ObjectId
|
||||
from tmtccmd.utility.tmtc_printer import FsfwTmTcPrinter
|
||||
from tmtccmd.logging import get_console_logger
|
||||
|
||||
from common_tmtc.config.object_ids import TEST_DEVICE_0_ID, TEST_DEVICE_1_ID
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
def service_3_hk_handling(
|
||||
object_id: bytes, set_id: int, hk_data: bytearray, service3_packet: Service3Base
|
||||
) -> Tuple[list, list, bytearray, int]:
|
||||
"""This function is called when a Service 3 Housekeeping packet is received.
|
||||
def handle_hk_packet(
|
||||
raw_tm: bytes,
|
||||
obj_id_dict: ObjectIdDictT,
|
||||
printer: FsfwTmTcPrinter,
|
||||
):
|
||||
tm_packet = Service3FsfwTm.unpack(raw_telemetry=raw_tm, custom_hk_handling=False)
|
||||
named_obj_id = obj_id_dict.get(tm_packet.object_id.as_bytes)
|
||||
if named_obj_id is None:
|
||||
named_obj_id = tm_packet.object_id
|
||||
if tm_packet.subservice == 25 or tm_packet.subservice == 26:
|
||||
hk_data = tm_packet.tm_data[8:]
|
||||
printer.generic_hk_tm_print(
|
||||
content_type=HkContentType.HK,
|
||||
object_id=named_obj_id,
|
||||
set_id=tm_packet.set_id,
|
||||
hk_data=hk_data,
|
||||
)
|
||||
handle_regular_hk_print(
|
||||
printer=printer,
|
||||
object_id=named_obj_id,
|
||||
hk_packet=tm_packet,
|
||||
hk_data=hk_data,
|
||||
)
|
||||
if tm_packet.subservice == 10 or tm_packet.subservice == 12:
|
||||
LOGGER.warning("HK definitions printout not implemented yet")
|
||||
|
||||
Please note that the object IDs should be compared by value because direct comparison of
|
||||
enumerations does not work in Python. For example use:
|
||||
|
||||
if object_id.value == ObjectIds.TEST_OBJECT.value
|
||||
|
||||
to test equality based on the object ID list.
|
||||
|
||||
@param object_id:
|
||||
@param set_id:
|
||||
@param hk_data:
|
||||
@param service3_packet:
|
||||
@return: Expects a tuple, consisting of two lists, a bytearray and an integer
|
||||
The first list contains the header columns, the second list the list with
|
||||
the corresponding values. The bytearray is the validity buffer, which is usually appended
|
||||
at the end of the housekeeping packet. The last value is the number of parameters.
|
||||
"""
|
||||
def handle_regular_hk_print(
|
||||
printer: FsfwTmTcPrinter,
|
||||
object_id: ObjectId,
|
||||
hk_packet: Service3Base,
|
||||
hk_data: bytes,
|
||||
):
|
||||
if object_id == TEST_DEVICE_0_ID or object_id == TEST_DEVICE_1_ID:
|
||||
return handle_test_set_deserialization(hk_data=hk_data)
|
||||
else:
|
||||
LOGGER.info("Service3TM: Parsing for this SID has not been implemented.")
|
||||
return [], [], bytearray(), 0
|
||||
handle_test_set_deserialization(hk_data=hk_data)
|
||||
|
||||
|
||||
def handle_test_set_deserialization(
|
||||
hk_data: bytearray,
|
||||
hk_data: bytes,
|
||||
) -> Tuple[list, list, bytearray, int]:
|
||||
header_list = []
|
||||
content_list = []
|
@ -1,20 +0,0 @@
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def custom_service_8_handling(
|
||||
object_id: int, action_id: int, custom_data: bytearray
|
||||
) -> Tuple[list, list]:
|
||||
"""
|
||||
This function is called by the TMTC core if a Service 8 data reply (subservice 130)
|
||||
is received. The user can return a tuple of two lists, where the first list
|
||||
is a list of header strings to print and the second list is a list of values to print.
|
||||
The TMTC core will take care of printing both lists and logging them.
|
||||
|
||||
@param object_id:
|
||||
@param action_id:
|
||||
@param custom_data:
|
||||
@return:
|
||||
"""
|
||||
header_list = []
|
||||
content_list = []
|
||||
return header_list, content_list
|
28
pus_tm/verification_handler.py
Normal file
28
pus_tm/verification_handler.py
Normal file
@ -0,0 +1,28 @@
|
||||
from typing import cast
|
||||
|
||||
from tmtccmd.tm.pus_1_verification import Service1TMExtended
|
||||
from tmtccmd.logging import get_console_logger
|
||||
from tmtccmd.utility.tmtc_printer import FsfwTmTcPrinter
|
||||
from common_tmtc.config.retvals import get_retval_dict
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
def handle_service_1_packet(printer: FsfwTmTcPrinter, raw_tm: bytes):
|
||||
tm_packet = Service1TMExtended.unpack(raw_telemetry=raw_tm)
|
||||
printer.handle_long_tm_print(packet_if=tm_packet, info_if=tm_packet)
|
||||
srv1_packet = cast(Service1TMExtended, tm_packet)
|
||||
retval_dict = get_retval_dict()
|
||||
if srv1_packet.has_tc_error_code:
|
||||
retval_info = retval_dict.get(srv1_packet.error_code)
|
||||
if retval_info is None:
|
||||
LOGGER.info(
|
||||
f"No returnvalue information found for error code {srv1_packet.error_code}"
|
||||
)
|
||||
else:
|
||||
retval_string = (
|
||||
f"Error Code information for code {srv1_packet.error_code} | "
|
||||
f"Name: {retval_info.name} | Info: {retval_info.info}"
|
||||
)
|
||||
LOGGER.info(retval_string)
|
||||
printer.file_logger.info(retval_string)
|
65
tmtcc.py
Normal file
65
tmtcc.py
Normal file
@ -0,0 +1,65 @@
|
||||
import argparse
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Optional
|
||||
|
||||
try:
|
||||
import spacepackets
|
||||
except ImportError as error:
|
||||
print(error)
|
||||
print("Python spacepackets module could not be imported")
|
||||
print(
|
||||
'Install with "cd spacepackets && python3 -m pip intall -e ." for interative installation'
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
import tmtccmd.runner as tmtccmd
|
||||
from tmtccmd.logging.pus import create_tmtc_logger
|
||||
from tmtccmd.ccsds.handler import ApidHandler, CcsdsTmHandler
|
||||
from tmtccmd.config import SetupArgs, default_json_path
|
||||
from tmtccmd.config.args import (
|
||||
create_default_args_parser,
|
||||
add_default_tmtccmd_args,
|
||||
parse_default_input_arguments,
|
||||
)
|
||||
except ImportError as error:
|
||||
run_tmtc_commander = None
|
||||
initialize_tmtc_commander = None
|
||||
tb = traceback.format_exc()
|
||||
print(tb)
|
||||
print("Python tmtccmd submodule could not be imported")
|
||||
sys.exit(1)
|
||||
|
||||
from common_tmtc.config import __version__
|
||||
from common_tmtc.config.definitions import PUS_APID
|
||||
from common_tmtc.config.hook_implementation import FsfwHookBase
|
||||
from common_tmtc.pus_tm.factory_hook import ccsds_tm_handler
|
||||
from common_tmtc.pus_tc.tc_packing import pre_tc_send_cb
|
||||
|
||||
|
||||
def tmtcc_pre_args() -> FsfwHookBase:
|
||||
print(f"-- eive tmtc v{__version__} --")
|
||||
print(f"-- spacepackets v{spacepackets.__version__} --")
|
||||
tmtccmd.init_printout(False)
|
||||
return FsfwHookBase(json_cfg_path=default_json_path())
|
||||
|
||||
|
||||
def tmtcc_post_args(
|
||||
hook_obj: FsfwHookBase, use_gui: bool, args: Optional[argparse.Namespace]
|
||||
):
|
||||
setup_args = SetupArgs(
|
||||
hook_obj=hook_obj, use_gui=use_gui, apid=PUS_APID, cli_args=args
|
||||
)
|
||||
tmtc_file_logger = create_tmtc_logger()
|
||||
apid_handler = ApidHandler(cb=ccsds_tm_handler, queue_len=50, user_args=None)
|
||||
ccsds_handler = CcsdsTmHandler()
|
||||
ccsds_handler.add_tm_handler(apid=PUS_APID, handler=apid_handler)
|
||||
tmtccmd.setup(setup_args=setup_args)
|
||||
tmtccmd.add_ccsds_handler(ccsds_handler)
|
||||
tmtc_backend = tmtccmd.create_default_tmtc_backend(
|
||||
setup_args=setup_args,
|
||||
tm_handler=ccsds_handler,
|
||||
)
|
||||
tmtc_backend.usr_send_wrapper = (pre_tc_send_cb, tmtc_file_logger)
|
||||
tmtccmd.run(tmtc_backend=tmtc_backend)
|
Loading…
Reference in New Issue
Block a user