diff --git a/obsw_tmtc_client.py b/obsw_tmtc_client.py index e502717fda8cd2ba2db5c963c394fec2eec3ea43..600db5aef0cd0e10ae9f4602259a7a36c595a72e 100755 --- a/obsw_tmtc_client.py +++ b/obsw_tmtc_client.py @@ -48,7 +48,7 @@ from tmtc_core.utility.obsw_logger import set_tmtc_logger, get_logger from test.obsw_pus_service_test import run_selected_pus_tests from tc.obsw_pus_tc_packer import create_total_tc_queue, ServiceQueuePacker from utility.obsw_args_parser import parse_input_arguments -from utility.obsw_binary_uploader import perform_file_upload +from utility.obsw_binary_uploader import BinaryFileUploader from gui.obsw_tmtc_gui import TmTcGUI from gui.obsw_backend_test import TmTcBackend @@ -205,7 +205,9 @@ class TmTcHandler: elif self.mode == g.ModeList.BinaryUploadMode: # Upload binary, prompt user for input, in the end prompt for new mode and enter that # mode - perform_file_upload(self.communication_interface, self.tmtc_printer, self.tm_listener) + file_uploader = BinaryFileUploader(self.communication_interface, self.tmtc_printer, + self.tm_listener) + file_uploader.perform_file_upload() self.command_received = True self.mode = g.ModeList.ListenerMode diff --git a/utility/obsw_binary_uploader.py b/utility/obsw_binary_uploader.py index 5930a349caa31871a46dea965b41b10ae199ce12..0ad1b6aeeb638c9d6ecc9f1ec7d5fb126a528252 100644 --- a/utility/obsw_binary_uploader.py +++ b/utility/obsw_binary_uploader.py @@ -25,193 +25,192 @@ LOGGER = get_logger() class BinaryFileUploader: - def __init__(self): - pass - - -def perform_file_upload(com_if: CommunicationInterface, tmtc_printer: TmTcPrinter, - tm_listener: TmListener): - """ - TODO: This should be a class.. - @param com_if: - @param tmtc_printer: - @param tm_listener: - @return: - """ - gui_cl_prompt = input("GUI(0) or command line version (1)? [0/1]: ") - if gui_cl_prompt == 0: - gui_cl_prompt = True - else: - gui_cl_prompt = False - print("Please select file to upload: ") - file_path = "" - if gui_cl_prompt: - root = tk.Tk() - root.withdraw() - root.wm_attributes('-topmost', 1) - file_path = filedialog.askopenfilename(parent=root) - print("File select: " + str(file_path)) - if file_path == (): - LOGGER.warning("Invalid file path, exiting binary upload mode.") - return - else: - result = [y for x in os.walk("../_bin") for y in glob(os.path.join(x[0], '*.bin'))] - print("Files found in _bin folder: ") - for idx, path in enumerate(result): - print("Selection " + str(idx) + ": " + str(path)) - select_valid = False - selection = input("Please enter desired selection [c to cancel]: ") - while not select_valid: - if selection == 'c': - print("Exiting binary upload mode..") + def __init__(self, com_if: CommunicationInterface, tmtc_printer: TmTcPrinter, + tm_listener: TmListener): + """ + Initializes the binary file uploader with the required components. + @param com_if: + @param tmtc_printer: + @param tm_listener: + """ + self.com_if = com_if + self.tmtc_printer = tmtc_printer + self.tm_listener = tm_listener + + def perform_file_upload(self): + gui_cl_prompt = input("GUI(0) or command line version (1)? [0/1]: ") + if gui_cl_prompt == 0: + gui_cl_prompt = True + else: + gui_cl_prompt = False + print("Please select file to upload: ") + file_path = "" + if gui_cl_prompt: + root = tk.Tk() + root.withdraw() + root.wm_attributes('-topmost', 1) + file_path = filedialog.askopenfilename(parent=root) + print("File select: " + str(file_path)) + if file_path == (): + LOGGER.warning("Invalid file path, exiting binary upload mode.") return - if not selection.isdigit(): - selection = input("Invalid input, try again [c to cancel]: ") - if selection.isdigit(): - if int(selection) < len(result): - file_path = result[int(selection)] - select_valid = True - else: + else: + result = [y for x in os.walk("../_bin") for y in glob(os.path.join(x[0], '*.bin'))] + print("Files found in _bin folder: ") + for idx, path in enumerate(result): + print("Selection " + str(idx) + ": " + str(path)) + select_valid = False + selection = input("Please enter desired selection [c to cancel]: ") + while not select_valid: + if selection == 'c': + print("Exiting binary upload mode..") + return + if not selection.isdigit(): selection = input("Invalid input, try again [c to cancel]: ") + if selection.isdigit(): + if int(selection) < len(result): + file_path = result[int(selection)] + select_valid = True + else: + selection = input("Invalid input, try again [c to cancel]: ") + + print_string = file_path.rsplit(os.path.sep, 1)[-1] + " was selected." + LOGGER.info(print_string) + calc_hamming_code = input("Calculate and send hamming code? [y/n]: ") + if calc_hamming_code in ['y', 'yes', 1]: + calc_hamming_code = True + print("Hamming code will be calculated and sent in tail packet") + else: + calc_hamming_code = False + print("Hamming code will not be calculated") - print_string = file_path.rsplit(os.path.sep, 1)[-1] + " was selected." - LOGGER.info(print_string) - calc_hamming_code = input("Calculate and send hamming code? [y/n]: ") - if calc_hamming_code in ['y', 'yes', 1]: - calc_hamming_code = True - print("Hamming code will be calculated and sent in tail packet") - else: - calc_hamming_code = False - print("Hamming code will not be calculated") - - iobc_prompt = input("iOBC? [y/n]: ") - if iobc_prompt in ['y', 'yes', 1]: - iobc_prompt = True - else: - iobc_prompt = False - - bootloader_prompt = input("Bootloader (0) or Software Image (1)? [0/1]: ") - if str(bootloader_prompt) == "0": - bootloader_prompt = True - else: - bootloader_prompt = False - - prompt_lock = input("Lock file with last packet? [y/n]: ") - if prompt_lock in ['n', "no", 0]: - prompt_lock = False - else: - prompt_lock = True - - if bootloader_prompt: - file_name = "bl.bin" - else: - file_name = "obsw_up.bin" - - if iobc_prompt: - if bootloader_prompt: - repository_name = "BIN/IOBC/BL" + iobc_prompt = input("iOBC? [y/n]: ") + if iobc_prompt in ['y', 'yes', 1]: + iobc_prompt = True else: - repository_name = "BIN/IOBC/OBSW" - else: + iobc_prompt = False + + bootloader_prompt = input("Bootloader (0) or Software Image (1)? [0/1]: ") + if str(bootloader_prompt) == "0": + bootloader_prompt = True + else: + bootloader_prompt = False + + prompt_lock = input("Lock file with last packet? [y/n]: ") + if prompt_lock in ['n', "no", 0]: + prompt_lock = False + else: + prompt_lock = True + if bootloader_prompt: - repository_name = "BIN/AT91/BL" + file_name = "bl.bin" + else: + file_name = "obsw_up.bin" + + if iobc_prompt: + if bootloader_prompt: + repository_name = "BIN/IOBC/BL" + else: + repository_name = "BIN/IOBC/OBSW" + else: + if bootloader_prompt: + repository_name = "BIN/AT91/BL" + else: + repository_name = "BIN/AT91/OBSW" + + # Right now, the size of PUS packets is limited to 1500 bytes which also limits the app + # data length. + frame_length = g.G_MAX_APP_DATA_LENGTH + + if calc_hamming_code: + # now we calculate the hamming code + pass + + tc_queue = deque() + + # Delete existing binary file first, otherwise data might be appended to otherwise + # valid file which already exists. + file_transfer_helper = FileTransferHelper( + tc_queue=tc_queue, max_size_of_app_data=frame_length, target_repository=repository_name, + target_filename=file_name) + + init_ssc = 0 + self.tmtc_printer.set_display_mode(DisplayMode.SHORT) + + # Configure file transfer helper + file_transfer_helper.set_data_from_file(file_path) + file_transfer_helper.set_to_delete_old_file() + if prompt_lock: + file_transfer_helper.set_to_lock_file(prompt_lock) + else: + file_transfer_helper.set_to_lock_file(prompt_lock) + + # Generate the packets. + file_transfer_helper.generate_packets(init_ssc) + + self.tm_listener.set_listener_mode(TmListener.ListenerModes.MANUAL) + print_string = "BinaryUploader: Detected file size: " + str( + file_transfer_helper.file_size()) + LOGGER.info(print_string) + total_num_packets = file_transfer_helper.get_number_of_packets_generated() + print_string = "BinaryUploader: " + str(total_num_packets) + \ + " packets generated." + if prompt_lock: + print_string += " File will be locked." else: - repository_name = "BIN/AT91/OBSW" - - # Right now, the size of PUS packets is limited to 1500 bytes which also limits the app - # data length. - frame_length = g.G_MAX_APP_DATA_LENGTH - - if calc_hamming_code: - # now we calculate the hamming code - pass - - tc_queue = deque() - - # Delete existing binary file first, otherwise data might be appended to otherwise - # valid file which already exists. - file_transfer_helper = FileTransferHelper( - tc_queue=tc_queue, max_size_of_app_data=frame_length, target_repository=repository_name, - target_filename=file_name) - - init_ssc = 0 - tmtc_printer.set_display_mode(DisplayMode.SHORT) - - # Configure file transfer helper - file_transfer_helper.set_data_from_file(file_path) - file_transfer_helper.set_to_delete_old_file() - if prompt_lock: - file_transfer_helper.set_to_lock_file(prompt_lock) - else: - file_transfer_helper.set_to_lock_file(prompt_lock) - - # Generate the packets. - file_transfer_helper.generate_packets(init_ssc) - - tm_listener.set_listener_mode(TmListener.ListenerModes.MANUAL) - print_string = "BinaryUploader: Detected file size: " + str(file_transfer_helper.file_size()) - LOGGER.info(print_string) - total_num_packets = file_transfer_helper.get_number_of_packets_generated() - print_string = "BinaryUploader: " + str(total_num_packets) + \ - " packets generated." - if prompt_lock: - print_string += " File will be locked." - else: - print_string += " File will not be locked." - LOGGER.info(print_string) - - reception_deque = deque() - perform_send_algorithm(tc_queue, total_num_packets, com_if, tmtc_printer, tm_listener, - reception_deque) - - print_string = "BinaryUploader: All binary packets were sent!" - LOGGER.info(print_string) - print_string = str(reception_deque.__len__()) + " replies received." - - LOGGER.info(print_string) - time.sleep(15) - reception_deque.extend(tm_listener.retrieve_tm_packet_queue()) - for tm_list in reception_deque: - for tm_packet in tm_list: - if tm_packet.get_service() == 23 and tm_packet.get_subservice() == 132: - # tmtc_printer.print_telemetry(tm_packet) - pass - tm_listener.clear_tm_packet_queue() - LOGGER.info("Transitioning back to listener mode..") - - -def perform_send_algorithm(tc_queue: Deque, number_of_packets: int, com_if: CommunicationInterface, - tmtc_printer: TmTcPrinter, tm_listener: TmListener, - reception_deque: Deque): - interval = 0.6 - last_check = time.time() - last_sent = time.time() - total_time = interval * number_of_packets - idx = 1 - while tc_queue: - next_send = last_sent + interval - (tc_packet, tc_info) = tc_queue.pop() - if not isinstance(tc_packet, str): - # print_string = "Sending packet " + str(idx) + ".." - # LOGGER.info(print_string) - idx += 1 - com_if.send_telecommand(tc_packet, tc_info) - tmtc_printer.print_telecommand(tc_packet, tc_info) - elif tc_packet == "print": - LOGGER.info(tc_info) - remaining_time_string = "Remaining time: " + \ - str(round(total_time - (idx - 2) * interval, 2)) + \ - " seconds" - print_progress_bar(idx - 2, number_of_packets, print_end="\n", suffix=remaining_time_string) - # sys.stdout.write("\033[F") # Cursor up one line - packets_received = tm_listener.retrieve_tm_packet_queue() - reception_deque.extend(packets_received) - # Every 5 seconds, check whether any reply has been received. If not, cancel operation. - if time.time() - last_check > 5.0 and len(packets_received) == 0: - LOGGER.warning("No replies are being received, cancelling upload operation..") - time_to_sleep = next_send - time.time() - last_sent = next_send - time.sleep(time_to_sleep) + print_string += " File will not be locked." + LOGGER.info(print_string) + + reception_deque = deque() + self.__perform_send_algorithm(tc_queue, total_num_packets, reception_deque) + + print_string = "BinaryUploader: All binary packets were sent!" + LOGGER.info(print_string) + print_string = str(reception_deque.__len__()) + " replies received." + + LOGGER.info(print_string) + time.sleep(15) + reception_deque.extend(self.tm_listener.retrieve_tm_packet_queue()) + for tm_list in reception_deque: + for tm_packet in tm_list: + if tm_packet.get_service() == 23 and tm_packet.get_subservice() == 132: + # tmtc_printer.print_telemetry(tm_packet) + pass + self.tm_listener.clear_tm_packet_queue() + LOGGER.info("Transitioning back to listener mode..") + + def __perform_send_algorithm(self, tc_queue: Deque, number_of_packets: int, reception_deque: + Deque): + interval = 0.6 + last_check = time.time() + last_sent = time.time() + total_time = interval * number_of_packets + idx = 1 + while tc_queue: + next_send = last_sent + interval + (tc_packet, tc_info) = tc_queue.pop() + if not isinstance(tc_packet, str): + # print_string = "Sending packet " + str(idx) + ".." + # LOGGER.info(print_string) + idx += 1 + self.com_if.send_telecommand(tc_packet, tc_info) + self.tmtc_printer.print_telecommand(tc_packet, tc_info) + elif tc_packet == "print": + LOGGER.info(tc_info) + remaining_time_string = "Remaining time: " + \ + str(round(total_time - (idx - 2) * interval, 2)) + \ + " seconds" + print_progress_bar(idx - 2, number_of_packets, print_end="\n", + suffix=remaining_time_string) + # sys.stdout.write("\033[F") # Cursor up one line + packets_received = self.tm_listener.retrieve_tm_packet_queue() + reception_deque.extend(packets_received) + # Every 5 seconds, check whether any reply has been received. If not, cancel operation. + if time.time() - last_check > 5.0 and len(packets_received) == 0: + LOGGER.warning("No replies are being received, cancelling upload operation..") + time_to_sleep = next_send - time.time() + last_sent = next_send + time.sleep(time_to_sleep) # https://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console