class DirectViewWindow(QtGui.QMainWindow): ''' View Window that can be connected to a simulation ''' def __init__(self, views, *args, **kwargs): QtGui.QMainWindow.__init__(self, *args, **kwargs) ''' 1. members ''' self.builder = GBuilder() ''' 2. initialize the gui factories ''' self.view_plugins = views ''' 3. actions ''' self.init_actions() self.create_widgets() @try_ex def create_widgets(self): ''' 1. Main window ''' self.setWindowTitle('TUMCreate - Automotive Simulator - Direct View') self.setWindowIcon(QtGui.QIcon(os.path.join(os.path.dirname(__file__), r'../icons/tumcreatelogo2.png'))) self.builder.set_props(self, ctr_lout=True, min_sz_x=1200, min_sz_y=700) ''' 2. Two Group Boxes ''' self.groupb_info = self.builder.groupbox(self, 'Information', max_height=200, max_width=2000) self.set_info_group() self.groupb_viewer = self.builder.groupbox(self, 'View') self.set_viewer_group() ''' 3. Init Menubar ''' self.init_menubar(); ''' 4. Toolbar''' self.toolbar_gen_sets = self.builder.toolbar(self, GEnums.T_TOP, actions=self.gen_set_actions) ''' 5. Create Layout''' self.init_layout() @try_ex def init_actions(self): ''' 1. Create General Settings''' self.exit_action = QtGui.QAction(QtGui.QIcon(os.path.join(os.path.dirname(__file__), r'../icons/exit.png')), '&Exit', self) self.exit_action.setShortcut('Ctrl+Q') self.exit_action.setStatusTip('Exit application') self.exit_action.triggered.connect(QtGui.qApp.quit) self.help_action = QtGui.QAction(QtGui.QIcon(os.path.join(os.path.dirname(__file__), r'../icons/help.png')), '&Help', self) self.help_action.setShortcut('F3') self.help_action.setStatusTip('Open Help') self.help_action.triggered.connect(QtGui.qApp.quit) self.clear_action = QtGui.QAction(QtGui.QIcon(os.path.join(os.path.dirname(__file__), r'../icons/clear.png')), '&Clear all parameters', self) self.clear_action.setShortcut('Ctrl+Shift+N') self.clear_action.setStatusTip('Open Help') self.clear_action.triggered.connect(QtGui.qApp.quit) self.load_action = QtGui.QAction(QtGui.QIcon(os.path.join(os.path.dirname(__file__), r'../icons/load.png')), '&Clear all parameters', self) self.load_action.setShortcut('Ctrl+Shift+L') self.load_action.setStatusTip('Load file') self.load_action.triggered.connect(self._load_views_hit) ''' 2. define all actions that will appear in the general Toolbar ''' self.gen_set_actions = [self.clear_action, self.help_action, self.load_action] @try_ex def init_layout(self): ''' Sets the layout for the three main groupboxes ''' main_layout = self.centralWidget().layout() h_layout = QtGui.QHBoxLayout() h_layout.addWidget(self.groupb_info) main_layout.addLayout(h_layout) main_layout.addWidget(self.groupb_viewer) @try_ex def init_menubar(self): ''' 1. Create Menubar''' menubar = self.menuBar() ''' 2. add Menus and actions''' # File file_menu = menubar.addMenu('&File') file_menu.addAction(self.exit_action) # Help help_menu = menubar.addMenu('&Help') help_menu.addAction(self.help_action) def link_axis(self): link_plot = False for view in self.view_plugins: # check if there are link axis p = view.link_axis() if p != None: if link_plot: p.setXLink(link_plot) else: link_plot = p @try_ex def set_cb_changed_event_set(self): self.settings_stack.setCurrentIndex(self.settings_cbox.currentIndex()) @try_ex def set_info_group(self): ''' 1. Logo''' self.space = QtGui.QLabel() self.info_label = QtGui.QLabel("\nTitle: \t%s \nAuthor: \t%s\nCompany:\t%s\nDepartement:\t%s\nVersion: \t%s" % (__title__, __author__, __enterprise__, __departement__ , __version__)) self.space.setFixedWidth(10) self.info_logo = self.builder.image(self.groupb_info, os.path.dirname(__file__)[:-4] + r'/icons/tumcreatelogo.png', 2.4) self.info_logo.setMaximumWidth(270) ''' 2. Description Text ''' self.desc_txt = self.builder.label(self.groupb_info, "<b>Description: </b>" + '\n\nThis application simulates an automotive environment. It offers the possibility to perform timing analyses of communication flows between a certain number of ECUs.') ''' 3. Groupbox Layout''' v_layout = QtGui.QVBoxLayout(self.groupb_info) h_layout_one = QtGui.QHBoxLayout() h_layout_one.addWidget(self.space) h_layout_one.addWidget(self.info_label) h_layout_one.addWidget(self.info_logo) v_layout.addLayout(h_layout_one) v_layout.addWidget(self.desc_txt) @try_ex def set_cb_changed_event_view(self, e): # check which items are selected and show all of them try: # clear all try: for ky in self.wid_to_idx: self.wid_to_idx[ky].setParent(None) except: ECULogger().log_traceback() # get checked items checked_idx = [] for cnt in range(self.viewer_cbox.count()): item = self.viewer_cbox.model().item(cnt, 0) if item.checkState(): checked_idx.append(cnt) row_nr = int(self.arrange_rows.text()) col_nr = int(self.arrange_cols.text()) if row_nr * col_nr < len(checked_idx): row_nr = ceil(float(len(checked_idx)) / col_nr) self.arrange_rows.setText(str(row_nr)) # arrange cnt = 0 for r in range(row_nr): hlay = QHBoxLayout() for c in range(col_nr): try: wid = self.wid_to_idx[checked_idx[cnt]]; cnt += 1 hlay.addWidget(wid) except: pass try: self.main_v_layout.addLayout(hlay) except: pass except: pass @try_ex def set_viewer_group(self): ''' 1. Load Items from viewer factory ''' self.wid_to_idx = {} self.viewer_cbox = self.builder.checkable_combobox(self.groupb_viewer, [], self.set_cb_changed_event_view) self.save_but = self.builder.pushbutton(self.groupb_viewer, "Save", self._save_hit) self.save_but.setFixedWidth(100) # field to enter arrangement [lay_r, self.arrange_rows] = self.builder.label_text(self.groupb_viewer, "rows:", 25, 40, self.set_cb_changed_event_view) self.arrange_rows.setText('2') [lay_c, self.arrange_cols] = self.builder.label_text(self.groupb_viewer, "columns:", 40, 40, self.set_cb_changed_event_view) self.arrange_cols.setText('2') cnt = 0 for view in self.view_plugins: if view != None: self.viewer_cbox.addItem(view.get_combobox_name()) item = self.viewer_cbox.model().item(cnt, 0) item.setCheckState(QtCore.Qt.Checked) self.wid_to_idx[cnt] = view.get_widget(self) cnt += 1 ''' Layout ''' self.main_v_layout = QVBoxLayout() self.viewer_cbox.setFixedHeight(25) hl = QHBoxLayout() hl.addWidget(self.viewer_cbox) hl.addLayout(lay_r) hl.addLayout(lay_c) hl.addWidget(self.save_but) self.main_v_layout.addLayout(hl) self.groupb_viewer.setLayout(self.main_v_layout) self.set_cb_changed_event_view(None) def _load_views_hit(self, filename=False): if not filename: filename = QtGui.QFileDialog.getOpenFileName(self, 'Load', '', 'Simulation (*.tum)') with open(filename, 'rb') as f: save_vals = pickle.load(f) for view in self.view_plugins: if view != None: try: save_val = save_vals[view.get_combobox_name()] except: logging.warn("Warning: On GUI load no saved values found for %s" % view.__class__.__name__) # ECULogger().log_traceback() continue view.load(save_val) def _save_hit(self): save_vals = {} for view in self.view_plugins: if view != None: try: print("Call save on %s" % view) save_val = view.save() print("OK!") except: ECULogger().log_traceback() continue save_vals[view.get_combobox_name()] = save_val filename = QtGui.QFileDialog.getSaveFileName(self, "Save file", "", ".tum") with open(filename, 'wb') as f: pickle.dump(save_vals, f, pickle.HIGHEST_PROTOCOL)
class ECUMessagesViewPluginGUI(dockarea.DockArea): def __init__(self, parent): dockarea.DockArea.__init__(self) self.builder = GBuilder() self.widget_index = {} self.widget_text = {} self.dock_index = {} self._external_core = CheckpointInterpreterCore() self._information_box_items = ['Time', 'Associated Id', 'Monitor Tag', 'Message Id', 'Message', 'Size', 'Stream Id', 'Monitor Data', 'Description'] self._information_checked = {'Time': True, 'Associated Id': True, 'Monitor Tag': True, 'Message Id': True, 'Message': True, 'Size': True, 'Stream Id': False, 'Monitor Data': False, 'Description': True} self._info_widget_index = {} self.known = [] self.create_widgets(parent) def _already_there(self, mon_input): ''' handles duplicates''' if hash(mon_input) in self.known: return True self.known.append(hash(mon_input)) if len(self.known) > 1000: del self.known[:floor(float(len(self.known)) / 2.0)] return False def create_widgets(self, parent): h_layout = QHBoxLayout() self.viewer_cbox = self.builder.checkable_combobox(parent, [], self._set_cb_changed) self.information_cbox = self.builder.checkable_combobox(parent, [], self._set_information_changed) self.information_cbox.setFixedWidth(150) cnt = 0 for info in self._information_box_items: self.information_cbox.addItem(info) new_row = self.information_cbox.count() - 1 item = self.information_cbox.model().item(new_row, 0) if self._information_checked[info]: item.setCheckState(QtCore.Qt.Checked) else: item.setCheckState(QtCore.Qt.Unchecked) self._info_widget_index[cnt] = info cnt += 1 h_layout.addWidget(self.viewer_cbox) h_layout.addItem(QSpacerItem(10, 10)) h_layout.addWidget(self.information_cbox) # add ecu selection self.label_top = QtGui.QLabel() self.label_top.setText("Message View") self.viewDock = dockarea.Dock('view', size=(1000, 600)) self.layout.addWidget(self.label_top) self.label_top.setFixedHeight(20) self.layout.addLayout(h_layout) self.layout.addItem(QSpacerItem(10, 10)) def _set_information_changed(self, e): # get checked items checked_idx = [] for cnt in range(self.information_cbox.count()): item = self.information_cbox.model().item(cnt, 0) if item.checkState(): checked_idx.append(cnt) # checked items set them for idx in self._info_widget_index.keys(): info = self._info_widget_index[idx] if idx in checked_idx: self._information_checked[info] = True else: self._information_checked[info] = False def _add_items_ecu_ids(self, ecu_ids): items = [] for ecu_id in ecu_ids: try: items += [self.add_item(ecu_id)] except: pass if not items: return for i in items: i.setCheckState(QtCore.Qt.Unchecked) items[0].setCheckState(QtCore.Qt.Checked) self._set_cb_changed(None) def add_item(self, title_text): # add item to dock new_widget = QTextEdit() new_widget.setText("") new_widget.setReadOnly(True) new_dock = dockarea.Dock(title_text, size=(1000, 20)) new_dock.setOrientation('horizontal') new_dock.addWidget(new_widget) self.addDock(new_dock, 'right') # add item to combobox self.viewer_cbox.addItem(title_text) new_row = self.viewer_cbox.count() - 1 item = self.viewer_cbox.model().item(new_row, 0) item.setCheckState(QtCore.Qt.Checked) # link items self.widget_index[new_row] = new_widget self.widget_text[title_text] = new_widget self.dock_index[new_row] = new_dock return item def _set_cb_changed(self, e): # clear all try: for ky in self.dock_index: self.dock_index[ky].setParent(None) except: ECULogger().log_traceback() # get checked items checked_idx = [] for cnt in range(self.viewer_cbox.count()): item = self.viewer_cbox.model().item(cnt, 0) if item.checkState(): checked_idx.append(cnt) for ky in range(self.viewer_cbox.count()): # selected draw if ky in checked_idx: self.addDock(self.dock_index[ky], 'right') self.widget_index[ky].verticalScrollBar().setValue(self.widget_index[ky].verticalScrollBar().maximum()); def save(self): return [] def load(self, val_pairs): pass def update_gui(self, monitor_input_list): # receive the ecu ids try: if isinstance(monitor_input_list[0], str): return constellation = monitor_input_list[0].data ecu_groups = constellation[0] ecu_ids = [e.ecu_id for e in APICore()._ecu_list_from_groups(ecu_groups)] self._add_items_ecu_ids(ecu_ids) return except: pass monitor_input_list.sort(key=lambda x: x[0], reverse=False) # receive simple inputs for monitor_input in monitor_input_list: # read information time = monitor_input[0] ecu_id = monitor_input[1] associated_id = monitor_input[2] tag = eval(monitor_input[3]) message_id = monitor_input[4] message = monitor_input[5] message_size = monitor_input[6] stream_id = monitor_input[7] unique_id = monitor_input[8] input_data = monitor_input[9] description = self._external_core.cp_string(tag, associated_id, stream_id, message) # get textedit text_edit = self.widget_text[ecu_id] # current_text = text_edit.toPlainText() # create new text part_append = "" if self._information_checked['Time']: part_append += "\n\nTime: \t%s" % time if self._information_checked['Associated Id']: part_append += "\nAssociated Id: \t%s" % associated_id if self._information_checked['Monitor Tag']: part_append += "\nMonitor Tag: \t%s" % tag if self._information_checked['Message Id']: part_append += "\nMessage Id: \t%s" % message_id if self._information_checked['Message']: part_append += "\nMessage: \t%s" % message if self._information_checked['Size']: part_append += "\nSize: \t%s" % message_size if self._information_checked['Stream Id']: part_append += "\nStream Id: \t%s" % stream_id if self._information_checked['Monitor Data']: part_append += "\nMonitor Data: \t%s" % input_data if self._information_checked['Description']: part_append += "\nDescription: \t%s" % description # add new part text_edit.append(part_append) # current_text += part_append # text_edit.setText(current_text) text_edit.verticalScrollBar().setValue(text_edit.verticalScrollBar().maximum());
class MessageCountViewPluginGUI(dockarea.DockArea): def __init__(self, parent): dockarea.DockArea.__init__(self) self.builder = GBuilder() self._bin = {} self.widget_index = {} self.widget_text = {} self.send_plot_text = {} self.rec_plot_text = {} self.dock_index = {} self._ecu_ids = [] self._information_box_items = ["a"] self._info_widget_index = {} self._init_tag_list() self.known = [] self.create_widgets(parent) # def _already_there(self, mon_input): # ''' handles duplicates''' # if hash(mon_input) in self.known: # return True # self.known.append(hash(mon_input)) # if len(self.known) > 1000: # del self.known[:floor(float(len(self.known)) / 2.0)] # return False def create_widgets(self, parent): h_layout = QHBoxLayout() self.viewer_cbox = self.builder.checkable_combobox(parent, [], self._set_cb_changed) h_layout.addWidget(self.viewer_cbox) h_layout.addItem(QSpacerItem(10, 10)) # add ecu selection self.label_top = QtGui.QLabel() self.label_top.setText("Message View: green: received messages red: send message") self.viewDock = dockarea.Dock('view', size=(1000, 600)) self.layout.addWidget(self.label_top) self.label_top.setFixedHeight(20) self.layout.addLayout(h_layout) self.layout.addItem(QSpacerItem(10, 10)) def _add_items_ecu_ids(self, ecu_ids): items = [] for ecu_id in ecu_ids: try: items += [self.add_item(ecu_id)] except: pass if not items: return for i in items: i.setCheckState(QtCore.Qt.Unchecked) items[0].setCheckState(QtCore.Qt.Checked) self._set_cb_changed(None) def _set_cb_changed(self, e): # clear all try: for ky in self.dock_index: self.dock_index[ky].setParent(None) except: ECULogger().log_traceback() # get checked items checked_idx = [] for cnt in range(self.viewer_cbox.count()): item = self.viewer_cbox.model().item(cnt, 0) if item.checkState(): checked_idx.append(cnt) for ky in range(self.viewer_cbox.count()): # selected draw if ky in checked_idx: self.addDock(self.dock_index[ky], 'right') self.widget_index[ky].verticalScrollBar().setValue(self.widget_index[ky].verticalScrollBar().maximum()); def add_item(self, title_text): # add item to dock new_dock = dockarea.Dock(title_text, size=(1000, 20)) new_dock.setOrientation('horizontal') widget, send_plot = self._new_plot_widget(new_dock) new_dock.addWidget(widget) self.addDock(new_dock, 'right') # add item to combobox self.viewer_cbox.addItem(title_text) new_row = self.viewer_cbox.count() - 1 item = self.viewer_cbox.model().item(new_row, 0) item.setCheckState(QtCore.Qt.Checked) # link items self.widget_index[new_row] = widget self.widget_text[title_text] = widget self.send_plot_text[title_text] = send_plot self.dock_index[new_row] = new_dock return item def _new_plot_widget(self, parent): widget = pg.GraphicsLayoutWidget(parent) # self.axis = ECUShowAxis(orientation='left') send_plot = widget.addPlot() # axisItems={'left': self.axis}) send_plot.setLabel('left', 'Number of messages') send_plot.setLabel('bottom', 'Message ID') send_plot.showGrid(x=True, y=True) x = [] y = [] try: barGraphItem = pg.BarGraphItem(x=x, height=y, width=0.5) send_plot.addItem(barGraphItem) except: ECULogger().log_traceback() # send_plot.plot(x, y, stepMode=True, fillLevel=0, brush=(0, 0, 255, 150)) # rec_plot.plot(x, y, stepMode=True, fillLevel=0, brush=(255, 0, 0, 150)) return widget, barGraphItem def save(self): data = {} data["ecu ids"] = self._ecu_ids data["bin"] = self._bin return data def load(self, data): self._ecu_ids = data["ecu ids"] self._bin = data["bin"] self._add_items_ecu_ids(self._ecu_ids) self._plot_bin() def _init_tag_list(self): # NO TESLA TAGS HERE YET! self._sent_tags = [MonitorTags.CP_SEC_ECNRYPTED_CONFIRMATION_MESSAGE, MonitorTags.CP_SEC_INIT_AUTHENTICATION, MonitorTags.CP_SEC_ENCRYPTED_DENY_MESSAGE, MonitorTags.CP_SEC_ENCRYPTED_GRANT_MESSAGE, MonitorTags.CP_ECU_INTENT_SEND_SIMPLE_MESSAGE, MonitorTags.CP_ECU_SEND_REG_MESSAGE, MonitorTags.CP_ECU_ENCRYPTED_REQ_MESSAGE, MonitorTags.CP_SEND_CLIENT_HELLO, MonitorTags.CP_SEND_SERVER_HELLO, MonitorTags.CP_SEND_SERVER_CERTIFICATE, MonitorTags.CP_SEND_SERVER_KEYEXCHANGE, MonitorTags.CP_SEND_CERTIFICATE_REQUEST, MonitorTags.CP_SEND_SERVER_HELLO_DONE, MonitorTags.CP_SEND_CLIENT_CERTIFICATE, MonitorTags.CP_ENCRYPTED_CERTIFICATE_VERIFY, MonitorTags.CP_SEND_CIPHER_SPEC, MonitorTags.CP_GENERATED_HASH_FROM_PRF_CLIENT_FINISHED, MonitorTags.CP_SESSION_AVAILABLE_SEND_MESSAGE, MonitorTags.CP_SETUP_FINISHED_CREATE_KEYS, MonitorTags.CP_INIT_TRANSMIT_MESSAGE, MonitorTags.CP_SEND_SYNC_MESSAGE, MonitorTags.CP_SEND_SYNC_RESPONSE_MESSAGE, MonitorTags.CP_ENCRYPTED_EXCHANGE_FIRST_KEY_KN] self._received_tags = [MonitorTags.CP_SEC_RECEIVE_REG_MESSAGE, MonitorTags.CP_SEC_RECEIVE_REQ_MESSAGE, MonitorTags.CP_ECU_RECEIVE_SIMPLE_MESSAGE, MonitorTags.CP_ECU_RECEIVE_SEC_MOD_ADVERTISEMENT, MonitorTags.CP_ECU_RECEIVE_CONF_MESSAGE, MonitorTags.CP_ECU_RECEIVE_DENY_MESSAGE, MonitorTags.CP_ECU_RECEIVE_GRANT_MESSAGE, MonitorTags.CP_RECEIVE_CLIENT_HELLO, MonitorTags.CP_RECEIVE_SERVER_HELLO, MonitorTags.CP_RECEIVE_SERVER_CERTIFICATE, MonitorTags.CP_RECEIVE_SERVER_KEYEXCHANGE, MonitorTags.CP_RECEIVE_CERTIFICATE_REQUEST, MonitorTags.CP_RECEIVE_SERVER_HELLO_DONE, MonitorTags.CP_RECEIVE_CLIENT_CERTIFICATE, MonitorTags.CP_RECEIVE_CLIENT_KEYEXCHANGE, MonitorTags.CP_DECRYPTED_CERTIFICATE_VERIFY, MonitorTags.CP_RECEIVED_CHANGE_CIPHER_SPEC, MonitorTags.CP_RECEIVE_CLIENT_FINISHED, MonitorTags.CP_RECEIVE_SERVER_FINISHED, MonitorTags.CP_GENERATED_HASH_FROM_PRF_SERVER_FINISHED, MonitorTags.CP_RECEIVE_SIMPLE_MESSAGE, MonitorTags.CP_RECEIVED_SIMPLE_MESSAGE, MonitorTags.CP_RECEIVED_EXCHANGE_FIRST_KEY_KN, MonitorTags.CP_RECEIVE_SYNC_RESPONSE_MESSAGE, MonitorTags.CP_RECEIVE_SYNC_MESSAGE] @try_ex def update_gui(self, monitor_input_list): # receive the ecu ids: show only the once selected then try: if isinstance(monitor_input_list[0], str): return constellation = monitor_input_list[0].data ecu_groups = constellation[0] self._ecu_ids = [e.ecu_id for e in APICore()._ecu_list_from_groups(ecu_groups)] self._add_items_ecu_ids(self._ecu_ids) return except: pass try: monitor_input_list.sort(key=lambda x: x[0], reverse=False) except: pass # receive simple inputs for monitor_input in monitor_input_list: # if self._already_there(monitor_input): continue # read information ecu_id = monitor_input[1] tag = eval(monitor_input[3]) message_id = monitor_input[4] stream_id = message_id # monitor_input[7] if stream_id in [-1, 0]: continue if tag in self._sent_tags: add_tag = 'sender' elif tag in self._received_tags: add_tag = 'receiver' else: continue if not General().four_dict_exists(self._bin, ecu_id, stream_id, add_tag): General().add_to_four_dict(self._bin, ecu_id, stream_id, add_tag, 1) else: self._bin[ecu_id][stream_id][add_tag] += 1 # workaround tesla if tag == MonitorTags.CP_SEND_SYNC_RESPONSE_MESSAGE: if not General().four_dict_exists(self._bin, ecu_id, can_registration.CAN_TESLA_TIME_SYNC, "receiver"): General().add_to_four_dict(self._bin, ecu_id, can_registration.CAN_TESLA_TIME_SYNC, "receiver", 1) else: self._bin[ecu_id][can_registration.CAN_TESLA_TIME_SYNC]["receiver"] += 1 # show updated self._plot_bin() def _plot_bin(self): # collect information for ecu_id in self._bin.keys(): x_values_send = [] y_values_send = [] color = [] for stream_id in self._bin[ecu_id].keys(): if stream_id == -1: continue # sender or receiver color? add_tag = list(self._bin[ecu_id][stream_id].keys())[0] x_values_send += [stream_id] y_values_send += [self._bin[ecu_id][stream_id][add_tag]] if add_tag == 'sender': color += [QColor(255, 0, 0)] elif add_tag == 'receiver': color += [QColor(0, 255, 0)] else: continue try: # send self.send_plot_text[ecu_id].setOpts(x=x_values_send, height=y_values_send, width=0.5, brushes=color) except KeyError: pass except: ECULogger().log_traceback()