From f388d038db80da6e628d68dfaed9c35573d30165 Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Thu, 9 Apr 2026 15:21:46 +0200 Subject: [PATCH] fix: initialize setpoint to 0.0 and update from readback after connection --- csaxs_bec/devices/npoint/npoint.py | 12 +++++++++++- csaxs_bec/devices/omny/galil/fgalil_ophyd.py | 8 ++++++++ csaxs_bec/devices/omny/galil/fupr_ophyd.py | 8 ++++++++ csaxs_bec/devices/omny/galil/galil_ophyd.py | 5 ++++- csaxs_bec/devices/omny/galil/lgalil_ophyd.py | 8 ++++++++ csaxs_bec/devices/omny/galil/ogalil_ophyd.py | 8 ++++++++ csaxs_bec/devices/omny/galil/sgalil_ophyd.py | 13 ++++++++++++- csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py | 9 ++++++++- csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py | 13 ++++++++++++- csaxs_bec/devices/omny/rt/rt_omny_ophyd.py | 9 ++++++++- csaxs_bec/devices/omny/rt/rt_ophyd.py | 5 ++++- tests/tests_devices/test_galil.py | 3 ++- 12 files changed, 93 insertions(+), 8 deletions(-) diff --git a/csaxs_bec/devices/npoint/npoint.py b/csaxs_bec/devices/npoint/npoint.py index d672329..481b30e 100644 --- a/csaxs_bec/devices/npoint/npoint.py +++ b/csaxs_bec/devices/npoint/npoint.py @@ -346,7 +346,9 @@ class NpointSetpointSignal(NpointSignalBase): Signal to set the target position of an nPoint piezo stage. """ - setpoint = 0 + def __init__(self, signal_name, **kwargs): + super().__init__(signal_name, **kwargs) + self.setpoint = 0.0 @threadlocked def _socket_get(self): @@ -444,6 +446,14 @@ class NPointAxis(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/galil/fgalil_ophyd.py b/csaxs_bec/devices/omny/galil/fgalil_ophyd.py index f705f88..f8d424b 100644 --- a/csaxs_bec/devices/omny/galil/fgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/fgalil_ophyd.py @@ -214,6 +214,14 @@ class FlomniGalilMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/galil/fupr_ophyd.py b/csaxs_bec/devices/omny/galil/fupr_ophyd.py index e7c0612..2b693dd 100644 --- a/csaxs_bec/devices/omny/galil/fupr_ophyd.py +++ b/csaxs_bec/devices/omny/galil/fupr_ophyd.py @@ -187,6 +187,14 @@ class FuprGalilMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/galil/galil_ophyd.py b/csaxs_bec/devices/omny/galil/galil_ophyd.py index f05325e..d6fcda9 100644 --- a/csaxs_bec/devices/omny/galil/galil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/galil_ophyd.py @@ -381,7 +381,10 @@ class GalilReadbackSignal(GalilSignalRO): class GalilSetpointSignal(GalilSignalBase): - setpoint = 0 + + def __init__(self, signal_name, **kwargs): + super().__init__(signal_name, **kwargs) + self.setpoint = 0.0 def _socket_get(self) -> float: """Get command for receiving the setpoint / target value. diff --git a/csaxs_bec/devices/omny/galil/lgalil_ophyd.py b/csaxs_bec/devices/omny/galil/lgalil_ophyd.py index b17d429..bff1cd6 100644 --- a/csaxs_bec/devices/omny/galil/lgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/lgalil_ophyd.py @@ -262,6 +262,14 @@ class LamniGalilMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/galil/ogalil_ophyd.py b/csaxs_bec/devices/omny/galil/ogalil_ophyd.py index ca55b9d..a7086ab 100644 --- a/csaxs_bec/devices/omny/galil/ogalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/ogalil_ophyd.py @@ -326,6 +326,14 @@ class OMNYGalilMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/galil/sgalil_ophyd.py b/csaxs_bec/devices/omny/galil/sgalil_ophyd.py index c787aaf..16b1c93 100644 --- a/csaxs_bec/devices/omny/galil/sgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/sgalil_ophyd.py @@ -388,7 +388,10 @@ class GalilReadbackSignal(GalilSignalRO): class GalilSetpointSignal(GalilSignalBase): - setpoint = 0 + + def __init__(self, signal_name, **kwargs): + super().__init__(signal_name, **kwargs) + self.setpoint = 0.0 def _socket_get(self) -> float: """Get command for receiving the setpoint / target value. @@ -532,6 +535,14 @@ class SGalilMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py index d882f4d..1626ebc 100644 --- a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py @@ -490,7 +490,6 @@ class RtFlomniReadbackSignal(RtReadbackSignal): class RtFlomniSetpointSignal(RtSetpointSignal): - setpoint = 0 @retry_once @threadlocked @@ -605,6 +604,14 @@ class RtFlomniMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py index 53c6e4f..e69207a 100644 --- a/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py @@ -441,7 +441,10 @@ class RtLamniReadbackSignal(RtLamniSignalRO): class RtLamniSetpointSignal(RtLamniSignalBase): - setpoint = 0 + + def __init__(self, signal_name, **kwargs): + super().__init__(signal_name, **kwargs) + self.setpoint = 0.0 def _socket_get(self) -> float: """Get command for receiving the setpoint / target value. @@ -563,6 +566,14 @@ class RtLamniMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py index ef0aa09..f84441b 100644 --- a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py @@ -901,7 +901,6 @@ class RtOMNYReadbackSignal(RtReadbackSignal): class RtOMNYSetpointSignal(RtSetpointSignal): - setpoint = 0 @retry_once @threadlocked @@ -1002,6 +1001,14 @@ class RtOMNYMotor(Device, PositionerBase): def wait_for_connection(self, timeout: float = 30.0) -> bool: self.controller.on(timeout=timeout) + self._update_setpoint_from_readback() + + def _update_setpoint_from_readback(self): + """ + The setpoint is only stored locally. After a restart, + we need to update it to match the current readback value. + """ + self.user_setpoint.setpoint = self.readback.get() def destroy(self): """Make sure to turn off the controller socket on destroy.""" diff --git a/csaxs_bec/devices/omny/rt/rt_ophyd.py b/csaxs_bec/devices/omny/rt/rt_ophyd.py index d61d3bd..1948b08 100644 --- a/csaxs_bec/devices/omny/rt/rt_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_ophyd.py @@ -81,7 +81,10 @@ class RtReadbackSignal(RtSignalRO): class RtSetpointSignal(RtSignalBase): - setpoint = 0 + + def __init__(self, signal_name, **kwargs): + super().__init__(signal_name, **kwargs) + self.setpoint = 0.0 def _socket_get(self) -> float: """Get command for receiving the setpoint / target value. diff --git a/tests/tests_devices/test_galil.py b/tests/tests_devices/test_galil.py index f4f9578..dc38c54 100644 --- a/tests/tests_devices/test_galil.py +++ b/tests/tests_devices/test_galil.py @@ -217,7 +217,8 @@ def test_wait_for_connection_called(dm_with_devices): } motor = motor_cls(*args, **kwargs) with mock.patch.object(motor.controller, "on") as mock_on: - motor.controller.get_position = mock.MagicMock(return_value=0) + if motor_cls != GalilRIO: # galilrio does not have a proper setpoint + motor._update_setpoint_from_readback = mock.MagicMock() motor.wait_for_connection(timeout=5.0) assert mock_on.call_args_list[-1] == mock.call(timeout=5.0) -- 2.52.0