Skip to content

Commit

Permalink
refactor(app, api): calibration check middleware (#6781)
Browse files Browse the repository at this point in the history
  • Loading branch information
Laura-Danielle authored Oct 22, 2020
1 parent 297bf06 commit 25c9eb9
Show file tree
Hide file tree
Showing 75 changed files with 2,201 additions and 6,131 deletions.
52 changes: 0 additions & 52 deletions app/src/analytics/__tests__/sessions-events.test.js

This file was deleted.

7 changes: 1 addition & 6 deletions app/src/analytics/make-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,7 @@ export function makeEvent(
}

case Sessions.DELETE_SESSION: {
const { robotName, sessionId } = action.payload
const analyticsProps = Sessions.getAnalyticsPropsForRobotSessionById(
state,
robotName,
sessionId
)
const analyticsProps = null
if (analyticsProps) {
return Promise.resolve({
name: `${analyticsProps.sessionType}SessionExit`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Epic, State } from '../../../types'
import type { SessionType } from '../../../sessions/types'
import {
DELETE_SESSION,
SESSION_TYPE_CALIBRATION_CHECK,
SESSION_TYPE_CALIBRATION_HEALTH_CHECK,
SESSION_TYPE_TIP_LENGTH_CALIBRATION,
SESSION_TYPE_DECK_CALIBRATION,
SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION,
Expand All @@ -19,7 +19,7 @@ import { getRobotSessionById } from '../../../sessions/selectors'

const isTargetSessionType: SessionType => boolean = sessionType =>
[
SESSION_TYPE_CALIBRATION_CHECK,
SESSION_TYPE_CALIBRATION_HEALTH_CHECK,
SESSION_TYPE_TIP_LENGTH_CALIBRATION,
SESSION_TYPE_DECK_CALIBRATION,
SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import type { Epic, State } from '../../../types'
import type { SessionType } from '../../../sessions/types'
import {
DELETE_SESSION,
SESSION_TYPE_CALIBRATION_CHECK,
SESSION_TYPE_CALIBRATION_HEALTH_CHECK,
SESSION_TYPE_TIP_LENGTH_CALIBRATION,
SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION,
} from '../../../sessions/constants'
import { getRobotSessionById } from '../../../sessions/selectors'

const isTargetSessionType: SessionType => boolean = sessionType =>
[
SESSION_TYPE_CALIBRATION_CHECK,
SESSION_TYPE_CALIBRATION_HEALTH_CHECK,
SESSION_TYPE_TIP_LENGTH_CALIBRATION,
SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION,
].includes(sessionType)
Expand Down
3 changes: 3 additions & 0 deletions app/src/components/CalibrationPanels/DeckSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ const contentsBySessionType: {
[Sessions.SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION]: {
moveCommandString: Sessions.sharedCalCommands.MOVE_TO_TIP_RACK,
},
[Sessions.SESSION_TYPE_CALIBRATION_HEALTH_CHECK]: {
moveCommandString: Sessions.sharedCalCommands.MOVE_TO_TIP_RACK,
},
[Sessions.SESSION_TYPE_TIP_LENGTH_CALIBRATION]: {
moveCommandString: Sessions.sharedCalCommands.MOVE_TO_REFERENCE_POINT,
},
Expand Down
47 changes: 37 additions & 10 deletions app/src/components/CalibrationPanels/Introduction.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const DECK_CAL_HEADER = 'deck calibration'
const DECK_CAL_BODY =
'Deck calibration ensures positional accuracy so that your robot moves as expected. It will accurately establish the OT-2’s deck orientation relative to the gantry.'

const HEALTH_CHECK_HEADER = 'calibration health check'
const HEALTH_CHECK_BODY =
'Checking the OT-2’s calibration is a first step towards diagnosing and troubleshooting common pipette positioning problems you may be experiencing.'
const HEALTH_CHECK_PROCEDURE = 'to calibration health check'

const PIP_OFFSET_CAL_HEADER = 'pipette offset calibration'
const PIP_OFFSET_CAL_BODY =
'Calibrating pipette offset enables robot to accurately establish the location of the mounted pipette’s nozzle, relative to the deck.'
Expand All @@ -54,6 +59,8 @@ const NOTE_BODY_OUTSIDE_PROTOCOL =
'important you perform this calibration using the Opentrons tips and tip racks specified above, as the robot determines accuracy based on the measurements of these tips.'
const NOTE_BODY_PRE_PROTOCOL =
'important you perform this calibration using the exact tips specified in your protocol, as the robot uses the corresponding labware definition data to find the tip.'
const NOTE_HEALTH_CHECK_OUTCOMES =
'If the difference between the two coordinates falls within the acceptable tolerance range for the given pipette, the check will pass. Otherwise, it will fail and you’ll be provided with troubleshooting guidance. You may exit at any point or continue through to the end to check the overall calibration status of your robot.'
const VIEW_TIPRACK_MEASUREMENTS = 'View measurements'

const contentsBySessionType: {
Expand Down Expand Up @@ -82,6 +89,13 @@ const contentsBySessionType: {
continueButtonText: `${START} ${TIP_LENGTH_CAL_HEADER}`,
noteBody: NOTE_BODY_PRE_PROTOCOL,
},
[Sessions.SESSION_TYPE_CALIBRATION_HEALTH_CHECK]: {
headerText: HEALTH_CHECK_HEADER,
bodyText: HEALTH_CHECK_BODY,
continueButtonText: `${START} ${HEALTH_CHECK_HEADER}`,
continuingToText: HEALTH_CHECK_PROCEDURE,
noteBody: NOTE_HEALTH_CHECK_OUTCOMES,
},
}

export function Introduction(props: CalibrationPanelProps): React.Node {
Expand All @@ -100,6 +114,8 @@ export function Introduction(props: CalibrationPanelProps): React.Node {
const lookupType = isExtendedPipOffset
? Sessions.SESSION_TYPE_TIP_LENGTH_CALIBRATION
: sessionType
const isHealthCheck =
sessionType === Sessions.SESSION_TYPE_CALIBRATION_HEALTH_CHECK

const proceed = () =>
sendCommands({ command: Sessions.sharedCalCommands.LOAD_LABWARE })
Expand Down Expand Up @@ -149,16 +165,27 @@ export function Introduction(props: CalibrationPanelProps): React.Node {
)}
</Flex>
<Box fontSize={FONT_SIZE_BODY_1} marginY={SPACING_3}>
<Text>
<b
css={css`
text-transform: uppercase;
`}
>{`${NOTE_HEADER} `}</b>
{IT_IS}
<u>{` ${EXTREMELY} `}</u>
{noteBody}
</Text>
{!isHealthCheck ? (
<Text>
<b
css={css`
text-transform: uppercase;
`}
>{`${NOTE_HEADER} `}</b>
{IT_IS}
<u>{` ${EXTREMELY} `}</u>
{noteBody}
</Text>
) : (
<Text>
<b
css={css`
text-transform: uppercase;
`}
>{`${NOTE_HEADER} `}</b>
{noteBody}
</Text>
)}
</Box>
</Flex>
<Flex width="100%" justifyContent={JUSTIFY_CENTER}>
Expand Down
72 changes: 58 additions & 14 deletions app/src/components/CalibrationPanels/SaveXYPoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import * as Sessions from '../../sessions'
import type { JogAxis, JogDirection, JogStep } from '../../http-api-client'
import type { CalibrationPanelProps } from './types'
import type {
SessionCommandString,
SessionType,
CalibrationSessionStep,
SessionCommandString,
} from '../../sessions/types'
import { JogControls } from '../JogControls'
import { formatJogVector } from './utils'
Expand Down Expand Up @@ -76,59 +76,92 @@ const assetMap = {
}

const SAVE_XY_POINT_HEADER = 'Calibrate the X and Y-axis in'
const CHECK_POINT_XY_HEADER = 'Check the X and Y-axis in'
const SLOT = 'slot'
const JOG_UNTIL = 'Jog the robot until the tip is'
const PRECISELY_CENTERED = 'precisely centered'
const ABOVE_THE_CROSS = 'above the cross in'
const THEN = 'Then press the'
const TO_SAVE = 'button to calibrate the x and y-axis in'
const TO_CHECK =
'button to determine how this position compares to the previously-saved x and y-axis calibration coordinates.'

const BASE_BUTTON_TEXT = 'save calibration'
const HEALTH_BUTTON_TEXT = 'check x and y-axis'
const MOVE_TO_POINT_TWO_BUTTON_TEXT = `${BASE_BUTTON_TEXT} and move to slot 3`
const MOVE_TO_POINT_THREE_BUTTON_TEXT = `${BASE_BUTTON_TEXT} and move to slot 7`
const HEALTH_POINT_TWO_BUTTON_TEXT = `${HEALTH_BUTTON_TEXT} and move to slot 3`
const HEALTH_POINT_THREE_BUTTON_TEXT = `${HEALTH_BUTTON_TEXT} and move to slot 7`

const contentsBySessionTypeByCurrentStep: {
[SessionType]: {
[CalibrationSessionStep]: {
slotNumber: string,
buttonText: string,
moveCommandString: SessionCommandString | null,
moveCommand: SessionCommandString | null,
finalCommand?: SessionCommandString | null,
},
},
} = {
[Sessions.SESSION_TYPE_DECK_CALIBRATION]: {
[Sessions.DECK_STEP_SAVING_POINT_ONE]: {
slotNumber: '1',
buttonText: MOVE_TO_POINT_TWO_BUTTON_TEXT,
moveCommandString: Sessions.deckCalCommands.MOVE_TO_POINT_TWO,
moveCommand: Sessions.deckCalCommands.MOVE_TO_POINT_TWO,
},
[Sessions.DECK_STEP_SAVING_POINT_TWO]: {
slotNumber: '3',
buttonText: MOVE_TO_POINT_THREE_BUTTON_TEXT,
moveCommandString: Sessions.deckCalCommands.MOVE_TO_POINT_THREE,
moveCommand: Sessions.deckCalCommands.MOVE_TO_POINT_THREE,
},
[Sessions.DECK_STEP_SAVING_POINT_THREE]: {
slotNumber: '7',
buttonText: BASE_BUTTON_TEXT,
moveCommandString: Sessions.sharedCalCommands.MOVE_TO_TIP_RACK,
moveCommand: Sessions.sharedCalCommands.MOVE_TO_TIP_RACK,
},
},
[Sessions.SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION]: {
[Sessions.PIP_OFFSET_STEP_SAVING_POINT_ONE]: {
slotNumber: '1',
buttonText: BASE_BUTTON_TEXT,
moveCommandString: null,
moveCommand: null,
},
},
[Sessions.SESSION_TYPE_CALIBRATION_HEALTH_CHECK]: {
[Sessions.CHECK_STEP_COMPARING_POINT_ONE]: {
slotNumber: '1',
buttonText: HEALTH_POINT_TWO_BUTTON_TEXT,
moveCommand: Sessions.deckCalCommands.MOVE_TO_POINT_TWO,
finalCommand: Sessions.sharedCalCommands.MOVE_TO_TIP_RACK,
},
[Sessions.CHECK_STEP_COMPARING_POINT_TWO]: {
slotNumber: '3',
buttonText: HEALTH_POINT_THREE_BUTTON_TEXT,
moveCommand: Sessions.deckCalCommands.MOVE_TO_POINT_THREE,
},
[Sessions.CHECK_STEP_COMPARING_POINT_THREE]: {
slotNumber: '7',
buttonText: HEALTH_BUTTON_TEXT,
moveCommand: Sessions.sharedCalCommands.MOVE_TO_TIP_RACK,
},
},
}

export function SaveXYPoint(props: CalibrationPanelProps): React.Node {
const { isMulti, mount, sendCommands, currentStep, sessionType } = props
const {
isMulti,
mount,
sendCommands,
currentStep,
sessionType,
activePipette,
} = props

const {
slotNumber,
buttonText,
moveCommandString,
moveCommand,
finalCommand,
} = contentsBySessionTypeByCurrentStep[sessionType][currentStep]

const demoAsset = React.useMemo(
Expand All @@ -137,6 +170,8 @@ export function SaveXYPoint(props: CalibrationPanelProps): React.Node {
[slotNumber, mount, isMulti]
)

const isHealthCheck =
sessionType === Sessions.SESSION_TYPE_CALIBRATION_HEALTH_CHECK
const jog = (axis: JogAxis, dir: JogDirection, step: JogStep) => {
sendCommands({
command: Sessions.sharedCalCommands.JOG,
Expand All @@ -147,10 +182,19 @@ export function SaveXYPoint(props: CalibrationPanelProps): React.Node {
}

const savePoint = () => {
let commands = [{ command: Sessions.sharedCalCommands.SAVE_OFFSET }]

if (moveCommandString) {
commands = [...commands, { command: moveCommandString }]
let commands = null
if (isHealthCheck) {
commands = [{ command: Sessions.checkCommands.COMPARE_POINT }]
} else {
commands = [{ command: Sessions.sharedCalCommands.SAVE_OFFSET }]
}
if (
finalCommand &&
activePipette?.rank === Sessions.CHECK_PIPETTE_RANK_SECOND
) {
commands = [...commands, { command: finalCommand }]
} else if (moveCommand) {
commands = [...commands, { command: moveCommand }]
}
sendCommands(...commands)
}
Expand All @@ -167,7 +211,7 @@ export function SaveXYPoint(props: CalibrationPanelProps): React.Node {
fontWeight={FONT_WEIGHT_SEMIBOLD}
textTransform={TEXT_TRANSFORM_UPPERCASE}
>
{SAVE_XY_POINT_HEADER}
{isHealthCheck ? CHECK_POINT_XY_HEADER : SAVE_XY_POINT_HEADER}
{` ${SLOT} ${slotNumber || ''}`}
</Text>
<Flex
Expand All @@ -185,7 +229,7 @@ export function SaveXYPoint(props: CalibrationPanelProps): React.Node {
<br />
{THEN}
<b>{` ${buttonText} `}</b>
{`${TO_SAVE} ${SLOT} ${slotNumber}`}.
{`${isHealthCheck ? TO_CHECK : TO_SAVE} ${SLOT} ${slotNumber}`}.
</Text>
<video
key={String(demoAsset)}
Expand Down
Loading

0 comments on commit 25c9eb9

Please sign in to comment.