import enum import struct from spacepackets.ecss import PusTelecommand from tmtccmd.config.tmtc import ( CmdTreeNode, ) from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str from tmtccmd.pus.s8_fsfw_action import create_action_cmd from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservices from tmtccmd.pus.tc.s3_fsfw_hk import generate_one_hk_command, make_sid from tmtccmd.tmtc import DefaultPusQueueHelper from eive_tmtc.config.object_ids import BPX_HANDLER_ID from eive_tmtc.pus_tm.defs import PrintWrapper class BpxSetId(enum.IntEnum): GET_HK_SET = 0 GET_CFG_SET = 5 class BpxActionId: REBOOT = 2 RESET_COUNTERS = 3 CONFIG_CMD = 4 GET_CFG = 5 SET_CFG = 6 MAN_HEATER_ON = 10 MAN_HEATER_OFF = 11 class BpxHeaterModeSelect(enum.IntEnum): OFF = 0 AUTO = 1 class BpxOpCode: HK = "hk" OFF = "off" ON = "on" RST_CFG = "reset_cfg" SET_CFG = "set_cfg" MAN_HEATER_ON = "man_heater_on" MAN_HEATER_OFF = "man_heater_off" RST_BOOT_CNT = "rst_boot_cnt" REQUEST_CFG = "cfg" REQUEST_CFG_HK = "cfg_hk" REBOOT = "reboot" def create_bpx_batt_node() -> CmdTreeNode: node = CmdTreeNode("bat", "BPX battery device", hide_children_for_print=True) node.add_child(CmdTreeNode(BpxOpCode.ON, "ON command")) node.add_child(CmdTreeNode(BpxOpCode.OFF, "OFF command")) node.add_child(CmdTreeNode(BpxOpCode.HK, "HK command")) node.add_child(CmdTreeNode(BpxOpCode.RST_BOOT_CNT, "Reset boot count")) node.add_child( CmdTreeNode(BpxOpCode.RST_CFG, "Reset Config to stored default settings") ) node.add_child(CmdTreeNode(BpxOpCode.SET_CFG, "Set BPX configuration")) node.add_child(CmdTreeNode(BpxOpCode.MAN_HEATER_ON, "Manual heater on")) node.add_child(CmdTreeNode(BpxOpCode.MAN_HEATER_OFF, "Manual heater off")) node.add_child( CmdTreeNode(BpxOpCode.REQUEST_CFG, "Request Configuration Struct (Step 1)") ) node.add_child( CmdTreeNode( BpxOpCode.REQUEST_CFG_HK, "Request Configuration Struct HK (Step 2)" ) ) node.add_child(CmdTreeNode(BpxOpCode.REBOOT, "Reboot Command")) return node def pack_bpx_commands( q: DefaultPusQueueHelper, cmd_str: str ): # noqa C901: Complexity is okay here. if cmd_str == BpxOpCode.HK: q.add_log_cmd("Requesting BPX battery HK set") sid = make_sid(object_id=BPX_HANDLER_ID, set_id=BpxSetId.GET_HK_SET) q.add_pus_tc(generate_one_hk_command(sid=sid)) if cmd_str == BpxOpCode.OFF: q.add_log_cmd("Off mode") mode_cmd = pack_mode_data(BPX_HANDLER_ID, Mode.OFF, 0) q.add_pus_tc( PusTelecommand( service=200, subservice=ModeSubservices.TC_MODE_COMMAND, app_data=mode_cmd, ) ) if cmd_str == BpxOpCode.ON: q.add_log_cmd("On mode") mode_cmd = pack_mode_data(BPX_HANDLER_ID, Mode.ON, 0) q.add_pus_tc( PusTelecommand( service=200, subservice=ModeSubservices.TC_MODE_COMMAND, app_data=mode_cmd, ) ) if cmd_str == BpxOpCode.RST_BOOT_CNT: q.add_log_cmd("Resetting reboot counters") q.add_pus_tc( create_action_cmd( object_id=BPX_HANDLER_ID, action_id=BpxActionId.RESET_COUNTERS ) ) if cmd_str == BpxOpCode.RST_CFG: q.add_log_cmd("Reset BPX configuration") q.add_pus_tc( create_action_cmd( object_id=BPX_HANDLER_ID, action_id=BpxActionId.CONFIG_CMD ) ) if cmd_str == BpxOpCode.SET_CFG: q.add_log_cmd("Setting BPX configuration") user_data = bytearray() batt_mode = BpxHeaterModeSelect( int(input("BPX heater mode select, 0 for OFF 1 for AUTO: ")) ) user_data.append(batt_mode) lower_limit = int(input("Lower heater limit (-2 default): ")) user_data.append(struct.pack("!b", lower_limit)[0]) upper_limit = int(input("Upper heater limit (3 default): ")) user_data.append(struct.pack("!b", upper_limit)[0]) q.add_pus_tc( create_action_cmd( object_id=BPX_HANDLER_ID, action_id=BpxActionId.SET_CFG, user_data=user_data, ) ) if cmd_str == BpxOpCode.REQUEST_CFG: q.add_log_cmd("Requesting configuration struct") q.add_pus_tc( create_action_cmd(object_id=BPX_HANDLER_ID, action_id=BpxActionId.GET_CFG) ) if cmd_str == BpxOpCode.REQUEST_CFG_HK: q.add_log_cmd("Requesting configuration struct HK") sid = make_sid(object_id=BPX_HANDLER_ID, set_id=BpxSetId.GET_CFG_SET) q.add_pus_tc(generate_one_hk_command(sid=sid)) if cmd_str == BpxOpCode.REBOOT: q.add_log_cmd("Rebooting BPX battery") q.add_pus_tc( create_action_cmd(object_id=BPX_HANDLER_ID, action_id=BpxActionId.REBOOT) ) if cmd_str == BpxOpCode.MAN_HEATER_ON: q.add_log_cmd("BPX manual heater on with seconds burntime") burn_time = int(input("BPX heater burn time in seconds [1-65535]: ")) if burn_time < 1 or burn_time > 65535: raise ValueError("Invalid burntime, smaller than 0 or larger than 65535") q.add_pus_tc( create_action_cmd( object_id=BPX_HANDLER_ID, action_id=BpxActionId.MAN_HEATER_ON, user_data=struct.pack("!H", burn_time), ) ) if cmd_str == BpxOpCode.MAN_HEATER_OFF: q.add_log_cmd("BPX manual heater off") q.add_pus_tc( create_action_cmd( object_id=BPX_HANDLER_ID, action_id=BpxActionId.MAN_HEATER_OFF ) ) HEADER_LIST = [ "Charge Current", "Discharge Current", "Heater Current", "Battery Voltage", "Batt Temp 1", "Batt Temp 2", "Batt Temp 3", "Batt Temp 4", "Reboot Counter", "Boot Cause", ] def handle_bpx_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes): if set_id == BpxSetId.GET_HK_SET: fmt_str = "!HHHHhhhhIB" inc_len = struct.calcsize(fmt_str) ( charge_current, discharge_current, heater_current, batt_voltage, batt_temp_1, batt_temp_2, batt_temp_3, batt_temp_4, reboot_cntr, boot_cause, ) = struct.unpack(fmt_str, hk_data[0:inc_len]) content_list = [ charge_current, discharge_current, heater_current, batt_voltage, batt_temp_1, batt_temp_2, batt_temp_3, batt_temp_4, reboot_cntr, boot_cause, ] validity_buffer = hk_data[inc_len:] pw.dlog(str(HEADER_LIST)) pw.dlog(str(content_list)) pw.dlog(get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=10)) elif set_id == BpxSetId.GET_CFG_SET: battheat_mode = hk_data[0] battheat_low = struct.unpack("!b", hk_data[1:2])[0] battheat_high = struct.unpack("!b", hk_data[2:3])[0] header_list = [ "Battery Heater Mode", "Battery Heater Low Limit", "Battery Heater High Limit", ] content_list = [battheat_mode, battheat_low, battheat_high] validity_buffer = hk_data[3:] pw.dlog(str(header_list)) pw.dlog(str(content_list)) pw.dlog(get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=10))