From 933175f387d5a897c41579b62f5b2c96fbd5f925 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Fri, 30 Aug 2024 13:02:48 -0400 Subject: [PATCH] fix(app): handle detaching 96 when attaching right (#16174) When we're switching pipettes from a preprotocol flow, we were not properly handling the case where a 96 is attached and we want to take it off and attach a pipette to the right mount. Add handling for that. I'm not really sure how this survived so long because it sure seems like it's always been there. When reviewing, go commit by commit to see the flow of refactors. Also the logic table looks awful in the diff view unless you make your screen really wide but it's fine if you're just looking at the file ## testing - [x] if you have a 96 channel attached, and you set up a protocol with a multi or single on the right mount, does the flow for detaching the 96 and attaching the right mount pipette go correctly Closes RQA-3123 --- .../move_to_maintenance_position.py | 7 +- .../getPipetteWizardStepsForProtocol.test.tsx | 68 +- .../getPipetteWizardStepsForProtocol.ts | 810 +++++++++--------- 3 files changed, 501 insertions(+), 384 deletions(-) diff --git a/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py b/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py index 81d9e30d1cc..168ade95a2e 100644 --- a/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +++ b/api/src/opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py @@ -108,10 +108,15 @@ async def execute( await ot3_api.move_axes( { Axis.Z_L: max_motion_range + _LEFT_MOUNT_Z_MARGIN, + } + ) + await ot3_api.disengage_axes([Axis.Z_L]) + await ot3_api.move_axes( + { Axis.Z_R: max_motion_range + _RIGHT_MOUNT_Z_MARGIN, } ) - await ot3_api.disengage_axes([Axis.Z_L, Axis.Z_R]) + await ot3_api.disengage_axes([Axis.Z_R]) return SuccessData(public=MoveToMaintenancePositionResult(), private=None) diff --git a/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx b/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx index 1fc4ea2464e..aa4ad467729 100644 --- a/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx +++ b/app/src/organisms/PipetteWizardFlows/__tests__/getPipetteWizardStepsForProtocol.test.tsx @@ -17,6 +17,9 @@ const mockPipetteInfo = [ const mockPipettesInProtocolNotEmpty = [ { id: '123', pipetteName: 'p1000_single_flex', mount: 'left' }, ] +const mockPipettesInProtocolOnRight = [ + { id: '123', pipetteName: 'p1000_single_flex', mount: 'right' }, +] const mockPipettesInProtocolMulti = [ { id: '123', pipetteName: 'p1000_multi_flex', mount: 'left' }, ] @@ -113,7 +116,7 @@ describe('getPipetteWizardStepsForProtocol', () => { ).toStrictEqual(mockFlowSteps) }) - it('returns the correct array of info when the attached 96-channel pipette needs to be switched out for single mount', () => { + it('returns the correct array of info when the attached 96-channel pipette needs to be switched out for single mount on left', () => { const mockFlowSteps = [ { section: SECTIONS.BEFORE_BEGINNING, @@ -176,6 +179,69 @@ describe('getPipetteWizardStepsForProtocol', () => { ) ).toStrictEqual(mockFlowSteps) }) + it('returns the correct array of info when the attached 96-channel pipette needs to be switched out for single mount on right', () => { + const mockFlowSteps = [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.MOUNTING_PLATE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.CARRIAGE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.DETACH, + nextMount: RIGHT, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount: RIGHT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount: RIGHT, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount: RIGHT, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount: RIGHT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount: RIGHT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount: RIGHT, + flowType: FLOWS.CALIBRATE, + }, + ] as PipetteWizardStep[] + expect( + getPipetteWizardStepsForProtocol( + { left: mock96ChannelAttachedPipetteInformation, right: null }, + mockPipettesInProtocolOnRight as any, + RIGHT + ) + ).toStrictEqual(mockFlowSteps) + }) it('returns the correct array of info when the attached pipette on left mount needs to be switched out for 96-channel', () => { const mockFlowSteps = [ { diff --git a/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts b/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts index 064b65b7f95..c5fa4739161 100644 --- a/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts +++ b/app/src/organisms/PipetteWizardFlows/getPipetteWizardStepsForProtocol.ts @@ -5,415 +5,461 @@ import type { Mount } from '../../redux/pipettes/types' import type { AttachedPipettesFromInstrumentsQuery } from '../Devices/hooks' import type { PipetteWizardStep } from './types' +const calibrateAlreadyAttachedPipetteOn = ( + mount: Mount +): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount, + flowType: FLOWS.CALIBRATE, + }, + { + section: SECTIONS.ATTACH_PROBE, + mount, + flowType: FLOWS.CALIBRATE, + }, + { + section: SECTIONS.DETACH_PROBE, + mount, + flowType: FLOWS.CALIBRATE, + }, + { section: SECTIONS.RESULTS, mount, flowType: FLOWS.CALIBRATE }, +] + +const detachNinetySixAndAttachSingleMountOn = ( + mount: Mount +): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.MOUNTING_PLATE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.CARRIAGE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.DETACH, + nextMount: mount, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount, + flowType: FLOWS.CALIBRATE, + }, +] + +const detachSingleMountAndAttachSingleMountOn = ( + mount: Mount +): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount, + flowType: FLOWS.DETACH, + }, + { section: SECTIONS.RESULTS, mount, flowType: FLOWS.DETACH }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount, + flowType: FLOWS.CALIBRATE, + }, +] + +const detachTwoSingleMountsAndAttachNinetySix = (): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.DETACH, + nextMount: RIGHT, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount: RIGHT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.RESULTS, + mount: RIGHT, + flowType: FLOWS.DETACH, + nextMount: 'both', + }, + { + section: SECTIONS.CARRIAGE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNTING_PLATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.CALIBRATE, + }, +] + +const detachSingleMountOnLeftAndAttachNinetySix = (): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount: LEFT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.DETACH, + nextMount: 'both', + }, + { + section: SECTIONS.CARRIAGE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNTING_PLATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.CALIBRATE, + }, +] + +const detachSingleMountOnRightAndAttachNinetySix = (): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount: RIGHT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.DETACH_PIPETTE, + mount: RIGHT, + flowType: FLOWS.DETACH, + }, + { + section: SECTIONS.RESULTS, + mount: RIGHT, + flowType: FLOWS.DETACH, + nextMount: 'both', + }, + { + section: SECTIONS.CARRIAGE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNTING_PLATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.CALIBRATE, + }, +] + +const fromEmptyGantryAttachNinetySix = (): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.CARRIAGE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNTING_PLATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount: LEFT, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount: LEFT, + flowType: FLOWS.CALIBRATE, + }, +] + +const fromEmptyMountAttachSingleMountOn = ( + mount: Mount +): PipetteWizardStep[] => [ + { + section: SECTIONS.BEFORE_BEGINNING, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.MOUNT_PIPETTE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.FIRMWARE_UPDATE, + mount, + flowType: FLOWS.ATTACH, + }, + { section: SECTIONS.RESULTS, mount, flowType: FLOWS.ATTACH }, + { + section: SECTIONS.ATTACH_PROBE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.DETACH_PROBE, + mount, + flowType: FLOWS.ATTACH, + }, + { + section: SECTIONS.RESULTS, + mount, + flowType: FLOWS.CALIBRATE, + }, +] +/** ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ +| requested > |96 |left |right | +| | | | | +| v attached | | | | ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ +| 96 | calibrateAlreadyAttachedPipetteOn(left) | detachNinetySixAndAttachSingleMountOn(left) | detachNinetySixAndAttachSingleMountOn(right) | ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ +| | | calibrateAlreadyAttachedPipetteOn(left) or | fromEmptyMountAttachSingleMountOn(right) | +| left only | detachSingleMountOnLeftAndAttachNinetySix() | detachSingleMountAndAttachSingleMountOn(left)| | +| | | | | ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ +| | | | calibrateAlreadyAttachedPipetteOn(right) or | +| right only | detachSingleMountOnRightAndAttachNinetySix() |fromEmptyMountAttachSingleMountOn(left) | detachSingleMountAndAttachSingleMountOn(right)| +| | | | | ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ +| left and | | calibrateAlreadyAttachedPipetteOn(left) or | calibrateAlreadyAttachedPipetteOn(right) or | +| right | detachTwoSingleMountsAndAttachNinetySix() | detachSingleMountAndAttachSingleMountOn(left)| detachSingleMountAndAttachSingleMountOn(right)| +| | | | | ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ +| | | | | +| nothing | fromEmptyGantryAttachNinetySix() | fromEmptyMountAttachSingleMountOn(left) | fromEmptyMountAttachSingleMountOn(right) | +| | | | | ++-------------+-----------------------------------------------+----------------------------------------------+-----------------------------------------------+ + **/ + export const getPipetteWizardStepsForProtocol = ( attachedPipettes: AttachedPipettesFromInstrumentsQuery, pipetteInfo: LoadedPipette[], mount: Mount ): PipetteWizardStep[] | null => { const requiredPipette = pipetteInfo.find(pipette => pipette.mount === mount) - const nintySixChannelAttached = + const ninetySixChannelAttached = attachedPipettes[LEFT]?.instrumentName === 'p1000_96' + const ninetySixChannelRequested = requiredPipette?.pipetteName === 'p1000_96' - // return empty array if no pipette is required in the protocol if (requiredPipette == null) { + // return empty array if no pipette is required in the protocol return null - // return calibration flow if correct pipette is attached } else if ( requiredPipette?.pipetteName === attachedPipettes[mount]?.instrumentName ) { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount, - flowType: FLOWS.CALIBRATE, - }, - { - section: SECTIONS.ATTACH_PROBE, - mount, - flowType: FLOWS.CALIBRATE, - }, - { - section: SECTIONS.DETACH_PROBE, - mount, - flowType: FLOWS.CALIBRATE, - }, - { section: SECTIONS.RESULTS, mount, flowType: FLOWS.CALIBRATE }, - ] - } else if ( - requiredPipette.pipetteName !== 'p1000_96' && - attachedPipettes[mount] != null - ) { - // 96-channel pipette attached and need to attach single mount pipette - if (nintySixChannelAttached) { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.MOUNTING_PLATE, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.CARRIAGE, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.DETACH, - nextMount: mount, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount, - flowType: FLOWS.CALIBRATE, - }, - ] - // Single mount pipette attached and need to attach new single mount pipette - } else { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount, - flowType: FLOWS.DETACH, - }, - { section: SECTIONS.RESULTS, mount, flowType: FLOWS.DETACH }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount, - flowType: FLOWS.CALIBRATE, - }, - ] - } - // Single mount pipette attached to both mounts and need to attach 96-channel pipette + // return calibration flow if correct pipette is attached + return calibrateAlreadyAttachedPipetteOn(mount) + } else if (!ninetySixChannelRequested && ninetySixChannelAttached) { + // 96-channel pipette attached and need to attach single mount pipette + return detachNinetySixAndAttachSingleMountOn(mount) + } else if (!ninetySixChannelRequested && attachedPipettes[mount] != null) { + // Single mount pipette attached and need to attach new single mount pipette + return detachSingleMountAndAttachSingleMountOn(mount) } else if ( - requiredPipette.pipetteName === 'p1000_96' && + ninetySixChannelRequested && attachedPipettes[LEFT] != null && attachedPipettes[RIGHT] != null ) { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.DETACH, - nextMount: RIGHT, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount: RIGHT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.RESULTS, - mount: RIGHT, - flowType: FLOWS.DETACH, - nextMount: 'both', - }, - { - section: SECTIONS.CARRIAGE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNTING_PLATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.CALIBRATE, - }, - ] - // Single mount pipette attached to left mount and need to attach 96-channel pipette + // Single mount pipette attached to both mounts and need to attach 96-channel pipette + return detachTwoSingleMountsAndAttachNinetySix() } else if ( - requiredPipette.pipetteName === 'p1000_96' && + ninetySixChannelRequested && attachedPipettes[LEFT] != null && attachedPipettes[RIGHT] == null ) { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount: LEFT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.DETACH, - nextMount: 'both', - }, - { - section: SECTIONS.CARRIAGE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNTING_PLATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.CALIBRATE, - }, - ] - // Single mount pipette attached to right mount and need to attach 96-channel pipette + // Single mount pipette attached to left mount and need to attach 96-channel pipette + return detachSingleMountOnLeftAndAttachNinetySix() } else if ( - requiredPipette.pipetteName === 'p1000_96' && + ninetySixChannelRequested && attachedPipettes[LEFT] == null && attachedPipettes[RIGHT] != null ) { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: RIGHT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.DETACH_PIPETTE, - mount: RIGHT, - flowType: FLOWS.DETACH, - }, - { - section: SECTIONS.RESULTS, - mount: RIGHT, - flowType: FLOWS.DETACH, - nextMount: 'both', - }, - { - section: SECTIONS.CARRIAGE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNTING_PLATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.CALIBRATE, - }, - ] - // if no pipette is attached to gantry + // Single mount pipette attached to right mount and need to attach 96-channel pipette + return detachSingleMountOnRightAndAttachNinetySix() } else { - // Gantry empty and need to attach 96-channel pipette - if (requiredPipette.pipetteName === 'p1000_96') { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.CARRIAGE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNTING_PLATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount: LEFT, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount: LEFT, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount: LEFT, - flowType: FLOWS.CALIBRATE, - }, - ] - // Gantry empty and need to attach single mount pipette + // if no pipette is attached to gantry + + if (ninetySixChannelRequested) { + // Gantry empty and need to attach 96-channel pipette + return fromEmptyGantryAttachNinetySix() } else { - return [ - { - section: SECTIONS.BEFORE_BEGINNING, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.MOUNT_PIPETTE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.FIRMWARE_UPDATE, - mount, - flowType: FLOWS.ATTACH, - }, - { section: SECTIONS.RESULTS, mount, flowType: FLOWS.ATTACH }, - { - section: SECTIONS.ATTACH_PROBE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.DETACH_PROBE, - mount, - flowType: FLOWS.ATTACH, - }, - { - section: SECTIONS.RESULTS, - mount, - flowType: FLOWS.CALIBRATE, - }, - ] + // Gantry empty and need to attach single mount pipette + return fromEmptyMountAttachSingleMountOn(mount) } } }