def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() if self.firmware_version >= (1, 1, 0): self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) else: self.check_extensions = False self.extension_type_button.setEnabled(False) if self.firmware_version >= (1, 2, 1): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.master.reset()) self.set_actions(reset) self.extension_type_preset = [None, False, False, False, False, False] self.update_extensions_in_device_info() def update_extensions_in_device_info(self): def is_present_async(present, extension_type, name): self.extension_type_preset[extension_type] = present if present: if self.device_info.extensions['ext0'] == None: ext = 'ext0' elif self.device_info.extensions['ext1'] == None: ext = 'ext1' else: return # This should never be the case self.device_info.extensions[ext] = infos.ExtensionInfo() self.device_info.extensions[ext].name = name self.device_info.extensions[ext].extension_type = extension_type self.device_info.extensions[ext].position = ext self.device_info.extensions[ext].master_info = self.device_info infos.update_info(self.uid) def get_wifi2_firmware_version_async(version, ext): self.device_info.extensions[ext].firmware_version_installed = version infos.update_info(self.uid) get_main_window().update_tree_view() # FIXME: this is kind of a hack self.is_wifi2_present_async(True) if extension_type == self.master.EXTENSION_TYPE_WIFI2: self.device_info.extensions[ext].url_part = 'wifi_v2' ''' When WIFI2 extension firmware version is being requested the extension might still not be done with booting and thus the message won't be received by the extension. So we delay sending the request which gives enough time to the extension to finish booting. Note that this delay is only induced when there is a WIFI2 extension present. ''' time.sleep(2) async_call(self.master.get_wifi2_firmware_version, None, lambda v: get_wifi2_firmware_version_async(v, ext), self.increase_error_count) def get_connection_type_async(connection_type): self.device_info.connection_type = connection_type infos.update_info(self.uid) if self.firmware_version >= (1, 1, 0): async_call(self.master.is_chibi_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_CHIBI, 'Chibi Extension'), self.increase_error_count) if self.firmware_version >= (1, 2, 0): async_call(self.master.is_rs485_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_RS485, 'RS485 Extension'), self.increase_error_count) if self.firmware_version >= (1, 3, 0): async_call(self.master.is_wifi_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_WIFI, 'WIFI Extension'), self.increase_error_count) if self.firmware_version >= (2, 1, 0): async_call(self.master.is_ethernet_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_ETHERNET, 'Ethernet Extension'), self.increase_error_count) if self.firmware_version >= (2, 4, 0): async_call(self.master.is_wifi2_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_WIFI2, 'WIFI Extension 2.0'), self.increase_error_count) async_call(self.master.get_connection_type, None, get_connection_type_async, self.increase_error_count) async_call(lambda: None, None, lambda: get_main_window().update_tree_view(), None) def is_wifi2_present_async(self, present): if present: wifi2 = Wifi2(self) self.extensions.append(wifi2) self.tab_widget.addTab(wifi2, 'WIFI 2.0') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() ''' Check if the master brick and WIFI extension 2 firmware versions support mesh networking feature. Also set firmware version information for the WIFI2 extension 2 object. ''' for ext in self.device_info.extensions: if not self.device_info.extensions[ext]: continue if self.device_info.extensions[ext].name != 'WIFI Extension 2.0': continue wifi2.wifi2_firmware_version = \ self.device_info.extensions[ext].firmware_version_installed if self.device_info.extensions[ext].firmware_version_installed >= (2, 0, 4) \ and self.firmware_version >= (2, 4, 2): wifi2.wifi_mode.addItem('Mesh') wifi2.get_current_status() break def is_ethernet_present_async(self, present): if present: ethernet = Ethernet(self) self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, 'Ethernet') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_wifi_present_async(self, present): if present: wifi = Wifi(self) self.extensions.append(wifi) self.tab_widget.addTab(wifi, 'WIFI') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_rs485_present_async(self, present): if present: rs485 = RS485(self) self.extensions.append(rs485) self.tab_widget.addTab(rs485, 'RS485') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_chibi_present_async(self, present): if present: chibi = Chibi(self) self.extensions.append(chibi) self.tab_widget.addTab(chibi, 'Chibi') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.check_extensions: self.check_extensions = False self.is_chibi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_CHIBI]) self.is_rs485_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_RS485]) self.is_wifi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI]) self.is_ethernet_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_ETHERNET]) ''' For WIFI extension 2, self.is_ethernet_present_async() isn't called here but called from the async callback, get_wifi2_firmware_version_async(). This is to ensure that both the master brick and WIFI extension 2 firmware versions are avilable before creating the tab widget of the extension. This is required because WIFI extension 2 supports mesh networking for which the GUI is updated dynamically only when the version information is available. ''' self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True def get_url_part(self): return 'master' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.get_stack_voltage_async, self.increase_error_count) async_call(self.master.get_stack_current, None, self.get_stack_current_async, self.increase_error_count) for extension in self.extensions: extension.update_data() def get_stack_voltage_async(self, voltage): self.stack_voltage_label.setText('{:g} V'.format(round(voltage / 1000.0, 1))) def get_stack_current_async(self, current): self.stack_current_label.setText(format_current(current / 1000.0)) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.wifi2_get_firmware_version_timer = QTimer() self.wifi2_get_firmware_version_timer.timeout.connect( self.wifi2_get_firmware_version) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.wifi2_ext = None self.wifi2_firmware_version = None self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() if self.firmware_version >= (1, 1, 0): self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) else: self.check_extensions = False self.extension_type_button.setEnabled(False) if self.firmware_version >= (2, 3, 2): self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.master.enable_status_led() if checked else self.master.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None if self.firmware_version >= (1, 2, 1): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.master.reset()) self.set_actions([(0, None, [reset])]) self.extension_type_preset = [ None, # None False, # Chibi False, # RS485 False, # WIFI False, # Ethernet False ] # WIFI 2.0 self.update_extensions_in_device_info() def update_extensions_in_device_info(self): def is_present_async(present, extension_type, name): self.extension_type_preset[extension_type] = present if present: if self.device_info.extensions['ext0'] == None: ext = 'ext0' elif self.device_info.extensions['ext1'] == None: ext = 'ext1' else: return # This should never be the case self.device_info.extensions[ext] = infos.ExtensionInfo() self.device_info.extensions[ext].name = name self.device_info.extensions[ ext].extension_type = extension_type self.device_info.extensions[ext].position = ext self.device_info.extensions[ext].master_info = self.device_info infos.update_info(self.uid) if extension_type == self.master.EXTENSION_TYPE_WIFI2: self.device_info.extensions[ext].url_part = 'wifi_v2' # When WIFI2 extension firmware version is being requested the # extension might still not be done with booting and thus the # message won't be received by the extension. So we delay sending # the request which gives enough time to the extension to finish # booting. Note that this delay is only induced when there is a # WIFI2 extension present. self.wifi2_ext = ext self.label_no_extension.setText( 'Waiting for WIFI Extension 2.0 firmware version...') self.wifi2_get_firmware_version_timer.start(2000) def get_connection_type_async(connection_type): self.device_info.connection_type = connection_type infos.update_info(self.uid) if self.firmware_version >= (1, 1, 0): async_call( self.master.is_chibi_present, None, lambda p: is_present_async( p, self.master.EXTENSION_TYPE_CHIBI, 'Chibi Extension'), self.increase_error_count) if self.firmware_version >= (1, 2, 0): async_call( self.master.is_rs485_present, None, lambda p: is_present_async( p, self.master.EXTENSION_TYPE_RS485, 'RS485 Extension'), self.increase_error_count) if self.firmware_version >= (1, 3, 0): async_call( self.master.is_wifi_present, None, lambda p: is_present_async( p, self.master.EXTENSION_TYPE_WIFI, 'WIFI Extension'), self.increase_error_count) if self.firmware_version >= (2, 1, 0): async_call( self.master.is_ethernet_present, None, lambda p: is_present_async( p, self.master.EXTENSION_TYPE_ETHERNET, 'Ethernet Extension'), self.increase_error_count) if self.firmware_version >= (2, 4, 0): async_call( self.master.is_wifi2_present, None, lambda p: is_present_async( p, self.master.EXTENSION_TYPE_WIFI2, 'WIFI Extension 2.0'), self.increase_error_count) async_call(self.master.get_connection_type, None, get_connection_type_async, self.increase_error_count) async_call(lambda: None, None, lambda: get_main_window().update_tree_view(), None) def get_wifi2_firmware_version_async(self, version): self.wifi2_firmware_version = version self.device_info.extensions[ self.wifi2_ext].firmware_version_installed = version infos.update_info(self.uid) get_main_window().update_tree_view() # FIXME: this is kind of a hack self.wifi2_present(True) def wifi2_get_firmware_version(self): if self.wifi2_firmware_version != None: return self.wifi2_get_firmware_version_timer.stop() async_call(self.master.get_wifi2_firmware_version, None, self.get_wifi2_firmware_version_async, self.increase_error_count) def wifi2_present(self, present): if present and self.wifi2_firmware_version != None and not self.check_extensions: wifi2 = Wifi2(self.wifi2_firmware_version, self) wifi2.start() self.extensions.append(wifi2) self.tab_widget.addTab(wifi2, 'WIFI 2.0') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def ethernet_present(self, present): if present: ethernet = Ethernet(self) ethernet.start() self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, 'Ethernet') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def wifi_present(self, present): if present: wifi = Wifi(self) wifi.start() self.extensions.append(wifi) self.tab_widget.addTab(wifi, 'WIFI') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def rs485_present(self, present): if present: rs485 = RS485(self) rs485.start() self.extensions.append(rs485) self.tab_widget.addTab(rs485, 'RS485') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def chibi_present(self, present): if present: chibi = Chibi(self) chibi.start() self.extensions.append(chibi) self.tab_widget.addTab(chibi, 'Chibi') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.firmware_version >= (2, 3, 2): async_call(self.master.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) if self.check_extensions: self.check_extensions = False self.chibi_present( self.extension_type_preset[self.master.EXTENSION_TYPE_CHIBI]) self.rs485_present( self.extension_type_preset[self.master.EXTENSION_TYPE_RS485]) self.wifi_present( self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI]) self.ethernet_present(self.extension_type_preset[ self.master.EXTENSION_TYPE_ETHERNET]) self.wifi2_present( self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]) self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.get_stack_voltage_async, self.increase_error_count) async_call(self.master.get_stack_current, None, self.get_stack_current_async, self.increase_error_count) for extension in self.extensions: extension.update_data() def get_stack_voltage_async(self, voltage): self.stack_voltage_label.setText('{:g} V'.format( round(voltage / 1000.0, 1))) def get_stack_current_async(self, current): self.stack_current_label.setText(format_current(current / 1000.0)) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() if self.firmware_version >= (1, 1, 0): self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) else: self.check_extensions = False self.extension_type_button.setEnabled(False) if self.firmware_version >= (1, 2, 1): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.master.reset()) self.set_actions(reset) self.extension_type_preset = [None, False, False, False, False, False] self.update_extensions_in_device_info() def update_extensions_in_device_info(self): def is_present_async(present, extension_type, name): self.extension_type_preset[extension_type] = present if present: if self.device_info.extensions['ext0'] == None: ext = 'ext0' elif self.device_info.extensions['ext1'] == None: ext = 'ext1' else: return # This should never be the case self.device_info.extensions[ext] = infos.ExtensionInfo() self.device_info.extensions[ext].name = name self.device_info.extensions[ext].extension_type = extension_type self.device_info.extensions[ext].position = ext self.device_info.extensions[ext].master_info = self.device_info infos.update_info(self.uid) def get_wifi2_firmware_version_async(version, ext): self.device_info.extensions[ext].firmware_version_installed = version infos.update_info(self.uid) if extension_type == self.master.EXTENSION_TYPE_WIFI2: self.device_info.extensions[ext].url_part = 'wifi_v2' async_call(self.master.get_wifi2_firmware_version, None, lambda v: get_wifi2_firmware_version_async(v, ext), self.increase_error_count) def get_connection_type_async(connection_type): self.device_info.connection_type = connection_type infos.update_info(self.uid) if self.firmware_version >= (1, 1, 0): async_call(self.master.is_chibi_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_CHIBI, 'Chibi Extension'), self.increase_error_count) if self.firmware_version >= (1, 2, 0): async_call(self.master.is_rs485_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_RS485, 'RS485 Extension'), self.increase_error_count) if self.firmware_version >= (1, 3, 0): async_call(self.master.is_wifi_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_WIFI, 'WIFI Extension'), self.increase_error_count) if self.firmware_version >= (2, 1, 0): async_call(self.master.is_ethernet_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_ETHERNET, 'Ethernet Extension'), self.increase_error_count) if self.firmware_version >= (2, 4, 0): async_call(self.master.is_wifi2_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_WIFI2, 'WIFI Extension 2.0'), self.increase_error_count) async_call(self.master.get_connection_type, None, get_connection_type_async, self.increase_error_count) async_call(lambda: None, None, lambda: get_main_window().update_tree_view(), None) def is_wifi2_present_async(self, present): if present: wifi2 = Wifi2(self) self.extensions.append(wifi2) self.tab_widget.addTab(wifi2, 'WIFI 2.0') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_ethernet_present_async(self, present): if present: ethernet = Ethernet(self) self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, 'Ethernet') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_wifi_present_async(self, present): if present: wifi = Wifi(self) self.extensions.append(wifi) self.tab_widget.addTab(wifi, 'WIFI') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_rs485_present_async(self, present): if present: rs485 = RS485(self) self.extensions.append(rs485) self.tab_widget.addTab(rs485, 'RS485') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_chibi_present_async(self, present): if present: chibi = Chibi(self) self.extensions.append(chibi) self.tab_widget.addTab(chibi, 'Chibi') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.check_extensions: self.check_extensions = False self.is_chibi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_CHIBI]) self.is_rs485_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_RS485]) self.is_wifi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI]) self.is_ethernet_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_ETHERNET]) self.is_wifi2_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]) self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True def get_url_part(self): return 'master' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.get_stack_voltage_async, self.increase_error_count) async_call(self.master.get_stack_current, None, self.get_stack_current_async, self.increase_error_count) for extension in self.extensions: extension.update_data() def get_stack_voltage_async(self, voltage): self.stack_voltage_label.setText('{:g} V'.format(round(voltage / 1000.0, 1))) def get_stack_current_async(self, current): self.stack_current_label.setText(format_current(current / 1000.0)) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() if self.firmware_version >= (1, 1, 0): self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) else: self.check_extensions = False self.extension_type_button.setEnabled(False) if self.firmware_version >= (1, 2, 1): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.master.reset()) self.set_actions(reset) self.extension_type_preset = [None, False, False, False, False, False] self.update_extensions_in_device_info() def update_extensions_in_device_info(self): def is_present(present, extension_type, name): self.extension_type_preset[extension_type] = present if present: if self.device_info.extensions['ext0'] == None: self.device_info.extensions['ext0'] = infos.ExtensionInfo() self.device_info.extensions['ext0'].name = name self.device_info.extensions['ext0'].extension_type = extension_type elif self.device_info.extensions['ext1'] == None: self.device_info.extensions['ext1'] = infos.ExtensionInfo() self.device_info.extensions['ext1'].name = name self.device_info.extensions['ext1'].extension_type = extension_type else: pass # This should never be the case if self.firmware_version >= (1, 1, 0): async_call(self.master.is_chibi_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_CHIBI, 'Chibi Extension'), self.increase_error_count) if self.firmware_version >= (1, 2, 0): async_call(self.master.is_rs485_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_RS485, 'RS485 Extension'), self.increase_error_count) if self.firmware_version >= (1, 3, 0): async_call(self.master.is_wifi_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_WIFI, 'WIFI Extension'), self.increase_error_count) if self.firmware_version >= (2, 1, 0): async_call(self.master.is_ethernet_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_ETHERNET, 'Ethernet Extension'), self.increase_error_count) if self.firmware_version >= (2, 4, 0): async_call(self.master.is_wifi2_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_WIFI2, 'WIFI Extension 2.0'), self.increase_error_count) async_call(lambda: None, None, lambda: get_main_window().update_tree_view(), None) def is_wifi2_present_async(self, present): if present: wifi2 = Wifi2(self) self.extensions.append(wifi2) self.tab_widget.addTab(wifi2, 'Wifi 2.0') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_ethernet_present_async(self, present): if present: ethernet = Ethernet(self) self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, 'Ethernet') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_wifi_present_async(self, present): if present: wifi = Wifi(self) self.extensions.append(wifi) self.tab_widget.addTab(wifi, 'WIFI') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_rs485_present_async(self, present): if present: rs485 = RS485(self) self.extensions.append(rs485) self.tab_widget.addTab(rs485, 'RS485') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_chibi_present_async(self, present): if present: chibi = Chibi(self) self.extensions.append(chibi) self.tab_widget.addTab(chibi, 'Chibi') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.check_extensions: self.check_extensions = False self.is_chibi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_CHIBI]) self.is_rs485_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_RS485]) self.is_wifi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI]) self.is_ethernet_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_ETHERNET]) self.is_wifi2_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]) self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True def get_url_part(self): return 'master' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.stack_voltage_update, self.increase_error_count) async_call(self.master.get_stack_current, None, self.stack_current_update, self.increase_error_count) for extension in self.extensions: extension.update_data() def stack_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def stack_current_update(self, sc): if sc < 999: sc_str = "%gmA" % sc else: sc_str = "%gA" % round(sc/1000.0, 1) self.stack_current_label.setText(sc_str) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'Master Brick', version) self.setupUi(self) self.master = BrickMaster(uid, ipcon) self.device = self.master self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.extension_label.setText("None Present") # Chibi widget if self.version >= (1, 1, 0): self.extension_type_button.pressed.connect(self.extension_pressed) async_call(self.master.is_chibi_present, None, self.is_chibi_present_async, self.increase_error_count) else: self.extension_type_button.setEnabled(False) # RS485 widget if self.version >= (1, 2, 0): async_call(self.master.is_rs485_present, None, self.is_rs485_present_async, self.increase_error_count) # Wifi widget if self.version >= (1, 3, 0): async_call(self.master.is_wifi_present, None, self.is_wifi_present_async, self.increase_error_count) # Ethernet widget if self.version >= (2, 1, 0): async_call(self.master.is_ethernet_present, None, self.is_ethernet_present_async, self.increase_error_count) def is_ethernet_present_async(self, present): if present: ethernet = Ethernet(self) self.extensions.append(ethernet) self.extension_layout.addWidget(ethernet) self.num_extensions += 1 self.extension_label.setText("" + str(self.num_extensions) + " Present") def is_wifi_present_async(self, present): if present: wifi = Wifi(self) self.extensions.append(wifi) self.extension_layout.addWidget(wifi) self.num_extensions += 1 self.extension_label.setText("" + str(self.num_extensions) + " Present") def is_rs485_present_async(self, present): if present: rs485 = RS485(self) self.extensions.append(rs485) self.extension_layout.addWidget(rs485) self.num_extensions += 1 self.extension_label.setText("" + str(self.num_extensions) + " Present") def is_chibi_present_async(self, present): if present: chibi = Chibi(self) self.extensions.append(chibi) self.extension_layout.addWidget(chibi) self.num_extensions += 1 self.extension_label.setText("" + str(self.num_extensions) + " Present") def start(self): self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() if self.extension_type: self.extension_type.close() def has_reset_device(self): return self.version >= (1, 2, 1) def reset_device(self): if self.has_reset_device(): self.master.reset() def is_brick(self): return True def is_hardware_version_relevant(self, hardware_version): return True def get_url_part(self): return 'master' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.stack_voltage_update, self.increase_error_count) async_call(self.master.get_stack_current, None, self.stack_current_update, self.increase_error_count) for extension in self.extensions: extension.update_data() def stack_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def stack_current_update(self, sc): if sc < 999: sc_str = "%gmA" % sc else: sc_str = "%gA" % round(sc/1000.0, 1) self.stack_current_label.setText(sc_str) def extension_pressed(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() if self.firmware_version >= (1, 1, 0): self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) else: self.check_extensions = False self.extension_type_button.setEnabled(False) if self.firmware_version >= (1, 2, 1): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.master.reset()) self.set_actions(reset) def is_ethernet_present_async(self, present): if present: ethernet = Ethernet(self) self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, 'Ethernet') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_wifi_present_async(self, present): if present: wifi = Wifi(self) self.extensions.append(wifi) self.tab_widget.addTab(wifi, 'WIFI') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_rs485_present_async(self, present): if present: rs485 = RS485(self) self.extensions.append(rs485) self.tab_widget.addTab(rs485, 'RS485') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_chibi_present_async(self, present): if present: chibi = Chibi(self) self.extensions.append(chibi) self.tab_widget.addTab(chibi, 'Chibi') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.check_extensions: self.check_extensions = False # Chibi widget if self.firmware_version >= (1, 1, 0): async_call(self.master.is_chibi_present, None, self.is_chibi_present_async, self.increase_error_count) # RS485 widget if self.firmware_version >= (1, 2, 0): async_call(self.master.is_rs485_present, None, self.is_rs485_present_async, self.increase_error_count) # Wifi widget if self.firmware_version >= (1, 3, 0): async_call(self.master.is_wifi_present, None, self.is_wifi_present_async, self.increase_error_count) # Ethernet widget if self.firmware_version >= (2, 1, 0): async_call(self.master.is_ethernet_present, None, self.is_ethernet_present_async, self.increase_error_count) self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True def get_url_part(self): return 'master' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.stack_voltage_update, self.increase_error_count) async_call(self.master.get_stack_current, None, self.stack_current_update, self.increase_error_count) for extension in self.extensions: extension.update_data() def stack_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def stack_current_update(self, sc): if sc < 999: sc_str = "%gmA" % sc else: sc_str = "%gA" % round(sc/1000.0, 1) self.stack_current_label.setText(sc_str) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device # the firmware version of a Brick can (under common circumstances) not # change during the lifetime of a Brick plugin. therefore, it's okay to # make final decisions based on it here self.has_status_led = self.firmware_version >= (2, 3, 2) self.update_timer = QTimer(self) self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extension_tabs = [] self.wifi2_firmware_version = None self.wifi2_update_button = IconButton( QIcon(load_pixmap('update-icon-normal.png')), QIcon(load_pixmap('update-icon-hover.png')), self.tab_widget) self.wifi2_update_button.setToolTip('Update available') self.wifi2_update_button.clicked.connect(lambda: get_main_window( ).show_extension_update(self.device_info.uid)) self.wifi2_update_button.hide() self.wifi2_tab_idx = None self.wifi2_start_done = False self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() self.start_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) if self.has_status_led: self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.master.enable_status_led() if checked else self.master.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None reset = QAction('Reset', self) reset.triggered.connect(self.master.reset) self.set_actions([(0, None, [reset])]) self.extension_type_present = [ None, # None False, # Chibi False, # RS485 False, # WIFI False, # Ethernet False ] # WIFI 2.0 self.query_extensions() def show_wifi_update(self): self.device_info.tab_window.show_update_tab_button( 'WIFI Extension 2.0 Update available', lambda: get_main_window(). show_extension_update(self.device_info.uid)) if self.wifi2_tab_idx is not None: self.tab_widget.tabBar().setTabButton(self.wifi2_tab_idx, QTabBar.LeftSide, self.wifi2_update_button) self.wifi2_update_button.show() for ext in self.extension_tabs: if isinstance(ext, Wifi2): ext.wifi_update_firmware_button.show() def hide_wifi_update(self): self.device_info.tab_window.hide_update_tab_button() if self.wifi2_tab_idx is not None: self.tab_widget.tabBar().setTabButton(self.wifi2_tab_idx, QTabBar.LeftSide, None) if self.wifi2_update_button is not None: self.wifi2_update_button.hide() for ext in self.extension_tabs: if isinstance(ext, Wifi2): ext.wifi_update_firmware_button.hide() def hide_master_update(self): self.device_info.tab_window.hide_update_tab_button() if self.device_info.tab_window is not None: self.device_info.tab_window.button_update.hide() def show_master_update(self): self.device_info.tab_window.show_update_tab_button( 'Update available', lambda: get_main_window().show_brick_update( self.device_info.url_part)) if self.device_info.tab_window is not None: self.device_info.tab_window.button_update.show() # overrides PluginBase.device_info_changed def device_info_changed(self, uid): if uid != self.device_info.uid: return if self.extension_type_present[self.master.EXTENSION_TYPE_WIFI2]: wifi_info = self.device_info.get_extension_info( self.master.EXTENSION_TYPE_WIFI2) if wifi_info is None: wifi_update_avail = False else: wifi_update_avail = wifi_info.firmware_version_installed != ( 0, 0, 0 ) and wifi_info.firmware_version_installed < wifi_info.firmware_version_latest else: wifi_update_avail = False brick_update_avail = self.device_info.firmware_version_installed < self.device_info.firmware_version_latest # As the master and wifi update share buttons, first hide all updates, # then show all updates. Control flow such as # if master_update: show else: hide # if wifi_update: show else: hide # would hide some of the controls for the master update if there is no wifi update. if not brick_update_avail: self.hide_master_update() if not wifi_update_avail: self.hide_wifi_update() if brick_update_avail: self.show_master_update() # Intentionally override possible Master Brick update notification: The Extension update is easier for users # so they are more likely to update at least the Extension. Also when the Extension is updated, device_info_changed # will be called again, then notifying the user of the Master Brick update. if wifi_update_avail: self.show_wifi_update() def query_extensions(self): def is_present_async(extension_type, name, present): self.extension_type_present[extension_type] = present if not present: return if self.device_info.extensions['ext0'] == None: ext = 'ext0' elif self.device_info.extensions['ext1'] == None: ext = 'ext1' else: return # This should never be the case self.device_info.extensions[ext] = ExtensionInfo() self.device_info.extensions[ext].name = name self.device_info.extensions[ext].extension_type = extension_type self.device_info.extensions[ext].position = ext self.device_info.extensions[ext].master_info = self.device_info if extension_type == self.master.EXTENSION_TYPE_WIFI2: self.device_info.extensions[ext].url_part = 'wifi_v2' self.device_info.extensions[ ext].update_firmware_version_latest() label = QLabel( 'Waiting for WIFI Extension 2.0 firmware version...') label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) wrapper = QWidget() layout = QVBoxLayout(wrapper) layout.addWidget(label) layout.setContentsMargins(0, 0, 0, 0) self.wifi2_tab_idx = self.tab_widget.addTab( wrapper, 'WIFI 2.0') # When WIFI2 extension firmware version is being requested the # extension might still not be done with booting and thus the # message won't be received by the extension. So we delay sending # the request which gives enough time to the extension to finish # booting. Note that this delay is only induced when there is a # WIFI2 extension present. async_call(self.master.get_wifi2_firmware_version, None, functools.partial( self.get_wifi2_firmware_version_async, ext), self.increase_error_count, delay=2.0) inventory.sync() def get_connection_type_async(connection_type): self.device_info.connection_type = connection_type inventory.sync() async_call( self.master.is_chibi_present, None, functools.partial(is_present_async, self.master.EXTENSION_TYPE_CHIBI, 'Chibi Extension'), self.increase_error_count) async_call( self.master.is_rs485_present, None, functools.partial(is_present_async, self.master.EXTENSION_TYPE_RS485, 'RS485 Extension'), self.increase_error_count) async_call( self.master.is_wifi_present, None, functools.partial(is_present_async, self.master.EXTENSION_TYPE_WIFI, 'WIFI Extension'), self.increase_error_count) if self.firmware_version >= (2, 1, 0): async_call( self.master.is_ethernet_present, None, functools.partial(is_present_async, self.master.EXTENSION_TYPE_ETHERNET, 'Ethernet Extension'), self.increase_error_count) if self.firmware_version >= (2, 4, 0): async_call( self.master.is_wifi2_present, None, functools.partial(is_present_async, self.master.EXTENSION_TYPE_WIFI2, 'WIFI Extension 2.0'), self.increase_error_count) async_call(self.master.get_connection_type, None, get_connection_type_async, self.increase_error_count) async_call(lambda: None, None, get_main_window().update_tree_view, None) def get_wifi2_firmware_version_async(self, ext, version): self.wifi2_firmware_version = version self.device_info.extensions[ext].firmware_version_installed = version # Start the plugin before sending the device_info_changed signal, so that # the slot registered to the signal will already see the plugin in self.extension_tabs. self.wifi2_start() inventory.sync() def wifi2_start(self): if self.wifi2_start_done or self.wifi2_firmware_version == None: return self.wifi2_start_done = True wifi2 = Wifi2(self.wifi2_firmware_version, self) wifi2.start() self.extension_tabs.append(wifi2) wrapper = self.tab_widget.widget(self.wifi2_tab_idx) wrapper.layout().replaceWidget(wrapper.layout().itemAt(0).widget(), wifi2) def add_non_wifi2_tab(self, widget, title): if self.wifi2_tab_idx != None: self.tab_widget.insertTab(self.wifi2_tab_idx, widget, title) self.wifi2_tab_idx += 1 else: self.tab_widget.addTab(widget, title) self.tab_widget.setCurrentIndex(0) def ethernet_start(self): ethernet = Ethernet(self) ethernet.start() self.extension_tabs.append(ethernet) self.add_non_wifi2_tab(ethernet, 'Ethernet') def wifi_start(self): wifi = Wifi(self) wifi.start() self.extension_tabs.append(wifi) self.add_non_wifi2_tab(wifi, 'WIFI') def rs485_start(self): rs485 = RS485(self) rs485.start() self.extension_tabs.append(rs485) self.add_non_wifi2_tab(rs485, 'RS485') def chibi_start(self): chibi = Chibi(self) chibi.start() self.extension_tabs.append(chibi) self.add_non_wifi2_tab(chibi, 'Chibi') def start(self): if self.has_status_led: async_call(self.master.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) if self.start_extensions: self.start_extensions = False if self.extension_type_present[self.master.EXTENSION_TYPE_CHIBI]: self.chibi_start() if self.extension_type_present[self.master.EXTENSION_TYPE_RS485]: self.rs485_start() if self.extension_type_present[self.master.EXTENSION_TYPE_WIFI]: self.wifi_start() if self.extension_type_present[ self.master.EXTENSION_TYPE_ETHERNET]: self.ethernet_start() if self.extension_type_present[self.master.EXTENSION_TYPE_WIFI2]: self.wifi2_start() if self.tab_widget.count() > 0: self.tab_widget.show() self.extension_label.setText( str(self.tab_widget.count()) + " Present") self.label_no_extension.hide() self.update_timer.start(1000) def show_extension(self, ext_idx): self.tab_widget.setCurrentIndex(ext_idx) def stop(self): self.update_timer.stop() def destroy(self): for ext in self.extension_tabs: ext.destroy() ext.hide() ext.setParent(None) self.extension_tabs = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.get_stack_voltage_async, self.increase_error_count) async_call(self.master.get_stack_current, None, self.get_stack_current_async, self.increase_error_count) for ext in self.extension_tabs: ext.update_data() def get_stack_voltage_async(self, voltage): self.stack_voltage_label.setText('{:g} V'.format( round(voltage / 1000.0, 1))) def get_stack_current_async(self, current): self.stack_current_label.setText(format_current(current / 1000.0)) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() if self.firmware_version >= (1, 1, 0): self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) else: self.check_extensions = False self.extension_type_button.setEnabled(False) if self.firmware_version >= (1, 2, 1): reset = QAction("Reset", self) reset.triggered.connect(lambda: self.master.reset()) self.set_actions(reset) self.extension_type_preset = [None, False, False, False, False, False] self.update_extensions_in_device_info() def update_extensions_in_device_info(self): def is_present(present, extension_type, name): self.extension_type_preset[extension_type] = present if present: if self.device_info.extensions["ext0"] == None: self.device_info.extensions["ext0"] = infos.ExtensionInfo() self.device_info.extensions["ext0"].name = name self.device_info.extensions["ext0"].extension_type = extension_type elif self.device_info.extensions["ext1"] == None: self.device_info.extensions["ext1"] = infos.ExtensionInfo() self.device_info.extensions["ext1"].name = name self.device_info.extensions["ext1"].extension_type = extension_type else: pass # This should never be the case if self.firmware_version >= (1, 1, 0): async_call( self.master.is_chibi_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_CHIBI, "Chibi Extension"), self.increase_error_count, ) if self.firmware_version >= (1, 2, 0): async_call( self.master.is_rs485_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_RS485, "RS485 Extension"), self.increase_error_count, ) if self.firmware_version >= (1, 3, 0): async_call( self.master.is_wifi_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_WIFI, "WIFI Extension"), self.increase_error_count, ) if self.firmware_version >= (2, 1, 0): async_call( self.master.is_ethernet_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_ETHERNET, "Ethernet Extension"), self.increase_error_count, ) if self.firmware_version >= (2, 4, 0): async_call( self.master.is_wifi2_present, None, lambda p: is_present(p, self.master.EXTENSION_TYPE_WIFI2, "WIFI Extension 2.0"), self.increase_error_count, ) async_call(lambda: None, None, lambda: get_main_window().update_tree_view(), None) def is_wifi2_present_async(self, present): if present: wifi2 = Wifi2(self) self.extensions.append(wifi2) self.tab_widget.addTab(wifi2, "Wifi 2.0") self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_ethernet_present_async(self, present): if present: ethernet = Ethernet(self) self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, "Ethernet") self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_wifi_present_async(self, present): if present: wifi = Wifi(self) self.extensions.append(wifi) self.tab_widget.addTab(wifi, "WIFI") self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_rs485_present_async(self, present): if present: rs485 = RS485(self) self.extensions.append(rs485) self.tab_widget.addTab(rs485, "RS485") self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def is_chibi_present_async(self, present): if present: chibi = Chibi(self) self.extensions.append(chibi) self.tab_widget.addTab(chibi, "Chibi") self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.check_extensions: self.check_extensions = False self.is_chibi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_CHIBI]) self.is_rs485_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_RS485]) self.is_wifi_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI]) self.is_ethernet_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_ETHERNET]) self.is_wifi2_present_async(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]) self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True def get_url_part(self): return "master" @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.stack_voltage_update, self.increase_error_count) async_call(self.master.get_stack_current, None, self.stack_current_update, self.increase_error_count) for extension in self.extensions: extension.update_data() def stack_voltage_update(self, sv): sv_str = "%gV" % round(sv / 1000.0, 1) self.stack_voltage_label.setText(sv_str) def stack_current_update(self, sc): if sc < 999: sc_str = "%gmA" % sc else: sc_str = "%gA" % round(sc / 1000.0, 1) self.stack_current_label.setText(sc_str) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()
class Master(PluginBase, Ui_Master): def __init__(self, *args): PluginBase.__init__(self, BrickMaster, *args) self.setupUi(self) self.master = self.device # the firmware version of a Brick can (under common circumstances) not # change during the lifetime of a Brick plugin. therefore, it's okay to # make final decisions based on it here self.has_status_led = self.firmware_version >= (2, 3, 2) self.update_timer = QTimer(self) self.update_timer.timeout.connect(self.update_data) self.extension_type = None self.extensions = [] self.num_extensions = 0 self.wifi2_ext = None self.wifi2_firmware_version = None self.wifi_update_button = IconButton(QIcon(load_pixmap('update-icon-normal.png')), QIcon(load_pixmap('update-icon-hover.png')), self.tab_widget) self.wifi_update_button.setToolTip('Update available') self.wifi_update_button.clicked.connect(lambda: get_main_window().show_extension_update(self.device_info.uid)) self.wifi_update_button.hide() self.wifi_update_available = False self.wifi_tab_idx = None self.extension_label.setText("None Present") self.tab_widget.removeTab(0) self.tab_widget.hide() self.check_extensions = True self.extension_type_button.clicked.connect(self.extension_clicked) if self.has_status_led: self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect(lambda checked: self.master.enable_status_led() if checked else self.master.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None reset = QAction('Reset', self) reset.triggered.connect(self.master.reset) self.set_actions([(0, None, [reset])]) self.extension_type_preset = [None, # None False, # Chibi False, # RS485 False, # WIFI False, # Ethernet False] # WIFI 2.0 self.update_extensions_in_device_info() # overrides PluginBase.device_infos_changed def device_infos_changed(self, uid): if uid != self.device_info.uid: return if self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]: try: wifi_info = next(ext for ext in self.device_info.extensions.values() if ext.extension_type == self.master.EXTENSION_TYPE_WIFI2) wifi_update_avail = wifi_info.firmware_version_installed != (0, 0, 0) and wifi_info.firmware_version_installed < wifi_info.firmware_version_latest except StopIteration: wifi_update_avail = False else: wifi_update_avail = False brick_update_avail = self.device_info.firmware_version_installed < self.device_info.firmware_version_latest tab_idx = get_main_window().tab_widget.indexOf(self.device_info.tab_window) if not brick_update_avail and not wifi_update_avail: if self.device_info.tab_window is not None: self.device_info.tab_window.button_update.hide() get_main_window().tab_widget.tabBar().setTabButton(tab_idx, QTabBar.RightSide, None) if self.wifi_tab_idx is not None: self.tab_widget.tabBar().setTabButton(self.wifi_tab_idx, QTabBar.LeftSide, None) if self.wifi_update_button is not None: self.wifi_update_button.hide() return self.update_tab_button = IconButton(QIcon(load_pixmap('update-icon-normal.png')), QIcon(load_pixmap('update-icon-hover.png'))) if brick_update_avail: if self.device_info.tab_window is not None: self.device_info.tab_window.button_update.show() self.update_tab_button.setToolTip('Update available') self.update_tab_button.clicked.connect(lambda: get_main_window().show_brick_update(self.device_info.url_part)) if self.wifi_tab_idx is not None: self.tab_widget.tabBar().setTabButton(self.wifi_tab_idx, QTabBar.LeftSide, None) if self.wifi_update_button is not None: self.wifi_update_button.hide() # Intentionally override possible Master Brick update notification: The Extension update is easier for users # so they are more likely to update at least the Extension. Also when the Extension is updated, device_infos_changed # will be called again, then notifying the user of the Master Brick update. if wifi_update_avail: self.update_tab_button.setToolTip('WIFI Extension 2.0 Update available') self.update_tab_button.clicked.connect(lambda: get_main_window().show_extension_update(self.device_info.uid)) if self.wifi_tab_idx is not None: self.tab_widget.tabBar().setTabButton(self.wifi_tab_idx, QTabBar.LeftSide, self.wifi_update_button) self.wifi_update_button.show() get_main_window().tab_widget.tabBar().setTabButton(tab_idx, QTabBar.RightSide, self.update_tab_button) def update_extensions_in_device_info(self): def is_present_async(present, extension_type, name): self.extension_type_preset[extension_type] = present if present: if self.device_info.extensions['ext0'] == None: ext = 'ext0' elif self.device_info.extensions['ext1'] == None: ext = 'ext1' else: return # This should never be the case self.device_info.extensions[ext] = infos.ExtensionInfo() self.device_info.extensions[ext].name = name self.device_info.extensions[ext].extension_type = extension_type self.device_info.extensions[ext].position = ext self.device_info.extensions[ext].master_info = self.device_info if extension_type == self.master.EXTENSION_TYPE_WIFI2: self.device_info.extensions[ext].url_part = 'wifi_v2' # When WIFI2 extension firmware version is being requested the # extension might still not be done with booting and thus the # message won't be received by the extension. So we delay sending # the request which gives enough time to the extension to finish # booting. Note that this delay is only induced when there is a # WIFI2 extension present. self.wifi2_ext = ext self.label_no_extension.setText('Waiting for WIFI Extension 2.0 firmware version...') async_call(self.master.get_wifi2_firmware_version, None, self.get_wifi2_firmware_version_async, self.increase_error_count, delay=2.0) infos.update_info(self.uid) def get_connection_type_async(connection_type): self.device_info.connection_type = connection_type infos.update_info(self.uid) async_call(self.master.is_chibi_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_CHIBI, 'Chibi Extension'), self.increase_error_count) async_call(self.master.is_rs485_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_RS485, 'RS485 Extension'), self.increase_error_count) async_call(self.master.is_wifi_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_WIFI, 'WIFI Extension'), self.increase_error_count) if self.firmware_version >= (2, 1, 0): async_call(self.master.is_ethernet_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_ETHERNET, 'Ethernet Extension'), self.increase_error_count) if self.firmware_version >= (2, 4, 0): async_call(self.master.is_wifi2_present, None, lambda p: is_present_async(p, self.master.EXTENSION_TYPE_WIFI2, 'WIFI Extension 2.0'), self.increase_error_count) async_call(self.master.get_connection_type, None, get_connection_type_async, self.increase_error_count) async_call(lambda: None, None, get_main_window().update_tree_view, None) def get_wifi2_firmware_version_async(self, version): self.wifi2_firmware_version = version self.device_info.extensions[self.wifi2_ext].firmware_version_installed = version infos.update_info(self.uid) get_main_window().update_tree_view() # FIXME: this is kind of a hack self.wifi2_present(True) def wifi2_present(self, present): if present and self.wifi2_firmware_version != None and not self.check_extensions: wifi2 = Wifi2(self.wifi2_firmware_version, self) wifi2.start() self.extensions.append(wifi2) self.wifi_tab_idx = self.tab_widget.addTab(wifi2, 'WIFI 2.0') self.device_infos_changed(self.device_info.uid) # Trigger device_infos_changed to show potential wifi updates. self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def ethernet_present(self, present): if present: ethernet = Ethernet(self) ethernet.start() self.extensions.append(ethernet) self.tab_widget.addTab(ethernet, 'Ethernet') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def wifi_present(self, present): if present: wifi = Wifi(self) wifi.start() self.extensions.append(wifi) self.tab_widget.addTab(wifi, 'WIFI') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def rs485_present(self, present): if present: rs485 = RS485(self) rs485.start() self.extensions.append(rs485) self.tab_widget.addTab(rs485, 'RS485') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def chibi_present(self, present): if present: chibi = Chibi(self) chibi.start() self.extensions.append(chibi) self.tab_widget.addTab(chibi, 'Chibi') self.tab_widget.show() self.num_extensions += 1 self.extension_label.setText(str(self.num_extensions) + " Present") self.label_no_extension.hide() def start(self): if self.has_status_led: async_call(self.master.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) if self.check_extensions: self.check_extensions = False self.chibi_present(self.extension_type_preset[self.master.EXTENSION_TYPE_CHIBI]) self.rs485_present(self.extension_type_preset[self.master.EXTENSION_TYPE_RS485]) self.wifi_present(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI]) self.ethernet_present(self.extension_type_preset[self.master.EXTENSION_TYPE_ETHERNET]) self.wifi2_present(self.extension_type_preset[self.master.EXTENSION_TYPE_WIFI2]) self.update_timer.start(1000) def stop(self): self.update_timer.stop() def destroy(self): for extension in self.extensions: extension.destroy() extension.hide() extension.setParent(None) self.extensions = [] if self.extension_type: self.extension_type.close() def is_hardware_version_relevant(self): return True @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickMaster.DEVICE_IDENTIFIER def update_data(self): async_call(self.master.get_stack_voltage, None, self.get_stack_voltage_async, self.increase_error_count) async_call(self.master.get_stack_current, None, self.get_stack_current_async, self.increase_error_count) for extension in self.extensions: extension.update_data() def get_stack_voltage_async(self, voltage): self.stack_voltage_label.setText('{:g} V'.format(round(voltage / 1000.0, 1))) def get_stack_current_async(self, current): self.stack_current_label.setText(format_current(current / 1000.0)) def extension_clicked(self): if self.extension_type is None: self.extension_type = ExtensionType(self) self.extension_type.show()