"""Custom widgets."""
from functools import partial as _part
import numpy as _np
from qtpy.QtCore import Qt, Slot, QTimer
from qtpy.QtGui import QColor, QPalette, QIcon
from qtpy.QtWidgets import QComboBox, QSizePolicy as QSzPlcy, \
QLabel, QGridLayout, QWidget, QHBoxLayout, QPushButton, \
QVBoxLayout, QTabWidget, QCheckBox, QScrollArea, QMessageBox
import qtawesome as qta
from matplotlib import cm
from siriuspy.namesys import SiriusPVName as _PVName
from siriuspy.clientconfigdb import ConfigDBClient, ConfigDBException
from siriuspy.devices import Device, FOFBCtrlDCC, FamFOFBControllers
from siriuspy.diagbeam.bpm.csdev import Const as _csbpm
from pydm.widgets import PyDMPushButton
from ..util import connect_window
from ..widgets import SiriusConnectionSignal as _ConnSignal, SiriusLedAlert, \
SiriusDialog, PyDMLedMultiChannel, SiriusLabel, PyDMLed, SiriusLedState, \
CAPushButton
from ..widgets.windows import create_window_from_widget
from ..as_ap_configdb import LoadConfigDialog, SaveConfigDialog
from ..common.afc_acq_core import LogicalTriggers
from ..as_ap_sofb.graphics.base import Graph
from .base import BaseObject, get_fofb_icon
from .graphics import RefOrbViewWidget
[docs]
class StatusDialog(SiriusDialog):
"""Status Detail Dialog."""
def __init__(
self, parent, pvname, labels, cmds, title='', detail_button=None):
super().__init__(parent)
self.setObjectName('SIApp')
self.pvname = _PVName(pvname)
self.labels = labels
self.cmds = cmds
self.title = title
self.detail_button = detail_button
lay = QGridLayout(self)
label = QLabel(
'<h4>'+self.title+'</h4>', self, alignment=Qt.AlignCenter)
lay.addWidget(label, 0, 0, 1, 3)
for idx, desc in enumerate(self.labels):
led = SiriusLedAlert(self, self.pvname, bit=idx)
lbl = QLabel(desc, self)
lay.addWidget(led, idx+1, 0)
lay.addWidget(lbl, idx+1, 1)
if self.cmds[idx]:
btn = PyDMPushButton(
self, icon=qta.icon('fa5s.sync'), pressValue=1,
init_channel=self.cmds[idx])
btn.setDefault(False)
btn.setAutoDefault(False)
btn.setObjectName('btn')
btn.setStyleSheet(
'#btn{min-width:25px; max-width:25px; icon-size:20px;}')
lay.addWidget(btn, idx+1, 2)
if self.detail_button is not None:
lay.addWidget(
self.detail_button, len(self.labels)+1, 1,
alignment=Qt.AlignCenter)
[docs]
class ControllersDetailDialog(BaseObject, SiriusDialog):
"""Controllers detail dialog."""
def __init__(self, parent, device, prefix='', tab_selected=0):
BaseObject.__init__(self, device, prefix)
SiriusDialog.__init__(self, parent)
self.tab_selected = tab_selected
self.setObjectName('SIApp')
self.setWindowTitle('SI - FOFB - Controllers Details Dialog')
self.setWindowIcon(get_fofb_icon())
self.ctrlrs = FOFBCtrlDCC.DEVICES
ctrlr_offset = FamFOFBControllers.FOFBCTRL_BPMID_OFFSET
self.dccnames, self.dccids = list(), list()
for dcc in FOFBCtrlDCC.PROPDEVICES.ALL:
for ctrl in self.ctrlrs:
bid = ctrlr_offset - 1 + int(ctrl[3:5])
self.dccnames.append(ctrl+':'+dcc)
self.dccids.append(bid)
for idx, bpm in enumerate(self._csorb.bpm_names):
self.dccnames.append(bpm+':DCCP2P')
bid = ((idx + 1) // 2) * 2 % 160
self.dccids.append(bid)
self._setupUi()
self._ch_synenls = _ConnSignal(
self.devpref.substitute(propty='CtrlrSyncEnblList-Mon'))
self._ch_synenls.new_value_signal[_np.ndarray].connect(
self._update_dcc_enbllist)
self._ch_synenls.new_value_signal[_np.ndarray].connect(
self._update_refpacketloss)
self.setFocusPolicy(Qt.StrongFocus)
def _setupUi(self):
tab = QTabWidget(self)
tab.setObjectName('SITab')
tab.addTab(self._setupBPMIdsTab(), 'DCC BPM Ids')
tab.addTab(self._setupNetSyncTab(), 'Net Sync Status')
tab.addTab(self._setupLinkPartnerTab(), 'DCC Linked Partners')
tab.addTab(self._setupRefOrbTab(), 'RefOrb Sync Status')
tab.addTab(self._setupTimeFrameLenTab(), 'DCC TimeFrameLen')
tab.addTab(self._setupBPMLogTrigTab(), 'BPM Logical Trigger Configs')
tab.addTab(self._setupOrbDistTab(), 'Orbit Distortion Detection')
tab.addTab(self._setupPacketLossTab(), 'Packet Loss Detection')
tab.addTab(self._setupIntlkTab(), 'Loop Interlock')
tab.addTab(self._setupSYSIDExc(), 'SYSID Excitation States')
tab.setCurrentIndex(self.tab_selected)
lay = QVBoxLayout(self)
lay.addWidget(tab)
self.setStyleSheet('SiriusLabel{qproperty-alignment: AlignCenter;}')
def _setupBPMIdsTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>BPMId</h4>', self, alignment=Qt.AlignCenter), 0, 1)
# table
for idx, dcc in enumerate(self.dccnames):
row = idx + 1
lbl = QLabel(dcc, self, alignment=Qt.AlignCenter)
pvn = _PVName(dcc).substitute(prefix=self.prefix) + 'BPMId-RB'
plb = SiriusLabel(self, pvn)
led = PyDMLedMultiChannel(self, {pvn: self.dccids[idx]})
lay.addWidget(lbl, row, 0)
lay.addWidget(plb, row, 1)
lay.addWidget(led, row, 2)
return self._build_scroll_area(wid)
def _setupNetSyncTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>BPM Count</h4>', self, alignment=Qt.AlignCenter), 0, 1)
lay.addWidget(
QLabel('<h4>Enable</h4>', self, alignment=Qt.AlignCenter), 0, 2)
# table
self.leds_sync, self.leds_dccsts = dict(), dict()
for idx, dcc in enumerate(self.dccnames):
row = idx + 1
lbl = QLabel(dcc, self, alignment=Qt.AlignCenter)
pvn = _PVName(dcc).substitute(prefix=self.prefix) + 'BPMCnt-Mon'
plb = SiriusLabel(self, pvn)
lay.addWidget(lbl, row, 0)
lay.addWidget(plb, row, 1)
pvn = _PVName(dcc).substitute(prefix=self.prefix) + 'CCEnable-Sts'
led = PyDMLed(self, pvn)
led.setObjectName('led_status')
led.shape = led.ShapeMap.Square
if 'FOFBCtrl' in dcc:
led.offColor = led.Red
self.leds_dccsts[dcc] = led
lay.addWidget(led, row, 2, alignment=Qt.AlignTop)
if 'FMC' in dcc:
c2v = {pvn: FOFBCtrlDCC.DEF_FMC_BPMCNT}
led = PyDMLedMultiChannel(self, c2v)
self.leds_sync[dcc] = led
lay.addWidget(led, row, 3)
return self._build_scroll_area(wid)
def _update_dcc_enbllist(self, value):
for dcc, led in self.leds_sync.items():
pvn = _PVName(dcc).substitute(prefix=self.prefix) + 'BPMCnt-Mon'
c2v = {pvn: int(_np.sum(value))}
led.set_channels2values(c2v)
for idx, bpm in enumerate(self._csorb.bpm_names):
led = self.leds_dccsts[bpm+':DCCP2P']
if value[idx]:
led.offColor = led.Red
led.onColor = led.LightGreen
else:
led.offColor = led.DarkGreen
led.onColor = led.Red
def _setupLinkPartnerTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
lpart_pvs = ['BPMId-RB', ] + [
'LinkPartnerCH'+str(idx)+'-Mon' for idx in range(8)]
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
for idx, link in enumerate(lpart_pvs):
col = idx + 1
text = '<h4>' + link.split('-')[0] + '</h4>'
lbl = QLabel(text, self, alignment=Qt.AlignCenter)
lay.addWidget(lbl, 0, col)
# table
row = 1
for dcc in self.dccnames:
lbl = QLabel(dcc, self, alignment=Qt.AlignCenter)
lay.addWidget(lbl, row, 0)
for idx, link in enumerate(lpart_pvs):
col = idx + 1
pvn = _PVName(dcc).substitute(prefix=self.prefix) + link
plb = SiriusLabel(self, pvn)
lay.addWidget(plb, row, col)
row += 1
return self._build_scroll_area(wid)
def _setupRefOrbTab(self):
self._refimpl = {
plane: _np.zeros(2*self._csorb.nr_bpms)
for plane in ['x', 'y']}
self._ch_refx = _ConnSignal(
self.devpref.substitute(propty='RefOrbHwX-Mon'))
self._ch_refx.new_value_signal[_np.ndarray].connect(
_part(self._update_reforb, 'x'))
self._ch_refy = _ConnSignal(
self.devpref.substitute(propty='RefOrbHwY-Mon'))
self._ch_refy.new_value_signal[_np.ndarray].connect(
_part(self._update_reforb, 'y'))
# title
title = QLabel(
'<h4>Reference Orbit [X, Y] in Hardware Units [nm]</h4>', self,
alignment=Qt.AlignCenter)
# graph
self.curve_hlref = dict()
colors = cm.jet(_np.linspace(0, 1, len(self.ctrlrs)))*255
coloros = [QColor(*color) for color in colors]
graph_refs, c2v, visisel = dict(), dict(), dict()
for plane in ['x', 'y']:
graph_refs[plane] = Graph(self)
graph_refs[plane].showLegend = False
graph_refs[plane].setTitle('RefOrb'+plane.upper())
opts = dict(
y_channel='', name='HL RefOrb'+plane.upper(),
color='black', redraw_mode=2,
lineStyle=1, lineWidth=2,
symbol='o', symbolSize=10)
graph_refs[plane].addChannel(**opts)
self.curve_hlref[plane] = graph_refs[plane].curveAtIndex(0)
for ctrl, coloro in zip(self.ctrlrs, coloros):
pvn = _PVName(ctrl).substitute(
prefix=self.prefix, propty='RefOrb'+plane.upper()+'-RB')
c2v[pvn] = self._refimpl[plane]
opts = dict(
y_channel=pvn, name='', color=coloro, redraw_mode=2,
lineStyle=1, lineWidth=2, symbol='o', symbolSize=10)
graph_refs[plane].addChannel(**opts)
curve = graph_refs[plane].curveAtIndex(-1)
if ctrl not in visisel:
cbx = QCheckBox(ctrl[3:5], self)
cbx.setChecked(True)
cbx.setSizePolicy(QSzPlcy.Maximum, QSzPlcy.Maximum)
pal = cbx.palette()
pal.setColor(QPalette.Base, coloro)
pal.setColor(QPalette.Text, Qt.white)
cbx.setPalette(pal)
visisel[ctrl] = cbx
visisel[ctrl].stateChanged.connect(curve.setVisible)
# led
self.led_reforb_c2v = c2v
self.led_ref = PyDMLedMultiChannel(self, c2v)
# curves
lay_sel = QGridLayout()
lay_sel.setContentsMargins(0, 0, 0, 0)
colsel = 2
for idx, cbx in enumerate(visisel.values()):
lay_sel.addWidget(cbx, idx // colsel, idx % colsel)
wid = QWidget()
lay = QGridLayout(wid)
lay.addWidget(title, 0, 0)
lay.addWidget(self.led_ref, 0, 1, alignment=Qt.AlignRight)
for idx, graph in enumerate(graph_refs.values()):
lay.addWidget(graph, idx+1, 0)
lay.addLayout(lay_sel, 1, 1, len(graph_refs), 1)
return wid
def _update_reforb(self, plane, value):
self._refimpl[plane] = value
self.curve_hlref[plane].receiveYWaveform(value)
prop = 'RefOrb'+plane.upper()+'-RB'
self.led_reforb_c2v.update({
_PVName(ctrl).substitute(
prefix=self.prefix, propty=prop): value
for ctrl in self.ctrlrs})
self.led_ref.set_channels2values(self.led_reforb_c2v)
def _setupTimeFrameLenTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>TimeFrameLen</h4>', self, alignment=Qt.AlignCenter),
0, 1)
# table
self._led_timeframelen = dict()
for idx, dcc in enumerate(self.dccnames):
row = idx + 1
lbl = QLabel(dcc, self, alignment=Qt.AlignCenter)
pvn = _PVName(dcc).substitute(prefix=self.prefix)
pvn += 'TimeFrameLen-RB'
plb = SiriusLabel(self, pvn)
led = PyDMLedMultiChannel(self)
self._led_timeframelen[pvn] = led
lay.addWidget(lbl, row, 0)
lay.addWidget(plb, row, 1)
lay.addWidget(led, row, 2)
self._ch_tfl = _ConnSignal(
self.devpref.substitute(propty='TimeFrameLen-RB'))
self._ch_tfl.new_value_signal[int].connect(
self._update_reftimeframelen)
return self._build_scroll_area(wid)
def _update_reftimeframelen(self, value):
for pvn, led in self._led_timeframelen.items():
led.set_channels2values({pvn: value})
def _setupOrbDistTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>Threshold</h4>', self, alignment=Qt.AlignCenter), 0, 1)
lay.addWidget(
QLabel('<h4>Enable</h4>', self, alignment=Qt.AlignCenter), 0, 2)
# table
self.leds_odd = dict()
for idx, ctl in enumerate(self.ctrlrs):
row = idx + 1
c2v = dict()
lbl = QLabel(ctl, self, alignment=Qt.AlignCenter)
pvn = _PVName(ctl).substitute(
prefix=self.prefix, propty='MaxOrbDistortion-RB')
c2v[pvn] = 0
plb = SiriusLabel(self, pvn)
lay.addWidget(lbl, row, 0)
lay.addWidget(plb, row, 1)
pvn = _PVName(ctl).substitute(
prefix=self.prefix, propty='MaxOrbDistortionEnbl-Sts')
c2v[pvn] = 0
led = SiriusLedState(self, pvn)
led.setObjectName('led_status')
led.shape = led.ShapeMap.Square
lay.addWidget(led, row, 2, alignment=Qt.AlignTop)
led = PyDMLedMultiChannel(self, c2v)
self.leds_odd[ctl] = led
lay.addWidget(led, row, 3)
self._ch_odt = _ConnSignal(
self.devpref.substitute(propty='LoopMaxOrbDistortion-RB'))
self._ch_odt.new_value_signal[float].connect(
self._update_reforbdist)
self._ch_odd = _ConnSignal(
self.devpref.substitute(propty='LoopMaxOrbDistortionEnbl-Sts'))
self._ch_odd.new_value_signal[int].connect(
self._update_reforbdist)
return self._build_scroll_area(wid)
def _update_reforbdist(self, _):
odt = self._ch_odt.value
odd = self._ch_odd.value
if odt is None or odd is None:
return
odt = int(odt*self.UM2NM)
for ctl, led in self.leds_odd.items():
pref = _PVName(ctl).substitute(prefix=self.prefix)
c2v = {
pref.substitute(propty='MaxOrbDistortion-RB'): odt,
pref.substitute(propty='MaxOrbDistortionEnbl-Sts'): odd,
}
led.set_channels2values(c2v)
def _setupPacketLossTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>MinBPMCount</h4>', self, alignment=Qt.AlignCenter), 0, 1)
lay.addWidget(
QLabel('<h4>Enable</h4>', self, alignment=Qt.AlignCenter), 0, 2)
# table
self.leds_pld = dict()
for idx, ctl in enumerate(self.ctrlrs):
row = idx + 1
c2v = dict()
lbl = QLabel(ctl, self, alignment=Qt.AlignCenter)
pvn = _PVName(ctl).substitute(
prefix=self.prefix, propty='MinBPMCnt-RB')
c2v[pvn] = 0
plb = SiriusLabel(self, pvn)
lay.addWidget(lbl, row, 0)
lay.addWidget(plb, row, 1)
pvn = _PVName(ctl).substitute(
prefix=self.prefix, propty='MinBPMCntEnbl-Sts')
c2v[pvn] = 0
led = SiriusLedState(self, pvn)
led.setObjectName('led_status')
led.shape = led.ShapeMap.Square
lay.addWidget(led, row, 2, alignment=Qt.AlignTop)
led = PyDMLedMultiChannel(self, c2v)
self.leds_pld[ctl] = led
lay.addWidget(led, row, 3)
self._ch_ple = _ConnSignal(
self.devpref.substitute(propty='LoopPacketLossDetecEnbl-Sts'))
self._ch_ple.new_value_signal[int].connect(
self._update_refpacketloss)
return self._build_scroll_area(wid)
def _update_refpacketloss(self, _):
plc = self._ch_synenls.value
ple = self._ch_ple.value
if plc is None or ple is None:
return
plc = int(_np.sum(plc))
for ctl, led in self.leds_pld.items():
pref = _PVName(ctl).substitute(prefix=self.prefix)
c2v = {
pref.substitute(propty='MinBPMCnt-RB'): plc,
pref.substitute(propty='MinBPMCntEnbl-Sts'): ple,
}
led.set_channels2values(c2v)
def _setupIntlkTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>Interlock</h4>', self, alignment=Qt.AlignCenter), 0, 1)
# table
for idx, dcc in enumerate(self.ctrlrs):
row = idx + 1
lbl = QLabel(dcc, self, alignment=Qt.AlignCenter)
lay.addWidget(lbl, row, 0)
pvn = _PVName(dcc).substitute(
prefix=self.prefix, propty='LoopIntlk-Mon')
led = SiriusLedAlert(self, pvn)
led.setObjectName('led_status')
lay.addWidget(led, row, 1, alignment=Qt.AlignTop)
return self._build_scroll_area(wid)
def _setupBPMLogTrigTab(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
trigid = FamFOFBControllers.BPM_TRIGS_ID
propties = ['RcvSrc-Sts', 'RcvInSel-RB']
# header
devlbl = QLabel('<h4>BPM</h4>', self, alignment=Qt.AlignCenter)
lay.addWidget(devlbl, 0, 0, 2, 1)
text = f'<h4>TRIGGER {trigid}</h4>'
lbl = QLabel(text, self, alignment=Qt.AlignCenter)
lay.addWidget(lbl, 0, 1, 1, 2)
for idx, prop in enumerate(propties):
text = prop.split('-')[0]
lbl = QLabel(text, self, alignment=Qt.AlignCenter)
lay.addWidget(lbl, 1, idx+1)
# table
for idxr, bpm in enumerate(self._csorb.bpm_names):
row = idxr + 2
btn = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self)
btn.setObjectName('btn')
btn.setStyleSheet(
'#btn{min-width:25px; max-width:25px; icon-size:20px;}')
btn.setDefault(False)
btn.setAutoDefault(False)
win = create_window_from_widget(
LogicalTriggers, title=bpm+': ACQ Logical Triggers')
connect_window(
btn, win, parent=self, prefix=self.prefix, device=bpm,
names=_csbpm.LogTrigIntern._fields)
lbl = QLabel(bpm, self, alignment=Qt.AlignCenter)
lbl.setObjectName('lbl_bpmname')
hwid = QWidget()
hwid.setObjectName('wid')
hwid.setStyleSheet('#wid{border: 1px solid gray;}')
hlay = QHBoxLayout(hwid)
hlay.setContentsMargins(2, 0, 2, 0)
hlay.addWidget(btn)
hlay.addWidget(lbl)
lay.addWidget(hwid, row, 0)
c2v = dict()
for idx, prop in enumerate(propties):
pvn = _PVName(bpm).substitute(
prefix=self.prefix, propty='TRIGGER'+str(trigid)+prop)
dval = FamFOFBControllers.DEF_BPMTRIG_RCVIN if 'RcvIn' \
in prop else FamFOFBControllers.DEF_BPMTRIG_RCVSRC
c2v[pvn] = dval
plb = SiriusLabel(self, pvn)
lay.addWidget(plb, row, idx+1)
led = PyDMLedMultiChannel(self, c2v)
lay.addWidget(led, row, 7)
return self._build_scroll_area(wid)
def _setupSYSIDExc(self):
wid = QWidget()
lay = QGridLayout(wid)
lay.setSpacing(1)
lay.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# header
lay.addWidget(
QLabel('<h4>Device</h4>', self, alignment=Qt.AlignCenter), 0, 0)
lay.addWidget(
QLabel('<h4>FOFBAcc.Enbl.</h4>', self, alignment=Qt.AlignCenter),
0, 1)
lay.addWidget(
QLabel('<h4>BPMPos.Enbl.</h4>', self, alignment=Qt.AlignCenter),
0, 2)
# table
for idx, ctl in enumerate(self.ctrlrs):
row = idx + 1
lbl = QLabel(ctl, self, alignment=Qt.AlignCenter)
pvnacc = _PVName(ctl).substitute(
prefix=self.prefix, propty='SYSIDPRBSFOFBAccEn-Sts')
ledacc = SiriusLedState(self, pvnacc)
ledacc.shape = ledacc.ShapeMap.Square
ledacc.setObjectName('led_status')
pvnbpm = _PVName(ctl).substitute(
prefix=self.prefix, propty='SYSIDPRBSBPMPosEn-Sts')
ledbpm = SiriusLedState(self, pvnbpm)
ledbpm.shape = ledbpm.ShapeMap.Square
ledbpm.setObjectName('led_status')
ledsum = PyDMLedMultiChannel(self, {pvnacc: 0, pvnbpm: 0})
lay.addWidget(lbl, row, 0)
lay.addWidget(ledacc, row, 1, alignment=Qt.AlignTop)
lay.addWidget(ledbpm, row, 2, alignment=Qt.AlignTop)
lay.addWidget(ledsum, row, 3)
return self._build_scroll_area(wid)
def _build_scroll_area(self, widget):
area = QScrollArea(self)
area.setSizeAdjustPolicy(QScrollArea.AdjustToContentsOnFirstShow)
area.setWidgetResizable(True)
area.setWidget(widget)
widget.setObjectName('widget')
widget.setStyleSheet(
'#widget{background-color: transparent;}'
'QLabel{border: 1px solid gray; min-height: 1.5em;}'
'#lbl_bpmname{border: 0px solid gray; min-height: 1.5em;}'
'#led_status{border: 1px solid gray; min-height: 1.5em;}')
return area