Skip to content

Commit

Permalink
Merge pull request #633 from BCDA-APS/632-Enable
Browse files Browse the repository at this point in the history
Move `enable` Component out from synApps Record devices
  • Loading branch information
prjemian authored Jan 26, 2022
2 parents de6ac33 + a7b7e8f commit b5698e9
Show file tree
Hide file tree
Showing 25 changed files with 629 additions and 363 deletions.
55 changes: 47 additions & 8 deletions apstools/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,36 +81,75 @@
from .xia_slit import XiaSlit2D

# synApps

# ## _common
from ..synApps import EpicsRecordDeviceCommonAll
from ..synApps import EpicsRecordInputFields
from ..synApps import EpicsRecordOutputFields
from ..synApps import EpicsRecordFloatFields
from ..synApps import EpicsSynAppsRecordEnableMixin

# ## asyn
from ..synApps import AsynRecord

# ## busy
from ..synApps import BusyRecord

# ## calcout
from ..synApps import CalcoutRecord
from ..synApps import CalcoutRecordChannel
from ..synApps import setup_gaussian_calcout
from ..synApps import setup_incrementer_calcout
from ..synApps import setup_lorentzian_calcout
from ..synApps import UserCalcoutDevice
from ..synApps import UserCalcoutN

# ## epid
from ..synApps import EpidRecord

# ## iocstats
from ..synApps import IocStatsDevice

# ## save_data
from ..synApps import SaveData

# ## scalcout
from ..synApps import UserScalcoutDevice
from ..synApps import UserScalcoutN
from ..synApps import ScalcoutRecord
from ..synApps import ScalcoutRecordNumberChannel
from ..synApps import ScalcoutRecordStringChannel

# ## sscan
from ..synApps import SscanRecord
from ..synApps import SscanDevice

# sseq
from ..synApps import EditStringSequence
from ..synApps import SseqRecord
from ..synApps import UserStringSequenceDevice
from ..synApps import UserStringSequenceN

# ## sub
from ..synApps import SubRecord
from ..synApps import SubRecordChannel
from ..synApps import UserAverageN
from ..synApps import UserAverageDevice

# ## swait
from ..synApps import SwaitRecord
from ..synApps import SwaitRecordChannel
from ..synApps import UserCalcN
from ..synApps import UserCalcsDevice
from ..synApps import setup_random_number_swait
from ..synApps import setup_gaussian_swait
from ..synApps import setup_lorentzian_swait
from ..synApps import setup_incrementer_swait

# ## transform
from ..synApps import TransformRecord
from ..synApps import UserTransformN
from ..synApps import UserTransformsDevice
from ..synApps import UserScalcoutDevice
from ..synApps import ScalcoutRecord
from ..synApps import ScalcoutRecordNumberChannel
from ..synApps import ScalcoutRecordStringChannel
from ..synApps import SubRecord
from ..synApps import SubRecordChannel
from ..synApps import UserAverage
from ..synApps import UserAverageDevice

# -----------------------------------------------------------------------------
# :author: Pete R. Jemian
Expand Down
5 changes: 2 additions & 3 deletions apstools/devices/positioner_soft_done.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
from ophyd import EpicsSignalRO
from ophyd.signal import EpicsSignalBase
import logging
import time

from ..tests import SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING
from ..tests import short_delay_for_EPICS_IOC_database_processing


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -207,7 +206,7 @@ def stop(self, *, success=False):
"""
if not self.inposition:
self.setpoint.put(self.position)
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
self.cb_readback() # re-evaluate soft done Signal


Expand Down
24 changes: 12 additions & 12 deletions apstools/devices/tests/test_positioner_soft_done.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ..positioner_soft_done import PVPositionerSoftDoneWithStop
from ...utils import run_in_thread
from ...tests import IOC
from ...tests import SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING
from ...tests import short_delay_for_EPICS_IOC_database_processing

import pytest
import time
Expand Down Expand Up @@ -83,11 +83,11 @@ def test_put_and_stop(rbv, prec):
# ensure starting value at 0.0
pos.setpoint.put(0)
rbv.put(1) # make the readback to different
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert not pos.inposition

rbv.put(0) # make the readback match
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert pos.position == 0.0

assert pos.done.get() is True
Expand All @@ -96,29 +96,29 @@ def test_put_and_stop(rbv, prec):

# change the setpoint
pos.setpoint.put(1)
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert not pos.inposition

# change the readback to match
rbv.put(1)
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert pos.inposition

# change the setpoint
pos.setpoint.put(0)
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert not pos.inposition

# move the readback part-way, but move is not over yet
rbv.put(0.5)
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert not pos.inposition

# force a stop now
pos.stop()
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
pos.cb_readback()
time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
short_delay_for_EPICS_IOC_database_processing()
assert pos.setpoint.get() == 0.5
assert pos.readback.get() == 0.5
assert pos.position == 0.5
Expand All @@ -142,7 +142,7 @@ def test_put_and_stop(rbv, prec):
# dt = time.time() - t0
# assert status.done
# assert status.success
# time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
# short_delay_for_EPICS_IOC_database_processing()
# assert dt >= longer_delay
# assert pos.inposition

Expand All @@ -154,7 +154,7 @@ def test_put_and_stop(rbv, prec):
# dt = time.time() - t0
# assert status.done
# assert status.success
# time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
# short_delay_for_EPICS_IOC_database_processing()
# assert dt >= longer_delay
# assert pos.setpoint.get() == target
# assert pos.position == target
Expand All @@ -163,7 +163,7 @@ def test_put_and_stop(rbv, prec):
# # move to 0.0
# delayed_complete(pos, rbv, delay=longer_delay)
# pos.move(0)
# time.sleep(SHORT_DELAY_FOR_EPICS_IOC_DATABASE_PROCESSING)
# short_delay_for_EPICS_IOC_database_processing()
# assert pos.setpoint.get() == 0
# assert pos.position == 0
# assert pos.inposition
21 changes: 16 additions & 5 deletions apstools/synApps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@
from ._common import EpicsRecordInputFields
from ._common import EpicsRecordOutputFields
from ._common import EpicsRecordFloatFields
from ._common import EpicsSynAppsRecordEnableMixin

from .asyn import AsynRecord

from .busy import BusyRecord

from .calcout import CalcoutRecord
from .calcout import CalcoutRecordChannel
from .calcout import setup_gaussian_calcout
from .calcout import setup_incrementer_calcout
from .calcout import setup_lorentzian_calcout
from .calcout import UserCalcoutN
from .calcout import UserCalcoutDevice

from .epid import EpidRecord

from .iocstats import IocStatsDevice

from .luascript import LuascriptRecord
Expand All @@ -26,32 +32,37 @@
from .save_data import SaveData

from .scalcout import UserScalcoutDevice
from .scalcout import UserScalcoutN
from .scalcout import ScalcoutRecord
from .scalcout import ScalcoutRecordNumberChannel
from .scalcout import ScalcoutRecordStringChannel

from .sscan import SscanRecord
from .sscan import SscanDevice

from .sseq import EditStringSequence
from .sseq import SseqRecord
from .sseq import UserStringSequenceDevice
from .sseq import UserStringSequenceN

from .sub import SubRecord
from .sub import SubRecordChannel
from .sub import UserAverage
from .sub import UserAverageN
from .sub import UserAverageDevice

from .swait import SwaitRecord
from .swait import SwaitRecordChannel
from .swait import UserCalcN
from .swait import UserCalcsDevice
from .swait import setup_random_number_swait
from .swait import setup_gaussian_swait
from .swait import setup_lorentzian_swait
from .swait import setup_incrementer_swait

from .transform import TransformRecord
from .transform import UserTransformN
from .transform import UserTransformsDevice

from .sseq import EditStringSequence
from .sseq import SseqRecord
from .sseq import UserStringSequenceDevice

# MUST come AFTER previous imports
from .db_2slit import Optics2Slit1D
from .db_2slit import Optics2Slit2D_HV
Expand Down
11 changes: 11 additions & 0 deletions apstools/synApps/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
~EpicsRecordInputFields
~EpicsRecordOutputFields
~EpicsRecordFloatFields
~EpicsSynAppsRecordEnableMixin
:see: https://wiki-ext.aps.anl.gov/epics/index.php/RRM_3-14_dbCommon
:see: https://wiki-ext.aps.anl.gov/epics/index.php/RRM_3-14_Common
Expand Down Expand Up @@ -114,3 +115,13 @@ class EpicsRecordFloatFields(Device):
low_alarm_severity = Component(EpicsSignal, ".LSV", kind="config")
lolo_alarm_severity = Component(EpicsSignal, ".LLSV", kind="config")
alarm_hysteresis = Component(EpicsSignal, ".HYST", kind="config")


class EpicsSynAppsRecordEnableMixin(Device):
"""Supports ``{PV}Enable`` feature from user databases."""
enable = Component(EpicsSignal, "Enable", kind="config")

def reset(self):
"""set all fields to default values"""
self.enable.put(self.enable.enum_strs[1]) # Enable
super().reset()
36 changes: 20 additions & 16 deletions apstools/synApps/calcout.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
.. autosummary::
~UserCalcoutDevice
~UserCalcoutN
~CalcoutRecord
~CalcoutRecordChannel
~setup_gaussian_calcout
Expand Down Expand Up @@ -36,6 +37,7 @@

from ._common import EpicsRecordDeviceCommonAll
from ._common import EpicsRecordFloatFields
from ._common import EpicsSynAppsRecordEnableMixin
from .. import utils as APS_utils


Expand All @@ -53,10 +55,10 @@ class CalcoutRecordChannel(Device):
~reset
"""

input_value = FC(EpicsSignal, "{self.prefix}.{self._ch_letter}")
last_value = FC(EpicsSignalRO, "{self.prefix}.L{self._ch_letter}")
input_pv = FC(EpicsSignal, "{self.prefix}.INP{self._ch_letter}")
input_pv_valid = FC(EpicsSignalRO, "{self.prefix}.IN{self._ch_letter}V")
input_value = FC(EpicsSignal, "{self.prefix}.{self._ch_letter}", kind="config")
last_value = FC(EpicsSignalRO, "{self.prefix}.L{self._ch_letter}", kind="config")
input_pv = FC(EpicsSignal, "{self.prefix}.INP{self._ch_letter}", kind="config")
input_pv_valid = FC(EpicsSignalRO, "{self.prefix}.IN{self._ch_letter}V", kind="config")

read_attrs = [
"input_value",
Expand Down Expand Up @@ -92,8 +94,6 @@ class CalcoutRecord(EpicsRecordFloatFields, EpicsRecordDeviceCommonAll):
:see: https://wiki-ext.aps.anl.gov/epics/index.php/RRM_3-14_Calcout
"""
enable = Cpt(EpicsSignal, "Enable", kind="omitted")

units = Cpt(EpicsSignal, ".EGU", kind="config")
precision = Cpt(EpicsSignal, ".PREC", kind="config")

Expand Down Expand Up @@ -154,6 +154,10 @@ def reset(self):
self.read_attrs = ["channels.%s" % c for c in CHANNEL_LETTERS_LIST]


class UserCalcoutN(EpicsSynAppsRecordEnableMixin, CalcoutRecord):
"""Single instance of the userCalcoutN database."""


class UserCalcoutDevice(Device):
"""
EPICS synApps XXX IOC setup of user calcouts: ``$(P):userCalcOut$(N)``
Expand All @@ -167,16 +171,16 @@ class UserCalcoutDevice(Device):
"""

enable = Cpt(EpicsSignal, "userCalcOutEnable", kind="omitted")
calcout1 = Cpt(CalcoutRecord, "userCalcOut1")
calcout2 = Cpt(CalcoutRecord, "userCalcOut2")
calcout3 = Cpt(CalcoutRecord, "userCalcOut3")
calcout4 = Cpt(CalcoutRecord, "userCalcOut4")
calcout5 = Cpt(CalcoutRecord, "userCalcOut5")
calcout6 = Cpt(CalcoutRecord, "userCalcOut6")
calcout7 = Cpt(CalcoutRecord, "userCalcOut7")
calcout8 = Cpt(CalcoutRecord, "userCalcOut8")
calcout9 = Cpt(CalcoutRecord, "userCalcOut9")
calcout10 = Cpt(CalcoutRecord, "userCalcOut10")
calcout1 = Cpt(UserCalcoutN, "userCalcOut1")
calcout2 = Cpt(UserCalcoutN, "userCalcOut2")
calcout3 = Cpt(UserCalcoutN, "userCalcOut3")
calcout4 = Cpt(UserCalcoutN, "userCalcOut4")
calcout5 = Cpt(UserCalcoutN, "userCalcOut5")
calcout6 = Cpt(UserCalcoutN, "userCalcOut6")
calcout7 = Cpt(UserCalcoutN, "userCalcOut7")
calcout8 = Cpt(UserCalcoutN, "userCalcOut8")
calcout9 = Cpt(UserCalcoutN, "userCalcOut9")
calcout10 = Cpt(UserCalcoutN, "userCalcOut10")

def reset(self): # lgtm [py/similar-function]
"""set all fields to default values"""
Expand Down
12 changes: 6 additions & 6 deletions apstools/synApps/luascript.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ class _LuascriptRecordInputBase(Device):

# Components must be defined in subclass

read_attrs = [
"input_value",
]
hints = {"fields": read_attrs}
# read_attrs = [
# "input_value",
# ]
# hints = {"fields": read_attrs}

def __init__(self, prefix, letter, **kwargs):
self._ch = letter
Expand All @@ -61,7 +61,7 @@ class LuascriptRecordNumberInput(_LuascriptRecordInputBase):
"""

pv_link = FC(EpicsSignal, "{prefix}.INP{_ch}", kind="config", string=True)
input_value = FC(EpicsSignal, "{prefix}.{_ch}", kind="hinted")
input_value = FC(EpicsSignal, "{prefix}.{_ch}", kind="config")
description = FC(EpicsSignal, "{prefix}.{_ch}DSC", kind="config", string=True)

def reset(self):
Expand All @@ -79,7 +79,7 @@ class LuascriptRecordStringInput(_LuascriptRecordInputBase):
"""

pv_link = FC(EpicsSignal, "{prefix}.IN{_ch}", kind="config", string=True)
input_value = FC(EpicsSignal, "{prefix}.{_ch}", kind="hinted", string=True)
input_value = FC(EpicsSignal, "{prefix}.{_ch}", kind="config", string=True)
description = FC(EpicsSignal, "{prefix}.{_ch}DN", kind="config", string=True)

def reset(self):
Expand Down
Loading

0 comments on commit b5698e9

Please sign in to comment.