diff --git a/api/src/opentrons/protocol_engine/commands/absorbance_reader/close_lid.py b/api/src/opentrons/protocol_engine/commands/absorbance_reader/close_lid.py index 6252be497e9..31c51676e7d 100644 --- a/api/src/opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +++ b/api/src/opentrons/protocol_engine/commands/absorbance_reader/close_lid.py @@ -65,80 +65,72 @@ async def execute( loaded_lid = self._state_view.labware.get(mod_substate.lid_id) assert labware_validation.is_absorbance_reader_lid(loaded_lid.loadName) - # If the lid is already Closed, No-op out - if mod_substate.is_lid_on: - current_offset_id = self._equipment.find_applicable_labware_offset_id( + hardware_lid_status = AbsorbanceReaderLidStatus.OFF + # If the lid is closed, if the lid is open No-op out + if not self._state_view.config.use_virtual_modules: + abs_reader = self._equipment.get_module_hardware_api(mod_substate.module_id) + + if abs_reader is not None: + result = await abs_reader.get_current_lid_status() + hardware_lid_status = result + else: + raise CannotPerformModuleAction( + "Could not reach the Hardware API for Opentrons Plate Reader Module." + ) + + # If the lid is already ON, no-op losing lid + if hardware_lid_status is AbsorbanceReaderLidStatus.ON: + # The lid is already On, so we can no-op and return the lids current location data + assert isinstance(loaded_lid.location, AddressableAreaLocation) + new_location = loaded_lid.location + new_offset_id = self._equipment.find_applicable_labware_offset_id( labware_definition_uri=loaded_lid.definitionUri, labware_location=loaded_lid.location, ) - return SuccessData( - public=CloseLidResult( - lidId=loaded_lid.id, - newLocation=loaded_lid.location, - offsetId=current_offset_id, - ), - private=None, - ) - - # Allow propagation of ModuleNotAttachedError. - _ = self._equipment.get_module_hardware_api(mod_substate.module_id) - - current_location = loaded_lid.location - validated_current_location = ( - self._state_view.geometry.ensure_valid_gripper_location(current_location) - ) + else: + # Allow propagation of ModuleNotAttachedError. + _ = self._equipment.get_module_hardware_api(mod_substate.module_id) - # we need to move the lid onto the module reader - absorbance_model = self._state_view.modules.get_requested_model(params.moduleId) - assert absorbance_model is not None - new_location = AddressableAreaLocation( - addressableAreaName=self._state_view.modules.ensure_and_convert_module_fixture_location( - deck_slot=self._state_view.modules.get_location( - params.moduleId - ).slotName, - deck_type=self._state_view.config.deck_type, - model=absorbance_model, + current_location = self._state_view.modules.absorbance_reader_dock_location( + params.moduleId ) - ) - validated_new_location = ( - self._state_view.geometry.ensure_valid_gripper_location(new_location) - ) - lid_gripper_offsets = self._state_view.labware.get_labware_gripper_offsets( - loaded_lid.id, None - ) - if lid_gripper_offsets is None: - raise ValueError( - "Gripper Offset values for Absorbance Reader Lid labware must not be None." + # we need to move the lid onto the module reader + absorbance_model = self._state_view.modules.get_requested_model( + params.moduleId + ) + assert absorbance_model is not None + new_location = AddressableAreaLocation( + addressableAreaName=self._state_view.modules.ensure_and_convert_module_fixture_location( + deck_slot=self._state_view.modules.get_location( + params.moduleId + ).slotName, + deck_type=self._state_view.config.deck_type, + model=absorbance_model, + ) ) - # Skips gripper moves when using virtual gripper - await self._labware_movement.move_labware_with_gripper( - labware_id=loaded_lid.id, - current_location=validated_current_location, - new_location=validated_new_location, - user_offset_data=lid_gripper_offsets, - post_drop_slide_offset=None, - ) - - new_offset_id = self._equipment.find_applicable_labware_offset_id( - labware_definition_uri=loaded_lid.definitionUri, - labware_location=new_location, - ) + lid_gripper_offsets = self._state_view.labware.get_labware_gripper_offsets( + loaded_lid.id, None + ) + if lid_gripper_offsets is None: + raise ValueError( + "Gripper Offset values for Absorbance Reader Lid labware must not be None." + ) - if not self._state_view.config.use_virtual_modules: - abs_reader = self._equipment.get_module_hardware_api(mod_substate.module_id) + # Skips gripper moves when using virtual gripper + await self._labware_movement.move_labware_with_gripper( + labware_id=loaded_lid.id, + current_location=current_location, + new_location=new_location, + user_offset_data=lid_gripper_offsets, + post_drop_slide_offset=None, + ) - if abs_reader is not None: - result = await abs_reader.get_current_lid_status() - if result is not AbsorbanceReaderLidStatus.ON: - raise CannotPerformModuleAction( - "The mechanical position of the Absorbance Plate Reader's lid did not match the expected 'closed' state." - ) - else: - raise CannotPerformModuleAction( - "Could not reach the Hardware API for Opentrons Plate Reader Module." - ) + new_offset_id = self._equipment.find_applicable_labware_offset_id( + labware_definition_uri=loaded_lid.definitionUri, + labware_location=new_location, + ) return SuccessData( public=CloseLidResult( diff --git a/api/src/opentrons/protocol_engine/commands/absorbance_reader/open_lid.py b/api/src/opentrons/protocol_engine/commands/absorbance_reader/open_lid.py index cef90051f9c..f12a612f649 100644 --- a/api/src/opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +++ b/api/src/opentrons/protocol_engine/commands/absorbance_reader/open_lid.py @@ -11,6 +11,7 @@ from .types import MoveLidResult from opentrons.protocol_engine.resources import labware_validation +from opentrons.protocol_engine.types import AddressableAreaLocation from opentrons.drivers.types import AbsorbanceReaderLidStatus @@ -59,76 +60,75 @@ async def execute(self, params: OpenLidParams) -> SuccessData[OpenLidResult, Non loaded_lid = self._state_view.labware.get(mod_substate.lid_id) assert labware_validation.is_absorbance_reader_lid(loaded_lid.loadName) - # If the lid is already Open, No-op out - if not mod_substate.is_lid_on: - current_offset_id = self._equipment.find_applicable_labware_offset_id( - labware_definition_uri=loaded_lid.definitionUri, - labware_location=loaded_lid.location, - ) - return SuccessData( - public=OpenLidResult( - lidId=loaded_lid.id, - newLocation=loaded_lid.location, - offsetId=current_offset_id, - ), - private=None, - ) - - # Allow propagation of ModuleNotAttachedError. - _ = self._equipment.get_module_hardware_api(mod_substate.module_id) - - current_location = loaded_lid.location - validated_current_location = ( - self._state_view.geometry.ensure_valid_gripper_location(current_location) - ) - - # we need to move the lid to the lid dock - new_location = self._state_view.modules.absorbance_reader_dock_location( - mod_substate.module_id - ) - validated_new_location = ( - self._state_view.geometry.ensure_valid_gripper_location(new_location) - ) - - lid_gripper_offsets = self._state_view.labware.get_labware_gripper_offsets( - loaded_lid.id, None - ) - if lid_gripper_offsets is None: - raise ValueError( - "Gripper Offset values for Absorbance Reader Lid labware must not be None." - ) - - # Skips gripper moves when using virtual gripper - await self._labware_movement.move_labware_with_gripper( - labware_id=loaded_lid.id, - current_location=validated_current_location, - new_location=validated_new_location, - user_offset_data=lid_gripper_offsets, - post_drop_slide_offset=None, - ) - new_offset_id = self._equipment.find_applicable_labware_offset_id( - labware_definition_uri=loaded_lid.definitionUri, - labware_location=new_location, - ) - + hardware_lid_status = AbsorbanceReaderLidStatus.ON + # If the lid is closed, if the lid is open No-op out if not self._state_view.config.use_virtual_modules: abs_reader = self._equipment.get_module_hardware_api(mod_substate.module_id) if abs_reader is not None: result = await abs_reader.get_current_lid_status() - if result is not AbsorbanceReaderLidStatus.OFF: - raise CannotPerformModuleAction( - "The Opentrons Plate Reader lid mechanicaly position did not match expected Open state." - ) + hardware_lid_status = result else: raise CannotPerformModuleAction( "Could not reach the Hardware API for Opentrons Plate Reader Module." ) + # If the lid is already OFF, no-op the lid removal + if hardware_lid_status is AbsorbanceReaderLidStatus.OFF: + assert isinstance(loaded_lid.location, AddressableAreaLocation) + new_location = loaded_lid.location + new_offset_id = self._equipment.find_applicable_labware_offset_id( + labware_definition_uri=loaded_lid.definitionUri, + labware_location=loaded_lid.location, + ) + else: + # Allow propagation of ModuleNotAttachedError. + _ = self._equipment.get_module_hardware_api(mod_substate.module_id) + + absorbance_model = self._state_view.modules.get_requested_model( + params.moduleId + ) + assert absorbance_model is not None + current_location = AddressableAreaLocation( + addressableAreaName=self._state_view.modules.ensure_and_convert_module_fixture_location( + deck_slot=self._state_view.modules.get_location( + params.moduleId + ).slotName, + deck_type=self._state_view.config.deck_type, + model=absorbance_model, + ) + ) + + # we need to move the lid to the lid dock + new_location = self._state_view.modules.absorbance_reader_dock_location( + mod_substate.module_id + ) + + lid_gripper_offsets = self._state_view.labware.get_labware_gripper_offsets( + loaded_lid.id, None + ) + if lid_gripper_offsets is None: + raise ValueError( + "Gripper Offset values for Absorbance Reader Lid labware must not be None." + ) + + # Skips gripper moves when using virtual gripper + await self._labware_movement.move_labware_with_gripper( + labware_id=loaded_lid.id, + current_location=current_location, + new_location=new_location, + user_offset_data=lid_gripper_offsets, + post_drop_slide_offset=None, + ) + new_offset_id = self._equipment.find_applicable_labware_offset_id( + labware_definition_uri=loaded_lid.definitionUri, + labware_location=new_location, + ) + return SuccessData( public=OpenLidResult( lidId=loaded_lid.id, - newLocation=validated_new_location, + newLocation=new_location, offsetId=new_offset_id, ), private=None, diff --git a/api/src/opentrons/protocol_engine/commands/load_module.py b/api/src/opentrons/protocol_engine/commands/load_module.py index c24825d64e2..d4cd1efba60 100644 --- a/api/src/opentrons/protocol_engine/commands/load_module.py +++ b/api/src/opentrons/protocol_engine/commands/load_module.py @@ -179,11 +179,12 @@ async def execute( lid_labware = self._state_view.labware.get_by_addressable_area( reader_area ) + if lid_labware is not None: - lid_labware.location = ( - self._state_view.modules.absorbance_reader_dock_location( - params.moduleId - ) + self._state_view.labware._state.labware_by_id[ + lid_labware.id + ].location = self._state_view.modules.absorbance_reader_dock_location( + params.moduleId ) return SuccessData(