def remove_device_info(self, uid): tab_id = self.tab_for_uid(uid) device_info = inventory.get_info(uid) device_info.plugin.stop_plugin() device_info.plugin.destroy_plugin() if tab_id >= 0: self.tab_widget.removeTab(tab_id) # ensure that the widget gets correctly destroyed. otherwise QWidgets # tend to leak as Python is not able to collect their PyQt object tab_window = device_info.tab_window device_info.tab_window = None # If we reboot the RED Brick, the tab_window sometimes is # already None here if tab_window != None: tab_window.hide() tab_window.setParent(None) plugin = device_info.plugin device_info.plugin = None if plugin != None: plugin.hide() plugin.setParent(None) inventory.remove_info(uid)
def cb_statistics(self, statistics): self.label_messages_from_brick.setText( str(statistics.messages_from_brick)) self.label_messages_from_bricklet.setText( str(statistics.messages_from_bricklet)) try: name = inventory.get_info(statistics.connected_bricklet_uid ).plugin.device_class.DEVICE_DISPLAY_NAME except: name = None if statistics.connected_bricklet_uid != '' and name != None: self.label_isolated_bricklet.setText( '<b>{0}</b> with UID "{1}"'.format( name, statistics.connected_bricklet_uid)) self.button_bricklet.setText('Open {0}'.format(name)) if self.last_connected != statistics.connected_bricklet_uid: self.last_connected = statistics.connected_bricklet_uid try: self.button_bricklet.clicked.disconnect() except: pass self.button_bricklet.clicked.connect(lambda: get_main_window( ).show_plugin(statistics.connected_bricklet_uid)) self.button_bricklet.setEnabled(True) else: self.label_isolated_bricklet.setText( 'Unknown Bricklet (Did you connect a Bricklet?)') self.button_bricklet.setText('Open Bricklet') self.button_bricklet.setEnabled(False)
def update_metric_values(self, parent=None): if not self.isVisible(): return self.update_metric_values_timer.stop() if parent == None: parent = self.tree_view_model.invisibleRootItem() def make_async_call(info, uid, index): async_call( info.plugin.get_health_metric_values, None, lambda metric_values: self.get_health_metric_values_async( uid, index, metric_values), lambda: self.get_health_metric_values_error(uid, index)) # FIXME: avoid getter burst! for r in range(parent.rowCount()): child = parent.child(r, 0) index = child.index() uid = parent.child(r, 1).text() info = inventory.get_info(uid) if info == None: # FIXME: unknown UID, remove row or mark it as broken? continue make_async_call(info, uid, index) self.update_metric_values(parent=child) async_call(lambda: None, None, self.update_metric_values_timer.start, None)
def remove_device_tab(self, uid): device_info = inventory.get_info(uid) if device_info == None: return assert isinstance(device_info, DeviceInfo) self.tab_widget.setCurrentIndex(0) self.remove_device_info(device_info.uid) for other_info in inventory.get_device_infos(): other_info.connections_remove_value(device_info) self.update_tree_view()
def start_async(self): self.update_address = 0 self.update_address_slave = 0 def get_rs485_address_async(address_async): self.update_address = address_async next(self.update_generator) def get_rs485_slave_address_async(update_address_slave_async): self.update_address_slave = update_address_slave_async next(self.update_generator) async_call(self.master.get_rs485_address, None, get_rs485_address_async, self.parent.increase_error_count) yield address_slave = [] for i in range(32): async_call(self.master.get_rs485_slave_address, i, get_rs485_slave_address_async, self.parent.increase_error_count) yield if self.update_address_slave == 0: break else: address_slave.append(str(self.update_address_slave)) address_slave_text = ', '.join(address_slave) typ = 0 if self.update_address == 0: typ = 1 # trigger enumerate for rs485 slaves if inventory.get_info( self.parent.uid ).enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED: self.parent.ipcon.enumerate() self.lineedit_slave_addresses.setText(address_slave_text) self.address_spinbox.setValue(self.update_address) self.save_button.clicked.connect(self.save_clicked) self.rs485_type.currentIndexChanged.connect(self.rs485_type_changed) self.rs485_type.setCurrentIndex(typ) self.rs485_type_changed(typ)
def hack_to_remove_red_brick_tab(self, uid): device_info = inventory.get_info(uid) if device_info == None: return assert isinstance(device_info, DeviceInfo) self.tab_widget.setCurrentIndex(0) self.remove_device_info(device_info.uid) self.red_session_losts += 1 self.label_red_session_losts.setText( 'RED Brick Session Loss Count: {0}'.format(self.red_session_losts)) self.label_red_session_losts.show() self.update_tree_view()
def show_plugin(self, uid): device_info = inventory.get_info(uid) if device_info == None: return index = self.tab_for_uid(uid) tab_window = device_info.tab_window if index > 0 and self.tab_widget.isTabEnabled(index): self.tab_widget.setCurrentIndex(index) QApplication.setActiveWindow(tab_window) tab_window.show() tab_window.activateWindow() tab_window.raise_() return device_info.plugin
def update_bricklets(self): info = inventory.get_info(self.uid) if info == None: return for i in range(4): port = chr(ord('a') + i) try: bricklet = info.connections_get(port)[0] text = '{0} ({1})'.format(bricklet.name, bricklet.uid) if text != self.ports[i].text(): self.ports[i].setText(text) self.ports[i].setProperty('_bricklet_uid', bricklet.uid) self.ports[i].setEnabled(True) except: self.ports[i].setText('Not Connected') self.ports[i].setProperty('_bricklet_uid', None) self.ports[i].setEnabled(False)
def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if self.ipcon.get_connection_state( ) != IPConnection.CONNECTION_STATE_CONNECTED: # ignore enumerate callbacks that arrived after the connection got closed return if enumeration_type in [ IPConnection.ENUMERATION_TYPE_AVAILABLE, IPConnection.ENUMERATION_TYPE_CONNECTED ]: device_info = inventory.get_info(uid) # If the enum_type is CONNECTED, the bricklet was restarted externally. # The plugin could now be in an inconsistent state. if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED and device_info is not None: if device_info.connected_uid != connected_uid: # Fix connections if bricklet was connected to another brick. parent_info = inventory.get_info(device_info.connected_uid) if parent_info is not None: parent_info.connections_remove_item( (device_info.position, device_info)) self.show_status( "Hot plugging is not supported! Please reset Brick with UID {} and reconnect Brick Viewer." .format(device_info.connected_uid), message_id='mainwindow_hotplug') device_info.reverse_connection = connected_uid elif device_info.position != position: # Bricklet was connected to the same brick, but to another port self.show_status( "Hot plugging is not supported! Please reset Brick with UID {} and reconnect Brick Viewer." .format(device_info.connected_uid), message_id='mainwindow_hotplug') # If the plugin is not running, pause will do nothing, so it is always save to call it. # The plugin will be (unconditionally) resumed later, as resume also only does something # if it was paused before (e.g. here). if device_info.plugin is not None: device_info.plugin.pause_plugin() if device_info == None: if device_identifier == BrickMaster.DEVICE_IDENTIFIER: device_info = BrickMasterInfo() elif device_identifier == BrickRED.DEVICE_IDENTIFIER: device_info = BrickREDInfo() elif hat_brick_supported and device_identifier == BrickHAT.DEVICE_IDENTIFIER: device_info = BrickHATInfo() elif hat_zero_brick_supported and device_identifier == BrickHATZero.DEVICE_IDENTIFIER: device_info = BrickHATZeroInfo() elif device_identifier == BrickletIsolator.DEVICE_IDENTIFIER: device_info = BrickletIsolatorInfo() elif str(device_identifier).startswith('20'): device_info = TNGInfo() elif '0' <= position <= '9': device_info = BrickInfo() else: device_info = BrickletInfo() position = position.lower() device_info.uid = uid device_info.connected_uid = connected_uid device_info.position = position device_info.hardware_version = hardware_version if device_identifier != BrickRED.DEVICE_IDENTIFIER: device_info.firmware_version_installed = firmware_version device_info.device_identifier = device_identifier device_info.enumeration_type = enumeration_type # Update connections and reverse_connection with new device for info in inventory.get_device_infos(): if info == device_info: continue def add_to_connections(info_to_add, connected_info): hotplug = connected_info.connections_add_item( (info_to_add.position, info_to_add)) info_to_add.reverse_connection = connected_info # '0' is the port where other stacks connected by RS485 extensions are connected. Multiple connections are allowed here. if hotplug and info_to_add.position != '0': self.show_status( "Hot plugging is not supported! Please reset Brick with UID {} and reconnect Brick Viewer." .format(connected_info.uid), message_id='mainwindow_hotplug') if info.uid != '' and info.uid == device_info.connected_uid: if device_info in info.connections_values( ): # device was already connected, but to another port info.connections_remove_value(device_info) if device_info not in info.connections_get( device_info.position): add_to_connections(device_info, info) if info.connected_uid != '' and info.connected_uid == device_info.uid: if info in device_info.connections_values( ): # device was already connected, but to another port device_info.connections_remove_value(info) if info not in device_info.connections_get(info.position): add_to_connections(info, device_info) if device_info.plugin == None: self.plugin_manager.create_plugin_instance( device_identifier, self.ipcon, device_info) device_info.tab_window = self.create_tab_window( device_info, self.ipcon) device_info.tab_window.setWindowFlags(Qt.Widget) device_info.tab_window.tab() inventory.add_info(device_info) device_info.update_firmware_version_latest() inventory.sync() # The plugin was paused before if it was reconnected. device_info.plugin.resume_plugin() elif enumeration_type == IPConnection.ENUMERATION_TYPE_DISCONNECTED: self.remove_device_tab(uid)
def start_async(self): self.update_address = 0 self.update_chibi_slave_address = 0 self.update_chibi_master_address = 0 self.update_chibi_frequency = 0 self.update_chibi_channel = 0 def get_chibi_address_async(address_async): self.update_address = address_async next(self.update_generator) def get_chibi_slave_address_async(chibi_slave_address_async): self.update_chibi_slave_address = chibi_slave_address_async next(self.update_generator) def get_chibi_master_address_async(chibi_master_address_async): self.update_chibi_master_address = chibi_master_address_async next(self.update_generator) def get_chibi_frequency_async(chibi_frequency_async): self.update_chibi_frequency = chibi_frequency_async next(self.update_generator) def get_chibi_channel_async(chibi_channel_async): self.update_chibi_channel = chibi_channel_async next(self.update_generator) async_call(self.master.get_chibi_address, None, get_chibi_address_async, self.parent.increase_error_count) yield address_slave = [] for i in range(32): async_call(self.master.get_chibi_slave_address, i, get_chibi_slave_address_async, self.parent.increase_error_count) yield if self.update_chibi_slave_address == 0: break else: address_slave.append(str(self.update_chibi_slave_address)) address_slave_text = ', '.join(address_slave) async_call(self.master.get_chibi_master_address, None, get_chibi_master_address_async, self.parent.increase_error_count) yield async_call(self.master.get_chibi_frequency, None, get_chibi_frequency_async, self.parent.increase_error_count) yield async_call(self.master.get_chibi_channel, None, get_chibi_channel_async, self.parent.increase_error_count) yield typ = 0 if self.update_address == self.update_chibi_master_address: typ = 1 # trigger enumerate for chibi slaves if inventory.get_info(self.parent.uid).enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED: self.parent.ipcon.enumerate() self.lineedit_slave_address.setText(address_slave_text) self.address_spinbox.setValue(self.update_address) self.master_address_spinbox.setValue(self.update_chibi_master_address) self.chibi_frequency.setCurrentIndex(self.update_chibi_frequency) self.chibi_channel.setCurrentIndex(self.update_chibi_channel) self.save_button.clicked.connect(self.save_clicked) self.chibi_type.currentIndexChanged.connect(self.chibi_type_changed) self.chibi_frequency.currentIndexChanged.connect(self.chibi_frequency_changed) self.chibi_channel.currentIndexChanged.connect(self.chibi_channel_changed) self.chibi_type.setCurrentIndex(typ) self.chibi_type_changed(typ) self.new_max_count()