Skip to content

Commit

Permalink
Merge branch 'edge' into chore_no-unsafe-argument
Browse files Browse the repository at this point in the history
  • Loading branch information
b-cooper committed Jun 18, 2024
2 parents b3827a8 + b9e1b74 commit d2c48f3
Show file tree
Hide file tree
Showing 47 changed files with 1,030 additions and 92 deletions.
9 changes: 9 additions & 0 deletions .storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import { I18nextProvider } from 'react-i18next'
import { GlobalStyle } from '../app/src/atoms/GlobalStyle'
import { i18n } from '../app/src/i18n'

global.APP_SHELL_REMOTE = {
ipcRenderer: {
on: (topic, cb) => {},
invoke: (callname, args) => {},
send: (message, payload) => {}
},
}
global._PKG_VERSION_ = '0.0.0-storybook'

export const customViewports = {
onDeviceDisplay: {
name: 'Touchscreen',
Expand Down
3 changes: 3 additions & 0 deletions api-client/src/dataFiles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { uploadCsvFile } from './uploadCsvFile'

export * from './types'
24 changes: 24 additions & 0 deletions api-client/src/dataFiles/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Represents the parameters for uploading a CSV file.
*
* @interface UploadCsvFileParams
* @property {File | string} [fileData] - File object for Desktop app and string for USB drive on ODD
*/

export type FileData = File | string

interface CsvFileData {
id: string
createdAt: string
name: string
}

export interface UploadedCsvFileResponse {
data: CsvFileData
}

export interface UploadedCsvFilesResponse {
data: {
files: CsvFileData[]
}
}
36 changes: 36 additions & 0 deletions api-client/src/dataFiles/uploadCsvFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { v4 as uuidv4 } from 'uuid'
// import { POST, request } from '../request'

// import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { FileData /** UploadedCsvFileResponse */ } from './types'

// export function uploadCsvFile(
// config: HostConfig,
// data FileData
// ): ResponsePromise<UploadedCsvFileResponse> {
// return request<UploadedCsvFileResponse>(
// POST,
// '/dataFiles',
// null,
// config,
// data
// )
// }

// ToDo (kk:06/14/2024) remove when activate the above code
export function uploadCsvFile(
config: HostConfig,
data: FileData
// Note (kk: 06/14/2024) temporary using any for useUploadCsvFileMutation
): Promise<any> {
const fileId = uuidv4()
const stub = {
data: {
id: fileId,
createdAt: '2024-06-07T19:19:56.268029+00:00',
name: 'rtp_mock_file.csv',
},
}
return Promise.resolve(stub)
}
1 change: 1 addition & 0 deletions api-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// api client entry point
export * from './calibration'
export * from './dataFiles'
export * from './deck_configuration'
export * from './health'
export * from './instruments'
Expand Down
47 changes: 47 additions & 0 deletions api-client/src/protocols/getCsvFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { v4 as uuidv4 } from 'uuid'

// import { GET, request } from '../request'

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

/**
export function getCsvFiles(
config: HostConfig,
protocolId: string
): ResponsePromise<UploadCsvFilesResponse> {
return request<UploadCsvFilesResponse>(
GET,
`/protocols/${protocolId}/dataFiles`,
null,
config
)
}
*/

// ToDo (kk:06/14/2024) remove when activate the above code
export function getCsvFiles(
config: HostConfig,
protocolId: string
): Promise<{ data: UploadedCsvFilesResponse }> {
const fileIdOne = uuidv4()
const fileIdTwo = uuidv4()
const stub = {
data: {
files: [
{
id: fileIdOne,
createdAt: '2024-06-07T19:19:56.268029+00:00',
name: 'rtp_mock_file1.csv',
},
{
id: fileIdTwo,
createdAt: '2024-06-17T19:19:56.268029+00:00',
name: 'rtp_mock_file2.csv',
},
],
},
}
return Promise.resolve({ data: stub })
}
9 changes: 5 additions & 4 deletions api-client/src/protocols/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export { createProtocol } from './createProtocol'
export { createProtocolAnalysis } from './createProtocolAnalysis'
export { deleteProtocol } from './deleteProtocol'
export { getCsvFiles } from './getCsvFiles'
export { getProtocol } from './getProtocol'
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'
export { getProtocols } from './getProtocols'

export * from './types'
export * from './utils'
Expand Down
2 changes: 1 addition & 1 deletion api/docs/v2/new_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ Opentrons electronic pipettes can do some things that a human cannot do with a p
p300.return_tip()
Notice here how Python's :py:class:`slice` functionality (in the code sample as ``[:4]``) lets us select the first five wells of the well plate only. Also, in Python, a range of numbers is *exclusive* of the end value and counting starts at 0, not 1. For the Corning 96-well plate used here, this means well A1=0, B1=1, C1=2, and so on to the last well used, which is E1=4. See also, the :ref:`tutorial-commands` section of the Tutorial.
Notice here how Python's :py:class:`slice` functionality (in the code sample as ``[:5]``) lets us select the first five wells of the well plate only. Also, in Python, a range of numbers is *exclusive* of the end value and counting starts at 0, not 1. For the USA Scientific 12-well reservoir used here, this means well A1=0, A2=1, A3=2, and so on to the last well used, which is A5=4. See also, the :ref:`tutorial-commands` section of the Tutorial.

Dilution
========
Expand Down
2 changes: 0 additions & 2 deletions api/src/opentrons/config/defaults_ot3.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

DEFAULT_LIQUID_PROBE_SETTINGS: Final[LiquidProbeSettings] = LiquidProbeSettings(
starting_mount_height=100,
max_z_distance=40,
mount_speed=10,
plunger_speed=5,
sensor_threshold_pascals=40,
Expand Down Expand Up @@ -335,7 +334,6 @@ def _build_default_liquid_probe(
starting_mount_height=from_conf.get(
"starting_mount_height", default.starting_mount_height
),
max_z_distance=from_conf.get("max_z_distance", default.max_z_distance),
mount_speed=from_conf.get("mount_speed", default.mount_speed),
plunger_speed=from_conf.get("plunger_speed", default.plunger_speed),
sensor_threshold_pascals=from_conf.get(
Expand Down
1 change: 0 additions & 1 deletion api/src/opentrons/config/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ class ZSenseSettings:
@dataclass
class LiquidProbeSettings:
starting_mount_height: float
max_z_distance: float
mount_speed: float
plunger_speed: float
sensor_threshold_pascals: float
Expand Down
4 changes: 2 additions & 2 deletions api/src/opentrons/hardware_control/backends/ot3controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
PipetteOverpressureError,
FirmwareUpdateRequiredError,
FailedGripperPickupError,
LiquidNotFoundError,
PipetteLiquidNotFoundError,
CommunicationError,
PythonException,
UnsupportedHardwareCommand,
Expand Down Expand Up @@ -1412,7 +1412,7 @@ async def liquid_probe(
or positions[head_node].move_ack
== MoveCompleteAck.complete_without_condition
):
raise LiquidNotFoundError(
raise PipetteLiquidNotFoundError(
"Liquid not found during probe.",
{
str(node_to_axis(node)): str(point.motor_position)
Expand Down
23 changes: 12 additions & 11 deletions api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
GripperNotPresentError,
InvalidActuator,
FirmwareUpdateFailedError,
LiquidNotFoundError,
PipetteLiquidNotFoundError,
)

from .util import use_or_initialize_loop, check_motion_bounds
Expand Down Expand Up @@ -2594,7 +2594,8 @@ def _get_probe_distances(

async def liquid_probe(
self,
mount: OT3Mount,
mount: Union[top_types.Mount, OT3Mount],
max_z_dist: float,
probe_settings: Optional[LiquidProbeSettings] = None,
probe: Optional[InstrumentProbeType] = None,
) -> float:
Expand All @@ -2605,7 +2606,7 @@ async def liquid_probe(
reading from the pressure sensor.
If the move is completed without the specified threshold being triggered, a
LiquidNotFoundError error will be thrown.
PipetteLiquidNotFoundError error will be thrown.
Otherwise, the function will stop moving once the threshold is triggered,
and return the position of the
Expand All @@ -2622,21 +2623,21 @@ async def liquid_probe(
if not probe_settings:
probe_settings = self.config.liquid_sense

pos = await self.gantry_position(mount, refresh=True)
pos = await self.gantry_position(checked_mount, refresh=True)
probe_start_pos = pos._replace(z=probe_settings.starting_mount_height)
await self.move_to(mount, probe_start_pos)
total_z_travel = probe_settings.max_z_distance
await self.move_to(checked_mount, probe_start_pos)
total_z_travel = max_z_dist
z_travels = self._get_probe_distances(
checked_mount,
total_z_travel,
probe_settings.plunger_speed,
probe_settings.mount_speed,
)
error: Optional[LiquidNotFoundError] = None
error: Optional[PipetteLiquidNotFoundError] = None
for z_travel in z_travels:

if probe_settings.aspirate_while_sensing:
await self._move_to_plunger_bottom(mount, rate=1.0)
await self._move_to_plunger_bottom(checked_mount, rate=1.0)
else:
# find the ideal travel distance by multiplying the plunger speed
# by the time it will take to complete the z move.
Expand All @@ -2656,17 +2657,17 @@ async def liquid_probe(
await self._move(target_pos, speed=speed, acquire_lock=True)
try:
height = await self._liquid_probe_pass(
mount,
checked_mount,
probe_settings,
probe if probe else InstrumentProbeType.PRIMARY,
z_travel,
)
# if we made it here without an error we found the liquid
error = None
break
except LiquidNotFoundError as lnfe:
except PipetteLiquidNotFoundError as lnfe:
error = lnfe
await self.move_to(mount, probe_start_pos)
await self.move_to(checked_mount, probe_start_pos)
if error is not None:
# if we never found an liquid raise an error
raise error
Expand Down
13 changes: 13 additions & 0 deletions api/src/opentrons/hardware_control/protocols/liquid_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,16 @@ async def drop_tip(
the ejector shroud after a drop.
"""
...

async def liquid_probe(
self,
mount: MountArgType,
max_z_dist: float,
) -> float:
"""Search for and return liquid level height using this pipette
at the current location.
mount : Mount.LEFT or Mount.RIGHT
max_z_dist : maximum depth to probe for liquid
"""
...
14 changes: 14 additions & 0 deletions api/src/opentrons/protocol_engine/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,14 @@
VerifyTipPresenceCommandType,
)

from .liquid_probe import (
LiquidProbe,
LiquidProbeParams,
LiquidProbeCreate,
LiquidProbeResult,
LiquidProbeCommandType,
)

__all__ = [
# command type unions
"Command",
Expand Down Expand Up @@ -566,4 +574,10 @@
"VerifyTipPresenceParams",
"VerifyTipPresenceResult",
"VerifyTipPresenceCommandType",
# liquid probe command bundle
"LiquidProbe",
"LiquidProbeParams",
"LiquidProbeCreate",
"LiquidProbeResult",
"LiquidProbeCommandType",
]
Loading

0 comments on commit d2c48f3

Please sign in to comment.