diff --git a/hush.py b/hush.py index ee4ddf2..83e69b4 100644 --- a/hush.py +++ b/hush.py @@ -1,41 +1,31 @@ """Hush.py module for energy saving accounting """ import inspect -import logging import os import platform -import random import sys import time - -from qtpy import QtCore, QtGui -from qtpy.QtGui import QColor, QFont, QIcon from qtpy.QtCore import __version__ as QT_VERSION_STR -from qtpy.QtCore import ( - PYQT_VERSION_STR, QFile, QIODevice, Qt, QThread, Signal, Slot) -from qtpy.QtWidgets import ( - QApplication, QDockWidget, QGridLayout, QGroupBox, QHBoxLayout, QLabel, - QMainWindow, QMessageBox, QProgressBar, QPushButton, QSizePolicy, - QSpacerItem, QTabWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, - QWidget) +from qtpy.QtCore import PYQT_VERSION_STR, Signal, Slot +from qtpy.QtWidgets import QApplication, QMessageBox from apps4ops.bdbase.base import BaseWindow -from apps4ops.bdbase.enumkind import MsgSeverity, UserMode, Facility +from apps4ops.bdbase.enumkind import UserMode, Facility from apps4ops.bdbase.helpbrowser import HelpBrowser from apps4ops.hipa.sendeloghipa import QSendToELOG - from apps4ops.hipa.enumkind import ElogHIPA from src.gui import AppGui -from pyrcc5 import hush_resources +from pyrcc5 import hush_resources _pymodule = os.path.basename(__file__) _appname, _appext = _pymodule.split(".") _appversion = "2.0.0" -#_title = """HIPA Power Usage & Saving Hierarchy""" #, HUSH!""" +# _title = """HIPA Power Usage & Saving Hierarchy""" #, HUSH!""" _title = """HUSH!""" + def _line(): """Macro to return the current line number. @@ -47,76 +37,79 @@ def _line(): """ return inspect.currentframe().f_back.f_lineno + class StartMain(BaseWindow): + ''' Main class for HUSH + ''' trigger_log_message = Signal(str, str, int, str, dict) - - def __init__(self, parent=None): - super(StartMain, self).__init__( - parent=parent, pymodule=_pymodule, appversion=_appversion, + + def __init__(self, parent=None): + #super(StartMain, self).__init__( + # parent=parent, pymodule=_pymodule, appversion=_appversion, + # title=_title, user_mode=UserMode.OPERATION, facility=Facility.HIPA, + # has_optics=False, has_procedure=False) + super().__init__( + parent=parent, pymodule=_pymodule, appversion=_appversion, title=_title, user_mode=UserMode.OPERATION, facility=Facility.HIPA, 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'] + simulation = self.input_parameters["simulation"] if self.all_data: - if self.all_data['Input data'] is not None: + if self.all_data["Input data"] is not None: try: - _simulation = self.all_data['Input data']['simulation'] + simulation = self.all_data["Input data"]["simulation"] except KeyError: - _simulation = self.input_parameters['simulation'] + simulation = self.input_parameters["simulation"] pass - - self.logbook = "Sandkasten" if _simulation else "HIPA" + self.logbook = "Sandkasten" if simulation else "HIPA" self.title = _title - sector = ["
IP2: ","
IW2: ","
PK1: ", "
PK2: ","
SNQ: ", - "
UCN: ","
------------------
Tot: "] + 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'] + 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( + 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): @Slot() def save_fig_thread_finished(): - + time.sleep(0.2) - + if self.all_data: QSendToELOG(self, logbook=self.logbook, projektIdx=self.projekt_idx, @@ -128,15 +121,14 @@ class StartMain(BaseWindow): title=self.title, message=self.message, attachFile=self.attach_files) - + time.sleep(1.0) - return - - #if not self.verify_send_to_elog(): + + # if not self.verify_send_to_elog(): # return self.prepare_elog_message() - + print(self.message, flush=True) if not self.all_data: @@ -152,28 +144,26 @@ class StartMain(BaseWindow): attachFile=self.attach_files) return + folder_name = self.elog_dest + if not os.path.exists(folder_name): + os.makedirs(folder_name) - _folder_name = self.elog_dest - if not os.path.exists(_folder_name): - os.makedirs(_folder_name) - - time_in_seconds = self.all_data['Ambient data']['Time in seconds'] - if self.all_data['Processed data']['Reanalysis time']: - reanalysis_time = self.all_data['Processed data'][ - 'Reanalysis time in seconds'] + time_in_seconds = self.all_data["Ambient data"]["Time in seconds"] + if self.all_data["Processed data"]["Reanalysis time"]: + reanalysis_time = self.all_data["Processed data"][ + "Reanalysis time in seconds"] else: reanalysis_time = None - - self.folder_name = _folder_name + + self.folder_name = folder_name save_fig_thread = self.SaveFigureThread( self, self.folder_name, time_in_seconds, reanalysis_time) save_fig_thread.finished.connect(save_fig_thread_finished) - + save_fig_thread.start() time.sleep(0.05) - @Slot() def closeEvent(self, event): @@ -198,7 +188,7 @@ class StartMain(BaseWindow):

IOC Administrator: H. Lutz

1st Responsible: A. Barchetti, Tel. 4779 or 3301 (Control Room)

- +

Initiates energy saving procedures and records power saved

Python {2} - Qt {3} - PyQt {4}
cafe {5} - epics {6} on {7}""".format( @@ -212,24 +202,24 @@ class StartMain(BaseWindow): def show_help(self): """ Invoke help pages from hush_resources """ - index_html ="index.html" #self.appname + "/index.html" - help_base = ":" # + self.appname + index_html = "index.html" # self.appname + "/index.html" + help_base = ":" # + self.appname help_page = HelpBrowser(help_base, index_html, self) help_page.show() + ######################################################################### if __name__ == "__main__": app = QApplication(sys.argv) splash = BaseWindow.initialize_application( app, appname=_appname, delay=25, facility=Facility.HIPA) - + myapp = StartMain() - + myapp.show() if splash is not None: splash.finish(myapp) app.exec_() - diff --git a/hush.sh b/hush.sh index 7e8624d..0ee1694 100755 --- a/hush.sh +++ b/hush.sh @@ -1,5 +1,5 @@ #!/bin/bash -cd /hipa/bd/applications/hush/hla/2.0.0 +cd /hipa/bd/applications/hush/hla/2.1.0 # For use if script is sourced rather than executed appNameDefault="hush.sh" @@ -83,6 +83,8 @@ echo "nameLog: $nameLog" #Configuration files can be overwritten #python ${name}.py -s="/sf/bd/deps/pyqtacc/common/config/style.json" -f="/sf/bd/deps/pyqtacc/v1.0.0/pyqtacc/qrc_resources/facility/sf/config/base.json" -q="/sf/bd/deps/pyqtacc/common/config/acc.qss" & +python wakeup.py 00:00 & + if [ "${STDOUT_FLAG}" -gt "0" ] ; then #if changing the std::out destination, remember to also change it in your json config file (for reading) if test -f "$STDOUT_DIR/${nameLog}.log---"; then diff --git a/src/gui.py b/src/gui.py index a4b78bd..4a4dac6 100644 --- a/src/gui.py +++ b/src/gui.py @@ -2,31 +2,27 @@ ''' import decimal import getpass -import inspect import os -import platform import random import socket -import sys +import threading import time from datetime import timedelta #from qtpy import QtCore, QtGui -from qtpy.QtGui import QColor, QFont, QIcon, QPixmap +from qtpy.QtGui import QColor, 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.QtCore import QEventLoop, Qt, QTimer, Slot from qtpy.QtWidgets import ( - QApplication, QDockWidget, QFrame, QGridLayout, QGroupBox, QHBoxLayout, - QLabel, QMainWindow, QMessageBox, QProgressBar, QPushButton, - QSizePolicy, QSpacerItem, QStackedWidget, QTabBar, QTabWidget, - QTableWidget, QTableWidgetItem, QTextEdit, QVBoxLayout, QWidget) + QApplication, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QMessageBox, + QPushButton, QTabBar, QTabWidget, QTableWidgetItem, QTextEdit, QVBoxLayout, + QWidget) from common.packages import elog from apps4ops.bdbase.utils import _line -from apps4ops.bdbase.base import BaseWindow + from apps4ops.bdbase.enumkind import MsgSeverity from caqtwidgets.pvwidgets import ( CAQLabel, CAQLineEdit, CAQMessageButton, CAQTableWidget, CAQTextEntry, @@ -34,10 +30,15 @@ from caqtwidgets.pvwidgets import ( _pymodule = os.path.basename(__file__) + class AppGui(QWidget): + ''' Main GUI class + ''' def __init__(self, parent): - super(AppGui, self).__init__() + #super(AppGui, self).__init__() + # using Python 3 style super() without arguments + super().__init__() self.parent = parent self.cafe = self.parent.cafe self.cyca = self.parent.cyca @@ -48,65 +49,82 @@ class AppGui(QWidget): 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 - self.input_parameters = self.parent.input_parameters + self.input_parameters = self.parent.input_parameters self.input_labels = self.parent.input_labels - self.expert_parameters = self.parent.expert_parameters + 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(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) - + # self.gui_frame.operator_wgt.setFixedHeight(240) + # self.gui_frame.expert_wgt.setFixedHeight(240) + self.gui_frame.central_tab_widget.tabBar().setTabText(0, "Control") - self.gui_frame.central_tab_widget.tabBar().setTabText(1, "IOC") - + self.gui_frame.central_tab_widget.tabBar().setTabText(1, "IOC") + self.expert_labels = self.parent.expert_labels self.settings = self.parent.settings - self.obj_to_upper = True if random.randint(1, 10) > 3 else False - + self.lock = threading.Lock() + self.timer = QTimer() + self.timer.setSingleShot(True) + + self.obj_to_upper = bool(random.randint(1, 10) > 3) + self.table_sol_dict = {} self.table_pwr_dict = {} self.offtime_dict = {} - + self.I_min = 1.0 self.with_rf = False - self.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(["ZHIPA-HUSH:LASTPWR", "ZHIPA-HUSH:TOTPWR", + "ZHIPA-HUSH:LASTSAVE", "ZHIPA-HUSH:TOTSAVE"]) self.cafe.open(self.sec_state_list) self.cafe.open("UCN:BEAMREQ:STATUS") self.cafe.openNowAndWait(0.1) self.cafe.monitor("UCNQ:BEAMREQ:STATUS") + idx = self.settings.data["header"].index("IP2") + self.sectorI_dict = {} + for sector in self.settings.data["header"][idx:]: + self.sectorI_dict[sector] = 0 + + self.sector_designated_magnet_standby_dict = {} + self.sector_designated_magnet_values_dict = {} + + for sector in self.settings.data["header"][idx:]: + self.sector_designated_magnet_standby_dict[sector] = {} + self.sector_designated_magnet_values_dict[sector] = {} + self.sector_designated_magnet_standby_dict[ + sector] = self.get_standby_dict(sector) + self.sector_designated_magnet_values_dict[ + sector] = self.get_standby_dict(sector) + + print(sector, self.sector_designated_magnet_standby_dict[sector]) + wgt = self.group_sector_qtabwidget() self.gui_frame.measurement_layout.addWidget( - wgt, 0, 1, 6, 3, alignment=Qt.AlignTop) + wgt, 0, 1, 6, 3, alignment=Qt.AlignTop) status_wgt = self.group_sector_status() - - self.gui_frame.measurement_layout.addWidget( - status_wgt, 2, 0, 2, 1, alignment=Qt.AlignTop) # | Qt.AlignHCenter) - - #qf = QFrame() - #qf.setFixedHeight(16) - #self.gui_frame.measurement_layout.addWidget( - # qf, 4, 0, 4, 1, alignment=Qt.AlignBottom) - + self.gui_frame.measurement_layout.addWidget( + status_wgt, 2, 0, 2, 1, alignment=Qt.AlignTop) # | Qt.AlignHCenter) + + self.gui_frame.results_wgt.setFixedWidth(1500) self.gui_frame.results_wgt.setFixedHeight(860) self.gui_frame.results_wgt.setLayout(self.gui_frame.results_layout) @@ -127,66 +145,67 @@ class AppGui(QWidget): label.setFixedHeight(180) label.setPixmap(pixmap) label.setScaledContents(True) - - self.gui_frame.results_layout.addWidget(label, 0, 2, 1, 1, Qt.AlignLeft) + + self.gui_frame.results_layout.addWidget( + label, 0, 2, 1, 1, Qt.AlignLeft) self.gui_frame.results_layout.setContentsMargins(10, 40, 10, 10) self.gui_frame.results_layout.setVerticalSpacing(20) self.gui_frame.results_layout.setHorizontalSpacing(10) self.gui_frame.results_layout.addWidget( self.reset_lastpwr(), 1, 0, 1, 1, - Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignCenter)) - - - self.sectorI_dict = {} - self.sectorI_dict['IP2'] = 0 - self.sectorI_dict['IW2'] = 0 - self.sectorI_dict['PK1'] = 0 - self.sectorI_dict['PK2'] = 0 - self.sectorI_dict['SINQ'] = 0 - self.sectorI_dict['UCN'] = 0 - + Qt.AlignmentFlag(Qt.AlignTop | Qt.AlignCenter)) + ucn_line = ["PK1", "PK2", "UCN"] sinq_line = ["PK1", "PK2", "SINQ"] pk1_line = ["IW2"] pk2_line = ["IW2"] + for sector in self.settings.data["header"][idx:]: + gateway_indices = self.get_standby_index_list(sector) + for idx in gateway_indices: + pv_name_gw = self.table_sol_dict[sector].pv_gateway[idx].pv_name + pvd = self.cafe.getPVCache(pv_name_gw, dt="float") + #print(sector, "pv_name_gw", pv_name_gw, flush=True) + # pvd.show() + self.table_sol_dict[sector].pv_gateway[ + idx].trigger_monitor_float.emit( + pvd.value[0], pvd.status, pvd.alarmSeverity) + def enable_disable_ucn(sect, sector_line, value): self.sectorI_dict[sect] = value beam_req_running = True beam_req_status = self.cafe.getCache("UCNQ:BEAMREQ:STATUS") #print(" beam_req_status", beam_req_status, flush=True) - + if beam_req_status is not None: if beam_req_status == "stopped": beam_req_running = False - for sector in sector_line: beam_req_flag = True - if sector == 'UCN': - beam_req_flag = beam_req_running - - #if self.sectorI_dict['UCN'] > self.I_min or self.sectorI_dict[ + if sector == "UCN": + beam_req_flag = beam_req_running + + # if self.sectorI_dict['UCN'] > self.I_min or self.sectorI_dict[ # 'SINQ'] > self.I_min: if self.sectorI_dict[sector] > self.I_min or beam_req_flag: if self.table_sol_dict[ sector].standby_value_button.isEnabled(): self.table_sol_dict[ sector].standby_value_button.setEnabled(False) - + else: if not self.table_sol_dict[ sector].standby_value_button.isEnabled(): self.table_sol_dict[ sector].standby_value_button.setEnabled(True) - def enable_disable_end(sect, sector_line, value): self.sectorI_dict[sect] = value for sector in sector_line: - #if self.sectorI_dict['UCN'] > self.I_min or self.sectorI_dict[ + # if self.sectorI_dict['UCN'] > self.I_min or self.sectorI_dict[ # 'SINQ'] > self.I_min: if self.sectorI_dict[sector] > self.I_min: if self.table_sol_dict[ @@ -198,13 +217,12 @@ class AppGui(QWidget): sector].standby_value_button.isEnabled(): self.table_sol_dict[ sector].standby_value_button.setEnabled(True) - def enable_disable_pk(sect, sector_line, value): self.sectorI_dict[sect] = value for sector in sector_line: - if self.sectorI_dict['PK1'] > self.I_min or self.sectorI_dict[ - 'PK2'] > self.I_min: + if self.sectorI_dict["PK1"] > self.I_min or self.sectorI_dict[ + "PK2"] > self.I_min: if self.table_sol_dict[ sector].standby_value_button.isEnabled(): self.table_sol_dict[ @@ -214,17 +232,22 @@ class AppGui(QWidget): sector].standby_value_button.isEnabled(): self.table_sol_dict[ sector].standby_value_button.setEnabled(True) - - def receive_ucn_update(value, status, alarm_severity): - enable_disable_ucn('UCN', ucn_line, value) + del status, alarm_severity + enable_disable_ucn("UCN", ucn_line, value) + def receive_sinq_update(value, status, alarm_severity): - enable_disable_end('SINQ', sinq_line, value) + del status, alarm_severity + enable_disable_end("SINQ", sinq_line, value) + def receive_pk1_update(value, status, alarm_severity): - enable_disable_pk('PK1', pk1_line, value) + del status, alarm_severity + enable_disable_pk("PK1", pk1_line, value) + def receive_pk2_update(value, status, alarm_severity): - enable_disable_pk('PK2', pk2_line, value) + del status, alarm_severity + enable_disable_pk("PK2", pk2_line, value) self.gui_header.beam_current_wgt_dict[ "UCN"].trigger_monitor_float.connect(receive_ucn_update) @@ -235,74 +258,151 @@ class AppGui(QWidget): self.gui_header.beam_current_wgt_dict[ "PK2"].trigger_monitor_float.connect(receive_pk2_update) - - def receive_sec_state(handle, pv, pvdata): + # Not required any longer + @Slot(int, str, object) + def receive_sec_state(handle, pv, pvdata): + del handle pvsplit = pv.split("-") secsplit = pvsplit[0].split("Z") sec = secsplit[1] - if pvdata.status == self.cyca.ICAFE_CA_OP_CONN_DOWN: + if pvdata.status == self.cyca.ICAFE_CA_OP_CONN_DOWN: return - - #But is SHIFTTYPE CORRECT? + + # But is SHIFTTYPE CORRECT? #is_shift_type_ok = True #shift_type = self.cafe.getCache("ZORG:SHIFT-TYPE", 'str') - #if shift_type is not None: + # if shift_type is not None: # if shift_type not in ['Produktion', 'Strahlentwicklung']: # is_shift_type_ok = False - + def already_in_standby(): devices = self.settings.data[sec]["iocDevice"] pv_list = [] standby_value_list = [] - + for magnet in devices: pv_list.append(magnet + ":SOL:2") idx = self.settings.data[sec]["device"].index(magnet) standby_value = self.settings.data[sec]["standby"][idx] standby_value_list.append(standby_value) - + value_list, status, status_list = self.cafe.getScalarList( pv_list, cacheFlag=True) - - + if status != self.cyca.ICAFE_NORMAL: self.check_status_list(_pymodule, "getScalarListCache", pv_list, status_list, _line()) - - #check standby values - in_standby = True + + # check standby values + in_standby = True for value, standby in zip(value_list, standby_value_list): - if abs(value) < abs(standby)*0.8 or abs(value) > abs(standby)*1.2: + # if abs(value) < abs(standby)*0.8 or abs(value) > + # abs(standby)*1.2: + if abs(value) > abs(standby) * 1.2: in_standby = False break - + return in_standby - - if pvdata.value[0] == 'ON' and not already_in_standby(): - #print("sec-ON", secsplit[1], flush=True) + + if pvdata.value[0] == "ON" and not already_in_standby(): + print("sec-ON", secsplit[1], flush=True) self.table_sol_dict[sec].init_value_button.setEnabled(True) self.table_pwr_dict[sec].init_value_button.setEnabled(True) else: - #print("sec-OFF", secsplit[1], flush=True) + print("sec-OFF", secsplit[1], flush=True) self.table_sol_dict[sec].init_value_button.setEnabled(False) self.table_pwr_dict[sec].init_value_button.setEnabled(False) - - #print("sec", secsplit[1], flush=True) - - for state in self.sec_state_list: - self.cafe.monitor(state, receive_sec_state) - - - + #print("sec", secsplit[1], flush=True) + + # April 2024 - NOT REQUIRED + # for state in self.sec_state_list: + #### self.cafe.monitor(state, receive_sec_state) + + def get_standby_index_list(self, sec): + devices = self.settings.data[sec]["iocDevice"] + standby_index_list = [] + + for magnet in devices: + # get standby values + idx = self.settings.data[sec]["device"].index(magnet) + standby_index_list.append(idx) + return standby_index_list + + def get_standby_list(self, sec): + devices = self.settings.data[sec]["iocDevice"] + pv_standby_list = [] + for magnet in devices: + pv_magnet = magnet + ":SOL:2" + pv_standby_list.append(pv_magnet) + return pv_standby_list + + def get_standby_dict(self, sec): + devices = self.settings.data[sec]["iocDevice"] + pv_standby_dict = {} + + for magnet in devices: + pv_magnet = magnet + ":SOL:2" + # get standby values + idx = self.settings.data[sec]["device"].index(magnet) + standby_value = self.settings.data[sec]["standby"][idx] + pv_standby_dict[pv_magnet] = standby_value + return pv_standby_dict + + def is_sector_standby(self, sector, pv_name, value): + self.sector_designated_magnet_values_dict[sector][pv_name] = value + #print(self.sector_designated_magnet_values_dict[sector], flush=True) + is_standby = True + for pv in self.sector_designated_magnet_values_dict[sector]: + val_now = self.sector_designated_magnet_values_dict[sector][pv] + val_standby = self.sector_designated_magnet_standby_dict[sector][pv] + #print(sector, val_now, val_standby) + if abs(val_now) > (1.2 * abs(val_standby)): + is_standby = False + break + + with self.lock: + if not is_standby: + if not self.table_sol_dict[sector].init_value_button.isEnabled( + ): + self.table_sol_dict[sector].init_value_button.setEnabled( + True) + + if not self.table_pwr_dict[sector].init_value_button.isEnabled( + ): + self.table_pwr_dict[sector].init_value_button.setEnabled( + True) + else: + if self.table_sol_dict[sector].init_value_button.isEnabled(): + self.table_sol_dict[sector].init_value_button.setEnabled( + False) + if self.table_pwr_dict[sector].init_value_button.isEnabled(): + self.table_pwr_dict[sector].init_value_button.setEnabled( + False) + + + @Slot(float, int, int) + def designated_magnet_cb(self, value, status, alarm_severity): + #print("designated_magnet_cb", status, flush=True) + if status == self.cyca.ICAFE_CA_OP_CONN_DOWN: + return + sender = self.sender() + sector = sender.sector + pv_name = sender.pv_name + # print("local_cb", sender.pv_name, value, status, alarm_severity, + # flush=True) + self.timer.singleShot( + 0, lambda: self.is_sector_standby(sector, pv_name, value)) + #print("designated_magnet_cb end for sector", sector, flush=True) + def group_sector_status(self): qgrid = QGridLayout() - #Connect all channels - #Heading + # Connect all channels + # Heading idx = self.settings.data["header"].index("IP2") - #Sector - + # Sector + qlp = QLabel("Power \n(kW)") f = qlp.font() f.setPixelSize(13) @@ -315,7 +415,7 @@ class AppGui(QWidget): qli.setFont(f) qli.setAlignment(Qt.AlignCenter) qgrid.addWidget(qli, 0, 1, 1, 1) - + qsa = QLabel("Saving \n(MWh)") f = qsa.font() f.setPixelSize(13) @@ -338,41 +438,39 @@ class AppGui(QWidget): qgrid.addWidget(qsa, 0, 3, 1, 1) qgrid.addWidget(qti, 0, 4, 1, 1) qgrid.addWidget(qtotsav, 0, 5, 1, 1) - for i, sector in enumerate(self.settings.data["header"][idx:]): a, b, c, d, e, f = self.sector_status(sector) a.setContentsMargins(2, 0, 0, 0) - qgrid.addWidget(a, i+1, 0, 1, 1) - qgrid.addWidget(b, i+1, 1, 1, 1) - qgrid.addWidget(c, i+1, 2, 1, 1) - qgrid.addWidget(d, i+1, 3, 1, 1) - qgrid.addWidget(e, i+1, 4, 1, 1) - qgrid.addWidget(f, i+1, 5, 1, 1) - _line = QHLine() - _line.setFixedHeight(10) - _row = qgrid.rowCount() - qgrid.addWidget(_line, _row, 1, 1, 5) - #qgrid.setRowMinimumHeight(_row, 60) - + qgrid.addWidget(a, i + 1, 0, 1, 1) + qgrid.addWidget(b, i + 1, 1, 1, 1) + qgrid.addWidget(c, i + 1, 2, 1, 1) + qgrid.addWidget(d, i + 1, 3, 1, 1) + qgrid.addWidget(e, i + 1, 4, 1, 1) + qgrid.addWidget(f, i + 1, 5, 1, 1) + qh_line = QHLine() + qh_line.setFixedHeight(10) + row = qgrid.rowCount() + qgrid.addWidget(qh_line, row, 1, 1, 5) + #qgrid.setRowMinimumHeight(row, 60) qtot = QLabel("Total:") fnt = qtot.font() fnt.setPixelSize(13) qtot.setFont(fnt) - qgrid.addWidget(qtot, _row+1, 0, 1, 1) + qgrid.addWidget(qtot, row + 1, 0, 1, 1) qgrid.addWidget( CAQLineEdit(self, pv_name="ZHIPA-HUSH:LASTPWR", show_units=True), - _row+1, 1, 1, 1) + row + 1, 1, 1, 1) qgrid.addWidget( CAQLineEdit(self, pv_name="ZHIPA-HUSH:TOTPWR", show_units=True), - _row+1, 2, 1, 1) + row + 1, 2, 1, 1) qgrid.addWidget( CAQLineEdit(self, pv_name="ZHIPA-HUSH:LASTSAVE", show_units=False), - _row+1, 3, 1, 1) + row + 1, 3, 1, 1) qgrid.addWidget( CAQLineEdit(self, pv_name="ZHIPA-HUSH:TOTSAVE", show_units=False), - _row+1, 5, 1, 1) + row + 1, 5, 1, 1) qgrid.setContentsMargins(9, 20, 9, 9) @@ -380,93 +478,84 @@ class AppGui(QWidget): qw.setContentsMargins(9, 9, 9, 9) 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 }") - #item.widget().setStyleSheet("background-color: green") #widgets on grid from left to right starting at top rtow + qw.setFixedWidth(496) # 480 + qw.setFixedHeight(346) # 480 + return qw def sector_status(self, sector): '''Create each sector line for inclusion into group ''' - #device = "SEC-" + sector device = "Z" + sector + "-HUSH" - #Qlabel - qsector = QLabel(sector+":") + # Qlabel + qsector = QLabel(sector + ":") f = qsector.font() f.setPixelSize(13) qsector.setFont(f) - _color = "black" + color = "black" try: - _color = self.settings.data[sector]["color"] + color = self.settings.data[sector]["color"] except KeyError as ex: print(ex, self.settings.data[sector]) - _color_str = "color : {0};".format(_color) - _incolor = "QLabel {" + _color_str + "}" - - qsector.setStyleSheet(_incolor) - #Savings - pv_pwr_tot = device + ":TOTPWR" - pv_pwr_last = device + ":LASTPWR" - pv_pwr_saved = device + ":LASTSAVE" + color_str = "color : {0};".format(color) + incolor = "QLabel {" + color_str + "}" + + qsector.setStyleSheet(incolor) + # Savings + pv_pwr_tot = device + ":TOTPWR" + pv_pwr_last = device + ":LASTPWR" + pv_pwr_saved = device + ":LASTSAVE" pv_pwr_timeout = device + ":OFFTIME" - pv_pwr_totsave = device + ":TOTSAVE" - + pv_pwr_totsave = device + ":TOTSAVE" + self.cafe.openPrepare() self.cafe.open([pv_pwr_tot, pv_pwr_last, pv_pwr_saved, pv_pwr_timeout]) self.cafe.openNowAndWait(2.0) time.sleep(0.1) - #print("device", device, flush=True) def cb_outtime(handle, pv, pvdata): - - try: + try: delta = "{}".format(str(timedelta(seconds=(pvdata.value[0])))) if delta == "0:00:00": - delta = "0 s " self.offtime_dict[pv].setAlignment(Qt.AlignRight) - elif ", " in delta: - le_split = _delta.split(", ") + le_split = delta.split(", ") if len(le_split) == 2: if len(le_split[1]) == len("0:00:00"): delta = le_split[0] + ", " + le_split[1] - if 'days,' in delta: - delta = delta.replace("days,", "d") - elif 'day,' in delta: + if "days," in delta: + delta = delta.replace("days,", "d") + elif "day," in delta: delta = delta.replace("day,", "d") - + self.offtime_dict[pv].setText(delta) - + except KeyError: pass - now = QDateTime.currentDateTime() - xdate = QDate(now.date().year(), 1, 15) - xstart = QDateTime(xdate) - + #now = QDateTime.currentDateTime() + #xdate = QDate(now.date().year(), 1, 15) + #xstart = QDateTime(xdate) + qpinit = CAQLineEdit(self, pv_name=pv_pwr_last, show_units=False) qpnow = CAQLineEdit(self, pv_name=pv_pwr_tot, show_units=False) qpsave = CAQLineEdit(self, pv_name=pv_pwr_saved, show_units=False) qptotsave = CAQLineEdit(self, pv_name=pv_pwr_totsave, show_units=False) qptime = CAQLineEdit(self, pv_name=pv_pwr_timeout, - monitor_callback=cb_outtime, show_units=True) + monitor_callback=cb_outtime, show_units=True) self.offtime_dict[pv_pwr_timeout] = qptime - + qptime.setFixedWidth(104) return qsector, qpinit, qpnow, qpsave, qptime, qptotsave def group_sector_qtabwidget(self): - + idx_inj = self.settings.data["header"].index("INJ2") idx = self.settings.data["header"].index("IP2") - #open all PVS + # open all PVS pv = [] for sector in self.settings.data["header"][idx_inj:]: device_list = self.settings.data[sector]["device"] @@ -474,19 +563,20 @@ class AppGui(QWidget): for att in attribute_list: for dev in device_list: pv.append(dev + ":" + att) - + self.cafe.openPrepare() self.cafe.open(pv) self.cafe.openNowAndWait(1.0) - #self.cafe.supplementHandles() - + # self.cafe.supplementHandles() + sector_wgt_dict = {} sector_wgt_dict["INJ2"] = self.ca_table_rf_widget(sector="INJ2") for sector in self.settings.data["header"][idx:]: - sector_wgt_dict[sector] = self.ca_table_sector_widget(sector=sector) - - sector_tab_widget = QTabWidget() + sector_wgt_dict[sector] = self.ca_table_sector_widget( + sector=sector) + + sector_tab_widget = QTabWidget() sector_tab_widget.setFont(self.font_gui) sector_tab_widget.setStyleSheet("QTabBar {font-size: 12pt;}") sector_tab_widget.tabBar().setShape(QTabBar.TriangularNorth) @@ -495,57 +585,55 @@ class AppGui(QWidget): sector_tab_widget.addTab(sector_wgt_dict[sector], sector) color = self.settings.data[sector]["color"] sector_tab_widget.tabBar().setTabTextColor(i, QColor(color)) - + sector_tab_widget.addTab(sector_wgt_dict["INJ2"], "RF") color = self.settings.data["INJ2"]["color"] sector_tab_widget.tabBar().setTabTextColor( len(self.settings.data["header"][idx:]), QColor(color)) - + return sector_tab_widget - - def ca_table_rf_widget(self, sector: str="", color: str="MACHINE"): + def ca_table_rf_widget(self, sector: str = ""): device_list = self.settings.data[sector]["device"] attribute_list = self.settings.data[sector]["attribute"] - + pv_dict = {} for att in attribute_list: - pv_dict[att] = [] #[None] * len(device_list) + pv_dict[att] = [] # [None] * len(device_list) for dev in device_list: pv_dict[att].append(dev + ":" + att) try: - CR1IN_idx = pv_dict['IST:2'].index("CR1IN:IST:2") + CR1IN_idx = pv_dict["IST:2"].index("CR1IN:IST:2") except ValueError: CR1IN_idx = 3 - table_pwr = [None] * 1 ##2 + table_pwr = [None] * 2 table_pwr[0] = CAQTableWidget( - self, pv_list=pv_dict['IST:2'][0:CR1IN_idx], show_units=False, - notify_freq_hz=0, suffix = "MW", + self, pv_list=pv_dict["IST:2"][0:CR1IN_idx], show_units=False, + notify_freq_hz=0, suffix="MW", notify_unison=False, scale_factor=0.001, show_timestamp=False, - init_column=True, pv_list_show=device_list[0:CR1IN_idx]) + init_column=True, pv_list_show=device_list[0:CR1IN_idx]) - - #table_pwr[1] = CAQTableWidget( - # self, pv_list=pv_dict['IST:2'][CR1IN_idx:], show_units=False, - # notify_freq_hz=0, suffix = "MW", - # notify_unison=False, scale_factor=0.001, show_timestamp=False, - # init_column=True, pv_list_show=device_list[CR1IN_idx:]) + table_pwr[1] = CAQTableWidget( + self, pv_list=pv_dict["IST:2"][CR1IN_idx:], show_units=False, + notify_freq_hz=0, suffix="MW", + notify_unison=False, scale_factor=0.001, show_timestamp=False, + init_column=True, pv_list_show=device_list[CR1IN_idx:]) for tab in table_pwr: header_item = QTableWidgetItem() header_init = QTableWidgetItem() - header_standby = QTableWidgetItem() + #header_standby = QTableWidgetItem() header_value = QTableWidgetItem() f = header_value.font() f.setPixelSize(13) header_item.setFont(f) - header_item.setText('Device') + header_item.setText("Device") header_init.setFont(f) - header_init.setText('Init. Value') + header_init.setText("Init. Value") header_value.setFont(f) - header_value.setText('IST:2') + header_value.setText("IST:2") tab.setContentsMargins(15, 0, 15, 10) tab.setHorizontalHeaderItem(0, header_item) tab.setHorizontalHeaderItem(1, header_init) @@ -553,57 +641,58 @@ class AppGui(QWidget): tab.setColumnWidth(0, 80) tab.setColumnWidth(1, 88) tab.setColumnWidth(2, 88) - tab.setFixedWidth(304) - # _table_height = 700 - #tab.setFixedHeight(_table_height) + tab.setFixedWidth(304) + tab.restore_layout.removeWidget(tab.restore_value_button) tab.restore_value_button.deleteLater() - tab.restore_value_button= None - + tab.restore_value_button = None + tab.init_value_button.setToolTip( ("Shows initial, pre-standby values. Update is also " + "executed automatically before the standby procedure.")) - - box = QVBoxLayout() + box = QVBoxLayout() box.addWidget(table_pwr[0]) - ##box.addWidget(table_pwr[1]) - box.setAlignment(Qt.AlignTop | Qt.AlignCenter) + box.addWidget(table_pwr[1]) + box.setAlignment(Qt.AlignTop | Qt.AlignLeft) box.setSpacing(10) qw = QWidget() qw.setLayout(box) - + obj_name = self.settings.data[sector]["colorObj"] if self.obj_to_upper: - obj_name = obj_name.upper() - + obj_name = obj_name.upper() + qw.setObjectName(obj_name) - + return qw - def on_sector_standby(self): + def on_sector_standby(self): target = self.sender() sector = target.sector - _table = self.table_sol_dict[sector] - + table = self.table_sol_dict[sector] + def is_update_enabled(): - '''Check if update buttons are enabled + '''Check if update buttons are enabled if NOT, then do not allow inital values values to be updated" ''' - - if self.table_pwr_dict[sector].init_value_button.isEnabled() \ - and _table.init_value_button.isEnabled(): - return True - else: - return False + return bool( + self.table_pwr_dict[sector].init_value_button.isEnabled( + ) and table.init_value_button.isEnabled()) + + # if self.table_pwr_dict[sector].init_value_button.isEnabled() \ + # and table.init_value_button.isEnabled(): + # return True + # else: + # return False def write_to_restore_ucn(): - if sector != 'UCN': + if sector != "UCN": return - restore_pvs = self.settings.data['RestoreUCN']['PV'] - default_values = self.settings.data['RestoreUCN']['value'] + restore_pvs = self.settings.data["RestoreUCN"]["PV"] + default_values = self.settings.data["RestoreUCN"]["value"] #print(restore_pvs, default_values, flush=True) - values_dict = self.table_sol_dict['UCN'].get_init_values() + values_dict = self.table_sol_dict["UCN"].get_init_values() #print(values_dict, flush=True) values = [] pvs = [] @@ -616,137 +705,140 @@ class AppGui(QWidget): values.append(_val) except KeyError as ex: print("ex", ex) - - + if pvs: status, status_list = self.cafe.setScalarList(pvs, values) if status != self.cyca.ICAFE_NORMAL: self.send_to_log_window(pv_list=pvs, status=status, status_list=status_list, - operation='set', pymodule=_pymodule, + operation="set", pymodule=_pymodule, line=_line()) - - if sector == 'UCN': + if sector == "UCN": write_to_restore_ucn() - QApplication.processEvents(QEventLoop.AllEvents, 1) - - #Do NOT do updates if in standby mode! - #Update button is disabled when in standby - - - #disenable widgets to avoid circular behaviour since - #updates of SOL also update PWR, and vice-versa - #Do not click if already on standby!! + # Do NOT do updates if in standby mode! + # Update button is disabled when in standby - update_enabled = is_update_enabled() - - if update_enabled: + # disenable widgets to avoid circular behaviour since + # updates of SOL also update PWR, and vice-versa + # Do not click if already on standby!! + + with self.lock: + update_enabled = is_update_enabled() + + if update_enabled: + + self.table_pwr_dict[sector].init_value_button.setEnabled(False) + table.init_value_button.click() + time.sleep(0.05) + self.table_pwr_dict[sector].init_value_button.setEnabled(True) + + table.init_value_button.setEnabled(False) + self.table_pwr_dict[sector].init_value_button.click() + time.sleep(0.05) + self.table_sol_dict[sector].init_value_button.setEnabled(True) - self.table_pwr_dict[sector].init_value_button.setEnabled(False) - _table.init_value_button.click() - time.sleep(0.05) - self.table_pwr_dict[sector].init_value_button.setEnabled(True) - - _table.init_value_button.setEnabled(False) - self.table_pwr_dict[sector].init_value_button.click() - time.sleep(0.05) - self.table_sol_dict[sector].init_value_button.setEnabled(True) - QApplication.processEvents(QEventLoop.AllEvents, 1) - - - - if not self.input_parameters['simulation']: - if sector == 'UCN': + + if not self.input_parameters["simulation"]: + if sector == "UCN": write_to_restore_ucn() - status, status_list, pv_list = _table.set_standby_values() - + 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(_pymodule, "setScalarList", - 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 + # Seqeuncer ONLY determines when to go into STANDBY mode + # and NOT the HLA ##pv = 'Z' + target.sector + "-HUSH:STATE" ##stat = self.cafe.set(pv, 0) ##self.check_status(pv, stat, _line()) - - #Disable because _table.set_standby_values() enables it + # Disable because table.set_standby_values() enables it if not update_enabled: - self.table_pwr_dict[sector].init_value_button.setEnabled(False) - _table.init_value_button.setEnabled(False) - - - def on_sector_restore(self): + with self.lock: + self.table_pwr_dict[sector].init_value_button.setEnabled(False) + table.init_value_button.setEnabled(False) + + def on_sector_restore(self): target = self.sender() sector = target.sector - _table = self.table_sol_dict[sector] + table = self.table_sol_dict[sector] + + if not self.input_parameters["simulation"]: + status, status_list, pv_list = table.restore_init_values() - if not self.input_parameters['simulation']: - 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(_pymodule, "getScalarListCache", - 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 - #pv = 'Z' + target.sector + "-HUSH:STATE" + # Seqeuncer ONLY determines when to go into STANDBY mode + # and NOT the HLA + #pv = "Z" + target.sector + "-HUSH:STATE" #stat = self.cafe.set(pv, 1) #self.check_status(pv, stat, _line()) - - _table_pwr = self.table_pwr_dict[sector] - row_pwr_dict = _table_pwr.get_init_values() + table_pwr = self.table_pwr_dict[sector] + row_pwr_dict = table_pwr.get_init_values() sum_pwr = sum(list(row_pwr_dict.values())) - #pv_last_pwr = 'SEC-' + target.sector + ":LASTPWR" - pv_last_pwr = 'Z' + target.sector + "-HUSH:LASTPWR" - + #pv_last_pwr = "SEC-" + target.sector + ":LASTPWR" + 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(_pymodule, "set", pv_last_pwr, stat, _line()) - def ca_table_sector_widget(self, sector: str="", color: str="MACHINE"): + def ca_table_sector_widget(self, sector: str = ""): device_list = self.settings.data[sector]["device"] attribute_list = self.settings.data[sector]["attribute"] try: - _standby_values = self.settings.data[sector]["standby"] + standby_values = self.settings.data[sector]["standby"] except KeyError as ex: - print("On Standby values not given") + print("On Standby values not given", ex) pv_dict = {} for att in attribute_list: - pv_dict[att] = [] #[None] * len(device_list) + pv_dict[att] = [] # [None] * len(device_list) for dev in device_list: pv_dict[att].append(dev + ":" + att) - - _table_height = 700 - + + self.cafe.openPrepare() + # for key, val in pv_dict.items(): + for val in pv_dict.values(): + self.cafe.open(val) + self.cafe.openNowAndWait(2.0) + time.sleep(0.05) + try: - _delay = self.input_parameters["delayRamp"] + _delay = self.input_parameters["delayRamp"] except KeyError: _delay = 0.09 pass + pvlist = self.get_standby_list(sector) + + for pv in pvlist: + value = self.cafe.getCache(pv) + if value is not None: + self.sector_designated_magnet_values_dict[sector][pv] = value + table_sol = CAQTableWidget( - self, pv_list=pv_dict['SOL:2'], show_units=True, notify_freq_hz=0, + self, pv_list=pv_dict["SOL:2"], show_units=True, notify_freq_hz=0, notify_unison=False, scale_factor=1, show_timestamp=False, init_column=True, pv_list_show=device_list, standby_column=True, - standby_values=_standby_values, set_delay = _delay) + standby_values=standby_values, set_delay=_delay) table_sol.restore_value_button.setToolTip( - ("Restore devices to their pre-standby values")) + ("Restore devices to their pre-standby values")) table_sol.init_value_button.setToolTip( - ("Shows initial, pre-standby values. Update is also " + - "executed automatically before the standby procedure.")) + ("Shows initial, pre-standby values. Update is also " + + "executed automatically before the standby procedure.")) table_sol.standby_value_button.sector = sector table_sol.standby_value_button.clicked.disconnect() @@ -754,23 +846,23 @@ 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( - self, pv_list=pv_dict['IST:2'], show_units=True, notify_freq_hz=2, + self, pv_list=pv_dict["IST:2"], show_units=True, notify_freq_hz=2, notify_unison=True, scale_factor=1, show_timestamp=False, init_column=False, pv_list_show=[False]) table_pwr = CAQTableWidget( - self, pv_list=pv_dict['PWR:2'], show_units=False, notify_freq_hz=0, - suffix = "kW", + self, pv_list=pv_dict["PWR:2"], show_units=False, notify_freq_hz=0, + suffix="kW", notify_unison=False, scale_factor=0.001, show_timestamp=False, - init_column=True, init_list=pv_dict['PWR:2'], pv_list_show=[False]) + init_column=True, init_list=pv_dict["PWR:2"], pv_list_show=[False]) table_pwr.init_value_button.setToolTip( - ("Shows initial, pre-standby values. Update is also " + - "executed automatically before the standby procedure.")) + ("Shows initial, pre-standby values. Update is also " + + "executed automatically before the standby procedure.")) self.table_pwr_dict[sector] = table_pwr @@ -781,13 +873,13 @@ class AppGui(QWidget): f = header_value.font() f.setPixelSize(13) header_item.setFont(f) - header_item.setText('Device') + header_item.setText("Device") header_init.setFont(f) - header_init.setText('Init. Value') + header_init.setText("Init. Value") header_standby.setFont(f) - header_standby.setText('Standby') + header_standby.setText("Standby") header_value.setFont(f) - header_value.setText('SOL:2') + header_value.setText("SOL:2") table_sol.setContentsMargins(15, 0, 15, 10) table_sol.setHorizontalHeaderItem(0, header_item) table_sol.setHorizontalHeaderItem(1, header_init) @@ -797,77 +889,83 @@ class AppGui(QWidget): table_sol.setColumnWidth(1, 88) table_sol.setColumnWidth(2, 80) table_sol.setColumnWidth(3, 88) - table_sol.setFixedWidth(386) - + table_sol.setFixedWidth(386) + ioc_magnets = [] for i, device in enumerate(device_list): if device in self.settings.data[sector]["iocDevice"]: ioc_magnets.append(i) - header_value = QTableWidgetItem() f = header_value.font() f.setPixelSize(13) header_value.setFont(f) - header_value.setText('IST:2') + header_value.setText("IST:2") table_ist.setContentsMargins(15, 0, 15, 10) table_ist.setHorizontalHeaderItem(0, header_value) table_ist.setColumnWidth(0, 90) - table_ist.setFixedWidth(140) - + table_ist.setFixedWidth(140) + header_init = QTableWidgetItem() f = header_init.font() header_init.setFont(f) - header_init.setText('Init. Value') + header_init.setText("Init. Value") header_value = QTableWidgetItem() f = header_value.font() f.setPixelSize(13) header_value.setFont(f) - header_value.setText('PWR:2') + header_value.setText("PWR:2") table_pwr.setContentsMargins(15, 0, 15, 10) table_pwr.setHorizontalHeaderItem(0, header_init) table_pwr.setHorizontalHeaderItem(1, header_value) table_pwr.setColumnWidth(0, 88) table_pwr.setColumnWidth(1, 88) - table_pwr.setFixedWidth(226) - - for i in ioc_magnets: - table_sol.paint_rows(row_range=[i, i+1], reset=False, - columns=[0, 1]) - table_ist.paint_rows(row_range=[i, i+1], reset=False) - table_pwr.paint_rows(row_range=[i, i+1], reset=False) + table_pwr.setFixedWidth(226) - pvI = self.settings.data[sector]['current'] + for i in ioc_magnets: + table_sol.paint_rows(row_range=[i, i + 1], reset=False, + columns=[0, 1]) + 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: if I < self.I_min: try: - values = self.settings.data[sector]['ref'] + values = self.settings.data[sector]["ref"] table_sol.set_init_values(values) except KeyError: pass try: - pwr_values = self.settings.data[sector]['pwrref'] - table_pwr.set_init_values(pwr_values) + pwr_values = self.settings.data[sector]["pwrref"] + table_pwr.set_init_values(pwr_values) except KeyError: pass + gateway_indices = self.get_standby_index_list(sector) + + for idx in gateway_indices: + table_sol.pv_gateway[idx].sector = sector + table_sol.pv_gateway[idx].trigger_monitor_float.connect( + self.designated_magnet_cb) + def on_sol_update(): table_sol.init_value_button.setEnabled(False) table_pwr.init_value_button.click() time.sleep(0.1) table_sol.init_value_button.setEnabled(True) #pv = "SEC-" + table_pwr.init_value_button.sector + ":LASTPWR" - pv = "Z" + table_pwr.init_value_button.sector + "-HUSH:LASTPWR" + pv = "Z" + table_pwr.init_value_button.sector + "-HUSH:LASTPWR" _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(_pymodule, "set", pv, stat, _line()) - - def on_init_update(): + + def on_init_update(): table_pwr.init_value_button.setEnabled(False) - table_sol.init_value_button.click() + table_sol.init_value_button.click() time.sleep(0.1) table_pwr.init_value_button.setEnabled(True) @@ -876,25 +974,24 @@ class AppGui(QWidget): table_pwr.init_value_button.sector = sector table_pwr.init_value_button.clicked.connect(on_init_update) - hbox = QHBoxLayout() + hbox = QHBoxLayout() hbox.addWidget(table_sol) hbox.addWidget(table_ist) hbox.addWidget(table_pwr) - + hbox.setSpacing(10) hbox.setAlignment(Qt.AlignTop) qw = QWidget() qw.setLayout(hbox) - + obj_name = self.settings.data[sector]["colorObj"] if self.obj_to_upper: - obj_name = obj_name.upper() - + obj_name = obj_name.upper() + qw.setObjectName(obj_name) return qw - def clear_saving(self, sector_prefix_list: list = None): if not sector_prefix_list: return @@ -910,7 +1007,6 @@ class AppGui(QWidget): if reply == QMessageBox.No: return - self.parent.prepare_elog_message() print("message", self.parent.message, flush=True) print("logbook", self.parent.logbook, flush=True) @@ -934,13 +1030,13 @@ class AppGui(QWidget): attributes["Ort"] = "Global" elif "Strahlentwicklung" in self.parent.logbook: pass - #HIPA Log Book + # HIPA Log Book else: attributes["Eintrag"] = self.elog_enum.eintrag.INFO.name - attributes["Effekt"] = self.elog_enum.effekt.NONE.name #keiner - #"Elektorversogung" + attributes["Effekt"] = self.elog_enum.effekt.NONE.name # keiner + # "Elektorversogung" attributes["System"] = self.elog_enum.system.ELECTRICAL_SUPPLY.name - attributes["Ort"] = self.elog_enum.ort.GLOBAL.name + attributes["Ort"] = self.elog_enum.ort.GLOBAL.name log_mess = self.parent.message.replace("
", "\n") @@ -964,7 +1060,6 @@ class AppGui(QWidget): 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 @@ -975,7 +1070,6 @@ class AppGui(QWidget): QApplication.processEvents() return - def clear_sector_saving(self, sector_prefix: str = None): if not sector_prefix: return @@ -1014,16 +1108,20 @@ class AppGui(QWidget): 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.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) @@ -1064,7 +1162,7 @@ class AppGui(QWidget): 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_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) @@ -1092,30 +1190,33 @@ class AppGui(QWidget): qw.setFixedHeight(280) return qw - - + def reset_lastpwr(self): - sector_label = [None] * len(self.sec_state_list) + sector_label = [None] * len(self.sec_state_list) pv_initpwr = [None] * len(self.sec_state_list) pv_lastpwr = [None] * len(self.sec_state_list) - + qgrid = QGridLayout() qsection = QLabel("Section") - qsection.setAlignment(Qt.AlignmentFlag(Qt.AlignBottom|Qt.AlignHCenter)) + qsection.setAlignment( + Qt.AlignmentFlag( + Qt.AlignBottom | Qt.AlignHCenter)) qnominal = QLabel("Nominal \n Value (kW)") - qnominal.setAlignment(Qt.AlignmentFlag(Qt.AlignBottom|Qt.AlignHCenter)) + qnominal.setAlignment( + Qt.AlignmentFlag( + Qt.AlignBottom | Qt.AlignHCenter)) qset = QLabel("Set \n Value (kW)") - qset.setAlignment(Qt.AlignmentFlag(Qt.AlignBottom|Qt.AlignHCenter)) - + qset.setAlignment(Qt.AlignmentFlag(Qt.AlignBottom | Qt.AlignHCenter)) + qgrid.addWidget(qsection, 0, 0, 1, 1) qgrid.addWidget(qnominal, 0, 1, 1, 1) qgrid.addWidget(qset, 0, 2, 1, 1) - + for i, pv in enumerate(self.sec_state_list): pvsplit = pv.split("-") sector = pvsplit[0][1:] sum_pwr = round(sum(self.settings.data[sector]["pwrref"]), 3) - pv_initpwr_value = decimal.Decimal(format(sum_pwr, '.3f')) + pv_initpwr_value = decimal.Decimal(format(sum_pwr, ".3f")) pv_lastpwr_name = pv.replace("STATE", "LASTPWR") qsector = QLabel(sector + ":") @@ -1128,26 +1229,24 @@ class AppGui(QWidget): except KeyError as ex: print(ex, self.settings.data[sector]) - weight = "medium" + weight = "medium" color_str = "color : {0}; font-weight:{1};".format(color, weight) incolor = "QLabel {" + color_str + "}" qsector.setStyleSheet(incolor) - + sector_label[i] = qsector - ql = QLabel(str(pv_initpwr_value)) + ql = QLabel(str(pv_initpwr_value)) ql.setFont(f) pv_initpwr[i] = ql ca_qtext_entry = CAQTextEntry(self, pv_name=pv_lastpwr_name) f = ca_qtext_entry.font() f.setPixelSize(8) - ca_qtext_entry.setFont(f) + ca_qtext_entry.setFont(f) pv_lastpwr[i] = ca_qtext_entry qgrid.addWidget(sector_label[i], i + 1, 0, 1, 1, Qt.AlignLeft) qgrid.addWidget(pv_initpwr[i], i + 1, 1, 1, 1, Qt.AlignRight) qgrid.addWidget(pv_lastpwr[i], i + 1, 2, 1, 1, Qt.AlignLeft) - #print("GRID", pv_lastpwr[i].font().pixelSize()) - qgrid.setContentsMargins(9, 9, 9, 9) qgrid.setSpacing(10) @@ -1161,4 +1260,3 @@ class AppGui(QWidget): qw.setFixedHeight(280) return qw - diff --git a/wakeup.py b/wakeup.py new file mode 100644 index 0000000..e97f361 --- /dev/null +++ b/wakeup.py @@ -0,0 +1,57 @@ +'''Precedes splashscreen of main application +''' +import sys +import time + +from qtpy.QtCore import Qt, QTime, QTimer +from qtpy.QtGui import QColor, QImage, QPainter, QPixmap +from qtpy.QtWidgets import QApplication, QLabel + +from pyqtacc.qrc_resources.facility.proscan.pyrcc5 import qrc_resources + + +app = QApplication(sys.argv) + +try: + due = QTime.currentTime() + message = "HUSH! will begin to load shortly" + if len(sys.argv) < 2: + raise ValueError + hours, mins = sys.argv[1].split(":") + due = QTime(int(hours), int(mins)) + if not due.isValid(): + raise ValueError + if len(sys.argv) > 2: + message = " ".join(sys.argv[2:]) +except ValueError: + message = "Usage: wakeup.py HH:MM [optional message]" + + +while QTime.currentTime() < due: + time.sleep(1) + +image = QImage(":/Hush.jpg") +p = QPainter(image) +font = p.font() +font.setPixelSize(54) +p.setFont(font) +p.setPen(QColor(Qt.red)) +#p.setStyleSheet("color:red;") +#p.save() +p.drawText(40, 350, message) +#p.restore() + +pixmap = QPixmap.fromImage(image) + +label = QLabel() +label.setPixmap(pixmap) +label.setScaledContents(True) + +label.setWindowFlags(Qt.SplashScreen) +label.setAlignment(Qt.AlignCenter) +label.setFixedHeight(600) +label.setFixedWidth(600) +label.show() +QTimer.singleShot(5000, app.quit) #5 seconds + +app.exec_()