Skip to content

Commit c2c764a

Browse files
authored
fix(app): add EmptyHopper screen for stacker stalled error recovery flows (#19129)
# Overview This PR adds a screen to advice user to empty the stacker hopper when recovering from a stacker stalled error.
1 parent 2ce8dbb commit c2c764a

File tree

6 files changed

+62
-16
lines changed

6 files changed

+62
-16
lines changed

app/src/assets/localization/en/error_recovery.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"clear_track_of_obstructions_and_close_door": "<block>Carefully clear the track of any dislodged labware or obstructions.</block><block>Close the robot and stacker door before proceeding.</block>",
2121
"close_door_to_resume": "Close robot door to resume",
2222
"close_robot_and_stacker_door": "Close the robot and stacker door",
23+
"close_robot_and_stacker_door_before_proceeding": "Close the robot and stacker door before proceeding.",
2324
"close_robot_door": "Close the robot door",
2425
"close_the_robot_door": "Close the robot door, and then resume the recovery action.",
2526
"confirm": "Confirm",
@@ -30,7 +31,7 @@
3031
"door_open_robot_home": "The robot needs to safely move to its home location before you manually move the labware.",
3132
"droplets_or_liquid_cause_failure": "Droplets or liquid in the tips may cause liquid level detection to fail",
3233
"empty_stacker_of_labware_above_latch": "Empty stacker of labware above latch",
33-
"empty_stacker_of_labware_above_latch_labware_stuck": "<block>Empty the stacker of all labware above the latch.</block><block>Labware stuck on the latch will be retrieved later in recovery.</block>",
34+
"empty_stacker_of_all_labware": "Empty the stacker of all labware above the latch.",
3435
"ensure_lw_is_accurately_placed": "Ensure labware is accurately placed in the slot to prevent further errors.",
3536
"ensure_stacker_has_labware": "Ensure stacker has labware",
3637
"error": "Error",
@@ -61,6 +62,7 @@
6162
"labware_missing_detected_when": "Stacker empty errors occur when the robot tries to retrieve labware from an empty stacker",
6263
"labware_not_retrieved": "Stacker latch jammed",
6364
"labware_released_from_current_height": "The labware will be released from its current height.",
65+
"labware_stuck_on_latch": "Labware stuck on the latch will be retrieved later in recovery.",
6466
"latch_releasing_labware": "Latch releasing labware",
6567
"latch_will_release_in_s": "Latch will release labware in {{seconds}} seconds",
6668
"launch_recovery_mode": "Launch recovery mode",

app/src/organisms/ErrorRecoveryFlows/RecoveryOptions/StackerStalledRetry.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { RECOVERY_MAP } from '../constants'
22
import {
33
RetryStepInfo,
4+
StackerEmptyHopper,
45
StackerEnsureShuttleEmpty,
56
StackerHomeShuttle,
67
StackerHopperLwInfo,
@@ -15,6 +16,8 @@ export function StackerStalledRetry(props: RecoveryContentProps): JSX.Element {
1516
const { STACKER_STALLED_RETRY } = RECOVERY_MAP
1617

1718
switch (step) {
19+
case STACKER_STALLED_RETRY.STEPS.EMPTY_STACKER:
20+
return <StackerEmptyHopper {...props} />
1821
case STACKER_STALLED_RETRY.STEPS.PREPARE_TRACK_FOR_HOMING:
1922
case STACKER_STALLED_RETRY.STEPS.CLEAR_TRACK_OF_OBSTRUCTIONS:
2023
return <StackerHomeShuttle {...props} />

app/src/organisms/ErrorRecoveryFlows/RecoveryOptions/StackerStalledSkip.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { RECOVERY_MAP } from '../constants'
22
import {
33
SkipStepInfo,
4+
StackerEmptyHopper,
45
StackerHomeShuttle,
56
StackerHopperLwInfo,
67
StackerShuttleLwInfo,
@@ -15,6 +16,8 @@ export function StackerStalledSkip(props: RecoveryContentProps): JSX.Element {
1516
const { STACKER_STALLED_SKIP } = RECOVERY_MAP
1617

1718
switch (step) {
19+
case STACKER_STALLED_SKIP.STEPS.EMPTY_STACKER:
20+
return <StackerEmptyHopper {...props} />
1821
case STACKER_STALLED_SKIP.STEPS.PREPARE_TRACK_FOR_HOMING:
1922
case STACKER_STALLED_SKIP.STEPS.CLEAR_TRACK_OF_OBSTRUCTIONS:
2023
return <StackerHomeShuttle {...props} />

app/src/organisms/ErrorRecoveryFlows/constants.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ export const RECOVERY_MAP = {
206206
STACKER_STALLED_RETRY: {
207207
ROUTE: 'stacker-stalled-retry',
208208
STEPS: {
209+
EMPTY_STACKER: 'empty-stacker',
209210
PREPARE_TRACK_FOR_HOMING: 'prepare-track-for-homing',
210211
CLEAR_TRACK_OF_OBSTRUCTIONS: 'clear-track-of-obstructions',
211212
CHECK_HOPPER: 'check-hopper',
@@ -216,6 +217,7 @@ export const RECOVERY_MAP = {
216217
STACKER_STALLED_SKIP: {
217218
ROUTE: 'stacker-stalled-skip',
218219
STEPS: {
220+
EMPTY_STACKER: 'empty-stacker',
219221
PREPARE_TRACK_FOR_HOMING: 'prepare-track-for-homing',
220222
CLEAR_TRACK_OF_OBSTRUCTIONS: 'clear-track-of-obstructions',
221223
PLACE_LABWARE_ON_SHUTTLE: 'place-labware-on-shuttle',
@@ -416,13 +418,15 @@ export const STEP_ORDER: StepOrder = {
416418
MANUAL_REPLACE_AND_RETRY.STEPS.RETRY,
417419
],
418420
[STACKER_STALLED_RETRY.ROUTE]: [
421+
STACKER_STALLED_RETRY.STEPS.EMPTY_STACKER,
419422
STACKER_STALLED_RETRY.STEPS.PREPARE_TRACK_FOR_HOMING,
420423
STACKER_STALLED_RETRY.STEPS.CLEAR_TRACK_OF_OBSTRUCTIONS,
421424
STACKER_STALLED_RETRY.STEPS.CHECK_HOPPER,
422425
STACKER_STALLED_RETRY.STEPS.ENSURE_SHUTTLE_EMPTY,
423426
STACKER_STALLED_RETRY.STEPS.RETRY,
424427
],
425428
[STACKER_STALLED_SKIP.ROUTE]: [
429+
STACKER_STALLED_SKIP.STEPS.EMPTY_STACKER,
426430
STACKER_STALLED_SKIP.STEPS.PREPARE_TRACK_FOR_HOMING,
427431
STACKER_STALLED_SKIP.STEPS.CLEAR_TRACK_OF_OBSTRUCTIONS,
428432
STACKER_STALLED_SKIP.STEPS.PLACE_LABWARE_ON_SHUTTLE,
@@ -621,6 +625,9 @@ export const RECOVERY_MAP_METADATA: RecoveryRouteStepMetadata = {
621625
[MANUAL_REPLACE_AND_RETRY.STEPS.RETRY]: { allowDoorOpen: true },
622626
},
623627
[STACKER_STALLED_RETRY.ROUTE]: {
628+
[STACKER_STALLED_RETRY.STEPS.EMPTY_STACKER]: {
629+
allowDoorOpen: true,
630+
},
624631
[STACKER_STALLED_RETRY.STEPS.PREPARE_TRACK_FOR_HOMING]: {
625632
allowDoorOpen: false,
626633
},
@@ -636,6 +643,9 @@ export const RECOVERY_MAP_METADATA: RecoveryRouteStepMetadata = {
636643
[STACKER_STALLED_RETRY.STEPS.RETRY]: { allowDoorOpen: false },
637644
},
638645
[STACKER_STALLED_SKIP.ROUTE]: {
646+
[STACKER_STALLED_SKIP.STEPS.EMPTY_STACKER]: {
647+
allowDoorOpen: true,
648+
},
639649
[STACKER_STALLED_SKIP.STEPS.PREPARE_TRACK_FOR_HOMING]: {
640650
allowDoorOpen: false,
641651
},

app/src/organisms/ErrorRecoveryFlows/shared/StackerEmptyHopper.tsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { Trans, useTranslation } from 'react-i18next'
1+
import { useTranslation } from 'react-i18next'
22

33
import { StyledText } from '@opentrons/components'
44

55
import EmptyHopper from '/app/assets/videos/error-recovery/FlexStacker_EmptyHopper.webm'
66
import { DescriptionContent, TwoColumn } from '/app/molecules/InterventionModal'
77

8+
import { RECOVERY_MAP } from '../constants'
89
import { RecoverySingleColumnContentWrapper } from './RecoveryContentWrapper'
910
import { RecoveryFooterButtons } from './RecoveryFooterButtons'
1011
import { RightColumnAnimation } from './RightColumnAnimation'
@@ -13,23 +14,29 @@ import type { RecoveryContentProps } from '../types'
1314

1415
export function StackerEmptyHopper(props: RecoveryContentProps): JSX.Element {
1516
const { t } = useTranslation('error_recovery')
16-
17-
const { routeUpdateActions } = props
17+
const { routeUpdateActions, recoveryMap } = props
18+
const { route } = recoveryMap
1819
const { proceedNextStep, goBackPrevStep } = routeUpdateActions
1920

21+
const getBodyText = (): string => {
22+
switch (route) {
23+
case RECOVERY_MAP.STACKER_SHUTTLE_EMPTY_RETRY.ROUTE:
24+
case RECOVERY_MAP.STACKER_SHUTTLE_EMPTY_SKIP.ROUTE:
25+
return t('labware_stuck_on_latch')
26+
default:
27+
return t('close_robot_and_stacker_door_before_proceeding')
28+
}
29+
}
30+
2031
const buildBodyText = (): JSX.Element => (
21-
<Trans
22-
t={t}
23-
i18nKey="empty_stacker_of_labware_above_latch_labware_stuck"
24-
components={{
25-
block: (
26-
<StyledText
27-
oddStyle="bodyTextRegular"
28-
desktopStyle="bodyDefaultRegular"
29-
/>
30-
),
31-
}}
32-
/>
32+
<>
33+
<StyledText oddStyle="bodyTextRegular" desktopStyle="bodyDefaultRegular">
34+
{t('empty_stacker_of_all_labware')}
35+
</StyledText>
36+
<StyledText oddStyle="bodyTextRegular" desktopStyle="bodyDefaultRegular">
37+
{getBodyText()}
38+
</StyledText>
39+
</>
3340
)
3441

3542
return (

app/src/organisms/ErrorRecoveryFlows/shared/__tests__/StackerEmptyHopper.test.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ describe('Render StackerEmptyHopper', () => {
3333
recoveryCommands: {
3434
skipFailedCommand: mockSkipFailedCommand,
3535
} as any,
36+
recoveryMap: {
37+
route: RECOVERY_MAP.STACKER_SHUTTLE_EMPTY_RETRY.ROUTE,
38+
step: RECOVERY_MAP.STACKER_SHUTTLE_EMPTY_RETRY.STEPS.EMPTY_STACKER,
39+
},
3640
currentRecoveryOptionUtils: {
3741
selectedRecoveryOption: RECOVERY_MAP.STACKER_SHUTTLE_EMPTY_RETRY.ROUTE,
3842
} as any,
@@ -72,6 +76,7 @@ describe('Render StackerEmptyHopper', () => {
7276
])(`renders correct title for step $step`, step => {
7377
props.recoveryMap = {
7478
...props.recoveryMap,
79+
route: RECOVERY_MAP.STACKER_SHUTTLE_EMPTY_RETRY.ROUTE,
7580
step: step,
7681
}
7782
render(props)
@@ -82,4 +87,20 @@ describe('Render StackerEmptyHopper', () => {
8287
'Labware stuck on the latch will be retrieved later in recovery.'
8388
)
8489
})
90+
91+
it.each([
92+
RECOVERY_MAP.STACKER_STALLED_RETRY.STEPS.EMPTY_STACKER,
93+
RECOVERY_MAP.STACKER_STALLED_SKIP.STEPS.EMPTY_STACKER,
94+
])(`renders correct title for step $step`, step => {
95+
props.recoveryMap = {
96+
...props.recoveryMap,
97+
route: RECOVERY_MAP.STACKER_STALLED_SKIP.ROUTE,
98+
step: step,
99+
}
100+
render(props)
101+
102+
screen.getByText('Empty stacker of labware above latch')
103+
screen.getByText('Empty the stacker of all labware above the latch.')
104+
screen.getByText('Close the robot and stacker door before proceeding.')
105+
})
85106
})

0 commit comments

Comments
 (0)