From c609105327dba181802a1b4d182bf5282372d826 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Jul 2025 10:43:02 +0200 Subject: [PATCH] add simple positioner for undulator --- .../devices/psi_positioner_undulator.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ophyd_devices/devices/psi_positioner_undulator.py diff --git a/ophyd_devices/devices/psi_positioner_undulator.py b/ophyd_devices/devices/psi_positioner_undulator.py new file mode 100644 index 0000000..ae86354 --- /dev/null +++ b/ophyd_devices/devices/psi_positioner_undulator.py @@ -0,0 +1,28 @@ +""" +Module for undulator control +""" + +from ophyd import EpicsSignal, EpicsSignalRO +from ophyd.device import Component as Cpt + +from ophyd_devices.interfaces.base_classes.psi_positioner_base import PSISimplePositionerBase + + +class UndulatorGap(PSISimplePositionerBase): + """ + SLS Undulator gap control + """ + + user_setpoint = Cpt(EpicsSignal, suffix="GAP-SP") + user_readback = Cpt(EpicsSignal, suffix="GAP-RBV", kind="hinted", auto_monitor=True) + + motor_stop = Cpt(EpicsSignal, suffix="STOP") + motor_done_move = Cpt(EpicsSignalRO, suffix="DONE", auto_monitor=True) + + select_control = Cpt(EpicsSignalRO, suffix="SCTRL", auto_monitor=True) + + def move(self, position, wait=True, timeout=None, moved_cb=None): + # If it is operator controlled, undulator will not move. + if self.select_control.get() == 0: + raise RuntimeError("Undulator is operator controlled!") + return super().move(position, wait=wait, timeout=timeout, moved_cb=moved_cb)