Skip to content

Commit fcb6bae

Browse files
committed
feat(step-generation): generate py command for moveToAddressableArea
1 parent d72ee2c commit fcb6bae

12 files changed

+155
-119
lines changed

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

+13-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,18 @@ import type { CutoutId } from '@opentrons/shared-data'
1010
import type { InvariantContext, RobotState } from '../types'
1111

1212
const mockCutout: CutoutId = 'cutoutA3'
13-
const invariantContext: InvariantContext = makeContext()
13+
const mockTrashId = 'mockTrashId'
14+
const invariantContext: InvariantContext = {
15+
...makeContext(),
16+
additionalEquipmentEntities: {
17+
[mockTrashId]: {
18+
id: mockTrashId,
19+
name: 'trashBin',
20+
pythonName: 'mock_trash_bin_1',
21+
location: mockCutout,
22+
},
23+
},
24+
}
1425
const prevRobotState: RobotState = getInitialRobotStateStandard(
1526
invariantContext
1627
)
@@ -22,7 +33,7 @@ describe('airGapInTrash', () => {
2233
pipetteId: DEFAULT_PIPETTE,
2334
volume: 10,
2435
flowRate: 10,
25-
trashLocation: mockCutout,
36+
trashId: mockTrashId,
2637
},
2738
invariantContext,
2839
prevRobotState

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

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
import { describe, it, expect } from 'vitest'
2+
import { WASTE_CHUTE_CUTOUT } from '@opentrons/shared-data'
23
import {
4+
DEFAULT_PIPETTE,
35
getInitialRobotStateStandard,
46
getSuccessResult,
57
makeContext,
68
} from '../fixtures'
79
import { airGapInWasteChute } from '../commandCreators/compound'
8-
import type { InvariantContext, PipetteEntities, RobotState } from '../types'
9-
10-
const mockId = 'mockId'
11-
const mockPipEntities: PipetteEntities = {
12-
[mockId]: {
13-
name: 'p50_single_flex',
14-
id: mockId,
15-
spec: { channels: 1 },
16-
},
17-
} as any
10+
import type { InvariantContext, RobotState } from '../types'
1811

12+
const wasteChuteId = 'wasteChuteId'
1913
const invariantContext: InvariantContext = {
2014
...makeContext(),
21-
pipetteEntities: mockPipEntities,
15+
additionalEquipmentEntities: {
16+
[wasteChuteId]: {
17+
id: wasteChuteId,
18+
name: 'wasteChute',
19+
pythonName: 'mock_waste_chute_1',
20+
location: WASTE_CHUTE_CUTOUT,
21+
},
22+
},
2223
}
2324
const prevRobotState: RobotState = getInitialRobotStateStandard(
2425
invariantContext
@@ -28,9 +29,10 @@ describe('airGapInWasteChute', () => {
2829
it('returns correct commands for air gap in waste chute', () => {
2930
const result = airGapInWasteChute(
3031
{
31-
pipetteId: mockId,
32+
pipetteId: DEFAULT_PIPETTE,
3233
volume: 10,
3334
flowRate: 10,
35+
wasteChuteId,
3436
},
3537
invariantContext,
3638
prevRobotState
@@ -40,7 +42,7 @@ describe('airGapInWasteChute', () => {
4042
commandType: 'moveToAddressableArea',
4143
key: expect.any(String),
4244
params: {
43-
pipetteId: mockId,
45+
pipetteId: DEFAULT_PIPETTE,
4446
addressableAreaName: '1ChannelWasteChute',
4547
offset: { x: 0, y: 0, z: 0 },
4648
},
@@ -49,14 +51,14 @@ describe('airGapInWasteChute', () => {
4951
commandType: 'prepareToAspirate',
5052
key: expect.any(String),
5153
params: {
52-
pipetteId: mockId,
54+
pipetteId: DEFAULT_PIPETTE,
5355
},
5456
},
5557
{
5658
commandType: 'airGapInPlace',
5759
key: expect.any(String),
5860
params: {
59-
pipetteId: mockId,
61+
pipetteId: DEFAULT_PIPETTE,
6062
flowRate: 10,
6163
volume: 10,
6264
},
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,95 @@
11
import { describe, it, expect } from 'vitest'
2-
import { getSuccessResult } from '../fixtures'
2+
import { WASTE_CHUTE_CUTOUT } from '@opentrons/shared-data'
3+
import {
4+
getSuccessResult,
5+
makeContext,
6+
getInitialRobotStateStandard,
7+
DEFAULT_PIPETTE,
8+
} from '../fixtures'
39
import { moveToAddressableArea } from '../commandCreators/atomic'
10+
import type { InvariantContext, RobotState } from '../types'
11+
import type { CutoutId } from '@opentrons/shared-data'
412

5-
const getRobotInitialState = (): any => {
6-
return {}
7-
}
8-
const mockId = 'mockId'
9-
const invariantContext: any = {
10-
pipetteEntities: {
11-
[mockId]: {
12-
name: 'p50_single_flex',
13-
id: mockId,
13+
const mockCutout = 'cutoutA3' as CutoutId
14+
const mockTrashId = 'mockTrashId'
15+
let invariantContext: InvariantContext = {
16+
...makeContext(),
17+
additionalEquipmentEntities: {
18+
[mockTrashId]: {
19+
id: mockTrashId,
20+
name: 'trashBin',
21+
pythonName: 'mock_trash_bin_1',
22+
location: mockCutout,
1423
},
1524
},
1625
}
26+
const prevRobotState: RobotState = getInitialRobotStateStandard(
27+
invariantContext
28+
)
1729

1830
describe('moveToAddressableArea', () => {
19-
it('should call moveToAddressableArea with correct params', () => {
20-
const robotInitialState = getRobotInitialState()
21-
const mockName = '1ChannelWasteChute'
31+
it('should call moveToAddressableArea with correct params for trash bin', () => {
32+
const result = moveToAddressableArea(
33+
{
34+
pipetteId: DEFAULT_PIPETTE,
35+
fixtureId: mockTrashId,
36+
offset: { x: 0, y: 0, z: 1 },
37+
},
38+
invariantContext,
39+
prevRobotState
40+
)
41+
const res = getSuccessResult(result)
42+
expect(res.commands).toEqual([
43+
{
44+
commandType: 'moveToAddressableArea',
45+
key: expect.any(String),
46+
params: {
47+
pipetteId: DEFAULT_PIPETTE,
48+
addressableAreaName: 'movableTrashA3',
49+
offset: { x: 0, y: 0, z: 1 },
50+
},
51+
},
52+
])
53+
expect(getSuccessResult(result).python).toBe(
54+
'mockPythonName.move_to(mock_trash_bin_1)'
55+
)
56+
})
57+
it('should call moveToAddressableArea with correct params for waste chute', () => {
58+
const wasteChuteId = 'wasteChuteId'
59+
invariantContext = {
60+
...invariantContext,
61+
additionalEquipmentEntities: {
62+
[wasteChuteId]: {
63+
id: wasteChuteId,
64+
name: 'wasteChute',
65+
pythonName: 'mock_waste_chute_1',
66+
location: WASTE_CHUTE_CUTOUT,
67+
},
68+
},
69+
}
2270
const result = moveToAddressableArea(
2371
{
24-
pipetteId: mockId,
25-
addressableAreaName: mockName,
26-
offset: { x: 0, y: 0, z: 0 },
72+
pipetteId: DEFAULT_PIPETTE,
73+
fixtureId: wasteChuteId,
74+
offset: { x: 0, y: 0, z: 1 },
2775
},
2876
invariantContext,
29-
robotInitialState
77+
prevRobotState
3078
)
3179
const res = getSuccessResult(result)
3280
expect(res.commands).toEqual([
3381
{
3482
commandType: 'moveToAddressableArea',
3583
key: expect.any(String),
3684
params: {
37-
pipetteId: mockId,
38-
addressableAreaName: mockName,
39-
offset: { x: 0, y: 0, z: 0 },
85+
pipetteId: DEFAULT_PIPETTE,
86+
addressableAreaName: '1ChannelWasteChute',
87+
offset: { x: 0, y: 0, z: 1 },
4088
},
4189
},
4290
])
91+
expect(getSuccessResult(result).python).toBe(
92+
'mockPythonName.move_to(mock_waste_chute_1)'
93+
)
4394
})
4495
})

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

+32-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,40 @@
1-
import { uuid } from '../../utils'
2-
import type { MoveToAddressableAreaParams } from '@opentrons/shared-data'
1+
import {
2+
getTrashBinAddressableAreaName,
3+
getWasteChuteAddressableAreaNamePip,
4+
uuid,
5+
} from '../../utils'
6+
import type {
7+
AddressableAreaName,
8+
CutoutId,
9+
MoveToAddressableAreaParams,
10+
} from '@opentrons/shared-data'
311
import type { CommandCreator } from '../../types'
412

5-
export const moveToAddressableArea: CommandCreator<MoveToAddressableAreaParams> = (
13+
interface MoveToAddressableAreaAtomicParams
14+
extends Omit<MoveToAddressableAreaParams, 'addressableAreaName'> {
15+
fixtureId: string
16+
}
17+
export const moveToAddressableArea: CommandCreator<MoveToAddressableAreaAtomicParams> = (
618
args,
719
invariantContext,
820
prevRobotState
921
) => {
10-
const { pipetteId, addressableAreaName, offset } = args
22+
const { pipetteId, fixtureId, offset } = args
23+
const { pipetteEntities, additionalEquipmentEntities } = invariantContext
24+
const pipetteEntity = pipetteEntities[pipetteId]
25+
const pipetteChannels = pipetteEntity.spec.channels
26+
const pipettePythonName = pipetteEntity.pythonName
27+
const fixtureEntity = additionalEquipmentEntities[fixtureId]
28+
const fixturePythonName = fixtureEntity.pythonName
29+
30+
let addressableAreaName: AddressableAreaName = getWasteChuteAddressableAreaNamePip(
31+
pipetteChannels
32+
)
33+
if (fixtureEntity.name === 'trashBin') {
34+
addressableAreaName = getTrashBinAddressableAreaName(
35+
fixtureEntity.location as CutoutId
36+
)
37+
}
1138

1239
const commands = [
1340
{
@@ -22,5 +49,6 @@ export const moveToAddressableArea: CommandCreator<MoveToAddressableAreaParams>
2249
]
2350
return {
2451
commands,
52+
python: `${pipettePythonName}.move_to(${fixturePythonName})`,
2553
}
2654
}

step-generation/src/commandCreators/compound/airGapInTrash.ts

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,28 @@
1-
import {
2-
getTrashBinAddressableAreaName,
3-
reduceCommandCreators,
4-
curryCommandCreator,
5-
} from '../../utils'
1+
import { reduceCommandCreators, curryCommandCreator } from '../../utils'
62
import { ZERO_OFFSET } from '../../constants'
73
import {
84
airGapInPlace,
95
moveToAddressableArea,
106
prepareToAspirate,
117
} from '../atomic'
128
import type { CurriedCommandCreator, CommandCreator } from '../../types'
13-
import type { CutoutId } from '@opentrons/shared-data'
149

1510
interface AirGapInTrashParams {
1611
pipetteId: string
1712
flowRate: number
1813
volume: number
19-
trashLocation: CutoutId
14+
trashId: string
2015
}
2116
export const airGapInTrash: CommandCreator<AirGapInTrashParams> = (
2217
args,
2318
invariantContext,
2419
prevRobotState
2520
) => {
26-
const { pipetteId, trashLocation, flowRate, volume } = args
27-
const addressableAreaName = getTrashBinAddressableAreaName(trashLocation)
21+
const { pipetteId, trashId, flowRate, volume } = args
2822
const commandCreators: CurriedCommandCreator[] = [
2923
curryCommandCreator(moveToAddressableArea, {
3024
pipetteId,
31-
addressableAreaName,
25+
fixtureId: trashId,
3226
offset: ZERO_OFFSET,
3327
}),
3428
curryCommandCreator(prepareToAspirate, {

step-generation/src/commandCreators/compound/airGapInWasteChute.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
curryCommandCreator,
3-
getWasteChuteAddressableAreaNamePip,
4-
reduceCommandCreators,
5-
} from '../../utils'
1+
import { curryCommandCreator, reduceCommandCreators } from '../../utils'
62
import { ZERO_OFFSET } from '../../constants'
73
import {
84
airGapInPlace,
@@ -15,24 +11,20 @@ interface AirGapInWasteChuteArgs {
1511
pipetteId: string
1612
volume: number
1713
flowRate: number
14+
wasteChuteId: string
1815
}
1916

2017
export const airGapInWasteChute: CommandCreator<AirGapInWasteChuteArgs> = (
2118
args,
2219
invariantContext,
2320
prevRobotState
2421
) => {
25-
const { pipetteId, volume, flowRate } = args
26-
const pipetteChannels =
27-
invariantContext.pipetteEntities[pipetteId].spec.channels
28-
const addressableAreaName = getWasteChuteAddressableAreaNamePip(
29-
pipetteChannels
30-
)
22+
const { pipetteId, volume, flowRate, wasteChuteId } = args
3123

3224
const commandCreators: CurriedCommandCreator[] = [
3325
curryCommandCreator(moveToAddressableArea, {
3426
pipetteId,
35-
addressableAreaName,
27+
fixtureId: wasteChuteId,
3628
offset: ZERO_OFFSET,
3729
}),
3830
curryCommandCreator(prepareToAspirate, {

step-generation/src/commandCreators/compound/blowOutInTrash.ts

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import {
2-
getTrashBinAddressableAreaName,
3-
reduceCommandCreators,
4-
curryWithoutPython,
5-
} from '../../utils'
1+
import { reduceCommandCreators, curryWithoutPython } from '../../utils'
62
import { ZERO_OFFSET } from '../../constants'
73
import { blowOutInPlace, moveToAddressableArea } from '../atomic'
84
import type { CurriedCommandCreator, CommandCreator } from '../../types'
9-
import type { CutoutId } from '@opentrons/shared-data'
105

116
interface BlowOutInTrashParams {
127
pipetteId: string
@@ -21,9 +16,6 @@ export const blowOutInTrash: CommandCreator<BlowOutInTrashParams> = (
2116
const { pipetteId, trashId, flowRate } = args
2217
const { pipetteEntities, additionalEquipmentEntities } = invariantContext
2318
const trashEntity = additionalEquipmentEntities[trashId]
24-
const addressableAreaName = getTrashBinAddressableAreaName(
25-
trashEntity.location as CutoutId
26-
)
2719
const pipettePythonName = pipetteEntities[pipetteId].pythonName
2820
const trashPythonName = trashEntity.pythonName
2921

@@ -38,7 +30,7 @@ export const blowOutInTrash: CommandCreator<BlowOutInTrashParams> = (
3830
const commandCreators = [
3931
curryWithoutPython(moveToAddressableArea, {
4032
pipetteId,
41-
addressableAreaName,
33+
fixtureId: trashId,
4234
offset: ZERO_OFFSET,
4335
}),
4436
curryWithoutPython(blowOutInPlace, {

0 commit comments

Comments
 (0)