Skip to content

Commit 83aacbf

Browse files
committed
add flex stacker timeline errors
1 parent 62d016d commit 83aacbf

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

protocol-designer/src/assets/localization/en/alert.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,22 @@
178178
"NEXT_TIPRACK_HAS_LID": {
179179
"title": "Unable to pick up tips",
180180
"body": "The next available tip rack has a lid. Remove the lid from the tip rack to pick up tips."
181+
},
182+
"SHUTTLE_FULL": {
183+
"title": "Cannot retrieve labware when shuttle is occupied",
184+
"body": "Shuttle must be empty in order to retrieve labware from the stacker."
185+
},
186+
"HOPPER_EMPTY": {
187+
"title": "Cannot retrieve labware from empty stacker",
188+
"body": "Refill the stacker."
189+
},
190+
"SHUTTLE_EMPTY": {
191+
"title": "Cannot store labware when shuttle is empty",
192+
"body": "There is no labware on the shuttle to store into the stacker."
193+
},
194+
"MISMATCHED_STACKER_LABWARE_TYPE": {
195+
"title": "Cannot store or refill multiple labware types in the stacker",
196+
"body": "The stacker can only store a single labware at a time."
181197
}
182198
},
183199
"warning": {

step-generation/src/__tests__/flexStackerRetrieve.test.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import {
88

99
import { flexStackerRetrieve } from '../commandCreators/atomic/flexStackerRetrieve'
1010
import { HOPPER_STACKER_LOCATION } from '../constants'
11-
import { getInitialRobotStateStandard, makeContext } from '../fixtures'
11+
import {
12+
getErrorResult,
13+
getInitialRobotStateStandard,
14+
makeContext,
15+
} from '../fixtures'
1216

1317
import type { LabwareDefinition2 } from '@opentrons/shared-data'
1418
import type { InvariantContext, RobotState } from '../types'
@@ -102,4 +106,41 @@ describe('flexStackerRetrieve', () => {
102106
python: 'wellPlate_1 = mock_flex_stacker_1.retrieve()',
103107
})
104108
})
109+
it('raises an error if the hopper is empty', () => {
110+
robotState = {
111+
...robotState,
112+
modules: {
113+
[mockModuleId]: {
114+
slot: 'D3',
115+
moduleState: {} as any,
116+
},
117+
},
118+
labware: {
119+
[mockLabwareId]: {
120+
stack: ['D2'],
121+
},
122+
},
123+
}
124+
invariantContext = {
125+
...invariantContext,
126+
labwareEntities: {
127+
[mockLabwareId]: {
128+
labwareDefURI: 'mockURI',
129+
def: fixture96Plate as LabwareDefinition2,
130+
pythonName: 'wellPlate_1',
131+
id: mockLabwareId,
132+
},
133+
},
134+
}
135+
const result = flexStackerRetrieve(
136+
{
137+
moduleId: mockModuleId,
138+
},
139+
invariantContext,
140+
robotState
141+
)
142+
expect(getErrorResult(result).errors[0]).toMatchObject({
143+
type: 'HOPPER_EMPTY',
144+
})
145+
})
105146
})

step-generation/src/commandCreators/atomic/flexStackerRetrieve.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as errorCreators from '../../errorCreators'
12
import { getLabwareIdOnHopper, uuid } from '../../utils'
23

34
import type { FlexStackerRetrieveCreateCommand } from '@opentrons/shared-data'
@@ -13,7 +14,12 @@ export const flexStackerRetrieve: CommandCreator<
1314
const moduleLocation = modules[moduleId].slot
1415
const labwareIdOnModule = getLabwareIdOnHopper(labware, moduleLocation)
1516
const labwarePythonName = labwareEntities[labwareIdOnModule]?.pythonName
16-
// TODO: add error creator if there is no labware in the hopper
17+
// TODO: add error for if there is labware on the shuttle
18+
if (!labwareIdOnModule) {
19+
return {
20+
errors: [errorCreators.flexStackerHopperEmpty()],
21+
}
22+
}
1723

1824
return {
1925
commands: [

step-generation/src/errorCreators.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,35 @@ export const flexStackerNoGripper = (): CommandCreatorError => {
192192
}
193193
}
194194

195+
export const flexStackerHopperEmpty = (): CommandCreatorError => {
196+
return {
197+
type: 'HOPPER_EMPTY',
198+
message: 'Cannot retrieve labware from empty stacker',
199+
}
200+
}
201+
202+
export const flexStackerShuttleFull = (): CommandCreatorError => {
203+
return {
204+
type: 'SHUTTLE_FULL',
205+
message:
206+
'Shuttle must be empty in order to retrieve labware from the stacker',
207+
}
208+
}
209+
210+
export const flexStackerShuttleEmpty = (): CommandCreatorError => {
211+
return {
212+
type: 'SHUTTLE_EMPTY',
213+
message: 'Shuttle must have labware in order to store it in the stacker',
214+
}
215+
}
216+
217+
export const flexStackerLabwareTypeMismatch = (): CommandCreatorError => {
218+
return {
219+
type: 'MISMATCHED_STACKER_LABWARE_TYPE',
220+
message: 'The stacker can only store a single type of labware at a time',
221+
}
222+
}
223+
195224
export const heaterShakerIsShaking = (): CommandCreatorError => {
196225
return {
197226
type: 'HEATER_SHAKER_IS_SHAKING',

step-generation/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,15 @@ export type ErrorType =
751751
| 'HEATER_SHAKER_LATCH_OPEN'
752752
| 'HEATER_SHAKER_NORTH_SOUTH__OF_NON_TIPRACK_WITH_MULTI_CHANNEL'
753753
| 'HEATER_SHAKER_NORTH_SOUTH_EAST_WEST_SHAKING'
754+
| 'HOPPER_EMPTY'
754755
| 'INSUFFICIENT_TIPS'
755756
| 'INVALID_SLOT'
756757
| 'LABWARE_DISCARDED_IN_TRASH'
757758
| 'LABWARE_DOES_NOT_EXIST'
758759
| 'LABWARE_OFF_DECK'
759760
| 'LABWARE_ON_ANOTHER_ENTITY'
760761
| 'MISMATCHED_SOURCE_DEST_WELLS'
762+
| 'MISMATCHED_STACKER_LABWARE_TYPE'
761763
| 'MISSING_96_CHANNEL_TIPRACK_ADAPTER'
762764
| 'MISSING_MODULE'
763765
| 'MISSING_TEMPERATURE_STEP'
@@ -776,6 +778,8 @@ export type ErrorType =
776778
| 'RETRACT_BELOW_ASPIRATE'
777779
| 'RETRACT_BELOW_DISPENSE'
778780
| 'RETURN_TIP_UNAVAILABLE'
781+
| 'SHUTTLE_FULL'
782+
| 'SHUTTLE_EMPTY'
779783
| 'STACK_TOO_HIGH'
780784
| 'SUBMERGE_BELOW_ASPIRATE'
781785
| 'SUBMERGE_BELOW_DISPENSE'

0 commit comments

Comments
 (0)