From f06759cf3f60e65030e60093d3e1e3c17efb122f Mon Sep 17 00:00:00 2001 From: chrin Date: Tue, 20 Feb 2024 10:27:12 +0100 Subject: [PATCH] write to elog for when counter reset --- hush.json | 6 +- hush.py | 103 ++--- hush.sh | 4 +- .../__pycache__/hush_resources.cpython-37.pyc | Bin 2824 -> 2824 bytes src/gui.py | 375 +++++++++++++----- 5 files changed, 338 insertions(+), 150 deletions(-) diff --git a/hush.json b/hush.json index 137f5cc..ee04c3a 100755 --- a/hush.json +++ b/hush.json @@ -109,9 +109,7 @@ "debug": {"flag" : 0, "data":{ "widget": "None", "text" : "Debug", "value" : 0}}, "simulation": {"flag" : 1, "data":{ "widget": "None", "text" : "Dry run", "value" : 0}} }, - "GUI": { - "resultsTabTitle" : "Results", - "subResultsTabTitle" : [], - "resultsSeq" : [] + "IOC": { + "resultsTabTitle" : "IOC" } } diff --git a/hush.py b/hush.py index 5d603bb..d41ccf8 100644 --- a/hush.py +++ b/hush.py @@ -1,3 +1,5 @@ +"""Hush.py module for energy saving accounting +""" import inspect import logging import os @@ -55,9 +57,58 @@ class StartMain(BaseWindow): has_optics=False, has_procedure=False) self.appname = _appname + self.elog_enum = ElogHIPA() self.gui = AppGui(self) + def prepare_elog_message(self): + + self.projekt_idx = self.elog_enum.projekt.NONE + self.system_idx = self.elog_enum.system.ELECTRICAL_SUPPLY + self.eintrag_idx = self.elog_enum.eintrag.INFO + self.ort_idx = self.elog_enum.ort.GLOBAL + self.status_idx = self.elog_enum.status.NONE + self.effekt_idx = self.elog_enum.effekt.NO + + + self.attach_files = [] + + _simulation = self.input_parameters['simulation'] + + if self.all_data: + if self.all_data['Input data'] is not None: + try: + _simulation = self.all_data['Input data']['simulation'] + except KeyError: + _simulation = self.input_parameters['simulation'] + pass + + + self.logbook = "Sandkasten" if _simulation else "HIPA" + self.title = _title + + sector = ["
IP2: ","
IW2: ","
PK1: ", "
PK2: ","
SNQ: ", + "
UCN: ","
------------------
Tot: "] + + pvlist = ['ZIP2-HUSH:TOTSAVE', 'ZIW2-HUSH:TOTSAVE', 'ZPK1-HUSH:TOTSAVE', + 'ZPK2-HUSH:TOTSAVE', 'ZSINQ-HUSH:TOTSAVE', 'ZUCN-HUSH:TOTSAVE', + 'ZHIPA-HUSH:TOTSAVE'] + + value, stat, stat_list =self.cafe.getScalarList( + pvlist, cacheFlag=True) + + if stat != self.cyca.ICAFE_NORMAL: + self.check_status_list(_pymodule, "getScalarListCache", + pvlist, stat_list, _line()) + + message = ("Power saved for the current year stands at " + + "{:.3f} MWh:").format(value[-1]) + for label, val in zip(sector, value): + message += label + "{:.3f}".format(val) + " MWh" + + + self.message = message + @Slot() def send_to_elog(self): @@ -84,56 +135,8 @@ class StartMain(BaseWindow): #if not self.verify_send_to_elog(): # return - - elog = ElogHIPA() - self.projekt_idx = elog.projekt.NONE - self.system_idx = elog.system.ELECTRICAL_SUPPLY - self.eintrag_idx = elog.eintrag.INFO - self.ort_idx = elog.ort.GLOBAL - self.status_idx = elog.status.NONE - self.effekt_idx = elog.effekt.NO - - - self.attach_files = [] - - _simulation = self.input_parameters['simulation'] - - if self.all_data: - if self.all_data['Input data'] is not None: - try: - _simulation = self.all_data['Input data']['simulation'] - except KeyError: - _simulation = self.input_parameters['simulation'] - pass - - - self.logbook = "Sandkasten" if _simulation else "HIPA" - self.title = _title - - sector = ["
IP2: ","
IW2: ","
PK1: ", "
PK2: ","
SNQ: ", - "
UCN: ","
------------------
Tot: "] - - pvlist = ['ZIP2-HUSH:TOTSAVE', 'ZIW2-HUSH:TOTSAVE', 'ZPK1-HUSH:TOTSAVE', - 'ZPK2-HUSH:TOTSAVE', 'ZSINQ-HUSH:TOTSAVE', 'ZUCN-HUSH:TOTSAVE', - 'ZHIPA-HUSH:TOTSAVE'] - - value, stat, stat_list =self.cafe.getScalarList(pvlist, cacheFlag=True) - - message = "Power saved for the current year stands at {:.3f} MWh:".format( - value[-1]) - for label, val in zip(sector, value): - message += label + "{:.3f}".format(val) + " MWh" + self.prepare_elog_message() - ''' - message += "IP2: " + str(value[0])+ " MWh
" - message += "IW2: " + str(value[1])+ " MWh
" - message += "PK1: " + str(value[2])+ " MWh
" - message += "PK2: " + str(value[3])+ " MWh
" - message += "SNQ: " + str(value[4])+ " MWh
" - message += "UCN: " + str(value[5])+ " MWh
" - message += "Tot: " + str(value[6])+ " MWh" - ''' - self.message = message print(self.message, flush=True) if not self.all_data: @@ -219,7 +222,7 @@ if __name__ == "__main__": app = QApplication(sys.argv) splash = BaseWindow.initialize_application( - app, appname=_appname, delay=20, facility=Facility.HIPA) + app, appname=_appname, delay=25, facility=Facility.HIPA) myapp = StartMain() diff --git a/hush.sh b/hush.sh index b517530..4ef8fad 100755 --- a/hush.sh +++ b/hush.sh @@ -1,5 +1,5 @@ #!/bin/bash -cd /hipa/bd/applications/hush/hla/1.2.0 +cd /hipa/bd/applications/hush/hla/2.0.0 # For use if script is sourced rather than executed appNameDefault="hush.sh" @@ -44,7 +44,7 @@ _EPICS_HOST_ARCH=${RHREL}-x86_64 #C_EXT version for Py 3.7: -export PYTHONPATH=.:/opt/gfa/cafe/python/pycafe/cafe-1.19.3/lib/${_EPICS_HOST_ARCH}:/hipa/bd/applications/deps/apps4ops/v1.6.0 +export PYTHONPATH=.:/opt/gfa/cafe/python/pycafe/cafe-1.19.3/lib/${_EPICS_HOST_ARCH}:/hipa/bd/applications/deps/apps4ops/v1.9.0 #:/afs/psi.ch/intranet/SLS/Controls/BD/pyqtacc/v1.5.2 diff --git a/pyrcc5/__pycache__/hush_resources.cpython-37.pyc b/pyrcc5/__pycache__/hush_resources.cpython-37.pyc index bd9bde5f48900463836f25146fc3128afadf2dff..f94837ee5ea31a37e95db2aa1c0f85b2e76746cb 100644 GIT binary patch delta 30 kcmeAW>k#8{;^pOH0D|xQms2k#8{;^pOH0D_;KpHnvSWO6ba>KSdW;GDn+0Bnl~kN^Mx diff --git a/src/gui.py b/src/gui.py index 7674335..b6f90cd 100644 --- a/src/gui.py +++ b/src/gui.py @@ -1,41 +1,37 @@ +'''The GUI module for Savings Overview and magnet control +''' +import getpass import inspect import os import platform import random +import socket import sys import time from datetime import timedelta -from qtpy import QtCore, QtGui -from qtpy.QtGui import QColor, QFont, QIcon +#from qtpy import QtCore, QtGui +from qtpy.QtGui import QColor, QFont, QIcon, QPixmap from qtpy.QtCore import __version__ as QT_VERSION_STR from qtpy.QtCore import ( PYQT_VERSION_STR, QDate, QDateTime, QEventLoop, Qt, Signal, Slot) from qtpy.QtWidgets import ( QApplication, QDockWidget, QFrame, QGridLayout, QGroupBox, QHBoxLayout, - QLabel, QMainWindow, QMessageBox, QProgressBar, QPushButton, QSizePolicy, - QSpacerItem, QStackedWidget, QTabBar, QTabWidget, QTableWidget, - QTableWidgetItem, QVBoxLayout, QWidget) + QLabel, QMainWindow, QMessageBox, QProgressBar, QPushButton, + QSizePolicy, QSpacerItem, QStackedWidget, QTabBar, QTabWidget, + QTableWidget, QTableWidgetItem, QTextEdit, QVBoxLayout, QWidget) +import elog +from apps4ops.bdbase.utils import _line from apps4ops.bdbase.base import BaseWindow -from apps4ops.bdbase.enumkind import MsgSeverity, UserMode, Facility -from caqtwidgets.pvwidgets import CAQLabel, CAQLineEdit, CAQTableWidget, QHLine +from apps4ops.bdbase.enumkind import MsgSeverity +from caqtwidgets.pvwidgets import ( + CAQLabel, CAQLineEdit, CAQMessageButton, CAQTableWidget, QHLine) _pymodule = os.path.basename(__file__) -def _line(): - """Macro to return the current line number.688 - - The current line number within the file is used when - reporting messages to the message logging window. - - Returns: - int: Current line number. - """ - return inspect.currentframe().f_back.f_lineno - class AppGui(QWidget): def __init__(self, parent): @@ -43,8 +39,14 @@ class AppGui(QWidget): self.parent = parent self.cafe = self.parent.cafe self.cyca = self.parent.cyca + self.check_status = self.parent.check_status + self.check_status_list = self.parent.check_status_list + self.elog_enum = self.parent.elog_enum self.send_to_log_window = self.parent.send_to_log_window + self.show_log_message = self.parent.show_log_message + self.statusbar = self.parent.statusbar + self.gui_frame = self.parent.gui_frame self.gui_header = self.parent.gui_header self.font_gui = self.parent.gui_frame.font_gui @@ -52,10 +54,11 @@ class AppGui(QWidget): self.input_labels = self.parent.input_labels self.expert_parameters = self.parent.expert_parameters self.gui_frame.expert_parameters_group.setFixedWidth(260) + self.gui_frame.expert_parameters_group.setFixedHeight(130) self.gui_frame.operator_parameters_group.setFixedWidth(260) - #self.gui_frame.operator_parameters_group.setFixedHeight(260) - self.gui_frame.measurement_tab_wgt.setMinimumWidth(440) - self.gui_frame.measurement_tab_wgt.setFixedHeight(280) + self.gui_frame.operator_parameters_group.setFixedHeight(130) + self.gui_frame.measurement_tab_wgt.setFixedWidth(496) + self.gui_frame.measurement_tab_wgt.setFixedHeight(210) #self.gui_frame.operator_wgt.setFixedHeight(240) #self.gui_frame.expert_wgt.setFixedHeight(240) @@ -77,14 +80,14 @@ class AppGui(QWidget): #sec_state_list = ['SEC-IP2:STATE','SEC-IW2:STATE','SEC-PK1:STATE', # 'SEC-PK2:STATE','SEC-SINQ:STATE','SEC-UCN:STATE'] - sec_state_list = ['ZIP2-HUSH:STATE', 'ZIW2-HUSH:STATE', - 'ZPK1-HUSH:STATE', 'ZPK2-HUSH:STATE', - 'ZSINQ-HUSH:STATE', 'ZUCN-HUSH:STATE'] + self.sec_state_list = ['ZIP2-HUSH:STATE', 'ZIW2-HUSH:STATE', + 'ZPK1-HUSH:STATE', 'ZPK2-HUSH:STATE', + 'ZSINQ-HUSH:STATE', 'ZUCN-HUSH:STATE'] self.cafe.openPrepare() self.cafe.open(['ZHIPA-HUSH:LASTPWR','ZHIPA-HUSH:TOTPWR', 'ZHIPA-HUSH:LASTSAVE', 'ZHIPA-HUSH:TOTSAVE']) - self.cafe.open(sec_state_list) + self.cafe.open(self.sec_state_list) self.cafe.open("UCN:BEAMREQ:STATUS") self.cafe.openNowAndWait(0.1) @@ -99,11 +102,37 @@ class AppGui(QWidget): self.gui_frame.measurement_layout.addWidget( status_wgt, 2, 0, 2, 1, alignment=Qt.AlignTop) # | Qt.AlignHCenter) - qf = QFrame() - qf.setFixedHeight(6) - self.gui_frame.measurement_layout.addWidget( - qf, 4, 0, 1, 1, alignment=Qt.AlignTop) + + #qf = QFrame() + #qf.setFixedHeight(16) + #self.gui_frame.measurement_layout.addWidget( + # qf, 4, 0, 4, 1, alignment=Qt.AlignBottom) + + self.gui_frame.results_wgt.setFixedWidth(1200) + self.gui_frame.results_wgt.setFixedHeight(400) + self.gui_frame.results_wgt.setLayout(self.gui_frame.results_layout) + self.gui_frame.results_layout.addWidget( + self.reset_ioc_sm(), 0, 0, 1, 1) + + sec_prefix_list = [ + sub[0: sub.index("-")] for sub in self.sec_state_list] + + self.gui_frame.results_layout.addWidget( + self.reset_ioc_saving(sec_prefix_list), 0, 1, 1, 1) + + label = QLabel() + pixmap = QPixmap(":/Hush.jpg") + pixmap.scaled(180, 180, Qt.KeepAspectRatio) + label.setFixedWidth(180) + label.setFixedHeight(180) + label.setPixmap(pixmap) + label.setScaledContents(True) + + self.gui_frame.results_layout.addWidget(label, 0, 2, 1, 1, Qt.AlignCenter) + self.gui_frame.results_layout.setContentsMargins(10, 10, 10, 10) + self.gui_frame.results_layout.setHorizontalSpacing(20) + self.sectorI_dict = {} self.sectorI_dict['IP2'] = 0 self.sectorI_dict['IW2'] = 0 @@ -227,21 +256,21 @@ class AppGui(QWidget): idx = self.settings.data[sec]["device"].index(magnet) standby_value = self.settings.data[sec]["standby"][idx] standby_value_list.append(standby_value) + + print("pvlist===>", pv_list, flush=True) + print("standby ist==>", standby_value_list, flush=True) value_list, status, status_list = self.cafe.getScalarList( pv_list, cacheFlag=True) + print("valuelist", pv_list, value_list, flush=True) - if status != self.cyca.ICAFE_NORMAL: - self.check_status_list(pv_list, status_list, _line()) + #if status != self.cyca.ICAFE_NORMAL: + # self.check_status_list(pv_list, status_list, _line()) - print("valuelist", pv_list, value_list) - #get standby values: - standby_value_list = [] - for magnet in devices: - idx = self.settings.data[sec]["device"].index(magnet) - standby_value = self.settings.data[sec]["standby"][idx] - standby_value_list.append(standby_value) + if status != self.cyca.ICAFE_NORMAL: + self.check_status_list(_pymodule, "getScalarListCache", + pv_list, status_list, _line()) #check standby values in_standby = True @@ -263,7 +292,7 @@ class AppGui(QWidget): #print("sec", secsplit[1], flush=True) - for state in sec_state_list: + for state in self.sec_state_list: self.cafe.monitor(state, receive_sec_state) @@ -354,7 +383,8 @@ class AppGui(QWidget): qw.setObjectName("OUTER") qw.setLayout(qgrid) qw.setFixedWidth(496) #480 - + qw.setFixedHeight(346) #480 + #for column_no in range(0, 5): # qgrid.itemAtPosition(1, column_no).widget().setStyleSheet("QWidget { background: lightblue; }") #addStyleName( #item = qgrid.itemAt(2) #.widget().setStyleSheet("QLabel { background-color: green }") @@ -554,49 +584,6 @@ class AppGui(QWidget): return qw - - - def check_status_list(self, pv_list, status_list, line): - _brk = ("------------------------------------------------------" + - "------------------------------------------------------") - self.parent.trigger_log_message.emit( - MsgSeverity.INFO.name, _pymodule, line, _brk, {}) - - _options = {} - - for pv, stat in zip(pv_list, status_list): - if stat != self.cyca.ICAFE_NORMAL: - _mess = ("Error in 'set' for " + pv + " ") - _options['statusCode'] = ( - str(stat) + " " + - self.cafe.getStatusCodeAsString(stat)) - _options['statusInfo'] = self.cafe.getStatusInfo(stat) - - self.parent.trigger_log_message.emit( - MsgSeverity.WARN.name, _pymodule, line, _mess, _options) - - - self.parent.trigger_log_message.emit( - MsgSeverity.INFO.name, _pymodule, line, _brk, {}) - - _mess = ("The following devices reported an error " + - "in 'set' operation:") - self.parent.trigger_log_message.emit( - MsgSeverity.INFO.name, _pymodule, line, _mess, {}) - - def check_status(self, pv, stat, line): - if stat != self.cyca.ICAFE_NORMAL: - _mess = ("Error in 'set' for " + pv + ".") - _options = {} - _options['statusCode'] = ( - str(stat) + " " + - self.cafe.getStatusCodeAsString(stat)) - _options['statusInfo'] = self.cafe.getStatusInfo( - stat) - self.parent.trigger_log_message.emit( - MsgSeverity.WARN.name, _pymodule, line, - _mess, _options) - def on_sector_standby(self): target = self.sender() sector = target.sector @@ -682,8 +669,9 @@ class AppGui(QWidget): status, status_list, pv_list = _table.set_standby_values() if status != self.cyca.ICAFE_NORMAL: - self.check_status_list(pv_list, status_list, _line()) - + #self.check_status_list(pv_list, status_list, _line()) + self.check_status_list(_pymodule, "setScalarList", + pv_list, status_list, _line()) #Seqeuncer ONLY determines when to go into STANDBY mode #and NOT the HLA @@ -707,8 +695,9 @@ class AppGui(QWidget): status, status_list, pv_list = _table.restore_init_values() if status != self.cyca.ICAFE_NORMAL: - self.check_status_list(pv_list, status_list, _line()) - + #self.check_status_list(pv_list, status_list, _line()) + self.check_status_list(_pymodule, "getScalarListCache", + pv_list, status_list, _line()) #Seqeuncer ONLY determines when to go into STANDBY mode @@ -725,8 +714,8 @@ class AppGui(QWidget): pv_last_pwr = 'Z' + target.sector + "-HUSH:LASTPWR" stat = self.cafe.set(pv_last_pwr, sum_pwr) - self.check_status(pv_last_pwr, stat, _line()) - + #self.check_status(pv_last_pwr, stat, _line()) + self.check_status(_pymodule, "set", pv_last_pwr, stat, _line()) def ca_table_sector_widget(self, sector: str="", color: str="MACHINE"): device_list = self.settings.data[sector]["device"] @@ -768,8 +757,7 @@ class AppGui(QWidget): table_sol.restore_value_button.sector = sector table_sol.restore_value_button.clicked.disconnect() table_sol.restore_value_button.clicked.connect(self.on_sector_restore) - - + self.table_sol_dict[sector] = table_sol table_ist = CAQTableWidget( @@ -852,7 +840,6 @@ class AppGui(QWidget): table_ist.paint_rows(row_range=[i, i+1], reset=False) table_pwr.paint_rows(row_range=[i, i+1], reset=False) - pvI = self.settings.data[sector]['current'] I = self.cafe.getCache(pvI) if I is not None: @@ -878,7 +865,8 @@ class AppGui(QWidget): _sum = sum(table_pwr.get_init_values().values()) #print("SUM up all the values", pv, _sum, flush=True) stat = self.cafe.set(pv, _sum) - self.check_status(pv, stat, _line()) + #self.check_status(pv, stat, _line()) + self.check_status(_pymodule, "set", pv, stat, _line()) def on_init_update(): table_pwr.init_value_button.setEnabled(False) @@ -901,7 +889,6 @@ class AppGui(QWidget): qw = QWidget() qw.setLayout(hbox) - obj_name = self.settings.data[sector]["colorObj"] if self.obj_to_upper: obj_name = obj_name.upper() @@ -909,3 +896,203 @@ class AppGui(QWidget): qw.setObjectName(obj_name) return qw + + + def clear_saving(self, sector_prefix_list: list = None): + if not sector_prefix_list: + return + qm = QMessageBox() + mess = ("This action will reset the energy saving account to zero. \n" + + "This is typically undertaken at the end of the calendar " + + "year. \n\n" + + "Present accounting figures will be entered in the elogbook\n" + + "Are you sure you wish to continue with the reset?") + reply = qm.warning(self, "Reset Accounting", mess, + QMessageBox.Yes | QMessageBox.No) + + if reply == QMessageBox.No: + return + + + self.parent.prepare_elog_message() + print("message", self.parent.message, flush=True) + print("logbook", self.parent.logbook, flush=True) + url = self.settings.data["ElogBooks"][self.parent.logbook]["url"] + print("url", url, flush=True) + logbook = elog.open(url, user="robot", password="robot") + # QApplication.processEvents() + + attributes = {} + attributes["Autor"] = getpass.getuser() + attributes["Author"] = getpass.getuser() + attributes["Application"] = self.parent.appname + attributes["Titel"] = self.parent.title + attributes["Title"] = self.parent.title + attributes["When"] = str(time.time()) + attributes["Wann"] = str(time.time()) + if "Sandkasten" in self.parent.logbook: + attributes["Eintrag"] = "Anregung" + elif "Bestandesaufnahme" in self.parent.logbook: + attributes["Konsole"] = socket.gethostname().split(".")[0] + attributes["Ort"] = "Global" + elif "Strahlentwicklung" in self.parent.logbook: + pass + #HIPA Log Book + else: + attributes["Eintrag"] = self.elog_enum.eintrag.INFO.name + attributes["Effekt"] = self.elog_enum.effekt.NO,name #keiner + #"Elektorversogung" + attributes["System"] = self.elog_enum.system.ELECTRICAL_SUPPLY.name + attributes["Ort"] = self.elog_enum.ort.GLOBAL.name + + log_mess = self.parent.message.replace("
", "\n") + + try: + logbook.post(log_mess, attributes=attributes) + + self.show_log_message(MsgSeverity.INFO, _pymodule, _line(), + log_mess) + self.statusbar.showMessage("Reset Savings Account." + + "Last values sent to elog") + except Exception as ex: + print("Exception in sendelog.py", str(ex), flush=True) + mess = "Failed to write last saving values to elog:" + str(ex) + self.show_log_message( + MsgSeverity.ERROR, _pymodule, _line(), mess) + self.statusbar.showMessage(mess) + + for sector in sector_prefix_list: + self.sector_sm_off(sector) + + for sector in sector_prefix_list: + self.clear_sector_saving(sector) + + + def sector_sm_off(self, sector_prefix: str = None): + if not sector_prefix: + return + pv1 = sector_prefix + "-HUSH:SEQ-ONOFF" + stat = self.cafe.set(pv1, 0) + self.check_status(_pymodule, "set", pv1, stat, _line()) + time.sleep(0.05) + QApplication.processEvents() + return + + + def clear_sector_saving(self, sector_prefix: str = None): + if not sector_prefix: + return + pv1 = sector_prefix + "-HUSH:SEQ-ONOFF" + pv2 = sector_prefix + "-HUSH:TOTSAVE" + pv3 = sector_prefix + "-HUSH:OFFTIME" + stat = self.cafe.set(pv1, 0) + self.check_status(_pymodule, "set", pv1, stat, _line()) + off_time = self.cafe.get(pv3) + self.check_status(_pymodule, "get", pv3, None, _line()) + + iloop = 0 + if off_time is not None: + while off_time > 0 and iloop < 100: + time.sleep(0.1) + off_time_tmp = self.cafe.get(pv3) + off_time = off_time_tmp if off_time_tmp is not None else 0 + iloop += 1 + QApplication.processEvents() + else: + time.sleep(0.1) + print("SECTOR ILOOP", sector_prefix, iloop) + stat = self.cafe.set(pv1, 1) + self.check_status(_pymodule, "set", pv1, stat, _line()) + stat = self.cafe.set(pv2, 0) + self.check_status(_pymodule, "set", pv2, stat, _line()) + return + + def reset_ioc_saving(self, sector_prefix_list: list = None): + if not sector_prefix_list: + return + qpb = QPushButton("Reset Account") + qpb.setObjectName("WriteData") + qpb.clicked.connect(lambda: self.clear_saving(sector_prefix_list)) + qpb.setFixedHeight(40) # self.gui_frame.widget_height) + qpb.setFixedWidth(160) + + qtext = QTextEdit() + qtext.setText("""
  The Reset Account Button resets Total Power Saved (MWh) to zero.
+   This is typically executed at the end of the calendar year.
+   The present energy saving figures will be entered into the elogbook.
+   The button prompts the user for confirmation before proceeding.
+ """) + qtext.setReadOnly(True) + qtext.setStyleSheet("background-color: QColor(0, 0, 50, 10);") + qtext.setFixedHeight(104) + qtext.setFixedWidth(440) + + qgrid = QGridLayout() + qgrid.setSpacing(0) + qgrid.addWidget(qtext, 0, 0, 1, 1, Qt.AlignHCenter) + qgrid.addWidget(qpb, 1, 0, 1, 1, Qt.AlignHCenter) + + qw = QGroupBox("HUSH! Accounting") + qw.setContentsMargins(5, 10, 5, 0) + qw.setAlignment(Qt.AlignTop) + qw.setObjectName("OUTER") + qw.setLayout(qgrid) + qw.setFixedWidth(460) + qw.setFixedHeight(280) + return qw + + def reset_ioc_sm(self): + msg_button = [None] * len(self.sec_state_list) + + monitor_seq_onoff = [None] * len(self.sec_state_list) + monitor_seq_state = [None] * len(self.sec_state_list) + monitor_standby_state = [None] * len(self.sec_state_list) + qgrid = QGridLayout() + qreset = QLabel("Reset") + qreset.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) + qsm = QLabel("SM ") + qsm.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) + qss = QLabel("Sequencer State ") + qss.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) + qstandby = QLabel("ON or \nStandby") + qstandby.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) + qgrid.addWidget(qreset, 0, 0, 1, 1) + qgrid.addWidget(qsm, 0, 1, 1, 1) + qgrid.addWidget(qss, 0, 2, 1, 1) + qgrid.addWidget(qstandby, 0, 3, 1, 1) + for i, pv in enumerate(self.sec_state_list): + pvsplit = pv.split("-") + sec = pvsplit[0][1:] + pv_seq_onoff = pv.replace("STATE", "SEQ-ONOFF") + pv_seq_state = pv.replace("STATE", "SEQ-STATE") + msg_button[i] = CAQMessageButton( + self, pv_name=pv_seq_onoff, msg_label=sec, + msg_press_value="Off", msg_release_value="On") + msg_button[i].setFixedWidth(60) + monitor_seq_onoff[i] = CAQLabel(self, pv_name=pv_seq_onoff) + monitor_seq_state[i] = CAQLabel(self, pv_name=pv_seq_state) + monitor_standby_state[i] = CAQLabel(self, pv_name=pv) + qgrid.addWidget(msg_button[i], i + 1, 0, 1, 1, Qt.AlignLeft) + qgrid.addWidget(monitor_seq_onoff[i], i + 1, 1, 1, 1, Qt.AlignLeft) + qgrid.addWidget(monitor_seq_state[i], i + 1, 2, 1, 1, Qt.AlignLeft) + qgrid.addWidget( + monitor_standby_state[i], + i + 1, + 3, + 1, + 1, + Qt.AlignLeft) + + qgrid.setContentsMargins(9, 9, 9, 9) + qgrid.setSpacing(10) + + qw = QGroupBox("State Machine") + qw.setContentsMargins(5, 10, 5, 0) + qw.setAlignment(Qt.AlignTop) + qw.setObjectName("OUTER") + qw.setLayout(qgrid) + qw.setFixedWidth(460) + qw.setFixedHeight(280) + + return qw +