# -*- coding: utf-8 -*- """ @file tmtcc_tc_pdu2.py @brief PDU2 tests @details PDU2 is mounted on the X4 slot of the P60 dock @author J. Meier @date 17.12.2020 """ from eive_tmtc.config.object_ids import PDU_2_HANDLER_ID from eive_tmtc.tmtc.power.common_power import ( pack_common_gomspace_cmds, req_hk_cmds, PowerOpCodes, generic_on_cmd, generic_off_cmd, add_gomspace_cmd_defs, pack_common_power_cmds, SetIds, add_common_power_defs, ) from eive_tmtc.gomspace.gomspace_common import * from eive_tmtc.gomspace.gomspace_pdu_definitions import * from tmtccmd.config import OpCodeEntry, TmtcDefinitionWrapper from tmtccmd.config.tmtc import tmtc_definitions_provider class Pdu2InfoBase: PL_PCDU_BAT_NOM = "Switch PL PCDU Nominal Battery Channel" RW = "Switch Reaction Wheel" HEATER = "Switch Heater" SUS_R = "Switch Sun Sensor Board Redundant" SOLAR_ARRAY_DEPL = "Switch Solar Array Deployment" PL_PCDU_BAT_RED = "Switch PL PCDU Redundant Battery Channel" ACS_B = "Switch ACS Board B-Side" PL_CAM = "Switch Payload Camera" class Pdu2ChIndex(enum.IntEnum): OBC = 0 PL_PCDU_BAT_NOM = 1 RW = 2 HEATER = 3 SUS_R = 4 SOLAR_ARRAY_DEPL = 5 PL_PCDU_BAT_RED = 6 ACS_B = 7 PL_CAM = 8 class PDU2TestProcedure: """ @brief Use this class to define the tests to perform for the PDU2. @details Setting all to True will run all tests. Setting all to False will only run the tests set to True. """ all = False reboot = False read_gnd_wdt = False gnd_wdt_reset = False ping = False channel_2_off = False # Reaction wheels 5V read_temperature = False read_channel_2_state = False # Reaction wheels 5V read_cur_lu_lim_0 = False # OBC channel_2_on = False # Reaction wheels 5V invalid_table_id_test = ( False # Test to check if software properly handles invalid table ids ) invalid_address_test = ( False # Test to check if software properly handles invalid addresses ) invalid_parameter_size_test = False request_hk_table = False def pack_pdu2_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str): q.add_log_cmd("Testing PDU2") objb = object_id.as_bytes pdu2_cmds(q, op_code) pdu2_req_hk_cmds(q, op_code) pack_common_power_cmds("PDU2", object_id, q, op_code) pack_common_gomspace_cmds("PDU2", object_id, q, op_code) if PDU2TestProcedure.all or PDU2TestProcedure.reboot: q.add_log_cmd("PDU2: Reboot") q.add_pus_tc(pack_reboot_command(object_id)) if PDU2TestProcedure.all or PDU2TestProcedure.read_gnd_wdt: q.add_log_cmd("PDU2: Reading ground watchdog timer value") q.add_pus_tc( pack_get_param_command( objb, TableIds.HK, PduHkTable.wdt_gnd_left.parameter_address, PduHkTable.wdt_gnd_left.parameter_size, ) ) if PDU2TestProcedure.all or PDU2TestProcedure.gnd_wdt_reset: q.add_log_cmd("PDU2: Testing ground watchdog reset") q.add_pus_tc(pack_gnd_wdt_reset_command(object_id)) if PDU2TestProcedure.all or PDU2TestProcedure.ping: q.add_log_cmd("PDU2: Ping Test") ping_data = bytearray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) q.add_pus_tc(pack_ping_command(object_id, ping_data)) if PDU2TestProcedure.all or PDU2TestProcedure.read_temperature: q.add_log_cmd("PDU2: Testing temperature reading") q.add_pus_tc( pack_get_param_command( objb, TableIds.HK, PduHkTable.temperature.parameter_address, PduHkTable.temperature.parameter_size, ) ) if PDU2TestProcedure.all or PDU2TestProcedure.read_channel_2_state: q.add_log_cmd("PDU2: Reading output channel 2 state (TCS Heater)") q.add_pus_tc( pack_get_param_command( objb, TableIds.CONFIG, PduConfigTable.out_en_2.parameter_address, PduConfigTable.out_en_2.parameter_size, ) ) if PDU2TestProcedure.all or PDU2TestProcedure.read_cur_lu_lim_0: q.add_log_cmd("PDU2: Reading current limit value of output channel 0 (OBC)") q.add_pus_tc( pack_get_param_command( objb, TableIds.CONFIG, PduConfigTable.cur_lu_lim_0.parameter_address, PduConfigTable.cur_lu_lim_0.parameter_size, ) ) if PDU2TestProcedure.all or PDU2TestProcedure.request_hk_table: q.add_log_cmd("PDU2: Requesting housekeeping table") q.add_pus_tc(pack_request_full_hk_table_command(object_id)) @tmtc_definitions_provider def add_pdu2_cmds(defs: TmtcDefinitionWrapper): oce = OpCodeEntry() add_pdu2_common_defs(oce) add_common_power_defs(oce) add_gomspace_cmd_defs(oce) oce.add( keys=PowerOpCodes.PRINT_SWITCH_V_I, info="PDU2: Print Switches, Voltages, Currents", ) oce.add( keys=PowerOpCodes.PRINT_LATCHUPS, info="PDU2: Print Latchups", ) defs.add_service( name="pdu2", info="PDU2 Device", op_code_entry=oce, ) def pdu2_cmds(q: DefaultPusQueueHelper, op_code: str): if op_code in PowerOpCodes.PL_PCDU_VBAT_NOM_ON: pl_pcdu_bat_nom_on_cmd(q) elif op_code in PowerOpCodes.PL_PCDU_VBAT_NOM_OFF: pl_pcdu_bat_nom_off_cmd(q) elif op_code in PowerOpCodes.RW_ON: reaction_wheel_on_cmd(q) elif op_code in PowerOpCodes.RW_OFF: reaction_wheel_off_cmd(q) elif op_code in PowerOpCodes.HEATER_ON: heater_on_cmd(q) elif op_code in PowerOpCodes.HEATER_OFF: heater_off_cmd(q) elif op_code in PowerOpCodes.SUS_R_ON: sus_red_on_cmd(q) elif op_code in PowerOpCodes.SUS_R_OFF: sus_red_off_cmd(q) elif op_code in PowerOpCodes.SOLAR_ARRAY_DEPL_ON: solar_array_deployment_on_cmd(q) elif op_code in PowerOpCodes.SOLAR_ARRAY_DEPL_OFF: solar_array_deployment_off_cmd(q) elif op_code in PowerOpCodes.PL_PCDU_VBAT_RED_ON: pl_pcdu_bat_red_on_cmd(q) elif op_code in PowerOpCodes.PL_PCDU_VBAT_RED_OFF: pl_pcdu_bat_nom_off_cmd(q) elif op_code in PowerOpCodes.ACS_B_ON: acs_board_b_side_on_cmd(q) elif op_code in PowerOpCodes.ACS_B_OFF: acs_board_b_side_off_cmd(q) elif op_code in PowerOpCodes.PL_CAM_ON: payload_camera_on_cmd(q) elif op_code in PowerOpCodes.PL_CAM_OFF: payload_camera_off_cmd(q) def info_on_pdu2(base: str) -> str: return "PDU2: " + base + " on" def info_off_pdu2(base: str) -> str: return "PDU2: " + base + " off" def add_pdu2_common_defs(oce: OpCodeEntry): oce.add(keys=PowerOpCodes.ACS_B_ON, info=info_on_pdu2(Pdu2InfoBase.ACS_B)) oce.add(keys=PowerOpCodes.ACS_B_OFF, info=info_off_pdu2(Pdu2InfoBase.ACS_B)) oce.add(keys=PowerOpCodes.SUS_R_ON, info=info_on_pdu2(Pdu2InfoBase.SUS_R)) oce.add(keys=PowerOpCodes.SUS_R_OFF, info=info_off_pdu2(Pdu2InfoBase.SUS_R)) oce.add(keys=PowerOpCodes.RW_ON, info=info_on_pdu2(Pdu2InfoBase.RW)) oce.add(keys=PowerOpCodes.RW_OFF, info=info_off_pdu2(Pdu2InfoBase.RW)) oce.add( keys=PowerOpCodes.PL_PCDU_VBAT_NOM_ON, info=info_on_pdu2(Pdu2InfoBase.PL_PCDU_BAT_NOM), ) oce.add( keys=PowerOpCodes.PL_PCDU_VBAT_NOM_OFF, info=info_off_pdu2(Pdu2InfoBase.PL_PCDU_BAT_NOM), ) oce.add( keys=PowerOpCodes.PL_PCDU_VBAT_RED_ON, info=info_on_pdu2(Pdu2InfoBase.PL_PCDU_BAT_RED), ) oce.add( keys=PowerOpCodes.PL_PCDU_VBAT_RED_OFF, info=info_off_pdu2(Pdu2InfoBase.PL_PCDU_BAT_RED), ) oce.add(keys=PowerOpCodes.HEATER_ON, info=info_on_pdu2(Pdu2InfoBase.HEATER)) oce.add(keys=PowerOpCodes.HEATER_OFF, info=info_off_pdu2(Pdu2InfoBase.HEATER)) oce.add( keys=PowerOpCodes.SOLAR_ARRAY_DEPL_ON, info=info_on_pdu2(Pdu2InfoBase.SOLAR_ARRAY_DEPL), ) oce.add( keys=PowerOpCodes.SOLAR_ARRAY_DEPL_OFF, info=info_off_pdu2(Pdu2InfoBase.SOLAR_ARRAY_DEPL), ) oce.add(keys=PowerOpCodes.PL_CAM_ON, info=info_on_pdu2(Pdu2InfoBase.PL_CAM)) oce.add(keys=PowerOpCodes.PL_CAM_OFF, info=info_off_pdu2(Pdu2InfoBase.PL_CAM)) def pdu2_req_hk_cmds(q: DefaultPusQueueHelper, op_code: str): req_hk_cmds("PDU2", q, op_code, PDU_2_HANDLER_ID, [SetIds.CORE, SetIds.AUX]) def pl_pcdu_bat_nom_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd( PDU_2_HANDLER_ID, q, Pdu2InfoBase.PL_PCDU_BAT_NOM, Pdu2ChIndex.PL_PCDU_BAT_NOM ) def pl_pcdu_bat_nom_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd( PDU_2_HANDLER_ID, q, Pdu2InfoBase.PL_PCDU_BAT_NOM, Pdu2ChIndex.PL_PCDU_BAT_NOM ) def reaction_wheel_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.RW, Pdu2ChIndex.RW) def reaction_wheel_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.RW, Pdu2ChIndex.RW) def heater_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.HEATER, Pdu2ChIndex.HEATER) def heater_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.HEATER, Pdu2ChIndex.HEATER) def sus_red_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.SUS_R, Pdu2ChIndex.SUS_R) def sus_red_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.SUS_R, Pdu2ChIndex.SUS_R) def solar_array_deployment_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd( PDU_2_HANDLER_ID, q, Pdu2InfoBase.SOLAR_ARRAY_DEPL, Pdu2ChIndex.SOLAR_ARRAY_DEPL ) def solar_array_deployment_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd( PDU_2_HANDLER_ID, q, Pdu2InfoBase.SOLAR_ARRAY_DEPL, Pdu2ChIndex.SOLAR_ARRAY_DEPL ) def pl_pcdu_bat_red_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd( PDU_2_HANDLER_ID, q, Pdu2InfoBase.PL_PCDU_BAT_RED, Pdu2ChIndex.PL_PCDU_BAT_RED ) def pl_pcdu_bat_red_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd( PDU_2_HANDLER_ID, q, Pdu2InfoBase.PL_PCDU_BAT_RED, Pdu2ChIndex.PL_PCDU_BAT_RED ) def acs_board_b_side_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.ACS_B, Pdu2ChIndex.ACS_B) def acs_board_b_side_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.ACS_B, Pdu2ChIndex.ACS_B) def payload_camera_on_cmd(q: DefaultPusQueueHelper): generic_on_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.PL_CAM, Pdu2ChIndex.PL_CAM) def payload_camera_off_cmd(q: DefaultPusQueueHelper): generic_off_cmd(PDU_2_HANDLER_ID, q, Pdu2InfoBase.PL_CAM, Pdu2ChIndex.PL_CAM)