Skip to content

Commit

Permalink
Merge branch 'chore_release-8.0.0' into partial_tip_smoke_test
Browse files Browse the repository at this point in the history
  • Loading branch information
y3rsh committed Aug 14, 2024
2 parents 11a9259 + afba276 commit 5218401
Show file tree
Hide file tree
Showing 49 changed files with 505 additions and 344 deletions.
9 changes: 3 additions & 6 deletions api/src/opentrons/hardware_control/instruments/ot3/pipette.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
InvalidLiquidClassName,
CommandPreconditionViolated,
PythonException,
InvalidInstrumentData,
)
from opentrons_shared_data.pipette.ul_per_mm import (
piecewise_volume_conversion,
Expand Down Expand Up @@ -652,12 +653,8 @@ def set_tip_type(self, tip_type: pip_types.PipetteTipType) -> None:
try:
new_tips = self._liquid_class.supported_tips[tip_type]
except KeyError as e:
raise InvalidLiquidClassName(
message=f"There is no configuration for {tip_type.name} in liquid class {str(self._liquid_class_name)} on a {self._config.display_name}",
detail={
"current-liquid-class": str(self._liquid_class_name),
"requested-type": tip_type.name,
},
raise InvalidInstrumentData(
message=f"There is no configuration for {tip_type.name} in the pick up tip configurations for a {self._config.display_name}",
wrapping=[PythonException(e)],
) from e

Expand Down
22 changes: 12 additions & 10 deletions api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio
from concurrent.futures import Future
import contextlib
from copy import deepcopy
from functools import partial, lru_cache, wraps
from dataclasses import replace
import logging
Expand Down Expand Up @@ -2684,7 +2685,17 @@ async def liquid_probe(
)

if not probe_settings:
probe_settings = self.config.liquid_sense
probe_settings = deepcopy(self.config.liquid_sense)

# We need to significatly slow down the 96 channel liquid probe
# TODO: (sigler) add LLD plunger-speed to pipette definitions
if self.gantry_load == GantryLoad.HIGH_THROUGHPUT:
max_plunger_speed = self.config.motion_settings.max_speed_discontinuity[
GantryLoad.HIGH_THROUGHPUT
][OT3AxisKind.P]
probe_settings.plunger_speed = min(
max_plunger_speed, probe_settings.plunger_speed
)

probe_start_pos = await self.gantry_position(checked_mount, refresh=True)

Expand All @@ -2697,15 +2708,6 @@ async def liquid_probe(
instrument.plunger_positions.bottom - instrument.plunger_positions.top
)

# We need to significatly slow down the 96 channel liquid probe
if self.gantry_load == GantryLoad.HIGH_THROUGHPUT:
max_plunger_speed = self.config.motion_settings.max_speed_discontinuity[
GantryLoad.HIGH_THROUGHPUT
][OT3AxisKind.P]
probe_settings.plunger_speed = min(
max_plunger_speed, probe_settings.plunger_speed
)

p_working_mm = p_total_mm - (instrument.backlash_distance + p_impulse_mm)

# height where probe action will begin
Expand Down
4 changes: 2 additions & 2 deletions app/src/App/DesktopApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export const DesktopApp = (): JSX.Element => {
<Route
key={path}
element={
<>
<React.Fragment key={Component.name}>
<Breadcrumbs />
<Box
position={POSITION_RELATIVE}
Expand All @@ -138,7 +138,7 @@ export const DesktopApp = (): JSX.Element => {
<Component />
</Box>
</Box>
</>
</React.Fragment>
}
path={path}
/>
Expand Down
Binary file modified app/src/assets/images/modules/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/src/assets/localization/en/protocol_setup.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
"protocol_run_complete": "Protocol run complete.",
"protocol_run_failed": "Protocol run failed.",
"protocol_run_started": "Protocol run started.",
"protocol_run_stopped": "Protocol run stopped.",
"protocol_specifies": "Protocol specifies",
"protocol_upload_revamp_feedback": "Have feedback about this experience?",
"quantity": "Quantity",
Expand Down
2 changes: 1 addition & 1 deletion app/src/atoms/Tooltip/__tests__/Tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('Tooltip', () => {
expect(tooltip).toHaveStyle('left: 0.25rem')
expect(tooltip).toHaveStyle(`background: ${COLORS.black90}`)
expect(tooltip).toHaveStyle(`color: ${COLORS.white}`)
expect(tooltip).toHaveStyle('width: 8.75rem')
expect(tooltip).toHaveStyle('max-width: 8.75rem')
expect(tooltip).toHaveStyle('font-size: 0.625rem')
expect(tooltip).toHaveAttribute('role', 'tooltip')
})
Expand Down
10 changes: 9 additions & 1 deletion app/src/atoms/Tooltip/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'
import {
COLORS,
FLEX_MAX_CONTENT,
TYPOGRAPHY,
Tooltip as SharedTooltip,
} from '@opentrons/components'
Expand All @@ -16,14 +17,21 @@ export interface TooltipProps extends StyleProps {
}

export function Tooltip(props: TooltipProps): JSX.Element {
const { children, tooltipProps, width = '8.75rem', ...styleProps } = props
const {
children,
tooltipProps,
width = FLEX_MAX_CONTENT,
maxWidth = '8.75rem',
...styleProps
} = props

return (
<SharedTooltip
{...tooltipProps}
backgroundColor={COLORS.black90}
fontSize={TYPOGRAPHY.fontSizeCaption}
width={width}
maxWidth={maxWidth}
{...styleProps}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type UseProtocolDropTipModalProps = Pick<
areTipsAttached: TipAttachmentStatusResult['areTipsAttached']
toggleDTWiz: () => void
currentRunId: string
onClose: () => void
onSkipAndHome: () => void
/* True if the most recent run is the current run */
isRunCurrent: boolean
}
Expand All @@ -49,15 +49,16 @@ export function useProtocolDropTipModal({
areTipsAttached,
toggleDTWiz,
isRunCurrent,
onClose,
onSkipAndHome,
...homePipetteProps
}: UseProtocolDropTipModalProps): UseProtocolDropTipModalResult {
const [showDTModal, setShowDTModal] = React.useState(areTipsAttached)

const { homePipettes, isHomingPipettes } = useHomePipettes({
...homePipetteProps,
onComplete: () => {
onClose()
isRunCurrent,
onHome: () => {
onSkipAndHome()
setShowDTModal(false)
},
})
Expand Down
47 changes: 34 additions & 13 deletions app/src/organisms/Devices/ProtocolRun/ProtocolRunHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export function ProtocolRunHeader({
?.data?.current
)
const mostRecentRunId = useMostRecentRunId()
const isMostRecentRun = mostRecentRunId === runId
const { closeCurrentRun, isClosingCurrentRun } = useCloseCurrentRun()
const { startedAt, stoppedAt, completedAt } = useRunTimestamps(runId)
const [showRunFailedModal, setShowRunFailedModal] = React.useState(false)
Expand All @@ -178,7 +179,7 @@ export function ProtocolRunHeader({
runStatus != null &&
// @ts-expect-error runStatus expected to possibly not be terminal
RUN_STATUSES_TERMINAL.includes(runStatus) &&
isRunCurrent,
isMostRecentRun,
})
const isResetRunLoadingRef = React.useRef(false)
const { data: runRecord } = useNotifyRunQuery(runId, { staleTime: Infinity })
Expand Down Expand Up @@ -222,6 +223,7 @@ export function ProtocolRunHeader({
resetTipStatus,
setTipStatusResolved,
aPipetteWithTip,
initialPipettesWithTipsCount,
} = useTipAttachmentStatus({
runId,
runRecord: runRecord ?? null,
Expand All @@ -240,7 +242,7 @@ export function ProtocolRunHeader({
instrumentModelSpecs: aPipetteWithTip?.specs,
mount: aPipetteWithTip?.mount,
robotType,
onClose: () => {
onSkipAndHome: () => {
closeCurrentRun()
},
})
Expand Down Expand Up @@ -283,6 +285,12 @@ export function ProtocolRunHeader({
...robotAnalyticsData,
},
})

// Close the run if no tips are attached after running tip check at least once.
// This marks the robot as "not busy" as soon as a run is cancelled if drop tip CTAs are unnecessary.
if (initialPipettesWithTipsCount === 0) {
closeCurrentRun()
}
}
}, [runStatus, isRunCurrent, runId])

Expand Down Expand Up @@ -415,7 +423,7 @@ export function ProtocolRunHeader({
{t('shared:close_robot_door')}
</Banner>
) : null}
{mostRecentRunId === runId ? (
{isMostRecentRun ? (
<TerminalRunBanner
{...{
runStatus,
Expand Down Expand Up @@ -515,13 +523,16 @@ export function ProtocolRunHeader({
robotType={isFlex ? FLEX_ROBOT_TYPE : OT2_ROBOT_TYPE}
mount={aPipetteWithTip.mount}
instrumentModelSpecs={aPipetteWithTip.specs}
closeFlow={() =>
setTipStatusResolved()
.then(toggleDTWiz)
.then(() => {
closeFlow={isTakeover => {
if (isTakeover) {
toggleDTWiz()
} else {
void setTipStatusResolved(() => {
toggleDTWiz()
closeCurrentRun()
})
}
}, toggleDTWiz)
}
}}
/>
) : null}
</Flex>
Expand Down Expand Up @@ -732,13 +743,21 @@ function ActionButton(props: ActionButtonProps): JSX.Element {
return module.moduleType === 'heaterShakerModuleType'
})
.some(module => module?.data != null && module.data.speedStatus !== 'idle')
const isValidRunAgain =
runStatus != null && RUN_AGAIN_STATUSES.includes(runStatus)
const validRunAgainButRequiresSetup = isValidRunAgain && !isSetupComplete
const runAgainWithSpinner = validRunAgainButRequiresSetup && isResetRunLoading

let buttonText: string = ''
let handleButtonClick = (): void => {}
let buttonIconName: IconName | null = null
let disableReason = null

if (currentRunId === runId && (!isSetupComplete || isFixtureMismatch)) {
if (
currentRunId === runId &&
(!isSetupComplete || isFixtureMismatch) &&
!isValidRunAgain
) {
disableReason = t('setup_incomplete')
} else if (isOtherRunCurrent) {
disableReason = t('shared:robot_is_busy')
Expand Down Expand Up @@ -803,7 +822,7 @@ function ActionButton(props: ActionButtonProps): JSX.Element {
}
}
} else if (runStatus != null && RUN_AGAIN_STATUSES.includes(runStatus)) {
buttonIconName = 'play'
buttonIconName = runAgainWithSpinner ? 'ot-spinner' : 'play'
buttonText = t('run_again')
handleButtonClick = () => {
reset()
Expand All @@ -825,7 +844,7 @@ function ActionButton(props: ActionButtonProps): JSX.Element {
boxShadow="none"
display={DISPLAY_FLEX}
padding={`${SPACING.spacing12} ${SPACING.spacing16}`}
disabled={isRunControlButtonDisabled}
disabled={isRunControlButtonDisabled && !validRunAgainButRequiresSetup}
onClick={handleButtonClick}
id="ProtocolRunHeader_runControlButton"
{...targetProps}
Expand All @@ -836,7 +855,9 @@ function ActionButton(props: ActionButtonProps): JSX.Element {
size={SIZE_1}
marginRight={SPACING.spacing8}
spin={
isProtocolAnalyzing || runStatus === RUN_STATUS_STOP_REQUESTED
isProtocolAnalyzing ||
runStatus === RUN_STATUS_STOP_REQUESTED ||
runAgainWithSpinner
}
/>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import type { NestedLabwareInfo } from './getNestedLabwareInfo'

const LabwareRow = styled.div`
display: grid;
grid-template-columns: 1fr 6fr 5.9fr;
grid-template-columns: 90px 12fr;
border-style: ${BORDERS.styleSolid};
border-width: 1px;
border-color: ${COLORS.grey30};
Expand Down Expand Up @@ -268,7 +268,7 @@ export function LabwareListItem(

return (
<LabwareRow>
<Flex alignItems={ALIGN_CENTER} width="80px" gridGap={SPACING.spacing2}>
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing2}>
{slotInfo != null && isFlex ? (
<DeckInfoLabel deckLabel={slotInfo} />
) : (
Expand All @@ -283,31 +283,10 @@ export function LabwareListItem(
<DeckInfoLabel iconName="stacked" />
) : null}
</Flex>
<Flex
flexDirection={DIRECTION_COLUMN}
gridGap={SPACING.spacing16}
width="45.875rem"
>
<Flex>
{showLabwareSVG && <StandaloneLabware definition={definition} />}
<Flex
flexDirection={DIRECTION_COLUMN}
justifyContent={JUSTIFY_CENTER}
marginLeft={SPACING.spacing8}
marginRight={SPACING.spacing24}
>
<StyledText desktopStyle="bodyDefaultSemiBold">
{labwareDisplayName}
</StyledText>
<StyledText desktopStyle="bodyDefaultRegular" color={COLORS.grey60}>
{nickName}
</StyledText>
</Flex>
</Flex>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing16}>
{nestedLabwareInfo != null &&
nestedLabwareInfo?.sharedSlotId === slotInfo ? (
<>
<Divider />
<Flex>
<Flex
flexDirection={DIRECTION_COLUMN}
Expand All @@ -326,8 +305,27 @@ export function LabwareListItem(
</StyledText>
</Flex>
</Flex>
<Divider />
</>
) : null}
<Flex>
{showLabwareSVG ? (
<StandaloneLabware definition={definition} />
) : null}
<Flex
flexDirection={DIRECTION_COLUMN}
justifyContent={JUSTIFY_CENTER}
marginLeft={SPACING.spacing8}
marginRight={SPACING.spacing24}
>
<StyledText desktopStyle="bodyDefaultSemiBold">
{labwareDisplayName}
</StyledText>
<StyledText desktopStyle="bodyDefaultRegular" color={COLORS.grey60}>
{nickName}
</StyledText>
</Flex>
</Flex>
{moduleDisplayName != null ? (
<>
<Divider />
Expand Down
Loading

0 comments on commit 5218401

Please sign in to comment.