upgrades of wago, reflaser, bernina config, xeye, and some more.

This commit is contained in:
2022-09-01 22:25:35 +02:00
parent 2fc5fb6947
commit 255e204df4
10 changed files with 428 additions and 68 deletions
+46
View File
@@ -126,6 +126,12 @@ namespace.append_obj(
name="slit_mono",
module_name="eco.xoptics.slits",
)
namespace.append_obj(
"SolidTargetDetectorPBPS",
"SAROP21-PBPS103",
name="mon_mono",
module_name="eco.xdiagnostics.intensity_monitors",
)
from eco.devices_general.motors import SmaractStreamdevice, SmaractRecord
@@ -242,6 +248,13 @@ namespace.append_obj(
module_name="eco.xdiagnostics.intensity_monitors",
lazy=True,
)
namespace.append_obj(
"SolidTargetDetectorPBPS",
"SARFE10-PBPS053",
name="mon_und",
module_name="eco.xdiagnostics.intensity_monitors",
)
namespace.append_obj(
"RefLaser_Aramis",
"SAROP21-OLAS136",
@@ -263,6 +276,10 @@ namespace.append_obj(
lazy=True,
)
namespace.append_obj(
"DownstreamDiagnostic", name="dsd", module_name="eco.xdiagnostics.dsd"
)
namespace.append_obj(
"Pprm_dsd",
pvname="SARES20-DSDPPRM",
@@ -443,6 +460,13 @@ namespace.append_obj(
name="analog_inputs",
module_name="eco.devices_general.wago",
)
namespace.append_obj(
"WagoAnalogOutputs",
"SARES20-CWAG-GPS01",
lazy=True,
name="analog_outputs",
module_name="eco.devices_general.wago",
)
namespace.append_obj(
"GudeStrip",
"SARES20-CPPS-01",
@@ -1345,6 +1369,17 @@ namespace.append_obj(JohannAnalyzer, name="analyzer")
############## experiment specific #############
namespace.append_obj(
"Bernina_XEYE",
zoomstage_pv=config_bernina.xeye.zoomstage_pv._value,
camera_pv=config_bernina.xeye.camera_pv._value,
bshost=config_bernina.xeye.bshost._value,
bsport=config_bernina.xeye.bsport._value,
name="xeye",
module_name="eco.xdiagnostics.profile_monitors",
)
# try to append pgroup folder to path !!!!! This caused eco to run in a timeout without error traceback !!!!!
try:
@@ -1365,6 +1400,17 @@ except:
print("Did not succed to append an eco folder in current prgoup")
class Xspect_EH55(Assembly):
def __init__(self, name="xspect_bernina"):
super().__init__(name=name)
self._append(MotorRecord, "SARES20-MF1:MOT_15", name="x_crystal")
self._append(MotorRecord, "SARES20-MF1:MOT_16", name="y_crystal")
# self._append(SmaractRecord,'SARES20-MF1:MOT_16',name='theta_crystal')
namespace.append_obj(Xspect_EH55, name="xspect_bernina", lazy=True)
#### pgroup specific appending, might be temporary at this location ####
# namespace.append_obj("Xom", module_name="xom", name="xom", lazy=True)
+22 -22
View File
@@ -75,28 +75,28 @@ components = [
# "type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS",
# "kwargs": {"VME_crate": "SAROP21-CVME-PBPS2", "link": 9},
# },
{
"name": "mon_und",
"z_und": 53,
"desc": "Intensity/position monitor after Undulator",
"type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS_new",
"args": ["SARFE10-PBPS053"],
"kwargs": {
"VME_crate": "SAROP21-CVME-PBPS1",
"link": 9,
"channels": {
"up": "SLAAR21-LSCP1-FNS:CH6:VAL_GET",
"down": "SLAAR21-LSCP1-FNS:CH7:VAL_GET",
"left": "SLAAR21-LSCP1-FNS:CH4:VAL_GET",
"right": "SLAAR21-LSCP1-FNS:CH5:VAL_GET",
},
"calc": {
"itot": "SLAAR21-LTIM01-EVR0:CALCI",
"xpos": "SLAAR21-LTIM01-EVR0:CALCX",
"ypos": "SLAAR21-LTIM01-EVR0:CALCY",
},
},
},
# {
# "name": "mon_und",
# "z_und": 53,
# "desc": "Intensity/position monitor after Undulator",
# "type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS_new",
# "args": ["SARFE10-PBPS053"],
# "kwargs": {
# "VME_crate": "SAROP21-CVME-PBPS1",
# "link": 9,
# "channels": {
# "up": "SLAAR21-LSCP1-FNS:CH6:VAL_GET",
# "down": "SLAAR21-LSCP1-FNS:CH7:VAL_GET",
# "left": "SLAAR21-LSCP1-FNS:CH4:VAL_GET",
# "right": "SLAAR21-LSCP1-FNS:CH5:VAL_GET",
# },
# "calc": {
# "itot": "SLAAR21-LTIM01-EVR0:CALCI",
# "xpos": "SLAAR21-LTIM01-EVR0:CALCX",
# "ypos": "SLAAR21-LTIM01-EVR0:CALCY",
# },
# },
# },
{
"name": "pshut_und",
"type": "eco.xoptics.shutters:PhotonShutter",
+31 -22
View File
@@ -883,6 +883,35 @@ class SmaractRecord(Assembly):
Alias(an, channel=".".join([pvname, af]), channeltype="CA")
)
self._currentChange = None
self._append(
AdjustablePvEnum,
self.pvname + "_POS_TYPE_RB",
pvname_set=self.pvname + "_POS_TYPE_SP",
name="sensor_type",
is_setting=True,
)
self._append(
AdjustablePv,
self.pvname + "_MAX_FREQ",
name="max_frequency",
is_setting=True,
)
self._append(
AdjustablePv, self.pvname + ".VELO", name="speed", is_setting=False
)
self._append(
AdjustablePv,
self.pvname + ".ACCL",
name="acceleration_time",
is_setting=False,
)
self._append(
AdjustablePv, self.pvname + ".LLM", name="limit_low", is_setting=False
)
self._append(
AdjustablePv, self.pvname + ".HLM", name="limit_high", is_setting=False
)
self._append(
AdjustablePvEnum,
self.pvname + ".STAT",
@@ -903,6 +932,7 @@ class SmaractRecord(Assembly):
name="autoset_unit",
is_setting=True,
)
self._append(
AdjustablePv,
self.pvname + ".HOMR",
@@ -927,21 +957,7 @@ class SmaractRecord(Assembly):
is_setting=False,
is_display=True,
)
self._append(
AdjustablePv, self.pvname + ".VELO", name="speed", is_setting=False
)
self._append(
AdjustablePv,
self.pvname + ".ACCL",
name="acceleration_time",
is_setting=False,
)
self._append(
AdjustablePv, self.pvname + ".LLM", name="limit_low", is_setting=False
)
self._append(
AdjustablePv, self.pvname + ".HLM", name="limit_high", is_setting=False
)
self._append(
AdjustablePvEnum, self.pvname + ".SPMG", name="mode", is_setting=False
)
@@ -979,13 +995,6 @@ class SmaractRecord(Assembly):
is_status=False,
is_display=False,
)
self._append(
AdjustablePvEnum,
self.pvname + "_POS_TYPE_RB",
pvname_set=self.pvname + "_POS_TYPE_SP",
name="sensor_type",
is_setting=True,
)
if backlash_definition:
self._append(
AdjustablePv,
+52
View File
@@ -42,3 +42,55 @@ class WagoAnalogInputs(Assembly):
self.pvbase = pvbase
for n in range(1, 9):
self._append(AnalogInput, pvbase + f":ADC{n:02d}", name=f"ch{n:d}")
class AnalogOutput(Assembly):
def __init__(self, pvname, name=None):
super().__init__(name=name)
self.pvname = pvname
self._append(
AdjustablePv,
self.pvname,
self.pvname + "_RB",
name="value",
is_setting=True,
is_display=True,
)
self._append(
AdjustablePvString,
self.pvname + ".DESC",
name="description",
is_setting=True,
is_display=True,
)
self._append(
AdjustablePvString,
self.pvname + ".EGU",
name="unit",
is_setting=False,
is_display=False,
)
self._append(
DetectorPvData,
self.pvname + ".RVAL",
name="raw",
is_setting=False,
is_display=False,
)
def get_current_value(self):
return self.value.get_current_value()
def __call__(self, *args):
if args:
self.value(*args).wait()
else:
return self.value.get_current_value()
class WagoAnalogOutputs(Assembly):
def __init__(self, pvbase, name=None):
super().__init__(name=name)
self.pvbase = pvbase
for n in range(1, 9):
self._append(AnalogOutput, pvbase + f":DAC{n:02d}", name=f"ch{n:d}")
+6
View File
@@ -23,6 +23,12 @@ class AdjustableObject(Assembly):
raise Exception(f"{fieldname} is not in dictionary")
return d[fieldname]
def update_base_dict(self, updatedict):
tmp = self._base_dict.get_current_value()
tmp.update(updatedict)
self._base_dict.set_target_value(tmp)
self.__init__(self._base_dict, name=self.name)
def init_object(self):
# super().__init__(name=self.name)
for k, v in self._base_dict.get_current_value().items():
+3
View File
@@ -125,6 +125,7 @@ class Memory:
show_changes_only=True,
set_changes_only=True,
check_limits=True,
change_serially=False,
force=False,
):
# if input_obj:
@@ -160,6 +161,8 @@ class Memory:
changes.append(to.set_target_value(val, check=check_limits))
else:
changes.append(to.set_target_value(val))
if change_serially:
changes[-1].wait()
if wait:
for change in changes:
change.wait()
+7 -1
View File
@@ -10,6 +10,7 @@ from ..elements.assembly import Assembly
from .profile_monitors import Pprm_dsd
from .intensity_monitors import SolidTargetDetectorPBPS_new_assembly
import numpy as np
from epics import PV
class DownstreamDiagnostic(Assembly):
@@ -24,9 +25,14 @@ class DownstreamDiagnostic(Assembly):
self._append(
MotorRecord, "SARES20-DSD:MOTOR_DSDY", name="ybase", is_setting=True
)
def get_xyposition_for_kb_angles_in_rad(self, theta_kbver, theta_kbhor):
y = np.tan(2 * theta_kbver) * 7075
x = np.tan(2 * theta_kbhor) / np.cos(2 * theta_kbver) * 6325
return x, y
def home(self):
self._run_cmd("python /ioc/qt/ESB_DSD_home.py SARES20-DSD")
def gui(self):
self._run_cmd("caqtdm -noMsg -macro P=SARES20-DSD /ioc/qt/ESB_DSD_motors.ui")
+162 -1
View File
@@ -63,7 +63,7 @@ class SolidTargetDetectorPBPS(Assembly):
# ch_left=15,
# ch_right=14,
# elog=None,
# name=None,
name=None,
# calc=None,
# calc_calib={},
):
@@ -95,6 +95,167 @@ class SolidTargetDetectorPBPS(Assembly):
DetectorPvDataStream, pvname + ":YPOS", name="ypos", is_setting=False
)
# Calibration calculation record
# Intensity
self._append(
AdjustablePv,
pvname + ":INTENSITY.INPA",
name="calc_intensity_input_A",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.INPB",
name="calc_intensity_input_B",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.INPC",
name="calc_intensity_input_C",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.INPD",
name="calc_intensity_input_D",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.E",
name="calc_intensity_const_E",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.F",
name="calc_intensity_const_F",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.G",
name="calc_intensity_const_G",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.H",
name="calc_intensity_const_H",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":INTENSITY.CALC",
name="calc_intensity_function",
is_setting=True,
is_display=False,
)
# X position
self._append(
AdjustablePv,
pvname + ":XPOS.INPA",
name="calc_xpos_input_A",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":XPOS.INPB",
name="calc_xpos_input_B",
is_setting=True,
is_display=False,
)
self._append(
AdjustablePv,
pvname + ":XPOS.CALC",
name="calc_xpos_function",
is_setting=True,
is_display=False,
)
# self._append(
# AdjustablePv, pvname + ":XPOS.INPD", name="calc_input_D", is_setting=True, is_display=False
# )
# self._append(
# AdjustablePv, pvname + ":XPOS.IE", name="calc_input_E", is_setting=True, is_display=False
# self._append(
# AdjustablePv, pvname + ":XPOS.IF", name="calc_input_F", is_setting=True, is_display=False
# )
# self._append(
# AdjustablePv, pvname + ":XPOS.INPG", name="calc_input_G", is_setting=True, is_display=False
# )
# self._append(
# AdjustablePv, pvname + ":XPOS.INPH", name="calc_input_H", is_setting=True, is_display=False
# )
# self._append(
# AdjustablePv, pvname + ":XPOS.CALC", name="calc_function", is_setting=True, is_display=False
# )
# # Intensity
# # Set channels
# # Input data
# ep.PV(Devive_prefix+'INTENSITY.INPA').put(bytes(channels[0], "utf8"))
# ep.PV(Devive_prefix+'INTENSITY.INPB').put(bytes(channels[1], "utf8"))
# ep.PV(Devive_prefix+'INTENSITY.INPC').put(bytes(channels[2], "utf8"))
# ep.PV(Devive_prefix+'INTENSITY.INPD').put(bytes(channels[3], "utf8"))
# # Calibration values
# ep.PV(Devive_prefix+'INTENSITY.E').put(bytes(str(norm_diodes[0,0]), "utf8"))
# ep.PV(Devive_prefix+'INTENSITY.F').put(bytes(str(norm_diodes[0,1]), "utf8"))
# ep.PV(Devive_prefix+'INTENSITY.G').put(bytes(str(norm_diodes[0,2]), "utf8"))
# ep.PV(Devive_prefix+'INTENSITY.H').put(bytes(str(norm_diodes[0,3]), "utf8"))
# # Calculation
# ep.PV(Devive_prefix+'INTENSITY.CALC').put(bytes("A*E+B*F+C*G+D*H", "utf8"))
# # XPOS
# # Set channels
# ep.PV(Devive_prefix+'XPOS.INPA').put(bytes(channels[2], "utf8"))
# ep.PV(Devive_prefix+'XPOS.INPB').put(bytes(channels[3], "utf8"))
# # Threshold value
# ep.PV(Devive_prefix+'XPOS.D').put(bytes(str(0.2), "utf8"))
# # Diode calibration value
# ep.PV(Devive_prefix+'XPOS.E').put(bytes(str(norm_diodes[0,2]), "utf8"))
# ep.PV(Devive_prefix+'XPOS.F').put(bytes(str(norm_diodes[0,3]), "utf8"))
# # Null value
# ep.PV(Devive_prefix+'XPOS.G').put(bytes(str(0), "utf8"))
# # Position calibration value
# ep.PV(Devive_prefix+'XPOS.I').put(bytes(str((Scan_x_range[1]-Scan_x_range[0])/ np.diff(scan_x_norm).mean()), "utf8"))
# # Intensity threshold value
# ep.PV(Devive_prefix+'XPOS.INPJ').put(bytes(Devive_prefix+'INTENSITY', "utf8"))
# # Calculation
# ep.PV(Devive_prefix+'XPOS.CALC').put(bytes("J<D?G:I*(A*E-B*F)/(A*E+B*F)", "utf8"))
# # YPOS
# # Set channels
# ep.PV(Devive_prefix+'YPOS.INPA').put(bytes(channels[0], "utf8"))
# ep.PV(Devive_prefix+'YPOS.INPB').put(bytes(channels[1], "utf8"))
# # Threshold value
# ep.PV(Devive_prefix+'YPOS.D').put(bytes(str(0.2), "utf8"))
# # Diode calibration value
# ep.PV(Devive_prefix+'YPOS.E').put(bytes(str(norm_diodes[0,0]), "utf8"))
# ep.PV(Devive_prefix+'YPOS.F').put(bytes(str(norm_diodes[0,1]), "utf8"))
# # Null value
# ep.PV(Devive_prefix+'YPOS.G').put(bytes(str(0), "utf8"))
# # Position calibration value
# ep.PV(Devive_prefix+'YPOS.I').put(bytes(str((Scan_y_range[1]-Scan_y_range[0])/ np.diff(scan_y_norm).mean()), "utf8"))
# # Intensity threshold value
# ep.PV(Devive_prefix+'YPOS.INPJ').put(bytes(Devive_prefix+'INTENSITY', "utf8"))
# # Calculation
# ep.PV(Devive_prefix+'YPOS.CALC').put(bytes("J<D?G:I*(A*E-B*F)/(A*E+B*F)", "utf8"))
# if VME_crate:
# self.diode_up = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_up))
# self.diode_down = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_down))
+34 -10
View File
@@ -40,6 +40,7 @@ class KbVer(Assembly):
lambda b1, b2: float(np.mean([b1, b2])),
lambda mn: self._get_benders_set_mean(mn),
name="bender_mean",
unit="mm",
is_setting=False,
is_display=True,
)
@@ -49,6 +50,7 @@ class KbVer(Assembly):
lambda b1, b2: float(np.diff([b1, b2])),
lambda mn: self._get_benders_set_diff(mn),
name="bender_diff",
unit="mm",
is_setting=False,
is_display=True,
)
@@ -68,11 +70,21 @@ class KbVer(Assembly):
)
#### actual motors ###
self._append(MotorRecord, pvname + ":TY1", name="_Y1", is_setting=True)
self._append(MotorRecord, pvname + ":TY2", name="_Y2", is_setting=True)
self._append(MotorRecord, pvname + ":TY3", name="_Y3", is_setting=True)
self._append(MotorRecord, pvname + ":TX1", name="_X1", is_setting=True)
self._append(MotorRecord, pvname + ":TX2", name="_X2", is_setting=True)
self._append(
MotorRecord, pvname + ":TY1", name="_Y1", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TY2", name="_Y2", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TY3", name="_Y3", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TX1", name="_X1", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TX2", name="_X2", is_setting=True, is_display=False
)
def _get_bend_mean(self):
return float(
@@ -132,6 +144,7 @@ class KbHor(Assembly):
lambda b1, b2: float(np.mean([b1, b2])),
lambda mn: self._get_benders_set_mean(mn),
name="bender_mean",
unit="mm",
is_setting=False,
is_display=True,
)
@@ -141,6 +154,7 @@ class KbHor(Assembly):
lambda b1, b2: float(np.diff([b1, b2])),
lambda mn: self._get_benders_set_diff(mn),
name="bender_diff",
unit="mm",
is_setting=False,
is_display=True,
)
@@ -160,11 +174,21 @@ class KbHor(Assembly):
)
#### actual motors ###
self._append(MotorRecord, pvname + ":TY1", name="_Y1", is_setting=True)
self._append(MotorRecord, pvname + ":TY2", name="_Y2", is_setting=True)
self._append(MotorRecord, pvname + ":TY3", name="_Y3", is_setting=True)
self._append(MotorRecord, pvname + ":TX1", name="_X1", is_setting=True)
self._append(MotorRecord, pvname + ":TX2", name="_X2", is_setting=True)
self._append(
MotorRecord, pvname + ":TY1", name="_Y1", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TY2", name="_Y2", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TY3", name="_Y3", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TX1", name="_X1", is_setting=True, is_display=False
)
self._append(
MotorRecord, pvname + ":TX2", name="_X2", is_setting=True, is_display=False
)
def _get_bend_mean(self):
return float(
+65 -12
View File
@@ -1,3 +1,5 @@
from enum import Enum
from eco.elements.adjustable import AdjustableGetSet
from ..devices_general.motors import MotorRecord
from epics import PV
from ..aliases import Alias, append_object_to_object
@@ -5,7 +7,7 @@ from ..elements.assembly import Assembly
class RefLaser_Aramis(Assembly):
def __init__(self, Id, elog=None, name=None, inpos=-18.818, outpos=-5):
def __init__(self, Id, elog=None, name=None, inpos=-13.7, outpos=-5):
super().__init__(name=name)
self.Id = Id
self.elog = elog
@@ -13,21 +15,37 @@ class RefLaser_Aramis(Assembly):
self._inpos = inpos
self._outpos = outpos
self._append(
AdjustableGetSet,
self.get_in_status,
self.set,
name="state",
is_setting=False,
)
self._append(MotorRecord, self.Id + ":MOTOR_1", name="mirror", is_setting=True)
self._append(MotorRecord, self.Id + ":MOTOR_X1", name="x1", is_setting=True)
self._append(MotorRecord, self.Id + ":MOTOR_Z1", name="z1", is_setting=True)
self._append(
MotorRecord, self.Id + ":MOTOR_ROT_X1", name="rx1", is_setting=True
RefLaserLaser,
self.Id,
name="laser",
is_setting=True,
is_display="recursive",
)
self._append(
MotorRecord, self.Id + ":MOTOR_ROT_Z1", name="rz1", is_setting=True
RefLaserAperture,
"SAROP21-OLIR136",
name="aperture",
is_setting=True,
is_display="recursive",
)
pv_lir0 = "SAROP21-OLIR136" # TODO hardcoded
self._append(MotorRecord, pv_lir0 + ":MOTOR_MX", name="x_ap1", is_setting=True)
self._append(MotorRecord, pv_lir0 + ":MOTOR_MY", name="y_ap1", is_setting=True)
pv_lir1 = "SAROP21-OLIR138" # TODO hardcoded
self._append(MotorRecord, pv_lir1 + ":MOTOR_MX", name="x_ap2", is_setting=True)
self._append(MotorRecord, pv_lir1 + ":MOTOR_MY", name="y_ap2", is_setting=True)
# self._append(MotorRecord, pv_lir0 + ":MOTOR_MX", name="x_ap1", is_setting=True)
# self._append(MotorRecord, pv_lir0 + ":MOTOR_MY", name="y_ap1", is_setting=True)
# pv_lir1 = "SAROP21-OLIR138" # TODO hardcoded
# self._append(MotorRecord, pv_lir1 + ":MOTOR_MX", name="x_ap2", is_setting=True)
# self._append(MotorRecord, pv_lir1 + ":MOTOR_MY", name="y_ap2", is_setting=True)
self.mirror.set_limits(-20, 0)
def __call__(self, *args, **kwargs):
@@ -50,7 +68,7 @@ class RefLaser_Aramis(Assembly):
isin = False
else:
isin = None
return isin
return State(isin)
def set(self, value):
if type(value) is str:
@@ -73,3 +91,38 @@ class RefLaser_Aramis(Assembly):
def __repr__(self):
return self.__str__() + "\n" + super().__repr__()
class RefLaserAperture(Assembly):
def __init__(self, pvname, name=None):
super().__init__(name=name)
self._append(
MotorRecord,
pvname + ":MOTOR_MX",
name="x",
is_setting=True,
is_display=True,
)
self._append(
MotorRecord,
pvname + ":MOTOR_MY",
name="y",
is_setting=True,
is_display=True,
)
class RefLaserLaser(Assembly):
def __init__(self, pvname, name=None):
super().__init__(name=name)
self._append(MotorRecord, pvname + ":MOTOR_X1", name="x", is_setting=True)
self._append(MotorRecord, pvname + ":MOTOR_Z1", name="z", is_setting=True)
self._append(MotorRecord, pvname + ":MOTOR_ROT_X1", name="rx", is_setting=True)
self._append(MotorRecord, pvname + ":MOTOR_ROT_Z1", name="rz", is_setting=True)
class State(Enum):
IN = 1
OUT = 0
UNDEFINED = None