Skip to content

Commit

Permalink
fix(app,components): include moved labware in deck config conflict ch…
Browse files Browse the repository at this point in the history
…eck (#14515)

adds a helper to check for moveLabware commands that use a new slot. uses the helper in determining compatibility with the existing deck config. this fixes a bug where the app wasn't surfacing a conflict with a moveLabware command moving to a slot occupied by a trash.

closes RAUT-967
  • Loading branch information
brenthagen authored Feb 21, 2024
1 parent 0e1c02b commit 78c85fc
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
6 changes: 4 additions & 2 deletions app/src/resources/deck_configuration/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getTopMostLabwareInSlots } from '@opentrons/components'
import { getInitialAndMovedLabwareInSlots } from '@opentrons/components'
import { useDeckConfigurationQuery } from '@opentrons/react-api-client'
import {
FLEX_ROBOT_TYPE,
Expand Down Expand Up @@ -43,7 +43,9 @@ export function useDeckConfigurationCompatibility(
? getAddressableAreasInProtocol(protocolAnalysis, deckDef)
: []
const labwareInSlots =
protocolAnalysis != null ? getTopMostLabwareInSlots(protocolAnalysis) : []
protocolAnalysis != null
? getInitialAndMovedLabwareInSlots(protocolAnalysis)
: []

const protocolModulesInfo =
protocolAnalysis != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getInitialLoadedLabwareByAdapter } from './getInitiallyLoadedLabwareByA
import type {
CompletedProtocolAnalysis,
LoadLabwareRunTimeCommand,
MoveLabwareRunTimeCommand,
ProtocolAnalysisOutput,
LabwareDefinition2,
} from '@opentrons/shared-data'
Expand All @@ -13,6 +14,82 @@ interface LabwareInSlot {
location: { slotName: string }
}

export const getInitialAndMovedLabwareInSlots = (
protocolAnalysis: CompletedProtocolAnalysis | ProtocolAnalysisOutput
): LabwareInSlot[] => {
const { commands } = protocolAnalysis
const initialLoadedLabwareByAdapter = getInitialLoadedLabwareByAdapter(
commands
)
const topMostLabwareInSlots = getTopMostLabwareInSlots(protocolAnalysis)

return commands
.filter(
(command): command is MoveLabwareRunTimeCommand =>
command.commandType === 'moveLabware'
)
.reduce<LabwareInSlot[]>((acc, command) => {
const labwareId = command.params.labwareId
const location = command.params.newLocation

const originalLabware = topMostLabwareInSlots.find(
labware => labware.labwareId === labwareId
)
const labwareDef = originalLabware?.labwareDef

if (
location === 'offDeck' ||
'moduleId' in location ||
'labwareId' in location
)
return acc
if (labwareId == null) {
console.warn('expected to find labware id but could not')
return acc
}
if (labwareDef == null) {
console.warn(
`expected to find labware def for labware id ${String(
labwareId
)} but could not`
)
return acc
}

const slotName =
'addressableAreaName' in location
? location.addressableAreaName
: location.slotName

// if list of labware already includes slotName, return acc
if (acc.find(labware => labware.location.slotName === slotName) != null) {
return acc
}

const labwareInAdapter = initialLoadedLabwareByAdapter[labwareId]

// NOTE: only grabbing the labware on top most layer so
// either the adapter or the labware but not both
const topLabwareDefinition =
labwareInAdapter?.result?.definition ?? labwareDef
const topLabwareId = labwareInAdapter?.result?.labwareId ?? labwareId
const topLabwareNickName =
labwareInAdapter?.params?.displayName ??
originalLabware?.labwareNickName ??
null

return [
...acc,
{
labwareId: topLabwareId,
labwareDef: topLabwareDefinition,
labwareNickName: topLabwareNickName,
location: { slotName },
},
]
}, topMostLabwareInSlots)
}

export const getTopMostLabwareInSlots = (
protocolAnalysis: CompletedProtocolAnalysis | ProtocolAnalysisOutput
): LabwareInSlot[] => {
Expand Down

0 comments on commit 78c85fc

Please sign in to comment.