diff --git a/ophyd/sim.py b/ophyd/sim.py index 8f43452ea..632fbecc4 100644 --- a/ophyd/sim.py +++ b/ophyd/sim.py @@ -470,6 +470,9 @@ def readback_func(x): self._events_per_move = events_per_move self.egu = egu + def _make_status(self, target: float): + return MoveStatus(positioner=self, target=target) + def set(self, value: float) -> MoveStatus: old_setpoint = self.sim_state["setpoint"] distance = value - old_setpoint @@ -499,7 +502,7 @@ def update_state(position: float) -> None: timestamp=self.sim_state["readback_ts"], ) - st = MoveStatus(positioner=self, target=value) + st = self._make_status(target=value) def sleep_and_finish(): event_delay = self.delay / self._events_per_move @@ -1143,6 +1146,9 @@ def inverse(self, real_pos): class SynAxisNoPosition(SynAxis): + def _make_status(self, target: float): + return DeviceStatus(device=self) + @property def position(self): raise AttributeError diff --git a/ophyd/tests/test_sim.py b/ophyd/tests/test_sim.py index 70b0da435..7bd6a66d1 100644 --- a/ophyd/tests/test_sim.py +++ b/ophyd/tests/test_sim.py @@ -1,5 +1,6 @@ import shutil import tempfile +from typing import Callable import numpy as np import pytest @@ -18,6 +19,9 @@ FakeEpicsSignalWithRBV, Syn2DGauss, SynAxis, + SynAxisEmptyHints, + SynAxisNoHints, + SynAxisNoPosition, SynGauss, SynSignalWithRegistry, clear_fake_device, @@ -104,6 +108,34 @@ def test_synaxis_requires_at_least_1_event_per_move(events_per_move): SynAxis(name="motor1", events_per_move=0) +@pytest.mark.parametrize( + "motor_factory", + [ + lambda: SynAxis(name="motor", value=0.0), + lambda: SynAxisEmptyHints(name="motor", value=0.0), + lambda: SynAxisNoHints(name="motor", value=0.0), + lambda: SynAxisNoPosition(name="motor", value=0.0), + ], +) +def test_move_synaxis(motor_factory: Callable[[], SynAxis]): + # Test is run twice, once for caproto and once for pyepics, so we need a + # factory rather than a global object to preserve state management + motor = motor_factory() + + initial_value = motor.readback.get() + motor.set(1.0).wait() + final_value = motor.readback.get() + + assert initial_value == 0.0 + assert final_value == 1.0 + + +def test_synaxisnoposition_has_no_position(): + motor = SynAxisNoPosition(name="motor", labels={"motors"}) + with pytest.raises(AttributeError): + motor.position + + @pytest.mark.parametrize("events_per_move", [1, 2, 6, 20]) def test_synaxis_subcribe(events_per_move: int): hits = dict.fromkeys(["r", "s", "a"], 0)