mirror of
https://github.com/bec-project/ophyd_devices.git
synced 2026-02-04 14:18:41 +01:00
fix(psi-motor): Add new user motor imlementation that checks if the IOC is enabled.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
from ophyd.quadem import QuadEM
|
||||
from ophyd.sim import SynAxis, SynPeriodicSignal, SynSignal
|
||||
|
||||
from .epics_motor_ex import EpicsMotorEx
|
||||
from .psi_motor import EpicsMotor, EpicsMotorEC
|
||||
from .sls_devices import SLSInfo, SLSOperatorMessages
|
||||
from .SpmBase import SpmBase
|
||||
|
||||
@@ -1,66 +1,18 @@
|
||||
from ophyd import Component as Cpt
|
||||
from ophyd import EpicsMotor, EpicsSignal
|
||||
# """Module extending EpicsMotor for VME based User motors with extra configuration fields."""
|
||||
|
||||
# from ophyd import Component as Cpt
|
||||
# from ophyd import EpicsSignal
|
||||
|
||||
# # from ophyd_devices.devices.psi_motor import EpicsUserMotors
|
||||
|
||||
|
||||
class EpicsMotorEx(EpicsMotor):
|
||||
"""Extend EpicsMotor with extra configuration fields.
|
||||
motor_done_move
|
||||
motor_is_moving
|
||||
"""
|
||||
# class EpicsMotorEx(EpicsUserMotors):
|
||||
# """
|
||||
# EpicsMotor that extends a VME based user motor with additional configuration signals,
|
||||
# motor_resolution, base_velocity and backlash_distance.
|
||||
# """
|
||||
|
||||
# configuration
|
||||
motor_resolution = Cpt(EpicsSignal, ".MRES", kind="config", auto_monitor=True)
|
||||
base_velocity = Cpt(EpicsSignal, ".VBAS", kind="config", auto_monitor=True)
|
||||
backlash_distance = Cpt(EpicsSignal, ".BDST", kind="config", auto_monitor=True)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
prefix="",
|
||||
*,
|
||||
name,
|
||||
kind=None,
|
||||
read_attrs=None,
|
||||
configuration_attrs=None,
|
||||
parent=None,
|
||||
**kwargs,
|
||||
):
|
||||
# get configuration attributes from kwargs and then remove them
|
||||
attrs = {}
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(EpicsMotorEx, key) and isinstance(getattr(EpicsMotorEx, key), Cpt):
|
||||
attrs[key] = value
|
||||
for key in attrs:
|
||||
kwargs.pop(key)
|
||||
|
||||
super().__init__(
|
||||
prefix,
|
||||
name=name,
|
||||
kind=kind,
|
||||
read_attrs=read_attrs,
|
||||
configuration_attrs=configuration_attrs,
|
||||
parent=parent,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# set configuration attributes
|
||||
for key, value in attrs.items():
|
||||
# print out attributes that are being configured
|
||||
print("setting ", key, "=", value)
|
||||
getattr(self, key).put(value)
|
||||
|
||||
# self.motor_done_move.subscribe(self._progress_update, run=False)
|
||||
|
||||
# def kickoff(self) -> DeviceStatus:
|
||||
# status = DeviceStatus(self)
|
||||
# self.move(
|
||||
# self._kickoff_params.get("position"),
|
||||
# wait = False
|
||||
# )
|
||||
# return status
|
||||
|
||||
# def _progress_update(self, value, **kwargs) -> None:
|
||||
# self._run_subs(
|
||||
# sub_type=self.SUB_PROGRESS,
|
||||
# value=value ,
|
||||
# done= 1,
|
||||
# )
|
||||
# # configuration
|
||||
# motor_resolution = Cpt(EpicsSignal, ".MRES", kind="config", auto_monitor=True)
|
||||
# base_velocity = Cpt(EpicsSignal, ".VBAS", kind="config", auto_monitor=True)
|
||||
# backlash_distance = Cpt(EpicsSignal, ".BDST", kind="config", auto_monitor=True)
|
||||
|
||||
@@ -14,6 +14,8 @@ from ophyd.status import MoveStatus
|
||||
from ophyd.utils.epics_pvs import AlarmSeverity, fmt_time
|
||||
from ophyd.utils.errors import UnknownStatusFailure
|
||||
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
|
||||
|
||||
class SpmgStates:
|
||||
"""Enum for the EPICS MotorRecord's SPMG state"""
|
||||
@@ -212,6 +214,45 @@ class EpicsMotor(OphydEpicsMotor):
|
||||
return status
|
||||
|
||||
|
||||
class EpicsUserMotorVME(PSIDeviceBase, EpicsMotor):
|
||||
"""
|
||||
EpicsMotor for VME based user motors. It includes additional checks for DISA and DISP.
|
||||
|
||||
"""
|
||||
|
||||
motor_resolution = Cpt(EpicsSignal, ".MRES", kind="config", auto_monitor=True)
|
||||
base_velocity = Cpt(EpicsSignal, ".VBAS", kind="config", auto_monitor=True)
|
||||
backlash_distance = Cpt(EpicsSignal, ".BDST", kind="config", auto_monitor=True)
|
||||
|
||||
_ioc_enable = Cpt(EpicsSignal, "_able", kind=Kind.omitted, string=True, auto_monitor=True)
|
||||
|
||||
def wait_for_connection(self, all_signals=False, timeout: float | None = None) -> None:
|
||||
"""
|
||||
Wait for connection with an additional check first if the IOC is enabled.
|
||||
"""
|
||||
if self._ioc_enable.get(use_monitor=False) != "Enable":
|
||||
self._ioc_enable.put("Enable")
|
||||
hl_switch = self.high_limit_switch.get(use_monitor=False)
|
||||
ll_switch = self.low_limit_switch.get(use_monitor=False)
|
||||
if hl_switch == 1 and ll_switch == 1:
|
||||
raise RuntimeError(
|
||||
f"Both limit switches are active for device {self.name}."
|
||||
f"This often indicates that the motor is disconnected! Please double-check your hardware!"
|
||||
)
|
||||
return super().wait_for_connection(all_signals, timeout)
|
||||
|
||||
def on_connected(self):
|
||||
self._ioc_enable.subscribe(self._ioc_enable_changed, run=False)
|
||||
|
||||
def _ioc_enable_changed(self, value, **kwargs):
|
||||
"""Callback for IOC enable signal changes"""
|
||||
if self.device_manager is None:
|
||||
return # no device manager assigned
|
||||
if self.name not in self.device_manager.devices:
|
||||
return # device not loaded in device_manager
|
||||
self.device_manager.devices[self.name].enabled = value == "Enable"
|
||||
|
||||
|
||||
class EpicsMotorEC(EpicsMotor):
|
||||
"""Detailed ECMC EPICS motor class
|
||||
|
||||
|
||||
Reference in New Issue
Block a user