-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Report Non run error on ABR robots. (#15356)
<!-- Thanks for taking the time to open a pull request! Please make sure you've read the "Opening Pull Requests" section of our Contributing Guide: https://github.com/Opentrons/opentrons/blob/edge/CONTRIBUTING.md#opening-pull-requests To ensure your code is reviewed quickly and thoroughly, please fill out the sections below to the best of your ability! --> # Overview Gives the option to report a non run error for a robot. # Test Plan <!-- If a user wants to report a non run error (ie: issue with calibration sequence, ODD, module not reaching temp, etc), the script now gives the ability to label the ticket with a unique title, rather than using the most recent run id failure. When the error is recording, it will not write on the ABR google sheet or download a run log. --> # Changelog <!-- List out the changes to the code in this PR. Please try your best to categorize your changes and describe what has changed and why. Example changelog: - Fixed app crash when trying to calibrate an illegal pipette - Added state to API to track pipette usage - Updated API docs to mention only two pipettes are supported IMPORTANT: MAKE SURE ANY BREAKING CHANGES ARE PROPERLY COMMUNICATED --> # Review requests <!-- Describe any requests for your reviewers here. --> # Risk assessment <!-- Carefully go over your pull request and look at the other parts of the codebase it may affect. Look for the possibility, even if you think it's small, that your change may affect some other part of the system - for instance, changing return tip behavior in protocol may also change the behavior of labware calibration. Identify the other parts of the system your codebase may affect, so that in addition to your own review and testing, other people who may not have the system internalized as much as you can focus their attention and testing there. -->
- Loading branch information
Showing
1 changed file
with
130 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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", | ||
"[email protected]", | ||
) | ||
# 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", | ||
"[email protected]", | ||
) | ||
# 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.") |