From 9cdf508f612431d99ba495a5465f253153738c4b Mon Sep 17 00:00:00 2001 From: Robert Tuck Date: Fri, 5 Dec 2025 11:36:11 +0000 Subject: [PATCH 1/2] Change BartRobot to use a sentinel instead of None for the empty location --- src/dodal/devices/robot.py | 13 ++++++++----- tests/devices/test_bart_robot.py | 7 ++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/dodal/devices/robot.py b/src/dodal/devices/robot.py index 0acb6e6eaf..235ca1f1f3 100644 --- a/src/dodal/devices/robot.py +++ b/src/dodal/devices/robot.py @@ -43,6 +43,9 @@ class SampleLocation: pin: int +SAMPLE_LOCATION_EMPTY = SampleLocation(0, 0) + + class PinMounted(StrictEnum): NO_PIN_MOUNTED = "No Pin Mounted" PIN_MOUNTED = "Pin Mounted" @@ -61,7 +64,7 @@ async def raise_if_error(self, raise_from: Exception): raise RobotLoadError(int(error_code), error_string) from raise_from -class BartRobot(StandardReadable, Movable[SampleLocation | None]): +class BartRobot(StandardReadable, Movable[SampleLocation]): """The sample changing robot.""" # How long to wait for the robot if it is busy soaking/drying @@ -179,16 +182,16 @@ async def _load_pin_and_puck(self, sample_location: SampleLocation): await self.pin_state_or_error() @AsyncStatus.wrap - async def set(self, value: SampleLocation | None): + async def set(self, value: SampleLocation): """ Perform a sample load from the specified sample location Args: - value: The pin and puck to load, or None to unload the sample. + value: The pin and puck to load, or SAMPLE_LOCATION_EMPTY to unload the sample. Raises: - RobotLoadError if a timeout occurs, or if an error occurs loading the smaple. + RobotLoadError if a timeout occurs, or if an error occurs loading the sample. """ try: - if value is not None: + if value != SAMPLE_LOCATION_EMPTY: await wait_for( self._load_pin_and_puck(value), timeout=self.LOAD_TIMEOUT + self.NOT_BUSY_TIMEOUT, diff --git a/tests/devices/test_bart_robot.py b/tests/devices/test_bart_robot.py index 59a9184003..abcb2179cd 100644 --- a/tests/devices/test_bart_robot.py +++ b/tests/devices/test_bart_robot.py @@ -14,6 +14,7 @@ ) from dodal.devices.robot import ( + SAMPLE_LOCATION_EMPTY, WAIT_FOR_NEW_PIN_MSG, WAIT_FOR_OLD_PIN_MSG, BartRobot, @@ -253,7 +254,7 @@ async def test_moving_the_robot_will_reset_error_if_light_curtain_is_tripped_and async def test_unloading_the_robot_waits_for_drying_to_complete(robot_for_unload): robot, trigger_completed, drying_completed = robot_for_unload drying_completed.set() - unload_status = robot.set(None) + unload_status = robot.set(SAMPLE_LOCATION_EMPTY) await asyncio.sleep(0.1) assert not unload_status.done @@ -269,7 +270,7 @@ async def test_unloading_the_robot_times_out_if_unloading_takes_too_long( ): robot, trigger_completed, drying_completed = robot_for_unload drying_completed.set() - unload_status = robot.set(None) + unload_status = robot.set(SAMPLE_LOCATION_EMPTY) with pytest.raises(RobotLoadError) as exc_info: await unload_status @@ -280,7 +281,7 @@ async def test_unloading_the_robot_times_out_if_unloading_takes_too_long( async def test_unloading_the_robot_times_out_if_drying_takes_too_long(robot_for_unload): robot, trigger_completed, drying_completed = robot_for_unload trigger_completed.set() - unload_status = robot.set(None) + unload_status = robot.set(SAMPLE_LOCATION_EMPTY) with pytest.raises(RobotLoadError) as exc_info: await unload_status From a946a46ffd418ea25fbae9134954659cfa223d6f Mon Sep 17 00:00:00 2001 From: Robert Tuck Date: Fri, 5 Dec 2025 13:14:37 +0000 Subject: [PATCH 2/2] Change SAMPLE_LOCATION_EMPTY to be less ambiguous --- src/dodal/devices/robot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dodal/devices/robot.py b/src/dodal/devices/robot.py index 235ca1f1f3..52e3b478cf 100644 --- a/src/dodal/devices/robot.py +++ b/src/dodal/devices/robot.py @@ -43,7 +43,7 @@ class SampleLocation: pin: int -SAMPLE_LOCATION_EMPTY = SampleLocation(0, 0) +SAMPLE_LOCATION_EMPTY = SampleLocation(-1, -1) class PinMounted(StrictEnum):