diff --git a/siriuspy/siriuspy/VERSION b/siriuspy/siriuspy/VERSION index 3cf561c0b..fb2c0766b 100644 --- a/siriuspy/siriuspy/VERSION +++ b/siriuspy/siriuspy/VERSION @@ -1 +1 @@ -2.12.1 +2.13.0 diff --git a/siriuspy/siriuspy/__init__.py b/siriuspy/siriuspy/__init__.py index d5d0a70cd..1857e4b7d 100644 --- a/siriuspy/siriuspy/__init__.py +++ b/siriuspy/siriuspy/__init__.py @@ -7,6 +7,9 @@ __all__ = [ - 'envars', 'util', 'csdev', 'clientweb', 'clientconfigdb', - 'diagnostics', 'pwrsupply', 'magnet', 'namesys', 'timesys', 'csdevice', - 'epics', 'callbacks', 'search', 'devices'] + 'callbacks', 'csdev', 'envars', 'thread', 'util', + 'bsmp', 'clientarch', 'clientconfigdb', 'clientweb', 'currinfo', + 'cycle', 'devices', 'diagbeam', 'diagsys', 'epics', 'machshift', + 'magnet', 'meas', 'namesys', 'optics', 'opticscorr', 'posang', + 'pwrsupply', 'ramp', 'search', 'simul', 'sofb', 'timesys' + ] diff --git a/siriuspy/siriuspy/devices/bpm.py b/siriuspy/siriuspy/devices/bpm.py index cebc6982d..e612f6c7e 100644 --- a/siriuspy/siriuspy/devices/bpm.py +++ b/siriuspy/siriuspy/devices/bpm.py @@ -3,7 +3,7 @@ import numpy as _np from .device import Device as _Device -from ..diag.bpm.csdev import Const as _csbpm +from ..diagbeam.bpm.csdev import Const as _csbpm from ..search import BPMSearch as _BPMSearch diff --git a/siriuspy/siriuspy/diag/dcct/__init__.py b/siriuspy/siriuspy/diag/dcct/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/siriuspy/siriuspy/diag/dcct/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/siriuspy/siriuspy/diag/ict/__init__.py b/siriuspy/siriuspy/diag/ict/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/siriuspy/siriuspy/diag/ict/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/siriuspy/siriuspy/diag/screen/__init__.py b/siriuspy/siriuspy/diag/screen/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/siriuspy/siriuspy/diag/screen/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/siriuspy/siriuspy/diag/slit/__init__.py b/siriuspy/siriuspy/diag/slit/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/siriuspy/siriuspy/diag/slit/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/siriuspy/siriuspy/diag/__init__.py b/siriuspy/siriuspy/diagbeam/__init__.py similarity index 100% rename from siriuspy/siriuspy/diag/__init__.py rename to siriuspy/siriuspy/diagbeam/__init__.py diff --git a/siriuspy/siriuspy/diag/bpm/__init__.py b/siriuspy/siriuspy/diagbeam/bpm/__init__.py similarity index 100% rename from siriuspy/siriuspy/diag/bpm/__init__.py rename to siriuspy/siriuspy/diagbeam/bpm/__init__.py diff --git a/siriuspy/siriuspy/diag/bpm/csdev.py b/siriuspy/siriuspy/diagbeam/bpm/csdev.py similarity index 100% rename from siriuspy/siriuspy/diag/bpm/csdev.py rename to siriuspy/siriuspy/diagbeam/bpm/csdev.py diff --git a/siriuspy/siriuspy/diagbeam/dcct/__init__.py b/siriuspy/siriuspy/diagbeam/dcct/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/siriuspy/siriuspy/diag/dcct/csdev.py b/siriuspy/siriuspy/diagbeam/dcct/csdev.py similarity index 100% rename from siriuspy/siriuspy/diag/dcct/csdev.py rename to siriuspy/siriuspy/diagbeam/dcct/csdev.py diff --git a/siriuspy/siriuspy/diagbeam/ict/__init__.py b/siriuspy/siriuspy/diagbeam/ict/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/siriuspy/siriuspy/diag/ict/csdev.py b/siriuspy/siriuspy/diagbeam/ict/csdev.py similarity index 100% rename from siriuspy/siriuspy/diag/ict/csdev.py rename to siriuspy/siriuspy/diagbeam/ict/csdev.py diff --git a/siriuspy/siriuspy/diagbeam/screen/__init__.py b/siriuspy/siriuspy/diagbeam/screen/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/siriuspy/siriuspy/diag/screen/csdev.py b/siriuspy/siriuspy/diagbeam/screen/csdev.py similarity index 100% rename from siriuspy/siriuspy/diag/screen/csdev.py rename to siriuspy/siriuspy/diagbeam/screen/csdev.py diff --git a/siriuspy/siriuspy/diagbeam/slit/__init__.py b/siriuspy/siriuspy/diagbeam/slit/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/siriuspy/siriuspy/diag/slit/csdev.py b/siriuspy/siriuspy/diagbeam/slit/csdev.py similarity index 100% rename from siriuspy/siriuspy/diag/slit/csdev.py rename to siriuspy/siriuspy/diagbeam/slit/csdev.py diff --git a/siriuspy/siriuspy/diagsys/__init__.py b/siriuspy/siriuspy/diagsys/__init__.py new file mode 100644 index 000000000..b11eb2a7a --- /dev/null +++ b/siriuspy/siriuspy/diagsys/__init__.py @@ -0,0 +1 @@ +"""DiagSys subpackage.""" diff --git a/siriuspy/siriuspy/diagsys/app.py b/siriuspy/siriuspy/diagsys/app.py new file mode 100644 index 000000000..ddaffae9c --- /dev/null +++ b/siriuspy/siriuspy/diagsys/app.py @@ -0,0 +1,52 @@ +#!/usr/local/bin/python-sirius +"""Application module.""" + +import time as _time +from threading import Thread as _Thread + +from ..callbacks import Callback as _Callback +from ..thread import QueueThread as _QueueThread + + +class App(_Callback): + """Main application responsible for updating DB.""" + + SCAN_FREQUENCY = 2 + + def __init__(self, prefix, *args): + """Create Computed PVs.""" + super().__init__() + self._prefix = prefix + self._queue = _QueueThread() + self.pvs = list() + self.scanning = False + self.quit = False + self._create_computed_pvs(*args) + + self.thread = _Thread(target=self.scan, daemon=True) + self.thread.start() + + def process(self, interval): + """Sleep.""" + _time.sleep(interval) + + def read(self, reason): + """Read from IOC database.""" + return None + + def write(self, reason, value): + """Write value to reason and let callback update PV database.""" + return False # return True to invoke super().write of PCASDriver + + def _create_computed_pvs(self): + raise NotImplementedError + + def _update_pvs(self): + raise NotImplementedError + + def scan(self): + """Run as a thread scanning PVs.""" + while not self.quit: + if self.scanning: + self._update_pvs() + _time.sleep(1.0/App.SCAN_FREQUENCY) diff --git a/siriuspy/siriuspy/diagsys/lidiag/__init__.py b/siriuspy/siriuspy/diagsys/lidiag/__init__.py new file mode 100644 index 000000000..2393153df --- /dev/null +++ b/siriuspy/siriuspy/diagsys/lidiag/__init__.py @@ -0,0 +1 @@ +"""Linac Diag subpackage.""" diff --git a/siriuspy/siriuspy/diagsys/lidiag/csdev.py b/siriuspy/siriuspy/diagsys/lidiag/csdev.py new file mode 100644 index 000000000..e90f6428d --- /dev/null +++ b/siriuspy/siriuspy/diagsys/lidiag/csdev.py @@ -0,0 +1,122 @@ +"""Linac Diag App.""" + +from ... import csdev as _csdev + + +class ETypes(_csdev.ETypes): + """Local enumerate types.""" + + DIAG_STATUS_LABELS_RF = ( + 'Disconnected', + 'State Off', + 'Trigger Off', + 'Integral Off', + 'Feedback Off', + 'Amp-(SP|RB) are different', + 'Phase-(SP|RB) are different', + 'IxQ (SP|Mon) are different') + + DIAG_STATUS_LABELS_EG_HVPS = ( + 'Disconnected', + 'Swicth Status Off', + 'Enable Status Off', + 'Voltage (SP|Mon) are different') + + DIAG_STATUS_LABELS_EG_FILA = ( + 'Disconnected', + 'Swicth Status Off', + 'Current-(SP|Mon) are different') + + +_et = ETypes # syntactic sugar + + +class Const(_csdev.Const): + """Local constant types.""" + + SHB = 'LI-01:RF-SHB' + KLY1 = 'LI-01:RF-Kly-1' + KLY2 = 'LI-01:RF-Kly-2' + RF_DEVICES = [SHB, KLY1, KLY2] + HVPS = 'LI-01:EG-HVPS' + FILA = 'LI-01:EG-FilaPS' + DEV_2_LINAME = { + HVPS: 'LI-01:EG-HVPS', + FILA: 'LI-01:EG-FilaPS', + SHB: 'LA-RF:LLRF:BUN1', + KLY1: 'LA-RF:LLRF:KLY1', + KLY2: 'LA-RF:LLRF:KLY2'} + ALL_DEVICES = DEV_2_LINAME.keys() + + LI_RF_AMP_TOL = 1e-2 + LI_RF_PHS_TOL = 1e-2 + LI_RF_IxQ_TOL = 5e-3 + LI_HVPS_TOL = 1.5 + LI_FILAPS_TOL = 1e-1 + + +_c = Const # syntactic sugar + + +def conv_dev_2_liname(device): + """Return Linac pvname.""" + return _c.DEV_2_LINAME[device] + + +def get_li_diag_status_labels(device): + """Return Diag Status Labels enum.""" + if 'RF' in device: + return _et.DIAG_STATUS_LABELS_RF + if 'HVPS' in device: + return _et.DIAG_STATUS_LABELS_EG_HVPS + if 'FilaPS' in device: + return _et.DIAG_STATUS_LABELS_EG_FILA + raise ValueError('Labels not defined to '+device+'.') + + +def get_li_diag_propty_database(device): + """Return property database of diagnostics for linac devices.""" + enums = get_li_diag_status_labels(device) + dbase = { + 'DiagVersion-Cte': {'type': 'str', 'value': 'UNDEF'}, + 'DiagStatus-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1 + }, + 'DiagStatusLabels-Cte': {'type': 'string', 'count': len(enums), + 'value': enums} + } + if 'RF' in device: + atol = _c.LI_RF_AMP_TOL + ptol = _c.LI_RF_PHS_TOL + vtol = _c.LI_RF_IxQ_TOL + dbase.update({ + 'DiagAmpDiff-Mon': { + 'type': 'float', 'value': 0.0, + 'hilim': atol, 'hihi': atol, 'high': atol, + 'low': -atol, 'lolo': -atol, 'lolim': -atol}, + 'DiagPhaseDiff-Mon': { + 'type': 'float', 'value': 0.0, + 'hilim': ptol, 'hihi': ptol, 'high': ptol, + 'low': -ptol, 'lolo': -ptol, 'lolim': -ptol}, + 'DiagIxQDiff-Mon': { + 'type': 'float', 'value': 0.0, + 'hilim': vtol, 'hihi': vtol, 'high': vtol, + 'low': -vtol, 'lolo': -vtol, 'lolim': -vtol}, + }) + elif 'HVPS' in device: + dtol = _c.LI_HVPS_TOL + dbase.update({ + 'DiagVoltDiff-Mon': { + 'type': 'float', 'value': 0.0, + 'hilim': dtol, 'hihi': dtol, 'high': dtol, + 'low': -dtol, 'lolo': -dtol, 'lolim': -dtol}}) + elif 'FilaPS' in device: + dtol = _c.LI_FILAPS_TOL + dbase.update({ + 'DiagCurrentDiff-Mon': { + 'type': 'float', 'value': 0.0, + 'hilim': dtol, 'hihi': dtol, 'high': dtol, + 'low': -dtol, 'lolo': -dtol, 'lolim': -dtol}}) + dbase = _csdev.add_pvslist_cte(dbase, 'Diag') + return dbase diff --git a/siriuspy/siriuspy/diagsys/lidiag/main.py b/siriuspy/siriuspy/diagsys/lidiag/main.py new file mode 100644 index 000000000..b66912cde --- /dev/null +++ b/siriuspy/siriuspy/diagsys/lidiag/main.py @@ -0,0 +1,132 @@ +#!/usr/local/bin/python-sirius +"""Driver module.""" + +from pcaspy import Alarm as _Alarm, Severity as _Severity + +from ...namesys import SiriusPVName +from ..app import App as _App +from ..pvs import ComputedPV as _ComputedPV + +from .csdev import conv_dev_2_liname, Const as _Const +from .pvs import LIScalarDiffPV as _LIScalarDiffPV, \ + LIVecDiffPV as _LIVecDiffPV, \ + LIRFStatusPV as _LIRFStatusPV, \ + LIEGHVStatusPV as _LIEGHVStatusPV, \ + LIFilaPSStatusPV as _LIFilaPSStatusPV + + +class LIDiagApp(_App): + """Main application responsible for updating DB.""" + + def _create_computed_pvs(self, *args): + # # RF devices + for dev in _Const.RF_DEVICES: + devname = SiriusPVName(self._prefix + dev) + liname = conv_dev_2_liname(dev) + + # DiagAmpDiff-Mon + pvs = [None]*2 + pvs[_LIScalarDiffPV.SP] = liname + ':SET_AMP' + pvs[_LIScalarDiffPV.RB] = liname + ':GET_AMP' + pvo = _ComputedPV( + devname + ':DiagAmpDiff-Mon', _LIScalarDiffPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # DiagPhaseDiff-Mon + pvs = [None]*2 + pvs[_LIScalarDiffPV.SP] = liname + ':SET_PHASE' + pvs[_LIScalarDiffPV.RB] = liname + ':GET_PHASE' + pvo = _ComputedPV( + devname + ':DiagPhaseDiff-Mon', _LIScalarDiffPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # DiagIxQDiff-Mon + pvs = [None]*4 + pvs[_LIVecDiffPV.I_SETT] = liname + ':GET_CH1_SETTING_I' + pvs[_LIVecDiffPV.Q_SETT] = liname + ':GET_CH1_SETTING_Q' + pvs[_LIVecDiffPV.I_DATA] = liname + ':GET_CH1_I' + pvs[_LIVecDiffPV.Q_DATA] = liname + ':GET_CH1_Q' + pvo = _ComputedPV( + devname + ':DiagIxQDiff-Mon', _LIVecDiffPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # DiagStatus-Mon + pvs = [None]*7 + pvs[_LIRFStatusPV.PV_STREAM] = liname + ':GET_STREAM' + pvs[_LIRFStatusPV.PV_EXTTRG] = \ + liname + ':GET_EXTERNAL_TRIGGER_ENABLE' + pvs[_LIRFStatusPV.PV_INTEGR] = liname + ':GET_INTEGRAL_ENABLE' + pvs[_LIRFStatusPV.PV_FBMODE] = liname + ':GET_FB_MODE' + pvs[_LIRFStatusPV.PV_AMPDIF] = devname + ':DiagAmpDiff-Mon' + pvs[_LIRFStatusPV.PV_PHSDIF] = devname + ':DiagPhaseDiff-Mon' + pvs[_LIRFStatusPV.PV_IXQDIF] = devname + ':DiagIxQDiff-Mon' + pvo = _ComputedPV( + devname + ':DiagStatus-Mon', _LIRFStatusPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # # Egun devices + # HVPS + devname = SiriusPVName(self._prefix + _Const.HVPS) + liname = conv_dev_2_liname(devname) + # DiagVoltDiff-Mon + pvs = [None]*2 + pvs[_LIScalarDiffPV.SP] = liname + ':voltoutsoft' + pvs[_LIScalarDiffPV.RB] = liname + ':voltinsoft' + pvo = _ComputedPV( + devname + ':DiagVoltDiff-Mon', _LIScalarDiffPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + # DiagStatus-Mon + pvs = [None]*3 + pvs[_LIEGHVStatusPV.PV_SWITCH] = liname + ':swstatus' + pvs[_LIEGHVStatusPV.PV_ENABLE] = liname + ':enstatus' + pvs[_LIEGHVStatusPV.PV_VLTDIF] = devname + ':DiagVoltDiff-Mon' + pvo = _ComputedPV( + devname + ':DiagStatus-Mon', _LIEGHVStatusPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # FilaPS + devname = SiriusPVName(self._prefix + _Const.FILA) + liname = conv_dev_2_liname(devname) + # DiagCurrentDiff-Mon + pvs = [None]*2 + pvs[_LIScalarDiffPV.SP] = liname + ':currentoutsoft' + pvs[_LIScalarDiffPV.RB] = liname + ':currentinsoft' + pvo = _ComputedPV( + devname + ':DiagCurrentDiff-Mon', _LIScalarDiffPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + # DiagStatus-Mon + pvs = [None]*2 + pvs[_LIFilaPSStatusPV.PV_SWITCH] = liname + ':swstatus' + pvs[_LIFilaPSStatusPV.PV_CURDIF] = devname + ':DiagCurrentDiff-Mon' + pvo = _ComputedPV( + devname + ':DiagStatus-Mon', _LIFilaPSStatusPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + self._pvs_connected = {pv: False for pv in self.pvs} + + def _update_pvs(self): + for pvo in self.pvs: + if not pvo.connected: + if self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.TIMEOUT_ALARM, + severity=_Severity.INVALID_ALARM, + field='status') + self._pvs_connected[pvo] = False + if 'DiagStatus' in pvo.pvname: + self.run_callbacks(pvo.pvname, value=pvo.value) + else: + if not self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.NO_ALARM, + severity=_Severity.NO_ALARM, field='status') + self._pvs_connected[pvo] = True + self.run_callbacks(pvo.pvname, value=pvo.value) diff --git a/siriuspy/siriuspy/diagsys/lidiag/pvs.py b/siriuspy/siriuspy/diagsys/lidiag/pvs.py new file mode 100644 index 000000000..b99cd765b --- /dev/null +++ b/siriuspy/siriuspy/diagsys/lidiag/pvs.py @@ -0,0 +1,217 @@ +#!/usr/local/bin/python-sirius +"""LI Diag PVs.""" + +import numpy as _np + +from .csdev import Const as _Const + + +class LIScalarDiffPV: + """Diff of a LI setpoint and a readback PVs.""" + + SP = 0 + RB = 1 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute difference between SP and RB values.""" + disconnected = \ + not computed_pv.pvs[LIScalarDiffPV.SP].connected or \ + not computed_pv.pvs[LIScalarDiffPV.RB].connected + if disconnected: + return None + value_sp = computed_pv.pvs[LIScalarDiffPV.SP].value + value_rb = computed_pv.pvs[LIScalarDiffPV.RB].value + diff = value_rb - value_sp + return {'value': diff} + + +class LIVecDiffPV: + """Diff of a LI setpoint and a readback PVs.""" + + I_SETT = 0 + Q_SETT = 1 + I_DATA = 2 + Q_DATA = 3 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute difference between SP and RB values.""" + disconnected = \ + not computed_pv.pvs[LIVecDiffPV.I_SETT].connected or \ + not computed_pv.pvs[LIVecDiffPV.Q_SETT].connected or \ + not computed_pv.pvs[LIVecDiffPV.I_DATA].connected or \ + not computed_pv.pvs[LIVecDiffPV.Q_DATA].connected + if disconnected: + return None + sp_i = computed_pv.pvs[LIVecDiffPV.I_SETT].value + sp_q = computed_pv.pvs[LIVecDiffPV.Q_SETT].value + sp_vec = _np.array([sp_i, sp_q]) + rb_i = computed_pv.pvs[LIVecDiffPV.I_DATA].value + rb_q = computed_pv.pvs[LIVecDiffPV.Q_DATA].value + rb_vec = _np.array([rb_i, rb_q]) + diff = _np.linalg.norm(rb_vec - sp_vec) + return {'value': diff} + + +class LIRFStatusPV: + """LI RF Status PV.""" + + BIT_DISCONN = 0b00000001 + BIT_STATOFF = 0b00000010 + BIT_TRIGOFF = 0b00000100 + BIT_INTGOFF = 0b00001000 + BIT_FBMDOFF = 0b00010000 + BIT_AMPDIFF = 0b00100000 + BIT_PHSDIFF = 0b01000000 + BIT_IXQDIFF = 0b10000000 + + PV_STREAM = 0 + PV_EXTTRG = 1 + PV_INTEGR = 2 + PV_FBMODE = 3 + PV_AMPDIF = 4 + PV_PHSDIF = 5 + PV_IXQDIF = 6 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute Status PV.""" + value = 0 + + # connected? + disconnected = \ + not computed_pv.pvs[LIRFStatusPV.PV_STREAM].connected or \ + not computed_pv.pvs[LIRFStatusPV.PV_EXTTRG].connected or \ + not computed_pv.pvs[LIRFStatusPV.PV_INTEGR].connected or \ + not computed_pv.pvs[LIRFStatusPV.PV_FBMODE].connected or \ + not computed_pv.pvs[LIRFStatusPV.PV_AMPDIF].connected or \ + not computed_pv.pvs[LIRFStatusPV.PV_PHSDIF].connected or \ + not computed_pv.pvs[LIRFStatusPV.PV_IXQDIF].connected + if disconnected: + value |= LIRFStatusPV.BIT_DISCONN + value |= LIRFStatusPV.BIT_STATOFF + value |= LIRFStatusPV.BIT_TRIGOFF + value |= LIRFStatusPV.BIT_INTGOFF + value |= LIRFStatusPV.BIT_FBMDOFF + value |= LIRFStatusPV.BIT_AMPDIFF + value |= LIRFStatusPV.BIT_PHSDIFF + value |= LIRFStatusPV.BIT_IXQDIFF + return {'value': value} + + # state? + sts = computed_pv.pvs[LIRFStatusPV.PV_STREAM].value + if sts != _Const.OffOn.On or sts is None: + value |= LIRFStatusPV.BIT_STATOFF + + # trigger? + sts = computed_pv.pvs[LIRFStatusPV.PV_EXTTRG].value + if sts != _Const.OffOn.On or sts is None: + value |= LIRFStatusPV.BIT_TRIGOFF + + # integral? + sts = computed_pv.pvs[LIRFStatusPV.PV_INTEGR].value + if sts != _Const.OffOn.On or sts is None: + value |= LIRFStatusPV.BIT_INTGOFF + + # feedback? + sts = computed_pv.pvs[LIRFStatusPV.PV_FBMODE].value + if sts != _Const.OffOn.On or sts is None: + value |= LIRFStatusPV.BIT_FBMDOFF + + # amp diff? + severity = computed_pv.pvs[LIRFStatusPV.PV_AMPDIF].severity + if severity != 0: + value |= LIRFStatusPV.BIT_AMPDIFF + + # phase diff? + severity = computed_pv.pvs[LIRFStatusPV.PV_PHSDIF].severity + if severity != 0: + value |= LIRFStatusPV.BIT_PHSDIFF + + # IxQ diff? + severity = computed_pv.pvs[LIRFStatusPV.PV_IXQDIF].severity + if severity != 0: + value |= LIRFStatusPV.BIT_IXQDIFF + + return {'value': value} + + +class LIEGHVStatusPV: + """LI Egun HVPS Status PV.""" + + BIT_DISCONN = 0b0001 + BIT_SWITOFF = 0b0010 + BIT_ENBLOFF = 0b0100 + BIT_VOLTDIF = 0b1000 + + PV_SWITCH = 0 + PV_ENABLE = 1 + PV_VLTDIF = 2 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute Status PV.""" + value = 0 + + # connected? + disconnected = \ + not computed_pv.pvs[LIEGHVStatusPV.PV_SWITCH].connected or \ + not computed_pv.pvs[LIEGHVStatusPV.PV_ENABLE].connected or \ + not computed_pv.pvs[LIEGHVStatusPV.PV_VLTDIF].connected + if disconnected: + value |= LIEGHVStatusPV.BIT_DISCONN + value |= LIEGHVStatusPV.BIT_SWITOFF + value |= LIEGHVStatusPV.BIT_ENBLOFF + value |= LIEGHVStatusPV.BIT_VOLTDIF + return {'value': value} + + # switch? + sts = computed_pv.pvs[LIEGHVStatusPV.PV_SWITCH].value + if sts != _Const.OffOn.On or sts is None: + value |= LIEGHVStatusPV.BIT_SWITOFF + + # enable? + sts = computed_pv.pvs[LIEGHVStatusPV.PV_ENABLE].value + if sts != _Const.OffOn.On or sts is None: + value |= LIEGHVStatusPV.BIT_ENBLOFF + + # volt diff? + severity = computed_pv.pvs[LIEGHVStatusPV.PV_VLTDIF].severity + if severity != 0: + value |= LIEGHVStatusPV.BIT_VOLTDIF + + return {'value': value} + + +class LIFilaPSStatusPV: + """LI FilaPS Status PV.""" + + BIT_DISCONN = 0b0001 + BIT_SWITOFF = 0b0010 + BIT_CURRDIF = 0b0100 + + PV_SWITCH = 0 + PV_CURDIF = 1 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute Status PV.""" + value = 0 + + # connected? + disconnected = \ + not computed_pv.pvs[LIFilaPSStatusPV.PV_SWITCH].connected or \ + not computed_pv.pvs[LIFilaPSStatusPV.PV_CURDIF].connected + if disconnected: + value |= LIFilaPSStatusPV.BIT_DISCONN + value |= LIFilaPSStatusPV.BIT_SWITOFF + value |= LIFilaPSStatusPV.BIT_CURRDIF + return {'value': value} + + # switch? + sts = computed_pv.pvs[LIFilaPSStatusPV.PV_SWITCH].value + if sts != _Const.OffOn.On or sts is None: + value |= LIFilaPSStatusPV.BIT_SWITOFF + + # volt diff? + severity = computed_pv.pvs[LIFilaPSStatusPV.PV_CURDIF].severity + if severity != 0: + value |= LIFilaPSStatusPV.BIT_CURRDIF + + return {'value': value} diff --git a/siriuspy/siriuspy/psdiag/__init__.py b/siriuspy/siriuspy/diagsys/psdiag/__init__.py similarity index 100% rename from siriuspy/siriuspy/psdiag/__init__.py rename to siriuspy/siriuspy/diagsys/psdiag/__init__.py diff --git a/siriuspy/siriuspy/diagsys/psdiag/csdev.py b/siriuspy/siriuspy/diagsys/psdiag/csdev.py new file mode 100644 index 000000000..fe8c2341b --- /dev/null +++ b/siriuspy/siriuspy/diagsys/psdiag/csdev.py @@ -0,0 +1,68 @@ +"""Power Supply Diag App.""" + +from ... import csdev as _csdev +from ...namesys import SiriusPVName as _PVName +from ...search import PSSearch as _PSSearch + + +class ETypes(_csdev.ETypes): + """Local enumerate types.""" + + DIAG_STATUS_LABELS_AS = ( + 'PS Disconnected', + 'PwrState-Sts Off', + 'Current-(SP|Mon) are different', + 'Interlocks', + 'OpMode-(Sel|Sts) are different', + 'Reserved') + + DIAG_STATUS_LABELS_LI = ( + 'PS Disconnected', + 'PwrState-Sts Off', + 'Current-(SP|Mon) are different', + 'Interlocks', + 'Reserved', + 'Reserved') + + DIAG_STATUS_LABELS_BO = ( + 'PS Disconnected', + 'PwrState-Sts Off', + 'Current-(SP|Mon) are different', + 'Interlocks', + 'OpMode-(Sel|Sts) are different', + 'Wfm error exceeded tolerance') + + +_et = ETypes # syntactic sugar + + +def get_ps_diag_status_labels(psname): + """Return Diag Status Labels enum.""" + psname = _PVName(psname) + if psname.sec == 'BO': + return _et.DIAG_STATUS_LABELS_BO + if psname.sec == 'LI': + return _et.DIAG_STATUS_LABELS_LI + return _et.DIAG_STATUS_LABELS_AS + + +def get_ps_diag_propty_database(psname): + """Return property database of diagnostics for power supplies.""" + pstype = _PSSearch.conv_psname_2_pstype(psname) + splims = _PSSearch.conv_pstype_2_splims(pstype) + dtol = splims['DTOL_CUR'] + enums = get_ps_diag_status_labels(psname) + dbase = { + 'DiagVersion-Cte': {'type': 'str', 'value': 'UNDEF'}, + 'DiagCurrentDiff-Mon': {'type': 'float', 'value': 0.0, + 'hilim': dtol, 'hihi': dtol, 'high': dtol, + 'low': -dtol, 'lolo': -dtol, 'lolim': -dtol}, + 'DiagStatus-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1 + }, + 'DiagStatusLabels-Cte': {'type': 'string', 'count': len(enums), + 'value': enums} + } + dbase = _csdev.add_pvslist_cte(dbase, 'Diag') + return dbase diff --git a/siriuspy/siriuspy/diagsys/psdiag/main.py b/siriuspy/siriuspy/diagsys/psdiag/main.py new file mode 100644 index 000000000..1412d9838 --- /dev/null +++ b/siriuspy/siriuspy/diagsys/psdiag/main.py @@ -0,0 +1,68 @@ +#!/usr/local/bin/python-sirius +"""Driver module.""" + +from pcaspy import Alarm as _Alarm, Severity as _Severity + +from ...namesys import SiriusPVName +from ..app import App as _App +from ..pvs import ComputedPV as _ComputedPV +from .pvs import PSStatusPV as _PSStatusPV, PSDiffPV as _PSDiffPV + + +class PSDiagApp(_App): + """Main application responsible for updating DB.""" + + def _create_computed_pvs(self, psnames): + self._psnames = psnames + for psname in self._psnames: + devname = SiriusPVName(self._prefix + psname) + + # DiagCurrentDiff-Mon + pvs = [None, None] + pvs[_PSDiffPV.CURRT_SP] = devname + ':Current-SP' + pvs[_PSDiffPV.CURRT_MON] = devname + ':Current-Mon' + pv = _ComputedPV( + psname + ':DiagCurrentDiff-Mon', _PSDiffPV(), self._queue, + pvs, monitor=False) + self.pvs.append(pv) + + # DiagStatus-Mon + if devname.sec != 'LI': + pvs = [None]*7 + pvs[_PSStatusPV.PWRSTE_STS] = devname + ':PwrState-Sts' + pvs[_PSStatusPV.CURRT_DIFF] = devname + ':DiagCurrentDiff-Mon' + pvs[_PSStatusPV.INTLK_SOFT] = devname + ':IntlkSoft-Mon' + pvs[_PSStatusPV.INTLK_HARD] = devname + ':IntlkHard-Mon' + pvs[_PSStatusPV.OPMODE_SEL] = devname + ':OpMode-Sel' + pvs[_PSStatusPV.OPMODE_STS] = devname + ':OpMode-Sts' + pvs[_PSStatusPV.WAVFRM_MON] = devname + ':Wfm-Mon' + # TODO: Add other interlocks for PS types that have them + else: + pvs = [None]*3 + pvs[_PSStatusPV.PWRSTE_STS] = devname + ':PwrState-Sts' + pvs[_PSStatusPV.CURRT_DIFF] = devname + ':DiagCurrentDiff-Mon' + pvs[_PSStatusPV.INTRLCK_LI] = devname + ':StatusIntlk-Mon' + pv = _ComputedPV( + psname + ':DiagStatus-Mon', _PSStatusPV(), self._queue, + pvs, monitor=False) + self.pvs.append(pv) + self._pvs_connected = {pv: False for pv in self.pvs} + + def _update_pvs(self): + for pvo in self.pvs: + if not pvo.connected: + if self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.TIMEOUT_ALARM, + severity=_Severity.INVALID_ALARM, + field='status') + self._pvs_connected[pvo] = False + if 'DiagStatus' in pvo.pvname: + self.run_callbacks(pvo.pvname, value=pvo.value) + else: + if not self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.NO_ALARM, + severity=_Severity.NO_ALARM, field='status') + self._pvs_connected[pvo] = True + self.run_callbacks(pvo.pvname, value=pvo.value) diff --git a/siriuspy/siriuspy/diagsys/psdiag/pvs.py b/siriuspy/siriuspy/diagsys/psdiag/pvs.py new file mode 100644 index 000000000..e0e7e0562 --- /dev/null +++ b/siriuspy/siriuspy/diagsys/psdiag/pvs.py @@ -0,0 +1,132 @@ +#!/usr/local/bin/python-sirius +"""PS Diag PVs.""" + +import numpy as _np + +from ...namesys import SiriusPVName as _PVName +from ...search import PSSearch as _PSSearch +from ...pwrsupply.csdev import Const as _PSConst +from ...pwrsupply.csdev import ETypes as _ETypes + + +class PSDiffPV: + """Diff of a PS current setpoint and a readback.""" + + CURRT_SP = 0 + CURRT_MON = 1 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute difference between SP and Mon current values.""" + disconnected = \ + not computed_pv.pvs[PSDiffPV.CURRT_SP].connected or \ + not computed_pv.pvs[PSDiffPV.CURRT_MON].connected + if disconnected: + return None + value_sp = computed_pv.pvs[PSDiffPV.CURRT_SP].value + value_rb = computed_pv.pvs[PSDiffPV.CURRT_MON].value + diff = value_rb - value_sp + return {'value': diff} + + +class PSStatusPV: + """Power Supply Status PV.""" + + # TODO: Add other interlocks for some PS types + + BIT_PSCONNECT = 0b000001 + BIT_PWRSTATON = 0b000010 + BIT_CURRTDIFF = 0b000100 + BIT_INTERLOCK = 0b001000 + BIT_OPMODEDIF = 0b010000 + BIT_BOWFMDIFF = 0b100000 + + PWRSTE_STS = 0 + CURRT_DIFF = 1 + INTRLCK_LI = 2 + INTLK_SOFT = 2 + INTLK_HARD = 3 + OPMODE_SEL = 4 + OPMODE_STS = 5 + WAVFRM_MON = 6 + + DTOLWFM_DICT = dict() + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute PS Status PV.""" + psname = _PVName(computed_pv.pvs[0].pvname).device_name + value = 0 + # ps connected? + if psname.sec != 'LI': + disconnected = \ + not computed_pv.pvs[PSStatusPV.PWRSTE_STS].connected or \ + not computed_pv.pvs[PSStatusPV.CURRT_DIFF].connected or \ + not computed_pv.pvs[PSStatusPV.INTLK_SOFT].connected or \ + not computed_pv.pvs[PSStatusPV.INTLK_HARD].connected or \ + not computed_pv.pvs[PSStatusPV.OPMODE_SEL].connected or \ + not computed_pv.pvs[PSStatusPV.OPMODE_STS].connected or \ + not computed_pv.pvs[PSStatusPV.WAVFRM_MON].connected + else: + disconnected = \ + not computed_pv.pvs[PSStatusPV.PWRSTE_STS].connected or \ + not computed_pv.pvs[PSStatusPV.CURRT_DIFF].connected or \ + not computed_pv.pvs[PSStatusPV.INTRLCK_LI].connected + if disconnected: + value |= PSStatusPV.BIT_PSCONNECT + value |= PSStatusPV.BIT_PWRSTATON + value |= PSStatusPV.BIT_CURRTDIFF + value |= PSStatusPV.BIT_INTERLOCK + value |= PSStatusPV.BIT_OPMODEDIF + value |= PSStatusPV.BIT_BOWFMDIFF + return {'value': value} + + # pwrstate? + pwrsts = computed_pv.pvs[PSStatusPV.PWRSTE_STS].value + if pwrsts != _PSConst.PwrStateSts.On or pwrsts is None: + value |= PSStatusPV.BIT_PWRSTATON + + if psname.sec != 'LI': + # opmode? + sel = computed_pv.pvs[PSStatusPV.OPMODE_SEL].value + sts = computed_pv.pvs[PSStatusPV.OPMODE_STS].value + if sel is not None and sts is not None: + opmode_sel = _ETypes.OPMODES[sel] + opmode_sts = _ETypes.STATES[sts] + if opmode_sel != opmode_sts: + value |= PSStatusPV.BIT_OPMODEDIF + # current-diff? + if sts == _PSConst.States.SlowRef: + severity = computed_pv.pvs[PSStatusPV.CURRT_DIFF].severity + if severity != 0: + value |= PSStatusPV.BIT_CURRTDIFF + # waveform diff? + elif (psname.sec == 'BO') and (sts == _PSConst.States.RmpWfm): + mon = computed_pv.pvs[PSStatusPV.WAVFRM_MON].value + if psname not in PSStatusPV.DTOLWFM_DICT.keys(): + pstype = _PSSearch.conv_psname_2_pstype(psname) + PSStatusPV.DTOLWFM_DICT[psname] = _PSSearch.get_splims( + pstype, 'DTOL_WFM') + if not _np.allclose(mon, 0.0, + atol=PSStatusPV.DTOLWFM_DICT[psname]): + value |= PSStatusPV.BIT_BOWFMDIFF + else: + value |= PSStatusPV.BIT_OPMODEDIF + + # interlocks? + intlksoft = computed_pv.pvs[PSStatusPV.INTLK_SOFT].value + intlkhard = computed_pv.pvs[PSStatusPV.INTLK_HARD].value + if intlksoft != 0 or intlksoft is None or \ + intlkhard != 0 or intlkhard is None: + value |= PSStatusPV.BIT_INTERLOCK + + else: + # current-diff? + severity = computed_pv.pvs[PSStatusPV.CURRT_DIFF].severity + if severity != 0: + value |= PSStatusPV.BIT_CURRTDIFF + + # interlocks? + intlk = computed_pv.pvs[PSStatusPV.INTRLCK_LI].value + if intlk > 55 or intlk is None: + value |= PSStatusPV.BIT_INTERLOCK + + return {'value': value} diff --git a/siriuspy/siriuspy/diagsys/pudiag/__init__.py b/siriuspy/siriuspy/diagsys/pudiag/__init__.py new file mode 100644 index 000000000..a444b50ab --- /dev/null +++ b/siriuspy/siriuspy/diagsys/pudiag/__init__.py @@ -0,0 +1 @@ +"""PUDiag subpackage.""" diff --git a/siriuspy/siriuspy/diagsys/pudiag/csdev.py b/siriuspy/siriuspy/diagsys/pudiag/csdev.py new file mode 100644 index 000000000..ce32a701d --- /dev/null +++ b/siriuspy/siriuspy/diagsys/pudiag/csdev.py @@ -0,0 +1,44 @@ +"""Pulsed Power Supply Diag App.""" + +from ... import csdev as _csdev +from ...search import PSSearch as _PSSearch + + +class ETypes(_csdev.ETypes): + """Local enumerate types.""" + + DIAG_STATUS_LABELS_PU = ( + 'PU Disconnected', + 'PwrState-Sts Off', + 'Pulse-Sts Off', + 'Voltage-(SP|Mon) are different', + 'Interlocks') + + +_et = ETypes # syntactic sugar + + +def get_pu_diag_status_labels(): + """Return Diag Status Labels enum.""" + return _et.DIAG_STATUS_LABELS_PU + + +def get_pu_diag_propty_database(puname): + """Return property database.""" + pstype = _PSSearch.conv_psname_2_pstype(puname) + splims = _PSSearch.conv_pstype_2_splims(pstype) + dtol = splims['DTOL_CUR'] + enums = get_pu_diag_status_labels() + dbase = { + 'DiagVersion-Cte': {'type': 'str', 'value': 'UNDEF'}, + 'DiagVoltageDiff-Mon': {'type': 'float', 'value': 0.0, + 'hilim': dtol, 'hihi': dtol, 'high': dtol, + 'low': -dtol, 'lolo': -dtol, 'lolim': -dtol}, + 'DiagStatus-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1}, + 'DiagStatusLabels-Cte': {'type': 'string', 'count': len(enums), + 'value': enums} + } + dbase = _csdev.add_pvslist_cte(dbase, 'Diag') + return dbase diff --git a/siriuspy/siriuspy/diagsys/pudiag/main.py b/siriuspy/siriuspy/diagsys/pudiag/main.py new file mode 100644 index 000000000..4f891dba8 --- /dev/null +++ b/siriuspy/siriuspy/diagsys/pudiag/main.py @@ -0,0 +1,66 @@ +#!/usr/local/bin/python-sirius +"""Driver module.""" + +from pcaspy import Alarm as _Alarm, Severity as _Severity + +from ...namesys import SiriusPVName +from ..app import App as _App +from ..pvs import ComputedPV as _ComputedPV +from .pvs import PUStatusPV as _PUStatusPV, PUDiffPV as _PUDiffPV + + +class PUDiagApp(_App): + """Main application responsible for updating DB.""" + + def _create_computed_pvs(self, punames): + self._punames = punames + for puname in self._punames: + devname = SiriusPVName(self._prefix + puname) + + # DiagVoltageDiff-Mon + pvs = [None, None] + pvs[_PUDiffPV.VOLTAGE_SP] = devname + ':Voltage-SP' + pvs[_PUDiffPV.VOLTAGE_MON] = devname + ':Voltage-Mon' + pv = _ComputedPV( + puname + ':DiagVoltageDiff-Mon', _PUDiffPV(), self._queue, + pvs, monitor=False) + self.pvs.append(pv) + + # DiagStatus-Mon + pvs = [None]*11 if 'Sept' not in puname else [None]*10 + pvs[_PUStatusPV.PWRST_STS] = devname + ':PwrState-Sts' + pvs[_PUStatusPV.PULSE_STS] = devname + ':Pulse-Sts' + pvs[_PUStatusPV.DIFFVOLTG] = devname + ':DiagVoltageDiff-Mon' + pvs[_PUStatusPV.INTRLCK_1] = devname + ':Intlk1-Mon' + pvs[_PUStatusPV.INTRLCK_2] = devname + ':Intlk2-Mon' + pvs[_PUStatusPV.INTRLCK_3] = devname + ':Intlk3-Mon' + pvs[_PUStatusPV.INTRLCK_4] = devname + ':Intlk4-Mon' + pvs[_PUStatusPV.INTRLCK_5] = devname + ':Intlk5-Mon' + pvs[_PUStatusPV.INTRLCK_6] = devname + ':Intlk6-Mon' + pvs[_PUStatusPV.INTRLCK_7] = devname + ':Intlk7-Mon' + if 'Sept' not in puname: + pvs[_PUStatusPV.INTRLCK_8] = devname + ':Intlk8-Mon' + pv = _ComputedPV( + puname + ':DiagStatus-Mon', _PUStatusPV(), self._queue, + pvs, monitor=False) + self.pvs.append(pv) + self._pvs_connected = {pv: False for pv in self.pvs} + + def _update_pvs(self): + for pvo in self.pvs: + if not pvo.connected: + if self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.TIMEOUT_ALARM, + severity=_Severity.INVALID_ALARM, + field='status') + self._pvs_connected[pvo] = False + if 'DiagStatus' in pvo.pvname: + self.run_callbacks(pvo.pvname, value=pvo.value) + else: + if not self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.NO_ALARM, + severity=_Severity.NO_ALARM, field='status') + self._pvs_connected[pvo] = True + self.run_callbacks(pvo.pvname, value=pvo.value) diff --git a/siriuspy/siriuspy/diagsys/pudiag/pvs.py b/siriuspy/siriuspy/diagsys/pudiag/pvs.py new file mode 100644 index 000000000..36ce4348f --- /dev/null +++ b/siriuspy/siriuspy/diagsys/pudiag/pvs.py @@ -0,0 +1,111 @@ +#!/usr/local/bin/python-sirius +"""PU Diag PVs.""" + +from ...namesys import SiriusPVName as _PVName +from ...pwrsupply.csdev import Const as _PSConst + + +class PUDiffPV: + """Diff of a PU voltage setpoint and a monitor.""" + + VOLTAGE_SP = 0 + VOLTAGE_MON = 1 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute difference between SP and Mon voltage values.""" + disconnected = \ + not computed_pv.pvs[PUDiffPV.VOLTAGE_SP].connected or \ + not computed_pv.pvs[PUDiffPV.VOLTAGE_MON].connected + if disconnected: + return None + + value_sp = computed_pv.pvs[PUDiffPV.VOLTAGE_SP].value + value_rb = computed_pv.pvs[PUDiffPV.VOLTAGE_MON].value + diff = value_rb - value_sp + return {'value': diff} + + +class PUStatusPV: + """Pulsed Power Supply Status PV.""" + + BIT_PUCONNECT = 0b00001 + BIT_PWRSTATON = 0b00010 + BIT_PULSEISON = 0b00100 + BIT_VOLTGDIFF = 0b01000 + BIT_INTERLOCK = 0b10000 + + PWRST_STS = 0 + PULSE_STS = 1 + DIFFVOLTG = 2 + INTRLCK_1 = 3 + INTRLCK_2 = 4 + INTRLCK_3 = 5 + INTRLCK_4 = 6 + INTRLCK_5 = 7 + INTRLCK_6 = 8 + INTRLCK_7 = 9 + INTRLCK_8 = 10 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute PU Status PV.""" + puname = _PVName(computed_pv.pvs[0].pvname).device_name + value = 0 + # connected? + disconnected = \ + not computed_pv.pvs[PUStatusPV.PWRST_STS].connected or \ + not computed_pv.pvs[PUStatusPV.PULSE_STS].connected or \ + not computed_pv.pvs[PUStatusPV.DIFFVOLTG].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_1].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_2].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_3].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_4].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_5].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_6].connected or \ + not computed_pv.pvs[PUStatusPV.INTRLCK_7].connected + if 'Sept' not in puname: + disconnected |= not computed_pv.pvs[PUStatusPV.INTRLCK_8].connected + if disconnected: + value |= PUStatusPV.BIT_PUCONNECT + value |= PUStatusPV.BIT_PWRSTATON + value |= PUStatusPV.BIT_PULSEISON + value |= PUStatusPV.BIT_VOLTGDIFF + value |= PUStatusPV.BIT_INTERLOCK + return {'value': value} + + # pwrstate? + pwrsts = computed_pv.pvs[PUStatusPV.PWRST_STS].value + if pwrsts != _PSConst.OffOn.On or pwrsts is None: + value |= PUStatusPV.BIT_PWRSTATON + else: + # voltage-diff? + severity = computed_pv.pvs[PUStatusPV.DIFFVOLTG].severity + if severity != 0: + value |= PUStatusPV.BIT_VOLTGDIFF + + # pulse? + pulsests = computed_pv.pvs[PUStatusPV.PULSE_STS].value + if pulsests != _PSConst.OffOn.On or pulsests is None: + value |= PUStatusPV.BIT_PULSEISON + + # interlocks? + intlk1 = computed_pv.pvs[PUStatusPV.INTRLCK_1].value + intlk2 = computed_pv.pvs[PUStatusPV.INTRLCK_2].value + intlk3 = computed_pv.pvs[PUStatusPV.INTRLCK_3].value + intlk4 = computed_pv.pvs[PUStatusPV.INTRLCK_4].value + intlk5 = computed_pv.pvs[PUStatusPV.INTRLCK_5].value + intlk6 = computed_pv.pvs[PUStatusPV.INTRLCK_6].value + intlk7 = computed_pv.pvs[PUStatusPV.INTRLCK_7].value + cond = intlk1 != 1 or intlk1 is None + cond |= intlk2 != 1 or intlk2 is None + cond |= intlk3 != 1 or intlk3 is None + cond |= intlk4 != 1 or intlk4 is None + cond |= intlk5 != 1 or intlk5 is None + cond |= intlk6 != 1 or intlk6 is None + cond |= intlk7 != 1 or intlk7 is None + if 'Sept' not in puname: + intlk8 = computed_pv.pvs[PUStatusPV.INTRLCK_8].value + cond |= intlk8 != 1 or intlk8 is None + if cond: + value |= PUStatusPV.BIT_INTERLOCK + + return {'value': value} diff --git a/siriuspy/siriuspy/epics/pv_psdiag.py b/siriuspy/siriuspy/diagsys/pvs.py similarity index 61% rename from siriuspy/siriuspy/epics/pv_psdiag.py rename to siriuspy/siriuspy/diagsys/pvs.py index d1a8bd34e..bc5965900 100644 --- a/siriuspy/siriuspy/epics/pv_psdiag.py +++ b/siriuspy/siriuspy/diagsys/pvs.py @@ -1,15 +1,9 @@ #!/usr/local/bin/python-sirius -"""PS Diag PVs.""" +"""Computed PV.""" import numpy as _np -from epics import PV as _PV - -from . import CONNECTION_TIMEOUT as _CONN_TIMEOUT -from ..namesys import SiriusPVName as _PVName -from ..search import PSSearch as _PSSearch -from ..pwrsupply.csdev import Const as _PSConst -from ..pwrsupply.csdev import ETypes as _ETypes +from ..epics import PV as _PV, CONNECTION_TIMEOUT as _CONN_TIMEOUT class ComputedPV: @@ -203,106 +197,3 @@ def _value_update_callback(self, pvname, value, **kwargs): def _issue_callback(self, **kwargs): for callback in self._callbacks.values(): callback(**kwargs) - - -class PSDiffPV: - """Diff of a PS current setpoint and a readback.""" - - CURRT_SP = 0 - CURRT_MON = 1 - - - def compute_update(self, computed_pv, updated_pv_name, value): - """Compute difference between SP and Mon current values.""" - disconnected = \ - not computed_pv.pvs[PSDiffPV.CURRT_SP].connected or \ - not computed_pv.pvs[PSDiffPV.CURRT_MON].connected - if disconnected: - return None - value_sp = computed_pv.pvs[PSDiffPV.CURRT_SP].value - value_rb = computed_pv.pvs[PSDiffPV.CURRT_MON].value - diff = value_rb - value_sp - return {'value': diff} - - -class PSStatusPV: - """Power Supply Status PV.""" - - # TODO: Add other interlocks for some PS types - - BIT_PSCONNECT = 0b000001 - BIT_PWRSTATON = 0b000010 - BIT_OPMODEDIF = 0b000100 - BIT_CURRTDIFF = 0b001000 - BIT_INTERLKOK = 0b010000 - BIT_BOWFMDIFF = 0b100000 - - PWRSTE_STS = 0 - INTLK_SOFT = 1 - INTLK_HARD = 2 - OPMODE_SEL = 3 - OPMODE_STS = 4 - CURRT_DIFF = 5 - WAVFRM_MON = 6 - - DTOLWFM_DICT = dict() - - def compute_update(self, computed_pv, updated_pv_name, value): - """Compute PS Status PV.""" - psname = _PVName(computed_pv.pvs[0].pvname).device_name - value = 0 - # ps connected? - disconnected = \ - not computed_pv.pvs[PSStatusPV.PWRSTE_STS].connected or \ - not computed_pv.pvs[PSStatusPV.INTLK_SOFT].connected or \ - not computed_pv.pvs[PSStatusPV.INTLK_HARD].connected or \ - not computed_pv.pvs[PSStatusPV.OPMODE_SEL].connected or \ - not computed_pv.pvs[PSStatusPV.OPMODE_STS].connected or \ - not computed_pv.pvs[PSStatusPV.CURRT_DIFF].connected - if disconnected: - value |= PSStatusPV.BIT_PSCONNECT - value |= PSStatusPV.BIT_PWRSTATON - value |= PSStatusPV.BIT_INTERLKOK - value |= PSStatusPV.BIT_OPMODEDIF - value |= PSStatusPV.BIT_CURRTDIFF - value |= PSStatusPV.BIT_BOWFMDIFF - return {'value': value} - - # pwrstate? - pwrsts = computed_pv.pvs[PSStatusPV.PWRSTE_STS].value - if pwrsts != _PSConst.PwrStateSts.On or pwrsts is None: - value |= PSStatusPV.BIT_PWRSTATON - - # opmode? - sel = computed_pv.pvs[PSStatusPV.OPMODE_SEL].value - sts = computed_pv.pvs[PSStatusPV.OPMODE_STS].value - if sel is not None and sts is not None: - opmode_sel = _ETypes.OPMODES[sel] - opmode_sts = _ETypes.STATES[sts] - if opmode_sel != opmode_sts: - value |= PSStatusPV.BIT_OPMODEDIF - # current-diff? - if sts == _PSConst.States.SlowRef: - severity = computed_pv.pvs[PSStatusPV.CURRT_DIFF].severity - if severity != 0: - value |= PSStatusPV.BIT_CURRTDIFF - # waveform diff? - elif (psname.sec == 'BO') and (sts == _PSConst.States.RmpWfm): - mon = computed_pv.pvs[PSStatusPV.WAVFRM_MON].value - if psname not in PSStatusPV.DTOLWFM_DICT.keys(): - pstype = _PSSearch.conv_psname_2_pstype(psname) - PSStatusPV.DTOLWFM_DICT[psname] = _PSSearch.get_splims( - pstype, 'DTOL_WFM') - if not _np.allclose(mon, 0.0, - atol=PSStatusPV.DTOLWFM_DICT[psname]): - value |= PSStatusPV.BIT_BOWFMDIFF - else: - value |= PSStatusPV.BIT_OPMODEDIF - - # interlocks? - intlksoft = computed_pv.pvs[PSStatusPV.INTLK_SOFT].value - intlkhard = computed_pv.pvs[PSStatusPV.INTLK_HARD].value - if intlksoft != 0 or intlksoft is None or \ - intlkhard != 0 or intlkhard is None: - value |= PSStatusPV.BIT_INTERLKOK - return {'value': value} diff --git a/siriuspy/siriuspy/diagsys/rfdiag/__init__.py b/siriuspy/siriuspy/diagsys/rfdiag/__init__.py new file mode 100644 index 000000000..63658817c --- /dev/null +++ b/siriuspy/siriuspy/diagsys/rfdiag/__init__.py @@ -0,0 +1 @@ +"""RFDiag subpackage.""" diff --git a/siriuspy/siriuspy/diagsys/rfdiag/csdev.py b/siriuspy/siriuspy/diagsys/rfdiag/csdev.py new file mode 100644 index 000000000..f06b4ec9a --- /dev/null +++ b/siriuspy/siriuspy/diagsys/rfdiag/csdev.py @@ -0,0 +1,75 @@ +"""RF Diag App.""" + +from ... import csdev as _csdev + + +class ETypes(_csdev.ETypes): + """Local enumerate types.""" + + DIAG_STATUS_LABELS_BORF = ( + 'Disconnected', + 'Sirius Interlock', + 'LLRF Interlock', + 'Ramp Disabled', + 'Ramp Not Ready', + ) + + DIAG_STATUS_LABELS_SIRF = ( + 'Disconnected', + 'Sirius Interlock', + 'LLRF Interlock', + 'Amplitude Error Out Of Tolerance', + 'Phase Error Out Of Tolerance', + 'Detune Error Out of Tolerance', + ) + + +_et = ETypes # syntactic sugar + + +class Const(_csdev.Const): + """Local constant types.""" + + BO_DEV = 'BO-05D:RF-P5Cav' + SI_DEV = 'SI-02SB:RF-P7Cav' + ALL_DEVICES = [BO_DEV, SI_DEV] + + SI_SL_ERRTOL_AMP = 1 # [mV] + SI_SL_ERRTOL_PHS = 1e-1 # [DEG] + SI_SL_ERRTOL_DTU = 2 # [DEG] + + +_c = Const # syntactic sugar + + +def get_rf_diag_status_labels(device): + """Return Diag Status Labels enum.""" + if 'BO' in device: + return _et.DIAG_STATUS_LABELS_BORF + elif 'SI' in device: + return _et.DIAG_STATUS_LABELS_SIRF + raise ValueError('Labels not defined to '+device+'.') + + +def get_rf_diag_propty_database(device): + """Return property database of diagnostics for RF devices.""" + enums = get_rf_diag_status_labels(device) + dbase = { + 'DiagVersion-Cte': {'type': 'str', 'value': 'UNDEF'}, + 'DiagStatus-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1}, + 'DiagStatusLabels-Cte': {'type': 'string', 'count': len(enums), + 'value': enums}, + 'DiagAmpErrSts-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1}, + 'DiagPhsErrSts-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1}, + 'DiagDTuneErrSts-Mon': {'type': 'int', 'value': 0, + 'hilim': 1, 'hihi': 1, 'high': 1, + 'low': -1, 'lolo': -1, 'lolim': -1}, + } + dbase = _csdev.add_pvslist_cte(dbase, 'Diag') + return dbase diff --git a/siriuspy/siriuspy/diagsys/rfdiag/main.py b/siriuspy/siriuspy/diagsys/rfdiag/main.py new file mode 100644 index 000000000..add0c4806 --- /dev/null +++ b/siriuspy/siriuspy/diagsys/rfdiag/main.py @@ -0,0 +1,94 @@ +#!/usr/local/bin/python-sirius +"""Driver module.""" + +from pcaspy import Alarm as _Alarm, Severity as _Severity + +from ...namesys import SiriusPVName +from ..app import App as _App +from ..pvs import ComputedPV as _ComputedPV + +from .csdev import Const as _Const +from .pvs import BORFStatusPV as _BORFStatusPV, \ + SIRFStatusPV as _SIRFStatusPV, \ + SICheckAmpErrPV as _SICheckAmpErrPV, \ + SICheckPhsErrPV as _SICheckPhsErrPV, \ + SICheckDTuneErrPV as _SICheckDTuneErrPV + + +class RFDiagApp(_App): + """Main application responsible for updating DB.""" + + def _create_computed_pvs(self, *args): + # BO + devname = SiriusPVName(self._prefix + _Const.BO_DEV) + + # DiagStatus-Mon + pvs = [None]*4 + pvs[_BORFStatusPV.PV_SIRIUS_INTLK] = 'BO-05D:RF-Intlk:BO-Mon' + pvs[_BORFStatusPV.PV_LLRF_INTLK] = 'BO-05D:RF-LLRF:Status-Mon' + pvs[_BORFStatusPV.PV_RMP_ENBLD] = 'BR-RF-DLLRF-01:RmpEnbl-Sts' + pvs[_BORFStatusPV.PV_RMP_READY] = 'BR-RF-DLLRF-01:RmpReady-Mon' + pvo = _ComputedPV( + devname + ':DiagStatus-Mon', _BORFStatusPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # SI + devname = SiriusPVName(self._prefix + _Const.SI_DEV) + + # DiagAmpErrSts-Mon + pvs = [None]*1 + pvs[_SICheckAmpErrPV.PV_ERR] = 'SR-RF-DLLRF-01:SL:ERR:AMP' + pvo = _ComputedPV( + devname + ':DiagAmpErrSts-Mon', _SICheckAmpErrPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # DiagPhsErrSts-Mon + pvs = [None]*1 + pvs[_SICheckPhsErrPV.PV_ERR] = 'SR-RF-DLLRF-01:SL:ERR:PHS' + pvo = _ComputedPV( + devname + ':DiagPhsErrSts-Mon', _SICheckPhsErrPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # DiagDTuneErrSts-Mon + pvs = [None]*1 + pvs[_SICheckDTuneErrPV.PV_ERR] = 'SR-RF-DLLRF-01:TUNE:DEPHS' + pvo = _ComputedPV( + devname + ':DiagDTuneErrSts-Mon', _SICheckDTuneErrPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + # DiagStatus-Mon + pvs = [None]*5 + pvs[_SIRFStatusPV.PV_SIRIUS_INTLK] = 'SI-02SB:RF-Intlk:SIA-Mon' + pvs[_SIRFStatusPV.PV_LLRF_INTLK] = 'SI-02SB:RF-LLRF:Intlk-Mon' + pvs[_SIRFStatusPV.PV_AMPL_ERR] = devname + ':DiagAmpErrSts-Mon' + pvs[_SIRFStatusPV.PV_PHSE_ERR] = devname + ':DiagPhsErrSts-Mon' + pvs[_SIRFStatusPV.PV_DTUN_ERR] = devname + ':DiagDTuneErrSts-Mon' + pvo = _ComputedPV( + devname + ':DiagStatus-Mon', _SIRFStatusPV(), + self._queue, pvs, monitor=False) + self.pvs.append(pvo) + + self._pvs_connected = {pv: False for pv in self.pvs} + + def _update_pvs(self): + for pvo in self.pvs: + if not pvo.connected: + if self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.TIMEOUT_ALARM, + severity=_Severity.INVALID_ALARM, + field='status') + self._pvs_connected[pvo] = False + if 'DiagStatus' in pvo.pvname: + self.run_callbacks(pvo.pvname, value=pvo.value) + else: + if not self._pvs_connected[pvo]: + self.run_callbacks( + pvo.pvname, alarm=_Alarm.NO_ALARM, + severity=_Severity.NO_ALARM, field='status') + self._pvs_connected[pvo] = True + self.run_callbacks(pvo.pvname, value=pvo.value) diff --git a/siriuspy/siriuspy/diagsys/rfdiag/pvs.py b/siriuspy/siriuspy/diagsys/rfdiag/pvs.py new file mode 100644 index 000000000..881a66242 --- /dev/null +++ b/siriuspy/siriuspy/diagsys/rfdiag/pvs.py @@ -0,0 +1,164 @@ +#!/usr/local/bin/python-sirius +"""RF Diag PVs.""" + +import numpy as _np + +from .csdev import Const as _Const + + +class BORFStatusPV: + """BO RF Status PV.""" + + BIT_DISCONN = 0b00001 + BIT_SIINTLK = 0b00010 + BIT_LLINTLK = 0b00100 + BIT_RMPDSBL = 0b01000 + BIT_RMPNRDY = 0b10000 + + PV_SIRIUS_INTLK = 0 + PV_LLRF_INTLK = 1 + PV_RMP_ENBLD = 2 + PV_RMP_READY = 3 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute Status PV.""" + value = 0 + + # connected? + disconnected = \ + not computed_pv.pvs[BORFStatusPV.PV_SIRIUS_INTLK].connected or \ + not computed_pv.pvs[BORFStatusPV.PV_LLRF_INTLK].connected or \ + not computed_pv.pvs[BORFStatusPV.PV_RMP_ENBLD].connected or \ + not computed_pv.pvs[BORFStatusPV.PV_RMP_READY].connected + + if disconnected: + value |= BORFStatusPV.BIT_DISCONN + value |= BORFStatusPV.BIT_SIINTLK + value |= BORFStatusPV.BIT_LLINTLK + value |= BORFStatusPV.BIT_RMPDSBL + value |= BORFStatusPV.BIT_RMPNRDY + return {'value': value} + + # sirius interlock? + sts = computed_pv.pvs[BORFStatusPV.PV_SIRIUS_INTLK].value + if sts != 0 or sts is None: + value |= BORFStatusPV.BIT_SIINTLK + + # llrf interlock? + sts = computed_pv.pvs[BORFStatusPV.PV_LLRF_INTLK].value + if sts != 0 or sts is None: + value |= BORFStatusPV.BIT_LLINTLK + + # rmp enabled? + sts = computed_pv.pvs[BORFStatusPV.PV_RMP_ENBLD].value + if sts != _Const.DsblEnbl.Enbl or sts is None: + value |= BORFStatusPV.BIT_RMPDSBL + + # rmp ready? + sts = computed_pv.pvs[BORFStatusPV.PV_RMP_READY].value + if sts != _Const.DsblEnbl.Enbl or sts is None: + value |= BORFStatusPV.BIT_RMPNRDY + + return {'value': value} + + +class CheckErrPV: + """Check error PV and filter spurious spikes.""" + + PV_ERR = 0 + _hist = [0]*10 + _idx = 0 + _tol = 0 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Check error exceeds tolerance.""" + if not computed_pv.pvs[CheckErrPV.PV_ERR].connected: + return None + value = computed_pv.pvs[CheckErrPV.PV_ERR].value + self._hist[self._idx] = value + self._idx += 1 + self._idx %= 10 + sts = 1 if _np.all([v > self._tol for v in self._hist]) else 0 + return {'value': sts} + + +class SICheckAmpErrPV(CheckErrPV): + """Check amplitude error.""" + + _tol = _Const.SI_SL_ERRTOL_AMP + + +class SICheckPhsErrPV(CheckErrPV): + """Check phase error.""" + + _tol = _Const.SI_SL_ERRTOL_PHS + + +class SICheckDTuneErrPV(CheckErrPV): + """Check detune error.""" + + _tol = _Const.SI_SL_ERRTOL_DTU + + +class SIRFStatusPV: + """SI RF Status PV.""" + + BIT_DISCONN = 0b000001 + BIT_SIINTLK = 0b000010 + BIT_LLINTLK = 0b000100 + BIT_AMPLERR = 0b001000 + BIT_PHSEERR = 0b010000 + BIT_DTUNERR = 0b100000 + + PV_SIRIUS_INTLK = 0 + PV_LLRF_INTLK = 1 + PV_AMPL_ERR = 2 + PV_PHSE_ERR = 3 + PV_DTUN_ERR = 4 + + def compute_update(self, computed_pv, updated_pv_name, value): + """Compute Status PV.""" + value = 0 + + # connected? + disconnected = \ + not computed_pv.pvs[SIRFStatusPV.PV_SIRIUS_INTLK].connected or \ + not computed_pv.pvs[SIRFStatusPV.PV_LLRF_INTLK].connected or \ + not computed_pv.pvs[SIRFStatusPV.PV_AMPL_ERR].connected or \ + not computed_pv.pvs[SIRFStatusPV.PV_PHSE_ERR].connected or \ + not computed_pv.pvs[SIRFStatusPV.PV_DTUN_ERR].connected + if disconnected: + value |= SIRFStatusPV.BIT_DISCONN + value |= SIRFStatusPV.BIT_SIINTLK + value |= SIRFStatusPV.BIT_LLINTLK + value |= SIRFStatusPV.BIT_AMPLERR + value |= SIRFStatusPV.BIT_PHSEERR + value |= SIRFStatusPV.BIT_DTUNERR + return {'value': value} + + # sirius interlock? + sts = computed_pv.pvs[SIRFStatusPV.PV_SIRIUS_INTLK].value + if sts != 0 or sts is None: + value |= SIRFStatusPV.BIT_SIINTLK + + # llrf interlock? + sts = computed_pv.pvs[SIRFStatusPV.PV_LLRF_INTLK].value + if sts != 0 or sts is None: + value |= SIRFStatusPV.BIT_LLINTLK + + # amplitude error? + severity = computed_pv.pvs[SIRFStatusPV.PV_AMPL_ERR].severity + if severity != 0: + value |= SIRFStatusPV.BIT_AMPLERR + + # phase error? + severity = computed_pv.pvs[SIRFStatusPV.PV_PHSE_ERR].severity + if severity != 0: + value |= SIRFStatusPV.BIT_PHSEERR + + # detune error? + severity = computed_pv.pvs[SIRFStatusPV.PV_DTUN_ERR].severity + if severity != 0: + value |= SIRFStatusPV.BIT_DTUNERR + + return {'value': value} diff --git a/siriuspy/siriuspy/psdiag/csdev.py b/siriuspy/siriuspy/psdiag/csdev.py deleted file mode 100644 index 903d76ad1..000000000 --- a/siriuspy/siriuspy/psdiag/csdev.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Power Supply Diag Control System App.""" - -from .. import csdev as _csdev -from ..search import PSSearch as _PSSearch - - -class ETypes(_csdev.ETypes): - """Local enumerate types.""" - - DIAG_STATUS = ( - 'PS Connected', 'PwrState-Sts On', 'OpMode-Sts SlowRef', - 'Current-(SP|Mon) differ', 'Interlocks', 'Wfm error') - - -_et = ETypes # syntactic sugar - - -def get_ps_diag_propty_database(psname): - """Return property database of diagnostics for power supplies.""" - pstype = _PSSearch.conv_psname_2_pstype(psname) - splims = _PSSearch.conv_pstype_2_splims(pstype) - dtol = splims['DTOL_CUR'] - dbase = { - 'DiagVersion-Cte': {'type': 'str', 'value': 'UNDEF'}, - 'DiagCurrentDiff-Mon': {'type': 'float', 'value': 0.0, - 'hilim': dtol, 'hihi': dtol, 'high': dtol, - 'low': -dtol, 'lolo': -dtol, 'lolim': -dtol}, - 'DiagStatus-Mon': {'type': 'int', 'value': 0, - 'hilim': 1, 'hihi': 1, 'high': 1, - 'low': -1, 'lolo': -1, 'lolim': -1 - }, - 'DiagStatusLabels-Cte': {'type': 'string', - 'count': len(_et.DIAG_STATUS), - 'value': _et.DIAG_STATUS}} - dbase = _csdev.add_pvslist_cte(dbase, 'Diag') - return dbase diff --git a/siriuspy/siriuspy/psdiag/main.py b/siriuspy/siriuspy/psdiag/main.py deleted file mode 100644 index 94606214e..000000000 --- a/siriuspy/siriuspy/psdiag/main.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/local/bin/python-sirius -"""Driver module.""" - -import time as _time -from threading import Thread as _Thread - -from pcaspy import Alarm as _Alarm, Severity as _Severity - -from ..callbacks import Callback as _Callback -from ..thread import QueueThread as _QueueThread -from ..epics.pv_psdiag import \ - ComputedPV as _ComputedPV, \ - PSStatusPV as _PSStatusPV, \ - PSDiffPV as _PSDiffPV - -SCAN_FREQUENCY = 2 - - -class App(_Callback): - """Main application responsible for updating DB.""" - - def __init__(self, prefix, psnames): - """Create Computed PVs.""" - super().__init__() - self._prefix = prefix - self._psnames = psnames - self._queue = _QueueThread() - self.pvs = list() - self.scanning = False - self.quit = False - self._create_computed_pvs() - - self.t = _Thread(target=self.scan, daemon=True) - self.t.start() - - def process(self, interval): - """Sleep.""" - _time.sleep(interval) - - def read(self, reason): - """Read from IOC database.""" - return None - - def write(self, reason, value): - """Write value to reason and let callback update PV database.""" - status = False - return status # return True to invoke super().write of PCASDriver - - def _create_computed_pvs(self): - for psname in self._psnames: - devname = self._prefix + psname - # DiagCurrentDiff-Mon - pvs = [None, None] - pvs[_PSDiffPV.CURRT_SP] = devname + ':Current-SP' - pvs[_PSDiffPV.CURRT_MON] = devname + ':Current-Mon' - pv = _ComputedPV( - psname + ':DiagCurrentDiff-Mon', _PSDiffPV(), self._queue, - pvs, monitor=False) - self.pvs.append(pv) - # DiagStatus-Mon - pvs = [None]*7 - pvs[_PSStatusPV.PWRSTE_STS] = devname + ':PwrState-Sts' - pvs[_PSStatusPV.INTLK_SOFT] = devname + ':IntlkSoft-Mon' - pvs[_PSStatusPV.INTLK_HARD] = devname + ':IntlkHard-Mon' - pvs[_PSStatusPV.OPMODE_SEL] = devname + ':OpMode-Sel' - pvs[_PSStatusPV.OPMODE_STS] = devname + ':OpMode-Sts' - pvs[_PSStatusPV.CURRT_DIFF] = devname + ':DiagCurrentDiff-Mon' - pvs[_PSStatusPV.WAVFRM_MON] = devname + ':Wfm-Mon' - # TODO: Add other interlocks for PS types that have them - pv = _ComputedPV( - psname + ':DiagStatus-Mon', _PSStatusPV(), self._queue, - pvs, monitor=False) - self.pvs.append(pv) - - def scan(self): - """Run as a thread scanning PVs.""" - connected = {pv: False for pv in self.pvs} - while not self.quit: - if self.scanning: - for pv in self.pvs: - if not pv.connected: - if connected[pv]: - self.run_callbacks( - pv.pvname, alarm=_Alarm.TIMEOUT_ALARM, - severity=_Severity.INVALID_ALARM, - field='status') - connected[pv] = False - if 'DiagStatus' in pv.pvname: - self.run_callbacks(pv.pvname, value=pv.value) - else: - if not connected[pv]: - self.run_callbacks( - pv.pvname, alarm=_Alarm.NO_ALARM, - severity=_Severity.NO_ALARM, field='status') - connected[pv] = True - self.run_callbacks(pv.pvname, value=pv.value) - _time.sleep(1.0/SCAN_FREQUENCY) diff --git a/siriuspy/siriuspy/sofb/bpms.py b/siriuspy/siriuspy/sofb/bpms.py index fae4042cd..47e6bcfe4 100644 --- a/siriuspy/siriuspy/sofb/bpms.py +++ b/siriuspy/siriuspy/sofb/bpms.py @@ -3,7 +3,7 @@ import numpy as _np from ..epics import PV as _PV -from ..diag.bpm.csdev import Const as _csbpm +from ..diagbeam.bpm.csdev import Const as _csbpm from ..timesys import csdev as _cstime from ..search import HLTimeSearch as _HLTimesearch from ..envars import VACA_PREFIX as LL_PREF diff --git a/siriuspy/siriuspy/sofb/csdev.py b/siriuspy/siriuspy/sofb/csdev.py index 233ab8bc2..fa18c7759 100644 --- a/siriuspy/siriuspy/sofb/csdev.py +++ b/siriuspy/siriuspy/sofb/csdev.py @@ -6,7 +6,7 @@ from ..namesys import SiriusPVName as _PVName from ..search import MASearch as _MASearch, BPMSearch as _BPMSearch, \ LLTimeSearch as _TISearch, PSSearch as _PSSearch -from ..diag.bpm.csdev import Const as _csbpm +from ..diagbeam.bpm.csdev import Const as _csbpm from ..timesys import csdev as _cstiming diff --git a/siriuspy/siriuspy/sofb/orbit.py b/siriuspy/siriuspy/sofb/orbit.py index b74138063..8ab6e6b59 100644 --- a/siriuspy/siriuspy/sofb/orbit.py +++ b/siriuspy/siriuspy/sofb/orbit.py @@ -13,7 +13,7 @@ import bottleneck as _bn from .. import util as _util -from ..diag.bpm.csdev import Const as _csbpm +from ..diagbeam.bpm.csdev import Const as _csbpm from ..thread import RepeaterThread as _Repeat from ..epics import PV as _PV