Skip to content

Commit

Permalink
Merge branch 'add_modules_to_deck_config' of https://github.com/Opent…
Browse files Browse the repository at this point in the history
…rons/opentrons into add_modules_to_deck_config
  • Loading branch information
CaseyBatten committed Apr 12, 2024
2 parents 584986f + ce3116c commit 12e7aed
Show file tree
Hide file tree
Showing 198 changed files with 3,571 additions and 1,269 deletions.
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
stories: [
'../components/**/*.stories.@(js|jsx|ts|tsx)',
'../app/**/*.stories.@(js|jsx|ts|tsx)',
'../opentrons-ai-client/**/*.stories.@(js|jsx|ts|tsx)',
],

addons: [
Expand Down
2 changes: 1 addition & 1 deletion .storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const parameters = {
options: {
storySort: {
method: 'alphabetical',
order: ['Design Tokens', 'Library', 'App', 'ODD'],
order: ['Design Tokens', 'Library', 'App', 'ODD', 'AI'],
},
},
}
Expand Down
11 changes: 10 additions & 1 deletion abr-testing/abr_testing/data_collection/abr_google_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def create_data_dictionary(
file_results = json.load(file)
else:
continue
if not isinstance(file_results, dict):
continue
run_id = file_results.get("run_id", "NaN")
if run_id in runs_to_save:
robot = file_results.get("robot_name")
Expand Down Expand Up @@ -107,7 +109,14 @@ def create_data_dictionary(
hs_dict = read_robot_logs.hs_commands(file_results)
tm_dict = read_robot_logs.temperature_module_commands(file_results)
notes = {"Note1": "", "Jira Link": issue_url}
row_2 = {**row, **all_modules, **notes, **hs_dict, **tm_dict, **tc_dict}
row_2 = {
**row,
**all_modules,
**notes,
**hs_dict,
**tm_dict,
**tc_dict,
}
headers = list(row_2.keys())
runs_and_robots[run_id] = row_2
else:
Expand Down
20 changes: 9 additions & 11 deletions abr-testing/abr_testing/data_collection/abr_robot_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,6 @@ def get_error_info_from_robot(
nargs=1,
help="Path to long term storage directory for run logs.",
)
parser.add_argument(
"robot_ip",
metavar="ROBOT_IP",
type=str,
nargs=1,
help="IP address of robot as string.",
)
parser.add_argument(
"jira_api_token",
metavar="JIRA_API_TOKEN",
Expand Down Expand Up @@ -130,14 +123,18 @@ def get_error_info_from_robot(
)
args = parser.parse_args()
storage_directory = args.storage_directory[0]
ip = args.robot_ip[0]
ip = str(input("Enter Robot IP: "))
url = "https://opentrons.atlassian.net"
api_token = args.jira_api_token[0]
email = args.email[0]
board_id = args.board_id[0]
reporter_id = args.reporter_id[0]
ticket = jira_tool.JiraTicket(url, api_token, email)
error_runs = get_error_runs_from_robot(ip)
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,
Expand All @@ -147,7 +144,7 @@ def get_error_info_from_robot(
whole_description_str,
run_log_file_path,
) = get_error_info_from_robot(ip, one_run, storage_directory)
# get calibration data
# Get Calibration Data
saved_file_path_calibration, calibration = read_robot_logs.get_calibration_offsets(
ip, storage_directory
)
Expand All @@ -156,6 +153,7 @@ def get_error_info_from_robot(
# TODO: make argument or see if I can get rid of with using board_id.
project_key = "RABR"
parent_key = project_key + "-" + robot[-1]
# TODO: read board to see if ticket for run id already exists.
# CREATE TICKET
issue_key = ticket.create_ticket(
summary,
Expand All @@ -172,7 +170,7 @@ def get_error_info_from_robot(
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, str("RABR-238"))
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(
Expand Down
154 changes: 154 additions & 0 deletions abr-testing/abr_testing/data_collection/module_ramp_rates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
"""Get ramp rates of modules."""
from abr_testing.automation import google_sheets_tool
from abr_testing.data_collection import read_robot_logs
import gspread # type: ignore[import]
import argparse
import os
import sys
import json
from datetime import datetime
from typing import Dict, Any
import requests


def ramp_rate(file_results: Dict[str, Any]) -> Dict[int, float]:
"""Get ramp rates."""
i = 0
commands = file_results["commands"]
for command in commands:
commandType = command["commandType"]
if (
commandType == "thermocycler/setTargetBlockTemperature"
or commandType == "temperatureModule/setTargetTemperature"
or commandType == "heaterShaker/setTargetTemperature"
):
temp = command["params"].get("celsius", 0.0)
if (
commandType == "thermocycler/waitForBlockTemperature"
or commandType == "temperatureModule/waitForTemperature"
or commandType == "heaterShaker/waitForTemperature"
):
start_time = datetime.strptime(
command.get("startedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
end_time = datetime.strptime(
command.get("completedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
duration = (end_time - start_time).total_seconds()
i += 1
temps_and_durations[duration] = temp
ramp_rates = {}
times = list(temps_and_durations.keys())
for i in range(len(times) - 1):
time1 = times[i]
time2 = times[i + 1]
temp1 = temps_and_durations[time1]
temp2 = temps_and_durations[time2]
ramp_rate = (temp2 - temp1) / (time2)
ramp_rates[i] = ramp_rate
return ramp_rates


if __name__ == "__main__":
# SCRIPT ARGUMENTS
parser = argparse.ArgumentParser(description="Read run logs on google drive.")
parser.add_argument(
"storage_directory",
metavar="STORAGE_DIRECTORY",
type=str,
nargs=1,
help="Path to long term storage directory for run logs.",
)
parser.add_argument(
"google_sheet_name",
metavar="GOOGLE_SHEET_NAME",
type=str,
nargs=1,
help="Google sheet name.",
)
parser.add_argument(
"email", metavar="EMAIL", type=str, nargs=1, help="opentrons gmail."
)
args = parser.parse_args()
storage_directory = args.storage_directory[0]
google_sheet_name = args.google_sheet_name[0]
# FIND CREDENTIALS FILE
try:
credentials_path = os.path.join(storage_directory, "credentials.json")
except FileNotFoundError:
print(f"Add credentials.json file to: {storage_directory}.")
sys.exit()
# CONNECT TO GOOGLE SHEET
try:
google_sheet = google_sheets_tool.google_sheet(
credentials_path, google_sheet_name, 1
)
print(f"Connected to google sheet: {google_sheet_name}")
except gspread.exceptions.APIError:
print("ERROR: Check google sheet name. Check credentials file.")
sys.exit()
run_ids_on_sheet = google_sheet.get_column(2)
runs_and_robots = {}
for filename in os.listdir(storage_directory):
file_path = os.path.join(storage_directory, filename)
if file_path.endswith(".json"):
with open(file_path) as file:
file_results = json.load(file)
else:
continue
# CHECK if file is ramp rate run
run_id = file_results.get("run_id", None)
temps_and_durations: Dict[float, float] = dict()
if run_id is not None and run_id not in run_ids_on_sheet:

ramp_rates = ramp_rate(file_results)
protocol_name = file_results["protocol"]["metadata"].get("protocolName", "")
if "Ramp Rate" in protocol_name:
ip = filename.split("_")[0]
if len(ramp_rates) > 1:
cooling_ramp_rate = abs(min(ramp_rates.values()))
heating_ramp_rate = abs(max(ramp_rates.values()))
start_time = datetime.strptime(
file_results.get("startedAt", ""), "%Y-%m-%dT%H:%M:%S.%f%z"
)
start_date = str(start_time.date())
module_serial_number = file_results["modules"][0].get(
"serialNumber", "NaN"
)
try:
response = requests.get(
f"http://{ip}:31950/modules",
headers={"opentrons-version": "3"},
)
modules = response.json()
for module in modules["data"]:
if module["serialNumber"] == module_serial_number:
firmwareVersion = module["firmwareVersion"]
else:
firmwareVersion = "NaN"
except requests.exceptions.ConnectionError:
firmwareVersion = "NaN"
row = {
"Robot": file_results.get("robot_name", ""),
"Run_ID": run_id,
"Protocol_Name": file_results["protocol"]["metadata"].get(
"protocolName", ""
),
"Software Version": file_results.get("API_Version", ""),
"Firmware Version": firmwareVersion,
"Date": start_date,
"Serial Number": module_serial_number,
"Approx. Average Heating Ramp Rate (C/s)": heating_ramp_rate,
"Approx. Average Cooling Ramp Rate (C/s)": cooling_ramp_rate,
}
headers = list(row.keys())
runs_and_robots[run_id] = row
read_robot_logs.write_to_local_and_google_sheet(
runs_and_robots,
storage_directory,
google_sheet_name,
google_sheet,
headers,
)
else:
continue
28 changes: 28 additions & 0 deletions api-client/src/protocols/createProtocolAnalysis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { POST, request } from '../request'

import type { ProtocolAnalysisSummary } from '@opentrons/shared-data'
import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { RunTimeParameterCreateData } from '../runs'

interface CreateProtocolAnalysisData {
runTimeParameterValues: RunTimeParameterCreateData
forceReAnalyze: boolean
}

export function createProtocolAnalysis(
config: HostConfig,
protocolKey: string,
runTimeParameterValues?: RunTimeParameterCreateData,
forceReAnalyze?: boolean
): ResponsePromise<ProtocolAnalysisSummary[]> {
const data = {
runTimeParameterValues: runTimeParameterValues ?? {},
forceReAnalyze: forceReAnalyze ?? false,
}
const response = request<
ProtocolAnalysisSummary[],
{ data: CreateProtocolAnalysisData }
>(POST, `/protocols/${protocolKey}/analyses`, { data }, config)
return response
}
1 change: 1 addition & 0 deletions api-client/src/protocols/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { getProtocolAnalyses } from './getProtocolAnalyses'
export { getProtocolAnalysisAsDocument } from './getProtocolAnalysisAsDocument'
export { deleteProtocol } from './deleteProtocol'
export { createProtocol } from './createProtocol'
export { createProtocolAnalysis } from './createProtocolAnalysis'
export { getProtocols } from './getProtocols'
export { getProtocolIds } from './getProtocolIds'

Expand Down
11 changes: 11 additions & 0 deletions api-client/src/robot/getRobotSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { GET, request } from '../request'

import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { RobotSettingsResponse } from './types'

export function getRobotSettings(
config: HostConfig
): ResponsePromise<RobotSettingsResponse> {
return request<RobotSettingsResponse>(GET, '/settings', null, config)
}
5 changes: 5 additions & 0 deletions api-client/src/robot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ export { getEstopStatus } from './getEstopStatus'
export { acknowledgeEstopDisengage } from './acknowledgeEstopDisengage'
export { getLights } from './getLights'
export { setLights } from './setLights'
export { getRobotSettings } from './getRobotSettings'

export type {
DoorStatus,
EstopPhysicalStatus,
EstopState,
EstopStatus,
Lights,
RobotSettings,
RobotSettingsField,
RobotSettingsResponse,
SetLightsData,
} from './types'
15 changes: 15 additions & 0 deletions api-client/src/robot/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,18 @@ export interface Lights {
export interface SetLightsData {
on: boolean
}

export interface RobotSettingsField {
id: string
title: string
description: string
value: boolean | null
restart_required?: boolean
}

export type RobotSettings = RobotSettingsField[]

export interface RobotSettingsResponse {
settings: RobotSettings
links?: { restart?: string }
}
1 change: 1 addition & 0 deletions api-client/src/subsystems/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type Subsystem =
| 'pipette_right'
| 'gripper'
| 'rear_panel'
| 'hepa_uv'

type UpdateStatus = 'queued' | 'updating' | 'done'
export interface SubsystemUpdateProgressData {
Expand Down
4 changes: 1 addition & 3 deletions api/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ def get_version():
"Intended Audience :: Science/Research",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Scientific/Engineering",
]
Expand Down Expand Up @@ -87,7 +85,7 @@ def read(*parts):

if __name__ == "__main__":
setup(
python_requires=">=3.8",
python_requires=">=3.10",
name=DISTNAME,
description=DESCRIPTION,
license=LICENSE,
Expand Down
4 changes: 4 additions & 0 deletions api/src/opentrons/config/advanced_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ class Setting(NamedTuple):
title="Enable OEM Mode",
description="This setting anonymizes Opentrons branding in the ODD app.",
robot_type=[RobotTypeEnum.FLEX],
show_if=(
"enableOEMMode",
True,
),
internal_only=True,
),
SettingDefinition(
Expand Down
4 changes: 4 additions & 0 deletions api/src/opentrons/config/feature_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@ def enable_error_recovery_experiments() -> bool:

def enable_performance_metrics(robot_type: RobotTypeEnum) -> bool:
return advs.get_setting_with_env_overload("enablePerformanceMetrics", robot_type)


def oem_mode_enabled() -> bool:
return advs.get_setting_with_env_overload("enableOEMMode", RobotTypeEnum.FLEX)
5 changes: 1 addition & 4 deletions api/src/opentrons/protocol_engine/actions/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ class PauseAction:

@dataclass(frozen=True)
class StopAction:
"""Stop the current engine execution.
After a StopAction, the engine status will be marked as stopped.
"""
"""Request engine execution to stop soon."""

from_estop: bool = False

Expand Down
Loading

0 comments on commit 12e7aed

Please sign in to comment.