diff --git a/api/src/opentrons/hardware_control/ot3api.py b/api/src/opentrons/hardware_control/ot3api.py index 7b01f234589..33b2fe6f710 100644 --- a/api/src/opentrons/hardware_control/ot3api.py +++ b/api/src/opentrons/hardware_control/ot3api.py @@ -1037,6 +1037,12 @@ def _assert_encoder_ok(self, axes: Sequence[Axis]) -> None: detail={"axes": axes_str}, ) + def motor_status_ok(self, axis: Axis) -> bool: + return self._backend.check_motor_status([axis]) + + def encoder_status_ok(self, axis: Axis) -> bool: + return self._backend.check_encoder_status([axis]) + async def encoder_current_position( self, mount: Union[top_types.Mount, OT3Mount], diff --git a/api/src/opentrons/hardware_control/protocols/__init__.py b/api/src/opentrons/hardware_control/protocols/__init__.py index d4250a5d589..2a717084a0c 100644 --- a/api/src/opentrons/hardware_control/protocols/__init__.py +++ b/api/src/opentrons/hardware_control/protocols/__init__.py @@ -1,6 +1,8 @@ """Typing protocols describing a hardware controller.""" from typing_extensions import Protocol +from opentrons.hardware_control.types import Axis + from .module_provider import ModuleProvider from .hardware_manager import HardwareManager from .chassis_accessory_manager import ChassisAccessoryManager @@ -43,6 +45,12 @@ class HardwareControlInterface( ... + def motor_status_ok(self, axis: Axis) -> bool: + ... + + def encoder_status_ok(self, axis: Axis) -> bool: + ... + __all__ = [ "HardwareControlAPI", 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 464b177e980..b610eefe86c 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 @@ -80,6 +80,12 @@ async def execute( ot3_api = ensure_ot3_hardware( self._hardware_api, ) + # the 96-channel mount is disengaged during gripper calibration and + # must be homed before the gantry position can be called + if ot3_api.encoder_status_ok(Axis.Z_L) and not ot3_api.motor_status_ok( + Axis.Z_L + ): + await ot3_api.home([Axis.Z_L]) current_position_mount = await ot3_api.gantry_position( Mount.LEFT, critical_point=CriticalPoint.MOUNT )