-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(protocol-designer,-step-generation): wire up absorbance reader i…
…n step-generation (#17287) This PR wires up absorbance reader step form field to step generation, including transforming form to args, getNextRobotStateAndWarnings, and error and command creators for all possible plate reader steps. I also memoize labware presence in AbsorbanceReaderTools for efficiency. Note that UI for creating initialization will be done in a followup PR. Dummy data is used for now. Closes AUTH-1268 Closes AUTH-1269 Closes AUTH-1279
- Loading branch information
Showing
28 changed files
with
957 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
protocol-designer/src/steplist/formLevel/stepFormToArgs/absorbanceReaderFormToArgs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { | ||
ABSORBANCE_READER_INITIALIZE, | ||
ABSORBANCE_READER_LID, | ||
ABSORBANCE_READER_READ, | ||
} from '../../../constants' | ||
import type { AbsorbanceReaderArgs } from '@opentrons/step-generation' | ||
import type { HydratedAbsorbanceReaderFormData } from '../../../form-types' | ||
|
||
// TODO (nd: 1/15/2025) replace with actual form data once UI is | ||
const DUMMY_INITIALIZATION = { | ||
wavelengths: [420, 600], | ||
referenceWavelength: 200, | ||
} | ||
|
||
export const absorbanceReaderFormToArgs = ( | ||
hydratedFormData: HydratedAbsorbanceReaderFormData | ||
): AbsorbanceReaderArgs | null => { | ||
const { | ||
absorbanceReaderFormType, | ||
fileName, | ||
lidOpen, | ||
moduleId, | ||
// mode, | ||
// referenceWavelength, | ||
// wavelengths, | ||
} = hydratedFormData | ||
const lidAction = lidOpen | ||
? 'absorbanceReaderOpenLid' | ||
: 'absorbanceReaderCloseLid' | ||
switch (absorbanceReaderFormType) { | ||
case ABSORBANCE_READER_INITIALIZE: | ||
return { | ||
module: moduleId, | ||
mode: 'multi', // TODO (nd: 1/16/2025): reflect actual `mode` form field | ||
commandCreatorFnName: 'absorbanceReaderInitialize', | ||
...DUMMY_INITIALIZATION, | ||
} | ||
case ABSORBANCE_READER_READ: | ||
return { | ||
module: moduleId, | ||
commandCreatorFnName: 'absorbanceReaderRead', | ||
fileName, | ||
} | ||
case ABSORBANCE_READER_LID: | ||
return { | ||
module: moduleId, | ||
commandCreatorFnName: lidAction, | ||
} | ||
default: | ||
return null | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
step-generation/src/__tests__/absorbanceReaderCloseInitialize.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import { beforeEach, describe, it, expect, vi, afterEach } from 'vitest' | ||
import { absorbanceReaderCloseInitialize } from '../commandCreators' | ||
import { | ||
absorbanceReaderStateGetter, | ||
getModuleState, | ||
} from '../robotStateSelectors' | ||
import { getInitialRobotStateStandard, makeContext } from '../fixtures' | ||
import { getErrorResult, getSuccessResult } from '../fixtures/commandFixtures' | ||
|
||
import type { | ||
AbsorbanceReaderInitializeArgs, | ||
AbsorbanceReaderState, | ||
InvariantContext, | ||
RobotState, | ||
} from '../types' | ||
import { | ||
ABSORBANCE_READER_TYPE, | ||
ABSORBANCE_READER_V1, | ||
} from '@opentrons/shared-data' | ||
|
||
vi.mock('../robotStateSelectors') | ||
|
||
describe('absorbanceReaderCloseInitialize compound command creator', () => { | ||
let absorbanceReaderCloseInitializeArgs: AbsorbanceReaderInitializeArgs | ||
const ABSORBANCE_READER_MODULE_ID = 'absorbanceReaderModuleId' | ||
const ABSORBANCE_READER_MODULE_SLOT = 'D3' | ||
let robotState: RobotState | ||
let invariantContext: InvariantContext | ||
beforeEach(() => { | ||
absorbanceReaderCloseInitializeArgs = { | ||
commandCreatorFnName: 'absorbanceReaderInitialize', | ||
module: ABSORBANCE_READER_MODULE_ID, | ||
mode: 'single', | ||
wavelengths: [450], | ||
} | ||
invariantContext = { | ||
...makeContext(), | ||
moduleEntities: { | ||
[ABSORBANCE_READER_MODULE_ID]: { | ||
id: ABSORBANCE_READER_MODULE_ID, | ||
type: ABSORBANCE_READER_TYPE, | ||
model: ABSORBANCE_READER_V1, | ||
}, | ||
}, | ||
} | ||
const state = getInitialRobotStateStandard(invariantContext) | ||
|
||
robotState = { | ||
...state, | ||
modules: { | ||
...state.modules, | ||
[ABSORBANCE_READER_MODULE_ID]: { | ||
slot: ABSORBANCE_READER_MODULE_SLOT, | ||
} as any, | ||
}, | ||
} | ||
vi.mocked(getModuleState).mockReturnValue({ | ||
type: ABSORBANCE_READER_TYPE, | ||
} as any) | ||
}) | ||
afterEach(() => { | ||
vi.restoreAllMocks() | ||
}) | ||
it('should return an error when module is not found', () => { | ||
const result = absorbanceReaderCloseInitialize( | ||
absorbanceReaderCloseInitializeArgs, | ||
invariantContext, | ||
robotState | ||
) | ||
vi.mocked(absorbanceReaderStateGetter).mockReturnValue(null) | ||
|
||
expect(getErrorResult(result).errors).toHaveLength(1) | ||
expect(getErrorResult(result).errors[0]).toMatchObject({ | ||
type: 'MISSING_MODULE', | ||
}) | ||
}) | ||
it('should emit close and intalize commands if single mode', () => { | ||
vi.mocked(absorbanceReaderStateGetter).mockReturnValue( | ||
{} as AbsorbanceReaderState | ||
) | ||
|
||
const result = absorbanceReaderCloseInitialize( | ||
absorbanceReaderCloseInitializeArgs, | ||
invariantContext, | ||
robotState | ||
) | ||
|
||
expect(getSuccessResult(result).commands).toEqual([ | ||
{ | ||
commandType: 'absorbanceReader/closeLid', | ||
key: expect.any(String), | ||
params: { | ||
moduleId: 'absorbanceReaderModuleId', | ||
}, | ||
}, | ||
{ | ||
commandType: 'absorbanceReader/initialize', | ||
key: expect.any(String), | ||
params: { | ||
moduleId: 'absorbanceReaderModuleId', | ||
sampleWavelengths: [450], | ||
measureMode: 'single', | ||
}, | ||
}, | ||
]) | ||
}) | ||
it('should emit close and intalize commands if multi mode', () => { | ||
absorbanceReaderCloseInitializeArgs = { | ||
...absorbanceReaderCloseInitializeArgs, | ||
mode: 'multi', | ||
wavelengths: [450, 600], | ||
} | ||
vi.mocked(absorbanceReaderStateGetter).mockReturnValue( | ||
{} as AbsorbanceReaderState | ||
) | ||
|
||
const result = absorbanceReaderCloseInitialize( | ||
absorbanceReaderCloseInitializeArgs, | ||
invariantContext, | ||
robotState | ||
) | ||
|
||
expect(getSuccessResult(result).commands).toEqual([ | ||
{ | ||
commandType: 'absorbanceReader/closeLid', | ||
key: expect.any(String), | ||
params: { | ||
moduleId: 'absorbanceReaderModuleId', | ||
}, | ||
}, | ||
{ | ||
commandType: 'absorbanceReader/initialize', | ||
key: expect.any(String), | ||
params: { | ||
moduleId: 'absorbanceReaderModuleId', | ||
sampleWavelengths: [450, 600], | ||
measureMode: 'multi', | ||
}, | ||
}, | ||
]) | ||
}) | ||
}) |
Oops, something went wrong.