From 5edecc0ab7a41cf0b959b7eb7fc449f2d0b8a346 Mon Sep 17 00:00:00 2001 From: Rhyann Clarke <146747548+rclarke0@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:23:58 -0400 Subject: [PATCH] Report Non run error on ABR robots. (#15356) # Overview Gives the option to report a non run error for a robot. # Test Plan # Changelog # Review requests # Risk assessment --- .../data_collection/abr_robot_error.py | 175 +++++++++++++----- 1 file changed, 130 insertions(+), 45 deletions(-) diff --git a/abr-testing/abr_testing/data_collection/abr_robot_error.py b/abr-testing/abr_testing/data_collection/abr_robot_error.py index e975455b765..d2b44a34e43 100644 --- a/abr-testing/abr_testing/data_collection/abr_robot_error.py +++ b/abr-testing/abr_testing/data_collection/abr_robot_error.py @@ -1,5 +1,5 @@ """Create ticket for robot with error.""" -from typing import List, Tuple +from typing import List, Tuple, Any from abr_testing.data_collection import read_robot_logs, abr_google_drive, get_run_logs import requests import argparse @@ -38,7 +38,62 @@ def get_error_runs_from_robot(ip: str) -> List[str]: return error_run_ids -def get_error_info_from_robot( +def get_robot_state( + ip: str, reported_string: str +) -> Tuple[Any, Any, Any, List[str], str]: + """Get robot status in case of non run error.""" + description = dict() + # Get instruments attached to robot + try: + response = requests.get( + f"http://{ip}:31950/health", headers={"opentrons-version": "3"} + ) + print(f"Connected to {ip}") + except Exception: + print(f"ERROR: Failed to read IP address: {ip}") + sys.exit() + response = requests.get( + f"http://{ip}:31950/health", headers={"opentrons-version": "3"} + ) + health_data = response.json() + parent = health_data.get("name", "") + # Create summary name + description["robot_name"] = parent + summary = parent + "_" + reported_string + affects_version = health_data.get("api_version", "") + description["affects_version"] = affects_version + # Instruments Attached + response = requests.get( + f"http://{ip}:31950/instruments", headers={"opentrons-version": "3"} + ) + + instrument_data = response.json() + for instrument in instrument_data["data"]: + description[instrument["mount"]] = instrument + # Get modules attached to robot + response = requests.get( + f"http://{ip}:31950/modules", headers={"opentrons-version": "3"} + ) + module_data = response.json() + for module in module_data["data"]: + print(module) + description[module["moduleType"]] = module + components = ["Flex-RABR"] + whole_description_str = ( + "{" + + "\n".join("{!r}: {!r},".format(k, v) for k, v in description.items()) + + "}" + ) + return ( + summary, + parent, + affects_version, + components, + whole_description_str, + ) + + +def get_run_error_info_from_robot( ip: str, one_run: str, storage_directory: str ) -> Tuple[str, str, str, List[str], str, str]: """Get error information from robot to fill out ticket.""" @@ -136,6 +191,11 @@ def get_error_info_from_robot( storage_directory = args.storage_directory[0] ip = str(input("Enter Robot IP: ")) assignee = str(input("Enter Assignee Full Name:")) + run_or_other = str( + input( + "Press ENTER to report run error. If not a run error, type short summary of error: " + ) + ) url = "https://opentrons.atlassian.net" api_token = args.jira_api_token[0] email = args.email[0] @@ -145,20 +205,30 @@ def get_error_info_from_robot( ticket.issues_on_board(board_id) users_file_path = ticket.get_jira_users(storage_directory) assignee_id = get_user_id(users_file_path, assignee) + run_log_file_path = "" try: error_runs = get_error_runs_from_robot(ip) except requests.exceptions.InvalidURL: print("Invalid IP address.") sys.exit() one_run = error_runs[-1] # Most recent run with error. - ( - summary, - robot, - affects_version, - components, - whole_description_str, - run_log_file_path, - ) = get_error_info_from_robot(ip, one_run, storage_directory) + if len(run_or_other) < 1: + ( + summary, + robot, + affects_version, + components, + whole_description_str, + run_log_file_path, + ) = get_run_error_info_from_robot(ip, one_run, storage_directory) + else: + ( + summary, + robot, + affects_version, + components, + whole_description_str, + ) = get_robot_state(ip, run_or_other) # Get Calibration Data saved_file_path_calibration, calibration = read_robot_logs.get_calibration_offsets( ip, storage_directory @@ -185,45 +255,60 @@ def get_error_info_from_robot( # OPEN TICKET issue_url = ticket.open_issue(issue_key) # MOVE FILES TO ERROR FOLDER. + error_files = [saved_file_path_calibration, run_log_file_path] + file_paths error_folder_path = os.path.join(storage_directory, issue_key) os.makedirs(error_folder_path, exist_ok=True) for source_file in error_files: - destination_file = os.path.join( - error_folder_path, os.path.basename(source_file) - ) - shutil.move(source_file, destination_file) + try: + destination_file = os.path.join( + error_folder_path, os.path.basename(source_file) + ) + shutil.move(source_file, destination_file) + except shutil.Error: + continue # OPEN FOLDER DIRECTORY subprocess.Popen(["explorer", error_folder_path]) - # CONNECT TO GOOGLE DRIVE - credentials_path = os.path.join(storage_directory, "credentials.json") - google_sheet_name = "ABR-run-data" - google_drive = google_drive_tool.google_drive( - credentials_path, - "1Cvej0eadFOTZr9ILRXJ0Wg65ymOtxL4m", - "rhyann.clarke@opentrons.ocm", - ) - # CONNECT TO GOOGLE SHEET - google_sheet = google_sheets_tool.google_sheet( - credentials_path, google_sheet_name, 0 - ) + # WRITE ERRORED RUN TO GOOGLE SHEET - error_run_log = os.path.join(error_folder_path, os.path.basename(run_log_file_path)) - google_drive.upload_file(error_run_log, "1Cvej0eadFOTZr9ILRXJ0Wg65ymOtxL4m") - run_id = os.path.basename(error_run_log).split("_")[1].split(".")[0] - ( - runs_and_robots, - headers, - runs_and_lpc, - headers_lpc, - ) = abr_google_drive.create_data_dictionary( - run_id, error_folder_path, issue_url, "", "" - ) - - start_row = google_sheet.get_index_row() + 1 - google_sheet.batch_update_cells(runs_and_robots, "A", start_row, "0") - print("Wrote run to ABR-run-data") - # Add LPC to google sheet - google_sheet_lpc = google_sheets_tool.google_sheet(credentials_path, "ABR-LPC", 0) - start_row_lpc = google_sheet_lpc.get_index_row() + 1 - google_sheet_lpc.batch_update_cells(runs_and_lpc, "A", start_row_lpc, "0") + if len(run_or_other) < 1: + # CONNECT TO GOOGLE DRIVE + credentials_path = os.path.join(storage_directory, "credentials.json") + google_sheet_name = "ABR-run-data" + google_drive = google_drive_tool.google_drive( + credentials_path, + "1Cvej0eadFOTZr9ILRXJ0Wg65ymOtxL4m", + "rhyann.clarke@opentrons.ocm", + ) + # CONNECT TO GOOGLE SHEET + google_sheet = google_sheets_tool.google_sheet( + credentials_path, google_sheet_name, 0 + ) + error_run_log = os.path.join( + error_folder_path, os.path.basename(run_log_file_path) + ) + try: + google_drive.upload_file(error_run_log, "1Cvej0eadFOTZr9ILRXJ0Wg65ymOtxL4m") + except FileNotFoundError: + print("Run file not uploaded.") + run_id = os.path.basename(error_run_log).split("_")[1].split(".")[0] + ( + runs_and_robots, + headers, + runs_and_lpc, + headers_lpc, + ) = abr_google_drive.create_data_dictionary( + run_id, error_folder_path, issue_url, "", "" + ) + + start_row = google_sheet.get_index_row() + 1 + google_sheet.batch_update_cells(runs_and_robots, "A", start_row, "0") + print("Wrote run to ABR-run-data") + # Add LPC to google sheet + google_sheet_lpc = google_sheets_tool.google_sheet( + credentials_path, "ABR-LPC", 0 + ) + start_row_lpc = google_sheet_lpc.get_index_row() + 1 + google_sheet_lpc.batch_update_cells(runs_and_lpc, "A", start_row_lpc, "0") + else: + print("Ticket created.")