Skip to content

Commit 67bc901

Browse files
authored
Merge pull request #261 from ISISComputingGroup/motor_limits_tests
Motor limits are now checked by `ophyd-async`
2 parents 2b4d3ea + 64f7e36 commit 67bc901

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

doc/devices/blocks.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ type `float`, and as such does not take a type argument (unlike the other block
118118

119119
`Checkable` means that moves which would eventually violate limits can be detected by
120120
bluesky simulators, before the plan ever runs. This can help to catch errors before
121-
the plan is executed against hardware.
121+
the plan is executed against hardware. There is also limit-checking at runtime;
122+
a {external+ophyd_async:py:obj}`MotorLimitsException <ophyd_async.epics.motor.MotorLimitsException>` will be raised
123+
at runtime if a requested position is outside the motor's limits.
122124

123125
`Stoppable` means that the motor can be asked to stop by bluesky. Plans may choose to execute
124126
a `stop()` on failure, or explicitly during a plan.

src/ibex_bluesky_core/devices/block.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ def set( # pyright: ignore
407407
"""Pass through set to superclass.
408408
409409
This is needed so that type-checker correctly understands the type of set.
410+
411+
This method will raise
412+
:external+ophyd_async:py:obj:`ophyd_async.epics.motor.MotorLimitsException`
413+
if the requested position was outside the motor's limits.
410414
"""
411415
return super().set(value, timeout)
412416

tests/devices/test_block.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import bluesky.plan_stubs as bps
88
import bluesky.plans as bp
9+
import ophyd_async
910
import pytest
1011
from ophyd_async.testing import get_mock_put, set_mock_value
1112

@@ -349,13 +350,31 @@ def test_block_reprs():
349350
assert repr(BlockMot(block_name="qux", prefix="")) == "BlockMot(name=qux)"
350351

351352

352-
async def test_block_mot_set(mot_block):
353+
async def test_block_mot_set_within_limits(mot_block):
353354
set_mock_value(mot_block.user_setpoint, 10)
354355
set_mock_value(mot_block.velocity, 10)
356+
set_mock_value(mot_block.high_limit_travel, 1000)
357+
set_mock_value(mot_block.low_limit_travel, -1000)
355358
await mot_block.set(20)
356359
get_mock_put(mot_block.user_setpoint).assert_called_once_with(20, wait=True)
357360

358361

362+
@pytest.mark.skipif(
363+
ophyd_async._version.version_tuple < (0, 13, 2),
364+
reason="Exception only raised in ophyd_async >= 0.13.2",
365+
)
366+
async def test_block_mot_set_outside_limits(mot_block):
367+
# Local import as API not available in older ophyd_async versions
368+
from ophyd_async.epics.motor import MotorLimitsException # noqa PLC0415
369+
370+
set_mock_value(mot_block.user_setpoint, 10)
371+
set_mock_value(mot_block.velocity, 10)
372+
set_mock_value(mot_block.high_limit_travel, 15)
373+
set_mock_value(mot_block.low_limit_travel, 5)
374+
with pytest.raises(MotorLimitsException):
375+
await mot_block.set(20)
376+
377+
359378
@pytest.mark.parametrize("timeout_is_error", [True, False])
360379
async def test_block_failing_write(timeout_is_error):
361380
block = await _block_with_write_config(BlockWriteConfig(timeout_is_error=timeout_is_error))

0 commit comments

Comments
 (0)