From 8790bc8a6dd6a022a864d26f8dac38ea86d74211 Mon Sep 17 00:00:00 2001 From: Brent Hagen Date: Fri, 16 Feb 2024 11:14:55 -0500 Subject: [PATCH] fix(app,components): include moved labware in deck config conflict check adds a helper to check for moveLabware commands that use a new slot. use 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 --- app/src/resources/deck_configuration/hooks.ts | 6 +- .../ProtocolDeck/utils/getLabwareInSlots.ts | 77 +++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/app/src/resources/deck_configuration/hooks.ts b/app/src/resources/deck_configuration/hooks.ts index b939696c5c6..95b92e9f7dc 100644 --- a/app/src/resources/deck_configuration/hooks.ts +++ b/app/src/resources/deck_configuration/hooks.ts @@ -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, @@ -43,7 +43,9 @@ export function useDeckConfigurationCompatibility( ? getAddressableAreasInProtocol(protocolAnalysis, deckDef) : [] const labwareInSlots = - protocolAnalysis != null ? getTopMostLabwareInSlots(protocolAnalysis) : [] + protocolAnalysis != null + ? getInitialAndMovedLabwareInSlots(protocolAnalysis) + : [] const protocolModulesInfo = protocolAnalysis != null diff --git a/components/src/hardware-sim/ProtocolDeck/utils/getLabwareInSlots.ts b/components/src/hardware-sim/ProtocolDeck/utils/getLabwareInSlots.ts index b54d13561fa..88d769409ae 100644 --- a/components/src/hardware-sim/ProtocolDeck/utils/getLabwareInSlots.ts +++ b/components/src/hardware-sim/ProtocolDeck/utils/getLabwareInSlots.ts @@ -2,6 +2,7 @@ import { getInitialLoadedLabwareByAdapter } from './getInitiallyLoadedLabwareByA import type { CompletedProtocolAnalysis, LoadLabwareRunTimeCommand, + MoveLabwareRunTimeCommand, ProtocolAnalysisOutput, LabwareDefinition2, } from '@opentrons/shared-data' @@ -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((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[] => {