From ae20de9391255c50902de99fce62cbbcc69ea8e0 Mon Sep 17 00:00:00 2001 From: appel_c Date: Thu, 22 Jan 2026 08:43:46 +0100 Subject: [PATCH 1/2] fix(controller): Ensure that destroy calls controller.off --- csaxs_bec/devices/npoint/npoint.py | 7 ++++++- csaxs_bec/devices/omny/galil/fgalil_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/galil/fupr_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/galil/lgalil_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/galil/ogalil_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/galil/sgalil_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py | 7 ++++++- csaxs_bec/devices/omny/rt/rt_omny_ophyd.py | 7 ++++++- csaxs_bec/devices/smaract/smaract_ophyd.py | 7 ++++++- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/csaxs_bec/devices/npoint/npoint.py b/csaxs_bec/devices/npoint/npoint.py index c99b185..d672329 100644 --- a/csaxs_bec/devices/npoint/npoint.py +++ b/csaxs_bec/devices/npoint/npoint.py @@ -442,9 +442,14 @@ class NPointAxis(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/galil/fgalil_ophyd.py b/csaxs_bec/devices/omny/galil/fgalil_ophyd.py index 37640fb..f705f88 100644 --- a/csaxs_bec/devices/omny/galil/fgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/fgalil_ophyd.py @@ -212,9 +212,14 @@ class FlomniGalilMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/galil/fupr_ophyd.py b/csaxs_bec/devices/omny/galil/fupr_ophyd.py index 7ca1439..e7c0612 100644 --- a/csaxs_bec/devices/omny/galil/fupr_ophyd.py +++ b/csaxs_bec/devices/omny/galil/fupr_ophyd.py @@ -185,9 +185,14 @@ class FuprGalilMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/galil/lgalil_ophyd.py b/csaxs_bec/devices/omny/galil/lgalil_ophyd.py index 2f2d304..87d3c19 100644 --- a/csaxs_bec/devices/omny/galil/lgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/lgalil_ophyd.py @@ -170,9 +170,14 @@ class LamniGalilMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/galil/ogalil_ophyd.py b/csaxs_bec/devices/omny/galil/ogalil_ophyd.py index 90f45fe..ca55b9d 100644 --- a/csaxs_bec/devices/omny/galil/ogalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/ogalil_ophyd.py @@ -324,9 +324,14 @@ class OMNYGalilMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/galil/sgalil_ophyd.py b/csaxs_bec/devices/omny/galil/sgalil_ophyd.py index d0e838b..c787aaf 100644 --- a/csaxs_bec/devices/omny/galil/sgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/sgalil_ophyd.py @@ -530,9 +530,14 @@ class SGalilMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py index 044884f..a4eaee4 100644 --- a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py @@ -678,9 +678,14 @@ class RtFlomniMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py index 60e8730..8e65acc 100644 --- a/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py @@ -588,9 +588,14 @@ class RtLamniMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py index a1ee947..13a5fa2 100644 --- a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py @@ -1119,9 +1119,14 @@ class RtOMNYMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) diff --git a/csaxs_bec/devices/smaract/smaract_ophyd.py b/csaxs_bec/devices/smaract/smaract_ophyd.py index 8944ddf..827e564 100644 --- a/csaxs_bec/devices/smaract/smaract_ophyd.py +++ b/csaxs_bec/devices/smaract/smaract_ophyd.py @@ -153,9 +153,14 @@ class SmaractMotor(Device, PositionerBase): self.low_limit_travel.put(limits[0]) self.high_limit_travel.put(limits[1]) - def wait_for_connection(self, all_signals=False, timeout: float = 30.0) -> bool: + def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + def destroy(self): + """Make sure to turn off the controller socket on destroy.""" + self.controller.off(update_config=False) + return super().destroy() + @property def limits(self): return (self.low_limit_travel.get(), self.high_limit_travel.get()) -- 2.49.1 From 5c5a5c3d98aa1ed70153eb31a363e92b41fa1761 Mon Sep 17 00:00:00 2001 From: appel_c Date: Thu, 22 Jan 2026 08:45:35 +0100 Subject: [PATCH 2/2] test: add test for controller to call destroy controller.off --- tests/tests_devices/test_galil.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/tests_devices/test_galil.py b/tests/tests_devices/test_galil.py index dc0ed68..841f4f4 100644 --- a/tests/tests_devices/test_galil.py +++ b/tests/tests_devices/test_galil.py @@ -207,6 +207,15 @@ def test_wait_for_connection_called(): motor.wait_for_connection(timeout=5.0) assert mock_on.call_args_list[-1] == mock.call(timeout=5.0) + + # Make sure destroy calls controller off + + with mock.patch.object(motor.controller, "off") as mock_off: + motor.destroy() + assert mock_off.call_count == 1 + assert mock_off.call_args_list[0] == mock.call(update_config=False) + assert motor._destroyed is True + finally: controller_cls._reset_controller() controller_cls._axes_per_controller = ctrl_axis_backup -- 2.49.1