initial version

This commit is contained in:
Grzegorz Kowalski 2020-11-30 20:57:22 +01:00
parent fcb3c40b48
commit 5a38f67e60
16 changed files with 4038 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.pyc

14
config/solaris.json Normal file
View File

@ -0,0 +1,14 @@
{
"devices": {
"TS": "testing/libera-brilliance/raf4",
"EVG": "R1-SGD/CTL/R1-SGDCAB10-CTL-EVG1"
},
"units": {
},
"settings": {
"x": "TS",
"y": "TS",
"global_orbit": "TS",
"global_magnet": "TS"
}
}

56
errorhook.py Normal file
View File

@ -0,0 +1,56 @@
# Adapted from http://timlehr.com/python-exception-hooks-with-qt-message-box/
import sys
import traceback
from PyQt4 import QtCore, QtGui
def show_exception_box(log_msg):
"""
Checks if a QApplication instance is available and shows a messagebox with the exception message
If unavailable (non-console application), log an additional notice.
"""
print "[ERROR]: An unexpected error occured: %s" % log_msg
if QtGui.QApplication.instance() is not None:
QtGui.QMessageBox.critical(
None,
"FOFB: Unexpected error",
"""
<b>An unexpected error occured:</b>
<br>
<br>
%s
""" % log_msg.replace("\n", "<br>")
)
class UncaughtHook(QtCore.QObject):
_exception_caught = QtCore.Signal(object)
def __init__(self, *args, **kwargs):
super(UncaughtHook, self).__init__(*args, **kwargs)
# this registers the exception_hook() function as hook with the Python interpreter
sys.excepthook = self.exception_hook
# connect signal to execute the message box function always on main thread
self._exception_caught.connect(show_exception_box)
def exception_hook(self, exc_type, exc_value, exc_traceback):
"""Function handling uncaught exceptions.
It is triggered each time an uncaught exception occurs.
"""
if issubclass(exc_type, KeyboardInterrupt):
# ignore keyboard interrupt to support console applications
sys.__excepthook__(exc_type, exc_value, exc_traceback)
else:
exc_info = (exc_type, exc_value, exc_traceback)
log_msg = "\n".join([
"".join(traceback.format_tb(exc_traceback)),
"%s: %s" % (exc_type.__name__, exc_value)
])
# trigger message box show
self._exception_caught.emit(log_msg)
# create a global instance of our class to register the hook
qt_exception_hook = UncaughtHook()

38
fofbcontrol Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env python2.7
import os
import sys
from signal import signal, SIGINT, SIG_DFL
from subprocess import check_output
from PyQt4.QtGui import QApplication
# from splash import SplashScreen
from mainwindow import MainWindow
# import errorhook # noqa - this only needs to register an exception hook
if __name__ == "__main__":
signal(SIGINT, SIG_DFL)
base_dir = os.path.dirname(os.path.realpath(__file__))
version = check_output(["git", "describe", "--tags", "--always"])[:-1]
app = QApplication([])
offline = False
# first - create the main window
window = MainWindow(offline=offline)
window.setVersion(version)
window.show()
# then - show the splash screen
# splash = SplashScreen(window)
# splash.setVersion(version)
# and finally start the main window
if len(sys.argv) >= 2:
window.start(sys.argv[1])
else:
window.start("%s/config/solaris.json" % base_dir)
sys.exit(app.exec_())

88
grouping.py Normal file
View File

@ -0,0 +1,88 @@
import os
from PyQt4 import QtGui, QtCore, uic
from labels import cm
base_dir = os.path.dirname(os.path.realpath(__file__))
class GroupingWindow(QtGui.QWidget):
def __init__(self, main_window, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi("%s/ui/grouping.ui" % base_dir, self)
self.main_window = main_window
self.units = self.main_window.units
self.addAttribute = lambda dev, attr: self.main_window.addAttribute(dev, attr)
self.list_layout = QtGui.QVBoxLayout()
self.ContentFrame.setLayout(self.list_layout)
self.liberas = {}
def addLibera(self, dev):
print "[ INFO]: grouping: add Libera %s" % dev
libera = GroupingWidget(self.main_window, dev)
self.connect(self, QtCore.SIGNAL("update"), libera.update)
self.liberas[dev] = libera
self.list_layout.addWidget(libera)
def addGlobal(self, orbit, magnet):
print "[ INFO]: grouping: global: orbit %s; magnet %s" % (orbit, magnet)
w = GlobalWidget(self.main_window, orbit, magnet)
self.connect(self, QtCore.SIGNAL("update"), w.update)
self.list_layout.addWidget(w)
def update(self, cache):
self.emit(QtCore.SIGNAL("update"), cache)
def showEvent(self, evt):
self.emit(QtCore.SIGNAL("show"))
evt.accept()
def hideEvent(self, evt):
self.emit(QtCore.SIGNAL("hide"))
evt.accept()
class GroupingWidget(QtGui.QWidget):
def __init__(self, main_window, device, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi("%s/ui/groupingwidget.ui" % base_dir, self)
self.main_window = main_window
self.units = self.main_window.units
self.addAttribute = lambda dev, attr: self.main_window.addAttribute(dev, attr)
self.device = device
self.IDLabel.setText(device)
self.SFP3StatusLabel.setModel(device, "GdxSFP3Status")
self.SFP4StatusLabel.setModel(device, "GdxSFP4Status")
def update(self, cache):
self.emit(QtCore.SIGNAL("update"), cache)
class GlobalWidget(QtGui.QWidget):
def __init__(self, main_window, orbit, magnet, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi("%s/ui/globalwidget.ui" % base_dir, self)
self.main_window = main_window
self.units = self.main_window.units
self.addAttribute = lambda dev, attr: self.main_window.addAttribute(dev, attr)
self.orbit = orbit
self.magnet = magnet
self.GlobalOrbitIDLabel.setText(orbit)
self.GlobalOrbitStateLabel.setModel(orbit, "GdxOrbitStatus")
self.GlobalOrbitStateLabel.setColorMap(cm.GREEN_BOOL)
self.GlobalMagnetIDLabel.setText(magnet)
self.GlobalMagnetStateLabel.setModel(orbit, "GdxMagnetStatus")
self.GlobalMagnetStateLabel.setColorMap(cm.GREEN_BOOL)
def update(self, cache):
self.emit(QtCore.SIGNAL("update"), cache)

218
labels.py Normal file
View File

@ -0,0 +1,218 @@
from PyQt4 import QtGui, QtCore
from tango import DevState
class cm:
FOFB_STATE = {
1: "#000000",
2: "#7CFC00",
4: "#FFFF00"
}
RED_BOOL = {
0: "#000000",
1: "#FF0000"
}
GREEN_BOOL = {
0: "#000000",
1: "#7CFC00"
}
SER_OFF = {
0: "#FF0000",
1: "#000000",
2: "#000000"
}
SER_MANUAL = {
0: "#000000",
1: "#000000",
2: "#FF8C00"
}
SER_FOFB = {
0: "#000000",
1: "#7CFC00",
2: "#000000"
}
class TangoLabel(QtGui.QLabel):
def __init__(self, parent=None):
QtGui.QLabel.__init__(self, parent)
self.device = None
self.attr = None
def setModel(self, device, attr):
self.window().addAttribute(device, attr)
self.device = device
self.attr = attr
# force the color of the tooltip text
if self.toolTip():
self.setToolTip("<font color=\"black\">%s<br><br>%s/%s</font>" % (self.toolTip(), device, attr))
else:
self.setToolTip("<font color=\"black\">%s/%s</font>" % (device, attr))
self.connect(self.window(), QtCore.SIGNAL("update"), self.update)
def update(self, cache):
value = cache[self.device][self.attr]
if value is None:
value = float("-inf")
try:
fmt = self.window().units[self.device][self.attr]["format"]
except (KeyError, TypeError):
fmt = "%d"
try:
unit = self.window().units[self.device][self.attr]["unit"]
except (KeyError, TypeError):
unit = None
value = fmt % value
if unit is not None:
value = "%s %s" % (value, unit)
self.setText(value)
class StateLabel(TangoLabel):
ColorMap = {
DevState.ON: "#7CFC00",
DevState.OFF: "#FFFFFF",
DevState.CLOSE: "#FFFFFF",
DevState.OPEN: "#7CFC00",
DevState.INSERT: "#FFFFFF",
DevState.EXTRACT: "#7CFC00",
DevState.MOVING: "#80A0FF",
DevState.STANDBY: "#FFFF00",
DevState.FAULT: "#FF0000",
DevState.INIT: "#CCCC7A",
DevState.RUNNING: "#80A0FF",
DevState.ALARM: "#FF8C00",
DevState.DISABLE: "#FF00FF",
DevState.UNKNOWN: "#808080"
}
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
def setModel(self, device, attr="State"):
TangoLabel.setModel(self, device, attr)
def update(self, cache):
state = cache[self.device][self.attr]
if state is None:
state = DevState.UNKNOWN
self.setStyleSheet("color: %s" % self.ColorMap[state])
class BeamLabel(TangoLabel):
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
def update(self, cache):
value = cache[self.device][self.attr]
if value > 0:
self.setStyleSheet("background-color: yellow")
else:
self.setStyleSheet("background-color: gray")
class OperationLabel(QtGui.QLabel):
ColorMap = {
"on": "#7CFC00",
"off": "#000000",
"manual": "#FFA500",
"skipped": "#ADD8E6",
"fault": "#FF0000"
}
def __init__(self, parent=None):
QtGui.QLabel.__init__(self, parent)
def setState(self, state):
self.setStyleSheet("color: %s" % self.ColorMap[state])
class BstLabel(TangoLabel):
ColorMap = {
"Status: OPEN": "#7CFC00",
"Status: UNKNOWN": "#80A0FF",
"STATUS: UNKNOWN": "#80A0FF",
"Status: CLOSED": "#FFFFFF",
None: "#808080"
}
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
def update(self, cache):
state = cache[self.device][self.attr]
self.setStyleSheet("color: %s" % self.ColorMap[state])
class BooleanLabel(TangoLabel):
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
self.true_color = "#7CFC00"
self.false_color = "#000000"
def setColors(self, true_color, false_color):
self.true_color = true_color
self.false_color = false_color
def update(self, cache):
if cache[self.device][self.attr]:
self.setStyleSheet("color: %s" % self.true_color)
else:
self.setStyleSheet("color: %s" % self.false_color)
class InterlockLabel(TangoLabel):
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
def update(self, cache):
if cache[self.device][self.attr]:
self.setStyleSheet("background:red; color:white")
else:
self.setStyleSheet("")
class ArrayElementLabel(TangoLabel):
ColorMap = {
0: "#000000",
1: "#7CFC00"
}
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
def setModel(self, device, attr, i):
self.i = i
TangoLabel.setModel(self, device, attr)
def setColorMap(self, cm):
self.ColorMap = cm
def update(self, cache):
value = cache[self.device][self.attr][self.i]
self.setStyleSheet("color: %s" % self.ColorMap[value])
class EnumStateLabel(TangoLabel):
ColorMap = {
0: "#000000",
1: "#7CFC00"
}
def __init__(self, parent=None):
TangoLabel.__init__(self, parent)
def setColorMap(self, cm):
self.ColorMap = cm
def update(self, cache):
value = cache[self.device][self.attr]
self.setStyleSheet("color: %s" % self.ColorMap[value])

9
magic_numbers.py Normal file
View File

@ -0,0 +1,9 @@
MASTER_TIMER = 1000
IREG_EXECUTE = 238
class EventID:
FOFB_OFF = 100
FOFB_ON = 101
FOFB_STANDBY = 102
UPDATE_DOUBLE_BUFFERS = 103

259
mainwindow.py Normal file
View File

@ -0,0 +1,259 @@
import os
import json
from time import time, sleep
from PyQt4 import QtGui, QtCore, uic
import tango
import magic_numbers
from labels import cm
from threads import ThreadWrapper
from grouping import GroupingWindow
from seroutput import SERWindow
base_dir = os.path.dirname(os.path.realpath(__file__))
class MainWindow(QtGui.QWidget):
def __init__(self, offline=False, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi("%s/ui/main.ui" % base_dir, self)
self.offline = offline
self.devices = {}
self.units = None
self.cache = {}
self.virtual = {
"delay": 0,
"avg_delay": 0,
"_delay_sum": 0,
"_delay_n": 0
}
self.grouping = GroupingWindow(self)
self.ser_output = SERWindow(self)
self.connect(self.FOFBONButton, QtCore.SIGNAL("clicked()"),
lambda: self.send_tim_event("EVG", magic_numbers.EventID.FOFB_ON)
)
self.connect(self.FOFBOFFButton, QtCore.SIGNAL("clicked()"),
lambda: self.send_tim_event("EVG", magic_numbers.EventID.FOFB_OFF)
)
self.connect(self.FOFBStandbyButton, QtCore.SIGNAL("clicked()"),
lambda: self.send_tim_event("EVG", magic_numbers.EventID.FOFB_STANDBY)
)
self.connect(self.SwitchBuffersButton, QtCore.SIGNAL("clicked()"),
lambda: self.send_tim_event("EVG", magic_numbers.EventID.UPDATE_DOUBLE_BUFFERS)
)
self.connect(self.SendEventButton, QtCore.SIGNAL("clicked()"),
lambda: self.send_tim_event("EVG", self.EventSpinBox.value())
)
self.connect(self.GroupingButton, QtCore.SIGNAL("clicked()"), self.grouping.show)
self.connect(self.SERButton, QtCore.SIGNAL("clicked()"), self.ser_output.show)
self.connect(self.XInterlockResetButton, QtCore.SIGNAL("clicked()"),
lambda: self.execute_ireg_command_on_axis("x", "GdxFOFBIlkReset")
)
self.connect(self.XReconnectButton, QtCore.SIGNAL("clicked()"),
lambda: self.execute_ireg_command_on_axis("x", "GdxFOFBReconnect")
)
self.connect(self.XResetPIButton, QtCore.SIGNAL("clicked()"),
lambda: self.execute_ireg_command_on_axis("x", "GdxFOFBPIReset")
)
self.connect(self.XSaturationResetButton, QtCore.SIGNAL("clicked()"),
lambda: self.execute_ireg_command_on_axis("x", "GdxFOFBSaturationReset")
)
# self.connect(self.YInterlockResetButton, QtCore.SIGNAL("clicked()"),
# lambda: self.execute_ireg_command_on_axis("y", "GdxFOFBIlkReset")
# )
# self.connect(self.YReconnectButton, QtCore.SIGNAL("clicked()"),
# lambda: self.execute_ireg_command_on_axis("y", "GdxFOFBReconnect")
# )
# self.connect(self.YResetPIButton, QtCore.SIGNAL("clicked()"),
# lambda: self.execute_ireg_command_on_axis("y", "GdxFOFBPIReset")
# )
# self.connect(self.YSaturationResetButton, QtCore.SIGNAL("clicked()"),
# lambda: self.execute_ireg_command_on_axis("y", "GdxFOFBSaturationReset")
# )
self.update_timer = QtCore.QTimer()
self.connect(self.update_timer, QtCore.SIGNAL("timeout()"), self.update)
self.connect(self, QtCore.SIGNAL("update"), self.grouping.update)
self.connect(self, QtCore.SIGNAL("update"), self.ser_output.update)
self.connect(self, QtCore.SIGNAL("loadingdone"), self.loading_done)
self.connect(self, QtCore.SIGNAL("update"), self.update_virtual_in_gui)
def setModel(self):
self.EVGStateLabel.setModel("EVG")
self.XStateLabel.setModel(self.settings["x"])
self.XInterlockLabel.setModel(self.settings["x"], "GdxFOFBIlk")
self.XIDLabel.setText(self.settings["x"])
self.XFOFBStateLabel.setModel(self.settings["x"], "GdxFOFBState")
self.XFOFBStateLabel.setColorMap(cm.FOFB_STATE)
# self.XBuffersLabel.setModel()
self.XS1Label.setModel(self.settings["x"], "GdxFOFBSaturation", 0)
self.XS1Label.setColorMap(cm.RED_BOOL)
self.XS2Label.setModel(self.settings["x"], "GdxFOFBSaturation", 1)
self.XS2Label.setColorMap(cm.RED_BOOL)
self.XS3Label.setModel(self.settings["x"], "GdxFOFBSaturation", 2)
self.XS3Label.setColorMap(cm.RED_BOOL)
self.XS4Label.setModel(self.settings["x"], "GdxFOFBSaturation", 3)
self.XS4Label.setColorMap(cm.RED_BOOL)
# self.YStateLabel.setModel(self.settings["y"])
# self.YInterlockLabel.setModel(self.settings["y"], "GdxFOFBIlk")
# self.YIDLabel.setText(self.settings["y"])
# self.YFOFBStateLabel.setModel(self.settings["y"], "GdxFOFBState")
# self.YFOFBStateLabel.setColorMap(cm.FOFB_STATE)
# # self.XBuffersLabel.setModel()
# self.YS1Label.setModel(self.settings["y"], "GdxFOFBSaturation", 0)
# self.YS1Label.setColorMap(cm.RED_BOOL)
# self.YS2Label.setModel(self.settings["y"], "GdxFOFBSaturation", 1)
# self.YS2Label.setColorMap(cm.RED_BOOL)
# self.YS3Label.setModel(self.settings["y"], "GdxFOFBSaturation", 2)
# self.YS3Label.setColorMap(cm.RED_BOOL)
# self.YS4Label.setModel(self.settings["y"], "GdxFOFBSaturation", 3)
# self.YS4Label.setColorMap(cm.RED_BOOL)
def start(self, fn, config=None):
ThreadWrapper(self.load, args=(fn, config)).start()
def loading_done(self):
# show all startup windows
self.show()
# fill grouping and magnets
for dev in self.devices.keys():
if dev.upper() != "EVG":
self.grouping.addLibera(dev)
self.ser_output.addLibera(dev)
self.grouping.addGlobal(self.settings["global_orbit"], self.settings["global_magnet"])
# start updates
self.update_timer.start(magic_numbers.MASTER_TIMER)
def closeEvent(self, evt):
self.grouping.close()
self.ser_output.close()
evt.accept()
def setVersion(self, version):
self.VersionLabel.setText("v.%s" % version)
def load(self, fn, cfg=None):
if fn:
with open(fn) as f:
conf = json.load(f)
else:
conf = json.loads(cfg)
for label, dev in conf["devices"].iteritems():
self.addDevice(label, dev)
self.units = conf["units"]
self.settings = conf["settings"]
self.setModel()
self.applySettings()
self.emit(QtCore.SIGNAL("loadingdone"))
def addDevice(self, label, dev):
self.emit(QtCore.SIGNAL("loadstatus"), "Loading %s = %s" % (label, dev))
if not self.offline:
self.devices[label] = tango.DeviceProxy(dev)
if label not in self.cache:
self.cache[label] = {}
def applySettings(self):
pass
def addAttribute(self, dev, attr):
self.emit(QtCore.SIGNAL("loadstatus"), "Add attribute %s of device %s" % (attr, dev))
if dev not in self.cache:
self.cache[dev] = {}
self.cache[dev][attr] = None
def update(self):
print "[ INFO]: update"
try:
start = time()
threads = {}
for dev, attrs in self.cache.iteritems():
threads[dev] = {}
for attr in attrs.keys():
threads[dev][attr] = ThreadWrapper(self.read_attribute, args=(dev, attr))
threads[dev][attr].start()
for dev, attrs in self.cache.iteritems():
for attr in attrs.keys():
threads[dev][attr].join()
self.cache[dev][attr] = threads[dev][attr].result
self.update_virtual(time() - start)
except Exception as e:
print "[ERROR]: update failed: %s" % str(e)
self.emit(QtCore.SIGNAL("update"), self.cache)
def read_attribute(self, dev, attr):
try:
value = self.devices[dev].read_attribute(attr).value
if type(value) in (int, float):
try:
conv = self.units[dev][attr]["conversion"]
except (KeyError, TypeError):
conv = 1
value = value * conv
# special case for machine state attribute
if dev == "statemachine" and attr == "MachineState":
if not value:
value = "UNKNOWN !!!"
return value
except Exception as e:
print "[ERROR]: could not read attribute %s of device %s: %s" % (attr, dev, str(e))
return None
def update_virtual(self, fetch_time):
self.virtual["delay"] = fetch_time * 1000.0 # convert to ms
self.virtual["_delay_sum"] += self.virtual["delay"]
self.virtual["_delay_n"] += 1
self.virtual["avg_delay"] = self.virtual["_delay_sum"] / self.virtual["_delay_n"]
def update_virtual_in_gui(self):
# This whole thing is a big, big technical debt
self.DelayLabel.setText("%.02f ms" % self.virtual["delay"])
if self.virtual["delay"] > magic_numbers.MASTER_TIMER:
style = "background:red; color:white"
elif self.virtual["delay"] > magic_numbers.MASTER_TIMER / 2.0:
style = "background:orange; color:white"
else:
style = ""
self.DelayLabel.setStyleSheet(style)
self.AvgDelayLabel.setText("avg: %.02f ms" % self.virtual["avg_delay"])
if self.virtual["avg_delay"] > magic_numbers.MASTER_TIMER:
style = "background:red; color:white"
elif self.virtual["avg_delay"] > magic_numbers.MASTER_TIMER / 2.0:
style = "background:orange; color:white"
else:
style = ""
self.AvgDelayLabel.setStyleSheet(style)
def execute_ireg_command(self, dev, cmd):
try:
print "[ INFO]: ireg_execute %s/%s" % (dev, cmd)
self.devices[dev].write_attribute(cmd, magic_numbers.IREG_EXECUTE)
except Exception as e:
print str(e)
def execute_ireg_command_on_axis(self, axis, cmd):
self.execute_ireg_command(self.settings[axis], cmd)
def send_tim_event(self, dev, evt):
print "[ INFO]: sw event %s/%d" % (dev, evt)
self.devices[dev].SendSoftwareEvent(evt)

100
seroutput.py Normal file
View File

@ -0,0 +1,100 @@
import os
from PyQt4 import QtGui, QtCore, uic
from labels import cm
base_dir = os.path.dirname(os.path.realpath(__file__))
class SERWindow(QtGui.QWidget):
def __init__(self, main_window, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi("%s/ui/ser.ui" % base_dir, self)
self.main_window = main_window
self.units = self.main_window.units
self.addAttribute = lambda dev, attr: self.main_window.addAttribute(dev, attr)
self.list_layout = QtGui.QVBoxLayout()
self.ContentFrame.setLayout(self.list_layout)
self.liberas = {}
def addLibera(self, dev):
print "[ INFO]: SER: add Libera %s" % dev
libera = SERWidget(self.main_window, dev)
self.connect(self, QtCore.SIGNAL("update"), libera.update)
self.liberas[dev] = libera
self.list_layout.addWidget(libera)
def update(self, cache):
self.emit(QtCore.SIGNAL("update"), cache)
def showEvent(self, evt):
self.emit(QtCore.SIGNAL("show"))
evt.accept()
def hideEvent(self, evt):
self.emit(QtCore.SIGNAL("hide"))
evt.accept()
class SERWidget(QtGui.QWidget):
def __init__(self, main_window, device, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi("%s/ui/serwidget.ui" % base_dir, self)
self.main_window = main_window
self.units = self.main_window.units
self.addAttribute = lambda dev, attr: self.main_window.addAttribute(dev, attr)
self.device = device
self.IDLabel.setText(device)
self.M1IDLabel.setModel(device, "GdxSERM1Id")
self.M1OffLabel.setModel(device, "GdxSERM1Output")
self.M1OffLabel.setColorMap(cm.SER_OFF)
self.M1ManualLabel.setModel(device, "GdxSERM1Output")
self.M1ManualLabel.setColorMap(cm.SER_MANUAL)
self.M1FOFBLabel.setModel(device, "GdxSERM1Output")
self.M1FOFBLabel.setColorMap(cm.SER_FOFB)
self.M1FOFBValueLabel.setModel(device, "GdxSERM1FOFB")
self.M2IDLabel.setModel(device, "GdxSERM2Id")
self.M2OffLabel.setModel(device, "GdxSERM2Output")
self.M2OffLabel.setColorMap(cm.SER_OFF)
self.M2ManualLabel.setModel(device, "GdxSERM2Output")
self.M2ManualLabel.setColorMap(cm.SER_MANUAL)
self.M2FOFBLabel.setModel(device, "GdxSERM2Output")
self.M2FOFBLabel.setColorMap(cm.SER_FOFB)
self.M2FOFBValueLabel.setModel(device, "GdxSERM2FOFB")
self.M3IDLabel.setModel(device, "GdxSERM3Id")
self.M3OffLabel.setModel(device, "GdxSERM3Output")
self.M3OffLabel.setColorMap(cm.SER_OFF)
self.M3ManualLabel.setModel(device, "GdxSERM3Output")
self.M3ManualLabel.setColorMap(cm.SER_MANUAL)
self.M3FOFBLabel.setModel(device, "GdxSERM3Output")
self.M3FOFBLabel.setColorMap(cm.SER_FOFB)
self.M3FOFBValueLabel.setModel(device, "GdxSERM3FOFB")
self.M4IDLabel.setModel(device, "GdxSERM4Id")
self.M4OffLabel.setModel(device, "GdxSERM4Output")
self.M4OffLabel.setColorMap(cm.SER_OFF)
self.M4ManualLabel.setModel(device, "GdxSERM4Output")
self.M4ManualLabel.setColorMap(cm.SER_MANUAL)
self.M4FOFBLabel.setModel(device, "GdxSERM4Output")
self.M4FOFBLabel.setColorMap(cm.SER_FOFB)
self.M4FOFBValueLabel.setModel(device, "GdxSERM4FOFB")
def update(self, cache):
self.emit(QtCore.SIGNAL("update"), cache)
# def showEvent(self, evt):
# self.emit(QtCore.SIGNAL("show"))
# evt.accept()
# def hideEvent(self, evt):
# self.emit(QtCore.SIGNAL("hide"))
# evt.accept()

19
threads.py Normal file
View File

@ -0,0 +1,19 @@
from threading import Thread
class ThreadWrapper(Thread):
""" A thread you can get the result value from """
def __init__(self, target, args=(), kwargs={}):
Thread.__init__(self)
self.target = target
self.args = args
self.kwargs = kwargs
self.result = None
self.error = None
def run(self):
try:
self.result = self.target(*self.args, **self.kwargs)
except Exception as e:
self.error = e

254
ui/globalwidget.ui Normal file
View File

@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>349</width>
<height>52</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>1</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item row="1" column="4">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="7">
<widget class="QLabel" name="GlobalMagnetIDLabel">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="6">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="6" colspan="5">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Global magnet</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="GlobalOrbitResetButton">
<property name="maximumSize">
<size>
<width>45</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="1" column="10">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Global orbit</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="EnumStateLabel" name="GlobalMagnetStateLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="GlobalOrbitIDLabel">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="5">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2">
<widget class="EnumStateLabel" name="GlobalOrbitStateLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="9">
<widget class="QPushButton" name="GlobaMagnetResetButton">
<property name="maximumSize">
<size>
<width>45</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>EnumStateLabel</class>
<extends>QLabel</extends>
<header>labels</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

94
ui/grouping.ui Normal file
View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>395</width>
<height>699</height>
</rect>
</property>
<property name="windowTitle">
<string>FOFB: Libera Grouping</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Grouping timeout</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="WarningLabel">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:orange</string>
</property>
<property name="text">
<string>⚠</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="TimeoutSpinBox">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="5">
<widget class="QFrame" name="ContentFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

498
ui/groupingwidget.ui Normal file
View File

@ -0,0 +1,498 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>351</width>
<height>45</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QLabel" name="IDLabel">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="OperationLabel" name="MovePlungersLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_4">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_5">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_6">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="TangoLabel" name="SFP3StatusLabel">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ClearSFP3Button">
<property name="maximumSize">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_7">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_8">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_9">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_10">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_11">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="OperationLabel" name="MovePlungersLabel_12">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="TangoLabel" name="SFP4StatusLabel">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ClearSFP4Button">
<property name="maximumSize">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>OperationLabel</class>
<extends>QLabel</extends>
<header>labels</header>
</customwidget>
<customwidget>
<class>TangoLabel</class>
<extends>QLabel</extends>
<header>labels</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

1467
ui/main.ui Normal file

File diff suppressed because it is too large Load Diff

31
ui/ser.ui Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>622</width>
<height>691</height>
</rect>
</property>
<property name="windowTitle">
<string>FOFB: Local magnet output</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QFrame" name="ContentFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

892
ui/serwidget.ui Normal file
View File

@ -0,0 +1,892 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>573</width>
<height>49</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>79</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QLabel" name="IDLabel">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>M1</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="TangoLabel" name="M1IDLabel">
<property name="toolTip">
<string>Magnet ID</string>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="EnumStateLabel" name="M1OffLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: OFF</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M1ManualLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: MANUAL</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M1FOFBLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: FOFB</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="TangoLabel" name="M1FOFBValueLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="toolTip">
<string>FOFB value</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="M1ManualSpinBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Manual value</string>
</property>
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
<property name="value">
<number>-32768</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>M2</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="TangoLabel" name="M2IDLabel">
<property name="toolTip">
<string>Magnet ID</string>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="EnumStateLabel" name="M2OffLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: OFF</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M2ManualLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: MANUAL</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M2FOFBLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: FOFB</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="TangoLabel" name="M2FOFBValueLabel">
<property name="toolTip">
<string>FOFB value</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="M2ManualSpinBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Manual value</string>
</property>
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
<property name="value">
<number>-32768</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_9">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QLabel" name="label_8">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>M3</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="TangoLabel" name="M3IDLabel">
<property name="toolTip">
<string>Magnet ID</string>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="EnumStateLabel" name="M3OffLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: OFF</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M3ManualLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: MANUAL</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M3FOFBLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: FOFB</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="TangoLabel" name="M3FOFBValueLabel">
<property name="toolTip">
<string>FOFB value</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="M3ManualSpinBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Manual value</string>
</property>
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
<property name="value">
<number>-32768</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::VLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_15">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QLabel" name="label_12">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>M4</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="TangoLabel" name="M4IDLabel">
<property name="toolTip">
<string>Magnet ID</string>
</property>
<property name="text">
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_13">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="EnumStateLabel" name="M4OffLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: OFF</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M4ManualLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: MANUAL</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="EnumStateLabel" name="M4FOFBLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>15</height>
</size>
</property>
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string>Output: FOFB</string>
</property>
<property name="text">
<string>∙</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_14">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="TangoLabel" name="M4FOFBValueLabel">
<property name="toolTip">
<string>FOFB value</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="M4ManualSpinBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Manual value</string>
</property>
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
<property name="value">
<number>-32768</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>EnumStateLabel</class>
<extends>QLabel</extends>
<header>labels</header>
</customwidget>
<customwidget>
<class>TangoLabel</class>
<extends>QLabel</extends>
<header>labels</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>