Skip to content

Commit

Permalink
feat(app): add inPlace and moveToAddressableArea command text (#13958)
Browse files Browse the repository at this point in the history
closes RAUT-851

Generate different commands from dropping tips in other locations if we select the waste chute as our drop tip location. For the waste chute, we generate moveToAddressableArea followed by dropTipInPlace commands.
  • Loading branch information
ncdiehl11 committed Nov 14, 2023
1 parent 90038a8 commit daf6ea9
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 23 deletions.
4 changes: 4 additions & 0 deletions app/src/assets/localization/en/protocol_command_text.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"adapter_in_slot": "{{adapter}} in {{slot}}",
"aspirate": "Aspirating {{volume}} µL from well {{well_name}} of {{labware}} in {{labware_location}} at {{flow_rate}} µL/sec",
"blowout": "Blowing out at well {{well_name}} of {{labware}} in {{labware_location}} at {{flow_rate}} µL/sec",
"blowout_in_place": "Blowing out in place at {{flow_rate}} µL/sec",
"closing_tc_lid": "Closing Thermocycler lid",
"comment": "Comment",
"configure_for_volume": "Configure {{pipette}} to aspirate {{volume}} µL",
Expand All @@ -16,7 +17,9 @@
"disengaging_magnetic_module": "Disengaging Magnetic Module",
"dispense_push_out": "Dispensing {{volume}} µL into well {{well_name}} of {{labware}} in {{labware_location}} at {{flow_rate}} µL/sec and pushing out {{push_out_volume}} µL",
"dispense": "Dispensing {{volume}} µL into well {{well_name}} of {{labware}} in {{labware_location}} at {{flow_rate}} µL/sec",
"dispense_in_place": "Dispensing {{volume}} µL in place at {{flow_rate}} µL/sec",
"drop_tip": "Dropping tip in {{well_name}} of {{labware}}",
"drop_tip_in_place": "Dropping tip in place",
"engaging_magnetic_module": "Engaging Magnetic Module",
"fixed_trash": "Fixed Trash",
"home_gantry": "Homing all gantry, pipette, and plunger axes",
Expand All @@ -31,6 +34,7 @@
"move_to_coordinates": "Moving to (X: {{x}}, Y: {{y}}, Z: {{z}})",
"move_to_slot": "Moving to Slot {{slot_name}}",
"move_to_well": "Moving to well {{well_name}} of {{labware}} in {{labware_location}}",
"move_to_addressable_area": "Moving to {{addressable_area}} at {{speed}} mm/s at {{height}} mm high",
"notes": "notes",
"off_deck": "off deck",
"offdeck": "offdeck",
Expand Down
42 changes: 20 additions & 22 deletions app/src/organisms/CommandText/PipettingCommandText.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { useTranslation } from 'react-i18next'

import {
CompletedProtocolAnalysis,
AspirateRunTimeCommand,
DispenseRunTimeCommand,
BlowoutRunTimeCommand,
MoveToWellRunTimeCommand,
DropTipRunTimeCommand,
PickUpTipRunTimeCommand,
getLabwareDefURI,
RobotType,
} from '@opentrons/shared-data'

import { getLabwareDefinitionsFromCommands } from '../LabwarePositionCheck/utils/labware'
import { getLoadedLabware } from './utils/accessors'
import {
Expand All @@ -18,15 +14,10 @@ import {
getFinalLabwareLocation,
} from './utils'

type PipettingRunTimeCommmand =
| AspirateRunTimeCommand
| DispenseRunTimeCommand
| BlowoutRunTimeCommand
| MoveToWellRunTimeCommand
| DropTipRunTimeCommand
| PickUpTipRunTimeCommand
import type { PipettingRunTimeCommand } from '@opentrons/shared-data'

interface PipettingCommandTextProps {
command: PipettingRunTimeCommmand
command: PipettingRunTimeCommand
robotSideAnalysis: CompletedProtocolAnalysis
robotType: RobotType
}
Expand All @@ -38,7 +29,10 @@ export const PipettingCommandText = ({
}: PipettingCommandTextProps): JSX.Element | null => {
const { t } = useTranslation('protocol_command_text')

const { labwareId, wellName } = command.params
const labwareId =
'labwareId' in command.params ? command.params.labwareId : ''
const wellName = 'wellName' in command.params ? command.params.wellName : ''

const allPreviousCommands = robotSideAnalysis.commands.slice(
0,
robotSideAnalysis.commands.findIndex(c => c.id === command.id)
Expand Down Expand Up @@ -95,13 +89,6 @@ export const PipettingCommandText = ({
flow_rate: flowRate,
})
}
case 'moveToWell': {
return t('move_to_well', {
well_name: wellName,
labware: getLabwareName(robotSideAnalysis, labwareId),
labware_location: displayLocation,
})
}
case 'dropTip': {
const loadedLabware = getLoadedLabware(robotSideAnalysis, labwareId)
const labwareDefinitions = getLabwareDefinitionsFromCommands(
Expand All @@ -128,6 +115,17 @@ export const PipettingCommandText = ({
labware_location: displayLocation,
})
}
case 'dropTipInPlace': {
return t('drop_tip_in_place')
}
case 'dispenseInPlace': {
const { volume, flowRate } = command.params
return t('dispense_in_place', { volume: volume, flow_rate: flowRate })
}
case 'blowOutInPlace': {
const { flowRate } = command.params
return t('blowout_in_place', { flow_rate: flowRate })
}
default: {
console.warn(
'PipettingCommandText encountered a command with an unrecognized commandType: ',
Expand Down
82 changes: 82 additions & 0 deletions app/src/organisms/CommandText/__tests__/CommandText.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import * as React from 'react'
import { renderWithProviders } from '@opentrons/components'
import {
BlowoutInPlaceRunTimeCommand,
DispenseInPlaceRunTimeCommand,
DropTipInPlaceRunTimeCommand,
FLEX_ROBOT_TYPE,
MoveToAddressableAreaRunTimeCommand,
PrepareToAspirateRunTimeCommand,
} from '@opentrons/shared-data'
import { i18n } from '../../../i18n'
Expand Down Expand Up @@ -85,6 +89,26 @@ describe('CommandText', () => {
)
}
})
it('renders correct text for dispenseInPlace', () => {
const { getByText } = renderWithProviders(
<CommandText
robotSideAnalysis={mockRobotSideAnalysis}
robotType={FLEX_ROBOT_TYPE}
command={
{
commandType: 'dispenseInPlace',
params: {
pipetteId: 'f6d1c83c-9d1b-4d0d-9de3-e6d649739cfb',
flowRate: 300,
volume: 50,
},
} as DispenseInPlaceRunTimeCommand
}
/>,
{ i18nInstance: i18n }
)[0]
getByText('Dispensing 50 µL in place at 300 µL/sec')
})
it('renders correct text for blowout', () => {
const dispenseCommand = mockRobotSideAnalysis.commands.find(
c => c.commandType === 'dispense'
Expand All @@ -108,6 +132,25 @@ describe('CommandText', () => {
)
}
})
it('renders correct text for blowOutInPlace', () => {
const { getByText } = renderWithProviders(
<CommandText
robotSideAnalysis={mockRobotSideAnalysis}
robotType={FLEX_ROBOT_TYPE}
command={
{
commandType: 'blowOutInPlace',
params: {
pipetteId: 'f6d1c83c-9d1b-4d0d-9de3-e6d649739cfb',
flowRate: 300,
},
} as BlowoutInPlaceRunTimeCommand
}
/>,
{ i18nInstance: i18n }
)[0]
getByText('Blowing out in place at 300 µL/sec')
})
it('renders correct text for moveToWell', () => {
const dispenseCommand = mockRobotSideAnalysis.commands.find(
c => c.commandType === 'aspirate'
Expand All @@ -129,6 +172,27 @@ describe('CommandText', () => {
getByText('Moving to well A1 of NEST 1 Well Reservoir 195 mL in Slot 5')
}
})
it('renders correct text for moveToAddressableArea', () => {
const { getByText } = renderWithProviders(
<CommandText
robotSideAnalysis={mockRobotSideAnalysis}
robotType={FLEX_ROBOT_TYPE}
command={
{
commandType: 'moveToAddressableArea',
params: {
pipetteId: 'f6d1c83c-9d1b-4d0d-9de3-e6d649739cfb',
addressableAreaName: 'D3',
speed: 200,
minimumZHeight: 100,
},
} as MoveToAddressableAreaRunTimeCommand
}
/>,
{ i18nInstance: i18n }
)[0]
getByText('Moving to D3 at 200 mm/s at 100 mm high')
})
it('renders correct text for configureForVolume', () => {
const command = {
commandType: 'configureForVolume',
Expand Down Expand Up @@ -204,6 +268,24 @@ describe('CommandText', () => {
)[0]
getByText('Returning tip to A1 of Opentrons 96 Tip Rack 300 µL in Slot 9')
})
it('renders correct text for dropTipInPlace', () => {
const { getByText } = renderWithProviders(
<CommandText
robotSideAnalysis={mockRobotSideAnalysis}
robotType={FLEX_ROBOT_TYPE}
command={
{
commandType: 'dropTipInPlace',
params: {
pipetteId: 'f6d1c83c-9d1b-4d0d-9de3-e6d649739cfb',
},
} as DropTipInPlaceRunTimeCommand
}
/>,
{ i18nInstance: i18n }
)[0]
getByText('Dropping tip in place')
})
it('renders correct text for pickUpTip', () => {
const command = mockRobotSideAnalysis.commands.find(
c => c.commandType === 'pickUpTip'
Expand Down
46 changes: 45 additions & 1 deletion app/src/organisms/CommandText/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { useTranslation } from 'react-i18next'

import { Flex, DIRECTION_COLUMN, SPACING } from '@opentrons/components'
import { getPipetteNameSpecs, RunTimeCommand } from '@opentrons/shared-data'
import {
getLabwareName,
getLabwareDisplayLocation,
getFinalLabwareLocation,
} from './utils'
import { StyledText } from '../../atoms/text'
import { LoadCommandText } from './LoadCommandText'
import { PipettingCommandText } from './PipettingCommandText'
Expand Down Expand Up @@ -50,9 +55,11 @@ export function CommandText(props: Props): JSX.Element | null {
switch (command.commandType) {
case 'aspirate':
case 'dispense':
case 'dispenseInPlace':
case 'blowout':
case 'moveToWell':
case 'blowOutInPlace':
case 'dropTip':
case 'dropTipInPlace':
case 'pickUpTip': {
return (
<StyledText as="p" {...styleProps}>
Expand Down Expand Up @@ -138,6 +145,31 @@ export function CommandText(props: Props): JSX.Element | null {
</StyledText>
)
}
case 'moveToWell': {
const { wellName, labwareId } = command.params
const allPreviousCommands = robotSideAnalysis.commands.slice(
0,
robotSideAnalysis.commands.findIndex(c => c.id === command.id)
)
const labwareLocation = getFinalLabwareLocation(
labwareId,
allPreviousCommands
)
const displayLocation =
labwareLocation != null
? getLabwareDisplayLocation(
robotSideAnalysis,
labwareLocation,
t,
robotType
)
: ''
return t('move_to_well', {
well_name: wellName,
labware: getLabwareName(robotSideAnalysis, labwareId),
labware_location: displayLocation,
})
}
case 'moveLabware': {
return (
<StyledText as="p" {...styleProps}>
Expand Down Expand Up @@ -182,6 +214,18 @@ export function CommandText(props: Props): JSX.Element | null {
</StyledText>
)
}
case 'moveToAddressableArea': {
const { addressableAreaName, speed, minimumZHeight } = command.params
return (
<StyledText as="p" {...styleProps}>
{t('move_to_addressable_area', {
addressable_area: addressableAreaName,
speed: speed,
height: minimumZHeight,
})}
</StyledText>
)
}
case 'touchTip':
case 'home':
case 'savePosition':
Expand Down

0 comments on commit daf6ea9

Please sign in to comment.