""" The Alarms ui loader class container file """ # Python import os from datetime import datetime # Qt from PySide2 import QtWidgets from PySide2.QtCore import Slot, QTimer, Qt # parent from simulator.dynamicloader import DynamicLoader # hd Simulator from simulator.interface import SimulationInterface # plugin specific from dialin.common.prs_defs import AlarmPriority class Loader(DynamicLoader): """ The Alarms ui loader class """ canMaximize = True timer: QTimer btnTrigger: QtWidgets.QPushButton btnClear: QtWidgets.QPushButton btnCondition: QtWidgets.QPushButton spnAlarmID: QtWidgets.QSpinBox tblStatusIDs: QtWidgets.QTableWidget btnSend: QtWidgets.QPushButton btnMute: QtWidgets.QPushButton spnTopID: QtWidgets.QSpinBox rdoPriorityNone: QtWidgets.QToolBox rdoPriorityLow: QtWidgets.QToolBox rdoPriorityMed: QtWidgets.QToolBox rdoPriorityHigh: QtWidgets.QToolBox spnEscalatesIn: QtWidgets.QSpinBox spnMuteTimeout: QtWidgets.QSpinBox lstFlags: QtWidgets.QListWidget tblTriggeredIDs: QtWidgets.QTableWidget cbFieldDescriptor1: QtWidgets.QComboBox cbFieldDescriptor2: QtWidgets.QComboBox leDataField1: QtWidgets.QLineEdit leDataField2: QtWidgets.QLineEdit btnAccept: QtWidgets.QPushButton btnReject: QtWidgets.QPushButton spnReason: QtWidgets.QSpinBox spnP0: QtWidgets.QSpinBox spnP1: QtWidgets.QSpinBox spnP2: QtWidgets.QSpinBox spnP3: QtWidgets.QSpinBox spnP4: QtWidgets.QSpinBox spnP5: QtWidgets.QSpinBox spnP6: QtWidgets.QSpinBox spnP7: QtWidgets.QSpinBox spnP8: QtWidgets.QSpinBox spnP9: QtWidgets.QSpinBox priority = AlarmPriority.ALARM_HIGH flags = 0 eColTime = 0 eColID = 1 eColMute = 2 eColEscalate = 3 eColFlags = 4 eColMessage = 5 eColCount = 6 eRowMute = 9 # column: (width, text) fixedLabels = { eColTime: (70, 'Time'), eColID: (45, 'Top ID'), eColMute: (100, 'Mute'), eColEscalate: (45, 'Escl'), eColFlags: (150, 'Flags'), eColMessage: (100, 'Message'), } colors = { AlarmPriority.ALARM_NONE: Qt.green, AlarmPriority.ALARM_LOW: Qt.yellow, AlarmPriority.ALARM_MED: Qt.yellow, AlarmPriority.ALARM_HIGH: Qt.red } styles = { AlarmPriority.ALARM_NONE: 'rgb(78, 154, 6)', AlarmPriority.ALARM_LOW: 'rgb(237, 212, 0)', AlarmPriority.ALARM_MED: 'rgb(237, 212, 0)', AlarmPriority.ALARM_HIGH: 'rgb(239, 41, 41)' } def __init__(self, interface: SimulationInterface): super().__init__(os.path.dirname(__file__), interface) def _init_loader(self): """ finds and creates widgets :return: none """ self.btnSend = self.find_button('btnSend') self.btnMute = self.find_button('btnMute') self.spnTopID = self.find_spinbox('spnTopID') self.rdoPriorityNone = self.find_tool_button('rdoPriorityNone') self.rdoPriorityLow = self.find_tool_button('rdoPriorityLow') self.rdoPriorityMed = self.find_tool_button('rdoPriorityMed') self.rdoPriorityHigh = self.find_tool_button('rdoPriorityHigh') self.spnEscalatesIn = self.find_spinbox('spnEscalatesIn') self.spnMuteTimeout = self.find_spinbox('spnMuteTimeout') self.lstFlags = self.find_list_widget('lstFlags') self.tblStatusIDs = self.find_table_widget('tblStatusIDs') self.btnTrigger = self.find_button('btnTrigger') self.btnClear = self.find_button('btnClear') self.btnCondition = self.find_button('btnCondition') self.spnAlarmID = self.find_spinbox('spnAlarmID') self.tblTriggeredIDs = self.find_table_widget('tblTriggeredIDs') self.cbFieldDescriptor1 = self.find_combobox('cbFieldDescriptor1') self.cbFieldDescriptor2 = self.find_combobox('cbFieldDescriptor2') self.leDataField1 = self.find_line_edit('leDataField1') self.leDataField2 = self.find_line_edit('leDataField2') self.btnAccept = self.find_button('btnAccept') self.btnReject = self.find_button('btnReject') self.spnReason = self.find_spinbox('spnReason') self.spnP0 = self.find_spinbox('spnP0') self.spnP1 = self.find_spinbox('spnP1') self.spnP2 = self.find_spinbox('spnP2') self.spnP3 = self.find_spinbox('spnP3') self.spnP4 = self.find_spinbox('spnP4') self.spnP5 = self.find_spinbox('spnP5') self.spnP6 = self.find_spinbox('spnP6') self.spnP7 = self.find_spinbox('spnP7') self.spnP8 = self.find_spinbox('spnP8') self.spnP9 = self.find_spinbox('spnP9') def _init_widgets(self): """ initializes the widgets' properties :return: none """ self.timer = QTimer() self.timer.start(1000) self.__populate_status_ids_columns() self.rdoPriorityNone.setStyleSheet('background-color: {};'.format(self.styles[AlarmPriority.ALARM_NONE])) self.rdoPriorityLow.setStyleSheet('background-color: {};'.format(self.styles[AlarmPriority.ALARM_LOW])) self.rdoPriorityMed.setStyleSheet('background-color: {};'.format(self.styles[AlarmPriority.ALARM_MED])) self.rdoPriorityHigh.setStyleSheet('background-color: {};'.format(self.styles[AlarmPriority.ALARM_HIGH])) self.tblTriggeredIDs.setColumnWidth(0, 75) self.tblTriggeredIDs.setColumnWidth(1, 45) def _init_connections(self): """ initializes the widgets connections :return: """ self.timer.timeout.connect(self.do_timer_timeout) self.btnTrigger.clicked.connect(self.do_trigger) self.btnClear.clicked.connect(self.do_clear) self.btnCondition.clicked.connect(self.do_clear_condition) self.tblTriggeredIDs.itemClicked.connect(self.on_trigger_ids_item_clicked) self.btnSend.clicked.connect(self.do_send) self.btnMute.clicked.connect(self.do_mute) # item clicked might be enough self.tblStatusIDs.itemClicked.connect(self.on_status_ids_item_clicked) self.rdoPriorityNone.toggled.connect(self.do_set_priority_none) self.rdoPriorityLow.toggled.connect(self.do_set_priority_low) self.rdoPriorityMed.toggled.connect(self.do_set_priority_med) self.rdoPriorityHigh.toggled.connect(self.do_set_priority_high) self.btnAccept.clicked.connect(self.do_active_list_accept) self.btnReject.clicked.connect(self.do_active_list_reject) def set_flags(self): """ the slot for flags :return: none """ highest = False lst = self.lstFlags for i in range(lst.count()): if highest: bit = pow(2, 15 - i) else: bit = pow(2, i) if lst.item(i).checkState() == Qt.Checked: self.flags |= bit else: self.flags &= ~bit @Slot() def do_timer_timeout(self) -> None: """ one second timer to send the alarm status at all the time like what FW does but in lower frequency :return: None """ # self.do_send() @Slot() def do_set_priority_none(self): """ the slot for priority buttons :return: none """ self.priority = AlarmPriority.ALARM_NONE @Slot() def do_set_priority_low(self): """ the slot for priority buttons :return: none """ self.priority = AlarmPriority.ALARM_LOW @Slot() def do_set_priority_med(self): """ the slot for priority buttons :return: none """ self.priority = AlarmPriority.ALARM_MED @Slot() def do_set_priority_high(self): """ the slot for priority buttons :return: none """ self.priority = AlarmPriority.ALARM_HIGH @Slot() def do_send(self): """ the slot for send button :return: none """ alarm_id = self.spnTopID.value() escalate = self.spnEscalatesIn.value() mute_out = self.spnMuteTimeout.value() if alarm_id >= 0: self.set_flags() self.interface.alarm.cmd_activate_alarm_id( self.priority, alarm_id, escalate, mute_out, self.flags ) self.__append_status_ids_row(alarm_id) @Slot() def do_trigger(self): """ the slot for trigger button :return: none """ alarm_id = self.spnAlarmID.value() field_descriptor_1 = self.cbFieldDescriptor1.currentIndex() data_field_1 = self.leDataField1.text() if data_field_1 == "": data_field_1 = "0" field_descriptor_2 = self.cbFieldDescriptor2.currentIndex() data_field_2 = self.leDataField2.text() if data_field_2 == "": data_field_2 = "0" if alarm_id: self.interface.alarm.cmd_set_alarm_triggered( alarm_id, field_descriptor_1, data_field_1, field_descriptor_2, data_field_2) self.__append_triggered_row(alarm_id) @Slot() def do_clear(self): """ the slot for clear button :return: none """ [alarm_id, row] = self.alarm_id() self.interface.alarm.cmd_set_alarm_cleared(alarm_id) self.tblTriggeredIDs.removeRow(row) @Slot() def do_clear_condition(self): """ the slot for condition button :return: none """ [alarm_id, row] = self.alarm_id() self.interface.alarm.cmd_set_alarm_cleared_condition(alarm_id) self.tblTriggeredIDs.item(row, self.eColID).setBackground(self.colors[AlarmPriority.ALARM_NONE]) self.tblTriggeredIDs.item(row, self.eColID).setSelected(False) @Slot() def do_mute(self, value): """ the slot for mute button :return: none """ print(self.lstFlags.item(self.eRowMute).checkState()) if self.lstFlags.item(self.eRowMute).checkState() == Qt.CheckState.Unchecked: self.lstFlags.item(self.eRowMute).setCheckState(Qt.CheckState.Checked) else: self.lstFlags.item(self.eRowMute).setCheckState(Qt.CheckState.Unchecked) self.do_send() @Slot() def do_active_list_accept(self): """ the slot for mute button :return: none """ a0 = self.spnP0.value() a1 = self.spnP1.value() a2 = self.spnP2.value() a3 = self.spnP3.value() a4 = self.spnP4.value() a5 = self.spnP5.value() a6 = self.spnP6.value() a7 = self.spnP7.value() a8 = self.spnP8.value() a9 = self.spnP9.value() self.interface.alarm.cmd_send_active_list_response(True, 0, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) @Slot() def do_active_list_reject(self): """ the slot for mute button :return: none """ reason = self.spnReason.value() self.interface.alarm.cmd_send_active_list_response(False, reason) @Slot() def on_status_ids_item_clicked(self, item: QtWidgets.QTableWidgetItem): """ slot to handle on item clicked :param item: the clicked item :return: None """ selected = item.isSelected() @Slot() def on_trigger_ids_item_clicked(self, item: QtWidgets.QTableWidgetItem): """ slot to handle on item clicked :param item: the clicked item :return: None """ selected = item.isSelected() self.btnClear.setEnabled(selected) self.btnCondition.setEnabled(selected) def __populate_status_ids_columns(self): """ adds alarm flags as columns in the Status alarms table :return: None """ items = sorted(self.fixedLabels.items()) self.tblStatusIDs.setColumnCount(self.eColCount) self.tblStatusIDs.setHorizontalHeaderLabels([v[1] for k, v in items]) for col, item in items: self.tblStatusIDs.setColumnWidth(col, item[0]) def __append_status_ids_row(self, alarm_id): """ appends the Status alarm id into the Status list :return: None """ inset_at_top = True now = datetime.now().strftime("%H:%M:%S") items = self.tblStatusIDs.findItems(str(alarm_id), Qt.MatchExactly) if len(items): item: QtWidgets.QTableWidgetItem = items[0] row = item.row() else: row = 0 if inset_at_top else self.tblStatusIDs.rowCount() self.tblStatusIDs.insertRow(row) model = self.tblStatusIDs.model() model.setData(model.index(row, self.eColTime), now) model.setData(model.index(row, self.eColID), alarm_id) model.setData(model.index(row, self.eColMute), self.spnMuteTimeout.value()) model.setData(model.index(row, self.eColEscalate), self.spnEscalatesIn.value()) self.tblStatusIDs.item(row, self.eColMute).setCheckState(Qt.Unchecked) model.setData(model.index(row, self.eColMessage), "N/A") model.setData(model.index(row, self.eColFlags), '{:016b}'.format(self.flags, 'b')) self.tblStatusIDs.item(row, self.eColID).setBackground(self.colors[self.priority]) def __append_triggered_row(self, alarm_id): """ appends the triggered alarm id into the triggered list :return: None """ inset_at_top = True now = datetime.now().strftime("%H:%M:%S") items = self.tblTriggeredIDs.findItems(str(alarm_id), Qt.MatchExactly) if len(items): item: QtWidgets.QTableWidgetItem = items[0] row = item.row() else: row = 0 if inset_at_top else self.tblTriggeredIDs.rowCount() self.tblTriggeredIDs.insertRow(row) model = self.tblTriggeredIDs.model() model.setData(model.index(row, self.eColTime), now) model.setData(model.index(row, self.eColID), alarm_id) self.tblTriggeredIDs.item(row, self.eColID).setBackground(self.colors[AlarmPriority.ALARM_HIGH]) def alarm_id(self): """ gets the alarm id from the list of the triggered id list :return: """ row = 0 alarm_id = 0 items = self.tblTriggeredIDs.selectedItems() if len(items): item: QtWidgets.QTableWidgetItem = items[0] row = item.row() model = self.tblTriggeredIDs.model() alarm_id = model.data(model.index(row, self.eColID)) return [alarm_id, row]