Skip to content

Commit

Permalink
refactor(app): verify probe presence before pipette cal, module cal, …
Browse files Browse the repository at this point in the history
…LPC (#14126)

Uses the new verify tip presence command to check that the calibration probe is present where relevant instead of getting tip status data from /instruments.

---------

Co-authored-by: Seth Foster <[email protected]>
  • Loading branch information
ahiuchingau and sfoster1 authored Dec 7, 2023
1 parent 72255ab commit 7e765eb
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 198 deletions.
84 changes: 35 additions & 49 deletions app/src/organisms/LabwarePositionCheck/AttachProbe.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { RESPONSIVENESS, SPACING, TYPOGRAPHY } from '@opentrons/components'
import { useInstrumentsQuery } from '@opentrons/react-api-client'
import {
CompletedProtocolAnalysis,
getPipetteNameSpecs,
CreateCommand,
} from '@opentrons/shared-data'
import { css } from 'styled-components'
import { StyledText } from '../../atoms/text'
Expand All @@ -22,7 +22,7 @@ import type {
RegisterPositionAction,
WorkingOffset,
} from './types'
import type { LabwareOffset, PipetteData } from '@opentrons/api-client'
import type { LabwareOffset } from '@opentrons/api-client'

interface AttachProbeProps extends AttachProbeStep {
protocolData: CompletedProtocolAnalysis
Expand All @@ -48,7 +48,6 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
setFatalError,
isOnDevice,
} = props
const [isPending, setIsPending] = React.useState<boolean>(false)
const [showUnableToDetect, setShowUnableToDetect] = React.useState<boolean>(
false
)
Expand All @@ -68,17 +67,6 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
}

const pipetteMount = pipette?.mount
const { refetch, data: attachedInstrumentsData } = useInstrumentsQuery({
enabled: false,
onSettled: () => {
setIsPending(false)
},
})
const attachedPipette = attachedInstrumentsData?.data.find(
(instrument): instrument is PipetteData =>
instrument.ok && instrument.mount === pipetteMount
)
const is96Channel = attachedPipette?.data.channels === 96

React.useEffect(() => {
// move into correct position for probe attach on mount
Expand All @@ -101,42 +89,41 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
pipetteMount === 'left' ? 'leftZ' : 'rightZ'

const handleProbeAttached = (): void => {
setIsPending(true)
refetch()
const verifyCommands: CreateCommand[] = [
{
commandType: 'verifyTipPresence',
params: { pipetteId: pipetteId, expectedState: 'present' },
},
]
const homeCommands: CreateCommand[] = [
{ commandType: 'home', params: { axes: [pipetteZMotorAxis] } },
{
commandType: 'retractAxis' as const,
params: {
axis: pipetteZMotorAxis,
},
},
{
commandType: 'retractAxis' as const,
params: { axis: 'x' },
},
{
commandType: 'retractAxis' as const,
params: { axis: 'y' },
},
]
chainRunCommands(verifyCommands, false)
.then(() => {
if (is96Channel || attachedPipette?.state?.tipDetected) {
chainRunCommands(
[
{ commandType: 'home', params: { axes: [pipetteZMotorAxis] } },
{
commandType: 'retractAxis' as const,
params: {
axis: pipetteZMotorAxis,
},
},
{
commandType: 'retractAxis' as const,
params: { axis: 'x' },
},
{
commandType: 'retractAxis' as const,
params: { axis: 'y' },
},
],
false
)
.then(() => proceed())
.catch((e: Error) => {
setFatalError(
`AttachProbe failed to move to safe location after probe attach with message: ${e.message}`
)
})
} else {
setShowUnableToDetect(true)
}
chainRunCommands(homeCommands, false)
.then(() => proceed())
.catch((e: Error) => {
setFatalError(
`AttachProbe failed to move to safe location after probe attach with message: ${e.message}`
)
})
})
.catch(error => {
setFatalError(error.message)
.catch((e: Error) => {
setShowUnableToDetect(true)
})
}

Expand All @@ -150,7 +137,6 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
handleOnClick={handleProbeAttached}
setShowUnableToDetect={setShowUnableToDetect}
isOnDevice={isOnDevice}
isPending={isPending}
/>
)

Expand Down
146 changes: 86 additions & 60 deletions app/src/organisms/ModuleWizardFlows/AttachProbe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import attachProbe8 from '../../assets/videos/pipette-wizard-flows/Pipette_Attac
import attachProbe96 from '../../assets/videos/pipette-wizard-flows/Pipette_Attach_Probe_96.webm'
import { Trans, useTranslation } from 'react-i18next'
import { useDeckConfigurationQuery } from '@opentrons/react-api-client'
import { WASTE_CHUTE_CUTOUT } from '@opentrons/shared-data'
import { WASTE_CHUTE_CUTOUT, CreateCommand } from '@opentrons/shared-data'
import {
LEFT,
THERMOCYCLER_MODULE_MODELS,
Expand All @@ -22,6 +22,7 @@ import {
import { Banner } from '../../atoms/Banner'
import { StyledText } from '../../atoms/text'
import { GenericWizardTile } from '../../molecules/GenericWizardTile'
import { ProbeNotAttached } from '../PipetteWizardFlows/ProbeNotAttached'

import type { ModuleCalibrationWizardStepProps } from './types'
interface AttachProbeProps extends ModuleCalibrationWizardStepProps {
Expand Down Expand Up @@ -66,8 +67,12 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
'module_wizard_flows',
'pipette_wizard_flows',
])
const [showUnableToDetect, setShowUnableToDetect] = React.useState<boolean>(
false
)

const moduleDisplayName = getModuleDisplayName(attachedModule.moduleModel)
const pipetteId = attachedPipette.serialNumber

const attachedPipetteChannels = attachedPipette.data.channels
let pipetteAttachProbeVideoSource, probeLocation
Expand Down Expand Up @@ -124,29 +129,6 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
})
}

if (isRobotMoving)
return (
<InProgressModal
// TODO ND: 9/6/23 use spinner until animations are made
alternativeSpinner={null}
description={
isExiting
? t('stand_back')
: t('module_calibrating', {
moduleName: moduleDisplayName,
})
}
>
{isExiting ? undefined : (
<Flex marginX={isOnDevice ? '4.5rem' : '8.5625rem'}>
<StyledText css={IN_PROGRESS_STYLE}>
{moduleCalibratingDisplay}
</StyledText>
</Flex>
)}
</InProgressModal>
)

const bodyText = (
<>
<Trans
Expand Down Expand Up @@ -177,46 +159,90 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => {
setErrorMessage('calibration adapter has not been loaded yet')
return
}
chainRunCommands?.(
[
{
commandType: 'home' as const,
params: {
axes: attachedPipette.mount === LEFT ? ['leftZ'] : ['rightZ'],
},
const verifyCommands: CreateCommand[] = [
{
commandType: 'verifyTipPresence',
params: { pipetteId: pipetteId, expectedState: 'present' },
},
]
const homeCommands: CreateCommand[] = [
{
commandType: 'home' as const,
params: {
axes: attachedPipette.mount === LEFT ? ['leftZ'] : ['rightZ'],
},
{
commandType: 'calibration/calibrateModule',
params: {
moduleId: attachedModule.id,
labwareId: adapterId,
mount: attachedPipette.mount,
},
},
{
commandType: 'calibration/calibrateModule',
params: {
moduleId: attachedModule.id,
labwareId: adapterId,
mount: attachedPipette.mount,
},
{
commandType: 'calibration/moveToMaintenancePosition' as const,
params: {
mount: attachedPipette.mount,
},
},
{
commandType: 'calibration/moveToMaintenancePosition' as const,
params: {
mount: attachedPipette.mount,
},
],
false
)
.then(() => proceed())
.catch((e: Error) =>
setErrorMessage(`error starting module calibration: ${e.message}`)
)
},
]

chainRunCommands?.(verifyCommands, false)
.then(() => {
chainRunCommands?.(homeCommands, false)
.then(() => {
proceed()
})
.catch((e: Error) => {
setErrorMessage(`error starting module calibration: ${e.message}`)
})
})
.catch((e: Error) => {
setShowUnableToDetect(true)
})
}

if (isRobotMoving)
return (
<InProgressModal
// TODO ND: 9/6/23 use spinner until animations are made
alternativeSpinner={null}
description={
isExiting
? t('stand_back')
: t('module_calibrating', {
moduleName: moduleDisplayName,
})
}
>
{isExiting ? undefined : (
<Flex marginX={isOnDevice ? '4.5rem' : '8.5625rem'}>
<StyledText css={IN_PROGRESS_STYLE}>
{moduleCalibratingDisplay}
</StyledText>
</Flex>
)}
</InProgressModal>
)
else if (showUnableToDetect)
return (
<ProbeNotAttached
handleOnClick={handleBeginCalibration}
setShowUnableToDetect={setShowUnableToDetect}
isOnDevice={isOnDevice ?? false}
/>
)
// TODO: add calibration loading screen and error screen
return (
<GenericWizardTile
header={i18n.format(t('attach_probe'), 'capitalize')}
rightHandBody={pipetteAttachProbeVid}
bodyText={bodyText}
proceedButtonText={t('begin_calibration')}
proceed={handleBeginCalibration}
back={goBack}
/>
)
else
return (
<GenericWizardTile
header={i18n.format(t('attach_probe'), 'capitalize')}
rightHandBody={pipetteAttachProbeVid}
bodyText={bodyText}
proceedButtonText={t('begin_calibration')}
proceed={handleBeginCalibration}
back={goBack}
/>
)
}
Loading

0 comments on commit 7e765eb

Please sign in to comment.