Skip to content

Commit 0fee111

Browse files
committed
feat(protocol-designer): add designerApplication labware, pipettes, modules keys
closes AUTH-1407
1 parent 9d28971 commit 0fee111

File tree

8 files changed

+364
-126
lines changed

8 files changed

+364
-126
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { describe, it, expect } from 'vitest'
2+
import {
3+
fixture96Plate,
4+
fixtureP1000SingleV2Specs,
5+
} from '@opentrons/shared-data'
6+
import {
7+
getLabwareLoadInfo,
8+
getModulesLoadInfo,
9+
getPipettesLoadInfo,
10+
} from '../selectors/utils'
11+
import type { LabwareDefinition2, PipetteName } from '@opentrons/shared-data'
12+
13+
describe('getPipettesLoadInfo', () => {
14+
it('returns pipettes from pipette entities', () => {
15+
const pipId = '1'
16+
const results = {
17+
[pipId]: {
18+
pipetteName: fixtureP1000SingleV2Specs.displayName,
19+
},
20+
}
21+
expect(
22+
getPipettesLoadInfo({
23+
pipId: {
24+
spec: fixtureP1000SingleV2Specs,
25+
tiprackLabwareDef: [],
26+
name: fixtureP1000SingleV2Specs.displayName as PipetteName,
27+
id: pipId,
28+
tiprackDefURI: [],
29+
},
30+
})
31+
).toEqual(results)
32+
})
33+
})
34+
35+
describe('getModuleLoadInfo', () => {
36+
it('returns modules from module entities', () => {
37+
const moduleId = '1'
38+
const results = {
39+
[moduleId]: {
40+
model: 'magneticModuleV2',
41+
},
42+
}
43+
expect(
44+
getModulesLoadInfo({
45+
moduleId: {
46+
id: moduleId,
47+
model: 'magneticModuleV2',
48+
type: 'magneticModuleType',
49+
},
50+
})
51+
).toEqual(results)
52+
})
53+
})
54+
55+
describe('getLabwareLoadInfo', () => {
56+
it('returns labwares from labware entities', () => {
57+
const labwareId = '1'
58+
const uri = 'mockUri'
59+
const results = {
60+
[labwareId]: {
61+
displayName: 'nick name',
62+
labwareDefURI: uri,
63+
},
64+
}
65+
const labwareNicknamesById: Record<string, string> = {
66+
[labwareId]: 'nick name',
67+
}
68+
69+
expect(
70+
getLabwareLoadInfo(
71+
{
72+
labwareId: {
73+
id: labwareId,
74+
labwareDefURI: uri,
75+
def: fixture96Plate as LabwareDefinition2,
76+
},
77+
},
78+
labwareNicknamesById
79+
)
80+
).toEqual(results)
81+
})
82+
})

protocol-designer/src/file-data/selectors/fileCreator.ts

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,21 @@ import { selectors as ingredSelectors } from '../../labware-ingred/selectors'
1717
import { selectors as stepFormSelectors } from '../../step-forms'
1818
import { selectors as uiLabwareSelectors } from '../../ui/labware'
1919
import { swatchColors } from '../../organisms/DefineLiquidsModal/swatchColors'
20-
import {
21-
DEFAULT_MM_TOUCH_TIP_OFFSET_FROM_TOP,
22-
DEFAULT_MM_BLOWOUT_OFFSET_FROM_TOP,
23-
DEFAULT_MM_OFFSET_FROM_BOTTOM,
24-
} from '../../constants'
2520
import { getStepGroups } from '../../step-forms/selectors'
2621
import { getFileMetadata, getRobotType } from './fileFields'
2722
import { getInitialRobotState, getRobotStateTimeline } from './commands'
28-
import { getLoadCommands } from './utils'
23+
import {
24+
getLabwareLoadInfo,
25+
getLoadCommands,
26+
getModulesLoadInfo,
27+
getPipettesLoadInfo,
28+
} from './utils'
2929

3030
import type { SecondOrderCommandAnnotation } from '@opentrons/shared-data/commandAnnotation/types'
3131
import type {
3232
PipetteEntity,
3333
LabwareEntities,
3434
PipetteEntities,
35-
LiquidEntities,
3635
} from '@opentrons/step-generation'
3736
import type {
3837
CommandAnnotationV1Mixin,
@@ -45,23 +44,9 @@ import type {
4544
ProtocolBase,
4645
ProtocolFile,
4746
} from '@opentrons/shared-data'
48-
import type { DismissedWarningState } from '../../dismiss/reducers'
4947
import type { LabwareDefByDefURI } from '../../labware-defs'
5048
import type { Selector } from '../../types'
51-
52-
// DesignerApplication type for version 8_5
53-
export interface DesignerApplicationDataV8_5 {
54-
ingredients: LiquidEntities
55-
ingredLocations: {
56-
[labwareId: string]: {
57-
[wellName: string]: { [liquidId: string]: { volume: number } }
58-
}
59-
}
60-
savedStepForms: Record<string, any>
61-
orderedStepIds: string[]
62-
pipetteTiprackAssignments: Record<string, string[]>
63-
dismissedWarnings: DismissedWarningState
64-
}
49+
import type { PDMetadata } from '../../file-types'
6550

6651
// TODO: BC: 2018-02-21 uncomment this assert, causes test failures
6752
// console.assert(!isEmpty(process.env.OT_PD_VERSION), 'Could not find application version!')
@@ -159,15 +144,6 @@ export const createFile: Selector<ProtocolFile> = createSelector(
159144
version: applicationVersion,
160145
data: {
161146
_internalAppBuildDate,
162-
defaultValues: {
163-
// TODO: Ian 2019-06-13 load these into redux and always get them from redux, not constants.js
164-
// This `defaultValues` key is not yet read by anything, but is populated here for auditability
165-
// and so that later we can do #3587 without a PD migration
166-
aspirate_mmFromBottom: DEFAULT_MM_OFFSET_FROM_BOTTOM,
167-
dispense_mmFromBottom: DEFAULT_MM_OFFSET_FROM_BOTTOM,
168-
touchTip_mmFromTop: DEFAULT_MM_TOUCH_TIP_OFFSET_FROM_TOP,
169-
blowout_mmFromTop: DEFAULT_MM_BLOWOUT_OFFSET_FROM_TOP,
170-
},
171147
pipetteTiprackAssignments: mapValues(
172148
pipetteEntities,
173149
(p: typeof pipetteEntities[keyof typeof pipetteEntities]): string[] =>
@@ -178,6 +154,9 @@ export const createFile: Selector<ProtocolFile> = createSelector(
178154
ingredLocations,
179155
savedStepForms,
180156
orderedStepIds: savedOrderedStepIds,
157+
pipettes: getPipettesLoadInfo(pipetteEntities),
158+
modules: getModulesLoadInfo(moduleEntities),
159+
labware: getLabwareLoadInfo(labwareEntities, labwareNicknamesById),
181160
},
182161
}
183162

@@ -268,7 +247,7 @@ export const createFile: Selector<ProtocolFile> = createSelector(
268247
commandAnnotations,
269248
}
270249

271-
const protocolBase: ProtocolBase<DesignerApplicationDataV8_5> = {
250+
const protocolBase: ProtocolBase<PDMetadata> = {
272251
$otSharedSchema: '#/protocol/schemas/8',
273252
schemaVersion: 8,
274253
metadata: {

protocol-designer/src/file-data/selectors/utils.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import map from 'lodash/map'
33
import reduce from 'lodash/reduce'
44
import { getLoadLiquidCommands } from '../../load-file/migration/utils/getLoadLiquidCommands'
55
import { COLUMN_4_SLOTS, uuid } from '@opentrons/step-generation'
6-
76
import type {
87
AddressableAreaName,
98
CreateCommand,
@@ -21,9 +20,13 @@ import type {
2120
ModuleEntities,
2221
TimelineFrame,
2322
LiquidEntities,
23+
PipetteEntity,
24+
ModuleEntity,
25+
LabwareEntity,
2426
} from '@opentrons/step-generation'
27+
import type { Labware, Modules, Pipettes } from '../../file-types'
2528

26-
interface Pipettes {
29+
interface MappedPipettes {
2730
[pipetteId: string]: { name: PipetteName }
2831
}
2932

@@ -36,7 +39,7 @@ export const getLoadCommands = (
3639
liquidEntities: LiquidEntities,
3740
ingredLocations: LabwareLiquidState
3841
): CreateCommand[] => {
39-
const pipettes: Pipettes = mapValues(
42+
const pipettes: MappedPipettes = mapValues(
4043
initialRobotState.pipettes,
4144
(
4245
pipette: typeof initialRobotState.pipettes[keyof typeof initialRobotState.pipettes],
@@ -196,3 +199,41 @@ export const getLoadCommands = (
196199
...loadLiquidCommands,
197200
]
198201
}
202+
203+
export const getPipettesLoadInfo = (
204+
pipetteEntities: PipetteEntities
205+
): Pipettes => {
206+
return Object.values(pipetteEntities).reduce<Pipettes>(
207+
(acc, pipetteEntity: PipetteEntity) => ({
208+
...acc,
209+
[pipetteEntity.id]: { pipetteName: pipetteEntity.name },
210+
}),
211+
{}
212+
)
213+
}
214+
215+
export const getModulesLoadInfo = (moduleEntities: ModuleEntities): Modules => {
216+
return Object.values(moduleEntities).reduce<Modules>(
217+
(acc, moduleEntity: ModuleEntity) => ({
218+
...acc,
219+
[moduleEntity.id]: { model: moduleEntity.model },
220+
}),
221+
{}
222+
)
223+
}
224+
225+
export const getLabwareLoadInfo = (
226+
labwareEntities: LabwareEntities,
227+
labwareNicknamesById: Record<string, string>
228+
): Labware => {
229+
return Object.values(labwareEntities).reduce<Labware>(
230+
(acc, labwareEntity: LabwareEntity) => ({
231+
...acc,
232+
[labwareEntity.id]: {
233+
displayName: labwareNicknamesById[labwareEntity.id],
234+
labwareDefURI: labwareEntity.labwareDefURI,
235+
},
236+
}),
237+
{}
238+
)
239+
}

protocol-designer/src/file-types.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
1+
import type {
2+
ModuleModel,
3+
PipetteName,
4+
ProtocolFile,
5+
} from '@opentrons/shared-data'
6+
import type { LiquidEntities } from '@opentrons/step-generation'
17
import type { RootState as IngredRoot } from './labware-ingred/reducers'
28
import type { RootState as StepformRoot } from './step-forms'
39
import type { RootState as DismissRoot } from './dismiss'
4-
import type { ProtocolFile as ProtocolFileV3 } from '@opentrons/shared-data/protocol/types/schemaV3'
5-
import type { ProtocolFile as ProtocolFileV4 } from '@opentrons/shared-data/protocol/types/schemaV4'
6-
import type { ProtocolFile as ProtocolFileV5 } from '@opentrons/shared-data/protocol/types/schemaV5'
7-
import type { ProtocolFile as ProtocolFileV6 } from '@opentrons/shared-data/protocol/types/schemaV6'
8-
import type { LiquidEntities } from '@opentrons/step-generation'
10+
export interface PipetteLoadInfo {
11+
pipetteName: PipetteName
12+
}
13+
export interface ModuleLoadInfo {
14+
model: ModuleModel
15+
}
16+
export interface LabwareLoadInfo {
17+
displayName: string // either labwareDef displayName or user defined nickName
18+
labwareDefURI: string // the labware definition URI
19+
}
920

21+
export type Pipettes = Record<string, PipetteLoadInfo>
22+
export type Modules = Record<string, ModuleLoadInfo>
23+
export type Labware = Record<string, LabwareLoadInfo>
1024
export interface PDMetadata {
1125
// pipetteId to tiprackModel
1226
pipetteTiprackAssignments: Record<string, string[]>
@@ -15,19 +29,12 @@ export interface PDMetadata {
1529
ingredLocations: IngredRoot['ingredLocations']
1630
savedStepForms: StepformRoot['savedStepForms']
1731
orderedStepIds: StepformRoot['orderedStepIds']
18-
defaultValues: {
19-
aspirate_mmFromBottom: number | null
20-
dispense_mmFromBottom: number | null
21-
touchTip_mmFromTop: number | null
22-
blowout_mmFromTop: number | null
23-
}
32+
pipettes: Pipettes
33+
modules: Modules
34+
labware: Labware
2435
}
25-
// NOTE: PD currently supports saving both v3 and v4, depending on whether it has modules
26-
export type PDProtocolFile =
27-
| ProtocolFileV3<PDMetadata>
28-
| ProtocolFileV4<PDMetadata>
29-
| ProtocolFileV5<PDMetadata>
30-
| ProtocolFileV6<PDMetadata>
36+
37+
export type PDProtocolFile = ProtocolFile<PDMetadata> & PDMetadata
3138

3239
export function getPDMetadata(file: PDProtocolFile): PDMetadata {
3340
const metadata = file.designerApplication?.data

protocol-designer/src/load-file/migration/8_5_0.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,26 @@ import floor from 'lodash/floor'
22
import { swatchColors } from '../../organisms/DefineLiquidsModal/swatchColors'
33
import { getMigratedPositionFromTop } from './utils/getMigrationPositionFromTop'
44
import { getAdditionalEquipmentLocationUpdate } from './utils/getAdditionalEquipmentLocationUpdate'
5+
import { getEquipmentLoadInfoFromCommands } from './utils/getEquipmentLoadInfoFromCommands'
56
import type {
67
LoadLabwareCreateCommand,
78
ProtocolFile,
89
} from '@opentrons/shared-data'
910
import type { LiquidEntities } from '@opentrons/step-generation'
10-
import type { DesignerApplicationDataV8_5 } from '../../file-data/selectors'
1111
import type { DesignerApplicationData } from './utils/getLoadLiquidCommands'
12+
import type { PDMetadata } from '../../file-types'
1213

1314
export const migrateFile = (
1415
appData: ProtocolFile<DesignerApplicationData>
15-
): ProtocolFile<DesignerApplicationDataV8_5> => {
16+
): ProtocolFile<PDMetadata> => {
1617
const {
1718
designerApplication,
1819
commands,
1920
labwareDefinitions,
2021
liquids,
2122
robot,
2223
} = appData
24+
2325
if (designerApplication == null || designerApplication?.data == null) {
2426
throw Error('The designerApplication key in your file is corrupt.')
2527
}
@@ -156,13 +158,19 @@ export const migrateFile = (
156158
},
157159
{}
158160
)
161+
const equipmentLoadInfoFromCommands = getEquipmentLoadInfoFromCommands(
162+
commands,
163+
labwareDefinitions
164+
)
165+
159166
return {
160167
...appData,
161168
designerApplication: {
162169
...designerApplication,
163170
data: {
164171
...designerApplication.data,
165172
ingredients: migratedIngredients,
173+
...equipmentLoadInfoFromCommands,
166174
savedStepForms: {
167175
...designerApplication.data.savedStepForms,
168176
...updatedInitialStep,

0 commit comments

Comments
 (0)