Source code for siriushla.as_ps_diag.ps_graph_mon
"""PS Graph Monitor."""
import time as _time
from copy import deepcopy as _dcopy
from concurrent.futures import ThreadPoolExecutor
import numpy as _np
import epics
from qtpy.QtCore import Qt, QSize, Slot, Signal, QThread
from qtpy.QtGui import QColor
from qtpy.QtWidgets import QGridLayout, QWidget, QLabel, QHBoxLayout, \
QComboBox, QToolTip, QSpacerItem, QSizePolicy as QSzPlcy, QInputDialog, \
QAction, QMenu
import qtawesome as qta
from pyqtgraph import mkPen, mkBrush
from pydm.connection_inspector import ConnectionInspector
from siriuspy.util import get_strength_label
from siriuspy.envars import VACA_PREFIX as _vaca_prefix
from siriuspy.namesys import SiriusPVName
from siriuspy.search import PSSearch as _PSSearch, \
MASearch as _MASearch
from siriuspy.pwrsupply.csdev import Const as _PSConst
from siriushla.util import run_newprocess
from siriushla.widgets import SiriusMainWindow, SiriusWaveformPlot
[docs]
class PSGraphMonWindow(SiriusMainWindow):
"""Power supply graph monitor window."""
def __init__(self, parent=None, prefix=_vaca_prefix, filters=''):
super().__init__(parent)
self.setWindowTitle('Power Supplies Graph Monitor')
self._prefix = prefix
self._filters = filters
if not filters:
self.setObjectName('ASApp')
filters = {'sec': 'SI', 'dis': 'PS', 'dev': 'CH'}
else:
self.setObjectName(filters['sec']+'App')
self._psnames = _PSSearch.get_psnames(filters)
self._magfunc = _PSSearch.conv_psname_2_magfunc(self._psnames[0])
self._pstype = _PSSearch.conv_psname_2_pstype(self._psnames[0])
self._setupUi()
def _setupUi(self):
aux_label = '' if not self._filters \
else ' - '+self._filters['sec']+' '+self._filters['dev']
self._label = QLabel('<h3>PS Graph Monitor'+aux_label+'</h3>',
self, alignment=Qt.AlignCenter)
self.propty_sel = PSGraphProptySelWidget(self)
self.propty_sel.change_matype(self._magfunc, self._pstype)
self.graph = PSGraphMonWidget(
self, self._prefix, self._psnames)
self.propty_sel.propty_symb_changed.connect(
self.graph.update_property_symb)
self.propty_sel.propty_line_changed.connect(
self.graph.update_property_line)
if not self._filters:
self.dev_sel = PSGraphDevicesSelWidget(self, self._psnames)
self.dev_sel.matype_changed.connect(self.propty_sel.change_matype)
self.dev_sel.psnames_changed.connect(self.graph.update_psnames)
cwid = QWidget()
lay = QGridLayout(cwid)
lay.setVerticalSpacing(9)
lay.addWidget(self._label, 0, 0, 1, 2)
if not self._filters:
lay.addWidget(self.dev_sel, 1, 0)
lay.addItem(
QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Ignored), 1, 1)
lay.addWidget(self.propty_sel, 2, 0)
lay.addItem(
QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Ignored), 2, 1)
lay.addWidget(self.graph, 3, 0, 1, 2)
lay.setColumnStretch(0, 1)
lay.setColumnStretch(1, 1)
self.setCentralWidget(cwid)
[docs]
def contextMenuEvent(self, event):
point = event.pos()
menu = self.graph.contextMenuEvent(event, return_menu=True)
menu.addSeparator()
action = menu.addAction('Show Connections...')
action.triggered.connect(self.show_connections)
menu.popup(self.mapToGlobal(point))
[docs]
def show_connections(self, checked):
"""."""
_ = checked
conn = ConnectionInspector(self)
conn.show()
[docs]
class PSGraphDevicesSelWidget(QWidget):
"""Power supply selection widget."""
psnames_changed = Signal(list)
matype_changed = Signal(str, str)
def __init__(self, parent, psnames):
super().__init__(parent)
self._psnames = psnames
self._choose_sec = ['TB', 'BO', 'TS', 'SI']
self._choose_sub = ['All', ]
self._choose_sub.extend(['{0:02d}.*'.format(i+1) for i in range(20)])
self._choose_sub.extend(['.*M1', '.*M2',
'.*C1', '.*C2', '.*C3', '.*C4',
'.*SA', '.*SB', '.*SP'])
self._choose_dev = {
sec: ['CH', 'CV', 'C(H|V)'] for sec in self._choose_sec}
self._choose_dev['SI'].extend(
['QS', 'QFA', 'QFB', 'QFP', 'QF.*',
'QDA', 'QDB1', 'QDB2', 'QDP1', 'QDP2', 'QD.*',
'Q1', 'Q2', 'Q3', 'Q4', 'Q[1-4]',
'Q(D|F).*', 'Q(F|D|[1-4]).*',
'FCH', 'FCV', 'FC(H|V)'])
self.magfunc = _PSSearch.conv_psname_2_magfunc(self._psnames[0])
self.pytype = _PSSearch.conv_psname_2_pstype(self._psnames[0])
self._setupUi()
def _setupUi(self):
self._label_dev = QLabel('Power supply: ', self)
self._label_dev.setStyleSheet(
'min-width: 8em; max-width: 8em;')
self.cb_sec = QComboBox(self)
for item in self._choose_sec:
self.cb_sec.addItem(item)
self.cb_sec.setCurrentText('SI')
self.cb_sec.currentTextChanged.connect(
self._handle_cb_visibility)
self.cb_sec.currentTextChanged.connect(
self._set_psnames)
self.cb_sub = QComboBox(self)
self.cb_sub.setEditable(True)
self.cb_sub.setMaxVisibleItems(10)
for item in self._choose_sub:
self.cb_sub.addItem(item)
self.cb_sub.currentTextChanged.connect(
self._set_psnames)
glay_choose = QGridLayout()
glay_choose.addWidget(self.cb_sub, 0, 0)
self.cb_dev = dict()
for sec in self._choose_sec:
visible = sec == 'SI'
self.cb_dev[sec] = QComboBox(self)
self.cb_dev[sec].setMaxVisibleItems(10)
self.cb_dev[sec].setVisible(visible)
for item in self._choose_dev[sec]:
self.cb_dev[sec].addItem(item)
self.cb_dev[sec].currentTextChanged.connect(
self._set_psnames)
glay_choose.addWidget(self.cb_dev[sec], 0, 1)
lay = QGridLayout(self)
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(self._label_dev, 0, 0)
lay.addWidget(self.cb_sec, 0, 1)
lay.addLayout(glay_choose, 0, 2)
def _set_psnames(self):
sec = self.cb_sec.currentText()
if sec == 'SI':
sub = self.cb_sub.currentText()
sub = sub if sub != 'All' else '.*'
else:
sub = '.*'
dev = self.cb_dev[sec].currentText()
self._psnames = _PSSearch.get_psnames(
{'sec': sec, 'sub': '(?!Fam)'+sub, 'dis': 'PS', 'dev': dev})
if self._psnames and self.sender() == self.cb_dev[sec]:
self.magfunc = _PSSearch.conv_psname_2_magfunc(self._psnames[0])
self.pytype = _PSSearch.conv_psname_2_pstype(self._psnames[0])
self.matype_changed.emit(self.magfunc, self.pytype)
self.psnames_changed.emit(self._psnames)
def _handle_cb_visibility(self):
current_sec = self.sender().currentText()
self.cb_sub.setVisible(current_sec == 'SI')
for sec in self._choose_sec:
self.cb_dev[sec].setVisible(current_sec == sec)
[docs]
class PSGraphProptySelWidget(QWidget):
"""Power supply property selection widget."""
propty_symb_changed = Signal(str)
propty_line_changed = Signal(str)
PROP_SYMB_DEFAULT = [
'DiagStatus-Mon', 'IntlkSoft-Mon', 'IntlkHard-Mon',
'PwrState-Sel', 'PwrState-Sts', 'OpMode-Sel', 'OpMode-Sts',
'CtrlMode-Mon', 'CtrlLoop-Sel', 'CtrlLoop-Sts', 'CycleEnbl-Mon']
PROP_LINE_DEFAULT = [
'Current-Mon', 'Current-SP', 'Current-RB', 'CurrentRef-Mon',
'DiagCurrentDiff-Mon', 'WfmSyncPulseCount-Mon',
'PRUCtrlQueueSize-Mon']
PROP_SYMB_FASTCORR = [
'DiagStatus-Mon', 'AlarmsAmp-Mon', 'AlarmsAmpLtc-Mon',
'PwrState-Sel', 'PwrState-Sts']
PROP_LINE_FASTCORR = [
'Current-Mon', 'Current-SP', 'Current-RB', 'CurrentRef-Mon',
'DiagCurrentDiff-Mon']
def __init__(self, parent):
super().__init__(parent)
self._magfunc = None
self._pstype = None
self._intstr_propty = ''
self._intstr_suffix = ['-Mon', '-SP', '-RB', 'Ref-Mon']
self._choose_prop_symb = PSGraphProptySelWidget.PROP_SYMB_DEFAULT
self._choose_prop_line = PSGraphProptySelWidget.PROP_LINE_DEFAULT
self._setupUi()
def _setupUi(self):
self._label_prop = QLabel('Properties: ', self)
self._label_prop.setStyleSheet(
'min-width: 8em; max-width: 8em;')
self._label_symb = QLabel()
icon = qta.icon('mdi.record-circle-outline')
pixmap = icon.pixmap(icon.actualSize(QSize(20, 20)))
self._label_symb.setPixmap(pixmap)
self._label_symb.setSizePolicy(QSzPlcy.Fixed, QSzPlcy.Fixed)
self.cb_prop_symb = QComboBox(self)
self.cb_prop_symb.currentTextChanged.connect(
self.propty_symb_changed.emit)
self.cb_prop_symb.setSizePolicy(
QSzPlcy.Expanding, QSzPlcy.Preferred)
self.cb_prop_symb.setMaxVisibleItems(10)
self.cb_prop_symb.addItems(self._choose_prop_symb)
hbox_prop_symb = QHBoxLayout()
hbox_prop_symb.addWidget(self._label_symb)
hbox_prop_symb.addWidget(self.cb_prop_symb)
self._label_line = QLabel()
icon = qta.icon('mdi.pulse')
pixmap = icon.pixmap(icon.actualSize(QSize(20, 20)))
self._label_line.setPixmap(pixmap)
self._label_line.setSizePolicy(QSzPlcy.Fixed, QSzPlcy.Fixed)
self.cb_prop_line = QComboBox(self)
self.cb_prop_line.currentTextChanged.connect(
self.propty_line_changed.emit)
self.cb_prop_line.setSizePolicy(
QSzPlcy.Expanding, QSzPlcy.Preferred)
self.cb_prop_line.setMaxVisibleItems(10)
self.cb_prop_line.addItems(self._choose_prop_line)
hbox_prop_line = QHBoxLayout()
hbox_prop_line.addWidget(self._label_line)
hbox_prop_line.addWidget(self.cb_prop_line)
lay = QGridLayout(self)
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(self._label_prop, 0, 0)
lay.addLayout(hbox_prop_symb, 0, 1)
lay.addLayout(hbox_prop_line, 0, 2)
[docs]
def change_matype(self, magfunc, pstype):
"""Change MA type."""
currline = self.cb_prop_line.currentText()
currlineidx = self.cb_prop_line.currentIndex()
currsymb = self.cb_prop_symb.currentText()
self._magfunc = magfunc
self._pstype = pstype
if 'si-corrector-fc' in self._pstype:
self._choose_prop_symb = PSGraphProptySelWidget.PROP_SYMB_FASTCORR
self._choose_prop_line = PSGraphProptySelWidget.PROP_LINE_FASTCORR
else:
self._choose_prop_symb = PSGraphProptySelWidget.PROP_SYMB_DEFAULT
self._choose_prop_line = PSGraphProptySelWidget.PROP_LINE_DEFAULT
self.cb_prop_symb.clear()
self.cb_prop_symb.addItems(self._choose_prop_symb)
self.cb_prop_line.clear()
self.cb_prop_line.addItems(self._choose_prop_line)
self._intstr_propty = get_strength_label(self._magfunc)
for suf in self._intstr_suffix:
self.cb_prop_line.addItem(self._intstr_propty+suf)
if currline in self._choose_prop_line:
self.cb_prop_line.setCurrentText(currline)
elif currlineidx <= self.cb_prop_line.count():
self.cb_prop_line.setCurrentIndex(currlineidx)
if currsymb in self._choose_prop_symb:
self.cb_prop_symb.setCurrentText(currsymb)
[docs]
class PSGraph(SiriusWaveformPlot):
"""Power supply data graph."""
def __init__(self, parent=None, psnames=list(), y_data=list(),
symbols=list(), color='blue'):
"""Init."""
super().__init__(parent)
self.setBackgroundColor(QColor(255, 255, 255))
self.setAutoRangeX(True)
self.setAutoRangeY(True)
self.setShowXGrid(True)
self.setShowYGrid(True)
self.plotItem.setLabel('bottom', 's', units='m')
self.plotItem.setLabel('left', ' ')
self._nok_pen = mkPen(QColor(color))
self._nok_brush = mkBrush(QColor(255, 0, 0))
self._ok_pen = mkPen(QColor(color))
self._ok_brush = mkBrush(QColor(0, 200, 0))
self._none_pen = mkPen(QColor(color))
self._none_brush = mkBrush(QColor(220, 220, 220))
self._all_pen = [self._nok_pen, ]
self._all_brush = [self._nok_brush, ]
self.addChannel(
y_channel='Mean', x_channel='Pos', color='black',
lineStyle=2, lineWidth=2)
self.mean = self.curveAtIndex(0)
self.addChannel(
y_channel='Kicks', x_channel='Pos', color=color,
lineWidth=2, symbol='o', symbolSize=10)
self.curve = self.curveAtIndex(1)
self.redraw_timer.timeout.disconnect()
self.psnames = psnames
self.symbols = symbols
self.y_data = y_data
@property
def psnames(self):
"""Return psnames."""
return _dcopy(self._psnames)
@psnames.setter
def psnames(self, new):
if not new:
self._psnames = new
self._x_data = _np.array([0, ])
self._tooltips = ['', ]
self._sector = ''
else:
self._x_data = _np.array(_MASearch.get_mapositions(map(
lambda x: x.substitute(dis='MA'), new)))
self._psnames = [psn for _, psn in sorted(zip(self._x_data, new))]
self._x_data = _np.sort(self._x_data)
self._tooltips = [
psn.get_nickname(dev=True) for psn in self._psnames]
self._sector = SiriusPVName(new[0]).sec
if self._sector == 'TB':
self._c0 = 21.2477
elif self._sector == 'TS':
self._c0 = 26.8933
elif self._sector == 'BO':
self._c0 = 496.8
elif self._sector == 'SI':
self._c0 = 518.396
else:
self._c0 = 1.0
self.curve.receiveXWaveform(self._x_data)
self.mean.receiveXWaveform(self._x_data)
@property
def sector(self):
"""Return sector."""
return self._sector
@property
def tooltips(self):
"""Return tooltips."""
return self._tooltips
@property
def x_data(self):
"""Return x_data."""
return self._x_data
@property
def y_data(self):
"""Return y_data."""
return self._y_data
@y_data.setter
def y_data(self, new):
if not new or any([n is None for n in new]):
self._y_data = _np.array([0, ])
else:
self._y_data = _np.array(new)
self.curve.receiveYWaveform(self._y_data)
self.curve.opts['symbolPen'] = self._all_pen
self.curve.opts['symbolBrush'] = self._all_brush
self.curve.redrawCurve()
self.mean.receiveYWaveform(
_np.array([_np.mean(self._y_data)]*len(self._y_data)))
self.mean.redrawCurve()
@property
def symbols(self):
"""Return symbols."""
return self._symbols
@symbols.setter
def symbols(self, new):
self._symbols = new
if new:
all_brush, all_pen = [], []
for sym in self._symbols:
if sym:
all_pen.append(self._ok_pen)
all_brush.append(self._ok_brush)
else:
all_pen.append(self._nok_pen)
all_brush.append(self._nok_brush)
self._all_pen = all_pen
self._all_brush = all_brush
else:
self._all_pen = [self._none_pen, ]
self._all_brush = [self._none_brush, ]
[docs]
def mouseMoveEvent(self, event):
"""Reimplement mouseMoveEvent."""
pos = event.pos()
posx = self.curve.scatter.mapFromScene(pos).x()
posx = posx % self._c0
ind = _np.argmin(_np.abs(_np.array(self._x_data)-posx))
txt = '{0:s}, x = {1:.3f} m'.format(self.tooltips[ind], posx)
QToolTip.showText(
self.mapToGlobal(pos), txt, self, self.geometry(), 500)
super().mouseMoveEvent(event)
[docs]
def mouseDoubleClickEvent(self, event):
"""Reimplement mouseDoubleClickEvent."""
posx = self.curve.xData
view = self.plotItem.getViewBox()
pos = view.mapSceneToView(event.pos())
idx = _np.argmin(_np.abs(posx-pos.x()))
psname = self._psnames[idx]
self._open_ps_detail(psname)
super().mouseDoubleClickEvent(event)
def _open_ps_detail(self, psname):
"""Open PSDetailWindow."""
run_newprocess(['sirius-hla-as-ps-detail.py', psname])
[docs]
class PSGraphMonWidget(QWidget):
"""Power supply graph monitor widget."""
propLineChanged = Signal(str)
propSymbChanged = Signal(str)
psnamesChanged = Signal(list)
def __init__(self, parent=None, prefix=_vaca_prefix, psnames=''):
super().__init__(parent)
self._prefix = prefix
self._psnames = psnames
self._property_line = 'Current-Mon'
self._property_symb = 'DiagStatus-Mon'
self._pvhandler = _PVHandler(self._psnames, self._prefix, self)
self._setupUi()
self._create_commands()
epics.ca.use_initial_context()
self._thread = _UpdateGraphThread(
self._property_line, self._property_symb, self._pvhandler,
parent=self)
self.propLineChanged.connect(self._thread.set_property_line)
self.propSymbChanged.connect(self._thread.set_property_symb)
self._thread.dataChanged.connect(self._update_graph)
self._thread.start()
def _setupUi(self):
self.graph = PSGraph(self, self._psnames)
self.graph.setObjectName('graph')
lay = QGridLayout(self)
lay.addWidget(self.graph, 0, 0)
self.setStyleSheet('#graph{min-width:60em;min-height:12em;}')
[docs]
def update_psnames(self, psnames):
"""Update psnames."""
self.graph.psnames = _dcopy(psnames)
self._psnames = self.graph.psnames
self._pvhandler.set_psnames(self._psnames)
[docs]
@Slot(str)
def update_property_line(self, text):
"""Update property line."""
self._property_line = text
self.propLineChanged.emit(text)
[docs]
@Slot(str)
def update_property_symb(self, text):
"""Update property symbol."""
self._property_symb = text
self.propSymbChanged.emit(text)
def _update_graph(self, symbols, y_data):
if len(self._psnames) != len(symbols):
return
self.graph.symbols = symbols
self.graph.y_data = y_data
def _create_commands(self):
self.cmd_turnon_act = QAction("Turn On", self)
self.cmd_turnon_act.triggered.connect(
self._pvhandler.cmd_turn_on)
self.cmd_turnoff_act = QAction("Turn Off", self)
self.cmd_turnoff_act.triggered.connect(
self._pvhandler.cmd_turn_off)
self.cmd_ctrlloopclose_act = QAction("Close Control Loop", self)
self.cmd_ctrlloopclose_act.triggered.connect(
self._pvhandler.cmd_ctrlloop_close)
self.cmd_ctrlloopopen_act = QAction("Open Control Loop", self)
self.cmd_ctrlloopopen_act.triggered.connect(
self._pvhandler.cmd_ctrlloop_open)
self.cmd_setslowref_act = QAction("Set OpMode to SlowRef", self)
self.cmd_setslowref_act.triggered.connect(
self._pvhandler.cmd_set_opmode_slowref)
self.cmd_setcurrent_act = QAction("Set Current SP", self)
self.cmd_setcurrent_act.triggered.connect(
self._pvhandler.cmd_set_current)
self.cmd_reset_act = QAction("Reset Interlocks", self)
self.cmd_reset_act.triggered.connect(
self._pvhandler.cmd_reset)
[docs]
def contextMenuEvent(self, event, return_menu=False):
"""Show a custom context menu."""
point = event.pos()
if not self.graph.geometry().contains(point) or return_menu:
menu = QMenu("Actions", self)
menu.addAction(self.cmd_turnon_act)
menu.addAction(self.cmd_turnoff_act)
menu.addAction(self.cmd_setcurrent_act)
menu.addAction(self.cmd_reset_act)
if not SiriusPVName(self._psnames[0]).dev in ('FCH', 'FCV'):
menu.addAction(self.cmd_ctrlloopclose_act)
menu.addAction(self.cmd_ctrlloopopen_act)
menu.addAction(self.cmd_setslowref_act)
if return_menu:
return menu
menu.popup(self.mapToGlobal(point))
class _PVHandler:
"""PV Handler."""
_pvs = dict()
PROPSYMB_2_DEFVAL_DEF = {
'DiagStatus-Mon': 0,
'IntlkSoft-Mon': 0,
'IntlkHard-Mon': 0,
'PwrState-Sel': _PSConst.PwrStateSel.On,
'PwrState-Sts': _PSConst.PwrStateSts.On,
'OpMode-Sel': _PSConst.OpMode.SlowRef,
'OpMode-Sts': _PSConst.States.SlowRef,
'CtrlMode-Mon': _PSConst.Interface.Remote,
'CtrlLoop-Sel': _PSConst.OpenLoop.Closed,
'CtrlLoop-Sts': _PSConst.OpenLoop.Closed,
'CycleEnbl-Mon': _PSConst.DsblEnbl.Enbl
}
PROPSYMB_2_DEFVAL_FCS = {
'DiagStatus-Mon': 0,
'AlarmsAmp-Mon': 0,
'AlarmsAmpLtc-Mon': 0,
'PwrState-Sel': _PSConst.PwrStateSel.On,
'PwrState-Sts': _PSConst.PwrStateSts.On,
}
def __init__(self, psnames=list(), prefix=_vaca_prefix, parent=None):
"""Init."""
self._psnames = psnames
self._propsymb_2_defval = _PVHandler.PROPSYMB_2_DEFVAL_DEF
self._prefix = prefix
self._parent = parent
def set_psnames(self, psnames):
"""Set psnames."""
self._psnames = _dcopy(psnames)
if SiriusPVName(self._psnames[0]).dev in ('FCH', 'FCV'):
self._propsymb_2_defval = _PVHandler.PROPSYMB_2_DEFVAL_FCS
else:
self._propsymb_2_defval = _PVHandler.PROPSYMB_2_DEFVAL_DEF
def get_values(self, propty):
"""Get PV values."""
if not self._psnames:
return []
psnames = list(self._psnames)
self._create_pvs(psnames, propty)
values = list()
for psn in psnames:
pvname = self._get_pvname(psn, propty)
_PVHandler._pvs[pvname].wait_for_connection()
for psn in psnames:
pvname = self._get_pvname(psn, propty)
try:
val = _PVHandler._pvs[pvname].get()
except epics.ca.ChannelAccessException:
val = None
val = val if val is not None else 0
if propty in self._propsymb_2_defval.keys():
defval = self._propsymb_2_defval[propty]
val = 1 if val == defval else 0
values.append(val)
return values
def _get_pvname(self, psname, propty):
"""Get PV name for psname and propty."""
return SiriusPVName(psname).substitute(
prefix=self._prefix, propty=propty)
def _create_pvs(self, psnames, propty):
"""Create PVs."""
new_pvs = dict()
for psn in psnames:
pvname = self._get_pvname(psn, propty)
if pvname in _PVHandler._pvs:
continue
new_pvs[pvname] = epics.PV(pvname, connection_timeout=0.05)
_PVHandler._pvs.update(new_pvs)
def set_values(self, propty, value):
"""Set PV values."""
psnames = self._psnames
self._create_pvs(psnames, propty)
for psn in psnames:
pvname = self._get_pvname(psn, propty)
_PVHandler._pvs[pvname].wait_for_connection()
for psn in psnames:
pvname = self._get_pvname(psn, propty)
_PVHandler._pvs[pvname].put(value)
def cmd_set_opmode_slowref(self):
"""Set power supplies OpMode to SlowRef."""
self.set_values('OpMode-Sel', _PSConst.OpMode.SlowRef)
def cmd_turn_on(self):
"""Turn power supplies on."""
self.set_values('PwrState-Sel', _PSConst.PwrStateSel.On)
def cmd_turn_off(self):
"""Turn power supplies off."""
self.set_values('PwrState-Sel', _PSConst.PwrStateSel.Off)
def cmd_ctrlloop_close(self):
"""Close power supplies control loop."""
value = _PSConst.OffOn.On \
if SiriusPVName(self._psnames[0]).dev in ('FCH', 'FCV') \
else _PSConst.CloseOpen.Closed
self.set_values('CtrlLoop-Sel', value)
def cmd_ctrlloop_open(self):
"""Open power supplies control loop."""
value = _PSConst.OffOn.Off \
if SiriusPVName(self._psnames[0]).dev in ('FCH', 'FCV') \
else _PSConst.CloseOpen.Open
self.set_values('CtrlLoop-Sel', value)
def cmd_set_current(self):
"""Set power supplies current."""
value, res = QInputDialog.getDouble(
self._parent, "Insert current setpoint", "Value")
if res:
self.set_values('Current-SP', value)
def cmd_reset(self):
"""Reset power supplies."""
pvn = 'AlarmsAmpLtcRst-Cmd' \
if self._psnames[0].endswith(('-FCH', '-FCV')) \
else 'Reset-Cmd'
self.set_values(pvn, 1)
class _UpdateGraphThread(QThread):
"""Update Graph Thread."""
dataChanged = Signal(list, list)
def __init__(self, property_line, property_symb, pvhandler, parent=None):
super().__init__(parent)
self._property_line = property_line
self._property_symb = property_symb
self._pvhandler = pvhandler
self._quit_task = False
def set_property_line(self, new):
"""Update property line."""
self._property_line = new
def set_property_symb(self, new):
"""Update property symbol."""
self._property_symb = new
def exit_task(self):
"""Set flag to quit thread."""
self._quit_task = True
def run(self):
"""Run task."""
epics.ca.use_initial_context()
while not self._quit_task:
_t0 = _time.time()
self._update_data()
_dt = _time.time() - _t0
sleep = 0.25 - _dt
if sleep > 0:
_time.sleep(sleep)
def _update_data(self):
symbols = self._pvhandler.get_values(self._property_symb)
y_data = self._pvhandler.get_values(self._property_line)
self.dataChanged.emit(symbols, y_data)