From cfbd7b9e8d64d6447664be5f856d5fa532b4f4ff Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Fri, 29 Nov 2024 16:57:23 +0000 Subject: [PATCH] Ensure motors can be stopped --- src/ophyd_async/epics/motor.py | 9 ++++++--- tests/epics/test_motor.py | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ophyd_async/epics/motor.py b/src/ophyd_async/epics/motor.py index 482adfd97c..c512f4ba03 100644 --- a/src/ophyd_async/epics/motor.py +++ b/src/ophyd_async/epics/motor.py @@ -20,7 +20,7 @@ observe_value, ) from ophyd_async.core import StandardReadableFormat as Format -from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal_x +from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal_w class MotorLimitsException(Exception): @@ -76,7 +76,10 @@ def __init__(self, prefix: str, name="") -> None: self.low_limit_travel = epics_signal_rw(float, prefix + ".LLM") self.high_limit_travel = epics_signal_rw(float, prefix + ".HLM") - self.motor_stop = epics_signal_x(prefix + ".STOP") + # Note:cannot use epics_signal_x here, as the motor record specifies that + # we must write 1 to stop the motor. Simply processing the record is not + # sufficient. + self.motor_stop = epics_signal_w(int, prefix + ".STOP") # Whether set() should complete successfully or not self._set_success = True @@ -178,7 +181,7 @@ async def stop(self, success=False): self._set_success = success # Put with completion will never complete as we are waiting for completion on # the move above, so need to pass wait=False - await self.motor_stop.trigger(wait=False) + await self.motor_stop.set(1, wait=False) async def _prepare_velocity( self, start_position: float, end_position: float, time_for_move: float diff --git a/tests/epics/test_motor.py b/tests/epics/test_motor.py index 055d49cb31..fc513e8f8d 100644 --- a/tests/epics/test_motor.py +++ b/tests/epics/test_motor.py @@ -10,6 +10,7 @@ AsyncStatus, DeviceCollector, callback_on_mock_put, + get_mock_put, mock_puts_blocked, observe_value, set_mock_put_proceeds, @@ -164,6 +165,11 @@ async def test_motor_moving_stopped(sim_motor: motor.Motor): await asyncio.sleep(0.2) assert not s.done await sim_motor.stop() + + # Note: needs to explicitly be called with 1, not just processed. + # See https://epics.anl.gov/bcda/synApps/motor/motorRecord.html#Fields_command + get_mock_put(sim_motor.motor_stop).assert_called_once_with(1, wait=False) + set_mock_put_proceeds(sim_motor.user_setpoint, True) await wait_for_wakeups() assert s.done