Skip to content
Snippets Groups Projects
Commit b5d8bf7e authored by Claudio Scafuri's avatar Claudio Scafuri :speech_balloon:
Browse files

imported from repo fermi/panels/openBST

parent e4e1028a
No related branches found
No related tags found
No related merge requests found
*.pyc
bin
Makefile 0 → 100644
NAME = openBST-gui
MAIN = openBST.py
DIRNAME = $(NAME:-gui=)
MODNAME = $(MAIN:.py=)
PY_FILES += $(wildcard src/*.py)
default: bin ${PY_FILES}
@cp ${PY_FILES} bin/${DIRNAME}
@echo "#!/usr/bin/env python\nimport sys\nsys.path.append(sys.path[0]+'/${DIRNAME}')\nfrom ${MODNAME} import main\nif __name__ == '__main__':\n main()\n" > bin/${NAME}
@chmod +x bin/${NAME} bin/${DIRNAME}/${MAIN}
bin:
@test -d $@ || mkdir -p $@/${DIRNAME}
clean:
@rm -fr bin/ src/*~
.PHONY: clean
# openBST
# Project name
openBST
## Description
python gui for manging FERMI stoppers
## Dependencies
PyQt4, PyTango
## Installation & deployment
first version must be installed by hand
## History
2020-08-14 imported from repo fermi/panels/openBST
## Credits
first development by Eugenio Ferrari
Elettra-Sincrotrone Trieste S.C.p.A. di interesse nazionale
Strada Statale 14 - km 163,5 in AREA Science Park
34149 Basovizza, Trieste ITALY
## License
GPL 3
import PyTango
import time
class TangoDev(object):
"""
A generic tango device
"""
def __init__(self, name):
self.dev = None
self._name = name
self.initDev()
def initDev(self):
try:
self.dev = PyTango.DeviceProxy(self._name)
except:
print('Cannot initialize %s device' % self._name)
def cmd_exec(self, comm, *args, **kwargs):
if self.dev is None:
self.initDev()
if len(args) > 0:
try:
self.dev.command_inout(comm, args[0])
except Exception as error:
print('Failed to execute command %s (with arguments) on device %s.' % (comm, self.dev))
print(error[1].desc)
else:
try:
self.dev.command_inout(comm)
except Exception as error:
print('Failed to execute command %s on device %s.' % (comm, self.dev))
print(error[1].desc)
def getAttrValue(self, attr):
if self.dev is None:
self.initDev()
try:
temp = self.dev.read_attribute(attr)
if temp.quality != PyTango.AttrQuality.ATTR_INVALID:
if type(temp.value) == type('abc'):
return temp.value
try:
dataSize = len(temp.value)
# If excepting, it is real because reals have no size
return temp.value[0]
except:
return temp.value
else:
return None
except:
self.initDev()
return None
def setAttrValue(self, attr, value):
if self.dev is None:
self.initDev()
try:
temp = self.dev.write_attribute(attr, value)
except:
print('Cannot set %f for device %s' % (value, self._name))
def State(self):
try:
temp = self.dev.command_inout('State')
return str(temp).upper()
except:
return '####'
def getProperty(self, propertyName):
try:
temp = self.dev.get_property(propertyName)
if propertyName in temp.keys():
return float(temp[propertyName][0])
else:
return None
except:
return None
class TangoDevAttRW(TangoDev):
def __init__(self, name, att_name):
super(self.__class__, self).__init__(name)
self.att_name = att_name
self._value = self.value
@property
def value(self):
return self.getAttrValue(self.att_name)
@value.setter
def value(self, value):
self.setAttrValue(self.att_name, value)
class Shutter(TangoDev):
def OPEN(self):
"""
Opens the shutter
"""
self.cmd_exec('Open')
def CLOSE(self):
"""
Closes the shutter
"""
self.cmd_exec('Close')
def isEnabled(self):
"""
Check if the opening of the shutter is enabled
"""
return self.getAttrValue('AbiGroup')
class Stopper(TangoDev):
def __init__(self, stateList, cmdPrefix, idxOpenClose):
name = 'f/access_control/safety'
super(self.__class__, self).__init__(name)
self._stateList = stateList
self._cmdPrefix = cmdPrefix
self._cmd_open = self._cmdPrefix + 'Open'
self._cmd_close = self._cmdPrefix + 'Close'
self._idxOpenClose = idxOpenClose
def OPEN(self):
if self._idxOpenClose is None:
self.cmd_exec(self._cmd_open)
else:
for idx in self._idxOpenClose:
self.cmd_exec(self._cmd_open, idx)
def CLOSE(self):
if self._idxOpenClose is None:
self.cmd_exec(self._cmd_close)
else:
for idx in self._idxOpenClose:
self.cmd_exec(self._cmd_close, idx)
def State(self):
controllo = list()
status = list()
for stopper in self._stateList:
controllo.append(1)
status.append(self.getAttrValue(stopper))
if None in status:
return '####'
if controllo == status:
return 'OPEN'
else:
return 'CLOSED'
class OperationMode(TangoDev):
def __init__(self):
name = 'usa/mps/plcmps'
super(self.__class__, self).__init__(name)
self._att = 'OperationModeCode'
def State(self):
opMode = self.getAttrValue(self._att)
if opMode == 1:
return 'LH'
elif opMode == 2:
return 'BC01'
elif opMode == 3:
return 'DBD'
elif opMode == 4:
return 'FEL01'
elif opMode == 5:
return 'FEL02'
else:
return 'DBD'
class Trigger(TangoDev):
def __init__(self, name, attMaster, delayDevName):
super(self.__class__, self).__init__(name)
self._attMaster = attMaster
self._attMasterRef = self._attMaster + 'Ref'
self.delayDev = TangoDev(delayDevName)
self._trigger = self.trigger
self._reference = self.reference
self._delayOffset = self.delayOffset
@property
def trigger(self):
return self.getAttrValue(self._attMaster)
@property
def reference(self):
return self.getAttrValue(self._attMasterRef)
@property
def delayOffset(self):
return self.delayDev.getProperty('DelayOffset')
def State(self):
return abs(self.reference - self.trigger) < 2.0
def RESET(self):
if self.reference:
self.setAttrValue(self._attMaster, self.reference)
def SHIFT(self):
self.RESET()
time_shift = self.trigger - self.delayOffset * 12.675
if time_shift:
self.setAttrValue(self._attMaster, time_shift)
else:
print('Error trying to shift trigger reference for dev %s.' % self._name)
class BSTController(object):
maxDelay = 10.
def __init__(self):
"""Constructor"""
# Devices PIL
self.PILShutter = Shutter('usa/mps/shutter')
# Beam stopper
self.LinacStopper = Stopper(['Linac_bst_1'], 'LinacBst', None)
self.FEL1Stopper = Stopper(['Undulator_bst1_fel1', 'Undulator_bst2_fel1'], 'UndulatorBst', [1, 2])
self.FEL2Stopper = Stopper(['Undulator_bst1_fel2', 'Undulator_bst2_fel2'], 'UndulatorBst', [3, 4])
# Shutter Padres
self.FEL1Shutter = Shutter('tango://srv-padres-srf:20000/pfe_f01/interlock/sh_pfe_f01.01')
self.FEL2Shutter = Shutter('tango://srv-padres-srf:20000/pfe_f02/interlock/sh_pfe_f02.01')
# Operation mode (DBD - FEL1 - FEL2 or other)
self.FERMImode = OperationMode()
# Trigger SEED
self.SEEDTrigger = Trigger('sl/timing/timing_sl.01', 'SeedMasterDelay', 'f/timing/rttrigger_sl.01')
# Time to Go
self.TimeToGo = TangoDevAttRW('f/modulators/modulators', 'TimeString')
# FermiStatus
self.fstatus = TangoDev('f/misc/fermistatus')
#terfermistatus
self.terafermistatus = TangoDev('srv-tf-srf:20000/tf/mover1d/x_sdiag_tf.01')
##############################
### FEL1 stopper & shutter ###
def openFEL1stopper(self):
self.FEL1Stopper.OPEN()
def closeFEL1(self):
self.FEL1Stopper.CLOSE()
def openFEL1shutter(self):
t1 = time.time()
while True:
if self.FEL1Shutter.isEnabled():
break
else:
t2 = time.time()
if abs(t2 - t1) >= self.maxDelay:
return
time.sleep(0.1)
self.FEL1Shutter.OPEN()
def openFEL1(self):
self.openFEL1stopper()
self.openFEL1shutter()
##############################
### FEL2 stopper & shutter ###
def openFEL2stopper(self):
self.FEL2Stopper.OPEN()
def openFEL2shutter(self):
t1 = time.time()
while True:
if self.FEL2Shutter.isEnabled():
break
else:
t2 = time.time()
if abs(t2 - t1) >= self.maxDelay:
return
time.sleep(0.1)
self.FEL2Shutter.OPEN()
def openFEL2(self):
self.openFEL2stopper()
self.openFEL2shutter()
def closeFEL2(self):
self.FEL2Stopper.CLOSE()
\ No newline at end of file
#!/usr/bin/python
import sys
from PyQt4 import QtGui, QtCore
import openBSTGUI
import bstController
class MainWindow(QtGui.QMainWindow, openBSTGUI.Ui_OpenBST):
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.BST = bstController.BSTController()
self.update()
# PIL
self.OpenPIL.clicked.connect(self.BST.PILShutter.OPEN)
self.ClosePIL.clicked.connect(self.BST.PILShutter.CLOSE)
# LINAC
self.OpenLINACthr = Executor(self.BST.LinacStopper.OPEN)
self.OpenLINAC.clicked.connect(self.OpenLINACthr.start)
self.CloseLINACthr = Executor(self.BST.LinacStopper.CLOSE)
self.CloseLINAC.clicked.connect(self.CloseLINACthr.start)
# FEL1
self.OpenFEL1thr = Executor(self.BST.openFEL1)
self.OpenFEL1.clicked.connect(self.OpenFEL1thr.start)
self.CloseFEL1thr = Executor(self.BST.closeFEL1)
self.CloseFEL1.clicked.connect(self.CloseFEL1thr.start)
# FEL2
self.OpenFEL2thr = Executor(self.BST.openFEL2)
self.OpenFEL2.clicked.connect(self.OpenFEL2thr.start)
self.CloseFEL2thr = Executor(self.BST.closeFEL2)
self.CloseFEL2.clicked.connect(self.CloseFEL2thr.start)
# Trigger
#self.PILTRG.clicked.connect(self.BST.PILTrigger.RESET)
self.SLTRG.clicked.connect(self.BST.SEEDTrigger.RESET)
# collegamenti del menu
self.action_menu_Silent_SEED.triggered.connect(self.BST.SEEDTrigger.SHIFT)
self.action_menu_FEL1_shutter.triggered.connect(self.BST.FEL1Shutter.CLOSE)
self.action_menu_FEL2_shutter.triggered.connect(self.BST.FEL2Shutter.CLOSE)
# Timer for GUI update
self.timer = QtCore.QBasicTimer()
self.timer.start(1000, self)
def __del__(self):
self.timer.stop()
def timerEvent(self, event):
self.update()
def update(self):
PILShutter = self.BST.PILShutter.State()
LINACStopper = self.BST.LinacStopper.State()
FEL1 = self.stateForFEL(self.BST.FEL1Stopper.State(), self.BST.FEL1Shutter.State())
FEL2 = self.stateForFEL(self.BST.FEL2Stopper.State(), self.BST.FEL2Shutter.State())
#SEEDTrigger = self.BST.SEEDTrigger.State()
SEEDTrigger = 'Open'
opMode = self.BST.FERMImode.State()
timeToGo = self.BST.TimeToGo.value
# PIL shutter status
self.setStateStringEnableColor(self.StatusPIL, PILShutter, changeString=True)
# LINAC status
self.setStateStringEnableColor(self.StatusLINAC, LINACStopper, changeString=True)
# FEL status
self.setStateStringEnableColor(self.StatusFEL1, FEL1, changeString=True)
self.setStateStringEnableColor(self.StatusFEL2, FEL2, changeString=True)
# Trigger Status
self.setStateStringEnableColor(self.SLTRG, self.boolToState(SEEDTrigger), enabled=(not SEEDTrigger))
# Enabled buttons
if opMode == 'FEL01':
self.OpenPIL.setEnabled(True)
self.OpenLINAC.setEnabled(True)
self.OpenFEL1.setEnabled(True)
self.OpenFEL2.setEnabled(False)
elif opMode == 'FEL02':
self.OpenPIL.setEnabled(True)
self.OpenLINAC.setEnabled(True)
self.OpenFEL1.setEnabled(False)
self.OpenFEL2.setEnabled(True)
else:
self.OpenPIL.setEnabled(True)
self.OpenLINAC.setEnabled(False)
self.OpenFEL1.setEnabled(False)
self.OpenFEL2.setEnabled(False)
# menu shutter
if opMode == 'FEL01':
self.menuClose_Shutter.setEnabled(True)
self.action_menu_FEL1_shutter.setEnabled(True)
self.action_menu_FEL2_shutter.setEnabled(False)
elif opMode == 'FEL02':
self.menuClose_Shutter.setEnabled(True)
self.action_menu_FEL1_shutter.setEnabled(False)
self.action_menu_FEL2_shutter.setEnabled(True)
else:
self.menuClose_Shutter.setEnabled(False)
# menu SEED trigger
if SEEDTrigger:
self.action_menu_Silent_SEED.setEnabled(True)
else:
self.action_menu_Silent_SEED.setEnabled(False)
# update time to go
self.timeToGo.setPlainText(timeToGo)
# update fermi status - beamto main indicator
self.setBooleanColor(self.label_gun, self.BST.fstatus.getAttrValue('beamto_gun'))
self.setBooleanColor(self.label_linac, self.BST.fstatus.getAttrValue('beamto_linac'))
self.label_opmode.setText(opMode)
if opMode == 'FEL01':
self.setStringBooleanColor(self.label_fel1, self.BST.fstatus.getAttrValue('beamto_fel1'),'FEL 1')
elif opMode == 'FEL02':
self.setStringBooleanColor(self.label_fel1, self.BST.fstatus.getAttrValue('beamto_fel2'), 'FEL 2')
else:
self.setStringBooleanColor(self.label_fel1, False, 'FEL')
self.setBooleanColor(self.label_PADRES, self.BST.fstatus.getAttrValue('beamto_padres'))
#self.setBooleanColor(self.label_lines, self.BST.fstatus.getAttrValue('beamto_lines'))
# update fermi status - beamto detail indicators
self.setStringBooleanColor(self.mscr_gun, self.BST.fstatus.getAttrValue('z_internal_gun_multiscreen'),'')
self.setStringBooleanColor(self.vlv_gun, self.BST.fstatus.getAttrValue('z_internal_gun_valves'), '')
self.setStringBooleanColor(self.mscr_linac, self.BST.fstatus.getAttrValue('z_internal_linac_multiscreen'), '')
self.setStringBooleanColor(self.vlv_linac, self.BST.fstatus.getAttrValue('z_internal_linac_valves'), '')
if opMode== 'FEL01':
self.setStringBooleanColor(self.mscr_fel, self.BST.fstatus.getAttrValue('z_internal_fel1_multiscreen'), '')
self.setStringBooleanColor(self.vlv_fel, self.BST.fstatus.getAttrValue('z_internal_fel1_valves'), '')
self.setStringBooleanColor(self.bst_fel, self.BST.fstatus.getAttrValue('z_internal_fel1_bst'), '')
self.setStringBooleanColor(self.vlv_padres, self.BST.fstatus.getAttrValue('z_internal_padres1_valves'), '')
self.setStringBooleanColor(self.shut_padres, self.BST.fstatus.getAttrValue('z_internal_padres1_shutter'), '')
elif opMode == 'FEL02':
self.setStringBooleanColor(self.vlv_fel, self.BST.fstatus.getAttrValue('z_internal_fel2_valves'), '')
self.setStringBooleanColor(self.bst_fel, self.BST.fstatus.getAttrValue('z_internal_fel2_bst'), '')
self.setStringBooleanColor(self.vlv_padres, self.BST.fstatus.getAttrValue('z_internal_padres2_valves'), '')
self.setStringBooleanColor(self.shut_padres, self.BST.fstatus.getAttrValue('z_internal_padres2_shutter'), '')
#TODO : opMode == BC01
else:
self.setStringBooleanColor(self.mscr_fel, False, '---')
self.setStringBooleanColor(self.vlv_fel, False, '---')
self.setStringBooleanColor(self.bst_fel, False, '---')
self.setStringBooleanColor(self.vlv_padres, False, '---')
self.setStringBooleanColor(self.shut_padres, False, '---')
#update terafermistatus
instru = self.BST.terafermistatus.getAttrValue('Instrument')
if instru == 'OffBeam':
self.setStringBooleanColor(self.label_tf,True,'TeraFermi ON')
else:
self.setStringBooleanColor(self.label_tf,False,'TeraFermi OFF')
@staticmethod
def stateForFEL(stateStopper, stateShutter):
if stateStopper == 'CLOSED':
return 'CLOSED'
elif stateShutter == 'CLOSED' or stateShutter == 'CLOSE':
return 'SHUTTER'
else:
return 'OPEN'
@staticmethod
def boolToState(status):
if status:
return 'OPEN'
else:
return 'CLOSED'
@staticmethod
def setStateStringEnableColor(guiElement, state, changeString=False, enabled=True):
if state == 'OPEN' or state == 'ON':
guiElement.setStyleSheet("background-color: #00ff00")
elif state == 'CLOSE' or state == 'CLOSED':
guiElement.setStyleSheet("background-color: #ff0000")
elif state == 'SHUTTER' or state == 'STANDBY':
guiElement.setStyleSheet("background-color: yellow")
else:
guiElement.setStyleSheet("background-color: None")
if changeString:
guiElement.setText(state)
guiElement.setEnabled(enabled)
@staticmethod
def setBooleanColor(guiElement, value, is_valid=True):
if is_valid:
if value:
guiElement.setStyleSheet("background-color: #00ff00")
else:
guiElement.setStyleSheet("background-color: #ff0000")
else:
guiElement.setStyleSheet("background-color: None")
@staticmethod
def setStringBooleanColor(guiElement, value, message ,is_valid=True):
if is_valid:
guiElement.setText(message)
if value:
guiElement.setStyleSheet("background-color: #00ff00")
else:
guiElement.setStyleSheet("background-color: #ff0000")
else:
guiElement.setText('##')
guiElement.setStyleSheet("background-color: None")
class Executor(QtCore.QThread):
def __init__(self, funct, parent = None):
super(Executor, self).__init__(parent)
self.function = funct
def run(self):
# print("Running")
self.function()
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
This diff is collapsed.
This diff is collapsed.
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment